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

uart irq_handler

Hi everyone.
I've got a problem using the UART irq_Handler.

I'm working with an STM32E ev board and i want to receive data from an AHRS throught the COM port.
I've to manage a message of many bytes and i need to use an UART interrupt handler to pass charater to a task that will collect all the bytes of the mesage and then, when complete, send it to another task.
The problem is that i never get into the UART IRQ_Handler routine and i cannot understand why.

Here is the code:

/*----- Usart Interrupt Service routine----- */

void USART2_IRQHandler(void)
{
    char *char_ptr;
    char char_rec;

     _init_box(charpool,sizeof(charpool),sizeof(U32));

     while(1){
        os_mbx_init(MsgBoxA,sizeof(MsgBoxA));
        char_ptr = _alloc_box(charpool);
        char_rec = getkey();
        char_ptr = &char_rec;
        os_mbx_send(MsgBoxA,char_ptr,0xffff);
        GLCD_displayStringLn(Line4, "  Get some  ");
        }
}
/*----------------------------------------------------------------------------
*   Task getAhrs: receive the character, then switch the state of the machine and collect the
*                  payload character in a buffer to send to the manage task
*---------------------------------------------------------------------------*/

__task void getAhrs(void){

        char *car_rec;
        U32 *buf_ptr;

        os_mbx_init(MsgBoxB,sizeof(MsgBoxB));              /*init the mailbox B */

        GLCD_displayStringLn(Line3, "In the task get");

        while(1){
                switch (buf_count){
                        case 0: buf_ptr = _alloc_box(bufpool_0);        /*memory allocation */
                                        break;
                        case 1: buf_ptr = _alloc_box(bufpool_1);
                                        break;
                        case 2: buf_ptr = _alloc_box(bufpool_2);
                                        break;
                        }

                os_mbx_wait(MsgBoxA,(void**)&car_rec,0xffff);                  /*receive the
                                                                             mailbox from the
                                                                                 IRQ_hanlder*/
                current_char = *car_rec;

The code then goes on managing the character and colecting it into a buffer pointed by buf_ptr.

When I ebug it I get o errors, but, using the breakpoints i can see that it never step into the IRQ_Hanler.

A clarification:

I set up the UART in the starter task that is as follow:

/*----------------------------------------------------------------------------
 *   Task starter:  init and configure the UART and create all the tasks
 *---------------------------------------------------------------------------*/
__task void starter (void){

        USART_InitStructure.USART_BaudRate = 115200;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        USART_InitStructure.USART_StopBits = USART_StopBits_1;
        USART_InitStructure.USART_Parity = USART_Parity_No;
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        USART_InitStructure.USART_Mode = USART_Mode_Rx;

  /* Configure USART2 */
        USART_Init(USART2, &USART_InitStructure);

        USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); /* enable usart2 receive interrupt*/
        USART_Cmd(USART2, ENABLE);

        state = IDLE;           /*state machine in IDLE state */

        _init_box(mpool,sizeof(mpool),sizeof(U32));               /*mailboxes memory spaces */
        _init_box(bufpool_0,sizeof(bufpool_0),sizeof(U32));
        _init_box(bufpool_1,sizeof(bufpool_1),sizeof(U32));
        _init_box(bufpool_2,sizeof(bufpool_2),sizeof(U32));

        GLCD_setBackColor(Green);
        GLCD_setTextColor(Red);

        os_tsk_create(printLCD,1);
        os_tsk_create(manageAhrs,2);
        os_tsk_create(getAhrs,3);

        os_tsk_delete_self();
}

If anyone coul explain me where i wrong... i've also tried to look at some eamples but also them did not work.. It's a problem of my board or maybe i don't set something very important?
Thanks

Parents
  • I really hope that "void USART2_IRQHandler(void)" isn't intended to be the interrupt handler that is called by the hardware when a character is received.

    The ISR (Interrupt Service Routine) should not be a RTOS task. It is a special type of function called by the processor - not by any task scheduler. And it should not contain lots of loops etc. It should figure out why the UART needs services. Capture any incomming data. Possibly feed the UART with pending outging data. Then quickly return until the UART wants services again.

    The ISR can only call OS functions that are named like isr_xxx().

    Then you have an RTOS task that waits for being signaled by the UART ISR that there are pending data. This being a task, it should use OS functions named like os_xx().

    Start reading up on this and look at all the available examples.

    Another thing - you take the address of a local character variable and send using the mailbox - but how well do you think that works if the variable gets updated with next received character before any other task reacts to the mailbox event and picks up the previous contents of your variable? By the way - it's possible to send the character data directly in on the mailbox instead of sending a pointer to a character. All it takes is for the receiver to know that it doesn't receive a pointer but an actual 8-bit data value.

    Above functionality have been covered many, many, many times on this forum. I will not repeat it. I will not search for previous threads. You'll have to do a bit of work too. But stop doing "programming by trial and error". Everything that compile is not working code. You should be able to prove to yourself - and the rest of the world - exacly why every single source code line looks like it does.

Reply
  • I really hope that "void USART2_IRQHandler(void)" isn't intended to be the interrupt handler that is called by the hardware when a character is received.

    The ISR (Interrupt Service Routine) should not be a RTOS task. It is a special type of function called by the processor - not by any task scheduler. And it should not contain lots of loops etc. It should figure out why the UART needs services. Capture any incomming data. Possibly feed the UART with pending outging data. Then quickly return until the UART wants services again.

    The ISR can only call OS functions that are named like isr_xxx().

    Then you have an RTOS task that waits for being signaled by the UART ISR that there are pending data. This being a task, it should use OS functions named like os_xx().

    Start reading up on this and look at all the available examples.

    Another thing - you take the address of a local character variable and send using the mailbox - but how well do you think that works if the variable gets updated with next received character before any other task reacts to the mailbox event and picks up the previous contents of your variable? By the way - it's possible to send the character data directly in on the mailbox instead of sending a pointer to a character. All it takes is for the receiver to know that it doesn't receive a pointer but an actual 8-bit data value.

    Above functionality have been covered many, many, many times on this forum. I will not repeat it. I will not search for previous threads. You'll have to do a bit of work too. But stop doing "programming by trial and error". Everything that compile is not working code. You should be able to prove to yourself - and the rest of the world - exacly why every single source code line looks like it does.

Children