How can I use a sleep function in a static library project?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How can I use a sleep function in a static library project?

Jump to solution
1,935 Views
nhantran
Contributor II

Hello all,

I am programming a Morse code decoder, which translate a string message in to Morse code, on an LPC1549 board. I implement a Morse code decoder class in the file containing the main function, and everything works fine. But when I want my project a bit more well organized by moving the class to a static library project, I am stuck at the sleep/delay function (the purpose of the sleep function is to blink a led to meet the timing requirement for Morse code). The reason is that the sleep function relies on a global variable "counter" that decrements every time Systick_Handler (which is configured to trigger every 1 ms) is called. So if I move the Morse code decoder class to another project, the sleep function called inside the decoder class cannot run. The Systick_Handler and Sleep function are shown below. I kindly ask for an advice. Any help is appreciated!

static volatile int state;
static volatile std::atomic_int counter;

extern "C"{
void SysTick_Handler(void)
{

   static int ticks = 0;
   if(counter > 0) counter--;
   ticks++;
   if (ticks > TICKRATE_HZ) {
   ticks = 0;
   state = 1 - state;
   }
}
}
void Sleep(int ms)
{
   counter = ms;
   while(counter > 0) {
      __WFI();
   }
}

Labels (2)
1 Solution
1,434 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Nhan Tran,

   I have checked your link's code, about the piece code of systick and the sleep function, I think you can change the method to write it.

   As you know, LPC1549 sleep can be waked up by the interrupt.

pastedImage_1.png

So, even you use the code like this:

extern "C"{
void SysTick_Handler(void)
{
     static int ticks = 0;
     if(counter > 0) counter--;
     ticks++;
     if (ticks > TICKRATE_HZ) {
          ticks = 0;
          state = 1 - state;
     }
}
}
void Sleep(int ms)
{
     counter = ms;
     while(counter > 0) {
          __WFI();
     }
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

You want to define the sleep time, but it will be waked up by the systick, then you use while enter the sleep again.

Please double think, is it good enough? You chip will enter the sleep, wake up, sleep, wakeup ...

Actually, I think you don't need to write it like that, let me tell you my thought.

As you know, systick is a Simple 24-bit timer. The timer clock source is the system clock, in LPC1549, the max system clock should be 72Mhz, let's take 72Mhz as an example.

From you code, I find the biggest sleep time you calling is 5000ms, it also in the while(1), actually, you want it always in the sleep.

In other area, you are call 10ms, 70ms.

Let's calculate the systick time, 24bit = 16777216, if you just use 72Mhz, clock no divide, then the max time should be 167726*(1/72)us=233016us, it is 233.016ms, actually, it is enough for your usage.

Each time when you want to change the sleep time, you just need to initialize the systick again, just redefine the systick time, then when the time is reached, enter the SysTick_Handler function, disable the systick, the sleep mode will waked up automatically.

If you want the systick timer longer than 233ms, you still can divide the systick clock,

pastedImage_2.png

Then your code will totally separate your relationship between the systick code and the sleep code.

When you want to modify the sleep time, you just need to call:

SysTick_Config(DefinedTime);

Sleep();//__WFI;

About the SysTick_Handler, you just need to clear the interrupt, and disable the systick.

Wish it helps you!

If you still have question about it, please kindly let me know!

Have a great day,
Kerry

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

View solution in original post

5 Replies
1,434 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Nhan Tran,

    I think you can modify your code structure.

   You don't need to use the variable to combine the SysTick and the Sleep function together in the lib.

   I don't know where you call the sleep function, I think you don't need to use counter in both the sleep and the void SysTick_Handler(void).

   You totally can use another variable in the main function, then combine the systick and the sleep function together, not in the lib, in the lib, separate the relationship between the sleep and the systick, combine it in the main code.

Wish it helps you!

   


Have a great day,
Kerry

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

1,434 Views
nhantran
Contributor II

Hello Kerry, I appreciate your help. I don't quite get your idea. Firstly, I separate the sleep and the systick because I want to vary the sleep time (by changing the argument "ms" of the Sleep function. I cannot do so if I combine the sleep into the systick because systick_handler is an interrupt service routine and it should not take any argument nor return any thing.

Secondly, how does combining the sleep function into the systick affect the result? I think the problem is that in a library project, there are no interrupts going on, and unfortunately, the sleep function relies on interrupts to work. So I am looking for a way a library project can use the systick_handler from an application project or a mutual variable between them.

By the way, this is my full project code: I want to take the MorseSender class to a library project, and in the Send member function of the class, I call the sleep function which is also my problem. You can ignore the other member functions :smileyhappy:. Once again thank you very much.

https://github.com/tranngocnhan93/MorseSender/blob/master/src/embd_prog_lab4_ex2.cpp

0 Kudos
1,435 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Nhan Tran,

   I have checked your link's code, about the piece code of systick and the sleep function, I think you can change the method to write it.

   As you know, LPC1549 sleep can be waked up by the interrupt.

pastedImage_1.png

So, even you use the code like this:

extern "C"{
void SysTick_Handler(void)
{
     static int ticks = 0;
     if(counter > 0) counter--;
     ticks++;
     if (ticks > TICKRATE_HZ) {
          ticks = 0;
          state = 1 - state;
     }
}
}
void Sleep(int ms)
{
     counter = ms;
     while(counter > 0) {
          __WFI();
     }
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

You want to define the sleep time, but it will be waked up by the systick, then you use while enter the sleep again.

Please double think, is it good enough? You chip will enter the sleep, wake up, sleep, wakeup ...

Actually, I think you don't need to write it like that, let me tell you my thought.

As you know, systick is a Simple 24-bit timer. The timer clock source is the system clock, in LPC1549, the max system clock should be 72Mhz, let's take 72Mhz as an example.

From you code, I find the biggest sleep time you calling is 5000ms, it also in the while(1), actually, you want it always in the sleep.

In other area, you are call 10ms, 70ms.

Let's calculate the systick time, 24bit = 16777216, if you just use 72Mhz, clock no divide, then the max time should be 167726*(1/72)us=233016us, it is 233.016ms, actually, it is enough for your usage.

Each time when you want to change the sleep time, you just need to initialize the systick again, just redefine the systick time, then when the time is reached, enter the SysTick_Handler function, disable the systick, the sleep mode will waked up automatically.

If you want the systick timer longer than 233ms, you still can divide the systick clock,

pastedImage_2.png

Then your code will totally separate your relationship between the systick code and the sleep code.

When you want to modify the sleep time, you just need to call:

SysTick_Config(DefinedTime);

Sleep();//__WFI;

About the SysTick_Handler, you just need to clear the interrupt, and disable the systick.

Wish it helps you!

If you still have question about it, please kindly let me know!

Have a great day,
Kerry

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

1,434 Views
nhantran
Contributor II

Oh yes, I got your idea now. I will try to apply it. Thank you very much for your time Kerry

0 Kudos
1,434 Views
kerryzhou
NXP TechSupport
NXP TechSupport

You are welcome.

After you try it, if you still have question, just let me know!

If your question is solved, please help me to mark the correct answer, just to close this case, thank you!


Have a great day,
Kerry

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos