1驱动中分配内存kmalloc
分配连续的虚拟地址,用于小内存分配。在include/linux/slab.h
2cdev操作 cdev_init cdev_add cdev_del
字符设备初始化函数cdev_init
– 在头文件include/linux/cdev.h中
– 参数1:cdev字符设备文件结构体
– 参数2:file_operations结构体
– 注册设备本质是向linux设备文件中添加数据,这些数据需要初始化
• 字符设备注册函数cdev_add
– 在头文件include/linux/cdev.h中
– 参数1:cdev字符设备文件结构体
– 参数2:设备号
– 参数3:设备范围大小
– 向系统注册设备,也就是向linux系统添加数据
注册字符类设备
• 卸载设备函数cdev_del
– 参数1:cdev结构体
– 移除字符设备
3创建设备节点
函数class_create创建class类文件
– 参数1:一般是THIS_MODULE
– 参数2:设备名称
– 创建一个设备类,用于设备节点文件的创建
– 返回一个class结构体变量
• class结构体变量
– class是设备驱动模型中通用的设备类结构
– 在头文件include/linux/device.h的280行
创建设备节点函数device_create
– 头文件include/linux/device.h中
– 参数1:设备所属于的类
– 参数2:设备的父设备,NULL
– 参数3:设备号
– 参数4:设备数据,NULL
– 参数4:设备名称
• 摧毁设备节点函数device_destroy
– 参数1:设备所属于的类
– 参数2:设备号
4根据需要实现接口
file_operations中的函数比较多,选取用的比较多的函数简单介绍,后
面的驱动教程中调用了对应的函数,再详细介绍
• int (*open) (struct inode *, struct file )
– 打开函数
• int (release) (struct inode *, struct file )
– 释放close函数
• long (unlocked_ioctl) (struct file , unsigned int, unsigned long)
– io控制函数
www.topeetboard.com
完成字符驱动
• ssize_t (read) (struct file *, char __user *, size_t, loff_t )
– 读函数
• ssize_t (write) (struct file *, const char __user *, size_t, loff_t )
– 写函数
• loff_t (llseek) (struct file *, loff_t, int)
– 定位函数
• 如果需要不同的设备节点有不同的功能,只需要在注册设备的时候添
加不同的file_operations结构体即可
5实现代码
#include <linux/init.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/device.h>
/*Linux中申请GPIO的头文件*/
#include <linux/gpio.h>
/*三星平台的GPIO配置函数头文件*/
/*三星平台EXYNOS系列平台,GPIO配置参数宏定义头文件*/
#include <plat/gpio-cfg.h>
/*三星平台4412平台,GPIO宏定义头文件*/
#include <mach/gpio-exynos4.h>
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("kerwin");
#define DEVICE_NAME "led_driver"
#define CLASS_NAME "led_driver_C"
#define LED EXYNOS4_GPL2(0)
unsigned int maj=0,min=0;
dev_t dev_num;
int leds_open(struct inode *inode,struct file *filp)
{
return 0;
}
int leds_release(struct inode *inode,struct file *filp)
{
return 0;
}
long leds_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
{
gpio_set_value(LED, cmd ? 1:0);
return 0;
}
static struct file_operations led_ops = {
.owner = THIS_MODULE,
.open = leds_open,
.release= leds_release,
.unlocked_ioctl = leds_ioctl,
};
struct cdev led_cdev;
struct class *m_class;
int led_init(void)
{
int ret;
printk(KERN_EMERG"module_init call \n");
if(alloc_chrdev_region(&dev_num, 0,1,DEVICE_NAME)<0)
{
printk(KERN_EMERG"alloc_chrdev_region err \n");
}else
{
maj=MAJOR(dev_num);
min=MINOR(dev_num);
printk(KERN_EMERG"alloc_chrdev_region success %d %d \n",maj,min);
}
cdev_init(&led_cdev,&led_ops);
if(cdev_add(&led_cdev, MKDEV(maj,min), 1)<0)
{
printk(KERN_EMERG"add cdev err\n");
cdev_del(&led_cdev);
}else
{
printk(KERN_EMERG"add cdev success\n");
}
m_class=class_create(THIS_MODULE,CLASS_NAME);
if(device_create(m_class, NULL, dev_num,NULL, DEVICE_NAME)<0)
{
printk(KERN_EMERG"device_create err\n");
}else
{
printk(KERN_EMERG"device_create success\n");
ret = gpio_request(LED, "LED");
if(ret<0)
{
printk(KERN_EMERG"gpio_request err\n");
}else
{
printk(KERN_EMERG"gpio_request success\n");
}
s3c_gpio_cfgpin(LED, S3C_GPIO_OUTPUT);
}
return 0;
}
void led_exit(void)
{
printk(KERN_EMERG"module_exit call \n");
cdev_del(&led_cdev);
unregister_chrdev_region(dev_num, 1);
}
module_init(led_init);
module_exit(led_exit);
应用程序代码
#include "stdio.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>//定义了open函数
#include <unistd.h>//定义了close函数
#include <sys/ioctl.h>//定义了ioctl函数
#include <time.h>//
#include <sys/time.h>//
void delay_ms(int ms)
{
usleep(ms*1000);
}
#define LED_ON() ioctl(fd,0,1)
#define LED_OFF() ioctl(fd,1,0)
void fun_flash(int on_ms,int fd)//0--50
{
if(on_ms)
{
LED_ON();
delay_ms(on_ms);
}
if(50-on_ms)
{
LED_OFF();
delay_ms(51-on_ms);
}
}
void ledfun (int fd)//主函数
{
#define NN 3
int i=0,j;
for(i=0;i<51;i++)
{
for(j=0;j<NN;j++)
fun_flash(i,fd);
}
delay_ms(500);
for(i=51;i>0;i--)
{
for(j=0;j<NN;j++)
fun_flash(i,fd);
}
delay_ms(500);
}
int main()
{
char *device="/dev/led_driver";
long sleep_time=0;
int ind=0;
int times=0;
int fd = open(device,O_RDWR|O_NDELAY);
if(fd<0)
{
printf("open file %s err \n",device);
}else
{
printf("open file %s seuccess \n",device);
while(1)
{
ledfun(fd);
printf("flash times %d \n",times++);
}
}
close(fd);
}