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 leads to a system fault

Part Number: EK-TM4C1294XL

Hi,

Not sure why, but sscanf is causing a system fault in my code. It always had run fine, but I did something with the program that sscanf no longer works. To make things worse, I modified the program a lot and it is heavily modular (with lots of .c and .h files). What in the world would cause this fault ISR?

One example of sscanf usage is below:

/*
 * blink.c
 *
 *  Created on: 24 de jan de 2017
 *      Author: Helder Sales
 */

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

inline 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);
}

inline float 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_PERIODIC);

    float fPeriod = 16000000/(freq*2);

    ROM_TimerLoadSet(TIMER0_BASE, TIMER_A, fPeriod -1);

    ROM_IntEnable(INT_TIMER0A);
    ROM_TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    ROM_IntPrioritySet(INT_TIMER0A, 0xE0);

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

void Timer0IntHandler(void)
{
    ROM_TimerIntClear(TIMER0_BASE, TIMER_TIMA_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);
    }

    else
    {
        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);
    }
}

inline int blink_main(int argc, char *argv[])
{
    if(argc != 2)
        return(CMD_ERROR);

    if(strcmp(argv[1], "stop") == 0)
    {
        if(!ROM_SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER0))
        {
            UARTprintf("\nBlink nao estava em execucao.\n\n");
            return(0);
        }

        ROM_IntDisable(INT_TIMER0A);
        ROM_TimerIntClear(TIMER0_BASE, TIMER_TIMA_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("\nTerminou a execucao do blink.\n");
        return(CMD_SUCESS);
    }

    float freq;
    char ch;

    //to verify characters, and return error status if found any
    int8_t condition = sscanf(argv[1], "%f%c", &freq, &ch);

    if (freq < 0 || condition != 1)
        return(CMD_ERROR);

    Blink_InitLedPins();

    Init_Timer0(freq);

    return(CMD_SUCESS);
}

  • Actually, I found the problem, please see the code below. If I comment out any function, say CMD_led for example (and the respective call in the g_psCmdTable[]) , the sscanf works just fine. But I cannot make sense why this is happening...

    /*
     * comandos.c
     *
     *  Created on: 3 de jan de 2017
     *      Author: Helder Sales
     */
    
    #include "commands.h"
    #include "../includes.h"
    #include "../functions/messages/help.h"
    #include "../functions/messages/list.h"
    #include "../functions/adc/adc.h"
    #include "../functions/blink/blink.h"
    #include "../functions/led/led.h"
    #include "../functions/wdog/wdog.h"
    #include "../functions/pwm/pwm.h"
    #include "../functions/timerpwm/timerpwm.h"
    #include "../functions/opendrain/opendrain.h"
    #include "../functions/eepromerase/eepromerase.h"
    
    tCmdLineEntry g_psCmdTable[] =
    {
     {"list",           CMD_list,           ": Mostra lista de comandos."},
     {"help",           CMD_help,           ": Mostra ajuda."},
     { "h",             CMD_help,           ": Alias de ajuda" },
     { "?",             CMD_help,           ": Alias de ajuda" },
     {"led",            CMD_led,            ": Leds on/off."},
     {"opendrain",      CMD_opendrain,      ": GPIO PM0/PM1/PM2 Open-Drain."},
     {"pwm",            CMD_pwm,            ": Liga PWM."},
     {"timerpwm",       CMD_timerpwm,       ": Usa Timer 4 como PWM."},
     {"blink",          CMD_blink,          ": Led blink."},
     {"adc",            CMD_ADC,            ": Inicia ADC, canais 2 e 3."},
     {"wdog",           CMD_Watchdog,       ": Liga/desativa Watchdog."},
     {"eeprom_erase",   CMD_eepromerase,    ": Limpa a memoria EEPROM."},
     {"clear",          CMD_clear,          ": Limpa tela."},
     {"reset",          CMD_reset,          ": Software 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_opendrain(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)
            return(CMD_ERROR);
    
        return(CMD_CLEAR);
    }
    
    int CMD_reset(int argc, char *argv[])
    {
        if(argc > 1)
            return(CMD_ERROR);
    
        ROM_SysCtlReset();
    
        return(0);
    }
    

  • Try increasing the stacksize for your project - the printf/scanf functions weighting heavily on the stack. I usually have 2k ... 4k for similar projects.

  • That worked. Thank you very much! Stack size was only 512 bytes, so I used 1024 instead.