giving uninterrupted access to parallel port linux - c

I want to modify my program so that I can ensure my linux system can give my C application 100% uninterrupted access to my parallel port.
I have the following statements in my program already:
if (ioperm(0x378,3,1) ==-1){printf("Access denied");return -1;}
...
outb(data,0x378);
Essentially I request permission then do direct I/O with the port but it doesn't seem like direct I/O because sometimes when I use it, somewhere extra incorrect bytes are written to it (I'm guessing interrupt signals) which is throwing my homemade programmer off.
The linux manual suggested the use of the iopl function so between the statements above I added:
if (iopl(3) ==-1){printf("Error");return -1;}
but the iopl() made no difference.
Is there some kind of function I can use for C that would allow ONLY my program to access the parallel port and allow all others to access it only after my program terminates?

Related

creating a serial loopback under VxWorks

I'm fairly new to VxWorks OS and hence wouldn't mind explanations in case I differ in my understanding of things under the hood when they differ from more traditional OSes like Linux and the likes. With that out of the way, let me begin my actual question.
I am trying to create a loop-back test for testing changes I made to the serial UART driver on the board. Since I do not want to use a cross cable to actually short two UART ports externally, I've connected both of those ports to my dev machine. One configured as an output port from the dev machine's perspective (and consequently as an Input port on the board) and the other an input port (an output port on the board). I am actually doing the loopback using a shared memory buffer which I am protecting using a mutex. So there are two threads on the board, one of which reads from the input port, copies data to the shared memory and the other reads from the memory and sends it over the output port.
And I am using regular open, read and write calls in my VxWorks application (by the way I think it is part of the application code as I call the functions from usrAppInit.c not withstanding the fact that I can even call driver routines from here! (Is it because of a flat memory model vis-a-vis Linux?? Anyhow).
Now I these ports on VxWorks have been opened in a non blocking mode and here's the code snippet which configures one of the ports:
if( (fdIn = open(portstrIn, O_RDONLY | O_NOCTTY, 0) ) == ERROR) {
return 1;
}
if(((status = ioctl(fdIn, FIOSETOPTIONS, OPT_RAW))) == ERROR)
{
return 1;
}
/* set the baud rate to 115200
*/
if((status = ioctl(fdIn, FIOBAUDRATE, 115200)) == ERROR)
{
return 1;
}
/* set the HW options
*/
if((status = ioctl(fdIn, SIO_HW_OPTS_SET, (CS8 | 0 | 0))) == ERROR)
{
return 1;
}
And similarly the output port is also configured. These two are part of two separate tasks spawned using taskSpawn and have the same priority of 100. However what I am annoyed by, is that when I write to the in port from my dev machine (using a python script), the read call on the board get's sort of staggered (I wonder if that's the right way to refer to it). It is most likely due to the short availability of hardware buffer space on the UART input buffer (or some such). This is usually not much of a problem if that is all I am doing.
However, as explained earlier, I am trying to copy the whole received character stream into a common memory buffer (guarded by a mutex of course) which is then read by another task and then re-transmitted over another serial port (sort of an in memory loopback if you will)
In lieu of that aforementioned staggering of the read calls, I thought of holding the mutex as long as there are characters to be read from the Inport and once there are no chars to be read, release the mutex and since this is VxWorks, do an explicit taskDelay(0) to schedule the next ready task (my other task). However since this is a blocking read, I am (as expected) stuck on the read call due to which my other thread never gets a chance to execute.
I did think of checking if the buffer was full and then doing the explicit task switch however if any of you have a better idea, I'm all ears.
Also just to see how this staggered read thing works from the perspective of the kernel, I timed it using a time(NULL) call just before and right after the read. So surprisingly, the very first chunk shows up a number, every other chunk after that (if it's a part of the same data block coming from the outside) shows 0. Could anyone explain that as well?
Keen to hear
I don't have 50 rep points for commenting, but without a loopback cable attached, the only way you can arrive at testing serial loopback behavior is to switch the uart into loopback mode. This often means making changes to the specific hardware part driver.

How to open a serial port with read/write lines reversed?

I know how to open a serial port using 'open' function:
open("/dev/portname", flags)
But I want two programs to open this port but with reversed read/write lines. For example when program 2 writes something to the port, program 1 can read it.
If you're using a Unix-like operating system, and if you don't need full serial port semantics, named pipes can be quite useful for doing this sort of thing.
If you need more control, you could perhaps use a pair of pseudoterminals, with a third program running in the background shuttling characters between the master ends.
And do see the related question "Virtual Serial Port for Linux" that the StackOverflow machinery already found for you.
You cannot typically do that in software.
Such things are normally done by hardware, and that is what cross-over cables and "null-modem" cables are good for.

sysfs, ifreq, IOCTL or ??? to programatically monitor network status

We have an embedded SoC running BusyBox Linux (kernel 2.6.x), and we have a need to monitor or at least notice in a timely manner when the network connection goes down or comes up (catching other events would be good but not essential).
I've spent a long time googling & reading SO threads and there seems to be a ton of different answers depending on the exact task at hand on the particular OS and the phases of the moon etc.
Our specific criteria are:
We are looking from inside a C program, so C code is preferable to command line calls.
Although the interface is always there, we can't guarantee it is or has ever been up (I have seen comments on some examples that only work when the interface is up even if the link is down)
It would be nice not to have to poll, but rather to send/catch status change messages as and when they happen. I believe the kernel may already get such messages from the driver, but I'm not sure if there's anything we can hook into?
I've narrowed the likely seeming answers down to a few candidates but can't work out which is the nicest (least overhead, most reliable, least likely to break in future versions):
cat sys/class/net/eth0/operstate
cat sys/class/net/eth0/carrier (I can find no good explanation of the difference between these two)
Using ifreq or various sequences of ioctl calls to read the socket status (looks kinda messy to me) as per answers here and here (more tidy looking).
Somehow catch status change messages???
You can use inotify to keep check on the /sys/class/net/eth0/operstate. Inotify allows different events to be watched on specified file or directory e.g. CREATE, MODIFY, WRITE etc.
You can seen the working example here

why clear interrput flag cause segmentation fault in C?

I am learning some basics about Assembly and C. for learning purpose I decide to write a simple program that disable Interrupts and when user wants to type something in the console he/she can't :
#include <stdio.h>
int main(){
int a;
printf("enter your number : ");
asm ("cli");
scanf("%d", &a);
printf("your number is %d\n" , a);
return 0;
}
but when I compile this with GCC I got segmentation fault :
Segmentation fault (core dumped)
And when I debug it with gdb I got this message when program reach to the asm("cli"); line:
Program received signal SIGSEGV, Segmentation fault.
main () at cli.c:6
6 asm ("cli");
This is happening because You can't disable interrupts from user space program. All interrupts are under the control of kernel. You need to do it from kernel space. Before you do it you need to learn kernel internals first and playing with interrupts are very critical and requires more knowledge on kernel according to my knowledge.
You need to write a kernel module that can interact with user space through /dev/ (or some other) interface. User space code should request kernel module to disable interrupts.
cli is a privileged instruction. It raises a #GP(0) exception "If the CPL is greater (has less privilege) than the IOPL of the current program or procedure". This #GP is what causes Linux to deliver a SIGSEGV to your process.
Under Linux, you could make an iopl(3) system call to raise your IO priv level to match your ring 3 CPL, and then you could disable interrupts from user-space. (But don't do this, it's not supported AFAIK. The intended use-case for iopl is to use in and out instructions from user-space with high port numbers, not cli/sti. x86 just happens to use the same permissions for both.)
You'll probably crash your system if you don't re-enable interrupts right away, or maybe even if you do. Or at least screw up that CPU on a multi-core system. Basically don't do this unless you're ready to press the reset button, i.e. shut down X11, saved your files and run sync. Also remount your filesystems read-only.
Or try it in a virtual machine or simulator like BOCHS that will let you break in with a debugger even while interrupts are disabled. Or try it while booted from a USB stick.
Note that disabling interrupts only disables external interrupts. Software-generated interrupts like int $0x80 are still taken, but making system calls with interrupts disabled is probably an even worse idea. (It might work, though. The kernel saves/restores EFLAGS, so it probably won't return to user-space with interrupts re-enabled. Still, leaving interrupts disabled for a long time is a Bad Thing for interrupt latency.)
If you want to play around with disabling interrupts as a beginner, you should probably do it from a toy boot-sector program that uses BIOS calls for I/O. Or just look in the Linux kernel source for some places where it disables/enables interrupts if you're curious why it might do that.
IMO, "normal" asm in user-space is plenty interesting. With performance counters, you can see the details of how the CPU decodes and executes instructions. See links in the x86 tag wiki for manuals, guides, and performance tuning info.

From userspace, how can I tell if Linux's soft watchdog is configured with no way out?

I am writing a system monitor for Linux and want to include some watchdog functionality. In the kernel, you can configure the watchdog to keep going even if /dev/watchdog is closed. In other words, if my daemon exits normally and closes /dev/watchdog, the system would still re-boot 59 seconds later. That may or may not be desirable behavior for the user.
I need to make my daemon aware of this setting because it will influence how I handle SIGINT. If the setting is on, my daemon would need to (preferably) start an orderly shutdown on exit or (at least) warn the user that the system is going to reboot shortly.
Does anyone know of a method to obtain this setting from user space? I don't see anything in sysconf() to get the value. Likewise, I need to be able to tell if the software watchdog is enabled to begin with.
Edit:
Linux provides a very simple watchdog interface. A process can open /dev/watchdog , once the device is opened, the kernel will begin a 60 second count down to reboot unless some data is written to that file, in which case the clock re-sets.
Depending on how the kernel is configured, closing that file may or may not stop the countdown. From the documentation:
The watchdog can be stopped without
causing a reboot if the device
/dev/watchdog is closed correctly,
unless your kernel is compiled with
the CONFIG_WATCHDOG_NOWAYOUT option
enabled.
I need to be able to tell if CONFIG_WATCHDOG_NOWAYOUT was set from within a user space daemon, so that I can handle the shutdown of said daemon differently. In other words, if that setting is high, a simple:
# /etc/init.d/mydaemon stop
... would reboot the system in 59 seconds, because nothing is writing to /dev/watchdog any longer. So, if its set high, my handler for SIGINT needs to do additional things (i.e. warn the user at the least).
I can not find a way of obtaining this setting from user space :( Any help is appreciated.
AHA! After digging through the kernel's linux/watchdog.h and drivers/watchdog/softdog.c, I was able to determine the capabilities of the softdog ioctl() interface. Looking at the capabilities that it announces in struct watchdog_info:
static struct watchdog_info ident = {
.options = WDIOF_SETTIMEOUT |
WDIOF_KEEPALIVEPING |
WDIOF_MAGICCLOSE,
.firmware_version = 0,
.identity = "Software Watchdog",
};
It does support a magic close that (seems to) override CONFIG_WATCHDOG_NOWAYOUT. So, when terminating normally, I have to write a single char 'V' to /dev/watchdog then close it, and the timer will stop counting.
A simple ioctl() on a file descriptor to /dev/watchdog asking WDIOC_GETSUPPORT allows one to determine if this flag is set. Pseudo code:
int fd;
struct watchdog_info info;
fd = open("/dev/watchdog", O_WRONLY);
if (fd == -1) {
perror("open");
// abort, timer did not start - no additional concerns
}
if (ioctl(fd, WDIOC_GETSUPPORT, &info)) {
perror("ioctl");
// abort, but you probably started the timer! See below.
}
if (WDIOF_MAGICCLOSE & info.options) {
printf("Watchdog supports magic close char\n");
// You have started the timer here! Handle that appropriately.
}
When working with hardware watchdogs, you might want to open with O_NONBLOCK so ioctl() not open() blocks (hence detecting a busy card).
If WDIOF_MAGICCLOSE is not supported, one should just assume that the soft watchdog is configured with NOWAYOUT. Remember, just opening the device successfully starts the countdown. If all you're doing is probing to see if it supports magic close and it does, then magic close it. Otherwise, be sure to deal with the fact that you now have a running watchdog.
Unfortunately, there's no real way to know for sure without actually starting it, at least not that I could find.
a watchdog guards against hard-locking the system, either because of a software crash, or hardware failure.
what you need is a daemon monitoring daemon (dmd). check 'monit'
I think the watchdog device drivers are really intended for use on embedded platforms (or at least well controlled ones) where the developers will have control of which kernel is in use.
This could be considered to be an oversight, but I think it is not.
One other thing you could try, if the watchdog was built as a loadable module, unloading it will presumably abort the shutdown?

Resources