摘要:#include <stdio.h>#include <stdlib.h>void test(int* a,int* b){b = a;}int main(void){ int *a,*b=NULL; int c = 2; a = &c; //b = a; test(a,b); if(b) printf("aaaaaaaaaaaaa:%d\n",*b); else printf("bbbbbbbbbbbb\n");}为什么在函数test赋值之后b还是null?毛病出在函数test中。编译器总是要为函数的每个参数制作临时副本
阅读全文
04 2011 档案
摘要:生成静态链接库/动态链接库的makefile如下:#CC:=arm-linux-gccCFLAGS := -I..LDFLAGS := -lpthread -lrtSRCS := $(wildcard *.c)ifdef ARCHlibclient := libclient-$(ARCH).aelselibclient := libclient.aendifall: $(libclient) libclient.so$(libclient): client.o net.o $(AR) -rcv $@ $^libclient.so: client.o net.o $(CC) -shared -o
阅读全文
摘要:读取一个文件,类似IP=192.168.1.8NETMASK=255.255.255.0格式的文件,并对文件进行解析,得到其key和value,可以读取相应key的value值,也可以得到配置相应的value;typedef struct item_t { char *key; char *value;}ITEM;/* *去除字符串右端空格 */char *strtrimr(char *pstr){ int i; i = strlen(pstr) - 1; while (isspace(pstr[i]) && (i >= 0)) pstr[i--] = '\0
阅读全文
摘要:同样以触摸屏的适配器tslib中的函数进行描述,如何从当前的环境变量中读取一个环境变量,并利进行文件的解析,下面先对几个程序看几个将要用到的函数:FILE * fopen(const char * path,const char * mode); 函数功能: 打开一个文件 函数原型:FILE * fopen(const char * path,const char * mode); 相关函数:open,fclose,fopen_s[1] ,_wfopen 所需库: <stdio.h> 返回值: 文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回NULL,并把错误代
阅读全文
摘要:在应用程序中经常需要用到打印错误信息的函数,以便我们能更方便地调试。考虑到程序的可扩展性,将对该函数作如下的封装:static int stderrfn(const char *fmt, va_list ap){ return vfprintf(stderr, fmt, ap);}/* * Change this hook to point to your custom error handling function. */int (*ts_error_fn)(const char *fmt, va_list ap) = stderrfn;int ts_error(const char *fm
阅读全文
摘要:linux下加载动态链接库的方法:以下以触摸屏为例:介绍是如何加载一下共享库的。首先让我们看看以下几个函数:dlopen() 功能:打开一个动态链接库 包含头文件: #include <dlfcn.h> 函数定义: void * dlopen( const char * pathname, int mode ); 函数描述: 在dlopen的()函数以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程。使用dlclose()来卸载打开的库。dlclose(handle); 功能:关闭一个动态链接库dlsym() 函数原型: void* dlsym(void* handle,
阅读全文
摘要:12864是128*64点阵液晶模块的点阵数简称,业界约定俗成的简称。一、液晶显示模块概述12864A-1 汉字图形点阵液晶显示模块,可显示汉字及图形,内置 8192 个中文汉字(16X16 点阵,16*8=128,16*4=64,一行只能写 8 个汉字,4 行;、128 个字符(8X16 点阵)及 64X256 点阵显示 RAM(GDRAM))。主要技术参数和显示特性:电源:VDD 3.3V~+5V(内置升压电路,无需负压);显示内容:128 列× 64 行(128 表示点数)显示颜色:黄绿显示角度:6:00 钟直视LCD 类型:STN与 MCU 接口:8 位或 4 位并行/3 位
阅读全文
摘要:#/bin/sh i=0 chapter=$1 book_name=$2 while [ $i != $3 ] do echo "第 $i 正在下载第 $book_name 个文件..." wget http://www.qqshuwu.com/files/article/attachment/5/5759/$chapter/$book_name.gif i=`expr $i + 1` book_name=`expr $book_name + 1` chapter=`expr $chapter + 1` done 本文来自CSDN博客,转载请标明出处:http://blog
阅读全文
摘要:Kobjectskobject是一种数据结构,定义在 。 struct kobject { const char * k_name;/*kobject 的名字数组(sysfs 入口使用的名字)指针;如果名字数组大小小于KOBJ_NAME_LEN,它指向本数组的name,否则指向另外分配的一个名字数组空间 */ char name[KOBJ_NAME_LEN];/*kobject 的名字数组,若名字数组大小不小于KOBJ_NAME_LEN,只储存前KOBJ_NAME_LEN个字符*/ struct kref kref;/*kobject 的引用计数*/ struct list_head entr
阅读全文
摘要:copy_to_user -- Copy a block of data into user space. copy_from_user -- Copy a block of data from user space.get_user -- Get a simple variable from user space. put_user -- Write a simple value into user space. copy_from_userNamecopy_from_user -- Copy a block of data from user space. Synopsisunsigned
阅读全文
摘要:2.4内核中,模块自身通过 MOD_INC_USE_COUNT, MOD_DEC_USE_COUNT宏来管理自己被使用的计数。 2.6内核提供了更健壮、灵活的模块计数管理接口 try_module_get(&module), module_put(&module)取代2.4中的模块使用计数管理宏;模块的使用计数不必由自身管理,而且在管理模块使用计数时考虑到 SMP与PREEMPT机制的影响。 int try_module_get(struct module *module); 用于增加模块使用计数;若返回为0,表示调用失败,希望使用的模块没有被加载或正在被卸载中。 void m
阅读全文
摘要:将创建字符设备的三种方法记录一下,以便以后参考.1. 使用早期的register_chardev()方法#include<linux/kernel.h>#include<linux/module.h>#include<linux/fs.h>#include<asm/uaccess.h>int init_module(void);void cleanup_module(void);static int device_open(struct inode*, struct file*);static int device_release(struct
阅读全文
摘要:功能描述: 获取或者设置与某个套接字关联的选项。选项可能存在于多层协议中,它们总会出现在最上面的套接字层。当操作套接字选项时,选项位于的层和选项的名称必须给出。为了操作套接字层的选项,应该 将层的值指定为SOL_SOCKET。为了操作其它层的选项,控制选项的合适协议号必须给出。例如,为了表示一个选项由TCP协议解析,层应该设定为协议 号TCP。用法:#include #include int getsockopt(int sock, int level, int optname, void *optval, socklen_t *optlen);int setsockopt(int sock.
阅读全文
摘要:开发环境:ubuntu10.04 tq2440第一步sqlite在arm-linux下的编译1、下载sqlite2.8.17:请到http://www.sqlite.org/download.html,将下载的代码包解开,将生成sqlite目录,另外新建一个build目录,如sqlite-arm,再在此目录下建build目录,sqlite-arm应该是和sqlite-2.8.17目录平行的同级目录注:下载的是sqlite-2.8.17.tar.gz2、确认arm-linux-toolchains.tgz已经安装到你的linux系统.3、为了在arm-linux下能正常运行sqlite,我们需要
阅读全文
摘要:1.中断处理的体系结构 我们知道编写设备驱动程序一定要用到中断处理函数,这在驱动程序的编写中,占据很重要的一部分。在响应一个特定的中断的时候,内核会执行一个函数,该函数叫做中断处理程序(interrupt handler)或中断服务例程(interrupt service routine ,ISP).产生中断的每个设备都有一个相应的中断处理程序,中断处理程序通常不和特定的设备关联,而是和特定的中断关联的,也就是说,如果一个设备可以产生多种不同的中断,那么该就可以对应多个中断处理程序,相应的,该设备的驱动程序也就要准备多个这样的函数。在Linux内核中处理中断是分为上半部(top half),和
阅读全文
摘要:异常,就是可以打断CPU正常运行流程的一些事情,比如外部中断、未定义指令、试图修改只读的数据、执行swi指令(Software Interrupt Instruction ,软件中断指令)等。当这些事情发生时,CPU暂停当前的程序,先处理异常事件,然后再继续执行被中断的程序。操作系统中经常通过异常来完成一些特定的功能。其中的中断也占有很大的一部分。例如下面的这几种情况:当CPU执行未定义的机器指令时将触发“未定义指令异常”,操作系统可以利用这个特点使用一些自定义的机器指令,它们在异常处理函数中实现。 当用户程序试图读写的数据或执行的指令不在内存中时,也会触发一个“数据访问中止异常”或“指令预.
阅读全文
摘要:在Linux的用户空间,我们经常会调用系统调用,下面我们跟踪一下read系统调用,使用的Linux内核版本为Linux2.6.37。不同的Linux版本其中的实现略有不同。在一些应用中我们可以看到下面的一些定义:#define real_read(fd, buf, count ) (syscall(SYS_read, (fd), (buf), (count))) 其实真正调用的还是系统函数syscall(SYS_read),也就是sys_read()函数中,在Linux2.6.37中的利用几个宏定义实现。 Linux 系统调用(SCI,system call interface)的实现机制实.
阅读全文
摘要:skb_put() 增长数据区的长度来为memcpy准备空间. 许多的网络操作需要加入一些桢头, 这可以使用skb_push来将数据区向后推, 为头留出空间. 请参见下图: ---------------------------------------- | head | data | | ---------------------------------------- skb_put ----------------------------------------- | head | data | put_data | | ----------------------------------
阅读全文
摘要:Netlink 是一种特殊的 socket,它是 Linux 所特有的,类似于 BSD 中的AF_ROUTE 但又远比它的功能强大,目前在最新的 Linux 内核(2.6.14)中使用netlink 进行应用与内核通信的应用很多,包括:路由 daemon(NETLINK_ROUTE),1-wire 子系统(NETLINK_W1),用户态 socket 协议(NETLINK_USERSOCK),防火墙(NETLINK_FIREWALL),socket 监视(NETLINK_INET_DIAG),netfilter 日志(NETLINK_NFLOG),ipsec 安全策略(NETLINK_XFRM
阅读全文
摘要:系统调用是内核提供给应用程序的接口,应用对底层硬件的操作大部分都是通过调用系统调用来完成的,例如得到和设置系统时间,就需要分别调用 gettimeofday 和 settimeofday 来实现。事实上,所有的系统调用都涉及到内核与应用之间的数据交换,如文件系统操作函数 read 和 write,设置和读取网络协议栈的 setsockopt 和 getsockopt。本节并不是讲解如何增加新的系统调用,而是讲解如何利用现有系统调用来实现用户的数据传输需求。一般地,用户可以建立一个伪设备来作为应用与内核之间进行数据交换的渠道,最通常的做法是使用伪字符设备,具体实现方法是:1.定义对字符设备进行操
阅读全文
摘要:sysctl是一种用户应用来设置和获得运行时内核的配置参数的一种有效方式,通过这种方式,用户应用可以在内核运行的任何时刻来改变内核的配置参数,也可以在任何时候获得内核的配置参数,通常,内核的这些配置参数也出现在proc文件系统的/proc/sys目录下,用户应用可以直接通过这个目录下的文件来实现内核配置的读写操作,例如,用户可以通过cat /proc/sys/net/ipv4/ip_forward 来得知内核IP层是否允许转发IP包,用户可以通过echo 1 > /proc/sys/net/ipv4/ip_forward 把内核 IP 层设置为允许转发 IP 包,即把该机器配置成一个路由
阅读全文
摘要:内核子系统或设备驱动可以直接编译到内核,也可以编译成模块,如果编译到内核,可以使用前一节介绍的方法通过内核启动参数来向它们传递参数,如果编译成模块,则可以通过命令行在插入模块时传递参数,或者在运行时,通过sysfs来设置或读取模块数据。Sysfs是一个基于内存的文件系统,实际上它基于ramfs,sysfs提供了一种把内核数据结构、它们的属性以及属性与数据结构的联系开放给用户态的方式,它与kobject子系统紧密地结合在一起,因此内核开发者不需要直接使用它,而是内核的各个子系统使用它。用户要想使用 sysfs 读取和设置内核参数,仅需装载 sysfs 就可以通过文件操作应用来读取和设置内核通过
阅读全文
摘要:Linux 提供了一种通过 bootloader 向其传输启动参数的功能,内核开发者可以通过这种方式来向内核传输数据,从而控制内核启动行为。通常的使用方式是,定义一个分析参数的函数,而后使用内核提供的宏 __setup把它注册到内核中,该宏定义在 linux/init.h 中,因此要使用它必须包含该头文件:__setup("para_name=", parse_func) para_name 为参数名,parse_func 为分析参数值的函数,它负责把该参数的值转换成相应的内核变量的值并设置那个内核变量。内核为整数参数值的分析提供了函数 get_option 和 get_o
阅读全文
摘要:relayfs是一个快速的转发(relay)数据的文件系统,它以其功能而得名。它为那些需要从内核空间转发大量数据到用户空间的工具和应用提供了快速有效的转发机制。Channel是relayfs文件系统定义的一个主要概念,每一个channel由一组内核缓存组成,每一个CPU有一个对应于该channel 的内核缓存,每一个内核缓存用一个在relayfs文件系统中的文件文件表示,内核使用relayfs提供的写函数把需要转发给用户空间的数据快速地写入当前CPU上的channel内核缓存,用户空间应用通过标准的文件I/O函数在对应的channel文件中可以快速地取得这些被转发出的数据mmap 来。写入到c
阅读全文
摘要:一般地,内核通过在procfs文件系统下建立文件来向用户空间提供输出信息,用户空间可以通过任何文本阅读应用查看该文件信息,但是procfs 有一个缺陷,如果输出内容大于1个内存页,需要多次读,因此处理起来很难,另外,如果输出太大,速度比较慢,有时会出现一些意想不到的情况, Alexander Viro实现了一套新的功能,使得内核输出大文件信息更容易,该功能出现在2.4.15(包括2.4.15)以后的所有2.4内核以及2.6内核中,尤其 是在2.6内核中,已经大量地使用了该功能。要想使用seq_file功能,开发者需要包含头文件linux/seq_file.h,并定义与设置一个seq_opera
阅读全文
摘要:procfs是比较老的一种用户态与内核态的数据交换方式,内核的很多数据都是通过这种方式出口给用户的,内核的很多参数也是通过这种方式来让用户方便设置的。除了sysctl出口到/proc下的参数,procfs提供的大部分内核参数是只读的。实际上,很多应用严重地依赖于procfs,因此它几乎是必不可少的组件。本节将讲解如何使用procfs。Procfs提供了如下API: struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, struct proc_dir_entry *parent)该函数用于创建一个正常的pr
阅读全文
摘要:内核开发者经常需要向用户空间应用输出一些调试信息,在稳定的系统中可能根本不需要这些调试信息,但是在开发过程中,为了搞清楚内核的行为,调试信息非常必要,printk可能是用的最多的,但它并不是最好的,调试信息只是在开发中用于调试,而printk将一直输出,因此开发完毕后需要清除不必要 的printk语句,另外如果开发者希望用户空间应用能够改变内核行为时,printk就无法实现。因此,需要一种新的机制,那只有在需要的时候使用,它在需要时通过在一个虚拟文件系统中创建一个或多个文件来向用户空间应用提供调试信息。有几种方式可以实现上述要求:(1)使用procfs,在/proc创建文件输出调试信息,但是p
阅读全文
摘要:1 引言Linux中的进程间通信机制源自于Unix平台上的进程通信机制。Unix的两大分支AT&T Unix和BSD Unix在进程通信实现机制上的各有所不同,前者形成了运行在单个计算机上的System V IPC,后者则实现了基于socket的进程间通信机制。同时Linux也遵循IEEE制定的Posix IPC标准,在三者的基础之上实现了以下几种主要的IPC机制:管道(Pipe)及命名管道(Named Pipe),信号(Signal),消息队列(Message queue),共享内存(Shared Memory),信号量(Semaphore),套接字(Socket)。通过这些IPC机
阅读全文
摘要:相对于linux来说,udev还是一个新事物。然而,尽管它03年才出现,尽管它很低调(J),但它无疑已经成为linux下不可或缺的组件了。udev是什么?它是如何实现的?最近研究Linux设备管理时,花了一些时间去研究udev的实现。 udev是什么?u 是指user space,dev是指device,udev是用户空间的设备驱动程序吗?最初我也这样认为,调试内核空间的程序要比调试用户空间的程序复杂得多,内核空间的程序的BUG所引起的后果也严重得多,device driver是内核空间中所占比较最大的代码,如果把这些device driver中硬件无关的代码,从内核空间移动到用户空间,自然.
阅读全文
摘要:一、 什么是系统调用 在Linux的世界里,我们经常会遇到系统调用这一术语,所谓系统调用,就是内核提供的、功能十分强大的一系列的函数。这些系统调用是在内核中实现的,再通过一定的方式把系统调用给用户,一般都通过门(gate)陷入(trap)实现。系统调用就是用户空间应用程序和内核提供的服务之间的一个接口。由于服务是在内核中提供的,因此无法执行直接调用;相反,您必须使用一个进程来跨越用户空间与内核之间的界限。在特定架构中实现此功能的方法会有所不同。因此,本文将着眼于最通用的架构 —— i386。二、 系统调用的作用 系统调用在Linux系统中发挥着巨大的作用,如果没有系统调用,那么应用程序就失去了
阅读全文
摘要:1什么是系统调用 系统调用,顾名思义,说的是操作系统提供给用户程序调用的一组“特殊”接口。用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务,比如用户可以通过文件系统相关的调用请求系统打开文件、关闭文件或读写文件,可以通过时钟相关的系统调用获得系统时间或设置定时器等。从逻辑上来说,系统调用可被看成是一个内核与用户空间程序交互的接口——它好比一个中间人,把用户进程的请求传达给内核,待内核把请求处理完毕后再将处理结果送回给用户空间。系统服务之所以需要通过系统调用来提供给用户空间的根本原因是为了对系统进行“保护”,因为我们知道Linux的运行空间分为内核空间与用户空间,它们各自运行在不同的
阅读全文
摘要:去掉Ubuntu桌面硬盘图标:(1)应用程序-附件-终端-输入gconf-editor(相当于“Alt+F2“,弹出对话框输入gconf-editor,点击“运行“)(2)打开后,在窗口左侧依次点开:apps->nautilus->desktop(3)在右边的窗口中找到“volumes_visible”选项,去掉后面的勾Ubuntu窗口关闭、最小化、最大化按钮修改:PS:本人不建议修改,虽然与Windows不同,但感觉这个设计其实挺合理的,软件菜单都在左上角,为什么“关闭、最小化、最大化”这三个按钮非要放在右上角呢?而且如果像Windows一样放在了右上角,就会和Ubuntu关机按
阅读全文
摘要:涉及到很多库的依赖问题。gphoto2 : libusb, libexif, libgphotoptpcam : libusb, libptp经过一天的摸索,终于成功将ptpcam移植到了mini2440的板子上,由于还没有相机,目前还不知道是否成功。但是程序运行没问题。下面记下此次移植的过程:1.下载libptp软件包:http://sourceforge.net/projects/libptp/files/ 下载libusb-0.1.12软件包:http://sourceforge.net/projects/libusb/files/2.分别解压3.进入libusb-0.1.12,交叉编译
阅读全文
摘要:驱动开发向来是内核开发中工作量最多的一块,随着USB设备的普及,大量的USB设备的驱动开发也成为驱动开发者手头上做的最多的事情。本文主要介绍Linux平台下基于libusb的驱动开发,希望能够给从事Linux驱动开发的朋友带来些帮助,更希望能够给其他平台上的无驱设计带来些帮助。文章是我在工作中使用libusb的一些总结,难免有错误,如有不当的地方,还请指正。 Linux 平台上的usb驱动开发,主要有内核驱动的开发和基于libusb的无驱设计。对于内核驱动的大部分设备,诸如带usb接口的hid设备,linux本身已经自带了相关的驱动,我们只要操作设备文件便可以完成对设备大部分的操作,而另外一些
阅读全文
摘要:一、tasklet使用Tasklet的使用比较简单,只需要定义tasklet及其处理函数并将两者关联例子:Void my_tasklet_func(unsigned long)DECLARE_TASKLET(my_tasklet.my_tasklet_func,data)代码DECLARE_TASKLET实现了定义名称为my_tasklet的tasklet并将其与my_tasklet_func这个函数绑定,而传入这个函数的参数为data。需要调度tasklet的时候引用一个tasklet_schedule()函数就能使系统在适当的时候进行调度,如下所示Tasklet_schedule(&
阅读全文
摘要:在编写设备驱动时, tasklet 机制是一种比较常见的机制,通常用于减少中断处理的时间,将本应该是在中断服务程序中完成的任务转化成软中断完成。 为了最大程度的避免中断处理时间过长而导致中断丢失,有时候我们需要把一些在中断处理中不是非常紧急的任务放在后面执行,而让中断处理程序尽快返回。在老版本的 linux 中通常将中断处理分为 top half handler 、 bottom half handler 。利用 top half handler 处理中断必须处理的任务,而 bottom half handler 处理不是太紧急的任务。 但是 linux2.6 以后的 linux 采取了另外一
阅读全文
摘要:(本部分的一些示例源码来自drivers/usb/usb-skeleton.c,它是Linux内核为我们提供的最基础的USB驱动程序,USB骨架程序)驱动程序把驱动对象注册到 USB 子系统中,之后使用供应商(idVendor)和设备(idProduct)标识来判断对应的硬件是否已经安装.驱动的设备支持列表struct usb_device_id 结构提供了这个驱动支持的不同类型 USB 设备的列表. USB 核心通过此列表用来决定设备对应的驱动,热插拔脚本也通过此列表来决定当特定设备被插入系统时,应该自动加载的驱动.struct usb_device_id {/* 确定设备信息去和结构体中哪
阅读全文
摘要:USB 设备驱动代码通过urb和所有的 USB 设备通讯。urb用 struct urb 结构描述(include/linux/usb.h )。urb以一种异步的方式同一个特定USB设备的特定端点发送或接受数据。一个 USB 设备驱动可根据驱动的需要,分配多个 urb 给一个端点或重用单个 urb 给多个不同的端点。设备中的每个端点都处理一个 urb 队列, 所以多个 urb 可在队列清空之前被发送到相同的端点。一个 urb 的典型生命循环如下:(1)被创建;(2)被分配给一个特定 USB 设备的特定端点;(3)被提交给 USB 核心;(4)被 USB 核心提交给特定设备的特定 USB 主机控
阅读全文
摘要:内核使用2.6.29.4 拓扑结构上, 一个 USB 子系统并不是以总线的方式来分布; 它是一棵由几个点对点连接构成的树。这些连接是连接设备和集线器的4线电缆(地, 电源, 和 2 个差分信号线), 如同以太网的双绞线。USB主控制器负责询问每个USB设备是否有数据需要发送。由于这个拓扑结构,一个 USB 设备在没有主控制器要求的情况下不能发送数据. 也就是说:USB是单主方式的实现,主机轮询各外设。但是设备也可以要求一个固定的数据传输带宽,以保证可靠的音视频I/O。USB只作为数据传输通道,对他所收发的数据格式没有特殊的内容和结构上的要求,也就是类似于透传。Linux内核支持两种主要类型的U
阅读全文
摘要:USB 总线引出两个重要的链表! 一个 USB 总线引出两个重要的链表,一个为 USB 设备链表,一个为 USB 驱动链表。设备链表包含各种系统中的 USB 设备以及这些设备的所有接口,驱动链表包含 USB 设备驱动程序(usb device driver)和 USB 驱动程序(usb driver)。 USB 设备驱动程序(usb device driver)和 USB 驱动程序(usb driver)的区别是什么? USB 设备驱动程序包含 USB 设备的一些通用特性,将与所有 USB 设备相匹配。在 USB core 定义了:struct usb_device_driver usb_ge
阅读全文
摘要:最近看到linux的设备驱动模型,关于Kobject、Kset等还不是很清淅。看到了struct device_driver这个结构时,想到一个问题:它的初始化函数到底在哪里调用呢?以前搞PCI驱动时用pci驱动注册函数就可以调用它,搞s3c2410驱动时只要在mach-smdk2410.c中的struct platform_device *smdk2410_devices {}中加入设备也会调用。但从来就没有想过具体的驱动注册并调用probe的过程。于是打开SourceInsight追踪了一下:从driver_register看起:int driver_register(struct dev
阅读全文