• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
3  *
4  * UniProton is licensed under Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *          http://license.coscl.org.cn/MulanPSL2
8  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11  * See the Mulan PSL v2 for more details.
12  * Create: 2009-12-22
13  * Description: 任务模块的对外头文件。
14  */
15 #ifndef PRT_TASK_H
16 #define PRT_TASK_H
17 
18 #include "prt_buildef.h"
19 #include "prt_module.h"
20 #include "prt_errno.h"
21 #if (OS_HARDWARE_PLATFORM == OS_CORTEX_M4)
22 #include "./hw/armv7-m/prt_task.h"
23 #endif
24 
25 #ifdef __cplusplus
26 #if __cplusplus
27 extern "C" {
28 #endif /* __cpluscplus */
29 #endif /* __cpluscplus */
30 
31 /*
32  * 任务名的最大长度。
33  *
34  * 任务名的最大长度,包括结尾符'\0'。
35  */
36 #define OS_TSK_NAME_LEN 16
37 
38 /*
39  * U32类型的PID中,TCB Index占用的比特数
40  */
41 #define OS_TSK_TCB_INDEX_BITS ((4 - OS_TSK_CORE_BYTES_IN_PID) * 8)
42 
43 /*
44  * 从线程PID获取核内线程handle号
45  */
46 #define GET_HANDLE(pid) ((pid) & ((1U << OS_TSK_TCB_INDEX_BITS) - 1))
47 
48 /*
49  * 硬中断核内线程handle号
50  */
51 #define OS_HWI_HANDLE ((1U << OS_TSK_TCB_INDEX_BITS) - 1)
52 
53 /*
54  * 从线程PID获取核号
55  */
56 #define GET_COREID(pid) ((U8)((pid) >> OS_TSK_TCB_INDEX_BITS))
57 
58 /*
59  * 将coreid与handle组成PID,  coreid:[0, OS_MAX_CORE_NUM); handle:[0, 255]
60  */
61 #define COMPOSE_PID(coreid, handle) \
62     ((((U32)(coreid)) << OS_TSK_TCB_INDEX_BITS) + ((U8)(handle))) /* 将(coreid)与(handle)组成PID,UIPC不使用该接口 */
63 
64 /*
65  * 支持的优先级(0~31),OS系统IDLE线程使用最低优先级(31),用户不能使用。
66  * 可用的任务优先级宏定义。
67  *
68  */
69 #define OS_TSK_PRIORITY_00 0
70 
71 /*
72  * 可用的任务优先级宏定义。
73  *
74  */
75 #define OS_TSK_PRIORITY_01 1
76 
77 /*
78  * 可用的任务优先级宏定义。
79  *
80  */
81 #define OS_TSK_PRIORITY_02 2
82 
83 /*
84  * 可用的任务优先级宏定义。
85  *
86  */
87 #define OS_TSK_PRIORITY_03 3
88 
89 /*
90  * 可用的任务优先级宏定义。
91  *
92  */
93 #define OS_TSK_PRIORITY_04 4
94 
95 /*
96  * 可用的任务优先级宏定义。
97  *
98  */
99 #define OS_TSK_PRIORITY_05 5
100 
101 /*
102  * 可用的任务优先级宏定义。
103  *
104  */
105 #define OS_TSK_PRIORITY_06 6
106 
107 /*
108  * 可用的任务优先级宏定义。
109  *
110  */
111 #define OS_TSK_PRIORITY_07 7
112 
113 /*
114  * 可用的任务优先级宏定义。
115  *
116  */
117 #define OS_TSK_PRIORITY_08 8
118 
119 /*
120  * 可用的任务优先级宏定义。
121  *
122  */
123 #define OS_TSK_PRIORITY_09 9
124 
125 /*
126  * 可用的任务优先级宏定义。
127  *
128  */
129 #define OS_TSK_PRIORITY_10 10
130 
131 /*
132  * 可用的任务优先级宏定义。
133  *
134  */
135 #define OS_TSK_PRIORITY_11 11
136 
137 /*
138  * 可用的任务优先级宏定义。
139  *
140  */
141 #define OS_TSK_PRIORITY_12 12
142 
143 /*
144  * 可用的任务优先级宏定义。
145  *
146  */
147 #define OS_TSK_PRIORITY_13 13
148 
149 /*
150  * 可用的任务优先级宏定义。
151  *
152  */
153 #define OS_TSK_PRIORITY_14 14
154 
155 /*
156  * 可用的任务优先级宏定义。
157  *
158  */
159 #define OS_TSK_PRIORITY_15 15
160 
161 /*
162  * 可用的任务优先级宏定义。
163  *
164  */
165 #define OS_TSK_PRIORITY_16 16
166 
167 /*
168  * 可用的任务优先级宏定义。
169  *
170  */
171 #define OS_TSK_PRIORITY_17 17
172 
173 /*
174  * 可用的任务优先级宏定义。
175  *
176  */
177 #define OS_TSK_PRIORITY_18 18
178 
179 /*
180  * 可用的任务优先级宏定义。
181  *
182  */
183 #define OS_TSK_PRIORITY_19 19
184 
185 /*
186  * 可用的任务优先级宏定义。
187  *
188  */
189 #define OS_TSK_PRIORITY_20 20
190 
191 /*
192  * 可用的任务优先级宏定义。
193  *
194  */
195 #define OS_TSK_PRIORITY_21 21
196 
197 /*
198  * 可用的任务优先级宏定义。
199  *
200  */
201 #define OS_TSK_PRIORITY_22 22
202 
203 /*
204  * 可用的任务优先级宏定义。
205  *
206  */
207 #define OS_TSK_PRIORITY_23 23
208 
209 /*
210  * 可用的任务优先级宏定义。
211  *
212  */
213 #define OS_TSK_PRIORITY_24 24
214 
215 /*
216  * 可用的任务优先级宏定义。
217  *
218  */
219 #define OS_TSK_PRIORITY_25 25
220 
221 /*
222  * 可用的任务优先级宏定义。
223  *
224  */
225 #define OS_TSK_PRIORITY_26 26
226 
227 /*
228  * 可用的任务优先级宏定义。
229  *
230  */
231 #define OS_TSK_PRIORITY_27 27
232 
233 /*
234  * 可用的任务优先级宏定义。
235  *
236  */
237 #define OS_TSK_PRIORITY_28 28
238 
239 /*
240  * 可用的任务优先级宏定义。
241  *
242  */
243 #define OS_TSK_PRIORITY_29 29
244 
245 /*
246  * 可用的任务优先级宏定义。
247  *
248  */
249 #define OS_TSK_PRIORITY_30 30
250 
251 /*
252  * 可用的任务优先级宏定义。
253  *
254  */
255 #define OS_TSK_PRIORITY_31 31
256 
257 /*
258  * 可用的任务优先级宏定义。
259  *
260  */
261 #define OS_TSK_PRIORITY_32 32
262 
263 /*
264  * 可用的任务优先级宏定义。
265  *
266  */
267 #define OS_TSK_PRIORITY_33 33
268 
269 /*
270  * 可用的任务优先级宏定义。
271  *
272  */
273 #define OS_TSK_PRIORITY_34 34
274 
275 /*
276  * 可用的任务优先级宏定义。
277  *
278  */
279 #define OS_TSK_PRIORITY_35 35
280 
281 /*
282  * 可用的任务优先级宏定义。
283  *
284  */
285 #define OS_TSK_PRIORITY_36 36
286 
287 /*
288  * 可用的任务优先级宏定义。
289  *
290  */
291 #define OS_TSK_PRIORITY_37 37
292 
293 /*
294  * 可用的任务优先级宏定义。
295  *
296  */
297 #define OS_TSK_PRIORITY_38 38
298 
299 /*
300  * 可用的任务优先级宏定义。
301  *
302  */
303 #define OS_TSK_PRIORITY_39 39
304 
305 /*
306  * 可用的任务优先级宏定义。
307  *
308  */
309 #define OS_TSK_PRIORITY_40 40
310 
311 /*
312  * 可用的任务优先级宏定义。
313  *
314  */
315 #define OS_TSK_PRIORITY_41 41
316 
317 /*
318  * 可用的任务优先级宏定义。
319  *
320  */
321 #define OS_TSK_PRIORITY_42 42
322 
323 /*
324  * 可用的任务优先级宏定义。
325  *
326  */
327 #define OS_TSK_PRIORITY_43 43
328 
329 /*
330  * 可用的任务优先级宏定义。
331  *
332  */
333 #define OS_TSK_PRIORITY_44 44
334 
335 /*
336  * 可用的任务优先级宏定义。
337  *
338  */
339 #define OS_TSK_PRIORITY_45 45
340 
341 /*
342  * 可用的任务优先级宏定义。
343  *
344  */
345 #define OS_TSK_PRIORITY_46 46
346 
347 /*
348  * 可用的任务优先级宏定义。
349  *
350  */
351 #define OS_TSK_PRIORITY_47 47
352 
353 /*
354  * 可用的任务优先级宏定义。
355  *
356  */
357 #define OS_TSK_PRIORITY_48 48
358 
359 /*
360  * 可用的任务优先级宏定义。
361  *
362  */
363 #define OS_TSK_PRIORITY_49 49
364 
365 /*
366  * 可用的任务优先级宏定义。
367  *
368  */
369 #define OS_TSK_PRIORITY_50 50
370 
371 /*
372  * 可用的任务优先级宏定义。
373  *
374  */
375 #define OS_TSK_PRIORITY_51 51
376 
377 /*
378  * 可用的任务优先级宏定义。
379  *
380  */
381 #define OS_TSK_PRIORITY_52 52
382 
383 /*
384  * 可用的任务优先级宏定义。
385  *
386  */
387 #define OS_TSK_PRIORITY_53 53
388 
389 /*
390  * 可用的任务优先级宏定义。
391  *
392  */
393 #define OS_TSK_PRIORITY_54 54
394 
395 /*
396  * 可用的任务优先级宏定义。
397  *
398  */
399 #define OS_TSK_PRIORITY_55 55
400 
401 /*
402  * 可用的任务优先级宏定义。
403  *
404  */
405 #define OS_TSK_PRIORITY_56 56
406 
407 /*
408  * 可用的任务优先级宏定义。
409  *
410  */
411 #define OS_TSK_PRIORITY_57 57
412 
413 /*
414  * 可用的任务优先级宏定义。
415  *
416  */
417 #define OS_TSK_PRIORITY_58 58
418 
419 /*
420  * 可用的任务优先级宏定义。
421  *
422  */
423 #define OS_TSK_PRIORITY_59 59
424 
425 /*
426  * 可用的任务优先级宏定义。
427  *
428  */
429 #define OS_TSK_PRIORITY_60 60
430 
431 /*
432  * 可用的任务优先级宏定义。
433  *
434  */
435 #define OS_TSK_PRIORITY_61 61
436 
437 /*
438  * 可用的任务优先级宏定义。
439  *
440  */
441 #define OS_TSK_PRIORITY_62 62
442 
443 /*
444  * 可用的任务优先级宏定义。
445  *
446  */
447 #define OS_TSK_PRIORITY_63 63
448 
449 /*
450  * 任务或任务控制块状态标志。
451  *
452  * 任务控制块未被使用。
453  */
454 #define OS_TSK_UNUSED 0x0000
455 
456 /*
457  * 任务或任务控制块状态标志。
458  *
459  * 任务控制块被使用,任务被创建。
460  */
461 #define OS_TSK_INUSE 0x0001
462 
463 /*
464  * 任务或任务控制块状态标志。
465  *
466  * 任务被挂起。
467  */
468 #define OS_TSK_SUSPEND 0x0004
469 
470 /*
471  * 任务或任务控制块状态标志。
472  *
473  * 任务被阻塞(等待信号量)。
474  */
475 #define OS_TSK_PEND 0x0008
476 
477 /*
478  * 任务或任务控制块状态标志。
479  *
480  * 任务在等待信号量或者事件的标志。
481  */
482 #define OS_TSK_TIMEOUT 0x0010
483 
484 /*
485  * 任务或任务控制块状态标志。
486  *
487  * 任务被延时。
488  */
489 #define OS_TSK_DELAY 0x0020
490 
491 /*
492  * 任务或任务控制块状态标志。
493  *
494  * 任务已就绪,已加入就绪队列。
495  */
496 #define OS_TSK_READY 0x0040
497 
498 /*
499  * 任务或任务控制块状态标志。
500  *
501  * 任务正运行,仍在就绪队列。
502  */
503 #define OS_TSK_RUNNING 0x0080
504 
505 /*
506  * 任务或任务控制块状态标志。
507  *
508  * OS_TSK_EVENT_PEND      --- 任务阻塞于等待读事件。
509  */
510 #define OS_TSK_EVENT_PEND 0x0800
511 
512 /*
513  * 任务或任务控制块状态标志。
514  *
515  * OS_TSK_EVENT_TYPE    --- 任务读事件类型,0:ANY; 1:ALL。
516  */
517 #define OS_TSK_EVENT_TYPE 0x1000
518 
519 /*
520  * 任务或任务控制块状态标志。
521  *
522  * OS_TSK_QUEUE_PEND      --- 任务阻塞与等待队列。
523  */
524 #define OS_TSK_QUEUE_PEND 0x2000
525 
526 /*
527  * 任务或任务控制块状态标志。
528  *
529  * OS_TSK_QUEUE_BUSY      --- 队列正在读写数据。
530  */
531 #define OS_TSK_QUEUE_BUSY 0x4000
532 
533 /*
534  * 任务模块的错误码定义。
535  */
536 /*
537  * 任务错误码:申请内存失败。
538  *
539  * 值: 0x02000301
540  *
541  * 解决方案: 分配更大的私有FSC内存分区
542  *
543  */
544 #define OS_ERRNO_TSK_NO_MEMORY OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x01)
545 
546 /*
547  * 任务错误码:指针参数为空。
548  *
549  * 值: 0x02000302
550  *
551  * 解决方案: 检查参数指针是否为NUL。
552  */
553 #define OS_ERRNO_TSK_PTR_NULL OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x02)
554 
555 /*
556  * 任务错误码:任务栈大小未按16字节大小对齐。
557  *
558  * 值: 0x02000303
559  *
560  * 解决方案: 检查入参任务栈大小是否按16字节对齐。
561  */
562 #define OS_ERRNO_TSK_STKSZ_NOT_ALIGN OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x03)
563 
564 /*
565  * 任务错误码:任务优先级非法。
566  *
567  * 值: 0x02000304
568  *
569  * 解决方案: 检查入参任务优先级不能大于63,其他平台不能大于31。
570  */
571 #define OS_ERRNO_TSK_PRIOR_ERROR OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x04)
572 
573 /*
574  * 任务错误码:任务入口函数为空。
575  *
576  * 值: 0x02000305
577  *
578  * 解决方案: 检查入参任务入口函数是否为NULL。
579  */
580 #define OS_ERRNO_TSK_ENTRY_NULL OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x05)
581 
582 /*
583  * 任务错误码:任务名的指针为空或任务名为空字符串。
584  *
585  * 值: 0x02000306
586  *
587  * 解决方案: 检查任务名指针和任务名。
588  */
589 #define OS_ERRNO_TSK_NAME_EMPTY OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x06)
590 
591 /*
592  * 任务错误码:指定的任务栈空间太小。
593  *
594  * 值: 0x02000307
595  *
596  * 解决方案: 检查任务栈是否小于OS_TSK_MIN_STACK_SIZE。
597  */
598 #define OS_ERRNO_TSK_STKSZ_TOO_SMALL OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x07)
599 
600 /*
601  * 任务错误码:任务ID非法。
602  *
603  * 值: 0x02000308
604  *
605  * 解决方案: 检查当前运行任务的PID是否超过任务最大数或检查用户入参任务PID是否合法。
606  */
607 #define OS_ERRNO_TSK_ID_INVALID OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x08)
608 
609 /*
610  * 任务错误码:任务已被挂起。
611  *
612  * 值: 0x02000309
613  *
614  * 解决方案: 检查所挂起任务是否为已挂起任务。
615  */
616 #define OS_ERRNO_TSK_ALREADY_SUSPENDED OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x09)
617 
618 /*
619  * 任务错误码:任务未被挂起。
620  *
621  * 值: 0x0200030a
622  *
623  * 解决方案: 检查所恢复任务是否未挂起。
624  */
625 #define OS_ERRNO_TSK_NOT_SUSPENDED OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x0a)
626 
627 /*
628  * 任务错误码:任务未创建。
629  *
630  * 值: 0x0200030b
631  *
632  * 解决方案: 检查任务是否创建。
633  */
634 #define OS_ERRNO_TSK_NOT_CREATED OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x0b)
635 
636 /*
637  * 任务错误码:在锁任务的状态下删除当前任务。
638  *
639  * 值: 0x0300030c
640  *
641  * 解决方案: 用户确保删除任务时,将任务解锁。
642  *
643  */
644 #define OS_ERRNO_TSK_DELETE_LOCKED OS_ERRNO_BUILD_FATAL(OS_MID_TSK, 0x0c)
645 
646 /*
647  * 任务错误码:在硬中断的处理中进行延时操作。
648  *
649  * 值: 0x0300030d
650  *
651  * 解决方案: 此操作禁止在中断中进行调度。
652  *
653  */
654 #define OS_ERRNO_TSK_DELAY_IN_INT OS_ERRNO_BUILD_FATAL(OS_MID_TSK, 0x0d)
655 
656 /*
657  * 任务错误码:在锁任务的状态下进行延时操作。
658  *
659  * 值: 0x0200030e
660  *
661  * 解决方案: 检查是否锁任务。
662  */
663 #define OS_ERRNO_TSK_DELAY_IN_LOCK OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x0e)
664 
665 /*
666  * 任务错误码:任务ID不在Yield操作指定的优先级队列中。
667  *
668  * 值: 0x0200030f
669  *
670  * 解决方案: 检查操作的任务的优先级。
671  */
672 #define OS_ERRNO_TSK_YIELD_INVALID_TASK OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x0f)
673 
674 /*
675  * 任务错误码:Yield操作指定的优先级队列中,就绪任务数小于2。
676  *
677  * 值: 0x02000310
678  *
679  * 解决方案: 检查指定优先级就绪任务,确保就绪任务数大于1。
680  */
681 #define OS_ERRNO_TSK_YIELD_NOT_ENOUGH_TASK OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x10)
682 
683 /*
684  * 任务错误码:没有可用的任务控制块资源或配置项中任务裁剪关闭。
685  *
686  * 值: 0x02000311
687  *
688  * 解决方案: 打开配置项中任务裁剪开关,并配置足够大的任务资源数。
689  */
690 #define OS_ERRNO_TSK_TCB_UNAVAILABLE OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x11)
691 
692 /*
693  * 任务错误码:操作IDLE任务。
694  *
695  * 值: 0x02000312
696  *
697  * 解决方案: 检查是否操作IDLE任务。
698  */
699 #define OS_ERRNO_TSK_OPERATE_IDLE OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x12)
700 
701 /*
702  * 任务错误码:在锁任务的状态下挂起当前任务。
703  *
704  * 值: 0x03000313
705  *
706  * 解决方案: 确保任务挂起的时候,任务已经解锁。
707  *
708  */
709 #define OS_ERRNO_TSK_SUSPEND_LOCKED OS_ERRNO_BUILD_FATAL(OS_MID_TSK, 0x13)
710 
711 /*
712  * 任务错误码:系统初始化任务激活失败。
713  *
714  * 值: 0x02000314
715  *
716  * 解决方案: 查看任务栈是否配置错误。
717  *
718  */
719 #define OS_ERRNO_TSK_ACTIVE_FAILED OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x14)
720 
721 /*
722  * 任务错误码:配置的任务数量太多,配置的最大任务个数不能大于254,
723  * 总任务个数不包括Idle任务且不能为0。
724  *
725  * 值: 0x02000315
726  *
727  * 解决方案: 在任务配置项中将最大任务数改为小于等于254且大于0。
728  */
729 #define OS_ERRNO_TSK_MAX_NUM_NOT_SUITED OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x15)
730 
731 /*
732  * 任务错误码:获取任务信息时,用户实际欲获取任务数为0。
733  *
734  * 值: 0x02000316
735  *
736  * 解决方案: 获取任务信息时,用户实际输入的欲获取任务数不为0。
737  */
738 #define OS_ERRNO_TSK_INPUT_NUM_ERROR OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x16)
739 
740 /*
741  * 任务错误码:用户配置的任务栈首地址未16字节对齐。
742  *
743  * 值: 0x02000317
744  *
745  * 解决方案: 配置进来任务栈首地址需16字节对齐。
746  */
747 #define OS_ERRNO_TSK_STACKADDR_NOT_ALIGN OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x17)
748 
749 /*
750  * 任务错误码:任务正在操作队列。
751  *
752  * 值: 0x02000318
753  *
754  * 解决方案: 让被删除的任务得到调度读取完队列数据,即可删除。
755  */
756 #define OS_ERRNO_TSK_QUEUE_DOING OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x18)
757 
758 /*
759  * 任务错误码:任务退出时没有完全释放资源。
760  *
761  * 值: 0x03000319
762  *
763  * 解决方案: 任务退出前确保完全释放其占有的资源(如消息,互斥信号量等)。
764  *
765  */
766 #define OS_ERRNO_TSK_EXIT_WITH_RESOURCE OS_ERRNO_BUILD_FATAL(OS_MID_TSK, 0x19)
767 
768 /*
769  * 任务错误码:解锁任务之前并未上锁。
770  *
771  * 值: 0x0200031a
772  *
773  * 解决方案: 任务上锁解锁必须配对使用,不能不加锁,直接解锁,可能导致误解锁。
774  */
775 #define OS_ERRNO_TSK_UNLOCK_NO_LOCK OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x1a)
776 
777 /*
778  * 任务错误码:指定的任务栈地址太大导致任务栈初始化的时候整形溢出。
779  *
780  * 值: 0x0200031b
781  *
782  * 解决方案: 限制任务栈地址大小,确保任务栈初始化地址不大于0xFFFFFFFF。
783  */
784 #define OS_ERRNO_TSK_STACKADDR_TOO_BIG OS_ERRNO_BUILD_ERROR(OS_MID_TSK, 0x1b)
785 
786 /*
787  * 任务ID的类型定义。
788  */
789 typedef U32 TskHandle;
790 
791 /*
792  * 任务优先级的类型定义。
793  */
794 typedef U16 TskPrior;
795 
796 /*
797  * 任务状态的类型定义。
798  */
799 typedef U16 TskStatus;
800 
801 /*
802  * 任务信息结构体
803  */
804 struct TskInfo {
805     /* 任务切换时的SP */
806     uintptr_t sp;
807     /* 任务切换时的PC */
808     uintptr_t pc;
809     /* 任务状态 */
810     TskStatus taskStatus;
811     /* 任务优先级 */
812     TskPrior taskPrio;
813     /* 任务栈的大小 */
814     U32 stackSize;
815     /* 任务栈的栈顶 */
816     uintptr_t topOfStack;
817     /* 任务名 */
818     char name[OS_TSK_NAME_LEN];
819     /* 任务入口函数 */
820     void *entry;
821     /* 任务控制块地址 */
822     void *tcbAddr;
823     /* 栈底 */
824     uintptr_t bottom;
825     /* 栈当前使用的大小 */
826     U32 currUsed;
827     /* 栈使用的历史峰值 */
828     U32 peakUsed;
829     /* 栈是否溢出 */
830     bool ovf;
831     /* 任务上下文 */
832     struct TskContext context;
833 };
834 
835 /*
836  * 任务模块配置信息的结构体定义。
837  *
838  * 保存任务模块的配置项信息。
839  */
840 struct TskModInfo {
841     /* 最大支持的任务数 */
842     U32 maxNum;
843     /* 缺省的任务栈大小 */
844     U32 defaultSize;
845     /* Idle任务的任务栈大小 */
846     U32 idleStackSize;
847     /* 任务栈初始化魔术字 */
848     U32 magicWord;
849 };
850 
851 /*
852  * @brief 任务入口函数类型定义。
853  *
854  * @par 描述
855  * 用户通过任务入口函数类型定义任务入口函数,在任务创建触发之后调用该函数进行任务执行。
856  * @attention 无。
857  *
858  * @param param1 [IN]  类型#uintptr_t,传递给任务处理函数的第一个参数。
859  * @param param2 [IN]  类型#uintptr_t,传递给任务处理函数的第二个参数。
860  * @param param3 [IN]  类型#uintptr_t,传递给任务处理函数的第三个参数。
861  * @param param4 [IN]  类型#uintptr_t,传递给任务处理函数的第四个参数。
862  *
863  * @retval 无。
864  * @par 依赖
865  * <ul><li>prt_task.h:该接口声明所在的头文件。</li></ul>
866  * @see 无。
867  */
868 typedef void (*TskEntryFunc)(uintptr_t param1, uintptr_t param2, uintptr_t param3, uintptr_t param4);
869 
870 /*
871  * @brief 任务创建钩子函数类型定义。
872  *
873  * @par 描述
874  * 用户通过任务创建钩子函数类型定义任务创建钩子,在系统创建任务时,调用该钩子。
875  * @attention 无。
876  *
877  * @param taskPid [IN]  类型#TskHandle,新创建任务的PID。
878  *
879  * @retval 无。
880  * @par 依赖
881  * <ul><li>prt_task.h:该接口声明所在的头文件。</li></ul>
882  * @see 无。
883  */
884 typedef U32(*TskCreateHook)(TskHandle taskPid);
885 
886 /*
887  * @brief 任务删除钩子函数类型定义。
888  *
889  * @par 描述
890  * 用户通过任务删除钩子函数类型定义任务删除钩子,在系统对任务进行删除时,调用该钩子。
891  * @attention 无。
892  *
893  * @param taskPid [IN]  类型#TskHandle,删除任务的PID。
894  *
895  * @retval 无。
896  * @par 依赖
897  * <ul><li>prt_task.h:该接口声明所在的头文件。</li></ul>
898  * @see 无。
899  */
900 typedef U32(*TskDeleteHook)(TskHandle taskPid);
901 
902 /*
903  * @brief 任务切换钩子函数类型定义。
904  *
905  * @par 描述
906  * 用户通过任务切换钩子函数类型定义任务切换钩子,在系统对任务进行切换时,调用该钩子。
907  * @attention 无。
908  *
909  * @param lastTaskPid [IN]  类型#TskHandle,上一个任务的PID。
910  * @param nextTaskPid [IN]  类型#TskHandle,下一个任务的PID。
911  *
912  * @retval 无。
913  * @par 依赖
914  * <ul><li>prt_task.h:该接口声明所在的头文件。</li></ul>
915  * @see 无。
916  */
917 typedef U32(*TskSwitchHook)(TskHandle lastTaskPid, TskHandle nextTaskPid);
918 
919 /*
920  * 空任务ID。
921  *
922  * 调用PRT_TaskYield时,使用OS_TSK_NULL_ID,由OS选择就绪队列中的第一个任务。
923  */
924 #define OS_TSK_NULL_ID 0xFFFFFFFF
925 
926 /*
927  * 任务栈信息的结构体定义。
928  *
929  * 保存任务栈的信息。
930  */
931 struct TskStackInfo {
932     /* 栈顶 */
933     uintptr_t top;
934     /* 栈底 */
935     uintptr_t bottom;
936     /* 栈当前SP指针值 */
937     uintptr_t sp;
938     /* 栈当前使用的大小 */
939     U32 currUsed;
940     /* 栈使用的历史峰值 */
941     U32 peakUsed;
942     /* 栈是否溢出 */
943     bool ovf;
944 };
945 
946 /*
947  * 任务创建参数的结构体定义。
948  *
949  * 传递任务创建时指定的参数信息。
950  */
951 struct TskInitParam {
952     /* 任务入口函数 */
953     TskEntryFunc taskEntry;
954     /* 任务优先级 */
955     TskPrior taskPrio;
956     U16 reserved;
957     /* 任务参数,最多4个 */
958     uintptr_t args[4];
959     /* 任务栈的大小 */
960     U32 stackSize;
961     /* 任务名 */
962     char *name;
963     /*
964      * 本任务的任务栈独立配置起始地址,用户必须对该成员进行初始化,
965      * 若配置为0表示从系统内部空间分配,否则用户指定栈起始地址
966      */
967     uintptr_t stackAddr;
968 };
969 
970 /*
971  * @brief 创建任务,但不激活任务。
972  *
973  * @par 描述
974  * 创建一个任务。该任务不加入就绪队列,只处于挂起状态,用户需要激活该任务需要通过调用PRT_TaskResume函数将其激活。
975  *
976  * @attention
977  * <ul>
978  * <li>任务创建时,会对之前自删除任务的任务控制块和任务栈进行回收,用户独立配置的任务栈除外。</li>
979  * <li>任务名的最大长度为16字节,含结束符。</li>
980  * <li>同一核内任务名不允许重复。</li>
981  * <li>若指定的任务栈大小为0,则使用配置项#OS_TSK_DEFAULT_STACK_SIZE指定的默认的任务栈大小。</li>
982  * <li>任务栈的大小必须按16字节大小对齐。确定任务栈大小的原则是,够用就行:多了浪费,少了任务栈溢出。</li>
983  * <li>具体多少取决于需要消耗多少的栈内存,视情况而定:函数调用层次越深,栈内存开销越大,</li>
984  * <li>局部数组越大,局部变量越多,栈内存开销也越大。</li>
985  * <li>用户配置的任务栈首地址需16字节对齐。</li>
986  * <li>用户配置的任务栈空间需由用户保证其合法性,即对可cache空间的地址用户需要保证其任务栈首地址及栈大小cache</li>
987  * <li>line对齐,系统不做对齐处理,并在使用后需由用户进行释放。</li>
988  * <li>任务创建时,任务创建参数中的任务栈大小配置建议不要使用最小任务栈大小OS_TSK_MIN_STACK_SIZE,</li>
989  * <li>该项只是包含任务上下文预留的栈空间,任务调度时额外的任务开销需要由用户自行保证足够的任务栈空间配置。</li>
990  * </ul>
991  *
992  * @param taskPid   [OUT] 类型#TskHandle *,保存任务PID。
993  * @param initParam [IN]  类型#struct TskInitParam *,任务创建参数,
994  * 其结构体中的成员参数stackAddr传入时必须进行初始化,若不采用用户配置的独立任务栈进行栈空间分配,
995  * 该成员必须初始化为0。
996  *
997  * @retval #OS_OK  0x00000000,任务创建成功。
998  * @retval #其它值,创建失败。
999  * @par 依赖
1000  * <ul><li>prt_task.h:该接口声明所在的头文件。</li></ul>
1001  * @see PRT_TaskDelete | PRT_TaskCreateHookAdd | PRT_TaskCreate
1002  */
1003 extern U32 PRT_TaskCreate(TskHandle *taskPid, struct TskInitParam *initParam);
1004 
1005 /*
1006  * @brief 恢复任务。
1007  *
1008  * @par 描述
1009  * 恢复挂起的任务。
1010  *
1011  * @attention
1012  * <ul>
1013  * <li>在osStart之前不能调用该接口。</li>
1014  * <li>若任务仍处于延时、阻塞态,则只是取消挂起态,并不加入就绪队列。</li>
1015  * </ul>
1016  *
1017  * @param taskPid [IN]  类型#TskHandle,任务PID。
1018  *
1019  * @retval #OS_OK  0x00000000,恢复任务成功。
1020  * @retval #其它值,恢复任务失败。
1021  * @par 依赖
1022  * <ul><li>prt_task.h:该接口声明所在的头文件。</li></ul>
1023  * @see PRT_TaskSuspend
1024  */
1025 extern U32 PRT_TaskResume(TskHandle taskPid);
1026 
1027 /*
1028  * @brief 挂起任务。
1029  *
1030  * @par 描述
1031  * 挂起指定的任务,任务将从就绪队列中被删除。
1032  *
1033  * @attention
1034  * <ul>
1035  * <li>在osStart之前不能调用该接口。</li>
1036  * <li>若为当前任务且已锁任务,则不能被挂起。</li>
1037  * <li>IDLE任务不能被挂起。</li>
1038  * </ul>
1039  *
1040  * @param taskPid [IN]  类型#TskHandle,任务PID。
1041  *
1042  * @retval #OS_OK  0x00000000,挂起任务成功。
1043  * @retval #其它值,挂起任务失败。
1044  * @par 依赖
1045  * <ul><li>prt_task.h:该接口声明所在的头文件。</li></ul>
1046  * @see PRT_TaskResume | PRT_TaskLock
1047  */
1048 extern U32 PRT_TaskSuspend(TskHandle taskPid);
1049 
1050 /*
1051  * @brief 删除任务。
1052  *
1053  * @par 描述
1054  * 删除指定的任务,释放任务栈和任务控制块资源。
1055  *
1056  * @attention
1057  * <ul>
1058  * <li>若为自删除,则任务控制块和任务栈在下一次创建任务时才回收。</li>
1059  * <li>对于任务自删除,处理该任务相关的信号量和接收到的消息会强制删除。</li>
1060  * <li>任务自删除时,删除钩子不允许进行pend信号量、挂起等操作。</li>
1061  * </ul>
1062  *
1063  * @param taskPid [IN]  类型#TskHandle,任务PID。
1064  *
1065  * @retval #OS_OK  0x00000000,删除任务成功。
1066  * @retval #其它值,删除任务失败。
1067  * @par 依赖
1068  * <ul><li>prt_task.h:该接口声明所在的头文件。</li></ul>
1069  * @see PRT_TaskCreate | PRT_TaskDeleteHookAdd
1070  */
1071 extern U32 PRT_TaskDelete(TskHandle taskPid);
1072 
1073 /*
1074  * @brief 延迟正在运行的任务。
1075  *
1076  * @par 描述
1077  * 延迟当前运行任务的执行。任务延时等待指定的Tick数后,重新参与调度。
1078  *
1079  * @attention
1080  * <ul>
1081  * <li>在osStart之前不能调用该接口。</li>
1082  * <li>硬中断处理中,或已锁任务,则延时操作失败。</li>
1083  * <li>若传入参数0,且未锁任务调度,则顺取同优先级队列中的下一个任务执行。如没有同级的就绪任务,</li>
1084  * <li>则不发生任务调度,继续执行原任务。</li>
1085  * </ul>
1086  *
1087  * @param tick [IN]  类型#U32,延迟的Tick数。
1088  *
1089  * @retval #OS_OK  0x00000000,任务延时成功。
1090  * @retval #其它值,延时任务失败。
1091  * @par 依赖
1092  * <ul><li>prt_task.h:该接口声明所在的头文件。</li></ul>
1093  * @see PRT_TaskYield
1094  */
1095 extern U32 PRT_TaskDelay(U32 tick);
1096 
1097 /*
1098  * @brief 锁任务调度。
1099  *
1100  * @par 描述
1101  * 锁任务调度。若任务调度被锁,则不发生任务切换。
1102  *
1103  * @attention
1104  * <ul>
1105  * <li>只是锁任务调度,并不关中断,因此任务仍可被中断打断。</li>
1106  * <li>执行此函数则锁计数值加1,解锁则锁计数值减1。因此,必须与#PRT_TaskUnlock配对使用。</li>
1107  * </ul>
1108  *
1109  * @param 无。
1110  *
1111  * @retval 无
1112  * @par 依赖
1113  * <ul><li>prt_task.h:该接口声明所在的头文件。</li></ul>
1114  * @see PRT_TaskUnlock
1115  */
1116 extern void PRT_TaskLock(void);
1117 
1118 /*
1119  * @brief 解锁任务调度。
1120  *
1121  * @par 描述
1122  * 任务锁计数值减1。若嵌套加锁,则只有锁计数值减为0才真正的解锁了任务调度。
1123  *
1124  * @attention
1125  * <ul>
1126  * <li>在osStart之前不能调用该接口。</li>
1127  * <li>执行此函数则锁计数值加1,解锁则锁计数值减1。因此,必须与#PRT_TaskLock配对使用。</li>
1128  * </ul>
1129  *
1130  * @param 无。
1131  *
1132  * @retval 无
1133  * @par 依赖
1134  * <ul><li>prt_task.h:该接口声明所在的头文件。</li></ul>
1135  * @see PRT_TaskLock
1136  */
1137 extern void PRT_TaskUnlock(void);
1138 
1139 /*
1140  * @brief 获取当前任务PID。
1141  *
1142  * @par 描述
1143  * 获取处于运行态的任务PID。
1144  *
1145  * @attention
1146  * <ul>
1147  * <li>硬中断处理中,也可获取当前任务PID,即被中断打断的任务。</li>
1148  * <li>在任务切换钩子处理中调用时,获取的是切入任务的ID。</li>
1149  * </ul>
1150  *
1151  * @param taskPid [OUT] 类型#TskHandle *,保存任务PID。
1152  *
1153  * @retval #OS_OK  0x00000000,获取成功。
1154  * @retval #其它值,获取失败。
1155  * @par 依赖
1156  * <ul><li>prt_task.h:该接口声明所在的头文件。</li></ul>
1157  * @see PRT_TaskGetStatus | PRT_TaskGetInfo
1158  */
1159 extern U32 PRT_TaskSelf(TskHandle *taskPid);
1160 
1161 /*
1162  * @brief 获取任务状态。
1163  *
1164  * @par 描述
1165  * 获取指定任务的状态。
1166  *
1167  * @attention 无
1168  *
1169  * @param taskPid [IN]  类型#TskHandle,任务PID。
1170  *
1171  * @retval #(TskStatus)OS_INVALID    返回失败。
1172  * @retval #任务状态 返回成功。
1173  * @par 依赖
1174  * <ul><li>prt_task.h:该接口声明所在的头文件。</li></ul>
1175  * @see PRT_TaskGetInfo
1176  */
1177 extern TskStatus PRT_TaskGetStatus(TskHandle taskPid);
1178 
1179 /*
1180  * @brief 获取任务信息。
1181  *
1182  * @par 描述
1183  * 获取指定任务的信息。
1184  *
1185  * @attention
1186  * <ul>
1187  * <li>若获取当前任务的信息,则只在硬中断、异常的处理中才有意义,</li>
1188  * <li>由于任务切换时,上下文信息也保存在任务栈中,因此任务信息中的SP是保存上下文之后的实际的SP值。</li>
1189  * </ul>
1190  *
1191  * @param taskPid  [IN]  类型#TskHandle,任务PID。
1192  * @param taskInfo [OUT] 类型#struct TskInfo *,保存任务信息。
1193  *
1194  * @retval #OS_OK  0x00000000,获取成功。
1195  * @retval #其它值,获取失败。
1196  * @par 依赖
1197  * <ul><li>prt_task.h:该接口声明所在的头文件。</li></ul>
1198  * @see PRT_TaskGetStatus
1199  */
1200 extern U32 PRT_TaskGetInfo(TskHandle taskPid, struct TskInfo *taskInfo);
1201 
1202 /*
1203  * @brief 获取优先级。
1204  *
1205  * @par 描述
1206  * 获取指定任务的优先级。
1207  *
1208  * @attention 无
1209  *
1210  * @param taskPid  [IN]  类型#TskHandle,任务PID。
1211  * @param taskPrio [OUT] 类型#TskPrior *,保存任务优先级指针。
1212  *
1213  * @retval #OS_OK  0x00000000,获取成功。
1214  * @retval #其它值,获取失败。
1215  * @par 依赖
1216  * <ul><li>prt_task.h:该接口声明所在的头文件。</li></ul>
1217  * @see PRT_TaskSetPriority
1218  */
1219 extern U32 PRT_TaskGetPriority(TskHandle taskPid, TskPrior *taskPrio);
1220 
1221 /*
1222  * @brief 设置优先级。
1223  *
1224  * @par 描述
1225  * 设置指定任务的优先级。
1226  *
1227  * @attention
1228  * <ul>
1229  * <li>在osStart之前不能调用该接口。</li>
1230  * <li>若设置的优先级高于当前运行的任务,则可能引发任务调度。</li>
1231  * <li>若调整当前运行任务的优先级,同样可能引发任务调度。</li>
1232  * <li>若任务发生优先级继承,或者任务阻塞在互斥信号量或优先级唤醒模式的信号量上,不可以设置任务的优先级。</li>
1233  * </ul>
1234  *
1235  * @param taskPid  [IN]  类型#TskHandle,任务PID。
1236  * @param taskPrio [IN]  类型#TskPrior,任务优先级。
1237  *
1238  * @retval #OS_OK  0x00000000,设置成功。
1239  * @retval #其它值,设置失败。
1240  * @par 依赖
1241  * <ul><li>prt_task.h:该接口声明所在的头文件。</li></ul>
1242  * @see PRT_TaskGetPriority
1243  */
1244 extern U32 PRT_TaskSetPriority(TskHandle taskPid, TskPrior taskPrio);
1245 
1246 /*
1247  * @brief 查询本核指定任务正在PEND的信号量。
1248  *
1249  * @par 描述
1250  * 根据任务状态和任务控制块,判断任务是否在PEND信号量,以及PEND的信号量ID。
1251  *
1252  * @attention
1253  * <ul>
1254  * <li>用户应先判断PEND状态,状态为0表明任务没有被信号量阻塞。</li>
1255  * </ul>
1256  *
1257  * @param taskId    [IN]  类型#TskHandle,任务PID。
1258  * @param semId     [OUT] 类型#U16 *,任务PEND的信号量ID或者#OS_INVALID。
1259  * @param pendState [OUT] 类型#U16 *,任务的PEND状态:0,#OS_TSK_FSEM_PEND,#OS_TSK_PEND, #OS_TSK_MCSEM_PEND。
1260  *
1261  * @retval #OS_OK  0x00000000,查询成功。
1262  * @retval #其它值,查询失败。
1263  * @par 依赖
1264  * <ul><li>prt_task.h:该接口声明所在的头文件。</li></ul>
1265  * @see PRT_SemGetPendList
1266  */
1267 extern U32 PRT_TaskGetPendSem(TskHandle taskId, U16 *semId, U16 *pendState);
1268 
1269 /*
1270  * @brief 查询任务名。
1271  *
1272  * @par 描述
1273  * 根据任务PID,查询任务名。
1274  *
1275  * @attention
1276  * <ul>
1277  * <li>在osStart之前不能调用该接口。</li>
1278  * <li>不能查询ID不合法的任务名。</li>
1279  * <li>若查询没有创建的任务名,查询失败。</li>
1280  * </ul>
1281  *
1282  * @param taskId  [IN]  类型#TskHandle,任务ID。
1283  * @param name [OUT] 类型#char **,保存任务名字符串的首地址。
1284  *
1285  * @retval #OS_OK  0x00000000,查询成功。
1286  * @retval #其它值,查询失败。
1287  * @par 依赖
1288  * <ul><li>prt_task.h:该接口声明所在的头文件。</li></ul>
1289  * @see
1290  */
1291 extern U32 PRT_TaskGetName(TskHandle taskId, char **name);
1292 
1293 /*
1294  * @brief 注册任务切换钩子。
1295  *
1296  * @par 描述
1297  * 注册任务切换钩子函数。钩子函数在切入新任务前被调用。
1298  *
1299  * @attention
1300  * <ul>
1301  * <li>不同钩子函数间执行的先后顺序,不应当存在依赖关系。</li>
1302  * <li>不应在任务切换钩子里进行可能引起任务调度的处理,如:任务延时、P信号量等。</li>
1303  * </ul>
1304  *
1305  * @param hook [IN]  类型#TskSwitchHook,任务切换钩子函数。
1306  *
1307  * @par 依赖
1308  * <ul><li>prt_task.h:该接口声明所在的头文件。</li></ul>
1309  * @see PRT_TaskDelSwitchHook | PRT_TaskDeleteHookAdd | PRT_TaskCreateHookAdd
1310  */
1311 extern U32 PRT_TaskAddSwitchHook(TskSwitchHook hook);
1312 
1313 /*
1314  * @brief 取消任务切换钩子。
1315  *
1316  * @par 描述
1317  * 取消指定的任务切换钩子。钩子函数在切入新任务前被调用。
1318  *
1319  * @attention  无
1320  *
1321  * @param hook [IN]  类型#TskSwitchHook,任务切换钩子函数。
1322  *
1323  * @par 依赖
1324  * <ul><li>prt_task.h:该接口声明所在的头文件。</li></ul>
1325  * @see PRT_TaskAddSwitchHook
1326  */
1327 extern U32 PRT_TaskDelSwitchHook(TskSwitchHook hook);
1328 
1329 #ifdef __cplusplus
1330 #if __cplusplus
1331 }
1332 #endif /* __cpluscplus */
1333 #endif /* __cpluscplus */
1334 
1335 #endif /* PRT_TASK_H */
1336