七、linux2.6驱动开发

一、linux2.6与杂项驱动的不同

  • linux2.6不会生成设备文件,需要用到其他的接口或者指令生成
  • 需要申请设备号

二、使用的函数

1.申请设备号

  •  功能:让内核分配一个或者多个可以用的设备号
  • 头文件:<linux/fs.h>
  • 原型:int alloc_chrdev_region(
    dev_t * devnum,     //向内核申请的设备号
    unsigned base,      //自己申请的次设备号
    unsigned count,     //连续申请几个
    const char * lable  //标签名字
    );

2.结构体初始化函数

  •  功能:初始化Linux2.6的核心结构体
  • 头文件:<linux/cdev.h>
  • 原型:void cdev_init(struct cdev * cdev , const struct file_operations * fops);// 核心结构体 内核操作集合

3.内核的注册添加

  •  功能:向内核添加一个已经完成初始化工作的 cdev 核心结构体
  • 头文件:<linux/cdev.h>
  • 原型:int cdev_add(struct cdev * cdev, dev_t devnum,unsigned count);

4.创造一个设备文件

  •  功能:创造一个设备文件
  • 头文件:<linux/device.h>
  • 原型:struct device *device_create(
    struct class *cls,
    struct device *parent,
    dev_t devt,
    void *drvdata,
    const char *fmt, ...
    );

实现使用Linux2.6驱动蜂鸣器

设备代码

#include "linux/kernel.h"
#include "linux/module.h"
#include "linux/miscdevice.h"
#include "linux/fs.h"
#include "linux/gpio.h"
#include "linux/cdev.h"

dev_t my_dev;
struct cdev mycdev;
struct file_operations my_oper;
struct class *my_class;

//功能函数
int mybeep_open(struct inode *i, struct file *f)
{
    gpio_set_value(36,1);
    return 0;
}

int mybeep_close(struct inode *i, struct file *f)
{
    gpio_set_value(36,0);
    return 0;
}

//加載函數
static int __init mybeep_init(void)
{
    //初始化GPIO
    gpio_request(36,"beep");
    gpio_direction_output(36,0);

    //申请设备号
    alloc_chrdev_region(&my_dev,18,1,"mybeepdevice");
    printk("申请的设备号是%d\r\n",my_dev);
    printk("主设备号为:%d\r\n",my_dev>>20);
    printk("次设备号为:%d\r\n",my_dev & 0xFFFFF);

    //初始化Linux2.6核心结构体
    my_oper.owner = THIS_MODULE;
    my_oper.open = mybeep_open;
    my_oper.release = mybeep_close;
    cdev_init(&mycdev,&my_oper);

    //向内核添加设备
    cdev_add(&mycdev,my_dev,1);
    //需要用函数添加设备文件
    //生成一个类结构体
    my_class = class_create(THIS_MODULE,"MY_beep");
    //生成设备文件
    device_create(my_class,NULL,my_dev,NULL,"MY_beep");
    return 0;    
}

static void __exit mybeep_exit(void) 
{
    device_destroy(my_class,my_dev);
    class_destroy(my_class);
    cdev_del(&mycdev);
    unregister_chrdev_region(my_dev,1);
}

module_init(mybeep_init);
module_exit(mybeep_exit);
MODULE_LICENSE("GPL");


主函数代码

#include "stdio.h"
#include "unistd.h"
#include "fcntl.h"
#include "sys/types.h"
#include <sys/stat.h>

int main()
{
    int fd = 0;
    while (1)
    {
        /* code */
        fd = open("/dev/MY_beep", O_RDWR);
        sleep(1);
        close(fd);
        sleep(1);
    }
    return 0;
    
}   

出现的问题

错误原因一:89编译模式下 变量的声明要放到函数体内的上面,也可以在kernel修改Makefile中的-std=gnu89改为-std=gnu99 注释掉KBUILD_CFLAGS += -Wdeclaration-after-statement

错误原因二:编写mybeep_exit函数的时候多打了一个{

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值