В процессе серийного производства электронных устройств следующим этапом после монтажа печатных плат является стенд серийной прошивки и тестирования. На нем производится прошивка микроконтроллера/микропроцессора, запуск платы и ее проверка в том или ином объеме. Естественно, как и монтаж плат, работа стенда также должна быть мах автоматизирована. В крайнем случае, ручные операции, от которых не удалось избавиться, должны быть предельно просты, интуитивно понятны и монотонны. В статье описывается процесс разработки подобного стенда под микропроцессор IMX6ULL.
В конце приводится ссылка на исходный код стенда, который может быть адаптирован под другие семейства микропроцессоров с архитектурой ARM.
Итак, в процессе работы с отладочной платой мы более-менее убедились в том, что выбранный микропроцессор нас более-менее устраивает, - нужные интерфейсы поддерживаются, быстродействия хватает и появилось понимание примерного размера финальной прошивки. Останавливаем свой выбор на данном процессоре. Пора приступать к разработке печатной платы.
Среди прочих требований к плате нужно продумать решение трех вопросов:
где будет храниться образ ядра Linux (прошивка, image): SPI флеш, NAND флеш, microSD карта или еще что-либо;
как эта прошивка будет поставляться в серийно выпускаемые изделия;
как будет задаваться загрузочный интерфейс процессора;
Варианты ответов на каждый вопрос:
Проще всего использовать microSD карту. В этом случае вам нужно лишь подготовить N-ное количество microSD карт с образом ядра вставить их во все изготовленные устройства. Но такой способ может не подойти, если:
необходимо разработать устройство в индустриальном исполнении (рабочие температуры от -40 С);
вы хотите осложнить доступ к прошивке устройства;
устройство может подвергаться вибрациям;
у вас есть строгие ограничения по себестоимости конечного изделия и каждый цент на счету (microSD карта + разъем заведомо дороже, чем микросхема флеш-памяти распаянная на плате);
у вас есть строгие ограничения по габаритам конечного изделия;
Если microSD-карта не подходит, - остается выбор между NOR и NAND памятью. В целом, при выборе типа памяти нужно отталкиваться от размера финальной прошивки. Если до 32 Мб, - то лучше выбрать микросхему памяти NOR (цена - меньше, ресурс - выше), если больше 32 Мб - то остается NAND.
Если выбор пал на микросхему памяти, распаянную на плате, то есть два варианта:
образ ядра прошивается в микросхему до распайки на плате. В этом случае микросхемы по-очередно извлекаются из катушки, устанавливаются в программатор (наподобие такого), затем упаковываются обратно в катушку. Очень трудоемкий и не технологичный процесс.
образ ядра прошивается в микросхему после распайки на плате с помощью микропроцессора. Процессор нужно каким-либо образом запустить (при этом загрузочная микросхема флеш памяти пуста!), доставить ему образ прошивки, которую процессор и загрузит в м/сх памяти. Звучит как нечто, что очень сложное в реализации, зато это снижает количество ручных операций в процессе производства. Забегая вперед скажу, что мы выбрали именно этот вариант и нам удалось его автоматизировать.
При работе с отладочными платами вы почти наверняка встречали нечто подобное:
переключатель, задающий загрузочный режим. Дело в том, что процессоры, как правило, поддерживают несколько различных вариантов загрузки, таких как SPI, QSPI, SDHC, UART и пр. Какой-именно вариант загрузки использовать определяется фьюз-битами. Процессор может вычитать фьюз-биты из регистров, либо определив состояние определенных GPIO. Какой именно способ процессору использовать, в свою очередь, задается состоянием двух других ножек (BOOT_MODE0 и BOOT_MODE1).
Также можно встретить вариант одного-единственного варианта загрузки, заданного резисторами:
Если габариты позволяют и не жалко несколько ножек процессора, то лучше выбрать один из этих вариантов (переключатель или резисторы).
В случае же, если вы ограничены в габаритах (наш случай) или нужно высвободить ножки процессора под другие задачи, то остается только третий вариант, - "прожигать" фьюз-биты.
Итак, в нашем случае, ответы на три озвученных ранее вопроса были такими:
Образ хранится в микросхеме памяти. SPI NOR флешка.
Флешка прошивается уже будучи распаянной на плате.
"Прожиг" фьюз битов.
Стенд
Решением задачи при такой постановке вопроса стал разработанный стенд серийной прошивки и первоначального тестирования.
Устройство, под которое был разработан стенд:
SoM-модуль, на борту стандартный для SoM-модулей набор: Процессор, память RAM, память flash, физика ethernet, физика wi-fi. По всем четырем граням расположены контактные площадки в форме полу-отверстий с шагом 1.5мм.
А вот и собственно сам стенд:
С аппаратной точки зрения, все довольно тривиально: по центру набор пружинных контактов под тестируемый SoM, который прижимается сверху вертикальным зажимом. Из подведенной к модулю периферии: UART, JTAG, Ethernet. Ну и питание.
Алгоритм работы стенда
В ручную, процедура прошивки и прожига фьюз-битов выглядит следующим образом:
Тестируемое устройство устанавливается в стенд
подключается usb-uart переходник, программатор JLink, Ethernet-кабель, подается питание.
Запускается openocd сервер (openocd.exe);
Производится подключение к openocd серверу по telnet (openocd клиент);
Открывается COM-порт, назначенный USB-UART переходнику;
Сброс процессора (через консоль openocd-клиента):
reset init; arm core_state arm; halt;
Грузим образ u-boot (через консоль openocd-клиента):
load_image u-boot.imx 0x877ff400
Грузим образ ядра linux (через консоль openocd-клиента):
load_image openwrt-imx6ull-cortexa7-video-squashfs.mtd-factory.bin 0x82000000
Запускаем работу процессора (через консоль openocd-клиента):
resume 0x87800000
В это время должен стартануть u-boot и в консоли com-порта появятся логи загрузки. Нажимаем enter, чтобы остаться в консоли u-boot.
Определите флешку (консоль COM-порта):
=> sf probe
И прошейте флешку (консоль COM-порта):
=> sf update 0x82000000 0x1000 0x8000
Прожгите фьюз-биты (консоль COM-порта):
=> fuse prog -y 0 5 0x0a000030
=> fuse prog -y 0 6 0x00000010
Ребутните процессор (консоль COM-порта):
=> reset
После этого процессор должен ребутнуться и загрузить ядро линукс с флешки без помощи программатора.
Автоматизируй это
Естественно, шаги с 3-его по 13-й можно автоматизировать. По-питонячьи это выглядит так:
# 1. Init OpenOCD server
device_state = Queue()
p_openocd = Process(target=run_openocd_server, args=(device_state,))
p_openocd.start()
check_state(device_state, STATE_JTAG_DEVICE_DETECTED)
# 2. Init. Connect to OpenOCD server via Telnet
telnet_socket_write_queue = Queue()
p_telnet = Process(target=run_telnet_client, args=(telnet_socket_write_queue,))
p_telnet.start()
check_state(device_state, STATE_TELNET_CLIENT_CONNECTED)
# 3. Init. Open COM port.
device_state_com = Queue()
com_port_write_queue = Queue()
p_com_port = Process(target=run_com_port_handler, args=(device_state_com,com_port_write_queue,CFG_COM_PORT,))
p_com_port.start()
# 4. Reset CPU
telnet_socket_write_queue.put((TELNET_CMD_RESTART_CPU + "\r\n").encode())
check_state(device_state, STATE_CPU_RESET_COMPLETED)
# 5. Load u-boot image
telnet_socket_write_queue.put((TELNET_CMD_LOAD_U_BOOT_IMAGE + "\r\n").encode())
check_state(device_state, STATE_IMAGE_LOADED, 30)
# 6. Load kernel image
telnet_socket_write_queue.put((TELNET_CMD_LOAD_KERNEL_IMAGE + "\r\n").encode())
check_state(device_state, STATE_IMAGE_LOADED, 600)
# 7. Start U-boot execution
telnet_socket_write_queue.put((TELNET_CMD_START_U_BOOT + "\r\n").encode())
check_state(device_state_com, STATE_U_BOOT_CONSOLE_ACCESSED)
# 8. Check flash IC available
com_port_write_queue.put(COM_CMD_CHECK_FLASH + "\r")
check_state(device_state_com, STATE_FLASH_IC_DETECTED)
# 9. Flash firmware to IC
com_port_write_queue.put(COM_CMD_WRITE_FIRMWARE_TO_FLASH + "\r")
check_state(device_state_com, STATE_FIRMWARE_FLASHED_TO_IC, 300)
# 10. Burn fuse bit (ECSPI3 programming 0x450 = 0x0a000030)
com_port_write_queue.put(COM_CMD_BURN_FUSE_BITS_1 + "\r")
check_state(device_state_com, STATE_FUSE_BITS_BURNED)
# 11. Burn fuse bit (BT_FUSE_SEL programming 0x460 = 0x00000010)
com_port_write_queue.put(COM_CMD_BURN_FUSE_BITS_2 + "\r")
check_state(device_state_com, STATE_FUSE_BITS_BURNED)
# 12. Reset device
com_port_write_queue.put(COM_CMD_RESET_DEVICE + "\r")
Исходники можно найти тут. Скрипт может быть относительно легко адаптирован под другие семейства процессоров с архитектурой ARM (семейства IMX компании NXP, по крайней мере).
TO-DO
В планах - замена шага №6 (загрузка factory образа по JTAG занимает очень много времени) на загрузку с TFTP-сервера с помощью u-boot утилиты tftp.
Комментарии (23)
fk0
25.01.2022 03:29Зачем мучения с пружинными контактами и сложной приспособой к ним, когда проще для программирования и отладки добавить один дешевый коннектор (1.27mm double row pin header) который может быть подключен вручную (это проще...) На который вывести:
сигналы для программирования (JTAG, SWD, etc...);
питание от внешнего источника;
контрольные точки (измерение напряжений вторичных источников питания размещённых на плате, частоты опорного генератора и т.п.);
последовательный порт, USB или сеть (настройка, вывод диагностической информации от процедуры самотестирования).
Если речь о тестировании, то проще реализовать самотестирование путём прошивки отдельной программы или чем-то вроде, а не путём подключения к исключительно сложному внешнему стенду (причем еще разному для каждой новой версии или варианта изделия...) И для чего ещё на этапе разработки электронной схемы предусмотреть механизмы самотестирования.
Причём это может быть даже не разъём, а контакты с краю печатной платы наподобии PCI-ex ламелей и включаться может в какой-либо подходящий ламельный разъём. Соответственно можно сделать "материнскую плату" для программирования и тестирования разом десятка дочерних плат.
Или что-то вроде tag-connect, который может быть как в виде отверстий и контактов на плате (занимает площадь), так и в виде краевых контактов (плата сложней).
Разумеется нужна минимальная защита от дурака, вроде того, что коннектор должен быть или симметричным, или не позволять неправильное включение. И контакты "земли" должны быть продублированы со всех возможных сторон, чтоб питание не осуществлялось через сигнальные цели и защитные диоды при включении "на горячую".
Лучше конечно, чтоб после замыкания контакта и выдержки паузы в полсекунды просто автоматически включалось питание и запускалось программирование, чтоб на компе ничего нажимать не надо было.
almaz1c Автор
25.01.2022 11:31проще для программирования и отладки добавить один дешевый коннектор (1.27mm double row pin header)
Предлагаете тестируемое устройство габаритами 42 х 43 х 3 мм превратить в устройство габаритами 42 х 49 х 7 мм ?
Если речь о тестировании, то проще реализовать самотестирование путём прошивки отдельной программы или чем-то вроде, а не путём подключения к исключительно сложному внешнему стенду
Каким образом прошивка протестирует работу аудио, видео, LoRaWAN, 2 езернета, 2 юсб и пр без стенда, к которому подключена вся эта периферия?
а контакты с краю печатной платы наподобии PCI-ex ламелей
http://suddendocs.samtec.com/catalog_english/pcie.pdf
PCI Express разъем на 98 пинов (количество пинов в нашем SoM-модуле) имеет длину 56 мм. Предлагаете устройство габаритами 42 х 43 х 3 мм превратить в устройство габаритами 42 х 56 х 3 мм?
Соответственно можно сделать "материнскую плату" для программирования и тестирования разом десятка дочерних плат
десяток JTAG программаторов, десяток USB-UART адаптеров, два десятка USB-портов на ПК, десяток подключенных аудио-модулей, десяток подключенных видео-модулей, ....
AlexVRud
25.01.2022 12:42+1А вариант вывести MicroSD и пару boot битов на контакты SoM-а не рассматривали? Тогда на стенде, за счёт переподтяжки boot битов, можно было бы грузиться с MicroSD и прошивать без программатора. А через нескольких GPIO контролировать результат.
almaz1c Автор
25.01.2022 12:50Опять же все в габариты упирается. Размеры SoM-модуля 42 х 43 мм. Разместить на нем разъем для microSD карты не представляется возможным. Плюс, если посмотрите на SoM-модули таких известных производителей, как variscite, например, то SD-карту все-таки выносят на платы расширения.
AlexVRud
25.01.2022 13:39то SD-карту все-таки выносят на платы расширения.
Так я об этом и говорю.
almaz1c Автор
25.01.2022 15:35Аа, понял)
Даже не думали. JTAG нас в принципе устраивает. Видимо, у любой задачи может быть несколько решений.
Sawko88
25.01.2022 15:39almaz1c Автор
25.01.2022 15:41Доводилось работать с похожим. Если я правильно понял, то его нужно удерживать руками во время обновления прошивки и тестирования? Автоматизация тут не светит.
Sawko88
25.01.2022 15:49Да, все верно, держать руками нужно, вопрос лишь только в том , сколько времени занимает весь процес программирования и тестирования , если в течении 1 минуты , то вполне рабочий вариант, если дольше , то тут уже все будет зависеть от выносливости работника, который подготавливает оборудование =) . Но в вашем случае, тоже ведь нужно , чтобы кто-то менял модуль после программирования и тестирования ? =) а могу ещё поинтересоваться , где вы достали подпружиненные контакты ?
almaz1c Автор
25.01.2022 15:57Да, модуль сменил, запустил скрипт и 5 минут (время работы скрипта) я свободен)
А сидеть неподвижно, затаив дыхание, в течении 5 минут, - нет спасибо)
Sawko88
25.01.2022 15:59Согласне , что этим Ваш вариант лучше, что можно раслабляться во время тестирования =)
fk0
26.01.2022 03:01+1Вот поэтому я и предлагал материнскую плату на N изделий разом. Логика в том, чтобы экономить время человека. Так получается эти самые 5 минут всё равно человек нужен и за рабочую смену не выпустить более 96 изделий, реально раза в два меньше, и не может работник ничем заниматься ещё.
Вот если бы можно было те же самые 96 плат подключить, условно, за полтора часа, а потом на три часа идти чем-то другим заниматься -- совершенно другое дело было бы. Чтоб потом только где-то на той же матьплате красными диодиками, или на компе, отображались прошедшие тест и неисправные изделия.
Иметь 96 программаторов для этого не нужно. Нужен какой-то коммутатор, мультиплексор, переключающий единственный программатор и всё прочее ко всем приборам по-очереди. Я понимаю, что в случае USB это уже не просто... И в данном случае может быть практически не применимо (много слишком разнотипных сигналов). Но в общем случае такая идея может быть стоящая.
Конечно это зависит от объёмов, зарплат и всего прочего... Если, условно, лишняя сотня рублей в себестоимости производства важна. Или если тест не дай бог не пять минут, а все два часа (с прожаркой в духовке для куры гриль).
PS: честно говоря пост прочитал по диагонали в первый раз и подумалось, что ваш стенд и есть ваше изделие, потому такой странный на ваш взгляд комментарий и написал изначально. Да, в в случае мелкого модуля ваш вариант вполне оптимален...
almaz1c Автор
26.01.2022 12:52Наверное я еще по объемам не дорос - 8-ми часовой полноценно загруженной смены нет и в помине.
Наверное, в ближайшее время придем к подобному стенду - на miniPCIe разъемы переходим прямо сейчас. Не соображу пока, как 5-6 пинов JTAG мультиплексировать на N модулей, - но и это решаемо наверное.
А производительность можно ускорить и без распараллеливания. Достаточно скрипт довести до ума, - заменить JTAG на ethernet при обновлении прошивки. В этом случае вполне реально снизить время работы скрипта с 5-ти до 2-х минут.
fk0
26.01.2022 02:45+1Бывают похожие с защелками: https://www.tag-connect.com/wp-content/uploads/bsk-pdf-manager/TC2050-IDC_Datasheet_7.pdf
hooperer
26.01.2022 11:34Бывают ещё "летающие контакты".
Мы вот поджимаем "иголками" при тестировании и прошивки ( используем VAR Som Solo).
Да, SD карточка на материнской плате, да с тестированием одновременным и её и usb. Да, сотнями приборов.
Считается хорошим тоном всё таки посмотреть после прошивки, по Ethernet версию того, что зашилось. Мы так вообще ставим в usb на стенде прошички и тестирования wifi и отдельно проверяем трафик с него в эзернет порт.
almaz1c Автор
26.01.2022 12:33А зачем тестировать/прошивать готовый SoM-модуль? Он же почти наверняка тестировался производителем и к вам приходят заведомо исправные модули с уже прожжеными фьюзами и прошитой прошивкой, которую можно обновить стандартными средствами (sysupgrade, например)?
hooperer
26.01.2022 17:53+1Вопрос:
"А зачем тестировать/прошивать готовый SoM-модуль? Он же почти наверняка тестировался производителем и к вам приходят заведомо исправные модули с уже прожжеными фьюзами и прошитой прошивкой, которую можно обновить стандартными средствами (sysupgrade, например)? "
Первая часть ответа : Для того чтобы обеспечить надёжность в соответствии со стандартом надёжности в компании. Типичный пример для нас - прибор 15-и летней давности достают из за фальш потолка, сдувают пыль, обновляют прошивку и ставят работать дальше.
Вторая часть Вопроса "Он же почти наверняка тестировался производителем и к вам приходят заведомо исправные модули с уже прожжеными фьюзами и прошитой прошивкой, которую можно обновить стандартными средствами (sysupgrade, например)? "
Ответ делиться тоже на две части. Первая часть говорит о том, что мы делаем ВСЮ прошивку Сами. и фьюзы и секьюр область шьём сами, свои номера.
Вторая часть ответа на этот вопрос заключается в том, что до этого я работал в компании Овен. и мы делали похожие SOM модули, только на ситаре. Они до сих пор используются в плк110[m02]. И как бы маштаб производства достаточно большой, и при этом мы накушались Внезапных проблемм на SOM модулях. И предпочитаю надёжность в тестировании и прошивке проблемам по возврату дорогих модулей от Потребителя.
Тем более что если модуль сторонний - стоит понимать его Гарантийный срок в соотнесении с Гарантийным сроком Вашего изделия. А он зачастую исчисляется временем попадания на Ваш склад. А в текущих реалиях, я думаю Вы можете прикинуть когда возникшая у Потребителя проблема может вернуться, относительно уже истёкшего гарантийного срока к Вам, и темболее поставщику модулей.
srg27y
27.01.2022 14:46pogo-pin в помощь
можно не ставить в ряд как разъем, а в удобных местах по плате раскидать
osmanpasha
А по USB оно умеет загружаться? Мы с am335x от TI пробовали такой вариант: встроенный загрузчик грузит по USB специально собранный uboot, uboot грузится и создаёт поверх USB сетевой интерфейс и запускает TFTP-сервер, а потом ПК на этот сервер шлёт прошивку, которая записывается uboot-ом во флэш. Всё по одному интерфейсу. Правда, фьюзы мы не прожигали
almaz1c Автор
Перебирали разные варианты, в том числе, загрузку по usb в recovery режиме. Видимо, с jtag я дружу больше, чем с usb)