STM32 — скорость и размер кода. Часть 2

Это описание крошечного проектика по морганию светодиодом.

Исходные данные такие:

  • Плата STM32VLDiscovery
  • Debian Squeeze 6.0.6
  • Свеже-установленный тулчейн для кросс-компиляции ARM/Cortex

В состав проекта входят всего три файла:

  • main.c — файл программы
  • maikfile — файл управления проектом
  • stm32.ld — скрипт для линковщика

Вот их содержимое:

main.c

// By Wolfgang Wieser, heavily based on:
// http://fun-tech.se/stm32/OlimexBlinky/mini.php

#include <cmsis/stm32.h>

#define STACK_TOP 0x20000800   // just a tiny stack for demo

static void nmi_handler(void)
{
  while (1)
    ;
}

static void hardfault_handler(void)
{
  while (1)
    ;
}

void SystemInit(void)
{
  RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;

  GPIOC->CRH |=  (GPIO_CRH_MODE9_1  | GPIO_CRH_MODE8_1);
  GPIOC->CRH &= ~(GPIO_CRH_CNF9 | GPIO_CRH_CNF8);
}

void sleep(void)
{
  volatile uint32_t i = 32768;

  while (i--)
    ;
}

int main(void)
{
  SystemInit();

  while (1)
  {
    GPIOC->BSRR = GPIO_BSRR_BS8;  sleep();
    GPIOC->BSRR = GPIO_BSRR_BR8;  sleep();
    GPIOC->BSRR = GPIO_BSRR_BS9;  sleep();
    GPIOC->BSRR = GPIO_BSRR_BR9;  sleep();
  }
}

// Define the vector table
unsigned int *myvectors[4]
__attribute__ ((section("vectors"))) = {
  (unsigned int *) STACK_TOP,         // stack pointer
  (unsigned int *) main,              // code entry point
  (unsigned int *) nmi_handler,       // NMI handler (not really)
  (unsigned int *) hardfault_handler  // hard fault handler
};

makefile

PROGNAME = main

PREFIX = arm-none-eabi-
CC = $(PREFIX)gcc
LD = $(PREFIX)ld
CP = $(PREFIX)objcopy
OD = $(PREFIX)objdump
SZ = $(PREFIX)size

CFLAGS = -I. -c -fno-common -Os -g -mcpu=cortex-m3 -mthumb
LFLAGS = -Tstm32.ld -nostartfiles
CPFLAGS = -Obinary
ODFLAGS = -S

# Uncomment this if you need in colorizing
COLORIZE  = "\033[01;38;05;192m"
BACKCOLOR = "\033[0;0;0m"

all: $(PROGNAME).bin $(PROGNAME).lst
        @echo $(COLORIZE)"Результат:"$(BACKCOLOR)
        $(SZ) $(PROGNAME).elf

$(PROGNAME).bin: $(PROGNAME).elf
        @echo $(COLORIZE)"Извлекаем бинарный код"$(BACKCOLOR)
        $(CP) $(CPFLAGS) $(PROGNAME).elf $(PROGNAME).bin

$(PROGNAME).lst: $(PROGNAME).elf
        @echo $(COLORIZE)"Делаем листинг"$(BACKCOLOR)
        $(OD) $(ODFLAGS) $(PROGNAME).elf > $(PROGNAME).lst

$(PROGNAME).elf: $(PROGNAME).o
        @echo $(COLORIZE)"Линкуем"$(BACKCOLOR)
        $(LD) $(LFLAGS) -o $(PROGNAME).elf $(PROGNAME).o

$(PROGNAME).o: $(PROGNAME).c
        @echo $(COLORIZE)"Компилируем"$(BACKCOLOR)
        $(CC) $(CFLAGS) $(PROGNAME).c

clean:
        -rm -f *.o *.elf *.bin *.lst
        @echo $(COLORIZE)"Хоп! И чисто."$(BACKCOLOR)

load: main.bin
        @echo $(COLORIZE)"Заливаем в микроконтроллер"$(BACKCOLOR)
        st-flash write /dev/stlinkv1_3 main.bin 0x08000000

stm32.ld

/* This will work with STM32 type of microcontrollers.    *
* The sizes of RAM and flash are specified smaller than  *
* what most of the STM32 provide to ensure that the demo *
* program will run on ANY STM32.                         */
MEMORY
{
  ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
  rom (rx)  : ORIGIN = 0x00000000, LENGTH = 128K
}

SECTIONS
{
  .  = 0x0;         /* From 0x00000000 */
  .text :
  {
    *(vectors)    /* Vector table */
    *(.text)      /* Program code */
    *(.rodata)    /* Read only data */
  } >rom

  .  = 0x20000000;  /* From 0x20000000 */
  .data :
  {
    *(.data)      /* Data memory */
  } >ram AT > rom

  .bss :
  {
    *(.bss)       /* Zero-filled run time allocate data memory */
  } >ram AT > rom
}

В основе проекта лежат публикации:


http://fun-tech.se/stm32/OlimexBlinky/mini.php

и
http://www.triplespark.net/elec/pdev/arm/stm32.html

В результате сборки проекта

test-1

мы имеем пару моргающих по-переменно светодиодов и код, размером всего 136 байт.

На что следует обратить внимание.

Во первых, при копировании отсюда текстов для этих трех файлов, обратите особое внимание на текст makefile. В правилах сборки должен быть символ табуляции, а не восемь пробелов каку меня здесь. Дело в том, что блоговский движок на корню зарубает табуляцию, а как обойти это дело, я — не знаю.

* После публикации статьи я выложил проект на github. Подробности см. ниже — под отметкой upgrade.

Второй момент. Не следует рассматривать проект как какой-то коммерческий или как проект для подражания. Здесь все вычищено и код сделан максимально прозрачным, дабы не тупить над ним, а быстро схватить основную идею. Более того, не все сделано идеально. Например, в makefile можно было бы не писать сотню раз $(PROGNAME), а воспользоваться другим приемом. Если вы знаете как — сделайте так, как вам больше нравится Если нет — используйте пока такой подход. Потом, может быть, если у меня будет настроение, я расскажу, что тут можно улучшить.

Ну и наконец. Я пишу в блог прежде всего для себя. Так сказать, это моя публичная ЛТР (Личная Тетрадь Разработчика).

UPGRADE 13.12.2012-02:01

Чтобы забрать (или как более правильно — клонировать) проект с Github-a, вам нужно выполнить команду:

$ git clone git://github.com/zhevak/stm32-test-1.git

Команду можете выполнить в любом директории. (Разумеется в своем, ну, в том смысле, что вам можно в нем писать, читать и запускать.) Команда  сначала создаст поддиректорий stm32-test-1, а затем клонирует в него проект. Все происходит практически мгновенно!

После клонирования вам нужно зайти в этот директорий. Убедитесь, что в директории присутствуют три описываемых в этой статье файла, а так же четвертый файл README.

В принципе, если у вас уже установлен тулчейн, то вы можете сразу откомпилировать проект:

$ make

Обратите внимание на размер полученного кода. Если у вас уже имеется отладочная плата STM32VLDISCOVERY, можете подцепить ее к компу и залить программу:

$ make load

Светодиоды должны замаргать.

Выполняя операцию клонирования, на самом деле вы клонировали сразу три ветки проекта. Они называются :

  • master — основная ветка. Вы с ней как раз и работаете сейчас.
  • humans-names — ветка, в которой имена портов управления названы по-человечески. В результате исходный код стал легче и стал выглядеть более понятно.
  • six-7segments — эта ветка для программы, которая управляет линейкой из 7-сегментных индикаторов.

Но прежде чем мы перейдем на ветку humans-names, давайте почистим проект от скомпилированных файлов:

$ make clean

Чтобы переключиться на другую ветку нужно ввести команду:

$ git checkout humans-names

Посмотрите на файлы — они изменились! Вы можете переключиться обратно на ветку master:

$ git checkout master

или на ветку six-7segments:

$ git checkout six-7segments

Попробуйте теперь самостоятельно поиграться с проектами на разных ветках, посмотрите как компилируются их коды.

Только я хочу сразу вас предупредить —

НЕ ИЗМЕНЯЙТЕ ФАЙЛЫ ПРОЕКТА!

Изменив файл, который находится под контролем Git-а, вы не сможете переключиться на другую ветку — Git вам просто не позволит ничего сделать, пока вы не зафиксируете в локальном  репозитории изменения.

Git ведь не знает всех ваших намерений, но он строго следит чтобы ничего не потерялось. И если в проекте произошли какие-то изменения, то из сначала нужно либо зафиксировать, либо «откатить» обратно, и только тогда можно будет переключиться на другую ветку. Это не неудобства — это проявление заботы и гарантия сверх-надежности Git-овских репозиториев. Не даром ведь говорят, что если что-то попало в Git-репозитоий, то потерять это — практически невозможно!

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

$ git checkout *

Не расстраивайтесь, если у вас что-то не получается. Постепенно, шаг за шагом, продвигаясь вперед вы научитесь работать и с Git-ом.

Линукс — это мощнейшая система. Шindows — ей в подметки не годится! Просто мы все — в прошлом вендузятники, и этим определяются все наши страдания. Чем глубже вы знаете Виндовс, тем труднее вам работать в Линуксе. Почему и говорят — учите сразу правильные инструменты и технологии!

Advertisements

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s