Linux内核的一些函数--总结笔记
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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,否则返回一个错误的负数代码。