kolhozing.ru
В началоАвторемонтМоделизмОргтехникаСад и огородЭлектроникаФорум

Программирование STM32 под Linux (Fedora)

Захотелось мне сделать небольшое устройство на МК и выбор остановился на микроконтроллерах семейства STM32, конкретно в виде демоплаты STM32F0 Discovery (об этом выборе, как и о демоплате, будет чуть позже). Так как я использую преимущественно СПО то встал вопрос как с этим микроконтроллером работать под Linux'ом? Оказалось, довольно просто.

Для начала подключаем плату, которая радостно замигает зеленым светодиодом в соответствии с ее тестовой прошивкой и убеждаемся, что ядро ее видит:
$ lsusb | grep -i stm
Bus 001 Device 017: ID 0483:3748 STMicroelectronics ST-LINK/V2
Если все так, то ура! идем дальше. Надо установить кросс-компилятор, отладчик, библиотеки и утилиты работы с st-link. Все, что не ставится из пакетов, а собирается локально, у меня будет лежать в каталоге ~/stm32

Первым делом устанавливаем компилятор с отладчиком и библиотеками:
$ sudo dnf install arm-none-eabi-{gdb,gcc-cs{,-c++},newlib}
Нужно еще поставить binutils, но они поставятся автоматически из зависимостей. Если все прошло гладко, ставим openocd, который будет служить интерфейсом между GDB и st-link для внутрисхемной отладки.
$ sudo dnf install openocd
Если нет ошибок идем дальше и ставим st-link c github'а.
$ mkdir ~/stm32 && cd ~/stm32
$ git clone https://github.com/texane/stlink
$ cd stlink/
$ ./autogen.sh
$ ./configure
$ make
$ sudo cp 49* /etc/udev/rules.d/
$ sudo udevadm control —reload-rules
Следующий и практически последний шаг, открытая библиотека libopencm3, которая содержит функции для работы с периферией микроконтроллера.
$ git clone git://github.com/libopencm3/libopencm3.git
$ cd libopencm3
$ make 
И вот на этом шаге я словил первую багу: в компиляторе нет поддержки cortext-m7, поддержка которого есть в библиотеке. Проверяется это просто:
$ arm-none-eabi-gcc -mcpu=cortex-m7 -mthumb -xc /dev/null
Assembler messages:
Error: unknown cpu `cortex-m7'
Error: unrecognized option -mcpu=cortex-m7
В принципе, для моего проекта это не страшно, М7 я использовать пока не планирую, как и все остальные ядра, которые поддерживаются в библиотеке, поэтому смело меняем в Makefile строку
TARGETS:= stm32/f0 stm32/f1 stm32/f2 stm32/f3 stm32/f4 stm32/f7 \
          stm32/l0 stm32/l1 stm32/l4 \
          lpc13xx lpc17xx lpc43xx/m4 lpc43xx/m0 lm3s lm4f \
          efm32/tg efm32/g efm32/lg efm32/gg \
          sam/3a sam/3n sam/3s sam/3u sam/3x \
          vf6xx
на строку
TARGETS:= stm32/f0 stm32/f1 stm32/f2 stm32/f3 stm32/f4
Остальные цели можно просто закомментировать. После этого библиотека собирается как надо.

Осталось проверить как это все будеть работать. Создаем каталог для тестового проекта
$ mkdir ~/stm32/test && cd ~/stm32/test
Первым делом набираем довольно универсальный make-файл
BINARY = test
DEVICE = stm32f030r8t6

LIBDIR = $(HOME)/stm32/libopencm3
STLINK = $(HOME)/stm32/stlink
CC = arm-none-eabi-gcc
OBJCOPY = arm-none-eabi-objcopy

FLASH = $(STLINK)/st-flash

ifndef CFLAGS
	CFLAGS = -Os
endif
CFLAGS += -mthumb -I$(LIBDIR)/include/

LDFLAGS += -Wl,--gc-sections --static -nostartfiles -lc -lgcc -lnosys -lm
LDFLAGS += -Wl,-Map,$(BINARY).map
LDFLAGS += -L$(LIBDIR)/lib/

LDSCRIPT ?= $(BINARY).ld

SOURCES=$(wildcard *.c *.cpp)
HEADERS=$(wildcard *.h)

all: $(BINARY).bin

SRCLIBDIR = $(LIBDIR)
include $(LIBDIR)/ld/Makefile.linker
LDFLAGS += -T$(LDSCRIPT)

$(BINARY).bin: $(BINARY).elf
	$(OBJCOPY) -Obinary $(BINARY).elf $(BINARY).bin
$(BINARY).elf: $(SOURCES) $(HEADERS) $(LDSCRIPT)
	$(CC) -o $(BINARY).elf $(SOURCES) $(CFLAGS) $(LDFLAGS)
flash: $(BINARY).bin
	$(FLASH) --reset write $(BINARY).bin 0x08000000
clean:
	rm -fv $(LDSCRIPT) $(BINARY).elf $(BINARY).bin $(BINARY).map *.o
В соответствии с этим файлом, все исходные тексты в текущем каталоге будут скомпилированы и собраны с библиотеками в двоичный файл. Имя файла это первая строка, параметр BINARY. Вторая строка задает тип микроконтроллера, на моей демоплате стоит stm32f030r8t6. Если при сборке будет выдана ошибка, значит такой контроллер не знаком библиотеке libopencm3, в которой описаны аппаратные особенности контроллеров, в частности, распределение памяти и размеры RAM/ROM. Третья и четвертая строка это пути до каталогов, в которых вы собрали stlink и libopencm3.

Теперь накидаем небольшой код для проверки, взят практически целиком из примеров к libopencm3 с небольшим изменением: мигать будут оба светодиода подключенные к МК, PC8 синий и PC9 зеленый.
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/cm3/nvic.h>
#include <libopencm3/cm3/systick.h>

int cnt = 0;

/* Called when systick fires */
void sys_tick_handler(void)
{
	if( cnt )
		gpio_toggle(GPIOC, GPIO8);
	else
		gpio_toggle(GPIOC, GPIO9);
	cnt = 1 - cnt;
			
}

/* Set up timer to fire freq times per second */
static void systick_setup(int freq)
{
	systick_set_clocksource(STK_CSR_CLKSOURCE_AHB);
	/* clear counter so it starts right away */
	STK_CVR = 0;

	systick_set_reload(rcc_ahb_frequency / freq);
	systick_counter_enable();
	systick_interrupt_enable();
}

/* set STM32 to clock by 48MHz from HSI oscillator */
static void clock_setup(void)
{
	rcc_clock_setup_in_hsi_out_48mhz();

	/* Enable clocks to the GPIO subsystems */
	rcc_periph_clock_enable(RCC_GPIOC);
	rcc_periph_clock_enable(RCC_GPIOA);
}

static void gpio_setup(void)
{
	/* Select pin functions. PC8/PC9 are the two LEDs on the STM32F0DISCOVERY board. */
	gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO8 | GPIO9);

	/* set GPIOA to AF 0 */
	gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO8);
}

static void mco_setup(void)
{
	/* Enable system clock output on pin PA8 (so it can be checked with a scope) */
	rcc_set_mco(RCC_CFGR_MCO_SYSCLK);
}

int main(void)
{
	clock_setup();
	gpio_setup();
	mco_setup();

	/* setup systick to generate 2 LED flashes per second */
	systick_setup(8);

	/* Do nothing in main loop */
	while (1);
}
Изменения коснулись только функции sys_tick_handler, в которой попеременно переключается состояния то одного, то другого выхода. Компилируем проект (make) и если нет ошибок, прошиваем его в МК (make flash). У меня МК прошился со второго раза, в первый st-flash вылетела с неинформативной ошибкой.
$ make
$ make flash
Если все прошло без ошибок, то радуемся мигающим светодиодам и думаем какую бы еще функциональность добавить к проекту. Но об этом в другой раз.


рубрика: электроника
Комментарии
Руслан
2016.04.27
 
Большое спасибо. Я как-то пробовал собрать но не стал разбираться. А тут всё получилось.
Ваше имя:

Ваше мнение:

введите код:
Пользовательский поиск
 
RSS-канал
Подписка по эл.почте
 
Реклама
 
Рубрики
 
Популярные метки