linux驱动程序设计实例
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
AT91SAM9G20驱动程序设计
开发环境:Vmware + ubuntu10.04
硬件平台:AT91SAM9G20
Linux版本:linux2.6.27
一:led驱动
说明:因为设计的开发板上没有led灯,便通过PC0来演示,通过示波器来观察引脚端的电平变化。
1.驱动程序:my_led.c
#include
#include
#include
#include
#include
#include
#include
#define MY_LED_MAJOR 250 //定义主设备号
#define LED_ON 0
#define LED_OFF 1
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;
return 0;
}
static int my_led_release(struct inode *inode, struct file *file)
{
return 0;
}
static int my_led_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data) {
switch(cmd)
{
case LED_ON:
at91_set_gpio_value(A T91_PIN_PC0, 0); //将PC0引脚置低
break;
case LED_OFF:
at91_set_gpio_value(A T91_PIN_PC0, 1); //将PC1引脚置高
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,
.ioctl = my_led_ioctl,
};
/*初始化设备结构体*/
static void my_led_setup(struct global_dev *dev, int index)
{
int err;
int devno = MKDEV(MY_LED_MAJOR, index);
cdev_init(&dev->cdev, &my_led_ctl_ops);
dev->cdev.owner = THIS_MODULE;
dev->cdev.ops = &my_led_ctl_ops;
err = cdev_add(&dev->cdev, devno, 1);
if(err)
printk("add my led setup failed!\n");
}
static int my_led_init(void)
{
int ret;
dev_t devno = MKDEV(MY_LED_MAJOR, 0); //创建设备号
printk("my first driver--led!\n");
at91_set_GPIO_periph(A T91_PIN_PC0, 1);
at91_set_gpio_output(A T91_PIN_PC0, 1); //对PC0引脚的初始化
ret = register_chrdev_region(devno, 1, "my_led"); //申请设备号
if( ret < 0) {
printk("my_led init_module failed with %d\n", ret);
return ret;
}
else
printk("my_led init_module success!\n");
global_devp = kmalloc(sizeof(struct global_dev), GFP_KERNEL); //申请设备内存memset(global_devp, 0, sizeof(struct global_dev));
my_led_setup(global_devp, 0);
return ret;
}
static void my_led_cleanup(void)
{
cdev_del(&global_devp->cdev); //删除设备
kfree(global_devp); //释放内存
unregister_chrdev_region(MKDEV(MY_LED_MAJOR, 0), 1); //释放设备号
}
MODULE_LICENSE("MYGPL");
MODULE_AUTHOR("FANY");
module_init(my_led_init); //注册设备
module_exit(my_led_cleanup); //卸载设备