目录
一、C66x的两种中断事件
1. 98个Primary Event
2. 通过CIC映射到二级事件
二、中断配置的方法
1.CSL方法配置
a、configuring the CorePac’s INTC
b 、Configuring CIC
c、Example
2、sysbios 的中断配置
a、 创建HWI线程
b、事件联合
c、CpIntc
CorePac interrupt controller 允许124个中断映射到DSP核上,拥有事件如图:事件可以单独映射
到CPU上,也可以多个事件形成组合事件映射到CPU上。
同时,一个CPU核心有16个中断,4 -- 15位可屏蔽可配置中断。
在SYSBIOS下,使用HWI模块可以直接配置,硬件中断号查询中断手册即可。
不运行SYSBIOS,则需要对中断进行配置。
SYSBIOS 不支持CIC事件直接映射到核心中断上,所以要先进行CIC配置 将 system interrupt 映射
为 Host interrupt ,Host interrupt 到Event id是固定的,可以在手册中查询;接下来执行第一
步。
将Event ID63 映射到 CPU中断4
-
{ C
-
SL_IntcObj intcObj63p;
-
CSL_IntcGlobalEnableState state;
-
CSL_IntcContext context;
-
CSL_Status intStat;
-
CSL_IntcParam vectId;
-
context.numEvtEntries =
0;
-
context.eventhandlerRecord =
NULL;
-
CSL_intcInit(&context);
-
CSL_intcGlobalNmiEnable();
-
intStat =
CSL_intcGlobalEnable(&state);
-
/*注释部分为修改部分*/
-
// 中断号
-
vectId = CSL_INTC_VECTID_4;
-
//CSL_INTC_EVENTID_63 代表 Event ID63
-
hIntc63 =
CSL_intcOpen (&intcObj63, CSL_INTC_EVENTID_63, &vectId,
NULL);
-
//event63Handler 中断函数
-
EventRecord.handler = &event63Handler;
-
EventRecord.arg = hIntc63;
-
CSL_intcPlugEventHandler(hIntc63,&EventRecord);
-
CSL_intcHwControl(hIntc63,CSL_INTC_CMD_EVTENABLE,
NULL);
-
//关闭中断
-
CSL_IntcClose(hIntc63);
-
} /
-
/中断函数
-
oid event63Handler(CSL_IntcHandle hIntc)
-
{ .
-
. .
-
}
CSL_intcGlobalEnable() and CSL_intcGlobalNmiEnable() APIs
CSL_intcOpen(…) API 为中断映射,当映射成功,会保存事件到中断并且返回一个有效的句柄。
CSL_intcPlugEventHandler(…)API 绑定事件和中断函数
CSL_intcHwControl(…) API 使能事件
CSL_intcClose(…) API 解除分配,释放事件
-
/* Disable all host interrupts. */
-
CSL_CPINTC_disableAllHostInterrupt(hnd);
-
/* Configure no nesting support in the CPINTC Module. */
-
//KeyStone devices不支持中断抢断
-
CSL_CPINTC_setNestingMode (hnd, CPINTC_NO_NESTING);
-
/* We now map System Interrupt 0 - 3 to channel 3 */
-
CSL_CPINTC_mapSystemIntrToChannel (hnd,
0 ,
2);
-
CSL_CPINTC_mapSystemIntrToChannel (hnd,
1 ,
4);
-
CSL_CPINTC_mapSystemIntrToChannel (hnd,
2 ,
5);
-
CSL_CPINTC_mapSystemIntrToChannel (hnd,
3 ,
3);
-
/* Enable system interrupts 0 - 3 */
-
CSL_CPINTC_enableSysInterrupt (hnd,
0);
-
CSL_CPINTC_enableSysInterrupt (hnd,
1);
-
CSL_CPINTC_enableSysInterrupt (hnd,
2);
-
CSL_CPINTC_enableSysInterrupt (hnd,
3);
-
/* Enable Host interrupt 3 */
-
CSL_CPINTC_enableHostInterrupt (hnd,
3);
-
/* Enable all host interrupts also. */
-
CSL_CPINTC_enableAllHostInterrupt(hnd);
'pdk_C6678_x_x_x_xx\packages\ti\csl\example\cpintc' 可以了解更多CIC相关信息
01
-
/************************ --- 头文件 --- ************************/
-
#include
-
#include
-
#include
-
#include
#include
-
#include
-
#include
-
#include
-
/************************ --- 头文件 --- ************************/
-
-
/************************ --- INTC Initializations --- ************************/
-
CSL_IntcEventHandlerRecord hyplnkExampleEvtHdlrRecord[
6];
-
CSL_IntcContext hyplnkExampleIntcContext;
-
CSL_IntcHandle hyplnkExampleIntcHnd[
6];
-
#define hyplnk_EXAMPLE_COREPAC_VEC 4
-
#define hyplnk_EXAMPLE_COREPAC_INT_INPUT 0x15
-
/* Note that hyplnk_EXAMPLE_COREPAC_VEC = 4, hyplnk_EXAMPLE_COREPAC_INT_INPUT =
-
0x15, */
-
/* CSL_INTC_CMD_EVTCLEAR = 3, CSL_INTC_CMD_EVTENABLE = 0 */
-
//hyplnk_EXAMPLE_COREPAC_VEC = 4;映射到中断4上;
-
CSL_IntcParam vectId = hyplnk_EXAMPLE_COREPAC_VEC;
-
//hyplnk_EXAMPLE_COREPAC_INT_INPUT = 21;Event ID 为21
-
Int16 eventId = hyplnk_EXAMPLE_COREPAC_INT_INPUT;
-
CSL_IntcGlobalEnableState state;
-
/* INTC module initialization */
-
hyplnkExampleIntcContext.eventhandlerRecord = hyplnkExampleEvtHdlrRecord;
-
hyplnkExampleIntcContext.numEvtEntries =
2;
-
CSL_intcInit(&hyplnkExampleIntcContext);
-
/* Enable NMIs */
-
CSL_intcGlobalNmiEnable();
-
/* Enable global interrupts */
-
CSL_intcGlobalEnable(&state);
-
hyplnkExampleIntcHnd =
CSL_intcOpen (&hyplnkExampleIntcObj, eventId, &vectId,
-
NULL);
-
hyplnkExampleEvtHdlrRecord[
0].handler = hyplnkExampleIsr;
-
hyplnkExampleEvtHdlrRecord[
0].arg = (
void *)eventId;
-
CSL_intcPlugEventHandler(hyplnkExampleIntcHnd, hyplnkExampleEvtHdlrRecord);
-
/* Clear the event in case it is pending */
-
CSL_intcHwControl(hyplnkExampleIntcHnd, CSL_INTC_CMD_EVTCLEAR,
NULL);
-
/* Enable event */
-
CSL_intcHwControl(hyplnkExampleIntcHnd, CSL_INTC_CMD_EVTENABLE,
NULL);
-
/************************ --- INTC Initializations --- ************************/
-
/************************ --- CIC Initializations --- ************************/
-
#define hyplnk_EXAMPLE_INTC_OUTPUT 43
-
CSL_CPINTC_Handle hnd;
-
hnd =
CSL_CPINTC_open (
0);
-
/* Disable all host interrupts. */
-
CSL_CPINTC_disableAllHostInterrupt(hnd);
-
/* Configure no nesting support in the CPINTC Module */
-
CSL_CPINTC_setNestingMode (hnd, CPINTC_NO_NESTING);
-
/* Clear Hyperlink system interrupt number 111 */
-
//CSL_INTC0_VUSR_INT_O 是system Interrupt id
-
CSL_CPINTC_clearSysInterrupt (hnd, CSL_INTC0_VUSR_INT_O);
-
/* Enable Hyperlink system interrupt number 111 on CIC0 */
-
CSL_CPINTC_enableSysInterrupt (hnd, CSL_INTC0_VUSR_INT_O);
-
/* Map System Interrupt to Channel. */注意:
6678 中host interrupt 与 channel 为一一对应的关系 。
-
02
-
/* Note that hyplnk_EXAMPLE_INTC_OUTPUT = 32 + (11 * CoreNumber) = 43 for
-
Core0*/
-
CSL_CPINTC_mapSystemIntrToChannel (hnd, CSL_INTC0_VUSR_INT_O,
-
hyplnk_EXAMPLE_INTC_OUTPUT);
-
/* Enable the Host Interrupt */
-
CSL_CPINTC_enableHostInterrupt (hnd, hyplnk_EXAMPLE_INTC_OUTPUT);
-
CSL_CPINTC_enableAllHostInterrupt(hnd);
-
-
-
/************************ --- CIC Initializations --- ************************/
注意: 6678 中host interrupt 与 channel 为一一对应的关系 。
02
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#define QPEND_IDX 5
-
#define FIRST_QPEND_QUEUE 662
-
#define FIRST_QPEND_CIC0_OUT_EVENT 56
-
/* Function declarations */
-
void init_interrupt_controllers();
-
void setup_qpend_interrupt(Uint16 qnum,Uint16 CorePac_event);
-
/* Global variable declarations */
-
CSL_IntcContext Intcontext;
//For CorePac INTC
-
CSL_IntcObj intcQmss;
//For CorePac INTC
-
CSL_IntcHandle hIntcQmss[
6];
//For CorePac INTC
-
CSL_IntcEventHandlerRecord Record[
6];
//For CorePac INTC
-
CSL_CPINTC_Handle cphnd;
//For chip-level CIC
-
Int16 sys_event;
-
Int16 host_event;
-
void main(void)
-
{ .
-
.....
-
/* Init Interrupt Controllers including chip-level CIC and CorePac INTC.*/
-
init_interrupt_controllers();
-
/* Setup ISR for QMSS que pend queue */
-
/* Queue pending signals are from 662 to 671 to CIC0 */
-
setup_qpend_interrupt(FIRST_QPEND_QUEUE, FIRST_QPEND_CIC0_OUT_EVENT);
-
......
-
} /
-
* Perform one-time initialization of chip-level
and CorePac
-
* interrupt controllers.
-
*/
-
void init_interrupt_controllers()
-
{ C
-
SL_IntcGlobalEnableState state;
-
/* Setup the global Interrupt */
-
Intcontext.numEvtEntries =
6;
-
Intcontext.eventhandlerRecord = Record;
-
CSL_intcInit(&Intcontext);
-
/* Enable NMIs */
-
CSL_intcGlobalNmiEnable();
-
/* Enable Global Interrupts */
-
CSL_intcGlobalEnable(&state);
-
/* Initialize the chip level CIC CSL handle. */
-
cphnd =
CSL_CPINTC_open(
0);
-
if (cphnd ==
0)
-
{
p
-
rintf
("Cannot initialize CPINTC\n");
-
return;
-
} } /
-
* This function connects a QMSS Queue Pend interrupt to a core event*/
-
void setup_qpend_interrupt(Uint16 qnum, Uint16 CorePac_event)
-
{ I
-
nt16 chan;
-
CSL_IntcParam vectId1;
-
/* These are event input index of CIC0 for Que_pend events from Que Manager */
-
Uint8 events[
10] = {
134,
135,
136,
137,
138,
139,
140,
141,
142,
175};
-
/* Step 1: Translate the queue number into the CIC input event. */
-
/* qnum is expected to be 662..671 */
-
chan = (qnum - FIRST_QPEND_QUEUE);
-
if ((chan <
0) || (chan >
10))
-
{
p
-
rintf
("Invalid Queue Pend queue %d\n", qnum);
-
return;
-
} s
-
ys_event = events[chan];
-
/* Step 2: Map the CIC input event to the CorePac input event
-
* (which are 56 to 63). */
-
CSL_CPINTC_disableAllHostInterrupt(cphnd);
-
CSL_CPINTC_setNestingMode(cphnd, CPINTC_NO_NESTING);
-
/* Map the input system event to a channel. Note, the
-
* mapping from channel to Host event is fixed.*/
-
CSL_CPINTC_mapSystemIntrToChannel(cphnd, sys_event,
0);
-
/* Enable the system interrupt */
-
CSL_CPINTC_enableSysInterrupt(cphnd, sys_event);
-
host_event = CorePac_event - FIRST_QPEND_CIC0_OUT_EVENT;
-
/* Enable the channel (output). */
-
CSL_CPINTC_enableHostInterrupt(cphnd, host_event);
-
/* Enable all host interrupts. */
-
CSL_CPINTC_enableAllHostInterrupt(cphnd);
-
/* Step 3: Hook an ISR to the CorePac input event. */
-
vectId1 = CSL_INTC_VECTID_12;
//4 through 15 are available
-
hIntcQmss[QPEND_IDX] =
CSL_intcOpen(&intcQmss,
-
CorePac_event,
// selected event ID
-
&vectId1,
-
NULL);
-
/* Hook the ISR */
-
Record[QPEND_IDX].handler = (CSL_IntcEventHandler)&QPEND_USER_DEFINED_ISR;
-
Record[QPEND_IDX].arg = (
void *)CorePac_event;
-
CSL_intcPlugEventHandler(hIntcQmss[QPEND_IDX],&(Record[QPEND_IDX]));
-
/* Clear the Interrupt */
-
CSL_intcHwControl(hIntcQmss[QPEND_IDX],CSL_INTC_CMD_EVTCLEAR,
NULL);
-
/* Enable the Event & the interrupt */
-
CSL_intcHwControl(hIntcQmss[QPEND_IDX],CSL_INTC_CMD_EVTENABLE,
NULL);
-
return;
-
} /
-
* This function ISR
for QPEND interrupts. Note the interrupt is
-
routed through chip-level CIC */
-
void QPEND_USER_DEFINED_ISR (Uint32 eventId)
-
{ /
-
* Disable the CIC0 host interrupt output */
-
CSL_CPINTC_disableHostInterrupt(cphnd, host_event);
-
/* Clear the CIC0 system interrupt */
-
CSL_CPINTC_clearSysInterrupt(cphnd, sys_event);
-
......
-
(service the interrupt at source)
-
(clear the source interrupt flag is typically the first step in the service)
-
/* Clear the CorePac interrupt */
-
CSL_intcHwControl(hIntcQmss[QPEND_IDX],CSL_INTC_CMD_EVTCLEAR,
NULL);
-
/* Enable the CIC0 host interrupt output */
-
CSL_CPINTC_enableHostInterrupt(cphnd, host_event);
-
/* Optional: Close the handle if we are remapping with each call. */
-
CSL_intcClose(&intcQmss);
-
}
(详细方法参考Sys BIOS教程,不赘述)
Example event ID 10 is mapped to interrupt vector 5
-
#
-
include
-
#include
-
Hwi_Handle myHwi;
-
Int main(Int argc, char* argv[])
-
{ H
-
wi_Params hwiParams;
-
Error_Block eb;
-
Hwi_Params_init(&hwiParams);
-
Error_init(&eb);
-
// set the argument you want passed to your ISR function
-
hwiParams.arg =
1;
-
// set the event id of the peripheral assigned to this interrupt
-
hwiParams.eventId =
10;
-
// don't allow this interrupt to nest itself
-
hwiParams.maskSetting = Hwi_MaskingOption_SELF;
-
//
-
// Configure interrupt 5 to invoke "myIsr".
-
// Automatically enables interrupt 5 by default
-
// set params.enableInt = FALSE if you want to control
-
// when the interrupt is enabled using Hwi_enableInterrupt()
-
//
-
myHwi =
Hwi_create(
5, myIsr, &hwiParams, &eb);
-
if (
Error_check(&eb)) {
-
// handle the error
-
} }
-
void myIsr(UArg arg)
-
{ /
-
/
this runs when interrupt #
5 goes offc
-
}
EventCombiner支持最高32个事件联合成一个事件,EventCombiner的输出可以连接到映射到任意一个可配置中断上,最高支持 32 * 4 个事件的组合。
支持对每个事件进行使能控制,中断函数。
01
-
var
EventCombiner = xdc.
useModule(
'ti.sysbios.family.c64p.EventCombiner');
-
EventCombiner.
events[
15].
unmask =
true;
-
EventCombiner.
events[
15].
fxn =
'&event15Fxn';
-
EventCombiner.
events[
15].
arg =
0x15;
-
EventCombiner.
events[
16].
unmask =
true;
-
EventCombiner.
events[
16].
fxn =
'&event16Fxn';
-
EventCombiner.
events[
16].
arg =
0x16
02
-
eventId =
4;
-
EventCombiner_dispatchPlug(eventId, &event4Fxn, arg,
TRUE);
-
EventCombiner_dispatchPlug(eventId +
1, &event5Fxn, arg,
TRUE);
-
Hwi_Params_init(¶ms);
-
params.
arg = (eventId /
32);
-
params.
eventId = (eventId /
32);
-
params.
enableInt =
TRUE;
-
intVector =
8;
-
Hwi_create(intVector, &
EventCombiner_dispatch, ¶ms,
NULL);
CpIntc管理CIC,CIC不支持中断嵌套。
开启或关闭 system and host interrupts ,
system interrupts到host interrupts的映射(CIC)
host interrupts 到HWIs ,EventCombiner
There is a dispatch function for handling GEM hardware interrupts triggered by a system
interrupt. The Global Enable Register is enabled by default in the module startup function.
CpIntc APIs is 'ti.sysbios.family.c66.tci66xx.CpIntc'
Example
01
-
// Map system interrupt 15 to host interrupt 8
-
CpIntc_mapSysIntToHostInt(
0,
15,
8);
-
// Plug the function for event #15
-
CpIntc_dispatchPlug(
15, &event15Fxn,
15, TRUE);
-
// Enable host interrupt #8
-
CpIntc_enableHostInt(
0,
8);
// enable host interrupt 8
02
-
/* Map the System Interrupt i.e. the Interrupt Destination 0 interrupt to the DIO
-
ISR Handler. */
-
CpIntc_dispatchPlug(CSL_INTC0_INTDST0, (CpIntc_FuncPtr)myDioTxCompletionIsr,
-
(UArg)hSrioDrv, TRUE);
-
/* The configuration is for CPINTC0. We map system interrupt 112 to Host
-
Interrupt 8. */
-
CpIntc_mapSysIntToHostInt(
0, CSL_INTC0_INTDST0,
8);
-
/* Enable the Host Interrupt. */
-
CpIntc_enableHostInt(
0,
8);
-
/* Enable the System Interrupt */
-
CpIntc_enableSysInt(
0, CSL_INTC0_INTDST0);
-
/* Get the event id associated with the host interrupt. */
-
eventId =
CpIntc_getEventId(
8);
-
Hwi_Params_init(¶ms);
-
/* Host interrupt value*/
-
params.arg =
8;
-
/* Event id for your host interrupt */
-
params.eventId = eventId;
-
/* Enable the Hwi */params.enableInt = TRUE;
-
/* This plugs the interrupt vector 4 and the ISR function. */
-
/* When using CpIntc, you must plug the Hwi fxn with CpIntc_dispatch */
-
/* so it knows how to process the CpIntc interrupts.*/
-
Hwi_create(
4, &CpIntc_dispatch, ¶ms,
NULL);