This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] EK-TM4C1294XL:sscanf 导致系统故障

Guru**** 1794070 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/573744/ek-tm4c1294xl-sscanf-leads-to-a-system-fault

器件型号:EK-TM4C1294XL

您好!

不确定原因、但 sscanf 会导致我的代码中出现系统故障。 它一直运行正常、但我对 sscanf 不再起作用的程序执行了一些操作。 更糟糕的是、我修改了该程序、它高度模块化(包含大量.c 和.h 文件)。 在世界上什么情况下会导致此故障 ISR?

下面是 sscanf 用法的一个示例:

/*
* blink.c
*
*创建日期:2017年1月24日
* 作者:Helder Sales
*/

#include "blink.h"
#include "../../includes.h

内联 void Blink_InitLedPins (void)
{
ROM_SysCtlPeripheralDisable (SYSCTL_Periph_GPION);
ROM_SysCtlPeripheralReset (SYSCTL_Periph_GPION);

ROM_SysCtlPeripheralDisable (SYSCTL_Periph_GPIOF);
ROM_SysCtlPeripheralReset (SYSCTL_Periph_GPIOF);

ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPION);
ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOF);

while (!ROM_SysCtlPeripheralReady (SYSCTL_Periph_GPION)||!ROM_SysCtlPeripheralReady (SYSCTL_Periph_GPIOF));

ROM_GPIOPinTypeGPIOOutput (GPIO_PORTN_BASE、GPIO_PIN_0 | GPIO_PIN_1);
ROM_GPIOPinTypeGPIOOutput (GPIO_PORTF_BASE、GPIO_PIN_0 | GPIO_PIN_4);
}

内联浮点 Init_Timer0 (float freq)
{
ROM_SysCtlPeripheralDisable (SYSCTL_Periph_TIMER0);
ROM_SysCtlPeripheralReset (SYSCTL_Periph_TIMER0);
ROM_SysCtlPeripheralEnable (SYSCTL_Periph_TIMER0);
while (!ROM_SysCtlPeripheralReady (SYSCTL_Periph_TIMER0));

ROM_TimerClockSourceSet (TIMER0_BASE、TIMER_CLOCK _PIOSC);

ROM_TimerConfigure (TIMER0_BASE、TIMER_CFG_PERIODICASE);

fPeriod = 16000000 /(freq*2);

ROM_TimerLoadSet (TIMER0_BASE、TIMER_A、fPeriod -1);

ROM_IntEnable (INT_TIMER0A);
ROM_TimerIntEnable (TIMER0_BASE、TIMER_TINA_TIMEOUT);
ROM_IntPrioritySet (INT_TIMER0A、0xE0);

ROM_TimerEnable (TIMER0_BASE、TIMER_A);
return (0);
}

void Timer0IntHandler (void)
{
ROM_TimerIntClear (TIMER0_BASE、TIMER_TINA_TIMEOUT);

IF (ROM_GPIOPINREAD (GPIO_PORTN_BASE、GPIO_PIN_0 | GPIO_PIN_1)& ROM_GPIOPinREAD (GPIO_PORTF_BASE、GPIO_PIN_0 | GPIO_PIN_4)))
{
ROM_GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_0 | GPIO_PIN_1、0);
ROM_GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_0 | GPIO_PIN_4、0);
}

其他
{
ROM_GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_0 | GPIO_PIN_1、GPIO_PIN_0 | GPIO_PIN_1);
ROM_GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_0 | GPIO_PIN_4、GPIO_PIN_0 | GPIO_PIN_4);
}
}

内联 int blink_main (int argc、char * argv[])
{
if (argc!= 2)
返回(CMD_ERROR);

if (strcmp (argv[1]、"stop")==0)
{
if (!ROM_SysCtlPeripheralReady (SYSCTL_Periph_TIMER0))
{
UARTprintf ("\nBlink NAO estava em executcao。\n\n");
返回(0);
}

ROM_IntDisable (INT_TIMER0A);
ROM_TimerIntClear (TIMER0_BASE、TIMER_TINA_TIMEOUT);
ROM_TimerDisable (TIMER0_BASE、TIMER_A);

ROM_SysCtlPeripheralDisable (SYSCTL_Periph_TIMER0);
ROM_SysCtlPeripheralReset (SYSCTL_Periph_TIMER0);

ROM_SysCtlPeripheralDisable (SYSCTL_Periph_GPION);
ROM_SysCtlPeripheralDisable (SYSCTL_Periph_GPIOF);

ROM_SysCtlPeripheralReset (SYSCTL_Periph_GPION);
ROM_SysCtlPeripheralReset (SYSCTL_Periph_GPIOF);

UARTprintf ("\n 终止一个执行函数执行闪烁。\n");
return (CMD_sucess);
}

float freq;
字符 ch;

//验证字符,并返回错误状态(如果有)
INT8_t 条件= sscanf (argv[1]、"%f%c"、&freq、&ch);

if (freq < 0 ||条件!= 1)
返回(CMD_ERROR);

Blbing_InitLedPins();

init_Timer0 (freq);

return (CMD_sucess);
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    实际上、我发现了问题、请参阅下面的代码。  如果我注释掉任何函数,例如 CMD_led (以及 g_psCmdTable[]中的相应调用) ,sscanf 就可以正常工作。 但我无法理解为什么会发生这种情况...

    /*
    * Comandos.c
    *
    *创建日期:2017年1月3日
    * 作者:Helder Sales
    */
    
    #include "commands.h"
    #include "../include.h"
    #include "../functions/messages/help.h
    #include "../functions/messages/list.h
    #include "../functions/adc/adc.h "
    #include "../functions/blink/blink.h
    
    
    /functions/pwm/pwm.h
    
    
    /functions/eepromerase/eepromerase.h #include "../functions/led/led.h #include "../functions/timerpwm/timerpwm.h #include "../functions/wdog/wdog.h /functions/opendrain/opendrain.h #include "..#include "#include ".mdLine"
    
    
    {#include ".Cmdg"}。
    CMD_LIST、 ":Mostra lista de Comandos."}
    、{"帮助"、 CMD_Help、 ":Mostra Ajuda。"}、
    {"h"、 CMD_Help、 ":别名 de Ajuda"}、
    {"?"、 CMD_Help、 ":别名 de Ajuda"}、
    {"led"、 CMD_LED、 ":LED 开/关。"}、
    {"openree"、 CMD_openDRAIN、 ":GPIO PM0/PM1/PM2开漏。"}、
    {"PWM"、 CMD_PWM、 ":Liga PWM。"}、
    {"timerpwm"、 CMD_timerpwm、 ":美国定时器4 COMO PWM。"}
    、{"Blind"、 CMD_BLINK、 ":LED 闪烁。"}、
    {"ADC"、 CMD_ADC、 ":inicia adc、canais 2 e 3。"}
    、{"wdog"、 CMD_Watchdog、 ":Liga/desativa Watchdog."}、
    {"EEPROM_ERASE"、CMD_eepromerase、":Limpa memoria EEPROM。"}、
    {"clear"、 CMD_CLEAR、 ":Limpa TELA。"}、
    {"reset"、 CMD_RESET、 ":软件复位。\n"}、
    {0、0、0}
    };
    
    int CMD_Watchdog (int argc、 char * argv[])
    {
    return (Watchdog_main (argc、argv));
    }
    
    int CMD_ADC (int argc、char * argv[])
    {
    return (adc_main (argc、argv));
    }
    
    int cmd_led (int argc、char * argv[])
    {
    return (led_main (argc、argv));
    }
    
    int cmd_openeDRAIN (int argc、char * argv[])
    {
    return (OpenDrain_main (argc、argv));
    }
    
    int CMD_PWM (int argc、char * argv[])
    {
    return (pwm_main (argc、argv));
    }
    
    int cmd_timerpwm (int argc、char * argv[])
    {
    return (TimerPWM_main (argc、argv));
    }
    
    int CMD_blink (int argc、char * argv[])
    {
    return (blink_main (argc、argv));
    }
    
    int cmd_eepromerase (int argc、char * argv[])
    {
    return (EEPROM_Erase (argc、argv));
    }
    
    int CMD_list (int argc、char * argv[])
    {
    return (list_main (argc、argv));
    }
    
    int CMD_help (int argc、char * argv[])
    {
    return (help_main (argc、argv));
    }
    
    int cmd_clear (int argc、char * argv[])
    {
    if (argc > 1)
    返回(CMD_ERROR);
    
    return (CMD_CLEAR);
    }
    
    int CMD_RESET (int argc、char * argv[])
    {
    if (argc > 1)
    返回(CMD_ERROR);
    
    ROM_SysCtlReset();
    
    返回(0);
    }
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尝试增大项目的堆栈大小- printf/scanf 函数在堆栈上的加权较大。 我通常有2k…… 4K 用于类似项目。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    那是可行的。 非常感谢! 堆栈大小仅为512字节、因此我使用了1024。