RTOS_MSPM0  1.1
ECE445M starter code
OS.h
Go to the documentation of this file.
1 
14 #ifndef __OS_H
15 #define __OS_H 1
16 #include <stdint.h>
20 #define LAB1 0
21 #define LAB2 0
22 #define LAB3 0
23 #define LAB4 0
24 #define LAB5 1
25 #define LAB6 0
29 #define TIME_1MS 80000
30 #define TIME_2MS (2*TIME_1MS)
31 #define TIME_500US (TIME_1MS/2)
32 #define TIME_250US (TIME_1MS/4)
33 
37 struct Sema4{
38  int32_t Value; // >0 means free, otherwise means busy
39 // add other components here, if necessary to implement blocking
40 };
41 typedef struct Sema4 Sema4_t;
42 
51 void OS_Init(void);
52 
53 // ******** OS_InitSemaphore ************
54 // initialize semaphore
55 // input: pointer to a semaphore
56 // output: none
57 void OS_InitSemaphore(Sema4_t *semaPt, int32_t value);
58 
59 // ******** OS_Wait ************
60 // decrement semaphore
61 // Lab2 spinlock
62 // Lab3 block if less than zero
63 // input: pointer to a counting semaphore
64 // output: none
65 void OS_Wait(Sema4_t *semaPt);
66 
67 // ******** OS_Signal ************
68 // increment semaphore
69 // Lab2 spinlock
70 // Lab3 wakeup blocked thread if appropriate
71 // input: pointer to a counting semaphore
72 // output: none
73 void OS_Signal(Sema4_t *semaPt);
74 
75 // ******** OS_bWait ************
76 // Lab2 spinlock, set to 0
77 // Lab3 block if less than zero
78 // input: pointer to a binary semaphore
79 // output: none
80 void OS_bWait(Sema4_t *semaPt);
81 
82 // ******** OS_bSignal ************
83 // Lab2 spinlock, set to 1
84 // Lab3 wakeup blocked thread if appropriate
85 // input: pointer to a binary semaphore
86 // output: none
87 void OS_bSignal(Sema4_t *semaPt);
88 
89 //******** OS_AddThread ***************
90 // add a foreground thread to the scheduler
91 // Inputs: pointer to a void/void foreground task
92 // number of bytes allocated for its stack
93 // priority, 0 is highest, 255 is the lowest
94 // Priorities are relative to other foreground threads
95 // Outputs: 1 if successful, 0 if this thread can not be added
96 // In Lab 2, you can ignore both the stackSize and priority fields
97 // In Lab 3, you can ignore the stackSize fields
98 // In Lab 4, the stackSize can be 128, 256, or 512 bytes
99 int OS_AddThread(void(*task)(void),
100  uint32_t stackSize, uint32_t priority);
101 
102 //******** OS_Id ***************
103 // returns the thread ID for the currently running thread
104 // Inputs: none
105 // Outputs: Thread ID, number greater than zero
106 uint32_t OS_Id(void);
107 
108 //******** OS_AddPeriodicThread ***************
109 // Add a background periodic thread
110 // typically this function receives the highest priority
111 // Inputs: task is pointer to a void/void background function
112 // period in ms
113 // priority 0 is the highest, 3 is the lowest
114 // Priorities are relative to other background periodic threads
115 // Outputs: 1 if successful, 0 if this thread can not be added
116 // You are free to select the resolution of period
117 // It is assumed that the user task will run to completion and return
118 // This task can not spin, block, loop, sleep, or kill
119 // This task can call OS_Signal OS_bSignal OS_AddThread
120 // This task does not have a Thread ID
121 // In lab 2, this command will be called 0 or 1 times
122 // In lab 3, this command will be called 0 to 4 times
123 // In labs 3-7, there will be 0 to 4 background periodic threads, and this priority field
124 // determines the relative priority of these threads
125 // For Lab 3, it ok to make reasonable limits to reduce the complexity. E.g.,
126 // - You can assume there are 0 to 4 background periodic threads
127 // - You can assume the priorities are sequential 0,1,2,3
128 // - You can assume a maximum thread execution time, e.g., 50us
129 // - You can assume a slowest period, e.g., 50ms
130 // - You can limit possible periods, e.g., 1,2,4,5,10,20,25,50ms
131 // - You can assume (E0/T0)+(E1/T1)+(E2/T2)+(E3/T3) is much less than 1
132 int OS_AddPeriodicThread(void(*task)(void),
133  uint32_t period, uint32_t priority);
134 
135 // ******** OS_AddS1Task ***************
136 // add a background task to run whenever the S1 (PA18) button is pushed
137 // Inputs: pointer to a void/void background function
138 // priority 0 is the highest, 1 is the lowest
139 // Outputs: 1 if successful, 0 if this thread can not be added
140 // It is assumed that the user task will run to completion and return
141 // This task can not spin, block, loop, sleep, or kill
142 // This task can call OS_Signal OS_bSignal OS_AddThread
143 // This task does not have a Thread ID
144 // Because of the pin conflict with TFLuna, this command will not be called
145 // In lab 2, the priority field can be ignored
146 // In labs 3-7, there will be many background threads, and this priority field
147 // determines the relative priority of these threads
148 int OS_AddS1Task(void(*task)(void), uint32_t priority);
149 
150 // ******** OS_AddS2Task ***************
151 // add a background task to run whenever the S2 (PB21) button is pushed
152 // Inputs: pointer to a void/void background function
153 // priority 0 is highest, 1 is lowest
154 // Outputs: 1 if successful, 0 if this thread can not be added
155 // It is assumed user task will run to completion and return
156 // This task can not spin block loop sleep or kill
157 // This task can call issue OS_Signal, it can call OS_AddThread
158 // This task does not have a Thread ID
159 // In labs 3-7, this command will be called will be called 0 or 1 times
160 // In labs 3-7, there will be many background threads, and this priority field
161 // determines the relative priority of these threads
162 int OS_AddS2Task(void(*task)(void), uint32_t priority);
163 
164 // ******** OS_AddPA28Task ***************
165 // add a background task to run whenever the bump (PA28) button is pushed
166 // Inputs: pointer to a void/void background function
167 // priority 0 is the highest, 1 is the lowest
168 // Outputs: 1 if successful, 0 if this thread can not be added
169 // It is assumed that the user task will run to completion and return
170 // This task can not spin, block, loop, sleep, or kill
171 // This task can call OS_Signal OS_bSignal OS_AddThread
172 // This task does not have a Thread ID
173 // In lab 3, this command will be called 0 or 1 times
174 // In lab 2, not implemented
175 // In lab 3, there will be many background threads, and this priority field
176 // determines the relative priority of these four threads
177 int OS_AddPA28Task(void(*task)(void), uint32_t priority);
178 
179 // ******** OS_Sleep ************
180 // place this thread into a dormant state
181 // input: number of msec to sleep
182 // output: none
183 // You are free to select the time resolution for this function
184 // OS_Sleep(0) implements cooperative multitasking
185 void OS_Sleep(uint32_t sleepTime);
186 
187 // ******** OS_Kill ************
188 // kill the currently running thread, release its TCB and stack
189 // input: none
190 // output: none
191 void OS_Kill(void);
192 
193 // ******** OS_Suspend ************
194 // suspend execution of currently running thread
195 // scheduler will choose another thread to execute
196 // Can be used to implement cooperative multitasking
197 // Same function as OS_Sleep(0)
198 // input: none
199 // output: none
200 void OS_Suspend(void);
201 
202 // temporarily prevent foreground thread switch (but allow background interrupts)
203 uint32_t OS_LockScheduler(void);
204 // resume foreground thread switching
205 void OS_UnLockScheduler(uint32_t previous);
206 
207 // ******** OS_Fifo_Init ************
208 // Initialize the Fifo to be empty
209 // Inputs: size
210 // Outputs: none
211 // In Lab 2, you can ignore the size field
212 // In Lab 3, you should implement the user-defined fifo size
213 // In Lab 3, you can put whatever restrictions you want on size
214 // e.g., 4 to 64 elements
215 // e.g., must be a power of 2,4,8,16,32,64,128
216 void OS_Fifo_Init(uint32_t size);
217 
218 // ******** OS_Fifo_Put ************
219 // Enter one data sample into the Fifo
220 // Called from the background, so no waiting
221 // Inputs: data
222 // Outputs: true if data is properly saved,
223 // false if data not saved, because it was full
224 // Since this is called by interrupt handlers
225 // this function can not disable or enable interrupts
226 int OS_Fifo_Put(uint32_t data);
227 
228 // ******** OS_Fifo_Get ************
229 // Remove one data sample from the Fifo
230 // Called in foreground, will spin/block if empty
231 // Inputs: none
232 // Outputs: data
233 uint32_t OS_Fifo_Get(void);
234 
235 // ******** OS_Fifo_Size ************
236 // Check the status of the Fifo
237 // Inputs: none
238 // Outputs: returns the number of elements in the Fifo
239 // greater than zero if a call to OS_Fifo_Get will return right away
240 // zero or less than zero if the Fifo is empty
241 // zero or less than zero if a call to OS_Fifo_Get will spin or block
242 int32_t OS_Fifo_Size(void);
243 
244 // ******** OS_MailBox_Init ************
245 // Initialize communication channel
246 // Inputs: none
247 // Outputs: none
248 void OS_MailBox_Init(void);
249 
250 // ******** OS_MailBox_Send ************
251 // enter mail into the MailBox
252 // Inputs: data to be sent
253 // Outputs: none
254 // This function will be called from a foreground thread
255 // It will spin/block if the MailBox contains data not yet received
256 void OS_MailBox_Send(uint32_t data);
257 
258 // ******** OS_MailBox_Recv ************
259 // remove mail from the MailBox
260 // Inputs: none
261 // Outputs: data received
262 // This function will be called from a foreground thread
263 // It will spin/block if the MailBox is empty
264 uint32_t OS_MailBox_Recv(void);
265 
266 // ******** OS_Time ************
267 // return the system time counting up
268 // Inputs: none
269 // Outputs: time in 12.5ns units, 0 to 4294967295
270 // The time resolution should be less than or equal to 1us, and the precision 32 bits
271 // It is ok to change the resolution and precision of this function as long as
272 // this function and OS_TimeDifference have the same resolution and precision
273 uint32_t OS_Time(void);
274 
275 // ******** OS_TimeDifference ************
276 // Calculates difference between two times
277 // Inputs: two times measured with OS_Time
278 // Outputs: time difference in 12.5ns units
279 // The time resolution should be less than or equal to 1us, and the precision at least 12 bits
280 // It is ok to change the resolution and precision of this function as long as
281 // this function and OS_Time have the same resolution and precision
282 uint32_t OS_TimeDifference(uint32_t start, uint32_t stop);
283 
284 // ******** OS_ClearMsTime ************
285 // sets the system time to zero (from Lab 1)
286 // Inputs: none
287 // Outputs: none
288 // You are free to change how this works
289 void OS_ClearMsTime(void);
290 
291 // ******** OS_MsTime ************
292 // reads the current time in msec
293 // Inputs: none
294 // Outputs: time in ms units
295 // You are free to select the time resolution for this function
296 // It is ok to make the resolution to match the first call to OS_AddPeriodicThread
297 uint32_t OS_MsTime(void);
298 
299 //******** OS_Launch ***************
300 // start the scheduler, enable interrupts
301 // Inputs: number of 12.5ns clock cycles for each time slice
302 // you may select the units of this parameter
303 // Outputs: none (does not return)
304 // In Lab 2, you can ignore the theTimeSlice field
305 // In Lab 3, you should implement the user-defined TimeSlice field
306 // It is ok to limit the range of theTimeSlice to match the 24-bit SysTick
307 void OS_Launch(uint32_t theTimeSlice);
308 
309 // Program has these fields
310 struct Program{
311  uint32_t StartOffset; // offset to starting location
312  uint32_t CodeSize; // size of code segment
313  uint32_t StackSize; // size of stack segment
314  uint32_t DataSize; // size of data segment (globals)
315  char Name[8]; // ASCII string
316 };
317 typedef struct Program Program_t;
318 
319 // Load program from disk and launch process
320 // open file for reading
321 // read StartOffset,CodeSize,StackSize,DataSize,Name
322 // Allocate spaces in RAM for data, stack, and code segments
323 // Reads the object code from file into the code segment
324 // Closes the file
325 // Add program as a process, create a thread for it, and execute
326 // SP => stack segment
327 // R7 => data segment
328 // PC => code segment (entry point at first location)
329 // Inputs: name is the name of the file on SDC
330 // priority is the thread priority
331 // Output: 1 success, 0 failure
332 int OS_LoadProgram(char *name, uint32_t priority);
333 
334 
335 #endif
void OS_Init(void)
Initialize OS.
Definition: OS.h:310
Semaphore structure. Feel free to change the type of semaphore, there are lots of good solutions.
Definition: OS.h:37