本帖最后由 pingis58 于 2017-6-5 11:13 编辑
real_2004 发表于 2017-6-3 09:20
兄弟,这个问题你最终怎么解决的?我看你在21ic上说是官方的库有问题,清除中断时要把CPU ID带过去,没太懂 ...
不知道你遇的问题是不是跟我的同一个。
我用的是ISE14.7带的SDK。
官方库 xscugic_hw.c 文件中替换下面函数:
void XScuGic_DeviceInterruptHandler(void *DeviceId)
{
u32 IntID;
XScuGic_VectorTableEntry *TablePtr;
XScuGic_Config *CfgPtr;
CfgPtr = &XScuGic_ConfigTable[(u32 )DeviceId];
/*
* Read the int_ack register to identify the highest priority
* interrupt ID and make sure it is valid. Reading Int_Ack will
* clear the interrupt in the GIC.
*/
IntID = XScuGic_ReadReg(CfgPtr->CpuBaseAddress, XSCUGIC_INT_ACK_OFFSET)
& XSCUGIC_ACK_INTID_MASK;
if(XSCUGIC_MAX_NUM_INTR_INPUTS < IntID){
goto IntrExit;
}
/*
* If the interrupt is shared, do some locking here if there are
* multiple processors.
*/
/*
* If pre-eption is required:
* Re-enable pre-emption by setting the CPSR I bit for non-secure ,
* interrupts or the F bit for secure interrupts
*/
/*
* If we need to change security domains, issue a SMC instruction here.
*/
/*
* Execute the ISR. Jump into the Interrupt service routine based on
* the IRQSource. A software trigger is cleared by the ACK.
*/
TablePtr = &(CfgPtr->HandlerTable[IntID]);
TablePtr->Handler(TablePtr->CallBackRef);
IntrExit:
/*
* Write to the EOI register, we are all done here.
* Let this function return, the boot code will restore the stack.
*/
XScuGic_WriteReg(CfgPtr->CpuBaseAddress, XSCUGIC_EOI_OFFSET, IntID);
/*
* Return from the interrupt. Change security domains could happen
* here.
*/
}
原因如下:CPUID域,在软件中断时,必须要把触发CPUID写回。这也是当时找了N久无果,无意在国外一个论坛看到的,那个帖已经找不到了。