API resquest and idea …

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 “TaskHandlet” 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 “heap4.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

API resquest and idea …

A short answer to a long email :o) I think both of these are very good ideas. A couple of notes of caution though: 1) Using at task name Obtaining the handle of a task from its name would be quite a lengthy operation as it would require string comparison. It may be possible to speed that up using caching, or hashing, or both (as per the directory name hashing using in FreeRTOS+FAT). 2) Freeing the memory used by a task It might be dangerous to automatically free all the memory allocated by a task itself if, for example, the task created a queue and other tasks were still using the queue. There are other examples too, for example if a task created a persistant buffer etc.. So there would have to be a means of a task somehow noting which memory should be left unfreed. Another possibility might be to have a task register which blocks of RAM should be freed when the task was deleted. The function called from the Idle task that frees the task’s stack and TCB could then also free the memory the task had specifically said should be freed. Regards.

API resquest and idea …

One comment on the idea of trying to free memory allocated to a task. This is really only an issue if you are trying to “remote kill” a task asyncronously. Tasks are NOT a ‘Process’ which are kept distinct with well defined and limited interfaces to other Tasks/Processes and that the OS can keep track of resources and clean up when the process is killed. Tasks are part of a cooperative enviroment, and can share resources between tasks without the OS needing to keep track of things. They are much more “entangled” than processes (and in fact are basically threads in a classical OS) This means that the method used on some “heavy” OSes of monitoring a process and killing it if it looks hung just isn’t normally appropriate for a system eeded data/signals not being rnlike FreeRTOS. If a task isn’t responding properly, you really don’t know how big the issue is, and really the only true solution would be to reset the system. Rather than trying to build a watchdog on a processes poised to kill it and restart it, write the process defensively so it can’t get locked up, and error checks on not getting data/signals that it needs and reports the errors “upline”. Such a task won’t need to be killed and restarted. Having done that, if things ‘hang’ then it is clear that you do need to restart to clear things (perhaps with an opertunity to go to a debugger first to analyse the system to debug way things hung).

API resquest and idea …

1) Using at task name Obtaining the handle of a task from its name would be quite a lengthy operation as it would require >string comparison. It may be possible to speed that up using caching, or hashing, or both (as per the >directory name hashing using in FreeRTOS+FAT).
I’m curious about this thing, I will check in directory name hashing using in FreeRTOS+FAT.
2) Freeing the memory used by a task It might be dangerous to automatically free all the memory allocated by a task itself if, for example, >the task created a queue and other tasks were still using the queue. There are other examples too, >for example if a task created a persistant buffer etc.. So there would have to be a means of a task >somehow noting which memory should be left unfreed. Another possibility might be to have a task register which blocks of RAM should be freed when the >task was deleted. The function called from the Idle task that frees the task’s stack and TCB could >then also free the memory the task had specifically said should be freed.
Excuse me, I did not remember that even Queue, Semaphore and other features freeRTOS use the same “malloc” and “free” that is used in the “user”. I imagine this feature only for the user who creates a task, not must certainly complicate any system that already works fine as well. I also thank Richard Damon for the excellent clarification. debugasm