Hello ARM-world!

Достал из ящика стола STM32 VL Discovery. На борту ARM 32-bit Cortex-M3, 24MHz, 128Kib flash, 8Kib ram, бла-бла-бла и все такое, что нужно для dev-платки. «Hello, world!» для таких плат является мигалка светодиодом. Стандартный демо-пример на Си, использующий библиотеку CMSIS занимает около трех килобайт (с выравниванием четыре килобайта), правда там еще предусмотрено изменение частоты моргания посредством нажатия кнопки USER, ну и фиг с ним. Наваял свою «дрыгалку» (естесственно в самом простейшем виде, без всяких оптимизаций и использования преимуществ arm, так как бы я написал для x86 на скорую руку):

/*
 * file: stm32.ld
 */
SECTIONS
{
        /* interrupt vectors start at zero */
        . = 0x0;  /* start of flash */

        .text :  {  *(.text)   }

        /* constant data follows code but still in flash */
        .data :
        {
          *(.data)
          *(.rom)
        }

        /* internal RAM starts at 0x20000000 */
        . = 0x20000000;
        .ram : { *(.ram) }

        .bss :
        {
          *(.bss)
          *(.ram)
        }
}
    @
    @ file: led2.s
    @
    .syntax unified
    .cpu cortex-m3
    .thumb

    .equ STACKINIT,             0x20001FFF

    .equ PERIPH_BASE,           0x40000000
    .equ APB1PERIPH_BASE,       (PERIPH_BASE + 0x00000)
    .equ APB2PERIPH_BASE,       (PERIPH_BASE + 0x10000)
    .equ AHBPERIPH_BASE,        (PERIPH_BASE + 0x20000)

    .equ RCC_BASE,              (AHBPERIPH_BASE + 0x1000)
    .equ RCC_APB2ENR,           (RCC_BASE + 0x18)

    .equ GPIOC_BASE,            (APB2PERIPH_BASE + 0x1000)
    .equ GPIOC_CRH,             (GPIOC_BASE + 0x04)
    .equ GPIOC_BSRR,            (GPIOC_BASE + 0x10)

    .equ LED_DELAY,             0x30000

.section .text
    .org 0x0

vectors:
    .word   STACKINIT
    .word   _start + 1

_start:
    @ разрешаем тактирование порта C
    ldr r6, = RCC_APB2ENR
    mov r0, 0x10
    str r0, [r6]

    @ устанавливаем режимы тактирования ног 8 и 9 порта C
    @ (синий и зеленый светодиоды, соответственно)
    ldr r6, = GPIOC_CRH
    ldr r0, = 0x44444433
    str r0, [r6]

    @ глушим синий, зажигаем зеленый
    ldr r2, = 0x01000200
    @ глушим зеленый зажигаем синий
    ldr r3, = 0x02000100
    @ порт сброса/установки сигнала на ноги
    ldr r6, = GPIOC_BSRR

    @ бесконечный цикл
loop:
    @ blue - off, green - on
    str r2, [r6]
    bl delay
    @ blue - on, green - off
    str r3, [r6]
    bl delay
    b loop

    @ простенькая задержка
delay:
    ldr r1, = LED_DELAY
delay3:
    subs r1, 1
    bne delay3
    bx lr

компилируем и прошиваем:

arm-none-eabi-as -mcpu=cortex-m3 -mthumb -ahls=led2.lst -o led2.o ./led2.s
arm-none-eabi-ld -v -Tstm32.ld -nostartfiles -o led2.elf ./led2.o
arm-none-eabi-objcopy -O binary ./led2.elf ./led2.bin
st-flash write v1 ./led2.bin 0x08000000

— набор компиляторов GCC под ARM брал тут
— утилиту для прошивки брал тут (git clone https://github.com/texane/stlink && cd ./stlink && ./autogen.sh && ./configure && make)

— под Mac OS не забываем поставить драйвер (cd stlinkv1_macosx_driver/osx && sudo ./install.sh), если не ставится из-за неподходящей версии системы, то просто правим скрипт, я под yosemite добавил вот такие строчки:

10.10.3)
    KEXT="stlink_shield10_10.kext"
    ;;

результат: файл прошивки уменьшился с 3-4 кбайт до 84 байт (если развернуть цикл delay, то 80)

Запись опубликована в рубрике Новости. Добавьте в закладки постоянную ссылку.