|
VC5509中断程序的完整例子 cmd文件
MEMORY { PAGE 0:
MMR : origin = 0000000h, length = 00000c0h SPRAM : origin = 00000c0h, length = 0000040h VECS : origin = 0000100h, length = 0000100h DARAM : origin = 0000200h, length = 000FE00h SARAM0 : origin = 0010000h, length = 0010000h SARAM1 : origin = 0020000h, length = 0010000h SARAM2 : origin = 0030000h, length = 0010000h CE0 : origin = 0040000h, length = 03c0000h CE1 : origin = 0400000h, length = 0400000h CE2 : origin = 0800000h, length = 0400000h CE3 : origin = 0c00000h, length = 03f8000h
PDROM : origin = 0ff8000h, length = 07f00h
PAGE 2: /* -------- 64K-word I/O Address Space -------- */
IOPORT (RWI) : origin = 0x000000, length = 0x020000 }
SECTIONS { .vectors : {} > VECS PAGE 0 /* interrupt vector table */ .text : {} > SARAM0 PAGE 0 /* Code */ /* These sections must be on same physical memory page when */ /* small memory model is used */ .data : {} > DARAM PAGE 0 /* Initialized vars */ .bss : {} > DARAM PAGE 0 /* Global & static vars */ .const : {} > DARAM PAGE 0 /* Constant data */ .sysmem : {} > DARAM PAGE 0 /* Dynamic memory (malloc) */ .stack : {} > DARAM PAGE 0 /* Primary system stack */ .sysstack: {} > DARAM PAGE 0 /* Secondary system stack */ .cio : {} > DARAM PAGE 0 /* C I/O buffers */
/* The .switch, .cinit, and .pinit sections may be on any */ /* physical memory page when small memory model is used */
.switch : {} > DARAM PAGE 0 /* Switch statement tables */ .cinit : {} > DARAM PAGE 0 /* Auto-initialization tables */ .pinit : {} > DARAM PAGE 0 /* Initialization fn tables */ .csldata : {} > DARAM PAGE 0 .far : {} > DARAM PAGE 0 .ioport : {} > IOPORT PAGE 2 /* Global & static IO vars */ dmaMem1: {} > SARAM1 PAGE 0 dmaMem2: {} > SARAM2 PAGE 0 }
main.c
#include "stdint.h" #include "emif.h" #include "intr.h" #include "limits.h" #include "regs55x.h" #include "type.h" #include "board.h" #include "dma55x.h"
#define SIZE 0x4000
#pragma DATA_SECTION(src1,"dmaMem1") unsigned int src1[SIZE]; #pragma DATA_SECTION(src2,"dmaMem2") unsigned int src2[SIZE];
#define XBSR_ADDR (0x6C00u) //External Bus Selection Register Address #define XBSR (*(ioport volatile unsigned int *)XBSR_ADDR)
#define PLLENABLE 4 #define PLLENABLE_SZ 1
#define MyPLL_MULT 10 #define MyPLL_DIV 0 //设置频率10M×10/(1+0)=100M
#define TYPE_16ASYNC 0x1 //001b空间类型为16-bit-wide asynchronous #define MyCE0_READ_SETUP 0 #define MyCE0_READ_STROBE 2 #define MyCE0_READ_HOLD 2
#define MyCE0_WRITE_SETUP 0 //0 #define MyCE0_WRITE_STROBE 4 //4 #define MyCE0_WRITE_HOLD 2 //2
extern int _vectors;
inline void board_init();
interrupt void Timer0Isr(void);
#define TIMER_PORT0 0 #define PRD_OFFSET 1 #define TCR_OFFSET 2 #define PRSC_OFFSET 3
u32 addr; unsigned int tcount0;
void main(void) { board_init(); INTR_GLOBAL_DISABLE; IFR0 |= IFR0; IFR1 |= IFR1; //Timer0设置 TIMER_INIT(TIMER_PORT0,0xd30,0x3ff,0x3); hook_interrupt(TINT0_TRAP, Timer0Isr); //hook interrupt vectors REG_WRITE(IVPH_ADDR,(((u32)&_vectors & 0xffff00) >> 8)); REG_WRITE(IVPD_ADDR,(((u32)&_vectors & 0xffff00) >> 8)); IER0 |= (1<<TINT0); //enable DSP int
INTR_GLOBAL_ENABLE; //enable global interrupts while (1) { }; }
interrupt void Timer0Isr(void) //Timer0中断服务程序 { // PerformTimer0Isr(); tcount0++;
} inline void board_init() {
//下面为设置系统时钟 CLKMD = 0; //强制进入BYPASS mode (b4=0) while (CLKMD & (1《PLLENABLE)); //等待BYPASS mode激活 CLKMD = ((1《IOB)|(MyPLL_MULT《PLL_MULT)|(MyPLL_DIV《PLL_DIV)|(1《PLL_ENABLE));//IOB=1 则失锁后可重新启动相位锁定过程;PLL_MULT:分子;PLL_DIV:分母 while (!(CLKMD & (1《LOCK))); //等待锁定,时钟稳定下来
/*EMIF 设置*/ EMIF_GCTRL = 0x1; XBSR=0x0201u; //写External Bus Selection Register EMIF_CE0_CTRL1 =(TYPE_16ASYNC << MTYPE) | (MyCE0_READ_SETUP << READ_SETUP) | (MyCE0_READ_STROBE << READ_STROBE) | (MyCE0_READ_HOLD << READ_HOLD); EMIF_CE0_CTRL2 =(MyCE0_WRITE_SETUP << WRITE_SETUP) | (MyCE0_WRITE_STROBE<< WRITE_STROBE) | (MyCE0_WRITE_HOLD << WRITE_HOLD) | (0x1 << EXT_HOLD_WRITE) | (u16)(0x1 << EXT_HOLD_READ); EMIF_CE0_CTRL3 = 0;
}
intr.c
#include" intr.h"
extern interrupt void _intr_handler(); extern int _vectors; //Start label of vector table
void hook_interrupt(unsigned int trap, Ip func) { unsigned long _branch = 0x6a00ul; unsigned long _func = (unsigned long)func; unsigned long *_addr = (unsigned long *)(((unsigned long)&_vectors + (trap * 0x8)) >> 1); //因为对于一个程序标号来说,它的地址是字节寻址的,也就是说这里的_vectors是字节地址, //因此再加上trap*8的字节地址偏移后,右移一位除以2,得到的就是字地址,这样在数据空间寻址才是正确的 *_addr = (_branch << 16) | _func; //B P24指令的机器码为0110 1010 PPPP PPPP PPPP PPPP PPPP PPPP //_func最多是24位的,(这由5509的寻址空间决定),再前面加上0x6a,就是B func指令 }
void unhook_interrupt(unsigned int trap) { unsigned long _branch = 0x6a00ul; unsigned long _func = (unsigned long)_intr_handler; unsigned long *_addr = (unsigned long *)(((unsigned long)&_vectors + (trap * 0x8)) >> 1);
*_addr = (_branch << 16) | _func; }
;========================================================= ; vectors.asm: ;========================================================= .global __vectors .global __intr_handler .global _c_int00
;VECS .set 31
;========================================================= ; Default handler ;========================================================= .text
__intr_handler b __intr_handler
;reti ; do nothing ;========================================================= ; Interrupt vectors. ; set trap=vector number ; call sw_trap and passing trap ;========================================================= .sect ".vectors"
__vectors:
b _c_int00 nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
b __intr_handler nop nop_16 || nop
.end
另外注意的是编译时选择large模式,由于发帖中左移符号<<显示不正常,用《代替,请各位拷贝后改正
|