воскресенье, 26 февраля 2012 г.

I & STM32-discovery part8 - Interrupts

Простая программа из предыдущих примеров по своему развитию зашла в тупик - почти все время ядро мк тупо считает такты находясь в функции программного ожидания. Мы же займемся усовершенствованием программы чтобы в последствии расширить ее функционал.

Также как и предыдущей статье начнем с краткой теории. Тот подход который мы использовали в программах называется работа с периферией методом опроса. Мы в цикле опрашиваем нужные нам блоки попутно выполняя между этими опросами необходимые расчеты. Несмотря на простоту реализации этот подход имеет как минимум один очевидный недостаток - необходимо вручную вплоть до такта рассчитывать операции и передавать управление от одной функции к другой по потребностям. Это влечет за собой увеличение сложности программы в целом и запутанности ее алгоритма в частности. Причем увеличение сложности возрастает не линейно, а с некоторой прогрессией так как возрастает количество зависимых элементов.

Не смотря на некоторый пессимистичный подход в начале, кроме метода опроса есть еще и метод событий. Этот подход основан на том что ядро мк настраивает периферию так что она при определенных условия генерирует события, мк исполняя основной код, прерывает его исполнение, обрабатывает событие и продолжает исполнение кода. Так как ядро мк прерывается, то и метод назван: работа с прерываниями. Переходим от логических рассуждений к  практической теории.

NVIC - векторный контроллер прерываний с поддержкой вложенности и приоритета. Этот блок является неразделимой частью ядра arm-cortex-m3 и предназначен для управления обработкой прерываний. Общее количество прерываний - 81(максимальное количество, зависит от модели мк), количество приоритетов - 16(уровень 0 считается самым высоким).
Также к плюсам можно отнести динамическая смена приоритетов, а также тип прерывания - по лог уровню или направлению пульса.
Управление NVIC осуществляется с помощью группы регистров.

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

Для пример работы с прерываниями возьмем блок обработки внешних прерываний - EXTI, этот блок может обрабатывать события с внешних выводов, таких может быть 18 из них 16 можно переназначить на на пин с номером как у прерывания на любой порт. Также это событие можно настроить как на возрастание и спад лог уровня, либо по любому из этих событий.

Перейдем в нашу рабочую директорию и создадим новый проект.

nis@jane ~ $ cd stm32
nis@jane ~/stm32 $ cd examples/
nis@jane ~/stm32/examples $ cp -a 02-and-button/ 03-exti-int
nis@jane ~/stm32/examples $ cd 03-exti-int/

Модифицируем стартап для мк, для этого вынесем его в отдельный файл.
Здесь мы расположим обработчик вектора для EXTI, т.к. на 0вой вывод у нас выделен отдельный вектор это упрощает нашу задачу. В обработчике мы выполняем вызов внешней функции изменения флага статуса и сбрасываем статус заброса этого прерывания. startup.c:


Помимо файла стартапа, нужен еще файл системной инициализации. В этом файле мы производим начальную конфигурацию системы тактирования и NVIC. sys_init.c:


И конечно основной файл проекта. Здесь не так много изменений. В основном добавилась инициализация внешнего прерывания и функции изменения флага. main.c:


После этого соберём проект и прошьем его во флешь мк.

nis@jane ~/stm32/examples/03-exti-int $ make all write
arm-softfloat-linux-gnueabi-gcc -g -O2 -mlittle-endian -mthumb -ffreestanding -nostdlib -nostdinc -mcpu=cortex-m3 -DSTM32F10X_MD_VL -I. -I../../stlink/example/libs_stm/inc/base -I../../stlink/example/libs_stm/inc/core_support -I../../stlink/example/libs_stm/inc/device_support -Wl,-T,stm32f100xb_flash.ld   -c -o main.o main.c
arm-softfloat-linux-gnueabi-gcc -g -O2 -mlittle-endian -mthumb -ffreestanding -nostdlib -nostdinc -mcpu=cortex-m3 -DSTM32F10X_MD_VL -I. -I../../stlink/example/libs_stm/inc/base -I../../stlink/example/libs_stm/inc/core_support -I../../stlink/example/libs_stm/inc/device_support -Wl,-T,stm32f100xb_flash.ld -o firmware.elf main.o sys_init.o startup.o -L.
arm-softfloat-linux-gnueabi-objcopy -O binary firmware.elf firmware.bin
st-flash write v1 firmware.bin 0x8000000
2012-02-26T18:49:18 INFO src/stlink-common.c: Loading device parameters....
2012-02-26T18:49:18 INFO src/stlink-common.c: Device connected is: F1 Medium-density Value Line device
2012-02-26T18:49:18 INFO src/stlink-common.c: SRAM size: 0x2000 bytes (8 KiB), Flash: 0x20000 bytes (128 KiB) in pages of 1024 bytes
2012-02-26T18:49:18 INFO src/stlink-sg.c: Successfully opened a stlink v1 debugger
2012-02-26T18:49:18 INFO src/stlink-common.c: Successfully unlocked flash
Erasing chip entirely... Done
2012-02-26T18:49:18 INFO src/stlink-common.c: Attempting to write 692 (0x2b4) bytes to stm32 address: 134217728 (0x8000000)
2012-02-26T18:49:18 INFO src/stlink-common.c: Erasing flash page at addr: 0x8000000
2012-02-26T18:49:18 INFO src/stlink-common.c: Successfully unlocked flash
2012-02-26T18:49:18 INFO src/stlink-common.c: Finished erasing 1 pages of 1024 (0x400) bytes
2012-02-26T18:49:18 INFO src/stlink-common.c: Starting Flash write for VL core id
2012-02-26T18:49:18 INFO src/stlink-common.c: Successfully loaded flash loader in sram
2012-02-26T18:49:18 INFO src/stlink-common.c: Writing flash block 0 of size 64 (0x40)
2012-02-26T18:49:18 INFO src/stlink-common.c: Successfully unlocked flash
2012-02-26T18:49:18 INFO src/stlink-common.c: Writing flash block 1 of size 64 (0x40)
2012-02-26T18:49:18 INFO src/stlink-common.c: Successfully unlocked flash
2012-02-26T18:49:18 INFO src/stlink-common.c: Writing flash block 2 of size 64 (0x40)
2012-02-26T18:49:18 INFO src/stlink-common.c: Successfully unlocked flash
2012-02-26T18:49:18 INFO src/stlink-common.c: Writing flash block 3 of size 64 (0x40)
2012-02-26T18:49:18 INFO src/stlink-common.c: Successfully unlocked flash
2012-02-26T18:49:18 INFO src/stlink-common.c: Writing flash block 4 of size 64 (0x40)
2012-02-26T18:49:18 INFO src/stlink-common.c: Successfully unlocked flash
2012-02-26T18:49:18 INFO src/stlink-common.c: Writing flash block 5 of size 64 (0x40)
2012-02-26T18:49:18 INFO src/stlink-common.c: Successfully unlocked flash
2012-02-26T18:49:18 INFO src/stlink-common.c: Writing flash block 6 of size 64 (0x40)
2012-02-26T18:49:18 INFO src/stlink-common.c: Successfully unlocked flash
2012-02-26T18:49:18 INFO src/stlink-common.c: Writing flash block 7 of size 64 (0x40)
2012-02-26T18:49:18 INFO src/stlink-common.c: Successfully unlocked flash
2012-02-26T18:49:18 INFO src/stlink-common.c: Writing flash block 8 of size 64 (0x40)
2012-02-26T18:49:18 INFO src/stlink-common.c: Successfully unlocked flash
2012-02-26T18:49:19 INFO src/stlink-common.c: Writing flash block 9 of size 64 (0x40)
2012-02-26T18:49:19 INFO src/stlink-common.c: Successfully unlocked flash
2012-02-26T18:49:19 INFO src/stlink-common.c: Writing flash block 10 of size 64 (0x40)
2012-02-26T18:49:19 INFO src/stlink-common.c: Successfully unlocked flash
2012-02-26T18:49:19 INFO src/stlink-common.c: Starting verification of write complete
2012-02-26T18:49:19 INFO src/stlink-common.c: Flash written and verified! jolly good!

И наконец видео процесса:
На этом все.