Part Number:TMS320C6655
环境: CCS 5.5, Complier: 8.3.12, DSP TMS320C6655
目标: 1. 理解DSP如何跳转到相应的Interrupt Service Routine; 2) 通过自己写代码来验证上述想法
在CCS中建立个工程,仅包含三个文件:main.c, intvecs.asm, and C665x.cmd (Linker Command File). 本人可以通过对ISR寄存器Bit4置位来触发INT4中断,随后IntDefaultHandler函数会被调用。但编译过程中报错,信息如下:
#10234-D unresolved symbols remain InterruptTest #10010 errors encountered during linking; "InterruptTest.out" not built InterruptTest unresolved symbol intcVectorTable, first referenced in ./main.obj InterruptTest
附上三个文件:
main.c
/* * main.c */ #define C674X_NMI 1 #define C674X_GEE 2 #define C674X_XEN 3 #define C674X_INT_COUNT 16 #define NUM_SYS_EVENTS 128 extern cregister volatile unsigned int AMR; //Addressing mode register extern cregister volatile unsigned int CSR; //Control status register extern cregister volatile unsigned int GFPGFR; //Galois field multiply control register extern cregister volatile unsigned int ICR; //Interrupt clear register extern cregister volatile unsigned int IER; //Interrupt enable register extern cregister volatile unsigned int IFR; //Interrupt flag register extern cregister volatile unsigned int IRP; //Interrupt return pointer register extern cregister volatile unsigned int ISR; //Interrupt set register extern cregister volatile unsigned int ISTP; //Interrupt service table pointer register typedef void (*c674xISR)(void); void Intc_Init (void); void IntDefaultHandler (void); /****************************************************************************** **EXTERNALLY DEFINED FUNCTIONS ******************************************************************************/ extern void intcVectorTable(void); /****************************************************************************** **STATIC VARIABLES/FUNCTIONS ******************************************************************************/ static c674xISR c674xISRtbl[C674X_INT_COUNT]; int main(void) { Intc_Init(); // pInterruptRegs->INTMUX1 = IER |= (1<<4) + (1<<1); // set INT4 and NMIE CSR |= 1; // enable GIE while(1) { ISR = (1<<4); // trigger INT4 asm(" NOP"); asm(" NOP"); asm(" NOP"); } return 0; } void Intc_Init (void) {unsigned int step = 0;/* Set ISRs to default "do-nothing" routine */while(step != C674X_INT_COUNT)c674xISRtbl[step++] = IntDefaultHandler;/* Set interrupt service table pointer to the vector table */ISTP = (unsigned int)intcVectorTable;/* Clear pending CPU maskable interrupts (if any) */ICR = 0xFFF0;/* Enable NMIE bit to allow CPU maskable interrupts */IER = (1 << C674X_NMI); } void Intc_IntRegister (unsigned int cpuINT, void (*userISR)(void)) {/* Assign the user's ISR to the CPU maskable interrupt */c674xISRtbl[cpuINT] = userISR; } /****************************************************************************** **INTERRUPT SERVICE ROUTINES - Used Internally ******************************************************************************/ void IntDefaultHandler (void) {while(1); } interrupt void c674x_nmi_isr (void) {c674xISRtbl[1](); } interrupt void c674x_rsvd_int2_isr (void) {c674xISRtbl[2](); } interrupt void c674x_rsvd_int3_isr (void) {c674xISRtbl[3](); } interrupt void c674x_mask_int4_isr (void) {c674xISRtbl[4](); } interrupt void c674x_mask_int5_isr (void) {c674xISRtbl[5](); } interrupt void c674x_mask_int6_isr (void) {c674xISRtbl[6](); } interrupt void c674x_mask_int7_isr (void) {c674xISRtbl[7](); } interrupt void c674x_mask_int8_isr (void) {c674xISRtbl[8](); } interrupt void c674x_mask_int9_isr (void) {c674xISRtbl[9](); } interrupt void c674x_mask_int10_isr (void) {c674xISRtbl[10](); } interrupt void c674x_mask_int11_isr (void) {c674xISRtbl[11](); } interrupt void c674x_mask_int12_isr (void) {c674xISRtbl[12](); } interrupt void c674x_mask_int13_isr (void) {c674xISRtbl[13](); } interrupt void c674x_mask_int14_isr (void) {c674xISRtbl[14](); } interrupt void c674x_mask_int15_isr (void) {c674xISRtbl[15](); }
intvecs.asm
; ; File: intvecs.asm ; ; Brief: Contains interrupt vector table and fetch packets ; ; Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti2k.com/wp-content/uploads/ti2k/DeyiSupport_DSP_ ; ALL RIGHTS RESERVED ;********************************************************** ; Global Symbols ;********************************************************** .global _intcVectorTable .ref __c_int00 .global _c674x_nmi_isr .global _c674x_rsvd_int2_isr .global _c674x_rsvd_int3_isr .global _c674x_mask_int4_isr .global _c674x_mask_int5_isr .global _c674x_mask_int6_isr .global _c674x_mask_int7_isr .global _c674x_mask_int8_isr .global _c674x_mask_int9_isr .global _c674x_mask_int10_isr .global _c674x_mask_int11_isr .global _c674x_mask_int12_isr .global _c674x_mask_int13_isr .global _c674x_mask_int14_isr .global _c674x_mask_int15_isr ;********************************************************** ; Interrupt Fetch Packet ;********************************************************** VEC_ENTRY .macro addr STW B0,*--B15 MVKL addr,B0 MVKH addr,B0 B B0 LDW *B15++,B0 NOP 2 NOP NOP .endm ;********************************************************** ; Interrupt Vector Table ;********************************************************** .align 1024 _intcVectorTable: VEC_ENTRY __c_int00 VEC_ENTRY _c674x_nmi_isr VEC_ENTRY _c674x_rsvd_int2_isr VEC_ENTRY _c674x_rsvd_int3_isr VEC_ENTRY _c674x_mask_int4_isr VEC_ENTRY _c674x_mask_int5_isr VEC_ENTRY _c674x_mask_int6_isr VEC_ENTRY _c674x_mask_int7_isr VEC_ENTRY _c674x_mask_int8_isr VEC_ENTRY _c674x_mask_int9_isr VEC_ENTRY _c674x_mask_int10_isr VEC_ENTRY _c674x_mask_int11_isr VEC_ENTRY _c674x_mask_int12_isr VEC_ENTRY _c674x_mask_int13_isr VEC_ENTRY _c674x_mask_int14_isr VEC_ENTRY _c674x_mask_int15_isr
C665x.cmd
-stack 0x4000 -heap 0x4000 MEMORY { L2SRAM o = 0x00800000 l = 0x00100000 /* 1MB L2SRAM */ /* Core0 running IBL will take up 0x0C000000 ~ 0x0C01FFFF(128KB), reserve at here! */ MSMCSRAM o = 0x0C010000 l = 0x000F0000 /* 896KB MSMCSRAM */ DDR3 o = 0x80000000 l = 0x20000000 /* 512MB DDR3 */ //MSMCRAM o = 0xC000000 l = 0x00100000 } SECTIONS { .text > L2SRAM .cinit > L2SRAM .const > L2SRAM .switch > L2SRAM .stack > L2SRAM .fardata > L2SRAM .cio > L2SRAM .far > L2SRAM GROUP { .neardata /* far uninitialized global and global variables */ .rodata /* global static constant */ .bss /* uninitialized global variables*/ } > L2SRAM }
看上去intvecs.asm未被编译,导致main.c无法识别全局变量intcVectorTable。
查阅了很多资料和论坛帖子,至今未解决。请TI专家识别下哪里有缺失。万分感谢。
Chunhua Ni:
我准备用pdk_c665x_2_0_16\packages\ti\csl\arch\c66x\src目录下的intvecs.asm替换掉当前的c674x的,再做一些修改,有问题再请教,谢谢!
,
Shine:
如果您工程生成的.out文件是ELF格式(旧的是COFF格式),汇编语言里变量/函数名前不需要下划线,请尝试将_intcVectorTable前面的下划线去掉。
Removing the COFF Underscore[edit]
COFF ABI adds a leading underscore to C and C++ symbols to prevent name collisions with symbols defined in hand-coded assembly, but EABI does not add this underscore. When using COFF ABI, a function named red_fish written in C will produce a function entry label with the name _red_fish in the assembly source. Under the EABI, the name of the function as it appears in the assembly source will be exactly as it appears in the C code, so the function entry label for red_fish will be red_fish.