FreeRTOS+CLI: Static allocation of command list


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.

  1. 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.

  2. 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.

Looking forward to your input.

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.

My intention was that the user would have a:

static CLI_Definition_List_Item_t myCommandList[20];
FreeRTOS_CLICreateStatic(myCommandList, 20);

Similar to how xQueueCreateStatic works.

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.