I troubleshot a very frustrating problem last night regarding queues. Here’s what I’m using: Olimex SAM7P256S CPU, ARM SDT 2.51 compiler, and some custom tweaks to FreeRTOS for the SAM7S32P Olimex board. CPU Is running at about 50Mhz (slightly lower because of UART divisor alignment). I have a UART driver that handles both UARTs. For transmission, I have a 2048 byte queue for each UART. Foreground code queues things up with xQueueSend, and inside the ISR, it calls xQueueReceiveISR to grab the data. I have a very simple test – take data received from one UART and send it out the other. UART 0 Is the UART doing the transmitting, and UART 1 is the UART doing the receiving. Anywhere between about 3 seconds and 5 minutes of operation from reset, the whole system locks up. I don’t have a JTAG debugger so I can’t see what’s going on, but everything halts (that’s what the data abort/prefetch abort, etc… handlers do). So… I modified the UART transmit routines to use a ring buffer. It has now been running for almost 24 hours solid without any issue. Not conclusive, but if I don’t use queue transmitting/receiving in my ISR, I never see any problems. There’s not a lot going on here, but I’m wondering if there’s anyone who might have any ideas as to what to look for. I can see a lot of possibilities – everything from bugs in FreeRTOS (unlikely) to buggered interrupt disabling (still unlikely, but more likely than FreeRTOS bugs). Thoughts?
Its going to be difficult without a debugger, but the first thing to always check is that you are not running out of stack in one of the tasks. Try increasing the stack sizes (got in before you on that one, Richard). Also, the UART drivers supplied are generally intended to test the port code, rather than be optimised drivers. This means they generate as many interrupts as possible rather than using DMA or FIFO’s, etc. This would not make it crash, but would impact performance. I use a ring buffer to buffer multiple characters at once, then a semaphore (which is faster than a queue as it does not copy any data) to wake the task to process the characters.
The stack size problem was something I thought of as well. I’ve tried increasing the stack size of the IRQ context, user, and superviors, as well as the task itself (there is only one thread running now) with absolutely no effect on the problem. Interestingly enoguh, if I lower the baud rate from 115,200, the problem happens less frequently. I’m not using the supplied UART drivers – they are written by me and are interrupt driven. I don’t have dedicated serial port threads. They are all interrupt driven. For threads that call the UART routines for transmitting, it’s OK and expected for any calling thread to block on the queue. I’m starting to wonder if there’s something about a register that’s getting trashed somewhere at a critical point. I’ll examine the output of the compiler. I do have the routine tagged as an "irq" which will save off all registers, but I’m wondering if it’s missing something….
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.