USART interrupt using mailbox

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • USART interrupt using mailbox

    I'm not getting any output from my USART ISR. I looked at your example code that uses a mailbox as an output buffer and it calls OS_GetMailCond1(). The manual specifically says OS_GetMailCond1() must NOT be used in ISRs. I'm confused.

    Also, it seems I have not enabled my interrupts properly, or you can not set a breakpoint in an ISR either. I'm using AVR32 and EWAVR32. Does this explain why I get an error when I call OS_EnterInterrupt()?

    I copied the code from the OS_COM_Init for COM0 to turn on COM1and made my own OS_OnRx and OS_OnTx routines, but they never get executed. What am I missing? Please help.

    I'm using the demo version of embOS, does that allow ISRs?

    Thanks,

    Mike.
  • Maybe this will give you some more info. I compiled the example that comes with the AVR32 drivers and needed to add "exception.s82" in the project. But, when I did that I got the following

    Error[e24]: Segment EV100 (from module "OS_Switch", address [80004100-800041af]) overlaps segment EVTAB (from module "exception", address [80004000-800041b7])

    I needed this for the definition of ipr_val used in init_interrupts and register_interrupt which are in intc.c file.

    I know this is something simple. I can understand the AVR32 data sheet, but mixing the method in embOS and the drivers included with AVR32 it gets crazy.

    Mike.
  • Well - I fixed it, but not with an interrupt, but rather by polling the CSR in the idle loop.

    void OS_Idle(void) { // Idle loop: No task is ready to exec
    char c;
    while (1) {
    if ((_USART1_CSR & 0x00000001) != 0) {
    c = _USART1_RHR;
    On485Rx(c);
    }
    }
    }

    So, my code is working, I'm just lacking the proper bit to have the hardware generate the interrupt. Help please.
  • Hi
    OS_GetMail cannot be used in an interrupt because it suspends the calling task if the mailbox is empty and an interrupt cannot be suspended as it is not a task.
    OS_GetMailCond does not suspend the calling task if the mailbox is empty, it checks to see if the mailbox has any messages. If it does, it returns 0. If the mailbox is empty it returns 1. Thus it can be used in an interrupt.

    Hope this helps
    Lawrence
  • mfarnet wrote:

    Well - I fixed it, but not with an interrupt, but rather by polling the CSR in the idle loop.

    void OS_Idle(void) { // Idle loop: No task is ready to exec
    char c;
    while (1) {
    if ((_USART1_CSR & 0x00000001) != 0) {
    c = _USART1_RHR;
    On485Rx(c);
    }
    }
    }

    So, my code is working, I'm just lacking the proper bit to have the hardware generate the interrupt. Help please.

    Hello,
    Polling the UART during OS_Idle() this way is no good idea.
    As OS_Idle() is no task, local variables may got lost.
    Even the execution of the code may be interrupted and discontinued.
    OS_idle() may be interrupted any time by any interrupt.
    If this happens and the interrupt causes a task switch, OS_Idle() will not resume.
    Your On485Rx() function may be interrupted and will not continue.
    You will lose characters.
    You might use OS_IncDI() and OS_DecRI() around the two lines of code which get the data from UART and process the data:
    ...
    OS_IncDI();
    c = _USART1_RHR;
    On485Rx(c)
    OS_DecRI();
    ...
    But this may increase interrupt latency and task activation time drastically, depending on what your On485Rx() function is doing.
    I am sorry, that I don't have the correct interrupt handling sample for yor particular USART device.
    But you should try to find out, how the hardware interrupt can be handled correctly.
    Best regards,
    Armin