This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Semaphore problem

Has anyone experienced problems using semaphores in interrupt routines? I have a UART ISR that places a received character into a FIFO buffer and sets a semaphore using isr_sem_send().

void SerialIsr(void) __irq
{
    volatile uint8_t Temp;
    switch( COMIID0 & 0x0fU )
    {
        case MSI:
            Temp = COMSTA1;
        break ;

        case THRE:
        break;

        case RDA:
            Temp = (char_t)COMRX;
            if(BufferCount < BUFFER_SIZE)
            {
                BufferCount++;
                isr_sem_send(SerialSemaphor);
            }
        break;
        case RLS:
            Temp = COMSTA0;
        break ;

        default:
        case NO_PENDING_INTERUPT:
        break;
    }
}

The GetByte routine waits on this semaphore for a specified timeout period. If the semaphore is set, the next available char in the buffer is returned, otherwise a user defined timeout character is returned. The problem I am getting is that it appears that the semaphore is becoming corrupted and generating a lot of tokens. I test this by trapping the condition where os_sem_wait(sem) != OS_R_TMO and the buffer is empty. I.e. a semaphore token has been returned but the buffer is empty.
note that I have replaced the buffers with a counter for simplicity.

char_t GetByte (uint16_t File, uint32_t Timeout)
{

    OS_RESULT Result;
    char_t RetValue;
    uint32_t Copy;

    DISABLE_UART_INT();
    Copy = SerialSemaphor[0];

    Result = os_sem_wait(SerialSemaphor,Timeout);
    if(Result !=  OS_R_TMO && BufferCount == 0U)
    {
        Result = 1;
    }

    if(BufferCount == 0)
    {
        RetValue = ( (char_t)GETC_TIMEOUT_CHAR );
    }
    else
    {
        BufferCount--;
    }
    ENABLE_UART_INT();

    return RetValue;
}

If I then look at the semaphore object I can see that the most significant 16 bits of the first 32 bit word in the semaphore object is 0xFFFF (I am assuming this is the token counter). Subsequent calls os_sem_wait() return OS_R_OK, decrementing the token counter each time. This has the result that the thread is not released until the os_sem_wait() has been called sufficient times to decrement the token counter to zero (The os_sem_wait() is the only function to release the thread).

The target is an ADuC7021 and I am using the RTL-ARM.