【发布时间】:2019-10-28 20:09:06
【问题描述】:
我正在使用微控制器进行一些 ADC 测量。当我尝试使用 -O2 优化编译以下代码时遇到问题,当代码中存在 PrintVal() 函数时,MCU 会冻结。我做了一些调试,结果发现当我添加 -fno-inline 编译器标志时,即使使用 PrintVal() 函数,代码也能正常运行。
这里有一些背景:
AdcIsr.c 包含在 ADC 完成工作时执行的中断。该文件还包含初始化变量的 ISRInit() 函数,该变量将在转换后保存值。在主循环中将等待中断,然后才访问 AdcMeas.value。
AdcIsr.c
static volatile uin16_t* isrVarPtr = NULL;
ISR()
{
uint8_t tmp = readAdc();
*isrVarPtr = tmp;
}
void ISRInit(volatile uint16_t *var)
{
isrVarPtr = var;
}
AdcMeas.c
typedef struct{
uint8_t id;
volatile uint16_t value;
}AdcMeas_t;
static AdcMeas_t AdcMeas = {0};
const AdcMeas_t* AdcMeasGetStructPtr()
{
return &AdcMeas;
}
main.c
void PrintVal(const AdcMeas_t* data)
{
printf("AdcMeas %d value: %d\r\n", data->id, data->value);
}
void StartMeasurement()
{
...
AdcOn();
...
}
int main()
{
ISRInit(AdcMeasGetStructPtr()->value);
while(1)
{
StartMeasurement();
WaitForISR();
PrintVal(AdcMeasGetStructPtr());
DelayMs(1000);
}
}
问题:
使用 const AdcMeas_t* 数据作为 PrintVal() 函数的参数是否有问题?我知道 AdcMeas.value 可能会在中断内部发生变化,并且 PrintVal() 可能已过时。
AdcMeas 包含一个“通用吸气剂”。使用这种函数允许对静态结构进行只读访问是一个好习惯吗?还是我应该实现 AdcMeasGetId() 和 AdcMeasGetValue 函数(注意这个结构只有 2 个成员,如果它有 8 个成员呢?
我知道这段代码有点笨(在while循环中等待中断),这只是一个例子。
【问题讨论】:
-
isrVarPtr是一个指针,但tmp是一个整数。你应该收到isrVarPtr = tmp;的警告 -
也许你的意思是
*isrVarPtr = tmp;? -
@Barmar 对不起,错字,是的,我的意思是
*isrVarPtr = tmp;
标签: c embedded constants volatile