ISR/semaphore help on PIC18F

rjcitw3656 wrote on Friday, May 07, 2010:

Hi all,

I am new to FreeRTOS but I really need to get to grips with it so any help anyone can give me will be much appreciated.

I am using the PIC18 port on a PIC18F4680 and I am having trouble with the UART interrupt and a semaphore.
Esentially, I have 2 tasks a LED flashing task that is run every 250 ticks, and a Uart character recevied task which is blocked until a binary semaphore is taken. I am using xSemaphoreGiveFromISR inside the vSerialRxISR() to signal the uart task to wake up and process the char recieved but it does not work.
upon sending a char from hyperterm, the code on the pic handle the one char and then locks up and neither task ether led flashing or subsequent chars are handled. I can only assume I am missing something. I have posted my code snippetes below

void main(void) {
heapinit();                  //Start optimized “Heap Management For Small Microcontrollers”
//create LED flash task
xTaskCreate(Task1, (const portCHAR * const) “Ts1”, configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);
//create RX processing task
        xTaskCreate(Task2, (const portCHAR * const) “Ts2”, configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL);
    //start scheduler

while(1) {

void vSerialRxISR() {
static signed portBASE_TYPE xHigherPriorityTaskWoken;
xHigherPriorityTaskWoken = pdFALSE;

/* Unblock the task by releasing the semaphore. */
if(xSemaphoreGiveFromISR( xUartSem, &xHigherPriorityTaskWoken ) == pdTRUE){
//force a context switch

//led flash task
void Task1(void *params) {


     LATBbits.LATB4 ^= 1;
LATBbits.LATB5 ^= 1;
       vTaskDelay(250);             //block task for 1S (250 ticks)

//RX recieved task
void Task2(void *params) {
    vSemaphoreCreateBinary(xUartSem);                             //create the binary semaphore
     while(1) {
     /*Block waiting for the semaphore to become available. */
        if( xSemaphoreTake( xUartSem, 100 ) == pdTRUE )
            /* It is time to execute. */
            serial_register = RCREG;            // get the next byte
   Process_RX(); //process the command

            /* We have finished our task.  Return to the top of the loop where
            we will block on the semaphore until it is time to execute
            again.  Note when using the semaphore for synchronisation with an
            ISR in this manner there is no need to ‘give’ the semaphore back. */

rtel wrote on Friday, May 07, 2010:

The code you have posted is not particularly easy to read (formatting has been lost) but I cannot see anything that looks wrong.

The PIC18 is not an ideal target for running a real time kernel, and it might just be that it is running too slowly, resulting in overrun errors in the UART.  You could try adding the following to the ISR:

/* Clear any overrun errors. */

	if( RCSTAbits.OERR )

Also you could try looking at the usual suspects of stack overflow, etc.