linux驱动开发--内核链表

简介: <p>1、内核链表定义</p> <p>在<linux/list.h>中定义<br></p> <p></p> <pre code_snippet_id="129034" snippet_file_name="blog_20131226_1_9794223" name="code" class="objc">struct list_head{ struct list_he

1、内核链表定义

在<linux/list.h>中定义

struct list_head{
  struct list_head *next, *prev;
};
在list_head结构中包含两个指向list_head结构的指针next和prev,在实际使用中,它通常被组织成双向循环链表。

内核链表结构体不包含数据域,只包含维护链表的指针域。

内核链表被包含在其他数据结构体中使用。

初始化链表头INIT_LIST_HEAD函数
void INIT_LIST_HEAD(struct list_head *list);
list:待初始化链表头
插入节点list_add函数
void list_add(struct list_head *new, struct list_head *head);
void list_add_tail(struct list_head *new, struct list_head *head);

new:待插入到链表的新节点
head:待插入到链表的链表头

删除节点list_del函数
void list_del(struct list_head *entry);
entry:待删除的节点
提取数据结构list_entry宏
#define list_entry(ptr, type, member) container_of(ptr, type, member)
ptr:当前链表节点指针
type:包含该链表的数据结构体类型
member:在数据结构体类型中的list_head成员名称
返回:获取的数据结构体指针
实际是通过已知数据结构体中链表节点指针ptr,获取包含该链表节点的数据结构体指针

遍历链表list_for_each宏
#define list_for_each(pos, head) for(pos = (head)->next; prefetch(pos->next), pos != (head); pos = pos->next)
#define list_for_each_safe(pos, n, head) for(pos = (head)->next, n= pos->next; pos !=(head); pos = n, n = pos->next)

pos:list_head指针类型的循环变量
n:list_head指针类型的循环变量
head:待遍历链表的链表头

2、实例代码:

/**
*Copyright (c) 2013.TianYuan
*All rights reserved.
*
*文件名称: listtest.c
*文件标识: 内核链表的使用
*
*当前版本:1.0
*作者:wuyq 
*
*取代版本:xxx
*原作者:xxx
*完成日期:2013-11-18
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/list.h>

MODULE_LICENSE("GPL");

#define EMPLOYEE_NUM	10

struct employee
{
	char name[20];
	int id;
	int salary;
	int age;
	struct list_head list;
};

/*定义链表头节点*/
struct list_head  employee_list;
struct employee *employeep = NULL;/*保存首地址*/
struct list_head *pos = NULL;/*list_for_each*/
struct employee *employee_tmp = NULL;
static int __init listtest_init(void)
{
	int i = 0;
	
	/*初始化链表头节点*/
	INIT_LIST_HEAD(&employee_list);
	
	/*申请employee空间*/
	employeep = kmalloc(sizeof(struct employee)*EMPLOYEE_NUM, GFP_KERNEL);
	if(IS_ERR(employeep)){
		printk("kmalloc failed!\n");
		return -ENOMEM;
	}
	memset(employeep, 0, sizeof(struct employee)*EMPLOYEE_NUM);
	/*初始化每个struct*/
	for(i=0; i<EMPLOYEE_NUM; i++){
		sprintf(employeep[i].name, "employee%d", i);
		/*true*/sprintf((employeep+i)->name, "employee%d", i);
		employeep[i].id = 10000 + i;
		employeep[i].salary = 10000 + 1000*i;
		/*添加节点到链表中*/
		list_add(&(employeep[i].list), &employee_list);
	}
	/*链表节点的遍历*/	
	list_for_each(pos, &employee_list){
		employee_tmp = list_entry(pos, struct employee, list);
		printk("employee name :T=%s\tID:%d\tSalary:%d!\n",
				employee_tmp->name,
				employee_tmp->id,
				employee_tmp->salary);
	}	
		
	return 0;
}

static void __exit listtest_exit(void)
{
	int i = 0;
	for(i=0; i<EMPLOYEE_NUM; i++){
		list_del(&(employeep[i].list));
	}
	
	kfree(employeep);
}

module_init(listtest_init);
module_exit(listtest_exit);

KERNELDIR ?=/root/Desktop/work/ldd3/linux-2.6.31_TX2440A
PWD := $(shell pwd)
obj-m += listtest.o

default:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

clean:
	@rm -f *.o *.ord* *.sy* *.mod.* *.ko



目录
相关文章
|
7月前
|
Ubuntu 搜索推荐 Linux
详解Ubuntu的strings与grep命令:Linux开发的实用工具。
这就是Ubuntu中的strings和grep命令,透明且强大。我希望你喜欢这个神奇的世界,并能在你的Linux开发旅程上,通过它们找到你的方向。记住,你的电脑是你的舞台,在上面你可以做任何你想做的事,只要你敢于尝试。
395 32
|
9月前
|
JavaScript Linux 网络安全
Termux安卓终端美化与开发实战:从下载到插件优化,小白也能玩转Linux
Termux是一款安卓平台上的开源终端模拟器,支持apt包管理、SSH连接及Python/Node.js/C++开发环境搭建,被誉为“手机上的Linux系统”。其特点包括零ROOT权限、跨平台开发和强大扩展性。本文详细介绍其安装准备、基础与高级环境配置、必备插件推荐、常见问题解决方法以及延伸学习资源,帮助用户充分利用Termux进行开发与学习。适用于Android 7+设备,原创内容转载请注明来源。
2327 77
|
存储 网络协议 Ubuntu
【Linux开发实战指南】基于UDP协议的即时聊天室:快速构建登陆、聊天与退出功能
UDP 是一种无连接的、不可靠的传输层协议,位于IP协议之上。它提供了最基本的数据传输服务,不保证数据包的顺序、可靠到达或无重复。与TCP(传输控制协议)相比,UDP具有较低的传输延迟,因为省去了建立连接和确认接收等过程,适用于对实时性要求较高、但能容忍一定数据丢失的场景,如在线视频、语音通话、DNS查询等。 链表 链表是一种动态数据结构,用于存储一系列元素(节点),每个节点包含数据字段和指向下一个节点的引用(指针)。链表分为单向链表、双向链表和循环链表等类型。与数组相比,链表在插入和删除操作上更为高效,因为它不需要移动元素,只需修改节点间的指针即可。但访问链表中的元素不如数组直接,通常需要从
596 2
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
486 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
Web App开发 缓存 Linux
FFmpeg开发笔记(三十六)Linux环境安装SRS实现视频直播推流
《FFmpeg开发实战》书中第10章提及轻量级流媒体服务器MediaMTX,适合测试RTSP/RTMP协议,但不适合生产环境。推荐使用SRS或ZLMediaKit,其中SRS是国产开源实时视频服务器,支持多种流媒体协议。本文简述在华为欧拉系统上编译安装SRS和FFmpeg的步骤,包括安装依赖、下载源码、配置、编译以及启动SRS服务。此外,还展示了如何通过FFmpeg进行RTMP推流,并使用VLC播放器测试拉流。更多FFmpeg开发内容可参考相关书籍。
861 2
FFmpeg开发笔记(三十六)Linux环境安装SRS实现视频直播推流
|
Java Linux API
Linux设备驱动开发详解2
Linux设备驱动开发详解
247 6
|
消息中间件 算法 Unix
Linux设备驱动开发详解1
Linux设备驱动开发详解
273 5
|
存储 Linux 开发工具
如何进行Linux内核开发【ChatGPT】
如何进行Linux内核开发【ChatGPT】
|
Linux
FFmpeg开发笔记(三十四)Linux环境给FFmpeg集成libsrt和librist
《FFmpeg开发实战》书中介绍了直播的RTSP和RTMP协议,以及新协议SRT和RIST。SRT是安全可靠传输协议,RIST是可靠的互联网流传输协议,两者于2017年发布。腾讯视频云采用SRT改善推流卡顿。以下是Linux环境下为FFmpeg集成libsrt和librist的步骤:下载安装源码,配置、编译和安装。要启用这些库,需重新配置FFmpeg,添加相关选项,然后编译和安装。成功后,通过`ffmpeg -version`检查版本信息以确认启用SRT和RIST支持。详细过程可参考书中相应章节。
443 1
FFmpeg开发笔记(三十四)Linux环境给FFmpeg集成libsrt和librist
|
编解码 安全 Linux
基于arm64架构国产操作系统|Linux下的RTMP|RTSP低延时直播播放器开发探究
这段内容讲述了国产操作系统背景下,大牛直播SDK针对国产操作系统与Linux平台发布的RTMP/RTSP直播播放SDK。此SDK支持arm64架构,基于X协议输出视频,采用PulseAudio和Alsa Lib处理音频,具备实时静音、快照、缓冲时间设定等功能,并支持H.265编码格式。此外,提供了示例代码展示如何实现多实例播放器的创建与管理,包括窗口布局调整、事件监听、视频分辨率变化和实时快照回调等关键功能。这一技术实现有助于提高直播服务的稳定性和响应速度,适应国产操作系统在各行业中的应用需求。
428 3