Summary
I have been writing a bunch of articles about implementing PSoC FreeRTOS so, this morning I was reading the FreeRTOS manual (yes I am one of those…) and I noticed a section in the API guide that I hadn’t see before… Task Notifications. Every task in the FreeRTOS has a built in 32-bit integer notification value. This value is super light weight and can be used like a task specific counting semaphore, or a signaling bit mask, or binary semaphore. The API includes:
- xTaskNotifyGive()
- vTaskNotifyGiveFromISR()
- ulTaskNotifyTake()
- xTaskNotify()
- xTaskNotifyAndQuery()
- xTaskNotifyAndQueryFromISR()
- xTaskNotifyFromISR()
- xTaskNotifyWait()
- xTaskNotifyStateClear()
It seems like this API is good for the situations when your Semaphore has a specific task target in mind. I thought that this would be a perfect scheme to have a PSoC FreeRTOS UART ISR signal the UART Handling task that there is data available to do something with.
Setup the PSoC FreeRTOS Project
I start this process by making a copy of “1-BlinkingLED” (which already has all of the FreeRTOS stuff in it) and naming it “9-TaskNotify”. Then I add a UART to the schematic and name it “UART”
I attach the UART to the right pins on the CY8CKIT-044 kit.
Next I turn on the interrupt which will be called when there is data in the receive FIFO.
PSoC FreeRTOS UART Code
Now that the schematic is all configured I update my firmware. The function “uartHandler” is called when there is data in the UART RX FIFO. It turns of the interrupts for the UART (which I will turn back on after I have cleared the data in the input buffer), clears the interrupt (so that it will stop pending) and then sends the notification to the UART_Task.
The UART Task just registers the handler… then while(1)’s until the end of time. It waits for a notification, then reads data out of the RX fifo and puts out, then re-enables the interrupts.
CY_ISR(uartHandler) { BaseType_t xHigherPriorityTaskWoken; // disable the interrupt UART_SetRxInterruptMode(0); vTaskNotifyGiveFromISR(uartTaskHandle,&xHigherPriorityTaskWoken); portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); } void UART_Task( void *arg) { (void)arg; char c; UART_Start(); UART_SetCustomInterruptHandler(uartHandler); while(1) { ulTaskNotifyTake(pdTRUE,portMAX_DELAY); while(UART_SpiUartGetRxBufferSize()) { c = UART_UartGetChar(); UART_UartPutChar(c); } // clear & re-enable the interrupt UART_ClearRxInterruptSource(UART_INTR_RX_NOT_EMPTY); UART_SetRxInterruptMode(UART_INTR_RX_NOT_EMPTY); } }
Topic
Description
FreeRTOS: A PSoC4 FreeRTOS Port
An introduction to making FreeRTOS work on PSoC 4
FreeRTOS PSoC Examples
Using multiple tasks in FreeRTOS
FreeRTOS Queue Example
Using a queue to communicate between tasks
PSoC 6 FreeRTOS - The First Example
Booting FreeRTOS on PSoC 6
FreeRTOS Binary Semaphore
An first example of a binary semaphore
FreeRTOS Binary Semaphore (Part 2)
Removing polling in the UART Task
FreeRTOS Counting Semaphore
An example using a counting semaphore
PSoC FreeRTOS
Reading I2C Sensors with a shared I2C Bus
PSoC FreeRTOS Task Notify
A light weight scheme to replace Semaphores
PSoC FreeRTOS Task Notification Values
A very light weight method to transfer one word of information into a task
No comment yet, add your voice below!