一个简单的led驱动设备模型demo 以三星s5pc100的N类引脚的最低一位作为一个led灯设备
开发环境: 宿主机fedora13,交叉编译工具arm-linux-gcc4.3.2 处理器 s5pc100
先建一个工程文件夹
/home/led/
device/ 下放led设备有关文件
s5pc100_led.h s5pc100_leddev.c Makefile
driver/ led驱动程序
s5pc100_led.h s5pc100_leddriver.c Makefile
test/ 测试程序
led_test.c Makefile
重新编译内核即可。
开发环境: 宿主机fedora13,交叉编译工具arm-linux-gcc4.3.2 处理器 s5pc100
先建一个工程文件夹
/home/led/
device/ 下放led设备有关文件
s5pc100_led.h s5pc100_leddev.c Makefile
driver/ led驱动程序
s5pc100_led.h s5pc100_leddriver.c Makefile
test/ 测试程序
led_test.c Makefile
本文先介绍device目录下的3个文件
s5pc100_led.h具体内容
- #ifndef _LED_ANDROID_H_
- #define _LED_ANDROID_H_
- #include <linux/cdev.h>
- #include <linux/semaphore.h>
- #define LED_DEVICE_NODE_NAME "led"
- #define LED_DEVICE_FILE_NAME "led"
- #define LED_DEVICE_PROC_NAME "led"
- #define LED_DEVICE_CLASS_NAME "led"
- struct led_android_dev
- {
- int val;//设备属性
- struct semaphore sem;//信号量
- struct cdev dev;
- //这个地方还不是很规范
- unsigned long pc100_ncon; //gpio的N类引脚的控制寄存器 虚拟地址
- unsigned long pc100_ndat; //gpio的N类引脚的数据寄存器 虚拟地址
- };
- struct resource s3c_led_res[1] = {
- [0] = {
- .start = 0x56000000,
- .end = 0x560000ff,
- .flags = IORESOURCE_MEM,
- },
- };
- #endif
s5pc100_leddev.c函数具体内容
- #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/platform_device.h>
- #include "s5pc100_led.h"
- void led_dev_release(struct device *dev){
- printk("<kernel> release\n");
- }
- struct resource s3c_led_res[1] = {//led设备资源
- [0] = {
- .start = 0xE03001C0,//N类引脚寄存器物理起始地址
- .end = 0xE03001C8,//N类引脚寄存器物理结束地址
- .flags = IORESOURCE_MEM,//资源标识为IO空间
- },
- };
- struct platform_device s3c_led_dev = {
- .name = "led",
- .id = -1,
- .dev = {
- //.platform_data=&pc100_platdata,这里可以添加平台私有数据
- .release = led_dev_release,
- },
- .num_resources = ARRAY_SIZE(s3c_led_res),//platform资源的数量,为1
- .resource = s3c_led_res,
- };
- static int __init led_device_init(void){
- int ret;
- ret = platform_device_register(&s3c_led_dev);
- if(ret){
- printk("device register failed!\n");
- return ret;
- }
- printk("led device init\n");
- return 0;
- }
- static void __exit led_device_exit(void){
- platform_device_unregister(&s3c_led_dev);
- printk("led device bye!\n");
- }
- module_init(led_device_init);//注册设备
- module_exit(led_device_exit);//卸载设备
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("kevin");
Makefile具体内容
- KERNELDIR = /home/s5pc100-kernel
- PWD := $(shell pwd)
- INSTALLDIR = /tftpboot
- #CROSS_COMPILE :=
- #CC = $(CROSS_COMPILE)gcc
- obj-m := s5pc100_leddev.o
- .PHONY: modules modules_install clean
- modules:
- $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
- cp dev.ko $(INSTALLDIR)
- modules_install:
- cp dev.ko $(INSTALLDIR)
- clean:
- rm *.ko
以上为动态注册设备,一般我们设备的注册选用的是静态注册,在arch/arm/目录下 找到对应开发板 的bsp文件 我的开发板为ut-s5pc100 cpu为s5pc100
arch/arm/mach-smdkc100.c这个文件 中添加:
- static struct platform_device *smdkc100_devices[] __initdata 前面添加如下如下语句
- /*led device 2011.9.29*/
- struct resource s3c_led_res[1] = {//led设备资源
- [0] = {
- .start = 0xE03001C0,//N类引脚寄存器物理起始地址
- .end = 0xE03001C8,//N类引脚寄存器物理结束地址
- .flags = IORESOURCE_MEM,//资源标识为IO空间
- },
- };
- struct platform_device s3c_led_dev = {
- .name = "led",
- .id = -1,
- .dev = {
- //.platform_data=&pc100_platdata,这里可以添加平台私有数据
- .release = led_dev_release,
- },
- .num_resources = ARRAY_SIZE(s3c_led_res),//platform资源的数量,为1
- .resource = s3c_led_res,
- };
- 并 在static struct platform_device *smdkc100_devices[] __initdata结构体中的最后面添加
- &s3c_led_dev,
下文添加led设备驱动