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