freertos操作系统注意事项

消息队列与嵌入式任务管理

1.如果想用消息队列替代全局变量,在多个地方使用这个全局变量时,等待消息队列不能用xQueueReceive,这个函数会在使用后将消息队列中的数据删除,使用xQueuePeek,这个函数只会复制消息队列中的消息并不会删除消息队列中的参数,所以如果在接收完这个队列的时候如果要再次向这个队列发消息的情况下不建议使用这种方式

在一个函数中出现Peek和Send,如果send等待时间是永久等待会造成一些不可预估的现象

同样的,只有只是想将数据复制出来使用有两种方式,一种是Receive+Send适用于更改数据,但是也可以保证不会影响数据,还有一种是Peek,如果是这种适用于这个队列等于全局变量的情况,要么每一次send之前,自己来销毁数据而不是接收方销毁数据。

2.采取消息队列的方式需要注意在函数中还需要声明一个局部变量,如果被外部的任务调用这个函数,使用直接声明局部变量的方式在外部任务堆栈空间不够大的情况下会导致任务死机,这种情况出现取决于局部变量占据的空间,所以在操作系统中最好使用指针,pvPortMalloc+free的方式

3.操作系统的vportfree和pvportmalloc一定要对应起来,切记不要使用成free,否则会造成严重的内存泄漏问题,如果这个函数一直运行的话甚至会导致死机。虽然不当使用会造成内存泄漏,但是这个是比较容易发现的,最好在任务中定时打印获取可用空间大小,方便及时发现问题。

最容易出现问题的地方在于返回值,任何一个分支的返回值之前都要进行一个释放的操作,否则一旦进入异常分支造成的内存泄漏可能容易被忽略。有些异常现象可能是由于内存泄漏造成的。

另:在操作系统中就不要使用malloc和free了

4.高优先级任务后面需要加个延时把时间让给低优先级任务执行,但是这个延时需要注意如果在任务有固定频率的时候不可以设置的比应该有的频率还要低,否则会影响到原先的频率,比如说像有1Hz频率接收的情况下任务延时就不能超过1000ms

### FreeRTOS操作系统STM32单片机上的移植和应用实例 #### 1. FreeRTOS概述 FreeRTOS是一种轻量级的实时操作系统,专为嵌入式系统设计。它支持多任务调度、信号量、消息队列等功能,适用于资源受限的微控制器[^1]。通过合理配置,FreeRTOS可以在各种硬件平台上运行,包括STM32系列单片机。 #### 2. 移植FreeRTOSSTM32的关键步骤 ##### 2.1 配置开发环境 确保已安装适合STM32的开发工具链,例如STM32CubeIDE或Keil MDK。创建一个新的工程,并配置基本的硬件外设,如时钟、GPIO等[^2]。 ##### 2.2 添加FreeRTOS源文件 将FreeRTOS源码包中的核心文件和与STM32兼容的端口文件添加到工程中。这些文件通常位于`Source`和`portable`目录下[^2]。 ##### 2.3 配置`FreeRTOSConfig.h` 编辑`FreeRTOSConfig.h`以适应具体的硬件平台和应用需求。关键配置项包括: - `configTICK_RATE_HZ`:定义系统节拍频率。 - `configMINIMAL_STACK_SIZE`:设置最小堆栈大小。 - `configTOTAL_HEAP_SIZE`:指定可用堆内存大小。 ##### 2.4 修改中断向量表 更新中断向量表以包含FreeRTOS所需的中断处理函数,如`vPortSVCHandler`和`xPortPendSVHandler`[^2]。 #### 3. 应用实例:LED闪烁任务 以下是一个简单的FreeRTOS任务示例,用于控制STM32单片机上的LED闪烁: ```c #include "stm32f4xx_hal.h" #include "FreeRTOS.h" #include "task.h" void vLEDTask(void *pvParameters) { GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); while (1) { HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); vTaskDelay(pdMS_TO_TICKS(500)); // 延迟500毫秒 } } int main(void) { HAL_Init(); xTaskCreate(vLEDTask, "LED_TASK", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL); vTaskStartScheduler(); for (;;); } ``` 上述代码创建了一个名为`vLEDTask`的任务,该任务每隔500毫秒切换一次GPIOA上的PIN5状态[^4]。 #### 4. 进一步优化和扩展 根据项目需求,可以进一步优化FreeRTOS的配置和任务设计。例如,调整任务优先级、增加互斥锁或信号量以实现任务间的同步[^1]。 #### 5. 注意事项 - 确保堆栈大小足够以避免溢出。 - 在调试过程中,使用串口输出或调试工具监控任务状态。 - 如果使用STM32CubeMX生成代码,可以选择集成FreeRTOS的支持[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值