Чтение фьюзов на ATmega328P
- Войдите на сайт для отправки комментариев
Чт, 20/12/2018 - 01:12
Не знаю, кому и зачем это может нафиг понадобиться, но на Амперке кому-то приспичило, решил сдублировать здесь. Вдруг и нашим кому пригодится.
Собственно, читаем из программы фьюзы и локбиты. Все пояснения в даташите на 328P, раздел 26.2.2. Если после это нужно с этими фьюзами работать, можно использовать константы (битовые маски), которые определены в файле iom328p.h. Включать его не надо, он у Вас уже включён.
#define LFUSE 0
#define HFUSE 3
#define EFUSE 2
#define LOCKB 1
uint8_t readFuse(const uint8_t fuse = 0) {
uint8_t retval = 0;
__asm__ __volatile__ (
"mov zl, %[param] \n"
"ldi zh, 0 \n"
"in r25, %[reg] \n"
"ori r25, %[mask] \n"
"out %[reg], r25 \n"
"lpm %[retval], Z \n"
: [retval] "=r" (retval)
: [reg] "I" (_SFR_IO_ADDR(SPMCSR)), [mask] "I" (bit(BLBSET) | bit(SPMEN)), [param] "r" (fuse)
: "r25", "r30", "r31"
);
return retval;
}
void setup(void) {
Serial.begin(115200);
Serial.print("Low fuse="); Serial.println(readFuse(LFUSE), HEX);
Serial.print("High fuse="); Serial.println(readFuse(HFUSE), HEX);
Serial.print("Extended fuse="); Serial.println(readFuse(EFUSE), HEX);
Serial.print("Lock bits="); Serial.println(readFuse(LOCKB), HEX);
}
void loop(void) {}
Нада было там тока ссылку дать. Пусть сюда ходят.
Как всё накручено... Любит у нас народ изобретать.
#include <avr/boot.h>; void setup() { cli(); uint8_t lowBits = boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS); uint8_t highBits = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS); uint8_t extendedBits = boot_lock_fuse_bits_get(GET_EXTENDED_FUSE_BITS); uint8_t lockBits = boot_lock_fuse_bits_get(GET_LOCK_BITS); sei(); Serial.begin(9600); Serial.print("Low fuse = "); Serial.println(lowBits, HEX); Serial.print("High fuse = "); Serial.println(highBits, HEX); Serial.print("Extended fuse = "); Serial.println(extendedBits, HEX); Serial.print("Lock bits = "); Serial.println(lockBits, HEX); } void loop() { }Вот так и думал, что такая функция уже есть где-то готовая :)
Ну, тогда будем считать, что я просто показал как она внутри делается :)
Кстати, там она сделана в виде макроса, а не функции и использует "sts" вместо моей комбинации "in - ori - out". Т.е. они не только взводят в единицы нужные биты, но и заодно обнуляют все остальные. Я так побоялся делать, но, наверное, можно :)
#define boot_lock_fuse_bits_get(address) \ (__extension__({ \ uint8_t __result; \ __asm__ __volatile__ \ ( \ "sts %1, %2\n\t" \ "lpm %0, Z\n\t" \ : "=r" (__result) \ : "i" (_SFR_MEM_ADDR(__SPM_REG)), \ "r" ((uint8_t)(__BOOT_LOCK_BITS_SET)), \ "z" ((uint16_t)(address)) \ ); \ __result; \ }))Иногда нужно заказчику запудрить мозги... Увидев такой код, лох просто цепенеет.)
А вот искал и, тут решение, в закладочку добавлю
SysInfo кроме фьюзов ещё и сигнатуры читает, и по сигнатурам определяет контроллер (#74):
http://arduino.ru/forum/programmirovanie/sysinfo-arduino?page=1#comment-...
Я вот знаете о чём думаю. Вот, что в моём решении, что в решении из boot.h (пост #3) нет никаких cli, а ведь если между записью битов в регистр и командой lpm произойдёт прерывание, то потом lpm бред считает.
Я вот не поставил умышленно, типа мол если есть опасность прерываний ставь снаружи, а лишний раз прерывания закрывать не дело. Но так тввёрдо и не уверен, что прав. Может лучше было поставить. Они там (авторы boot.h) тоже из таких соображений не стали ставить? На самом деле - это ведь залёт, при определённых условиях.
При чтении серийника я ставлю запрет. Читал где-то дискуссию давно уже, с тех пор и ставлю...
Это уже по ситуации. Обычно использую save_interrupt()/restore_interrupt() - макросы сохраняющие и восстанавливающие SREG и запрещаю прерывания на время чтения фьюзов/локов.
SysInfo кроме фьюзов ещё и сигнатуры читает, и по сигнатурам определяет контроллер (#74):
http://arduino.ru/forum/programmirovanie/sysinfo-arduino?page=1#comment-...
Ага, только какие то школьные ошибки в сообщениях: "Unrecogized signature".))
SysInfo кроме фьюзов ещё и сигнатуры читает, и по сигнатурам определяет контроллер (#74):
http://arduino.ru/forum/programmirovanie/sysinfo-arduino?page=1#comment-...
Ага, только какие то школьные ошибки в сообщениях: "Unrecogized signature".))
Вот глаз-алмаз - за целый год никто эту опечатку не заметил. Спасибо, исправлю.
Иногда нужно заказчику запудрить мозги... Увидев такой код, лох просто цепенеет.)
и зачем вы обижаете 99% участников форума)))))
Зато правда.)
Вот глаз-алмаз - за целый год никто эту опечатку не заметил. Спасибо, исправлю.
Я бы вообще советовал писать по русски. Тогда у людей не будет никаких вопросов.)