LINUX.ORG.RU
ФорумTalks

Микроконтроллеры с прошивкой по SPI

 , ,


2

2

cast Eddy_Em

Хотел уточнить, какие из stm32 и примерно аналогичных arm-ок можно прошивать через SPI, как столько критикуемые avr-ки? Часто есть прошивка через uart, но uart не мультиплексируется без костылей, потому если есть центральный девайс, общающийся с N микроконтроллерами, то общение с ними куда проще по SPI сделать. И было бы очень неплохо, если бы их и перепрошивать можно было через тот же spi. С avr-ками это работает. А что насчет остального?

★★★★★

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

В AVR-ках в качестве ISP используется SPI + Reset.

cvs-255 ★★★★★
() автор топика
Последнее исправление: cvs-255 (всего исправлений: 2)

Не заморачивался. По-моему, через SPI никакие нельзя. А зачем так извращаться? Знаю, что некоторые поддерживают даже прошивку по CAN.

девайс, общающийся с N микроконтроллерами, то общение с ними куда проще по SPI сделать

Нет, только CAN. SPI — это вообще извращение какое-то, подходящее только для внутрисхемной коммутации (по аналогу с I2C).

АВРки шьются по SPI, потому что это у них такая рукожопая традиция. Через USB, например, шить куда как приятней же!

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

SPI — это вообще извращение какое-то, подходящее только для внутрисхемной коммутации

Так так и есть. Центральный модуль, на котором линукс, и куча мелких МК для руления железками. Все на одной плате.

Надо большие расстояния - используем LVDS преобразователи.

CAN же

1) требует бОльших телодвижений

2) это шина без master. Привет непредсказуемые задержки.

cvs-255 ★★★★★
() автор топика
Последнее исправление: cvs-255 (всего исправлений: 3)

Любой более-менее нормальный микроконтроллер (во всяком случае PIC, MSP430, AVR и ARM такое умеют) поддерживает создание bootloader. А значит может прошиваться через что угодно, хоть UART, хоть SPI, хоть I2C, хоть через Интернет (с помощью Wi-Fi или GSM-модуля, разумеется). Просто написать свой загрузчик или взять готовый, если он подходит тебе.

Да и UART в некоторых ситуациях вполне может мультиплексироваться. Например, рассмотрим MSP430. У него для прошивки через UART-BSL (такой bootloader прошитый изготовителем) надо сначала подать правильные импульсы на RESET и TEST, а UART через который идёт прошивка является программным и висит на других ножках, так что аппаратный не тратится. Можно соединить параллельно все МК и подключить к прошивальщику, а RESET и TEST вывести индивидуально от каждого МК. Благо импульсы на них очень просты и аппаратный UART для них не нужен, хватит GPIO. В итоге получается вполне себе мультиплексирование. Только если для SPI нужна одна линия для выбора МК (RESET у AVR), то у MSP430 потребуются две (RESET и TEST). У других МК ситуация та же - если для входа в bootloader (то что STM32 шьются по UART это таки бутлоадер, штатная прошивка у них идёт через JTAG, у AVR да, прошивка через SPI реализована аппаратно) требуются простые действия с некоторыми входами, то можно запараллелить все сигнальные линии кроме этих.

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

это у них такая рукожопая традиция

Это офигенно удобная традиция. Если есть N-микроконтроллеров на плате, и надо со всеми ними по очереди общаться с центрального сока и иногда перепрошивать, то 3 провода SPI, и по 2 провода (CS и Reset) на каждый мк.

cvs-255 ★★★★★
() автор топика
Ответ на: комментарий от KivApple

Только надо еще позаботиться о переводе выводов в высокоомное состояние у неиспользуемых девайсов.

cvs-255 ★★★★★
() автор топика
Ответ на: комментарий от cvs-255

Я бы посадил их на CAN: всего-то нужно 2 дорожки на сколько хочешь мелкоконтроллеров. А т.к. наружу это не пойдет, то преобразователи уровней не нужны. Удобней же!

А при прошивке просто резет удерживаешь у всех, кроме прошиваемого. Т.е. к центральному модулю пойдут: CANTx, CANRx и по одному reset. Уже на 2 дорожки меньше!

Я вообще не понимаю, нахрен это SPI так прижилось! Убогий же ублюдочный интерфейс! И целых три провода...

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

Разумеется. У того же MSP430 UART BSL если бутлоадер не стартовал, то соответствующие ножки программного UART остаются неинициализированными (то есть настроенными как Hi-Z вход). Впрочем, как и большинство остальных (там, по-моему, только низкоскоростной осциллятор запускается по дефолту, если подключен часовой кварц). И если их не использовать в своей программе (аппаратный UART висит на других ножках, так что мы его не потеряем), то они останутся в высокоомном состоянии.

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

CAN сложнее устроен.

битбангить мне его лень (к тому же, это на тратится время мк), а аппаратный can далеко не везде есть.

cvs-255 ★★★★★
() автор топика
Последнее исправление: cvs-255 (всего исправлений: 1)
Ответ на: комментарий от KivApple

Не-не, надо на ходу переводить в Hi-Z, как только CS в 1 перешел.

Иначе получится, что один МК держит выход в 1, другой в это время выставляет 0, и хорошо, если есть защита от большого тока.

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

И да, что в can насчет гарантии задержек?

cvs-255 ★★★★★
() автор топика
Ответ на: комментарий от Eddy_Em

Если есть только один главный, то можно ещё использовать UART, но запараллелить всех ведомых. Многие МК поддерживают так называемый Multiprocessor communication mode для UART. Если его включить, то все ведомые слушают свои RX, а TX находится в состоянии Hi-Z. В режиме MPCM slave игнорируются все байты, которые приходят на RX, кроме специального, адресного байта. Как правило это 9-битный байт, когда основной обмен выполняется в 8-битном режиме, а когда приходит адресный байт вызывается специальный обработчик прерывания (либо сравнение с нужным значением может происходить аппаратно). Если slave понравится адрес, который master послал в начале пакета данных, то он выходит из режима MPCM и работает с UART как обычно, остальные продолжают всё игнорировать. Slave должен определить, когда посылка закончилась (это уже надо предусмотреть в структуре пакета данных) и уйти обратно в MPCM, когда обмен закончен. Таким образом можно тоже обойтись только 2-мя проводами, но не потребуется контроллер с поддержкой CAN, а UART пихают практически везде.

И да, перезагружать всех совсем не обязательно. Можно пойти по пути ардуины и запускать bootloader всегда, ждать немного, если по UART/CAN придёт специальная команда, то переходить в режим прошивки и ожидать следующих пакетов данных, иначе стартовать как обычно. В этом случае надо перезагрузить лишь того, кого надо перепрошить, и тут же начать прошивку.

KivApple ★★★★★
()
Ответ на: комментарий от cvs-255

битбангить

Шо делать? Ты решил CAN ногодрыгом? Мде...

аппаратный can далеко не везде есть

Не поверишь, но даже на STM8 он есть!!!

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

Ты не сможешь запороть штатный бутлодырь.

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

Если не послать специальную последовательность инициализации для BSL, то его UART так и останется в Hi-Z состоянии. Если, конечно, не перенастроить его ножки на выход в своей программе. Но по такой логике можно и SPI перевести в Master-режим на Slave-контроллере и тоже устроить КЗ.

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

Я такое на пиках делал, а недавно еще на STM8 повторил. Но т.к. ни те, ни другие аппаратно так не умели, то я тупо 9-м битом игрался. Естественно, пришлось писать свой терминальный клиент, т.к. screen или что-нибудь еще так не умеют. Зато удобно: вешаешь дофига модулей на один конвертер на PL2303 — и все работает..

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

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

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

Нда, геммороя много) Особенно с 9-битным uart. Это же получается все время туда-сюда гонять, при каждой передаче.

Кстати, у uart я еще одну проблему заметил. Если мы хотим опросить мк по spi, то мы на мк просто кладем нужные данные в регистр spi, и когда spi-master захочет получить значение, он его получит. А с uart каждый раз надо послать 9-битный байт, затем переключиться в 8-битный режим и дождаться, когда мк соизволит передать данные.

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

AVR и MSP430 точно умеют. Удобно то, что можно использовать копеечные модули USB-UART. Ну и что можно использовать МК без CAN, а вот UART есть практически везде.

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

Кстати, для реализации 1-wire через жопу UART ноги настраивают не в пушпул, а в открытый коллектор. Поэтому когда у тебя на Tx единица, а датчик подтягивает линию к нулю, КЗ не получается. Но приходится внешним резистором подтягивать, если МК не умеет выход с подтяжкой (STM32F103 не умеет, а все остальные STM32 умеют).

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

Вот я баран! Там же все равно Rx/Tx ноги соединяются! Можно тупо Rx не в режиме floating input держать, а в pullup input, и никаких голимых резисторов не нужно будет (правда, будет 47кОм, а не 4.7кОм, как в даташите на DS18 написано, но там ведь не TTL — нафиг им 4.7к?)!

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

Согласен. Мы первый вариант почему на UART делали — неправильно выбран был тип МК, CAN там не было, вот и пришлось извращаться, реализуя эдакий псевдоCAN.

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

Это тебе только так кажется. Вот, смотри. Это — модульная управлялка драйверами ШД (по 3 шаговика на один мелкоконтроллер). Умеет запоминать свой номер (правда, нафига-то я во флеш пишу, а не еепром, но процедура редкая — можно и так). Сначала по одному подключаешь модули и раздаешь им номера, потом все вместе соединяешь и на общей шине они себе болтаются...

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

Кхм... в случае SPI:

Переключить CS в низкий уровень;
Послать и принять данные;
Переключить CS в высокий уровень;

В случае UART:

Переключить UART в режим 9 бит;
Послать адресный байт;
Переключить UART в режим 8 бит;
Послать и принять данные;

С учётом того, что перевод UART между 8 и 9 битами обычно осуществляется установкой одного флага в нужном регистре, это ничуть не сложнее. Зато размер переданных и полученных данных может отличаться. Причём slave сможет сам выбрать сколько байт вернуть на запрос. А ещё он может долго тупить перед ответом. SPI требует, чтобы на каждый отправленный байт был тут же предоставлен ответный. А UART позволяет отвечать не синхронно, а когда данные будут готовы.

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

volatile uint8_t input_data;
volatile uint8_t output_data;

ISR(SPI_STC_vect) {
input_data = SPDR;
SPDR = output_data;
}

Писать сразу в регистр плохая идея - а что если запрос по SPI придёт дважды между обновлениями данных? Тогда во второй раз прочитается мусор. Да и часто нужно возвращать больше 1 байта, а тут без буферизации и обработчика прерывания не обойтись вообще. В случае с UART надо будет просто добавить проверку адреса и пихать данные в другой регистр.

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

Послать и принять данные;

вот только принимать мы будем не сразу же как мы послали сигнал, а тогда, когда МК будет готов это сделать.

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

По идее резистор зависит от скорости передачи данных. Ведь линия передачи имеет ёмкость. Когда МК отпустит линию из низкого состояния, ёмкость будет заряжаться через этот самый резистор. И если она не успеет зарядиться до такого напряжения, которое все посчитают единичкой, до следующего такта передачи, то будет плохо. Как следствие номинал резистора зависит от длины линии и от скорости передачи. Чем длиннее линия и чем выше скорость, тем резистор должен быть меньше (а ещё поэтому на высоких скоростях применяют низкие уровни сигналов типа 3.3, 2.5 или даже 1.8 вольта - чтобы до меньшего напряжения пришлось заряжаться ёмкости линии). А на совсем больших скоростях или больших ёмкостях линии начинает влиять и внутреннее сопротивление ножки МК - линия не успевает не только заряжаться, но и разражаться.

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

KivApple ★★★★★
()
Последнее исправление: KivApple (всего исправлений: 2)
Ответ на: комментарий от cvs-255

Нормальные люди, если им нужна многозадачность, используют прерывания и им совершенно всё равно, когда придёт ответ. А если многозадачность не нужна, то просто делают busy loop и опять же не важно, когда slave ответит.

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

А ещё он может долго тупить перед ответом.

В тех реализациях SPI-slave, которые на avr, в ответ шлется текущее содержимое регистра. По-другому spi и не может работать.

Тогда во второй раз прочитается мусор

если данные не были обновлены, то во второй раз прочитается то, что было послано в мк в первый раз.

cvs-255 ★★★★★
() автор топика
Ответ на: комментарий от KivApple

Ты предлагаешь дополнительно тянуть от каждого мк отдельный провод для сигнала прерывания, а затем ковырять драйвер gpio в линуксе, который стоит на центральном модуле, чтобы засунуть туда свои обработчики прерываний?

Задача очень банальная: раз в несколько миллисекунд опросить девайсы, получить текущие показания, и заняться их серьезной обработкой (т.е. loop не годится).

cvs-255 ★★★★★
() автор топика
Последнее исправление: cvs-255 (всего исправлений: 1)
Ответ на: комментарий от cvs-255

Вот именно! Хотим мы считать данные с датчика, а он не успел их обновить, и мы получаем код команды чтения. Делать дополнительную проверку? А если значение датчика совпадёт с кодом команды? И разве это не «считался мусор»? Если вместо того, что мы хотели получить, мы получили совсем другое, то это и есть ничто иное как мусор. Так что если МК не успевает пихать данные в регистр SPI, то протокол обмена нарушается и требуются всякие извращения, чтобы это продолжило работать.

KivApple ★★★★★
()
Ответ на: комментарий от cvs-255

В варианте с MPCM UART ничего тянуть не требуется, только 2 провода UART. А дождаться ответа можно простым select для tty, если нужна многозадачность, или блокирующим вызовом read, если программа больше ничего делать не должна. Потребуются отдельные GPIO для каждого RESET, если хочешь перепрошивку, но для SPI она тоже нужна. Даже больше - CS и RESET, а тут только RESET.

Речь про прерывания для UART шла для микроконтроллеров.

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

Ухищрение очень простое: пишем 0xFF сразу после обмена. И если нас опросили раньше, чем мы что-то осмысленное туда записали, то прочитается 0xFF. Делается 1-й командой.

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

cvs-255 ★★★★★
() автор топика
Последнее исправление: cvs-255 (всего исправлений: 1)
Ответ на: комментарий от cvs-255

Я же сказал, нужны всякие извращения. А если 0xFF тоже допустимое значение? А если надо выдать последовательность байт? Я никогда так не работал с SPI. Всегда делал так:

volatile uint8_t pos;
volatile uint8_t input_data[BUFFER_SIZE];
volatile uint8_t output_data[BUFFER_SIZE];

ISR(SPI_STC_vect) {
input_data[pos] = SPDR;
SPDR = output_data[pos];
pos++;
if (pos >= BUFFER_SIZE) pos = 0;
}

А ещё pos обнуляется в момент перехода CS в низкое состояние по прерыванию. Если пакет содержит лишь 1 байт, то, конечно, это не нужно. Но буферизация всё равно нужна. Тогда в случае, если опрос будет слишком быстрый, считается предыдущее значение, что гораздо лучше мусора.

И да, машины состояний я активно использую. А вот костыли не люблю.

KivApple ★★★★★
()
Последнее исправление: KivApple (всего исправлений: 4)
Ответ на: комментарий от cvs-255

Ну на мой взгляд, его стоит применять и для однобайтных, чтобы не было неоднозначности. Не верю, что ты передаёшь с AVR'ки лишь один байт, но места под буфер для него в ОЗУ нет.

А для UART лишь добавится проверка адреса и регистры будут другими.

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

Еще насчет stm32 хотел узнать, у них DMA с таким режимом работы uart дружит?

cvs-255 ★★★★★
() автор топика

stm32 шьется через uart при нужном положении BOOTM'ки, man stm32flash. Альтернативы - только jtag и swd

ncrmnt ★★★★★
()

столько критикуемые avr-ки

И кто же их критикует? У каждого МК своя ниша, и не стоит сравнивать член и палец.

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

SPI — это вообще извращение какое-то, подходящее только для внутрисхемной коммутации

Запусти его через 485 драйвер и используй хоть километровые линии. Хотя CAN для таких вещей конечно логичней.

aiqu6Ait ★★★★
()

Насколько мне известно - никакие. Проще взять STM32 Discovery со встроенный ST-Link и шить через него. Есть ещё вариант - сделать загрузчик, который поддерживает прошивку по SPI.

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

Я вообще не понимаю, нахрен это SPI так прижилось! Убогий же ублюдочный интерфейс! И целых три провода...

Это самый простой последовательный интерфейс в принципе. Приемник и передатчик - просто сдвиговые регистры.

Kosyak ★★★★
()
Ответ на: комментарий от cvs-255

Это офигенно удобная традиция. Если есть N-микроконтроллеров на плате, и надо со всеми ними по очереди общаться с центрального сока и иногда перепрошивать, то 3 провода SPI, и по 2 провода (CS и Reset) на каждый мк.

Для этого придумали JTAG.

И да, много МК с минимальным кол-вом проводов - I2C или CAN какой-нибудь. Собственно, некоторые стмки умеют шиться по I2C.

И вообще: http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf (Table 3)

/thread

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

не считая постоянной необходимости в программаторе.

где программатор? Общаемся по SPI, по нему же и прошиваем.

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