#c #crash #embedded #stm32
Вопрос:
У меня есть следующий макрос, который я использую для чтения одного бита в регистре на моем STM32F091:
#define GET_BIT(reg, pos) (((reg)>>(pos))amp;0x00000001u)
Я должен использовать этот макрос с этими двумя параметрами:
#define FLASH_KEYR (*((u32_t *)(0x40022004u)))
#define BSY_FLASH_SR_POS (0u)
У меня нет никаких проблем с использованием этого макроса для оценки одной переменной, такой как:
uint32_t value = GET_BIT(FLASH_SR, BSY_FLASH_SR_POS);
Но, используя этот макрос в условном операторе, подобном этому:
while (GET_BIT(FLASH_SR, BSY_FLASH_SR_POS) == 1u);
Микропроцессор переходит в ISR для сбоя.
…Почему?
Комментарии:
1. Что такое FLASH_SR — т. е. показать определение (не объясняйте, что делает регистр SR). Waht-это АДРЕС РЕГИСТРАЦИИ
2. почему
0x00000001u
вместо простого1
3. @Toad __ —
GET_BIT(((REGISTER_ADDRESS)>>(FIELD_POSITION))amp;0x00000001u)
недопустимый вызов макроса с 2 аргументамиGET_BIT(reg, pos)
.4. Вызов, о котором вы говорите, работает, не совпадает с тем, что вы говорите, прерывается, поэтому вполне вероятно, что это не имеет ничего общего с «если» или «пока», а скорее с параметрами. В любом случае это ужасная идея. Вместо того, чтобы использовать макрос положения бита, используйте макрос битовой маски (вероятно, уже определенный в заголовке чипа) и протестируйте бит напрямую или используйте адрес битовой полосы для прямого считывания бита.
5. Итак, вы хотели изменить адрес регистрации или значение регистра? Что вы на самом деле делаете и имеет ли это смысл семантически, будет зависеть от определения FLASH_SR. Макросы плохи, потому что они запутывают семантику кода. Чтобы отладить его, вы должны рассмотреть полное расширение и определить, является ли оно синтаксически и в данном случае семантически правильным.
Ответ №1:
Проблема в том, что вы заново изобретаете колесо, и оно вышло неправильно.
Вместо того, чтобы помочь вам заново изобрести еще одно новое колесо, вот существующее колесо, которое ST уже сделал для вас:
#include "stm32f0xx.h"
...
while ((FLASH->SR amp; FLASH_SR_BSY) != 0);
Комментарии:
1. Нет, я не изобретаю колесо заново, потому что я не могу использовать библиотеку ST в этом критически важном для безопасности проекте
2. Я много работал над программным обеспечением IEC-62304 для медицинских устройств и проектами в области транспортных средств/военных. Любой аудитор с половиной клетки мозга доверял бы заголовкам определения регистра устройства от производителя оборудования, которые используются в тысячах проектов гораздо больше, чем все, что вы когда-либо могли написать. То же самое не относится к библиотекам STL или HAL, но вы, несомненно, должны использовать заголовки. Это подтверждается тем фактом, что вы не можете заставить его работать и просите случайных незнакомцев в Интернете о помощи в чем-то, что должно иметь решающее значение для безопасности.
3. Чтобы быть конкретным в отношении SMT32: эти заголовки определяют регистры как структуры, а ANSI-C не определяет объем памяти таких конструкций, лучше вообще их не использовать. В общем: я просто пишу некоторые периферийные драйверы, ничего сложного. Более того, вы можете забыть, что я нахожусь на STM32, этот вопрос является общим («почему этот код не работает»).
4. Вы не используете «какой-либо компилятор в целом». Вы используете компилятор, совместимый с ARM EABI, или должны им быть. Поместите ссылку на стандарт ARM EABI в пакет документации по проверке компилятора, а затем вы можете положиться на формальное определение упаковки структуры. Посмотрите на ISO14971 управление рисками для медицинских устройств (или эквивалент в вашей отрасли). Риск изобретения колеса всегда выше, чем делать это стандартным способом и предоставлять надлежащую документацию о том, почему действует стандартный способ.
Ответ №2:
Если вы настаиваете на изобретении колеса, то причина, по которой оно не работает в цикле, заключается в том, что вы упустили изменчивость из приведения указателя.
Мой другой ответ по-прежнему является правильным профессиональным (особенно в критических условиях безопасности), но из комментариев следует, что это ответ, который вы предпочли бы принять.