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

LPC2368系统中MUX多路复用器随机GPIO写入异常(约8小时一次)的故障排查求助

LPC2368系统中MUX多路复用器随机GPIO写入异常(约8小时一次)的故障排查求助

我手上有一套老的遗留系统,底层测量板SB用的是跑裸机C代码的LPC2368,上面还叠了一块跑Linux的LPC17xx板卡。

SB的核心逻辑分两部分:一个基础循环处理通用业务逻辑(比如CAN总线读取结果、电压测量结果的后续处理等);还有一个1ms的定时器中断服务程序,专门负责从AD转换器读取数值、通过DIO写控制MUX切换不同的输入电压通道,同时处理其他相关操作。

系统相关细节

  • MUX是三状态循环切换:状态按00→01→10→00循环,有个状态机专门跟踪当前阶段和选中的通道
  • 外部AD转换器读取MUX输出,转换时间150ms;SPI选通ADC时,会先输出上一次的转换结果,同时启动新的转换
  • 我用FIO0SET和FIO0CLR来控制GPIO,不过是通过一个结构体封装的方式调用的,结构体定义如下:
typedef struct {
    volatile u32* pu32Dir;
    volatile u32* pu32Data;
    volatile u32* pu32Set;
    volatile u32* pu32Clr;
    volatile u32* pu32Mask;
    volatile u32* pu32FuncSel[2];
    volatile u32* pu32PullEna[2];
} port_type;

const port_type gaxPortList[5]= {
    { (volatile u32*)&FIO0DIR, (volatile u32*)&FIO0PIN, (volatile u32*)&FIO0SET, (volatile u32*)&FIO0CLR, (volatile u32*)&FIO0MASK, {(volatile u32*)&PINSEL0, (volatile u32*)&PINSEL1}, {(volatile u32*)&PINMODE0, (volatile u32*)&PINMODE1} },
    // 其他端口定义省略
};
  • 负责MUX控制的Io_ReadAdc()是在1ms定时器中断里调用的,相关逻辑如下(只保留出问题的AMUX_VM_SB部分):
// 提前声明的配置项
DECL_AIO_CONFIG(AIO_SYS_VM, 0x40, AMUX_VM_SB, 0, AIO_OS_CNT_A, AIO_AVG_CNT_A, 151),
DECL_AIO_CONFIG(AIO_MIDPOINT_VM, 0x40, AMUX_VM_SB, 1, AIO_OS_CNT_A, AIO_AVG_CNT_A, 152),
DECL_AIO_CONFIG(AIO_IOB_EFD_VM, 0x40, AMUX_VM_SB, 2, AIO_OS_CNT_A, AIO_AVG_CNT_A, 153),

static void Io_ReadAdc(void) {
    static u8 u8CurrentDevice = 0;
    static u8 u8NextDevice = 0;
    static ms_timer_type tSbMuxVmTimer;
    static aio_meas_state_type eSbMuxVmMeasState = AIO_MEAS_STATE_IDLE;
    static u8 u8SbMuxVmActiveChanDevNum = SB_MUX_VM_MIDPOINT_INDEX;
    static u8 u8SbMuxVmOldChanDevNum = SB_MUX_VM_SYS_INDEX;
    const aio_config_type* pxConfig;
    aio_state_type* pxState;

    if (!gbInitialized) return;

    pxConfig = &(gaxAioConfig[u8CurrentDevice]);
    pxState = &(gaxAioState[pxConfig->eDevice]);

    if (pxConfig->eMux == AMUX_VM_SB) // 出问题的就是这个MUX
    {
        if (eSbMuxVmMeasState == AIO_MEAS_STATE_IDLE)
        {
            if (u8SbMuxVmActiveChanDevNum == SB_MUX_VM_SYS_INDEX)
            {
                u8SbMuxVmOldChanDevNum = u8SbMuxVmActiveChanDevNum;
                u8SbMuxVmActiveChanDevNum = SB_MUX_VM_MIDPOINT_INDEX;
            }
            else if (u8SbMuxVmActiveChanDevNum == SB_MUX_VM_MIDPOINT_INDEX)
            {
                u8SbMuxVmOldChanDevNum = u8SbMuxVmActiveChanDevNum;
                u8SbMuxVmActiveChanDevNum = SB_MUX_VM_EFD_INDEX;
            }
            else if (u8SbMuxVmActiveChanDevNum == SB_MUX_VM_EFD_INDEX)
            {
                u8SbMuxVmOldChanDevNum = u8SbMuxVmActiveChanDevNum;
                u8SbMuxVmActiveChanDevNum = SB_MUX_VM_SYS_INDEX;
            }
            Io_SetDoValue(DIO_VM_SB_MUX_SELECT, gaxAioConfig[u8SbMuxVmActiveChanDevNum].u8MuxChannel, FALSE, FALSE);
            eSbMuxVmMeasState = AIO_MEAS_STATE_WAIT_FOR_CHANGES;
            return; // 直接返回,下一次ISR调用再继续,不用等超过1kHz的周期
        }
        else if (eSbMuxVmMeasState == AIO_MEAS_STATE_WAIT_FOR_CHANGES)
        {
            pxConfig = &(gaxAioConfig[u8SbMuxVmOldChanDevNum]);
            pxState = &(gaxAioState[pxConfig->eDevice]);
            Io_AdcReadAndHandleConversion(pxState, pxConfig, pxConfig->u8AdcChannel, &u8NextDevice);
            MsTimerReset(&tSbMuxVmTimer);
            eSbMuxVmMeasState = AIO_MEAS_STATE_MEASURE;
        }
        else if (eSbMuxVmMeasState == AIO_MEAS_STATE_MEASURE)
        {
            if (u8MsTimerExceeded((&tSbMuxVmTimer), gaxAioConfig[u8SbMuxVmActiveChanDevNum].u16MinWait))
            {
                eSbMuxVmMeasState = AIO_MEAS_STATE_IDLE;
            }
        }
    }
    else
    {
        // 其他MUX的处理逻辑,此处省略
    }
}

故障现象

随机出现,平均大概每8小时一次。当MUX切换到10状态后,会突然出现一个精准的100.00 us的跳变凹口——看起来像是要切回00状态,但瞬间又弹回10,之后就像完全没发生过异常一样继续正常循环,后续的MUX切换一切正常,直到下一次随机间隔后再出现问题。

我已经做了这些排查:

  • 代码走查没找到明显问题
  • 检查过SB是否重启:通过UART调试信息确认,异常发生时SB没有重启
  • 听说过读-modify-write问题,但不确定是不是这里的情况——毕竟我用的是FIO0SET和FIO0CLR寄存器,不是直接操作Data寄存器

现在想求助大家:这种随机的、极短的GPIO跳变到底可能是什么原因?会不会真的是读-改-写的隐患?或者还有其他硬件/软件层面的可能性我没考虑到?

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 11:33:00