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