C66X中断整理 6678中断配置(含例程)

目录

一、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


一、C66x的两种中断事件

CorePac interrupt controller 允许124个中断映射到DSP核上,拥有事件如图:事件可以单独映射
到CPU上,也可以多个事件形成组合事件映射到CPU上。
同时,一个CPU核心有16个中断,4 -- 15位可屏蔽可配置中断。

1. 98个Primary Event

在SYSBIOS下,使用HWI模块可以直接配置,硬件中断号查询中断手册即可。
不运行SYSBIOS,则需要对中断进行配置。


2. 通过CIC映射到二级事件

SYSBIOS 不支持CIC事件直接映射到核心中断上,所以要先进行CIC配置 将 system interrupt 映射
为 Host interrupt ,Host interrupt 到Event id是固定的,可以在手册中查询;接下来执行第一
步。

二、中断配置的方法


1.CSL方法配置


a、configuring the CorePac’s INTC

将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 解除分配,释放事件
 

b 、Configuring CIC
 

/* 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相关信息

c、Example

01

/************************ --- 头文件 --- ************************/
#include <stdio.h>
#include <ti/csl/csl.h>
#include <ti/csl/tistdtypes.h>
#include <ti/csl/csl_error.h>#include <ti/csl/csl_intc.h>
#include <ti/csl/csl_cpIntcAux.h>
#include <ti/csl/csl_chip.h>
#include <ti/csl/soc.h>
/************************ --- 头文件 --- ************************/

/************************ --- 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 <stdio.h>
#include <ti/csl/csl.h>
#include <ti/csl/tistdtypes.h>
#include <ti/csl/csl_error.h>
#include <ti/csl/csl_intc.h>
#include <ti/csl/csl_cpIntcAux.h>
#include <ti/csl/csl_chip.h>
#include <ti/csl/soc.h>
#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);
}

2、sysbios 的中断配置
 

a、 创建HWI线程


(详细方法参考Sys BIOS教程,不赘述)

Example event ID 10 is mapped to interrupt vector 5
 

#
include <xdc/runtime/Error.h>
#include <ti/sysbios/hal/Hwi.h>
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
}

b、事件联合


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(&params);
params.arg = (eventId / 32);
params.eventId = (eventId / 32);
params.enableInt = TRUE;
intVector = 8;
Hwi_create(intVector, &EventCombiner_dispatch, &params, NULL);

c、CpIntc

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(&params);
/* 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, &params, NULL);

  • 4
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C66x是德州仪器(Texas Instruments)推出的一种高性能的数字信号处理器(DSP)系列,用于嵌入式系统中的实时信号处理应用。而bootload则是指在系统启动时加载和运行操作系统或应用程序的过程。 C66x bootload是指C66x DSP芯片的启动加载过程。在开机或重启时,C66x DSP芯片需要加载引导程序(bootloader)来初始化硬件设备、设置存储器和加载操作系统或应用程序。 C66x DSP芯片的bootload过程通常分为以下几个步骤: 1. 引导加载:C66x DSP芯片通过引导ROM中的引导加载程序,从外部存储器(如闪存或SD卡)中加载引导程序到DSP内部的存储器。 2. 硬件初始化:引导程序首先会初始化DSP芯片的外设和内存控制器,包括设置时钟、中断控制器、存储器映射等,为后续的操作系统或应用程序做准备。 3. 操作系统加载:引导程序根据配置文件或固定地址,从外部存储器中加载操作系统镜像或启动文件到DSP内存中,为后续的操作系统启动做准备。 4. 启动操作系统:引导程序最后会将控制权转交给操作系统,使其开始运行。操作系统可以是实时操作系统(RTOS)或其他适用于C66x DSP芯片的操作系统C66x bootload的目的是确保硬件设备正确初始化,并提供一个加载操作系统或应用程序的框架。通过可靠的引导加载过程,C66x DSP芯片可以在启动时完成必要的准备工作,并成功启动所需的软件,实现实时信号处理应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值