Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add one more semaphore-related function. #745

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion lispBM/c_libs/vesc_c_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -650,12 +650,16 @@ typedef struct {
const float* (*foc_get_audio_sample_table)(int channel);
bool (*foc_play_audio_samples)(const int8_t *samples, int num_samp, float f_samp, float voltage);

// Semaphore
// Semaphores
lib_semaphore (*sem_create)(void); // Use VESC_IF->free on the semaphore when done with it
void (*sem_wait)(lib_semaphore);
void (*sem_signal)(lib_semaphore);
bool (*sem_wait_to)(lib_semaphore, systime_t); // Returns false on timeout
void (*sem_reset)(lib_semaphore);
int32_t (*sem_drain_and_wait_timeout)(lib_semaphore, systime_t);

// Os continued
systime_t (*time_to_ticks)(uint32_t seconds, uint32_t millis, uint32_t micros);
} vesc_c_if;

typedef struct {
Expand Down
31 changes: 31 additions & 0 deletions lispBM/lispif_c_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,33 @@ static void lib_sem_reset(lib_semaphore s) {
chSemReset((semaphore_t*)s, 0);
}

// Guaranteed to block. First drains the semaphore to 0 if its counter is positive and
// then waits on it with given timeout(special values TIME_IMMEDIATE and TIME_INFINITE are honored).
// Returns MSG_RESET or MSG_TIMEOUT if that was the result of the wait operations.
// Otherwise returns a non-negative number of overruns, i.e. the number by which the semaphore
// had to be decreased before the wait operation.
//
// Useful for implementing binary-semaphore like semantics where it's important to ignore
// semaphore overruns.
static int32_t lib_sem_drain_and_wait_timeout(lib_semaphore sem, systime_t timeout) {
chSysLock();
const cnt_t sem_counter = chSemGetCounterI((semaphore_t*)sem);
// setCounter isn't exposed and I don't want to manually manipulate the internal counter
for (cnt_t i = 0; i < sem_counter; i++) {
chSemFastWaitI((semaphore_t*)sem);
}
const msg_t wait_result = chSemWaitTimeoutS((semaphore_t*)sem, timeout);
chSysUnlock();
if (wait_result < 0) { // MSG_RESET and MSG_TIMEOUT are negative
return wait_result;
}
return sem_counter < 0 ? 0 : sem_counter;
}

static systime_t lib_time_to_ticks(uint32_t seconds, uint32_t millis, uint32_t micros) {
return S2ST(seconds) + MS2ST(millis) + US2ST(micros);
}

static remote_state lib_get_remote_state(void) {
remote_state res;
res.js_x = app_nunchuk_get_decoded_x();
Expand Down Expand Up @@ -1022,6 +1049,10 @@ lbm_value ext_load_native_lib(lbm_value *args, lbm_uint argn) {
cif.cif.sem_signal = lib_sem_signal;
cif.cif.sem_wait_to = lib_sem_wait_to;
cif.cif.sem_reset = lib_sem_reset;
cif.cif.sem_drain_and_wait_timeout = lib_sem_drain_and_wait_timeout;

// OS continued
cif.cif.time_to_ticks = lib_time_to_ticks;

lib_init_done = true;
}
Expand Down