• 为何gpio_to_irq不能静态使用?【转】


    之前在调试传感器模块的时候发现,在结构体声明的时候irq成员使用gpio_to_irq会报错,而动态使用的话就没有问题。就对gpio_to_irq为什么不能静态使用产生了疑问。恰巧最近又有朋友遇到了同样的问题,也就提醒了我,去找出原因。

    转自:http://blog.csdn.net/airk000/article/details/23339257

    开始测试

    我写了一个简单的linux执行程序进行测试,因为在内核源码中发现不同平台对gpio_to_irq的定义不同,有的是宏定义,而更多的则直接是函数。所以在这个测试程序中我也以这一点作为切入点,进行测试。

    函数

    
    #include <stdio.h>
    
     static int plus_one(int x)
     {
         return (x + 1);
     }
    
     struct test {
         int num;
         char *name;
     };
    
     struct test test1 = { 
         .num = plus_one(5),
         .name = "test",
     };
    
     int main(void)
     {
         printf("%d %s
    ", test1.num, test1.name);
         return 0;
     }

    编译,果然出错了:

    main.c:14:5: error: initializer element is not constant
         .num = plus_one(5),
         ^
    main.c:14:5: error: (near initialization for ‘test1.num’)

    可见,函数是不能作为结构体声明静态使用的。那么改为动态试一试看:

     struct test test1 = { 
         .name = "test",
     };
    
     int main(void)
     {
         test1.num = plus_one(5);
    
         printf("%d %s
    ", test1.num, test1.name);
         return 0;
     }

    编译,通过,能够输出想要的结果。

    结论:函数不能在结构体声明等代码中静态使用,即使函数内容再简单。只能以动态方式使用函数。在Linux内核的omap2平台代码中也印证了这一点,许多设备资源都是在初始化函数中(即资源生效前)进行gpio_to_irq的动态赋值。

     

    宏定义

    使用宏定义代替上述代码中的plus_one函数

    #define plus_one(x) ((x) + 1)
    
    ...
    
     struct test test1 = { 
         .num = plus_one(5),
         .name = "test",
     };
    
     int main(void)
     {
         printf("%d %s
    ", test1.num, test1.name);
         return 0;
     }

    编译,通过,输出我们希望的结果。这证明宏定义可以静态使用,那么动态呢?

     struct test test1 = { 
         .name = "test",
     };
    
     int main(void)
     {
         test1.num = plus_one(5);
    
         printf("%d %s
    ", test1.num, test1.name);
         return 0;
     }

    编译,通过,输出想要的结果。OK,这说明宏定义同样可以进行动态引用。

    结论:宏定义在代码中无论是静态引用还是动态引用均可以。

     

    总结

    通过测试代码可以看出函数的使用有局限性:只能动态引用,而不能静态使用。宏定义就显得友好多了,静态、动态使用均可。回到开始的问题gpio_to_irq为什么不能静态使用?就是因为很多平台代码都将gpio_to_irq实现成为了函数,而非宏定义,这样就只能进行动态引用。但是,这在驱动编写中也不是什么问题,在上面已经说过,只要在设备资源生效前(设备注册前)将其irq动态赋值好就可以了,现有的很多成熟平台也是这样做的,并没有问题。这里我探究这个问题只是因为自己的好奇心而已。

  • 相关阅读:
    十四
    十三
    十二
    十一
    用Linq从一个集合选取几列得到一个新的集合-可改列名
    LINQ入门(完结篇)
    LINQ入门(下篇)
    LINQ入门(中篇)
    LINQ入门(上篇)
    MVC中View往Controllers传数据的方式-已发
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/4992241.html
Copyright © 2020-2023  润新知