#
#
# include $(TOPDIR)/rules.mk //一般在 Makefile 的开头
include $(INCLUDE_DIR)/kernel.mk // 文件对于 软件包为内核时是不可缺少 PKG_NAME:=mydrv // 表示软件包名称,将在 menuconfig 和 ipkg 可以看到
PKG_RELEASE:= //表示软件包版本号 include $(INCLUDE_DIR)/package.mk //一般在软件包的基本信息完 成后再引入 define KernelPackage/mydrv //编译包定义,应用程序和内核驱动模块的定义不一样。应用程序软件包使用 Package,內核驱动模 块使用 KernelPackage。
SUBMENU:=Other modules //进行分类
TITLE:=mydrv //标题
FILES:=$(PKG_BUILD_DIR)/mydrv.ko //模块文件
KCONFIG:=
endef define KernelPackage/mydrv/description
This is a mydrv drivers //描述
endef MAKE_OPTS:= \ //编译之前指定工具和内核arch等
ARCH="$(LINUX_KARCH)" \
CROSS_COMPILE="$(TARGET_CROSS)" \
SUBDIRS="$(PKG_BUILD_DIR)" define Build/Prepare //编译前准备工作
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef define Build/Compile //进行编译
$(MAKE) -C "$(LINUX_DIR)" \
$(MAKE_OPTS) modules
endef $(eval $(call KernelPackage,mydrv))

以上为驱动程序Makefile代码,驱动程序有两个Makefile,驱动文件夹里有一个(上面)以及src里也有一个Makefile

进入src中Makefile

我们看一下Makefile的内容,非常简单: obj-m += mydrv.o

告诉内核添加的模块目标文件名称为mydrv.o

当前还包含有驱动程序

mydrv.c

/*****************************
*
* 驱动程序模板
* 版本:V1
* 使用方法(末行模式下):
* :%s/mydrv/"你的驱动名称"/g
*
*******************************/ #include <linux/mm.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/mman.h>
#include <linux/random.h>
#include <linux/init.h>
#include <linux/raw.h>
#include <linux/tty.h>
#include <linux/capability.h>
#include <linux/ptrace.h>
#include <linux/device.h>
#include <linux/highmem.h>
#include <linux/crash_dump.h>
#include <linux/backing-dev.h>
#include <linux/bootmem.h>
#include <linux/splice.h>
#include <linux/pfn.h>
#include <linux/export.h>
#include <linux/io.h>
#include <linux/aio.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/uaccess.h>
#include <linux/ioctl.h> /**************** 基本定义 **********************/
//内核空间缓冲区定义
#if 0
#define KB_MAX_SIZE 20
#define kbuf[KB_MAX_SIZE];
#endif //加密函数参数内容: _IOW(IOW_CHAR , IOW_NUMn , IOW_TYPE)
//加密函数用于mydrv_ioctl函数中
//使用举例:ioctl(fd , _IOW('L',0x80,long) , 0x1);
//#define NUMn mydrv , if you need!
#define IOW_CHAR 'L'
#define IOW_TYPE long
#define IOW_NUM1 0x80 //初始化函数必要资源定义
//用于初始化函数当中
//device number;
dev_t dev_num;
//struct dev
struct cdev mydrv_cdev;
//auto "mknode /dev/mydrv c dev_num minor_num"
struct class *mydrv_class = NULL;
struct device *mydrv_device = NULL; /**************** 结构体 file_operations 成员函数 *****************/
//open
static int mydrv_open(struct inode *inode, struct file *file)
{
printk("mydrv drive open...\n"); return ;
} //close
static int mydrv_close(struct inode *inode , struct file *file)
{
printk("mydrv drive close...\n"); return ;
} //read
static ssize_t mydrv_read(struct file *file, char __user *buffer,
size_t len, loff_t *pos)
{
int ret_v = ;
printk("mydrv drive read...\n"); return ret_v;
} //write
static ssize_t mydrv_write( struct file *file , const char __user *buffer,
size_t len , loff_t *offset )
{
int ret_v = ;
printk("mydrv drive write...\n"); return ret_v;
} //unlocked_ioctl
static int mydrv_ioctl (struct file *filp , unsigned int cmd , unsigned long arg)
{
int ret_v = ;
printk("mydrv drive ioctl...\n"); switch(cmd)
{
//常规:
//cmd值自行进行修改
case 0x1:
{
if(arg == 0x1) //第二条件;
{ }
}
break; //带密码保护:
//请在"基本定义"进行必要的定义
case _IOW(IOW_CHAR,IOW_NUM1,IOW_TYPE):
{
if(arg == 0x1) //第二条件
{ } }
break; default:
break;
} return ret_v;
} /***************** 结构体: file_operations ************************/
//struct
static const struct file_operations mydrv_fops = {
.owner = THIS_MODULE,
.open = mydrv_open,
.release = mydrv_close,
.read = mydrv_read,
.write = mydrv_write,
.unlocked_ioctl = mydrv_ioctl,
}; /************* functions: init , exit*******************/
//条件值变量,用于指示资源是否正常使用
unsigned char init_flag = ;
unsigned char add_code_flag = ; //init
static __init int mydrv_init(void)
{
int ret_v = ;
printk("mydrv drive init...\n"); //函数alloc_chrdev_region主要参数说明:
//参数2: 次设备号
//参数3: 创建多少个设备
if( ( ret_v = alloc_chrdev_region(&dev_num,,,"mydrv") ) < )
{
goto dev_reg_error;
}
init_flag = ; //标示设备创建成功; printk("The drive info of mydrv:\nmajor: %d\nminor: %d\n",
MAJOR(dev_num),MINOR(dev_num)); cdev_init(&mydrv_cdev,&mydrv_fops);
if( (ret_v = cdev_add(&mydrv_cdev,dev_num,)) != )
{
goto cdev_add_error;
} mydrv_class = class_create(THIS_MODULE,"mydrv");
if( IS_ERR(mydrv_class) )
{
goto class_c_error;
} mydrv_device = device_create(mydrv_class,NULL,dev_num,NULL,"mydrv");
if( IS_ERR(mydrv_device) )
{
goto device_c_error;
}
printk("auto mknod success!\n"); //------------ 请在此添加您的初始化程序 --------------// //如果需要做错误处理,请:goto mydrv_error; add_code_flag = ;
//---------------------- END ---------------------------// goto init_success; dev_reg_error:
printk("alloc_chrdev_region failed\n");
return ret_v; cdev_add_error:
printk("cdev_add failed\n");
unregister_chrdev_region(dev_num, );
init_flag = ;
return ret_v; class_c_error:
printk("class_create failed\n");
cdev_del(&mydrv_cdev);
unregister_chrdev_region(dev_num, );
init_flag = ;
return PTR_ERR(mydrv_class); device_c_error:
printk("device_create failed\n");
cdev_del(&mydrv_cdev);
unregister_chrdev_region(dev_num, );
class_destroy(mydrv_class);
init_flag = ;
return PTR_ERR(mydrv_device); //------------------ 请在此添加您的错误处理内容 ----------------//
mydrv_error: add_code_flag = ;
return -;
//-------------------- END -------------------// init_success:
printk("mydrv init success!\n");
return ;
} //exit
static __exit void mydrv_exit(void)
{
printk("mydrv drive exit...\n"); if(add_code_flag == )
{
//---------- 请在这里释放您的程序占有的资源 ---------//
printk("free your resources...\n"); printk("free finish\n");
//---------------------- END -------------------//
} if(init_flag == )
{
//释放初始化使用到的资源;
cdev_del(&mydrv_cdev);
unregister_chrdev_region(dev_num, );
device_unregister(mydrv_device);
class_destroy(mydrv_class);
}
} /**************** module operations**********************/
//module loading
module_init(mydrv_init);
module_exit(mydrv_exit); //some infomation
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("from Jafy");
MODULE_DESCRIPTION("mydrv drive"); /********************* The End ***************************/

测试程序mydir_app

Makefile

##Copyright (C)  OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
# include $(TOPDIR)/rules.mk PKG_NAME:=mydrv_app
PKG_RELEASE:= PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) include $(INCLUDE_DIR)/package.mk define Package/mydrv_app
SECTION:=utils
CATEGORY:=Utilities
TITLE:=Frame buffer device testing tool
DEPENDS:=+libncurses
endef define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef define Build/Configure
endef TARGET_LDFLAGS := define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR) \
CC="$(TARGET_CC)" \
CFLAGS="$(TARGET_CFLAGS) -Wall" \
LDFLAGS="$(TARGET_LDFLAGS)"
endef define Package/mydrv_app/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mydrv_app $(1)/usr/sbin/
endef $(eval $(call BuildPackage,mydrv_app))

进入src文件夹

Makefile

ll: mydrv_app
OBJS = mydrv_app.o CC = gcc
CCFLAGS = -Wall -c -o %.o: %.c
$(CC) $(CCFLAGS) $@ $< $(LDFLAGS) fbtest: $(OBJS)
$(CC) -o $@ $(OBJS) $(LDFLAGS) clean:
rm -f rbcfg *.o

测试程序代码

#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h> int main(int argc , char** argv)
{
int fd;
int num = ; //打开驱动模块
fd = open("/dev/mydrv" , O_RDWR|O_NONBLOCK);
if(fd < )
{
printf("can't open /dev/mydrv\n");
return -;
} //函数测试
write(fd,&num,);
read(fd,&num,);
ioctl(fd,,);
close(fd); return ;
}

.OpenWrt驱动程序Makefile的分析概述 、驱动程序代码参考、以及测试程序代码参考的更多相关文章

  1. Linux内核启动代码分析二之开发板相关驱动程序加载分析

    Linux内核启动代码分析二之开发板相关驱动程序加载分析 1 从linux开始启动的函数start_kernel开始分析,该函数位于linux-2.6.22/init/main.c  start_ke ...

  2. openwrt: Makefile 框架分析

    openwrt: Makefile 框架分析 原文链接:blog.chinaunix.net/uid-26675482-id-4704952.html 本篇的主要目的是想通过分析Makefile,了解 ...

  3. Android日志系统驱动程序Logger源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6595744 我们知道,在Android系统中, ...

  4. openwrt: Makefile 框架分析[转载]

    openwrt目录结构 上图是openwrt目录结构,其中第一行是原始目录,第二行是编译过程中生成的目录.各目录的作用是: tools - 编译时需要一些工具, tools里包含了获取和编译这些工具的 ...

  5. 嵌入式Linux设备驱动程序:编写内核设备驱动程序

    嵌入式Linux设备驱动程序:编写内核设备驱动程序 Embedded Linux device drivers: Writing a kernel device driver 编写内核设备驱动程序 最 ...

  6. Linux移植随笔:对tslib库的ts_test测试程序代码的一点分析【转】

    转自:http://www.latelee.org/embedded-linux/porting-linux-tstest-code.html 本文是作者对tslib库的ts_test.c文件进行分析 ...

  7. uboot makefile构建分析-续

    前言 这篇博文是 uboot makefile构建分析的续篇,继续分析uboot构建u-boot.bin的过程 构建u-boot.bin过程分析 makefile一开始,就是确定链接脚本.在构建ubo ...

  8. linux内核分析作业4:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

    系统调用:库函数封装了系统调用,通过库函数和系统调用打交道 用户态:低级别执行状态,代码的掌控范围会受到限制. 内核态:高执行级别,代码可移植性特权指令,访问任意物理地址 为什么划分级别:如果全部特权 ...

  9. 想做一个整合开源安全代码扫描工具的代码安全分析平台 - Android方向调研

    想做一个整合开源安全代码扫描工具的代码安全分析平台 - Android方向调研 http://blog.csdn.net/testing_is_believing/article/details/22 ...

随机推荐

  1. 【转】使用DirectUI技术实现QQ界面

    转自http://bbs.csdn.net/topics/350023031 一.介绍 DirectUI技术说白了就是XML配置文件+图片+JavaScript控制界面.这点与网页css+图片+Jav ...

  2. JS进阶书籍

    http://blog.csdn.net/bingqingsuimeng/article/details/40535291 本来想尝试每天回答或看已解决的3个问题来学习总结今天的知识点,看了下博文里面 ...

  3. Infix expressions 中缀表达式

    中缀表达式的计算 利用两个栈来实现,操作数栈,操作符栈 只支持个位数运算 最后必须输入一个'#' #include<iostream> using namespace std; templ ...

  4. SharePoint 2010 Modal Dialog

    SharePoint 2010 Modal Dialog Tweet   Modal dialog play very important role to improve the user exper ...

  5. SVN和GIT的使用

    一.SVN通用流程 1.从服务器仓库的项目上右键拷贝项目地址,然后来到你的电脑桌面上右键“SVN checkout...”,这样就跟服务器建立了关联 2.如果有创建新文件,则右键选择“Tortoise ...

  6. 理解本真的REST架构风格

       http://kb.cnblogs.com/page/186516/ 引子 在移动互联网.云计算迅猛发展的今天,作为一名Web开发者,如果您还没听说过“REST”这个buzzword,显然已经落 ...

  7. MySQL事件【转载】

    在系统管理或者数据库管理中,经常要周期性的执行某一个命令或者SQL语句.对于linux系统熟悉的人都知道linux的cron计划任务,能很方便地实现定期运行指定命令的功能.Mysql在5.1以后推出了 ...

  8. log4j2.xml配置及例子

    1.使用log4j2需要下载包,如下: 2.配置文件可以有三种格式(文件名必须规范,否则系统无法找到配置文件): classpath下名为 log4j-test.json 或者log4j-test.j ...

  9. linux ubuntu下如何安装并且切换java版本(Unsupported major.minor version 52.0)

    最近在做一个dcos(数据中心操作系统)的东西,需要用marathon来做进程管理.遗憾的是0.6版本的marathon在API方面很是缺少,换成了0.15版本之后,运行时提示“Unsupported ...

  10. Spotlights

    Spotlights time limit per test 1 second memory limit per test 256 megabytes input standard input out ...