原文链接:https://blog.csdn.net/qq_21792169/article/details/50436089
struct i2c_driver {
int (*probe)(struct i2c_client *, const struct i2c_device_id *); //probe函数
struct device_driver driver; //表明这是一个驱动
const struct i2c_device_id *id_table; //要匹配的从设备信息(名称)
int (*detect)(struct i2c_client *, struct i2c_board_info *); //设备探测函数
const unsigned short *address_list; //设备地址
struct list_head clients; //设备链表
};
struct bus_type i2c_bus_type = {
.name = "i2c",
.match = i2c_device_match,
.probe = i2c_device_probe,
.remove = i2c_device_remove,
.shutdown = i2c_device_shutdown,
.pm = &i2c_device_pm_ops,
};
在学习嵌入式我们经常和结构体函数指针打交道,还有链表,环形缓冲区之类的,这里中点讲解结构体中定义函数指针。下面这个程序你看一遍你基本也明白用法了。
下面是我写的一个很简单的程序struct.c
#include /* 标准输入输出头文件 */
#include /* strtoul用到的头文件 */
struct test_pfun { /* 定义一个结构体,里面有三个成员,是三个函数指针 ,前面千万不要加static,这里并没有分配内存*/
int (*add) (int a,int b);
int (*sub) (int a,int b);
int (*mult) (int a,int b);
};
static int test_add(int a,int b) /* 定义求和函数 */
{
return (a+b);
}
static int test_sub(int a,int b) /* 定义相减函数 */
{
return (a-b);
}
static int test_mult(int a,int b) /* 定义乘法函数 */
{
return (a*b);
}
struct test_pfun pfun={ /* 关键的地方时在这里,看怎么函数指针赋值 */
.add =test_add,
.sub =test_sub,
.mult =test_mult,
};
/*
* usage:
* ./a.out num1 num2
*/
void print_uage()
{
printf("./a.out \n " ); /* 打印用法 */
}
int main(int argc,char **argv)
{
int a ,b;
if(argc!=3)
{
print_uage();
return -1;
}
a=strtoul(argv[1],NULL,0); /* 把字符串argv[1]转换成一个整数a */
b=strtoul(argv[2],NULL,0); /* 把字符串argv[2]转换成一个整数b */
/* 不懂strtoul命令的请点击这里:点击这里! */
printf("a+b=%d\n",pfun.add(a,b));
printf("a-b=%d\n",pfun.sub(a,b));
printf("a*b=%d\n",pfun.mult(a,b));
return 0;
}
struct结构体标识符
{
成员变量列表;…
};
struct 结构体标识符 *指针变量名;
变量初始化一:struct结构体标识符 变量名={初始化值1,初始化值2,…, 初始化值n };
struct结构体标识符
{
成员变量列表;…
} *指针变量名;
struct
{
成员变量列表;…
}*指针变量名;
其中“指针变量名”为结构体指针变量的名称。形式1是先定义结构体,然后再定义此类型的结构体指针变量;形式2和形式3是在定义结构体的同时定义此类型的结构体指针变量
最后我在举一个驱动中的典型例子:
struct button_irq_desc { /* 定义一个结构体,只是定义这种类型。再次强调前面不要加上static ,现在还没有分配内存 */
int irq;
unsigned long flags;
char *name;
};
/* 用来指定按键所用的外部中断引脚及中断触发方式, 名字 */
static struct button_irq_desc button_irqs [] = { /* 定义一个button_irq_desc结构体类型名字button_irqs的4元数组,这里就可以加上上static ,你定义变量当然得分配内存空间 */
{IRQ_EINT19, IRQF_TRIGGER_FALLING, "KEY1"}, /* K1 */
{IRQ_EINT11, IRQF_TRIGGER_FALLING, "KEY2"}, /* K2 */
{IRQ_EINT2, IRQF_TRIGGER_FALLING, "KEY3"}, /* K3 */
{IRQ_EINT0, IRQF_TRIGGER_FALLING, "KEY4"}, /* K4 */
};
request_irq(IRQ_EINT0, buttons_irq, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, "S2", &pins_desc[0]);
struct pin_desc * pindesc = (struct pin_desc *)dev_id; /* 强制转换成struct pin_desc *指针,这儿是驱动程序的用法 ,看不懂没有关系*/
这里我们还可以定义结构体指针对数组操作:
static struct button_irq_desc p_irq_desc=button_irqs; / 结构体数组的首地址 */
使用数组中其他选项时候,只需让p_irq_desc这个地址加一,这里加一等于地址加上sizeof(p_irq_desc)。
https://herok.blog.csdn.net/article/details/49048549
https://blog.csdn.net/weixin_42462202/article/details/91128914?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7Edefault-1.queryctr&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7Edefault-1.queryctr&utm_relevant_index=2