Возился тут как-то с RISC-V. Исследовал особенности архитектуры - доступ к CSR, выравнивание, байтовый и пословный доступ. На включении кварца подумалось, а почему бы на Cortex-M в лице STM32 то же самое не делать? Подумано - сделано. Докладываю результаты.
Берём первый попавшийся STM32 и разными способами включаем кварцевый резонатор. Для этого надо установить один бит в регистре RCC_CR.
Большинство (в библиотеках STM скорее всего так же) напишет вот так
Код: Выделить всё
RCC->CR |= RCC_CR_HSEON;
0x4840 LDR.N R0, [PC, #0x100] ; 0x4002'1000
0x6802 LDR R2, [R0]
0xf442 0x3280 ORR.W R2, R2, #65536 ; 0x1'0000
0x6002 STR R2, [R0]
data:
DC32 0x40021000
Хотелось бы оптимальнее. Воспользуемся тем, что мы при включении питания (а по хорошему вообще всегда) знаем полное состояние RCC_CR. И просто запишем это значение с взыдённым битом HSE_ON. Получается так
Код: Выделить всё
RCC->CR = _VAL2FLD(RCC_CR_HSITRIM,16) | RCC_CR_HSION | RCC_CR_HSEON;
0x483f LDR.N R0, [PC, #0xfc] ; 0x4002'1000
0x4a3f LDR.N R2, [PC, #0xfc] ; 0x1'0081 (65665)
0x6002 STR R2, [R0]
data:
DC32 0x40021000
DC32 0x10081
До сегодняшнего дня у меня в коде так и было и кочевало из контроллера в контроллер. Но ведь можно ещё лучше сделать. Попробуем, сработает ли с байтовым доступом?
Код: Выделить всё
*((volatile uint8_t *)&RCC->CR+2) = RCC_CR_HSEON>>16;
0x2201 MOVS R2, #1
0x483e LDR.N R0, [PC, #0xf8] ; 0x4002'1000
0x7082 STRB R2, [R0, #0x2]
data:
DC32 0x40021000
Замечания: 1. Загрузка адреса регистра RCC_CR принадлежит не только операции включения кварца, а всему блоку работы с RCC. Дальше по коду наверняка будет включение PLL и это всё та же байтовая запись в старший байт того же RCC_CR не задевая младших.
2. Не вся периферия поддерживает байтовый доступ. Нужно читать документацию или пробовать.



