设为首页 加入收藏

TOP

写驱动实现LED闪烁及基础概念查看(一)
2023-07-23 13:24:54 】 浏览:66
Tags:LED 查看

2023/7/20 初学内核,记录与分享,感叹内核学了后真的感觉很多东西都通透了,但是难度太大,只能浅浅初探。

前提

内核五大功能
? 进程管理:进程的创建,销毁,调度等功能
注:可中断,不可中断,就是是否被信号打断。从运行状态怎样改到可中断等待态,和不可中断等待态操作系统开始会对每个进程分配一个时间片,当进程里面写了sleep函数,进程由运行到休眠态,但是此时CPU不可能等着。有两种方法,1:根据时间片,CPU自动跳转,2:程序里面自己写能引起CPU调度的代码就可以
? 文件管理:通过文件系统ext2/ext3/ext4 yaff jiffs等来组织管理文件
? 网络管理:通过网络协议栈(OSI,TCP)对数据进程封装和拆解过程(数据发送和接收是通过网卡驱动完成的,网卡驱动不会产生文件(在Linux系统dev下面没有相应的文件),所以不能用open等函数,而是使用的socket)。
? 内存管理:通过内存管理器对用户空间和内核空间内存的申请和释放
? 设备管理: 设备驱动的管理(驱动工程师所对应的)
? 字符设备驱动: (led 鼠标 键盘 lcd touchscreen(触摸屏))
1.按照字节为单位进行访问,顺序访问(有先后顺序去访问)
2.会创建设备文件,open read write close来访问
? **块设备驱动 ** :(camera u盘 emmc)
1.按照块(512字节)(扇区)来访问,可以顺序访问,可以无序访问
2.会创建设备文件,open read write close来访问
? 网卡设备驱动:(猫)
1.按照网络数据包来收发的。

驱动

三要素:入口,出口,许可证
● 入口:资源的申请
● 出口:资源的释放
● 许可证:GPL(写一个模块需要开源,因为Linux系统是开源的,所以需要写许可协议)

1.基础模块

驱动格式

#include <linux/init.h>
#include<linux/module.h>
//__init将hello_init放到.init.text段中
static int __init hello_init(void)
{
    return 0;
}

//__exit将hello_exit放到.exit.text段中
static void __exit hello_exit(void)
{

}

	//告诉内核驱动的入口地址(函数名为函数首地址)
module_init(hello_init);
		//告诉内核驱动的出口地址
module_exit(hello_exit);
    	//许可证
MODULE_LICENSE("GPL");

makefile格式

//板子内核路径
#KERNEL_PATH=/home/hq/kernel/kernel-3.4.39
 //Ubuntu内核的路径
KERNEL_PATH=/lib/modules/$(shell uname -r)/build  

PWD=$(shell pwd)  //驱动文件的路径
all: //目标
	make -C $(KERNEL_PATH) M=$(PWD) modules //(-C:进入顶层目录)
   /*注:进入内核目录下执行make modules这条命令
如果不指定 M=$(PWD) 会把内核目录下的.c文件编译生成.ko*/

.PHONY:clean
clean:
	make -C $(KERNEL_PATH) M=$(PWD) clean

obj-m = hello.o   //指定编译模块的名字

命令的使用

	创建索引文件
		ctags -R
	在终端上
		vi -t xxx
	在代码中跳转
		ctrl + ]
		ctrl + t
	sudo insmod hello.ko   安装驱动模块
	sudo rmmod  hello      卸载驱动模块
	lsmod                  查看模块
	dmesg                  查看消息
	sudo dmesg -C          直接清空消息不回显
	sudo dmesg -c          回显后清空

打印函数

概念

1. #include <linux/printk.h>  //增加这个头文件

2. printk(KERN_ERR "Fail%d",a);//打印函数,KERN_ERR对应的是内核打印级别

3. grep "printk" * -nR  检索所有的打印函数
	vi -t  KERN_ERR(查看内核打印级别)
4. 
	#define KERN_EMERG  "<0>"   /* system is unusable        */(系统不用)
	#define KERN_ALERT  "<1>"   /* action must be taken immediately */(被立即处理)
	#define KERN_CRIT   "<2>"   /* critical conditions          */(临界条件,临界资源)
	#define KERN_ERR    "<3>"   /* error conditions         */(出错)
	#define KERN_WARNING    "<4>"   /* warning conditions           */(警告)
	#define KERN_NOTICE "<5>"   /* normal but significant condition */(提示)
	#define KERN_INFO   "<6>"   /* informational            */(打印信息时候的级别)
	#define KERN_DEBUG  "<7>"   /* debug-level messages         */ (调试级别)
	0 ------ 7
	最高的  最低的

5. 打印显示效果是有优先级的
inux@ubuntu:~$ cat  /proc/sys/kernel/printk 查看优先级,分布为以下的四个级别
终端的级别   消息的默认级别  终端的最大级别 终端的最小级别
4                4             1              7
更改方式为   echo 4 3 1 7 > /pro/sys/kernel/printk(切换成su权限) 
如果是更改开发板打印级别  vi  rootfs/etc/init.d/rcS
					echo 4 3 1 7 > /proc/sys/kernel/printk

驱动多文件编译

概念

hello.c  add.c
	 Makefile
	 obj-m:=demo.o
	 demo-y+=hello.o add.o
(-y作用:将hello.o add.o放到demo.o中)
	最终生成demo.ko文件

举例

#KERNEL_PATH=/home/hq/kernel/kernel-3.4.39
KERNEL_PATH=/lib/modules/$(shell uname -r)/build

PWD=$(shell pwd)
all:
	make -C $(KERNEL_PATH) M=$(PWD) modules
.PHONY:clean
clean:
	make -C $(KERNEL_PATH) M=$(PWD) clean

obj-m = printkk.o
demo-y+=add.o
demo-y+=sub.o
demo-y+=printk
首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇痞子衡嵌入式:说说职业生涯第一.. 下一篇《痞子衡嵌入式半月刊》 第 78 期

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目