前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux笔记(14)| 字符设备驱动基础入门(续)

Linux笔记(14)| 字符设备驱动基础入门(续)

作者头像
飞哥
发布2020-08-28 10:38:08
1.6K0
发布2020-08-28 10:38:08
举报

3、Makefile的编写

前面讲完了最简单的驱动模块的代码结构,这里继续讲解Makefile文件的编写。

代码语言:javascript
复制
KERNEL_DIR=/home/jianfei/workdir/linux_driver/ebf-buster-linux/build_image/build

ARCH=arm
CROSS_COMPILE=arm-linux-gnueabihf-
export  ARCH  CROSS_COMPILE

obj-m := led_driver.o
app_obj=led
all:
  $(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) modules
  arm-linux-gnueabihf-gcc led.c -o $(app_obj)
.PHONE:clean copy

clean:
  $(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) clean  
  sudo rm /home/jianfei/workdir/*.ko 
  sudo rm /home/jianfei/workdir/$(app_obj)
copy:
  sudo  cp  *.ko $(app_obj)  /home/jianfei/workdir
  

(1)KERNEL_DIR,变量的值就是我们用来编译这个模块的内核源码树的目录

(2)obj-m := led_driver.o,这一行就表示我们要将led_driver.c文件编译成一个模块

(3)make clean ,用来清除编译痕迹

总结:模块的makefile非常简单,本身并不能完成模块的编译,而是通过make -C进入到内核源码树下借用内核源码的体系来完成模块的编译链接的。这个Makefile本身是非常模式化的。

要注意第一个路径必须是自己编译的内核源码树,另外要注意编译工具链的选择,如果是在主机Ubuntu中编译,要使用交叉编译工具链。

编译好了之后就会生成一个.ko的驱动模块文件,我们就可以在linux系统中去安装这个模块,这在上一节已经提到过。

4、验证驱动程序工作是否正常

安装好这个模块之后,如何验证这个驱动模块能否正常工作呢?

在之前的驱动代码中,我们的代码逻辑就是当写入“on”的时候,点亮led灯,当写入“off”的时候,就关闭led灯。那么,到底是向哪里写入?这里涉及到设备文件的创建。之前说过,每个设备都可以抽象成一个设备文件,那么首先要创建这个设备文件,然后将这个设备文件和设备绑定起来,绑定的方法就是依据设备的设备号。我们可以使用mknod命令来创建设备文件。

代码语言:javascript
复制
mknod /dev/xxx c 主设备号 次设备号

设备文件的关键信息是:设备号 = 主设备号 + 次设备号,使用ls -l去查看设备文件,就可以得到这个设备文件对应的主次设备号。

在这个试验中,要验证驱动程序是否正常,应该向设备文件中写入值,方法有两种,一种是直接在终端里面通过echo指令,这样比较简单,还有一种方法就是编写一个应用程序,这种方法在实际中比较常用。

第一种方法很简单,就是

代码语言:javascript
复制
sudo sh -c "echo on >/dev/led c 244 0"

on是要写入的内容,/dev/led是设备文件,c代表字符设备,后面两个是主设备号和次设备号,这个是通过前面的mknod指定的。

这里主要讲一下应用程序的编写。其实也很容易,就是利用了之前的系统编程的知识,无非就是open、write这些。

代码语言:javascript
复制
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define filename "/dev/led"

char  rbuf[10]={0};
int main(void)
{
    int fd;
    int ret;
    fd=open(filename,O_RDWR);
    if(fd<0)
    {
        perror("open");
        return -1;
    }

   while (1)
   {
       printf("please input on or off to control the led,and q for exit\n");
        memset(rbuf,0,sizeof(rbuf));
        scanf("%s",rbuf);
        if(   (!strcmp(rbuf,"on"))  ||  (!strcmp(rbuf,"off"))     )
        {
            write(fd,rbuf,strlen(rbuf));
        }
        else if(!strcmp(rbuf,"q"))
        {
            return 0;
        }
        else
        {
            printf("error!   please input again");
        }
        
   }
   close(fd);
   return 0;
}

我们把编译好的程序放到开发板上执行,就可以在命令行里控制led灯的亮灭了。

当然,如果再要完整一点,应该还要包括类似GUI的设计,因为用户不可能去操作命令行。不过这里暂时不涉及。

好了,以上就是字符设备驱动开发的大致流程,后面将会逐步完善代码,包括建立一些框架什么的。总的来说,驱动部分应该只实现最基本的驱动硬件功能,而应用层部分就要完成用户的各种需求。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-08-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 电子技术研习社 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档