给我写一个测试代码测试我的freertos是否正确移植到我的stm32f401zet6开发板要标准库测试代码
时间: 2025-07-23 14:09:21 AIGC 浏览: 29
<think>我们使用标准库(而不是HAL库)来编写测试代码。验证FreeRTOS移植是否成功,通常包括以下几个步骤:
1. 创建两个任务:一个任务用于闪烁LED(表示系统正在运行),另一个任务通过串口打印信息(用于监控)。
2. 验证任务调度是否正常(LED按预期闪烁,串口有输出)。
3. 验证系统节拍(SysTick)是否正常(通过打印的tick计数判断)。
4. 如果可能,可以加入中断和任务间通信的测试(如队列、信号量等)以进一步验证。
注意:在STM32标准库中,我们需要自己配置时钟、GPIO和串口等外设。
以下是一个基于标准库的测试代码示例(假设使用USART1作为串口输出,LED连接在PA5上,按键在PC13):
注意:请根据实际硬件修改引脚。
步骤:
1. 在FreeRTOSConfig.h中配置好FreeRTOS,特别是系统时钟频率(configSYSTICK_CLOCK_HZ)和Tick频率(configTICK_RATE_HZ)。
2. 确保在stm32f4xx_it.c中,SysTick_Handler、PendSV_Handler和SVC_Handler这三个中断服务函数已经被FreeRTOS的相应函数接管(通常注释掉原有的,使用FreeRTOS提供的)。
3. 编写测试任务。
代码结构如下:</think>### 基于标准库的FreeRTOS移植验证测试(STM32F401ZET6)
以下是使用STM32标准外设库编写的测试代码,用于验证FreeRTOS在STM32F401ZET6上的移植是否成功:
```c
#include "stm32f4xx.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
// LED和串口引脚定义
#define LED_PIN GPIO_Pin_5
#define LED_PORT GPIOA
#define USART_TX_PIN GPIO_Pin_9
#define USART_RX_PIN GPIO_Pin_10
#define USART_PORT GPIOA
#define USART USART1
// 全局变量
QueueHandle_t xQueue;
// 函数声明
void RCC_Configuration(void);
void GPIO_Configuration(void);
void USART_Configuration(void);
void vTaskLED(void *pvParameters);
void vTaskPrint(void *pvParameters);
void vTaskSend(void *pvParameters);
int fputc(int ch, FILE *f);
int main(void) {
// 系统初始化
RCC_Configuration();
GPIO_Configuration();
USART_Configuration();
// 创建通信队列
xQueue = xQueueCreate(5, sizeof(uint32_t));
// 创建任务
xTaskCreate(vTaskLED, "LED", 128, NULL, 2, NULL);
xTaskCreate(vTaskPrint, "Print", 128, NULL, 1, NULL);
xTaskCreate(vTaskSend, "Send", 128, NULL, 3, NULL);
// 启动调度器
vTaskStartScheduler();
while(1); // 不应执行到这里
}
// LED闪烁任务
void vTaskLED(void *pvParameters) {
for(;;) {
GPIO_ToggleBits(LED_PORT, LED_PIN);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
// 串口打印任务
void vTaskPrint(void *pvParameters) {
uint32_t received;
for(;;) {
if(xQueueReceive(xQueue, &received, portMAX_DELAY) == pdPASS) {
printf("Recv: %lu | Tick: %lu\r\n", received, xTaskGetTickCount());
}
}
}
// 数据发送任务
void vTaskSend(void *pvParameters) {
uint32_t count = 0;
for(;;) {
xQueueSend(xQueue, &count, portMAX_DELAY);
count++;
vTaskDelay(200 / portTICK_PERIOD_MS);
}
}
// 串口发送字符
int fputc(int ch, FILE *f) {
USART_SendData(USART, (uint8_t)ch);
while(USART_GetFlagStatus(USART, USART_FLAG_TXE) == RESET);
return ch;
}
// 时钟配置
void RCC_Configuration(void) {
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
}
// GPIO配置
void GPIO_Configuration(void) {
GPIO_InitTypeDef GPIO_InitStructure;
// LED (PA5)
GPIO_InitStructure.GPIO_Pin = LED_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(LED_PORT, &GPIO_InitStructure);
// USART1 (PA9-TX, PA10-RX)
GPIO_InitStructure.GPIO_Pin = USART_TX_PIN | USART_RX_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(USART_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(USART_PORT, GPIO_PinSource9, GPIO_AF_USART1);
GPIO_PinAFConfig(USART_PORT, GPIO_PinSource10, GPIO_AF_USART1);
}
// 串口配置
void USART_Configuration(void) {
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART, &USART_InitStructure);
USART_Cmd(USART, ENABLE);
}
```
### 验证步骤与预期结果
1. **任务调度验证**:
- LED应每1秒闪烁一次(500ms亮/500ms灭)
- 串口输出示例:`Recv: 0 | Tick: 5`
- 系统不应进入`main()`中的`while(1)`循环
2. **队列通信验证**:
- 串口应每200ms输出递增数字(0,1,2...)
- 输出格式:`Recv: <数字> | Tick: <当前节拍>`
- 修改`vTaskSend`中的延迟值可改变输出频率
3. **优先级验证**:
- 发送任务(优先级3)应优先于LED任务(优先级2)
- 打印任务(优先级1)应最后执行
4. **稳定性验证**:
- 系统应连续运行至少30分钟不崩溃
- 无串口输出中断或数据丢失现象
### 常见问题排查
1. **LED不闪烁**:
- 检查`FreeRTOSConfig.h`中的`configTICK_RATE_HZ`设置
- 验证系统时钟配置(`SystemInit()`函数)
- 确认GPIO引脚配置正确[^2]
2. **串口无输出**:
- 检查USART时钟使能(`RCC_APB2PeriphClockCmd`)
- 验证波特率设置(115200)
- 确认串口重定向函数`fputc`正常工作
3. **编译错误**:
- 注释`stm32f4xx_it.c`中的`SVC_Handler`、`PendSV_Handler`和`SysTick_Handler`[^2]
- 确保所有FreeRTOS源文件已添加到工程
4. **系统崩溃**:
- 检查任务栈大小(建议初始128字)
- 启用堆栈溢出检测:
```c
// FreeRTOSConfig.h
#define configCHECK_FOR_STACK_OVERFLOW 2
```
### 验证成功标志
- ✅ 多任务按预期优先级执行
- ✅ 系统节拍稳定递增
- ✅ 任务间通信正常
- ✅ 系统可稳定运行
> **关键调试建议**:
> 1. 使用`uxTaskGetNumberOfTasks()`监控任务数量
> 2. 通过`vTaskList()`获取任务状态详情
> 3. 测量系统节拍精度(应接近1ms)
阅读全文
相关推荐


















