Мои интересы всегда были, я бы сказал, разнообразны и широки. Когда дело доходит до «технических» вещей, я бы сказал, что они на самом деле несколько ограничены или, скорее, специфичны там, где совпадают мои интересы. Настоящее удовольствие заключается в идее изучения «языка» — в самом общем смысле этого слова и приобретения навыков, которые бросают вызов и позволяют преодолевать так называемые проблемы реального мира. Решение проблем, логика, символы и забавная эстетика — все это играет важную роль, чтобы быть чрезвычайно интересным и, надеюсь, потенциально полезным для человечества.

Пытаясь получить дополнительный доход, чтобы погасить огромную сумму долга, мы с моей девушкой решили открыть магазин ebay, предложив услугу по перезаписи старых игровых файлов на карты micro-SD. Некоторое время бизнес шел довольно хорошо, в конечном итоге став слишком большим бременем по сравнению с полученной прибылью. На пике своего развития бизнес заставлял меня прошивать в среднем 5 карт в день — это означало, что моя девушка или я должны были уделять внимание своему MacBook и / или Raspberry Pi в течение примерно 4 часов или более, чтобы процесс прошивки продолжался. .

В то время я использовал замечательную программу Etcher для прошивки карт. К моему удивлению, не было возможности прошить файл образа (foo.img) на несколько устройств. Я должен быстро отметить, что Etcher в конечном итоге будет обновлен, чтобы включить эту функцию, и она прекрасно работает — хорошая работа, команда Etcher. До этого момента мой опыт программирования включал программирование Arduinos, atTinys, Raspberry Pi и немного программирования на Python и Linux. Когда возникла эта проблема, и я понял, что должен быть лучший способ… Я сразу подумал о том, как весело было бы решить мою проблему, создав программу, которая прошивает несколько устройств одновременно.

Принимая во внимание, что язык, с которым я лучше всего был знаком, был «C-подобным» языком Arduino, а в данный момент я не совсем готов к изучению C или C++, я решил использовать язык, с которым я не слишком недавно сталкивался — язык, названный в честь моей любимой вещи: Python.

Хотя это было сделано в спешке, я начал процесс с написания плана действий и обозначения «безусловно желательных функций/методов».

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

Графический интерфейс — это то, что я начал исследовать в первую очередь, обнаружив что-то под названием «TKinter/tkinter» — де-факто фреймворк графического интерфейса для Python. Это было относительно легко понять, поскольку я получил достаточно информации, чтобы заставить базовый графический интерфейс работать в течение часа.

На самом деле, многие из используемых макетов и методов графического интерфейса не были ни слишком сложными, ни разочаровывающими. Настоящая проблема заключалась в сложных процессах для многопоточности и, более того, в изучении модуля подпроцесса в попытке манипулировать командной строкой. Манипулирование включает в себя вызов команды dcfldd с необходимыми следующими аргументами для прошивки предполагаемого файла if= — обратите внимание, что if= на самом деле является инициализмом для входного файла — на несколько устройств с параметром of=, где of= означает выходной файл.

Поначалу модуль подпроцесса мог показаться довольно запутанным, и я опасался/осторожно относился к методам кодирования, которые манипулировали командной строкой. Попрактиковавшись в использовании модуля подпроцесса и его методов Popen, call, communicate и прочитав несколько статей по использованию подпроцесса (многие из статей были по большей части запутанными, похоже, одна и та же статья была перефразирована), я, наконец, нашел способ вызывать необходимые системные команды и осмысленно использовать их ввод, вывод, каналы ошибок:

Переменные для if=, of= и /dev/disk{}\n".format(device_name) задаются значениями ввода пользователя в графическом интерфейсе. После того, как пользователь выбрал файл для прошивки, устройства для прошивки и нажал кнопку «Flash», текстовый файл с расширением .sh создается и открывается с помощью dd_exe_f = open(file location, "w") — где «w» означает создание текстового файла для записи. к. Затем следует for i in range(1): , который представляет собой одноразовый цикл вложенной команды, которая записывает combo_fmt content: dcfldd if="inputFile" of="outputDevice1" of="outputDevice2" of="ouputDevice3" of="outputDevice4" в недавно созданный файл сверху.

Выше приведен фрагмент из моего приложения для дублирования microSD, которое определяет, какие и какие переменные должны быть включены в скрипт bash, который будет создан и запущен один раз, а затем отброшен — процесс, вызванный в $BASH, будет продолжать выполняться как threaded процесс (многопоточность).

Когда я, наконец, понял, что нужно сделать, чтобы вызвать команду dcfldd в $BASH и асинхронно, у меня была настроена работающая программа. Следующие проблемы были связаны с безопасным вводом команд в терминал, а не с остановкой всей программы во время фактического процесса перепрошивки.

Чтобы предотвратить зависание программы при запуске процесса перепрошивки с помощью инструмента dcfldd cli, определяется второй поток, и задействованные методы вызываются при нажатии кнопки «Flash».

Вот решение еще одной проблемы, связанной с многопоточностью. Как только процесс запущен асинхронно, нет никаких мер безопасности, чтобы предотвратить повторное нажатие кнопки «Flash», вызов команды dcfldd и прерывание чувствительного процесса перезаписи данных на запоминающее устройство. Чтобы предотвратить это, я включил аргумент, который предотвращает запуск любых других потоков после нажатия кнопки «Flash».

Фактическое объявление функции stoprequest включено в другую функцию, которая занимается прослушиванием USB-устройства, изменением событий до начала процесса перепрошивки. Этот процесс также необходим только перед мигающим событием, а также должен быть асинхронным, что достигается за счет многопоточности — изменения устройства обнаруживаются, и если устройство присутствует, значок помещается рядом с устройством в графическом интерфейсе. Как только процесс перепрошивки начался, в этом многопоточном процессе нет необходимости, поэтому threading.Event() определяется в функциональном блоке dev_status и вызывается при нажатии кнопки «Flash», в результате чего цикл while возвращает false и выходит из цикла. .

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

Ждите следующий пост об этом проекте — скоро он будет. Я продолжу изучение и реализацию сценариев bash и их выполнение с помощью Python.

Спасибо за чтение! すごいです!