Linux内核的一些函数--总结笔记

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Linux内核的一些函数

1、MKDEV(ma, mi)

构造设备号,将主设备号和次设备号转换为设备号类型(dev_t)。MKDEV宏将主设备号(ma)左移20位,然后与次设备号(mi)相与,得到设备号。

dev_t结构

主设备号12位次设备号20位

2、int register_chrdev_region(dev_t from, unsigned count, const char *name)

静态分配设备号,成功时返回0;错误时返回一个负的错误码,并且不能为字符设备分配设备号。

from是要分配的设备号范围的起始值,一般只提供from的主设备号,次设备号通常被设置为0。count是需要申请的连续设备号的个数。name是和该范围编号有关的设备名称,该名称不能超过64字节。

3、void unregister_chrdev_region(dev_t from, unsigned count)

释放申请的设备号。from表示要释放的设备号,count表示从from开始要释放的设备号个数。通常,在模块卸载函数中调用unregister_chrdev_region()函数。4、static inline void *kmalloc(size_t size, gfp_t flags)

在物理内存中为程序分配一个连续的存储空间。这个存储空间的数据不会被清零,也就是保存内存中原有的数据。

size表示分配内存的大小,flags是分配标志,可以通过这个标志控制kmalloc()函数的多种分配方式。常用的两种分配标志GFP_KERNEL,GFP_ATOMIC。GFP_KERNEL:内存分配时最常用的方法。当内存不足时,可能会引起休眠;GFP_ATOMIC:在不允许睡眠的进程中使用,不会引起睡眠。

5、void cdev_init(struct cdev *cdev, struct file_operations *fops)

静态初始化cdev设备。将设备结构体与file_operations指针相关联。事例如下:cdev_init(&my_cdev->cdev, &dsp2arm_fops); // 初始化cedv设备

my_cdev->cdev.owner = THIS_MODULE; // 使驱动程序属于该模块

my_cdev->cdev.ops = &dap2arm_fops; // cdev连接file_operations指针

6、int cdev_add(struct cdev *p, dev_t dev, unsigned count)

将字符设备注册到系统中(加入到内核中)。传入cdev的指针、起始设备编号、设备编号范围。如:cdev_add(&my_cdev->cdev, dev, 1)。

7、void cdev_del(struct cdev *p)

注销字符设备。如cdev_del(&my_cdev->cdev)。

8、void kfree(void *_ptr)

释放内存,释放的内存必须是kmalloc()申请的。

9、void ioremap(unsigned long phys_addr, unsigned long size)

将外部设备的I/O端口物理地址映射到虚拟地址。ioremap()函数接收一个物理地址和一个整个I/O端口的大小,返回一个虚拟地址,这个虚拟地址对应一个size 大小的物理地址空间。

10、void iounmap(volatile void __iomem *addr)

释放ioremap()函数申请的虚拟地址。iounmap()函数接收ioremap()函数申请的虚拟地址作为参数,并取消物理地址到虚拟地址的映射。

11、init_waitqueue_head(wait_queue_head_t *q)

一个等待队列必须初始化才能被使用,(动态)初始化一个等待队列。例如:wait_queue_head_t wait;

init_waitqueue_head(&wait);

12、wait_event_interruptible(wq, condition)

调用该函数在等待的过程中当前进程会被设置为TASK_INTERRUPTIBLE状态,意味着该进程将不会继续运行直到被唤醒,然后被添加到等待队列wq中。

在wait_event_interruptible()中首先判断condition是不是已经满足,如果条件满足则直接返回0,否则调用__wait_event_interruptible(),并用__ret来存放返回值。13、void wait_up_interruptible(wait_queue_head_t *q)

唤醒q指定的注册在等待队列上的进程。该函数不能直接的立即唤醒进程,而是由调度程序转换上下文,调整为可运行状态。q:等待队列变量指针。该函数只能唤醒TASK_INTERRUPTIBLE状态的的进程。

14、void init_timer(struct timer_list *timer)

初始化timer结构体变量,使其能够注册到内核定时器目录上。函数init_timer()主要设置该内核定时器归属系统中哪一个处理,并初始化内核定时器链表指针的next 域为NULL。其中,变量timer为内核定时器上注册的结构体的数据地址。

15、container_of(ptr, type, member)

通过一个结构变量中一个成员的地址找到这个结构体变量的首地址。ptr、type、member分别代表指针、类型、成员。例如:

struct test{int i; int j; char k}; struct test temp;

container_of(&temp.j, struct test, j);

通过temp.j的地址找到temp的首地址。

16、int request_irq(unsigned int irq, irq_handler_t handler, unsigned long irqflags,

const char *devname, void *dev_id)

用于申请中断线。irq表示要申请的中断号;handler表示要注册的中断处理函数指针,当中断发生时,内核会自动调用该函数;irqflags表示关于中断处理的属性,内核通过这个标志可以决定该中断应该如何处理;devname表示设备的名字;

dev_id这个指针是为共享中断线而设立的,如果不需要共享中断线,那么只要将该指针设为NULL即可。

request_irq()函数成功返回0,错误时返回-EINVAL(Invalid argument)或者-ENOMEM(out of memory)。

17、enable_irq(unsigned int irq)

置当前系统指定的中断号可用。

18、void poll_wait(struct file *filp, wait_queue_head_t *queue, poll_table *wait)将当前进程添加到wait参数指定的等待列表(poll_table),这个函数不会引起阻塞,用在select系统调用中。

19、int remap_pfn_range(struct vma_area_struct *vma, unsigned long virt_addr,

unsigned long pfn, unsigned long size, pgprot_t prot)

函数功能是一次性建立新的页表去映射物理地址(创建页表),映射成功时返回0,否则返回一个错误的负数代码。

相关文档
最新文档