STM32 使用 FreeRTOS过程记录
资源:http://blog.csdn.net/zhzht19861011/article/category/6191478
资源:可以下载安富莱的STM32-V5开发版资料中的FreeRTOS教程,里面有详细介绍各个功能,可以在http://wenku.baidu.com/search?word=%B0%B2%B8%BB%C0%B3STM32-V6%BF%AA%B7%A2%B0%E5FreeRTOS%BD%CC%B3%CC&lm=0&od=0&fr=top_home中查找相应的文档
移植的步骤在网上都能找到,这里只指出使用过程中遇到的问题
一、
1. 关于systick的设置
一般在stm32上运行实时操作系统,都会使用systick作为实时系统的时钟滴答,所以会涉及到systick的设置,在freeRTOS的FreeRTOSConfig.h文件中可以找到:
#define configCPU_CLOCK_HZ ( ( unsigned long ) 72000000 )
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
这个表示CPU的时钟为72MHZ,FreeRtos的时钟频率为1000HZ,这两个值可以根据实际的配置情况进行更改,
在port.c中有如下条件语句:
#ifndef configOVERRIDE_DEFAULT_TICK_CONFIGURATION
#define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 0
#endif
表示如果我们没有配置systick,那么freeRTOS就会根据 configCPU_CLOCK_HZ 和 configTICK_RATE_HZ 两个宏来对systick的寄存器进行配置;
2. FreeRTOS与ucos-ii的内存管理
UCOS-II把内存区域(memory partition)分成相同大小的内存块来使用,从而避免了内存碎化(fragmentation)带来的困扰。这种内存管理方式的缺点在于:大小不同的内存块必须提前订制,无法通用。
freeRTOS里最常用到的内存管理方式是:不固定内存块的大小;选择满足要求的最小空闲内存块使用,并将多余的部分划分出去形成一个新的内存块。这种管理方式有可能产生碎片,不过使用起来要方便一些。
3. FreeRTOS中断分级
3.1 在官方推荐中,强烈建议STM32的优先级分组采用4,即:
/* 优先级分组设置为4, 优先配置好NVIC */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
也就是说只有4个位的抢占优先级(0 ~ 16),而没有从优先级;为什么这样设计? 这得从FreeRTOS的对中断优先级的处理说起。在FreeRTOS中,FreeRTOS将优先级通过
configMAX_SYSCALL_INTERRUPT_PRIORITY(在FreeRTOSConfig.h中)分成两组进行处理:
1. 当中断的优先级数值高于configMAX_SYSCALL_INTERRUPT_PRIORITY的值(实际该中断优先级要小于configMAX_SYSCALL_INTERRUPT_PRIORITY对应的优先级,因为在STM32中,优先级数值越高,表明优先级越低)时,说明该中断可以被FreeRTOS系统进行屏蔽(通过FreeRTOS进入临界区屏蔽),同时,在该中断的中断服务例程中可以使用FreeRTOS 的API函数;
2.当中断的优先级数值低于configMAX_SYSCALL_INTERRUPT_PRIORITY的值时,说明该中断可以不能被FreeRTOS系统进行屏蔽(即使FreeRTOS进入临界区也不能),同时,在该中断的中断服务例程中不能使用FreeRTOS 的API函数;这些中断称为:不受FreeRTOS管理的中断
3.2 不受FreeRTOS管理的中断
讲解不受FreeRTOS 管理的中断之前要说一个小知识点----中断延迟。中断延迟时间是衡量RTOS 实时操作系统的一项重要指标,那什么又是中断延迟呢?从中断触发到执行中断服务程序的第一条指令这段时间就是中断延迟时间。
FreeRTOS 内核源码中有多处开关全局中断的地方,这些开关全局中断会加大中断延迟时间。比如在源码的某个地方关闭了全局中断,但是此时有外部中断触发,这个中断的服务程序就需要等到再次开启全局中断后才可以得到执行。开关中断之间的时间越长,中断延迟时间就越大,这样极其影响系统的实时性。如果这是一个紧急的中断事件,得不到及时执行的话,后果是可想而知的。针对这种情况,FreeRTOS 就专门做了一种新的开关中断实现机制。关闭中断时仅关闭受FreeRTOS管理的中断,不受FreeRTOS 管理的中断不关闭,这些不受管理的中断都是高优先级的中断,用户可以在这些中断里面加入需要实时响应的程序。FreeRTOS 能够实现这种功能的奥秘就在于FreeRTOS 开关中断使用的是寄存器basepri,而像uCOS 这种使用的是primask,详情请看下面整理的表格:
对寄存器basepri 我们举一个例子,帮助大家理解,比我们配置寄存器basepri 的数值为16,所有优先级数值大于等于16 的中断都会被关闭,优先级数值小于16 的中断不会被关闭。对寄存器basepri 寄存器赋值0,那么被关闭的中断会被打开。这个就是FreeRTOS 开关中断的实现方案。
4. FreeRTOS优先级
4.1 在FreeRTOS中,不同任务可以设置同一个优先级;多个任务可以共享一个优先级,RTOS调度器为相同优先级的任务分享CPU时间,在每一个RTOS 系统节拍中断到来时进行任务切换
4.2 在RTOS内核中,每个有效优先级都会消耗一定量的RAM,因此这个值不要超过你的应用实际需要的优先级数目。每一个任务都会被分配一个优先级,优先级值从0~ (configMAX_PRIORITIES - 1)之间。低优先级数表示低优先级任务。空闲任务的优先级为0(tskIDLE_PRIORITY),因此它是最低优先级任务。 处于就绪状态的相同优先级任务使用时间片调度机制共享处理器时间。
5. FreeRTOS堆栈
堆栈大小不是以字节为单位而是以字为单位的,比如在32位架构下,栈大小为100表示栈内存占用400字节的空间。
6.configUSE_TASK_NOTIFICATIONS
设置宏configUSE_TASK_NOTIFICATIONS为1(或不定义宏configUSE_TASK_NOTIFICATIONS)将会开启任务通知功能,有关的API函数也会被编译。设置宏 configUSE_TASK_NOTIFICATIONS为0则关闭任务通知功能,相关API函数也不会被编译。默认这个功能是开启的。开启后,每个任务多增加8字节RAM。
这是个很有用的特性,一大亮点。
每个RTOS任务具有一个32位的通知值,RTOS任务通知相当于直接向任务发送一个事件,接收到通知的任务可以解除任务的阻塞状态(因等待任务通知而进入阻塞状态)。相对于以前必须分别创建队列、二进制信号量、计数信号量或事件组的情况,使用任务通知显然更灵活。更好的是,相比于使用信号量解除任务阻塞,使用任务通知可以快45%(使用GCC编译器,-o2优化级别)。
7. 互斥信号量和二值信号量
关于互斥量和二进制信号量简单说:
- 互斥型信号量必须是同一个任务申请,同一个任务释放,其他任务释放无效。当多个任务使用同一个资源时,可以使用互斥信号量对共享资源进行互斥;
- 二进制信号量,一个任务申请成功后,可以由另一个任务释放。
- 互斥型信号量是二进制信号量的子集
- FreeRTOS的互斥信号量有一个优先级继承机制,可以防止优先级翻转的问题;而二值信号量则没有;
优先级继承防止优先级翻转问题:
- 创建2个任务Task1和Task2,优先级分别为1和3,也就是任务Task2的优先级最高。
- 任务Task1和Task2互斥访问串口打印printf。
- 使用FreeRTOS的互斥信号量实现串口打印printf的互斥访问。
- 低优先级任务Task1执行过程中先获得互斥资源printf的执行。此时任务Task2抢占了任务Task1的执行,任务Task1被挂起。任务Task2得到执行。
- 任务Task2执行过程中也需要调用互斥资源,但是发现任务Task1正在访问,此时任务Task1的优先级会被提升到与Task2同一个优先级,也就是优先级3,这个就是所谓的优先级继承(Priority inheritance),这样就有效地防止了优先级翻转问题。任务Task2被挂起,任务Task1有新的优先级继续执行。
- 任务Task1执行完毕并释放互斥资源后,优先级恢复到原来的水平。由于互斥资源可以使用,任务 Task2获得互斥资源后开始执行。
上面就是一个简单的FreeRTOS互斥信号量的实现过程。
8. 任务划分
8.1 任务的结构
任务的结构按照任务的执行方式可以分为三类:单次执行类、周期执行类和事件触发类
9. 数据通信
注意: 当对共享资源进行写操作的任务只有一个时,只要其优先级高于所有其他进行读操作的任务,就可以在进行写操作时不必关中断,这是因为低优先级任务执行读操作不可能在这个时候夺取运行权。而低优先级执行任务执行读操作必须采取关中断措施来访问全局变量,这是因为高优先级任务在进行写操作时,随时有可能被触发而获得运行权。
二、需要了解
RTOS的软件定时器功能
任务切换方式(任务管理)和调度器
2.1 任务切换
任务切换的实现在不同的嵌入式实时操作系统中区别不大,基本相同的硬件内核架构,任务切换也是相似的
2.2 调度器
调度器的核心是调度算法,嵌入式实时操作系统中,调度算法会有些区别
调度方式
FreeRTOS支持:抢占式调度、时间片调度和合作式调度;实际应用主要是抢占式调度和时间片调度,合作式调度用到很少;在FreeRTOS代码中会保持合作式调度,但不会再进行更新
3.1 抢占式调度
每个任务都有不同的优先级,任务会一直运行直到被高优先级的任务抢占或遇到阻塞式的API函数,如vTaskDelay();
3.2 时间片调度
每个任务都有相同的优先级,任务会运行固定的时间片个数或遇到阻塞式的API函数,比如vTaskDelay,才会执行同优先级任务之间的人物切换
二、任务划分
IRQ任务:IRQ任务是指通过中断服务程序进行触发的任务,此类任务应该设置为所有任务里面优先级最高的。
高优先级后台任务:比如按键检测,触摸检测,USB消息处理,串口消息处理等,都可以归为这一类任务。
低优先级的时间片调度任务:比如emWin的界面显示,LED数码管的显示等不需要实时执行的都可以归为这一类任务。实际应用中用户不必拘泥于将这些任务都设置为优先级1的同优先级任务,可以设置多个优先级,只需注意这类任务不需要高实时性。
空闲任务:空闲任务是系统任务。
特别注意:IRQ任务和高优先级任务必须设置为阻塞式(调用消息等待或者延迟等函数即可),只有这样,高优先级任务才会释放CPU的使用权,,从而低优先级任务才有机会得到执行。 这里的优先级分配方案是我们推荐的一种方式,实际项目也可以不采用这种方法。调试出适合项目需求的才是最好的。
STM32 使用 FreeRTOS过程记录的更多相关文章
- STM32与FreeRTOS实现低功耗
在工作过程中,遇到这样一个产品,它基于 Cortex-M7 内核的 STM32F769 芯片,同时使用了 FreeRTOS 实时操作系统. 由于该产品使用电池供电,因此有着低功耗的需求. 接下来,我将 ...
- 升级Windows 10 正式版过程记录与经验
升级Windows 10 正式版过程记录与经验 [多图预警]共50张,约4.6MB 系统概要: 预装Windows 8.1中文版 64位 C盘Users 文件夹已经挪动到D盘,并在原处建立了符号链接. ...
- 双系统Ubuntu分区扩容过程记录
本人电脑上安装了Win10 + Ubuntu 12.04双系统.前段时间因为在Ubuntu上做项目要安装一个比较大的软件,导致Ubuntu根分区的空间不够了.于是,从硬盘又分出来一部分空间,分给Ubu ...
- CentOS 5.5 下安装Countly Web Server过程记录
CentOS 5.5 下安装Countly Web Server过程记录 1. 系统更新与中文语言包安装 2. 基本环境配置: 2.1. NodeJS安装 依赖项安装 yum -y install g ...
- linux-i386(ubuntu)下编译安装gsoap_2.8.17过程记录
过程记录 : 1.下载gsoap_2.8.17.zip 并 解压 : $unzip gsoap_2.8.17.zip 2.进入解压后的目录gsoap-2.8 3.自动配置编译环境: $ ...
- 【转】android 最新 NDK r8 在window下开发环境搭建 安装配置与使用 详细图文讲解,完整实际配置过程记录(原创)
原文网址:http://www.cnblogs.com/zdz8207/archive/2012/11/27/android-ndk-install.html android 最新 NDK r8 在w ...
- 升级到 ExtJS 5的过程记录
升级到 ExtJS 5的过程记录 最近为公司的一个项目创建了一个 ExtJS 5 的分支,顺便记录一下升级到 ExtJS 5 所遇到的问题以及填掉的坑.由于 Sencha Cmd 的 sencha ...
- Ubuntu14.04 Tomcat 安装过程记录
Ubuntu14.04 Tomcat 安装过程记录 检查java的版本 zhousp@ubuntu:~$ sudo java -version [sudo] password for zhousp: ...
- mercurial(Hg) Server 搭建 过程记录
mercurial(Hg) Server 搭建 过程记录 1. 环境说明 只是测试搭建,环境为本机开发环境:win 8.1 + IIS8.5 软件准备: 2. 软件安装 先安装Python2.7, ...
随机推荐
- Android Studio in OSX 提高工作效率的快捷键
前言 本篇文章参考了<倍数提高工作效率的Android Studio>一文,快捷键基于OS X系统. OS X Yosemite 10.10.5 Android Studio 1.3.1 ...
- unity 读取文本与写入文本
void writeData(string str,string file) { string parth = Application.dataPath; Strea ...
- 去除angularjs路由的显眼的#号
在接触到angularj并完成第一个demo后,惊奇地发现居然还可以这样开发前端界面.个人喜欢的一个功能点就是ng的路由功能,可以很好地将视图放入多个文件中.但最基础的使用会给url添加一个显眼的#, ...
- dos命令 禁用网络链接
获取所有的网络链接接口: C:\Users\Chris.JENNEY>netsh interface show interface Admin State State Type Interfa ...
- 关于ckeditor ajax提交到后台 问题
ckeditor 提交时 如果有带有html时是提交不了的 解决办法就是 你在提交的时候 将ckeditor获取的只编码(encodeURI) 然后在传到后台提交的时候 在解码 就ok了 ckname ...
- iOS学习之代码块(Block)
代码块(Block) (1)主要作用:将一段代码保存起来,在需要的地方调用即可. (2)全局变量在代码块中的使用: 全局变量可以在代码块中使用,同时也可以被改变,代码片段如下: ;//注意:全局变量 ...
- WS+MQ+WCF+EF(Code First)
前言 有段时间没有更新博文了,一直在忙工作很少有时间静下心来继续研究点东西,说来也惭愧,归咎原因最主要的还是因为懒惰.空想也是不管用的,有时候很多想法被扼杀到了摇篮里,还没开始做就放弃了,这是多数人会 ...
- 页面可见生Page Visibility
Page Visibility 会在浏览器的 document 对象上添加两个属性 hidden 和 visibilityState .如果当前的标签被激活了,那么 document.hidden 的 ...
- redhat yum 从 iso 安装
背景: 1)yum 在没有注册的redhat中无法使用,不能去自动搜索redhat的库 2)使用者不能上网 方法摘自网络,就是下载ISO文件,yum的下载点指向ISO的mount后(也就是解压缩)的目 ...
- 关于context:component-scan配置中use-default-filters参数的作用
参考了多篇文章都说明了use-default-filters参数的基本用途,但有些主要点没有说到,这里补充记录下: <context:component-scan base-package=&q ...