Knowledge Base Nr: 00079 stxetx.c - http://www.swe-kaiser.de
Downloads:
linux: treiber für serielle schnittstelle mit STX/ETX protokoll als module (incl. testprogramm).
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/sched.h>
#include <asm/uaccess.h>
#include "direct.h"
static int direct_proc_pid=0;
static int direct_buf_pos=0;
static char direct_buffer[2000];
static int direct_mode=IDLE;
int direct_open(struct tty_struct * tty)
{
//printk("<1> opening .xx..pid:%d\n",current->pid);
direct_proc_pid=current->pid;
direct_buf_pos=0;
direct_mode=IDLE;
return 0;
}
int direct_write(struct tty_struct *tty, struct file *filp,const unsigned char * data, unsigned int count)
{
int i;
tty->driver.put_char(tty,STX);
for (i=0;i<count;i++)
tty->driver.put_char(tty,data[i]);
tty->driver.put_char(tty,ETX);
tty->driver.flush_chars(tty);
return count;
}
int direct_read(struct tty_struct *tty, struct file *filp, unsigned char *buf, unsigned int count)
{
int helper;
//printk("<1> reading ...\n");
copy_to_user(buf,direct_buffer,direct_buf_pos);
helper=direct_buf_pos;
direct_buf_pos=0;
return helper;
}
void direct_receive(struct tty_struct *tty,const unsigned char *cp, char *fp, int count)
{
int action=0;
int i;
//printk ("<1> receiving data...\n");
for (i=0;i<count;i++)
{
if (cp[i]==STX)
{
//if (direct_buf_pos > 0)
// direct_buffer[direct_buf_pos++]=STX;
direct_buf_pos = 0;
//direct_buf_pos=0;
direct_mode=READING;
}
else if(cp[i]==ETX)
{
direct_mode=IDLE;
action=1;
}
else if (direct_mode==READING)
direct_buffer[direct_buf_pos++]=cp[i];
}
if (action)
kill_proc(direct_proc_pid,SIGIO,1);
}
int direct_room(struct tty_struct *tty)
{
return -1;
}
struct tty_ldisc direct_ldisc={
TTY_LDISC_MAGIC,
"DIRECT",
0,
0,
direct_open,
0,//close
0,
0,
direct_read,
direct_write,
0,//ioctl
0,//set_termios
0,//poll
direct_receive,
direct_room,
0
};
int init_module(void)
{
int status=tty_register_ldisc(N_DIRECT,&direct_ldisc);
if (status!=0)
printk("<1> konnte nicht ld registrieren ...\n");
else
printk("<1> ld registriert ok ...\n");
return status;
}
void cleanup_module(void)
{
int status=tty_register_ldisc(N_DIRECT,NULL);
if (status!=0)
printk("<1> konnte nicht ld deregistrieren ...\n");
else
printk("<1> ld deregistriert ok ...\n");
}