| 
 
| 一 Bios的启动过程 DSP/BIOS的启动过程包括以下几步:
 * 初始化DSP:复位中断向量指向c_int00地址,DSP/BIOS程序从入口点c_int00开始运行。对C6000,初试化堆栈指针(B15)和全局页指针(B14)分别指向堆栈底部与.bss段的开始,控制寄存器AMR、IER和CSR也被初始化;
 * 用.cinit段中的记录来初始化.bss段;
 * 调用BIOS_init初始化DSP/BIOS模块:BIOS_init执行基本的模块初始化,然后调用MOD_init宏分别初始化每个用到的模块;
 * 处理.pinit表:.pinit表包含了初始化函数的指针;
 * 调用应用程序main函数:在所有DSP/BIOS模块初始化之后,调用main函数。由图2可以看到,本程序在main函数中添加了必要的初始化代码。Main函数初始化之后CPU的控制权交给DSP/BIOS。需注意,main函数中一定不能存在无限循环,否则整个DSP/BIOS程序将瘫痪;
 * 调用BIOS_start启动DSP/BIOS:BIOS_start函数是由配置工具产生的,包含在programcfg.s62文件中,它负责使能DSP/BIOS模块并为每个用到的模块调用MOD_startup宏使其开始工作。
 在这些工作完成之后,DSP/BIOS调用IDL_loop引导程序进入DSP/BIOS空闲循环,此时硬件和软件中断可以抢先空闲循环的执行,主机也可以和目标系统之间开始数据传输。
 二 硬件中断向量表的配置
 1. 编写中断服务例程
 在.c源文件中编写ISR函数c_intXX,用于中断处理,如:
 interrupt void c_intXX (void)
 {
 …;
 }
 注:对于硬件中断而言,XX = 00~15。
 2.初始化中断向量表,并在内存段中的中断向量表中配置好对应的中断向量
 首先是把中断向量表定位到某一内存段中,我们可以在cmd文件中配置中断向量表的内存映射,如:
 MEMORY
 {
 VECTORS:         org = 00000000h,       len = 00000400h
 L2SRAM:            org = 00000400h,       len = 00100000h
 SDRAM:             org = 80000000h,       len = 10000000h
 }
 SECTIONS
 {
 .vecs                  :>            VECTORS
 .data                  :>            L2SRAM
 .text                   :>            L2SRAM
 .switch               :>            L2SRAM
 .stack                 :>            L2SRAM
 .bss                    :>            L2SRAM
 .cinit                   :>            L2SRAM
 .far                     :>            L2SRAM
 .cio                     :>            L2SRAM
 .const                 :>            L2SRAM
 .sysmem             :>            SDRAM
 .tables                :>            L2SRAM
 }
 .vectors  中断向量表所在的段;
 .text     程序代码所在的段;
 .satext   非标准段,放置线性汇编程序代码;
 .bss      非初始化变量段
 .cinit    程序初始化段,经常放置一些没有用const说明的带初值变量的初始化值。
 .far      不可使用DP指针而必须使用全地址访问的变量所在的段,与far关键字和编译选项有关
 .stack    系统栈使用的段
 .cio      printf等输入输出函数使用的缓冲区所在的段
 .switch   程序中switch语句的跳转地址表
 .system   系统堆,内存的动态开辟即使用这个段
 然后建立一个.asm文件,用以配置中断向量表中的中断向量,我们需要声明一些全局变量,以便其他源文件可以引用这些变量或者引用其他源文件的变量,如:
 .global _vectors
 .global _c_int00
 .global _vector1
 .global _vector2
 .global _vector3
 .global _vector4
 .global _vector5
 .global _vector6
 .global _vector7
 .global _c_int08      ; 对应main()函数的c_int08中断服务例程(假设处理的是EDMA中断)
 .global _vector9
 .global _vector10
 .global _vector11
 .global _vector12
 .global _vector13
 .global _vector14
 .global _vector15
 
 因为引用了rts的_c_int00中断,即RESET中断,因此需要引入这个符号:
 .ref      _c_int00
 
 为了把中断服务例程的地址,即中断向量插入到中断向量表中,可以定义一个宏:
 VEC_ENTRY .macro addr
 STW       B0,*--B15
 MVKL      addr,B0
 MVKH      addr,B0
 B         B0
 LDW       *B15++,B0
 NOP       2
 NOP
 NOP
 .endm
 
 为了初始化中断向量表中的中断向量,可以定义一个虚拟的中断向量:
 _vec_dummy:
 B        B3
 NOP      5
 
 接下来就可以配置中断向量表了:
 .sect “.vecs”
 .align 1024
 _vectors:
 _vector0:       VEC_ENTRY _c_int00          ;RESET中断
 _vector1:       VEC_ENTRY _vec_dummy ;NMI不可屏蔽中断
 _vector2:       VEC_ENTRY _vec_dummy ;保留中断1
 _vector3:       VEC_ENTRY _vec_dummy ;保留中断2
 _vector4:       VEC_ENTRY _vec_dummy ;外部中断INT4
 _vector5:       VEC_ENTRY _vec_dummy ;外部中断INT5
 _vector6:       VEC_ENTRY _vec_dummy ;外部中断INT6
 _vector7:       VEC_ENTRY _vec_dummy ;外部中断INT7
 _vector8:       VEC_ENTRY _c_int08 ; EDMA控制器中断EDMAINT,对应于c_int08 ISR
 _vector9:       VEC_ENTRY _vec_dummy;JTAGRTDX中断
 _vector10:      VEC_ENTRY _vec_dummy;EMIF_SDRAM_Timer中断
 _vector11:      VEC_ENTRY _vec_dummy;McBSP_0_Receive中断
 _vector12:      VEC_ENTRY _vec_dummy;McBSP_1_Transmit中断
 _vector13:      VEC_ENTRY _vec_dummy;Host_Port_Host_to_DSP中断
 _vector14:      VEC_ENTRY _vec_dummy;Timer0中断
 _vector15:      VEC_ENTRY _vec_dummy;Timer1中断
 3. 在C程序中指定定义的中断向量表,并且启用CPU中断功能
 在C程序中,用CSL的IRQ模块来设置中断比较方便,在设置之前,需要外部链接上面的asm程序的中断向量表符号:
 extern far void vectors();//之所以为vectors,因为C编译器编译后自动改名其为_vectors
 引用了中断向量表之后,就可以设置中断了:
 IRQ_setVecs(vectors); //指向asm中定义的中断向量表
 IRQ_nmiEnable();
 IRQ_globalEnable();
 IRQ_map(IRQ_EVT_EDMAINT, 8);        //映射事件到指定的物理中断号
 IRQ_reset(IRQ_EVT_EDMAINT);
 4.启动中断源,如EDMA控制器的中断
 至此,中断服务例程c_int8就可以为EDMAINT中断服务了,其它硬件中断向量的配置同理。
 5. IRQ使用注意:
 不可在IRQ_globalDisable之后调用IRQ_clear,否则中断将设置失败。
 
 
 | 
 |