ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

驱动认知及代码框架的编写及运行(学习笔记)

2021-07-27 18:03:02  阅读:124  来源: 互联网

标签:obj open 认知 笔记 编写 include CONFIG class pin4


一、驱动认知:参考链接https://blog.csdn.net/weixin_41679960/article/details/116209261
用户态
App:cp指令,ftp的项目等等这就是App的开发。
App开发需要C的基础和C库,C库讲到文件,进程,进程间通信,线程,网络,界面(GTk)。
C库(是linux标准库一定有):就是Clibary,提供了APP支配内核干活的接口,调用的open,read,write,fork,pthread,socket由此处封装实现,由写的应用程序调用,C库中的各种API调用的是内核态,支配内核干活

内核态
进程,内存,线程,网络,设备驱动不需要上层应用开发者关心,驱动在前面的学习是调用wringpi库实现,接下来的学习就是要自己实现wringpi库,因为wringpi库由厂家提供,可能有可能没有,这样当我们拿到另一种类型的板子时,同样也可以完成开发。

驱动链表:管理所有设备的驱动,添加或查找,添加是发生在我们编写完驱动程序,加载到内核。查找发生在调用驱动程序,由应用层用户空间去open。

驱动插入链表的顺序由设备号检索,就是说主设备号和次设备号除了除了能区分不同种类的设备和不同类型的设备,还能起到将驱动程序创到链表的某个位置。

硬件
linux经典的一句话一切皆文件:包括文件,设备(鼠标,键盘,LED,屏幕,flash,内存,网卡等),普通的IO口,串口等等。

ls -l  查看设备号

驱动代码的开发无非就是添加驱动和调用驱动。
–>用户态调用引脚四open(“/de/pin4”,O_RDWR)
–>调用System call interface(这个函数是在内核中的)
–>这个函数会根据设备名找到设备号
–>调用VFS中的sys_open
–>sys_open会找到引脚4中的open函数
–>引脚4中的open函数是对寄存器的操作(实操)
–>用户态进入内核态会发生一次软中断 ,中断号是0x80。

在这里插入图片描述
二、代码框架编写即编译

要进入到源码树目录底下进行编译

cd ~/SYSTEM/linux-rpi-4.14.y/drivers/char

驱动代码:pin4driver2.c

#include <linux/fs.h>		 //file_operations声明
#include <linux/module.h>    //module_init  module_exit声明
#include <linux/init.h>      //__init  __exit 宏定义声明
#include <linux/device.h>	 //class  devise声明
#include <linux/uaccess.h>   //copy_from_user 的头文件
#include <linux/types.h>     //设备号  dev_t 类型声明
#include <asm/io.h>          //ioremap iounmap的头文件


static struct class *pin4_class;  
static struct device *pin4_class_dev;

static dev_t devno;                //设备号
static int major =231;  		   //主设备号
static int minor =0;			   //次设备号
static char *module_name="pin4";   //模块名




//led_open函数
static int pin4_open(struct inode *inode,struct file *file)
{
    printk("pin4_open\n");  //内核的打印函数和printf类似
   

    
    return 0;
}

//led_write函数
static ssize_t pin4_write(struct file *file,const char __user *buf,size_t count, loff_t *ppos)
{


    return 0;
}

static struct file_operations pin4_fops = {

    .owner = THIS_MODULE,
    .open  = pin4_open,
    .write = pin4_write,
};

int __init pin4_drv_init(void)   
{

    int ret;
    devno = MKDEV(major,minor);  //创建设备号
    ret   = register_chrdev(major, module_name,&pin4_fops);  //注册驱动  告诉内核,把这个驱动加入到内核驱动的链表中

    pin4_class=class_create(THIS_MODULE,"myfirstdemo");
    pin4_class_dev =device_create(pin4_class,NULL,devno,NULL,module_name);  //创建设备文件

 
    return 0;
}

void __exit pin4_drv_exit(void)
{

    device_destroy(pin4_class,devno);
    class_destroy(pin4_class);
    unregister_chrdev(major, module_name);  //卸载驱动

}

module_init(pin4_drv_init);  //入口
module_exit(pin4_drv_exit);
MODULE_LICENSE("GPL v2");

上层调用代码pin4test.c

#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
int main()
{
        int fd;
        char buf[128] = {0};

        fd = open("/dev/pin4",O_RDWR);
        if(fd < 0){

                printf("open failed\n");
                perror("reason");

        }else{

                printf("open success\n");
        }

        fd = write(fd,buf,1);

        return 0;
}

要让工程能编译到pin4driver2.c 要对Makefile进行修改

vi Makefile

在第二行加入

obj-m                           += pin4driver2.o
# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the kernel character device drivers.
#

obj-y                           += mem.o random.o
obj-m                           += pin4driver2.o		//编译成模块的方式(这句话自己添加)			
obj-$(CONFIG_TTY_PRINTK)        += ttyprintk.o
obj-y                           += misc.o
obj-$(CONFIG_ATARI_DSP56K)      += dsp56k.o
obj-$(CONFIG_VIRTIO_CONSOLE)    += virtio_console.o
obj-$(CONFIG_RAW_DRIVER)        += raw.o
obj-$(CONFIG_SGI_SNSC)          += snsc.o snsc_event.o
obj-$(CONFIG_MSPEC)             += mspec.o
obj-$(CONFIG_UV_MMTIMER)        += uv_mmtimer.o
obj-$(CONFIG_IBM_BSR)           += bsr.o
obj-$(CONFIG_SGI_MBCS)          += mbcs.o
obj-$(CONFIG_BFIN_OTP)          += bfin-otp.o

obj-$(CONFIG_PRINTER)           += lp.o

obj-$(CONFIG_APM_EMULATION)     += apm-emulation.o

obj-$(CONFIG_DTLK)              += dtlk.o
obj-$(CONFIG_APPLICOM)          += applicom.o
obj-$(CONFIG_SONYPI)            += sonypi.o
obj-$(CONFIG_RTC)               += rtc.o
obj-$(CONFIG_HPET)              += hpet.o
obj-$(CONFIG_EFI_RTC)           += efirtc.o
obj-$(CONFIG_DS1302)            += ds1302.o
obj-$(CONFIG_XILINX_HWICAP)     += xilinx_hwicap/
ifeq ($(CONFIG_GENERIC_NVRAM),y)
  obj-$(CONFIG_NVRAM)   += generic_nvram.o
else
  obj-$(CONFIG_NVRAM)   += nvram.o
endif
obj-$(CONFIG_TOSHIBA)           += toshiba.o

回到模块源码进行内核编译

cd ~/SYSTEM/linux-rpi-4.14.y

输入一下代码进行编译

ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make modules

成功后会生成 .ko文件

CHK     include/config/kernel.release
  CHK     include/generated/uapi/linux/version.h
  CHK     include/generated/utsrelease.h
  CHK     include/generated/bounds.h
  CHK     include/generated/timeconst.h
  CHK     include/generated/asm-offsets.h
  CALL    scripts/checksyscalls.sh
  CHK     scripts/mod/devicetable-offsets.h
  CHK     kernel/config_data.h
  CC [M]  drivers/char/pin4driver2.o
  Building modules, stage 2.
  MODPOST 1523 modules
  CC      drivers/char/pin4driver2.mod.o
  LD [M]  drivers/char/pin4driver2.ko

在对pin4test.c进行编译

arm-linux-gnueabihf-gcc -o pin4test

拷贝到树莓派上面进行测试

scp drivers/char/pin4driver2.ko pi@192.168.0.105:/home/pi
scp drivers/char/pin4test pi@192.168.0.105:/home/pi

在树莓派上面首先加载内核驱动

sudo insmod pin4driver2.ko

查看是否生成/dev/pin4的驱动

ls /dev/pin4

接着修改pin4test的权限为:

sudo chmod 666 /dev/pin4

运行./pin4test发现看不到现象
原因:看到的界面是在上层,要在内核态才能查看到数据
解决方法:运行指令

dmesg

会在最后一行看到添加成功
pin4_open

标签:obj,open,认知,笔记,编写,include,CONFIG,class,pin4
来源: https://blog.csdn.net/weixin_55286304/article/details/119147060

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有