硬汉嵌入式论坛

 找回密码
 立即注册
查看: 5637|回复: 0
收起左侧

[μCOS-III] 记录μCOS-III第五期任务切换配套例子的问题

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107527
QQ
发表于 2014-2-11 13:16:31 | 显示全部楼层 |阅读模式
共为第五期教程配套了三个例子。
1. SVC的使用
2. 任务切换设计(支持简易时间片调度不带浮点运算)
3. 任务切换设计(支持简易时间片调度带浮点运算)

这三个例子搞懂后,学习uCOS-III的任务切换基本无压力,剩下就是用心学习uCOS-III源码

问题一:如果程序采用下面的写法,会进入硬件异常。
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: main
  4. *    功能说明: c程序入口
  5. *    形    参:无
  6. *    返 回 值: 错误代码(无需处理)
  7. *********************************************************************************************************
  8. */
  9. int main(void)
  10. {
  11.     /* (在Cortex-M3 r1p1中需要开启,Cortex-M3 r2px 和 Cortex-M4是默认开启的) */
  12.     SCB->CCR |= SCB_CCR_STKALIGN_Msk; /* 使能双字的堆栈对齐方式 */
  13.    
  14.     bsp_Init();            /* 硬件初始化 */
  15.    
  16.     PrintfLogo();        /* 打印例程信息到串口1 */
  17.    
  18.      OS_Start();
  19.     /* 启动任务0 */
  20.     task0();      
  21.     /* 进入主程序循环体 */
  22.     while (1)
  23.     {
  24.         stop_cpu;
  25.     }
  26. }
复制代码
  1. void OS_Start(void)
  2. {
  3.     /* 创建任务0的堆栈 */
  4.     PSP_array[0] = ((unsigned int) task0_stack) + (sizeof task0_stack) - 16*4;
  5.     HW32_REG((PSP_array[0] + (14<<2))) = (unsigned long) task0; /* PC */
  6.     HW32_REG((PSP_array[0] + (15<<2))) = 0x01000000;            /* xPSR */
  7.         
  8.     /* 创建任务1的堆栈 */
  9.     PSP_array[1] = ((unsigned int) task1_stack) + (sizeof task1_stack) - 16*4;
  10.     HW32_REG((PSP_array[1] + (14<<2))) = (unsigned long) task1; /* PC */
  11.     HW32_REG((PSP_array[1] + (15<<2))) = 0x01000000;            /* xPSR */
  12.     /* 创建任务2的堆栈 */
  13.     PSP_array[2] = ((unsigned int) task2_stack) + (sizeof task2_stack) - 16*4;
  14.     HW32_REG((PSP_array[2] + (14<<2))) = (unsigned long) task2; /* PC */
  15.     HW32_REG((PSP_array[2] + (15<<2))) = 0x01000000;            /* xPSR */
  16.     /* 创建任务3的堆栈 */
  17.     PSP_array[3] = ((unsigned int) task3_stack) + (sizeof task3_stack) - 16*4;
  18.     HW32_REG((PSP_array[3] + (14<<2))) = (unsigned long) task3; /* PC */
  19.     HW32_REG((PSP_array[3] + (15<<2))) = 0x01000000;            /* xPSR */
  20.    
  21.     /* 任务0先执行 */
  22.     curr_task = 0;
  23.      
  24.     /* 设置PSP指向任务0堆栈的栈顶 */
  25.     __set_PSP((PSP_array[curr_task] + 16*4));
  26.    
  27.     /* 设置PendSV中断为最低优先级中断 */
  28.     NVIC_SetPriority(PendSV_IRQn, 0xFF);
  29.    
  30.     /* 设置嘀嗒定时器的中断时1ms */
  31.     SysTick_Config(SystemCoreClock / 1000);
  32.      
  33.     /* 使用堆栈指针,非特权级状态 */
  34.     __set_CONTROL(0x3);
  35.    
  36.     /* 改变CONTROL后执行ISB (architectural recommendation) */
  37.     __ISB();
  38. }
复制代码
按照上面的方式程序会进入硬件异常,串口打印结果如下:
1.png

造成上面问题的原因就在于从主堆栈指针MSP切换到进程堆栈指针PSP。在main函数中调用子函数OS_State后
部分寄存器会入栈,如果在这个子程序中做堆栈指针切换,退出的时候是用的PSP而不是MSP,用MSP入栈的寄
存器数据将无法返回,从而造成失败。
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-6-5 01:18 , Processed in 0.148258 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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