Squarewave-example
From RTwiki
Contents |
Abstract
This is a little example, how to use the realtime preemption patch. First ensure you installed the preemption patch like described on this page: RT_PREEMPT_HOWTO
The example writes a squarewave to the parallelport, so if you want to see something you should connect a oscilloscope to pin 2 of your parallelport.
Code
swave.c :
/* compile using "gcc -o swave swave.c -lrt -Wall" */
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <sched.h>
#include <sys/io.h>
#define PORT 0x378
#define NSEC_PER_SEC 1000000000
/* using clock_nanosleep of librt */
extern int clock_nanosleep(clockid_t __clock_id, int __flags,
__const struct timespec *__req,
struct timespec *__rem);
/* the struct timespec consists of nanoseconds
* and seconds. if the nanoseconds are getting
* bigger than 1000000000 (= 1 second) the
* variable containing seconds has to be
* incremented and the nanoseconds decremented
* by 1000000000.
*/
static inline void tsnorm(struct timespec *ts)
{
while (ts->tv_nsec >= NSEC_PER_SEC) {
ts->tv_nsec -= NSEC_PER_SEC;
ts->tv_sec++;
}
}
/* increment counter and write to parallelport */
void out()
{
static unsigned char state=0;
outb(state++,PORT);
}
int main(int argc,char** argv)
{
struct timespec t;
struct sched_param param;
/* default interval = 50000ns = 50us
* cycle duration = 100us
*/
int interval=50000;
/* set permissions of parallelport */
ioperm(PORT,1,1);
if(argc>=2 && atoi(argv[1])>0)
{
printf("using realtime, priority: %d\n",atoi(argv[1]));
param.sched_priority = atoi(argv[1]);
/* enable realtime fifo scheduling */
if(sched_setscheduler(0, SCHED_FIFO, ¶m)==-1){
perror("sched_setscheduler failed");
exit(-1);
}
}
if(argc>=3)
interval=atoi(argv[2]);
/* get current time */
clock_gettime(0,&t);
/* start after one second */
t.tv_sec++;
while(1){
/* wait untill next shot */
clock_nanosleep(0, TIMER_ABSTIME, &t, NULL);
/* do the stuff */
out();
/* calculate next shot */
t.tv_nsec+=interval;
tsnorm(&t);
}
return 0;
}
Compilation
Copy & paste the source and save it to "swave.c", then compile it using this commandline:
gcc -o swave swave.c -lrt -Wall
Execution
./swave arg1 arg2
- arg1 = realtime priority (0 = no realtime scheduling)
- arg2 = time between the shots in nanoseconds (default = 50000)
The cycle duration of the wave consists of two shots (pin2 of parallelport), so following cycle durations are achieved with the default time between shots (50000ns):
- pin2: 100microseconds
- pin3: 200microseconds
- pin4: 400microseconds
- pin5: 800microseconds
- ...
Execution without realtime scheduling
To run the example, just start it by typing:
./swave
This will start the example _NOT_ using the realtime scheduling. So when you create some system load, like with:
cat /dev/zero > delete_this_file
you will see on the scope, that the squarewave gets really screwed up.
Execution with realtime scheduling
To run it using realtime fifo scheduling execute it this way:
./swave 90
Now it is ran with fifo scheduling with priority 90. And you will see a perfect squarewave on the scope, even when creating heavy system load with
cat /dev/zero > delete_this_file
