STM8L–Первый старт

24 Января 2011 К комментариям

Сегодня по плану первый старт с демо платой STM8L-Discovery. В рамках которого хочется рассказать о том как самостоятельно создать простенький проект и прошить его. Что из этого получится посмотрим…

008

Введение

Ранее я писал что предлагаемые IDE меня не устраивают, уж больно сильно я подсел на Eclipse. Отказ ведет к потере автоматизма, в связи с чем придется собирать все ручками, но данный процесс меня устраивает. Однако это не мешает Вам использовать решения “по умолчанию”.

Cosmic

В состав пакета входят компилятор и компоновщик (линкер), задача компилятора прочитать наш программный код и сформировать из них набор инструкций, которые компоновщик соберет в конечный выходной файл годный для заливки в МК.

Исходя из того нам нужно каким-то образом объяснить компоновщику как устроен наш МК, т.е. написать некий сценарий (указать сколько у нас флеш и ОЗУ, по каким адресам расположены, а так же указать куда что «положить»).

Кроме того нужно выполнить начальную инициализацию МК.

Сценарий

Необходимый минимум информации который должен содержать сценарий:

  • расположение и размер флеш, ОЗУ и EEPROM
  • расположение кода, данных
  • размер и расположение стека

Шаблон сценария идёт в комплекте с компилятором, файл располагается в корневой директории Stm8lkf.lkf. Я немного скорректировал его, и добавил комментарии:

#==========================================================
#	File:	Linker Script File for STM8L152C6
#	Date:	2011-01-22
#==========================================================

# флеш: константы
+seg .const -b 0x8080 -m 0x7f80  -n .const -it

# флеш: программный код
+seg .text -a .const  -n .text

# EEPROM
+seg .eeprom -b 0x1000 -m 0x400  -n .eeprom

# ОЗУ: нулевая страница
+seg .bsct -b 0x0 -m 0x100  -n .bsct 
+seg .ubsct -a .bsct  -n .ubsct 
+seg .bit -a .ubsct  -n .bit -id 
+seg .share -a .bit  -n .share -is

# ОЗУ:
+seg .data -b 0x100 -m 0x4ff  -n .data 
+seg .bss -a .data  -n .bss 

#----------------------------------------------------------

# начальная инициализация
crtsi0.sm8

# исходники
target/main.o
target/lcd_nokia_1100.o

# библиотеки
libis0.sm8
libm0.sm8

# таблица прерываний
+seg .const -b 0x8000 -k
target/stm8_interrupt_vector.o

# определения используются при начальной инициализации
+def __endzp=@.ubsct
+def __memory=@.bss
+def __startmem=@.bss
+def __endmem=0x5fe
+def __stack=0x7ff

Формат файла довольно прост, необходимо указать распределение памяти: флеш, EEPROM, ОЗУ. Далее перечислить исходники: код начальной инициализации, ваши исходники, файлы библиотек и таблицу прерываний. В заключении описаны определения необходимые для начальной инициализации микроконтроллера.

Начальная инициализация

В отличии от STM32, здесь я решил воспользоваться файлами идущими в комплекте с компилятором. На выбор имеются несколько вариантов начальной инициализации:

Название файла Краткое описание
crts.sm8 crts0.sm8 Инициализация стека, передача управления основной программе
crtsif.sm8 crtsx.sm8 crtsx0.sm8 crtsxf.sm8 Инициализация стека, инициализация переменных, передача управления основной программе

Наличие нескольких файлов с инициализацией переменных обусловлено структурой памяти, например файлы с именами заканчивающимися нулем предназначены для приложений с размером кода менее 64 кБ (при этом файлы библиотек так же должны заканчиваться “нулем”). Более подробно можно почитать в документации: C Cross Compiler User’s Guide for ST Microelectronics STM8, раздел Programming Environments.

Makefile

Все необходимое для сборки проекта у нас есть, можно приступить к майк-файлу. Долго не мудрил взял готовый от проекта на STM32 и поправил только под текущий компилятор. Вот что получилось:

>#==========================================================
#	File:	Makefile for STM8
#	Date:	2011-01-22
#==========================================================

SRC_C  = main.c
SRC_C += stm8_interrupt_vector.c
SRC_C += lcd_nokia_1100.c

#----------------------------------------------------------

CROSS_PATH = C:/Tools/Cosmic/4.3.4

CROSS = $(CROSS_PATH)/

INCLUDES += -imcu
INCLUDES += -imcu/peripherals
INCLUDES += -iutility

VPATH += mcu
VPATH += mcu/peripherals
VPATH += utility

#----------------------------------------------------------

FLAGS_C  = +warn +mods0 -pxp -pp -l

#----------------------------------------------------------

all: clean target.elf

%.elf: $(SRC_C:%.c=target/%.o)
	@echo Linking: $@
	@echo '-----------------------------------------------------------'	
	@$(CROSS)clnk -l'$(CROSS_PATH)/Lib' -o'target/target.sm8' -m'target/target.map' -sa 'mcu/stm8l152c6.lsf'
	@$(CROSS)cvdwarf target/target.sm8
	@$(CROSS)chex -o target/target.s19 target/target.sm8
	@$(CROSS)cobj -n target/target.sm8
	@rm -f target/*.o

$(SRC_C:%.c=target/%.o): target/%.o: %.c
	@$(CROSS)cxstm8 $(FLAGS_C) $(INCLUDES) -i. -i$(CROSS_PATH)/Hstm8 -cl'target' -co'target' $>	

clean:
	@echo '-----------------------------------------------------------'
	@rm -f target/*.*	

mcu_program:
	@C:/Tools/STMicroelectronics/ToolKit/apisample.exe -BoardName=ST-LINK -Device=STM8L152x6 -Port=USB -ProgMode=SWIM -no_loop -no_log -FileProg=target/target.s19

mcu_restart:
	@C:/Tools/STMicroelectronics/ToolKit/gdb7.exe --quiet --command=mcu/stm8l152c6.ini

.PHONY : all clean program

Ни чего сложного в файле нет. Вначале из исходников получаем объектные файлы, далее их собирает компоновщик, ну и для информативности вывожу информацию о секциях.

Последние две цели mcu_program и mcu_restart позволяют прошить и сбросить микроконтроллер, что очень удобно не нужно переключаться между окнами. (К сожалению данная утилита не хочет прошивать микроконтроллер установленный в STM32-Discovery, хотя теоритически должна. И почему то в ней не предусмотрен сброс, поэтому приходится использовать костыль в виде mcu_restart). Файл управляющих команд (stm8l152c6.ini):

#
# define emulator reset port and MCU
#
define emulator-reset-port-mcu
target gdi -dll swimstm_swim.dll -stlink3 -port $arg0 -mcuname $arg1
mcuname -set $arg1
end

#
# reset command and quit
#
emulator-reset-port-mcu usb://usb stm8l152c6
quit

В результате получаем вот такую информацию (сборка, прошивка, сброс):

make all 
-----------------------------------------------------------
main.c:
mcu/stm8_interrupt_vector.c:
mcu/peripherals/lcd_nokia_1100.c:
Linking: target.elf
-----------------------------------------------------------

sections:

.const: hilo code, at address 0x8080
      526 data  bytes (0x020e)
.text: hilo code, at address 0x8291
     1030 data  bytes (0x0406)
.eeprom: no attribute, at address 0x1000
        0 data  bytes (0x0000)
.bsct: no attribute, at address 0x0
        0 data  bytes (0x0000)
.ubsct: bss hilo zpage, at address 0x0
       11 reserved bytes (0x000b)
.bit: no attribute, at address 0xb
        0 data  bytes (0x0000)
.share: no attribute, at address 0xb
        0 data  bytes (0x0000)
.data: no attribute, at address 0x100
        0 data  bytes (0x0000)
.bss: bss hilo, at address 0x100
        0 reserved bytes (0x0000)
.info.: no attribute, at address 0x0
      770 data  bytes (0x0302)
.const: hilo code, at address 0x8000
      128 data  bytes (0x0080)
.init: hilo code, at address 0x828e
        3 data  bytes (0x0003)
make mcu_program 
Configuration:
BoardName=ST-LINK Device=STM8L152x6 Port=USB ProgMode=SWIM

Loading file target/target.s19 in PROGRAM MEMORY

Programming PROGRAM MEMORY
Cut Version and Revision of device: 2.0

Programming PROGRAM MEMORY succeeds

Verifying PROGRAM MEMORY
Cut Version and Revision of device: 2.0

Verifying PROGRAM MEMORY succeeds
make mcu_restart 
Connected to the GDI Debug Instrument.
Disconnected from the GDI Debug Instrument.

Последний штрих

Для полного счастья нахватает только описать таблицу прерываний и структуру регистров микроконтроллера. Данные файлы я взял из стандартной либы. (stm8_interrupt_vector.c, stm8l15x.h). Приведу только файл с таблицей:

/* BASIC INTERRUPT VECTOR TABLE FOR STM8S devices
 * Copyright (c) 2007 STMicroelectronics
 */

typedef void @far (*interrupt_handler_t)(void);

struct interrupt_vector
{
  unsigned char interrupt_instruction;
  interrupt_handler_t interrupt_handler;
};

@far @interrupt void NonHandledInterrupt (void)
{
  /* in order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction
  */
  return;
}

extern void _stext();     /* startup routine */

struct interrupt_vector const _vectab[] =
  {
    {
      0x82, (interrupt_handler_t)_stext
    }
    , /* reset */
    {0x82, NonHandledInterrupt}, /* trap */
    {0x82, NonHandledInterrupt}, /* irq0 - tli */
    {0x82, NonHandledInterrupt}, /* irq1 - awu */
    {0x82, NonHandledInterrupt}, /* irq2 - clk */
    {0x82, NonHandledInterrupt}, /* irq3 - exti0 */
    {0x82, NonHandledInterrupt}, /* irq4 - exti1 */
    {0x82, NonHandledInterrupt}, /* irq5 - exti2 */
    {0x82, NonHandledInterrupt}, /* irq6 - exti3 */
    {0x82, NonHandledInterrupt}, /* irq7 - exti4 */
    {0x82, NonHandledInterrupt}, /* irq8 - can rx */
    {0x82, NonHandledInterrupt}, /* irq9 - can tx */
    {0x82, NonHandledInterrupt}, /* irq10 - spi*/
    {0x82, NonHandledInterrupt}, /* irq11 - tim1 */
    {0x82, NonHandledInterrupt}, /* irq12 - tim1 */
    {0x82, NonHandledInterrupt}, /* irq13 - tim2 */
    {0x82, NonHandledInterrupt}, /* irq14 - tim2 */
    {0x82, NonHandledInterrupt}, /* irq15 - tim3 */
    {0x82, NonHandledInterrupt}, /* irq16 - tim3 */
    {0x82, NonHandledInterrupt}, /* irq17 - uart1 */
    {0x82, NonHandledInterrupt}, /* irq18 - uart1 */
    {0x82, NonHandledInterrupt}, /* irq19 - i2c */
    {0x82, NonHandledInterrupt}, /* irq20 - uart2/3 */
    {0x82, NonHandledInterrupt}, /* irq21 - uart2/3 */
    {0x82, NonHandledInterrupt}, /* irq22 - adc */
    {0x82, NonHandledInterrupt}, /* irq23 - tim4 */
    {0x82, NonHandledInterrupt}, /* irq24 - flash */
    {0x82, NonHandledInterrupt}, /* irq25 - reserved */
    {0x82, NonHandledInterrupt}, /* irq26 - reserved */
    {0x82, NonHandledInterrupt}, /* irq27 - reserved */
    {0x82, NonHandledInterrupt}, /* irq28 - reserved */
    {0x82, NonHandledInterrupt}  /* irq29 - reserved */
  };

Хух, на этом пока все, далее по плану линии ввода-вывода и пример работы с ЖКИ индикатором от мобильного телефона Нокиа 1100.


Стандартная библиотека (STM8L15x standard peripheral library)

STM8L-Ultra Low Power-8 bits Microcontrollers


UM0151: STVP programming toolkit



comments powered by Disqus