嵌入式Linux设备驱动程序开发指南7(helloworld驱动程序)——读书笔记

七、helloworld驱动程序

7.1 概述

嵌入式linux系统设计关键概念是将用户应用与底层硬件隔离,不允许上层应用直接操作底层硬件,防止硬件设备处于未知状态。内核态和用户态的隔离,提供给开发者较强的可移植性。内核模块一般存放于

/lib/modules

Linux内核使用GNU GPLv2许可证。更多开源软件许可证可访问http://opensource.org/license查看。

7.2 helloworld驱动(1)不带参数

helloworld驱动文件包括:

Makefile		//编译文件
helloworld.c	//源代码文件 <module name>.c

针对SAMA5D2写的helloworld驱动程序,即
helloworld.c代码:

#include <linux/module.h>

static int __init hello_init(void)
{
	pr_info("hello world init\n");
	return 0;
}
static int __init hello_exit(void)
{
	pr_info("hello world exit\n");
	return 0;
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR(" ");
MODULE_DESCRIPTION("This is print out hello world module");

Makefile:

obj-m += helloworld.o
KERNEL_DIR ?= $(home)/my-linux-imx

all:
    make -C $(KERNEL_DIR ) \
    		ARCH=arm CROSS_COMPILE=arm-poky-linux-gnueabi- \
    		SUBDIR=$(PWD) modules
    
clean:
    make -C $(KERNEL_DIR ) \
    		ARCH=arm CROSS_COMPILE=arm-poky-linux-gnueabi- \
    		SUBDIR=$(PWD) clean
    		
deploy:
    scp *.ko root@10.0.0.10:   		

简单的把<module name>.c 编译成<module name>.o ,随后到Makefile变量obj-m

打印备注:

printk()	//内核态下打印使用

测试调试

insmod helloworld.ko  			//加载模块
modinfo helloworld.ko  			//查看模块介绍
cat /proc/sys/kernel/tainted  	//打印 4096 = GPL, oot
rmmod helloworld.ko  			//卸载模块
cat /proc/modules
find /sys -name "*helloworld*"  //在sysfs中查找你的模块

7.2 helloworld驱动(2)带输入参数

在helloworld驱动(1)基础上增加参数传递,通过命令行提供模块加载时设置参数。你也可以通过sysfs文件系统读取参数,下面介绍sysfs(虚拟文件系统)。

sysfs是Linux内核提供的一个虚拟文件系统,内核通过虚拟文件系统将内核模型中的各种内核子系统、硬件设备以及关联的设备驱动信息导出到用户态。除了提供各种关于设备以及子系统的信息,导出的虚拟文件也被用于对它们进行配置。

模块参数的宏定义:
module_param(name, perm);

helloworld_with_param.c代码:

#include <linux/module.h>

static int num = 5;

module_param(num, int, S_IRUGO);

static int __init hello_init(void)
{
	pr_info("parameter num = %d\n", num);
	return 0;
}

static void __exit hello_exit(void)
{
	pr_info("Hello world with parameter exit\n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR(" ");
MODULE_DESCRIPTION("This is a module that accepts parameters");

Makefile:

obj-m += helloworld_with_param.o

KERNEL_DIR ?= $(HOME)/my-linux-imx

all:
	make -C $(KERNEL_DIR) \
		ARCH=arm CROSS_COMPILE=arm-poky-linux-gnueabi- \
		SUBDIRS=$(PWD) modules

clean:
	make -C $(KERNEL_DIR) \
		ARCH=arm CROSS_COMPILE=arm-poky-linux-gnueabi- \
		SUBDIRS=$(PWD) clean

deploy:
	scp *.ko root@10.0.0.10:

测试调试

insmod helloworld_with_param.ko num=10

7.2 helloworld驱动(3)带计时功能

功能描述:
在内核卸载时候,打印驱动从加载到卸载所经历的时间长度。

获取时间c函数:

kernel/time/keeping.c

timeval数据结构定义:

#incldue <linux/time.h>

struct timeval {
	_kernel_time_t	tv_sec;			//秒
	_kernel_suseconds_t tv_usec;  	//微秒
};

helloworld_with_timing.c代码:

#include <linux/module.h>
#include <linux/time.h>

static int num = 10;
static struct timeval start_time;

module_param(num, int, S_IRUGO);

static void say_hello(void)
{
	int i;
	for (i = 1; i <= num; i++)
      		pr_info("[%d/%d] Hello!\n",i,num);
}

static int __init first_init(void)
{

	do_gettimeofday(&start_time);
	pr_info("Loading first!\n");
	say_hello();
	return 0;
}

static void __exit first_exit(void)
{
	struct timeval end_time;
	do_gettimeofday(&end_time);
	pr_info("Unloading module after %ld seconds\n",
			end_time.tv_sec - start_time.tv_sec);
	say_hello();
}

module_init(first_init);
module_exit(first_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR(" ");
MODULE_DESCRIPTION("This is a module that will print the time since it was loaded");

Makefile:

obj-m += helloworld_with_timing.o

KERNEL_DIR ?= $(HOME)/my-linux-imx

all:
	make -C $(KERNEL_DIR) \
		ARCH=arm CROSS_COMPILE=arm-poky-linux-gnueabi- \
		SUBDIRS=$(PWD) modules

clean:
	make -C $(KERNEL_DIR) \
		ARCH=arm CROSS_COMPILE=arm-poky-linux-gnueabi- \
		SUBDIRS=$(PWD) clean

deploy:
	scp *.ko root@10.0.0.10:

测试调试:

insmod helloworld_timing.ko num=10
cat /sys/module/helloworld_with_timing/parameters/num
rmmod helloworld_timing.ko

感谢阅读,祝君成功!
-by aiziyou

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jack.Jia

感谢打赏!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值