教你在STVD环境下移植μC/OS-II到STM8S内核

本文详细介绍了如何在STM8S微控制器上移植μC/OS-II操作系统,包括数据类型定义、处理器相关声明、底层函数编写及移植步骤等关键环节。通过试验验证了系统的稳定性和安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文地址:http://sacredlps.blog.163.com/blog/static/1641440292012299444505/


STM8S移植μC/OS-II

By GDOU Sacredlps

All Rights Reserved

μC/OS-II相信大家都很熟悉了,是由美国嵌入式系统专家JeanJ.Labrosse 一种可移植的,可植入ROM的,可裁剪的,抢占式的,实时多任务操作系统内核。它被广泛应用于微处理器、微控制器和数字信号处理器。包含了任务调度,任务管理,时间管理,内存管理和任务间的通信和同步等基本功能。μC/OS-II可移植到几乎所有微处理器上面允许,既有执行效率高、实时性强、任务切换快的特点,版本从2.00到2.85,下面就以移植2.85为例,在STVD编译环境下移植到最新的ST意法半导体公司生产的STM8SMCU。

STM8S基本特点:8位CPU内核,3级流水线的哈佛结构,内核有6个寄存器,并拥有16位指令,指令执行速率可达0.8Mips/Mhz以上,24位的PC寻址空间可达16M,16位的SP寻址空间可达64KB,拥有不可屏蔽的软中断,由于这些特点使得移值操作系统成为了可能。

缺点是CPU内核没有通用寄存器,使得很多运算都要暂存在RAM里边,RAM的划分变得复杂,在STVD编译环境下,采用的方法是利用堆栈来处理临时性变量,全局变量放在RAM的最低处,这种方法很巧妙,但会使得RAM的使用无规则,在IAR环境下,采用的是在RAM划分一个区域来充当通用寄存器使用。为了在STVD下移植μC/OS-II,不仅要清楚CPU的内部原理,还要认识STVD的编译原理。移植步骤如下:

第一:OS数据类型定义

typedef unsignedchar OS_STK;

typedef unsignedchar BOOLEAN;

typedef unsignedchar INT8U;

typedef signed char INT8S;

typedef unsignedint INT16U;

typedef signed int INT16S;

typedef unsignedlong INT32U;

typedef signed long INT32S;

typedef float FP32;

typedef double FP64;

#defineBYTE INT8S

#defineUBYTE INT8U

#defineWORD INT16S

#defineUWORD INT16U

#defineLONG INT32S

#defineULONG INT32U

第二步:定义与处理器有关的声明

#define OS_CRITICAL_METHOD 2

#if OS_CRITICAL_METHOD==1

#define OS_ENTER_CRITICAL() _asm("SIM");

#define OS_EXIT_CRITICAL() _asm("RIM");

#endif

#if OS_CRITICAL_METHOD==2

#define OS_ENTER_CRITICAL() save_cpusr();

#define OS_EXIT_CRITICAL() restore_cpusr();

#endif

#define OS_STK_GROWTH 1

#define OS_TASK_SW() _asm("TRAP");

第三步:编写底层函数之一【系统开始运行最高优先级的任务】

voidOSStartHighRdy(void)

{

OSTaskSwHook();

#asm

LDWX,[_OSTCBCur.W] //获取最高优先级的SP指针值

LDWSP,X

#endasm

OSRunning=TRUE;

EN_OS_CLK; //开定时器

#asm

IRET

#endasm

}

第四步:编写底层函数之二【上下文任务切换函数】.TRAP中断服务函数

@far@interruptvoidOSCtxSw(void)

{

#asm

LDWX,SP

ADDWX,#6

LDWSP,X

POPA

ANDA,#0XF7

PUSHA //堆栈指针调整

LDW[_OSTCBCur.W],X //保存堆栈指针

#endasm

OSTaskSwHook();

OSTCBCur=OSTCBHighRdy;

OSPrioCur=OSPrioHighRdy;

#asm

POPWX //堆栈调整

LDW0X07,X

POP0X0009

POPWX

LDW0X04,X

POP0X0006

LDWX,[_OSTCBCur.W] //获取堆栈指针

LDWSP,X

IRET

#endasm

}

第五步:编程底层函数之三【中断级任务切换函数】

voidOSIntCtxSw(void)

{

#asm

ADDWSP,#10

POPA

ANDA,#0XF7

PUSHA

LDWX,SP

LDW[_OSTCBCur.W],X //堆栈指针调整和保存

#endasm

OSTaskSwHook();

OSTCBCur=OSTCBHighRdy;

OSPrioCur=OSPrioHighRdy;

#asm

POPWX

LDW0X07,X

POP0X0009

POPWX

LDW0X04,X

POP0X0006

LDWX,[_OSTCBCur.W] //堆栈调整和或者堆栈指针

LDWSP,X

IRET

#endasm

}

第六步:编写底层函数之四【系统时钟函数】.使用定时器中断服务

@far@interruptvoidOSTickISR(void)

{

TIM2->SR1=0X00; //清除定时器标志位

OSIntEnter();

OSTimeTick();

OSIntExit();

}

第七步:编写底层函数之五【堆栈初始化函数】

OS_STK*OSTaskStkInit(void(*task)(void*p_arg),void*p_arg,OS_STK*ptos,

INT16U opt)

{

OS_STK*stk;

(void)opt;

stk =ptos;

*(stk) =(INT8U)((INT16U)task); //PCL

*(--stk)=(INT8U)((INT16U)task>>8); //PCH

*(--stk)=(INT8U)((INT32U)task>>16); //PCE

*(--stk)=0X07; //YL

*(--stk)=0X04; //YH

*(--stk)=0X03; //XL

*(--stk)=0X02; //XH

*(--stk)=0X01; //A

*(--stk)=0X20; //CC

(--stk);

return(stk);

}

第八步:编写临界保护函数【其中MY_CPUSR要在μC/OS-II.H中声明

的全局变量】

voidsave_cpusr(void)

{

(INT8U)MY_CPUSR;

_asm("PUSHCC\nSIM\nPOPA\n");

_asm("LD_MY_CPUSR,A");

}

voidrestore_cpusr(void)

{

_asm("LDA,_MY_CPUSR\nPUSHA\nPOPCC");

}

结束语:

由于STM8S的内核结构和STVD环境下的变量处理方式,在移植μC/OS-II难免会有点复制,需要调整和计算好堆栈指针,临界保护函数也正因为STVD处理临时变量使用的是堆栈所以没有使用μC/OS-II中定义的临时cpu_sr,而使用了全局变量。经过试验在用高频外部中断触发下可以很稳定的运行,也证明了系统的稳定性和安全性。

限于篇幅,移植源文件不再详解,读者可以直接移植这些与处理器有关的函数,并在μC/OS-II.h内声明外部函数便可。如果想要移植好的工程,可以留下邮箱。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值