RTOS为什么要搞两种API?

发布者:HeavenlyWhisper最新更新时间:2024-06-24 来源: elecfans关键字:RTOS  API  STM32 手机看文章 扫描二维码
随时随地手机看文章

本文以FreeRTOS为例,如果我们自己在官网下载源码然后手动移植代码就是使用FreeRTOS的原生API接口,如果我们使用STM32CubeMX来配置工程就是使用的CMSIS-API接口,是对FreeRTOS的原生API接口进行了封装。


一、RTOS为什么要搞两种API?

CMSIS-RTOS API是ARM公司为RTOS内核制定的一套通用接口协议,它提供了一套「标准的API接口」,可以移植到各种各样的RTOS上,使得上层的软件、中间件、库以及其他组件在不同的RTOS之上都可以正常工作。

简单的说就是:STM32是ARM内核的,这大家都知道。FreeRTOS是一种免费的开源的嵌入式操作系统。那它肯定就不属于ARM公司的对不对?这也很好理解。现在你要在我ARM内核上面使用不是我的RTOS产品,那么我ARM公司就要把你这个RTOS给打包一遍,封装成属于我的适合我的API接口协议类型的CMSIS-RTOS API。这样解释应该好一点。

在STM32上使用FreeRTOS,可以直接使用FreeRTOS的原生接口(原生API),源码移植就是使用的是原生API接口,这无可厚非。你也可以选择CMSIS接口,实际上CMSIS接口和原生接口都是类似的,但是如果你学会了CMSIS的RTOS接口之后,也能自学对应的原生接口,当然还是有区别的,因此还是需要花时间去熟悉的。

学会了CMSIS的最大好处就是,只要其它RTOS有提供CMSIS接口,我们就可以直接使用CMSIS接口,而不需要再花时间去了解原生接口。比如我们在学习UCOS时,发现UCOS的API和FreeRTOS的API不同,是因为我们学的都是它们原生的API,就是我们下载源码后在keil中移植的那种。但是如果我们学会了CMSIS-API,那么不管以后学习哪一个OS,只要这个OS提供了CMSIS的接口,我们就直接可以用CMSIS的API来调用学习,而不需要再花时间去了解原生接口。

STM32CubeMX在提供FreeRTOS时也提供了CMSIS接口,后面具体举例时就可以看到封装的.c文件,总之ST对FreeRTOS封装出了CMSIS接口。

二、使用CubeMX配置FreeRTOS

以STM32F407ZGT6芯片为例,使用CubeMX配置FreeRTOS。

1、新建工程

ec13458c-54af-11ec-b2e9-dac502259ad0.png

2、外部晶振

选择外部晶振

ec4a9e74-54af-11ec-b2e9-dac502259ad0.png

4、下载器

选择四线的SWD接口下载器。

ec724690-54af-11ec-b2e9-dac502259ad0.png

5、打开FreeRTOS

这里可以看到STM32CubeMX只提供了一种RTOS就是FreeRTOS,并且提供的是CMSIS接口API,并没有提供原生的API,所以如果你想学习原生API就必须学会手动移植源码,使用STM32CubeMX来创建工程就必须使用ARM公司的CMSIS API

ec9da1be-54af-11ec-b2e9-dac502259ad0.png


ecc3036e-54af-11ec-b2e9-dac502259ad0.png

Include paramters

这一个与FreeRTOS的原生接口有关,大家凡是看到v打头、x打头的函数,都是FreeRTOS的原生函数,我们现在要使用的是对原生接口封装后的CMSIS API,通过Include paramter的配置可以决定哪些原生接口被使用,哪些不被使用,不过有关Include paramters中的内容,一般情况下使用默认设置即可。

ecfaecfc-54af-11ec-b2e9-dac502259ad0.png

User Constant

在该这栏目中可以添加宏定义,添加后就会在代码中自动生成宏定义的代码,但是我们一般不会这样添加,我们需要定义什么宏定义,我们一般都是直接在代码中编写。

ed341694-54af-11ec-b2e9-dac502259ad0.png

Task and Queues

在这一个栏目中,我们可以添加任务(线程),自动生成代码时就会生成创建任务(线程)的代码,一般会有一个默认任务,如果需要的话我们可以额外添加一个任务,当然我们也可以自己去写这些创建任务的代码。

添加一个任务(线程),默认任务+添加的任务,目前我们有两个任务,创建工程时会自动生成创建这两个任务的代码。

添加之前

ed64d540-54af-11ec-b2e9-dac502259ad0.png

添加之前

添加之后

edbcf324-54af-11ec-b2e9-dac502259ad0.png

添加之后

Timers and Semaphores

通过该栏目可以添加软件定时器、互斥锁和信号量,然后就可以自动生成软件定时器、互斥锁和信号量的代码,但是一般情况是在写代码时我们自己添加相应的代码,而不是自动生成能,所以这个栏目不配置。

edcf81f6-54af-11ec-b2e9-dac502259ad0.png

目前不添加定时器、互斥锁和信号量,编程时在代码中添加。

FreeRTOS Heap Usage(堆设置)

ee1bfffe-54af-11ec-b2e9-dac502259ad0.png

6、时钟配置


Fvco:VCO频率 SYSCLK:系统时钟频率 Fusb:USB,SDIO,RNG等的时钟频率 Fs:PLL输入时钟频率,可以是HSI,HSE等. plln:主PLL倍频系数(PLL倍频),取值范围:64~432. pllm:主PLL和音频PLL分频系数(PLL之前的分频),取值范围:2~63. pllp:系统时钟的主PLL分频系数(PLL之后的分频),取值范围:2,4,6,8.(仅限这4个值!) pllq:USB/SDIO/随机数产生器等的主PLL分频系数(PLL之后的分频),取值范围:2~15.


外部晶振为8M的时候,推荐值:plln=336,pllm=8,pllp=2

ee614c12-54af-11ec-b2e9-dac502259ad0.png

7、工程设置

ee914b56-54af-11ec-b2e9-dac502259ad0.png


eeb87820-54af-11ec-b2e9-dac502259ad0.png

8、生成代码

建议勾选上分文件管理。我们在生成代码的时候,出现了如下提示,我们这里需要解决这个警告,否者会出问题。

eedce2aa-54af-11ec-b2e9-dac502259ad0.png

前面介绍FreeRTOS时说过,FreeRTOS线程切换的本质就是定时器定一个时间,定的时间到了就切换运行其它线程,在默认情况下会使用Systick来作为RTOS的时间片定时器,这里不凑巧的是HAL 库代码已经使用了 Systick,所以上面警告就是告诉你冲突了,我们需要解决这个冲突。

如何解决冲突?

先点击“否”,将 sys 中的 Systick 换成其它定时器,比如tim1,RTOS就使用 tim1来做自己的Systick。

eef7defc-54af-11ec-b2e9-dac502259ad0.png

做了以上设置后在生成代码时就不会再出现前面所提到的警告。

FreeRTOSConfig.h

在生成的工程项目中的头文件目录下有一个FreeRTOSConfig.h,如果是源码移植的话,我们应该修改这一个.h来设置我们需要的配置,但是CubeMx提供了图形化的配置界面,也就是我们前面所介绍的内容,我们进行了前面的配置后,关键配置信息就会记录到这个.h中,最后 FreeRTOS在工作时就会使用到.h 中的相关配置。

3、工程文件介绍

ef116aca-54af-11ec-b2e9-dac502259ad0.png


ef3cd6d8-54af-11ec-b2e9-dac502259ad0.png

CMSIS API

ef7bd1ee-54af-11ec-b2e9-dac502259ad0.png

CMSIS API

怎么样是不是跟我们使用原生API创建的任务函数有点不一样,那是肯定不一样的。但是要明白这种方式只不过是给FreeRTOS原生的API穿上了一件华丽的外衣而已,函数内部其实还是调用的原生API,只不过没让你看见而已。

efb75386-54af-11ec-b2e9-dac502259ad0.png

原生API

eff75d5a-54af-11ec-b2e9-dac502259ad0.png

原生API

不管是CMSIS API还是原生API函数的创建过程基本是一样的,只不过函数不一样,所以也不要太过纠结使用哪一种API,后期这两种API都会分析它们之间的不同,包括消息队列、信号量、互斥量等等!

CMSIS API函数主要有:


SignalEvents//信号 osSignalSet:Setsignalflagsofathread. osSignalClear:Resetsignalflagsofathread. osSignalWait:Suspendexecutionuntilspecificsignalflagsareset. Mutexes//互斥锁 osMutexCreate:Defineandinitializeamutex. osMutexWait:ObtainamutexorWaituntilitbecomesavailable. osMutexRelease:Releaseamutex. osMutexDelete:Deleteamutex. Semaphores//信号量 osSemaphoreCreate:Defineandinitializeasemaphore. osSemaphoreWait:ObtainasemaphoretokenorWaituntilitbecomesavailable. osSemaphoreRelease:Releaseasemaphoretoken. osSemaphoreDelete:Deleteasemaphore. MemoryPool//内存池 osPoolCreate:Defineandinitializeafix-sizememorypool. osPoolAlloc:Allocateamemoryblock. osPoolCAlloc:Allocateamemoryblockandzero-setthisblock. osPoolFree:Returnamemoryblocktothememorypool. MessageQueue//消息队列 osMessageCreate:Defineandinitializeamessagequeue. osMessagePut:Putamessageintoamessagequeue. osMessageGet:Getamessageorsuspendthreadexecutionuntilmessagearrives. MailQueue//邮箱队列 osMailCreate:Defineandinitializeamailqueuewithfix-sizememoryblocks. osMailAlloc:Allocateamemoryblock. osMailCAlloc:Allocateamemoryblockandzero-setthisblock. osMailPut:Putamemoryblockintoamailqueue. osMailGet:Getamailorsuspendthreadexecutionuntilmailarrives. osMailFree:Returnamemoryblocktothemailqueue.


关键字:RTOS  API  STM32 引用地址:RTOS为什么要搞两种API?

上一篇:STMF103R8如何配置ADC采样
下一篇:关于多路步进电机控制系统的设计方案分析

推荐阅读最新更新时间:2024-11-12 15:10

C语言宏定义的使用原理
使用STM32开发的朋友不知道是否有发现过这样的一些宏定义? 如下: #if defined (__CC_ARM) #pragma anon_unions #endif 看到上面的语句一开始确实搞不懂为什么要写这些东西,通过上网去查询,才搞明白这其中的使用原理。 上面的代码段我们可以看到两部分的内容: 1) __CC_ARM 2) #pragma anon_unions 这两个都有啥用呢? 待我一一道来! 1、__CC_ARM 是 ARM 编译中的宏选项 __CC_ARM 是一个编译器的选项,在ARM开发中根据开发环境的不同,有好几个可选的宏选项。
[单片机]
STM32之独立看门狗的那些事
为什么MCU会具有看门狗呢?带着这个疑问,来了解看门狗的那些事。就连51单片机都带有看门狗,说明这条狗对我们来说有着 不一般的意义。看门狗的目的一句话说:防止程序乱跑。MCU在不同的环境下程序的运行会受到干扰,比如陷入死循环怎么办? 这就是养狗的好处呀,就算你没养过狗,你也看过猪跑吧。 先看固件库的几个函数 void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess); void IWDG_SetPrescaler(uint8_t IWDG_Prescaler); void IWDG_SetReload(uint16_t Reload); void IWDG_ReloadC
[单片机]
STM32开发 -- 继电器测试
继电器这个东西,怎么说呢。我之前学过自动化。。。 对它是有一定了解的。 思考: 比如如何测试继电器是否是OK的,能否吸合?? 接下来就简单的来看一下STM32上继电器的使用。 一、继电器介绍 参看:一文读懂继电器那些事儿 参看:维基百科 – 继电器 参看:电磁继电器工作原理透彻详解(1) 1、介绍 继电器(relay)是一种电控制器件,是当输入量的变化达到规定要求时,在电气输出电路中使被控量发生预定的阶跃变化的一种电器。它具有控制系统和被控制系统之间的互动关系。通常应用于自动化的控制电路中,它实际上是用小电流去控制大电流运作的一种 自动开关 。 故在电路中起着自动调节、安全保护、转换电路等作用。 2、分类 ●按用途
[单片机]
<font color='red'>STM32</font>开发 -- 继电器测试
STM32模拟IIC程序
#ifndef __AT24C02_H__ #define __AT24C02_H__ #include stm32f10x.h void i IC init(void); void iicwrite(u8 add,u8 Achar); u8 iicread(u8 add); #endif #include stm32f10x.h #include at24c02.h void iicstart(void); void iicstop(void); void ack(void); void iicwritebyte(u8 a); u8 iicreadbyte(voi
[单片机]
STM32程序超时设计
软件超时机制 1、背景 在嵌入式软件程序设计过程中中,经常会遇到超时(或定时)的处理情况,基本处理思想是在时间到的时候进行相关程序处理,下面介绍两种超时(或定时)的程序设计方案。 2、方案一 基本思想:定时器中断使用一个变量TICK,中断间隔时间t,在准备定时开始时读取此时刻的TICK,在程序运行过程中实时读取当前的TICK信息并计算即可。 因此在时间计算时只需计算开始STARTTICK和结束ENDTICK即可完成时间计算。时间计算T=(ENDTICK-STARTTICK)*t;使用一个定时器中断每t时间处理一次中断,中断里面时间计数值s_u32TCNT++,如下图所示: 程序中定义一个结构体来保存超时开始和超时结
[单片机]
<font color='red'>STM32</font>程序超时设计
STM32如何查找hardfault原因
STM32出现HardFault_Handler故障的原因主要有两个方面: 1、内存溢出或者访问越界。这个需要自己写程序的时候规范代码,遇到了需要慢慢排查。 2、堆栈溢出。增加堆栈的大小。 出现问题时排查的方法: 发生异常之后可首先查看LR寄存器中的值,确定当前使用堆栈为MSP或PSP,然后找到相应堆栈的指针,并在内存中查看相应堆栈里的内容。由于异常发生时,内核将R0~R3、R12、LR、PC、XPRS 寄存器依次入栈,其中LR即为发生异常前PC将要执行的下一条指令地址。 注意:寄存器均是32位,且STM32是小端模式。(参考Cortex-M3权威) 编写问题代码如下: void StackFlow(
[单片机]
<font color='red'>STM32</font>如何查找hardfault原因
STM32_HAL库入门笔记(一) USART配置
串口发送功能: uint8_t TxData = 01234abcde ; HAL_UART_Transmit(&huart2,TxData,10,0xffff);//把TxData的内容通过uart2发送出去,长度是10,timeout的时间是最大值0xffff 串口接收功能1: uint8_t value='F'; HAL_UART_Receive(&huart2,(uint8_t *)&value,1,1000);//在这个语句停留1000ms内等待接收1个字节数据,把数据存放在value中 串口接收功能2: HAL_UART_Receive_IT(&huart2,(uint8_t *)&valu
[单片机]
STM32_HAL库入门笔记(一) USART配置
基于STM32和CAN总线的电动车电池管理系统设计
 随着电池能源的广泛应用,石油资源的枯竭和环境污染,电动汽车以其节能环保的优势引起越来越多的重视,在电动汽车的研究和发展上,车载电池及其管理系统的研究与制造占据着重要位置。电动汽车动力电池在应用中的主要问题表现在:生产过程中,电池的工艺,技术以及成组技术还不能保证其初始性能具有良好的一致性;使用过程中,对过充电、过放电、过温度、过电流等非常敏感,这类情况的发生会明显缩短电池寿命,甚至会导致电池报废。电池组是几十个甚至上百个单体电池串联,单体电池之间存在不一致性,随着连续的充放电循环,电池间的不一致性加剧,电池组的可用容量受容量最小的单体电池制约。对于这些情况,电池的初始性能必须要依靠企业生产工艺的优化,生产过程关键参数的控制来改善
[电源管理]
基于<font color='red'>STM32</font>和CAN总线的电动车电池管理系统设计
小广播
设计资源 培训 开发板 精华推荐

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

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved