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.

Is this happening because of a silicon BUG?

Hi!

I am porting a RTOS fo the MSP4305529 platform.

I am having an issue regarding the GIE bit while wainting the system tick, whitin the schedule funciont of the OS.

In C, is something like this:

BackUp_and_DisableGIE;

/* lot of code */

while( !NewReadyTask() )

{

RestoreGIE;

Pause(); //here will be executed the LPM entering macro, or something similar. Now, there is NOP.

BackUp_and_DisableGIE;

}

ContextSwitch();

RestoreGIE;

The idea is to loop until the tick puts some task in running estate, and then when it happens, the Context Switch is done, and the execution continues.

The system hangs during the while loop. Somehow, the GIE bit is being disabled.

When the pause function is a LPM, surely I will eneble the GIE within the ISR vector, but for now is just a nop.

THe RestoreGIE and BackUp_and_DisableGIE are macros, where I tried fo follow every rule from the errata sheet, and the family guide in regard to the pipeline, the eint an dint instructions.

#define BackUp_and_DisableGIE() SR_BACK___ = _get_SR_register();   \
                                _disable_interrupts() ;            \
                                __asm__ __volatile__ ("nop");

#define RestoreGIE() if( SR_BACK___ & GIE )             \
                     {                                  \
                         __asm__ __volatile__ ("nop");  \
                         _enable_interrupts() ;         \
                     }

 

Maybe you can help me some how.

Thanks in advance.

UPDATE:

- I am using gcc  (SOMNIUM Technologies Limited - msp430-gcc 5.3.0.219) 5.3.0
- I am not using optimizations
- I have only 1 Enabled IRQ, that is the one for the tick. I placed a counter in the tick irq handler, in order to see if is a consistent behavior or something else. The counter changed during different runs... when the while is stucked.
- I am debuging with eclipse + mspdebug.
- I added a little delay after Pause()  (with an ugly for(;;) ), and   started to work... It doesn't hangs there

  • At which particular point in the loop do you observe GIE cleared when it should be set?
  • Silicon bug of GIE for sure would be immediately noticed, so it is something else. Did you look at disassembly of while loop in question? How does it look like? In case compiler optimizations are on, switch them off and check results.
  • I am (also) not quite clear on what "hang" means precisely. But there do seem to be some holes in this logic:

    1) The function takes care to maintain the GIE, presumably because it may be called with GIE either 0 or 1. However, if it is called with GIE=0, Pause() will run with GIE=0; if Pause() is an LPM call the CPU will be stuck forever. I suspect you want to unconditionally set GIE=1 before Pause() [but see below].

    2) Separating the GIE setting from the LPM setting introduces a race. If you imagine a one-time-ever wakeup interrupt that occurs between the two steps, it will result in sleeping forever. If you imagine the (more common) case where you have a periodic wakeup interrupt, you will miss one "beat", which may not be immediately noticeable but will subtly throw your timing off. This is why you see the idiom: __bis_SR_register(LPM0_bits+GIE). I wonder if this code was written with the AVR ["sleep" can be turned into a no-op] or an x86 [sleep implicitly sets GIE] in mind.

  • FAB63476 said:
    Somehow, the GIE bit is being disabled.

    I was wondering if the MSP430 Enhanced Emulation Module (EEM) could be used to find the instruction which is unexpectedly clearing the GIE bit. A watchpoint can be configured to Trigger Storage on a write the Status Register which has the GIE bit clear:

    The above causes the address bus to be sampled when an instruction which writes to the Status Register with the GIE bit clear, such that the address of 2 instructions after the DINT is stored.

    However, a limitation of the MSP430 State Storage is that only 8 entries can be stored. and when store on trigger always stops when the trace buffer is full:

    i.e. when the program hangs may be difficult to get the trace storage to contain the writes to the Status Register immediately prior to the hang.

  • See "UPDATE" in my original post.
    The system "hangs" always in that loop. I realized that is there, because I stopped execution while debugging, and the only one task I have (LED toggle) is no doing anything.
  • "But there do seem to be some holes in this logic:" ... probably.

    1) Yeah. Right. Is not the case now, but I will check this later.

    2) Right now I am not using LPM. But OK. Probably I should restore the GIE doing __bis_SR_register(LPM0_bits+GIE). (I was usung the intrinsic gcc function _enable_interrupts()  ).

    Thanks!

**Attention** This is a public forum