Loading...
Searching...
No Matches
debug_task.c
1/***********************************************************************************
2 * @file debug_stack.c *
3 * @author Matt Ricci *
4 * @addtogroup Shell *
5 * *
6 * @{ *
7 ***********************************************************************************/
8
9#include "FreeRTOSConfig.h"
10#include "FreeRTOS.h"
11#include "task.h"
12
13// ALLOW FORMATTING
14#if INCLUDE_uxTaskGetStackHighWaterMark == 1
15
16#include "stdio.h"
17#include "string.h"
18
19#include "tasklist.h"
20#include "parser.h"
21#include "state.h"
22#include "shell.h"
23
24static void Task_exec(UART_t *uart, char *flags);
25static void Task_help(UART_t *uart);
26
27static UART_t *pUart;
28
29DEFINE_PROGRAM_HANDLE("task", Task_exec, Task_help)
30
31static void Task_help(UART_t *uart) {
32 uart->println(uart, "NAME:");
33 uart->println(uart, "\ttask\n");
34 uart->println(uart, "USAGE:");
35 uart->println(uart, "\ttask print name");
36 uart->println(uart, "\ttask print stack [--task-name <name>]\n");
37 uart->println(uart, "DESCRIPTION:");
38 uart->println(uart, "\tprint name");
39 uart->println(uart, "\t Print the name of every task in the Australis Core list.\n");
40 uart->println(uart, "\tprint stack");
41 uart->println(uart, "\t Print the stack high-watermark of each/selected task.\n");
42 uart->println(uart, "OPTIONS:");
43 uart->println(uart, "\t-t, --task-name");
44 uart->println(uart, "\t Select a task to operate with. Has no effect when used with `print name`.");
45 uart->println(uart, "\t-h, --help");
46 uart->println(uart, "\t Print this help and exit");
47}
48
49static void printTaskName(TaskHandle_t task) {
50 char *taskName = pcTaskGetName(task);
51 pUart->println(pUart, taskName);
52}
53
54static void printTaskStack(TaskHandle_t task) {
55 unsigned int stackRemaining = uxTaskGetStackHighWaterMark(task);
56 char *taskName = pcTaskGetName(task);
57 uint8_t taskNameLength = strlen(taskName);
58
59 pUart->print(pUart, taskName);
60 for (uint8_t i = 0; i < (configMAX_TASK_NAME_LEN - taskNameLength); i++) {
61 pUart->send(pUart, ' ');
62 }
63
64 uint8_t stackRemainingLength = snprintf(NULL, 0, "%u", stackRemaining);
65
66 char stackStr[stackRemainingLength + 1];
67 snprintf(stackStr, stackRemainingLength + 1, "%u", stackRemaining);
68 pUart->println(pUart, stackStr);
69}
70
71/* ============================================================================================== */
78static void Task_exec(UART_t *uart, char *flags) {
79 pUart = uart;
80
81 ArgParser parser = ArgParser_init();
82 int argPrintIdx = parser.addArg(
83 &parser, "print", 0, ARG_TYPE_STRING, false
84 );
85 int argTaskNameIdx = parser.addArg(
86 &parser, "--task-name", 't', ARG_TYPE_STRING, false
87 );
88
89 char *tokens[MAX_ARGS];
90 int numTokens = 0;
91
92 // Tokenize the input string
93 char *token = strtok(flags, " ");
94 while (token != NULL && numTokens < MAX_ARGS) {
95 tokens[numTokens++] = token;
96 token = strtok(NULL, " ");
97 }
98
99 // Parse input tokens
100 parser.parseArgs(&parser, numTokens, tokens);
101
102 // Early exit with error message
103 if (parser.error.status == PARSER_STATUS_ERROR) {
104 uart->println(uart, parser.error.msg);
105 return;
106 }
107
108 // Print requested state variable value
109 if (parser.args[argPrintIdx].provided) {
110 char *value = parser.args[argPrintIdx].value;
111 State *state = State_getState();
112
113 char str[50] = "";
114
115 // Print name for each task
116 if (!strcmp(value, "name")) {
117 uart->println(uart, "");
118 uart->println(uart, "Task Name ");
119 uart->println(uart, "----------------");
120 TaskList_forEach(printTaskName);
121 }
122
123 // Print task for each/requested task
124 else if (!strcmp(value, "stack")) {
125 TaskHandle_t taskHandle;
126 uart->println(uart, "");
127 uart->println(uart, "Task Name Stack High Watermark");
128 uart->println(uart, "------------------------------------");
129
130 Argument argTaskName = parser.args[argTaskNameIdx];
131 char *taskName = argTaskName.provided ? argTaskName.value : NULL;
132
133 // Print error if requested task does not exist
134 if (taskName && (taskHandle = TaskList_getTaskByName(taskName))) {
135 printTaskStack(taskHandle);
136 }
137 // Print stack for task if provided
138 else if (taskName) {
139 snprintf(str, sizeof(str), "Error: Task `%s` not found\n", taskName);
140 }
141 // Print stack for all tasks otherwise
142 else {
143 TaskList_forEach(printTaskStack);
144 }
145 }
146
147 // Invalid argument
148 else {
149 snprintf(str, sizeof(str), "Error: invalid argument\n");
150 }
151
152 uart->println(uart, str);
153 }
154
155 pUart = NULL;
156}
157
158#endif
159
State * State_getState()
Definition state.c:69
State variable struct.
Definition state.h:36
TaskHandle_t TaskList_getTaskByName(char *)
Retrieve task handle from list by name string.
Definition tasklist.c:24
void TaskList_forEach(void(*func)(TaskHandle_t))
Definition tasklist.c:60
void(* println)(struct UART *, char *)
UART print line method.
Definition uart.h:141
Struct definition for UART interface.
Definition uart.h:132