Я использую микроконтроллер для измерения АЦП. У меня есть проблема, когда я пытаюсь скомпилировать следующий код с помощью оптимизации -O2, MCU зависает, когда в коде присутствует функция PrintVal (). Я сделал некоторую отладку, и оказалось, что когда я добавляю флаг компилятора -fno-inline
, код будет работать нормально даже с функцией PrintVal ().
Вот некоторый фон:
AdcIsr.c содержит прерывание, которое выполняется, когда АЦП завершает свою работу. Этот файл также содержит функцию 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);
}
}
Вопросы:
Что-то не так с использованиемконстантных данных AdcMeas_t * в качестве аргумента функции PrintVal ()? Я понимаю, что AdcMeas.value может изменяться внутри прерывания, а PrintVal () может быть устаревшим.
AdcMeas содержит «универсальный метод получения». Является ли хорошей практикой использование такого рода функций, чтобы разрешить доступ только для чтения к статической структуре? или я должен реализовать функции AdcMeasGetId () и AdcMeasGetValue (обратите внимание, что эта структура имеет только 2 члена, что, если она имеет 8 членов)?
Я знаю, что этот код немного тупой (ожиданиедля прерывания в цикле while), это всего лишь пример.