原子操作 不可分割的指令;有原子整数操作和原子位操作之分;
自旋锁 只能被一个线程持有的锁机制,如果该所被其他线程持有,本进程将会进入死循环等待所持有线程的释放, 如果没有被其他线程持 有,则本线程会继续执行下去;自旋锁是为了防止多个执行线程同时进入临界区;
信号量 它是一种睡眠锁,如果 有一个任务试图获得一个已经被占有的信号量时,信号量会将其推进一个等待队列, 然后让其睡眠,这时处 理器能重获自由,从而去执行其他的代码。当持有信号量的进程将信号量 释放后, 处于等待队列中的那个任务将被唤醒,并获得该 信号量。
#include <linux/param.h>
HZ HZ符号指出每秒钟产生的时钟滴答数。
volatile unsigned long jiffies jiffies变量每个时钟滴答后加1;因此它每秒增加1个HZ。
#include <linux/time.h>
void do_gettimeofday(struct timeval *tv); 该函数返回当前时间。1.2版的内核并不提供。
#include <linux/delay.h>
void udelay(unsigned long usecs); udelay函数延迟整数数目的微秒数,但不应超过1毫秒。
扫描二维码关注公众号,回复: 1094972 查看本文章#include <linux/tqueue.h>
void queue_task(struct tq_struct *task, task_queue *list);
void queue_task_irq();
void queue_task_irq_off();
这些函数注册延迟执行的任务。第一个函数,queue_task,总是可以被调用;第二个函数只能在不可重入的函数内被调用,而最后一个函数只有在关闭中断后才能被调用。新近的内核只提供第一种函数接口了。
void run_task_queue(task_queue *list); 该函数运行任务队列。
task_queue tq_immediate, tq_timer, tq_scheduler; 这些预定义的任务队列在每个时钟滴答后并在内核调度新的进程前尽快地分别得到执行。
#include <linux/timer.h>
void init_timer(struct timer_list *timer); 该函数初始化新分配的定时器队列。
void add_timer(struct timer_list * timer); 该函数将定时器插入待处理的定时器的全局队列。
int del_timer(struct timer_list *timer);
del_timer函数将定时器从挂起的定时器队列中删除。如果队列中有该定时器,del_timer返回1,否则返回0。
中断机制:硬件设备在产生事件的时候向内核发送信号(变内核主动为硬件主动)的机制;#include <linux/interrupt.h>int request_irq(unsigned int irq, irq_handler_t handler, unsigned long irqflags, const char *devname, void *dev_id)
irq: 中断号 arch/arm/plat-s3c64xx/include/plat/irqs.hhandler: 中断处理函数指针 irqreturn_t handler(int irq, void *dev_id);irqreturn_t: See include/linux/irqreturn.hirqflags: See line 21-59 in include/linux/interrupt.h 使用IRQF_SHARED共享irq时, irqflags必须相同
#include <asm/signal.h> =============== request_irq函数的标志SA_INTERRUPT:要求安装一个快速的处理例程;SA_SHIRQ:安装一个共享的处理例程;SA_SAMPLE_RANDOM:中断时间戳可用来生产系统熵;
如: request_irq(IRQ_EINT(0), handler1, IRQF_TRIGGER_FALLING | IRQF_SHARED, "dev1", &dev1);request_irq(IRQ_EINT(0), handler2, IRQF_TRIGGER_FALLING | IRQF_SHARED, "dev2", &dev2);dev_id: 发生中断时将dev_id传递给handler函数, irqflags含有IRQF_SHARED时dev_id不能为NULL, 并且要保证唯一 dev_id 一般采用当前设备的结构体指针devname: 设备名, cat /proc/interrupts
注:不能在中断上下文和不允许阻塞的代码中调用request_irq()函数;kmalloc()函数是会休眠的函数。
void free_irq ( unsigned int irq, void * dev_id); 释放匹配irq和dev_id的中断, 如果irq有多个相同的dev_id, 将释放第一个 So, 共享中断的dev_id不是唯一时, 可能会释放到其它设备的中断
启用可禁止单个指定的中断void disable_irq(unsigned int irq); 关闭指定irq号中断 (当前所有正在处理程序退出后才能返回)void enable_irq(unsigned int irq); 开启指定irq号中断 使用共享处理例程的驱动不能使用这两个函数;
无条件启动和禁止当前CPU的中断void local_irq_disable(void); 无条件关闭当前CPU中断void local_irq_enable(void); 无条件开启当前CPU中断
无条件启动和禁止当前CPU的中断,但是保存和恢复当前状态flagvoid local_irq_save(unsigned long flags); 关闭当前CPU中断并保存当前状态到flagsvoid local_irq_restore(unsigned long flags); 传递flags保存的先前中断状态到当前CPU
in_interrupt(); 如果在中断上下文中,则返回非0;如果在进程上下文中,则返回0;in_irq(); 如果当前正在执行的中断处理程序,则返回非0,否则返回0;注: 没有关闭和开启所有CPU中断的函数(没必要);