iTOP-4412核心板是迅为电子推出的一款高端四核核心板,配备三星Exynos 4412四核处理器,我是用的是SCP 1G的板子。
记录的内容来自于迅为的视频学习。
首先是对外部设备的操作的三部曲:
1.通过原理图找到设备连接的PIN脚 (处理器的数据手册)
2.通过PIN脚找到控制这个引脚的相关寄存器,并找到寄存器对应的物理地址
3.编写程序实现设备的操作
1. 设备和驱动的注册流程
一般都是先注册设备,再注册驱动。现在引入的热插拔设备是先注册的驱动。
1)注册设备使用结构体platform_device,结构体中有name和id
2)注册驱动使用结构体platform_driver,结构体中包括probe,suspend,remove,driver等
3)驱动的注册需要platform_match来判断设备和驱动name是否相同,不同则注册失败。否则probe然后初始化注册设备节点等
2. 查看设备或驱动的几个主要命令
1)insmod,rmmod
2)lsmod=cat /proc/modules
3)查看设备节点的命令cat /proc/devices (0~254)
4)查看注册的设备:ls /sys/devices/
5)查看总线:ls /sys/bus (platform虚拟总线,上面挂很多驱动和设备,通过两个结构体)
6)查看杂项设备号的命令:cat /proc/misc
3. 案例学习的流程
其中ITOP4412的设备程序在arm/arch/mach-exynos/mach-itop4412.c,使用的结构体为linux/platform_device.h中的两个。
通过hello_ctl的案例梳理设备和驱动注册
1)首先配置Koncifg,让menuconfig能够识别:
1 选用的是/driver/char/Kconfig,tristate:可编译成模块 2 config HELLO_CTL 3 tristate "Enable HELLO config" 4 default y 5 help 6 Enable HELLO config
2)增加注册设备的结构体调用。
1 选用的是/arch/arm/mach-exynos/mach-itop4412.c 2 #ifdef CONFIG_HELLO_CTL 3 struct platform_device s3c_device_hello_ctl = { 4 .name = "hello_ctl", 5 .id = -1, 6 }; 7 #endif 8 9 10 #ifdef CONFIG_HELLO_CTL 11 &s3c_device_hello_ctl, 12 #endif
3)重新编译内核
1 make zImage -j4
4)烧写内核
将zimage拷贝到SD卡的update目录下
在板子的uboot中运行sdfuse flash kernel zImage
reset
5)登录板子查看注册完成的设备
1 # ls /sys/devices/platform 2 hello_ctl
至此,设备注册完成。
驱动注册
6)写一个新的驱动文件,其中包含platform_driver结构体中的probe等 ,头文件要包含linux/platform_device.h
1 #include <linux/init.h> 2 #include <linux/module.h> 3 #include <linux/platform_device.h> 4 #define DEVICE_NAME "hello_ctl" 5 6 static int hello_probe(struct platform_device *pdv){ 7 printk(KERN_EMERG "probe hello_probe\n"); 8 return 0; 9 } 10 11 static int hello_remove(struct platform_device *pdv){ 12 return 0; 13 } 14 static int hello_suspend(struct platform_device *pdv){ 15 // 参数不太正确,这个测试主要看probe,不影响 16 return 0; 17 } 18 static int hello_resume(struct platform_device *pdv){ 19 return 0; 20 } 21 static void hello_shutdown(struct platform_device *pdv){ 22 ; 23 } 24 25 struct platform_driver hello_driver = { 26 .probe = hello_probe, 27 .remove = hello_remove, 28 .shutdown = hello_shutdown, 29 .suspend = hello_suspend, 30 .resume = hello_resume, 31 .driver = { 32 .name = DEVICE_NAME, 33 .owner = THIS_MODULE, 34 } 35 }; 36 37 static int hello_init(void) 38 { 39 int DriverState; 40 printk("init!\n"); 41 DriverState = platform_driver_register(&hello_driver); 42 printk(KERN_EMERG "initialized is %d.\n", DriverState); 43 return 0; 44 } 45 46 static void hello_exit(void) 47 { 48 printk("exit!\n"); 49 platform_driver_unregister(&hello_driver); 50 } 51 52 module_init(hello_init); 53 module_exit(hello_exit); 54 55 MODULE_LICENSE("GPL"); 56 MODULE_AUTHOR("NANZH");
1 Makefile 2 obj-m += probe_linux_module.o 3 4 KDIR := /home/nan/work/itop4412/iTop4412_Kernel_3.0 5 6 PWD ?= $(shell pwd) 7 8 all: 9 make -C $(KDIR) M=$(PWD) modules 10 11 clean: 12 rm -rf *.o
注:Makefile中-C调用的库需要是编译之后的,否则会找不到某些文件。
7)编译,将ko文件拷贝到板子中执行
依次打印hello_init中的printk,然后probe,然后hello_init中register之后的内容。
如果设备没有注册,则probe内容不会被打印。
结果在dmesg中查看。(ismod,rmmod)
特此记录。