You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32F429新芯片首次烧录程序后跑飞问题排查咨询

问题现象

新的STM32F429芯片首次烧录程序后出现死机跑飞现象,屏蔽部分无关代码后重新烧录恢复正常;还原原代码再次烧录也能正常运行。代码中使用了malloc且已正确释放,疑似栈空间问题但无法对应,仅首次烧录新芯片时出现该问题,后续多次烧录无异常。

已知信息:xMbHoldReg为Modbus全局变量,EEPROM底层驱动已验证可用。

相关代码

#include "bsp_all_define.h"
#include "bsp_cms_i2c.h"
#include "app_init.h"

#define EEPROM_STATE_ADR  0X0000
#define EEPROM_DATA_START_ADR  0X0001
uint8_t EEPROM_used_val=0x01;
typedef union
{
    struct
    {
        uint16_t wData_L:8;
        uint16_t wData_H:8;
    }bBit;
    uint16_t nData;
}UN_U16Data;

typedef struct 
{
      UN_U16Data wAI_Filter;
      UN_U16Data wTemptureFilter_1;
      UN_U16Data wTemptureFilter_2;
      UN_U16Data wVoltageFilter;
      UN_U16Data wOCV_Filter;
      UN_U16Data wRCV_Filter;
          UN_U16Data wCurrentFilter;
}S_eeprom_data;
S_eeprom_data eeprom_data;
S_eeprom_data eeprom_data_new;
uint8_t EEPROM_state;
/*******************************************************************************
* Function Name  : structToU8Array
* Description    : 
* Input          : None
* Output         : None
* Return         : None
********************************************************************************/
void structToU8Array(void *data, uint8_t *array, int size) {
     uint8_t *ptr = (uint8_t *)data;
    for (int i = 0; i < size; i++) {
        array[i] = *(ptr + i);
    }
}
/*******************************************************************************
* Function Name  : U8ArrayTostruct
* Description    : 
* Input          : None
* Output         : None
* Return         : None
********************************************************************************/
void U8ArrayTostruct(void *data, uint8_t *array, int size) {
    uint8_t *ptr = (uint8_t *)data;
    for (int i = 0; i < size; i++) {
         *(ptr + i)=array[i];
    }
}
/*******************************************************************************
* Function Name  : Modbus_data_to_eeprom
* Description    : 
* Input          : 
* Output         : None
* Return         : None
********************************************************************************/
void Modbus_data_to_eeprom(void)
{
    eeprom_data_new.wAI_Filter=xMbHoldReg.wAI_Filter;
    eeprom_data_new.wTemptureFilter_1=xMbHoldReg.wTemptureFilter_1;
    eeprom_data_new.wTemptureFilter_2=xMbHoldReg.wTemptureFilter_2;
    eeprom_data_new.wVoltageFilter=xMbHoldReg.wVoltageFilter;
    eeprom_data_new.wOCV_Filter=xMbHoldReg.wOCV_Filter;
    eeprom_data_new.wRCV_Filter=xMbHoldReg.wRCV_Filter;
    eeprom_data_new.wCurrentFilter=xMbHoldReg.wCurrentFilter;
}
/*******************************************************************************
* Function Name  : EEPROM_data_to_modbus
* Description    : 
* Input          : 
* Output         : None
* Return         : None
********************************************************************************/
void EEPROM_data_to_modbus(void)
{
    xMbHoldReg.wAI_Filter=eeprom_data_new.wAI_Filter;
    xMbHoldReg.wTemptureFilter_1=eeprom_data_new.wTemptureFilter_1;
    xMbHoldReg.wTemptureFilter_2=eeprom_data_new.wTemptureFilter_2;
    xMbHoldReg.wVoltageFilter=eeprom_data_new.wVoltageFilter;
    xMbHoldReg.wOCV_Filter=eeprom_data_new.wOCV_Filter;
    xMbHoldReg.wRCV_Filter=eeprom_data_new.wRCV_Filter;
    xMbHoldReg.wCurrentFilter=eeprom_data_new.wCurrentFilter;
}
/*******************************************************************************
* Function Name  : EEPROM_data_init
* Description    : 
* Input          : 
* Output         : None
* Return         : None
********************************************************************************/
void EEPROM_data_init(void)
{
    int size=sizeof(S_eeprom_data);
    EEPROM_Read(EEPROM_STATE_ADR,&EEPROM_state,1);
    if(EEPROM_state==0xFF||EEPROM_state!=EEPROM_used_val)//EEPROM未使用,设置默认参数
    {
        eeprom_data_new.wAI_Filter.nData =50;
        eeprom_data_new.wTemptureFilter_1.nData=50;
        eeprom_data_new.wTemptureFilter_2.nData=50;
        eeprom_data_new.wVoltageFilter.nData=50;
        eeprom_data_new.wOCV_Filter.nData=50;
        eeprom_data_new.wRCV_Filter.nData=50;
        eeprom_data_new.wCurrentFilter.nData=50;
        EEPROM_write_buff(EEPROM_STATE_ADR,&EEPROM_used_val,0x01);
        EEPROM_data_to_modbus();
    }
    else
    {
     uint8_t* data=malloc(size);
     EEPROM_Read(EEPROM_DATA_START_ADR,data,size);
     U8ArrayTostruct(&eeprom_data,data,size);
     U8ArrayTostruct(&eeprom_data_new ,data,size);
     EEPROM_data_to_modbus();
     free(data);
    }
}


/*******************************************************************************
* Function Name  : Data_changed_save
* Description    : 
* Input          : None
* Output         : None
* Return         : None
********************************************************************************/
void Data_changed_save(void)
{
    Modbus_data_to_eeprom();
    if(memcmp(&eeprom_data, &eeprom_data_new, sizeof(S_eeprom_data)) != 0)
    {
        int size=sizeof(S_eeprom_data);
        uint8_t* data=malloc(size);
        structToU8Array(&eeprom_data_new,data,size);
        EEPROM_write_buff(EEPROM_DATA_START_ADR,data,size);
        free(data);
        eeprom_data=eeprom_data_new;
    }
}
//
void Task_dataThread(void* pArg);
/*******************************************************************************
* Function Name  : Task_dataInit
* Description    : 
* Input          : None
* Output         : None
* Return         : None
********************************************************************************/
void Task_dataInit(void)
{
    g_xSysVar.dataThread.id = setThreadStart(Task_dataThread, 1024);
}

/*******************************************************************************
* Function Name  : Task_dataThread
* Description    : 数据更新线程
* Input          : None
* Output         : None
* Return         : None
********************************************************************************/
void Task_dataThread(void* pArg)
{
  EEPROM_data_init();
    while(1)
    {
    Data_changed_save();
    g_xSysVar.dataThread.nsignal++;
        osThreadYield();
        osDelay(100);
    }
}
排查建议
  • 全局变量未初始化问题:全局变量eeprom_data未显式初始化,若首次上电时进入EEPROM_data_init的else分支(比如EEPROM初始值意外匹配EEPROM_used_val),memcmp会对比未初始化的随机内存值,触发不可预期的操作。建议给eeprom_data和eeprom_data_new添加显式初始化,比如定义时赋值= {0}。
  • 堆初始化时机问题:首次上电时,堆内存可能未完成初始化就调用malloc,导致分配失败返回NULL,后续对NULL指针的读写直接引发硬件错误。可在系统初始化阶段先执行堆初始化,或者替换malloc为静态数组(如uint8_t data[sizeof(S_eeprom_data)]),避免动态内存分配的不确定性。
  • 栈空间溢出风险:当前线程栈设置为1024字节,首次上电时可能因系统初始化叠加线程操作导致栈空间不足。尝试增大Task_dataThread的栈空间(如调整为2048字节),同时开启编译器的栈溢出检测选项,捕捉潜在的越界问题。
  • EEPROM首次读写时序问题:新芯片的EEPROM首次上电可能存在时序不稳定,虽然驱动验证可用,但首次烧录时系统初始化速度与后续不同,可能导致读写异常破坏内存数据。建议在EEPROM_data_init开头添加短暂延时,或在系统初始化完成后再启动数据线程,确保外设稳定就绪。
  • 结构体对齐与编译器优化问题:UN_U16Data的位域定义可能导致结构体对齐异常,读写EEPROM时出现字节错位;同时编译器激进优化可能触发未定义行为。建议给S_eeprom_data添加__attribute__((packed))强制无对齐,或降低编译器优化等级(改用-O1或-O0),观察问题是否复现。

内容的提问来源于stack exchange,提问作者zhicheng SONG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 12:33:11