Mezgani blog

June 16, 2010

How to send a bit to the parallel port on Linux (2nd part)

Filed under: linux, programming c/c++, system — Tags: , — Ali MEZGANI @ 2:19 am

In this second part of how to send bits to the parallel port on Linux, i describe here basics on how to do the same on kernel space.
Here is a simple linux kernel module, that create a char device named parlport, and you can communicate directly with device using the /dev/parlport

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/unistd.h>
#include <asm/uaccess.h>
#include <linux/file.h>
#include <asm/io.h>

#define NAME “parlp”
#define VERSION “0.1″
#define LICENSE “GPL”
#define DESCPT “Simple Parallel Port LED driver”
#define AUTHOR “Mezgani Ali\n”\
“mail: mezgani [AT] nativelabs [.] org\n”\
“blog: http://securfox.wordpress.com/&#8221;

#define SUCCESS 0
#define DEVICE_NAME “parlport”
#define BASEPORT 0×0378

static int major = 61; /* major number assigned to our device driver */

static int __init start_module(void);
static void __exit clean_module(void);

static int device_open(struct inode *, struct file *);
static int device_release(struct inode *, struct file *);
static ssize_t device_read(struct file *, char *, size_t, loff_t *);
static ssize_t device_write(struct file *, char *, size_t, loff_t *);

static struct file_operations fops = {
.open = device_open,
.release = device_release,
.read = device_read,
.write = device_write
};

static int
__init start_module(void)
{
int result;

result = register_chrdev(major, DEVICE_NAME, &fops);

if (result < 0) {
printk(KERN_ALERT “Registering device failed with %d\n”, major);
return result;
}

if (!(request_region(BASEPORT, 1, DEVICE_NAME))){
printk(KERN_WARNING “Winbond error request region: %X\n”, BASEPORT);
release_region(BASEPORT, 1);

return result;
}

printk(KERN_INFO “I was assigned major number %d. To talk to\n”, major);
printk(KERN_INFO “the driver, create a dev file with\n”);
printk(KERN_INFO “‘mknod /dev/%s c %d 0′.\n”, DEVICE_NAME, major);

return SUCCESS;
}

static void
__exit clean_module(void)
{
release_region(BASEPORT, 1);

unregister_chrdev(major, DEVICE_NAME);
printk(KERN_ALERT “unregister_chrdev && cleaning module\n”);

}

static int
device_open(struct inode *inode, struct file *file)
{
try_module_get(THIS_MODULE);
return SUCCESS;
}

static int
device_release(struct inode *inode, struct file *file)
{
module_put(THIS_MODULE);
return 0;
}

static ssize_t
device_read(struct file *filp, char *buffer, size_t length, loff_t * offset)
{
unsigned char pbuffer;
int len;

/* input a byte (8 bits) from a port, call inb(port), it returns the byte it got */
pbuffer = inb(BASEPORT);

len = copy_to_user(buffer, &pbuffer, 1);
if (len) return -EFAULT;

if (*offset == 0) {
*offset += 1;
return 1;
} else {
return 0;
}
}

static ssize_t
device_write(struct file *filp, char *buffer, size_t length, loff_t * offset)
{

char pbuffer, *ptr;
int len;

ptr = buffer + length – 1;
len = copy_from_user(&pbuffer, ptr, 1);
if (len) return -EFAULT;

/* output the data to parallel port */
outb(pbuffer, BASEPORT);
return 1;
}

module_init(start_module);
module_exit(clean_module);

MODULE_LICENSE(LICENSE);
MODULE_AUTHOR(AUTHOR);
MODULE_DESCRIPTION(DESCPT);
MODULE_VERSION(VERSION);

Example of use after compilation ;

# insmod parlport.ko
# mknod /dev/parlport c 61 0
# chown 666 /dev/parlport
# echo F > /dev/parlport

April 21, 2009

How to look up domain names and addresses.

Filed under: programming c/c++ — Tags: — Ali MEZGANI @ 11:56 pm

To resolve host names and addresses in the domain name system or the local hosts, there are many functions defined as well as the function gethostbyname.

The gethostbyname() is a function that returns a structure of type hostent for the given host name.
Here name is either a host name, or an IPv4 address in standard dot notation.
You can find here an example of using gethostbyname(3).

#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>

struct hostent *ptr;

/* The hostent structure is defined in as follows:
struct hostent {
char *h_name; //official name of host
char **h_aliases; //alias list
int h_addrtype; //host address type
int h_length; // length of address
char **h_addr_list; //list of addresses
}
#define h_addr h_addr_list[0]
*/

int
main(int argc, char **argv)
{

// two arguments are permitted
// the second one is the hostname

if (argc != 2) {
fprintf(stderr,”Usage: %s hostname\n”,argv[0]);
exit(0);
}

ptr = gethostbyname(argv[1]);
int i=0;

// gethostbyname() returns NULL pointer if failed.
if (ptr == NULL) {
fprintf(stderr,”gethostbyname() failed\n”);
exit(1);
} else {

// If the host name, has many translation address so, until there are addresses loop

// we will only use the s_addr field in the in_addr structure
// which records the host address number as an uint32_t

while(ptr -> h_addr_list[i]) {
if ( ptr -> h_addr_list[i] != NULL)
printf(“%s\n”, inet_ntoa( *( struct in_addr*)( ptr -> h_addr_list[i])));
i++;
}
}
return 0;

}

March 12, 2009

Static and Shared library

Filed under: linux, programming c/c++ — Tags: , — Ali MEZGANI @ 12:23 am

Creating Shared library:
First, create the object files that will go into the shared library using the gcc -fPIC or -fpic flag.
The -fPIC and -fpic options enable “position independent code” generation, a requirement for shared libraries.

$ gcc -fPIC -Wall -g -c foo.c

Every shared library has a special name called the “soname”. The soname has the prefix “lib”,
the name of the library, the phrase “.so”, followed by a period and a version number.

We can use ‘ld’, the GNU linker to create our shared library. The ld combines a number of object and archive files,
relocates their data and ties up symbol references.

$ ld -shared -soname libfoo.so.1 -o libfoo.so.1.0 foo.o

Creating Static library:
Static libraries are simply a collection of ordinary object files; conventionally, static libraries end with the ‘.a’‘ .
To generate object file use ‘-c‘ flag with gcc.

$ gcc -c bar.c -o bar.o

Flags:
-c Compile or assemble the source files, but do not link. The compiler output is object files corresponding to each source file.
-o To specifiy the output file name.

A static library can contain more than one object files. We need to copy all object file in to a single file.
This single file is our static library. We can use archiver(ar) to create to create our static library.

$ ar rcs libbar.a bar.o

Options:
r – Insert the files into archive (with replacement).
c – Create the archive.
s – Write an object-file index into the archive, or update an existing one, even if no other change is made to the archive.

Theme: Silver is the New Black. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.