Allegro.cc - Online Community

Allegro.cc Forums » Allegro Development » Linux Fast Parallel Port Control using Allegro

This thread is locked; no one can reply to it. rss feed Print
Linux Fast Parallel Port Control using Allegro
Randall Dodson
Member #5,205
November 2004

Here is some parallel port routines that I am using to control some hardware that is attached to my parallel port. The writes seem to work, don't know about the reads yet. The main problem is that the reads and the writes seem to take way too long to execute.

Any suggestions on if the linux code is correct or on speeding up the parallel port routines? Thanks.

#include "allegro.h"
#include "sys/io.h"
#include "sys/time.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

// Parallel Port
#define DATA 0x378
#define STATUS DATA + 1
#define CONTROL DATA + 2

struct timespec ts;

int Main(){
...
ts.tv_sec = 0;
ts.tv_nsec = 500;
...
open_parallel_port();
initialize_port_signals();

//Write to Parallel Port
outb(0x55, DATA);
toggle_init();
outb(0x00, DATA);
toggle_strobe();

usleep(500000); // Delay 0.5 seconds
...

//Read from Parallel Port
outb(0xAA, DATA);
toggle_init();
outb(0xd2 ^0x0b, CONTROL);
PP_DATA = inb(DATA);
toggle_strobe();

close_parallel_port();
return 0;

}

END_OF_MAIN();

toggle_strobe(){
nanosleep(&ts, NULL);
outb(0xda ^ 0x0b, CONTROL);
nanosleep(&ts, NULL);
outb(0xdb ^ 0x0b, CONTROL);
nanosleep(&ts, NULL);
}
END_OF_FUNCTION(toggle_strobe);

toggle_init(){
outb(0xdf ^ 0x0b, CONTROL);
nanosleep(&ts, NULL);
outb(0xdb ^ 0x0b, CONTROL);
nanosleep(&ts, NULL);
}
END_OF_FUNCTION(toggle_init);

initialize_port_signals(){
outb(0xdb ^ 0x0b, CONTROL);
nanosleep(&ts, NULL);
}
END_OF_FUNCTION(initialize_port_signals);

open_parallel_port(){
if (ioperm (DATA,3,TURN_ON))
fprintf(stderr, "Couldn't open the port at %x\n", DATA), exit(1);

printf("data: %x\n", inb(DATA));
printf("status: %x\n", inb(STATUS));
printf("control: %x\n", inb(CONTROL));

usleep(1000);
return 0;
}
END_OF_FUNCTION(open_parallel_port);

close_parallel_port(){
printf("data: %x\n", inb(DATA));
printf("status: %x\n", inb(STATUS));
printf("control: %x\n", inb(CONTROL));

if (ioperm (DATA,3,TURN_OFF))
fprintf(stderr, "Couldn't close the port at %x\n", DATA), exit(1);

return 0;
}
END_OF_FUNCTION(close_parallel_port);

A J
Member #3,025
December 2002
avatar

you know how to time things, what bit takes too long ?

___________________________
The more you talk, the more AJ is right. - ML

Randall Dodson
Member #5,205
November 2004

I have decided to use parapin.c and parapin.h routines for parallel port control. Theses routines seem to work pretty well.

But, the "nanosleep(&ts, NULL);" which I have set to delay 500nsec takes several milliseconds to execute for some reason?

Does anybody know, using linux, how to delay 500nsec +/- 100nsec?

Thanks for your help.

Evert
Member #794
November 2000
avatar

Quote:

Does anybody know, using linux, how to delay 500nsec +/- 100nsec?

I'm not sure you can do that reliably. The nanosleep manpage says

the manpage said:

BUGS
The current implementation of nanosleep is based on the
normal kernel timer mechanism, which has a resolution of
1/HZ s (i.e, 10 ms on Linux/i386 and 1 ms on Linux/Alpha).
Therefore, nanosleep pauses always for at least the speciĀ­
fied time, however it can take up to 10 ms longer than
specified until the process becomes runnable again. For
the same reason, the value returned in case of a delivered
signal in *rem is usually rounded to the next larger
multiple of 1/HZ s.

As some applications require much more precise pauses
(e.g., in order to control some time-critical hardware),
nanosleep is also capable of short high-precision pauses.
If the process is scheduled under a real-time policy like
SCHED_FIFO or SCHED_RR, then pauses of up to 2 ms will be
performed as busy waits with microsecond precision.

I think other functions that try to do the same thing would have similar limitations and problems.

Randall Dodson
Member #5,205
November 2004

Thanks for pointing out the bug when using "nanosleep".

I will now attempt to use the scheduling functions that you mentioned.

Has anyone done any "hard" real time loops using linux? Here's what I want to do:

while(1){
//slot1 stuff - This slot takes 0.25msec to execute
reset_timer();
do_slot1_stuff();
wait_for_timer_to_expire();

//slot2 stuff - This slot takes 0.25msec to execute
reset_timer();
do_slot2_stuff();
wait_for_timer_to_expire();

//and so on with each slot consuming 0.25msec of time
}

Maybe I need to learn how to use the hardware timers on the Processor Board. Has anyone done this?

A J
Member #3,025
December 2002
avatar

maybe you need to realize that a multi-threaded environment means you have NO way of guaranteeing your thread is on the CPU when you want it.
NO amount of tickering with weird methods will help this.

best effort, and that is ALL it will be (whilst using a multi-threaded OS), is you create a REAL_TIME or TIME_CRITICAL thread and you completely hog the CPU and do NOT use any OS rest() / yield() functions.
this will render the rest of the system useless whilst you have the CPU.

___________________________
The more you talk, the more AJ is right. - ML

Randall Dodson
Member #5,205
November 2004

Thanks for the advise.

On my project, the complete CPU will be dedicated to executing my program.

I will be checking into the REAL_TIME or TIME_CRITICAL threads.

My goal is to have 16 processing slots that continuous repeat, with each slot lasting 0.25ms. A processing loop takes 4ms. During each slot, parallel port reads and writes are occuring, allegro graphics screens are showing and sound clips are playing.

Any additional advise is welcomed.

A J
Member #3,025
December 2002
avatar

Quote:

Any additional advise is welcomed.

if you are still considering real-time, time critical, on-the-msec accuracy, you are dreamin!

you want to do time critical, graphics, and audio.. you must have next to zero clue about how your CPU/OS works.

stop coding, go read about how your multi-tasking OS works.
the research will improve your coding, and set your ideas back in reality.

___________________________
The more you talk, the more AJ is right. - ML

Go to: