移植ucosII到STM32F103ZE(四)

发布者:caijt最新更新时间:2015-10-23 来源: eefocus关键字:移植  ucosII  STM32F103ZE 手机看文章 扫描二维码
随时随地手机看文章
a)      根据stm32f103芯片对系统文件进行修改
根据AN-1018.pdf 和移植详解介绍的移植基础知识,对OS-uCOSIIport 下的代码解释下。
并进行相关特性修改。
os_cpu.h
#ifdef    OS_CPU_GLOBALS  
#define  OS_CPU_EXT  
#else  
#define  OS_CPU_EXT  extern  
#endif 
 
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; 
因为 CM3 是32 位宽的,所以 OS_STK(堆栈的数据类型)被类型重定义为 unsigned int。
因为 CM3 的状态寄存器(xPSR)是32位宽的,因此 OS_CPU_SR 被类型重定义为 unsigned int。
OS_CPU_SR 是在OS_CRITICAL_METHOD 方法 3 中保存 cpu 状态寄存器用的。在 CM3 中,移植OS_ENTER_CRITICAL(),OS_EXIT_CRITICAL()选方法 3 是最合适的。
#define  OS_CRITICAL_METHOD  
 
#if  OS_CRITICAL_METHOD        
     #define  OS_ENTER_CRITICAL()  {cpu_sr = OS_CPU_SR_Save();}  
     #define  OS_EXIT_CRITICAL()   {OS_CPU_SR_Restore(cpu_sr);}  
#endif 
具体定义宏OS_ENTER_CRITICAL() 和OS_EXIT_CRITICAL()其中OS_CPU_SR_Save() 和OS_CPU_SR_Restore()是用汇编代码写的,代码在 os_cpu_a.asm 中,到时再解释。
#define  OS_STK_GROWTH        
CM3 中,栈是由高地址向低地址增长的,因此 OS_STK_GROWTH定义为 1。
#define OS_TASK_SW()  OSCtxSw()  
定义任务切换宏,OSCtxSw()是用汇编代码写的,代码在 os_cpu_a.asm 中,到时再解释。
#if OS_CRITICAL_METHOD                                
     OS_CPU_SR  OS_CPU_SR_Save(void);  
     void           OS_CPU_SR_Restore(OS_CPU_SR cpu_sr);  
#endif 
 
void       OSCtxSw(void);  
void       OSIntCtxSw(void);  
void       OSStartHighRdy(void);  
void       OS_CPU_PendSVHandler(void);  //PendSV 中断服务程序
 
void       OS_CPU_SysTickHandler(void);   //SysTick 中断服务程序
void       OS_CPU_SysTickInit(void);  
INT32U    OS_CPU_SysTickClkFreq(void); 
 
声明几个函数,OS_CPU_PendSVHandler(void)要替换为 PendSV__Handler(void)。另外这里最后三个函数需要注释掉,为什么呢?
移植ucosII到STM32F103ZE(四)


 
答案就在启动文件上,一般我们自己开发基于 stm32 芯片的软件,都会使用标准外设库 CMSIS 中提供的启动文件,比如 startup_stm32f10x_hd.s,而 Micrium官方没有用 ST 的标准启动文件,自写了启动文件,而且分开写成了两个.s 文件,即 init.s,vectors.s
(MicriumSoftwareEvalBoardsSTSTM3210B-EVALRVMDK)。init.s 负责进入 main(),vectors.s设置中断向量。OS_CPU_SysTickHandler和OS_CPU_PendSVHandler 这两个中断向量就是在 vectors.s 中被设置的。 
    使用标准的 startup_stm32f10x_hd.s 作为启动文件的,那该怎么来匹配呢?事实上在 startup_stm32f10x_hd.s 文件中 PendSV 中断向量名为 PendSV_Handler,所以只需用PendSV_Handler 替换掉OS_CPU_C.h和 OS_CPU_A.ASM 中的OS_CPU_PendSVHandler。 
    这样,替换后的void  PendSV_Handler(void)函数在OS_CPU_C.h 中有声明,在OS_CPU_A.ASM 中有具体的中断服务函数代码,在startup_stm32f10x_hd.s中有向量地址,匹配完毕,Ok。
接下来就该处理 SysTick 中断和启动任务了。SysTick是 OS 的“心跳”,可称为滴答时钟,本质上来说就是一个定时器。 
    同样,在 startup_stm32f10x_hd.s 文件中 SysTick 的中断向量名为 SysTick_Handler,我们本可按照上法继续炮制,但因为 ST 标准库已经有相关库函数,所以我们按照如下法子修改:
把 OS_CPU_C.C 文件中的 void OS_CPU_SysTickHandler (void)的内容代码复制到 stm32f10x_it.c
文件中的 SysTick_Handler (void)函数内;
 移植ucosII到STM32F103ZE(四)

      并且在文件头部添加:#include  
移植ucosII到STM32F103ZE(四)


 
这样子,替换后的 SysTick_Handler (void)函数在 stm32f10x_it.h 文件中声明,在stm32f10x_it.c
中有具体代码,在startup_stm32f100x_hd.s中有向量地址;同时需要在App文件中有对 SysTick的初始化函数(后面编写App.c时需要初始化)。
整个过程中 ST 官方标准启动文件啥也没动,防止了误修改。
OS_CPU_SysTickHandler()定义在 os_cpu_c.c 中,是 SysTick中断的中断处理函数,而 stm32f10x_it.c 中已经有该中断函数的定义 SysTick_Handler()),这里也就不需要了。
OS_CPU_SysTickInit() 定义在os_cpu_c.c中,用于初始化SysTick定时器,它依赖于 OS_CPU_SysTickClkFreq(),而此函数我们自己会实现,所以注释掉。
 OS_CPU_SysTickClkFreq()定义在 BSP.C (MicriumSoftwareEvalBoards)中,而本文移植中并未用到BSP.C,后面我们会自己实现,因此也将它注释掉,解除我们和 Micrium 官方bsp 的依赖关系。[page]
 
os_cpu_c.c
     ucosii 移植时需要我们写 10个相当简单的C 函数。
OSInitHookBegin()  
OSInitHookEnd()  
OSTaskCreateHook()  
OSTaskDelHook()  
OSTaskIdleHook()  
OSTaskStatHook()  
OSTaskStkInit()  
OSTaskSwHook()  
OSTCBInitHook()  
OSTimeTickHook() 
这些函数除了 OSTaskStkInit(),都是一些 hook 函数。这些 hook 函数如果不使能的话,都不会用上,也都比较简单,看看就应该明白了,所以就不介绍。
下面就说一说 OSTaskStkInit()。说之前还是得先说一下任务切换,因为初始化任务堆栈,是为任务切换服务的。代码在正常运行时,一行一行往下执行,怎么才能跑到另一个任务(即函数)执行呢?首先大家可以回想一下中断过程,当中断发生时,原来函数执行的地方(程序计数器PC、处理器状态寄存器及所有通用寄存器,即当前代码的现场)被保存到栈里面去了,然后开始取中断向量,跑到中断函数里面执行。执行完了呢,想回到原来函数执行的地方,该怎么办呢,只要把栈中保存的原来函数执行的信息恢复即可(把栈中保存的代码现场重新赋给 cpu 的各个寄存器),一切就都回去了,好像什么事都没发生一样。这个过程大家应该都比较熟悉,任务切换和这有什么关系,试想一下,如果有 3 个函数 foo1(), foo2(), foo3() 都像是刚被中断,现场保存到栈里面去了,而中断返回时做点手脚(调度程序的作用),想回哪个回哪个,是不是就做了函数(任务)切换了。看到这里应该有点明白 OSTaskStkInit()的作用了吧,它被任务创建函数调用,所以要在开始时,在栈中作出该任务好像刚被中断一样的假象。(关于任务切换的原理邵老师书中的 3.06 节有介绍)。
那么中断后栈中是个什么情形呢,<>中 9.1.1 有介绍,xPSR,PC,LR,R12,R3-R0 被自动保存到栈中的,R11-R4如果需要保存,只能手工保存。因此 OSTaskStkInit()的工作就是在任务自己的栈中保存 cpu 的所有寄存器。这些值里 R1-R12 都没什么意义,这里用相应的数字代号(如 R1 用0x01010101)主要是方便调试。
OS_STK *OSTaskStkInit (void (*task)(void  *p_arg), void  *p_arg, OS_STK  *ptos, INT16U opt)  
 
OS_STK  *stk;  
(void)opt;                          
stk       = ptos;                  
 
  
*(stk)    = (INT32U)0x01000000L;    
*(--stk)  = (INT32U)task;           
*(--stk)  = (INT32U)0xFFFFFFFEL;    
*(--stk)  = (INT32U)0x12121212L;    
*(--stk)  = (INT32U)0x03030303L;    
*(--stk)  = (INT32U)0x02020202L;    
*(--stk)  = (INT32U)0x01010101L;    
*(--stk)  = (INT32U)p_arg;         
 
  
*(--stk)  = (INT32U)0x11111111L;    
*(--stk)  = (INT32U)0x10101010L;    
*(--stk)  = (INT32U)0x09090909L;    
*(--stk)  = (INT32U)0x08080808L;    
*(--stk)  = (INT32U)0x07070707L;    
*(--stk)  = (INT32U)0x06060606L;    
*(--stk)  = (INT32U)0x05050505L;    
*(--stk)  = (INT32U)0x04040404L;   
 
return (stk);  
 
xPSR = 0x01000000L,xPSR T 位(第24 位)置 1,否则第一次执行任务时 Fault,
PC 肯定得指向任务入口,
R14 = 0xFFFFFFFEL,最低4位为E,是一个非法值,主要目的是不让使用 R14,即任务是不能返回的。R0 用于传递任务函数的参数,因此等于 p_arg。
把 OS_CPU_SysTickHandler(), OS_CPU_SysTickInit()这两个函数的内容代码注释掉。
os_cpu_c.c文件中的
移植ucosII到STM32F103ZE(四)

移植ucosII到STM32F103ZE(四)


 
#define  OS_CPU_CM3_NVIC_ST_CTRL    (*((volatile INT32U *)0xE000E010))   
#define  OS_CPU_CM3_NVIC_ST_RELOAD  (*((volatile  INT32U *)0xE000E014))   
#define  OS_CPU_CM3_NVIC_ST_CURRENT (*((volatile  INT32U *)0xE000E018))   
#define  OS_CPU_CM3_NVIC_ST_CALL     (*((volatile  INT32U *)0xE000E01C))  
 
#define  OS_CPU_CM3_NVIC_ST_CTRL_COUNT      0x00010000  
#define  OS_CPU_CM3_NVIC_ST_CTRL_CLK_SRC    0x00000004  
#define  OS_CPU_CM3_NVIC_ST_CTRL_INTEN       0x00000002  
#define  OS_CPU_CM3_NVIC_ST_CTRL_ENABLE     0x00000001 
把上面这些宏定义也注释掉,因为它们都用于 OS_CPU_SysTickHandler(), OS_CPU_SysTickInit()。
移植ucosII到STM32F103ZE(四)


关键字:移植  ucosII  STM32F103ZE 引用地址:移植ucosII到STM32F103ZE(四)

上一篇:移植ucosII到STM32F103ZE(五)
下一篇:移植ucosII到STM32F103ZE(三)

推荐阅读最新更新时间:2024-03-16 14:37

linux-3.0移植到FL2440(只做基本的移植
首先补丁包来自凌云实验室: 1.先打补丁: patch -p1 ../linux-3.0-s3c2440.patch 2.修改 Makefile: ARCH ?= arm CROSS_COMPILE ?= arm-linux- 3.修改补丁的错误: 在/arch/arm/plat-s3c24xx/devs.c //#ifdef CONFIG_SND_SOC_SAMSUNG_S3C24XX_UDA134X /* UDA1341 add by guowenxue, 2012.03.30 */ //注释掉 . . . //#endif 4.make s3c2410_defconfig 5.裁剪
[单片机]
S3C2416裸机开发系列十七_GCC下Fatfs的移植
对于固态存储器,其存储容量可以很大,往往需要一款文件系统对存储器用户数据进行组织文件的管理。它对文件存储器空间进行组织和分配,负责文件的存储并对存入的文件进行保护和检索。在嵌入式系统中,往往需要采用windows兼容的文件系统,像相机的照片、视频监控、语音产品等,很多都需要从windows计算机上提取资源或在windows计算机上进一步处理。Fatfs由于其开源免费,支持fat32,受到了广泛的应用,笔者此处就s3c2416移植Fatfs,对sd卡进行读写访问作一个简单的介绍。 1. Fatfs概述 Fatfs是由日本工程师ChaN所编写的fat文件系统模块,从06年发布第一个Fatfs版本开始,作者就从未停止维护和更新。Fat
[单片机]
STM32F103移植到AT32F403A之MDK(二)
上一篇我们已经实现了不改硬件,只改软件情况下将STM32F103C8T6替换为AT32F403ACGT7的过程,但毕竟STM32F103C8T6已经是10多年前的东西了,用现在的AT32F403ACGT7替换实在是大材小用了,毕竟这颗是主频能到240M的M4。 上篇我们解决了替换能用的问题,本篇我们来结合AT32F403ACGT7的优势,实现不改硬件只改BOM降成本的方法。 从接触MCU开始,MCU外围电路中就缺少不了很重要的器件,那就晶振,晶振是MCU的时钟源。随着技术的不断发展,越来越多的MCU将晶振集成到了MCU内部,但集成到内部后真的就能够省略掉外部晶振吗,当然不是,由于技术和工艺问题,前些年的MCU还无法完全摆脱
[单片机]
STM32F103<font color='red'>移植</font>到AT32F403A之MDK(二)
一文了解移植3.4.2的Kernel到JZ2440
本文将介绍如何移植linux-3.4.2内核到JZ2440开发板上的全过程,使用的交叉编译工具版本为 arm-linux-gcc-4.3.2.tar.bz2 下面来一步一步介绍如何移植。 由于kernel的启动参数是由Uboot传递的,关键的参数有 R0=0 R1=Mach-Type R2=Tag参数地址 其中,Mach-Type为内核支持板子的硬件型号,tag参数为Uboot存放传递给Kernel参数的内存地址。 内核启动时,根据传入的Mach-Type参数选择对应的板级初始化函数来初始化,然后解析tag参数,设置相应系统状态值,装载驱动程序,最后挂载根文件系统。 1. 编译内核 修改根目录下面的Make
[单片机]
移植u-boot-2010.09到S3C2440(一)——硬件初始化与测试
在u-boot的代码选择中,只有201009是最近的可直接编译通过的,不带memset.s的u-boot版本。 屏蔽lowlevel_init的调用之后,将我在u-boot-201112版本中所做的硬件初始化全部挪到本版本中,包括串口驱动的修改,时钟设置,LED的点亮。 这个时候通过开发板自带的u-boot写到SDRAM调试就直接有串口输出与提示符。 注:本系列文档只注释难点部分,其它略过。
[单片机]
人体器官移植突破:男子植入3D打印椎骨获新生
如今已经两个多月过去了,约塞夫斯基的恢复情况相当不错。    据外媒报道,人体器官移植频传福音,3D打印再写医疗新里程。澳大利亚医生为一名患了癌症的男子进行一项全球第一例手术,替他移除被癌细胞严重破坏的椎骨,再为他植入一条用3D打印技术打印出来旳椎骨。该病人现时康复的进展良好,重获新生。   据报道,病人约塞夫斯基患了脊索瘤,是一种十分罕见的癌症。癌细胞攻击他的脊椎和头骨,并在他的颈项上方位置生长,令他饮食和说话都有困难。医学界估计,每100万人当中,只有一人患上这种病。   去年12月,神经科医生莫布斯为他进行长达15小时的手术,移除本来的椎骨,植入3D打印的脊骨。   莫布斯称,“如果不动手术,又不进行
[医疗电子]
Fedora8上交叉编译qtopia4移植成功到s3c2410开发板
教程是这样的: 一.硬件平台 1.主机: PC机,512M内存以上。 2.目标机: UP-NetARM2410-S实验平台。 二.移植软件资源 1.Red Hat Linux 9.0(主机操作系统) 2.gcc-3.4.1.tar.gz(主机编译器) 3.arm-linux-gcc-3.4.1.tar.bz2(交叉编译器) 4.tslib-1.3.tar.bz2(管理目标平台的触摸屏) 5.qtopia-opensource-src-4.2.1.tar.gz(包含Qt, Qtopia core) 2 . GUI(QT)的移植过程 编译前的约定: 1)我的工作目录为:/mnt/nfs。 2)qtopia-o
[单片机]
U-Boot在基于ADSP BF533的嵌入式Linux系统上的移植
1 引言 Boot Loader(内核引导程序)是在操作系统内核运行之前运行的一段自举程序,用于初始化硬件设备、改变处理器运行模式、重组中断向量和建立内存空间映射图,从而将系统的软硬件带到一个合适的状态或者用户定制的特定状态,以便为最终加载操作系统内核准备好正确的环境 。 嵌入式Linux系统常用的Boot Loader有arm-boot、redboot、U-Boot等。U-Boot (全称Universal Boot Loader)是当前比较流行的遵循GPL条件的开放源码项目。U-Boot具有源码公开的特点,开发人员可根据自身需要进行裁减;支持多种处理器和嵌入式操作系统内核;具有多种设备驱动源码:支持种引导方式;具有功能强大
[嵌入式]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved