首页 > 代码库 > linux驱动开发要知道的那些知识(三)------container_of,定时器 及系统调用

linux驱动开发要知道的那些知识(三)------container_of,定时器 及系统调用

container_of

定义:

/**

 * container_of - cast a member of a structure out to the containing structure

 * @ptr:the pointer to the member.

 * @type:the type of the container struct this is embedded in.

 * @member:the name of the member within the struct.

 *

 */

#define container_of(ptr, type, member) ({\

const typeof(((type *)0)->member) * __mptr = (ptr);\

(type *)((char *)__mptr - offsetof(type, member)); })

#endif

 

第一步:

      Const typeof (((type *)0->member) * __mptr=(ptr)

         Struct list_head *__mptr=ptr

第二步:

       (type *)(char *)__mptr -offsetof(type,menber)

        0x***-offset

第三步:offsetof(type,member)

             ((TYPE *)0)->MEMBER

                  &(TYPE *)0)->MENBER

 

 

 

 

 

内核定时器

时钟中断

HZ:常数决定了时钟发生的频率

Tick:发生时间中断的时间间隔tick=1/HZ

Jiffies:核心变数,

struct timer_list

{

unsigned long expires;超时时间

void *function)(unsigned long0)处理函数

unsigned long data;内核调用超时处理函数时传递给它的参数

 

}

静态初始化

TIMER_INITALIZER(_function,_expires,_data)

DEFINE_TIME(_name,_function,_expires,_data);

_name 待定义的内核定时器变量名称

Void init_timer(struct timer_list *timer);

 

修改定时器

技术分享

 

 

 

init_timer(time)初始化定时器,传地址

#define BARK_TIMER  5

#deifne BARK_DATA  100

Xxx.expires = jiffies+HZ*BARK_TIMER;//BARK_TIMER=5五秒

Xxx.function=xxxxxx

Xxxx.data=http://www.mamicode.com/BARK_DATA;

Add_timer(&xxxxx

 

del_timer()

 

 

 

 

2系统调用

 ANSI C fopen(标准c的库函数)

UNIX C  open (系统调用)

 

 

用户态的程序一般情况是不能访问内核态的资源,只有通过中断或者系统调用才能从用户态进入内核态

 

 

2.6.35366个内核系统调用为应用程序服务。

系统调用的原理:

应用程序首先使用适当的值填充寄存器,然后调用一个特殊的指令,跳转到内核某个固定的位置,内核根据应用程序所填充的固定值来找到相应的函数执行。

适当的值:arch/arm/asm/unistd.h

调用特殊指令 arm->SWI(软中断)

              X86  0x80

固定位置:在arm体系中,应用程序跳转到entry-conmmon ->vector_swi ->会用到sys_call_table(calls.S)

 

 

用户空间编程 fd=openaa.txt...

            5->寄存器  

             SWI

      ____________________

            vector_swi

                 sys_call_table[5]

                       sys_open  

                             SYSCALL_DEFINR3  拼接   

 

1)添加新的内核函数

   vim arch/arm/kernel/sys_arm.c

   Asmlinkage int sys_add(int x,int y)

   {

        printk(entry sys_add!\n);

        Return x+y;

}

2)更新头文件 arch/arm/include/asm/unistd.h

      #define __NR_add    (__NR_SYSCALL_BASE+366)

  3)更新系统调用表(calls.S

CALL(sys_add)

 最后make下即可


本文出自 “毛散人” 博客,请务必保留此出处http://songmao.blog.51cto.com/11700139/1876960

linux驱动开发要知道的那些知识(三)------container_of,定时器 及系统调用