7 Replies Latest reply on Jun 28, 2018 5:25 PM by srsi_3347331

    systick race conditions

    srsi_3347331

      I am using a systick timer interrupt that looks something like this:

       

      static volatile uint16_t timer = 0;

      static int set_count = 0;

      void USR_Tick(void)   //ISR for systick

      {

         timer++;

      }

      void main(void)

      {

           while(1)

          {

               if (timer==100u )

                {

                     //hardware code (take ~700 micro seconds to execute)

                     set_count++;

                }

                if (timer==200u )

                {

                     //hardware code (take ~700 micro seconds to execute)

                     set_count++;

                }

                if (timer == 300)

                {

                    timer =0;

                }

          }

      }

       

       

      Within my 300 ms reset, I am getting a very high value of set_count, I expect it to be 2. Is that right or am I missing something?

        • 1. Re: systick race conditions
          srsi_3347331

          Using PSOC 4

          • 2. Re: systick race conditions
            rajivv_36

            Sravanthi,

             

            Between two ISR executions, that is timer variable update, set_count is getting incremented multiple times. For example, if timer is at 99, set_count is not incremented. When ISR is invoked, timer becomes 100. In while loop, set_count is continuously incremented till the next ISR execution.

             

            -Rajiv

            • 3. Re: systick race conditions
              rajivv_36

              Sravanthi,

               

              What is the reload value and clock source for SysTick configured in the project?

               

              -Rajiv

              • 4. Re: systick race conditions
                srsi_3347331

                Clock source is CY_SYS_CLK_HFCLK_IMO

                Reload value is cydelayFreqHz/1000u

                uint32 cydelayFreqHz  = CYDEV_BCLK__SYSCLK__HZ; (which is 24000000)

                • 5. Re: systick race conditions
                  srsi_3347331

                  I was able to toggle an led and check on oscilloscope- I was getting 5 micro second  pulses before my actual led pulse.

                  I looked at systick example code, they are not incrementing timer inside ISR. They are setting a variable to 1. I did the same and incremented in my while loop, I don't see the weird 5 micro pulses. I wonder why that is happening.

                  IMG_4141.jpgIMG_4142.jpg

                  • 6. Re: systick race conditions
                    BragadeeshV_41

                    Hi Sravanti,

                     

                    I assume your IMO clock speed is 24MHz.

                    If that is the case, then your systick ISR gets executed every 1 ms.

                     

                    There is no issue if you increment the timer variable in ISR.

                     

                    But you need to note that the "hardware code" in each "if block" has a delay of approximately 700 uS.

                    As the ISR gets executed only after 1 ms, the while loop (if block) will get executed for another 300 uS (approximately), making the if condition ( timer == 100u) true again.

                     

                    Hence the set_count gets incremented until the next interrupt.

                    This is the reason why you see the toggling of output in the oscilloscope.

                     

                    In order to rectify this issue, use a flag variable (tickStatus as given in the code example) to make sure that the "if block" gets executed only once.

                     

                    So, you can use the following code snippet or refer to the code example

                     

                    ISR()

                    {

                         timer++;

                         tickStatus=1;

                    }

                    -

                    -

                    while(1)

                    {

                        

                         if(timer ==100 && tickStatus == 1)

                            {

                              set_count++

                              tickStatus=0;

                              }

                    }

                     

                    Hope this helps.

                     

                    Regards,

                    Bragadeesh

                    • 7. Re: systick race conditions
                      srsi_3347331

                      Cant believe I didn't think of this. Thanks Bragadeesh!