完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
mini/OS嵌入式系统内核揭秘(1) 以下贴出mini/OS汇编部分的代码:
;/*********************** (C) COPYRIGHT 2010 Libraworks ************************* ;* File Name: os_cpu_a.asm ;* Author: Librae ;* Version: V1.0 ;* Date: 06/10/2010 ;* Description: μCOS-II asm port for STM32 ;*******************************************************************************/ IMPORT OSCurTCB ; External references IMPORT OSNewTCB IMPORT OSTaskSwHook EXPORT OSStartTask EXPORT OSCtxSw EXPORT OSIntCtxSw EXPORT OS_CPU_SR_Save ; Functions declared in this file EXPORT OS_CPU_SR_Restore EXPORT PendSV_Handler NVIC_PENDSV_PRI EQU 0xFFFF0000 ; PendSV priority value (lowest) NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2) RESERVE8 AREA |.text|, CODE, READONLY THUMB ;******************************************************************************************************** ; CRITICAL SECTION METHOD 3 FUNCTIONS ; ;********************************************************************************************************OS_CPU_SR_Save MRS R0, PRIMASK ;读取PRIMASK到R0,R0为返回值 CPSID I RIMASK=1,关中断(NMI和硬件FAULT可以响应) BX LR ;返回OS_CPU_SR_Restore MSR PRIMASK, R0 ;读取R0到PRIMASK中,R0为参数;open interrupt BX LR ;返回 ;/************************************************************************************** ;* 函数名称: OSStartTask ;* ;* 功能描述: 使用调度器运行第一个任务 ;* ;* 参 数: None ;* ;* 返 回 值: None ;**************************************************************************************/ OSStartTask LDR R4, =NVIC_SYSPRI2 ; set the PendSV exception priority LDR R5, =NVIC_PENDSV_PRI STR R5, [R4] MOV R4, #0 ; set the PSP to 0 for initial context switch call MSR PSP, R4 ;切换到最高优先级的任务 LDR R4, =NVIC_INT_CTRL ;rigger the PendSV exception (causes context switch) LDR R5, =NVIC_PENDSVSET ;触发PendSV异常 (causes context switch) STR R5, [R4] CPSIE I ;enable interrupts at processor level OSStartHang B OSStartHang ;should never get here;/************************************************************************************** ;* 函数名称: OSCtxSw ;* ;* 功能描述: 任务级上下文切换 ;* ;* 参 数: None ;* ;* 返 回 值: None ;***************************************************************************************/ OSCtxSw USH {R4, R5} LDR R4, =NVIC_INT_CTRL ;触发PendSV异常 (causes context switch) LDR R5, =NVIC_PENDSVSET STR R5, [R4] OP {R4, R5} BX LR NOP;/************************************************************************************** ;* 函数名称: OSIntCtxSw ;* ;* 功能描述: 中断级任务切换 ;* ;* 参 数: None ;* ;* 返 回 值: None ;***************************************************************************************/OSIntCtxSw USH {R4, R5} LDR R4, =NVIC_INT_CTRL ;触发PendSV异常 (causes context switch) LDR R5, =NVIC_PENDSVSET STR R5, [R4] OP {R4, R5} BX LR NOP ;/************************************************************************************** ;* 函数名称: OSPendSV ;* ;* 功能描述: OSPendSV is used to cause a context switch. ;* ;* 参 数: None ;* ;* 返 回 值: None ;***************************************************************************************/PendSV_Handler CPSID I ; Prevent interruption during context switch MRS R0, PSP ; PSP is process stack pointer 如果在用PSP堆栈,则可以忽略保存寄存器,参考CM3权威中的双堆栈-白菜注 CBZ R0, PendSV_Handler_Nosave ; Skip register save the first time SUBS R0, R0, #0x20 STM R0, {R4-R11} ; Save remaining regs r4-11 on process stack LDR R1, =OSCurTCB LDR R1, [R1] STR R0, [R1] ; R0 is SP of process being switched out PendSV_Handler_Nosave PUSH {R14} ; Save LR exc_return value LDR R0, =OSTaskSwHook ; OSTaskSwHook(); BLX R0 POP {R14} LDR R0, =OSCurTCB ;OSCurTCB=OSNewTCB; LDR R1, =OSNewTCB LDR R2, [R1] STR R2, [R0] LDR R0, [R2] ; R0 is new process SP; SP = OSCurTCB; LDM R0, {R4-R11} ; Restore r4-11 from new process stac ADD R0, R0, #0x20 MSR PSP, R0 ORR LR, LR, #0x04 CPSIE I ; Exception return will restore remaining context BX LR end 仔细看汇编部分,是否就是ucos在stm32系统上移植的翻版?利用以上汇编部分代码,你就可以不管汇编部分,专心做c语言部分任务调度方面的事了。该任务调度时调用OSCtxSw(),传递不同任务的堆栈指针OSCurTCB,OSNewTCB就完成了新旧任务之间的切换。 再来看看OSCurTCB,OSNewTCB分别是什么。 typedef struct taskControlBlock { /*当前的栈顶指针*/ OS_STK *pStackTop; /*当前优先级*/ RIO_TYPE CurPriority; /*任务状态*/ uint8 TaskStat; /*等待时间片的个数*/ int32 TCBDelay; } TCB; /*当前运行的任务*/ TCB *OSCurTCB;/*当前准备新运行的任务*/ TCB *OSNewTCB; /*当前OS中所有的任务*/ uint8 TaskNUM=0;TCB OSTCBTable[MAX_TASK_NUM]; 可见OSCurTCB和OSNewTCB分别是当前运行任务的堆栈指针和要运行的新任务的堆栈指针。 下面关心的可能是任务的创建了,任务是如何创建的。每个任务都有自己的堆栈空间,就像是单独占用CPU一样,所以创建任务的一方面主要是完成任务堆栈的初始化。 以下是c语言写的任务堆栈的初始化函数,位于文件OS_CPU.c中,如果需要移植,除了汇编部分OS_CPU_A.asm文件修改外,OS_CPU.c和OS_TYPE.h等文件也需要修改。仅这几个文件,所以mini/OS移植很简单。 OS_STK实际上就是int32,因为stm32上堆栈指针就是32位长度。第一个参数是任务的地址,即函数的地址,第二个参数是任务的堆栈指针。 OS_STK *OSTaskStkInit (void (*task),OS_STK *ptos) { OS_STK *stk; // (void)PSR; /* 'PSR' is not used, prevent warning */ stk = ptos; /* 获取堆栈指针 */ /* Registers stacked as if auto-saved on exception */ *(stk) = (uint32)0x01000000L; /* xPSR */ *(--stk) = (uint32)task; /* Entry Point */ *(--stk) = (uint32)0xFFFFFFFEL; /* R14 (LR) (init value will cause fault if ever used)*/ *(--stk) = (uint32)0x12121212L; /* R12 */ *(--stk) = (uint32)0x03030303L; /* R3 */ *(--stk) = (uint32)0x02020202L; /* R2 */ *(--stk) = (uint32)0x01010101L; /* R1 */ *(--stk) = (uint32)0; /* R0 : argument */ /* Remaining registers saved on process stack */ *(--stk) = (uint32)0x11111111L; /* R11 */ *(--stk) = (uint32)0x10101010L; /* R10 */ *(--stk) = (uint32)0x09090909L; /* R9 */ *(--stk) = (uint32)0x08080808L; /* R8 */ *(--stk) = (uint32)0x07070707L; /* R7 */ *(--stk) = (uint32)0x06060606L; /* R6 */ *(--stk) = (uint32)0x05050505L; /* R5 */ *(--stk) = (uint32)0x04040404L; /* R4 */ return (stk); } |
|
相关推荐 |
|
只有小组成员才能发言,加入小组>>
800 浏览 0 评论
1156 浏览 1 评论
2531 浏览 5 评论
2863 浏览 9 评论
移植了freeRTOS到STMf103之后显示没有定义的原因?
2714 浏览 6 评论
keil5中manage run-time environment怎么是灰色,不可以操作吗?
1089浏览 3评论
195浏览 2评论
461浏览 2评论
374浏览 2评论
M0518 PWM的电压输出只有2V左右,没有3.3V是怎么回事?
456浏览 1评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 21:51 , Processed in 0.975160 second(s), Total 77, Slave 57 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号