一、串口概述
1、TTL(正逻辑)
| TTL | 输入 | 输出 |
| 高电平 | 2-5V | 2.4-5V |
| 低电平 | 0-0.8V | 0-0.4V |
TTL属于板级通信,包括UART(串口A-A线、蓝牙模块、wifi模块)、IIC、SPI等。
2、UART和USART区别
UART:通用异步接收发送机(一般为通信方式)
USART:通用同步异步接收发送机(一般为stm32单片机的外设)
3、RS485(差分电平)
| RS485 | |
| 高电平 | 2-6V |
| 低电平 | (-2)-(-6)V |
| 特点 | 两线半双工、比特率10M、距离远(最远1.2km)、可以一对多 |
4、基本概念
(1)异步和同步
异步:没有时钟线,同步:有时钟线

(2)串口和并口
串口(串行):单方向通信的数据线只有一条

并口(并行):单方向通信的数据线有多条

(3)单工、半双工和全双工
单工:可以单方向通信的线

半双工:可以双向通信的线(读写不能同时)

全双工:可以双向通信的线(读写可以同时)

(4)波特率和比特率、校验方法
①什么是波特率和比特率?
1、波特率和比特率(位/秒) :描述数据在信道中传输速度的两个相关但不同的指标。
2、区别:波特率表示信号变化的频率,即每秒传输的符号数量。比特率表示信息传输的速率,即每秒传输的二进制位(比特)数量。
②校验方法有哪些?
CRC校验
1、CRC(循环冗余校验):一种检错码,主要用于检测数字数据在传输或存储过程中是否因干扰、硬件故障等原因产生了意外错误。它不是加密算法,不用于保密,只用于验证数据是否完好无损。
2、主要原理:发送端和接收端事先约定一个除数。发送端对原始数据执行一个特定的除法运算,得到的余数就是CRC码。发送方将“原始数据 + CRC码”一起发送。接收方用同样的除数对收到的数据再做一次除法。如果余数为0,则认为数据极大概率正确;如果余数不为0,则肯定发生了错误,数据有误。
奇偶校验
1、奇偶校验:一种最简单的检错码,主要用于检测数字数据在传输或存储过程中是否发生了奇数个比特错误(如1位、3位等)。它不是加密算法,不用于保密,只用于验证数据是否完好无损。
2、主要原理:发送端和接收端事先约定使用奇校验还是偶校验。发送端在原始数据末尾添加一个比特(校验位),使整个数据(原始数据+校验位)中“1”的个数为奇数(奇校验)或偶数(偶校验)。接收方对收到的数据(包括校验位)重新统计“1”的个数。如果统计结果与约定的奇偶性一致,则认为数据基本正确(但无法发现偶数个错误);如果奇偶性不一致,则肯定发生了奇数个错误。
二、IIC协议
IIC协议:半双工同步串行通信,两线制(SDA、SCL),多主多从,有起始/停止信号和应答位。
1、通信说明
SDA:串行数据线 SCL(SCK):串行时钟线
主机:启动总线传输数据,产生时钟信号开启传输的器件
从机:任何被寻址的器件

2、收发数据
主机发送数据给从机

主机接收从机的数据

3、时序图编程之砖头的建造
(1)起始信号

(2)停止信号

(3)数据有效性

(4)应答信号

4、时序图编程之总工程的建设
(1)单片机的通信大楼

(2)写数据

(3)读数据

三、SPI协议
SPI协议:全双工同步串行通信,四线制,一主多从,通过CS选择从机,时钟沿同步收发,无应答机制,速度高于IIC。
1、通信说明
Master:主机 Slave:从机
SCLK:串行时钟线
MOSI:主机发送数据,从机接收数据
MISO:主机接收数据,从机发送数据
SS/CS:选择从机(片选),高电平时从机不工作

2、单机通信和多机通信
(1)单机通信

(2)多机通信

3、通信过程
➊同步:我发送一个数据给你,你就要发回一个数据给我。
➋单片机->SPI模块,单片机发送想要发的8位数据,SPI模块发回8位数据(无意义的数据)。
➌SPI模块->单片机,单片机发送任意的8位数据(为了让SPI模块发送8位数据),SPI模块发送8位数据。


4、CPHA、CPOL、SPCLK
◉ CPHA:时钟相位(决定何时读数据:MISO),CPHA=0 在SPCLK第一个跳变沿读数据,CPHA=1 在SPCLK第二个跳变沿读数据。
◉ CPOL:时钟极性(决定何时写数据:MOSI),CPOL=0 SPCLK低电平不工作,高电平工作
,CPOL=1 SPCLK高电平不工作,低电平工作。
◉ SPCLK:同步串行端口时钟。
5、工作模式
四种模式00 01 10 11
(1)模式0(00)

(2)模式3(11)

6、模拟SPI和硬件SPI
(1)模拟SPI

(2)硬件SPI

(3)硬件SPI编程

四、IIC应用模块和SPI应用模块
1、IIC模块:AT24C02
AT24C02(I²C EEPROM)
1)接口:I²C(2线,低速,地址寻址)。
2)容量:2Kb(256字节),小容量。
3)特点:字节级读写,适用于小数据存储,如配置参数。
2、SPI模块:W25Q128
W25Q128(SPI Flash)
1)接口:SPI(4线,高速,指令寻址)。
2)容量:128Mb(16MB),大容量。
3)特点:页操作/扇区擦除,适合存储程序代码或大量数据。
3、核心区别
1)速度:SPI(W25Q128)远快于I²C(AT24C02)。
2)容量:W25Q128 容量是 AT24C02 的 6.5 万倍。
3)应用:AT24C02 存小参数,W25Q128 存代码/大数据。

五、RTOS实时操作系统
RTOS是一种能在严格时间限制内完成任务调度的嵌入式操作系统,强调确定性和可预测性。
RTOS(Real Time OS)即实时操作系统,根据各个任务的要求,进行资源(包括存储器、外设等)管理、消息管理、任务调度、异常处理等工作。
为什么使用RTOS?
a、嵌入式实时操作系统提高了系统的可靠性。
b、提高了开发效率,缩短了开发周期,例如官方设置提供网络协议栈、文件系统、图形界面(ucGUI、emWIN、QT.....)的支持。
c、嵌入式实时操作系统充分发挥了32位CPU的多任务的潜力。
(1)裸机开发的例子

(2)RTOS开发的例子

六、RTOS的任务状态

任务状态机制
七、资源保护
|
资源共享方法 |
何时选用 |
|
关中断、开中断 (临界区) |
前提条件: 当访问共享资源的速度很快(读取或写入极少量数据时、需要和中断服务程序共享变量或数据结构、喂狗操作等) 关于可靠访问也得使用开关中断的方法:如FLASH写数据。就算FLASH访问比较耗时,都得使用开关中断的方法,保证数据的可靠写入和访问,因为数据是无价的。 影响: 由于使用该方法会影响中断延迟,所以极度不推荐使用该方法。 |
|
给调度器上锁、解锁 |
前提条件: 当访问共享资源如访问变量缓冲区数据,甚至变量值自加/自减。 影响: 给调度器上锁同样有缺点,会导致给调度器上锁的任务成为最高优先级。 这已经有悖于RTOS的初衷,所以同样不推荐使用该方法,当然该方法比关中断要好些,起码不会影响系统的中断延迟。 |
|
信号量 |
前提条件: 当所有的任务可以无限等待对共享资源(常见于硬件的访问,而该硬件的使用时候也比较耗时间)的访问时。 影响: 使用信号量可能导致优先级反转的问题,这样会破坏任务的预期顺序;然而其优点在于它的速度使用互斥型信号量要略快一些。 |
|
互斥型信号量 (互斥量、互斥锁) |
前提条件: 这是访问共享资源的首选方法。特别是当某些任务对共享资源(常见于硬件的访问,而该硬件的使用时候也比较耗时间)访问有时间要求时。 影响: RTOS的互斥型信号量具有一套内建的优先级继承机制,用来避免优先级反转的问题。然而正如上文提到的,该方法相对于普通信号量来说要稍慢一些,因为占有互斥型信号量的任务的优先级可能需要改变,这要占用CPU的时间。 |
1、临界区
(1)涉及到的内核控制函数
①函数taskENTER_CRITICAL:进入临界区,用于任务函数中,此函数本质上是一个宏。
②函数taskEXIT_CRITICAL:退出临界区,用于任务函数中,此函数本质上是一个宏。
③函数taskENTER_CRITICAL_FROM_ISR:进入临界区,用于中断服务函数中,此函数本质上是一个宏。
④函数taskEXIT_CRITICAL_FROM_ISR:退出临界区,用于中断服务函数中,此函数本质上是一个宏。
2、调度器
①函数vTaskSuspendAll:挂起任务调度器,调用此函数不需要关闭可屏蔽中断即可挂起任务调度器。
②函数xTaskResumeAll:此函数用于将任务调度器从挂起状态恢复。
3、信号量
①创建一个计数信号量
#include "semphr.h"
SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount);
参数说明:
-
uxMaxCount:计数信号量的最大值,当达到这个值的时候,信号量不能再被释放。
-
uxInitialCount:创建计数信号量的初始值。
返回值:
-
成功:返回一个计数信号量句柄,用于访问创建的计数信号量。
-
失败:返回 NULL。
②删除一个信号量
vSemaphoreDelete()用于删除一个信号量,包括二值信号量、计数信号量、互斥量和递归互斥量。如果有任务阻塞在该信号量上,那么不要删除该信号量。
void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );
参数说明:xSemaphore信号量句柄。
返回值:无。
③信号量释放(V操作)
xSemaphoreGive() 是释放信号量的宏(实际调用消息队列发送函数),适用于二值信号量、计数信号量和互斥量,但不能用于递归互斥量,且禁止在中断中使用。
BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore );
参数说明:xSemaphore信号量句柄。
返回值:
-
成功:pdTRUE信号量被释放。
-
失败:使用pdFALSE。
④在中断释放信号量(V操作)
用于释放一个信号量,带中断保护。被释放的信号量可以是二进制信号量和计数信号量。
BaseType_t xSemaphoreGiveFromISR(SemaphoreHandle_t xSemaphore,signed BaseType_t *pxHigherPriorityTaskWoken)
参数说明:
-
xSemaphore:信号量句柄。
-
pxHigherPriorityTaskWoken:在中断中使用
xSemaphoreGiveFromISR()释放信号量时,若唤醒的任务优先级 ≥ 当前被中断的任务,则参数pxHigherPriorityTaskWoken会被设为pdTRUE,提示需在中断退出前执行上下文切换。从 FreeRTOS V7.3.0 起,该参数可为NULL(表示不需要此提示)。
返回值:
-
成功:pdTRUE信号量被释放。
-
失败:使用pdFALSE。
⑤获取一个信号量,可以是二值信号量、计数信号量、互斥量。(P操作)
xSemaphoreTake() 用于获取二值信号量、计数信号量或互斥量(递归互斥量除外),本质是调用 xQueueGenericReceive() 的宏,且不能用于中断,中断场景必须使用其保护版本 xQueueReceiveFromISR()。
BaseType_t xSemaphoreTake( SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait );
参数说明:
-
xSemaphore:信号量句柄。
-
xBlockTime :等待信号量的超时时间
xTicksToWait以 tick 为单位;若INCLUDE_vTaskSuspend为 1 且该参数设为portMAX_DELAY,则任务将无限期阻塞(无超时)。
返回值:
-
成功:返回pdTRUE。
-
失败:返回errQUEUE_EMPTY(指定的超时时间内获取失败)。
从该宏定义可以看出释放信号量本质是一次消息出队操作。当任务试图获取信号量时,若信号量无效,任务将在用户指定的阻塞时间(xBlockTime)内等待;若在此期间信号量变为有效,或等待超时,任务都会自动从阻塞态转移为就绪态。
⑥在中断获取一个信号量,可以是二值信号量、计数信号量(P操作)
xSemaphoreTakeFromISR() 是 xSemaphoreTake() 的中断安全版本,无阻塞机制,只能用于二值信号量和计数信号量,不能用于互斥量。原因是互斥量的优先级继承机制在中断中毫无意义,且互斥量本身不允许在中断中使用。
BaseType_t xSemaphoreTakeFromISR(SemaphoreHandle_t xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken)
功能描述:在中断中获一个信号量(其实很少在中断中获取信号量)。可以是二值信号量、计数信号量。
参数说明:
-
xSemaphore:信号量句柄。
-
pxHigherPriorityTaskWoken:在中断中使用
xSemaphoreTakeFromISR()时,若唤醒了更高优先级的任务,参数pxHigherPriorityTaskWoken会置为pdTRUE,提示需要在中断退出前进行上下文切换。从 FreeRTOS V7.3.0 起,该参数可为NULL(表示不需要此提示)。
返回值:
-
成功:返回 pdTRUE。
-
失败:返回 errQUEUE_EMPTY(失败因为信号量不可用)。
⑦创建一个二值信号量
二值信号量适合用于同步(因无优先级继承,简单高效),互斥信号量适合用于互斥访问(因有优先级继承,可避免优先级翻转)。二者虽类似,但优先级继承机制是关键区分点。
SemaphoreHandle_t vSemaphoreCreateBinary( void );
参数说明:无
返回值:
-
成功:返回一个二值信号量句柄,用于访问创建的二值信号量。
-
失败:返回 NULL。
⑧优先级翻转
优先级翻转(Priority Inversion)是一个实时操作系统中典型的多任务调度问题。
-
现象:当高优先级任务因等待被低优先级任务占用的共享资源(如互斥量)而被阻塞时,中优先级任务抢占CPU执行,导致高优先级任务迟迟无法运行,其优先级形同虚设。
-
后果:系统调度行为反常,仿佛高、低优先级发生了“翻转”,严重时会破坏任务的实时性。
-
解决方案:使用支持优先级继承机制(如FreeRTOS的互斥信号量)的锁,可有效防止此问题。
4、互斥信号量
①互斥量创建
SemaphoreHandle_t xSemaphoreCreateMutex( void )
参数说明:无
返回值:
-
成功:信号量句柄。
-
失败:NULL。
②互斥量删除
void vSemaphoreDelete( SemaphoreHandle_t xSemaphore )
参数说明:信号量句柄
返回值:无
③互斥量获取
xSemaphoreTake(SemaphoreHandle_t xSemaphore,TickType_t xBlockTime)
参数说明:
-
xSemaphore:信号量句柄。
-
xBlockTime:等待信号量的超时时间
xTicksToWait以 tick 为单位;若INCLUDE_vTaskSuspend为 1 且该参数设为portMAX_DELAY,则任务将无限期阻塞(无超时)。
返回值:
-
成功:返回pdTRUE。
-
失败:返回errQUEUE_EMPTY(指定的超时时间内获取失败)。
④互斥量释放
BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore )
参数说明:xSemaphore信号量句柄。
返回值:
-
成功:pdTRUE。
-
失败:pdFALSE。
⑤死锁
死锁是指两个或多个任务互相等待对方释放自己所需的资源,导致所有相关任务都无法继续执行的一种僵局。
发生死锁的四个必要情况(缺一不可):
-
互斥:资源不能被共享,一次只能一个任务占用。
-
持有并等待:任务已持有至少一个资源,又在等待其他任务持有的资源。
-
不可剥夺:资源只能由持有者主动释放,其他任务无法强行夺取。
-
循环等待:形成“任务A等B、B等C、C等A”的环形依赖链。
典型场景:任务A锁住资源1,等待资源2;任务B锁住资源2,等待资源1,双方永远等待。
5、事件标志组
①事件标志组创建
#include "event_groups.h"
EventGroupHandle_t xEventGroupCreate(void)
参数说明:无
返回值:
-
成功:返回事件标志组的句柄。
-
失败:返回NULL。
②事件标志组删除
void vEventGroupDelete( EventGroupHandle_t xEventGroup )
参数说明:xEventGroup事件标志组的句柄
返回值:无
③事件标志组指定的位的置位
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )
参数说明:
-
xEventGroup:事件标志组的句柄
-
uxBitsToSet:参数用于指定事件标志组中需要被置位(设为1)的事件位。其值是一个位掩码,每一位对应一个标志位,通过按位或组合可实现多个位同时置位(如0x09表示同时置位 bit3 和 bit0)。
返回值:返回调用xEventGroupSetBits()时事件组中的值。
④在中断中执行事件标志组置位
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken )
参数说明:
-
xEventGroup:事件标志组的句柄
-
uxBitsToSet:参数用于指定事件标志组中需要被置位(设为1)的事件位。其值是一个位掩码,每一位对应一个标志位,通过按位或组合可实现多个位同时置位(如0x09表示同时置位 bit3 和 bit0)。 -
pxHigherPriorityTaskWoken:在使用之前必须初始化成 pdFALSE。
在中断中使用 xEventGroupSetBitsFromISR() 设置事件位时,若因此唤醒了更高优先级的任务,则参数 pxHigherPriorityTaskWoken 会被设为 pdTRUE,提示需要在中断退出前进行任务切换。从 FreeRTOS V7.3.0 起,该参数可为 NULL(表示不需要此提示)。
返回值:
-
成功:返回pdPASS。
-
失败:返回pdFAIL。
⑤等待事件标志组
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait )
参数说明:
-
xEventGroup:事件标志组的句柄
-
uxBitsToWaitFor:指定要等待的一个或多个事件位(按位或组合)。 -
xClearOnExit:等待成功后,是否自动清除uxBitsToWaitFor指定的位。 -
xWaitForAllBits:-
pdTRUE:等待所有指定位都置位(逻辑与)。 -
pdFALSE:等待任意一个指定位置位(逻辑或)。
-
-
xTicksToWait:最大等待超时时间(tick),可用portTICK_PERIOD_MS换算为毫秒。
返回值:返回事件组的实际状态(所有被置位的位),可能包含额外位或仅部分指定位,需要用户自行按位和 uxBitsToWaitFor 来判断等待条件是否真正满足。
⑥事件标志组指定的位清零
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
参数说明:
-
xEventGroup:事件标志组的句柄
-
uxBitsToClear:指定事件标志组中需要被清除(设为0)的事件位。其值是一个位掩码,每一位对应一个标志位,通过按位或组合可实现多个位同时清除(如0x09表示同时清除 bit3 和 bit0)。
返回值:事件标志组还没有清除指定位之前的值。
⑦在中断中执行事件标志组指定的位清零
BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
参数说明:
-
xEventGroup:事件标志组的句柄
-
uxBitsToClear:指定事件标志组中需要被清除(设为0)的事件位。其值是一个位掩码,每一位对应一个标志位,通过按位或组合可实现多个位同时清除(如0x09表示同时清除 bit3 和 bit0)。
返回值:
-
成功:返回pdPASS。
-
失败:返回pdFAIL。
⚠️注意事项:若使用xEventGroupSetBitsFromISR、xEventGroupClearBitsFromISR等函数,官方要求3个宏定义生效。
FreeRTOSConfig.h文件
#define configUSE_TRACE_FACILITY 1
#define configUSE_TIMERS 1
FreeRTOS.h文件
#ifndef INCLUDE_xTimerPendFunctionCall
#define INCLUDE_xTimerPendFunctionCall 1
#endif
6、消息队列
①消息队列创建函数
QueueHandle_t xQueueCreate(UBaseType_t uxQueueLength, UBaseType_t uxItemSize);
功能描述:用于创建一个新的队列。
参数:
-
uxQueueLength:队列能够存储的最大消息单元数目,即队列长度。
-
uxItemSize:队列中消息单元的大小,以字节为单位,该大小设置非常重要,否则得到的数据不完整。
返回值:
-
成功:返回一个队列句柄,用于访问创建的队列;
-
失败:返回NULL,可能原因是创建队列需要的 RAM 无法分配成功。
②消息队列静态创建函数
QueueHandle_t xQueueCreateStatic(UBaseType_t uxQueueLength, UBaseType_t uxItemSize, uint8_t *pucQueueStorageBuffer, StaticQueue_t *pxQueueBuffer );
功能描述:用于创建一个新的队列。
参数:
-
uxQueueLength:队列能够存储的最大消息单元数目,即队列长度。
-
uxItemSize:队列中消息单元的大小,以字节为单位。
-
pucQueueStorageBuffer:指针,指向一个 uint8_t 类型的数组,数组的大小至少有uxQueueLength* uxItemSize 个字节。当 uxItemSize 为 0 时,pucQueueStorageBuffer 可以为 NULL。
-
pxQueueBuffer:指针,指向 StaticQueue_t 类型的变量,该变量用于存储队列的数据结构。
返回值:
-
成功:返回一个队列句柄,用于访问创建的队列;
-
失败:返回NULL,可能原因是创建队列需要的 RAM 无法分配成功。
③动态和静态创建函数
什么是动态创建函数和静态创建函数呢?这里我们额外了解一下它们的区别。
1. 动态创建(xQueueCreate())
-
内存来源:队列的控制块与存储区(消息缓冲区)均自动从堆(
pvPortMalloc)中动态分配。 -
优点:使用简单,无需关心内存布局。
-
缺点:可能导致堆碎片,且无法在编译期确定内存占用。
2. 静态创建(xQueueCreateStatic())
-
内存来源:队列的控制块与存储区需由用户预先提供(通常为全局数组或静态变量)。
-
优点:确定性高,无动态内存分配失败风险,适合对可靠性要求严格的系统(如汽车、医疗)。
-
缺点:需手动计算并分配内存,使用稍繁琐。
总结:
-
动态创建:内核自动用
pvPortMalloc()帮你申请内存。 -
静态创建:你必须自己提前准备好内存,然后传给内核。
一句话记住:动态 = 内核替你 malloc;静态 = 你自己给内存。
④用于向队列尾部发送一个队列消息
BaseType_t xQueueSend(QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait);
参数说明:
-
xQueue:队列句柄。
-
pvItemToQueue:指针,指向要发送到队列尾部的队列消息。
-
xTicksToWait:指定当队列满时,任务等待队列出现空闲的最大超时时间。若设为
0则立即返回;单位为 tick,可用portTICK_PERIOD_MS换算为毫秒;当INCLUDE_vTaskSuspend为 1 且设为portMAX_DELAY时,任务将无限期挂起等待(无超时)。
返回值:
-
成功:返回 pdTRUE。
-
失败:返回 errQUEUE_FULL。
⑤在中断服务程序中用于向队列尾部发送一个消息
BaseType_t xQueueSendFromISR(QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken);
参数说明:
-
xQueue:队列句柄。
-
pvItemToQueue:指针,指向要发送到队列尾部的消息。
-
pxHigherPriorityTaskWoken:在中断中使用队列发送函数时,若入队操作唤醒了更高优先级的任务,则参数
pxHigherPriorityTaskWoken会被设为pdTRUE,提示需要在中断退出前执行上下文切换。从 FreeRTOS V7.3.0 起,该参数可为NULL(表示不需要此提示)。
返回值:
-
成功:返回 pdTRUE。
-
失败:返回 errQUEUE_FULL。
⑥向队列队首发送一个消息
BaseType_t xQueueSendToFront( QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait );
参数说明:
-
xQueue:队列句柄。
-
pvItemToQueue:指针,指向要发送到队列尾部的消息。
-
xTicksToWait:指定当队列满时,任务等待队列出现空闲的最大超时时间。若设为
0则立即返回;单位为 tick,可用portTICK_PERIOD_MS换算为毫秒;当INCLUDE_vTaskSuspend为 1 且设为portMAX_DELAY时,任务将无限期挂起等待(无超时)。
返回值:
-
成功:返回 pdTRUE。
-
失败:返回 errQUEUE_FULL。
⑦在中断服务程序中向消息队列队首发送一个消息
BaseType_t xQueueSendToFrontFromISR(QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken);
参数说明:
-
xQueue:队列句柄。
-
pvItemToQueue:指针,指向要发送到队首的消息。
-
pxHigherPriorityTaskWoken:在中断中使用队列发送函数时,若入队操作唤醒了更高优先级的任务,则参数
pxHigherPriorityTaskWoken会被设为pdTRUE,提示需要在中断退出前执行上下文切换。从 FreeRTOS V7.3.0 起,该参数可为NULL(表示不需要此提示)。
返回值:
-
成功:返回 pdTRUE。
-
失败:返回 errQUEUE_FULL。
⑧从一个队列中接收消息,并把接收的消息从队列中删除
BaseType_t xQueueReceive(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait);
参数说明:
-
xQueue:队列句柄。
-
pvBuffer:指针,指向接收到要保存的数据。
-
xTicksToWait:指定当队列满时,任务等待队列出现空闲的最大超时时间。若设为
0则立即返回;单位为 tick,可用portTICK_PERIOD_MS换算为毫秒;当INCLUDE_vTaskSuspend为 1 且设为portMAX_DELAY时,任务将无限期挂起等待(无超时)。
返回值:
-
成功:返回 pdTRUE。
-
失败:返回 pdFALSE。
若接收完消息,不想删除,可以使用xQueuePeek函数。
⑨在中断中从一个队列中接收消息,并从队列中删除该消息
BaseType_t xQueueReceiveFromISR(QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxHigherPriorityTaskWoken);
参数说明:
-
xQueue:队列句柄。
-
pvBuffer:pxHigherPriorityTaskWoken
-
pxHigherPriorityTaskWoken:在中断中使用队列发送函数时,若入队操作唤醒了更高优先级的任务,则参数
pxHigherPriorityTaskWoken会被设为pdTRUE,提示需要在中断退出前执行上下文切换。从 FreeRTOS V7.3.0 起,该参数可为NULL(表示不需要此提示)。
返回值:
-
成功:返回 pdTRUE。
-
失败:返回 pdFALSE。
若接收完消息,不想删除,可以使用xQueuePeekFromISR函数。
⑩pdMS_TO_TICKS函数使用
宏pdMS_TO_TICKS用于将毫秒转成节拍数,FreeRTOS V8.1.0及以上版本才有这个宏。
const TickType_t xTicksToWait = pdMS_TO_TICKS( 100 );
八、时钟树

STM32F4系列时钟树


1万+

被折叠的 条评论
为什么被折叠?



