如何在一行源代码中包含几行 C 代码 (AVR-GCC)



有没有办法添加一个编译器会用多行代码替换的标识符?

我阅读了宏和内联函数,但无处可去。

我需要编写一个中断服务例程,而不是调用任何函数来提高速度。 麻烦的是我有几种情况需要使用一个函数,所以目前我只是在很多地方重复所有几行。

例如:

void ISR()
{
int a = 1;
int b = 2;
int c = 3;
// do some stuff here ...
int a = 1;
int b = 2;
int c = 3;
// do more stuff here ...

int a = 1;
int b = 2;
int c = 3;
}

该函数有很多页,我需要代码更具可读性。

我基本上同意其他人对使用宏的保留意见。 但是,为了回答您的问题,可以使用反斜杠创建多行宏。

#define INIT_VARS 
int a = 1;    
int b = 2;    
int c = 3; 
#define RESET_VARS 
a = 1;         
b = 2;         
c = 3; 
void ISR()
{    
INIT_VARS
// do some stuff here ...
RESET_VARS
// do more stuff here ...
RESET_VARS
}

您可以使用inline函数,该函数将集成到源代码中调用的位置,而不是真正被调用(请注意,其行为取决于几个因素,例如编译器支持和优化设置或使用-fno-inline标志功能(。关于内联函数的 GCC 文档。

为了完整性 - 另一种方法是将// do some stuff here...定义为预处理器宏,该宏再次插入到调用的位置; 这次由预处理器 - 所以没有类型安全,更难调试和阅读。通常的好经验法则是不要为可以用函数完成的事情编写宏

您是对的 - 建议您不要在 ISR 中进行函数调用。这并不是说你不能这样做,但根据调用的类型,这可能是一种内存负担。主要原因是时间安排。ISR 应快速进出。你不应该在它们里面做很多扩展的工作。

也就是说,以下是实际使用内联函数的方法。

// In main.c
#include static_defs.h
//...
void ISR() {
inline_func();
// ...
inline_func();
}
// In static_defs.h
static inline void inline_func(void) __attribute__((always_inline));
// ... Further down in file
static inline void inline_func(void) {
// do stuff
}

编译器基本上只会将"做事"代码多次粘贴到 ISR 中,但正如我之前所说,如果它是一个复杂的函数,那么在单个 ISR 中多次执行此操作可能不是一个好主意,无论是否内联。最好设置某种标志并在主循环中执行此操作,以便其他中断也可以完成其工作。然后,您可以使用普通函数来节省程序内存空间。这取决于你真正在做什么以及何时/为什么需要完成。

如果您实际上正在设置变量并返回值,那也很好,尽管设置多个变量可以通过传递/返回结构或使用指向描述所有相关变量的结构的指针来完成。


如果你更喜欢使用宏(我不会,因为应该避免使用类似函数的宏(,这里有一个例子:

#define RESET_VARS() do { 
a = 1; 
b = 2; 
c = 3; 
while (0)
//...
void ISR() {
uint8_t a=1, b=2, c=3;
RESET_VARS();
// ...
RESET_VARS();
}

另外,您说这是一个假设,但建议使用中找到的位宽 typedefs(当您包含时会自动包含,例如 uint8_t 而不是 int。在具有 AVR-GCC 的 8 位 MCU 上,int 是一个 16 位有符号变量,对于每个使用 8 位变量的操作,都需要(至少(2 个时钟周期。

最新更新