Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unify service arrays into a simple struct array #14

Merged
merged 2 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions cli/node_bin.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,14 +226,14 @@ static void service_exec_callback(struct ush_object *self, struct ush_file_descr
shell_print(err_msg);
}
else {
// Iterate through service_strings array to find the matching service index
// Iterate through service_descriptors array to find the matching service index
int i;
for (i = 0; i < (sizeof(service_strings)/sizeof(service_strings[0])); i++) {
if (strcmp(argv[2], service_strings[i]) == 0) {
service_functions[i](); // call the function pointer at the same index of the matched service string
for(i = 0; i < service_descriptors_length; i++) {
if (strcmp(argv[2], service_descriptors[i].name) == 0) {
service_descriptors[i].service_func();
break;
}
if (i == ((sizeof(service_strings)/sizeof(service_strings[0]))-1)) {
if (i == (service_descriptors_length - 1)) {
sprintf(err_msg, "%s is not an available service, try 'service list'", argv[2]);
shell_print(err_msg);
break;
Expand Down Expand Up @@ -276,15 +276,16 @@ static void service_exec_callback(struct ush_object *self, struct ush_file_descr
"Available Services\tStatus\r\n"
"------------------------------------\r\n"
USH_SHELL_FONT_STYLE_RESET;
char *service_list_msg = pvPortMalloc(strlen(service_list_header) + (sizeof(service_strings) * (configMAX_TASK_NAME_LEN + 16)));

char *service_list_msg = pvPortMalloc(strlen(service_list_header) + (service_descriptors_length * sizeof(char*) * (configMAX_TASK_NAME_LEN + 16)));
TaskHandle_t service_taskhandle;
char service_state[12];

strcpy(service_list_msg, service_list_header);

// interate through available services, get their states from RTOS
for (i = 0; i < (sizeof(service_strings)/sizeof(service_strings[0])); i++) {
service_taskhandle = xTaskGetHandle(service_strings[i]);
for (i = 0; i < service_descriptors_length; i++) {
service_taskhandle = xTaskGetHandle(service_descriptors[i].name);
if (service_taskhandle == NULL) {
strcpy(service_state, "not started");
}
Expand All @@ -306,9 +307,9 @@ static void service_exec_callback(struct ush_object *self, struct ush_file_descr
}

// copy current service name into table
strcpy(service_list_msg + strlen(service_list_msg), service_strings[i]);
strcpy(service_list_msg + strlen(service_list_msg), service_descriptors[i].name);
// add an extra tab to short service names to make the table look better
if (strlen(service_strings[i]) < (configMAX_TASK_NAME_LEN - 8)) {
if (strlen(service_descriptors[i].name) < (configMAX_TASK_NAME_LEN - 8)) {
strcpy(service_list_msg + strlen(service_list_msg), "\t");
}
// copy current service state into table
Expand Down
1 change: 1 addition & 0 deletions services/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ target_sources(${PROJ_NAME} PRIVATE
storman_service.c
watchdog_service.c
heartbeat_service.c
services.c
)
31 changes: 31 additions & 0 deletions services/services.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "services.h"

const ServiceDesc_t service_descriptors[] = {
{
.name = xstr(SERVICE_NAME_USB),
.service_func = usb_service,
.startup = true
},
{
.name = xstr(SERVICE_NAME_CLI),
.service_func = cli_service,
.startup = true
},
{
.name = xstr(SERVICE_NAME_STORMAN),
.service_func = storman_service,
.startup = true
},
{
.name = xstr(SERVICE_NAME_WATCHDOG),
.service_func = watchdog_service,
.startup = true
},
{
.name = xstr(SERVICE_NAME_HEARTBEAT),
.service_func = heartbeat_service,
.startup = false
}
};

const size_t service_descriptors_length = sizeof(service_descriptors)/sizeof(ServiceDesc_t);
72 changes: 37 additions & 35 deletions services/services.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,44 +203,46 @@ BaseType_t heartbeat_service(void);


/************************
* Service Arrays
* Service Definitions
*************************/

// function ptr array of available service functions above for launching with taskmanager.
// note that taskmanager itself is not in this list (it is a base service).
// the corresponding string in service_strings[] below will be used to match the service.
// service_functions[] and service_strings[] need to be in the same order!
typedef BaseType_t (*ServiceFunc_t)(void);
static const ServiceFunc_t service_functions[] = {
cli_service,
usb_service,
storman_service,
watchdog_service,
heartbeat_service
};

// string versions of service names, used when comparing against user input.
// use xstr() to convert the SERVICE_NAME_ #define to a usable string.
// the corresponding index number in the service_functions[] array above will be the
// function ptr to launch the service.
// service_functions[] and service_strings[] need to be in the same order!
static const char *service_strings[] = {
xstr(SERVICE_NAME_CLI),
xstr(SERVICE_NAME_USB),
xstr(SERVICE_NAME_STORMAN),
xstr(SERVICE_NAME_WATCHDOG),
xstr(SERVICE_NAME_HEARTBEAT)
};

// startup services - launched automatically by taskmanager at boot.
// these strings should match with what is in service_strings[] for the intended service.
// these can be in any order, the corresponding FreeRTOS tasked will be launched in this order.
static const char *startup_services[] = {
"usb",
"cli",
"storagemanager",
"watchdog"
};

/**
* Structure to hold the service name, service function and whether or not this is a startup service.
* TODO: add __attribute__((PACKED))?
*/
typedef struct ServiceDesc {
/**
* String version of the service name, used when comparing against user input.
* It is recommended to use xstr() to convert the SERVICE_NAME_ #define to a usable string (e.g. xstr(SERVICE_NAME_HEARTBEAT)).
*/
const char * const name;
/**
* Defines wether or not this service should automatically get launched by taskmanager at boot.
*/
const bool startup;
/**
* Function pointer to the service that creates the respective FreeRTOS task.
*/
ServiceFunc_t service_func;
} ServiceDesc_t;

/**
* Holds all the services that can be launched with taskmanager.
* These can be in any order, the corresponding FreeRTOS tasks will be launched in this order.
* Note: taskmanager itself is not in this list (it is a base service).
*
* Edit services.c to add your own services!
*/
extern const ServiceDesc_t service_descriptors[];

/**
* Amount of entries in the service_descriptors array.
*/
extern const size_t service_descriptors_length;




#endif /* SERVICES_H */
11 changes: 5 additions & 6 deletions services/taskman_service.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,14 @@ static void prvTaskManagerTask(void *pvParameters)
// launch startup services
cli_uart_puts(timestamp());
cli_uart_puts("Starting all bootup services...\r\n");
int i, j;
for (i = 0; i < (sizeof(startup_services)/sizeof(startup_services[0])); i++) {
for (j = 0; j < (sizeof(service_strings)/sizeof(service_strings[0])); j++) {
if (strcmp(service_strings[j], startup_services[i]) == 0) {
service_functions[j]();
}
int i;
for (i = 0; i < service_descriptors_length;i++) {
if(service_descriptors[i].startup) {
service_descriptors[i].service_func();
}
}


// At this point the system is fully running. Print a message
cli_uart_puts(timestamp());
cli_uart_puts("All startup services launched.\r\n");
Expand Down