×
单片机 > 单片机程序设计 > 详情

ucosii在stm32上的移植详解1

发布时间:2020-06-20 发布时间:
|
    虽然目前网上已经有不少关于ucosii在stm32上的移植版本,包括micrium也有官方移植版本。但这些版本具体是怎么移植出来的,又该怎么基于移植好的ucosii开发应用软件,网上介绍的并不多。这里介绍一下我的移植经历,希望对大家有所帮助。

    我的移植基本上是从零开始的。首先想要做好移植,有两方面的内容是必须要了解。1.目标芯片;2.ucosii内核原理。
    虽然我们移植的目标芯片是stm32,但操作系统的移植基本是针对Cortex-M3内核(以下简称CM3)而言的,所以我们只需了解CM3内核就好了。stm32芯片就是CM3内核加上各种各样的外设。
    怎么才能了解CM3呢?看一本书<>(宋岩译,网上多的很)就好了,很多同学可能想,看完这本书移植的新鲜劲都没了,因此我把该书和移植有关的章节都列了出来,并对其中的重点内容进行介绍,我数了数相关章节还不到100页,就这点内容,总要看了吧。

相关章节如下:
chapter2 Cortex-M3概览
2.1 - 2.9 
    主要了解Cortex-M3的概貌。刚开始看时不用追求全部理解,后面会有详细介绍,很多内容多看几遍就明白。其中2.8 指令集,只要了解,CM3只使用thumb2就ok了。

chapter3 Cortex-M3基础
3.1 寄存器组
    R0-R12: 通用寄存器
   
    R13: 堆栈寄存器
      有两个,MSP和PSP,同时只能看见一个
      引用R13时,引用的是正在使用的那个
      MSP:可用于异常服务和应用程序
      PSP:只能用于应用程序
      系统复位后,用的堆栈指针是MSP。
 
    R14: 连接寄存器,又名LR
       存储返回地址

    R15: 程序计数寄存器,又名PC

3.2 特殊功能寄存器
    程序状态字寄存器组(PSRs)
    中断屏蔽寄存器组(PRIMASK, FAULTMASK, BASEPRI)
    控制寄存器(CONTROL)
   
    程序状态字寄存器组(PSRs)分为
       应用程序 PSR(APSR)
       中断号 PSR(IPSR)
       执行 PSR(EPSR)
    
    每个都是32位,由于这3个寄存器有效位是错开的,因此可以组合访问。

    中断屏蔽寄存器组(PRIMASK, FAULTMASK, BASEPRI)
    这三个寄存器用于控制异常的使能和除能。

    控制寄存器(CONTROL)
    它有两个作用:
       1.定义特权级别
       2.选择当前使用哪个堆栈指针

3.3 操作模式和特权极别
    操作模式: 处理者模式和线程模式
    异常处理:处理者模式
    主程序:线程模式

    ucosii不区分特权级和用户级,程序始终工作在特权级
    这两个堆栈指针的切换是全自动的,就在出入异常服务例程时由硬件处理。

3.4 - 3.7
    没什么好讲的,需要看。

3.8 复位序列
    0x00000000 MSP初值
    0x00000004 PC初值 复位向量

chapter7 异常
7.1 异常类型
    分为系统异常(编号1-15)和外部中断(大于15)

7.2 优先级
    CM3支持3个固定的高优先级和多达256级的可编程优先级。
    在NVIC中,每个中断都有一个优先级配置寄存器(1个byte),用来配置该中断的优先级。但该寄存器并不是每个位都被使用,不同制造商生产的芯片不相同,譬如stm32使用4位,也就是说stm32支持16个可编程优先级(参考:chapter9) 。
    注意该寄存器是以MSB对齐的,因此stm32每个中断的优先级配置寄存器7:4位有效,3:0位无效。

    对于优先级,CM3又分为抢占优先级和亚优先级,
    NVIC中的应用程序中断及复位控制寄存器(AIRCR)的优先级分组(10:8)描述了如何划分抢占优先级和亚优先级。
    什么意思?以stm32为例,优先级配置寄存器不是7:4位有效吗,如果AIRCR中的优先级分组值为4,则优先级配置寄存器的7:5位确定抢占优先级,位4确定亚优先级。此时所有中断有8个抢占优先级,每个抢占优先级有2个亚优先级。
    抢占优先级高的中断可以抢占抢占优先级低的中断,即抢占优先级决定了中断是否可以嵌套。
    相同抢占优先级的中断不能嵌套,但当抢占优先级相同的异常有不止一个到来时,就优先响应亚优先级最高的异常。
    参考附录D 
    表D.9 中断优先级寄存器阵列 0xE000_E400 - 0xE000_E4EF 共240个。
    表D.16系统异常优先级寄存器 0xE000_ED18 - 0xE000_ED23 共12个。

    优先级相同,看中断号,中断号小的优先。

7.3 向量表  
    初始在0x00000000处,可以通过向量表偏移量寄存器(VTOR)(地址:0xE000_ED08)更改,一般无需更改。

7.4 中断输入及挂起行为
    需要看。

7.5 Fault异常
    可不看。

7.6 SVC和PendSV
    SVC主要用在分特权级和用户级的操作系统,ucosii不区分特权级和用户级,可以不管这个东西。

    这里说点题外话,一开始我很奇怪为什么会提供这种中断,因为这种中断一般都是用在大型的操作系统上,如linux系统上,可CM3又不提供MMU,应该是无法移植linux系统。后来我才知道uclinux是针对没有MMU的嵌入式系统而设计的,不过还是很怀疑有人会在像stm32这种芯片上用uclinux。

    PendSV
    PendSV中断主要做上下文切换,也就是任务切换,是ucosii移植过程中最重要的中断。
    主要有两点:
    1.PendSV中断是手工往NVIC的PendSV悬起寄存器中写1产生的(由OS写)。
    2.PendSV中断优先级必须设为最低。

    在讲移植代码时会介绍具体是如何做的。
    对于7.6的PendSV部分应认真研读一下。

chapter8 NVIC与中断控制
    NVIC负责芯片的中断管理,它和CM3内核紧密相关。
    如果对于CM3中断配置不是很了解,可以看看8.1, 8.2, 8.3, 8.4节。
    8.7节讲述了SysTick定时器,需要看。

chapter9 中断的具体行为
9.1 中断/异常的响应序列
    当CM3开始响应一个中断时
    1.xPSR, PC, LR, R12以及R3‐R0入栈
    2.取向量
    3.选择堆栈指针MSP/PSP,更新堆栈指针SP,更新连接寄存器LR,更新程序计数器PC
   
   对移植ucosii来说,需要注意1,3

9.2 异常返回
    在CM3中,进入中断时,LR寄存器的值会被自动更新。
    9.6节对更新后的值进行说明。这里统称EXC_RETURN。
    返回时通过把EXC_RETURN往PC里写来识别返回动作的。
    因为EXC_RETURN是一个特殊值,所以对于CM3,汇编语言就不需要类似reti这种指令,而用C语言开发时,不需要特殊编译器命令指示一个函数为中断服务程序。实际上,中断服务程序如果是c代码编写,汇编成汇编代码,函数结尾一般是reti。
 
9.3 嵌套的中断
    只要注意:中断嵌套不能过深即可。

9.4和9.5
    这两节说明CM3对中断的响应能力大大提高了,主要是硬件机制的改进。
    但对移植来说,并不需要关注。

9.6 异常返回值
    对不同状态进入中断时,LR寄存器的值进行说明,需要看。
    这里有一点需要注意,该点在讲移植代码时再介绍。

9.7和9.8
    对移植来说,并不需要关注。

chapter10 Cortex-M3的低层编程
    这一章仅需关注10.2节,因为对移植来说汇编与C的接口是必须面对的。
10.2 汇编与C的接口
    有两点需要知道:
    1.当主调函数需要传递参数(实参)时,它们使用R0‐R3。其中R0传递第一个,R1传递第2个……在返回时,把返回值写到R0中。
    2.在函数中,用汇编写代码时,R0-R3, R12可以随便使用,而使用R4‐R11,则必须先PUSH,后POP。

    以上内容和移植多少都有些关系,刚开始看,可能不太明白,多看几遍就好了。

关键字:ucosii  stm32  移植详解

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
STM32 USB HID 键盘