Hi,
sometimes my program crashes and I do not know why. I have a error "OS_ERR_FIFO_OVF". I read the information Keil : http://www.keil.com/support/docs/3604.htm and http://www.keil.com/support/man/docs/rlarm/rlarm_ar_cfgfifosz.htm I followed the advice but nothing happens. I use a lot of interruptions in my program.
I'd like to know what interruptions are in the buffer "os_fifo[]" when my programm craches. It would give me a direction to look.
someone is how it works?
Thanks. JB
Forgot about another issue:
else if ( IIRValue == IIR_THRE )
Remember that you can have both a receive and transmit event pending when you enter your interrupt handler - so there should not be any "else" there. You should always test all relevant flags that you have enabled for interrupt generation. Your "else" means that you sometimes directly leaves the ISR after handling a received byte and then directly enters the ISR again to handle the transmit empty case.
I use it because I'm half-duplex. I disable the reception when I transmit and I disable the transmission when I receive. I will review this part of my code.
I'm not sure my problem is there. is there a trick to a debugger?
how you set the size of the variable OS_FIFOSZ? how do you calculate for the size you need? it's random?
I would like to understand and not just increase the size because my program crashes.
No easy formula. But how many interrupts do you have that requires slots in the FIFO? And how many slots do the different interrupt handlers need? And how much time is there to process these entries before you add new entries?
I don't think you should go for less than twice the number of ticks you need if every interrupt that uses the RTOS functionality performs all posts they can.
But note again that your transmit interrupt can result in a flooding of isr_evt_set() calls because of your "do nothing" design of your ISR. If the transmit interrupt has a high enough priority then I don't think any FIFO length will be long enough.
But how many interrupts do you have that requires slots in the FIFO? And how many slots do the different interrupt handlers need?
8 for UARTs 4 for CAN 1 for GPIO 4 for RTC 10 for USB 1 for IP
But they do not trigger all at the same time.
And how much time is there to process these entries before you add new entries? tasks run in less than 20us.
tasks that manages the UART have the highest priority.
I feel that the problem is with the USB HID device, but it is the stack of KEIL. Every 1ms, the USB interrupt triggers even when the USB cable is unplugged.
The RTOS doesn't care about the exact number of interrupts.
It cares about the total amount of time the process spends servicing interrupts. And it cares about how many events you trig from the interrupts.
Next thing - I ask how much time before interrupts can trig again and push new events but you instead think about how fast the processor may do a task switch. But if the top priority isn't to do a task switch then you don't get a task switch.
And it's only when the interrupts are disabled that the processor will not try to push in any new, pending, interrupt.
Unless your specific processor has an edge-trigged UART transmit interrupt, it can generate maybe 100000 UART-empty interrupts in a second. And then do 100000 calls to that set-event function. That type of code is extremely dangerous for any processor that has a level-trigged UART-empty interrupt, so it's a coding style that should better be avoided.
By the way - you have the option of using volatile unsigned variables that you count up in every interrupt handler. Then you can see how many interrupts of the different sort you have had. And you can also count the number of times you have set or cleared an event. That is a great way to verify if the number of events you think you should get matches reality. Such a counter can quickly tell if the number of UART interrupts matches the expected, or if the number of UART interrupts that received a character matches the number of characters your task code did manage to find and pick up. Or if the number of transmit empty interrupts matches the number of characters you managed to send.
OK, thank you for all your advice.
So you tell me to do the UARTs treatment in interrupts. Then the example above with the mailbox is not good.
The volatile unsigned variables that I count up in every interrupt handler, it's good trick. It applies well to the UARTs but not for USB device.
The use of a mailbox in the previously posted example was for handling received bytes. It's ok to send them to a consumer using a mailbox. Or insert them into a ring buffer and use an event to wake up the consumer.
It's the handling - or non-handling - of the transmit interrupt that is the critical part. If there are characters to send, then the interrupt should feed the UART directly. If there are no characters to send, then the interrupt handler should deactivate the transmit empty interrupt. The event should instead be used to inform a producer thread that there is room in the output buffer and request that the producer tries to fill up this output ring buffer.
But in the end, code should always be written so reduce issues with latency and response time of main application. So if a UART has FIFO support, then that should be used. This allows multiple bytes to be received without character loss if the interrupt is a bit slow to react and pick up a received byte. And a transmit FIFO that gets filled with multiple outgoing characters means that the UART transmit can continue to run at max speed even if the processor is a bit slow reacting and adding new data.
If the UART hasn't FIFO support, then the interrupt handler itself should at least be written so that it can keep the UART going without requiring the main program to react to every incoming or outgoing event at a guaranteed pace that is faster than the inter-character delay. A ring buffer for incoming data means the consumer thread can sleep for several character periods and still not miss any data. A ring buffer for outgoing data means that the producer thread can sleep for multiple character intervals and the UART can still be fed with new data at maximum speed by the interrupt handler. Obviously - a device that supports DMA transfers can make use of that instead of a FIFO. But the rule is the same: a good design should try to keep down the hard real-time requirements of as large parts of the application code as possible. This means that a critical thread can be given a critical priority to get activated, perform the critical task and then go to sleep - without having resulted in all UART/CAN/SPI/... transmissions being starved because the interrupt handlers had no outgoing data or no free space for incoming data.
But in the end, code should always be written to reduce issues with latency and response time of main application.
But in the end, code should always be written to eliminate issues with latency and response time of main application.
many miss the silent 'U' in URTOS. things do not happen in 'real time' but when time is available
What means "U"?
un-
You may not always solve all latency issues, which is a reason why it is important to identify what parts of the application that requires strict real time performance with guaranteed response times, and what part of the program that is fine with a best effort approach with a well defined recovery strategy.
It's the same thing with software development as with real life - don't give out more promises than what you can fulfill. So don't promise real-time performance for a task that doesn't need it.
Erik, you are such a tease!
Then the example above with the mailbox is not good. Justify. Also point an alternate Good method.