Hello everyone,
I have used freeRTOS for many time, although the start was tragic now I get along pretty well. I use freeRTOS on Xilinx hardware with MicroBlaze CPU, one of these days I’ll try on Zynq.
In my projects I have never used an external CPU but I always all centralized
around the FPGA. By working alone, I prefer use one device so a single development tool with which to do everything.
My last project was very complex with many Tasks that were created, deleted. These communicate with each other using different “Queue”, “Semaphore”, for using Custom Hardware on FPGA. I have used Lwip for Web Server, TFTP, Announce, Discovery.
I come to the question. After all this time I have had in mind a couple of APIs
that may be added to freeRTOS. I wanted to try alone to implement them, just for fun, but because of the limited time, I ask the community developers if these APIs may be useful.
(1)
In the latest versions of freeRTOs there is the ability to use the “TaskNotify”,
optimal solution. The only drawback using it is that you should always store
the “TaskHandle
t” in global variable. You can implement an API that passing
“pcName” of the TaskFunction to get the “TaskHandlet” ?
:::python
BaseType_t xTaskCreate(
TaskFunction_t pvTaskCode,
const char * const pcName,
unsigned short usStackDepth,
void *pvParameters,
UBaseType_t uxPriority,
TaskHandle_t *pvCreatedTask
);
“const char * const pcName” : Give the name at “TaskFunction”
“TaskHandle_t pvCreatedTask” : “TaskHandle” that identifies the task, to be stored globally for access
Using an API like this:
TaskHandle_t xTaskGetTaskHandleByName( const char * const pcName );
I could get “TaskHandle” looking for the name given. If not assigned any name I can not find TaskHandle of interest. I would avoid so store it globally.
It could be useful ?
P.S. At this point all API that use “TaskHandle_t” can be have Override with
“…ByName” API version.
(2)
In large project I always using a “malloc” and “free” routine with “heap_4.c” code. The memory region is very large (64 MByte) and for speed-up MicroBlaze init I have create separate section on memory with this :
:::python
/* Allocate the memory for the heap. */
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ] __attribute__((section(".heap_noload")));
With custom section in linker “lscript.ld”
:::python
.heap_noload (NOLOAD) : {
. = ALIGN(8);
_heap_noload = .;
} > memory_S1_AXI_BASEADDR
So far no problem.
The most boring thing at this point is that memory once allocated must always be freed if no longer used. To avoid memory is then fully occupied if ever released. The most serious problem is the “vTaskDelete”. I can not delete a task that use memory with “malloc”. Therefore I must first send a signal with the “Queue”, “Semaphore” or “TaskNotify” to free up memory, and then “vTaskDelete” for terminate the task.
The code written in “heap
4.c” uses a proprietary algorithm, which works very well. I imagined that if you change the structure of block memory “BlockLinkt” :
:::python
/* Define the linked list structure. This is used to link free blocks in order
of their memory address. */
typedef struct A_BLOCK_LINK
{
struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */
size_t xBlockSize; /*<< The size of the free block. */
} BlockLink_t;
With inserting a “TaskHandle_t” of the Task that uses the memory block. The structure of memory block could become:
:::python
/* Define the linked list structure. This is used to link free blocks in order
of their memory address. */
typedef struct A_BLOCK_LINK
{
struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */
size_t xBlockSize; /*<< The size of the free block. */
TaskHandle_t vCreatedTask;
} BlockLink_t;
On call of “malloc” function the routine add “TaskHandle_t” of the task that calling. With “vTaskDelete” I can free memory in an automatic way, freeing up all the memory used by the Task.
It could be useful ?
P.S. : I know the memory allocated to each task, free it completely in one shot, even if you use a store nested type.
debugasm