- cm3 - аналог CMSIS. Тот самый случай, когда религия противоречит здравому смыслу. Т.е. уже существует полноценная библиотека от создателя процессора, включающая в себя даже функции ЦОС. И в это время авторы проекта пишут её огрызок, только ради того, что бы она стала копилефтной.
- регистры (например stm32/f1/gpio.h) - полный набор макросов на все регистры, эта часть отлажена полностью, ошибок никаких. Вызывает трудности только перемещение по проекту. Например, когда нужно подсмотреть регистры к файлу stm32/f1/flash.h, нужно заглянуть в stm32/common/flash_common_all.h, stm32/common/flash_common_f.h, и stm32/common/flash_common_f01.h. Что не очень то удобно.
- стандартные функции (например rtc_set_prescaler(), gpio_set(GPIOC, GPIO8)) - бывают удобными, повторяют примеры кода из datasheet. Я же предпочитаю писать все то же самое еще раз.
- api - на него даже есть описание, состоящее из doxygen. Как говорят сами разработчики, оно недописано, я же думаю что оно невозможно.
- все остальное (скрипты компоновщика, таблицы векторов прерываний и т.д.)
apt install gcc-arm-none-eabi libnewlib-arm-none-eabi
apt install gdb-multiarch git stlink-tools python
git clone --recurse-submodules https://github.com/libopencm3/libopencm3-template.git your-project
cd your-project
make -C libopencm3
#include "stdint.h"
#include "stdio.h"
#include "stdlib.h"
#include "../libopencm3/include/libopencm3/stm32/rcc.h"
#include "../libopencm3/include/libopencm3/stm32/flash.h"
#include "../libopencm3/include/libopencm3/stm32/gpio.h"
void rough_delay_us(uint16_t us);
void delay_s(uint16_t s);
void sysClk(void);
void rough_delay_us(uint16_t us)
{
volatile uint32_t cnt = (uint32_t)us*(uint32_t)4;
while(cnt-- > 0);
}
void delay_s(uint16_t s)
{
uint16_t cnt = s*20;
while(cnt-- > 0) rough_delay_us(50000);
}
void sysClk()
{
// включаем кварц, ждем пока прогреется
RCC_CR |= (uint32_t)RCC_CR_HSEON;
uint32_t timeout = 1e8;
while ( ((RCC_CR & RCC_CR_HSERDY) == 0) && (--timeout > 1) );
// рассчет на тактирование от кварца 8 мГц, на максимальную частоту в 72 мГц
// AHB, APB1, APB2 36 (разрешенный максимум)
// APB2 36 мГц (для таймеров 72), на АЦП забили, не используем.
uint32_t cfgr = (RCC_CFGR_USBPRE_PLL_CLK_DIV1_5 << 22) \
| (RCC_CFGR_PLLMUL_PLL_CLK_MUL9 << RCC_CFGR_PLLMUL_SHIFT) \
| (RCC_CFGR_PLLXTPRE_HSE_CLK << 17) \
| (RCC_CFGR_PLLSRC_HSE_CLK << 16) \
| (RCC_CFGR_PPRE2_HCLK_NODIV << RCC_CFGR_PPRE2_SHIFT) \
| (RCC_CFGR_PPRE1_HCLK_NODIV << RCC_CFGR_PPRE1_SHIFT) \
| (RCC_CFGR_HPRE_SYSCLK_DIV2 << RCC_CFGR_HPRE_SHIFT);
RCC_CFGR = cfgr;
// что то с памятью, копипаста с функций stmhal
FLASH_ACR |= (uint32_t)FLASH_ACR_PRFTBE;
FLASH_ACR &= ((uint32_t)~FLASH_ACR_LATENCY_MASK);
FLASH_ACR |= (uint32_t)FLASH_ACR_LATENCY_2WS;
// передергиваем PLL, что бы точно все включилось
timeout = 9e6;
if ( (RCC_CFGR & RCC_CFGR_SWS) == (RCC_CFGR_SWS_SYSCLKSEL_PLLCLK << RCC_CFGR_SWS_SHIFT) )
{
RCC_CFGR &= ~((uint32_t)RCC_CFGR_SW);
while ( ((RCC_CFGR & RCC_CFGR_SWS) != (RCC_CFGR_SWS_SYSCLKSEL_HSICLK << RCC_CFGR_SWS_SHIFT) ) && \
(--timeout > 1) );
}
RCC_CR &= ~(uint32_t)(RCC_CR_PLLON);
timeout = 9e6;
while( ((RCC_CR & RCC_CR_PLLRDY) != 0) && (--timeout > 1) );
RCC_CR |= (uint32_t)RCC_CR_PLLON;
timeout = 9e6;
while( ((RCC_CR & RCC_CR_PLLRDY) == 0) && (--timeout > 1) );
// включаем sysclk, ждем
RCC_CFGR |= (uint32_t)(RCC_CFGR_SW_SYSCLKSEL_PLLCLK << RCC_CFGR_SW_SHIFT);
timeout = 9e6;
while( ((RCC_CFGR & RCC_CFGR_SWS) != (RCC_CFGR_SWS_SYSCLKSEL_PLLCLK << RCC_CFGR_SWS_SHIFT)) && (--timeout > 1) );
}
int main(void)
{
// тактирование микроконтроллера
sysClk();
// тактирование порта ввода вывода
RCC_APB2ENR |= (uint32_t)RCC_APB2ENR_IOPBEN;
// сконфигурировать 45 лапку контроллера как выход
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO8);
// цикл дерганья лапкой
while(1){
gpio_clear(GPIOB, GPIO8);
rough_delay_us(1000);
gpio_set(GPIOB, GPIO8);
rough_delay_us(10000);
}
}
target remote localhost:5555
load my-project/awesomesauce.elf
continue
make -C my-project clean
make -C my-project
st-flash erase
xfce4-terminal -e "st-util -p 5555 -n" --tab -e "gdb-multiarch --init-command="initgdb" my-project/awesomesauce.elf"
Комментариев нет :
Отправить комментарий