|
Пытаюсь написать Bootloader для Atmega128, Не получается стереть страницу |
|
|
|
Dec 1 2008, 16:29
|
Местный
  
Группа: Свой
Сообщений: 212
Регистрация: 26-08-04
Пользователь №: 545

|
Пытаюсь написать загрузчик (bootloader) для ATMEGA128 и не получается. Программа должна постранично модифицировать память программ. Посмотрел много примеров, вроде делаю все как у всех, но не работает. Не работает самое элементарное - стирание страницы, запись пока не пробовал, т.к. перед записью нужно стереть страницу. Вот кусок программы, должна стираться нулевая (для примера) страница:
;Задаем нулевую страницу для стирания clr ZL clr ZH
;Проверяем, что не идет запись, ждем когда кончится, если идет M1: lds r16,SPMCSR sbrc r16,SPMEN rjmp M1
;>Проверяем, что не идет запись в EE, ждем когда кончится, если идет M2: sbic EECR,EEWE rjmp M2
;>Запускаем стирание ldi r16, (1<<PGERS) | (1<<SPMEN) sts SPMCSR,r16 spm
;Ждем, когда окончится стирание M3: lds r16,SPMCSR sbrc r16,SPMEN rjmp M3
Программа виснет на команде spm, дальше не идет. Если закомментировать команду spm, то все проскакивает (но стирания, естественно тоже не происходит).
Данная программа стартует с адреса 0x1F000 и расположена в области 0x1F000...0x1FFFF.
Может не так устанавливаю FUSES??? Установлено вот так: BODLEVEL = 1 BODEN = 0 SUT = 2 CKSEL = F BLB1 = 3 <-полный доступ к памяти зпгрузчика BLB0 = 3 <-полный доступ к памяти программ OCDEN = 1 JTAGEN = 1 CKOPT = 1 EESAVE = 0 BOOTSZ = 0 <- 4K область загрузчика (адреса 1F000-1FFFF) BOOTRST = 0 <- Стартовать с загрузчика (c адреса 1F000) M103C = 1 WDTON = 1
Где я ошибся, не понимаю?
|
|
|
|
|
 |
Ответов
(1 - 9)
|
Dec 2 2008, 06:08
|
Участник

Группа: Участник
Сообщений: 51
Регистрация: 8-01-07
Из: Одесса
Пользователь №: 24 196

|
Обычно проблема в том что в даташите адрес в словах а пишут адрес байтовый. Старт идет не с того адреса но при этом попадает на исполняемый код загрузчика. Естественно чип не дает ничего сделать с памятью.
--------------------
Опыт - это та чудесная штука, которая позволяет вам узнать ошибку, когда вы ее повторите.
|
|
|
|
|
Dec 2 2008, 09:57
|
Местный
  
Группа: Свой
Сообщений: 212
Регистрация: 26-08-04
Пользователь №: 545

|
Цитата А не проще тупо взять нужные файлы (те же spm.asm, spm.h) из AVR231 - AES Bootloader? Приведенный ассемблерный код присутствует во всех загрузчиках (со своими нюансами). Цитата Почитайте про бит RWWSRE регистра SPMCR wink.gif Ну пробовал поставить перед стиранием: ldi r16, (1<<RWWSRE) | (1<<SPMEN) sts SPMCSR,r16 spm и потом окончание ожидания сброса SPMEN, результат тот же. Цитата Обычно проблема в том что в даташите адрес в словах а пишут адрес байтовый. Старт идет не с того адреса но при этом попадает на исполняемый код загрузчика. Естественно чип не дает ничего сделать с памятью. Но ведь установка BOOTSZ = 0 означает, что размер загрузчика равен 4К. Значит старт будет с адреса 1FFFF-4K=1F000. В HEX файле именно с этого адреса и начинается программа.
|
|
|
|
|
Dec 2 2008, 11:03
|
Местный
  
Группа: Свой
Сообщений: 212
Регистрация: 26-08-04
Пользователь №: 545

|
Хм... Написал чисто ассемблерную программу из приведенных выше строк, страница стирается. Пишу программу на С с ассемблерной подпрограммой стирания страницы, вызываю эту ассемблерную подпрограмму из С - результат нулевой. Что-то я совсем ничего не понимаю. Видимо мозг чувствует приближение Нового года и отказывается думать.  Может препроцессор что-то такое делает, что блокирует модификацию памяти???
|
|
|
|
|
Dec 2 2008, 16:42
|
Местный
  
Группа: Свой
Сообщений: 212
Регистрация: 26-08-04
Пользователь №: 545

|
Что-то я совсем ничего не понимаю (т.е. уже вообще ничего) Вот так программа очищает нулевую страницу (переменная XX-локальная): extern void CLR_STR(void); void main(void) {unsigned char XX; CLR_STR(); //Стирание нулевой страницы while(1){_WDR(); XX++;} } А вот так нулевую страница не очищается (переменная XX-глобальная): unsigned char XX; extern void CLR_STR(void); void main(void) {CLR_STR(); //Стирание нулевой страницы while(1){_WDR();XX++;} } Т.е. если есть обращение к глобальной переменной, то программа почему-то не хочет стирать страницу памяти.
|
|
|
|
|
Dec 2 2008, 21:36
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(afad @ Dec 2 2008, 18:42)  Т.е. если есть обращение к глобальной переменной, то программа почему-то не хочет стирать страницу памяти. Вы вроде и на форуме давно, и сообщений много написали, а выкладывать код при помощи кнопки "#" на форме ввода так и не научились. А по вопросу - без листинга телепатировать очень трудно.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 5 2008, 16:37
|
Местный
  
Группа: Свой
Сообщений: 212
Регистрация: 26-08-04
Пользователь №: 545

|
Цитата Вы вроде и на форуме давно, и сообщений много написали, а выкладывать код при помощи кнопки "#" на форме ввода так и не научились. Зато теперь, длагодаря Вашей подсказке умею! Цитата Кстати - а что у нас в RAMPZ ? Да, проблема была в этом или почти в этом. В начале ассемблерной подпрограммы я написал: Код clr r16 sts RAMPZ,r16 Транслятор, естественно, все это проглотил, но результат оказался непредсказуемый (т.е. зависел от непонятных мне факторов). А причина в том, что RAMPZ находится в области IO, следовательно команда: Код sts RAMPZ,r16 портила ячейку RAM. После того, как исправил коменду на: Код out RAMPZ,r16 все заработало предсказуемо и нужная мне страница стирается. Также ошибся в выборе размера bootloadera: BOOTSZ=0 - это не 4Кбайт, а 4К слов. Вопросы еще остались, но об этом позже.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|