arm驱动linux内核链表

发布者:黑白之间最新更新时间:2016-06-06 来源: eefocus关键字:arm驱动  linux  内核链表 手机看文章 扫描二维码
随时随地手机看文章
《[arm驱动]linux内核链表》涉及内核驱动函数五个,内核结构体一个,分析了内核驱动函数二个;可参考的相关应用程序模板或内核驱动模板零个,可参考的相关应用程序模板或内核驱动一个

一、描述

  链表是一种常用的数据结构,它通过指针将一系列数据节点连接成一条数据链。相对于数组,链表具有更好的动态性,建立链表时无需预先知道数据总量,可以随机分配空间,可以高效地在链表中的任意位置实时插入或删除数据。链表的开销主要是访问的顺序性和组织链的空间损失。通常链表数据结构至少包含两个域:数据域和指针域,数据域用于存储数据,指针域用于建立与下一个节点的联系。Linux内核中使用了大量的链表结构来组织数据。这些链表大多采用了include/linux/list.h中实现的一套精彩的链表数据结构。

二、结构提及函数

结构体一)1、结构体:双向循环链表
struct list_head
{
  struct list_head *next, *prev;
};
2、相关函数
内核驱动函数一)初始化
INIT_LIST_HEAD(list_head *head)

内核驱动函数二)插入节点

list_add(struct list_head *new, struct list_head *head)
list_add_tail(struct list_head *new, struct list_head *head)

内核驱动函数三)删除节点
list_del(struct list_head *entry)

内核驱动函数四)提取数据结构(获取一个节点)
list_entry(ptr, type, member)

内核驱动函数五)遍历节点
list_for_each(pos, head)

内核源码一)函数原型内核中的定义

//INIT_LIST_HEAD构造双向循环链表,将首尾相连
#define INIT_LIST_HEAD(ptr) do { (ptr)->next = (ptr); (ptr)->prev = (ptr);
} while (0)
#define list_for_each(pos, head)
for (pos = (head)->next; prefetch(pos->next), pos != (head);
pos = pos->next)
#define list_entry(ptr, type, member)
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))

4、关于list_entry(ptr, type, member) 详解

内核源码二)

#define list_entry(ptr, type, member)
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))在0这个地址看做有一个虚拟的type类型的变量,那么取一个成员再取这个成员的地址,就是这个结构体中这个成员的绝对地址 。
a)list_entry的原理结合代码分析

typedef struct
{
int i;
int j;
}exp;
这个exp结构体占用8个字节,假设声明一个变量。
exp e1;
那么假如已知e1.j的地址,想知道e1的地址该如何办呢?只要知道j在e1中的偏移,然后把j的地址减去这个偏移就是e1的地址了。
int *p = e1.j;
假设e1的地址是0x100,那么p就是0x104。
list_entry(p, exp, j);
变成:
(exp *)((char *)p-(unsigned long)(&((exp *)0)->j)) ,在exp结构体中j成员的绝对地址是4,所以&((exp *)0)->j 就是4
&e1 == list_entry(p, exp, j)

实例一)三、使用案例:

#include
#include
#include
#include
#include
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Xie");
MODULE_DESCRIPTION("List Module");
MODULE_ALIAS("List module");
struct student
{
char name[100];
int num;
struct list_head list;
};
struct student *pstudent;//存储student指针数组,在list_del,list_add使用
struct student *tmp_student;//临时student节点
struct list_head student_list;//本程序中的循环链表
struct list_head *pos;//节点pos
int mylist_init(void)
{
int i = 0;
INIT_LIST_HEAD(&student_list);//初始化,构造双向循环链表
pstudent = kmalloc(sizeof(struct student)*5,GFP_KERNEL);//分配5个student的空间
memset(pstudent,0,sizeof(struct student)*5);
for(i=0;i<5;i++)
{
sprintf(pstudent[i].name,"Student%d",i+1);//赋值
pstudent[i].num = i+1;
list_add( &(pstudent[i].list), &student_list);//添加到循环链表中
}
list_for_each(pos,&student_list)
{
tmp_student = list_entry(pos,struct student,list);//获得临时student节点
printk("<0>student %d name: %s\n",tmp_student->num,tmp_student->name);
}
return 0;
}
void mylist_exit(void)
{
int i ;
/* 将for换成list_for_each来遍历删除结点,观察要发生的现象,并考虑解决办法*/
for(i=0;i<5;i++)
{
list_del(&(pstudent[i].list));//删除节点
}
kfree(pstudent);
}
module_init(mylist_init);
module_exit(mylist_exit);

关键字:arm驱动  linux  内核链表 引用地址:arm驱动linux内核链表

上一篇:arm驱动Linux内核开发之阻塞非阻塞IO轮询操作
下一篇:arm 驱动linux内核驱动之中断下半部编程

推荐阅读最新更新时间:2024-03-16 14:56

基于ARM-Linux和GPRS技术的家庭智能控制终端
1引言     随着网络技术和通信技术的不断发展,人们希望即使在工作或外出时也能通过某种方式及时了解和控制家中的情况,同时伴随着数字化家庭的普及,实现智能家居的远程控制已经成为一种趋势。家庭智能控制系统通过家庭总线技术,把家庭中各种家用电器、家庭保安装置和各种计量设备连接到一起组成一个家庭内部网络,由家庭智能控制器进行统一管理 。远程控制就是通过某种通讯方式将智能家庭控制器与外界相连,使人们能够在本地或异地对家庭系统进行集中的监视、控制。本文中介绍的方案,结合了GPRS(GeneralPacketRadioService)技术永远在线,速度快,接入范围广,体积小,功耗低等优点 ,采用RS485工业总线,设计实现了一种基于嵌入式
[嵌入式]
OK6410A 开发板 (八) 49 linux-5.11 OK6410A linux用户空间虚拟内存的管理 VMA
之前介绍过了 linux 虚拟内存管理方式 有5种,其中一种(名为VMA)用于 用户空间虚拟内存的管理,本篇就介绍 VMA VMA 是什么 task_struct 中的 mm_struct 中的 mmap(VMA) // mmap 的结构体类型 为 vm_area_struct 可以看出来 , VMA是一种数据结构,结构体类型为vm_area_struct,那么对应的就有算法 VMA 相关的数据结构 与 算法的集合 就是我们这篇要讨论的内容 用户空间 可访问的区域 是 0G-3G 当然不是 0-3G内的所有地址都可访问 , 可访问的地址空间 被称为 进程地址空间 只有做了内存申请的区域才可以被访问 做一次内存申请 ,
[单片机]
嵌入式Linux系统小型化技术
作者Email: zhh@httc.cn 介绍了Linux在嵌入式领域中的应用和宿主机、目标机开发模式,详细地给出了精简内核的实现过程。分析了glibc系统库和ELF文件格式的结构和其中的共享库裁剪技术的原理,提出并实现了一种库裁剪方案。 关键词 嵌入式;Linux;小型化 一、 概述 嵌入式Linux一般是指对标准Linux发行版本进行小型化裁剪处理之后,适合于特定嵌入式应用场合的专用Linux操作系统。嵌入式系统通常是资源受限的系统,无论是处理器计算能力还是RAM或其他存储器容量都比较“小”。因此,如何创建一个小型化的Linux作为操作系统开发成为首先需要考虑的问题。嵌入式Linux系统中普遍采用三层结构
[嵌入式]
简单说明gcc和arm-linux-gcc的区别
首先了解一下编译的过程:一个源文件经过gcc编译器编译后生成可执行文件其实经历了四个过程: * 预处理(Pre-processing) * 编译(Compiling) * 汇编(Assembling) * 链接(Linking) 而gcc经过编译后生成的可执行文件(最后也就是一大堆机器码)是在linux操作系统之上运行的,也就是说经过gcc编译器最后生成的一大堆机器码只有Linux操作系统认识,但是我们做ARM裸机实验时Soc上是没有linux操作系统的,所以这时候ARM裸机只认识经过ARM指令集生成的机器码。这时候我们要想让可执行文件在ARM裸机上运行就需要使用arm-linux-gcc (交叉编译工具)编译
[单片机]
基于Linux核心的汉字显示的尝试(frambuffer分析)
在阐述基于Linux核心的汉字显示的技术细节之前,有必要介绍一下原有linux的工作机制。这里主要涉及到两部分的知识,就是Linux下终端和帧缓冲的实现. 控制台(console) 通常我们在linux下看到的控制台(console)是由几个设备完成的。分别是/dev/ttyN(其中tty0就是/dev/console,tty1,tty2就是不同的虚拟终端(virtual console)).通常使用热键alt Fn来在这些虚拟终端之间进行切换。所有的这些tty设备都是由linux/drivers/char/console.c和vt.c对应。其中console.c负责绘制屏幕上的字符,vt.c负责管理不同的虚拟终端,并且负
[嵌入式]
采用S3C2410和Linux系统的指纹识别管理系统
指纹识别技术在金融、交通、安全等领域以及日常工作和生活中被越来越广泛地应用。指纹识别的算法中通常有大量的矩阵运算,域变换,三角函数运算等等,属于典型的运算密集型的应用,因此通常采用DSP来实现嵌入式应用。不过近期情况有了很大改观,MCU的性能突飞猛进,使得指纹识别这样的运算密集型的应用也可以采用MCU来实现。例如,三星公司推出的基于ARM920内核的嵌入式处理器S3C2410,速度高达200MIPS,完全可以满足指纹识别应用对运算速度的要求。S3C2410具有的丰富外设,并且可以运行Linux操作系统,这样的特性则是传统的DSP所无法比拟的。 进行指纹识别,首先要设法获取指纹。之前用得最多的是光学采集器,特点是价格相对便宜($1
[单片机]
采用S3C2410和<font color='red'>Linux</font>系统的指纹识别管理系统
如何在Linux下进行stc51单片机的开发
第一次接触 单片机 ,自然选择了简单的51单片机。然而我的操作系统是 Linux 。在 Windows 下上手51似乎很容易。但是 Linux 上搭建 51 开发环境不是很顺。 那么谈谈 Linux 我如何搭建 STC89C52RC 的开发环境吧。 (一) 选择自己喜好的 代码编辑器 即可。vim , emacs , gedit 等都可以。 (二) 安装编译器。一般选择 sdcc 。一般可从发行版的包管理器中直接安装。 如Arch中:   $ sudo pacman -S sdcc 如果不行,需要自行下载编译。 简单介绍使用sdcc: 假如当前目录有一个写好的源文件 main.c 。 使用如下简单方式即可编译。 $ s
[单片机]
基于2.6.19内核的小型Linux系统制作与移植
引言 ARM9 S3C2410微处理器与Linux的结合越来越紧密,逐渐在嵌入式领域得到广范的应用。目前,在便携式消费类电子产品、无线设备、汽车、网络、存储产品等都可以看到S3C2410与Linux相结合的身影。 S3C2410微处理器是一款由Samsung公司为手持终端设计的低价格、低功耗、高性能,基于ARM920T核的微处理器。它带有内存管理单元(MMU),采用0.18mm工艺和AMBA新型总线结构,主频可达203MHz。同时,它支持Thumb 16位压缩指令集,从而能以较小的存储空间获得32位的系统性能。 在众多嵌入式操作系统中,Linux目前发展最快、应用最为广泛 。性能优良、源码开放的Linux具有体积小、内核可裁
[嵌入式]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved