c - 这听起来像堆栈溢出吗?

标签 c stack-overflow firmware

我认为我的嵌入式固件代码中可能存在堆栈溢出问题或类似问题。我是一名新程序员,从未处理过 SO,所以我不确定这是否正在发生。

固件控制一个带有轮子的设备,轮子周围有均匀分布的磁铁,电路板有一个霍尔效应传感器,可以感应磁铁何时在其上方。我的固件操作步进器并计算步数,同时监控磁传感器以检测车轮是否失速。

我在我的芯片上使用定时器中断(8 位,8057 acrh。)来设置输出端口以控制电机和失速检测。失速检测代码如下所示...

    //   Enter ISR
    //   Change the ports to the appropriate value for the next step
    //    ...

    StallDetector++;      // Increment the stall detector

    if(PosSensor != LastPosMagState)
    {
        StallDetector = 0;

        LastPosMagState = PosSensor;
    }
    else
    {
        if (PosSensor == ON) 
        {
            if (StallDetector > (MagnetSize + 10))
            {
                HandleStallEvent();
            }
        }
        else if (PosSensor == OFF) 
        {
            if (StallDetector > (GapSize + 10))
            {
                HandleStallEvent();
            }
        }
    }

每次触发 ISR 时都会调用此代码。 PosSensor 是磁传感器。 MagnetSize 是通过磁场所需的步进器步数。 GapSize 是两个磁铁之间的步数。所以我想检测车轮是否被传感器卡在磁铁上或没有卡在磁铁上。

这在很长一段时间内都很好用,但过了一会儿,第一个停顿事件会发生,因为“StallDetector > (MagnetSize + 10)”,但当我查看 StallDetector 的值时,它总是在 220 左右!这没有意义,因为 MagnetSize 始终在 35 左右。所以失速事件应该在 46 左右触发,但不知何故一直上升到 220?而且我没有在我的代码中的其他任何地方设置失速检测器的值。

对于我如何追查这个问题的根源,您有什么建议吗?

ISR 看起来像这样

void Timer3_ISR(void) interrupt 14
{
    OperateStepper();  // This is the function shown above
    TMR3CN &= ~0x80;   // Clear Timer3 interrupt flag        
}

HandleStallEvent 只是将一些变量设置回它们的默认值,以便它可以尝试另一次移动...

#pragma save
#pragma nooverlay
void HandleStallEvent()
{
///*
    PulseMotor = 0;                 //Stop the wheel from moving
    SetMotorPower(0);               //Set motor power low
    MotorSpeed = LOW_SPEED;
    SetSpeedHz();
    ERROR_STATE = 2;
    DEVICE_IS_HOMED = FALSE;
    DEVICE_IS_HOMING = FALSE;
    DEVICE_IS_MOVING = FALSE;
    HOMING_STATE = 0;
    MOVING_STATE = 0;
    CURRENT_POSITION = 0;
    StallDetector = 0;
    return;
//*/
}
#pragma restore

最佳答案

PosSensor 是否不稳定?也就是说,您是在某处更新 PosSensor,还是直接读取 GPIO?

我假设 GapSize 相当大(> 220?)在我看来你可能有竞争条件。

// PosSensor == OFF, LastPosMagState == OFF
    if(PosSensor != LastPosMagState)
    {
        StallDetector = 0;

        LastPosMagState = PosSensor;
    }
    else
    {
// Race Condition: PosSensor turns ON here
// while LastPosMagState still == OFF
        if (PosSensor == ON) 
        {
            if (StallDetector > (MagnetSize + 10))
            {
                HandleStallEvent();
            }
        }
        else if (PosSensor == OFF) 
        {
            if (StallDetector > (GapSize + 10))
            {
                HandleStallEvent();
            }
        }
    }

您应该在执行 StallDetector++ 之后立即缓存 PosSensor 的值一次,以便在您的代码期间 PosSensor 发生变化时,您不会开始测试新值。

关于c - 这听起来像堆栈溢出吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2654895/

相关文章:

c - 如何搜索、查找和打印用户给出的单词的索引?

c# - 发生类型为 'System.StackOverflowException' 的未处理异常

python - 列表索引越界和堆栈溢出错误

iPhone 3GS 3.1.3 固件?

ARM Cortex-R4F、缓存和 MPU

c - 在 CC2541 IC 上以编程方式禁用常规广告并仅按需进行广告,这可能吗?

C WikiBooks - C 是一种小型 "what you see is all you get"语言吗?

c - 俄罗斯农民乘法

c - Ping6无响应?

crash - Lua:如何正确清理 lua_pcall 返回的错误