STM32入门学习笔记之uCOS-II系统移植3

⑤这两个函数都用于任务切换,它们的本质都是触发pendsv中断,具体切换过程在pendsv的中断函数中进行,其中osctxsw是任务级切换,osintctxsw是中断级切换,是从中断退出时切换到一个任务中,从中断切换到任务的过程中,cpu的寄存器入栈工作已经完成。
osctxsw push {r4, r5} ldr r4, =nvic_int_ctrl ;触发pendsv异常 ldr r5, =nvic_pendsvset str r5, [r4] ;向nvic_int_ctrl写入nvic_pendsvset触发pendsv中断 pop {r4, r5} bx lrosintctxsw push {r4, r5} ldr r4, =nvic_int_ctrl ;触发pendsv异常 ldr r5, =nvic_pendsvset str r5, [r4] ;向nvic_int_ctrl写入nvic_pendsvset触发pendsv中断 pop {r4, r5} bx lr nop⑥这部分代码才是真正的任务切换函数,通过触发pendsv中断来进入该函数内进行任务切换
pendsv_handler cpsid i ;任务切换过程中必须关闭所有中断 mrs r0, psp ;如果在用psp堆栈,则可以忽略保存寄存器 cbz r0, pendsv_handler_nosave ;如果psp为0就转移到pendsv_handler_nosave subs r0, r0, #0x20 ;r0-=20h stm r0, {r4-r11} ldr r1, =ostcbcur ldr r1, [r1] str r0, [r1]pendsv_handler_nosave push {r14} ;保存r14的值 ldr r0, =ostaskswhook ;调用ostaskswhook() blx r0 pop {r14} ldr r0, =ospriocur ldr r1, =ospriohighrdy ldrb r2, [r1] strb r2, [r0] ldr r0, =ostcbcur ldr r1, =ostcbhighrdy ldr r2, [r1] str r2, [r0] ldr r0, [r2] ;r0作为新任务的sp ldm r0, {r4-r11} ;从堆栈中恢复r4-r11 adds r0, r0, #0x20 msr psp, r0 ;用新任务的sp加载psp orr lr, lr, #0x04 ;确保lr的bit2为1,返回后使用进程堆栈 cpsie i ;开启所有中断 bx lr ;中断返回 end(2)os_cpu.h文件详解
①这部分主要用于定义一些数据类型,其中重点关注os_stk这个数据类型,我们在定义任务堆栈的时候就是该类型数据,这是一个32位的数据类型,按字节算的话实际堆栈大小是我们定义的4倍。
typedef unsigned char boolean;typedef unsigned char int8u;typedef signed char int8s;typedef unsigned short int16u;typedef signed short int16s;typedef unsigned int int32u;typedef signed int int32s;typedef float fp32;typedef double fp64;typedef unsigned int os_stk;typedef unsigned int os_cpu_sr;②这部分代码定义了堆栈的增长方向,任务机切换的宏定义os_task_sw,如果os_critical_method被定义为3的话那么进出临界段的宏定义分别为os_enter_critical和os_exit_critical,这两个函数都是用汇编语言编写的
//os_critical_method = 1 :直接使用处理器的开关中断指令来实现宏 //os_critical_method = 2 :利用堆栈保存和恢复cpu的状态 //os_critical_method = 3 :利用编译器扩展功能获得程序状态字,保存在局部变量cpu_sr#define os_critical_method 3 //进入临界段的方法#if os_critical_method == 3#define os_enter_critical() {cpu_sr = os_cpu_sr_save();}#define os_exit_critical() {os_cpu_sr_restore(cpu_sr);}#endifvoid osctxsw(void);void osintctxsw(void);void osstarthighrdy(void);void ospendsv(void);#if os_critical_method == 3uos_cpu_sr os_cpu_sr_save(void);void os_cpu_sr_restore(os_cpu_sr cpu_sr);#endifos_cpu_ext int32u osinterrputsum;(3)sys.h文件修改
添加关于条件编译的定义,在文件中添加以下代码即可。
#define system_support_os 1
当宏定义为1的时候,编译器在编译的时候会只编译满足条件的代码,当为0时,这部分代码不会被编译。
(4)delay.c文件修改
①添加sys_tick中断服务函数与函数定义
#include includes.h//支持ucosii#ifdef os_critical_method#define delay_osrunning osrunning //os是否运行标记,0,不运行;1,在运行#define delay_ostickspersec os_ticks_per_sec //os时钟节拍,即每秒调度次数#define delay_osintnesting osintnesting //中断嵌套级别,即中断嵌套次数#endif//systick中断服务函数,使用os时用到void systick_handler(){ //os开始跑了,才执行正常的调度处理 if( delay_osrunning==1 ) { osintenter() ; //进入中断 ostimetick() ; //调用ucos的时钟服务程序 osintexit() ; //触发任务切换软中断 }}②时钟初始化函数修改
void systick_init( u8 sysclk ){#if system_support_os u32 reload;#endif systick->ctrl &= ~( 1ctrl |= 1<<0 ; //开启systick#else fac_ms = ( u16 )fac_us*1000 ; //代表每个ms需要的systick时钟数#endif}

LDR6328Q小家电PCBA多协议快充取电方案
橙群微电子NanoBeacon打破障碍: 实现令人瞩目的 2.61 千米长距离测试里程碑!
基于Fluent的18650锂电池热分析实操
美国空军正在考虑采用SAOC WS来取代波音E-4B末日飞机操作中心
把面向数字家庭的Adobe Flash引进到MIPS-Based平台
STM32入门学习笔记之uCOS-II系统移植3
一个简单的恒流齐纳二极管电路
路虎揽胜星脉的设计理念是革新性的,星光闪耀、高贵夺目的路虎揽胜星脉,8月18震撼上市!
介绍下集成电路MOS管的基础
薄膜图像传感技术实现柔性薄膜指纹和掌纹识别
中国薄膜太阳能电池行业产量及市场竞争现状分析
彩色时代的现代经典黑与白 vivo S6展现黑白艺术魅力
电动汽车HVAC系统的不同之处
三星注册新商标,它或许也要加入研发区块链智能手机的大军了
电机技术的参数
17亿元收购思立微背后,兆易创新在下一盘大棋!
优秀试验设计的8个专业建议
赋能高效化之路丨极海APM32F407低压伺服驱动器应用方案
人工智能方面专业大受应届考生青睐
高通第三财季营收96亿美元 净利润同比增79%