Цитата(Alex_akn @ Jul 15 2008, 11:31)

(В курсе: MEMMAP =0x2 -> User RAM Mode. Interrupt vectors are re-mapped to Static RAM).
Вектора IRQ, FIQ он явно кладет по нужным адресам.
MEMMAP же нигде в программе больше не трогается.
???
Здесь MEMMAP не используется. Если вы посмотрите в fwu_startup_iar.s79 :
Код
reset ldr pc, ?vect_entry
ldr pc, ?vect_entry + 4
ldr pc, ?vect_entry + 8
ldr pc, ?vect_entry + 12
ldr pc, ?vect_entry + 16
DC32 0xB8A06F58 /* 0 - (sum of other vectors instructions) */
ldr pc, ?vect_entry + 24
ldr pc, ?vect_entry + 28
?vect_entry:
DC32 ?cstartup; RES ( 0)
DC32 ?cstartup; UND ( +4)
DC32 ?cstartup; SWI ( +8)
DC32 ?cstartup; P_ABT (+12)
DC32 ?cstartup; D_ABT (+16)
DC32 0; ARM-reserved vector (+20)
DC32 0x40000018; cpu_irq_isr; IRQ (+24)
DC32 0x4000001C; cpu_fiq_isr; FRQ (+28)
видно, что 0x40000018 и 0x4000001C - адреса, по которым будет передаваться управление при IRQ и FIQ. Фактически комбинация ldr pc,xxx и собственно ячейки xxx,например
Код
ldr pc, ?vect_entry
?vect_entry:
DC32 ?cstartup; RES ( 0)
это branch, то есть безусловный переход в любое место в пределах адресного пространства.
В tnkernel таким образом сделаны векторы прерываний для того, чтобы проложение могло установить свой вектор (в flash-то лежат векторы загрузчика). Совершенно нормальный подход. Хотя я в своем загрузчике использую немного другой подход, по мотивам кода уважаемого Zltigo.
Код
__program_start:
ldr pc,(?vect_entry + 4*0) // 00
ldr pc,(?vect_entry + 4*1) // 04
ldr pc,(?vect_entry + 4*2) // 08
ldr pc,(?vect_entry + 4*3) // 0C
ldr pc,(?vect_entry + 4*4) // 10
dc32 0 // 14 Summ of other vectors instructions
ldr pc,[pc,#-0x0120] // 18 Jump directly to the address given by the VIC
// from [0xFFFFFF00] Curent 18h +8(conveyer)=20h
ldr pc,(?vect_entry + 4*7) // 1C
//---------------------------------------------------------------------------
ORG 0x20 // Constant table entries (for ldr pc) will be placed at 0x20
?vect_entry:
dc32 ?cstartup // Reset
dc32 ?cstartup // UND
dc32 Application_SWI // SWI
dc32 PABT_handler // P_ABT
dc32 DABT_handler // D_ABT
dc32 0 // ARM-reserved vector
dc32 0 // IRQ (Jump directly!)
dc32 Application_FIQ // FIQ
Здесь адрес обработчика IRQ берется непосредственно из VIC, reset в начало загрузчика, SWI и FIQ берутся из заголовка приложения по адресу, где приложение будет располагаться. Вот заголовок приложения:
Код
//== With Loader
dc8 Hardware_Version // 00 Hardware revision
dc8 Bootloader_Version // 01
dc8 Application_VersionL // 02
dc8 Application_VersionH // 03
dc32 SFB(CHECKSUM) // 04 End of code address
ldr pc,[pc,#-0x4] // 08 Start Entry Point
dc32 ?cstartup // 0C *Reset
ldr pc,[pc,#-0x4] // 10 SWI
dc32 ?cstartup //vPortYieldProcessor // 14 *SWI
// Place for FIQ Handler ----------------------------------------------------
ldr pc,[pc,#-0x4] // 18 FIQ
dc32 FIQ_ISR_handler // 1C *FIQ
То есть при SWI будет сначала переход в заголовок загрузчика, потом уже в собственно обработчик. RAM при этом не используется вообще. Правда есть дополнительный переход.
Единственное что, поскольку в загрузчике жестко прописан переход по SWI в приложение, при необходимости использования SWI (или FIQ) в загрузчике приходится использовать MEMMAP=2.
Здесь ldr pc,[pc,#-0x4] грузит в pc на самом деле константу из следующих четырех байт, из-за конвеера тут -4(+8) а не +4.
Уфф.