What is the outp() counterpart in gcc compiler? - c

In my School my project is to make a simple program that controls the LED lights
my professor said that outp() is in the conio.h, and I know that conio.h is not a standard one.
example of outp()
//assume that port to be used is 0x378
outp(0x378,1); //making the first LED light
thanks in advance

You can do this from user space in Linux by writing to /dev/port as long as you have write permissions to /dev/port (root or some user with write permissions). You can do it in the shell with:
echo -en '\001' | dd of=/dev/port bs=1 count=1 skip=888
(note that 888 decimal is 378 hex). I once wrote a working parallel port driver for Linux entirely in shell script this way. (It was rather slow, though!)
You can do this in C in Linux like so:
f = open("/dev/port", O_WRONLY);
lseek(f, 0x378, SEEK_SET);
write(f, "\01", 1);
Obviously, add #include and error handling.

How to write to a parallel port depends on the OS, not the compiler. In Linux, you'd open the appropriate device file for your parallel port, which is /dev/lp1 on PC hardware for port 0x0378.
Then, interpreting the MS docs for _outp, I guess you want to write a single byte with the value 1 to the parallel port. That's just
FILE *fp = fopen("/dev/lp1", "wb");
// check for errors, including permission denied
putc(1, fp);

You're mixing up two things. A compiler makes programs for an OS. Your school project made a program for DOS. outp(0x378,1); is essentially a DOS function. It writes to the parallel port. Other operating systems use other commands.
GCC is a compiler which targets multiple Operating Systems. On each OS, GCC will be able to use header files particular top that system.
It's usually going to be a bit more complex. DOS runs one program at a time, so there's no contention for port 0x378. About every other OS runs far more programs concurrently, so you first have to figure out who gets it.

Related

Print debug text from C code into Lauterbach TRACE32

Is it possible to print debug text from C code (running on embedded system) into Lauterbach TRACE32 (connected over Lauterbach hardware)? Previously we used to output it via UART (serial connection) but now it is not available.
It is possible to print text from the target application to TRACE32. Some vendors call the mechanism you are searching for a JTAG Terminal, Semihosting (ARM) or Hostlink (Synopsys).
This is handled in TRACE32 with the TERM command group.
The usual approach is as following:
Add t32term.c, t32term_memory.c and t32term.h to you project. You can find those files in your TRACE32 installation at <t32>/demo/etc/terminal/t32term.
Compile t32term.c and t32term_memory.c with defined macro T32_TERM_BLOCKED=1, T32_TERM_METHOD_MEMORY=1, and T32_TERM_MEMORY_BLOCKED_SIZE=256 . E.g.:
TERMOPT:=-DT32_TERM_BLOCKED=1 -DT32_TERM_METHOD_MEMORY=1 -DT32_TERM_MEMORY_BLOCKED_SIZE=256
gcc $(TERMOPT) -c -o t32term.o t32term.c
gcc $(TERMOPT) -c -o t32term_memory.o t32term_memory.c
Of course instead of just "gcc" you have to use here the cross-compiler for your target with all the CPU specific options.
In your application use function T32_Term_Puts(const char *str) to send a text-buffer to TRACE32
To use something like printf() write a wrapper function around T32_Term_Puts() around vsprintf(). Some compiler's C library provides already some printf(), which calls in the end some weakly declared puts() function, which you can overwrite with T32_Term_Puts().
During linking ensure that the buffers T32_Term_Memory_Tar2HostBuffer and T32_Term_Memory_Host2TarBuffer get placed into uncached memory.
In TRACE32 use the following commands:
SYStem.MemAccess Enable // Enable memory access to running CPU
TERM.METHOD BufferE E:T32_Term_Memory_Tar2HostBuffer E:T32_Term_Memory_Host2TarBuffer
TERM.GATE
The window TERM.GATE receives the data you've send with T32_Term_Puts(). You have to keep it open.
TERM.METHOD specifies the way how TRACE32 receives the printed data from your target application. The method BufferE is pretty common and works with all CPUs which support reading memory by the debugger while the CPU is running. There are other methods available you might have to use if BufferE is not possible.
For the method BufferE you have to allow the debugger to access target memory while the CPU is running. This is done with the command SYStem.MemAccess Enable. Depending on the CPU family you are debugging and the version of TRACE32 you have to use the keyword CPU, DAP or NEXUS instead of Enable.
The mechanism allows you not only to send text to TRACE32. It allows you also to open files from the PC running TRACE32, write data to a file, get the system time or start applications.
If your target chip contains an ITM or STM hardware trace module and you own a tracing hardware from Lauterbach (like CombiProbe or PowerTrace) you can also use that mechanism to send text from you target application to TRACE32.

What is the difference between reboot arguments RB_HALT_SYSTEM and RB_POWER_OFF?

What is the real difference between the LINUX_REBOOT_CMD_HALT and LINUX_REBOOT_CMD_POWER_OFF arguments to the reboot() system call (resp. the RB_HALT_SYSTEM and RB_POWER_OFF arguments given to its wrapper function)?
The reboot(2) manual page has the following descriptions (differences emphasized):
RB_HALT_SYSTEM
LINUX_REBOOT_CMD_HALT
(RB_HALT_SYSTEM, 0xcdef0123; since Linux 1.1.76). The message "System halted." is printed, and the system is halted. Control is given to the ROM monitor, if there is one. If not preceded by a sync(2), data will be lost.
LINUX_REBOOT_CMD_POWER_OFF
(RB_POWER_OFF, 0x4321fedc; since Linux 2.1.30).
The message "Power down." is printed, the system is stopped, and all power is removed from the system, if possible. If not preceded by a sync(2), data will be lost.
Reading the descriptions, a few questions come up:
What is the difference between halted and stopped?
Would a reboot(RB_HALT_SYSTEM) call not remove power from the
system?
Where would the "System halted." and "Power down." messages be printed?
I don't think there is a difference; those words are synonyms in common English and I think this documentation is just using their English meaning, not as specific technical terms.
correct, that's exactly what the docs are trying to tell you.
on the console and/or kernel log, duh. Where kernel messages are normally printed, like during bootup.
You can easily try these for yourself to see what they do; the user-space shutdown(8) command has -H (halt) and -P / -h (poweroff) options, as well as -r. Read the man page. I assume it eventually makes a reboot(2) system call, or causes init to make one, after a sync.
And yes, the traditional shutdown -h command is halt + power off, i.e. POWER_OFF. Back in the old days, computers didn't used to be able to power themselves off, but these days that's usually what people think of as a non-reboot shutdown. Especially on systems where the kernel can't "return" to a BIOS / firmware command interface.
On a PC, one of the few use-cases I could imagine for halt without poweroff would be to insert a USB drive or CD before pressing the reset button (or ctrl+alt+delete). But maybe you don't want the currently-booted Linux kernel to react to the new hardware at all, so you want to halt Linux first.
You could poweroff to do this, but you don't need to and there's no need to start/stop your rotating disks and put extra wear on their motors.

giving uninterrupted access to parallel port linux

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?

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.

48bit and 28bit ATA commands with ioctl

During sending ATA commands I found several classifications. For example, first one - we can divide the commands to Data-In, Data-Out and Non-Data commands. Another classification can be that there are 48bit commands and 28bit comands. First ones are for the disks, which are larger that 120Gb.
The question is: do I need to set up some values that the disk will know that it get the 48bit command or not? For example, if I send SCSI command with ATA through SATL or ATA PASS THROUGH command through the controller.
During the research it was found that every controller has its own specificities depending on the driver. That is why implementation of ATA PASS THROUGH commands are so difficult work.
Through reading the Linux driver and checking what structures are sent with ioctl it is possible to figure out if it is 28 or 48 bit command.
Moreover, it is also quite important to check how new is the software, because 48-bit Logical Block Addressing (LBA) was introduced in 2006 in ATA-6 standard. Most probably nowadays all the controllers supports 48-bit command set, but still you should check if the controller supports it.
So, the answer to this question strongly depends on the using controller.

Resources