Как прошить телефон через uart
В статье Загрузка программы в ОЗУ и запуск через UART было рассказано о том, как загрузить программу в ОЗУ и запустить ее. Теперь рассмотрим создание программы для ОЗУ, которая умеет записывать массив данных из ОЗУ во FLASH память. Эту программу можно назвать "прошиватель". В массиве данных будет находиться программа мигания диодом. В итоге, после прошивки при запуске из Flash на плате будет мигать светодиод.
Программа "Прошиватель"
Создадим новый проект и назовем его "Flash_UartWriter". В библиотеках необходимо выбирать пункты - Startup_MDR1986BE9x, EEMPROM, PORT, RST_CLK. Затем добавить в проект новый файл "main.c" (подробнее о создании нового проекта рассказано в статье Создаем новый проект)
Теперь установим настройки проекта для запуска в ОЗУ. Как это можно сделать описано в Запуск программы из ОЗУ в среде Keil. В данном случае, файл "setup.ini" можно не создавать и не подключать, так как не планируется запускать проект в отладчике.
Далее приведен листинг программы "прошивателя", состоящий из одного файла "main.c". Код собран из двух примеров:
Мигание светодиодом - Hello World - светодиод. Отсюда взята настройка порта и цикл мигания светодиодом, для того чтобы отображать статус того, что происходит в программе. И пример работы с EEPROM под названием "Sector_Operations" из библиотеки SPL (Расположение функций в ОЗУ, программирование EEPROM).Пример "Sector_Operations" при стандартной установке Keil можно найти по пути:
C:\Keil_v5\ARM\PACK\Keil\MDR1986BExx\1.xx\Examples\MDR1986VE9x\MDR32F9Q1_EVAL\EEPROM\Sector_Operations
Файл "main.c" представлен в фрагменте кода 1:
uint32_t Led_Pin = PORT_Pin_1; // Вывод индикации на второй светодиод, в HelloWorld используется PORT_Pin_0
uint32_t readAddr(uint32_t address); // Функция возвращает 32 битное слово, расположенное по указанному адресу
void Delay(int waitTicks); // Функция задержки из примера HelloWorld
void LedInit(void); // Функция инициализации PortC из примера HelloWorld, код ранее лежал в main()
void LedSetState(uint16_t ledOn); // Функция зажигает или гасит светодиод Led_Pin. Включим светодиод на время работы с Flash и выключим по окончании.
void LedShowStatus(uint32_t flashPeriod); // В Функции содержится бесконечный цикл мигания светодиодом с периодом flashPeriod из примера HelloWorld.
int main(void)
uint32_t Data = 0;
uint32_t i = 0;
// Тактирование EEPROM
RST_CLK_PCLKcmd(RST_CLK_PCLK_EEPROM, ENABLE);
//--------- Включаем светодиод - индикатор работы с EEPROM -------
LedInit();
LedSetState(1);
//------------ Стираем первую страницу в EEPROM ----------------
/* Erase main memory page MAIN_EEPAGE */
EEPROM_ErasePage (EEPROM_ADDR_START, EEPROM_Main_Bank_Select);
/* Check main memory page MAIN_EEPAGE */
Data = 0xFFFFFFFF;
for (i = 0; i < EEPROM_PAGE_SIZE; i += 4)
// При записи вся память страницы Flash заполняется единицами, т.е. значениями 0xFFFFFFFF.
// Проверяем так ли это
if (EEPROM_ReadWord (EEPROM_ADDR_START + i, EEPROM_Main_Bank_Select) != Data)
// Уходим в цикл мигания в случае ошибки с периодом ERR_DELAY_CLEAR
LedShowStatus(ERR_DELAY_CLEAR);
>
>
//------------ Запись программы в первую страницу EEPROM -------
/* Fill main memory page MAIN_EEPAGE */
for (i = 0; i < EEPROM_PAGE_SIZE; i += 4)
// Считываем по словам код программы HelloWorld, записанной по UART с адреса 0x20002000
Data = readAddr(RAM_ADDR_START + i);
// Записываем код в Flash память, начиная с адреса 0x08000000
EEPROM_ProgramWord (EEPROM_ADDR_START + i, EEPROM_Main_Bank_Select, Data);
>
/* Check main memory page MAIN_EEPAGE */
for (i = 0; i < EEPROM_PAGE_SIZE; i +=4 )
// Считываем по словам код программы HelloWorld, записанной по UART с адреса 0x20002000
Data = readAddr(RAM_ADDR_START + i);
// Считываем код программы из Flash памяти и сравниваем с кодом из ОЗУ
if (EEPROM_ReadWord (EEPROM_ADDR_START + i, EEPROM_Main_Bank_Select) != Data)
// Уходим в цикл мигания в случае ошибки с периодом ERR_DELAY_VERIFY LedShowStatus(ERR_DELAY_VERIFY);
>
>
//------------ Гасим светодиод -------
// LedSetState(0); // Выключаем светодиод по окончании работы с Flash
// Показываем длинными периодами мигания, что программа успешно закончила свою работу.
LedShowStatus(ST_DELAY_OK);
>
uint32_t readAddr(uint32_t address)
return (*(__IO uint32_t*) address);
>
void Delay(int waitTicks)
int i;
for (i = 0; i < waitTicks; i++)
__NOP();
>
>
void LedSetState(uint16_t ledOn)
if (ledOn) PORT_SetBits(MDR_PORTC, Led_Pin);
else
PORT_ResetBits(MDR_PORTC, Led_Pin);
>
void LedShowStatus(uint32_t flashPeriod)
// Запускаем бесконечный цикл обработки
while (1)
// Считываем состояние ввода PD0
// Если на выводе логический "0", то выставляем вывод в логическую "1"
if (PORT_ReadInputDataBit (MDR_PORTC, Led_Pin) == 0)
PORT_SetBits(MDR_PORTC, Led_Pin);
>
// Считываем состояние вода PD0
// Если на выводе = "1", то выставляем "0"
if (PORT_ReadInputDataBit (MDR_PORTC, Led_Pin) == 1)
PORT_ResetBits(MDR_PORTC, Led_Pin);
>;
void LedInit(void)
// Заводим структуру конфигурации вывода(-ов) порта GPIO
PORT_InitTypeDef GPIOInitStruct;
// Включаем тактирование порта C
RST_CLK_PCLKcmd (RST_CLK_PCLK_PORTC, ENABLE);
// Инициализируем структуру конфигурации вывода(-ов) порта значениями по умолчанию
PORT_StructInit(&GPIOInitStruct);
// Изменяем значения по умолчанию на необходимые нам настройки
GPIOInitStruct.PORT_Pin = Led_Pin;
GPIOInitStruct.PORT_OE = PORT_OE_OUT;
GPIOInitStruct.PORT_SPEED = PORT_SPEED_SLOW;
GPIOInitStruct.PORT_MODE = PORT_MODE_DIGITAL;
// Применяем заполненную нами структуру для PORTC.
PORT_Init(MDR_PORTC, &GPIOInitStruct);
>
Данный код будет располагаться в ОЗУ, поскольку загружается через UART. По этой причине нет необходимости решать вопрос с расположением файла "MDR32F9Qx_eeprom.c" в ОЗУ, как это было сделано в Расположение функций в ОЗУ, программирование EEPROM
Bin файл для "HelloWorld"
Теперь необходимо получить bin-файл для программы, которую будем прошивать в Flash. Как это сделать, написано в статье Загрузка программы в ОЗУ и запуск через UART, "Получение bin файла":
открыть проект "HelloWorld";
в настройках проекта выбрать в Options - User;
найти пункт AfterBuild/Rebuild;
дописать: $K\ARM\ARMCC\bin\fromelf.exe --bin [email protected] !L
пересобрать проект ("F7");
в папке проекта найти файл "HelloWorld.bin".
Перед запуском "прошивателя" сотрем Flash память и убедимся, что в памяти пусто. В меню выбираем Flash - Erase. Для того чтобы данная операция отработала, к демо-плате должен быть подключен программатор в Jtag_B, переключатели Mode должны быть в режиме "000" и должно быть подано питание. Без установленного соединения, данный пункт меню не активен.
Теперь можно нажать Reset или выключить-включить питание, чтобы убедиться, что светодиод не мигает. После работы "прошивателя", Reset и подача питания должны будут приводить к миганию светодиодом.
программирование микроконтроллера по UART
Для программирования микроконтроллера по UART необходимо выставить режим загрузки через UART, Mode = "110". Операции работы с UART загрузчиком были рассмотрены в статье Тестируем Bootloader в режиме UART. Далее загружаем обе программы - "HelloWorld" и "прошиватель" в ОЗУ.
Как было указано в коде, "прошиватель" будет копировать память с адреса 0x2000_2000. Сюда и необходимо загрузить файл "HelloWorld.bin". Сам же "прошиватель" запишем в адреса с 0x2000_0000, потому что так было настроено в опциях проекта. Запуск "прошивателя" также необходимо произвести с адреса 0x2000_0000. В свойствах bin файлов узнаем их размеры. Подробно действия описаны в статье Загрузка программы в ОЗУ и запуск через UART. Дополнительно загружается программа "HelloWorld".
В итоге информация, необходимая для загрузки:
Подключаем UART адаптер, подаем питание на плату, открываем программу "Terminal v1.9b". Максросы, используемые в этой программе, можно найти в статье Тестируем Bootloader в режиме UART. Необходимо добавить к ним следующие:
Код M10: загрузка HelloWorld.bin
L$00$20$00$20$CC$05$00$00 = L 0x00200020 0xCC050000 - младшими байтами вперед
Код M11: загрузка Flash_UartWriter.bin
L$00$00$00$20$DC$09$00$00 = L 0x00000020 0xDC090000
Код M12: запуск Flash_UartWriter
R$00$00$00$20 = R L 0x00000020
Проверяем, что "HelloWorld" еще не прошит
В программе Terminal нужно нажать Connect. Настройки обмена должны быть выставлены согласно спецификации или статье Тестируем Bootloader в режиме UART. Для синхронизации скорости необходимо отправлять 0 циклически. Запускаем макрос М1 - период посылки устанавливаем минимальный, ставим галочку. Дожидаемся приглашения '>' и останавливаем циклическую посылку 0 - снимаем галочку!. Запустить Макрос М8 - переход на программу из Flash, чтобы убедиться, что там еще не зашита программа мигания светодиодами. Наблюдаем, что светодиод не мигает. Если светодиод мигает, значит память не была очищена, возвращаемся к пункту Bin файл для "HelloWorld".Важно не забыть снять галочку циклической посылки 0-ля после получения ответа от МК, иначе этот ноль продолжает посылаться, и весь последующий обмен через UART будет нарушен!
Протокол обмена в окне терминала выглядит так:
>R - т.е. получили приглашение и выполнили команду Run.
в Hex окне видим пришедшие данные:
0D 0A 3E = '>' 52 = 'R'
Прошиваем Flash
Для того, чтобы прошить Flash необходимо нажать Reset на плате для того, чтобы вернуться в UART-загрузчик, и начать все с начала:
Макрос "М7" - Увеличиваем скорость обмена до 19200 бод, чтобы загрузка прошла быстрее. В данном случае приходит неправильный ответ от МК, игнорируем. Выставляем в программе "Terminal" скорость обмена 19200 бод, и запрашиваем приглашение - макрос "М2". Получаем '>', скорость поменялась, значит все в порядке. Выполняем макрос "М10" - МК входит в режим загрузки массива данных и ожидает 1484 байт. Нажимаем SendFile и выбираем "HelloWorld.bin". Файл загружается и приходит ответ - 'K'. Загрузка прошла успешно. В SendFile выбираем "Flash_UartWriter.bin". Ждем окончания загрузки, получаем ответ - 'K'. Нажимаем макрос "М12" - запускаем "прошиватель". В ответ приходит символ 'R' как подтверждение команды запуска.В этот момент видим, что на плате зажегся светодиод. То есть запустился "прошиватель", и идет работа с Flash памятью. После короткого периода времени этот светодиод начинает медленно мигать, с периодом порядка 3 секунд. Это означает, что прошивка прошла успешно.
Если бы возникли проблемы, то светодиод мигал бы существенно быстрее. Для того чтобы различать, работает программа "прошиватель" или "HelloWorld", мигание в них реализовано разными диодами.
Проверяем зашитую программу
Давайте проверим, как прошилась наша программа. Испробуем два варианта:
1 - Проверка через UART загрузчик
Запускаем макрос "М1" - синхронизация нулями. Получаем приглашение '>'. Выполняем макрос "М8" - запускаем программу из Flash памяти.2 - Проверка сбросом питания
Выставляем переключателями режим загрузки из Flash, Mode = "000".В обоих случаях убеждаемся, что программа прошита успешно. И после Reset и после сброса питания программа исполняется именно из Flash памяти, куда мы ее и записали.
Таким вот образом можно запросто прошить микроконтроллер через UART. В данном примере программа у нас была заведомо небольшая, поэтому мы прошивали только одну страницу Flash. Но при небольшой доработке программы "Прошиватель", можно организовать загрузку программ размера большего чем одна страница. Так же при прошивке программ больших, чем размер ОЗУ, можно побить исходный bin файл и прошить его частями.
В статье Загрузка программы в ОЗУ и запуск через UART мы научились загружать программу в ОЗУ и запускать ее. Давайте напишем программу для ОЗУ, которая умеет записывать массив данных из ОЗУ во FLASH память. Назовем эту программу "прошиватель". В массиве данных будет лежать наша программа мигания диодом. В итоге после прошивки при запуске из Flash на плате будет мигать светодиод.
Программа "Прошиватель"
Создаем новый проект, назовем его "Flash_UartWriter". В библиотеках выбираем пункты - Startup_MDR1986BE9x, EEMPROM, PORT, RST_CLK. Добавляем в проект новый файл "main.c". Как это сделать описано здесь - Создаем новый проект.
Теперь делаем настройки проекта для запуска в ОЗУ. Подробно это описано тут - Запуск программы в ОЗУ из Keil. В данном случае, файл "setup.ini" можно не создавать и не подключать, мы не планируем запускать проект в отладчике.
Далее приведен листинг программы "прошивателя", состоящий из одного файла "main.c". Код собран из двух примеров:
Мигание светодиодом - Hello World - светодиод. Отсюда мы возьмем настройку порта и цикл мигания светодиодом, для того чтобы как-то отображать статус того, что происходит в программе. И пример работы с EEPROM под названием "Sector_Operations" из библиотеки SPL. Этого примера мы уже слегка касались в статье Расположение функций в ОЗУ, программирование EEPROM.Пример "Sector_Operations" при стандартной установке Keil можно найти по пути:
C:\Keil_v5\ARM\PACK\Keil\MDR1986BExx\1.4\Examples\MDR1986VE9x\MDR32F9Q1_EVAL\EEPROM\Sector_Operations
Полный листинг файла "main.c" получился такой:
Думаю ничего сложного в программе нет, я написал побольше комментариев, чтобы вопросов не возникло. Данный код будет располагаться в ОЗУ, поскольку мы загрузим его через UART. По этой причине нет необходимости решать вопрос с расположением файла "MDR32F9Qx_eeprom.c" в ОЗУ, как мы это делали в Расположение функций в ОЗУ, программирование EEPROM.
Bin файл для "HelloWorld"
Теперь нам необходимо получить bin файл для программы, которую мы будем прошивать в Flash. Как это сделать, написано тут - Загрузка программы в ОЗУ и запуск через UART, "Получение bin файла".
Пересобираем проект ("F7") и находим в папке проекта файл "HelloWorld.bin".
Давайте так же сотрем Flash память и убедимся, что до запуска нашего "прошивателя" в памяти пусто. В меню выбираем Flash - Erase. Для того чтобы данная операция отработала, к демо-плате должен быть подключен программатор в Jtag_B, переключатели Mode должны быть в режиме "000" и должно быть подано питание. Без установленного соединения, данный пункт меню не активен.
Давайте теперь нажмем Reset или передернем питание, чтобы убедиться, что светодиод не мигает. После работы нашего "прошивателя", Reset и подача питания должны будут приводить к миганию светодиодом.
Прошиваем через UART
Выставляем режим загрузки через UART, Mode = "110". Операции работы с UART загрузчиком мы рассмотрели в статье - Тестируем Bootloader в режиме UART. Далее загружаем обе программы "HelloWorld" и "прошиватель" в ОЗУ.
Как было указано в коде, "прошиватель" будет копировать память с адреса 0x2000_2000. Сюда и загрузим файл "HelloWorld.bin". Сам же "прошиватель" запишем в адреса с 0x2000_0000, потому что так было настроено в опциях проекта. Запуск "прошивателя" так же необходимо произвести с адреса 0x2000_0000. В свойствах bin файлов узнаем так же их размеры. В общем, делаем все тоже самое, что и в "Загрузка программы в ОЗУ и запуск через UART", с той лишь разницей, что дополнительно загружается программа "HelloWorld".
В итоге необходимая нам информация для загрузки:
Подключаем UART адаптер, подаем питание на плату, открываем программу "Terminal v1.9b". Там у нас уже были написаны и сохранены макросы для работы с UART. Допишем к ним следующие:
Проверяем, что "HelloWorld" еще не прошит
В программе Terminal нажимаем Connect. Настройки обмена должны быть выставлены согласно спецификации или статье Тестируем Bootloader в режиме UART. Запускаем Макрос М8 - прыгаем на программу из Flash, чтобы убедиться, что там еще не зашита программа мигания светодиодами. Наблюдаем, что светодиод не мигает. Если светодиод мигает, значит память не была очищена, возвращаемся к пункту Bin файл для "HelloWorld" .Важно не забыть снять галочку циклической посылки 0-ля после получения ответа от МК, иначе этот ноль продолжает посылаться и весь последующий обмен через UART будет нарушен!
Протокол обмена в окне терминала выглядит так:
в Hex окне видим пришедшие данные:
Прошиваем Flash
Нажимаем Reset на плате для того, чтобы вернуться в UART загрузчик и начинаем все с начала:
Макрос "М7" - Увеличиваем скорость обмена до 19200 бод, чтобы загрузка прошла быстрее. В данном случае приходит неправильный ответ от МК, игнорируем. Выполняем макрос "М10" - МК входит в режим загрузки массива данных и ожидает 1484 байт.В этот момент видим, что на плате зажегся светодиод. Т.е. запустился наш "прошиватель", и идет работа с Flash памятью. После короткого периода времени этот светодиод начинает медленно мигать, с периодом порядка 3 секунд. Это означает, что прошивка прошла успешно.
Если бы возникли проблемы, то светодиод мигал бы существенно быстрее. Возможно, индикация миганием не самый лучший вариант, раньше я просто включал и гасил светодиод по окончании процесса записи. Но при выключенном диоде было не понятно, выполняется какая-то программа, или внутри что-то зависло. По этой причине я остановился на варианте с миганием, он показывает, что программа внутри вертится. Для того чтобы различать, работает программа "Прошиватель" или "HelloWorld" мигание в них реализовано разными диодами.
Проверяем зашитую программу
Давайте проверим, как прошилась наша программа. Испробуем два варианта:
1 - Проверка через UART загрузчик
Выполняем макрос "М8" - запускаем программу из Flash памяти.2 - Проверка сбросом питания
Выставляем переключателями режим загрузки из Flash, Mode = "000".В обоих случаях убеждаемся, что программа прошита успешно. И после Reset и после сброса питания программа исполняется именно из Flash памяти, куда мы ее и записали.
Таким вот образом можно запросто прошить микроконтроллер через UART. В данном примере программа у нас была заведомо небольшая, поэтому мы прошивали только одну страницу Flash. Но при небольшой доработке программы "Прошиватель", можно организовать загрузку программ размера большего чем одна страница. Так же при прошивке программ больших, чем размер ОЗУ, можно побить исходный bin файл и прошить его частями.
Недавно нам с друзьями пришло несколько VoCore, которые заказывали летом. Мы сразу же начали их изучать и всячески экспериментировать. В ходе моих попыток настроить одну, система была убита и мини-компьютер больше не загружался. Через несколько минут было найдено несколько страниц, посвященных VoCore, и инструкция по использованию kermit.
Чтобы перепрошить сей девайс, нам понадобится преобразователь USB-UART и проводочки, чтобы это всё соединить. На картинке ниже указаны, где находится питание и порт UART:
Втыкаем монтажные проводки и загибаем концы, чтобы не не паять. Контакт получается стабильным.
Была такая проблема, что плата видела только 13М RAM вместо положенных 32М. На форуме VoCore посоветовали подключить общий провод к другому контакту GND, но это не помогло. Поэтому у меня питание идет напрямую от USB.
Далее включаем kermit, передаем в него параметры и подключаемся:
Передергиваем питание вокорки и нажимаем 'x' (по умолчанию у нас есть 1 секунда):
Переводим вокорку в режим приёма данных:
Теперь нажимаем Ctrl+\ и затем C, чтобы вернуться в меню kermit. Заливаем прошивку:
Пока прошивка передаётся, можно пойти попить чайку, у нас есть на это примерно 12 минут…
После того, как прошивка скачалась, снова подключаемся к консоли:
Сравниваем полученный размер с размером исходного файла — он должен быть одинаковым. Запоминаем его.
Далее стираем, что у нас было:
Записываем свой линукс (размер указывайте свой!):
Если что-то пошло не так и ОС не загрузилась, то БЕЗ ПАНИКИ делаем всё заново. У меня получилось с первого раза, чего и вам желаю.
При удачном исходе загрузка пройдет успешно:
После такого достижения я рассказал свою историю друзьям. Они, в свою очередь, обозвали меня дураком и поведали, что можно восстановить настройки командой:
Загрузчик (bootloader)
Загрузчик живёт в самом конце Flash памяти МК и позволяет записывать прошивку, отправляемую через UART. Загрузчик стартует при подаче питания на МК, ждёт некоторое время (вдруг кто-то начнёт слать код прошивки по UART), затем передаёт управление основной программе. И так происходит каждый каждый раз при старте МК.
- Загрузчик позволяет прошивать МК через UART;
- Загрузчик замедляет запуск МК, т.к. при каждом запуске ждёт некоторое время для потенциальной загрузки прошивки;
- Загрузчик занимает место во Flash памяти. Стандартный старый для Arduino NANO занимает около 2 кБ, что весьма существенно!
- Именно загрузчик мигает светодиодом на 13 пине при включении, как индикация работы.
Программатор
Помимо записи прошивки во flash память, программатор позволяет:
- Считывать содержимое Flash памяти (скачать прошивку на компьютер)
- Полностью очищать чип от всех данных и настроек
- Записывать и читать загрузчик
- Считывать/записывать EEPROM память
- Читать и настраивать фьюзы (fuses, fuse-bits) и лок биты.
USB-TTL (UART)
USB-TTL | Arduino |
DTR | DTR |
RX | TX |
TX | RX |
GND | GND |
VCC/5V/3.3V | VCC |
Фьюзы (Pro)
Фьюзы (фьюз-биты) являются низкоуровневыми настройками микроконтроллера, которые хранятся в специальном месте в памяти и могут быть изменены только при помощи ISP программатора. Это такие настройки как выбор источника тактирования, размер области памяти под загрузчик, настройка отсечки по напряжению и прочее. Фьюз-биты собраны по 8 штук в байты (т.н. байты конфигурации), как типичный регистр микроконтроллера AVR. Таких байтов может быть несколько, они называются low fuses, high fuses, extended fuses. Для конфигурации байтов рекомендуется использовать калькулятор фьюзов (например, вот такой), в котором просто ставятся галочки на нужных битах, и на выходе получается готовый байт в hex виде. Рассмотрим на примере ATmega328p:
Лок-биты (Pro)
Лок-биты (lock-bits) позволяют управлять доступом к памяти микроконтроллера, что обычно используется для защиты устройства от копирования. Лок-биты собраны опять же в конфигурационный лок-байт, который содержит: BOOTLOCK01, BOOTLOCK02, BOOTLOCK11, BOOTLOCK12, LOCKBIT1, LOCKBIT2 (для ATmega328). Калькулятор лок-битов можно использовать этот. BOOTLOCK биты позволяют запретить самому МК запись (самопрограммирование) во flash память (область программы и область загрузчика)
А вот локбиты LOCKBIT позволяют запретить запись и чтение flash и EEPROM памяти извне, при помощи программатора, т.е. полностью защитить прошивку от скачивания и копирования:
Таким образом включив LOCKBIT1 (лок-байт будет 0x3E) мы запретим внешнюю запись во Flash и EEPROM память, т.е. при помощи ISP программатора, а включив LOCKBIT1 и LOCKBIT2 (лок-байт: 0x3C) полностью заблокируем заодно и чтение данных из памяти микроконтроллера. Повторюсь, всё описанное выше относится к ATmega328p, для других моделей МК читайте в соответствующих даташитах.
ISP программатор
USBasp
Решение проблем
Решение большинства проблем с загрузкой через программатор (независимо от того, что написано в логе ошибки):
- Вытащить и обратно вставить usbasp в usb порт
- Вставить в другой usb порт
- Переустановить драйвер на usbasp
- Проверить качество соединения USBasp с МК
- Перепаять переходник и отмыть флюс
Для прошивки микроконтроллера, тактирующегося низкой частотой (менее 1 МГц внутренний клок):
Основные ошибки в логе Arduino IDE
Arduino as ISP
Почти любая другая плата Arduino может стать ISP программатором, для этого нужно просто загрузить в неё скетч ArduinoISP:
- Открыть скетч Файл > Примеры > 11. ArduinoISP > ArduinoISP
- Всё! Ваша Arduino теперь стала ISP программатором
- Подключаем к ней другую Arduino или голый чип по схеме ниже
- Выбираем Arduino as ISP в Инструменты > Программатор
- И можем писать загрузчики, фьюзы или загружать прошивку напрямую во Flash
-
Либо поставить поставить конденсатор ёмкостью
Решение проблем
Для прошивки микроконтроллера, тактирующегося низкой частотой (менее 1 МГц внутренний клок):
- Arduino ISP: нужно изменить частоту загрузки прошивки в скетче Arduino ISP и снова прошить его в ардуино-программатор (см. строку в скетче 45 и ниже);
Работа в Arduino IDE
Прошивка загрузчика
Как убрать загрузчик?
Загрузка скетча
В Arduino IDE можно зашить скетч через программатор, для этого надо нажать Скетч > Загрузить через программатор. Это очень удобно в том случае, когда МК используется без загрузчика, или просто голый МК.
Фьюзы
Конфигуратор платы в Arduino IDE устроен следующим образом: каждой плате в Инструменты > Плата соответствует свой набор настроек, включая фьюзы, которые прошиваются вместе с загрузчиком . Некоторые из них:
- Загрузчик (путь к файлу)
- Скорость загрузки (через загрузчик)
- Объем доступной flash и sram памяти
- Весь набор фьюзов и лок-биты
Файл конфигурации называется boards.txt и найти его можно в папке с ядром Arduino: C:\Program Files (x86)\Arduino\hardware\arduino\avr\boards.txt. Документацию на boards.txt можно почитать здесь. При желании можно вывести нужные фьюзы через калькулятор (читайте выше), изменить их в boards.txt (главное не запутаться, для какой выбранной конфигурации платы делается изменение) и прошить в МК, нажав Инструменты > Записать загрузчик.
Такая работа с фьюзами максимально неудобна, но есть и другие варианты:
- Ядро GyverCore для atmega328, в нем мы сделали кучу готовых настроек фьюзов прямо в настройках платы, читайте в уроке про GyverCore. Несколько загрузчиков, включая вариант без загрузчика, выбор источника тактирования и другие настройки в один клик мышкой.
- Программа AVRdudeprog, про нее поговорим ниже
Avrdudeprog
- Чтение/запись/очистка flash памяти
- Чтение/запись/очистка eeprom памяти
- Полная очистка чипа
- Калькулятор фьюзов и локбитов (чтение/запись)
Более подробный обзор на avrdudeprog можно посмотреть здесь . Давайте посмотрим на калькулятор фьюзов. Выбираем свой микроконтроллер и программатор (можно добавить другие модели микроконтроллеров и программаторов, читай тут). Переходим во вкладку Fuses, нажимаем прочитать. При успешном чтении увидим текущий набор настроек своего чипа. Можно их поменять и загрузить. Важно! Галку инверсные биты не трогаем! Лок-биты и отключение RST заблокирует микроконтроллер, не трогайте их, если такой цели нет! Можно загружать прошивку или загрузчик из .hex файла, указав путь к ней на первой вкладке в окне Flash. Очень удобная утилита для низкоуровневой работы с МК.
Видео
Читайте также: