百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

全志V3S开发板驱动示例(linux demo驱动开发)

csdh11 2024-12-30 03:06 12 浏览

1.前言

本文描述了基于全志V3S开发板的简单驱动程序测试应用程序的设计流程。我们设计的驱动程序和测试程序极其简单,适合初学者上手学习。

软件运行的硬件环境是基于V3S开发板中的全志V3S处理器,该处理器集成了一个1.2GHz工作主频的单ARM CortexTM-A7 核,芯片内部集成了64MB DRAM 存储器。


软件设计是基于
linux3.4内核

2.设计流程概述

设计的步骤依次是:

步骤一:编写一个demo_driver.c的驱动程序。

步骤二:编写makefile文件。

步骤三:编写一个demo_app.c的应用程序。

步骤四:在V3S开发板中安装demo_driver驱动程序,并测试demo_app应用程序。

linux系统是一个分层结构,我们设计的demo_driver位于内核中的驱动部分,demo_app位于用户级。

3.编写驱动程序

编写一个demo_driver.c的驱动程序,驱动程序源码如下:

/**
*********************************************************************************************************
*                                        		demo_driver
*                                      (c) Copyright 2021-2031
*                                         All Rights Reserved
*
* @File    : 
* @By      : liwei
* @Version : V0.01
* 
*********************************************************************************************************
**/

/**********************************************************************************************************
Includes 
**********************************************************************************************************/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>

/**********************************************************************************************************
Define
**********************************************************************************************************/
#define    DRIVER_MAJOR     188
#define    DEVICE_NAME     "demo_driver"


/***********************************************************************************************************
* @描述	:  
***********************************************************************************************************/
static int demo_open(struct inode *inode, struct file *file)
{	
	printk(KERN_EMERG "======================demo_open======================\n");
	return 0;
}
/***********************************************************************************************************
* @描述	:  
***********************************************************************************************************/
static ssize_t demo_write(struct file *file, const char __user * buf, size_t count, loff_t *ppos)
{
    printk(KERN_EMERG "======================demo_write======================\n");
    return 0;
}
/***********************************************************************************************************
* @描述	:  
***********************************************************************************************************/
static ssize_t demo_read(struct file *file,  char __user * buf, size_t count, loff_t *ppos)
{
    printk(KERN_EMERG "======================demo_read ======================\n");  
    return 0;
}
/***********************************************************************************************************
* @描述	:  
***********************************************************************************************************/
static int demo_close(struct inode *inode, struct file *file)
{
    printk(KERN_EMERG "======================demo_close ======================\n");
    return 0;
}

/***********************************************************************************************************
* @描述	:  
***********************************************************************************************************/
static struct file_operations demo_flops = 
{
	.owner  =   THIS_MODULE,
	.open   =   demo_open,     
	.write  =   demo_write,
	.read 	=  	demo_read,
	.release =  demo_close,
};

/***********************************************************************************************************
* @描述	:  
***********************************************************************************************************/
static int __init demo_init(void)
{
    int ret;
 		
	//注册设备
    ret = register_chrdev(DRIVER_MAJOR,DEVICE_NAME, &demo_flops);

    if (ret < 0) 
	{
      printk(KERN_EMERG DEVICE_NAME " can't register major number.\n");
      return ret;
    }
	else
	{
		printk(KERN_EMERG DEVICE_NAME " ======================demo init======================\n");
	}

    return 0;
}
/***********************************************************************************************************
* @描述	:  
***********************************************************************************************************/
static void __exit demo_exit(void)
{
    unregister_chrdev(DRIVER_MAJOR, DEVICE_NAME);
    printk(KERN_EMERG DEVICE_NAME " ======================demoexit======================\n");
}


module_init(demo_init);
module_exit(demo_exit);
MODULE_LICENSE("GPL");
/***********************************************END*******************************************************/

编译驱动程序依赖linux内核源码环境,需要把驱动C文件放在linux源码目录中,通过编译linux内核的方式得到驱动ko文件。


为了得到驱动ko,我们在easyboard/corelinux/v3ssdk/linux-3.4/drivers/char目录下面
创建一个demo_driver的文件夹,并把demo_driver.c程序拷贝到demo_driver的文件夹中。

4.编写makefile

我们通过编译linux内核的方式得到驱动ko文件,为了在编译内核时得到相应的驱动,我们需要在linux-3.4内核代码中增加和修改Makefile文件(Makefile的作用指定了工程编译的方法和步骤)。
首先我们
修改easyboard/corelinux/v3ssdk/linux-3.4/drivers/char目录下Makefile文件,在Makefile文件内容最末行加入一行代码:

obj    += demo_driver/

这句代码的意思是:编译内核时,子目录demo_driver/下的文件也将进行编译。


我们在easyboard/corelinux/v3ssdk/linux-3.4/drivers/char/demo_driver中
创建一个Makefile文件,同时在Makefile文件中加入一行代码:

obj-m		+= demo_driver.o

这句代码的意思是:编译当前目录中的demo_driver.c文件,输出一个demo_driver.ko的驱动文件。


准备好demo_driver.c文件和Makefile文件后,我们
执行编译内核指令

./linux_docker_build.sh

内核编译需要等待10分钟左右。


经过上述一波操作,我们得到了
demo_driver.ko的驱动文件


到目前为止我们的代码设计工作
完成了50% ,如下图所示:

5.编写应用程序

编写一个demo_app.c的应用程序,程序源码如下:

/**
*********************************************************************************************************
*                                        		demo_driver
*                                      (c) Copyright 2021-2031
*                                         All Rights Reserved
*
* @File    : 
* @By      : liwei
* @Version : V0.01
* 
*********************************************************************************************************
**/

/**********************************************************************************************************
Includes 
**********************************************************************************************************/
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h> 
#include <fcntl.h> 
#include <unistd.h>



/***********************************************************************************************************
* @描述	:  
***********************************************************************************************************/
int main(int arvc, char *argv[])
{
	int fd;
	int value = 0;
	printf("==========demo_test==================\n");
	//打开驱动 
	fd = open("/dev/demo_driver",O_RDWR);

	while(1)
	{
		//执行驱动读操作
		read(fd,&value,4);
		sleep(1);
		//执行驱动写操作
		write(fd,&value,4);
		sleep(1);	
		
		printf("==========run==================\n");
	}
	return 0;

}
/***********************************************END*******************************************************/

将应用程序源码放在虚拟机的任意一个目录中如:/home/easyboard/work/demo

然后我们在终端中进入/home/easyboard/work/demo目录,在该目录下执行如下gcc编译指令

arm-buildroot-linux-gnueabihf-gcc -o demo_app demo_app.c

于是我们得到一个demo_app可执行文件


在虚拟机中我们利用交叉编译工具,直接编译即可得到V3S目标板的可执行文件。


到目前为止我们的代码设计工作
完成100%,如下图所示:

6.安装驱动及运行应用程序

经过上述操作,我们得到了demo_driver.ko和demo_app两个文件,我们使用SecureCRTPortable工具将这两个文件传输到V3S开发板中。(传输手段不限,用自己熟悉的方法将文件复制到开发板中即可)


完成文件传输后,我们需要先安装我们编译的驱动ko文件,然后运行测试程序,操作流程如下:

操作一:执行安装驱动指令:

insmod demo_driver.ko 


操作二:执行创建文件节点指令:

mknod /dev/demo_driver c 188 0

188的是设备号,我们在设计的驱动C文件中有如下定义:

/**********************************************************************************************************
Define
**********************************************************************************************************/
#define    DRIVER_MAJOR     188
#define    DEVICE_NAME     "demo_driver"

操作三(可选):执行查看驱动设备指令:

ls /dev

此时我们看到Linux内核中已经包含了我们驱动设备,如下图所示:

操作四:执行修改demo_app文件权限指令:

chmod 777 demo_app

操作五:执行运行demo_app指令:

./demo_app

demo_app运行结果如下:


注意:设备重启后,需要重新加载驱动!

7.总结

编译驱动程序依赖linux内核源码环境,我们设计的驱动文件放需要在linux源码目录中,同时编写Makefile文件,最终通过编译内核的方式得到驱动ko文件。

在虚拟机中使用交叉编译工具,可以编译得到可执行文件。

创作不易希望朋友们点赞,转发,评论,关注。
您的点赞,转发,评论,关注将是我持续更新的动力
作者:李巍
Github:liyinuoman2017
CSDN:liyinuo2017
今日头条:程序猿李巍

相关推荐

探索Java项目中日志系统最佳实践:从入门到精通

探索Java项目中日志系统最佳实践:从入门到精通在现代软件开发中,日志系统如同一位默默无闻却至关重要的管家,它记录了程序运行中的各种事件,为我们排查问题、监控性能和优化系统提供了宝贵的依据。在Java...

用了这么多年的java日志框架,你真的弄懂了吗?

在项目开发过程中,有一个必不可少的环节就是记录日志,相信只要是个程序员都用过,可是咱们自问下,用了这么多年的日志框架,你确定自己真弄懂了日志框架的来龙去脉嘛?下面笔者就详细聊聊java中常用日志框架的...

物理老师教你学Java语言(中篇)(物理专业学编程)

第四章物质的基本结构——类与对象...

一文搞定!Spring Boot3 定时任务操作全攻略

各位互联网大厂的后端开发小伙伴们,在使用SpringBoot3开发项目时,你是否遇到过定时任务实现的难题呢?比如任务调度时间不准确,代码报错却找不到方向,是不是特别头疼?如今,随着互联网业务规模...

你还不懂java的日志系统吗 ?(java的日志类)

一、背景在java的开发中,使用最多也绕不过去的一个话题就是日志,在程序中除了业务代码外,使用最多的就是打印日志。经常听到的这样一句话就是“打个日志调试下”,没错在日常的开发、调试过程中打印日志是常干...

谈谈枚举的新用法--java(java枚举的作用与好处)

问题的由来前段时间改游戏buff功能,干了一件愚蠢的事情,那就是把枚举和运算集合在一起,然后运行一段时间后buff就出现各种问题,我当时懵逼了!事情是这样的,做过游戏的都知道,buff,需要分类型,且...

你还不懂java的日志系统吗(javaw 日志)

一、背景在java的开发中,使用最多也绕不过去的一个话题就是日志,在程序中除了业务代码外,使用最多的就是打印日志。经常听到的这样一句话就是“打个日志调试下”,没错在日常的开发、调试过程中打印日志是常干...

Java 8之后的那些新特性(三):Java System Logger

去年12月份log4j日志框架的一个漏洞,给Java整个行业造成了非常大的影响。这个事情也顺带把log4j这个日志框架推到了争议的最前线。在Java领域,log4j可能相对比较流行。而在log4j之外...

Java开发中的日志管理:让程序“开口说话”

Java开发中的日志管理:让程序“开口说话”日志是程序员的朋友,也是程序的“嘴巴”。它能让程序在运行过程中“开口说话”,告诉我们它的状态、行为以及遇到的问题。在Java开发中,良好的日志管理不仅能帮助...

吊打面试官(十二)--Java语言中ArrayList类一文全掌握

导读...

OS X 效率启动器 Alfred 详解与使用技巧

问:为什么要在Mac上使用效率启动器类应用?答:在非特殊专业用户的环境下,(每天)用户一般可以在系统中进行上百次操作,可以是点击,也可以是拖拽,但这些只是过程,而我们的真正目的是想获得结果,也就是...

Java中 高级的异常处理(java中异常处理的两种方式)

介绍异常处理是软件开发的一个关键方面,尤其是在Java中,这种语言以其稳健性和平台独立性而闻名。正确的异常处理不仅可以防止应用程序崩溃,还有助于调试并向用户提供有意义的反馈。...

【性能调优】全方位教你定位慢SQL,方法介绍下!

1.使用数据库自带工具...

全面了解mysql锁机制(InnoDB)与问题排查

MySQL/InnoDB的加锁,一直是一个常见的话题。例如,数据库如果有高并发请求,如何保证数据完整性?产生死锁问题如何排查并解决?下面是不同锁等级的区别表级锁:开销小,加锁快;不会出现死锁;锁定粒度...

看懂这篇文章,你就懂了数据库死锁产生的场景和解决方法

一、什么是死锁加锁(Locking)是数据库在并发访问时保证数据一致性和完整性的主要机制。任何事务都需要获得相应对象上的锁才能访问数据,读取数据的事务通常只需要获得读锁(共享锁),修改数据的事务需要获...