|
startup asm |
|
|
|
Jan 14 2009, 14:12
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Объясните как работает этот кот, с ассемблером плохо знаком, сейчас читаю, но не совсем все понятно. А именно инструкция ldr записывает значение находящееся по адресу RESET_ADDR , в регистр pc, переменная RESET_ADDR не где не объявляется так же как и pc ? код взят отсюда : http://electronix.ru/forum/index.php?act=a...st&id=16569Код ldr pc, RESET_ADDR ldr pc, UNDEF_ADDR ldr pc, SWI_ADDR ldr pc, PREFETCH_ABORT_ADDR ldr pc, DATA_ABORT_ADDR .word 0 ldr pc, IRQ_ADDR ldr pc, FIQ_ADDR RESET_ADDR: .word RESET_handler UNDEF_ADDR: .word UNDEF_handler SWI_ADDR: .word SWI_handler PREFETCH_ABORT_ADDR: .word PREFETCH_ABORT_handler DATA_ABORT_ADDR: .word DATA_ABORT_handler .word 0 IRQ_ADDR: .word IRQ_handler FIQ_ADDR: .word FIQ_handler
|
|
|
|
10 страниц
1 2 3 > »
|
 |
Ответов
(1 - 99)
|
Jan 14 2009, 15:56
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
В один регистр PC, по очереди запишутся адреса меток, или pc это счетчик и при каждой последующей записи он инкриминируется ? Еще простой вопрос, что означает .word 0 ? Где можно прочитать по ассемблеру для арм, здесь есть, но не подробно http://www.gaw.ru/html.cgi/txt/doc/micros/..._arm/survey.htmКод ldr pc, RESET_ADDR ldr pc, UNDEF_ADDR ldr pc, SWI_ADDR ldr pc, PREFETCH_ABORT_ADDR ldr pc, DATA_ABORT_ADDR
|
|
|
|
|
Jan 14 2009, 16:26
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(sergey sva @ Jan 14 2009, 18:56)  В один регистр PC, по очереди запишутся адреса меток....  да уж.... а что такое у нас PC? И что произойдет после первой-же в него записи? У Вас проблемы не с ASM а много более глубокие  Цитата Где можно прочитать по ассемблеру для арм, Базовые понятия на http://arm.com Нюансы - в документации на конкретный ассемблер.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 14 2009, 16:28
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sergey sva @ Jan 14 2009, 18:56)  В один регистр PC, по очереди запишутся адреса меток, или pc это счетчик и при каждой последующей записи он инкриминируется ? В регистр PC (Program Counter) пишется один раз, после чего процессор уходит на исполнение программы по записанному в PC адресу. Как уже писали, это таблица векторов исключений. Цитата(sergey sva @ Jan 14 2009, 18:56)  Еще простой вопрос, что означает .word 0 ? Где можно прочитать по ассемблеру для арм .word резервирует в памяти 32-х битное слово, надо полагать. Особенности синтаксиса ассемблера в вашей среде лучше всего описаны в ее документации.
|
|
|
|
|
Jan 14 2009, 17:17
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Цитата(zltigo @ Jan 14 2009, 19:26)   да уж.... а что такое у нас PC? И что произойдет после первой-же в него записи? У Вас проблемы не с ASM а много более глубокие  Базовые понятия на http://arm.com Нюансы - в документации на конкретный ассемблер. Да это верно, проблема гораздо глубже чем думал, не пойму как работает директива "Align 4"  нашел такой текст прочел : не совсем понятно как выравнивается, к примеру если в pc 0x000000ff после align 4 какое значение там будет? http://www.lib.kiev.ua/books/7/40n42.html вот отрывок где эта директива используется: Код .align 4 UNDEF_string: .asciz "\r\nUNDEFINED INSTRUCTION Exception!!!" .align 4 SWI_string: .asciz "\r\nSWI Exception!!!" .align 4 PREFETCH_ABORT_string: .asciz "\r\nPREFETCH ABORT Exception!!!" .align 4 DATA_ABORT_string: .asciz "\r\nDATA ABORT Exception!!!\r\n" .align 4 STOPPED_string: .asciz "\r\nStopped!!!" .align 4 eclipse + yagarto
Сообщение отредактировал sergey sva - Jan 14 2009, 17:21
|
|
|
|
|
Jan 14 2009, 17:25
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sergey sva @ Jan 14 2009, 20:17)  не совсем понятно как выравнивается, к примеру если в pc 0x000000ff после align 4 какое значение там будет? 0x000000ff, ибо align к PC ну никак не относится. Это просто указание ассемблеру, что следующий после align обект будет иметь соответствующее выравнивание. Код ldr r0, [r0] DCB "ab" ALIGN 4 ldr r0, [r0] Код 0x0000006c: e5900000 .... LDR r0,[r0,#0] $d 0x00000070: 00006261 ab.. DCD 25185 <---- ассемблер добавил два байта для выравнивания $a 0x00000074: e5900000 .... LDR r0,[r0,#0]
|
|
|
|
|
Jan 14 2009, 18:46
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(sergey sva @ Jan 14 2009, 21:39)  строка abcdef занимает 6 байт Нет. Cемь. Цитата но если использовать выравнивание align 4 то она будет размещена в 8 байтах ? Нет. Семь или в зависимости от нюансов конткретного ассемблера, но совершенно вне зависимости от одиночного align перед этой строкой. P.S. Так и будете заниматься гаданиями?
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 15 2009, 21:24
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
С этим кажется разобрался, ядро настраивается отдельно, для каждого режима и стек тоже для каждого режима свой. Другой вопрос: правильно я распределил адреса, для стеков. Ремап не используется. Начала адреса озу с 0x20000000 (at91sam7). Где нужно настраивать компоновщик ( в makefile ? )что бы не записать в стек переменные которые будут использоваться в программе? Код ldr r0, #0x20000900 msr cpsr_c, #(UNDEF_MODE | I_BIT | F_BIT) mov sp, r0 sub r0, r0, #0x00000100 msr cpsr_c, #(ABT_MODE | I_BIT | F_BIT) mov sp, r0 sub r0, r0, #0x00000100 msr cpsr_c, #(FIQ_MODE | I_BIT | F_BIT) mov sp, r0 sub r0, r0, #0x00000100 msr cpsr_c, #(IRQ_MODE | I_BIT | F_BIT) mov sp, r0 sub r0, r0, #0x00000100 msr cpsr_c, #(SVC_MODE | I_BIT | F_BIT) mov sp, r0 sub r0, r0, #0x00000100 msr cpsr_c, #USR_MODE mov sp, r0 sub sl, sp, #0x00000400
Сообщение отредактировал sergey sva - Jan 15 2009, 21:53
|
|
|
|
|
Jan 15 2009, 21:47
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sergey sva @ Jan 16 2009, 00:24)  Начала адреса озу с 0x20000000 (at91sam7). С количеством нулей ошиблись: ОЗУ у SAM7 начинается с 0x200000. Стек обычно располагают в конце ОЗУ, а не в начале. P.S. Пожалуйста, используйте знаки препинания: Цитата другой вопрос правильно распределил адреса для стеков ремап не используется - это можно примерно понять только с десятого прочтения.
|
|
|
|
|
Jan 15 2009, 22:05
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Цитата P.S. Пожалуйста, используйте знаки препинания: Виноват, исправил. Компоновщик настраиваться, в этом файле: CODE /* identify the Entry Point (_vec_reset is defined in file crt.s) */ ENTRY(_vec_reset)
/* specify the AT91SAM7S64 memory areas */ MEMORY { flash : ORIGIN = 0, LENGTH = 64K /* FLASH EPROM */ ram : ORIGIN = 0x00200000, LENGTH = 16K /* static RAM area */ }
/* define a global symbol _stack_end (see analysis in annotation above) */ _stack_end = 0x203FFC;
/* now define the output sections */ SECTIONS { . = 0; /* set location counter to address zero */ .text : /* collect all sections that should go into FLASH after startup */ { *(.text) /* all .text sections (code) */ *(.rodata) /* all .rodata sections (constants, strings, etc.) */ *(.rodata*) /* all .rodata* sections (constants, strings, etc.) */ *(.glue_7) /* all .glue_7 sections (no idea what these are) */ *(.glue_7t) /* all .glue_7t sections (no idea what these are) */ _etext = .; /* define a global symbol _etext just after the last code byte */ } >flash /* put all the above into FLASH */
.data : /* collect all initialized .data sections that go into RAM */ { _data = .; /* create a global symbol marking the start of the .data section */ *(.data) /* all .data sections */ _edata = .; /* define a global symbol marking the end of the .data section */ } >ram AT >flash /* put all the above into RAM (but load the LMA initializer copy into FLASH) */
.bss : /* collect all uninitialized .bss sections that go into RAM */ { _bss_start = .; /* define a global symbol marking the start of the .bss section */ *(.bss) /* all .bss sections */ } >ram /* put all the above in RAM (it will be cleared in the startup code */
. = ALIGN(4); /* advance location counter to the next 32-bit boundary */ _bss_end = .; /* define a global symbol marking the end of the .bss section */ } _end = .; /* define a global symbol marking the end of application RAM */ Где про это можно прочитать? Пробовал запустить из командной строки, arm-elf-ld -? Окно закрывается. Использую yagarto. Модератор. Для цитирования объемных исходников используйте тэги codebox, вместо code.
|
|
|
|
|
Jan 16 2009, 06:34
|

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

|
Цитата(sergey sva @ Jan 16 2009, 00:05)  Где про это можно прочитать? В документации на binutils. Конкретно скрипты линкера (ld) - в документации на ld.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 16 2009, 12:37
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Буду читать. Мне еще не понятен один момент по работе прерываний: После включения питания, контроллер переходит на первую строчку кода, запись адреса вектора сброса в PC ldr pc, RESET_ADDR, после происходит настройка ядра, стека, прочие настройки, таймеров, и дт дальше вызов функции маин. В ней цикл for(;;){} , все зацикливается. Возникло прерывании, например IRQ в PC должен записаться адрес кода где находится программа обработки прерывания. Адрес метки программы прерываний нужно тоже записывать в какой то регистр?
|
|
|
|
|
Jan 16 2009, 19:16
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(sergey sva @ Jan 16 2009, 22:11)  Как разместить метку, на асме .... Ой  , что сейчас будет.... Код ORG 0x18 ldr pc,[pc,#-0xFF0]; Jump directly to the address given by the AIC Тема напоминает строительство дома без фундамента  P.S. Может объединить c http://electronix.ru/forum/index.php?showtopic=57912&hl= до кучи?
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 16 2009, 19:33
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Цитата строительство дома без фундамента sad.gif Ничего страшного Москва не сразу строилась. Было бы желание  Да это точно, что то будет  Понял что так можно перейти на выполнение кода находящегося по адресу, но как разместить код по этому адресу 0х18? В документации написано что после прерывания в счетчик программ будет записано 0х18 или 0х1С. По этому адресу нужно разместить, код который будет читать вектор прерывания и записывать его в PC. The CPSR is stored in SPSR_irq, the current value of the Program Counter is loaded in the Interrupt link register (R14_irq) and the Program Counter (R15) is loaded with 0x18.
Сообщение отредактировал sergey sva - Jan 16 2009, 20:00
|
|
|
|
|
Jan 16 2009, 20:10
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sergey sva @ Jan 16 2009, 22:33)  но как разместить код по этому адресу 0х18? Помните код из своего первого поста? Вот он с небольшими модификациями: Код ldr pc, RESET_ADDR ldr pc, UNDEF_ADDR ldr pc, SWI_ADDR ldr pc, PREFETCH_ABORT_ADDR ldr pc, DATA_ABORT_ADDR .word 0 ldr pc,[pc,#-0xF20]; IRQ ldr pc,[pc,#-0xF20]; FIQ RESET_ADDR: .word RESET_handler UNDEF_ADDR: .word UNDEF_handler SWI_ADDR: .word SWI_handler PREFETCH_ABORT_ADDR: .word PREFETCH_ABORT_handler DATA_ABORT_ADDR: .word DATA_ABORT_handler
|
|
|
|
|
Jan 16 2009, 22:18
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Если правильно понимаю? После перехода PC на адрес 0x1000018 происходит вычитания - 0хF20 программный счетчик переходит на адрес AIC_IVR читается его значение и записывается в pc после выполняется программа обработки прерывания. Запись в AIC_SVR0 - 31 нужно делать после сброса, после перехода по метке LAB1? Код 0xFFFFF100 AIC_IVR 0xFFFFF104 AIC_FVR
.global _start _start:
0x1000000 ldr pc, lab1 0x1000004 ldr pc, lab2 0x1000008 ldr pc, lab3 0x100000C ldr pc, lab4 0x1000010 ldr pc, lab5 0x1000014 .word 0 0x1000018 ldr pc,[pc,#-0xF20]; @IRQ_ADDR 0x100001C ldr pc,[pc,#-0xF20]; @ FIQ_ADDR
lab1: .... lab2: ....
|
|
|
|
|
Jan 16 2009, 22:32
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sergey sva @ Jan 17 2009, 01:18)  Если правильно понимаю? Почти: после перехода PC на адрес 0x18 (он же 0x100018 без ремапа - внимательнее с количеством нулей) произойдет загрузка регистра PC значением, расположенным по адресу PC-0xF20+8 = 0xFFFFF100 = AIC_IVR, и процессор отправится выполнять подпрограмму прерывания. Цитата(sergey sva @ Jan 17 2009, 01:18)  Запись в AIC_SVR0 - 31 нужно делать после сброса, после перехода по метке LAB1? Ну не обязательно прямо так сразу и все. Не стоит забывать только про установку AIC_SPU.
|
|
|
|
|
Jan 17 2009, 21:36
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Понятно. Разбираюсь еще с ассемблером, появился вопрос, простой  , Подумал лучше спросить чем оставаться с сомнениями. команда and логическое и, с флагом S выполняется если условие истинно. Получается если: mov R1 , #0xFF ands R1 , R1, #0xFF B lab1 условие истинное будет выполняться эта команда B lab2 условие не истинное будет выполняться эта команда
|
|
|
|
|
Jan 17 2009, 22:33
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sergey sva @ Jan 18 2009, 01:29)  Если правильно понял: mov R1, #0xFF ands R1, R1, #0xFF mov ne R2 , #0xFF ; этот код выполняется, если R1 & 0xFF != 0 mov R3 , #0xFF ;этот код выполняется всегда
|
|
|
|
|
Jan 18 2009, 13:38
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Что проверяет _check_mapping: , для чего сохранять 0x12345678 в конец таблицы векторов, по адресу 0x200014 . ? Код _check_mapping: ldr r0, =0x200014 mov r1, #0x14 ldr r2, =0x12345678 str r2, [r0] ldr r0, [r1] cmp r0, r2 beq _check_mapping_end _mem_remap: @ RAM remap ldr r0, =MC_BASE mov r1, #1 str r1, [r0, #MC_RCR] _check_mapping_end: mov r0, #0x14 mov r1, #0 str r1, [r0]
|
|
|
|
|
Jan 18 2009, 16:30
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sergey sva @ Jan 18 2009, 19:08)  Объясните, пожалуйста Код AREA code1, DATA, READWRITE @ DATA эта директива как то влияет на код , или это для удобства чтения кода ?
regs_temp @метка SPACE 0x40 @указатель на структуру 0х40 ?
END @ конец AREA1, или всей страницы кода? AREA - указывает название и тип сегмента для линковки. SPACE n - резервирует n байт памяти END - конец файла Все вышеперечисленное имеет смысл только для RVCT. У GCC дериктивы будут другими (.section, .zero и т.д).
|
|
|
|
|
Jan 18 2009, 18:10
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Поправите если что не так понял. Изучаю доку, но не все же не понятно, CPSR регистр статуса и регистр сохранного статуса SPSR , SPSR это резервный регист, в него нужно программно сохранять статус или он сам сохраняет CPSR что то я не где это не нашел. Еще в программе обработки исключительной ситуации, вместе с включением прерываний ядро переключается в ABORT_MODE, а где его переводить в USER_MODE? CODE DATA_ABORT_handler: sub r14, r14, #0x04 @ регистр связи r14 = r14 - 0x04 stmfd r13!, {r14} @ Сохранить регистр R14 в Стеке stmfd r13!, {r0-r3, r12} @ Сохранить регистры r0 - r3 и r12 в Стеке ldr r0, = regs_temp @ Сохранить в r0 адрес структуры regs_temp str r14, [r0], #0x04 @ Сохранить r14 в в структуре regs_temp mov r14, r0 @ Записать в регистр связи адрес regs_temp ldr r0, [r13] @ Прочитать r0 из стека stmia r14!, {r0-r12} @ Сохранит в regs_temp регистры r0 - r12 mov r0, r14 @ Записать в r0 r14(адрес regs_temp) mrs r14, SPSR @ сохранить в r14, копию сохраненого статуса программы stmfd r13!, {r14} @ Сохранить в стеке регистр r14 orr r14, r14, #F_BIT orr r14, r14, #I_BIT @ запрет прерываний, логическое или r14 = r14 || #F_BIT || #I_BIT msr CPSR_c, r14 @ запись в регистр статуса stmia r0!, {r13-r14} @ Сохранит в regs_temp регистры r13-r14 and r0, #F_BIT and r0, #I_BIT and r0, #ABT_MODE @ логическое и, разрешение прерываний, переключение режима работы в аварийный. @ r0 = r0 && #F_BIT && #I_BIT && #ABT_MODE msr CPSR_c, r0 @ Записать в CPSR r0 ldr r0, = regs_temp @ Записать в r0 указатель на regs_temp @ bl func_obr_data_abort **** Вызов функции C ldmfd r13!, {r0} @ прочитать из стека r0 msr SPSR_c, r0 @ записать в регистр статуса r0. Возврат статуса. ldmfd r13!, {r0-r3, r12, pc}^ @ Возврат програмного счетчика, и регистров r0-r3 r12 pc @----------------------------------------------------------------------------------------
|
|
|
|
|
Jan 18 2009, 19:28
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Код sub r14, r14, #0x04 @ LR_abt = LR_abt - 0x04 stmfd r13!, {r14} @ Сохранить LR_abt на стеке ABT stmfd r13!, {r0-r3, r12} @ Сохранить r0 - r3 и r12 на стеке ABT ldr r0, = regs_temp @ Загрузить в r0 адрес структуры regs_temp str r14, [r0], #0x04 @ Сохранить LR_abt в структуре regs_temp mov r14, r0 @ Записать в LR_abt адрес regs_temp+4 ldr r0, [r13] @ Прочитать r0 из стека ABT stmia r14!, {r0-r12} @ Сохранить в regs_temp+4 регистры r0 - r12 mov r0, r14 @ Записать в r0 LR_abt (адрес regs_temp+56) mrs r14, SPSR @ Загрузить в LR_abt копию сохраненого статуса программы stmfd r13!, {r14} @ Сохранить в стеке ABT регистр LR_abt orr r14, r14, #F_BIT @ запрет прерываний, побитовое ИЛИ r14 = r14 | #F_BIT | #I_BIT orr r14, r14, #I_BIT msr CPSR_c, r14 @ запись в регистр статуса, переключение в режим XXX stmia r0!, {r13-r14} @ Сохранить в regs_temp+56 регистры SP_XXX и LR_XXX and r0, #F_BIT @ ???????? and r0, #I_BIT @ ???????? and r0, #ABT_MODE @ ???????? msr CPSR_c, r0 @ Записать в CPSR r0, переключение в режим ABT ldr r0, = regs_temp @ Записать в r0 указатель на regs_temp @ bl func_obr_data_abort @ Вызов функции C ldmfd r13!, {r0} @ прочитать r0 из стека ABT msr SPSR_c, r0 @ записать в регистр сохраненного статуса r0. Возврат статуса. ldmfd r13!, {r0-r3, r12, pc}^ @ Возврат програмного счетчика, и регистров r0-r3 r12 pc, переключение в режим XXX Вот здесь у вас что-то, мягко говоря, странное написано: Код and r0, #F_BIT and r0, #I_BIT and r0, #ABT_MODE msr CPSR_c, r0 Цитата(sergey sva @ Jan 18 2009, 21:10)  SPSR это резервный регист, в него нужно программно сохранять статус или он сам сохраняет CPSR Сам сохраняет. Цитата(sergey sva @ Jan 18 2009, 21:10)  Еще в программе обработки исключительной ситуации, вместе с выключением прерываний ядро переключается в ABORT_MODE, а где его переводить в USER_MODE? Обратите внимание на "^" в последней инструкции.
|
|
|
|
|
Jan 19 2009, 18:13
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
После чтения SPSR_c , устанавливаются биты #F_BIT | #I_BIT , после записывается в стек и в регистр CPSR_c Режим не переключали, он сам переключается , в режим XXX (неопределенный а в эту обработку программа пришла из вектора 0х10 )? Код mrs r14, SPSR @ Загрузить в LR_abt копию сохраненого статуса программы stmfd r13!, {r14} @ Сохранить в стеке ABT регистр LR_abt orr r14, r14, #F_BIT @ запрет прерываний, побитовое ИЛИ r14 = r14 | #F_BIT | #I_BIT orr r14, r14, #I_BIT msr CPSR_c, r14 @ запись в регистр статуса, переключение в режим XXX stmia r0!, {r13-r14} @ Сохранить в regs_temp+56 регистры SP_XXX и LR_XXX orr r0, #F_BIT orr r0, #I_BIT orr r0, #ABT_MODE msr CPSR_c, r0 @ Записать в CPSR r0, переключение в режим ABT
|
|
|
|
|
Jan 19 2009, 18:23
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sergey sva @ Jan 19 2009, 21:13)  После чтения SPSR_c , устанавливаются биты #F_BIT | #I_BIT , после записывается в стек и в регистр CPSR_c Режим не переключали, он сам переключается , в режим XXX (неопределенный а в эту обработку программа пришла из вектора 0х10 )? SPSR сохраняется на стеке до того, как устанавливаются биты F и I. Режим XXX не неопределенный, а тот, в котором случилось исключение. Т.е. получается так: XXX->ABT->XXX->ABT->XXX. Код orr r0, #F_BIT orr r0, #I_BIT orr r0, #ABT_MODE msr CPSR_c, r0 @ Записать в CPSR r0, переключение в режим ABT Во-первых, Вы пропустили инициализацию R0, во-вторых, лучше бы найти "волшебное слово" для операции OR в ассемблере, чем плодить ненужные инструкции.
|
|
|
|
|
Jan 19 2009, 22:10
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Сделайте замечания что, тут я не правильно понял в irq обработчике, Еще вопрос по fiq , теневой регистр, вроде не мало прочел, не где это не встречалось , это R8 -R14 что в них сохраняется, тоже что и RL ? CODE @---------------------------------------------------------------------------------------- IRQ_handler: sub lr, lr, #4 @ LR_IRQ - 4 stmfd sp!, {r0, r3, lr} @ сохранить в стеке IRQ, регистры R0 R1 и LR ldr r0, = AIC_BASE @ чтение из AIC_BASE и запись в регистр R0 ldr r1, [r0, #AIC_IVR] @ чтение из r0 + #AIC_IVR и запись в регистр R1 вектора прерываний mrs r0, SPSR @ Запись в регистр R0 Сохраненого Статуса SPSR stmdb sp!, {r0} @ сохранить в стеке регистр R0 (статус до прервания) mrs r0, CPSR @ Запись в регистре R0, и возврат в режим который был до прерывания orr r0, r0, #SYS_MODE @ Логическое ИЛИ регистра R0 с #SYS_MODE с сохранением в R0 msr CPSR, r0 @ переключение ядра, в Системный режим stmdb sp!, {r2, r3, r4, r5, r6, r7, r8, r9, r10, fp, ip, lr}@ сохранить в стеке SyS регистры r2, r3, r4, r5, r6, r7, r8, r9, r10, fp, ip, lr mov lr, pc @ Копировать в LR регистр, регистр r14 + 0х04 bl r1 @ Переход на вектор программы обработки прерывания ldmia sp!, {r2, r3, r4, r5, r6, r7, r8, r9, r10, fp, ip, lr}@ Прочитать из стека регистры r2, r3, r4, r5, r6, r7, r8, r9, r10, fp, ip, lr mrs r0, CPSR @ сохранить в регистре R0 текущий статус bic r0, r0, #SYS_MODE @ Логическая операция AND NOT регистра R0 и #SYS_MODE orr r0, r0, #IRQ_MODE @ Логическое ИЛИ регистра R0 и #IRQ_MODE msr CPSR, r0 @ Запись в регистр CPSR регистр R0 и переключение ядра в IRQ_mode, ldr r0, = AIC_BASE @ чтение из AIC_BASE и запись в регистр R0 (базовый адрес AIC) str r0, [r0, #AIC_EOICR] @ сохранить R0 по адресу R0 + #AIC_EOICR и сброс прерывания ldmia sp!, {r0} @ чтение из стека и запись в R0 (статус до прерывания) msr SPSR, r0 @ запись в SPSR регистр R0 (возврат статуса до прерывания) ldmia sp!, {r0, r3, pc}^ @ запись в PC значения сохраненого, в момент возникновения прерывания и востановление регистров r0 r3, обновить CPSR @----------------------------------------------------------------------------------------
|
|
|
|
|
Jan 19 2009, 22:17
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sergey sva @ Jan 20 2009, 01:10)  Сделайте замечания что, тут я не правильно понял в irq обработчике,  Вроде все правильно поняли, только вот обработчик - дрянь  Цитата(sergey sva @ Jan 20 2009, 01:10)  Еще вопрос по fiq , теневой регистр, вроде не мало прочел, не где это не встречалось , это R8 -R14 что в них сохраняется, тоже что и RL ? Теневые регистры FIQ - R8-R12 (R13 и R14 и так у всех свои). В них ничего не сохраняется, они просто существуют только в режиме FIQ, из других режимов к ним доступа нет.
|
|
|
|
|
Jan 19 2009, 22:42
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sergey sva @ Jan 20 2009, 01:21)  где бы посмотреть как он должен работать правильно, или что лучше изменить ? В приведенном вами коде выполняется несколько абсолютно бессмысленных действий: 1. Ручное чтение AIC_IVR 2. Переход в режим SYS с запрещенными прерываниями 3. Сохранение всех подряд регистров при вызове подпрограммы Теперь как все это исправить: 1. Если уж у AIC есть механизм автовекторинга, то грех его не использовать: Код ldr pc, RESET_ADDR ldr pc, UNDEF_ADDR ldr pc, SWI_ADDR ldr pc, PREFETCH_ABORT_ADDR ldr pc, DATA_ABORT_ADDR .word 0 ldr pc,[pc,#-0xF20]; IRQ ldr pc,[pc,#-0xF20]; FIQ RESET_ADDR: .word RESET_handler UNDEF_ADDR: .word UNDEF_handler SWI_ADDR: .word SWI_handler PREFETCH_ABORT_ADDR: .word PREFETCH_ABORT_handler DATA_ABORT_ADDR: .word DATA_ABORT_handler Т.е. сразу, первой же командой, переходим на адрес из AIC_IVR. 2. Если Вы не планируете использовать вложенные прерывания, то можно на этом остановитться, и оформлять обработчики стандартно: Код RVCT: __irq void handler(void); GCC: void handler(void) __attribute__ ((interrupt ("IRQ"))); и т.д. 2a. Если же нужны вложенные прерывание, то каждое из них снабжаем своей оберткой: CODE irq_wrapper ; Модифицируем и сохраняем LR sub r14, r14, #0x04 stmfd sp!, {r14}
; Сохраняем SPSR и r0 на стеке IRQ mrs r14, SPSR stmfd sp!, {r0, r14}
; Включаем прерывания и переключаемся в режим SYS mrs r14, CPSR bic r14, r14, #I_BIT orr r14, r14, #ARM_MODE_SVC msr CPSR_c, r14
; Сохраняем только нужные регистры на стеке USER/SYS stmfd sp!, {r1-r3, r12, r14}
; Вызываем C-обработчик bl irq_handler
; Восстанавливаем регистры ldmfd sp!, {r1-r3, r12, r14}
; Запрещаем прерывания, переключаемся в режим IRQ mrs r0, CPSR bic r0, r0, #ARM_MODE_SYS orr r0, r0, #I_BIT :OR: ARM_MODE_IRQ msr CPSR_c, r0
; Извещаем AIC об окончании обработки прерывания ldr r0, =AT91C_BASE_AIC str r0, [r0, #AIC_EOICR]
; Восстанавливаем SPSR_irq и r0 из стека IRQ ldmfd sp!, {r0, r14} msr SPSR_cxsf, r14
; Загружаем в PC модифицированный LR и переключаем режим ldmfd sp!, {pc}^ В этом случае C-обработчик будет обычной процедурой: Код void handler(void);
|
|
|
|
|
Jan 20 2009, 18:00
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sergey sva @ Jan 20 2009, 20:56)  А в чем будет разница, если не устанавливать cxsf ? Код msr SPSR , r14 Во-первых, написать msr SPSR , r14 Вам нормальный ассемблер не позволит, заставив указать хотя бы одно поле. А если позволит, то сам сделает cxsf. Применительно к коду обработчика прерывания, не восстановление хотя бы одного из полей SPSR грозит трудновыловимыми глюками при работе.
|
|
|
|
|
Jan 20 2009, 18:25
|
Профессионал
    
Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007

|
Цитата В приведенном вами коде выполняется несколько абсолютно бессмысленных действий: 1. Ручное чтение AIC_IVR 2. Переход в режим SYS с запрещенными прерываниями По п.1. Ручное чтение AIC_IVR не такое уж зло. При этом достаточно написать один обработчик прерываний для всех функций прерываний, а не обрамлять каждую из них соответствуюшим кодом. По п.2 Переход в режим SYS с запрещенными прерываниями. Так и вы тоже самое делаете в приведенном примере для вложенных прерываний. Кстати, как то набрел на такой обработчик, который короче и быстрее, но требует 128 байт в irq стеке: Код ;16 instructions (16*8) = 128 bytes in irq_stack ;40 bus cycles IRQ_Handler_Entry: sub lr, lr, #4 stmfd sp!, {r4-r6, lr} mrs r4, SPSR ldr r5, =AT91C_BASE_AIC ldr r6, [r5, #AIC_IVR] str r6, [r5, #AIC_IVR] nop msr CPSR_c, #ARM_MODE_SYS stmfd sp!, {r0-r3, r12, lr} mov lr, pc bx r6 ldmia sp!, {r0-r3, r12, lr} msr CPSR_c, #I_BIT | ARM_MODE_IRQ str r0, [r5, #AIC_EOICR] msr SPSR_cxsf, r4 ldmia sp!, {r4-r6, pc}^ ;; using more IRQ stack... the linker config file may ;; have to be fixed ; ENDP
|
|
|
|
|
Jan 20 2009, 19:12
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Если не ошибаюсь, то в этом обработчике, переход на вектор прерывания будет с выключенными прерываниями, если вдруг обработка немного затянется а прерывания будут выключены то данные потеряются. А для чего это перезапись? Код ldr r6, [r5, #AIC_IVR] str r6, [r5, #AIC_IVR]
|
|
|
|
|
Jan 20 2009, 19:28
|
Профессионал
    
Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007

|
Цитата(sergey sva @ Jan 20 2009, 23:12)  Если не ошибаюсь, то в этом обработчике, переход на вектор прерывания будет с выключенными прерываниями, если вдруг обработка немного затянется а прерывания будут выключены то данные потеряются. А для чего это перезапись? Код ldr r6, [r5, #AIC_IVR] str r6, [r5, #AIC_IVR] Ошибаетесь. Переход на функцию обработки прерывания происходит при разрешенных прерываниях (мы же переключились в SYS режим). При чтении по AT91C_BASE_AIC->AIC_IVR в r6 загружается адрес функции обработки прерывания. А запись туда же - сброс AIC'a, чтобы он мог обрабатывать последующие прерывания.
|
|
|
|
|
Jan 20 2009, 20:29
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Сделайте замечания, по FIQ обработчику. Код @---------------------------------------------------------------------------------------- FIQ_handler: sub r14, r14, #0x04 @ LR_FIQ - 4 mrs r8 , SPSR @ сохранить в регистре R8_FIQ статуса программы до прерывания (SPSR) stmfd sp!, {r0} @ сохранить в стеке FIQ регистры r0 mrs r9 , CPSR @ сохранить в R9_FIQ текущий статус CPSR bic r9 , r9 , #F_BIT @ логическое И НЕТ С сохранением в R9_FIQ orr r9 , r9 , #SYS_MODE @ логическое ИЛИ с сохранением в R9_FIQ msr CPSR_c, r9 @ Запись в CPSR R9_FIQ, разрешение прерывания и переключения в режим SYS stmfd sp!, {r1-r3, r12, r14} @ сохраняем в стеке R1 - R3 и RL_SYS @ bl fiq_handler @ Вызов си обработчика ldmfd sp!, {r1-r3, r12, r14} @ чтение из стека SYS регистров R1-R3 и RL_SYS mrs r0, CPSR @ запись в R0 текущий статус CPSR bic r0, r0, #SYS_MODE @ логическое И НЕТ c сохранением в R0 orr r0, r0, #F_BIT | FIQ_MODE @ логическое ИЛИ с сохранением в R0 msr CPSR_c, r0 @ Запрет прерываний и переключение в FIQ_MODE ldr r0, = AT91C_BASE_AIC @ запись в R0 базовый адрес AIC str r0, [r0, #AIC_EOICR] @ запись R0 по адресу R0 + #AIC_EOICR (окончание прерывания) ldmfd sp!, {r0} @ чтение из стека FIQ R0 msr SPSR_cxsf, r8 @ возврат режима, ldmfd sp!, {pc}^ @ запись в pc, модифицированого RL_FIQ
@----------------------------------------------------------------------------------------
|
|
|
|
|
Jan 20 2009, 20:59
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sergeeff @ Jan 20 2009, 21:25)  По п.1. Ручное чтение AIC_IVR не такое уж зло. При этом достаточно написать один обработчик прерываний для всех функций прерываний, а не обрамлять каждую из них соответствуюшим кодом. В данном случае зло, ибо обработчик не делает ничего полезного. Цитата(sergeeff @ Jan 20 2009, 21:25)  По п.2 Переход в режим SYS с запрещенными прерываниями. Так и вы тоже самое делаете в приведенном примере для вложенных прерываний. Да, но я-то прерывания включаю, а не бестолково меняю один режим на другой! Цитата(sergey sva @ Jan 20 2009, 23:29)  Сделайте замечания, по FIQ обработчику. Могу сделать одно, зато глобальное: использование подобного обработчика не имеет смысла.
|
|
|
|
|
Jan 20 2009, 21:52
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sergey sva @ Jan 21 2009, 00:11)  Тоже хорошо, как говорится тяжело в учении легко в бою.  . Если не затруднит, на что обратить внимание ? Логика приоритетов в AIC на FIQ не распространяется, источники Fast Forcing нужно снимать вручную, поэтому переключать режим и разрешать FIQ смысла не имеет - вложенности все равно не будет. Если же абстрагироваться от этих моментов, то тут у Вас ошибка: Код mrs r8 , SPSR @ сохранить в регистре R8_FIQ статуса программы до прерывания (SPSR) Сохранять при таком раскладе что-либо в R8 нельзя, так как он может перетереться следующим прерыванием. Цитата(sergeeff @ Jan 20 2009, 21:25)  Кстати, как то набрел на такой обработчик, который короче и быстрее, но требует 128 байт в irq стеке: А еще некорректно работает с CPSR.
|
|
|
|
|
Jan 20 2009, 23:30
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
При входе в FIQ прерывание ,запрещаются автоматом, тогда обработчик должен: сохранить регистр связи и SPSR , r1- r3 , после перейти на обработку прерывания, после окончания си обработки, сбросить AIC , во становить CPSR. ? Код @---------------------------------------------------------------------------------------- FIQ_handler: sub r14, r14, #0x04 @ LR_FIQ - 4 stmfd sp!, {r0-r3,r14} @ сохранить в стеке FIQ, регистры LR R0-R3, sp - 0x04 mrs r8 , SPSR @ сохранить в регистре R8_FIQ статуса программы до прерывания (SPSR) @ bl fiq_handler @ Вызов си обработчика ldr r9, = AT91C_BASE_AIC @ запись в R9 базовый адрес AIC str r9, [r9, #AIC_EOICR] @ запись R9 по адресу R9 + #AIC_EOICR (окончание прерывания) msr SPSR_cxsf, r8 @ возврат режима, ldmfd sp!, {r0-r3,pc}^ @ запись в pc, модифицированого RL_FIQ востановление R0-R3 обновление CPSR
@----------------------------------------------------------------------------------------
|
|
|
|
|
Jan 21 2009, 00:05
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
SPSR-то зачем сохранять? Можно извратиться так: Код FIQ_handler: sub r14, r14, #4 stmfd sp!, {r14} mov r8, r0 mov r9, r1 mov r10, r2 mov r11, r3 bl fiq_handler_c mov r3, r11 mov r2, r10 mov r1, r9 mov r0, r8 ldmfd sp!, {pc}^ А можно и просто поручить все это дело компилятору.
|
|
|
|
|
Jan 21 2009, 10:51
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Цитата SPSR-то зачем сохранять?
Можно извратиться так: CODE FIQ_handler: sub r14, r14, #4 stmfd sp!, {r14} mov r8, r0 mov r9, r1 mov r10, r2 mov r11, r3 bl fiq_handler_c mov r3, r11 mov r2, r10 mov r1, r9 mov r0, r8 ldmfd sp!, {pc}^
А можно и просто поручить все это дело компилятору. Вложенность на FIQ сделать нельзя ? Информировать AIC об окончании прерывания FIQ не нужно str r9, [r9, #AIC_EOICR] ?
|
|
|
|
|
Jan 21 2009, 12:17
|
Профессионал
    
Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007

|
Цитата(aaarrr @ Jan 21 2009, 14:06)  Нельзя писать "потолочные" значения в зарезервированные биты CPSR. То есть правильный подход это чтение-модификация-запись. Обратимся к первоисточнику : ARM Architecture Reference Manual, 2005, p.A4-78 Цитата You must normally update the value of a PSR by moving the PSR to a general-purpose register (using the MRS instruction), modifying the relevant bits of the general-purpose register, and restoring the updated general-purpose register value back into the PSR (using the MSR instruction). For example, a good way to switch the ARM to Supervisor mode from another privileged mode is:
MRS R0,CPSR ; Read CPSR BIC R0,R0,#0x1F ; Modify by removing current mode ORR R0,R0,#0x13 ; and substituting Supervisor mode MSR CPSR_c,R0 ; Write the result back to CPSR
For maximum efficiency, MSR instructions should only write to those fields that they can potentially change. For example, the last instruction in the above code can only change the CPSR control field, as all bits in the other fields are unchanged since they were read from the CPSR by the first instruction. So it writes to CPSR_c, not CPSR_fsxc or some other combination of fields. таким образом, устанавливаются только контрольные биты в статус регистре.
|
|
|
|
|
Jan 21 2009, 13:02
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sergeeff @ Jan 21 2009, 15:17)  таким образом, устанавливаются только контрольные биты в статус регистре. Согласен, хотя выделили Вы не совсем тот фрагмент первоисточника: Цитата The immediate form must therefore only be used when the intention is to modify all the bits in the specified fields and, in particular, must not be used if the specified fields include any as-yet-unallocated bits. Так как в control field заменяются все биты, то immediate form можно применить. Справедливости ради замечу, что в старых выпусках ARM7TDMI Datasheet упоминались только CPSR_flg и CPSR, т.е. варианта CPSR_c не было вообще.
|
|
|
|
|
Jan 21 2009, 15:51
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Сделайте замечания, дайте советы,  если не затруднит. CODE .include "crtinc.s" @---------------------------------------------------------------------------------------- .section .text .arm .code 32 .global _start _start: @---------------------------------------------------------------------------------------- @ Таблица векторов исключительных ситуаций ldr pc, RESET_ADDR ldr pc, UNDEF_ADDR ldr pc, SWI_ADDR ldr pc, PREFETCH_ABORT_ADDR ldr pc, DATA_ABORT_ADDR .word 0 ldr pc,[pc,#-0xF20] @ IRQ ldr pc,[pc,#-0xF20] @ FIQ
RESET_ADDR: .word RESET_handler UNDEF_ADDR: .word UNDEF_handler SWI_ADDR: .word SWI_handler PREFETCH_ABORT_ADDR: .word PREFETCH_ABORT_handler DATA_ABORT_ADDR: .word DATA_ABORT_handler @---------------------------------------------------------------------------------------- RESET_handler: ldr r0, = STACK msr cpsr_c, #(UNDEF_MODE | I_BIT | F_BIT) mov sp, r0 sub r0, r0, #UNDEF_STACK_SIZE msr cpsr_c, #(ABT_MODE | I_BIT | F_BIT) mov sp, r0 sub r0, r0, #ABT_STACK_SIZE msr cpsr_c, #(FIQ_MODE | I_BIT | F_BIT) mov sp, r0 sub r0, r0, #FIQ_STACK_SIZE msr cpsr_c, #(IRQ_MODE | I_BIT | F_BIT) mov sp, r0 sub r0, r0, #IRQ_STACK_SIZE msr cpsr_c, #(SVC_MODE | I_BIT | F_BIT) mov sp, r0 sub r0, r0, #SVC_STACK_SIZE msr cpsr_c, #USR_MODE mov sp, r0 sub sl, sp, #USR_STACK_SIZE @---------------------------------------------------------------------------------------- @ WatchDog ldr r0, = WDT_BASE ldr r1, = WDD_IS str r1, [r0, #WDT_MR] @---------------------------------------------------------------------------------------- @ EFC ldr r0, = MC_BASE ldr r1, = MC_FWS str r1, [r0, #MC_FMR] @---------------------------------------------------------------------------------------- @ включение тактового генератора и установка времени запуска ldr r0, = PMC_BASE ldr r1, = PMC_MOR_Val str r1, [r0, #PMC_MOR] @ проверка, тактовый генератор стабилизирован или нет ldr r2, [r0, #PMC_SR] ands r2, r2, #PMC_MOSCS @ bne func mainclock ne stabiln****** @ настройка PMC_USBDIV PMC_MUL PMC_OUT PMC_PLLCOUNT PMC_DIV ldr r1, = PMC_PLLR_Val str r1, [r0, #PMC_PLLR] @ Проверка, ФАПЧ зафиксирована ldr r2, [r0, #PMC_SR] ands r2, r2, #PMC_LOCK @ bne func pll not lock******* @ установка предделителя, главного генератора ldr r1, = PMC_PRES str r1, [r0, #PMC_MCKR] @ проверка главного генератора готов или нет ldr r2, [r0, #PMC_SR] ands r2, r2, #PMC_MCKRDY @ bne func mainosc not redy****** @ выбор источника генератора и настройка предварительного делителя ldr r1, = PMC_MCKR_Val str r1, [r0, #PMC_MCKR] @ проверка главного генератора готов или нет ldr r2, [r0, #PMC_SR] ands r2, r2, #PMC_MCKRDY @ bne func mainosc not redy****** @---------------------------------------------------------------------------------------- .if REMAP @ запись таблици векторов прерываний в RAM ldr r0, = _start ldr r1, = INTERNAL_RAM_START ldr r2, = INTERRUPT_VECTORS_END copy: ldr r3, [r0], #4 str r3, [r1], #4 cmp r0, r2 bne copy @ проверка был ремап, или нет. @ запись значения 0x12345678 по адресу 0x200014 @ после выполняется сравнение что по адресу 0x200014 и 0x14 если равно, @ то ремап выполнялся ldr r0, = 0x200014 mov r1, #0x14 ldr r2, = 0x12345678 str r2, [r0] ldr r0, [r1] cmp r0, r2 beq remap_end @ выполнение перераспределения памяти ldr r0, = MC_BASE mov r1, #1 str r1, [r0, #MC_RCR] @ Запись 0х00 по адресу 0x14 remap_end: mov r0, #0x14 mov r1, #0 str r1, [r0] .endif @---------------------------------------------------------------------------------------- @ сдесь инициализация векторов прерываний
@---------------------------------------------------------------------------------------- @ Вызов функции main mov r0, #0 mov r1, #0 mov r2, #0 mov r3, #0 mov r4, #0 bl main __main_exit: b __main_exit @---------------------------------------------------------------------------------------- DATA_ABORT_handler: sub r14, r14, #0x04 @ LR_abt = LR_abt - 0x04 stmfd r13!, {r14} @ Сохранить LR_abt на стеке ABT stmfd r13!, {r0-r3, r12} @ Сохранить r0 - r3 и r12 на стеке ABT ldr r0, = regs_temp @ Загрузить в r0 адрес структуры regs_temp str r14, [r0], #0x04 @ Сохранить LR_abt в структуре regs_temp mov r14, r0 @ Записать в LR_abt адрес regs_temp+4 ldr r0, [r13] @ Прочитать r0 из стека ABT stmia r14!, {r0-r12} @ Сохранить в regs_temp+4 регистры r0 - r12 mov r0, r14 @ Записать в r0 LR_abt (адрес regs_temp+56) mrs r14, SPSR @ Загрузить в LR_abt копию сохраненого статуса программы stmfd r13!, {r14} @ Сохранить в стеке ABT регистр LR_abt orr r14, r14, #F_BIT | I_BIT @ запрет прерываний, побитовое ИЛИ r14 = r14 | #F_BIT | #I_BIT msr CPSR_c, r14 @ запись в регистр статуса, переключение в режим который был до режима ABORT stmia r0!, {r13-r14} @ Сохранить в regs_temp+56 регистры SP_XXX и LR_XXX, r0 + 0x08 mrs r0, CPSR @ чтение текущего статуса в r0 orr r0, r0, #F_BIT |I_BIT|ABT_MODE msr CPSR_c, r0 @ Записать в CPSR r0, переключение в режим ABT ldr r0, = regs_temp @ Записать в r0 указатель на regs_temp @ bl func_obr_data_abort @ Вызов функции C ldmfd r13!, {r0} @ прочитать r0 из стека ABT msr SPSR_c, r0 @ записать в регистр сохраненного статуса r0. Возврат статуса. ldmfd r13!, {r0-r3, r12, pc}^ @ Возврат програмного счетчика, и регистров r0-r3 r12 pc, переключение в режим XXX @---------------------------------------------------------------------------------------- FIQ_handler: sub r14, r14, #0x04 @ LR_FIQ - 4 stmfd sp!, {r0-r3,r14} @ сохранить в стеке FIQ, регистры LR R0-R3, sp - 0x04 @ bl fiq_handler @ Вызов си обработчика ldmfd sp!, {r0-r3,pc}^ @ запись в pc, модифицированого RL_FIQ востановление R0-R3 обновление CPSR @---------------------------------------------------------------------------------------- IRQ_handler: sub r14, r14, #0x04 @ LR_IRQ - 4 stmfd sp!, {r14} @ сохранить в стеке IRQ, регистры LR sp +0x04 mrs r14, SPSR @ сохранить в регистре RL_IRQ статуса программы до прерывания (SPSR) stmfd sp!, {r0, r14} @ сохранить в стеке IRQ регистры r0 r14 mrs r14, CPSR @ сохранить в RL_IRQ текущий статус CPSR bic r14, r14, #I_BIT @ логическое И НЕТ С сохранением в RL_IRQ orr r14, r14, #SYS_MODE @ логическое ИЛИ с сохранением в RL_IRQ msr CPSR_c, r14 @ Запись в CPSR RL_IRQ, разрешение прерывания и переключения в режим SYS stmfd sp!, {r1-r3, r12, r14} @ сохраняем в стеке R1 - R3 и RL_SYS @ bl irq_handler @ Вызов си обработчика ldmfd sp!, {r1-r3, r12, r14} @ чтение из стека SYS регистров R1-R3 и RL_SYS mrs r0, CPSR @ запись в R0 текущий статус CPSR bic r0, r0, #SYS_MODE @ логическое И НЕТ c сохранением в R0 orr r0, r0, #I_BIT | IRQ_MODE @ логическое ИЛИ с сохранением в R0 msr CPSR_c, r0 @ Запрет прерываний и переключение в IRQ_MODE ldr r0, = AIC_BASE @ запись в R0 базовый адрес AIC str r0, [r0, #AIC_EOICR] @ запись R0 по адресу R0 + #AIC_EOICR (окончание прерывания) ldmfd sp!, {r0, r14} @ чтение из стека IRQ R0 ,R14 msr SPSR_cxsf, r14 @ возврат режима, ldmfd sp!, {pc}^ @ запись в pc, модифицированого RL_IRQ @---------------------------------------------------------------------------------------- PREFETCH_ABORT_handler: sub r14, r14, #0x04 @ LR_Pabt = LR_abt - 0x04 stmfd r13!, {r14} @ Сохранить LR_abt на стеке PABT stmfd r13!, {r0-r3, r12} @ Сохранить r0 - r3 и r12 на стеке ABT ldr r0, = regs_temp @ Загрузить в r0 адрес структуры regs_temp str r14, [r0], #0x04 @ Сохранить LR_abt в структуре regs_temp mov r14, r0 @ Записать в LR_abt адрес regs_temp+4 ldr r0, [r13] @ Прочитать r0 из стека ABT stmia r14!, {r0-r12} @ Сохранить в regs_temp+4 регистры r0 - r12 mov r0, r14 @ Записать в r0 LR_abt (адрес regs_temp+56) mrs r14, SPSR @ Загрузить в LR_abt копию сохраненого статуса программы stmfd r13!, {r14} @ Сохранить в стеке ABT регистр LR_abt orr r14, r14, #F_BIT | I_BIT @ запрет прерываний, побитовое ИЛИ r14 = r14 | #F_BIT | #I_BIT msr CPSR_c, r14 @ запись в регистр статуса, переключение в режим который был до режима ABORT stmia r0!, {r13-r14} @ Сохранить в regs_temp+56 регистры SP_XXX и LR_XXX, r0 + 0x08 mrs r0, CPSR @ чтение текущего статуса в r0 orr r0, r0, #F_BIT |I_BIT|ABT_MODE msr CPSR_c, r0 @ Записать в CPSR r0, переключение в режим ABT ldr r0, = regs_temp @ Записать в r0 указатель на regs_temp @ bl func_obr_Pdata_abort @ Вызов функции C ldmfd r13!, {r0} @ прочитать r0 из стека ABT msr SPSR_c, r0 @ записать в регистр сохраненного статуса r0. Возврат статуса. ldmfd r13!, {r0-r3, r12, pc}^ @ Возврат програмного счетчика, и регистров r0-r3 r12 pc, переключение в режим XXX @---------------------------------------------------------------------------------------- UNDEF_handler: sub r14, r14, #0x04 @ LR_Pabt = LR_udef - 0x04 stmfd r13!, {r14} @ Сохранить LR_udef на стеке PABT stmfd r13!, {r0-r3, r12} @ Сохранить r0 - r3 и r12 на стеке udef ldr r0, = regs_temp @ Загрузить в r0 адрес структуры regs_temp str r14, [r0], #0x04 @ Сохранить LR_udef в структуре regs_temp mov r14, r0 @ Записать в LR_udef адрес regs_temp+4 ldr r0, [r13] @ Прочитать r0 из стека udef stmia r14!, {r0-r12} @ Сохранить в regs_temp+4 регистры r0 - r12 mov r0, r14 @ Записать в r0 LR_udef (адрес regs_temp+56) mrs r14, SPSR @ Загрузить в LR_udef копию сохраненого статуса программы stmfd r13!, {r14} @ Сохранить в стеке udef регистр LR_udef orr r14, r14, #F_BIT | I_BIT @ запрет прерываний, побитовое ИЛИ r14 = r14 | #F_BIT | #I_BIT msr CPSR_c, r14 @ запись в регистр статуса, переключение в режим который был до режима udef stmia r0!, {r13-r14} @ Сохранить в regs_temp+56 регистры SP_XXX и LR_XXX, r0 + 0x08 mrs r0, CPSR @ чтение текущего статуса в r0 orr r0, r0, #F_BIT |I_BIT|UNDEF_MODE msr CPSR_c, r0 @ Записать в CPSR r0, переключение в режим UNDEF_MODE ldr r0, = regs_temp @ Записать в r0 указатель на regs_temp @ bl func_obr_udef @ Вызов функции C ldmfd r13!, {r0} @ прочитать r0 из стека udef msr SPSR_c, r0 @ записать в регистр сохраненного статуса r0. Возврат статуса. ldmfd r13!, {r0-r3, r12, pc}^ @ Возврат програмного счетчика, и регистров r0-r3 r12 pc, переключение в режим XXX @---------------------------------------------------------------------------------------- SWI_handler: sub r14, r14, #0x04 @ LR_SWI - 4 stmfd sp!, {r0-r3,r14} @ сохранить в стеке SWI, регистры LR R0-R3, sp - 0x04 @ bl swi_handler @ Вызов си обработчика ldmfd sp!, {r0-r3,pc}^ @ запись в pc, модифицированого RL_FIQ востановление R0-R3 обновление CPSR @----------------------------------------------------------------------------------------
regs_temp: .SPACE 0x40
.end Модератор. Да научитесь же наконец пользоваться тегами правильно! Для вставки объемных исходников вместо code используйте codebox.
|
|
|
|
|
Jan 21 2009, 16:04
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Что-то я не нашел INTERRUPT_VECTORS_END. А регистры зачем очищать перед вызовом main? FIQ и SWI handlers в таком виде не нужны вообще - поручите все компилятору (у GCC, правда, был какой-то древний глюк с генерацией пролога/эпилога). На всякий случай прикладываю свой код запуска генератора и PLL: CODE ; *************************************************************************** ; * PLL
; Flash Wait State Setup ldr r0, =AT91C_BASE_MC mov r1, #AT91C_MC_FWS_1FWS str r1, [r0, #MC_FMR]
; Watchdog Disable ldr r0, =AT91C_BASE_WDTC mov r1, #AT91C_WDTC_WDDIS str r1, [r0, #WDTC_WDMR]
; Set AT91C_MASTER_CLOCK at 55 296 000
ldr r0, =AT91C_BASE_PMC
; 1 Enabling the Main Oscillator: ; SCK = 1/32768 = 30.51 uSecond ; Start up time = 8 * 6 / SCK = 56 * 30.51 = 1,46484375 ms
mov r1, #(0x06 :SHL: 0x08) orr r1, r1, #AT91C_CKGR_MOSCEN str r1, [r0, #PMC_MOR]
; Wait the startup time 0 ldr r1, [r0, #PMC_SR] tst r1, #AT91C_PMC_MOSCS beq %B0
; 2 Checking the Main Oscillator Frequency (Optional) ; 3 Setting PLL and divider: ; - div by 1 Fin = 18,432 ; - Mul 5+1: Fout = 110,592 = (18,432 * 6) ; Field out NOT USED = 0 ; PLLCOUNT pll startup time estimate at : 0.844 ms ; PLLCOUNT 28 = 0.000844 /(1/32768)
mov r1, #0x01 ; AT91C_CKGR_DIV orr r1, r1, #(0x1c :SHL: 0x08) ; AT91C_CKGR_PLLCOUNT orr r1, r1, #(0x05 :SHL: 0x10) ; AT91C_CKGR_MUL orr r1, r1, #AT91C_CKGR_USBDIV_1 str r1, [r0, #PMC_PLLR]
; Wait the startup time 0 ldr r1, [r0, #PMC_SR] tst r1, #AT91C_PMC_LOCK beq %B0 0 ldr r1, [r0, #PMC_SR] tst r1, #AT91C_PMC_MCKRDY beq %B0
; 4. Selection of Master Clock and Processor Clock ; select the PLL clock divided by 2
mov r1, #AT91C_PMC_PRES_CLK_2 str r1, [r0, #PMC_MCKR] 0 ldr r1, [r0, #PMC_SR] tst r1, #AT91C_PMC_MCKRDY beq %B0
ldr r1, [r0, #PMC_MCKR] orr r1, r1, #AT91C_PMC_CSS_PLL_CLK str r1, [r0, #PMC_MCKR] 0 ldr r1, [r0, #PMC_SR] tst r1, #AT91C_PMC_MCKRDY beq %B0
|
|
|
|
|
Jan 21 2009, 16:32
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
>Что-то я не нашел INTERRUPT_VECTORS_END > FIQ и SWI handlers в таком виде не нужны вообще - поручите все компилятору (у GCC, правда, был какой-то древний глюк с генерацией > пролога/эпилога). Куда должен указывать INTERRUPT_VECTORS_END ? А если использовать свои FIQ и SWI handlers то что в них добавить исключить? Компилятору пока не хочется поручать, хочу разобраться как все это работает
|
|
|
|
|
Jan 21 2009, 16:36
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sergey sva @ Jan 21 2009, 19:32)  Куда должен указывать INTERRUPT_VECTORS_END ? Туда же, куда и RESET_handler. Цитата(sergey sva @ Jan 21 2009, 19:32)  А если использовать свои FIQ и SWI handlers то что в них добавить исключить? Компилятору пока не хочется поручать, хочу разобраться как все это работает  Это зависит от задачи - мало ли как используются FIQ и SWI. Пока ничего добавлять/исключать не надо.
|
|
|
|
|
Jan 21 2009, 17:42
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(sergey sva @ Jan 21 2009, 17:51)  Сделайте замечания, дайте советы,  если не затруднит. Обработчик exception незачем иметь размазанным через copy-paste. Вызов неких сишных функций приводит необходимости раздувать стек да и система может быть уже начисто сломана, и железо распрограммировано..... Возращаться обратно после exception - отгребете продолжение глюков - надежнее на перезапуск при котором собствено и разберетесь что там было запротоколировано. Содержимое стека тоже надо запоминать - толку от того, что по LR Вы найдете, например, какой-нибудь memcpy() вызываемый из десятков мест просто никакого.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 21 2009, 17:58
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(zltigo @ Jan 21 2009, 20:42)  Обработчик exception незачем иметь размазанным через copy-paste. Возвраты из разных типов исключений разные. Так получится один размазанный обработчик. Цитата(zltigo @ Jan 21 2009, 20:42)  Вызов неких сишных функций приводит необходимости раздувать стек да и система может быть уже начисто сломана, и железо распрограммировано..... Сишная функция мало чем отличается от ассемблерного аналога. Вполне себе безопасно отработает в режиме исключения. Цитата(zltigo @ Jan 21 2009, 20:42)  Возращаться обратно после exception - отгребете продолжение глюков - надежнее на перезапуск при котором собствено и разберетесь что там было запротоколировано. Это уже дело верхнего уровня - решить, что именно делать: зависнуть, перезапуститься и т.п. Архитектурой ARM предусмотрен возврат, так почему бы его не поддержать? Цитата(zltigo @ Jan 21 2009, 20:42)  Содержимое стека тоже надо запоминать - толку от того, что по LR Вы найдете, например, какой-нибудь memcpy() вызываемый из десятков мест просто никакого. Содержимое стека можно спокойно потом достать и из C-подпрограммы. 2 sergey sva: Еще ошибки, должо быть так: Код DATA_ABORT_handler: sub r14, r14, #0x08 @ LR_abt = LR_abt - 0x08 stmfd r13!, {r14} @ Сохранить LR_abt на стеке ABT ...
PREFETCH_ABORT_handler: sub r14, r14, #0x04 @ LR_Pabt = LR_abt - 0x04 stmfd r13!, {r14} @ Сохранить LR_abt на стеке ABT ...
UNDEF_handler: stmfd r13!, {r14} @ Сохранить LR_udef на стеке UNDEF
|
|
|
|
|
Jan 21 2009, 19:06
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Почему для UNDEF_handler:(Неопределенная инструкция) не нужно модифицировать LR? При возникновение, неопределенного прерывания в какой режим переключится ядро? Код @---------------------------------------------------------------------------------------- UNDEF_IRQ: sub r14, r14, #0x04 @ LR - 4 stmfd sp!, {r0,r14} @ сохранить в стеке ??, регистры LR , sp - 0x04 ldr r0, = AIC_BASE @ запись в R0 базовый адрес AIC str r0, [r0, #AIC_EOICR] @ запись R0 по адресу R0 + #AIC_EOICR (окончание прерывания) ldmfd sp!, {r0,pc}^ @ запись в pc, модифицированого RL востановление R0 обновление CPSR @----------------------------------------------------------------------------------------
|
|
|
|
|
Jan 21 2009, 19:11
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(aaarrr @ Jan 21 2009, 19:58)  Возвраты из разных типов исключений разные. Так получится один размазанный обработчик. Отличий много меньше, нежели общего. Цитата Сишная функция мало чем отличается от ассемблерного аналога. Вполне себе безопасно отработает в режиме исключения. Угу, только вот произвольная функция начинает требовать побольше места под стек, вызывать, например, printf(), захочет воспользоваться прерываниями.... Цитата Это уже дело верхнего уровня - решить, что именно делать: зависнуть, перезапуститься и т.п. Архитектурой ARM предусмотрен возврат, так почему бы его не поддержать? Потому, что это в подавляющем большинстве случаев возврат в сошедшую с ума программу. Типа а почему-бы его не прeдусмотреть... Цитата Содержимое стека можно спокойно потом достать и из C-подпрограммы. Которая или этим стеком уже воспользовалась испортила, или должна переключиться, испортить и посмотреть....
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 21 2009, 20:25
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(zltigo @ Jan 21 2009, 22:11)  Отличий много меньше, нежели общего. Вам жалко 200 байт? Цитата(zltigo @ Jan 21 2009, 22:11)  Угу, только вот произвольная функция начинает требовать побольше места под стек, вызывать, например, printf(), захочет воспользоваться прерываниями.... Это не произвольная функция, а вполне определенная функция обработки исключения. Вы же пишете обработчики прерываний на C, так почему здесь C-подпрограмма вызывает такую реакцию? Просто удобнее сохранение/вывод истории ошибки сделать на C. Цитата(zltigo @ Jan 21 2009, 22:11)  Потому, что это в подавляющем большинстве случаев возврат в сошедшую с ума программу. Типа а почему-бы его не прeдусмотреть... Да, почему бы не предусмотреть. Это универсальное решение. Цитата(zltigo @ Jan 21 2009, 22:11)  Которая или этим стеком уже воспользовалась испортила, или должна переключиться, испортить и посмотреть.... Сишная программа вызывается в режиме ABORT/UNDEF с соответствующим стеком, как она может испортить другой? Цитата(sergeeff @ Jan 21 2009, 22:17)  По поводу выдачи дампа стека. Как-то не ясно, что он может дать для прояснения возникновения exception'a? Ведь вызов функции не всегда сопровождается запихиванием чего бы то ни было в стек. Если не сопровождается - смотрим LR, в противном случае - то место в стеке, где должен быть адрес возврата. Так мы почти в любом случае можем установить ту процедуру, которая вызвала "упавшую".
|
|
|
|
|
Jan 21 2009, 20:48
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(aaarrr @ Jan 21 2009, 22:25)  Сишная программа вызывается в режиме ABORT/UNDEF с соответствующим стеком, как она может испортить другой? Ну в принципе, если указатель на стек в обработчике сохранили, то можно действительно безболезненно посмотреть. Ну а со всем отальным как быть? Вывались в эту "сишную функцию", например, из обработчика прерывания, штатный ввод/вывод обеспечивает операционка. Что будем делать, как сообщать о случишемся. Да, я понимаю, что можно написать аварийную консольку, проинициализировать перед этми железо по минимуму... Но зачем все эти пляски?
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 21 2009, 22:19
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(zltigo @ Jan 21 2009, 23:48)  Ну а со всем отальным как быть? Вывались в эту "сишную функцию", например, из обработчика прерывания, штатный ввод/вывод обеспечивает операционка. Что будем делать, как сообщать о случишемся. Да, я понимаю, что можно написать аварийную консольку, проинициализировать перед этми железо по минимуму... Но зачем все эти пляски? А на асме что бы делали? Вот и здесь то же. К чему эти вопросы, я не пойму? Цитата(sergey sva @ Jan 22 2009, 01:10)  Контроллер aic поддерживает 32 прерывания, эти прерывания закреплены к источникам, или перенастраиваются для разных источников Закреплены.
|
|
|
|
|
Jan 21 2009, 23:30
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(aaarrr @ Jan 22 2009, 00:19)  А на асме что бы делали? Только самое необходимое. Сохраняется, все, что можно-нужно, устанавливается признак exception и на restart. После инициализации системы при наличии флага распечатка, или любые иные действия с сохраненной информацией о вылете. Цитата Вот и здесь то же. 'Здесь' некие действия с негарантированным результатом и непредсказуемым продолжением. Цитата К чему эти вопросы, я не пойму? Был задан вопрос о недостатках приведенного решения.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 21 2009, 23:53
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(zltigo @ Jan 22 2009, 02:30)  'Здесь' некие действия с негарантированным результатом и непредсказуемым продолжением. Укажите, почему это здесь "негарантированный результат" и "непредсказуемое продолжение". Только конкретно. Голословные обвинения не рассматриваются. Цитата(zltigo @ Jan 22 2009, 02:30)  Был задан вопрос о недостатках приведенного решения. У приведенного решения недостатков я не вижу. printf, ввод/вывод и прочую требуху придумали Вы, а не я.
|
|
|
|
|
Jan 22 2009, 09:06
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(zltigo @ Jan 22 2009, 11:24)  Лично мня отладка локализующая проблему только в паректных условиях не устраивает. Опять 25! Последний раз спрашиваю: где паркетные условия, как она ломается? Цитата(zltigo @ Jan 22 2009, 11:24)  Причины и как сделано у меня уже описал, и если все это "требуха", то это в общем-то проблемы того, кто так поступает. Требуха - это то, что Вы мне пытаетесь навязать: Цитата Угу, только вот произвольная функция начинает требовать побольше места под стек, вызывать, например, printf(), захочет воспользоваться прерываниями.... Совершенно высосанные из пальца претензии.
|
|
|
|
|
Jan 22 2009, 17:30
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Каждый человек индивидуальный, как и его решения, конкретных ошибок ведь нет? А стоит возвращаться, или нет после exeption это не такая уж проблема  объясните пожалуйста, по векторам в aic регистры AIC_SVR0-31 содержат вектора прерываний от 0 до 31, регистры AIC_SMR0-31 настраивают прерывания от 0 - 31 приоритеты,фронты. Регистр AIC_SMR0 настраивает прерывание FIQ, регистры AIC_SVR0 и AIC_FVR содержат вектора прерывания FIQ, получается у FIQ два вектора почему два и если приоритет не для FIQ не действует тогда что настраивает регистр SMR0?
|
|
|
|
|
Jan 22 2009, 17:40
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sergey sva @ Jan 22 2009, 20:30)  AIC_SVR0 и AIC_FVR содержат вектора прерывания FIQ, получается у FIQ два вектора AIC_FVR - read only регистр, из которого можно прочитать только содержимое AIC_SVR0. Цитата(sergey sva @ Jan 22 2009, 20:30)  что настраивает регистр SMR0? Цитата The fast interrupt logic of the AIC has no priority controller. The mode of interrupt source 0 is programmed with the AIC_SMR0 and the field PRIOR of this register is not used even if it reads what has been written. The field SRCTYPE of AIC_SMR0 enables programming the fast interrupt source to be positive-edge triggered or negative-edge triggered or high-level sensitive or low-level sensitive
|
|
|
|
|
Jan 22 2009, 18:11
|
Гуру
     
Группа: Свой
Сообщений: 2 546
Регистрация: 23-05-07
Из: Самарская область Сызрань
Пользователь №: 27 923

|
Еще одна неясность возникла, вот код из файла описания AT91sam7s256.h Код // ***************************************************************************** // PERIPHERAL ID DEFINITIONS FOR AT91SAM7XC256 // ***************************************************************************** #define AT91C_ID_FIQ ((unsigned int) 0) // Advanced Interrupt Controller (FIQ) #define AT91C_ID_SYS ((unsigned int) 1) // System Peripheral #define AT91C_ID_PIOA ((unsigned int) 2) // Parallel IO Controller A #define AT91C_ID_PIOB ((unsigned int) 3) // Parallel IO Controller B #define AT91C_ID_SPI0 ((unsigned int) 4) // Serial Peripheral Interface 0 #define AT91C_ID_SPI1 ((unsigned int) 5) // Serial Peripheral Interface 1 #define AT91C_ID_US0 ((unsigned int) 6) // USART 0 #define AT91C_ID_US1 ((unsigned int) 7) // USART 1 #define AT91C_ID_SSC ((unsigned int) 8) // Serial Synchronous Controller #define AT91C_ID_TWI ((unsigned int) 9) // Two-Wire Interface #define AT91C_ID_PWMC ((unsigned int) 10) // PWM Controller #define AT91C_ID_UDP ((unsigned int) 11) // USB Device Port #define AT91C_ID_TC0 ((unsigned int) 12) // Timer Counter 0 #define AT91C_ID_TC1 ((unsigned int) 13) // Timer Counter 1 #define AT91C_ID_TC2 ((unsigned int) 14) // Timer Counter 2 #define AT91C_ID_CAN ((unsigned int) 15) // Control Area Network Controller #define AT91C_ID_EMAC ((unsigned int) 16) // Ethernet MAC #define AT91C_ID_ADC ((unsigned int) 17) // Analog-to-Digital Converter #define AT91C_ID_AES ((unsigned int) 18) // Advanced Encryption Standard 128-bit #define AT91C_ID_TDES ((unsigned int) 19) // Triple Data Encryption Standard #define AT91C_ID_20_Reserved ((unsigned int) 20) // Reserved #define AT91C_ID_21_Reserved ((unsigned int) 21) // Reserved #define AT91C_ID_22_Reserved ((unsigned int) 22) // Reserved #define AT91C_ID_23_Reserved ((unsigned int) 23) // Reserved #define AT91C_ID_24_Reserved ((unsigned int) 24) // Reserved #define AT91C_ID_25_Reserved ((unsigned int) 25) // Reserved #define AT91C_ID_26_Reserved ((unsigned int) 26) // Reserved #define AT91C_ID_27_Reserved ((unsigned int) 27) // Reserved #define AT91C_ID_28_Reserved ((unsigned int) 28) // Reserved #define AT91C_ID_29_Reserved ((unsigned int) 29) // Reserved #define AT91C_ID_IRQ0 ((unsigned int) 30) // Advanced Interrupt Controller (IRQ0) #define AT91C_ID_IRQ1 ((unsigned int) 31) // Advanced Interrupt Controller (IRQ1) #define AT91C_ALL_INT ((unsigned int) 0xC00FFFFF) // ALL VALID INTERRUPTS
// ***************************************************************************** Понятно что этот код описывает номера регистров SMR ,то есть какой регистр SMP отвечает за какую периферию. прерывание от юсб будет настраиваться в smp11 USART 0 в smr6, а AT91C_ID_SYS, это прерывание в каком случае возникает, или AT91C_ID_IRQ0 это ,прерывание от контроллера прерываний, в каком случае может возникнуть для чего это может понадобится ?
|
|
|
|
|
Jan 22 2009, 18:20
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(sergey sva @ Jan 22 2009, 21:11)  AT91C_ID_SYS, это прерывание в каком случае возникает Прерывание от System Controllera (DBGU, PITC etc). Цитата(sergey sva @ Jan 22 2009, 21:11)  или AT91C_ID_IRQ0 Прерывание от внешнего пина.
|
|
|
|
|
Jan 22 2009, 18:23
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(sergey sva @ Jan 22 2009, 19:30)  Каждый человек индивидуальный, как и его решения, Допущенные системные ошибки вполне объективны  . А вот Ваша и aaarrr оценка серьезности этих системных ошибок индивидуально-субьективна  , это да  . Цитата конкретных ошибок ведь нет? Конкретных? Вычитывать не стал, но уж если собрались куда-то корректно "возвращаться" из exceptions для начала подумайте, куда возвратитесь по минус 4 от LR и куда хотели возвратиться.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 22 2009, 18:32
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(zltigo @ Jan 22 2009, 21:23)  Допущенные системные ошибки вполне объективны  Еще раз спрашиваю: где они? Пока все Ваши утверждения остаются абсолютно голословными.Цитата(zltigo @ Jan 22 2009, 21:23)  Конкретных? Вычитывать не стал, но уж если собрались куда-то корректно "возвращаться" из exceptions для начала подумайте, куда возвратитесь по минус 4 от LR и куда хотели возвратиться. Цитата After fixing the reason for the abort, the handler should execute the following irrespective of the state (ARM or Thumb): SUBS PC,R14_abt,#4 for a prefetch abort, or SUBS PC,R14_abt,#8 for a data abort This restores both the PC and the CPSR, and retries the aborted instruction. Цитата After emulating the failed instruction, the trap handler should execute the following irrespective of the state (ARM or Thumb): MOVS PC,R14_und This restores the CPSR and returns to the instruction following the undefined instruction.
|
|
|
|
|
Jan 22 2009, 20:34
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(aaarrr @ Jan 22 2009, 20:32)  Еще раз спрашиваю: Перечитайте, если это все еще кажется Вам несущественным, то это Ваши проблемы. Приведннные цитаты мне? Я то знаю, по этой причине и спросил. А что там в сишной функции-то "для исправления"-то сделаете и куда попадете возвращению без разбору по типу аборта на -4?
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|