Skip to main content
Visitor II
January 2, 2017
Question

STM8S - 32bit atomic access

  • January 2, 2017
  • 2 replies
  • 1777 views
Posted on January 02, 2017 at 09:12

Hi,

I'm stm8 newbie, and i wonder if i can do assumption, that reading uint32 variable will be atomic.

There is simple function returning system time measured in ms using uint32_t variable, and it's looks like following

 207                     ; 109 uint32_t systemGetBootTime(void)

 207                     ; 110 {

 208                     .text:    section    .text,new

 209  0000               _systemGetBootTime:

 211                     ; 111     return systemBootTime;

 212  0000 ae0000            ldw    x,♯_systemBootTime

 215  0003 cc0000            jp    c_ltor

so i wonder how it works, because ldw instruction is described as 16 bit transferring...

what is c_ltor?

Thank you in advance.

Krzysiek

#stm8 #atomic
    This topic has been closed for replies.

    2 replies

    Visitor II
    January 2, 2017
    Posted on January 02, 2017 at 11:25

    To me, the asm code looks like _systemBootTime is a 16-bit variable and c_ltor might be some compiler-specific internal function for casts from 16 bit to 32 bit.

    However it is hard to tell without knowing more. Compileable source for the function, including all declarations might help. Which compiler did you use?

    But in general, there is no instruction for an atomic 32-bit read in the STM8. You'd have to disable interrupts during the read to do a reliable 32-bit atomic read.

    Philipp

    Visitor II
    January 2, 2017
    Posted on January 02, 2017 at 11:59

    Than you Philipp for quick answer .

    I use cosmic free compiler, and variable is declared as

    __IO uint32_t systemBootTime = 0;

    I just did additional 8 bit flag to disable bootTime increase during reading instead of switching interrupts off

    __IO uint8_t sytemDontIncBootTime = 0;

    uint32_t systemGetBootTime(void)

    {

        volatile uint32_t tmpBootTime;

        sytemDontIncBootTime = 1;

        tmpBootTime = systemBootTime;

        sytemDontIncBootTime = 0;

        return tmpBootTime;

    }

    and timer code ...

    void systemTIM4IRQ(void)

    {

        // called at 1000Hz

        if (sytemDontIncBootTime == 0)

        {

            systemBootTime++;

        }

    ...

    I know that some ms will be not counted, but it's acceptable

    Have a nice day.

    Krzysiek

    Visitor II
    January 3, 2017
    Posted on January 03, 2017 at 09:32

    Hello,

    generally speaking access to 32 bits variables is not atomic in the stm8 because the core does not have the kind of instructions that would allow to implement this easily: if you want to make sure access to some variables is atomic you should implement that yourself, usually disabling interrupts.

    In your specific case, c_lreg is a Cosmic-specifc 32-bits pseudo register (4 bytes in page 0 that the compilers reserves to manage 32 bits calculations): in the assembler you posted the address of the variable systemBootTime is put into X, and than the library function c_ltor is called to copy the content of this variable in the 32bit c_lreg pseudo register, that is used as return value. Note that if you want to make sure that c_lreg is saved under interrupt (something that you should always do if your interrut routines use long or floats) you must specify the keyword @svlreg on the interrupt function.

    Regards,

    Luca

    Visitor II
    January 3, 2017
    Posted on January 03, 2017 at 09:38

    Thank you Luca,

    I didn't know about c_lreg pseudo register. Now need to review my coding

    Krzysiek