一个简单的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设备驱动