OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5218|回复: 6

请问各位一个ucos的问题??

[复制链接]

54

主题

248

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
484
金钱
484
注册时间
2012-3-23
在线时间
0 小时
发表于 2012-9-3 23:19:55 | 显示全部楼层 |阅读模式
在原子的例程《扩展实验14 UCOSII多任务运行LED+KEY+LCD+触摸画笔》中,
在建立一个开始任务后,启动这个开始任务。在这个开始任务中仅仅只是建立了4个
子任务,然后将这个任务挂起。那4个子任务是如何的启动的呢???

 int main(void)
 {
SystemInit();   //系统初始化 72M
delay_init(72);     //延时初始化
NVIC_Configuration();
uart_init(9600);//串口初始化,波特率9600
  LED_Init();    //LED0,LED1端口初始化
KEY_Init(); //KEY端口初始化
LCD_Init(); //LCD显示初始化
SPI_Flash_Init();
AT24CXX_Init(); //IIC初始化 
Touch_Init();       //触摸屏初始化
delay_ms(500);
Load_Drow_Dialog();
  POINT_COLOR=RED;
OSInit();
OSTaskCreate( TaskStart, //task pointer
(void *)0, //parameter
(OS_STK *)&TASK_START_STK[START_STK_SIZE-1], //task stack top pointer
START_TASK_Prio ); //task priority
OSStart();
return 0;

 }
  
//开始任务
void TaskStart(void * pdata)
{
pdata = pdata; //
OS_ENTER_CRITICAL();   
OSTaskCreate(TaskLed, (void * )0, (OS_STK *)&TASK_LED_STK[LED_STK_SIZE-1], LED_TASK_Prio);
OSTaskCreate(TaskLed1, (void * )0, (OS_STK *)&TASK_LED1_STK[LED1_STK_SIZE-1], LED1_TASK_Prio);
  OSTaskCreate(TaskLCD, (void * )0, (OS_STK *)&TASK_LCD_STK[LCD_STK_SIZE-1], LCD_TASK_Prio);
  OSTaskCreate(TaskKey, (void * )0, (OS_STK *)&TASK_KEY_STK[KEY_STK_SIZE-1], KEY_TASK_Prio);
  OSTaskCreate(TaskTouch, (void * )0, (OS_STK *)&TASK_TOUCH_STK[TOUCH_STK_SIZE-1], TOUCH_TASK_Prio);
  OSTaskSuspend(START_TASK_Prio); //suspend but not delete
OS_EXIT_CRITICAL();
}

就算能启动,那么根据优先级顺序,就会执行任务void TaskKey(void *pdata),在这个任务中调用
延时函数 OSTimeDlyHMSM() ,当时间到期时,就会在就绪表中选择一个最高优先级的任务执行,
但是最高优先级的任务还是 void TaskKey(void *pdata) 啊???  那难道不会出不来这个任务吗???
其他的任务就没机会执行了啊????






从心所欲
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

54

帖子

0

精华

初级会员

Rank: 2

积分
99
金钱
99
注册时间
2012-8-31
在线时间
0 小时
发表于 2012-9-4 00:38:09 | 显示全部楼层
回复【楼主位】 楚地狂生 :
---------------------------------
楼主,

      我没有研究这个程序,只是做过最简单的UCOS实验。把我的理解说一下,大家探讨:

   在建立一个开始任务后,启动这个开始任务。在这个开始任务中仅仅只是建立了4个
子任务,然后将这个任务挂起。那4个子任务是如何的启动的呢???   

流程应该如下:
1.TaskStart这个任务创建


2.OSStartHighRdy();  
在这个程序中,
        LDR     R4, =NVIC_INT_CTRL     ;rigger the PendSV exception (causes context switch)
        LDR     R5, =NVIC_PENDSVSET
        STR     R5, [R4]        表示在中断开启的情况下,进入PendSV_Handler中断 
                                   
       CPSIE   I                然后第一次打开中断,然后就进入了 PendSV_Handler 这个中断程序,而这个中断程序就是任务的切换程序。
      这个时候, TaskStart 优先级最高(其它四个任务此时还没建立),开始运行 TaskStart 这个任务。


3.   在TaskStart中创建任务的时候, OS_ENTER_CRITICAL();    将中断关闭,直到将4个任务创建完毕,OS_EXIT_CRITICAL();将中断打开
      (注意,因为在进入OS_ENTER_CRITICAL()时,OSInterrputSum加1,当 OSInterrputSum为0时,才能彻底中断打开)

4.由于任务创建时,已经触发了PendSV_Handler发生中断的条件,只是因为中断未开而已。此时中断开,则进入 PendSV_Handler 中断 。然后
  进入优先级最高的4个任务中的一个。比如执行TaskKey 这个任务。


就算能启动,那么根据优先级顺序,就会执行任务void TaskKey(void *pdata),在这个任务中调用
延时函数 OSTimeDlyHMSM() ,当时间到期时,就会在就绪表中选择一个最高优先级的任务执行,
但是最高优先级的任务还是 void TaskKey(void *pdata) 啊???  那难道不会出不来这个任务吗???
其他的任务就没机会执行了啊???? 

5.当这个任务执行完,通过 OSTimeDlyHMSM() 进入等待状态,在OSTimeDlyHMSM()结尾处有 OS_Sched();  ,这个时候
 再次进入PendSV_Handler中断,进入优先级第二高的任务....

6.在每次任务结束后,会进入最高优先级的任务,所以4个任务都会执行。而你的  TaskKey 只有到延时时间到了才会再次执行(当然它
 优先级最高,当时间到了,则马上可以打断其它正在执行的任务
)。






      




        









回复 支持 反对

使用道具 举报

54

主题

248

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
484
金钱
484
注册时间
2012-3-23
在线时间
0 小时
 楼主| 发表于 2012-9-4 11:39:51 | 显示全部楼层
回复【2楼】杨遥:
---------------------------------
taskkey()任务具有最高优先级。

再问个问题。执行延时函数OSTimeDlyHMSM(),在时间到期后,taskkey()任务进入就绪状态,
接着执行已经选择好的任务比如taskled(),在这个taskled()中也是有延时函数OSTimeDlyHMSM()
在时间到期后,是不是会再一次执行taskkey()吗???
从心所欲
回复 支持 反对

使用道具 举报

230

主题

1950

帖子

10

精华

论坛元老

Rank: 8Rank: 8

积分
4562
金钱
4562
注册时间
2010-12-14
在线时间
32 小时
发表于 2012-9-4 11:44:22 | 显示全部楼层
回复【3楼】楚地狂生:
---------------------------------
你记住一点,每次时间到了,就会去查任务就绪表,找出就绪表中优先级高的任务执行即可。
我是开源电子网?网站管理员,对网站有任何问题,请与我联系!QQ:389063473Email:389063473@qq.com
回复 支持 反对

使用道具 举报

98

主题

408

帖子

3

精华

金牌会员

Rank: 6Rank: 6

积分
1280
金钱
1280
注册时间
2010-12-14
在线时间
0 小时
发表于 2012-9-4 11:49:35 | 显示全部楼层
这就是调度的概念。
每次时间到,就会引发任务调度,任务调度就要去任务就绪表中查找最高优先级的就绪任务执行。
比如A在执行,有B和C在就绪状态,那么A的延时开始的时候释放控制权同时引发一次任务调度,任务调度器去查找任务就绪表中的任务,如果B高就执行B,B执行的过程中有高任务的优先级延时到了,也会引发任务调度。这个时候只有A任务延时结束了,它才进入就绪状态,才会去执行他。
希望openedv能给大家提供一个友好的技术交流平台!
回复 支持 反对

使用道具 举报

6

主题

54

帖子

0

精华

初级会员

Rank: 2

积分
99
金钱
99
注册时间
2012-8-31
在线时间
0 小时
发表于 2012-9-4 11:51:26 | 显示全部楼层
就是楼上说的 。

在这个taskled()中也是有延时函数OSTimeDlyHMSM() 
在时间到期后,是不是会再一次执行taskkey()吗???

taskled的时间到后,也会执行taskled.   taskkey与taskled的延时没有关系。

如果系统中断设置1ms,则每1ms进去检测是否有任务时间到。有的话,则进入相应任务。(如果有多个任务时间到,则进入优先级最高的)
回复 支持 反对

使用道具 举报

6

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2014-9-16
在线时间
0 小时
发表于 2014-11-15 11:28:35 | 显示全部楼层
不是延时结束才引发任务调度,延时开始也会引发任务调度
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-29 09:30

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表