參考資訊:
https://www.aps-web.jp/en/ca-en/21578/#anchor2
User Application可以透過read()、write()傳送資料給驅動程式,但是需要注意的地方是,在Linux Kernel中,如果要存取User Application傳送過來的資料時,必須使用copy_to_user()、copy_from_user(),而不是一般的memcpy()或者直接指標操作,否則會導致驅動程式崩潰,這是因為Linux Kernel和User Application是位於不同保護空間,因此,在存取User Application資料時,必須確保該資料已經被Map且位於記憶體
使用方式:
1. copy_to_user() 2. copy_from_user()
main.c
#include <linux/cdev.h> #include <linux/init.h> #include <linux/device.h> #include <linux/module.h> #include <linux/uaccess.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("Steward Fu"); MODULE_DESCRIPTION("Linux Driver"); static int base = 0; static struct cdev mycdev; static char mybuf[255] = {0}; static struct class *myclass = NULL; static int myopen(struct inode *inode, struct file *file) { printk("%s\n", __func__); return 0; } static int myclose(struct inode *inode, struct file *file) { printk("%s\n", __func__); return 0; } static ssize_t myread(struct file *flip, char __user *buf, size_t len, loff_t *off) { int r = 0; r = copy_to_user(buf, mybuf, strlen(mybuf)); printk("%s, %s\n", __func__, mybuf); return r; } static ssize_t mywrite(struct file *flip, const char __user *buf, size_t len, loff_t *off) { int r = 0; r = copy_from_user(mybuf, buf, len); printk("%s, %s\n", __func__, mybuf); return r; } static const struct file_operations myfops = { .owner = THIS_MODULE, .open = myopen, .read = myread, .write = mywrite, .release = myclose, }; int ldd_init(void) { alloc_chrdev_region(&base, 0, 1, "myfile"); myclass = class_create(THIS_MODULE, "myfile"); device_create(myclass, NULL, base, NULL, "myfile"); cdev_init(&mycdev, &myfops); cdev_add(&mycdev, base, 1); return 0; } void ldd_exit(void) { device_destroy(myclass, base); cdev_del(&mycdev); class_destroy(myclass); unregister_chrdev_region(base, 1); } module_init(ldd_init); module_exit(ldd_exit);
ldd_init: 建立字元驅動程式
myopen: 僅列印字串
mywrite: 儲存並且列印User Application傳送的字串
myread: 複製儲存的字串給User Application並且列印出來
myclose: 僅列印字串
ldd_exit: 刪除字元驅動程式
寫入字串
# echo "test" > /dev/myfile mywrite, test
P.S. 按下Ctrl+C停止
讀取字串
# cat /dev/myfile myopen myread, test myclose