Part Number:AM5728
编译环境是CCS10,AM5728 ARM侧A15的裸机程序,在调试模式下运行,中断源是千兆网0的网线连接变化中断,插上网线后能很快进入相应中断服务程序,在服务程序中对相应中断标志位做了清除动作,GMAC模块中的MDIO寄存器,对应的LINKINTRAW和LINKINTMASKED寄存器相应位都正确的被清零了。该中断在退出后又在快速的第二次进入,但没有插拔过网线,之前已被清零的标志位一直保持是0的状态。后面再次插拔网线都不在进中断了,但主循环中的代码跑的好好的,没有死机。调试模式下看了GMAC模块中的MDIO寄存器,对应的LINKINTRAW和LINKINTMASKED寄存器相应位在重新插拔网线后能识别到网线重新连接上了,因而对应中断标志位又在重新置一,但就是不进中断。调试了很久,一直找不到原因在哪里。以下是中断允许,中断处理各过程的代码:
在C文件csl_a15_startup.c的中断向量表中调用了如下函数:
Intc_IntRegister(4,MDIO_ISR,0); //注册千兆网MDIO中断,编号为4
main函数的系统初始化中,调用了下面三个函数:
IntMasterIRQEnable(); //使能主IRQ中断
Intc_IntPrioritySet(4,10,0);//4号中断优先级为10
Intc_SystemEnable(4); //使能4号中断
模块级中断配置中,编写了如下中断配置函数
void Init_EtherNet_Interrupt_Parameter(void)
{
CPDMA_Regs.EOI_VECTOR = 0;
CPDMA_Regs.EOI_VECTOR = 1;
CPDMA_Regs.EOI_VECTOR = 2;
CPDMA_Regs.EOI_VECTOR = 3;
CPDMA_Regs.EOI_VECTOR = 4;
MDIORegs.USERPHYSEL0.bit.LINKINTENB = 1;//允许网线连接状态变化中断
CPSW_WR_Regs.C0MISCEN.bit.LINKINT0 = 1;//杂项配置中允许网线连接状态变化中断
CPSW_WR_Regs.C0RXEN.bit.CH0 = 1;//允许接收中断
CPSW_WR_Regs.C0TXEN.bit.CH0 = 1;//允许发送中断
}
以下是网线连接状态变化的中断服务函数
interrupt void MDIO_ISR(void)
{
if(CPSW_WR_Regs.C0MISCSTAT.bit.LINKINT0 == 1)
{
MDIORegs.LINKINTMASKED.bit.LINK_ChangEvent = 1;//清除中断
CPDMA_Regs.EOI_VECTOR = 3;//
DHCP_Discover();
}
LED3 = ~LED3;
//D3_GREEN = 1;
}
中断服务函数里面if语句中的代码都能正确运行
另外,不仅是这个网线连接状态变化中断会连续两次进入中断,之后就无论什么情况都不在进,我另外开了个定时器中断,也是同样的情况
Shine:
请问中断使能位都正确吗?是否有尝试过加大堆栈?
,
user18914063:
中断使能位应该都没问题,我测试了的,代码里使能的寄存器位,改为禁止后,中断就不响应了,加大堆栈倒是没试过,不过,代码里就这么一个中断,应该不是堆栈的问题吧,CMD文件里面堆栈的设置如下:
/****************************************************************************//* AM57xx_ARM.cmd *//****************************************************************************/–retain="*(.intvecs)"-c-stack 0x8000-heap 0x2000–args 0x1000-e EntryMEMORY{ VECTORS : o = 0x40300000, l = 0x00000200 /* 中断向量表,占用512字节空间 */ OCMC_RAM1 : o = 0x40300200, l = 0x0007FE00 /* 512kB L3 OCMC RAM1 */ OCMC_RAM2 : o = 0x40400000, l = 0x00100000 /* 1MB L3 OCMC RAM2 */ OCMC_RAM3 : o = 0x40500000, l = 0x00100000 /* 1MB L3 OCMC RAM3 */ DDR0 : o = 0x80000000, l = 0x40000000 /* 1GB external DDR Bank 0 */ DDR1 : o = 0xC0000000, l = 0x40000000 /* 1GB external DDR Bank 1 */}
SECTIONS{ .intvecs > VECTORS .text > OCMC_RAM1 .stack > OCMC_RAM1
堆栈就是0x8000吧,应该不小了
,
Shine:
如果只用定时器中断,也不能连续进两次中断?
,
user18914063:
说反了,是这两个中断都是连续进两次,就再也不响应了,我分开测试的,定时器测试的时候没有开网口的那个中断,网口的中断也关了定时器,所以不存在两者互相干扰的问题
,
user18914063:
我又在仔细看了5728的手册,第17章里面关于A15那边的中断提到了MPU_INTC寄存器,但相关寄存器没有在5728的手册里列出,问题是要求自己到ARM的官网下载,我下载了,看了下,似乎是进了中断后要对MPU_INTC的相关寄存器位做清零或者别的什么动作,但感觉说的不详细,不知道TI那边有没有这方面的资料参考下,或者我说的MPU_INTC的这个方向对我的问题有没有帮助
,
Shine:
MPU_INTC寄存器的资料要到ARM公司网站查找,请看下面的帖子。https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/892340/ccs-am5718-unavailability-of-register-details-for-registering-interrupts/3303165建议先从比较容易的定时器中断排查,比较一下能进中断和不能进中断时的各个寄存器是否完全一样?