Вообще по идее стек должен быть один. для программы. Так как в кодевижене один код, я так подозреваю стек тоже будет один.
Зачем тебе здесь ассемблер? что ты хочешь в итоге получить? я не понял.
Как передать параметры ассемблерной вставке?
- Реклама
Re: Как передать параметры ассемблерной вставке?
Да вот кодвижен использует два стека. Пару постов выше есть картинка.
Делаю бутлодер, в кодвижене и необходимо было передать параметры ассемблерной вставке.
Адрес бата, команду и значение байта.
Это получилось сделать таким образом (тут передаю только два значения):
и получается, что обращение к параметрам функции, из ассемблера, осуществляется через некий "у". Что это за "у" я не совсем понимаю.
Но подозреваю, что это указатель на вершину стека данных (есть еще и аппаратный стек).
Еще мне неясно, почему, при вызове push, эта вершина не уходит (не уменьшается), это выяснил методом научного тыка, т.к. если я воде выше написать так:
то эта функция не работает. Хотя до этого, был вызван push 5 раз, значит push кладет параметр в другой стек, в аппаратный.
Все это мои догадки, а хотелось бы разобраться и быть уверенным что к чему.
Делаю бутлодер, в кодвижене и необходимо было передать параметры ассемблерной вставке.
Адрес бата, команду и значение байта.
Это получилось сделать таким образом (тут передаю только два значения):
Код: Выделить всё
void fill_temp_buffer(unsigned int data, unsigned int adr){
while (SPMCSR&1); //wait for spm complete
#asm
push r30
push r31
push r20
push r0
push r1
ldi r20, 1 ;//put CMD to r20
ld r30, y ;//move CurrentAddress LSB to Z pointer
ldd r31, y+1 ;//move CurrentAddress MSB to Z pointer
ldd r0, y+2 ;//move data LSB
ldd r1, y+3 ;//move data MSB
sts 0x68, r20 ;//move CMD to SPM control register
spm ;//store program memory
pop r1
pop r0
pop r20
pop r31
pop r30
#endasm
}
Но подозреваю, что это указатель на вершину стека данных (есть еще и аппаратный стек).
Еще мне неясно, почему, при вызове push, эта вершина не уходит (не уменьшается), это выяснил методом научного тыка, т.к. если я воде выше написать так:
Код: Выделить всё
ldd r30, y+5 ;//move CurrentAddress LSB to Z pointer
ldd r31, y+6 ;//move CurrentAddress MSB to Z pointer
ldd r0, y+7 ;//move data LSB
ldd r1, y+8 ;//move data MSB
Все это мои догадки, а хотелось бы разобраться и быть уверенным что к чему.
Re: Как передать параметры ассемблерной вставке?
Y- это регистр , в котором находится адрес в SRAM уВас же в комментах почти русским языком написано Current AddressЧто это за "у" я не совсем понимаю.
Z- тоже регистр , с той разницей , что через него можно обращатся к памяти программ
Вообще-то не плохо было Вам почитать DS на Ваш контроллер , узнали бы очень многое
Код: Выделить всё
ld ZL, y+ ;//move CurrentAddress LSB to Z pointer
ld ZH, y+ ;//move CurrentAddress MSB to Z pointer
ld r0, y+ ;//move data LSB
ld r1, y ;//move data MSB
ldi r20, 1 ;//put CMD to r20
sts 0x68, r20 ;//move CMD to SPM control register
spm ;//store program memory Re: Как передать параметры ассемблерной вставке?
Всем добрый день. Пришло время поднять старую тему.
Работал мой ботлодер (написанный в CVAVR) честно и корректно на меге 64.
Теперь пробую его прикруть к меге 128й.
Согласно даташту, у меги128 есть регистр RMAPZ, и нулевой бит в нем надо выставить в 1 если читаем/пишем флеш "выше" 64К, 0 если ниже.
Такой функцией делаю запись/стирание страницы флеша.
И все вроде-бы ничего, бутлодер записывает страницы, контрольная сумма сходится, но все страницы записать неудается.
После отправки 224й, бутлодер перестает работать.
Помогает только запись бутлодера заново.
После записи 224х страниц, прочитал флеш, и вижу, что они записаны, не с адерса 0, а со адреса 127, и по всей вероятности, произошла перезапись бутлодера (он у меня 4К занимет).
Функция write_pate вызывается таким образом:
Сижу ломаю голову, почему у меня бутлодер пишет не с нулевого адреса, а непонятно куда...
Пробовал вместо писать , результат тот-же, складывается впечатление, что в RAMPZ "намертво" записана 1.
Значение SWDL_CurrPage передается правильное, дебагером смотрел и оно изменяется от 0 до 224, потом краш бутлодера.
Адреса в hex файле прошивки не учитываются, т.к. используется свой формат, чистых бинарных данных (что-то вроде ROM)
Возможно ли, что надо изменить опции компиляции, а конкретно Memory Model, со Small на Medium? Нет возможности сейчас проверить, т.к. при изменении бутлодер становится больше 4К.
Есть сомнения в правильности записи значения above256 в регистр RAMPZ + сомнения в правильности записи адреса в Z pointer (хотя фактически добавилась только запись в RAMPZ, запись в Z работала корректно)
Нагуглил такую тему:
http://www.avrfreaks.net/index.php?name ... ic&t=37236
либо тут:
http://webcache.googleusercontent.com/s ... en&ct=clnk
У человека тоже была проблема с бутлодером для меги128. Ему помогло сохранение значения RAMPZ перед стиранием/записью страницы.
В моем же случае поведение точно такое-же, независимо от сохранения/несохрания RAMPZ.
Может кто-то сталкивался с подобной проблемой в CVAVR?
Спасибо за помощь.
Работал мой ботлодер (написанный в CVAVR) честно и корректно на меге 64.
Теперь пробую его прикруть к меге 128й.
Согласно даташту, у меги128 есть регистр RMAPZ, и нулевой бит в нем надо выставить в 1 если читаем/пишем флеш "выше" 64К, 0 если ниже.
Такой функцией делаю запись/стирание страницы флеша.
Код: Выделить всё
void write_page (unsigned char above256, unsigned int adr, unsigned char cmd){
while (SPMCSR&1); //wait for spm complete
#asm
push r20
push r21
push r23
in r23, RAMPZ ;Save prevRAMPZ to r23
push r23 ;Store the current RAMPZ value
ld r20, y ;move cmd to r20
ldd r30, y+1 ;move adr LSB to Z pointer
ldd r31, y+2 ;move adr MSB to Z pointer
ldd r21, y+3 ;move above256 to r21
sts RAMPZ, r21 ;setting RAMPZ register
sts 0x68, r20 ;move r20 to SPM control register
spm ;execute command
pop r23 ;Restore prevRAMPZ value to r23
out RAMPZ, r23 ;Restore prevRAMPZ valut to RAMPZ
pop r23
pop r21
pop r20
#endasm
}
После отправки 224й, бутлодер перестает работать.
Помогает только запись бутлодера заново.
После записи 224х страниц, прочитал флеш, и вижу, что они записаны, не с адерса 0, а со адреса 127, и по всей вероятности, произошла перезапись бутлодера (он у меня 4К занимет).
Функция write_pate вызывается таким образом:
Код: Выделить всё
//заполнение временного буффера
i=0;
do
{
tmp_int = SWDL_PageBuffer[i+1];
tmp_int = tmp_int<<8;
tmp_int += (unsigned int)SWDL_PageBuffer[i];
fill_temp_buffer(tmp_int, i);
i+=(unsigned int)2; //т.к. пиешм по два байта за раз
}while(i<PAGE_SIZE);
write_page((SWDL_CurrPage>>8)?1:0, SWDL_CurrPage<<NSHIFTPAGE, 0x03); //Perform page ERASE
write_page((SWDL_CurrPage>>8)?1:0, SWDL_CurrPage<<NSHIFTPAGE, 0x05);
Пробовал вместо
Код: Выделить всё
(SWDL_CurrPage>>8)?1:0Код: Выделить всё
(SWDL_CurrPage>>8)?0:1Значение SWDL_CurrPage передается правильное, дебагером смотрел и оно изменяется от 0 до 224, потом краш бутлодера.
Адреса в hex файле прошивки не учитываются, т.к. используется свой формат, чистых бинарных данных (что-то вроде ROM)
Возможно ли, что надо изменить опции компиляции, а конкретно Memory Model, со Small на Medium? Нет возможности сейчас проверить, т.к. при изменении бутлодер становится больше 4К.
Есть сомнения в правильности записи значения above256 в регистр RAMPZ + сомнения в правильности записи адреса в Z pointer (хотя фактически добавилась только запись в RAMPZ, запись в Z работала корректно)
Нагуглил такую тему:
http://www.avrfreaks.net/index.php?name ... ic&t=37236
либо тут:
http://webcache.googleusercontent.com/s ... en&ct=clnk
У человека тоже была проблема с бутлодером для меги128. Ему помогло сохранение значения RAMPZ перед стиранием/записью страницы.
В моем же случае поведение точно такое-же, независимо от сохранения/несохрания RAMPZ.
Может кто-то сталкивался с подобной проблемой в CVAVR?
Спасибо за помощь.
Re: Как передать параметры ассемблерной вставке?
Изменил мемори модел со смолл на мидиум, и ничего не изменилось.
Бутлодер все так-же записывает страницы с неправильного адреса.
По уточненным данным кладет нулевую страницу в 256ю.
Похоже RAMPZ выставлен неправильно, но как это можно проверить...
Бутлодер все так-же записывает страницы с неправильного адреса.
По уточненным данным кладет нулевую страницу в 256ю.
Похоже RAMPZ выставлен неправильно, но как это можно проверить...
- Реклама
Re: Как передать параметры ассемблерной вставке?
Мог-бы кто-нибудь взглянуть на эту функцию, правильно передается значение above256 в регистр RAMPZ?
Код: Выделить всё
void write_page (unsigned char above256, unsigned int adr, unsigned char cmd){
while (SPMCSR&1); //wait for spm complete
#asm
push r20
push r21
push r23
in r23, RAMPZ ;Save prevRAMPZ to r23
push r23 ;Store the current RAMPZ value
ld r20, y ;move cmd to r20
ldd r30, y+1 ;move adr LSB to Z pointer
ldd r31, y+2 ;move adr MSB to Z pointer
ldd r21, y+3 ;move above256 to r21
sts RAMPZ, r21 ;setting RAMPZ register
sts 0x68, r20 ;move r20 to SPM control register
spm ;execute command
pop r23 ;Restore prevRAMPZ value to r23
out RAMPZ, r23 ;Restore prevRAMPZ valut to RAMPZ
pop r23
pop r21
pop r20
#endasm
}
Re: Как передать параметры ассемблерной вставке?
Записать значение в регистр RMAPZ через ассемблер не получилось.
Работает при таких условиях:
запись в RAMPZ = (SWDL_CurrPage>>8) & 1;
считывать флеш при помощи ELPM
выставлять RAMPZ, перед считыванием каждого байта из флеша
Memory model = Medium
Работает при таких условиях:
запись в RAMPZ = (SWDL_CurrPage>>8) & 1;
считывать флеш при помощи ELPM
выставлять RAMPZ, перед считыванием каждого байта из флеша
Memory model = Medium


