-
Notifications
You must be signed in to change notification settings - Fork 1
/
TISM.c
198 lines (162 loc) · 6.85 KB
/
TISM.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/*
TISM.c - "The Incredible State Machine" - functions to set up the system and some generic tools.
Copyright (c) 2024 Maarten Klarenbeek (https://github.com/mjklaren)
Distributed under the GPLv3 license
*/
#include <string.h>
#include <stdio.h>
#include "TISM.h"
/*
Description
Get the TaskID for the task specified by name from the global Task structs.
Parameters:
*TaskName - Pointer to a string with the name of the task.
Return value:
-1 - Specified task name not found.
<int value> - Task ID for the specific task, starting with 0.
*/
int TISM_GetTaskID(char *TaskName)
{
int TaskID=-1;
for(int counter=0;counter<System.NumberOfTasks;counter++)
if(strcmp(System.Task[counter].TaskName,TaskName)==0)
TaskID=counter;
return(TaskID);
}
/*
Description
Check if the specified TaskID is valid (=in use)
Parameters:
int TaskID - The number of the task to check.
Return value:
false - Invalid task ID
true - Valid task ID
*/
bool TISM_IsValidTaskID(int TaskID)
{
if((TaskID>=0) && (TaskID<System.NumberOfTasks))
return(true);
return(false);
}
/*
Description
Check if the specified Task is awake.
Parameters:
int TaskID - The number of the task to check.
Return value:
false - Task is sleeping, or invalid task ID.
true - Task is awake
*/
bool TISM_IsTaskAwake(int TaskID)
{
if((TaskID>=0) && (TaskID<System.NumberOfTasks))
return(!System.Task[TaskID].TaskSleeping);
return(false);
}
/*
Description
Check if the specified Task is a system task by checking first 5 characters for "TISM_".
Parameters:
int TaskID - The number of the task to check.
Return value:
true - Specified task is a system task.
false - Specified task is not a system task.
*/
bool TISM_IsSystemTask(int TaskID)
{
return(strncmp(System.Task[TaskID].TaskName,"TISM_",5)==0?true:false);
}
/*
Description
Register a new task in the global System struct.
Parameters:
int *Function - Pointer to the function for this task; function returns int and takes no variables.
char *Name - Pointer to text buffer with name of this process.
int TaskDefaultPriority - Priority for this task (PRIORITY_HIGH, PRIORITY_NORMAL, PRIORITY_LOW or other value in msec).
Return value:
ERR_TOO_MANY_TASKS - Attempt was made to register > MAX_TASKS.
OK - Succes
*/
int TISM_RegisterTask(uint8_t (*Function)(TISM_Task), char *Name, uint32_t TaskPriority)
{
// Register the task-related data in the struct. Default values will be placed when initializing the System.
// Check if not too many tasks are registered.
if(System.NumberOfTasks>=MAX_TASKS)
{
// We have reached our task limit.
fprintf(STDERR, "TISM_RegisterTask: too many tasks to register (maximum: %d) while attempting to register %s.\n", MAX_TASKS, Name);
return(ERR_TOO_MANY_TASKS);
}
// Set task-related information.
System.Task[System.NumberOfTasks].TaskID=System.NumberOfTasks;
System.Task[System.NumberOfTasks].RunningOnCoreID=-1;
strncpy(System.Task[System.NumberOfTasks].TaskName, Name, MAX_TASK_NAME_LENGTH);
System.Task[System.NumberOfTasks].TaskFunction=Function;
System.Task[System.NumberOfTasks].TaskState=INIT;
System.Task[System.NumberOfTasks].TaskDebug=System.SystemDebug;
System.Task[System.NumberOfTasks].TaskPriority=TaskPriority;
System.Task[System.NumberOfTasks].TaskWakeUpTimer=0;
System.Task[System.NumberOfTasks].TaskSleeping=false;
System.Task[System.NumberOfTasks].TaskDebug=DEBUG_NONE;
// Initialize the inbound messaging queue for this task. Place a pointer to the corresponding queue in the task struct.
System.Task[System.NumberOfTasks].InboundMessageQueue=&InboundMessageQueue[System.NumberOfTasks];
TISM_CircularBufferInit(System.Task[System.NumberOfTasks].InboundMessageQueue);
System.Task[System.NumberOfTasks].OutboundMessageQueue=NULL; // Will be provided by the scheduler.
if(System.SystemDebug>=DEBUG_LOW)
fprintf (STDOUT, "TISM: Task %s registered as task ID %d with priority %d.\n", System.Task[System.NumberOfTasks].TaskName, System.NumberOfTasks, System.Task[System.NumberOfTasks].TaskPriority);
System.NumberOfTasks++;
return(OK);
}
/*
Description
Initialize the global System-struct by providing default values. Furthermore, register the standard TISM tasks.
Parameters:
None - This function works my modifying the global System and Task structs.
Return value:
ERR_INITIALIZING - Error occured during initializing the system.
OK - Succes
*/
int TISM_InitializeSystem()
{
// Initialize the RP2040
stdio_init_all();
// Set the SYSTEM_READY_PORT to low to indicate that the system is not ready (yet). The TISM_Scheduler will set the port high.
gpio_init(SYSTEM_READY_PORT);
gpio_set_dir(SYSTEM_READY_PORT, GPIO_OUT);
gpio_put(SYSTEM_READY_PORT, 0);
sleep_ms(STARTUP_DELAY); // Add some sleep to allow USB comms to initialize.
// Initialize the TISM-system. Provide variables default values where possible and register the TISM system tasks.
System.State=INIT;
for(int counter=0;counter<MAX_CORES;counter++)
{
// Uneven core numbers start at 0 and run the queue upwards; even cores start at the last task and run downwards.
System.RunPointer[counter]=255; // 255 shows this pointer isn´t used yet; 0 is also a valid task number.
System.RunPointerDirection[counter]=(counter%2==0?QUEUE_RUN_ASCENDING:QUEUE_RUN_DESCENDING);
TISM_CircularBufferInit (&(OutboundMessageQueue[counter]));
}
System.NumberOfTasks=0;
TISM_CircularBufferInit (&IRQHandlerInboundQueue);
// Now register the standard TISM_processes.
if ((TISM_RegisterTask(NULL, "TISM_Scheduler", PRIORITY_LOW)+ // Dummy entry for the scheduler
TISM_RegisterTask(&TISM_EventLogger, "TISM_EventLogger", PRIORITY_LOW)+
TISM_RegisterTask(&TISM_Postman, "TISM_Postman", PRIORITY_LOW)+
TISM_RegisterTask(&TISM_IRQHandler, "TISM_IRQHandler", PRIORITY_LOW)+
TISM_RegisterTask(&TISM_Watchdog, "TISM_Watchdog", PRIORITY_LOW)+
TISM_RegisterTask(&TISM_TaskManager, "TISM_TaskManager", PRIORITY_LOW)+
TISM_RegisterTask(&TISM_SoftwareTimer, "TISM_SoftwareTimer", PRIORITY_HIGH))!=0)
{
// Some error during setting up ITSM system tasks
return(ERR_INITIALIZING);
}
else
{
// Collect the Task IDs for the system tasks.
System.TISM_PostmanTaskID=TISM_GetTaskID("TISM_Postman");
System.TISM_IRQHandlerTaskID=TISM_GetTaskID("TISM_IRQHandler");
System.TISM_TaskManagerTaskID=TISM_GetTaskID("TISM_TaskManager");
System.TISM_WatchdogTaskID=TISM_GetTaskID("TISM_Watchdog");
System.TISM_EventLoggerTaskID=TISM_GetTaskID("TISM_EventLogger");
System.TISM_SoftwareTimerTaskID=TISM_GetTaskID("TISM_SoftwareTimer");
return(OK);
}
}