Миграция с PICX на PICY посредством MplabX.
Оглавление
Шаг 1. Подготовка исходного проекта.
Шаг 2. Создание нового проекта.
Шаг 3. Приведение инициализации/настроек узлов нового проекта к исходному.
Шпаргалка создавалась в следующих обстоятельствах:
MCU = PIC
IDE = MplabX + MCC (или вручную)
Смена MCU pin to pin, а значит расположение модулей либо вообще не отличается, либо отличается незначительно.
Задача - переехать на новый камень без смены настроек и функционала.
Полагаю 90% инфы актуальна и в других типах миграций.
Цели.
Многим покажется что в скрипте есть лишние шаги. Их смысл в достижении следующих задач.
Миграция идет с сохранением жизни исходного проекта.
Любое изменение в целевом проекте сразу можно проверить/отладить на исходном-живом.
Компиляция на исходном показывает нарушение связей — контроль миграции на каждом шаге.
При обнаружении проблемы можно переместится на любую ревизию и посмотреть как себя ведет устройство.
Можно писать что-то для нового камня пока его «не подвезли» и отлаживать на старом железе.
Любые действия до начала отладки с целью снижения затрат на поиск багов при отладке стоят своего времени.
Общие для всех шагов принципы.
На любом шаге вызывающем сомнения уместно проверить как компилируется проект в исходом и целевом — не поломались ли связи между объектами.
Подготовка состоит в выделении и переносе пользовательских исходников из папки проекта где они обычно размещаются вместе с папками/файлами генерируемыми средой разработки (описание можно глянуть тут руководство: MPLAB X IDE User’s Guide – глава: Saving Project Files), в отдельную папку, находящуюся на одном уровне с проектом.
Перемещение пользовательских исходников
Уяснить, что составляет файлы проекта (руководство), а что «свои» файлы.
Переместить «свои» исходники в папку с названием типа Common.
Скомпилировать и удостовериться что возникает множество ошибок связанных с не нахождением заголовочных файлов
Восстановление связей в проекте.
Создать в общем инклюднике 2 дефайна типа OLD_MCU и NEW_MCU
Найти все места где используется обращения к регистрам микроконтроллера
Заменить в них код который обращается к регистром блоком ниже
#ifdef OLD_MCU
[код обращающийся к регистрам. например: userBuf = U1RXB;]
#endif
#ifdef NEW_MCU
..пока пусто..
#endif
Найти все места где используется обращение к файлам драйверов
Заменить в них код который подключает библиотеки блоком ниже
#ifdef OLD_MCU
[код ссылающийся на заголовочные файлы SDK исходного MCU. например: #include "mcc_generated_files/file1.h"]
#endif
#ifdef NEW_MCU
..пока пусто..
#endif
Завершение
В результате должен получиться проект где можно выбором NEW_MCU отключать все модули связанные с старым железом и заголовками.
Активировать NEW_MCU и убедится что все собралось без ошибок.
Создать, выбрав тип
File – New Project – Microchip Embedded – Standalone Project. - Next
Выбрать MCU и отладчик.
Select Device – задать нужные Family, Device, Tool – Next
Выбрать компилятор.
Select Compiller – Compiler Toolchain – XC8 – XC8 vX.XX – Next
Выбрать имя и расположение проекта.
Задать Project Name и Project Locaton.
Расположить в той же папке где находится исходный проект и общая папка пользовательских исходников.
Новый проект откроется в IDE, теперь нужно добавить общие пользовательские исходники в проект.
Находим каждый блок OLD_MCU / NEW_MCU и добавляем ссылки на заголовочные файлы ядра, теперь уже нового проекта.
Включаем NEW_MCU и если проект компилируется без ошибок можно переходить следующему шагу — замене регистров. Оживлению драйверной части — восстановления функционирования регистров MCU.
Таким образом в одной общей папке должны содержаться три:
папка со старым исходным проектом
папка с новым целевым проектом
папка с пользовательскими исходниками.
Запустить плагин MCC в проекте источнике.
Project Resources или Flat View ( Flat View скорее всего удобнее — сразу видно весь набор активных узлов, разворачивать ничего каждый раз не нужно).
Сохранить настройки всех открывающихся узлов как фото.
Сохранить остальные открытые по умолчанию окна с настройками.
Перейти к целевому проекту.
Задать все настройки
В случае настройки модулей «вручную» инициализирующие процедуры прописываются обычным порядком в файлах ядра. В этом случае переносим их подглядывая в процедуры инициализации — по сути это та же работа что описанная в следующем шаге, толь ко применяющаяся к процедурам инициализации узлов.
Подбор регистра аналога.
Перейти к не обработанному блоку OLD_MCU / NEW_MCU
Посмотреть на старый регистр в блоке OLD_MCU, понять его назначение.
Найти аналог для нового MCU, пользуясь описанием в даташите исходного и целевого MCU.
Создать аналогичную конструкцию.
Скомпилировать и удостовериться что нет ошибок.
Типы несовпадений регистров.
Совпадает название и регистра и бита этого регистра.
Регистры одинаковы.
Ничего не меняю, не смотрю назначение
Совпадает название бита регистра, но название регистра отличается цифрой.
Регистры одинаковы.
Ничего не меняю, не смотрю назначение
Совпадает название бита регистра, но название регистра не совпадает цифрой в названии (типа назначение номером регистра)
Регистры не равны
Анализ по даташиту необходим
Не совпадает ничего
Регистры не равны
Анализ по даташиту необходим
Общая последовательность: найти не поддерживаемый регистр (бит) и проработать все биты в регистре. Так уменьшаются затраты мозга на переключение контекста, понижается вероятность забыть что либо, пропустить объекты выпадающие из основного фокуса поиска.
Переходим в исходнике на определение регистра (структуру) в заголовочном файле.
Берем название структуры NAMEREGbits_t и отбрасываем bits_t.
Находим в руководстве название регистра по NAMEREG в таблице соответствующие ей.
Теперь у нас есть структура в исходнике и строчка в pdf ей соответствующая
Если это union то одна из структур внутри этого юниона по названию полей и расположению бит должна полностью совпасть с регистрами МК.
Остальные структуры нужны для более удобного обращения к регистру. Например, это может быть байт для стирания всех бит разом или что-то подобное.
Понимаем назначение и поведение, и записываем как комментарий в исходнике
Как вариант - записать два комментария общий выше дефайнов (или функции) и конкретный(ые) относящийся к регистру
Функция или дефайн?
Если регистр один, то меняем его с использованием ветвления в дефайнах
Если их таких мест (одинаковых применений регистров) много определяем функцию
Можно попробовать выносить любую активность в функцию, но нужно смотреть по месту, у каждого метода есть свои накладные расходы.
Проходим все места с данным регистром. В конце записывая в заметках его как обработанный.
Переходим к следующему
В истории миграции, которую лучше вести, будет полезно вести главу - «Долги. Пропущено/не доделано». Тот редкий случай когда полезно и правильно оставлять многое «на потом».
Цените свое время. Наиболее часто повторяемым операциям должны быть заданы горячие клавиши. Это не только затраты времени но и сил / внимания.
Обязательно узнать где находится таблички SUMMARY OF REGISTERS в обоих мануалах и понять где в руководстве хранятся самые полезные данные — они всегда на одних и тех же местах, даже если регистры переименованы и прочие изменения в наличии.
Изначально я выполнял эту работу в одном экземпляре IDE открыв два проекта. Но пришлось перейти на модель: два проекта — два экземпляра среды, чтобы избежать глюков при смене активного проекта, да и сама эта смена — небольшая, но, трата времени. Также стоит заметить что идентификаторы типа OLD_MCU / NEW_MCU лучше именовать не настолько однообразно, а разбивать на группы: дефайны для GPIO, дефайны для UART, дефайны для включения заголовков, но это можно отложить на второй третий проход, чтобы не запутаться.
Среда иногда ругается на #incoude с большими заголовочные файлы типа pic18f26q10.h которые нужны для поиска регистров
Выход открыть во внешнем редакторе
По Alt + F7 переходит не на тот заголовок если открыто два проекта.
Если закрыть второй проект — переходит правильно
По Alt + F7 не формирует список использующихся объектов / типов
В конце концов, можно открыть второй экземпляр среды "C:\Program Files (x86)\Microchip\MPLABX\v5.40\mplab_platform\bin\mplab_ide64.exe" --userdir /home/user/second
v2.