该问题已解决,void start_task(void *pvParameters)
{
for (;😉
{
if (mpu_init_flag == 0)
{
HAL_UART_Transmit(&huart1, (uint8_t *)"exec 3\r\n", 8, 0xFFFF);
uint8_t who_am_i = MPU6050_Read_ID();
HAL_UART_Transmit(&huart1, (uint8_t *)"exec 6\r\n", 8, 0xFFFF);
if (who_am_i != 0x68 && who_am_i != 0x69) // MPU6050的默认ID是0x68或0x69
{
HAL_UART_Transmit(&huart1, (uint8_t *)"exec 4\r\n", 8, 0xFFFF);
sprintf((char *)uart_buf, "MPU6050 ID error: 0x%02X (expected 0x68 or 0x69)\r\n", who_am_i);
HAL_UART_Transmit(&huart1, uart_buf, strlen((char *)uart_buf), 0xFFFF);
}
else
{
HAL_UART_Transmit(&huart1, (uint8_t *)"exec 5\r\n", 8, 0xFFFF);
if (!calibration_done)
{
MPU6050_Calibrate(&mpu_cal_data, 30); // 采集1000个样本
calibration_done = 1;
}
MPU6050_Read_Accel(&ax, &ay, &az);
MPU6050_Read_Gyro(&gx, &gy, &gz);
temp = MPU6050_Read_Temp();
MPU6050_ApplyCalibration(&ax, &ay, &az, &gx, &gy, &gz, &mpu_cal_data);
sprintf((char *)uart_buf,
"\r\n-----------------------------\r\n"
"Accel (raw): ax:%6d, ay:%6d, az:%6d\r\n" // 加速度原始值
"Gyro (raw): gx:%6d, gy:%6d, gz:%6d\r\n" // 陀螺仪原始值
"Temperature: %dC\r\n" // 温度
"-----------------------------\r\n\r\n",
ax, ay, az, gx, gy, gz, temp);
HAL_UART_Transmit(&huart1, uart_buf, strlen((char *)uart_buf), 0xFFFF);
HAL_UART_Transmit(&huart1, "\r\n sprintf\r\n", 24, 0xFFFF);
}
}这里展示了部分函数,最后发现是uint8_t uart_buf[128]; 这里,发生溢出了,可能原因是不同编译器内存机制的差异,Keil MDK:默认对内存越界的检测较宽松,可能未启用严格的栈 / 堆保护,即使缓冲区溢出,程序可能 “侥幸” 运行(但存在隐藏风险)。
VS Code + EIDE(通常搭配 GCC):GCC 默认可能启用更严格的内存检查(如 -fstack-protector 等编译选项),一旦检测到缓冲区溢出,会直接触发程序异常(如终止运行、进入硬件错误中断),表现为 “不能运行”。其他可能因素,栈空间分配差异
任务栈大小(如 START_TASK_STACK = 128)可能在不同环境下的实际占用不同:
GCC 编译的代码可能因库函数(如 sprintf)的实现方式,栈占用更大;
若任务栈与全局变量在内存布局上相邻,uart_buf 溢出可能直接破坏栈数据,导致任务崩溃。
内存布局差异
不同编译器对全局变量的内存分配顺序不同:
在 Keil 中,uart_buf 相邻的内存可能是 “无关数据”,溢出后影响较小;
在 EIDE(GCC)中,uart_buf 可能紧邻关键变量(如任务控制块、中断向量表),溢出后直接导致程序崩溃。建议使用snprintf