Метка: c
Test Driven Development for Embedded C By James W. Grenning
Непосредственно TDD мне далось с большим трудом. Примерно понимаю что происходит, но не понимаю почему. Зато очень понравилось описание принципов SOLID и подходов к рефакторингу legacy-кода. В целом, очень полезная книга, рекомендую.
Object-Oriented Programming With ANSI-C
О сколько нам открытий чудных…
Узнал как инициализировать массив в Си несколькими повторяющимися значениями:
int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };
Поддерживается только GCC. Источник: https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html
На той же странице есть интересное замечание про инициализацию union из int и float — если явно инициализировать float целочисленной константой, то она будет преобразована к float. Если же привести целое к union, то оно останется целым.
STM8 StdPeriph_Lib: UART1_ITConfig()
Для общего развития ковыряю STM8 + SDCC + StdPeriph_Lib. Дошёл до уарта и обнаружил, что контроллер виснет на инициализации прерываний. Проблема где-то в uart.c:UART1_ITConfig(). Если вместо вызова функции сделать запись в регистр, то инициализация проходит и контроллер начинает работать. Выглядит функция не очень. Особенно меня впечатлила вот такая строка:
itpos = (uint8_t)((uint8_t)1 << (uint8_t)((uint8_t)UART1_IT & (uint8_t)0x0F));
Дело в том, что библиотека универсальная, а контроллеры могут сильно отличаться. Так что функция настройки прерываний сначала выясняет в каком регистре и с каким смещением находится нужный бит. Посчитать в уме что делает этот код я не смог и просто засунул его в сишник на компе, скомпилировал и запустил. Результат - 32, т.е. 5-й бит (RXNE), что сходится с даташитом. Смещение регистра вычисляется проще:
uartreg = (uint8_t)((uint16_t)UART1_IT >> 0x08);
UART1_IT в данном случае равен 0x255, т.е. в итоге мы должны получить 0x02, что тоже верно, флаг лежит в регистре UART1_CR2. Однако что-то всё равно идет не так. В итоге вместо вызова функции написал:
//UART1_ITConfig(UART1_IT_RXNE, ENABLE);
UART1->CR2 |= (uint8_t)UART1_FLAG_RXNE;
Так работает.