I’m interested in allocating the command list in FreeRTOS+CLI statically instead of dynamically. I’m interested in contributing such a change but I would like some feedback on how to implement it.
I have thought of two different ways of doing this instead of using CLI_Definition_List_Item_t on the heap.
Make something similar to cOutputBuffer which is extern when configAPPLICATION_PROVIDES_cOutputBuffer is set.
I.e. add a configCLI_STATIC_ALLOCATION configure define and if it’s set to 1 then use extern CLI_Command_Definition_t * pxStaticCommandList and extern UBaseType_t uxStaticCommandListLength.
Add a BaseType_t FreeRTOS_CLICreateStatic( CLI_Command_Definition_t * pxStaticCommandList, const UBaseType_t uxStaticCommandListLength ) function and if it’s called then use the static storage provided when FreeRTOS_CLIRegisterCommand is used.
I’ll happily accept an other solution that might be better.
Additionally I wonder if I should #ifdef configSUPPORT_STATIC_ALLOCATION all of the code related to this. I’ve noticed though that configSUPPORT_DYNAMIC_ALLOCATION is not used in the current code.
configSUPPORT_DYNAMIC_ALLOCATION defaults to enabled if left undefined, whereas configSUPPORT_STATIC_ALLOCATION defaults to disabled. If we create a version that has the ability to be used with static allocation then we should introduce both constants into the code - then enable the APIs that call malloc() only configSUPPORT_DYNAMIC_ALLOCATION is set to 1.
I would like to understand your thoughts better here. In the examples we have the command definitions themselves are already const structures, such as:
static const CLI_Command_Definition_t xRunTimeStats =
{
"run-time-stats", /* The command string to type. */
"\r\nrun-time-stats:\r\n Displays a table showing how much processing time each FreeRTOS task has used\r\n\r\n",
prvRunTimeStatsCommand, /* The function to run. */
0 /* No parameters are expected. */
};
…but when a command is registered there is a list item that is dynamically allocated:
/* Create a new list item that will reference the command being registered. */
pxNewListItem = ( CLI_Definition_List_Item_t * ) pvPortMalloc( sizeof( CLI_Definition_List_Item_t ) );
configASSERT( pxNewListItem );
So it is the list item that would need to be statically allocated to in order to avoid using malloc. I think that could be done by inserting the list item into the command structure itself, then when you statically allocate the command structure you also statically allocate the list item - however that would have the disadvantage that the whole structure could not be const, and so held in RAM rather than in flash.
A different option would be to use a complete CLI_Definition_List_Item_t array with all the commands desired by the user. And pass that to a new FreeRTOS_CLIRegisterCommandsStatic(...) function. Then the list stored on flash could be traversed. It however removes the option to always add the help command automatically.