Как передать параметры ассемблерной вставке?

Обсуждаем контроллеры компании Atmel.
jonic
Встал на лапы
Сообщения: 96
Зарегистрирован: Чт май 22, 2008 12:43:16

Re: Как передать параметры ассемблерной вставке?

Сообщение jonic »

Вообще по идее стек должен быть один. для программы. Так как в кодевижене один код, я так подозреваю стек тоже будет один.
Зачем тебе здесь ассемблер? что ты хочешь в итоге получить? я не понял.
Реклама
Аватара пользователя
zebrox
Встал на лапы
Сообщения: 117
Зарегистрирован: Вс апр 12, 2009 22:40:37

Re: Как передать параметры ассемблерной вставке?

Сообщение zebrox »

Да вот кодвижен использует два стека. Пару постов выше есть картинка.

Делаю бутлодер, в кодвижене и необходимо было передать параметры ассемблерной вставке.
Адрес бата, команду и значение байта.

Это получилось сделать таким образом (тут передаю только два значения):

Код: Выделить всё

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
то эта функция не работает. Хотя до этого, был вызван push 5 раз, значит push кладет параметр в другой стек, в аппаратный.

Все это мои догадки, а хотелось бы разобраться и быть уверенным что к чему.
Реклама
Аватара пользователя
ILYAUL
Держит паяльник хвостом
Сообщения: 906
Зарегистрирован: Ср мар 28, 2012 21:45:24
Откуда: ВО

Re: Как передать параметры ассемблерной вставке?

Сообщение ILYAUL »

Что это за "у" я не совсем понимаю.
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    
Аватара пользователя
zebrox
Встал на лапы
Сообщения: 117
Зарегистрирован: Вс апр 12, 2009 22:40:37

Re: Как передать параметры ассемблерной вставке?

Сообщение zebrox »

Всем добрый день. Пришло время поднять старую тему.
Работал мой ботлодер (написанный в 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
, результат тот-же, складывается впечатление, что в 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?

Спасибо за помощь.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
zebrox
Встал на лапы
Сообщения: 117
Зарегистрирован: Вс апр 12, 2009 22:40:37

Re: Как передать параметры ассемблерной вставке?

Сообщение zebrox »

Изменил мемори модел со смолл на мидиум, и ничего не изменилось.
Бутлодер все так-же записывает страницы с неправильного адреса.
По уточненным данным кладет нулевую страницу в 256ю.
Похоже RAMPZ выставлен неправильно, но как это можно проверить...
Реклама
Аватара пользователя
zebrox
Встал на лапы
Сообщения: 117
Зарегистрирован: Вс апр 12, 2009 22:40:37

Re: Как передать параметры ассемблерной вставке?

Сообщение zebrox »

Мог-бы кто-нибудь взглянуть на эту функцию, правильно передается значение 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   

}
Реклама
Аватара пользователя
zebrox
Встал на лапы
Сообщения: 117
Зарегистрирован: Вс апр 12, 2009 22:40:37

Re: Как передать параметры ассемблерной вставке?

Сообщение zebrox »

Записать значение в регистр RMAPZ через ассемблер не получилось.
Работает при таких условиях:
запись в RAMPZ = (SWDL_CurrPage>>8) & 1;
считывать флеш при помощи ELPM
выставлять RAMPZ, перед считыванием каждого байта из флеша
Memory model = Medium
Ответить

Вернуться в «AVR»