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