1.内核中的XXX_ioctl(struct file *file, unsigned int cmd, unsigned long arg)与HAL中的ioctl(int fd, int request, void *arg)是对应的。
HAL层在调用ioctl时候,fd为之前打开某设备的文件描述符,request为需求的某命令(一般这个命令是在内核的xxx_ioctl函数中switch case的条件),arg为相关参数。
2.copy_to_user(void __user *to, const void *from, unsigned long n)和copy_from_user(void *to, const void __user *from, unsigned long n)
*to,即希望复制某数据到的目的地地址
*from,即数据来源地地址,const也代表这个地址一定是固定的。
n,复制数据的长度(一般用sizeof()计算)
大概作用就是将*from地址的内容复制n个字节到*to所指地址处。
3.cpu_to_be32()/be32_to_cpu()/cpu_to_le32()/le32_to_cpu()
The cpu_to_be32()
family (where the "32" can be replaced by 64 or 16, and the "be" can be replaced by "le") are the general way to do endian conversions in the kernel: they return the converted value. All variations supply the reverse as well: be32_to_cpu()
, etc.
There are two major variations of these functions: the pointer variation, such as cpu_to_be32p()
, which take a pointer to the given type, and return the converted value. The other variation is the "in-situ" family, such as cpu_to_be32s()
, which convert value referred to by the pointer, and return void.
4.container_of
元素1为结构体1中的元素,则可以通过container_of由元素1获取结构体1的指针,从而使用结构体1中的其他成员,例:
struct sample {
int num;
char *name;
}sample1;
...
struct sample tmp;
int num-x;
char *name-x;
num-x = sample1->num;
...
tmp = container_of(num-x, struct sample, num);
/* so ↓*/
name-x = tmp->name;
5.i2c driver & device
触发probe的条件:
1)注册总线信息,如:
static struct i2c_board_info i2c0_info[] __initdata =
{
I2C_BOARD_INFO("sample2", 0x0D)
...
}
i2c_register_board_info(I2C_XXX_ID, i2c0_info, ARRAY_SIZE(i2c0_info));
2)执行i2c_add_driver,如:
static struct i2c_driver sample2_driver = {
.probe= sample2_probe,
.remove= sample2_remove,
.id_table= sample2_id,
.driver= {
.name= "sample2",
},
}
...
i2c_add_driver(&sample2_driver);
...
6.strcpy, strncpy, strlcpy
strcpy, strncpy已经加入到unix库中作为公开支持,strlcpy还未。
strcpy以"/0"为结束标准,但是有溢出的危险,所以引出了strncpy;
strncpy可以指定拷贝长度,但是拷贝完后却没有加入"/0",可能在不注意的时候给混合使用造成麻烦而不好察觉;
strlcpy作为补全strncpy,可以指定长度,且在拷贝完后会自动加入"/0",避免混合使用造成的意外状况。