RTX任务管理

默认情况下用户创建的任务栈大小是由参数Task stack size决定的。

如果觉得每个任务都分配同样大小的栈空间不方便的话,可以采用自定义任务栈的方式创建任务。采用自定义方式更灵活些

由于Cortex-M3和M4内核具有双堆栈指针,MSP主堆栈指针和PSP进程堆栈指针,或者叫PSP任务堆栈指针也是可以的。

在RTX操作系统中,主堆栈指针MSP是给系统栈空间使用的,进程堆栈指针PSP是给任务栈使用的。

也就是说,在RTX任务中,所有栈空间的使用都是通过PSP指针进行指向的。一旦进入了中断函数已经可能发生的中断嵌套都是用的MSP指针

实际应用中系统栈空间分配多大,主要是看可能发生的中断嵌套层数,下面我们就按照最坏执行情况进行考虑,所有的寄存器都需要入栈,此时分为两种情况:

64字节 对于Cortex-M3内核和未使用FPU(浮点运算单元)功能的Cortex-M4内核在发生中断时需要将16个通用寄存器全部入栈,每个寄存器占用4个字节,也就是16*4 = 64字节的空间。 可能发生几次中断嵌套就是要64乘以几即可。当然,这种是最坏执行情况,也就是所有的寄存器都入栈。 (注:任务执行的过程中发生中断的话,有8个寄存器是自动入栈的,这个栈是任务栈,进入中断以后其余寄存器入栈以及发生中断嵌套都是用的系统栈)。

200字节 对于具有FPU(浮点运算单元)功能的Cortex-M4内核,如果在任务中进行了浮点运算,那么在发生中断的时候除了16个通用寄存器需要入栈,还有34个浮点寄存器也是要入栈的,也就是(16+34)*4 = 200字节的空间。当然,这种是最坏执行情况,也就是所有的寄存器都入栈。(注:任务执行的过程中发送中断的话,有8个通用寄存器和18个浮点寄存器是自动入栈的,这个栈是任务栈,进入中断以后其余通用寄存器和浮点寄存器入栈以及发生中断嵌套都是用的系统栈。)。

os_sys_init()

  1. void os_sys_init (
  2. void (*task)(void) ); /* 操作系统启动后执行的任务 */

函数描述:

该方法初始化并启动操作系统内核.

参数为系统初始化完成之后启动的任务的指针. 内核给予该任务默认的优先级1.

注意要点:

该函数在 rtl.h中定义.

该方法必须在主函数中调用main.

该任务使用默认的堆栈大小,该大小在 rtx_config.c中为任务定义.

返回值:

该函数不返回,函数会直接开始执行参数中指向的方法.

演示:

  1. #include <rtl.h>
  2. void main (void) {
  3. os_sys_init (task1); /* start the kernel */
  4. while(1); /* will never come here */
  5. }

os_sys_init_prio

  1. void os_sys_init_prio (
  2. void (*task)(void), /* Task to start */
  3. U8 priority); /* Task priority (1-254) */

函数描述:

该函数初始化并启动RTX内核.

task指针指向启动后系统执行的第一个任务.

优先级参数设置系统启动之后的第一个执行的任务的优先级. 默认优先级为1. 优先级0为空闲任务保留. 如果设置参数值为0,他会自动被参数1取代. 优先级255同样被保留.

该函数定义在rtl.h.

注意要点:

该函数必须在main函数中被调用.

该任务使用默认的堆栈大小,该大小在 rtx_config.c中为任务定义.

优先级255表示最重要任务,优先级越高,任务越重要.

返回值:

函数不返回,直接开始执行参数中指定的方法任务

演示:

  1. #include <rtl.h>
  2. void main (void) {
  3. os_sys_init_prio (task1, 10);
  4. while(1);
  5. }

os_sys_init_user

  1. void os_sys_init_user (
  2. void (*task)(void), /* Task to start */
  3. U8 priority, /* Task priority (1-254) */
  4. void* stack, /* Task stack */
  5. U16 size); /* Stack size */

函数描述:

初始化并启动操作系统内核. 当启动任务需要比较大的堆栈的时候使用该函数,可以自定义堆栈.

task参数指向系统启动后执行的第一个任务的指针.

优先级参数设置系统启动之后的第一个执行的任务的优先级. 默认优先级为1. 优先级0为空闲任务保留. 如果设置参数值为0,他会自动被参数1取代. 优先级255同样被保留.

stack参数指向启动任务将使用的堆栈的开头.

size表明任务堆栈的大小.

该函数定义在rtl.h.

该函数定义在rtl.h.注意要点:

T该函数必须在main函数中被调用.

任务栈空间必须8字节对齐,可以将任务栈数组定义成uint64_t类型即可(unsigned long long).

默认的堆栈大小,该大小在 rtx_config.c中为任务定义.

优先级255表示最重要任务,优先级越高,任务越重要.

返回值:

函数不返回,直接开始执行参数中指定的方法任务.

演示:

  1. static U64 stk1[400/8]; /* 400-byte stack */
  2. void main (void) {
  3. os_sys_init_user (task1, 10, &stk1, sizeof(stk1));
  4. while(1);
  5. }

os_tsk_create

  1. OS_TID os_tsk_create (
  2. void (*task)(void), /* Task to create */
  3. U8 priority ); /* Task priority (1-254) */

函数描述:

该任务创建一个任务,任务指向task指针指向的方法,函数将动态的创建一个任务表示符TID,并将该任务放到系统就绪任务队列中.

优先级参数设置系统启动之后的第一个执行的任务的优先级. 默认优先级为1. 优先级0为空闲任务保留. 如果设置参数值为0,他会自动被参数1取代. 优先级255同样被保留.

如果新创建的了任务优先级高于当前正在执行的任务,将引发一次调度,系统执行更高优先级的任务.

该函数定义在rtl.h.

注意要点:

该API创建的任务使用rtx_config.c定义的堆栈大小创建任务.

优先级255表示最重要任务,优先级越高,任务越重要.

返回值:

该函数返回创建的任务的标识符TID. 如果函数调用失败,将会返回0.

演示:

  1. OS_TID tsk1, tsk2;
  2. __task void task1 (void) {
  3. ..
  4. tsk2 = os_tsk_create (task2, 1);
  5. ..
  6. }
  7. __task void task2 (void) {
  8. ..
  9. }

os_tsk_create_ex

  1. OS_TID os_tsk_create_ex (
  2. void (*task)(void *), /* Task to create */
  3. U8 priority, /* Task priority (1-254) */
  4. void* argv ); /* Argument to the task */

函数描述:

该任务创建一个任务,任务指向task指针指向的方法,函数将动态的创建一个任务表示符TID,并将该任务放到系统就绪任务队列中. 该函数是os_tsk_create的扩展方法,可以支持先task指针指定的任务发送一个参数argv.

优先级参数设置系统启动之后的第一个执行的任务的优先级. 默认优先级为1. 优先级0为空闲任务保留. 如果设置参数值为0,他会自动被参数1取代. 优先级255同样被保留. .

argv参数在创建的任务被启动的时候,被系统传递给该任务. 该函数对于同一方法的多个任务的模式下比较实用.

该函数定义在rtl.h.

注意要点:

函数定义任务的时候使用rtx_config.c中指定的任务堆栈大小

返回值:

该函数返回创建的任务的标识符TID. 如果函数调用失败,将会返回0.

演示:

  1. #include <rtl.h>
  2. OS_TID tsk1, tsk2_0, tsk2_1;
  3. int param[2] = {0, 1};
  4. __task void task1 (void) {
  5. ..
  6. tsk2_0 = os_tsk_create_ex (task2, 1, &param[0]);
  7. tsk2_1 = os_tsk_create_ex (task2, 1, &param[1]);
  8. ..
  9. }
  10. __task void task2 (void *argv) {
  11. ..
  12. switch (*(int *)argv) {
  13. case 0:
  14. printf("This is a first instance of task2.\n");
  15. break;
  16. case 1:
  17. printf("This is a second instance of task2.\n");
  18. break;
  19. }
  20. ..
  21. }

os_tsk_create_user

  1. OS_TID os_tsk_create_user(
  2. void (*task)(void), /* Task to create */
  3. U8 priority, /* Task priority (1-254) */
  4. void* stk, /* Pointer to the task‘s stack */
  5. U16 size ); /* Number of bytes in the stack */

函数描述:

该任务创建一个任务,任务指向task指针指向的方法,函数将动态的创建一个任务表示符TID,并将该任务放到系统就绪任务队列中. 该函数支持为任务定义私有堆栈区. 在任务需要一个大的堆栈的时候该函数比较实用.

优先级参数设置系统启动之后的第一个执行的任务的优先级. 默认优先级为1. 优先级0为空闲任务保留. 如果设置参数值为0,他会自动被参数1取代. 优先级255同样被保留.如果新创建的了任务优先级高于当前正在执行的任务,将引发一次调度,系统执行更高优先级的任务.

第3个参数是任务栈地址.   第4个参数是任务栈大小,单位是字节.

该函数定义在rtl.h.

注意要点:

任务栈空间必须8字节对齐,可以将任务栈数组定义成uint64_t类型即可 (unsigned long long).

返回值:

该函数返回创建的任务的标识符TID. 如果函数调用失败,将会返回0.

演示:

  1. OS_TID tsk1,tsk2;
  2. static U64 stk2[400/8];
  3. __task void task1 (void) {
  4. ..
  5. /* Create task 2 with a bigger stack */
  6. tsk2 = os_tsk_create_user (task2, 1, &stk2, sizeof(stk2));
  7. ..
  8. }
  9. __task void task2 (void) {
  10. /* We need a bigger stack here. */
  11. U8 buf[200];
  12. ..
  13. }

os_tsk_create_user_ex

  1. OS_TID os_tsk_create_user_ex (
  2. void (*task)(void *), /* Task to create */
  3. U8 priority, /* Task priority (1-254) */
  4. void* stk, /* Pointer to the task‘s stack */
  5. U16 size, /* Size of stack in bytes */
  6. void* argv ); /* Argument to the task */

函数描述:

该任务创建一个任务,任务指向task指针指向的方法,函数将动态的创建一个任务表示符TID,并将该任务放到系统就绪任务队列中. 该函数支持为任务定义私有堆栈区. 在任务需要一个大的堆栈的时候该函数比较实用.同时还可以向任务传递一个argv参数.

优先级参数设置系统启动之后的第一个执行的任务的优先级. 默认优先级为1. 优先级0为空闲任务保留. 如果设置参数值为0,他会自动被参数1取代. 优先级255同样被保留.如果新创建的了任务优先级高于当前正在执行的任务,将引发一次调度,系统执行更高优先级的任务.

第3个参数是任务栈地址.   第4个参数是任务栈大小,单位是字节.

argv参数在创建的任务被启动的时候,被系统传递给该任务. 该函数对于同一方法的多个任务的模式下比较实用.

注意要点:

任务栈空间必须8字节对齐,可以将任务栈数组定义成uint64_t类型即可 (unsigned long long).

返回值:

该函数返回创建的任务的标识符TID. 如果函数调用失败,将会返回0.

演示:

  1. #include <rtl.h>
  2. OS_TID tsk1,tsk2_0,tsk2_1;
  3. static U64 stk2[2][400/8];
  4. __task void task1 (void) {
  5. ..
  6. /* Create task 2 with a bigger stack */
  7. tsk2_0 = os_tsk_create_user_ex (task2, 1,
  8. &stk2[0], sizeof(stk2[0]),
  9. (void *)0);
  10. tsk2_1 = os_tsk_create_user_ex (task2, 1,
  11. &stk2[1], sizeof(stk2[1]),
  12. (void *)1);
  13. ..
  14. }
  15. __task void task2 (void *argv) {
  16. /* We need a bigger stack here. */
  17. U8 buf[200];
  18. ..
  19. switch ((int)argv) {
  20. case 0:
  21. printf("This is a first instance of task2.\n");
  22. break;
  23. case 1:
  24. printf("This is a second instance of task2.\n");
  25. break;
  26. }
  27. ..
  28. }

os_tsk_delete

  1. OS_RESULT os_tsk_delete (
  2. OS_TID task_id ); /* Id of the task to delete */

函数描述:

当任务完成所有工作并不再想要的时候,可以调用该函数停止并删除任务,依靠task_id来停止并删除任务

注意要点:

如果task_id为0,则当前正在执行的任务被停止和删除. 程序将执行就绪队列中的下一个就绪任务.

返回值:

如果任务删除成功,函数返回OS_R_OK,其余所有情况返回OS_R_NOK,比如所写的任务ID不存在.

演示:

  1. #include <rtl.h>
  2. OS_TID tsk3;
  3. __task void task2 (void) {
  4. tsk3 = os_tsk_create (task3, 0);
  5. ..
  6. if (os_tsk_delete (tsk3) == OS_R_OK) {
  7. printf("\n‘task 3‘ deleted.");
  8. }
  9. else {
  10. printf ("\nFailed to delete ‘task 3‘.");
  11. }
  12. }
  13. __task void task3 (void) {
  14. ..
  15. }

os_tsk_delete_self

  1. #include <rtl.h>
  2. void os_tsk_delete_self (void);

函数描述:

该函数停止并删除当前正在执行的任务,程序将执行就绪队列中的下一个就绪任务.

注意要点:

该函数没有返回.,程序将执行就绪队列中的下一个就绪任务

返回值:

该函数没有返回.,程序将执行就绪队列中的下一个就绪任务.

演示:

  1. #include <rtl.h>
  2. __task void task2 (void) {
  3. ..
  4. os_tsk_delete_self();
  5. }

os_tsk_pass

  1. #include <rtl.h>
  2. void os_tsk_pass (void);

函数描述:

该函数将切换到和当前任务优先级相同的就绪队列中的其他任务. 如果就绪队列中没有相同优先级的任务, 当前任务将继续执行且没有任务切换发生。

注意要点:

可以用该方法在相同优先级的几个任务之间切换.

返回值:

None

演示:

  1. #include <rtl.h>
  2. OS_TID tsk1;
  3. __task void task1 (void) {
  4. ..
  5. os_tsk_pass();
  6. ..
  7. }

os_tsk_prio

  1. OS_RESULT os_tsk_prio (
  2. OS_TID task_id, /* ID of the task */
  3. U8 new_prio ); /* New priority of the task (1-254) */

函数描述:

该函数将修改task_id指定的任务的优先级.

如果新设置的优先级比当前执行的任务的优先级高,那么任务切换将会切换到task_id指定的任务并执行,同时优先级被修改. 如果低,那么依然执行当前任务.

如果task_id为0,修改的优先级是当前运行任务的优先级.

注意要点:

新优先级的取值为1-254.

新的优先级将一直保持直到你再次修改它.

优先级0是idle任务的优先级,如果设置某个任务优先级为0,程序将自动修改为1,255是保留优先级,也是一样的.

优先级数值越大,优先级越高.

返回值:

返回值如下所示:

演示:

  1. #include <RTL.h>
  2. OS_TID tsk1,tsk2;
  3. __task void task1 (void) {
  4. ..
  5. os_tsk_prio_self (5);
  6. /* Changing the priority of task2 will cause a task switch. */
  7. os_tsk_prio(tsk2, 10);
  8. ..
  9. }
  10. __task void task2 (void) {
  11. ..
  12. /* Change priority of this task will cause task switch. */
  13. os_tsk_prio_self (1);
  14. ..
  15. }

os_tsk_prio_self

  1. #include <rtl.h>
  2. OS_RESULT os_tsk_prio_self (
  3. U8 new_prio ); /* New priority of task (1-254) */

函数描述:

修改当前运行任务的优先级为新的优先级.

注意要点:

新优先级的取值为1-254.

新的优先级将一直保持直到你再次修改它.

优先级0是idle任务的优先级,如果设置某个任务优先级为0,程序将自动修改为1,255是保留优先级,也是一样的.

优先级数值越大,优先级越高..

返回值:

该函数始终返回 OS_R_OK.

演示:

  1. #include <rtl.h>
  2. OS_TID tsk1;
  3. __task void task1 (void) {
  4. ..
  5. os_tsk_prio_self(10); /* Increase its priority, for the critical section */
  6. .. /* This is a critical section */
  7. ..
  8. os_tsk_prio_self(2); /* Decrease its priority at end of critical section */
  9. ..
  10. }

os_tsk_self

  1. #include <rtl.h>
  2. OS_TID os_tsk_self (void);

函数描述:

该函数将返回当前运行任务的标识符,也就是TID.

注意要点:

返回值:

返回当前执行任务的TID标识符.

演示:

  1. #include <rtl.h>
  2. OS_TID tsk1;
  3. __task void task1 (void) {
  4. tsk1 = os_tsk_self();
  5. ..
  6. }

isr_tsk_get

  1. #include <rtl.h>
  2. OS_TID isr_tsk_get (void);

函数描述:

该函数返回当前正在运行的中断任务的标识符TID.

注意要点:

该函数只能在ISR任务中调用.

返回值:

该函数返回当前正在运行的中断任务的标识符TID.

演示:

  1. #include <rtl.h>
  2. void os_error (U32 err_code) {
  3. /* This function is called when a runtime error is detected. */
  4. OS_TID err_task;
  5. switch (err_code) {
  6. case OS_ERR_STK_OVF:
  7. /* Identify the task with stack overflow. */
  8. err_task = isr_tsk_get();
  9. break;
  10. case OS_ERR_FIFO_OVF:
  11. break;
  12. case OS_ERR_MBX_OVF:
  13. break;
  14. }
  15. for (;;);
  16. }

时间: 2024-12-28 21:18:58

RTX任务管理的相关文章

ARM RTX操作系统&mdash;Theory of Operation&mdash;System Task Manager &amp; Task Management

System Task Manager 任务管理器是一个系统任务进程,在每次RTX内核时钟发生timer tick interrupt时会运行,也就是每次RTX内核时钟发生中断都会运行.这个进程拥有最高的优先级而不会被其他进程取代.这个进程的基本任务,就是负责调度用户的任务进程. 基于RTX内核的用户任务进程,并不真正意义上是同时运行,他们是分时间片来运行的,time-sliced.可用的CPU timer,会切分成很小的时间片.RTX内核将一个时间片分配给某个任务进程.因为一个时间片很短(默认

RTX基础教程目录

6.第6章 RTX 操作系统源码方式移植 7.RTX--第7章 任务管理 8.RTX--第8章 任务优先级修改 9.RTX--第9章 任务运行在特权级或非特权级模式 10.RTX--第10章 任务调度-抢占式.时间片和合作式 11.RTX--第11章 临界段,任务锁和中断锁 12.RTX--第12章 系统时钟节拍和时间管理 13.RTX--第13章 事件标志组 14.RTX--第14章 信号量 15.RTX--第15章 互斥信号量 16.RTX--第16章 消息邮箱 17.RTX--第17章 定

第21章 RTX 低功耗之睡眠模式

低功耗是 MCU 的一项非常重要的指标,比如某些可穿戴的设备,其携带的电量有限,如果整个电路消耗的电量特别大的话,就会经常出现电量不足的情况,影响用户体验. 本章节为大家讲解 M3/4的低功耗方式之睡眠模式在 RTX 操作系统上面的实现方法(RTX 本身支持的 tickless 低功耗模式在第 24 章节讲解) STM32F103 睡眠模式介绍说明:在 RTX 系统上面实现睡眠方式仅需了解这里讲解的知识基本就够用了,更多睡眠方式的知识请看 STM32F103 参考手册和 Cortex-M3 权威

腾讯通RTX 手机安卓版试用

提到腾讯通RTX,很多朋友都耳熟能详,因为这是每天工作联络的必须品,同事间交流及传送文件都需要用到的工具.但提到RTX腾讯通手机版,不免会产生很多疑问.RTX还有手机版?带着这样的疑问,接下来就由昆明国防路百信手机大全为大家分享. 首先安装到手机.RTX手机版也延续了腾讯众多手机产品的特点,体积小权限多.安装完毕之后首次打开会看到"企业通讯录"的大Logo. 进行登录了,由于是需要"总机号",而非PC端的服务器地址,不清楚总机号的同学请询问本公司网管.登录后会看到底

RTX——第19章 SVC 中断方式调用用户函数(后期补历程)

本章节为大家讲解如何采用 SVC 中断方式调用用户函数. 当用户将 RTX 任务设置为工作在非特权级模式时,任务中是不允许访问特权级寄存器的,这个时候使用 SVC 中断,此问题就迎刃而解了. SVC 功能介绍SVC 用于产生系统函数的调用请求.例如,操作系统通常不让用户程序直接访问硬件,而是通过提供一些系统服务函数,让用户程序使用 SVC 发出对系统服务函数的呼叫请求,以这种方法调用它们来间接访问硬件.因此,当用户程序想要控制特定的硬件时,它就要产生一个 SVC 异常,然后操作系统提供的SVC

RTX——第8章 任务优先级修改

任务优先级设置注意事项RTX 操作系统任务优先级的设置要注意以下几个问题:? 设置任务的优先级时,数值越小优先级越低.? 最低任务优先级是 0,此优先级被空闲任务使用,任何其它任务都不可以使用.? 用户可以设置的优先级范围是 1-254,由于 RTX 支持时间片调度,所以也是支持用户任务设置为相同的优先级.? 优先级 255 被保留,用于最重要的任务. 任务优先级设置除了创建任务时可以设置任务优先级,也可以通过下面两个函数修改任务优先级:? os_tsk_prio? os_tsk_prio_se

Linux进程控制和计划任务管理

程序是保存在外部存储介质(如硬盘)中的可执行机器代码和数据的静态集合,而进程是在CPU及内存中处于动态执行状态的计算机程序.在Linux中,每个程序启动后可以创建一个或多个进程. ps命令   查看静态的进程统计信息 ps         只显示当前用户会话中打开的进程 ps  aux    以简单列表的形式显示出进程信息 ps  -elf   以长格式显示系统中的进程信息,包括更丰富的内容 top命令   查看进程动态信息 在当前终端已交互式的界面显示进程排名,及时跟踪CPU.内存等系统资源占

RTX临界段,中断锁与任务锁

临界段 代码的临界段也称为临界区,一旦这部分代码开始执行,则不允许任何中断打断.为确保临界段代码的执行不被中断,在进入临界段之前须关中断,而临界段代码执行完毕后,要立即开中断. 由于Cortex-M3/M4的RTX内核库中没有关闭中断的操作,也就是说RTX的源码中不存在临界段. 中断锁 中断锁就是RTOS提供的开关中断函数,因为Cortex-M3/M4的RTX源码中没有关闭中断的操作,所以也就没有提供开关中断函数. 由于RTX没有提供开关中断函数,如果用户自己的应用代码需要开关中断的话怎么办呢?

Eclipse插件Mylyn管理上下文任务管理

原文地址:http://www.ibm.com/developerworks/cn/java/j-mylyn1/ Mylyn 2.0,第 1 部分: 集成的任务管理 使用集成的 Eclipse 问题跟踪功能简化工作 现在,在 2.0 版中,Mylyn(以前称为 Mylar)通过将任务无缝集成到 Eclipse 中并在工作时自动管理任务上下文,提高了效率.Mylyn 项目主管 Mik Kersten 更新了他撰写的分两部分的 Mylyn 使用指南,以便包括根据 Mylyn 1.0 的大量用户反馈而