文章分类 -  linux_c

摘要:在刚开始写Linux设备驱动程序的时候,很多时候都是利用mknod命令手动创建设备节点,实际上Linux内核为我们提供了一组函数,可以用来在模块加载的时候自动在/dev目录下创建相应设备节点,并在卸载模块时删除该节点,当然前提条件是用户空间移植了udev。内核中定义了struct class结构体,顾名思义,一个struct class结构体类型变量对应一个类,内核同时提供了class_create(…)函数,可以用它来创建一个类,这个类存放于sysfs下面,一旦创建好了这个类,再调用device_create(…)函数来在/dev目录下创建相应的设备节点。这样,加载模块的时候,用户空间中的u 阅读全文
posted @ 2012-08-13 10:32 Drobobls 阅读(74) 评论(0) 推荐(0)
摘要:make -C /opt/FriendlyARM/linux-2.6.32.2 M=/opt/FriendlyARM/linux-arm-modules/plat_buttons modulesmake[1]: Entering directory `/opt/FriendlyARM/linux-2.6.32.2' CC [M] /opt/FriendlyARM/linux-arm-modules/plat_buttons/plat_buttons.o/opt/FriendlyARM/linux-arm-modules/plat_buttons/plat_buttons.c: In f 阅读全文
posted @ 2012-08-12 16:53 Drobobls 阅读(409) 评论(0) 推荐(0)
摘要:数组的元素也可以是结构类型的。因此可以构成结构型数组。结构数组的每一个元素都是具有相同结构类型的下标结构变量。在实际应用中,经常用结构数组来表示具有相同数据结构的一个群体。如一个班的学生档案,一个车间职工的工资表等。方法和结构变量相似,只需说明它为数组类型即可。例如:struct stu { int num; char *name; char sex; float score;}boy[5];定义了一个结构数组boy,共有5个元素,boy[0]~boy[4]。每个数组元素都具有struct stu的结构形式。对结构数组可以作初始化赋... 阅读全文
posted @ 2012-08-11 17:28 Drobobls 阅读(629) 评论(0) 推荐(0)
摘要:volatile的作用: 作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值,简单地说就是防止编译器对代码进行优化。 阅读全文
posted @ 2012-07-31 22:38 Drobobls 阅读(79) 评论(0) 推荐(0)
摘要:定义 #ifndef x //if not define的简写 #define x ... #endif 这是宏定义的一种,它可以根据是否已经定义了一个变量来进行分支选择,一般用于调试等等.实际上确切的说这应该是预处理功能中三种(宏定义,文件包含和条件编译)中的一种----条件编译。 C语言在对程序进行编译时,会先根据预处理命令进行“预处理”。C语言编译系统包括预处理,编译和链接等部分。 #ifndef x //先测试x是否被宏定义过 #define x 程序段1 //如果x没有被宏定义过,定义x,并编译程序段1 #endif 程序段2 //如果x已经定义过了则编译程序段... 阅读全文
posted @ 2012-07-31 22:35 Drobobls 阅读(143) 评论(0) 推荐(0)
摘要:strtoul (将字符串转换成无符号长整型数) 相关函数 atof,atoi,atol,strtod,strtol 表头文件 #include<stdlib.h> 定义函数 unsigned long strtoul(const char *nptr,char **endptr,int base); 函数说明 strtoul()会将参数nptr字符串根据参数base来转换成无符号的长整型数。参数base范围从2至36,或0。参数base代表采用的进制方式,如base值为10则采用10进制,若base值为16则采用16进制数等。当base值为0时则是采用10进制做转换,但遇到如.. 阅读全文
posted @ 2012-07-31 22:05 Drobobls 阅读(433) 评论(0) 推荐(0)
摘要:ascii码对照表ASCII, American Standard Code for Information Interchange 念起来像是 "阿斯key",定义从 0 到 127 的一百二十八个数字所代表的英文字母或一样的结果与意义。由于只使用7个位元(bit)就可以表示从0到127的数字,大部分的电脑都使用8个位元来存取 字元集(character set),所以从128到255之间的数字可以用来代表另一组一百二十八个符号,称为 extended ASCII。ASCII码键盘ASCII 码键盘ASCII码键盘ASCII 码键盘27ESC32SPACE33!34&qu 阅读全文
posted @ 2012-07-31 22:04 Drobobls 阅读(190) 评论(0) 推荐(0)
摘要:函数简介 原型:extern int strcmp(const char *s1,const char * s2); 用法:#include <string.h> 功能:比较字符串s1和s2。 一般形式:strcmp(字符串1,字符串2) 说明: 当s1<s2时,返回值<0 当s1=s2时,返回值=0 当s1>s2时,返回值>0 即:两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇'\0'为止。如: "A"<"B" "a">"A 阅读全文
posted @ 2012-07-31 22:04 Drobobls 阅读(248) 评论(0) 推荐(0)
摘要:Linux下的设备驱动程序被组织为一组完成不同任务的函数的集合,通过这些函数使得Windows的设备操作犹如文件一般。在应用程序看来,硬件设备只 是一个设备文件,应用程序可以象操作普通文件一样对硬件设备进行操作,如open ()、close ()、read ()、write () 等。Linux主要将设备分为二类:字符设备和块设备。字符设备是指设备发送和接收数据以字符的形式进行;而块设备则以整个数据缓冲区的形式进行。字符设备的驱动相对比较简单。 下面我们来假设一个非常简单的虚拟字符设备:这个设备中只有一个4个字节的全局变量int global_var,而这个设备的名字叫做"gobal 阅读全文
posted @ 2012-07-31 22:02 Drobobls 阅读(224) 评论(0) 推荐(0)
摘要:read函数(读取文件)read函数可以读取文件。读取文件指从某一个已打开地文件中,读取一定数量地字符,然后将这些读取的字符放入某一个预存的缓冲区内,供以后使用。使用格式如下:number = read( ...read函数(读取文件)read函数可以读取文件。读取文件指从某一个已打开地文件中,读取一定数量地字符,然后将这些读取的字符放入某一个预存的缓冲区内,供以后使用。使用格式如下:number = read(handle, buffer ,n) ;上述read调用函数中,各个参数的定义如下:handle: 这是一个已经打开的文件句柄,表示从这个文件句柄所代表的文件读取数据。buffer: 阅读全文
posted @ 2012-07-31 21:30 Drobobls 阅读(522) 评论(0) 推荐(0)
摘要:函数原型 void *memcpy(void *dest, const void *src, int n);功能 从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中所需头文件 #include <string.h>返回值 函数返回一个指向dest的指针。说明 1.source和destin所指内存区域不能重叠,函数返回指向destin的指针。 2.与strcpy相比,memcpy并不是遇到'\0'就结束,而是一定会拷贝完n个字节。 3.如果目标数组destin本身已有数据,执行memcpy()后,将覆盖原有数据(最多覆盖n)。 阅读全文
posted @ 2012-07-31 21:09 Drobobls 阅读(80) 评论(0) 推荐(0)
摘要:函数Linux中的字符设备驱动中有一个函数 unsigned int (*poll)(struct file * fp, struct poll_table_struct * table) 此函数在系统调用select内部被使用,作用是把当前的文件指针挂到设备内部定义的等待 队列中。这里的参数table可以不考虑,是在select函数实现过程中的一个内部变量。 函数具体实现时: wait_queue_head_t t = ((struct mydev *)filp->private_data)->wait_queue; poll_wait(filp, t, table); ret. 阅读全文
posted @ 2012-07-30 17:43 Drobobls 阅读(134) 评论(0) 推荐(0)
摘要:poll的作用:同时探测n个drivers,找到可以直接使用的driver,从而尽量block进程。以下kernel源代码来自于:<linux/poll.h> 与 fs/select.cstatic unsigned int scull_p_poll(struct file *filp, poll_table *wait){ struct scull_pipe *dev = filp->private_data; unsigned int mask = 0; /* * The buffer is circular; it is considered full ... 阅读全文
posted @ 2012-07-30 17:39 Drobobls 阅读(148) 评论(0) 推荐(0)
摘要:Linux中异步IO等待无非就三个系统调用:select, poll和epoll。很多人无法理解三种调用的区别,或不够了解,今天就结合Linux kernel code详细描述三个的区别!select: select 的限制就是最大1024个fd,可以查看kernel中的posix_types.h,里面定义了fdset数据结构,显然select不适合poll大量fd的场景(如webserver)。 include/linux/posix_types.h :C代码#undef__NFDBITS#define__NFDBITS(8*sizeof(unsignedlong))#undef__FD.. 阅读全文
posted @ 2012-07-30 17:36 Drobobls 阅读(232) 评论(0) 推荐(0)
摘要:名词解析mmap:内存映射。具体的意思就是共享同一块内存进行消息传递。我看见到比较多的地方就是内核态和用户态之间 的消息传递采用mmap技术。很明显,如果是使用一般的复制方法的话,在内核态和用户态之间的消息传递所需要的开销 就会很大。而使用了共享一块内存的技术之后就可以大大提高消息传递的效率。总述它们的作用都是监听文件描述符,姑且可以这么认为,然当主要作用是它监听文件描述符所发挥的作用了。select和poll这两个比较相似,其中select要早于poll出现。select默认监听文件描述符为1024个,在sys/select.h中有定义, 虽然可以修改值的大小,但是改变大小之后对使用的性能会 阅读全文
posted @ 2012-07-30 17:32 Drobobls 阅读(129) 评论(0) 推荐(0)
摘要:1中断和异常1.1中断的由来及实质Linux内核要管理计算机上的硬件设备,首先要和他们通信。而处理器的速度跟外围硬件设备的速度往往不在一个数量级上,因此,如果内核采取让处理器向硬件发出一个请求,然后专门等待回应的办法,显然差强人意。既然硬件的响应这么慢,那么内核就应该在此期间处理其他事务,等到硬件真正完成了请求的操作之后,再回过头来对它进行处理。想要实现这种功能,轮询(polling)可能会是一种解决办法。可以让内核定期对设备的状态进行查询,然后做出相应的处理。不过这种方法很可能会让内核做不少无用功,因为无论硬件设备是正在忙碌着完成任务还是已经大功告成,轮询总会周期性地重复执行。更好的办法是由 阅读全文
posted @ 2012-07-30 13:09 Drobobls 阅读(323) 评论(0) 推荐(0)
摘要:通过前一篇文章的介绍我们队等待队列有了一个比较具体的认识,本文将来分析一下等待队列是如何睡眠一个进程和如何唤醒一个进程的。使用等待队列前通常先定义一个等待队列头:static wait_queue_head_t wq ,然后调用wait_event_*函数将等待某条件condition的当前进程插入到等待队列wq中并睡眠,一直等到condition条件满足后,内核再将睡眠在等待队列wq上的某一进程或所有进程唤醒。这里我们来分析一下唤醒的过程,举比较常用的wait_event_interruptible来分析:/** * wait_event_interruptible - sleep unti 阅读全文
posted @ 2012-07-30 11:42 Drobobls 阅读(130) 评论(0) 推荐(0)
摘要:在Linux内核中等待队列有很多用途,可用于中断处理、进程同步及定时。我们在这里只说,进程经常必须等待某些事件的发生。等待队列实现了在事件上的条件等待: 希望等待特定事件的进程把自己放进合适的等待队列,并放弃控制全。因此,等待队列表示一组睡眠的进程,当某一条件为真时,由内核唤醒它们。等待队列由循环链表实现,其元素包括指向进程描述符的指针。每个等待队列都有一个等待队列头(wait queue head),等待队列头是一个类型为wait_queue_head_t的数据结构(1)定义等待队列头(相关内容可以在linux/include/wait.h中找到)等待队列头结构体的定义:struct__wa 阅读全文
posted @ 2012-07-30 11:39 Drobobls 阅读(127) 评论(0) 推荐(0)
摘要:等待队列(wait queue)用于使进程带等待某一特定的事件发生,而无需频繁的轮询操作,进程在等待时间内睡眠,在等待的事件发生时由内核自动唤醒。一、等待队列相关数据结构 每一个等待队列都由两部分组成:等待队列头(struct wait_queue_head_t)和等待队列成员(struct wait_queue)。struct __wait_queue_head{spinlock_t lock; /*因为等待队列可以在中断时随时修改,因此设置一个自旋锁保证一致性*/struct list_head task_list;};typedef struct __wait_queue_head wa 阅读全文
posted @ 2012-07-30 11:34 Drobobls 阅读(141) 评论(0) 推荐(0)
摘要:需要让进程睡眠的原因是要等待某些条件的满足,这时可以让进程进入睡眠状态,等设备可以进行读写操作时再将其唤醒。对此,内核提供了比较通用的机制,即等待队列。包含在头文件#include<linux/wait.h>中。1.定义和初始化定义一个变量:wait_queue_head_t wq;实际上,这个数据类型内部包含了一个双向循环链表,用来存放正在等待的进程信息。在使用前需将其初始化,使用接口函数:void init_waitqueue_head(wait_queue_head_t *q);还可以直接定义并初始化,这要用到一个宏:DECLARE_WAIT_QUEUE_HEAD(wq);等 阅读全文
posted @ 2012-07-30 11:28 Drobobls 阅读(162) 评论(0) 推荐(0)