Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Самопрограммирование AVR
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Len_OK
Помогите, please! Программирую в IARe!
Возникла такая ошибка

Fatal Error[e38]: Option -H must not be defined more than once: -H1895
Никак не могу её исправить!
Если кто-нибудь сталкивался, подскажите что бы это могло быть?
Igor26
Ничего не понял. Поподробней пожалуйста.

P.S. Вы "рихтуете" XCL-файл?
Len_OK
Цитата(Igor26 @ May 14 2008, 16:01) *
P.S. Вы "рихтуете" XCL-файл?

Я его даже не трогала, просто подключила. И вот вылезла вот такая ошибка.
Такое впечатление , что подключено два XCL-файла, уже перепроверила все настройки....
Igor26
Вектора прерываний на область загрузчика переключаете?
У меня когда-то, помоему, выскакивала такая ошибка. Было связано с XCL-файлом, если не ошибаюсь. Дома попробую получить её и вечером отпишусь. А как Вы подключаете XCL-файл?
Len_OK
Цитата(Igor26 @ May 14 2008, 16:09) *
Вектора прерываний на область загрузчика переключаете?
У меня когда-то, помоему, выскакивала такая ошибка. Было связано с XCL-файлом, если не ошибаюсь. Дома попробую получить её и вечером отпишусь. А как Вы подключаете XCL-файл?

Я подключаю в линкере!Области бутлоадера как таковой у меня нет, потому что это Tiny13! Поэтому адресов я не меняла.И программка сама весит мало, потому как это пока только тест записи во флеш
Сергей Борщ
Цитата(Len_OK @ May 14 2008, 16:19) *
Я подключаю в линкере!
Скорее всего вы не сняли галочку "Configure using dialogs (not .xcl file)" (или что-то подобное, поищите в Project->Options->General), поэтому ключ -H один раз подставляет оболочка в командную строку линкера, а второй раз он встречается в вашем .xcl
Len_OK
Цитата(Сергей Борщ @ May 14 2008, 17:17) *
Скорее всего вы не сняли галочку "Configure using dialogs (not .xcl file)" (или что-то подобное, поищите в Project->Options->General), поэтому ключ -H один раз подставляет оболочка в командную строку линкера, а второй раз он встречается в вашем .xcl

спасибо огромное!
Этот трабл решился!
Len_OK
Вот ещё ошибочка
Error[e46]: Undefined external "__AddrToZWordToR1R0ByteToSPMCR_SPM" referred in main (E:\Len_OK\iar\ work_flash\spm_Tiny13\Debug\Obj\main.r90 )
Error[e46]: Undefined external "__AddrToZByteToSPMCR_SPM" referred in main ( E:\Len_OK\iar\work_flash\ spm_Tiny13\Debug\Obj\main.r90 )
Error[e46]: Undefined external "__DataToR0ByteToSPMCR_SPM" referred in main ( E:\Len_OK\iar\work_flash\ spm_Tiny13\Debug\Obj\main.r90 )
Igor26
А подключен к проекту хидер inavr.h или intrinsics.h?
Len_OK
Цитата(Igor26 @ May 15 2008, 09:49) *
А подключен к проекту хидер inavr.h или intrinsics.h?

да
Igor26
Что удалось найти. Функция __AddrToZByteToSPMCR_SPM в хидере intrinsics.h выглядит так:
__AddrToZByteToSPMCR_SPM, pseudo code.
MOVW R31:R30,addr
OUT SPMCR,byte
SPM
Обратите внимание на регистр SPMCR. В Tiny2313 он называется SPMCSR. Отсюда и ругань компилятора. Как побороть - не знаю. Не работал с Тиньками.
Len_OK
Обратите внимание на регистр SPMCR. В Tiny2313 он называется SPMCSR. Отсюда и ругань компилятора. Как побороть - не знаю. Не работал с Тиньками.
[/quote]

Я поняла что разница в нвзваниях регистров, а как это исправить не знаю. Перечитала много инфы, но...
буду искать
Len_OK
sad.gif никто никогда не использовал spm для Tiny?
defunct
Цитата(Len_OK @ May 15 2008, 16:12) *
sad.gif никто никогда не использовал spm для Tiny?

Цитата
потому что это Tiny13!

Да вопрос то у вас не по SPM, а по IAR компилятору C.
На C для такой мелкой Tiny (1k флеш, 64 байта RAM) врятли кто-то что-то писал.
Cмысл писать под этот чип на C? Оперативки можно считать сразу не 64байта, а ~10, памяти программ под полезную часть программы тоже кот наплакал.

Пользуйте ассемблер.
Len_OK
ну хоть под Tiny2313?

Цитата(defunct @ May 15 2008, 16:19) *
Пользуйте ассемблер.


Ассемблером почти не пользовалась, а вставку ассемблерную сделать в ИАРе для меня проблематично
defunct
Цитата(Len_OK @ May 15 2008, 16:27) *
а вставку ассемблерную сделать в ИАРе для меня проблематично

Да я Вас понимаю, и еще отмечу, что правильную ассемблерную вставку сделать гораздо сложнее чем писать всю программу на ассемблере.

Цитата
ну хоть под Tiny2313?

Вечером посмотрю как в IAR'е можно выйти из положения (сейчас под рукой нет ни IAR'a, ни Tiny).
muravei
Цитата(Len_OK @ May 15 2008, 17:27) *
Ассемблером почти не пользовалась

Попробуйте АБ
Igor26
Я так понял, Вы пользуютесь апнотом от AVR. Те, которые попадались мне, были заточены под Меги. Попробуйте, пользуясь этим апнотом, написать бутлоадер, например, для Меги-8. Когда получиться, тогда приобретенный опыт можно будет применить и к Тинькам. Помоему, с бутлоадером для Меги здесь Вам помогут больше, чем с бутлоадером для Тини. Я в том числе. Здесь многие "грызли" и победили этот вопрос.
defunct
Использовать intrinsics для tiny у меня не получилось...
Но можно пойти таким путём.
Создаем и подключием к проекту asm модуль my_spm.s90 сл. содержания (это конечно не оптимальный вариант, но работать можно):
Код
#define SPMCR   0x37
#define SREG    0x3F

        PUBLIC  DoSpm
        
        RSEG    CODE:CODE:NOROOT(1)
        
DoSpm  
        PUSH    R31
        PUSH    R30
        MOVW    R31:R30, R17:R16
        MOVW    R17:R16, R1:R0  // R17:16 pair used as temp space
        MOVW    R1:R0, R19:R18
        CLI
        OUT     SPMCR, R20
        SPM
        SEI
        MOVW    R1:R0, R17:R16  // restore R1:R0 pair
        POP     R30
        POP     R31
        RET

        END     DoSpm


В основной программе объявляем функцию DoSpm:

Код
extern int DoSpm( int addr, int data, char spmcsr_code);


addr - помещается в Z
data - в R1-R0
spmcr_code - в SPMCSR (0x37 I/O space для t13)
и выполняется команда SPM
функция будет возвращать "мусор" (содержимое R1:R0 до вызова функции), на результат не смотрите.


Ну а дальше уже по даташиту делайте то, что вам нужно.
Len_OK
Цитата(Igor26 @ May 15 2008, 21:07) *
Попробуйте, пользуясь этим апнотом, написать бутлоадер, например, для Меги-8.

smile.gif Для меги у меня уже давно работает!А для тини(думала получиться аналогичным образом) не получается.Теперь вся сложность состоит в использовании ассемблера...

Цитата(defunct @ May 16 2008, 00:32) *
Использовать intrinsics для tiny у меня не получилось...
Но можно пойти таким путём.
Создаем и подключием к проекту asm модуль my_spm.s90 сл. содержания (это конечно не оптимальный вариант, но работать можно):
Код
#define SPMCR   0x37
#define SREG    0x3F

        PUBLIC  DoSpm
        
        RSEG    CODE:CODE:NOROOT(1)
        
DoSpm  
        PUSH    R31
        PUSH    R30
        MOVW    R31:R30, R17:R16
        MOVW    R17:R16, R1:R0  // R17:16 pair used as temp space
        MOVW    R1:R0, R19:R18
        CLI
        OUT     SPMCR, R20
        SPM
        SEI
        MOVW    R1:R0, R17:R16  // restore R1:R0 pair
        POP     R30
        POP     R31
        RET

        END     DoSpm


В основной программе объявляем функцию DoSpm:

Код
extern int DoSpm( int addr, int data, char spmcsr_code);


addr - помещается в Z
data - в R1-R0
spmcr_code - в SPMCSR (0x37 I/O space для t13)
и выполняется команда SPM
функция будет возвращать "мусор" (содержимое R1:R0 до вызова функции), на результат не смотрите.
Ну а дальше уже по даташиту делайте то, что вам нужно.

Вроде всё так сделала, но появляется ошибка
Error[e46]: Undefined external "DoSpm" referred in main ( E:\Len_OK\iar\work_flash\test3\Debug\Obj\main.r90 )
defunct
Цитата(Len_OK @ May 16 2008, 10:57) *
Вроде всё так сделала, но появляется ошибка
Error[e46]: Undefined external "DoSpm" referred in main ( E:\Len_OK\iar\work_flash\test3\Debug\Obj\main.r90 )

А вы подключили файл к проекту?
workspace->правой кнопкой мыши на названии проекта->Add->add files... ->my_spm.s90

или через меню Project->Add files->assembler files->my_spm.s90
Len_OK
Цитата(defunct @ May 16 2008, 12:38) *
А вы подключили файл к проекту?
workspace->правой кнопкой мыши на названии проекта->Add->add files... ->my_spm.s90

или через меню Project->Add files->assembler files->my_spm.s90

Да,всё поправила, но теперь теперь ругань на
Error[Pe020]: identifier "PUBLIC" is undefined E:\Len_OK\iar\work_flash\test3\asm.s90 4
Error[Pe065]: expected a ";" E:\Len_OK\iar\work_flash\test3\asm.s90 6
Warning[Pe012]: parsing restarts here after previous syntax error E:\Len_OK\iar\work_flash\test3\main.c 9


Цитата(Len_OK @ May 16 2008, 12:43) *
Да,всё поправила, но теперь теперь ругань на
Error[Pe020]: identifier "PUBLIC" is undefined E:\Len_OK\iar\work_flash\test3\asm.s90 4
Error[Pe065]: expected a ";" E:\Len_OK\iar\work_flash\test3\asm.s90 6
Warning[Pe012]: parsing restarts here after previous syntax error E:\Len_OK\iar\work_flash\test3\main.c 9


а если немного меняю define и у меня выходит такая вот картина

#ifdef __IAR_SYSTEMS_ASM__
#define SPMCR 0x37
#define SREG 0x3F
NAME DoSpm
public DoSpm

COMMON INTVEC
ORG INT0_vect
rjmp SIG_INTERRUPT0
RSEG CODE:CODE:NOROOT(1)


#endif /* __IAR_SYSTEMS_ASM__ */


DoSpm:
PUSH R31
PUSH R30
MOVW R31:R30, R17:R16
MOVW R17:R16, R1:R0 // R17:16 pair used as temp space
MOVW R1:R0, R19:R18
CLI
OUT SPMCR, R20
SPM
SEI
MOVW R1:R0, R17:R16 // restore R1:R0 pair
POP R30
POP R31
RET

END DoSpm
то ошибки уже такие
Error[Pe077]: this declaration has no storage class or type specifier E:\Len_OK\iar\work_flash\test3\asm.s90 15
Error[Pe065]: expected a ";" E:\Len_OK\iar\work_flash\test3\asm.s90 15
Warning[Pe012]: parsing restarts here after previous syntax error E:\Len_OK\iar\work_flash\test3\main.c 9
Error[Pe109]: expression must have (pointer-to-) function type E:\Len_OK\iar\work_flash\test3\main.c 45
defunct
Цитата(Len_OK @ May 16 2008, 12:48) *
а если немного меняю define и у меня выходит такая вот картина

#ifdef __IAR_SYSTEMS_ASM__
#define SPMCR 0x37
#define SREG 0x3F
NAME DoSpm // <-- не нужно
public DoSpm

COMMON INTVEC // Не нужно
ORG INT0_vect // <--- не нужно!
rjmp SIG_INTERRUPT0 // <--- НЕ НУЖНО
RSEG CODE:CODE:NOROOT(1) // <--- должно быть перед меткой всегда
#endif /* __IAR_SYSTEMS_ASM__ */
DoSpm: // <-- ":" лишнее

Погодите, вставьте в asm файл все как есть из комента выше!
После метки "DoSpm" двоеточие ":" не нужно !
Какая у вас версия IAR'a?

Компилирующийся проект смотрите в атаче.
Len_OK
Цитата(defunct @ May 16 2008, 12:55) *
Какая у вас версия IAR'a?

IAR4.11
defunct
Цитата(Len_OK @ May 16 2008, 13:17) *
IAR4.11

Это хорошо, значит пример из атача предыдущего комента должен собираться без проблем (проверил на 4.11A).
Len_OK
[quote name='Len_OK' post='412200' date='May 16 2008, 13:17']
IAR4.11
[/quote]


Ваш проект компилится на "ура"!
не могу понять в чем причина, я точно такой же проект создала с нуля, в нем вот такие ошибки
Error[Pe020]: identifier "PUBLIC" is undefined E:\Len_OK\iar\work_flash\test3\asm.s90 4
Error[Pe065]: expected a ";" E:\Len_OK\iar\work_flash\test3\asm.s90 6

Может в настройках что-то ещё устанавливать нужно
[/quote]
defunct
Цитата(Len_OK @ May 16 2008, 13:23) *
Может в настройках что-то ещё устанавливать нужно

Сравните по настройкам с моим. Я создавал так:
Project -> Create New -> C -> main.
потом создал файл my_spm.s90
подключил его к проекту
скопировал содержимое из форума.
Выбрал тип процессора в настройках проекта - tiny13.
ну и собсно все..

Цитата
is undefined E:\Len_OK\iar\work_flash\test3\asm.s90

Совсем дикая идея - может нельзя файл называть именем "asm"? т.к. может пересекается с ключевым словом компилятора.
Len_OK
есть ли разница между расширениями х.s90 и х.s?
Я изначально создавала х.s файл
Создала проект заново, кажется всё откомпилилось! smile.gif Спасибо
Len_OK
Решилась проблемка с записью во флешку ! Теперь можно использовать стандартные макросы для самопрограммирования и для МК Tiny с помощью IAR EW v5.10.


Только теперь не могу разобраться с таким трабло, когда данные записываются неверно!
При попытке записать страницу нулей, в одной из ячеек появляется значение 0хЕF
Может заполнение буфера производится некорректно!


do
{ fl_data=*(temp_buf+Buf_Adres+1);
fl_data<<=8;
fl_data|=*(temp_buf+Buf_Adres);
_FILL_TEMP_WORD(Buf_Adres,fl_data);
Buf_Adres+=2;
} while (Buf_Adres<32);
Len_OK
Помогите разобраться почему не пишутся данные во флеш(пытаюсь записать 2 байта )

#include <ioavr.h>

#define SPMCR 0x37
#define SREG 0x3F

PUBLIC DoSpm
EXTERN flash_data
EXTERN fl_data
EXTERN flash_adr
EXTERN hash
EXTERN st_hash
RSEG CODE:CODE:NOROOT(1)

DoSpm
//*************fill temp bufer*************
PUSH R31
PUSH R30
LDI R16,low(flash_adr)
LDI R17,high(flash_adr)
MOVW R31:R30,R17:R16

LDI R20,low(flash_data)
LDI R21,high(flash_data)
MOVW R1:R0,R21:R20
LDI R16,1
CLI
Wait_spm:
IN R18, 0x37
MOV R19, R18
SBRC R19, 0
RJMP Wait_spm


OUT SPMCR,R16
SPM
SEI

//*****************************************
//******* save data to programm memory*****

MOVW R31:R30,R17:R16

while_EEPROM:// not write to EEPROM
SBIC 0x1C, 0x01
RJMP while_EEPROM

call Wait_spm //enable write to prog. memory
LDI R16,5
CLI
OUT SPMCR,R16
SPM
SEI
POP R30
POP R31


//*****************************************
RET
END DoSpm
_Pasha
Цитата(Len_OK @ May 22 2008, 13:29) *
Помогите разобраться почему не пишутся данные во флеш(пытаюсь записать 2 байта )

DoSpm
**************SKIPPED***************

LDI R20,low(flash_data)
LDI R21,high(flash_data)
MOVW R1:R0,R21:R20


Тут какая-то неправда smile.gif
Получается, что Вы все время грузите r0:r1 одной и той же константой, т.е. адресом переменной.
Вам ведь надо загрузить указатель на extern flash_data и оттуда что-то взять ?
тогда это может выглядеть так:
Код
ldi r26,low(flash_data)
ldi r27,high(flash_data)
ld r0,X+
ld r1,X+
defunct
Заполнить надо весь temp буфер.
После этого писать.
Если хотите записать только 2 байта - то надо прочитать содержимое всей страницы, изменить 2 байта, и записать модифицированную страницу в temp буфер, потом стереть страницу, и инициировать запись страницы.


Цитата
почему не пишутся данные во флеш

У вас функция зацикливается здесь:
Код
Wait_spm:
...
SBRC R19, 0
RJMP Wait_spm

OUT SPMCR,R16
SPM
SEI     <--- к тому же запись в SPMCR происходит при разрешенных прерываниях!!!!
...
while_EEPROM:// not write to EEPROM
SBIC 0x1C, 0x01
RJMP while_EEPROM

call Wait_spm //enable write to prog. memory


Каждая функция (вызываемая CALL'ом) должна заканчиваться RET'ом.
Len_OK
Как заполнить всю страницу данными, например при вызове ассемблерной функции передать в нее данные из буфера на 32 элемента
=GM=
Цитата(Len_OK @ May 22 2008, 11:37) *
Как заполнить всю страницу данными, например при вызове ассемблерной функции передать в нее данные из буфера на 32 элемента

Если из одной области памяти в другую, то можно так, например
Код
;Move data from the RAM area into another one
ramram:  ld   temp1,z+
         st   y+,temp1
         dec  cntbyt
         brne ramram
         ret

Перед вызовом надо само собой настроить указатели Y и Z, ну и счётчик байт, как же без него.
Отправил пост и потом заметил, что это 800-й. Ну и ну, неужто я столько накатал(:-)?!
Len_OK
DoSpm
//*************fill temp bufer*************

PUSH R31
PUSH R30


ldi r18,96// load data from mem
ldi r19,0
st Z,R18
std Z+1,R19

ldi R26, low(flash_data)
ldi R27, high(flash_data)
ldi R23,0x32
fill_temp:
LD R0,X+
LD R1,X+
ST Z, R0
STD Z+1,R1
wait_spm:
IN R18,0x37
MOV R19,R18
SBRC R19, 0
RJMP wait_spm


LDI R18, 1
LDI R30, flash_data
LD R20, Z
LDD R21,Z+1
mov R30, R17
LDI R31,0
MOVW R1:R0,R21:R20
OUT 0x37,R18
SPM

LDI R16,1
OUT SPMCR,R16
SPM

dec R23
dec R23
cpi R23,0
brne fill_temp



//*****************************************
//******* save data to programm memory*****
LDI R16,low(flash_adr)//load address in prog.mem.
LDI R17,high(flash_adr)
MOVW R31:R30,R17:R16

LDI R16,5
OUT SPMCR,R16
SPM
POP R30
POP R31


//*****************************************
RET
END DoSpm
Вот накалякала вот такую штуку.В результате записывается один байт, во второй просто нули и всё
defunct
Цитата
Len_OK

bb-offtopic.gif У меня к вам вопрос (точнее два вопроса).
1. Если вы не собираетесь писать программу на "C" тогда зачем пользоваться убогим иаровским ассемблером? avrasm2 в AVR-Studio гораздо более удобен и правилен "как асм".
2. Напротив, если собираетесь писать на "C", то неужели одной DoSpm( addr, data, code) недостаточно?

имея одну функцию "заправки" требуемых регистров и вызова SPM, все остальное можно оформить на C примерно в таком виде:
Код
DoSpm( page_addr, 0x0, CODE_ERASE); // <--- стререть страницу
DoSpm( page_addr, 0x0, CODE_REENABLE_RWW); // <--- разлочить RWW секцию если работаем из boot секции
for( i = 0; i < PAGE_SIZE; i++)
{
    // fill temp buffer
    DoSpm( page_addr + i,  <слово данных>, CODE_FILL_TEMP_BUF); // <-- заполнить temp буфер
}
DoSpm( page_addr, 0x0,  CODE_DO_PROGRAM ); // <--- зашить темп буфер
DoSpm( page_addr, 0x0, CODE_REENABLE_RWW); // разлочить RWW если работаем из boot секции
Len_OK
Цитата(defunct @ May 22 2008, 23:57) *
bb-offtopic.gif У меня к вам вопрос (точнее два вопроса).
1. Если вы не собираетесь писать программу на "C" тогда зачем пользоваться убогим иаровским ассемблером? avrasm2 в AVR-Studio гораздо более удобен и правилен "как асм".
2. Напротив, если собираетесь писать на "C", то неужели одной DoSpm( addr, data, code) недостаточно?


Я конечно собираюсь все писать на си. Просто я решила написать полностью функцию на ассемблере, чтобы из си передавать только буфер с данными. И функцию заполнения страницы представляла себе намного сложнее.
Ваш вариант оказался проще, спасибо за терпение smile.gif
defunct
Цитата(Len_OK @ May 23 2008, 10:32) *
Я конечно собираюсь все писать на си.

Тогда хорошо бы "причесать" функцию - добавить в нее проверку на готовность SPM перед загрузкой SPMCR регистра. (не знаю насколько это актуально для tiny, но это нужно для мег, где есть RWW секция).
Код
WAIT_SPM_READY:
SBIC  SPMCR,  0
RJMP WAIT_SPM_READY
Len_OK
[quote name='defunct' date='May 23 2008, 13:02' post='415863']
У меня всё ещё возникают проблемы с записью.
Если я заполняю страницу какой-то интовой константой, размер страницы указываю 32(а должно быть 16 слов), то все нормально записывается.
Если же я пытаюсь заполнить страницу какими-то данными из моего буфера, то ничего не получаеся
defunct
Цитата
размер страницы указываю 32(а должно быть 16 слов),

Запоняется буфер словами, выходить за границы буфера при его заполнении нежелательно (может приводить к непредсказуемым последствиям).
(PAGE_SIZE >> 1) - будет количество слов. ;>
И при загрузке данных, надо увеличивать адрес на 2.
page_addr + (i << 1).
Если не заработает - приведите код, вечером смогу попробовать на тиньке.
Len_OK
Цитата(defunct @ May 23 2008, 18:09) *
Если не заработает - приведите код, вечером смогу попробовать на тиньке.


Прилагаю свой проект, потому как всё ещё не могу разобраться в чём проблема. Программка почему-то вообще не хочет работать с буфером.
defunct
Асм функция используемая вами - рабочая. Полагаю что-то не так было с загрузкой данных и возможно адресами.
Загружать temp буфер надо словами, а не байтами.

Цитата
Программка почему-то вообще не хочет работать с буфером.

Убедитесь что фуз SELFPRGEN запрограммирован (установлен в 0)!

см атач.
проверил в железе (на t2313).
Писал в последнюю страницу флеш - работает (стирает / пишет).
Len_OK
Цитата(defunct @ Jun 2 2008, 01:27) *
см атач.
проверил в железе (на t2313).
Писал в последнюю страницу флеш - работает (стирает / пишет).


Спасибо, я все проверила, всё работает...просто не хватало оперативки контроллера!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.