systick race conditions

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
srsi_3347331
Level 2
Level 2

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?

0 Likes
1 Solution

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

Regards,
Bragadeesh

View solution in original post

0 Likes
7 Replies
srsi_3347331
Level 2
Level 2

Using PSOC 4

0 Likes
Anonymous
Not applicable

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

0 Likes
Anonymous
Not applicable

Sravanthi,

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

-Rajiv

0 Likes

Clock source is CY_SYS_CLK_HFCLK_IMO

Reload value is cydelayFreqHz/1000u

uint32 cydelayFreqHz  = CYDEV_BCLK__SYSCLK__HZ; (which is 24000000)

0 Likes

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

0 Likes

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

Regards,
Bragadeesh
0 Likes

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

0 Likes