AT91SAM9X25字符驱动实例
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
AT91SAM9X25字符驱动实例
概述
Linux下的字符驱动写法有固定的模式,不同的芯片有略微的差别,可以参照之前在TiAM1808的实验板上完成的字符驱动写法,本实例是以Led闪烁为例来实现简单的字符驱动过程。
从CM板的原理图中(CM_EMBEST_RevB)可以看到:CM板上有一蓝一红两个LED,因为蓝灯还起到别的指示作用,我们就以红色led为实验对象,其控制管脚为CPU的PD21,将其置低电平时led为亮。
经过之前对内核打上atmel的补丁以后,内核的相应文件会增加芯片的管脚定义以及操作函数实现,相对TI的驱动简单一点。
驱动代码led.c
#include
#include
#include
#include
#include
#include
#include
#include
#define MY_LED_MAJOR 203 //定义主设备号
#define MY_LED_MINOR 0 //定义从设备号
#define LED_ON 0
#define LED_OFF 1
#define PIN AT91_PIN_PD21 //PD21为要Led的pin
#define DEVICE_NAME "my_led" //设备名
struct global_dev{
struct cdev cdev;
}; //定义设备结构体
struct global_dev *global_devp; //定义一个指向设备结构体的指针
static int my_led_open(struct inode *inode, struct file *filp) {
filp->private_data = global_devp;
printk("AT91-LED Driver Open Called!\n");
return 0;
}
static int my_led_release(struct inode *inode, struct file *file) {
printk("AT91-LED Driver Release Called!\n");
return 0;
}
static int my_led_ioctl(struct file *filp, unsigned int cmd)
{
switch(cmd)
{
case LED_ON:
at91_set_gpio_value(PIN, 0); //pin on
break;
case LED_OFF:
at91_set_gpio_value(PIN, 1); //pin off
break;
default:
printk("no valid cmd input!\n");
break;
}
return 0;
}
/*初始化设备结构体*/
struct file_operations my_led_ctl_ops ={
.owner = THIS_MODULE,
.open = my_led_open,
.release = my_led_release,
.unlocked_ioctl = my_led_ioctl,
};
static int my_led_init(void)
{
int result;
dev_t devno = MKDEV(MY_LED_MAJOR, MY_LED_MINOR);//通过主次设备号得到设备号at91_set_GPIO_periph(PIN, 1);
at91_set_gpio_output(PIN, 1); //对Pin引脚的初始化
result = register_chrdev_region(devno, 1, DEVICE_NAME);//注册静态设备号,与设备名相关联
if(result < 0)
printk(KERN_ERR "can't get device number \n");
else
printk("get device number\n");
global_devp = kmalloc(sizeof(struct global_dev), GFP_KERNEL); //申请设备内存
memset(global_devp, 0, sizeof(struct global_dev));
cdev_init(&global_devp->cdev, &my_led_ctl_ops); //初始化cdev,与fop相关联
global_devp->cdev.owner = THIS_MODULE;
global_devp->cdev.ops = &my_led_ctl_ops;
result = cdev_add(&global_devp->cdev, devno, 1); //注册设备,设备号与设备结构体相关联
if (result < 0)
printk(KERN_ERR "can't add led device");
return 0;
}
static void my_led_cleanup(void)
{