驱动程序的演变

最简单的驱动程序

一、驱动的硬件操作函数

  • copy_to_user():完成内核空间到用户空间的复制
  • 第一个参数 to:目标用户空间的地址

    第二个参数 from: 源内核空间地址。保存了要拷贝到用户空间的内容的地址

    第三个参数 n:要拷贝的字节数

  • copy_from_user 完成用户空间到内核空间的复制

  • 第一个参数 to:目标内核空间的地址

    第二个参数 from: 源用户空间地址。保存了用户要发送的数据,或者要拷贝到内核空间的内容的地址

    第三个参数 n:要拷贝的字节数

    返回值:成功返回 0

static char readbuf[100]; /* 读缓冲区 */
 
/*
 * 该函数一般用于内核中的 read 函数的定义中,将内核接收到的内容拷贝到用户缓冲区
 */
static ssize_t xxx_read(struct file *filp, char __user *buf,
                        size_t cnt, loff_t *offt)
{
    int ret = copy_to_user(buf, readbuf, cnt);     // 将readbuf中的内容拷贝到buf
                                                   // 拷贝的字节数大小为cnt
    if(ret == 0)
    {
        printk("kernel send data ok!\n");
    }
    else
    {
        printk("kernel send data failed!\n");    
    }
 
    return 0;
}



static char writebuf[100];
 
/*
 * 该函数一般用于内核中的 write 函数的定义中,将用户要发送的内容拷贝到内核缓冲区
 */
static ssize_t xxx_write(struct file *pfile, const char __user *buf, 
                        size_t cnt, loff_t *offset)
{
    /* 用户实现具体功能 */
	int ret = copy_from_user(writebuf, buf, cnt);    // 将buf中的内容拷贝到writebuf
	if(ret == 0)
	{
		printk("kernel read data ok!\n");
	}
	else
	{
		printk("kernel read data failed!\n");
	}
 
    return 0;
}

二、file_operation结构体管理硬件操作函数

三、入口函数,

1、注册file_opeation到内核数组中去

设备号分成主设备号与从设备号,主设备号相同的注册到一条链表上,共有一个驱动程序。

从设备号就是表示多个相同设备

2、将物理地址转换虚拟地址

3、设备节点自动创建函数

四、出口函数

1、撤销地址转换

2、销毁设备节点

代码分析:

分层思想

一、leddrv.c

   硬件操作函数以及它的上司file_operation结构体

  入口函数,

      1、注册file_opeation到内核数组中去

      2、设备节点自动创建函数

  出口函数

      1、销毁设备节点

二、LED资源分配

led_resource

1、定义引脚选择结构体

2、创建一个函数获得引脚选择结构体的指针

board_A_led.c

1、创建引脚选择结构体的实例,并且赋值

2、完善引脚结构体指针函数,返回指向实例的指针

三、LED硬件相关操作

led_opr.h

定义led操作结构体、定义一个函数获得led操作结构体的指针

chip_demo_gpio

1、创建led控制结构体的实例并且立于函数赋值,

2、创建led控制函数、led初始化函数

3、完善函数,获得led控制函数结构体的指针

总线设计思想

一、公共部分

leddrv.h 

定义三个函数封装了底层的设备节点创建、设备节点销毁、注册led_operations结构体(就是换一个指针指向led_operation结构体

设备节点的创建是我们自己创建,因为有多个,后面自己会调用

#ifndef _LEDDRV_H
#define _LEDDRV_H

#include "led_opr.h"

void led_class_create_device(int minor);
void led_class_destroy_device(int minor);
void register_led_operations(struct led_operations *opr);

#endif /* _LEDDRV_H */

leddrv.c

完善设备节点创建、设备节点销毁、注册led_operation封装函数

构建file_operation结构体,并且将对应函数进行赋值

入口函数

注册file_operations,

出口函数

撤销注册的file_operations结构体

撤销设备节点的前置

二、LED资源分配

注册platform_device 函数

       创建驱动资源结构体platform_device结构体

                   创建资源分配结构体数组

三、LED硬件相关操作

chip_demo_gpio

入口函数

1、注册硬件驱动结构体

       匹配成功函数

                       probe记录引脚信息

                      创建设备节点

       匹配失败 

              销毁设备节点

2、注册硬件操作结构体

      led引脚初始化

      控制led引脚

设备树

将led资源分配写成设备树的形式简化了代码

Printctrl 子系统和GPIO子系统

将对硬件的具体操作完全封装了,我们只需要调用指定的函数就可以完成

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值