UCOS_TI_LM3S_Keil
首页
相关页面
结构体
文件
文件列表
全局定义
全部
结构体
文件
函数
变量
类型定义
宏定义
页
os_task.c
浏览该文件的文档.
1
/*
2
*********************************************************************************************************
3
* uC/OS-II
4
* The Real-Time Kernel
5
* TASK MANAGEMENT
6
*
7
* (c) Copyright 1992-2009, Micrium, Weston, FL
8
* All Rights Reserved
9
*
10
* File : OS_TASK.C
11
* By : Jean J. Labrosse
12
* Version : V2.89
13
*
14
* LICENSING TERMS:
15
* ---------------
16
* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research.
17
* If you plan on using uC/OS-II in a commercial product you need to contact Micrim to properly license
18
* its use in your product. We provide ALL the source code for your convenience and to help you experience
19
* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a
20
* licensing fee.
21
*********************************************************************************************************
22
*/
23
24
#ifndef OS_MASTER_FILE
25
#include <
ucos_ii.h
>
26
#endif
27
28
/*$PAGE*/
29
/*
30
*********************************************************************************************************
31
* CHANGE PRIORITY OF A TASK
32
*
33
* Description: This function allows you to change the priority of a task dynamically. Note that the new
34
* priority MUST be available.
35
*
36
* Arguments : oldp is the old priority
37
*
38
* newp is the new priority
39
*
40
* Returns : OS_ERR_NONE is the call was successful
41
* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed
42
* (i.e. >= OS_LOWEST_PRIO)
43
* OS_ERR_PRIO_EXIST if the new priority already exist.
44
* OS_ERR_PRIO there is no task with the specified OLD priority (i.e. the OLD task does
45
* not exist.
46
* OS_ERR_TASK_NOT_EXIST if the task is assigned to a Mutex PIP.
47
*********************************************************************************************************
48
*/
49
50
#if OS_TASK_CHANGE_PRIO_EN > 0u
51
INT8U
OSTaskChangePrio
(
INT8U
oldprio,
52
INT8U
newprio)
53
{
54
#if (OS_EVENT_EN)
55
OS_EVENT
*pevent;
56
#if (OS_EVENT_MULTI_EN > 0u)
57
OS_EVENT
**pevents;
58
#endif
59
#endif
60
OS_TCB
*ptcb;
61
INT8U
y_new;
62
INT8U
x_new;
63
INT8U
y_old;
64
#if OS_LOWEST_PRIO <= 63u
65
INT8U
bity_new;
66
INT8U
bitx_new;
67
INT8U
bity_old;
68
INT8U
bitx_old;
69
#else
70
INT16U
bity_new;
71
INT16U
bitx_new;
72
INT16U
bity_old;
73
INT16U
bitx_old;
74
#endif
75
#if OS_CRITICAL_METHOD == 3u
76
OS_CPU_SR
cpu_sr = 0u;
/* Storage for CPU status register */
77
#endif
78
79
80
/*$PAGE*/
81
#if OS_ARG_CHK_EN > 0u
82
if
(oldprio >=
OS_LOWEST_PRIO
) {
83
if
(oldprio !=
OS_PRIO_SELF
) {
84
return
(
OS_ERR_PRIO_INVALID
);
85
}
86
}
87
if
(newprio >=
OS_LOWEST_PRIO
) {
88
return
(
OS_ERR_PRIO_INVALID
);
89
}
90
#endif
91
OS_ENTER_CRITICAL
();
92
if
(
OSTCBPrioTbl
[newprio] != (
OS_TCB
*)0) {
/* New priority must not already exist */
93
OS_EXIT_CRITICAL
();
94
return
(
OS_ERR_PRIO_EXIST
);
95
}
96
if
(oldprio ==
OS_PRIO_SELF
) {
/* See if changing self */
97
oldprio =
OSTCBCur
->
OSTCBPrio
;
/* Yes, get priority */
98
}
99
ptcb =
OSTCBPrioTbl
[oldprio];
100
if
(ptcb == (
OS_TCB
*)0) {
/* Does task to change exist? */
101
OS_EXIT_CRITICAL
();
/* No, can't change its priority! */
102
return
(
OS_ERR_PRIO
);
103
}
104
if
(ptcb ==
OS_TCB_RESERVED
) {
/* Is task assigned to Mutex */
105
OS_EXIT_CRITICAL
();
/* No, can't change its priority! */
106
return
(
OS_ERR_TASK_NOT_EXIST
);
107
}
108
#if OS_LOWEST_PRIO <= 63u
109
y_new = (
INT8U
)(newprio >> 3);
/* Yes, compute new TCB fields */
110
x_new = (
INT8U
)(newprio & 0x07);
111
bity_new = (
INT8U
)(1u << y_new);
112
bitx_new = (
INT8U
)(1u << x_new);
113
#else
114
y_new = (
INT8U
)((newprio >> 4) & 0x0F);
115
x_new = (
INT8U
)( newprio & 0x0F);
116
bity_new = (
INT16U
)(1u << y_new);
117
bitx_new = (
INT16U
)(1u << x_new);
118
#endif
119
120
OSTCBPrioTbl
[oldprio] = (
OS_TCB
*)0;
/* Remove TCB from old priority */
121
OSTCBPrioTbl
[newprio] = ptcb;
/* Place pointer to TCB @ new priority */
122
y_old = ptcb->
OSTCBY
;
123
bity_old = ptcb->
OSTCBBitY
;
124
bitx_old = ptcb->
OSTCBBitX
;
125
if
((
OSRdyTbl
[y_old] & bitx_old) != 0u) {
/* If task is ready make it not */
126
OSRdyTbl
[y_old] &= ~bitx_old;
127
if
(
OSRdyTbl
[y_old] == 0u) {
128
OSRdyGrp
&= ~bity_old;
129
}
130
OSRdyGrp
|= bity_new;
/* Make new priority ready to run */
131
OSRdyTbl
[y_new] |= bitx_new;
132
}
133
134
#if (OS_EVENT_EN)
135
pevent = ptcb->
OSTCBEventPtr
;
136
if
(pevent != (
OS_EVENT
*)0) {
137
pevent->
OSEventTbl
[y_old] &= ~bitx_old;
/* Remove old task prio from wait list */
138
if
(pevent->
OSEventTbl
[y_old] == 0u) {
139
pevent->
OSEventGrp
&= ~bity_old;
140
}
141
pevent->
OSEventGrp
|= bity_new;
/* Add new task prio to wait list */
142
pevent->
OSEventTbl
[y_new] |= bitx_new;
143
}
144
#if (OS_EVENT_MULTI_EN > 0u)
145
if
(ptcb->
OSTCBEventMultiPtr
!= (
OS_EVENT
**)0) {
146
pevents = ptcb->
OSTCBEventMultiPtr
;
147
pevent = *pevents;
148
while
(pevent != (
OS_EVENT
*)0) {
149
pevent->
OSEventTbl
[y_old] &= ~bitx_old;
/* Remove old task prio from wait lists */
150
if
(pevent->
OSEventTbl
[y_old] == 0u) {
151
pevent->
OSEventGrp
&= ~bity_old;
152
}
153
pevent->
OSEventGrp
|= bity_new;
/* Add new task prio to wait lists */
154
pevent->
OSEventTbl
[y_new] |= bitx_new;
155
pevents++;
156
pevent = *pevents;
157
}
158
}
159
#endif
160
#endif
161
162
ptcb->
OSTCBPrio
= newprio;
/* Set new task priority */
163
ptcb->
OSTCBY
= y_new;
164
ptcb->
OSTCBX
= x_new;
165
ptcb->
OSTCBBitY
= bity_new;
166
ptcb->
OSTCBBitX
= bitx_new;
167
OS_EXIT_CRITICAL
();
168
if
(
OSRunning
==
OS_TRUE
) {
169
OS_Sched
();
/* Find new highest priority task */
170
}
171
return
(
OS_ERR_NONE
);
172
}
173
#endif
174
/*$PAGE*/
175
/*
176
*********************************************************************************************************
177
* CREATE A TASK
178
*
179
* Description: This function is used to have uC/OS-II manage the execution of a task. Tasks can either
180
* be created prior to the start of multitasking or by a running task. A task cannot be
181
* created by an ISR.
182
*
183
* Arguments : task is a pointer to the task's code
184
*
185
* p_arg is a pointer to an optional data area which can be used to pass parameters to
186
* the task when the task first executes. Where the task is concerned it thinks
187
* it was invoked and passed the argument 'p_arg' as follows:
188
*
189
* void Task (void *p_arg)
190
* {
191
* for (;;) {
192
* Task code;
193
* }
194
* }
195
*
196
* ptos is a pointer to the task's top of stack. If the configuration constant
197
* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high
198
* memory to low memory). 'pstk' will thus point to the highest (valid) memory
199
* location of the stack. If OS_STK_GROWTH is set to 0, 'pstk' will point to the
200
* lowest memory location of the stack and the stack will grow with increasing
201
* memory locations.
202
*
203
* prio is the task's priority. A unique priority MUST be assigned to each task and the
204
* lower the number, the higher the priority.
205
*
206
* Returns : OS_ERR_NONE if the function was successful.
207
* OS_PRIO_EXIT if the task priority already exist
208
* (each task MUST have a unique priority).
209
* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed
210
* (i.e. >= OS_LOWEST_PRIO)
211
* OS_ERR_TASK_CREATE_ISR if you tried to create a task from an ISR.
212
*********************************************************************************************************
213
*/
214
215
#if OS_TASK_CREATE_EN > 0u
216
INT8U
OSTaskCreate
(
void
(*task)(
void
*p_arg),
217
void
*p_arg,
218
OS_STK
*ptos,
219
INT8U
prio)
220
{
221
OS_STK
*psp;
222
INT8U
err;
223
#if OS_CRITICAL_METHOD == 3u
/* Allocate storage for CPU status register */
224
OS_CPU_SR
cpu_sr = 0u;
225
#endif
226
227
228
229
#if OS_ARG_CHK_EN > 0u
230
if
(prio >
OS_LOWEST_PRIO
) {
/* Make sure priority is within allowable range */
231
return
(
OS_ERR_PRIO_INVALID
);
232
}
233
#endif
234
OS_ENTER_CRITICAL
();
235
if
(
OSIntNesting
> 0u) {
/* Make sure we don't create the task from within an ISR */
236
OS_EXIT_CRITICAL
();
237
return
(
OS_ERR_TASK_CREATE_ISR
);
238
}
239
if
(
OSTCBPrioTbl
[prio] == (
OS_TCB
*)0) {
/* Make sure task doesn't already exist at this priority */
240
OSTCBPrioTbl
[prio] =
OS_TCB_RESERVED
;
/* Reserve the priority to prevent others from doing ... */
241
/* ... the same thing until task is created. */
242
OS_EXIT_CRITICAL
();
243
psp =
OSTaskStkInit
(task, p_arg, ptos, 0u);
/* Initialize the task's stack */
244
err =
OS_TCBInit
(prio, psp, (
OS_STK
*)0, 0u, 0u, (
void
*)0, 0u);
245
if
(err ==
OS_ERR_NONE
) {
246
if
(
OSRunning
==
OS_TRUE
) {
/* Find highest priority task if multitasking has started */
247
OS_Sched
();
248
}
249
}
else
{
250
OS_ENTER_CRITICAL
();
251
OSTCBPrioTbl
[prio] = (
OS_TCB
*)0;
/* Make this priority available to others */
252
OS_EXIT_CRITICAL
();
253
}
254
return
(err);
255
}
256
OS_EXIT_CRITICAL
();
257
return
(
OS_ERR_PRIO_EXIST
);
258
}
259
#endif
260
/*$PAGE*/
261
/*
262
*********************************************************************************************************
263
* CREATE A TASK (Extended Version)
264
*
265
* Description: This function is used to have uC/OS-II manage the execution of a task. Tasks can either
266
* be created prior to the start of multitasking or by a running task. A task cannot be
267
* created by an ISR. This function is similar to OSTaskCreate() except that it allows
268
* additional information about a task to be specified.
269
*
270
* Arguments : task is a pointer to the task's code
271
*
272
* p_arg is a pointer to an optional data area which can be used to pass parameters to
273
* the task when the task first executes. Where the task is concerned it thinks
274
* it was invoked and passed the argument 'p_arg' as follows:
275
*
276
* void Task (void *p_arg)
277
* {
278
* for (;;) {
279
* Task code;
280
* }
281
* }
282
*
283
* ptos is a pointer to the task's top of stack. If the configuration constant
284
* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high
285
* memory to low memory). 'ptos' will thus point to the highest (valid) memory
286
* location of the stack. If OS_STK_GROWTH is set to 0, 'ptos' will point to the
287
* lowest memory location of the stack and the stack will grow with increasing
288
* memory locations. 'ptos' MUST point to a valid 'free' data item.
289
*
290
* prio is the task's priority. A unique priority MUST be assigned to each task and the
291
* lower the number, the higher the priority.
292
*
293
* id is the task's ID (0..65535)
294
*
295
* pbos is a pointer to the task's bottom of stack. If the configuration constant
296
* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high
297
* memory to low memory). 'pbos' will thus point to the LOWEST (valid) memory
298
* location of the stack. If OS_STK_GROWTH is set to 0, 'pbos' will point to the
299
* HIGHEST memory location of the stack and the stack will grow with increasing
300
* memory locations. 'pbos' MUST point to a valid 'free' data item.
301
*
302
* stk_size is the size of the stack in number of elements. If OS_STK is set to INT8U,
303
* 'stk_size' corresponds to the number of bytes available. If OS_STK is set to
304
* INT16U, 'stk_size' contains the number of 16-bit entries available. Finally, if
305
* OS_STK is set to INT32U, 'stk_size' contains the number of 32-bit entries
306
* available on the stack.
307
*
308
* pext is a pointer to a user supplied memory location which is used as a TCB extension.
309
* For example, this user memory can hold the contents of floating-point registers
310
* during a context switch, the time each task takes to execute, the number of times
311
* the task has been switched-in, etc.
312
*
313
* opt contains additional information (or options) about the behavior of the task. The
314
* LOWER 8-bits are reserved by uC/OS-II while the upper 8 bits can be application
315
* specific. See OS_TASK_OPT_??? in uCOS-II.H. Current choices are:
316
*
317
* OS_TASK_OPT_STK_CHK Stack checking to be allowed for the task
318
* OS_TASK_OPT_STK_CLR Clear the stack when the task is created
319
* OS_TASK_OPT_SAVE_FP If the CPU has floating-point registers, save them
320
* during a context switch.
321
*
322
* Returns : OS_ERR_NONE if the function was successful.
323
* OS_PRIO_EXIT if the task priority already exist
324
* (each task MUST have a unique priority).
325
* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed
326
* (i.e. > OS_LOWEST_PRIO)
327
* OS_ERR_TASK_CREATE_ISR if you tried to create a task from an ISR.
328
*********************************************************************************************************
329
*/
330
/*$PAGE*/
331
#if OS_TASK_CREATE_EXT_EN > 0u
332
INT8U
OSTaskCreateExt
(
void
(*task)(
void
*p_arg),
333
void
*p_arg,
334
OS_STK
*ptos,
335
INT8U
prio,
336
INT16U
id
,
337
OS_STK
*pbos,
338
INT32U
stk_size,
339
void
*pext,
340
INT16U
opt)
341
{
342
OS_STK
*psp;
343
INT8U
err;
344
#if OS_CRITICAL_METHOD == 3u
/* Allocate storage for CPU status register */
345
OS_CPU_SR
cpu_sr = 0u;
346
#endif
347
348
349
350
#if OS_ARG_CHK_EN > 0u
351
if
(prio >
OS_LOWEST_PRIO
) {
/* Make sure priority is within allowable range */
352
return
(
OS_ERR_PRIO_INVALID
);
353
}
354
#endif
355
OS_ENTER_CRITICAL
();
356
if
(
OSIntNesting
> 0u) {
/* Make sure we don't create the task from within an ISR */
357
OS_EXIT_CRITICAL
();
358
return
(
OS_ERR_TASK_CREATE_ISR
);
359
}
360
if
(
OSTCBPrioTbl
[prio] == (
OS_TCB
*)0) {
/* Make sure task doesn't already exist at this priority */
361
OSTCBPrioTbl
[prio] =
OS_TCB_RESERVED
;
/* Reserve the priority to prevent others from doing ... */
362
/* ... the same thing until task is created. */
363
OS_EXIT_CRITICAL
();
364
365
#if (OS_TASK_STAT_STK_CHK_EN > 0u)
366
OS_TaskStkClr
(pbos, stk_size, opt);
/* Clear the task stack (if needed) */
367
#endif
368
369
psp =
OSTaskStkInit
(task, p_arg, ptos, opt);
/* Initialize the task's stack */
370
err =
OS_TCBInit
(prio, psp, pbos,
id
, stk_size, pext, opt);
371
if
(err ==
OS_ERR_NONE
) {
372
if
(
OSRunning
==
OS_TRUE
) {
/* Find HPT if multitasking has started */
373
OS_Sched
();
374
}
375
}
else
{
376
OS_ENTER_CRITICAL
();
377
OSTCBPrioTbl
[prio] = (
OS_TCB
*)0;
/* Make this priority avail. to others */
378
OS_EXIT_CRITICAL
();
379
}
380
return
(err);
381
}
382
OS_EXIT_CRITICAL
();
383
return
(
OS_ERR_PRIO_EXIST
);
384
}
385
#endif
386
/*$PAGE*/
387
/*
388
*********************************************************************************************************
389
* DELETE A TASK
390
*
391
* Description: This function allows you to delete a task. The calling task can delete itself by
392
* its own priority number. The deleted task is returned to the dormant state and can be
393
* re-activated by creating the deleted task again.
394
*
395
* Arguments : prio is the priority of the task to delete. Note that you can explicitely delete
396
* the current task without knowing its priority level by setting 'prio' to
397
* OS_PRIO_SELF.
398
*
399
* Returns : OS_ERR_NONE if the call is successful
400
* OS_ERR_TASK_DEL_IDLE if you attempted to delete uC/OS-II's idle task
401
* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed
402
* (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
403
* OS_ERR_TASK_DEL if the task is assigned to a Mutex PIP.
404
* OS_ERR_TASK_NOT_EXIST if the task you want to delete does not exist.
405
* OS_ERR_TASK_DEL_ISR if you tried to delete a task from an ISR
406
*
407
* Notes : 1) To reduce interrupt latency, OSTaskDel() 'disables' the task:
408
* a) by making it not ready
409
* b) by removing it from any wait lists
410
* c) by preventing OSTimeTick() from making the task ready to run.
411
* The task can then be 'unlinked' from the miscellaneous structures in uC/OS-II.
412
* 2) The function OS_Dummy() is called after OS_EXIT_CRITICAL() because, on most processors,
413
* the next instruction following the enable interrupt instruction is ignored.
414
* 3) An ISR cannot delete a task.
415
* 4) The lock nesting counter is incremented because, for a brief instant, if the current
416
* task is being deleted, the current task would not be able to be rescheduled because it
417
* is removed from the ready list. Incrementing the nesting counter prevents another task
418
* from being schedule. This means that an ISR would return to the current task which is
419
* being deleted. The rest of the deletion would thus be able to be completed.
420
*********************************************************************************************************
421
*/
422
423
#if OS_TASK_DEL_EN > 0u
424
INT8U
OSTaskDel
(
INT8U
prio)
425
{
426
#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u)
427
OS_FLAG_NODE
*pnode;
428
#endif
429
OS_TCB
*ptcb;
430
#if OS_CRITICAL_METHOD == 3u
/* Allocate storage for CPU status register */
431
OS_CPU_SR
cpu_sr = 0u;
432
#endif
433
434
435
436
if
(
OSIntNesting
> 0u) {
/* See if trying to delete from ISR */
437
return
(
OS_ERR_TASK_DEL_ISR
);
438
}
439
if
(prio ==
OS_TASK_IDLE_PRIO
) {
/* Not allowed to delete idle task */
440
return
(
OS_ERR_TASK_DEL_IDLE
);
441
}
442
#if OS_ARG_CHK_EN > 0u
443
if
(prio >=
OS_LOWEST_PRIO
) {
/* Task priority valid ? */
444
if
(prio !=
OS_PRIO_SELF
) {
445
return
(
OS_ERR_PRIO_INVALID
);
446
}
447
}
448
#endif
449
450
/*$PAGE*/
451
OS_ENTER_CRITICAL
();
452
if
(prio ==
OS_PRIO_SELF
) {
/* See if requesting to delete self */
453
prio =
OSTCBCur
->
OSTCBPrio
;
/* Set priority to delete to current */
454
}
455
ptcb =
OSTCBPrioTbl
[prio];
456
if
(ptcb == (
OS_TCB
*)0) {
/* Task to delete must exist */
457
OS_EXIT_CRITICAL
();
458
return
(
OS_ERR_TASK_NOT_EXIST
);
459
}
460
if
(ptcb ==
OS_TCB_RESERVED
) {
/* Must not be assigned to Mutex */
461
OS_EXIT_CRITICAL
();
462
return
(
OS_ERR_TASK_DEL
);
463
}
464
465
OSRdyTbl
[ptcb->
OSTCBY
] &= ~ptcb->
OSTCBBitX
;
466
if
(
OSRdyTbl
[ptcb->
OSTCBY
] == 0u) {
/* Make task not ready */
467
OSRdyGrp
&= ~ptcb->
OSTCBBitY
;
468
}
469
470
#if (OS_EVENT_EN)
471
if
(ptcb->
OSTCBEventPtr
!= (
OS_EVENT
*)0) {
472
OS_EventTaskRemove
(ptcb, ptcb->
OSTCBEventPtr
);
/* Remove this task from any event wait list */
473
}
474
#if (OS_EVENT_MULTI_EN > 0u)
475
if
(ptcb->
OSTCBEventMultiPtr
!= (
OS_EVENT
**)0) {
/* Remove this task from any events' wait lists*/
476
OS_EventTaskRemoveMulti
(ptcb, ptcb->
OSTCBEventMultiPtr
);
477
}
478
#endif
479
#endif
480
481
#if (OS_FLAG_EN > 0u) && (OS_MAX_FLAGS > 0u)
482
pnode = ptcb->
OSTCBFlagNode
;
483
if
(pnode != (
OS_FLAG_NODE
*)0) {
/* If task is waiting on event flag */
484
OS_FlagUnlink
(pnode);
/* Remove from wait list */
485
}
486
#endif
487
488
ptcb->
OSTCBDly
= 0u;
/* Prevent OSTimeTick() from updating */
489
ptcb->
OSTCBStat
=
OS_STAT_RDY
;
/* Prevent task from being resumed */
490
ptcb->
OSTCBStatPend
=
OS_STAT_PEND_OK
;
491
if
(
OSLockNesting
< 255u) {
/* Make sure we don't context switch */
492
OSLockNesting
++;
493
}
494
OS_EXIT_CRITICAL
();
/* Enabling INT. ignores next instruc. */
495
OS_Dummy
();
/* ... Dummy ensures that INTs will be */
496
OS_ENTER_CRITICAL
();
/* ... disabled HERE! */
497
if
(
OSLockNesting
> 0u) {
/* Remove context switch lock */
498
OSLockNesting
--;
499
}
500
OSTaskDelHook
(ptcb);
/* Call user defined hook */
501
OSTaskCtr
--;
/* One less task being managed */
502
OSTCBPrioTbl
[prio] = (
OS_TCB
*)0;
/* Clear old priority entry */
503
if
(ptcb->
OSTCBPrev
== (
OS_TCB
*)0) {
/* Remove from TCB chain */
504
ptcb->
OSTCBNext
->OSTCBPrev = (
OS_TCB
*)0;
505
OSTCBList
= ptcb->
OSTCBNext
;
506
}
else
{
507
ptcb->
OSTCBPrev
->OSTCBNext = ptcb->
OSTCBNext
;
508
ptcb->
OSTCBNext
->OSTCBPrev = ptcb->
OSTCBPrev
;
509
}
510
ptcb->
OSTCBNext
=
OSTCBFreeList
;
/* Return TCB to free TCB list */
511
OSTCBFreeList
= ptcb;
512
#if OS_TASK_NAME_EN > 0u
513
ptcb->
OSTCBTaskName
= (
INT8U
*)
"?"
;
514
#endif
515
OS_EXIT_CRITICAL
();
516
if
(
OSRunning
==
OS_TRUE
) {
517
OS_Sched
();
/* Find new highest priority task */
518
}
519
return
(
OS_ERR_NONE
);
520
}
521
#endif
522
/*$PAGE*/
523
/*
524
*********************************************************************************************************
525
* REQUEST THAT A TASK DELETE ITSELF
526
*
527
* Description: This function is used to:
528
* a) notify a task to delete itself.
529
* b) to see if a task requested that the current task delete itself.
530
* This function is a little tricky to understand. Basically, you have a task that needs
531
* to be deleted however, this task has resources that it has allocated (memory buffers,
532
* semaphores, mailboxes, queues etc.). The task cannot be deleted otherwise these
533
* resources would not be freed. The requesting task calls OSTaskDelReq() to indicate that
534
* the task needs to be deleted. Deleting of the task is however, deferred to the task to
535
* be deleted. For example, suppose that task #10 needs to be deleted. The requesting task
536
* example, task #5, would call OSTaskDelReq(10). When task #10 gets to execute, it calls
537
* this function by specifying OS_PRIO_SELF and monitors the returned value. If the return
538
* value is OS_ERR_TASK_DEL_REQ, another task requested a task delete. Task #10 would look like
539
* this:
540
*
541
* void Task(void *p_arg)
542
* {
543
* .
544
* .
545
* while (1) {
546
* OSTimeDly(1);
547
* if (OSTaskDelReq(OS_PRIO_SELF) == OS_ERR_TASK_DEL_REQ) {
548
* Release any owned resources;
549
* De-allocate any dynamic memory;
550
* OSTaskDel(OS_PRIO_SELF);
551
* }
552
* }
553
* }
554
*
555
* Arguments : prio is the priority of the task to request the delete from
556
*
557
* Returns : OS_ERR_NONE if the task exist and the request has been registered
558
* OS_ERR_TASK_NOT_EXIST if the task has been deleted. This allows the caller to know whether
559
* the request has been executed.
560
* OS_ERR_TASK_DEL if the task is assigned to a Mutex.
561
* OS_ERR_TASK_DEL_IDLE if you requested to delete uC/OS-II's idle task
562
* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed
563
* (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
564
* OS_ERR_TASK_DEL_REQ if a task (possibly another task) requested that the running task be
565
* deleted.
566
*********************************************************************************************************
567
*/
568
/*$PAGE*/
569
#if OS_TASK_DEL_EN > 0u
570
INT8U
OSTaskDelReq
(
INT8U
prio)
571
{
572
INT8U
stat;
573
OS_TCB
*ptcb;
574
#if OS_CRITICAL_METHOD == 3u
/* Allocate storage for CPU status register */
575
OS_CPU_SR
cpu_sr = 0u;
576
#endif
577
578
579
580
if
(prio ==
OS_TASK_IDLE_PRIO
) {
/* Not allowed to delete idle task */
581
return
(
OS_ERR_TASK_DEL_IDLE
);
582
}
583
#if OS_ARG_CHK_EN > 0u
584
if
(prio >=
OS_LOWEST_PRIO
) {
/* Task priority valid ? */
585
if
(prio !=
OS_PRIO_SELF
) {
586
return
(
OS_ERR_PRIO_INVALID
);
587
}
588
}
589
#endif
590
if
(prio ==
OS_PRIO_SELF
) {
/* See if a task is requesting to ... */
591
OS_ENTER_CRITICAL
();
/* ... this task to delete itself */
592
stat =
OSTCBCur
->
OSTCBDelReq
;
/* Return request status to caller */
593
OS_EXIT_CRITICAL
();
594
return
(stat);
595
}
596
OS_ENTER_CRITICAL
();
597
ptcb =
OSTCBPrioTbl
[prio];
598
if
(ptcb == (
OS_TCB
*)0) {
/* Task to delete must exist */
599
OS_EXIT_CRITICAL
();
600
return
(
OS_ERR_TASK_NOT_EXIST
);
/* Task must already be deleted */
601
}
602
if
(ptcb ==
OS_TCB_RESERVED
) {
/* Must NOT be assigned to a Mutex */
603
OS_EXIT_CRITICAL
();
604
return
(
OS_ERR_TASK_DEL
);
605
}
606
ptcb->
OSTCBDelReq
=
OS_ERR_TASK_DEL_REQ
;
/* Set flag indicating task to be DEL. */
607
OS_EXIT_CRITICAL
();
608
return
(
OS_ERR_NONE
);
609
}
610
#endif
611
/*$PAGE*/
612
/*
613
*********************************************************************************************************
614
* GET THE NAME OF A TASK
615
*
616
* Description: This function is called to obtain the name of a task.
617
*
618
* Arguments : prio is the priority of the task that you want to obtain the name from.
619
*
620
* pname is a pointer to a pointer to an ASCII string that will receive the name of the task.
621
*
622
* perr is a pointer to an error code that can contain one of the following values:
623
*
624
* OS_ERR_NONE if the requested task is resumed
625
* OS_ERR_TASK_NOT_EXIST if the task has not been created or is assigned to a Mutex
626
* OS_ERR_PRIO_INVALID if you specified an invalid priority:
627
* A higher value than the idle task or not OS_PRIO_SELF.
628
* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname'
629
* OS_ERR_NAME_GET_ISR You called this function from an ISR
630
*
631
*
632
* Returns : The length of the string or 0 if the task does not exist.
633
*********************************************************************************************************
634
*/
635
636
#if OS_TASK_NAME_EN > 0u
637
INT8U
OSTaskNameGet
(
INT8U
prio,
638
INT8U
**pname,
639
INT8U
*perr)
640
{
641
OS_TCB
*ptcb;
642
INT8U
len;
643
#if OS_CRITICAL_METHOD == 3u
/* Allocate storage for CPU status register */
644
OS_CPU_SR
cpu_sr = 0u;
645
#endif
646
647
648
649
#if OS_ARG_CHK_EN > 0u
650
if
(perr == (
INT8U
*)0) {
/* Validate 'perr' */
651
return
(0u);
652
}
653
if
(prio >
OS_LOWEST_PRIO
) {
/* Task priority valid ? */
654
if
(prio !=
OS_PRIO_SELF
) {
655
*perr =
OS_ERR_PRIO_INVALID
;
/* No */
656
return
(0u);
657
}
658
}
659
if
(pname == (
INT8U
**)0) {
/* Is 'pname' a NULL pointer? */
660
*perr =
OS_ERR_PNAME_NULL
;
/* Yes */
661
return
(0u);
662
}
663
#endif
664
if
(
OSIntNesting
> 0u) {
/* See if trying to call from an ISR */
665
*perr =
OS_ERR_NAME_GET_ISR
;
666
return
(0u);
667
}
668
OS_ENTER_CRITICAL
();
669
if
(prio ==
OS_PRIO_SELF
) {
/* See if caller desires it's own name */
670
prio =
OSTCBCur
->
OSTCBPrio
;
671
}
672
ptcb =
OSTCBPrioTbl
[prio];
673
if
(ptcb == (
OS_TCB
*)0) {
/* Does task exist? */
674
OS_EXIT_CRITICAL
();
/* No */
675
*perr =
OS_ERR_TASK_NOT_EXIST
;
676
return
(0u);
677
}
678
if
(ptcb ==
OS_TCB_RESERVED
) {
/* Task assigned to a Mutex? */
679
OS_EXIT_CRITICAL
();
/* Yes */
680
*perr =
OS_ERR_TASK_NOT_EXIST
;
681
return
(0u);
682
}
683
*pname = ptcb->
OSTCBTaskName
;
684
len =
OS_StrLen
(*pname);
685
OS_EXIT_CRITICAL
();
686
*perr =
OS_ERR_NONE
;
687
return
(len);
688
}
689
#endif
690
691
/*$PAGE*/
692
/*
693
*********************************************************************************************************
694
* ASSIGN A NAME TO A TASK
695
*
696
* Description: This function is used to set the name of a task.
697
*
698
* Arguments : prio is the priority of the task that you want the assign a name to.
699
*
700
* pname is a pointer to an ASCII string that contains the name of the task.
701
*
702
* perr is a pointer to an error code that can contain one of the following values:
703
*
704
* OS_ERR_NONE if the requested task is resumed
705
* OS_ERR_TASK_NOT_EXIST if the task has not been created or is assigned to a Mutex
706
* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname'
707
* OS_ERR_PRIO_INVALID if you specified an invalid priority:
708
* A higher value than the idle task or not OS_PRIO_SELF.
709
* OS_ERR_NAME_SET_ISR if you called this function from an ISR
710
*
711
* Returns : None
712
*********************************************************************************************************
713
*/
714
#if OS_TASK_NAME_EN > 0u
715
void
OSTaskNameSet
(
INT8U
prio,
716
INT8U
*pname,
717
INT8U
*perr)
718
{
719
OS_TCB
*ptcb;
720
#if OS_CRITICAL_METHOD == 3u
/* Allocate storage for CPU status register */
721
OS_CPU_SR
cpu_sr = 0u;
722
#endif
723
724
725
726
#if OS_ARG_CHK_EN > 0u
727
if
(perr == (
INT8U
*)0) {
/* Validate 'perr' */
728
return
;
729
}
730
if
(prio >
OS_LOWEST_PRIO
) {
/* Task priority valid ? */
731
if
(prio !=
OS_PRIO_SELF
) {
732
*perr =
OS_ERR_PRIO_INVALID
;
/* No */
733
return
;
734
}
735
}
736
if
(pname == (
INT8U
*)0) {
/* Is 'pname' a NULL pointer? */
737
*perr =
OS_ERR_PNAME_NULL
;
/* Yes */
738
return
;
739
}
740
#endif
741
if
(
OSIntNesting
> 0u) {
/* See if trying to call from an ISR */
742
*perr =
OS_ERR_NAME_SET_ISR
;
743
return
;
744
}
745
OS_ENTER_CRITICAL
();
746
if
(prio ==
OS_PRIO_SELF
) {
/* See if caller desires to set it's own name */
747
prio =
OSTCBCur
->
OSTCBPrio
;
748
}
749
ptcb =
OSTCBPrioTbl
[prio];
750
if
(ptcb == (
OS_TCB
*)0) {
/* Does task exist? */
751
OS_EXIT_CRITICAL
();
/* No */
752
*perr =
OS_ERR_TASK_NOT_EXIST
;
753
return
;
754
}
755
if
(ptcb ==
OS_TCB_RESERVED
) {
/* Task assigned to a Mutex? */
756
OS_EXIT_CRITICAL
();
/* Yes */
757
*perr =
OS_ERR_TASK_NOT_EXIST
;
758
return
;
759
}
760
ptcb->
OSTCBTaskName
= pname;
761
OS_EXIT_CRITICAL
();
762
*perr =
OS_ERR_NONE
;
763
}
764
#endif
765
766
/*$PAGE*/
767
/*
768
*********************************************************************************************************
769
* RESUME A SUSPENDED TASK
770
*
771
* Description: This function is called to resume a previously suspended task. This is the only call that
772
* will remove an explicit task suspension.
773
*
774
* Arguments : prio is the priority of the task to resume.
775
*
776
* Returns : OS_ERR_NONE if the requested task is resumed
777
* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed
778
* (i.e. >= OS_LOWEST_PRIO)
779
* OS_ERR_TASK_RESUME_PRIO if the task to resume does not exist
780
* OS_ERR_TASK_NOT_EXIST if the task is assigned to a Mutex PIP
781
* OS_ERR_TASK_NOT_SUSPENDED if the task to resume has not been suspended
782
*********************************************************************************************************
783
*/
784
785
#if OS_TASK_SUSPEND_EN > 0u
786
INT8U
OSTaskResume
(
INT8U
prio)
787
{
788
OS_TCB
*ptcb;
789
#if OS_CRITICAL_METHOD == 3u
/* Storage for CPU status register */
790
OS_CPU_SR
cpu_sr = 0u;
791
#endif
792
793
794
795
#if OS_ARG_CHK_EN > 0u
796
if
(prio >=
OS_LOWEST_PRIO
) {
/* Make sure task priority is valid */
797
return
(
OS_ERR_PRIO_INVALID
);
798
}
799
#endif
800
OS_ENTER_CRITICAL
();
801
ptcb =
OSTCBPrioTbl
[prio];
802
if
(ptcb == (
OS_TCB
*)0) {
/* Task to suspend must exist */
803
OS_EXIT_CRITICAL
();
804
return
(
OS_ERR_TASK_RESUME_PRIO
);
805
}
806
if
(ptcb ==
OS_TCB_RESERVED
) {
/* See if assigned to Mutex */
807
OS_EXIT_CRITICAL
();
808
return
(
OS_ERR_TASK_NOT_EXIST
);
809
}
810
if
((ptcb->
OSTCBStat
&
OS_STAT_SUSPEND
) !=
OS_STAT_RDY
) {
/* Task must be suspended */
811
ptcb->
OSTCBStat
&= ~(
INT8U
)
OS_STAT_SUSPEND
;
/* Remove suspension */
812
if
(ptcb->
OSTCBStat
==
OS_STAT_RDY
) {
/* See if task is now ready */
813
if
(ptcb->
OSTCBDly
== 0u) {
814
OSRdyGrp
|= ptcb->
OSTCBBitY
;
/* Yes, Make task ready to run */
815
OSRdyTbl
[ptcb->
OSTCBY
] |= ptcb->
OSTCBBitX
;
816
OS_EXIT_CRITICAL
();
817
if
(
OSRunning
==
OS_TRUE
) {
818
OS_Sched
();
/* Find new highest priority task */
819
}
820
}
else
{
821
OS_EXIT_CRITICAL
();
822
}
823
}
else
{
/* Must be pending on event */
824
OS_EXIT_CRITICAL
();
825
}
826
return
(
OS_ERR_NONE
);
827
}
828
OS_EXIT_CRITICAL
();
829
return
(
OS_ERR_TASK_NOT_SUSPENDED
);
830
}
831
#endif
832
/*$PAGE*/
833
/*
834
*********************************************************************************************************
835
* STACK CHECKING
836
*
837
* Description: This function is called to check the amount of free memory left on the specified task's
838
* stack.
839
*
840
* Arguments : prio is the task priority
841
*
842
* p_stk_data is a pointer to a data structure of type OS_STK_DATA.
843
*
844
* Returns : OS_ERR_NONE upon success
845
* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed
846
* (i.e. > OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
847
* OS_ERR_TASK_NOT_EXIST if the desired task has not been created or is assigned to a Mutex PIP
848
* OS_ERR_TASK_OPT if you did NOT specified OS_TASK_OPT_STK_CHK when the task was created
849
* OS_ERR_PDATA_NULL if 'p_stk_data' is a NULL pointer
850
*********************************************************************************************************
851
*/
852
#if (OS_TASK_STAT_STK_CHK_EN > 0u) && (OS_TASK_CREATE_EXT_EN > 0u)
853
INT8U
OSTaskStkChk
(
INT8U
prio,
854
OS_STK_DATA
*p_stk_data)
855
{
856
OS_TCB
*ptcb;
857
OS_STK
*pchk;
858
INT32U
nfree;
859
INT32U
size;
860
#if OS_CRITICAL_METHOD == 3u
/* Allocate storage for CPU status register */
861
OS_CPU_SR
cpu_sr = 0u;
862
#endif
863
864
865
866
#if OS_ARG_CHK_EN > 0u
867
if
(prio >
OS_LOWEST_PRIO
) {
/* Make sure task priority is valid */
868
if
(prio !=
OS_PRIO_SELF
) {
869
return
(
OS_ERR_PRIO_INVALID
);
870
}
871
}
872
if
(p_stk_data == (
OS_STK_DATA
*)0) {
/* Validate 'p_stk_data' */
873
return
(
OS_ERR_PDATA_NULL
);
874
}
875
#endif
876
p_stk_data->
OSFree
= 0u;
/* Assume failure, set to 0 size */
877
p_stk_data->
OSUsed
= 0u;
878
OS_ENTER_CRITICAL
();
879
if
(prio ==
OS_PRIO_SELF
) {
/* See if check for SELF */
880
prio =
OSTCBCur
->
OSTCBPrio
;
881
}
882
ptcb =
OSTCBPrioTbl
[prio];
883
if
(ptcb == (
OS_TCB
*)0) {
/* Make sure task exist */
884
OS_EXIT_CRITICAL
();
885
return
(
OS_ERR_TASK_NOT_EXIST
);
886
}
887
if
(ptcb ==
OS_TCB_RESERVED
) {
888
OS_EXIT_CRITICAL
();
889
return
(
OS_ERR_TASK_NOT_EXIST
);
890
}
891
if
((ptcb->
OSTCBOpt
&
OS_TASK_OPT_STK_CHK
) == 0u) {
/* Make sure stack checking option is set */
892
OS_EXIT_CRITICAL
();
893
return
(
OS_ERR_TASK_OPT
);
894
}
895
nfree = 0u;
896
size = ptcb->
OSTCBStkSize
;
897
pchk = ptcb->
OSTCBStkBottom
;
898
OS_EXIT_CRITICAL
();
899
#if OS_STK_GROWTH == 1u
900
while
(*pchk++ == (
OS_STK
)0) {
/* Compute the number of zero entries on the stk */
901
nfree++;
902
}
903
#else
904
while
(*pchk-- == (
OS_STK
)0) {
905
nfree++;
906
}
907
#endif
908
p_stk_data->
OSFree
= nfree *
sizeof
(
OS_STK
);
/* Compute number of free bytes on the stack */
909
p_stk_data->
OSUsed
= (size - nfree) *
sizeof
(
OS_STK
);
/* Compute number of bytes used on the stack */
910
return
(
OS_ERR_NONE
);
911
}
912
#endif
913
/*$PAGE*/
914
/*
915
*********************************************************************************************************
916
* SUSPEND A TASK
917
*
918
* Description: This function is called to suspend a task. The task can be the calling task if the
919
* priority passed to OSTaskSuspend() is the priority of the calling task or OS_PRIO_SELF.
920
*
921
* Arguments : prio is the priority of the task to suspend. If you specify OS_PRIO_SELF, the
922
* calling task will suspend itself and rescheduling will occur.
923
*
924
* Returns : OS_ERR_NONE if the requested task is suspended
925
* OS_ERR_TASK_SUSPEND_IDLE if you attempted to suspend the idle task which is not allowed.
926
* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed
927
* (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
928
* OS_ERR_TASK_SUSPEND_PRIO if the task to suspend does not exist
929
* OS_ERR_TASK_NOT_EXITS if the task is assigned to a Mutex PIP
930
*
931
* Note : You should use this function with great care. If you suspend a task that is waiting for
932
* an event (i.e. a message, a semaphore, a queue ...) you will prevent this task from
933
* running when the event arrives.
934
*********************************************************************************************************
935
*/
936
937
#if OS_TASK_SUSPEND_EN > 0u
938
INT8U
OSTaskSuspend
(
INT8U
prio)
939
{
940
BOOLEAN
self
;
941
OS_TCB
*ptcb;
942
INT8U
y;
943
#if OS_CRITICAL_METHOD == 3u
/* Allocate storage for CPU status register */
944
OS_CPU_SR
cpu_sr = 0u;
945
#endif
946
947
948
949
#if OS_ARG_CHK_EN > 0u
950
if
(prio ==
OS_TASK_IDLE_PRIO
) {
/* Not allowed to suspend idle task */
951
return
(
OS_ERR_TASK_SUSPEND_IDLE
);
952
}
953
if
(prio >=
OS_LOWEST_PRIO
) {
/* Task priority valid ? */
954
if
(prio !=
OS_PRIO_SELF
) {
955
return
(
OS_ERR_PRIO_INVALID
);
956
}
957
}
958
#endif
959
OS_ENTER_CRITICAL
();
960
if
(prio ==
OS_PRIO_SELF
) {
/* See if suspend SELF */
961
prio =
OSTCBCur
->
OSTCBPrio
;
962
self
=
OS_TRUE
;
963
}
else
if
(prio ==
OSTCBCur
->
OSTCBPrio
) {
/* See if suspending self */
964
self
=
OS_TRUE
;
965
}
else
{
966
self
=
OS_FALSE
;
/* No suspending another task */
967
}
968
ptcb =
OSTCBPrioTbl
[prio];
969
if
(ptcb == (
OS_TCB
*)0) {
/* Task to suspend must exist */
970
OS_EXIT_CRITICAL
();
971
return
(
OS_ERR_TASK_SUSPEND_PRIO
);
972
}
973
if
(ptcb ==
OS_TCB_RESERVED
) {
/* See if assigned to Mutex */
974
OS_EXIT_CRITICAL
();
975
return
(
OS_ERR_TASK_NOT_EXIST
);
976
}
977
y = ptcb->
OSTCBY
;
978
OSRdyTbl
[y] &= ~ptcb->
OSTCBBitX
;
/* Make task not ready */
979
if
(
OSRdyTbl
[y] == 0u) {
980
OSRdyGrp
&= ~ptcb->
OSTCBBitY
;
981
}
982
ptcb->
OSTCBStat
|=
OS_STAT_SUSPEND
;
/* Status of task is 'SUSPENDED' */
983
OS_EXIT_CRITICAL
();
984
if
(
self
==
OS_TRUE
) {
/* Context switch only if SELF */
985
OS_Sched
();
/* Find new highest priority task */
986
}
987
return
(
OS_ERR_NONE
);
988
}
989
#endif
990
/*$PAGE*/
991
/*
992
*********************************************************************************************************
993
* QUERY A TASK
994
*
995
* Description: This function is called to obtain a copy of the desired task's TCB.
996
*
997
* Arguments : prio is the priority of the task to obtain information from.
998
*
999
* p_task_data is a pointer to where the desired task's OS_TCB will be stored.
1000
*
1001
* Returns : OS_ERR_NONE if the requested task is suspended
1002
* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed
1003
* (i.e. > OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
1004
* OS_ERR_PRIO if the desired task has not been created
1005
* OS_ERR_TASK_NOT_EXIST if the task is assigned to a Mutex PIP
1006
* OS_ERR_PDATA_NULL if 'p_task_data' is a NULL pointer
1007
*********************************************************************************************************
1008
*/
1009
1010
#if OS_TASK_QUERY_EN > 0u
1011
INT8U
OSTaskQuery
(
INT8U
prio,
1012
OS_TCB
*p_task_data)
1013
{
1014
OS_TCB
*ptcb;
1015
#if OS_CRITICAL_METHOD == 3u
/* Allocate storage for CPU status register */
1016
OS_CPU_SR
cpu_sr = 0u;
1017
#endif
1018
1019
1020
1021
#if OS_ARG_CHK_EN > 0u
1022
if
(prio >
OS_LOWEST_PRIO
) {
/* Task priority valid ? */
1023
if
(prio !=
OS_PRIO_SELF
) {
1024
return
(
OS_ERR_PRIO_INVALID
);
1025
}
1026
}
1027
if
(p_task_data == (
OS_TCB
*)0) {
/* Validate 'p_task_data' */
1028
return
(
OS_ERR_PDATA_NULL
);
1029
}
1030
#endif
1031
OS_ENTER_CRITICAL
();
1032
if
(prio ==
OS_PRIO_SELF
) {
/* See if suspend SELF */
1033
prio =
OSTCBCur
->
OSTCBPrio
;
1034
}
1035
ptcb =
OSTCBPrioTbl
[prio];
1036
if
(ptcb == (
OS_TCB
*)0) {
/* Task to query must exist */
1037
OS_EXIT_CRITICAL
();
1038
return
(
OS_ERR_PRIO
);
1039
}
1040
if
(ptcb ==
OS_TCB_RESERVED
) {
/* Task to query must not be assigned to a Mutex */
1041
OS_EXIT_CRITICAL
();
1042
return
(
OS_ERR_TASK_NOT_EXIST
);
1043
}
1044
/* Copy TCB into user storage area */
1045
OS_MemCopy
((
INT8U
*)p_task_data, (
INT8U
*)ptcb,
sizeof
(
OS_TCB
));
1046
OS_EXIT_CRITICAL
();
1047
return
(
OS_ERR_NONE
);
1048
}
1049
#endif
1050
/*$PAGE*/
1051
/*
1052
*********************************************************************************************************
1053
* GET THE CURRENT VALUE OF A TASK REGISTER
1054
*
1055
* Description: This function is called to obtain the current value of a task register. Task registers
1056
* are application specific and can be used to store task specific values such as 'error
1057
* numbers' (i.e. errno), statistics, etc. Each task register can hold a 32-bit value.
1058
*
1059
* Arguments : prio is the priority of the task you want to get the task register from. If you
1060
* specify OS_PRIO_SELF then the task register of the current task will be obtained.
1061
*
1062
* id is the 'id' of the desired task register. Note that the 'id' must be less
1063
* than OS_TASK_REG_TBL_SIZE
1064
*
1065
* perr is a pointer to a variable that will hold an error code related to this call.
1066
*
1067
* OS_ERR_NONE if the call was successful
1068
* OS_ERR_PRIO_INVALID if you specified an invalid priority
1069
* OS_ERR_ID_INVALID if the 'id' is not between 0 and OS_TASK_REG_TBL_SIZE-1
1070
*
1071
* Returns : The current value of the task's register or 0 if an error is detected.
1072
*
1073
* Note(s) : The maximum number of task variables is 254
1074
*********************************************************************************************************
1075
*/
1076
1077
#if OS_TASK_REG_TBL_SIZE > 0u
1078
INT32U
OSTaskRegGet
(
INT8U
prio,
1079
INT8U
id
,
1080
INT8U
*perr)
1081
{
1082
#if OS_CRITICAL_METHOD == 3u
/* Allocate storage for CPU status register */
1083
OS_CPU_SR
cpu_sr = 0u;
1084
#endif
1085
INT32U
value;
1086
OS_TCB
*ptcb;
1087
1088
1089
#if OS_ARG_CHK_EN > 0u
1090
if
(prio >=
OS_LOWEST_PRIO
) {
1091
if
(prio !=
OS_PRIO_SELF
) {
1092
*perr =
OS_ERR_PRIO_INVALID
;
1093
return
(0u);
1094
}
1095
}
1096
if
(
id
>=
OS_TASK_REG_TBL_SIZE
) {
1097
*perr =
OS_ERR_ID_INVALID
;
1098
return
(0u);
1099
}
1100
#endif
1101
OS_ENTER_CRITICAL
();
1102
if
(prio ==
OS_PRIO_SELF
) {
/* See if need to get register from current task */
1103
ptcb =
OSTCBCur
;
1104
}
else
{
1105
ptcb =
OSTCBPrioTbl
[prio];
1106
}
1107
value = ptcb->
OSTCBRegTbl
[id];
1108
OS_EXIT_CRITICAL
();
1109
*perr =
OS_ERR_NONE
;
1110
return
(value);
1111
}
1112
#endif
1113
1114
/*$PAGE*/
1115
/*
1116
*********************************************************************************************************
1117
* SET THE CURRENT VALUE OF A TASK VARIABLE
1118
*
1119
* Description: This function is called to change the current value of a task register. Task registers
1120
* are application specific and can be used to store task specific values such as 'error
1121
* numbers' (i.e. errno), statistics, etc. Each task register can hold a 32-bit value.
1122
*
1123
* Arguments : prio is the priority of the task you want to set the task register for. If you
1124
* specify OS_PRIO_SELF then the task register of the current task will be obtained.
1125
*
1126
* var_id is the 'id' of the desired task register. Note that the 'id' must be less
1127
* than OS_TASK_REG_TBL_SIZE
1128
*
1129
* value is the desired value for the task register.
1130
*
1131
* perr is a pointer to a variable that will hold an error code related to this call.
1132
*
1133
* OS_ERR_NONE if the call was successful
1134
* OS_ERR_PRIO_INVALID if you specified an invalid priority
1135
* OS_ERR_ID_INVALID if the 'id' is not between 0 and OS_TASK_REG_TBL_SIZE-1
1136
*
1137
* Returns : The current value of the task's variable or 0 if an error is detected.
1138
*
1139
* Note(s) : The maximum number of task variables is 254
1140
*********************************************************************************************************
1141
*/
1142
1143
#if OS_TASK_REG_TBL_SIZE > 0u
1144
void
OSTaskRegSet
(
INT8U
prio,
1145
INT8U
id
,
1146
INT32U
value,
1147
INT8U
*perr)
1148
{
1149
#if OS_CRITICAL_METHOD == 3u
/* Allocate storage for CPU status register */
1150
OS_CPU_SR
cpu_sr = 0u;
1151
#endif
1152
OS_TCB
*ptcb;
1153
1154
1155
#if OS_ARG_CHK_EN > 0u
1156
if
(prio >=
OS_LOWEST_PRIO
) {
1157
if
(prio !=
OS_PRIO_SELF
) {
1158
*perr =
OS_ERR_PRIO_INVALID
;
1159
return
;
1160
}
1161
}
1162
if
(
id
>=
OS_TASK_REG_TBL_SIZE
) {
1163
*perr =
OS_ERR_ID_INVALID
;
1164
return
;
1165
}
1166
#endif
1167
OS_ENTER_CRITICAL
();
1168
if
(prio ==
OS_PRIO_SELF
) {
/* See if need to get register from current task */
1169
ptcb =
OSTCBCur
;
1170
}
else
{
1171
ptcb =
OSTCBPrioTbl
[prio];
1172
}
1173
ptcb->
OSTCBRegTbl
[id] = value;
1174
OS_EXIT_CRITICAL
();
1175
*perr =
OS_ERR_NONE
;
1176
}
1177
#endif
1178
1179
/*$PAGE*/
1180
/*
1181
*********************************************************************************************************
1182
* CATCH ACCIDENTAL TASK RETURN
1183
*
1184
* Description: This function is called if a task accidentally returns without deleting itself. In other
1185
* words, a task should either be an infinite loop or delete itself if it's done.
1186
*
1187
* Arguments : none
1188
*
1189
* Returns : none
1190
*
1191
* Note(s) : This function is INTERNAL to uC/OS-II and your application should not call it.
1192
*********************************************************************************************************
1193
*/
1194
1195
void
OS_TaskReturn
(
void
)
1196
{
1197
OSTaskReturnHook
(
OSTCBCur
);
/* Call hook to let user decide on what to do */
1198
1199
#if OS_TASK_DEL_EN > 0u
1200
(void)
OSTaskDel
(
OS_PRIO_SELF
);
/* Delete task if it accidentally returns! */
1201
#else
1202
for
(;;) {
1203
OSTimeDly
(
OS_TICKS_PER_SEC
);
1204
}
1205
#endif
1206
}
1207
1208
/*$PAGE*/
1209
/*
1210
*********************************************************************************************************
1211
* CLEAR TASK STACK
1212
*
1213
* Description: This function is used to clear the stack of a task (i.e. write all zeros)
1214
*
1215
* Arguments : pbos is a pointer to the task's bottom of stack. If the configuration constant
1216
* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high
1217
* memory to low memory). 'pbos' will thus point to the lowest (valid) memory
1218
* location of the stack. If OS_STK_GROWTH is set to 0, 'pbos' will point to the
1219
* highest memory location of the stack and the stack will grow with increasing
1220
* memory locations. 'pbos' MUST point to a valid 'free' data item.
1221
*
1222
* size is the number of 'stack elements' to clear.
1223
*
1224
* opt contains additional information (or options) about the behavior of the task. The
1225
* LOWER 8-bits are reserved by uC/OS-II while the upper 8 bits can be application
1226
* specific. See OS_TASK_OPT_??? in uCOS-II.H.
1227
*
1228
* Returns : none
1229
*********************************************************************************************************
1230
*/
1231
#if (OS_TASK_STAT_STK_CHK_EN > 0u) && (OS_TASK_CREATE_EXT_EN > 0u)
1232
void
OS_TaskStkClr
(
OS_STK
*pbos,
1233
INT32U
size,
1234
INT16U
opt)
1235
{
1236
if
((opt &
OS_TASK_OPT_STK_CHK
) != 0x0000u) {
/* See if stack checking has been enabled */
1237
if
((opt &
OS_TASK_OPT_STK_CLR
) != 0x0000u) {
/* See if stack needs to be cleared */
1238
#if OS_STK_GROWTH == 1u
1239
while
(size > 0u) {
/* Stack grows from HIGH to LOW memory */
1240
size--;
1241
*pbos++ = (
OS_STK
)0;
/* Clear from bottom of stack and up! */
1242
}
1243
#else
1244
while
(size > 0u) {
/* Stack grows from LOW to HIGH memory */
1245
size--;
1246
*pbos-- = (
OS_STK
)0;
/* Clear from bottom of stack and down */
1247
}
1248
#endif
1249
}
1250
}
1251
}
1252
1253
#endif
UCOS_TI_LM3S_Keil
uCOS-II
Source
os_task.c
生成于 2013年 十月 1日 星期二 12:18:40 , 为 UCOS_TI_LM3S_Keil使用
1.8.4