I want to use serial port in kernel space, I have found some code which was in user space, I tried to convert the codes to work in kernel space...
this is my code
#include <linux/termios.h>#include <linux/unistd.h>#include <linux/signal.h>#include <linux/fcntl.h>#include <linux/types.h>#include <linux/socket.h>#include <linux/in.h>struct file * fp;...struct termios termAttr;struct sigaction saio;oldfs = get_fs();set_fs(KERNEL_DS);fp = filp_open("/dev/ttymxc0", O_RDWR | O_NOCTTY | O_NDELAY,0);if(fp == NULL) printk(KERN_ALERT "Serial openning error!!.\n");else{ saio.sa_handler = signal_handler_IO; saio.sa_flags = 0; saio.sa_restorer = NULL; sigaction(SIGIO,&saio,NULL); fcntl(fp, F_SETFL, O_NDELAY|FASYNC); fcntl(fp, F_SETOWN, THIS_MODULE); tcgetattr(fp,&termAttr); cfsetispeed(&termAttr,B115200); cfsetospeed(&termAttr,B115200); termAttr.c_cflag &= ~PARENB; termAttr.c_cflag &= ~CSTOPB; termAttr.c_cflag &= ~CSIZE; termAttr.c_cflag |= CS8; termAttr.c_cflag |= (CLOCAL | CREAD); termAttr.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); termAttr.c_iflag &= ~(IXON | IXOFF | IXANY); termAttr.c_oflag &= ~OPOST; tcsetattr(fp,TCSANOW,&termAttr); printk(KERN_ALERT "Serial configured....\n"); vfs_write(fp, "HI",2, NULL); filp_close(fp, NULL); set_fs(oldfs);}
while compiling, I got following errors:
note: each undeclared identifier is reported only once for each function it appears inerror: implicit declaration of function 'sigaction' [-Werror=implicit-function-declaration] sigaction(SIGIO,&saio,NULL); ^error: implicit declaration of function 'fcntl' [-Werror=implicit-function-declaration] fcntl(fp, F_SETFL, O_NDELAY|FASYNC); ^error: implicit declaration of function 'tcgetattr' [-Werror=implicit-function-declaration] tcgetattr(fp,&termAttr); ^error: implicit declaration of function 'cfsetispeed' [-Werror=implicit-function-declaration] cfsetispeed(&termAttr,B115200); ^error: implicit declaration of function 'cfsetospeed' [-Werror=implicit-function-declaration] cfsetospeed(&termAttr,B115200); ^error: implicit declaration of function 'tcsetattr' [-Werror=implicit-function-declaration]
I am cross compiling this driver and I already compiled Linux source, I have searched for this functions in my Linux source code but I did not find any of this functions! what should I use instead of this functions?
Edit 1:
I have changed my code into this:
//serial struct ktermios termAttr; struct sigaction saio; loff_t pos =0; struct tty_struct *tty; serialfp = file_open("/dev/ttyS1", O_RDWR | O_NOCTTY | O_NDELAY,0); if(serialfp == NULL) printk(KERN_ALERT "ARIO RMG Serial openning error!!.\n"); else{ tty = (struct tty_struct *)serialfp->private_data; tty_termios_encode_baud_rate(&tty->termios,B115200,B115200 ); printk(KERN_ALERT "ARIO RMG Serial configured....\n"); pos = serialfp->f_pos; file_write(serialfp, "\n\n\n\n\nThis is first test of sending serial data from kernel module\n\n\n\n\n",70,&pos); serialfp->f_pos=pos; serial_thread_condition = 1; mutex_init(&serial_mutex); task1 = kthread_create(&thread_function, (void *)&pid1, "pradeep"); wake_up_process(task1); printk(KERN_ALERT "data received:%s\n\n\n\n\n\n\n\n",rmg_drvstruct[0].RxSerial); }
I am able to send data into serial port now, I also created a thread to read data from serial port. with following code:
static int thread_function(void *data){ loff_t pos; while(serial_thread_condition){ mutex_lock(&serial_mutex); if (IS_ERR(serialfp)) { mutex_unlock(&serial_mutex); serial_thread_condition=0; return 0; } pos = serialfp->f_pos; printk(KERN_INFO "try to read from serial\r\n"); if(file_read(serialfp, rmg_drvstruct[0].RxSerial, 100, &pos)>0) { printk(KERN_INFO "Data: %s\r\n", rmg_drvstruct[0].RxSerial); serialfp->f_pos = pos; serial_thread_condition = 0; mutex_unlock(&serial_mutex); break; } mutex_unlock(&serial_mutex); }}int file_read(struct file *file, unsigned long long offset, unsigned char *data, unsigned int size){ mm_segment_t oldfs; int ret; oldfs = get_fs(); set_fs(get_ds()); ret = vfs_read(file, data, size, &offset); set_fs(oldfs); return ret;}
But I got nothing in serial port in my thread, I wanted to use interrupts for new received bytes, but irq_request function makes kernel panic and computer freezes out, so what should I do to properly receive data with interrupt or a thread?