新字符设备驱动框架代码搭建

一.  简介

前面一篇文章简单了解了,新字符设备驱动框架涉及的函数。文章地址如下:

新字符设备驱动所涉及的函数-CSDN博客

本文来使用 新字符设备驱动框架来实现字符设备的注册与卸载。

二.  新的字符设备驱动框架搭建

1.  创建工程

首先,创建文件夹。这里我的驱动代码都放在 ubuntu系统 /home/wangtian/zhengdian_Linux目录下,进入 /Linux_Drivers 目录下,创建文件夹为  3_newchrled:

wangtian@wangtian-virtual-machine:~/zhengdian_Linux/Linux_Drivers$ mkdir 3_newchrled

将 2_led工程下的 .vscode及其以下文件,拷贝到 3_newchrled 文件夹下(.vscode及其以下文件中配置了 所调用的 Linux内核源码路径):

wangtian@wangtian-virtual-machine:~/zhengdian_Linux/Linux_Drivers/3_newchrled$ cp ../2_led/.vscode/ ./ -rf

将 2_led工程下的 Makefile文件拷贝到 该工程下:

wangtian@wangtian-virtual-machine:~/zhengdian_Linux/Linux_Drivers/3_newchrled$ cp ../2_led/Makefile ./

更改 Makefile文件中涉及编译目标名 obj-m的所指向的名:

obj-m := newchrled.o

通过 vscode打开 3_newchrled 文件夹。在 3_newchrled文件夹下创建 newchrled.c 文件。

可以参考 2_led实验的代码,在 newchrled.c加入 头文件, 寄存器的物理地址,映射后的虚拟地址指针,以及 led的开关灯宏:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>

//寄存器的物理地址
#define  CCM_CCGR1_BASE          (0X020C406C)
#define  SW_MUX_GPIO1_IO03_BASE  (0X020E0068)
#define  SW_PAD_GPIO1_IO03_BASE  (0X020E02F4)
#define  GPIO1_GDIR_BASE         (0X0209C004)
#define  GPIO1_DR_BASE           (0X0209C000)

//地址映射后寄存器的虚拟地址指针
static void __iomem *  IMX6ULL_CCM_CCGR1;
static void __iomem *  IMX6ULL_SW_MUX_GPIO1_IO03;
static void __iomem *  IMX6ULL_SW_PAD_GPIO01_IO03;
static void __iomem *  IMX6ULL_GDIR;
static void __iomem *  IMX6ULL_DR;

#define  LED_OFF      0 //关闭Led灯
#define  LED_ON       1  //打开Led灯

2.  新的字符设备驱动框架搭建

可以参考 Linux内核源码(即 NXP官方提供的)中,新字符设备驱动框架代码,来编写 这里的设备驱动代码。

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/cdev.h>

//寄存器的物理地址
#define  CCM_CCGR1_BASE          (0X020C406C)
#define  SW_MUX_GPIO1_IO03_BASE  (0X020E0068)
#define  SW_PAD_GPIO1_IO03_BASE  (0X020E02F4)
#define  GPIO1_GDIR_BASE         (0X0209C004)
#define  GPIO1_DR_BASE           (0X0209C000)

#if  0
//地址映射后寄存器的虚拟地址指针
static void __iomem *  IMX6ULL_CCM_CCGR1;
static void __iomem *  IMX6ULL_SW_MUX_GPIO1_IO03;
static void __iomem *  IMX6ULL_SW_PAD_GPIO01_IO03;
static void __iomem *  IMX6ULL_GDIR;
static void __iomem *  IMX6ULL_DR;
#endif 

#define  NEWCHRLED    "newchrled" //设备名
#define  NEWCHRLED_COUNT     1    //设备个数
#define  LED_OFF      0 //关闭Led灯
#define  LED_ON       1  //打开Led灯

//Led设备结构体
struct newchrled_dev{
    struct cdev led_cdev; 
    dev_t dev_id;  //设备号
    int major;     //主设备号
    int minor;     //次设备号 

};

//字符设备的函数集
const struct file_operations fops = {  
    .owner = THIS_MODULE,

};

struct newchrled_dev newchr_led;

/*驱动模块入口函数 */
static int __init newchrled_init(void)
{
    int ret = 0;
    printk("newchrled_init!\r\n");
    newchr_led.major = 0;
    /* 注销字符设备 */
    //设备号的分配
    if(newchr_led.major) //给定主设备号
    {
        newchr_led.dev_id = MKDEV(newchr_led.major, 0);
        ret = register_chrdev_region(newchr_led.dev_id, NEWCHRLED_COUNT, NEWCHRLED);
    }
    else{ //没有给定主设备号
        ret = alloc_chrdev_region(&(newchr_led.dev_id), 0, NEWCHRLED_COUNT, NEWCHRLED);	
        newchr_led.major = MAJOR(newchr_led.dev_id);
        newchr_led.minor = MINOR(newchr_led.dev_id);
    }
	if (ret < 0) {
		printk("register-chrdev failed!\n");
		return -1;
	}
    //初始化设备
    newchr_led.led_cdev.owner = THIS_MODULE;
    cdev_init(&newchr_led.led_cdev, &fops);
    
    //注册设备
    cdev_add(&newchr_led.led_cdev, newchr_led.dev_id, NEWCHRLED_COUNT);

    return 0;
}

/*驱动模块出口函数 */
static void __exit newchrled_exit(void)
{
    printk("newchrled_eixt!\r\n");
    /* 注销字符设备 */
    //删除设备
    cdev_del(&newchr_led.led_cdev);
    //注销设备号
    unregister_chrdev_region(newchr_led.dev_id, NEWCHRLED_COUNT);
}

/* 注册与卸载驱动设备 */
module_init(newchrled_init);
module_exit(newchrled_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("LingXueWu");

新的字符设备驱动框架代码已经编写好。

编译驱动代码,可以正常编译生成 驱动文件 newchr_led.ko。下一篇加入 Led灯的函数操作集。

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值