I have FreeRTOS running on my Atmega128 and for the most part it appears to be running fine. But if I try to create a queue of 30,000 bytes xQueueCreate(30000, sizeof(uint8_t)); the returned xQueueHandle is always non-zero. Is there another API function I should check first to see if there is enough heap available, or is this a bug?
I just realized that queues on the Atmega128 are limited to 255. Is there an easy way to create a queue with more than 255 items?
Can you explain why you would need a queue so big? Are you caching an image?
I am using the FreeRTOS queue to hold incoming serial bytes. The RX ISR adds to the queue every time it receives a byte. We have a requirement to hold at least 1500 bytes in the queue as the remote transmitter sends out huge chunks of data periodically. My application does not need preemption so I was considering using coroutines for everything to save memory. Actually, I don’t even need to use FreeRTOS for my application, but I was hoping it would help structure and separate the different threads of my code.
I guess I could create my own global array of 1500 bytes and implement my own RX buffer. Then I would create a FreeRTOS queue of zero length and use that to essentially semaphore my coroutine when a new byte arrives.
As far as I know the Mega128 had 4K bytes of RAM so you would never be able to create a buffer of 30K even if queues could be that big.
To get over the 255 you can either just change the type used in the functions or define portBASE_TYPE to be a 16bit type. The latter would be inefficient in some cases.
If I did increase portBASE_TYPE to a 16 bit type would it affect stability? Do any atomic operations on the Atmega128 depend on working with 8 bit types. Does portBASE_TYPE need to be a signed value?
Given the large blocks to be received, and the likely need to prevent overflow, I would create a standard interrupt driven serial handler which manages its own buffers.
This interrupt handler should run at a higher priority than the clock tick and have no interaction with the RTOS. The RTOS should not totally disable interrupts in its critical regions, except for the time required to mask off all interrupts associated with the RTOS, after which the serial interrupt will be re-enabled. I know the 8051 interrupt system hardware is structured to enable this type of operation but others may not.
Set up like this the serial interrupt code can then break into the RTOS at any time, run to completion, return from interrupt leaving the stack unchanged as viewed by the RTOS. A standard task can then monitor the buffer status extracting and inserting blocks of characters.
In a similar situation I have used multiple RX buffers which are acquired and released via a state machine associated with each buffer, Rx buffer states are:(created & free), (receiving characters), (full & ready for processing)), (being processed), then back to (created & free)