最近在尝试多核的IPC中断同步与通信功能,参考官方提供的demo程序:IPC_example_on_6678。做了部分调整与函数封装后具体实现如下:
中断配置函数,将ipc事件映射到内核中断hwi7
void ipc_config(void)
{
gpCGEM_regs->INTMUX1 = (CSL_GEM_IPC_LOCAL<<CSL_CGEM_INTMUX1_INTSEL7_SHIFT);
/* enable INT7 */
CPU_interrupt_enable((1<<7));
}
指定Core内核ipc中断触发函数
void core_ipc_enable(unsigned int coreIdx)
{
// Unlock Config
KICK0 = KICK0_UNLOCK;
KICK1 = KICK1_UNLOCK;
*(volatile unsigned int *) iIPCGRInfo[coreIdx] = coreIdx*16;
*(volatile unsigned int *) iIPCGRInfo[coreIdx] |= 1;
// lock Config
KICK0 = KICK_LOCK;
KICK1 = KICK_LOCK;
}
Ipc中断处理函数
void interrupt ipc_isr()
{
volatile uint32_t read_ipcgr;
uint32_t CoreNum;
CoreNum = DNUM;
read_ipcgr = *(volatile Uint32 *) iIPCGRInfo[CoreNum];
*(volatile uint32_t *) iIPCARInfo[CoreNum] = read_ipcgr; //clear the related source info
//gpCGEM_regs->EVTCLR[2] = 0x08000000;
gIpcFlag = 1;
}
在开发板上进行core0与core1的在线仿真测试,具体调用方式如下:
Core0:
core_ipc_enable(1);
while(1)
{
if(gIpcFlag)
{
gIpcFlag = 0;
core_ipc_enable(1);
}
}
Core1:
while(1)
{
if(gIpcFlag)
{
gIpcFlag = 0;
core_ipc_enable(0);
}
}
实际执行过程中发现(demo程序IPC_example_on_6678可正常循环执行):
Core0仅触发1次ipc中断;
Core1仅触发2次ipc中断;
有以下几个问题请教:
1 函数core_ipc_enable内有*(volatile unsigned int *) iIPCGRInfo[coreIdx] = coreIdx*16;,因此core0对应的info为0,是否合适在文档中没有找到明确描述(IPCGRx)中SRCS是否可以全部为0。
2 文档《TMS320C6678 Multicore Fixed and Floating-Point Digital Signal Processor》中对于寄存器IPC Generation Registers (IPCGRx)与IPC Acknowledgement Registers (IPCARx)都有以下描述:“Any master that has access to BOOTCFG module space can write to these registers.”。但是我注意到demo程序中仅在写IPC Generation Registers (IPCGRx)的时候进行了对应操作(KICK0 = KICK0_UNLOCK),而IPC Acknowledgement Registers (IPCARx)是直接进行写操作的。严格来时是否需要在函数ipc_isr内IPC Acknowledgement Registers (IPCARx)寄存器写操作也加上KICK0 = KICK0_UNLOCK操作?
3 文档《C66x CorePac User's Guide》中9.4.2 DSP Servicing of Interrupt Events关于中断处理函数中对于事件标志是否要清楚的描述感觉有点矛盾:
For the case where the DSP services single-event interrupts (where system events are specified directly in the Interrupt Selector), there is no need to read or clear the Event Flag (EVTFLAGx) registers in the Interrupt Controller.
这里指出当单一事件与中断向量一一映射时,没有必要对事件标志进行清除操作。
However, you must use event flags within an interrupt service routine or an exception service routine when servicing combined system events. These flags are used to determine the event(s) that initiated an interrupt or exception. In other words, the DSP’s interrupt flag register (or exception flag register) tell the DSP a combined event has occurred, then the service routine must use the event flag register to determine the exact cause(s).
这里指出当多个事件组合后与中断向量映射时,需要对事件标志进行清除操作。
It is also important to note that within the service routine, the appropriate event flag register bits must be cleared by software in order to receive a subsequent event. If the event flag(s) does not clear, then a new system event will not be recognized. The new system event cannot be recognized as a dropped interrupt. This is because the DSP dropped interrupt logic applies to the DSP interrupt input (not the interrupt controller event input). Since the events are combined in the Interrupt Controller, the DSP has no visibility here.
这里又一次强调了需要对事件状态进行清除。请问这里是接着上一段的进一步描述吗?强调在多事件组合与中断向量映射时需要清除当前处理的事件标志。还是我对于上述三段描述理解有偏差?
countryhotel:
1 函数core_ipc_enable内有*(volatile unsigned int *) iIPCGRInfo[coreIdx] = coreIdx*16;,因此core0对应的info为0,是否合适在文档中没有找到明确描述(IPCGRx)中SRCS是否可以全部为0。
昨晚测试了,SRCS可以为0,其数值不影响中断触发。
Core0仅触发1次ipc中断;Core1仅触发2次ipc中断;的现象原因已经定位:
在sysbios中进行硬件中断hwi静态配置后,第一次进入中断就同步清除IER中该中断对应的IPC使能标志,并在中断处理函数返回后没有重新对其置1。后来改用程序的动态HWI配置(参见文档Configuring Interrupts on Keystone Devices),恢复正常;
但是原问题中的2,3还需技术专家给予答疑。
skysteed:
回复 countryhotel:
我以前用例程试过没问题 例程用的是CSL
我改为非CSL 也是只进一次中断
呵呵
skysteed:
回复 countryhotel:
后来改用程序的动态HWI配置(参见文档Configuring Interrupts on Keystone Devices)
这个意思是 最后还用的是例程的CSL方式?
能否把你的程序发一份?研究下!邮箱:43854061@qq.com
user5267556:
回复 skysteed:
您好,请问您的demo是在哪儿下的呢,我在ti上没有找到IPC_example_on_6678这个例程
skysteed:
回复 user5267556:
留个邮箱 发过去
你哪里有没有mcbsp的例程
user5267556:
回复 skysteed:
没有这个例程欸,邮箱是13261635288@163.com太感谢了
user5267556:
回复 skysteed:
对了题主我刚才发表了一个问题,我想你可能知道答案,能不能麻烦去看一下呢~?网址在下面了e2echina.ti.com/…/446854