为何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\n", 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\n", 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\n", test1.num, test1.name);
     return 0;
 }

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

 struct test test1 = { 
     .name = "test",
 };

 int main(void)
 {
     test1.num = plus_one(5);

     printf("%d %s\n", test1.num, test1.name);
     return 0;
 }

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

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

 

总结

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








本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/sky-heaven/p/4992241.html,如需转载请自行联系原作者


相关文章
|
Perl
PYNQ-关于PYNQ的GPIO的使用(RPI接口和arduino接口)或者常用的IO设备(如UART SPI IIC TIMER)
PYNQ-关于PYNQ的GPIO的使用(RPI接口和arduino接口)或者常用的IO设备(如UART SPI IIC TIMER)
660 0
PYNQ-关于PYNQ的GPIO的使用(RPI接口和arduino接口)或者常用的IO设备(如UART SPI IIC TIMER)
|
传感器 开发工具 C语言
EXTI外部中断介绍(内置1.中断系统+2.中断执行流程+3.STM32中断+4.NVIC基本结构+5.NVIC优先级分组+6.EXTI简介+7.EXTI基本结构...)
EXTI外部中断介绍(内置1.中断系统+2.中断执行流程+3.STM32中断+4.NVIC基本结构+5.NVIC优先级分组+6.EXTI简介+7.EXTI基本结构...)
330 0
EXTI外部中断介绍(内置1.中断系统+2.中断执行流程+3.STM32中断+4.NVIC基本结构+5.NVIC优先级分组+6.EXTI简介+7.EXTI基本结构...)
|
1月前
|
存储 数据管理 数据处理
处理STM32 DMA方式下的HAL_UART_ERROR_ORE错误
通过正确配置UART和DMA、实现有效的错误处理回调函数以及优化数据处理和缓冲区管理,可以有效处理STM32中DMA方式下的 `HAL_UART_ERROR_ORE`错误。这些方法确保了数据的高效传输和处理,避免了因数据溢出导致的通信中断和数据丢失。希望这些解决方案能够帮助您在实际应用中更好地应对和解决此类问题。
252 0
|
7月前
|
C语言 芯片
LED 底层原理 和 GPIO引脚、寄存器操作
LED 底层原理 和 GPIO引脚、寄存器操作
LED 底层原理 和 GPIO引脚、寄存器操作
|
6月前
经验大分享:STM32F4寄存器初始化系列:GPIO
经验大分享:STM32F4寄存器初始化系列:GPIO
36 0
|
7月前
|
芯片
STM32 GPIO工作原理详解
STM32 GPIO工作原理详解
117 0
|
7月前
看看FIQ和IRQ
看看FIQ和IRQ
142 0
|
7月前
|
Linux API 开发者
设备树知识小全(九):GPIO、时钟、pinmux连接
设备树知识小全(九):GPIO、时钟、pinmux连接
355 0
|
移动开发 API
STM32使用HAL库操作GPIO
使用HAL库的优点在于不用手动添加初始化的代码了,CubeMX会根据软件设置自动生成
242 0
|
芯片
stm32-HAL使用stop模式后DMA初始化的问题
stm32-HAL使用stop模式后DMA初始化的问题
281 1
stm32-HAL使用stop模式后DMA初始化的问题