tiny4412--linux驱动学习(2)
在ubuntu下編寫驗證字符設備驅動
并移植到arm開發(fā)板上
1,準備工作
?
2,編寫驅動程序
Global CharDev.c
/* GlobalCharDev.c */ #include <linux/module.h> #include <linux/init.h> #include <linux/fs.h>#include <asm/uaccess.h>#define DEV_NAME "GlobalChar"static ssize_t GlobalRead(struct file *, char *, size_t, loff_t *); static ssize_t GlobalWrite(struct file *, const char *, size_t,loff_t *);static int char_major = 0; static int GlobalData = 0; /* "GlobalChar"設備的全局變量 *//* 初始化字符設備驅動的 file_operations 結構體 */ struct file_operations globalchar_fops = {.read = GlobalRead,.write = GlobalWrite };/* 模塊初始化 */ static int __init GlobalChar_init(void) {int ret;ret = register_chrdev(char_major, DEV_NAME, &globalchar_fops);/* 注冊設備驅動,_driver_char_misc.c 第290行參考 */if(ret < 0 )printk(KERN_ALERT "GlobalChar Reg Fail\n");else{printk(KERN_ALERT "GlobalChar Reg Success\n");char_major = ret;printk(KERN_ALERT "Major = %d\n", char_major);}return ret; }/* 模塊卸載函數(shù) */ static void __exit GlobalChar_exit(void) {unregister_chrdev(char_major, DEV_NAME); /* 注銷設備驅動 */return; }/* 模塊驅動讀函數(shù) */ static ssize_t GlobalRead(struct file *file, char *buf, size_t len, loff_t *off) {if (copy_to_user(buf, &GlobalData ,sizeof(int))) {/* 從內核復制 GlobalData 到用戶空間*/return -EFAULT;}return sizeof(int); }/* 模塊驅動寫函數(shù) */ static ssize_t GlobalWrite(struct file *file, const char *buf, size_t len, loff_t *off) {if (copy_from_user(&GlobalData, buf, sizeof(int))){/* 從用戶復制 GlobalData 到內核 */return -EFAULT;}return sizeof(int); }module_init(GlobalChar_init); module_exit(GlobalChar_exit);MODULE_LICENSE("GPL"); MODULE_AUTHOR("dongjin");
?
Makefile
ifneq ($(KERNELRELEASE),) obj-m := GlobalCharDev.o else# KERNELDIR ?= /lib/modules/$(shell uname -r)/buildKERNELDIR ?= /usr/src/linux-headers-$(shell uname -r) //這兩個都可以PWD := $(shell pwd)default:$(MAKE) -C $(KERNELDIR) M=$(PWD) modulesclean:rm -rf rm -rf *.ko *.mod* *.o* *.sy* endif? 理解:
pwd-->? 驅動文件目錄
kerneldir -->? 內核源碼目錄
default -->? 表示到內核源碼目錄中去編譯pwd下的驅動文件
——————————————————————————————————————————————————————
? ? ? ? ? make 編譯
root@ubuntu:/home/arm/data/char_driver# make make -C /usr/src/linux-headers-4.4.0-31-generic M=/home/arm/data/char_driver modules make[1]: 正在進入目錄 `/usr/src/linux-headers-4.4.0-31-generic' CC [M] /home/arm/data/char_driver/GlobalCharDev.oBuilding modules, stage 2.MODPOST 1 modulesLD [M] /home/arm/data/char_driver/GlobalCharDev.ko make[1]:正在離開目錄 `/usr/src/linux-headers-4.4.0-31-generic'?
出現(xiàn)Global CharDev.ko文件
2,insmod Global CharDev.ko? 將模塊加入內核
3,cat? /proc/devices? 查看驅動設備
?
?
4,mknod? /dev/GlobalChar? ?c? 247? 0? ? ? 根據(jù)相應的設備號,建立設備節(jié)點。
5,測試文件
/* GlobaiCharText.c 測試文件*/#include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <fcntl.h> #include <unistd.h>#define DEV_NAME "/dev/GlobalChar"int main() {int fd, num;/* 打開設備文件 */fd = open(DEV_NAME, O_RDWR, S_IRUSR | S_IWUSR);if(fd < 0){printf("Open Device Fail!\n");return -1;}/* 讀取當前設備數(shù)值 */read(fd, &num, sizeof(int));printf("The GlobalChar is %d\n", num);printf("Please input a numble written to GlobalChar: ");scanf("%d", &num);/* 寫入新的數(shù)值 */write(fd, &num, sizeof(int));/* 重新讀取數(shù)值 */read(fd, &num, sizeof(int));printf("The GlobalChar is %d\n", num);close(fd);return 0;}?
? gcc -o? GlobalCharText? GlobalCharText.c? ? ? 編譯出可執(zhí)行文件
執(zhí)行:
root@ubuntu:/home/arm/data/char_driver# ./a.out The GlobalChar is 0 Please input a numble written to GlobalChar: 111 The GlobalChar is 111?
——————————————————————————————————————————————————————————————————————
通過NFS我們可以建立共享目錄,將編寫好的驅動加載到arm板,當然也需要配置環(huán)境變量。
1,驅動文件:需要將Make file中KERNLDIR 改成 自己下載內核的地址,如:
KERNELDIR ?= /home/arm/linux-4.4
?
?
?
2,測試文件:理所當然我們需要使用交叉編譯去編譯出可執(zhí)行文件。
注意:首先我們要知道自己制作的做小系統(tǒng)是采用靜態(tài)編譯還是動態(tài)編譯,我的采用靜態(tài)編譯
1,靜態(tài):
2,動態(tài):
需要在制作最小系統(tǒng)時,在? /lib? 下加入所需的動態(tài)交叉編譯庫(所選交叉編譯工具目錄下的鏈接庫),但是我在制作randisk的過程中,提示內存不足,暫沒查找其原因。
?
如果在靜態(tài)根文件系統(tǒng)內使用動態(tài)編譯鏈所編譯的elf,會提示:-sh:./test:no found? (這里 not found 指的是 鏈接庫)
?
測試:
?
卸載:
1,刪除? /dev? 下的設備節(jié)點
rm /dev/GlobalChar
2,卸載驅動
rmmod? GlopbalCharDev.ko
出現(xiàn)問題:
?
?
——————————————————————————————————————————————————————
參考:
http://tieba.baidu.com/p/3645403366
https://blog.csdn.net/Ultraman_hs/article/details/53239455
解決移植到arm上不兼容的問題
?
https://blog.csdn.net/zqj6893/article/details/48439711
解決驅動卸載問題
轉載于:https://www.cnblogs.com/chu-yi/p/10671865.html
總結
以上是生活随笔為你收集整理的tiny4412--linux驱动学习(2)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C#快速排序
- 下一篇: GIT-Linux(CentOS7)系统