Jump to content
OMRON Forums

Looping in "C" programs


bradp
 Share

Recommended Posts

When writing C programs for the Power Pmac you must be careful not to lock the code in any type of loop for too long a period. If you do lock the code in a loop you will lock-up the CPU and create either a soft or hard watchdog condition. When writing PowerPmac script code this is not an issue. Any code that encounters a 2nd jump to a previous program location will automatically release the CPU to let other other tasks have time. This is called the double jump back rule. This rule does not exist in C code. The programmer must decide to release the CPU at the end of each loop or after X number of cycles. This gives the programmer more capability with the cost of greater danger of locking the CPU. To release the CPU the programmer only needs to insert a Sleep() inside the loop. A simple example would be: While(i<100000){ i++; sleep(1); // release thread and wait about 1 msec } The commonly known sleep functions are sleep(i) (i is the sleep time in milliseconds) and usleep(j) (j is the sleep time in microseconds). These work fine for most applications but they are not very accurate because they are not part of the real time system. In situations where the sleep time must be very accurate the programmer should use the nanosleep() function. nanosleep is a little more complicated to use, a simple example example is: struct timespec next = {0}; While(i<100000){ i++; next.tv_nsec = 1000000; nanosleep(&next,NULL); // release thread and wait 1 msec }
Link to comment
Share on other sites

  • 1 year later...
  • Replies 5
  • Created
  • Last Reply

Top Posters In This Topic

An update on this subject. The Xenomai RTOS treats sleep() and usleep() as non real-time routines. So if you use these in a C-APP there is no real problem as C-APPS are not part of the real-time system. But BGCPLCs and RTICPLCs do run in the real-time system so the sleep() and usleep function can not be used in the bgcplc, rti, or usrcode programs. Instead, you should use the nanosleep function in bgcplc, rticplc and usercode.
Link to comment
Share on other sites

Just a note: If you are using a Xenomai scheduled periodic thread (I belive C PLCs are such) you can use the following: pthread_wait_np(NULL); Which is a call to the scheduler to essentially skip this thread until next period. Note that if you know something about RTOS systems you can create your own periodic threads, which is helpful if you want to control their execution. I like to define a helper function that makes it less ugly though: void Yield(void) { pthread_wait_np(NULL); } So in your user code you just have: while(SomeExpression) Yield(); or: while(SomeExpression) { DoSomething(); Yield(); } I think its cleaner, but everyone has their own preference for such things. KEJR
Link to comment
Share on other sites

  • 2 weeks later...
[quote='bradp' pid='224' dateline='1257463470'] next.tv_nsec = 1000000; nanosleep(&next,NULL); // release thread and wait 1 msec [/quote] Do not set next.tv_nsec > 999999999 . This causes the nanosleep pause to be ignored.
Link to comment
Share on other sites

I use both of these functions in the Xenomai threads regulary. There are no hitches on time limits (well, other than float seconds). Keep in mind that Pause does wake up every realtime period, but it hasn't proved to be inefficient for me yet. [code] double GetTimeSec(void) { return 1e-6*pshm->ClockSF*u64btod(fclock()); } void Yield(void) { pthread_wait_np(NULL); } void Pause(float PauseTimeSec) { double StartTime; StartTime=GetTimeSec(); while((GetTimeSec() - StartTime) < PauseTimeSec) Yield(); } [/code] So once these are in your library you just call them when you need them. If Pause() proves to be inefficient at some point (you would probably have to have ALOT of threads sleeping for this to be a problem) you can rewrite it using nanosleep and check the data and do multiple nanosleeps if PauseTimeSec exceeds the limit. KEJR
Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
 Share


×
×
  • Create New...