赞
踩
1.学习FreeRTOS操作系统的内核原理;
2.掌握stm32F1系列单片机的使用;
3.学习嵌入式实时操作系统内核的移植;
4.掌握FreeRTOS下基本多任务应用程序的编写,加深对嵌入式实时操作系统的理解。
做一个基于stm32的智能手表,实现读取RTC芯片时间、改变时间、多级菜单目录等功能。MCU芯片采用STM32F103C8T6,价格便宜,扩展外设齐全,满足项目需求。OLED选取1.3寸I2C协议的OLED,RTC时钟芯片采用DS3231,陀螺仪芯片采用MPU6050,均为I2C通信协议,总线式通信,易于设计与布线。
采用低压差LDO电源芯片利用type-c为电池供电,电池采用3.7V锂电池进行储存电能,为单片机供电。除此之外,还设计了一个一键开机电路,电池连接VBIN脚,VBAT为为单片机供电的脚,当SW1按下时,莫斯管导通,进而实现系统上电运转。
OLED选取1.3寸I2C协议的OLED,RTC时钟芯片采用DS3231,陀螺仪芯片采用MPU6050,因为它们均是I2C总线形式通信,所以节省引脚。因为芯片自带的I2C驱动有不稳定的问题,所以软件方面采用模拟I2C。
RTOS,real-time Operate System。有很多成熟的技术可以在不使用内核的情况下编写好的嵌入式软件,但是在复杂情况下,RTOS有如下的好处:
1)用户无需关心时间信息
内核负责计时,并由相关的API完成,从而使得用户的应用程序代码结构更简单。
2)模块化、可拓展性强
也正是由于第一点的原因,程序性能不易受底层硬件更改的影响。并且,各个任务是独立的模块,每个模块都有明确的目的,降低了代码的耦合性。
3)效率高
内核可以让软件完全由事件驱动,因次,轮询未发生的事件是不浪费时间的。相当于用中断来进行任务切换。
4)中断进程更短
通过把中断的处理推迟到用户创建的任务中,可以使得中断处理程序非常短。
FreeRTOS是一个迷你的实时操作系统内核。作为一个轻量级的操作系统,功能包括:任务管理、时间管理、信号量、消息队列、内存管理、记录功能、软件定时器、协程等,可基本满足较小系统的需要。由于RTOS需占用一定的系统资源(尤其是RAM资源),只有μC/OS-II、embOS、salvo、FreeRTOS等少数实时操作系统能在小RAM单片机上运行。相对μC/OS-II、embOS等商业操作系统,FreeRTOS操作系统是 完全免费的操作系统 ,具有源码公开、可移植、可裁减、调度策略灵活的特点,可以方便地移植到各种单片机上运行。
有抢占式和合作式两种任务调度方式,其中抢占式用的比较多。
任务状态有:挂起状态、就绪状态、阻塞状态、运行状态
高优先级的任务会打断低优先级的任务执行,抢占资源,使得低优先级退回就绪状态,等高优先级任务退回阻塞状态时才会执行低优先的任务。
在任务执行到延时函数或者等待信号量时,OS会让其进入到阻塞状态,空出资源执行其他任务。
OS的时钟节拍在stm32上是由滴答时钟实现的,每次会产生中断实现OS的时钟节拍。
下图为heap4内存分配方式
其中,heap4:我们主要用到的是动态内存分配的heap4。相比于heap2的链表式内存块结构,heap4是按照物理地址来进行排序。这样设计的目的是方便合并相邻物理地址中空闲的内存块。但是,当在嵌入式系统中,频繁的创建与释放内存,还是会导致空闲块物理地址相对分散,依然会产生较多内存碎片。
OS中,为了防止任务对公共资源的访问冲突,即同一时间访问同一公共资源,设计了信号量,消息队列,邮箱等通信方式。
信号量是操作系统中重要的一部分,信号量一般用来进行资源管理和任务同步,FreeRTOS中信号量又分为二值信号量、计数型信号量、互斥信号量和递归互斥信号量。不同的信号量其应用场景不同,但有些应用场景是可以互换着使用的。
二值信号量
二值信号量其实就是一个只有一个队列项的队列,这个特殊的队列要么是满的,要么是空的。二值信号量通常用于互斥访问或任务同步,二值信号量和互斥信号量非常类似,但是还是有一些细微的差别,互斥信号量拥有优先级继承机制,二值信号量没有优先级继承。因此二值信号另更适合用于同步(任务与任务或任务与中断的同步),而互斥信号量适合用于简单的互斥访问。
计数信号量
计数型信号量用于事件计数和资源管理。
计数信号量可以用于资源管理,允许多个任务获取信号量访问共享资源,但会限制任务的最大数目。
互斥信号量
互斥信号量的应用场景------------>>优先级翻转
高优先级任务被低优先级任务阻塞,导致高优先级任务迟迟得不到调度。但其他中等优先级的任务却能抢到CPU资源。-- 从现象上来看,好像是中优先级的任务比高优先级任务具有更高的优先权。
优先级继承就是为了解决优先级反转问题而提出的一种优化机制。其大致原理是让低优先级任务在获得互斥信号量的时候(如果有高优先级的线程也需要使用该互斥信号量时),临时提升其优先级。以前其能更快的执行并释放同步资源。释放同步资源后再恢复其原来的优先级。
互斥信号量为特殊的二值信号量,由于其特有的优先级继承机制,从而使它更适用于简单互锁,即保护临界资源。
递归信号量
递归,即可以重复获取调用。
即对于已经获取递归互斥量的任务可以重复获取该递归互斥量,该任务拥有递归信号量的所有权。
但任务成功获取多少次递归互斥量,就要返还几次,在此前递归互斥量都处于无效状态,其他任务无法获取,只有持有递归信号量的任务才能获取和释放。
选择抢占式调度器
禁能tickless低功耗模式
OS节拍选择1000Hz,选择TIM1滴答时钟实现
最大优先级数为5
因为芯片选用的STM32F103,RAM只有20K,OS堆大小选择7K
使能任务间直接的消息传递,包含信号量,事件标志组和消息邮箱
OS配置如下图所示:
创建多个任务,每个功能创建为一个任务,任务不需要时就挂起,需要运行时再运行,节省CPU等资源
任务的配置如下图:
采用信号量进行通信,其中互斥信号量进行任务间的通信,保证不同任务在访问共享资源时不会冲突;二值信号量为中断与任务的通信,任务请求信号量时进入阻塞状态,节省资源,中断释放信号量。
二值信号量(用于外部中断和按键扫描之间的通信):
互斥信号量:
Time_Signal负责保护当前时间变量,主要有读取RTC时间、显示时间这两个任务需要访问。
Gyro_Signal负责保护陀螺仪的角度数据,主要有陀螺仪角度读取、游戏这两个任务需要访问。
SW_Signal负责保护按键信息,其中显示时间、修改时间、菜单显示、动画显示、游戏、计时器、按键扫描、闹钟设置均需要访问。
Root显示
陀螺仪读取
菜单选择
更改时间
闹钟设置
闹钟提醒
游戏
动画
这个项目中,之前我是在裸机上采用的前后台系统;在了解了RTOS之后,转而应用了freertos。
在裸机上的感觉:因为多级目录的原因,我需要思考每个按键按下后如何,OLED显示哪些东西,有什么改变,实现什么功能等等;感觉非常复杂。
之后我应用了RTOS,我觉得多级目录变得简单了很多很多,因为我可以专注于当前的显示任务,不需要过多考虑切换的逻辑和按键标志位的有效性更新;当要改变OLED的显示时,直接挂起当前任务然后唤醒目标任务即可。在任务中,我只要专心于当前的和下一级目录即可,检测到什么按键按下时,实现相应功能即可。
同时操作系统移植也是非常简单的,只要改好接口函数或者接口协议即可移植过去,再底层的模块驱动函数不需要更改,系统兼容性和可移植性都变高了,这一特性尤其适合于团队合作一起做一个很大的项目时。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。