LINUX.ORG.RU

stm32 мигаем светодиодом

 


0

1

здрасьте здрасьте люди добрые. пришел контроллер и программатор STM32F103C8T, ST-LINK/V2. операционная система Ubuntu. если может кто-то то напишите пожалуйста пример програмки на assembler чтобы мигнуть светодиодом.

ее я скомпилирую и зашью. компилировать думаю

arm-none-eabi-as -o myfile.o myfile.s 

arm-none-eabi-objcopy mf.elf mf.bin -O binary
st-flash write my.bin 0x8000000
чего не могу? мигнуть светодиодом. или программка корявая или котроллер не работает. если можете дайте пример 100% рабочей программки на ассемблер чтобы проверить.



Последнее исправление: Assembler (всего исправлений: 3)

Ответ на: комментарий от anonymous

время есть свободное у вас?

А что хотели?

anonymous
()
Ответ на: комментарий от Eddy_Em

А теперь покажи код на асме, выполняющий тот же самый «блинки», что делает мой: «отморзянивать» SOS или же просто мигать светодиодом в зависимости от нажатой кнопки.

Не совсем то же самое. Но гораздо лучше.

$ cat blinky.bin.b64
AFAAILsAAAi3GC3bfxvFliItLTctKScKLW8tVyudLQkt5xItJhknLa8tqA8tLS0WLdb4AmoCKSUW
AhYAXQAACF8AAAiTAAAIoQAACKcAAAguLi4tLS0uLi4gICBgR0/wAQFP9AAy9kMM0OBdLSgEvwAh
T/TAIsi/ACEH8QEHr0IIvwAnyPgAEMn4ACDJ+AQgcEdP9PQi2PgAEG/qAQHx50/0wDL356vxOARP
8DQFT/AABjdGTPJQMu3nHkxP8AwFT/AABjdG3/hwgN/4cJCo8XwKqPHkA9/4aLAaSMD4ALBP8AEB
GEgBYBhJGUgBYE/0YEEYSAFgT/QAMMn4AAAL8UAL2/gAwE/wAwETSAFg2vgAANr4BBBA6kEAgPAD
AE/qgABYRND4AMAC8QECT+qSEBhg7OdQAAAItAEiQhTgAOAAAAAICO0A4BADQkJERESIBBABQAwQ
AUAQ4ADg

$ base64 -d blinky.bin.b64 > blinky.bin
$ stat -c %s blinky.bin
348

Извиняйся. :)

Исходник с комментариями. Бинарник скомпилен для флешки.

anonymous
()
Ответ на: комментарий от Eddy_Em

Нечитаемый адов трешняк!

По ссылке сходи xD

anonymous
()
Ответ на: комментарий от Eddy_Em

Интересно, конечно. А кириллицу в Юникоде отморзянит или как обычно?

Если ты за читаемость и удобство, то зачем тогда таблицу кодов такую неестественную сделал? Писал бы точками и тире, как нормальный человек.

Ссылка на видео ведёт на Гитхаб.

anonymous
()
Ответ на: комментарий от anonymous

Юникод на МК используют только совсем ополоумевшие! Морзянку на кириллицу я не делал - лень было, пусть кому нужно сделает.

Писал бы точками и тире, как нормальный человек.

Да, надо было макросы нагенерить, как в шрифтах. Но эту фиговину я рисовал в качестве развлекухи и никто ее все равно применять не будет: морзянка в наше время нафиг не нужна.

Вот - видео, меня опять заминусил Шома, так что я свои сообщения редактировать не могу. Почему-то, когда выделяешь на тытрубе ссылку, она не попадает в мышиный буфер обмена.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от anonymous

Привлекает в основном не столько ценник, сколько большая частота ядра и огромный объём SRAM и флеша у GD32 при pin-to-pin совместимости.

Насчёт прошивки клонов — там CPUTAPID другой, необходимо править конфиг OpenOCD.

Я пробовал GD32VF103, которые не совсем клоны: https://habr.com/ru/post/533272/

pin-to-pin совместимые, регистры почти одинаковые, но вот по SWD прошиваться не умеют (по JTAG вроде умеют, но я так и не понял как). И USB отличается очень сильно.

Но у этих другое ядро. Возможно, «более клоны» и склонированы более тщательно.

COKPOWEHEU
()
Ответ на: комментарий от Eddy_Em

Юникод на МК используют только совсем ополоумевшие!

То есть фирмы, успешно продающие многоязычные девайсы по всему миру - дурачки, а ты, не осиливший морзянку на кириллице, - царь?

anonymous
()
Ответ на: комментарий от Eddy_Em

Да, надо было макросы нагенерить, как в шрифтах.

Это да, уже намного удобнее.

видео

Help me, please

лол

anonymous
()
Ответ на: комментарий от anonymous

Мы под впечатлением от такого генильного кода. у нашей группы есть 500р и мы хотим попросить вас написать это же но для cortex a53. Бинарник который можно положить на sdсard, что бы зажесь светодиод на посаженый на GPIO. сможете начертать пару таких же гениальных строк?

anonymous
()
Ответ на: комментарий от Eddy_Em

Неюниксвейно как-то.

В смысле? openocd умеет прошивать контроллеры по JTAG, вызывается из makefile. Что еще от нее требуется? Ну разве что флаги запуска для каждого контроллера специфичные (для того же RISCV я их так и не подобрал), но это и у других утилит бывает.

COKPOWEHEU
()
Ответ на: комментарий от COKPOWEHEU

JTAG? На кой черт, если есть DFU или хоть что-то менее требующее количество ног?

DFU мне нравится больше всего: ни одной лишней ноги тратить не нужно + не нужно выводить кнопки BOOT0 и RESET и жамкать их, чтобы прошить МК! А в режим DFU выхожу программно.

Ну, чтобы вообще ничего не жамкать (и программно тоже), есть SDW, но мне он не нравится...

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

DFU мне нравится больше всего: ни одной лишней ноги тратить не нужно + не нужно выводить кнопки BOOT0 и RESET

Вот именно для этого: чтобы не дергать постоянно BOOT0 и RESET как приходится в stm32flash / dfu.

А в режим DFU выхожу программно.

Через что в МК подается команда войти в режим загрузчика?

Ну, чтобы вообще ничего не жамкать (и программно тоже), есть SDW, но мне он не нравится…

В данном случае я JTAG и SWD не разделял. openocd работает и с тем, и с другим. Для отладочной платы вообще безразлично: ноги-то совмещены, а разъем общий.

Но вот делал когда-то датчик один (на L151, еще до того как с USB разобрался), там USB не выводил (да МК через него вроде бы и не умеет), а вот SWD, UART и BOOT0 оставил. Вполне удобно получилось, и если режим сна заглючит (а я с ним первый раз работал), можно через BOOT0 подцепить и перепрошить.

COKPOWEHEU
()
Ответ на: комментарий от Eddy_Em

Я спрашивал не «как контроллер попадает в загрузчик», а «как он узнает, что пора в загрузчик». Кнопка? Спецпакет по USB?

COKPOWEHEU
()
Ответ на: комментарий от Eddy_Em

Скажете, не могли бы вы написать что-то вроде этого

syntax unified
.cpu cortex-m3
.thumb
.global _start

    PORT_C_ENABLE_BIT           = 0x42420310
    PORT_C_PIN13_MODE0_BIT      = 0x422200d0
    PORT_C_PIN13_OUTPUT_BIT     = 0x422201b4

.text
    stack_pointer_value:    .word   0x20005000
    reset_vector:           .word   _start + 1
    
    _start:
        movs    r1, #1
        
        ldr     r0, =PORT_C_ENABLE_BIT
        str     r1, [r0]
        ldr     r0, =PORT_C_PIN13_MODE0_BIT
        str     r1, [r0]
        
        ldr     r0, =PORT_C_PIN13_OUTPUT_BIT
        blink:
            str     r2, [r0]
            eors    r2, r1
для cortex a53? денег немного, к сажалению. только есть 500р. это скорее легкий презент. знакомы с cortex a53? мне хочется с GPIO тоже зажечь светодиод, как ТС, но только на cortex a53

anonymous
()
Ответ на: комментарий от anonymous

Блин!!! теперь этот кусок кода вечен! щас вся школота будет его таскать и копировать как священый рун! анус, ты вошел в историю.

anonymous
()
Ответ на: комментарий от Eddy_Em

Не оспаривая ваш опыт, укажу несколько моментов, когда DFU не удобно:

  • когда DFU просто нет (те же f103)
  • когда идет разработка самого USB и его стабильность под большим вопросом
  • когда USB вообще не предусмотрен
  • когда не гарантируется работоспособность устройства в целом (если зависнет в прерывании и не сможет обработать ваш запрос)
COKPOWEHEU
()
Ответ на: комментарий от Assembler

Все написано в даташите на конкретный камень.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Assembler

Проще всего смотреть в главном заголовочном файле, например stm32l151xc.h. Правда, там будет что-то вроде (если мы хотим узнать адреса для USART1):

typedef struct
{
  __IO uint32_t SR;         /*!< USART Status register,                   Address offset: 0x00 */
  __IO uint32_t DR;         /*!< USART Data register,                     Address offset: 0x04 */
  __IO uint32_t BRR;        /*!< USART Baud rate register,                Address offset: 0x08 */
  __IO uint32_t CR1;        /*!< USART Control register 1,                Address offset: 0x0C */
  __IO uint32_t CR2;        /*!< USART Control register 2,                Address offset: 0x10 */
  __IO uint32_t CR3;        /*!< USART Control register 3,                Address offset: 0x14 */
  __IO uint32_t GTPR;       /*!< USART Guard time and prescaler register, Address offset: 0x18 */
} USART_TypeDef;
...

#define PERIPH_BASE           ((uint32_t)0x40000000)
...
#define APB1PERIPH_BASE       PERIPH_BASE
#define APB2PERIPH_BASE       (PERIPH_BASE + 0x00010000)
#define AHBPERIPH_BASE        (PERIPH_BASE + 0x00020000)
...
#define ADC1_BASE             (APB2PERIPH_BASE + 0x00002400)
#define ADC_BASE              (APB2PERIPH_BASE + 0x00002700)
#define SPI1_BASE             (APB2PERIPH_BASE + 0x00003000)
#define USART1_BASE           (APB2PERIPH_BASE + 0x00003800)
...
#define USART1              ((USART_TypeDef *) USART1_BASE)

Но посчитать смещения вполне реально. Векторы прерываний там же.

Все тоже самое можно и из Reference Manual выковырять, но ИМХО сложнее.

COKPOWEHEU
()
Ответ на: комментарий от COKPOWEHEU

сложнее

Что ж там сложного? Открываешь RefMan на секции «Memory Map», там все есть. Конкретные смещения тоже описаны для каждого регистра.

Полностью же память разрисована в даташите. Скажем, для STM32F103xB мы видим, что область с 0 по 0x8000000 отображается на флеш или системную память (в зависимости от конфигурации Boot), сама флеш начинается с 0x8000000 (который мы и указываем прошивальщику при загрузке прошивки во флеш), и т.д., и т.п.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Что ж там сложного? Открываешь RefMan на секции «Memory Map»

В основном размер и неудобная навигация. Инклюдник поменьше все-таки и имена в нем фиксированные, даже опечатки исключены.

Ну и прыжки по читаемому документу менее удобны, чем по отдельному окну.

область с 0 по 0x8000000

Пишите, пожалуйста, 0x0800’0000 или 0x08000000 - с заполнением всех цифр, а то считая одинаковые нули легко запутаться.

COKPOWEHEU
()
Ответ на: комментарий от anonymous

С вашего позволения распишу как переводить bit-band в нормальные адреса. Картинку вы уже показывали, остается только оформить в виде алгоритма.

Согласно документации смещение для записи бита X в регистр по смещению Y равен A = Y∙32 + X∙4. Для RCC_APB2ENR |= RCC_APB2ENR_GPIOCEN, оно же RCC_APB2ENR |= (1<<4) получаем:

0x40000000 - PERIPH_BASE
   0x20000 - AHBPERIPH_BASE = (PERIPH_BASE + 0x20000)
    0x1000 - RCC_BASE       = (AHBPERIPH_BASE + 0x1000)
(6*4 = 0x18) - все регистры в структуре 4-байтные, а APB2ENR идет шестым
Убираем смещение 0x40000000
   0x21018 - X (Смещение нужного нам регистра)
Y = 4 (бит, который мы выставляем)
A = 0x21018*32 + 4*4 = 0x420310
Чтобы получить абсолютный адрес добавляем смещение 0x42000000
Addr = 0x42420310 - вроде похоже

Теперь обратно. Здесь есть фокус что регистры 32-битные, а адресация побайтная. Значит, адрес (и смещение) делятся на 4.

Y = trunc( A / 32 / 4 ) * 4
X = ( A - Y*32 ) / 4

A = 0x420310
Y = 0x21018
X = 4

Ну а из адреса получить имя регистра уже несложно.

COKPOWEHEU
()
Последнее исправление: COKPOWEHEU (всего исправлений: 1)
Ответ на: комментарий от Assembler

Лучше не рисовать магические числа, а из хедеров брать макросы соответствующие!

А 0x42420310 — как я понял, битбандинг. Формула есть в RM:

bit_word_addr = bit_band_base + (byte_offset x 32) + (bit_number × 4)

учитывая то, что не у всех есть битбандинг, код непереносим.

В любом случае, писать такое — рукожопие высшей степени (я уже говорил про магические числа).

Правильней инициализировать периферию, как это делают люди:

PERIPH->REGISTER = VALUES;

Eddy_Em ☆☆☆☆☆
()
Последнее исправление: Eddy_Em (всего исправлений: 1)
Ответ на: комментарий от Eddy_Em

Я сомневаюсь что этим кодом хоть кто-то будет пользоваться в реальности. Он платформо-зависим, криво оформлен и написан только чтобы попонтоваться знанием битбанда и опкодов ассемблера. Ну и ужиманием бинарника до минимума.

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

Правильней инициализировать периферию, как это делают люди:

PERIPH->REGISTER = VALUES;

Для большинства периферии надежнее через AND/OR:

PERIPH->REGISTER |= VALUES;

А то вдруг я порты в одном месте настраиваю, а какой-нибудь SPI в другом. Не надо чтобы они конфликтовали. А то, что вместо одной инструкции получается три - плевать. Тем более на этапе инициализации, когда нет требований к скорости.

COKPOWEHEU
()
Последнее исправление: COKPOWEHEU (всего исправлений: 2)
Ответ на: комментарий от COKPOWEHEU

надежнее

Не всегда. Ты не можешь знать, вызвана инициализация сразу после резета, или же вторично! Поэтому в начале нужно именно = использовать. А вот дальше - да, можно и |=. Но это работает лишь с регистрами, где флаги занимают 1 бит. Если у тебя флаги N-битные, так делать нельзя, нужно делать

PERIPH->REGISTER = ~(PERIPH->REGISTER & FLAG_MASK) | NEW_FLAG;
скажем, настройка режимов GPIO так работает (там по четыре бита на пин).

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Assembler

В принципе, STM32 настолько хорошо документированы (кроме DS, RM и errata есть еще уйма советов/appnote по использованию различной периферии), что прогать под них можно вообще с нуля — даже без заголовочных файлов, взяв лишь общекортексовскую часть CMSIS.

Но удобней таки не дефайнить эти 100500 регистров самостоятельно, а взять у ST готовые заголовочные файлы.

А, еще забыл: USB у ST явно делал какой-то наркоман! Нормальный человек не сводил бы в один регистр разные типы битов (set/reset/toggle).

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Ты не можешь знать, вызвана инициализация сразу после резета, или же вторично! Поэтому в начале нужно именно = использовать.

Для такого случая лучше в начале принудительно обнулить, а потом уж пусть каждый модуль единообразно OR’ом настраивает.

Но это работает лишь с регистрами, где флаги занимают 1 бит. Если у тебя флаги N-битные, так делать нельзя

Если известно, что данный набор битов больше никем не используется, можно и OR’ом. Например, при инициализации всяких SPI, ADC и т.д.

Но в общем случае - да. Сначала AND по маске, потом OR по данным.

COKPOWEHEU
()
Ответ на: комментарий от Eddy_Em

А, еще забыл: USB у ST явно делал какой-то наркоман! Нормальный человек не сводил бы в один регистр разные типы битов (set/reset/toggle).

Искренне подтверждаю! Модуль USB в STM32 писали наркоманы!

В регистре USB_EPxR напихали ВСЕ возможные способы доступа: одни биты на запись не доступны вообще, другие доступны, третьи игнорируют запись 0, четвертые игнорируют запись 1. Я бы понял, если бы игнорировали они одно и то же значение, скажем запись 1 не делает ничего, а 0 - сбрасывает одни биты и тогглит другие. Тогда бы для наложения маски хватало одной операции, а не того извращения, что сейчас.

Плюс точки с двойной буферизацией. Управление буфером на передачу через бит DTOG_RX. На передачу через бит приема.

Размер буферов под конечные точки в заголовочнике не прописан вообще. В разделе рефмана, посвещенному USB, тоже. Иди гадай что PMA не в основной памяти расположен (что было бы логично), а хз где размером 256 слов. Еще и слова 16-битные при 32-битной адресации. То есть просто memcpy туда сделать нельзя, будь добр перекодировать на лету. Хорошо хоть DMA это умеет.

COKPOWEHEU
()
Ответ на: комментарий от COKPOWEHEU

У них еще и этот буфер делится с CAN'ом! И ладно, в STM32F0x2 сделано по-человечески: CAN и USB тактируются от разных источников, поэтому могут использоваться одновременно (разве что размер буфера CAN я в RM не нашел, пришлось гуглить, а потом методом тыка проверять).

А вот в F103 нужно выбирать: или CAN, или USB. Отстойный МК.

Eddy_Em ☆☆☆☆☆
()

А зачем пердолится с ассемблером?

AUX ★★★
()
Ответ на: комментарий от Eddy_Em

можно еще вас спросить? порты-это набор пинов(по 16шт)

PORT A
PORT B
PROT C
PORT D
это они от ключа MK в группы по 16 шт против часовой? или что значта эти буквы?

Assembler
() автор топика
Ответ на: комментарий от Assembler

Да, порты это набор пинов, по 16 штук

Нет, они не идут от ключа подряд, они идут в рандомном порядке, который описан а даташите.

COKPOWEHEU
()
Ответ на: комментарий от Assembler

Открой datasheet на свой камень и посмотри, как порты на нем расположены. Обычно ноги разбросаны в каком-то хаотическом порядке. Особенно доставляет неудобство, если тебе нужно два целых порта, а они не целиком по порядку, а со всех сторон МК вперемешку!

Eddy_Em ☆☆☆☆☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.