Use task notification for mixer scheduler: faster and less RAM
This commit is contained in:
@@ -35,6 +35,8 @@
|
||||
#define configUSE_TRACE_FACILITY 0 // 1 rco: save some memory?
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configIDLE_SHOULD_YIELD 1
|
||||
// Use notifications
|
||||
#define configTASK_NOTIFICATION_ARRAY_ENTRIES 2
|
||||
#define configUSE_MUTEXES 0
|
||||
#define configQUEUE_REGISTRY_SIZE 0
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 0
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#if !defined(SIMU)
|
||||
|
||||
// Global trigger flag
|
||||
RTOS_FLAG_HANDLE mixerFlag;
|
||||
|
||||
// Mixer schedule
|
||||
struct MixerSchedule {
|
||||
@@ -52,7 +51,6 @@ uint16_t getMixerSchedulerPeriod()
|
||||
|
||||
void mixerSchedulerInit()
|
||||
{
|
||||
RTOS_CREATE_MUTEX(mixerFlag);
|
||||
memset(mixerSchedules, 0, sizeof(mixerSchedules));
|
||||
}
|
||||
|
||||
@@ -68,15 +66,48 @@ void mixerSchedulerSetPeriod(uint8_t moduleIdx, uint16_t periodUs)
|
||||
mixerSchedules[moduleIdx].period = periodUs;
|
||||
}
|
||||
|
||||
|
||||
bool mixerSchedulerWaitForTrigger(uint8_t timeoutMs)
|
||||
{
|
||||
return RTOS_WAIT_FLAG(mixerFlag, timeoutMs);
|
||||
uint32_t ulNotificationValue;
|
||||
const TickType_t xMaxBlockTime = pdMS_TO_TICKS( timeoutMs );
|
||||
|
||||
/* Wait to be notified that the transmission is complete. Note
|
||||
the first parameter is pdTRUE, which has the effect of clearing
|
||||
the task's notification value back to 0, making the notification
|
||||
value act like a binary (rather than a counting) semaphore. */
|
||||
ulNotificationValue = ulTaskNotifyTakeIndexed( 1 /* task notification index */,
|
||||
pdTRUE,
|
||||
xMaxBlockTime );
|
||||
|
||||
if( ulNotificationValue == 1 ) {
|
||||
/* The transmission ended as expected. */
|
||||
return false;
|
||||
|
||||
} else {
|
||||
/* The call to ulTaskNotifyTake() timed out. */
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void mixerSchedulerISRTrigger()
|
||||
{
|
||||
RTOS_ISR_SET_FLAG(mixerFlag);
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
/* At this point xTaskToNotify should not be NULL as
|
||||
a transmission was in progress. */
|
||||
configASSERT( mixerTaskId.rtos_handle != NULL );
|
||||
|
||||
/* Notify the task that the transmission is complete. */
|
||||
vTaskNotifyGiveIndexedFromISR( mixerTaskId.rtos_handle,
|
||||
1 /* task notification index */,
|
||||
&xHigherPriorityTaskWoken );
|
||||
|
||||
/* If xHigherPriorityTaskWoken is now set to pdTRUE then a
|
||||
context switch should be performed to ensure the interrupt
|
||||
returns directly to the highest priority task. The macro used
|
||||
for this purpose is dependent on the port in use and may be
|
||||
called portEND_SWITCHING_ISR(). */
|
||||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+25
-38
@@ -75,26 +75,6 @@ extern "C++" {
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
static inline void RTOS_CREATE_FLAG(RTOS_FLAG_HANDLE flag)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void RTOS_SET_FLAG(RTOS_FLAG_HANDLE flag)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void RTOS_CLEAR_FLAG(RTOS_FLAG_HANDLE flag)
|
||||
{
|
||||
}
|
||||
|
||||
static inline bool RTOS_WAIT_FLAG(RTOS_FLAG_HANDLE flag, uint32_t timeout)
|
||||
{
|
||||
simuSleep(timeout);
|
||||
return false;
|
||||
}
|
||||
|
||||
#define RTOS_ISR_SET_FLAG RTOS_SET_FLAG
|
||||
|
||||
template<int SIZE>
|
||||
class FakeTaskStack
|
||||
{
|
||||
@@ -169,7 +149,6 @@ inline void RTOS_CREATE_TASK(pthread_t &taskId, void * (*task)(void *), const ch
|
||||
|
||||
#define RTOS_MS_PER_TICK portTICK_PERIOD_MS
|
||||
|
||||
// TODO:
|
||||
typedef struct {
|
||||
TaskHandle_t rtos_handle;
|
||||
StaticTask_t task_struct;
|
||||
@@ -217,25 +196,29 @@ inline void RTOS_CREATE_TASK(pthread_t &taskId, void * (*task)(void *), const ch
|
||||
#define RTOS_CREATE_TASK(h,task,name,stackStruct,stackSize,prio) \
|
||||
_RTOS_CREATE_TASK(&h,task,name,stackStruct.stack,stackSize,prio)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
static inline void RTOS_CREATE_MUTEX(RTOS_MUTEX_HANDLE& h)
|
||||
static inline void _RTOS_CREATE_MUTEX(RTOS_MUTEX_HANDLE* h)
|
||||
{
|
||||
h.rtos_handle = xSemaphoreCreateBinaryStatic(&h.mutex_struct);
|
||||
xSemaphoreGive(h.rtos_handle);
|
||||
h->rtos_handle = xSemaphoreCreateBinaryStatic(&h->mutex_struct);
|
||||
xSemaphoreGive(h->rtos_handle);
|
||||
}
|
||||
|
||||
static inline void RTOS_LOCK_MUTEX(RTOS_MUTEX_HANDLE& h)
|
||||
#define RTOS_CREATE_MUTEX(handle) _RTOS_CREATE_MUTEX(&handle)
|
||||
|
||||
static inline void _RTOS_LOCK_MUTEX(RTOS_MUTEX_HANDLE* h)
|
||||
{
|
||||
xSemaphoreTake(h.rtos_handle, portMAX_DELAY);
|
||||
xSemaphoreTake(h->rtos_handle, portMAX_DELAY);
|
||||
}
|
||||
|
||||
static inline void RTOS_UNLOCK_MUTEX(RTOS_MUTEX_HANDLE& h)
|
||||
{
|
||||
xSemaphoreGive(h.rtos_handle);
|
||||
}
|
||||
#endif // __cplusplus
|
||||
#define RTOS_LOCK_MUTEX(handle) _RTOS_LOCK_MUTEX(&handle)
|
||||
|
||||
static inline void _RTOS_UNLOCK_MUTEX(RTOS_MUTEX_HANDLE* h)
|
||||
{
|
||||
xSemaphoreGive(h->rtos_handle);
|
||||
}
|
||||
|
||||
#define RTOS_UNLOCK_MUTEX(handle) _RTOS_UNLOCK_MUTEX(&handle)
|
||||
|
||||
//TODO: replace with FreeRTOS functions
|
||||
static inline uint32_t getStackAvailable(void * address, uint32_t size)
|
||||
{
|
||||
uint32_t * array = (uint32_t *)address;
|
||||
@@ -262,25 +245,29 @@ inline void RTOS_CREATE_TASK(pthread_t &taskId, void * (*task)(void *), const ch
|
||||
//#define RTOS_SET_FLAG(flag) (void)CoSetFlag(flag)
|
||||
//#define RTOS_CLEAR_FLAG(flag) (void)CoClearFlag(flag)
|
||||
|
||||
#ifdef __cplusplus
|
||||
// returns true if timeout
|
||||
static inline bool RTOS_WAIT_FLAG(RTOS_FLAG_HANDLE& flag, uint32_t timeout)
|
||||
static inline bool _RTOS_WAIT_FLAG(RTOS_FLAG_HANDLE* flag, uint32_t timeout)
|
||||
{
|
||||
return xSemaphoreTake(flag.rtos_handle, timeout * RTOS_MS_PER_TICK)
|
||||
return xSemaphoreTake(flag->rtos_handle, timeout * RTOS_MS_PER_TICK)
|
||||
== pdFALSE;
|
||||
}
|
||||
|
||||
static inline void RTOS_ISR_SET_FLAG(RTOS_FLAG_HANDLE& flag)
|
||||
#define RTOS_WAIT_FLAG(flag,timeout) _RTOS_WAIT_FLAG(&flag,timeout)
|
||||
|
||||
static inline void _RTOS_ISR_SET_FLAG(RTOS_FLAG_HANDLE* flag)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
// Give semaphore back from ISR to trigger a task waiting for it
|
||||
xSemaphoreGiveFromISR( flag.rtos_handle, &xHigherPriorityTaskWoken );
|
||||
xSemaphoreGiveFromISR( flag->rtos_handle, &xHigherPriorityTaskWoken );
|
||||
|
||||
// If xHigherPriorityTaskWoken was set to true we should yield
|
||||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
|
||||
#define RTOS_ISR_SET_FLAG(flag) _RTOS_ISR_SET_FLAG(&flag)
|
||||
|
||||
#ifdef __cplusplus
|
||||
template<int SIZE>
|
||||
class TaskStack
|
||||
{
|
||||
|
||||
@@ -51,7 +51,6 @@ void init_intmodule_heartbeat()
|
||||
|
||||
NVIC_SetPriority(INTMODULE_HEARTBEAT_EXTI_IRQn,
|
||||
// Highest priority interrupt
|
||||
// TODO: replace with a define...
|
||||
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
|
||||
|
||||
NVIC_EnableIRQ(INTMODULE_HEARTBEAT_EXTI_IRQn);
|
||||
|
||||
@@ -39,7 +39,6 @@ void mixerSchedulerStart()
|
||||
|
||||
NVIC_EnableIRQ(MIXER_SCHEDULER_TIMER_IRQn);
|
||||
NVIC_SetPriority(MIXER_SCHEDULER_TIMER_IRQn,
|
||||
// TODO: replace with a define...
|
||||
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
|
||||
|
||||
MIXER_SCHEDULER_TIMER->SR &= TIM_SR_UIF; // clear interrupt flag
|
||||
|
||||
Reference in New Issue
Block a user