I’ve got FreeRTOS 7.10 running on a Blackfin BF52x series. Tasks, semaphores etc are working fine.
I now want to integrate the AD supplied USB device stack. The USB driver is itself interrupt driven with an ISR callback invoked when connections etc occur. In this case there are only 3 interrupts at work, the timer, context switcher, and the USB. I’m assuming that xSemaphoreGiveFromISR() will be used to signal to the thread that some USB event has happened.
Are there any priority issues to worry about here? And has anyone else got an example that integrates a USB ISR with FreeRTOS threads? Does *not* have to be Blackfin, just something to get the right pattern.
I will post the BF project if anyone wants it - it’s based on the sample posted for the BF533 but should work for all single core BF processors.
I’m assuming that xSemaphoreGiveFromISR() will be used to signal to the thread that some USB event has happened
That would be a common way of doing it, yes. If there is a lot of processing to be done, you can even use that method to defer interrupt processing to a task to allow you to get out of the interrupt quickly. If the handler task has a suitably high priority, it will be executed as soon as the ISR completes (assuming you have implemented a task switch from ISR function) so it will execute contiguous in time with the interrupt.
Have you implemented interrupt nesting?
If so, you will need definitions for portSET_INTERRUPT_MASK_FROM_ISR and portCLEAR_INTERRUPT_MASK_FROM_ISR - you can use the PIC32 port as an example (FreeRTOS/Source/portable/MPLAB/PIC32MX/portmacro.h). Then, run the kernel tick at the lowest interrupt priority, and define configMAX_SYSCALL_INTERRUPT_PRIORITY however is appropriate for your port. See http://www.freertos.org/a00110.html#kernel_priority. Then you will be able to use the FreeRTOS API functions that end in FromISR safely, and the kernel code will take care of the rest.
I am not using nested interrupts at the moment, it’s one step at a time as I battle with the Blackfin tools …
A couple of questions if I may:
1. Slightly confused about binary semaphores. Thought if the ISR did a Give() and the worker thread did a Take() this synchronisation mechanism could be reused at each ISR invocation? Appears to work once then be permanently ‘given’?
2. If I replace the semaphore with a queue, the worker thread never pends on the xQueueReceive(), even with portMAX_DELAY for the timeout value. Is this working as designed?
It is entirely possible that this shows up a port problem but using these FreeRTOS API’s from standard ‘tasks’ seems to work fine.
1. Slightly confused about binary semaphores. Thought if the ISR did a Give() and the worker thread did a Take() this synchronisation mechanism could be reused at each ISR invocation? Appears to work once then be permanently ‘given’?
That does not sound right - something is amiss.
Normally the thread would only ever perform takes, and the ISR would only ever perform gives, as per your suggestion. If the ISR gives, and the thread takes, then the semaphore should be ‘empty’ again and able to receive another give. Even if the semaphore is not empty when the give occurs it should not cause a problem because the semaphore will be immediately available when the thread tries a take. You can also use counting semaphores.
2. If I replace the semaphore with a queue, the worker thread never pends on the xQueueReceive(), even with portMAX_DELAY for the timeout value. Is this working as designed?
Definitely not as designed. You seem to have problems somewhere with your queue mechanism, and this probably is also relevant to your first issue. The queue code is part of the kernel core, not the portable layer, so it should be fine no matter what you run it on - official or unofficial ports. The only thing almost port dependent in the RTOS tick used to generate the time base for blocking. If you specify a block time of portMAX_DELAY you should not unblock unless there is something in the queue - is there something in the queue? What does xQueueReceive() return?