New user created function: pcSetTaskName

Hello, and first post here; I have created a function that allows the user to change the “PC readable” ASCII text name of a task on the fly after it has been defined in the xTaskCreate function. I use this to modify the name of a task at different times during my application so when the task list is viewed, a better idea of what the task is doing can be determined. However, I’ve had to place this code within tasks.c/task.h, which has obvious drawbacks and could be condsidered going against many conventions. My post is two fold, First, would/could there be any consideration to adding this function to FreeRTOS in future versions, as I feel it does serve a purpose. Second, if anyone has some suggestions as to incorporate this routine from outside of tasks.c so the sanctity of the kernel is not touched, I would be most grateful. The function appears to be referencing items from within tasks.c that cannot be seen outside of it. Included here is the code used for this function. It is basically a modification of pcgetTaskName: ~~~ void pcTaskSetName( TaskHandlet xTaskToQuery, char *newName ) { TCBt *pxTCB;
/* If null is passed in here then the name of the calling task is being
queried. */
pxTCB = prvGetTCBFromHandle( xTaskToQuery );
configASSERT( pxTCB );
strncpy(pxTCB->pcTaskName, newName, configMAX_TASK_NAME_LEN - 1);
pxTCB->pcTaskName[configMAX_TASK_NAME_LEN - 1] = 0;
} ~~~ and the associated h file content in task.h: ~~~ /** * task. h *
char *pcTaskSetName( TaskHandle_t xTaskToQuery, char *newName );
* * @return The text (human readable) name of the task referenced by the handle * xTaskToQuery. A task can query its own name by either passing in its own * handle, or by setting xTaskToQuery to NULL. * * defgroup pcTaskGetName pcTaskGetName * ingroup TaskUtils */ void pcTaskSetName( TaskHandle_t xTaskToQuery, char *newName ) PRIVILEGED_FUNCTION; ~~~ Appreciate any thoughts.

New user created function: pcSetTaskName

To add your own code into tasks.c without editing the source file: 1) Create a file called freertostasksc_additions.h and place it somewhere in the compiler’s include path. 2) Add you code into the new header file. 3) Set configINCLUDEFREERTOSTASKCADDITIONS_H to 1 in FreeRTOSConfig. Now the header file will be included inline at the bottom of tasks.c :o)

New user created function: pcSetTaskName

Hi Richard, It appears this isn’t going to be that simple. I am still having the following issues: 1) Where do I put the prototype for the function? If I place it above the function in …additions.h I get Error ‘pcTaskSetName’ was not declared in this scope In all the modules it’s called from. Makes sense since the modules themselves don’t see …additions.h 2) If I put the prototype in each of the modules it’s used, then I get this error: Error undefined reference to pcTaskSetName(tskTaskControlBlock*, char*) Not sure how to resolve this as I still seem to need to keep the prototype in task.h, which still means modifying a file I shouldn’t touch.

New user created function: pcSetTaskName

The function itself should live in freertostaskc_additons.h (yes, the name is a header, but treat it as a source file). Make your own header (maybe taskadditions.h) with the prototype for the function with a name you desire, and preferably, call that header in freertostaskcadditons.h to verify the prototype. Files wanting to use your extension then include task_additons.h to get the prototype.

New user created function: pcSetTaskName

Hello to a second Richard, That just brings me back to the original error ” ‘pcTaskSetName’ was not declared in this scope” I originally had the protoype itself in freertostaskc_additions.h immediately above the actualy function code line, which is essentially the same as what the incluse is doing. freertostaskcadditions.h: ~~~ /* * freertostaskscadditions.h * * Created: 5/29/2019 11:56:12 AM * Author: Jeff */

ifndef FREERTOSTASKSCADDITIONSH_

define FREERTOSTASKSCADDITIONSH_

include “taskadditionsprototypes.h”

void pcTaskSetName( TaskHandlet xTaskToQuery, char *newName ) { TCBt *pxTCB;
/* If null is passed in here then the name of the calling task is being
queried. */
pxTCB = prvGetTCBFromHandle( xTaskToQuery );
configASSERT( pxTCB );
strncpy(pxTCB->pcTaskName, newName, configMAX_TASK_NAME_LEN - 1);
pxTCB->pcTaskName[configMAX_TASK_NAME_LEN - 1] = 0;
}

endif /* FREERTOSTASKSCADDITIONSH_ */

~~~ taskadditionsprototypes.h: ~~~ /* * taskadditionsprototypes.h * * Created: 5/29/2019 3:04:49 PM * Author: Jeff */

ifndef TASKADDITIONSPROTOTYPESH

define TASKADDITIONSPROTOTYPESH

void pcTaskSetName( TaskHandlet xTaskToQuery, char *newName ) PRIVILEGEDFUNCTION;

endif /* TASKADDITIONSPROTOTYPESH */

~~~

New user created function: pcSetTaskName

I could be wrong, but it seems a viable way to make this work is to use the same mechanism that’s used in the tasks.c file at the end of the task.h file, but it’s going to require a sanctioned change that’s placed into future versions. At the end of the task.h file, just above the “#ifdef cplusplus” line, the following lines are added: ~~~

if( configINCLUDEFREERTOSTASKCADDITIONS_H == 1 )

#include "../freertos_tasks_c_additions_prototypes.h"

endif

ifdef __cplusplus

~~~ So, if the config variable is set to “1”, then a companion h file called “freertostaskscadditionsprototypes.h” will also be looked for and included into task.h. This file would contain any prototypes for functions placed in the “freertostaskc_additions.h” file. This compiles and works, but until it is accepted and adopted it still requires modifying the task.h file and the associated issues when upgrading versions (like remembering you have to add those lines).

New user created function: pcSetTaskName

Just to be clear, WHERE does the error ” ‘pcTaskSetName’ was not declared in this scope” occur. What line of code is this flaged at? My comment was that your usage file would begin with somethng like: ~~~

include <FreeRTOS.h>

include <Task.h>

include <FreeRTOSTASKCADDITIONSPROOTYPES.H>

~~~ so the third include bring the prototypes into scope. There is no reason your extention header needs to be part of Task.h, it can be a totally independant header. (If you use C++, you will also need the #ifdeff __cplusplus stuff to mark the prototype as to a C function)

New user created function: pcSetTaskName

I’m not sure what problem this is trying to solve. If the new functions are added to tasks.c at the bottom of the tasks.c (using the extensions header file) then all the functions called by the new functions are in scope as are their prototypes. The prototypes for the functions being added do not need to be in tasks.c unless they are also being called from inside the header file (so the new header file implements one function that is then called by another function in the same header file) – in which case the prototype does not need to be at the top of the file and could just be in the same extensions header file – if I’m not talking around in circles here.

New user created function: pcSetTaskName

To Richard & Richard, OK, problem resolved, thank you. It’s all working now without any alternations to tasks.c or task.h Richard D, the answer to your “WHERE”, it was at the line of use of the function in each module. This turned out to be my fault for improper placement (or misunderstanding) of where to put the prototype. When I was placing the prototype it was in the “cpp” portion of the code, which made it invisible to the “c” modules. Putting the protoype include inside the “c” marked areas worked and all errors went away. ~~~ extern “C” { #include “FreeRTOS.h” #include “task.h” #include “..freertostaskscadditionsprototypes.h” …etc } ~~~ Richard B, sorry for causing any confusion. As stated above, my bad. Also, thanks for the “future proof” forsight in tasks.c to allow user additions. Thanks for the help guys. Jeff

New user created function: pcSetTaskName

One last quick comment on your last code you showed. You do NOT need to surrond the includes of FreeRTOS.h and task.h with an extern “C” decleration, as they were written to include that internally. Generally #include statements shouldn;t be inside ANY block structure (unless specifically designed to be). The extern “C” sometimes is needed to wrap headers that didn’t take C++ into consideration, but the extern “C” can cause issues if done indiscriminatory. Your additions header, if it is to usable (even potentially) with C++ should be designed with ~~~

ifdef __cplusplus

extern “C” {

endif

// Prototypes for C code here

ifdef __cplusplus

}

endif

~~~ So the code is valid for both C and C++ and establishes the proper linkage.