Semaphore Issue on STM32

anonymous wrote on Wednesday, July 13, 2011:

I have several tasks running, and two peripherals on a single SPI port.  I am using a semaphore to protect access to the SPI port so that one task that is using it finished before another task needs it (regardless of which peripheral).  I use xSemaphoreTake to “grab” the semaphore, and xSemaphoreGive to “release” it.  This has been working fine for quite a while, but recently I added a new reference to one of the SPI peripherals and I’m getting an odd hang.  It is hanging in the loop in vListInsert that has all the warnings about interrupt priorities on Cortex cores.  But all of my interrupts are set to configLIBRARY_KERNEL_INTERRUPT_PRIORITY (15, lowest priority), and the hang doesn’t occur in an interrupt at all.  What I see stepping through the debugger (IAR) is that one task grabs the SPI port, then a second task calls the xSemaphoreTake and blocks, as it should.  But the first task then never gives up the semaphore, and as best I can tell no more task switches occur while the second task is blocked.  I’m kind of at a loss on how to debug this.  Anyone have any suggestions?

anonymous wrote on Wednesday, July 13, 2011:

Oddly enough, rearranging the declarations of my semaphores made the lockup go away.  Very scary.

rtel wrote on Wednesday, July 13, 2011:

But all of my interrupts are set to configLIBRARY_KERNEL_INTERRUPT_PRIORITY (15, lowest priority), and the hang doesn’t occur in an interrupt at all.

You have to be very careful here on the STM32, as, unlike most (all?) other Cortex-M3 parts you normally have to manually set the number of pre-emption priority bits too.  That need only be done once, during start up, before the kernel is started.  Try placing a call to NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 ); at the start of main().  Getting the interrupt configuration wrong can have subtle side effects that you might not think are anything to do with the interrupts, but turn out to  be.

Oddly enough, rearranging the declarations of my semaphores made the lockup go away.  Very scary.

Yes that is scary.  Presumably the semaphores are being created correctly before being used, otherwise they wouldn’t work at all.  If you are saying that just changing their positioning in the memory map by changing where they are declared effects how they operate - then that could point to a problem in the linker script, overflowing heap, etc.  Do you have stack checking turned on?  It could just be a bug elsewhere in your application code that is corrupting RAM that was being used to hold the semaphore, but when you move it another variable is being corrupted instead.

Regards.

rtel wrote on Wednesday, July 13, 2011:

I think it is mentioned on a lot of pages, but here is one to start with: http://www.freertos.org/portlpc2106.html  Read the “Interrupt Service Routines” section, where it talks about an assembly wrapper.  Depending on your version of GCC, you may find that the call to the C function from the assembly wrapper also needs to be done using an asm statement.

Regards.

rtel wrote on Wednesday, July 13, 2011:

Ignore that last post - it was meant for another thread.

Regardsd.