Using Delay In Dev C++
2. Using I/O ports in C programs
Since dev-cpp keeps seperate compiter Mingw while Tubo-c was using Borland. However there are several ways to implement/use delay function in cpp code. First way: code#include <time.h> void delay(int delay) int now=time(NULL); int later=now+.
C is an object oriented language and some concepts may be new. Take breaks when needed, and go over the examples as many times as needed. Test Yourself With Exercises. Exercise: Insert the missing part of the code below to output 'Hello World'. ) Thank you for the constructive criticism, nonetheless ^^ Frederico Marques Date: Wed, 4 Feb 2009 05:45:39 -0500 From: ralatalo@. To: thesharrk1@. CC: dev-cpp-users@. Subject: Re: Dev-C Sleep / for specified time delay:(? Please for the sake of yourself and the sanity of anyone who later may need to debug or modify your.
2.1 The normal method
Routines for accessing I/O ports are in /usr/include/asm/io.h
(or linux/include/asm-i386/io.h
in the kernel sourcedistribution). The routines there are inline macros, so it is enoughto #include <asm/io.h>
; you do not need any additionallibraries.
Because of a limitation in gcc (present in all versions I know of,including egcs), you have to compile any source code that usesthese routines with optimisation turned on (gcc -O1
or higher),or alternatively use #define extern static
before you#include <asm/io.h>
(remember to #undefextern
afterwards).
For debugging, you can use gcc -g -O
(at least with modernversions of gcc), though optimisation can sometimes make the debuggerbehave a bit strangely. If this bothers you, put the routines that useI/O port access in a separate source file and compile only that withoptimisation turned on.
Permissions
Before you access any ports, you must give your program permission todo so. This is done by calling the ioperm()
function (declaredin unistd.h
, and defined in the kernel) somewhere near the startof your program (before any I/O port accesses). The syntax isioperm(from, num, turn_on)
, where from
is the first portnumber to give access to, and num
the number of consecutive portsto give access to. For example, ioperm(0x300, 5, 1)
would giveaccess to ports 0x300 through 0x304 (a total of 5 ports). The lastargument is a Boolean value specifying whether to give access to theprogram to the ports (true (1)) or to remove access (false (0)). Youcan call ioperm()
multiple times to enable multiplenon-consecutive ports. See the ioperm(2)
manual page for detailson the syntax.
The ioperm()
call requires your program to have root privileges;thus you need to either run it as the root user, or make it setuidroot. You can drop the root privileges after you have calledioperm()
to enable the ports you want to use. You are notrequired to explicitly drop your port access privileges withioperm(..., 0)
at the end of your program; this is doneautomatically as the process exits.
A setuid()
to a non-root user does not disable the port accessgranted by ioperm()
, but a fork()
does (the child processdoes not get access, but the parent retains it).
Delay In Dev C++
ioperm()
can only give access to ports 0x000 through 0x3ff; forhigher ports, you need to use iopl()
(which gives you access toall ports at once). Use the level argument 3 (i.e., iopl(3)
) togive your program access to all I/O ports (so be careful ---accessing the wrong ports can do all sorts of nasty things to yourcomputer). Again, you need root privileges to call iopl()
. Seethe iopl(2)
manual page for details.
Accessing the ports
To input a byte (8 bits) from a port, call inb(port)
, it returnsthe byte it got. To output a byte, call outb(value, port)
(pleasenote the order of the parameters). To input a word (16 bits) fromports x
and x+1
(one byte from each to form the word, usingthe assembler instruction inw
), call inw(x)
. To output aword to the two ports, use outw(value, x)
. If you're unsure ofwhich port instructions (byte or word) to use, you probably wantinb()
and outb()
--- most devices are designed for bytewiseport access. Note that all port access instructions take at leastabout a microsecond to execute.
The inb_p()
, outb_p()
, inw_p()
, and outw_p()
macros work otherwise identically to the ones above, but they do anadditional short (about one microsecond) delay after the port access;you can make the delay about four microseconds with #defineREALLY_SLOW_IO
before you #include <asm/io.h>
. Thesemacros normally (unless you #define SLOW_IO_BY_JUMPING
, whichis probably less accurate) use a port output to port 0x80 for theirdelay, so you need to give access to port 0x80 with ioperm()
first (outputs to port 0x80 should not affect any part of thesystem). For more versatile methods of delaying, read on.
There are manual pages for ioperm(2)
, iopl(2)
, and the abovemacros in reasonably recent releases of the Linux manual pagecollection.
2.2 An alternate method: /dev/port
Another way to access I/O ports is to open()
/dev/port
(acharacter device, major number 1, minor 4) for reading and/or writing(the stdio f*()
functions have internal buffering, so avoidthem). Then lseek()
to the appropriate byte in the file (fileposition 0 = port 0x00, file position 1 = port 0x01, and so on), andread()
or write()
a byte or word from or to it.
Naturally, for this to work your program needs read/write access to/dev/port
. This method is probably slower than the normalmethod above, but does not need compiler optimisation norioperm()
. It doesn't need root access either, if you give anon-root user or group access to /dev/port
--- but this is avery bad thing to do in terms of system security, since it is possibleto hurt the system, perhaps even gain root access, by using/dev/port
to access hard disks, network cards, etc. directly.
You cannot use select(2)
or poll(2)
to read /dev/port,because the hardware does not have a facility for notifying the CPUwhen a value in an input port changes.