STM32F401xx是意法半导体新推出的Cortex-M4内核的MCU,相较于已经非常流行的STM32F407xx和STM32F427xx等相同内核的MCU而言,其特点是功耗仅为128uA/MHz,且存在64pin封装的小封装器件。我设计一款新产品使用了STM32F401xx,想把自己熟悉的uC/OS-II实时操作系统移植到这款MCU上。懒得从底层开始从头移植,偷懒从原子的“探索者”开发板移植的uC/OS-II开始修改。完成后在板子上一跑,发现系统时钟总存在约5%的偏差。仔细搜索代码后才发现,问题在把原子的uC/OS-II移植直接用在STM32F401上时的一个小bug,把发现问题的过程和解决办法分享给大家。

以下原创内容欢迎网友转载,但请注明出处:http://cnblogs.com/helesheng

一、把探索者开发板移植的uC/OS-II用在STM32F401xx上

原子的探索者开发板使用了STM32F407ZG,其内核是和32F401xx 相同的Cortex-M4,外设也基本相同。简单地将原子在探索者开发板上移植的uC/OS-II工程中的Device修改为STM32F401RC,编译后发现大量的预定义找不到。想到可能是代表处理器的预定义的宏没有修改,在Option中的C/C++页中,将Preprocessor Symbols改为代表401的“STM32F401xx,USE_STDPERIPH_DRIVER”,直接编译通过,心中一阵窃喜。

图1 修改预定义

二、uC/OS-II系统时钟偏差的小问题

运行之前在其它款STM32上写的uC/OS-II程序,开始一切顺利,但随后用示波器仔细分析各个任务内部及相互间的时间关系时,发现总存在+5%左右的时间误差,即实际系统时钟的周期只有理论系统时钟的95%左右。以每秒系统节拍数OS_TICKS_PER_SEC设置为200为例,每个OSTimeDly(1);的任务延迟仅为4750us。

开始以为是原子编写的延迟函数void delay_ms(u16 nms);的问题,仔细阅读代码后发现,这个函数只是在调用系统延迟函数OSTimeDly();的基础之上,将无法由系统延迟实现的us级延迟改由硬延迟实现。虽然我个人非常不赞同这种做法,因为这会造成uC/OS-II时间调度的盲区,从而影响uC/OS-II系统的实时性。但这不至于造成系统时钟的偏差,继续查找问题的原因。

既然调用系统延迟函数OSTimeDly的过程没有问题,那么只可能是系统时钟本身出了问题。Cortex-M内核的uC/OS移植都会用了SysTick定时器的中断构建系统时钟,因此在SysTick上找原因。打开MDK,连接自制的STM32F401电路板和仿真器,进入Debug模式,运行程序,让uC/OS完成初始化配置,然后暂停程序;在外设(peripheral)菜单中找到SysTick定时器,界面如下图所示。

图2 System tick定时器状态监视器

其中重装寄存器中的值为0xC350,即50_000,仔细一想发现有问题——STM32F401的主频为84MHz,那要达到200Hz的系统时钟,无论如何都不可能把System Tick的初值配置为50_000啊!于是开始查找uC/OS移植代码中配置System Tick的部分,原来在探索者开发板移植代码中初始化延迟函数delay_init();中。看看原子的代码。

图3 delay_init();函数原来的代码

原子的代码简洁清晰,将System Tick的时钟配置为AHB时钟的1/8,在计算System Tick的初值。其中红圈中的一句是计算AHB时钟的八分之一,为后续计算定时器初始值做准备。但进一步仔细查看后发现变量SYSCLK中存放的AHB时钟数是以MHz作为单位的,对STM32F401xx而言,就是84。84无法整除8,而赋值语句左边的变量reload却是int型变量,从而导致了红圈中的一句计算误差。这样即使后一句将reload的单位切换回了Hz,也无法挽回前一句无法整除造成的计算误差。而这真是uC/OS系统时钟误差5%的真正原因!对这两句进行简单修改——现将SYSCLK折算为以Hz为单位,即可保证足够的计算精度。

图4 修改过的delay_init();函数代码

修改过后,uC/OS的系统时钟又恢复了原有的准确性。

究其原因并不是原子探索者开发板移植的uC/OS的问题,因为探索者采用的STM32F407ZG运行在168MHz,能够整除8,不存在这个问题。这里给大家展示这个过程,一是给大家在STM32F401上移植uC/OS做些探索,二是分享一下嵌入式调试和查找问题的点滴思路和心得。

在STM32F401上移植uC/OS的一个小问题 [原创]的更多相关文章

  1. FMX相当于在界面上自己又做了一个小操作系统

    FMX的自画界面我也不看好,比如复制粘贴,太丑了,系统做得很好很精细的复制粘贴界面,就是无法调出,比如MIUI,复制粘贴还能有个放大镜,可以选择到屏幕边缘的文字,可以选择剪贴板内多个可粘贴的文字:还有 ...

  2. 关于uC/OS的简单学习(转)

    1.微内核 与Linux的首要区别是,它是一个微内核,内核所实现的功能非常简单,主要包括: 一些通用函数,如TaskCreate(),OSMutexPend(),OSQPost()等. 中断处理函数, ...

  3. uc/os iii移植到STM32F4---IAR开发环境

    也许是先入为主的原因,时钟用不惯Keil环境,大多数的教程都是拿keil写的,尝试将官方的uc/os iii 移植到IAR环境. 1.首先尝试从官网上下载的官方移植的代码,编译通过,但是执行会报堆栈溢 ...

  4. uC/OS - III 移植 IAR平台

    关于移植uC/OS-III 网上已经有很多教程了此处只是做个记录 首先下载源码然后解压得到下面的文件: 然后在模版工程里新建各种文件夹: 最后全部都添加进工程: OK了,编译一下,惊呆了,竟然 0错误 ...

  5. uC/OS II原理分析及源码阅读(一)

    uC/OS II(Micro Control Operation System Two)是一个可以基于ROM运行的.可裁减的.抢占式.实时多任务内核,具有高度可移植性,特别适合于微处理器和控制器,是和 ...

  6. 【小梅哥SOPC学习笔记】NIOS II处理器运行UC/OS II

    SOPC开发流程之NIOS II 处理器运行 UC/OS II 这里以在芯航线FPGA学习套件的核心板上搭建 NIOS II 软核并运行 UCOS II操作系统为例介绍SOPC的开发流程. 第一步:建 ...

  7. 在秉火STM32F429挑战者开发板上移植Huawei LiteOS指南

    昨天在B站上突然看到了一个短视频,是在正点原子的战舰V3开发板上移植华为的Huawei LiteOS操作系统,就是这个视频:看完鸿蒙OS发布会,试用华为的物联网操作系统Lite OS(B站),于是呢, ...

  8. 树莓派3b在rt-thread上移植LittlevGL

    树莓派3b在rt-thread上移植LittlevGL 目录 树莓派3b在rt-thread上移植LittlevGL 1.本文概述 2.资源准备 3.上手体验 4.rt-thread与lvgl进行无缝 ...

  9. 在 Linux 的 KVM虚拟机 上安装 Mac OS 系统的研究总结

    在 Linux 的 KVM虚拟机 上安装 Mac OS 系统的研究总结 一.资料来源:    网上一共找到两个方法,一个是视频上的教程,一个是网页资料. 二.视频资料方法内容:1.install qe ...

随机推荐

  1. 28、python3.7(windows)将ORACLE11gR2中的数据取出写入excel表

    28.1.下载python的离线扩展模块: 1.windows下python的离线扩展模块下载地址为: https://www.lfd.uci.edu/~gohlke/pythonlibs/ 提示: ...

  2. LeSS 的诞生(一):大规模团队该何去何从

    <敏捷宣言>发布后,"敏捷"被越来越多的小型开发团队认可.与此同时,另一个问题也逐渐暴露了出来:以 Scrum 为首的敏捷方法论对那些大规模的开发团队并不友好. 基于此 ...

  3. POJ 1222 高斯消元更稳

    大致题意: 有5*6个灯,每个灯只有亮和灭两种状态,分别用1和0表示.按下一盏灯的按钮,这盏灯包括它周围的四盏灯都会改变状态,0变成1,1变成0.现在给出5*6的矩阵代表当前状态,求一个能全部使灯灭的 ...

  4. CentOS-查找删除历史文件

    背景:因服务器磁盘空间有限,根据实际情况控制保留指定的几天内的历史文件 find参数说明: /home/tmp        设置查找的目录 -mtime +30       设置修改时间为30天前 ...

  5. SpringBoot:WebSocket使用Service层的方法

    方法一: 创建工具类 ApplicationContextRegister.java import org.springframework.beans.BeansException; import o ...

  6. tf-gpu报错:ImportError: libcublas.so.10.0: cannot open shared object file: No such file or directory

    错误1:ImportError: libcublas.so.10.0: cannot open shared object file: No such file or directory 一般这种问题 ...

  7. Java 在Word中创建邮件合并模板并合并文本和图片

    Word里面的邮件合并功能是一种可以快速批量操作同类型数据的方式,常见的如数据填充.打印等.其中必不可少的步骤包括用于填充的模板文档.填充的数据源以及实现邮件合并的功能.下面,通过Java程序展示如何 ...

  8. TCP和UDP知识总结

    1.TCP粘包:Tcp是面向连接.流式传送的,没有明确的边界定义.他有一个缓冲区,每过一段时间或者缓存满了就发送出去,造成一次发送的数据可能是多个包或者包的一部分,这就是发送端的粘包.接收端的粘包指应 ...

  9. Nginx的安装和部署

    Nginx简介 Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行.其特点是占有内存少,并发能力强,事实上nginx的并发 ...

  10. excle名字后面直接跟别的出来

    名字后面直接跟别的出来 =IF($E6="","",VLOOKUP(E6,通讯录!$B$2:$D$1000,3,0)) $E6:是填写位置的地方 VLOOKUP ...