Eileen Yoon (eyn@p.nosp@m.urdu.nosp@m.e.edu)
usage as drop-in replacement for psched:
void heartbeat_LED() { PHAL_toggleGPIO(HEARTBEAT_LED_PORT, HEARTBEAT_LED_PIN); }
defineThreadStack(heartbeat_LED, 500, osPriorityNormal, 256);
defineStaticSemaphore(myHandle);
int main(void)
{
osKernelInitialize();
if(0 != PHAL_configureClockRates(&clock_config))
{
HardFault_Handler();
}
NVIC_SetPriority(CAN1_RX0_IRQn, 6);
createThread(heartbeat_LED);
myHandle = createStaticSemaphore();
osKernelStart();
}
Wrapper macros for FreeRTOS constructs (tasks, queues, semaphores) to simplify static memory allocati...
Very good resource: Mastering the FreeRTOS™ Real Time Kernel https://www.freertos.org/Documentation/02-Kernel/07-Books-and-manual/01-RTOS_book
Key notes:
- under the freertos kernel, a task can either be in running or blocked state. you can only block a task (in the freertos sense) by calling an rtos blocking function, e.g. osDelay, semaphore wait, queue receive, etc.
- blocking in the freertos sense does not mean it blocks in the usual sense (i.e. polls and waits within that function), it will switch to another task.
- specifically freertos will always execute the highest priority task that can run (i.e. not in blocked state)
Other notes:
- if it crashes try increasing stack size
- lock all hardware acceses, e.g. spi transfers. best to raise a semaphore in the ISR when its done
- switch queues (e.g can queues) to freertos queues so freertos knows to block. TODO CAN wrapper
- if the total given loop time is less than the time it takes to actually execute all the tasks, lower priority tasks (or the tasks started last) will not be executed (task starved)
- use static allocations for all freertos objects (queues, sema) hence the macros here
- no static local variables
- direct task notifications are useful for state machines. e.g.
e.g. eth_send_udp_periodic() blocks until a direct notification from the state updater eth_update_connection_state()
static void eth_update_connection_state(void)
switch (dh.eth_state)
case ETH_IDLE:
if (eth_init() == ETH_ERROR_NONE)
{
dh.eth_state = ETH_LINK_UP;
}
static void eth_send_udp_periodic(void)
if (dh.eth_state != ETH_LINK_UP)
{
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
}
#define getTaskHandle(NAME)
Retrieves the FreeRTOS task handle for the defined task.
Definition freertos.h:93
- note eth_send_udp_periodic child task has to be started before eth_update_connection_state so it can enter blocking state