声明
以下都是我刚开始看驱动视频的个人强行解读,如果有误请指出,共同进步。
本节目标
学会注册设备
上一篇说注册设备的时候谈到一个结构体 platform_device,我们直接找到linux的定义查看,首先你要进iTop4412源代码目录,输入命令
vim include/linux/platform_device.h
一进来就看到
struct platform_device {
const char * name;
int id;
struct device dev;
u32 num_resources;
struct resource * resource;
const struct platform_device_id *id_entry;
/* MFD cell pointer */
struct mfd_cell *mfd_cell;
/* arch specific additions */
struct pdev_archdata archdata;
};
- 参数 name 也提到过,linux在match设备和驱动的时候,首先你们名字要一样,才能让设备和驱动匹配成功。
- 参数 id ,举个例子,你叫张三,然而全国叫这个名字的不在少数,那怎么确定是你呢?name张三,id 420621…(身份证),通过这两个参数,你就知道张三是你,而非其他人。对于注册设备来说,如果只有一个,那么id设置为-1,如果有同名name,你就给他们分配id吧。
- 其他参数暂时先不了解,有兴趣自己查
现在开始注册设备
平台文件全部在 arch下,我们用的是arm芯片,4412属于三星mach-exynos,而平台文件是迅为写好的,名字叫mach-itop4412.c,所以我们应该找到
vim arch/arm/mach-exynos/mach-itop4412.c
打开之后,显然不用我们自己造轮子,找一个已有的拿来改就行了,以leds为例,就在leds下面仿照着写一个吧,我起的名字也与迅为的不一样,迅为的宏定义是CONFIG_HELLO_CTL,我的叫CONFIG_MRYANG_CTL。
(这里的宏定义源自笔记2仿写Kconfig的时候写的)
#ifdef CONFIG_MRYANG_CTL
struct platform_device s3c_device_mryang_ctl = {
.name = "mryang_ctl",
.id = -1,
};
不知道大家还记不记得,我们之前提到过强制编译和条件编译长什么样,我们之前做的都类似是个开关(Kconfig是图形界面开关,这里是定义了这个结构体),你编译勾选了也没用,因为他们根本没联系起来,而我们要把他们联系起来,肯定是要用C语言的条件编译的,我们继续在这个文件中搜索leds
#ifdef CONFIG_LEDS_CTL
&s3c_device_leds_ctl,
#endif
其实这就很清楚了,定义了CONFIG_LEDS_CTL,就传参这个结构体,为了让我们写的也生效,我们把这里也要仿写一下。
#ifdef CONFIG_MRYANG_CTL
&s3c_device_mryang_ctl,
#endif
然后保存退出就可以进行下一步了
为了保证正确,我们还是回过头检查一下之前我们定义的宏定义吧
vim drivers/char/Kconfig
搜索我定义的宏定义的关键词 MRYANG
啥?没搜到?那就搜一下LEDS,因为我们就是照着LEDS仿写的,搜到了,我之前定义了忘记保存了,难怪没搜到,重新补上吧…
config MRYANG_CTL
bool "Enable MRYANG config"
default y
help
Study Kconfig
因为我是仿写的,所以我写的就跟着LEDS后面,其实在哪都行。记得保存!!!
仿写结构体和宏变量完成,准备编译
我们查看一下图形界面,我们写的是否被选中编译进内核
make menuconfig
还是老地方,Device Drivers/Character devices 下(再次说明:因为我们是仿照字符设备LED写的,所以在这)
检查 Enable MRYANG config 前面确实有个星号,表示被编译进内核,那么就开始编译吧!
make zImage
我在 make zImage 的时候有提示问我 Enable MRYANG config (MRYANG_CTL) [Y/n/?] (NEW) ,我在后面输入了个y回车,表示确定编译进内核。
我去 怎么报错了,仔细一看,原来是定义结构体platform_device的s3c_device_mryang_ctl最后少了个 ; 号(上面已重新添加),这错误犯的真2…
修改之后 编译完成
生成的zImage路径是 /arch/arm/boot下,以后就不再叙述了
把编译生成的zImage烧写进板子
我们用命令查看虚拟总线platform是否挂载了我们仿写的驱动
ls /sys/devices/platform
果然看到了我们编写的 mryang_ctl (第一列倒数第7个)
当然,你也可以直接用 ls sys/devices/platform |grep mryang,免得显示这么多。
[root@iTOP-4412]# ls sys/devices/platform
adc_ctl s3c-pl330.1 s5pv210-uart.3
alarm s3c-pl330.2 samsung-audio
android_pmem.0 s3c-sdhci.2 samsung-audio-idma
android_pmem.1 s3c-sdhci.3 samsung-i2s.0
arm-pmu.0 s3c-usbgadget samsung-i2s.4
bt-sysfs s3c2410-wdt samsung-keypad
buzzer_ctl s3c2440-i2c.1 samsung-kmsg
dw_mmc s3c2440-i2c.3 samsung-pd.0
exynos-busfreq s3c2440-i2c.4 samsung-pd.1
exynos-usb-switch s3c2440-i2c.5 samsung-pd.2
exynos4412-adc s3c2440-i2c.7 samsung-pd.5
gpio-keys s3c24xx-pwm.1 samsung-pd.6
i2c-gpio.0 s3c64xx-rtc samsung-pd.7
ion-exynos s3c64xx-spi.2 samsung-rp
leds s5p-ehci serial8250
max485_ctl s5p-fimg2d si_gps
mryang_ctl s5p-pmic snd-soc-dummy
mt3326-gps s5p-sysmmu.15 soc-audio
power s5p-tvout-cec switch-gpio.0
power.0 s5p-tvout-hpd tc4-regulator-consumer
reg-dummy s5pv210-uart.0 uevent
regulatory.0 s5pv210-uart.1 wlan_ar6000_pm_dev.1
relay_ctl s5pv210-uart.2
至此,我们已经成功注册了设备,名字name叫 mryang_ctl,因为只有一个没有重名,所以id是-1。(文章开头定义结构体的时候写的)