完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
最近在学UC/OS II, 对于里面有一个临界段不是很理解。
OS_ENTER_CRItiCAL(); (1) . . (2) OS_EXIT_CRITICAL();(3) 书上说(1)是关中断 (3)是开中断。 我的问题是:UC/OS II里面是软中断来切换任务,那意思就是说(2)里面不能切换任务吗??? 还是(2)里面可以切换任务,那关的中断是硬件中断,而非所以中断???? |
|
相关推荐
10个回答
|
|
我的理解.
(1)的作用是让ucos无法再执行任务调度,也就是执行1之后,ucos处于关闭状态. (2)区域用于处理比较连续的事情,不希望被ucos打断. (3)用于恢复ucos的任务调度功能.重新开启ucos. 至于硬中断能否打断(2)的执行,就要看(1)里面是怎么做的 了. |
|
|
|
OS_cpu_a.asm文件中:
OS_ENTER_CRITICAL CPSID I ; Disable all the interrupts PUSH {R1,R2} LDR R1, =OSInterrputSum ; OSInterrputSum++ LDRB R2, [R1] ADD R2, R2, #1 STRB R2, [R1] POP {R1,R2} BX LR ;/*************************************************************************************** ;* 函数名称: OS_EXIT_CRITICAL ;* ;* 功能描述: 退出临界区 ;* ;* 参 数: None ;* ;* 返 回 值: None ;*****************************************************************************************/ OS_EXIT_CRITICAL PUSH {R1, R2} LDR R1, =OSInterrputSum ; OSInterrputSum-- LDRB R2, [R1] SUB R2, R2, #1 STRB R2, [R1] MOV R1, #0 CMP R2, #0 ; if OSInterrputSum=0,enable ; interrupts如果OSInterrputSum=0, MSREQ PRIMASK, R1 POP {R1, R2} BX LR -------------------------------------- 我的理解是硬中断+软中断, 我写过一段测试代码测试OS_ENTER_CRITICAL(),OS_EXIT_CRITICAL(); #include "sys.h" #include "usart.h" #include "delay.h" #include "led.h" #include "key.h" #include "includes.h" //Mini STM32开发板扩展实例 8 //ucos 实验 //发烧友@ALIENTEK //2010.12.25 //设置任务堆栈大小 #define LED_STK_SIZE 64 #define LED1_STK_SIZE 64 #define START_STK_SIZE 128 #define USART_STK_SIZE 64 //设置任务优先级 #define LED_TASK_Prio 5 #define LED1_TASK_Prio 9 #define USART_TASK_Prio 8 #define START_TASK_Prio 10 //这个任务的优先级应该是最高的 //任务堆栈 OS_STK TASK_LED1_STK[LED_STK_SIZE]; OS_STK TASK_LED_STK[LED_STK_SIZE]; OS_STK TASK_START_STK[START_STK_SIZE]; OS_STK TASK_USART_STK[USART_STK_SIZE]; //任务申明 void TaskStart(void *pdata); void TaskLed(void *pdata); void TaskLed1(void *pdata); void TaskUsart(void *pdata); //系统时钟配置函数 void SysTick_Configuration(void); INT32U time1=0; INT32U time2=0; //Mini STM32开发板ucos范例 //基于ucos2.52内核. //张洋@ALIENTEK //www.openedv.com //2010.12.15 /** * OS_ENTER_CRITICAL(),OS_EXIT_CRITICAL()之间的代码段构成临界段,此段代码不能被中断打断, *也就是说,在执行此段代码的过程中不进行任务调度,那么期间即使有高优先级的任务等待时间到达,那么也不能立即获得cpu的控制权 **/ void _delay(INT32U times){ while(times--); } int main(void) { INT8U state; Stm32_Clock_Init(9); //系统时钟设置 delay_init(72); //延时初始化 uart_init(72,9600); //串口初始化为9600 LED_Init(); //初始化与LED连接的硬件接口 SysTick_Configuration(); OSInit(); state=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 if(state==OS_PRIO_EXIST){} OSStart(); //开始调度 return 0; } //开始任务 void TaskStart(void * pdata) { pdata = pdata; //防止某些编译器报错 OS_ENTER_CRITICAL(); OSTaskCreate(TaskLed, (void *)0, &TASK_LED_STK[LED_STK_SIZE-1], LED_TASK_Prio); OSTaskCreate(TaskLed1, (void *)0, &TASK_LED1_STK[LED1_STK_SIZE-1], LED1_TASK_Prio); // OSTaskCreate(TaskUsart,(void *)0, &TASK_USART_STK[USART_STK_SIZE-1],USART_TASK_Prio); OSTaskSuspend(START_TASK_Prio); //suspend but not delete OS_EXIT_CRITICAL(); } //任务1 //控制DS0的亮灭. void TaskLed(void *pdata) { while(1) { LED0=!LED0; printf("TaskLED0...LED0=%dn",LED0); OSTimeDlyHMSM(0,0,0,100);//500ms } } //任务2 //控制DS1的亮灭. void TaskLed1(void *pdata) { while(1) { LED1=!LED1; printf("TaskLED1...LED1=%dn",LED1); OS_ENTER_CRITICAL(); printf("enter Critical...n"); _delay(1000000); printf("exit Critical...n"); OS_EXIT_CRITICAL(); printf("enter Active...n"); _delay(1000000); printf("exist Active...n"); OSTimeDlyHMSM(0,0,0,200);//500ms } } |
|
|
|
这个地方我理解也不透,楼主如果找到相关资料理解了,麻烦分享,谢谢!
|
|
|
|
回复【3楼】张洋:
------------------------------- 我也测了一下, OS_ENTER_CRITICAL(); (1) . . (2) OS_EXIT_CRITICAL();(3) (2)里面会出现任务调度的情况,在OS_ENTER_CRITICAL()里面用的了SPID I,关掉所有的中断,但是还会出现任务调度,真是不可理解。书上说任务调度也是用的中断来的,所有这样结果说明 SPID I不能把OSPendSV 中断禁止。 |
|
|
|
回复【3楼】张洋:
------------------------------- #include "includes.h" //UC/OS II 信号量实验 //Julius //13/04/2011 //声明信号量 INT8U err; OS_EVENT *Fun_Semp; //设置任务堆栈大小 #define LED_STK_SIZE 64 #define LED1_STK_SIZE 64 #define START_STK_SIZE 128 //设置任务优先级 #define LED_TASK_Prio 9 #define LED1_TASK_Prio 5 #define START_TASK_Prio 10 //任务堆栈 OS_STK TASK_LED1_STK[LED_STK_SIZE]; OS_STK TASK_LED_STK[LED_STK_SIZE]; OS_STK TASK_START_STK[START_STK_SIZE]; //任务申明 void TaskStart(void *pdata); void TaskLed(void *pdata); void TaskLed1(void *pdata); int main(void) { Wait_ms(1);//Ensure I/O is ready OSInit(); Fun_Semp = OSSemCreate(1); //定义信号量 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; CPU_Init(); Wait_ms(5); LED0=LED1=1; //OSStatInit(); 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); OSTaskSuspend(START_TASK_Prio);//suspend but not delete OS_EXIT_CRITICAL(); //开中断 } //任务1 //控制led0 led1 全亮. void TaskLed(void *pdata) { pdata=pdata; while(1) { OSSemPend(Fun_Semp,0,&err); //请求信号量 printf("task0"); LED0=!LED0; OSSemPost(Fun_Semp); OSTimeDlyHMSM(0,0,2,0); } } //任务2 //控制led0 led1的全灭. void TaskLed1(void *pdata) { pdata=pdata; while(1) { OSSemPend(Fun_Semp,0,&err); //请求信号量 printf("task1"); LED1=!LED1; OSSemPost(Fun_Semp); OSTimeDlyHMSM(0,0,4,0); } } 这段串口的输出结果是:task0task1task0task0task1task0task1task0task0task1task0task0task1task0task0task1task0task0task1task0 如果临界段里不出现切换任务的话,应该是task1 先输出的,因为一开中断优先级是TaskLed1高于TaskLed的,你的“#define START_TASK_Prio 10 //这个任务的优先级应该是最高的”这里应该错了,书上说越小优先级越高的。 所有对于这个关中断很迷惑。 |
|
|
|
引用自 1楼 ???????????? 的回复: 我的理解.
(1)的作用是让ucos无法再执行任务调度,也就是执行1之后,ucos处于关闭状态. (2)区域用于处理比较连续的事情,不希望被ucos打断. (3)用于恢复ucos的任务调度功能.重新开启ucos. 至于硬中断能否打断(2)的执行,就要看(1)里面是怎么做的 了. (1)和(3)中间确实不能进行调度,但是能够向中断控制器申请一个特殊的中断,此时(2)该中断产生但是不能响应,因为此时全局中断是关闭的。等(3)之后,全局中断打开,那么core自动响应在(2)时刻的中断。 你应该知道(2)那时候申请的是什么中断吧 |
|
|
|
引用自 4楼 Julius007 的回复: 回复【3楼】张洋:
------------------------------- 我也测了一下, OS_ENTER_CRITICAL(); (1) . . (2) OS_EXIT_CRITICAL();(3) (2)里面会出现任务调度的情况,在OS_ENTER_CRITICAL()里面用的了SPID I,关掉所有的中断,但是还会出现任务调度,真是不可理解。书上说任务调度也是用的中断来的,所有这样结果说明 SPID I不能把OSPendSV 中断禁止。 SPID I已经把OSPendSV 中断禁止了,所以在(2)只能申请这个OSPendSV ,但是core不会相应的。等打开全局中断后,core才会响应OSPendSV 中断。才会进一步调度任务。这点正是m3的精妙所在,任务级别的调度转化成中断级别的调度,所以ucosii才只需要一个调度处理函数,i |
|
|
|
|
|
|
|
在关闭全局中断的时候,基本都是内核在做关键操作,随后要申请任务调度。此时只需要作次OSPendSV申请 ,然后再打开
全局中断。再然后,core响应OSPendSV 中断请求。在OSPendSV 的isr中完成任务调度。 |
|
|
|
|
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1781 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1621 浏览 1 评论
1085 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
728 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1680 浏览 2 评论
1938浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
732浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
570浏览 3评论
596浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
559浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 13:01 , Processed in 0.828059 second(s), Total 65, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号