Таким образом, через некоторое время поиска и тестирования я использовал этот код для связи с последовательным портом, но я немного его изменил.
Пожалуйста, прочитайте мое редактирование перед использованием этот код
Я использовал поток для чтения из последовательного порта, потому что использование прерываний (request_irq) заставляет мое ядро стрелять себе в голову!
Так что это мой код для всех кто может захотеть использовать последовательный порт в модуле ядра.
#include <linux/tty.h>
#include <linux/delay.h>
#include <linux/kthread.h>
#include<linux/mutex.h>
MODULE_LICENSE("GPL");
struct file * serialfp;
struct task_struct *task1;
int pid1 = 1;
....
static struct file *file_open(const char *path, int flags, int rights)
{
struct file *filp = NULL;
mm_segment_t oldfs;
int err = 0;
oldfs = get_fs();
set_fs(get_ds());
filp = filp_open(path, flags, rights);
set_fs(oldfs);
if (IS_ERR(filp)) {
err = PTR_ERR(filp);
return NULL;
}
return filp;
}
static void file_close(struct file *file)
{
filp_close(file, NULL);
}
static 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;
}
static int file_write(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_write(file, data, size, offset);
set_fs(oldfs);
return ret;
}
int file_sync(struct file *file)
{
vfs_fsync(file, 0);
return 0;
}
static int thread_function(void *data){
loff_t pos;
int len;
while(serial_thread_condition){
mutex_lock(&serial_mutex);
if (IS_ERR(serialfp)|| serial_thread_condition==0) {
printk(KERN_INFO "serial reading thread has been terminated.\r\n");
mutex_unlock(&serial_mutex);
serial_thread_condition=0;
return 0;
}
pos = serialfp->f_pos;
if((len=file_read(serialfp,&pos, rmg_drvstruct[0].RxSerial, 100))>0){
printk(KERN_INFO "Received data : %s\r\n", rmg_drvstruct[0].RxSerial);
serialfp->f_pos = pos;
file_write(serialfp,&pos,"I have received:",16);
file_write(serialfp,&pos, rmg_drvstruct[0].RxSerial,len);
serialfp->f_pos = pos;
}
file_sync(serialfp);
mutex_unlock(&serial_mutex);
mdelay(5);
}
}
, поэтому моя функция открытия устройства выглядит так:
static int device_open(struct inode *inode, struct file *file){
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 "Serial configured....\n");
pos = serialfp->f_pos;
file_write(serialfp,&pos,"\n\n\n\n\nThis is first test of sending serial data from kernel module\n\n\n\n\n",70);
serialfp->f_pos=pos;
file_sync(serialfp);
serial_thread_condition = 1;
mutex_init(&serial_mutex);
task1 = kthread_create(&thread_function, (void *)&pid1, "pradeep");
wake_up_process(task1);
}
...
}
и функция закрытия модуля:
static int device_release(struct inode *inode, struct file *file){
...
if (!IS_ERR(serialfp)) {
mutex_lock(&serial_mutex);
printk(KERN_INFO " Trying to realease serail thread");
if(serial_thread_condition==1){
int i=0;
while(i++<256)serial_thread_condition =0;
}
printk(KERN_INFO " serial thread released.");
file_close(serialfp);
mutex_unlock(&serial_mutex);
}
....
}
Спасибо 0andriy за помощь и dmeister за его ответ в этой ссылке .
EDIT:
Итак, я сделал то, что хотел в ядре, открытие файла в пространстве ядра независимо от каких-либо предложений не делать этого.
Но мне нужно было открыть файл в модуле ядра ...
Итак, почему все говорят, что не открывают пользователя космические файлы в ядре? В этих двух статьях есть несколько причин, по которым файлы не используются в ядре, эта ссылка и эта ссылка .
, есть несколько причин, таких как: 1 - модуль ядра может потеря ЦП в любой момент, и файл, который открывается ядром, может закрыться.
2- Я не совсем уверен в этом, но они сказали, что файлы должны иметь процесс, чтобы оставаться открытым, но сам модуль ядра не процесс (возможно, я ошибаюсь!).
3- Если во время работы с файлами возникает какая-либо ошибка (открытие / закрытие / чтение / запись), модуль ядра не может ее обработать и вызывает pani ядра c. ..
Я испытал много паники ядра только при открытии и закрытии файла, с которым я хотел работать. Это некоторые из причин, по которым вам не следует использовать файлы в модулях ядра, поэтому, как уже говорилось в каждом тексте: «Если вам нужно использовать файлы в модуле ядра, вы, вероятно, сделали что-то не так в своем коде!»