Помогите разобраться. С АРМ - в начале пути.
Происходят непонятки с прерываниями. Используемое оборудование:
IAR 4.41 + H-JTAG V0.4.4 + Wiggler
В качестве основы приложения взял пример AT91SAM7X-Getting Started. Происходит слелующее.
При отработке кода cstartup.s79 в момент инициализации стека для режима SUPERVISOR на
последней строчке (mov r13, r0) программа "улетает" на default-обработчик прерывания IRQ, где, соответственно,
и остается.
Код
#define TOP_OF_MEMORY (AT91C_ISRAM + AT91C_ISRAM_SIZE)
#define IRQ_STACK_SIZE (3*8*4) ; 3 words to be saved per interrupt priority level
#define ARM_MODE_IRQ 0x12
#define ARM_MODE_SVC 0x13
#define I_BIT 0x80
#define F_BIT 0x40
.....
;- Retrieve end of RAM address
EXTERN lowlevel_init
ldr r13,=TOP_OF_MEMORY ;- Temporary stack in internal RAM for Low Level Init execution
ldr r0,=lowlevel_init
mov lr, pc
bx r0 ;- Branch on C function (with interworking)
;------------------------------------------------------------------------------
;- Setup the stack for each mode
;------------------------------------------------------------------------------
ldr r0, =TOP_OF_MEMORY
;- Set up Interrupt Mode and set IRQ Mode Stack
msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT
mov r13, r0 ; Init stack IRQ
sub r0, r0, #IRQ_STACK_SIZE
msr CPSR_c, #ARM_MODE_SVC | F_BIT
mov r13, r0
#define IRQ_STACK_SIZE (3*8*4) ; 3 words to be saved per interrupt priority level
#define ARM_MODE_IRQ 0x12
#define ARM_MODE_SVC 0x13
#define I_BIT 0x80
#define F_BIT 0x40
.....
;- Retrieve end of RAM address
EXTERN lowlevel_init
ldr r13,=TOP_OF_MEMORY ;- Temporary stack in internal RAM for Low Level Init execution
ldr r0,=lowlevel_init
mov lr, pc
bx r0 ;- Branch on C function (with interworking)
;------------------------------------------------------------------------------
;- Setup the stack for each mode
;------------------------------------------------------------------------------
ldr r0, =TOP_OF_MEMORY
;- Set up Interrupt Mode and set IRQ Mode Stack
msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT
mov r13, r0 ; Init stack IRQ
sub r0, r0, #IRQ_STACK_SIZE
msr CPSR_c, #ARM_MODE_SVC | F_BIT
mov r13, r0
вот код процедуры lowlevel_init:
Код
void lowlevel_init(void){
unsigned char i = 0;
// EFC Init
AT91C_BASE_MC->MC_FMR = AT91C_MC_FWS_1FWS; // 1 Wait State to work at 48MHz
// Init PMC Step 1. Enable Main Oscillator
AT91C_BASE_PMC->PMC_MOR = (((AT91C_CKGR_OSCOUNT & (0x40 << 8)) | AT91C_CKGR_MOSCEN));
// Wait Main Oscillator stabilization
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS));
// Init PMC Step 2.
AT91C_BASE_PMC->PMC_PLLR = AT91C_CKGR_USBDIV_1 |
AT91C_CKGR_OUT_0 |
(16 << 8) |
(AT91C_CKGR_MUL & (72 << 16)) |
(AT91C_CKGR_DIV & 14);
// Wait for PLL stabilization
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK));
// Wait until the master clock is established for the case we already
// turn on the PLL
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY));
// Init PMC Step 3.
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
// Wait until the master clock is established
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY));
AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK;
// Wait until the master clock is established
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY));
//инициализация AIC
AT91C_BASE_AIC->AIC_SVR[0] = (int) default_fiq_handler;
for (i = 1; i < 31; i++) {
AT91C_BASE_AIC->AIC_SVR[i] = (int) default_irq_handler;
}
AT91C_BASE_AIC->AIC_SPU = (unsigned int) default_spurious_handler;
// Perform 8 IT acknoledge (write any value in EOICR)
for (i = 0; i < 8; i++) {
AT91C_BASE_AIC->AIC_EOICR = 0;
}
// Enable the Debug mode
AT91C_BASE_AIC->AIC_DCR = AT91C_AIC_DCR_PROT;
// Disable Watchdog
AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;
}
unsigned char i = 0;
// EFC Init
AT91C_BASE_MC->MC_FMR = AT91C_MC_FWS_1FWS; // 1 Wait State to work at 48MHz
// Init PMC Step 1. Enable Main Oscillator
AT91C_BASE_PMC->PMC_MOR = (((AT91C_CKGR_OSCOUNT & (0x40 << 8)) | AT91C_CKGR_MOSCEN));
// Wait Main Oscillator stabilization
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS));
// Init PMC Step 2.
AT91C_BASE_PMC->PMC_PLLR = AT91C_CKGR_USBDIV_1 |
AT91C_CKGR_OUT_0 |
(16 << 8) |
(AT91C_CKGR_MUL & (72 << 16)) |
(AT91C_CKGR_DIV & 14);
// Wait for PLL stabilization
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK));
// Wait until the master clock is established for the case we already
// turn on the PLL
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY));
// Init PMC Step 3.
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
// Wait until the master clock is established
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY));
AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK;
// Wait until the master clock is established
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY));
//инициализация AIC
AT91C_BASE_AIC->AIC_SVR[0] = (int) default_fiq_handler;
for (i = 1; i < 31; i++) {
AT91C_BASE_AIC->AIC_SVR[i] = (int) default_irq_handler;
}
AT91C_BASE_AIC->AIC_SPU = (unsigned int) default_spurious_handler;
// Perform 8 IT acknoledge (write any value in EOICR)
for (i = 0; i < 8; i++) {
AT91C_BASE_AIC->AIC_EOICR = 0;
}
// Enable the Debug mode
AT91C_BASE_AIC->AIC_DCR = AT91C_AIC_DCR_PROT;
// Disable Watchdog
AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;
}
В симуляторе все работает нормально.
Перед выполнением команды [mov r13, r0] состояние AIC в дебаггере в режиме СИМУЛЯТОА
следующее:
AIC_SVR = 0x00000315
AIC_SPU = 0x00000305
AIC_DCR = 0x00000001
остальные - 0x00000000
Перед выполнением команды [mov r13, r0] состояние AIC в дебаггере в режиме RDI + H-JTAG
следующее:
AIC_SVR = 0x00000315
AIR_IVR = 0x00000325
AIR_FVR = 0x00000305
AIR_IPR = 0x00000002
AIR_IMR = 0x00000006
AIR_CISR = 0x00000002
AIC_SPU = 0x00000305
AIC_DCR = 0x00000001
НО:
1. При отключенном wiggler'е при пересбросе питания система работает нормально! О чем сужу
по поведению светодиодов.
2. Один раз из 100 в дебаггере все-таки добираюсь до точки main