# Unable to use BinarySemaphore on Cortex-M3

**URL:** <https://forums.freertos.org/t/unable-to-use-binarysemaphore-on-cortex-m3/4996>\
**Category:** Kernel\
**Created:** [May 21, 2010, 10:40am UTC](https://forums.freertos.org/t/unable-to-use-binarysemaphore-on-cortex-m3/4996 "2010-05-21T10:40:54Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [May 21, 2010, 10:40am UTC](https://forums.freertos.org/t/unable-to-use-binarysemaphore-on-cortex-m3/4996/1 "2010-05-21T10:40:54Z")

</div>

**[rgrover1](https://sourceforge.net/u/rgrover1/)** wrote on [Friday, May 21, 2010](https://sourceforge.net/p/freertos/discussion/382005/thread/dd28e376/#3b4c):

I am working with FreeRTOS6.0.4 using GCC on a Cortex-M3.

I would like to implement a driver for the UART peripheral using interrupts.  
I have created a binary semaphore to synchronize between the ISR and the task calling Uart\_GetChar(). The interrupt handler gets called, but it is unable to wakeup the task waiting on the binary semaphore. ☹

I started with the standard port for CORTEX\_CM3 and simply linked the PendSV\_Handler and SVC\_Handler to the appropriate functions in the port. Everything else seemed to be working thus far.

The following is the code I’m using:

uint8\_t  
UART\_GetChar(volatile Uart \*pUart)  
{  
&nbsp;&nbsp;&nbsp; /\* wait indefinitely for data to arrive \*/  
&nbsp;&nbsp;&nbsp; while ((pUart-\>UART\_SR & UART\_SR\_RXRDY) == 0) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xSemaphoreTake(xBinarySemaphore, portMAX\_DELAY);  
&nbsp;&nbsp;&nbsp; }

&nbsp;&nbsp;&nbsp; return (pUart-\>UART\_RHR);  
}

void  
UART0\_IrqHandler(void)  
{  
&nbsp;&nbsp;&nbsp; portBASE\_TYPE xHigherPriorityTaskWoken;

&nbsp;&nbsp;&nbsp; xHigherPriorityTaskWoken = pdFALSE;

&nbsp;&nbsp;&nbsp; /\* unblock a task waiting for data to arrive at UART0. \*/  
&nbsp;&nbsp;&nbsp; xSemaphoreGiveFromISR(xBinarySemaphore, &xHigherPriorityTaskWoken);  
&nbsp;&nbsp;&nbsp; if (xHigherPriorityTaskWoken == pdTRUE) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /\*  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \* If the priority of the unblocked task is higher than the  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \* currently running task - force a context switch to ensure  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \* that the interrupt returns directly to the unblocked  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \* (higher priority) task-i.e. the task waiting for the data.  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \*/  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; portYIELD();  
&nbsp;&nbsp;&nbsp; }  
}

I have verified that my interrupt handler gets called (using an LED).

Through debugging printfs, I have discovered that the IRQ is called only once (even though I’m generating multiple events) and the task is blocked within the call to xTaskResumeAll() (at line 944 in queue.c):

vTaskPlaceOnEventList( &( pxQueue-\>xTasksWaitingToReceive ), xTicksToWait );  
prvUnlockQueue( pxQueue );  
if( !xTaskResumeAll() )  
{  
portYIELD\_WITHIN\_API();  
}

Could someone please help?

Thanks.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [May 21, 2010, 10:52am UTC](https://forums.freertos.org/t/unable-to-use-binarysemaphore-on-cortex-m3/4996/2 "2010-05-21T10:52:24Z")

</div>

**[davedoors](https://sourceforge.net/u/davedoors/)** wrote on [Friday, May 21, 2010](https://sourceforge.net/p/freertos/discussion/382005/thread/dd28e376/#163a):

What priority is the UART interrupt running at? Is it at or below whatever you have configMAX\_SYSCALL\_INTERRUPT\_PRIORITY. And remember that a lower interrupt priority means a higher number (priority 5 is lower than priority 4). Are you sure that you have passed the priority into the function used to set the interrupt priority correctly as some want the number shifted and others don’t.

One other thing, you don’t mention that you installed the SysTick interrupt, which is another one FreeRTOS uses.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [May 21, 2010, 2:29pm UTC](https://forums.freertos.org/t/unable-to-use-binarysemaphore-on-cortex-m3/4996/3 "2010-05-21T14:29:08Z")

</div>

**[rgrover1](https://sourceforge.net/u/rgrover1/)** wrote on [Friday, May 21, 2010](https://sourceforge.net/p/freertos/discussion/382005/thread/dd28e376/#fc41):

I have not set the priority for the UART interrupt. According to the microcontroller’s datasheet, the uart interrupt would be running priority 0. Oops. This means that it is running at a priority higher than configMAX\_SYSCALL\_INTERRUPT\_PRIORITY while still attempting to use a FreeRTOS API. Perhaps that could explain why my program isn’t working.

I fail to understand why an interrupt executing at a high priority would fail to Give() to a binary semaphore. All it would need to do is to set the semaphore as being available and setup a pending SV exception to be triggered upon return. Why would this run into trouble because of the priority especially since nothing else in the system is competing with this sequence?

By the way, I forgot to mention that I have also setup the SysTick interrupt handler to be the one provided by the port.

I will try to set a reasonable priority for the UART interrupt and report back. Thanks.

---

<div class="post-metadata">

**Author:** ![richard-damon](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/richard-damon/32/38_2.png) [@richard-damon](https://forums.freertos.org/u/richard-damon)\
**Post date:** [May 21, 2010, 7:44pm UTC](https://forums.freertos.org/t/unable-to-use-binarysemaphore-on-cortex-m3/4996/4 "2010-05-21T19:44:52Z")

</div>

**[richard\_damon](https://sourceforge.net/u/richard_damon/)** wrote on [Friday, May 21, 2010](https://sourceforge.net/p/freertos/discussion/382005/thread/dd28e376/#f745):

The issue with I high priority interrupt accessing FreeRTOS structures is that they may not be in a stable condition, and accessing them may corrupt their state. FreeRTOS may (depending on the port) only block interrupts below a given priority when modifying critical resources, in order to not impact the latency of those higher priority interrupts that don’t need to interact with FreeRTOS.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [May 22, 2010, 4:38am UTC](https://forums.freertos.org/t/unable-to-use-binarysemaphore-on-cortex-m3/4996/5 "2010-05-22T04:38:48Z")

</div>

**[rgrover1](https://sourceforge.net/u/rgrover1/)** wrote on [Saturday, May 22, 2010](https://sourceforge.net/p/freertos/discussion/382005/thread/dd28e376/#8378):

Hello again,

I tried setting the priority of the UART interrupt to configMAX\_SYSCALL\_INTERRUPT\_PRIORITY-see the Configure() function included below,-but that still doesn’t help. I have added code in my UART0 ISR to toggle an LED, but the LED gets set only once. The task waiting in GetChar doesn’t make progress.

Please help.

```
#if defined( __FREERTOS__ ) && defined(UART_USES_INTERRUPTS)
/* The following pair of counting semaphores (one per UART) allow
 * tasks to block waiting for interrupt events. */
static xSemaphoreHandle xBinarySemaphore[2];
#endif /* defined( __FREERTOS__ ) && defined(UART_USES_INTERRUPTS) */
/**
 * \brief Configures an UART peripheral with the specified
 * parameters. The UART is configured for 8-bit I/O (with no parity)
 * using interrupts.
 *
 * \param uart The UART's configuration base memory address; as
 * defined in board/at91sam3s4/AT91SAM3S4.h.
 *
 * \param baud Baudrate at which the UART should operate (in Hz).
 */
void
UART_Configure(Uart *pUart, uint32_t baud)
{
    const Pin pins[] = {PINS_UART0, PINS_UART1};
    /*
     * For the AT91SAM3S4 micro-controller, there can only be two
     * possile UARTs. Given the UART's base address as a parameter, it
     * is possible to deduce some of the required initial state.
     */
    if (pUart == UART0) {
#if defined( __FREERTOS__ ) && defined(UART_USES_INTERRUPTS)
        /* IRQ must be enabled before configuring the UART registers */
        NVIC_EnableIRQ(UART0_IRQn);
        NVIC_SetPriority(UART0_IRQn, configMAX_SYSCALL_INTERRUPT_PRIORITY);
        vSemaphoreCreateBinary(xBinarySemaphore[0]);
#endif /* defined( __FREERTOS__ ) && defined(UART_USES_INTERRUPTS) */
        /* Configure the use of the UART pins */
        PIO_Configure(&pins[0], 1);
        /* Configure PMC to enable the UART0 peripheral */
        PMC->PMC_PCER0 = 1 << ID_UART0;
    } else if (pUart == UART1) {
#if defined( __FREERTOS__ ) && defined(UART_USES_INTERRUPTS)
        /* IRQ must be enabled before configuring the UART registers */
        NVIC_EnableIRQ(UART1_IRQn);
        NVIC_SetPriority(UART1_IRQn, configMAX_SYSCALL_INTERRUPT_PRIORITY);
        vSemaphoreCreateBinary(xBinarySemaphore[1]);
#endif /* defined( __FREERTOS__ ) && defined(UART_USES_INTERRUPTS) */
        /* Configure the use of the UART pins */
        PIO_Configure(&pins[1], 1);
        /* Configure PMC to enable the UART1 peripheral */
        PMC->PMC_PCER0 = 1 << ID_UART1;
    } else {
        /* NOTE: We should never be here!! */
        /* XXX: add a LOG_ERR message here! */
        return;
    }
    /* Reset and disable receiver & transmitter */
    pUart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX
                   | UART_CR_RXDIS | UART_CR_TXDIS;
    /* Configure mode */
    pUart->UART_MR = UART_MR_PAR_NONE;
    /* Configure baudrate */
    /* Asynchronous, no oversampling */
    pUart->UART_BRGR = (BOARD_MCK / 16) / baud;
    /* Disable PDC channel */
    pUart->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
    /* Enable receiver and transmitter */
    pUart->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
#if defined( __FREERTOS__ ) && defined(UART_USES_INTERRUPTS)
    pUart->UART_IER = UART_IER_RXRDY;
#endif /* defined( __FREERTOS__ ) && defined(UART_USES_INTERRUPTS) */
}
#if defined( __FREERTOS__ ) && defined(UART_USES_INTERRUPTS)
/*
 * Interrupt Handlers for UART.
 */
void
UART0_IrqHandler(void)
{
    portBASE_TYPE xHigherPriorityTaskWoken;
    xHigherPriorityTaskWoken = pdFALSE;
    LED_Toggle(0);
    /* unblock a task waiting for data to arrive at UART0. */
    xSemaphoreGiveFromISR(xBinarySemaphore[0], &xHigherPriorityTaskWoken);
    /*
     * If the priority of the unblocked task is higher than the
     * currently running task - force a context switch to ensure
     * that the interrupt returns directly to the unblocked
     * (higher priority) task--i.e. the task waiting for the data.
     */
    portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}
/**
 * \brief Input a character from the UART line.
 *
 * \note This function is synchronous
 * \return character received.
 */
uint8_t
UART_GetChar(volatile Uart *pUart)
{
    /* wait indefinitely for data to arrive */
    while ((pUart->UART_SR & UART_SR_RXRDY) == 0) {
            xSemaphoreTake(xBinarySemaphore[0], portMAX_DELAY);
    }
    return (pUart->UART_RHR);
}
```

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [May 22, 2010, 4:45am UTC](https://forums.freertos.org/t/unable-to-use-binarysemaphore-on-cortex-m3/4996/6 "2010-05-22T04:45:06Z")

</div>

**[rgrover1](https://sourceforge.net/u/rgrover1/)** wrote on [Saturday, May 22, 2010](https://sourceforge.net/p/freertos/discussion/382005/thread/dd28e376/#d156):

I apologize for that confusing

```
...

```

block I included in the previous post. I hope you able to make sense of it if you begin reading from UART\_Configure(). Thanks again.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [May 24, 2010, 5:53am UTC](https://forums.freertos.org/t/unable-to-use-binarysemaphore-on-cortex-m3/4996/7 "2010-05-24T05:53:02Z")

</div>

**[rgrover1](https://sourceforge.net/u/rgrover1/)** wrote on [Monday, May 24, 2010](https://sourceforge.net/p/freertos/discussion/382005/thread/dd28e376/#e182):

I have discovered that calling xQueueCreate (or vCreateBinarySemaphore) blows away my interrupt handler on the Cortex-CM3.

My initialization routine sets up the UART0 interrupt hander to go at configKERNEL\_INTERRUPT\_PRIORITY. Inside the ISR, I am toggling an LED plus reading UART0-\>UART\_RHR to clear the status register. With this setup, every time I press a key in the console window, my LED toggles.

But when I add a xQueueCreate() to this mix, the LED doesn’t toggle with key presses. I am not using the queue for anything and yet my ISR fails to go.

What am I missing? Please help.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [May 24, 2010, 9:20am UTC](https://forums.freertos.org/t/unable-to-use-binarysemaphore-on-cortex-m3/4996/8 "2010-05-24T09:20:32Z")

</div>

**[rgrover1](https://sourceforge.net/u/rgrover1/)** wrote on [Monday, May 24, 2010](https://sourceforge.net/p/freertos/discussion/382005/thread/dd28e376/#b3c4):

I hadn’t paid attention to the following in the FAQ:

> Many API functions cannot be called prior to the scheduler being started. It is best to restrict such usage to the creation of the tasks, queues and semaphores that will be used once the scheduler activity has commenced.

I have moved all my usage of Queues to after the scheduler is started; and now things appear to be working normally. I am able to use a queue to synchronize between an ISR and a task.

Thanks.
