基于stm32f103zet6之UC/OS_II的学习1(初步移植OS--点灯大法)

发布者:RadiantDreams最新更新时间:2017-09-06 来源: eefocus关键字:stm32f103zet6  移植OS 手机看文章 扫描二维码
随时随地手机看文章

代码这里可以下载http://download.csdn.net/detail/king_bingge/5353528

一、uc/OS的实时性是靠什么实现的?


1、uC/OS的实时性就是靠定时中断来完成。

2、每个时钟节拍到来,就会产生一次定时中断,中断后进行任务调度,运行就绪表中优先级最高的任务(非抢先型内核中断后继续运行被中断任务)。

即过一段时间就检测是否有重要任务需要运行,是的就转而运行更重要的任务,从而确保实时性(裸机程序就无法这样做了)。

当然这里没有把系统调用考虑进去。

二、首先整体把握一下在M3上运行ucosII的架构


这就是整个系统各模块之间的关系,好的接下来就按照手册来分析一下移植的时候需要注意的地方

1、关于OS_CPU.h文件


  1. #ifndef  OS_CPU_H  

  2. #define  OS_CPU_H  

  3.  

  4.  

  5. #ifdef   OS_CPU_GLOBALS  

  6. #define  OS_CPU_EXT  

  7. #else  

  8. #define  OS_CPU_EXT  extern  

  9. #endif  


一个全局变量的声明问题


2、类型定义



  1. typedef unsigned char  BOOLEAN;  

  2. typedef unsigned char  INT8U;                    /* Unsigned  8 bit quantity                           */  

  3. typedef signed   char  INT8S;                    /* Signed    8 bit quantity                           */  

  4. typedef unsigned short INT16U;                   /* Unsigned 16 bit quantity                           */  

  5. typedef signed   short INT16S;                   /* Signed   16 bit quantity                           */  

  6. typedef unsigned int   INT32U;                   /* Unsigned 32 bit quantity                           */  

  7. typedef signed   int   INT32S;                   /* Signed   32 bit quantity                           */  

  8. typedef float          FP32;                     /* Single precision floating point                    */  

  9. typedef double         FP64;                     /* Double precision floating point                    */  

  10.   

  11. typedef unsigned int   OS_STK;                   /* Each stack entry is 32-bit wide                    */  

  12. typedef unsigned int   OS_CPU_SR;                /* Define size of CPU status register (PSR = 32 bits) */  

对于常用的编译器,这些都是没有问题的


3、接下来是两个比较重要的函数,在汇编代码里面



  1. #define  OS_ENTER_CRITICAL()  {cpu_sr = OS_CPU_SR_Save();}  

  2. #define  OS_EXIT_CRITICAL()   {OS_CPU_SR_Restore(cpu_sr);}  

这两个代码就是进入和退出临界区的两个宏。所以当你使用了这两个宏定义,那么就需要加上这一句OS_CPU_SR  cpu_sr = 0;  进行定义并且初始化。


所谓临界区:是指一些不能被中断的代码。哪些代码是不能中断的呢,比如我们模拟的入栈操作,再比如当我们在执行系统调用的时候。那么类似于这钟代码就是临界区,而上面这两个宏的作用就是当某些代码为临界代码的时候,那么我们就在开始这段代码的时候加上ENTER宏,在退出这段代码的时候就加上EXIT宏。

4、接下来继续看看这两个宏做了什么事情吧

跟踪进去可以发现


  1. OS_CPU_SR_Save  

  2.     MRS     R0, PRIMASK                                         ; Set prio int mask to mask all (except faults)  

  3.     CPSID   I  

  4.     BX      LR  

  5.   

  6. OS_CPU_SR_Restore  

  7.     MSR     PRIMASK, R0  

  8.     BX      LR  


就是我们上一步所说的打开和屏蔽中断,注意了,根据ATCPS规则(不知道的可以百度),C和汇编进行混合调用的时候,R0传递着第一个参数,并且R0还是传递返回值的。


5、接下来就是栈的增长方向,在我们的stm32板子上面,栈是向下增长的,堆是向上增长的


  1. #define  OS_STK_GROWTH        1                   /* Stack grows from HIGH to LOW memory on ARM        */  

  2.  

  3. #define  OS_TASK_SW()         OSCtxSw()  


第二个宏定义是任务切换的宏,下面会提到


6、下面涉及到得就是这个文件里面需要修改的代码,首先看源代码,这是函数原型声明



  1. /* 

  2. ********************************************************************************************************* 

  3. *                                              PROTOTYPES 

  4. ********************************************************************************************************* 

  5. */  

  6.  

  7. #if OS_CRITICAL_METHOD == 3                       /* See OS_CPU_A.ASM                                  */  

  8. OS_CPU_SR  OS_CPU_SR_Save(void);  

  9. void       OS_CPU_SR_Restore(OS_CPU_SR cpu_sr);  

  10. #endif  

  11.   

  12. void       OSCtxSw(void);  

  13. void       OSIntCtxSw(void);  

  14. void       OSStartHighRdy(void);  

  15.   

  16. void       OS_CPU_PendSVHandler(void);  

  17.   

  18.                                                   /* See OS_CPU_C.C                                    */  

  19. void       OS_CPU_SysTickHandler(void);  

  20. void       OS_CPU_SysTickInit(void);  

  21.   

  22.                                                   /* See BSP.C                                         */  

  23. INT32U     OS_CPU_SysTickClkFreq(void);  


我们需要做的就是把这个三个函数注释掉,因为这是我们自己实现的



  1.                                                   /* See OS_CPU_C.C                                    */  

  2. // void       OS_CPU_SysTickHandler(void);  

  3. // void       OS_CPU_SysTickInit(void);  

  4.   

  5. //                                                   /* See BSP.C                                         */  

  6. // INT32U     OS_CPU_SysTickClkFreq(void);  

至此,第一个文件修改完毕,继续。。


三、关于os_cfg.h文件

1、这里都是一些配置,根据我们需要实现的功能来配置我们的OS,当然,如果只是为了点灯,那么我们可以这样做


  1.  #define OS_FLAG_EN                    0   //禁用信号量集      

  2.  #define OS_MBOX_EN                   0   //禁用邮箱      

  3.  #define OS_MEM_EN                     0   //禁用内存管理      

  4.  #define OS_MUTEX_EN                0   //禁用互斥信号量      

  5.  #define OS_Q_EN                        0   //禁用队列      

  6.  #define OS_SEM_EN                     0   //禁用信号量      

  7.  #define OS_TMR_EN                     0   //禁用定时器      

  8.  #define OS_DEBUG_EN               0   //禁用调试    

  9.   

  10.  #define OS_APP_HOOKS_EN           0    336. #define OS_FLAG_EN                0   //禁用信号量集      

  11.  #define OS_MBOX_EN                0   //禁用邮箱      

  12. #define OS_MEM_EN                 0   //禁用内存管理      

  13. #define OS_MUTEX_EN               0   //禁用互斥信号量      

  14.  #define OS_Q_EN                   0   //禁用队列      

  15. #define OS_SEM_EN                 0   //禁用信号量      

  16.  #define OS_TMR_EN                 0   //禁用定时器      

  17.  #define OS_DEBUG_EN               0   //禁用调试    

  18.  #define OS_APP_HOOKS_EN           0    //hook函数也可以注释掉  

  19.  #define OS_EVENT_MULTI_EN         0  //多重事件函数也是一样  

  20.  #define OS_EVENT_MULTI_EN         0    


那么,到这里,这个文件中需要修改的内容就是这么多了。


四、关于os_cpu_c.c文件。

这个文件是对应于之前的宏开关来说的,我们要把之前三个函数相关的宏开关以及函数的定义注释掉,具体操作如下


  1. // #define  OS_CPU_CM3_NVIC_ST_CTRL    (*((volatile INT32U *)0xE000E010))   /* SysTick Ctrl & Status Reg. */  

  2. // #define  OS_CPU_CM3_NVIC_ST_RELOAD  (*((volatile INT32U *)0xE000E014))   /* SysTick Reload  Value Reg. */  

  3. // #define  OS_CPU_CM3_NVIC_ST_CURRENT (*((volatile INT32U *)0xE000E018))   /* SysTick Current Value Reg. */  

  4. // #define  OS_CPU_CM3_NVIC_ST_CAL     (*((volatile INT32U *)0xE000E01C))   /* SysTick Cal     Value Reg. */  

  5. // #define  OS_CPU_CM3_NVIC_PRIO_ST    (*((volatile INT8U  *)0xE000ED23))   /* SysTick Handler Prio  Reg. */  

  6.   

  7. // #define  OS_CPU_CM3_NVIC_ST_CTRL_COUNT                    0x00010000     /* Count flag.                */  

  8. // #define  OS_CPU_CM3_NVIC_ST_CTRL_CLK_SRC                  0x00000004     /* Clock Source.              */  

  9. // #define  OS_CPU_CM3_NVIC_ST_CTRL_INTEN                    0x00000002     /* Interrupt enable.          */  

  10. // #define  OS_CPU_CM3_NVIC_ST_CTRL_ENABLE                   0x00000001     /* Counter mode.              */  

  11. // #define  OS_CPU_CM3_NVIC_PRIO_MIN                               0xFF     /* Min handler prio.          */  


对应的还有这个函数也需要注释掉


  1. //void  OS_CPU_SysTickInit (void)  

  2. //{  

  3. //    INT32U  cnts;  

  4. //  

  5. //  

  6. //    cnts = OS_CPU_SysTickClkFreq() / OS_TICKS_PER_SEC;  

  7. //  

  8. //    OS_CPU_CM3_NVIC_ST_RELOAD = (cnts - 1);  

  9. //                                                 /* Set prio of SysTick handler to min prio.           */  

  10. //    OS_CPU_CM3_NVIC_PRIO_ST   = OS_CPU_CM3_NVIC_PRIO_MIN;  

  11. //                                                 /* Enable timer.                                      */  

  12. //    OS_CPU_CM3_NVIC_ST_CTRL  |= OS_CPU_CM3_NVIC_ST_CTRL_CLK_SRC | OS_CPU_CM3_NVIC_ST_CTRL_ENABLE;  

  13. //                                                 /* Enable timer interrupt.                            */  

  14. //    OS_CPU_CM3_NVIC_ST_CTRL  |= OS_CPU_CM3_NVIC_ST_CTRL_INTEN;  

  15. /  


那么这样,这个文件也解决掉了。继续下一个


五、在OS_dbg.c这个文件中

修改一个地方,#define  OS_COMPILER_OPT  __root,将后面的__root注释掉,否则会报错。自己可以试试

六、来到OS_cpu_a.asm这个汇编文件

1、里面的PUBLIC全改为EXPORT。这是有ARM汇编语言语言规定的。

2、RSEG CODE:CODE:NOROOT(2)    开辟代码段的格式也是需要修改的

修改如下:


  1. AREA |.text|, CODE , READONLY, ALIGN = 2  

  2. THUMB  

  3. REQUIRE8  

  4. PRESERVE8  

具体解释,看ARM的汇编编程介绍就知道了。


到这里,这个文件也修改完毕。

七、关于启动文件

有一个地方需要修改,那就是中断这部分。把启动代码中所有出现PendSV_Handler的地方替换成OS_CPU_PendSVHandler即可。

那么这个文件也修改完毕

到这里,我们的移植也就完成了一大部分,接下来就是编写自己的代码了。

八、编写几个简单的函数就能实现点灯了


  1. #include "includes.h"  

  2.   

  3. static OS_STK startup_task_stk[STARTUP_TASK_STK_SIZE];        //定义栈  

  4.     

  5. int main(void)  

  6. {  

  7.     BSP_Init();  

  8.     OSInit();  

  9.     OSTaskCreate(Task_LED,(void *)0,  

  10.     &startup_task_stk[STARTUP_TASK_STK_SIZE-1], STARTUP_TASK_PRIO);  

  11.   

  12.     OSStart();  

  13.     return 0;  

  14.  }  

  15.    

  16.  /* 

  17.  * 函数名:BSP_Init 

  18.  * 描述  :时钟初始化、硬件初始化 

  19.  * 输入  :无 

  20.  * 输出  :无 

  21.  */  

  22. void BSP_Init(void)  

  23. {  

  24.     LED_GPIO_Config();  /* LED 端口初始化 */  

  25. }  

  26.   

  27. void Task_LED(void *p_arg)  

  28. {  

  29.    (void)p_arg;                     // 'p_arg' 并没有用到,防止编译器提示警告  

  30.     SysTick_init();  

  31.     while (1)  

  32.     {  

  33.         LED1( ON );  

  34.         OSTimeDlyHMSM(0, 0,0,500);  

  35.         LED1( OFF);  

  36.         OSTimeDlyHMSM(0, 0,0,500);  

  37.     }  

  38. }  

  39.    

  40. /* 

  41.  * 函数名:SysTick_init 

  42.  * 描述  :配置SysTick定时器 

  43.  * 输入  :无 

  44.  * 输出  :无 

  45.  */  

  46. void SysTick_init(void)  

  47. {  

  48.     SysTick_Config(SystemCoreClock /OS_TICKS_PER_SEC);//初始化并使能SysTick定时器  

  49. }  

到这里就实现单任务系统了,OK。点灯完毕!接下来就是仔细分析源码了。


关键字:stm32f103zet6  移植OS 引用地址:基于stm32f103zet6之UC/OS_II的学习1(初步移植OS--点灯大法)

上一篇:基于stm32f103zet6之UC/OS_II的学习2(初步分析OS--点灯大法)
下一篇:基于stm32f103zet6之DS18B20的学习

推荐阅读最新更新时间:2024-03-16 15:36

Snapdragon Sound骁龙畅听技术助力Cleer ARC II音弧开启开放式智能声学新时代
近日, Cleer正式推出Cleer ARC II音弧开放式耳机,这款全新蓝牙真无线耳机共分音乐版、运动版、游戏版三个版本,均采用高通S3音频平台 ,支持先进的Snapdragon Sound™骁龙畅听技术、蓝牙5.3和LE Audio(低功耗音频)等众多先进特性,通过稳健的蓝牙连接和超低功耗,针对音乐、游戏、办公等不同应用场景,提供全链路超低时延、高品质音频以及超清晰的语音通话。 Cleer ARC II音弧开放式耳机 作为开放式智能声学新时代的巅峰之作,Cleer ARC II音弧开放式耳机支持Snapdragon Sound骁龙畅听技术,带来包括高通aptX™ Lossless无损音频、aptX Adaptive
[模拟电子]
Snapdragon Sound骁龙畅听技术助力Cleer ARC <font color='red'>II</font>音弧开启开放式智能声学新时代
微软遭遇后来者挑战:三星RIM欲抢移动OS排名
    移动操作系统(移动OS)领域,近年来苹果与谷歌一直维持着双雄争霸的市场格局。   目前,谷歌Android平台虽然以免费模式广纳天下英才,但在Android生态链上,除了三星具备可观利润外,其他手机厂商没有任何一家取得实质性利润。这样的生态格局,面临合作伙伴弃之而去的风险。业内盛传,5月的GoogleI/O开发者大会上,谷歌将发布XPhone手机,以正式介入手机制造领域。这种猜测,给Android生态系统相关合作伙伴带来了恐慌,尤以三星最甚。   双雄之一的苹果,自乔布斯时代结束后,创新力似乎开始下降,苹果的股价也从神坛逐渐“跌入凡间”。   苹果的后劲疲乏和谷歌Android生态系统的不稳定性,让雄心者看到了一丝曙光。进入
[手机便携]
基于UC3842的电动车用开关电源设计
电动车是目前零排放的机动车,作为绿色交通工具,将在21世纪给人类社会带来巨大的变化。而直流无刷电机凭借着其优良的性能已经成为电动车电机领域的主流技术和发展方向。性能优良的无刷电机系统离不开性能优良的控制模块,而控制模块的性能在很大程度上取决于供电电源的性能,所以高质量的供电电源系统在整个电动车系统中占有相当重要的位置。 直流无刷电机的控制模块是采用微控制器的数字控制的电子系统。基于UC3842高性能电流模式PWM发生器控制的开关电源适合应用于此类系统。本设计通过小型高频变压器实现输出和输入的完全隔离,不仅提高了电源的效率,简化了外围电路,也降低了电源的成本和体积。电源输出电压稳定,波纹小,不间断,性能可靠。 1 单端反激式变
[嵌入式]
腾讯新一代电子书口袋阅II曝光:小巧如手机 能打电话
腾讯全新电子书——口袋阅电子书二代将于12月16日发布,依然是一款可以打电话的墨水屏阅读器口袋阅产品经理张光强在朋友圈晒出了新品的背部照片,可以看到口袋阅电子书二代机身依旧很小,方便手持,至少提供红、绿、白三色。   上一代“口袋阅”于今年4月发布,支持SIM卡和4G全网通,配备电话短信功能,是国内首款支持运营商网络的电子阅读器。   其配备5.2英寸300ppi超清墨水屏、内置20级可调节亮度的阅读灯,力求还原纸质书阅读体验。   口袋阅的重量比普通阅读器轻约1/3,体积约为普通阅读器的1/2,用户可以随时揣进口袋。与此同时,口袋阅还配备了超大电池容量,能支持待机数周。   新一代口袋阅电子书会带来哪些新功能呢?我们拭目
[手机便携]
腾讯新一代电子书口袋阅<font color='red'>II</font>曝光:小巧如手机 能打电话
基于MSP430和Cyclone II 的网络数据加密实现
简介:随着信息技术和网络化进程的发展,网络通信安全问题日益突出。现场可编程门阵列(FPGA)以其自身设计灵活、可靠性高的优点广泛应用于加密领域。硬件实现的加密算法不占用计算机资源.加密过程完全与外部总线隔离,具有较高的数据保护能力。算法可灵活改变,具有较强的独立性。加密机由单片机,FPGA和El通信接口组成。FPGA内部算法由VHDL语言编写。 2 流加密解密原理及算法 2.1 流加密解密原理 流密码由密钥和密码算法两部分组成,密钥一般存储在加解密设备内部,在数据传输前已设置完成。密码算法在较长时间内是不变的。在同步流密码中,只要发送端和接收端有相同的密钥和内部状态,就能产生相同的密钥流。 数据传输时,加密端和解密端
[单片机]
基于MSP430和Cyclone <font color='red'>II</font> 的网络数据加密实现
基于正点原子STM32F103ZET6的ESP8266应用
前言 本次测试所使用的是正点原子的ATK-ESP8266 WIFI模块。直接使用官方提供的固件使用AT指令来配置模块并使用。 模块默认为AT指令状态,模拟波特率为115200(8bit数据位,1bit停止位)。 硬件连接 使用USB转TTL方式(电脑需要安装CH340驱动)连接ESP8266,接线图如下: Wifi模块ESP8266简介 ESP8266 是串口型WIFI,速度比较低,不能用来传输图像或者视频这些大容量的数据,主要应用于数据量传输比较少的场合,比如温湿度信息,一些传感器的开关量等。 ESP8266与单片机串口连接。一方面单片机可以通过串口发送AT命令给ESP8266,ESP8266会返回给单片机一个返
[单片机]
基于正点原子<font color='red'>STM32F103ZET6</font>的ESP8266应用
把Raspberry Pi装入Cherry键盘 再现apple II
8月24日消息,Raspberry Pi迷你电脑最近颇为火热,人们总是热衷在其基础上DIY出各种有意思的产品,日前一个德国博客向我们展示了如何利用Raspberry Pi来自制一个键盘电脑,如果你也对老式键盘电脑感兴趣,比如Commodore International在1982年8月发行的8位元家用电脑Commodore 64或者苹果1977年推出的运行摩托罗拉6502处理器的apple II,那么你可以参考一下。 这位德国玩家表示,第一次看到Raspberry Pi就下定决心一定要自己拥有一台,经过几个月的等待,最终在网上买了一台,而发货地点是中国。他将Raspberry Pi塞进了Cherry G80-3000键盘中
[半导体设计/制造]
把Raspberry Pi装入Cherry键盘 再现apple <font color='red'>II</font>
在MOTOROLAA68K系列MCU上移植μC/OS-II
以下介绍如何将μC/OS-II移植到MOTOROLA MC68K系列CPU上。 一、MC68K CPU简介 MC68K及68020、68040等的著名的MOTOROLA32位微处理器,和与之兼容的68K、CPU32、CPU32+等CPU扩充定时处理单元TPU、队列串行模块QSM、系统控制模块和RAM等组成MC683xx系列单片机。 CPU32内部有8个32位通用数据寄存器,8个32位通用地址寄存器。8个通用数据寄存器可作为累加器使用,也可看成C语言中各种类型的变量;8个通用地址寄存器,可作为变址寄存器使用,也可看成C语言中的指针型变量。CPU32有独立的用户堆栈指针和系统堆栈指针,可区分程序区、数据区、系统区、
[应用]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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