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.

Hard fault? bus fault? driver lack time delay or optimization level problem

I am using tm4c123g mcu, when power up  it may drive a led up which can be seen easily to indicate running status. But sometimes(1/4 chances) it can not run.

Soon we find the mcu runs into hard fault and get the ti SPMA043.pdf  to solve the problem with a near result from driver context:

//! \note It takes five clock cycles after the write to enable a peripheral

//! before the the peripheral is actually enabled. During this time, attempts

//! to access the peripheral result in a bus fault. Care should be taken

//! to ensure that the peripheral is not accessed during this brief time

//! period.

//!

//! \return None.

//

//*****************************************************************************

void

SysCtlPeripheralEnable(unsigned long ulPeripheral)

When we add a little delay in SysCtlPeripheralEnable, the Hard fault- bus fault did not appear when we tested 50 times;

Also, when we changed the CCS V5.2.1  optimization level  -O2 --opt_for_speed=5 to none, the problem seems also disappeared.

I've checked the latest driver lib and find no changes about it.

So, advices please!

  • Hello Jays,

    Code optimization changes the manner in which code is placed compiled, assembled and placed. This causes a change in execution time for the code which has the same affect as adding delay.

    Please look at ISSUE#2 in the following link that will make the peripheral not to give a bus fault w/o having to add delay or make it susceptible to code optimization

    e2e.ti.com/.../374640

    Regards
    Amit
  • Might I suggest a modestly better solution?

    Instead of

    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C2);
    
    while(!(SysCtlPeripheralReady(SYSCTL_PERIPH_I2C2)));
    

    use something like

        SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);

    /*-sem(SysCtlPeripheralReady,pure)Add to lint files to indicate there are no side effects, here for illustration */ while(!(SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0) && SysCtlPeripheralReady(SYSCTL_PERIPH_ADC1) && SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOB) && SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOD) && SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOE) && SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOG))){ }

    Enable everything particular to that initialization function and then check them all before proceeding minimized any idle time. C's logic shortcut rules ensure that the peripherals are checked in the order written so this structure allows the maximum non-idle time before checking.

    And never ever use a single statement (ie a ; to indicate an empty loop). It is too prone to misreading and the resulting bugs are very difficult to find.

    Robert

  • Robert Adsett said:
    Might I suggest a modestly better solution?

    UCLA Law should receive commission for this particular arrival of manners w/in this (past) none too sacred ground.   

    Should the method you've exposed be confined to "modest" it appears the armament around "Ft. Knox" is equally, "modest."

    Your writing has been (duly appropriated) (i.e. stolen) and wound its way into "all cb1 open files" and will become de rigueur for all pending/future.

    Well done - thank you - much appreciated.

  • Ok, the issue shall solve my problem.

    I checked some of the examples in tivaware and find no usage of SysCtlPeripheralReady() yet.
  • Hello Jays,

    The existing examples do not but the driverlib user guide is now updated to show the same and newer examples also have the same updated in TivaWare 2.1.2.111 version

    Regards
    Amit