RT-Thread论坛
直播中

李超

8年用户 1397经验值
私信 关注
[问答]

相同代码在rt-thread-studio和keil编译和调试下效果不同是怎么回事?

我是刚刚开始学习rt-thread使用rt-thread-studio编译。创建了一个b1see线程下载后正常显示如图(1),一旦复位就会显示有问题如图(2)。
多次复位有概率文字显示正常但上方仍有白线。
每次下载后不复位显示一定正常且调试模式下无论如何复位一定正常。取消使用线程,直接在main循环显示,显示正常。使用cubemx创建nano在keil创建线程下载编译显示正常。请问这个是什么问题。

  • void b1see(void *parameter)
  • {
  •     while(1)
  •     {
  •         r37=HAL_ADC_GetValue(&hadc1)*3.3f/4096;
  •         HAL_ADC_Start(&hadc1);
  •         r38=HAL_ADC_GetValue(&hadc2)*3.3f/4096;
  •         HAL_ADC_Start(&hadc2);
  •         LCD_DisplayStringLine(Line1,(u8*)"       GOODS");
  •         sprintf(tem,"     R37:%0.2fV   ",r37);
  •         LCD_DisplayStringLine(Line3,(u8*)tem);
  •         sprintf(tem,"     R38:%0.2fV   ",r38);
  •         LCD_DisplayStringLine(Line4,(u8*)tem);
  •         rt_thread_mdelay(50);
  •     }
  • }



回帖(1)

敷衍作笑谈

2025-9-23 17:00:52

根据您的描述,问题可能涉及RT-Thread Studio的编译器优化、内存初始化或硬件时序问题。以下是详细分析和解决方案:


问题原因分析




  1. 编译器优化差异(主要嫌疑)



    • RT-Thread Studio默认使用GCC编译器(优化等级-Og),而Keil使用ARMCC(优化等级-O0

    • 浮点运算处理不同:GCC可能将浮点计算优化到寄存器,复位后寄存器值未重置导致异常
      r37 = HAL_ADC_GetValue(&hadc1) * 3.3f / 4096; // 浮点运算在复位后可能未重新初始化




  2. 内存未初始化问题



    • 全局变量在软件复位后未清除(非上电复位时RAM数据可能保留)
      float r37; // 全局变量在软件复位后可能保留旧值




  3. 硬件初始化时序



    • 复位后外设(ADC/显示)未完全初始化时线程已运行

    • 显示驱动复位时序要求严格(白线现象常见于时序问题)




  4. 线程栈溢出



    • 浮点运算占用较多栈空间,默认栈大小(512B-1KB)可能不足






解决方案


1. 关键修改:禁用浮点优化


在RT-Thread Studio的工程设置中:


项目属性 → C/C++构建 → 设置
  → 工具设置 → 优化等级:改为 -O0(无优化)
  → 额外编译标志:添加 -fsigned-char -fno-strict-aliasing

2. 强制硬件重新初始化


main()函数开头添加硬件复位标志:


// main.c
SystemInit(); // 确保调用系统初始化

// 添加硬件复位处理
if (__HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST)) {
    HAL_DeInit();         // 重置所有外设
    HAL_RCC_DeInit();
    __HAL_RCC_CLEAR_RESET_FLAGS(); // 清除复位标志
    SystemClock_Config(); // 重新配置时钟
    MX_GPIO_Init();       // 重新初始化GPIO
    MX_ADC1_Init();       // 重新初始化ADC
    // 显示设备重新初始化
    LCD_Init();
}

3. 增加线程栈大小


在创建线程时指定更大的栈(至少1.5KB):


rt_thread_t tid = rt_thread_create("b1see", b1see, RT_NULL, 
                                  1536,  // 栈大小改为1.5KB
                                  25,    // 优先级
                                  10);   // 时间片

4. 添加线程启动延迟


确保硬件初始化完成后再启动线程:


// main.c
int main(void) {
    // ...硬件初始化...

    // 添加500ms延迟确保外设稳定
    rt_thread_mdelay(500);

    rt_thread_startup(tid); // 启动线程
}

5. 浮点运算安全处理


修改ADC读取代码,避免优化问题:


// 使用volatile防止优化
volatile uint32_t adc_raw = HAL_ADC_GetValue(&hadc1);
r37 = (float)adc_raw * (3.3f / 4096.0f);

// 或改用整数运算(推荐):
int raw_val = HAL_ADC_GetValue(&hadc1);
int voltage_mv = raw_val * 3300 / 4096; // 单位:毫伏



验证步骤



  1. 在RT-Thread Studio中应用上述修改

  2. 执行 Clean 项目 → Rebuild

  3. 使用 SWD复位(非上电复位)测试多次

  4. 检查是否仍有白线/显示异常



特别注意:调试模式(Debug)会强制初始化寄存器,因此问题可能只在独立运行时出现。上述解决方案重点处理了复位时的寄存器/外设状态一致性。



如果问题仍然存在,建议在复位后立即暂停程序,检查:



  • r37变量的内存值

  • ADC寄存器的状态(CR、SR寄存器)

  • 显示控制器的初始化状态(通过STM32CubeMX确认时序参数)

举报

更多回帖

发帖
×
20
完善资料,
赚取积分