В настоящее время в моей прошивке прописан серийный номер для дизайна, с которым я работаю. Прошивка может прочитать и сообщить серийный номер. Это прекрасно работает для того, что мне нужно. Проблема в том, что каждый новый серийный номер требует от меня изменения кода и перекомпиляции. Это громоздко, когда нужно построить много модулей, возможно, они могут привести к ошибкам, и это плохая практика. Серийные номера даны мне, а аппаратный дизайн выложен камнем, поэтому я не могу добавить какие-либо функции в аппаратное обеспечение для сериализации устройств (EEPROM / Silicon ID Chip / Pull-Ups). Я хотел бы найти серийный номер по фиксированному адресу, скомпилировать код один раз, а затем отредактировать этот адрес в скомпилированном HEX-файле для каждого нового серийного номера. На номер ссылаются в нескольких местах, поэтому в идеале я хочу определить и найти его один раз, затем ссылка на эту «переменную» везде в моем коде. Кто-нибудь знает, как найти постоянные данные в определенном адресуемом месте памяти по моему выбору, используя компилятор C18? Кто-нибудь может предложить лучший способ?
источник
Ответы:
Специально для решения вопроса о привязке переменных к определенным адресам во флэш-памяти на PIC18 с помощью компилятора C18, пожалуйста, обратитесь к разделу «Прагмы» в hlpC18ug.chm в каталоге doc, где установлен компилятор.
Для этого вам нужно определить новый «раздел» в памяти и привязать его к начальному адресу, чтобы
#pragma romdata serial_no_section=0x1700
Это создает новый раздел с именем «serial_no_section», который начинается с адреса 0x1700 во флэш-памяти (программе) (поскольку мы определили «romdata» в #pragma).
Сразу после строки #pragma определите вашу переменную (и) так:
Теперь у вас есть 0x12 по адресу 0x1700 и 0x34 по адресу 0x1701 в памяти (потому что PIC18 использует модель с прямым порядком байтов). «Const rom» гарантирует, что компилятор знает, что это тип переменной const, и что переменная находится в памяти «rom» и, следовательно, должна быть доступна с помощью инструкций чтения таблиц.
Последний
#pragma romdata
оператор гарантирует, что любые последующие объявления переменных связаны с разделами памяти по умолчанию, так как компоновщик считает, что подходит, а не следует в разделе "serial_no_section".Теперь весь код может просто ссылаться на переменную «mySerialNumber», и вы точно знаете, по какому адресу находится серийный номер в памяти.
Редактирование кода HEX может быть немного сложным, так как вам нужно вычислить контрольную сумму для каждой строки, которую вы редактируете. Я работаю над классом C ++ для декодирования и кодирования файлов Intel HEX, что должно сделать это проще, но это еще не закончено. Декодирование файлов работает, кодирование снова еще не реализовано. Проект (если вы заинтересованы) находится здесь https://github.com/codinghead/Intel-HEX-Class
Надеюсь это поможет
источник
Я сделал серийный номер (s / n для краткости) способом, аналогичным тому, что описывает Джоэл. Я использовал PIC18F4620 и компилятор CCS. Расположение s / n во флэш-памяти было принудительно установлено до последних 4 байтов. Поскольку я использовал только 80% Flash, мой компилятор и компоновщик не писал бы исполняемый код в последние 4 байта.
Тогда у меня было 2 альтернативных способа записи s / n в отдельные единицы:
Ответить на комментарий Джоэла
Не знаю насчет C18, но CCS-компилятор поставляется с библиотечными функциями
write_program_eeprom(...)
иread_program_eeprom(...)
. Вот как они выглядят при сборке.источник
write_program_eeprom(...)
иread_program_eeprom(...)
. EEPROM и Flash - это две разные вещи!Я делал это несколько раз. Обычно я определяю область информации о прошивке в фиксированном месте в памяти программ, затем пишу программу, которая создает сериализованный HEX-файл из HEX-файла шаблона. Это все легко сделать.
В производстве вы запускаете программу сериализации один раз после того, как все тесты пройдены. Он создает временный HEX-файл с уникальным серийным номером, который запрограммирован в PIC, а затем временный HEX-файл удаляется.
Я не позволил бы переместить местоположение, тогда я должен найти его. Это может изменить каждую сборку, поскольку компоновщик перемещает вещи вокруг. Я сделал это для очень маленьких PIC, таких как серия 10F, где эти константы являются частью инструкций MOVLW. В этих случаях он читает файл MAP на лету, чтобы определить, где находятся эти места. У меня есть код разбора файла MPLINK MAP в библиотеке только для этой цели.
Чтобы поместить что-либо в фиксированное местоположение, определите сегмент по фиксированному адресу. Линкер будет сначала размещать такие абсолютные сегменты, а затем перемещаемые вокруг него. Не забудьте использовать CODE_PACK вместо просто CODE на PIC 18, иначе вы будете иметь дело со словами целого выражения вместо отдельных байтов. Например (только что набрал, а не запустить мимо ассемблера):
источник
Я бы предложил хранить серийный номер на фиксированном адресе. В зависимости от вашего компилятора / компоновщика и рассматриваемой части, вы можете выбрать несколько подходов:
источник
retlw
подход часто намного быстрее (на 18-разрядных PIC acall
to aretlw
занимает всего четыре цикла; использование -clrf TBLPTRU/movlw xx/movwf TBLPTRH/movlw xx/movwf TBLPTRL/tblrd *+/movf TABLAT,w
восемь).Я бы сделал наоборот: скомпилируйте и скомпонуйте код, а затем выясните, где хранится значение из файла компоновщика. Вам может потребоваться найти переменную явно в сегменте, который отображается во флэш-память.
Не просил об этом, но программное обеспечение для ПК, которое я предоставляю для моего программиста Wisp648, имеет возможность считывать файл .hex, изменять определенное местоположение и записывать файл .hex обратно (в тот же или другой файл). Нет необходимости присутствовать у моего программиста. Источник доступен (на Python), лицензия разрешает любое использование: www.voti.nl/xwisp Может пригодиться, как только вы решите свою основную проблему.
источник