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是固定的,可以在手册中查询;接下来执行第一
步。
C66X中断整理 6678中断配置(含例程)_第1张图片

C66X中断整理 6678中断配置(含例程)_第2张图片

二、中断配置的方法


1.CSL方法配置


a、configuring the CorePac’s INTC

将Event ID63 映射到 CPU中断4


   
   
     
     
     
     
  1. { C
  2. SL_IntcObj intcObj63p;
  3. CSL_IntcGlobalEnableState state;
  4. CSL_IntcContext context;
  5. CSL_Status intStat;
  6. CSL_IntcParam vectId;
  7. context.numEvtEntries = 0;
  8. context.eventhandlerRecord = NULL;
  9. CSL_intcInit(&context);
  10. CSL_intcGlobalNmiEnable();
  11. intStat = CSL_intcGlobalEnable(&state);
  12. /*注释部分为修改部分*/
  13. // 中断号
  14. vectId = CSL_INTC_VECTID_4;
  15. //CSL_INTC_EVENTID_63 代表 Event ID63
  16. hIntc63 = CSL_intcOpen (&intcObj63, CSL_INTC_EVENTID_63, &vectId, NULL);
  17. //event63Handler 中断函数
  18. EventRecord.handler = &event63Handler;
  19. EventRecord.arg = hIntc63;
  20. CSL_intcPlugEventHandler(hIntc63,&EventRecord);
  21. CSL_intcHwControl(hIntc63,CSL_INTC_CMD_EVTENABLE, NULL);
  22. //关闭中断
  23. CSL_IntcClose(hIntc63);
  24. } /
  25. /中断函数
  26. oid event63Handler(CSL_IntcHandle hIntc)
  27. { .
  28. . .
  29. }


CSL_intcGlobalEnable() and CSL_intcGlobalNmiEnable() APIs
CSL_intcOpen(…) API 为中断映射,当映射成功,会保存事件到中断并且返回一个有效的句柄。
CSL_intcPlugEventHandler(…)API 绑定事件和中断函数
CSL_intcHwControl(…) API 使能事件
CSL_intcClose(…) API 解除分配,释放事件
 

b 、Configuring CIC
 


   
   
     
     
     
     
  1. /* Disable all host interrupts. */
  2. CSL_CPINTC_disableAllHostInterrupt(hnd);
  3. /* Configure no nesting support in the CPINTC Module. */
  4. //KeyStone devices不支持中断抢断
  5. CSL_CPINTC_setNestingMode (hnd, CPINTC_NO_NESTING);
  6. /* We now map System Interrupt 0 - 3 to channel 3 */
  7. CSL_CPINTC_mapSystemIntrToChannel (hnd, 0 , 2);
  8. CSL_CPINTC_mapSystemIntrToChannel (hnd, 1 , 4);
  9. CSL_CPINTC_mapSystemIntrToChannel (hnd, 2 , 5);
  10. CSL_CPINTC_mapSystemIntrToChannel (hnd, 3 , 3);
  11. /* Enable system interrupts 0 - 3 */
  12. CSL_CPINTC_enableSysInterrupt (hnd, 0);
  13. CSL_CPINTC_enableSysInterrupt (hnd, 1);
  14. CSL_CPINTC_enableSysInterrupt (hnd, 2);
  15. CSL_CPINTC_enableSysInterrupt (hnd, 3);
  16. /* Enable Host interrupt 3 */
  17. CSL_CPINTC_enableHostInterrupt (hnd, 3);
  18. /* Enable all host interrupts also. */
  19. CSL_CPINTC_enableAllHostInterrupt(hnd);

 'pdk_C6678_x_x_x_xx\packages\ti\csl\example\cpintc' 可以了解更多CIC相关信息

c、Example

01


   
   
     
     
     
     
  1. /************************ --- 头文件 --- ************************/
  2. #include
  3. #include
  4. #include
  5. #include #include
  6. #include
  7. #include
  8. #include
  9. /************************ --- 头文件 --- ************************/
  10. /************************ --- INTC Initializations --- ************************/
  11. CSL_IntcEventHandlerRecord hyplnkExampleEvtHdlrRecord[ 6];
  12. CSL_IntcContext hyplnkExampleIntcContext;
  13. CSL_IntcHandle hyplnkExampleIntcHnd[ 6];
  14. #define hyplnk_EXAMPLE_COREPAC_VEC 4
  15. #define hyplnk_EXAMPLE_COREPAC_INT_INPUT 0x15
  16. /* Note that hyplnk_EXAMPLE_COREPAC_VEC = 4, hyplnk_EXAMPLE_COREPAC_INT_INPUT =
  17. 0x15, */
  18. /* CSL_INTC_CMD_EVTCLEAR = 3, CSL_INTC_CMD_EVTENABLE = 0 */
  19. //hyplnk_EXAMPLE_COREPAC_VEC = 4;映射到中断4上;
  20. CSL_IntcParam vectId = hyplnk_EXAMPLE_COREPAC_VEC;
  21. //hyplnk_EXAMPLE_COREPAC_INT_INPUT = 21;Event ID 为21
  22. Int16 eventId = hyplnk_EXAMPLE_COREPAC_INT_INPUT;
  23. CSL_IntcGlobalEnableState state;
  24. /* INTC module initialization */
  25. hyplnkExampleIntcContext.eventhandlerRecord = hyplnkExampleEvtHdlrRecord;
  26. hyplnkExampleIntcContext.numEvtEntries = 2;
  27. CSL_intcInit(&hyplnkExampleIntcContext);
  28. /* Enable NMIs */
  29. CSL_intcGlobalNmiEnable();
  30. /* Enable global interrupts */
  31. CSL_intcGlobalEnable(&state);
  32. hyplnkExampleIntcHnd = CSL_intcOpen (&hyplnkExampleIntcObj, eventId, &vectId,
  33. NULL);
  34. hyplnkExampleEvtHdlrRecord[ 0].handler = hyplnkExampleIsr;
  35. hyplnkExampleEvtHdlrRecord[ 0].arg = ( void *)eventId;
  36. CSL_intcPlugEventHandler(hyplnkExampleIntcHnd, hyplnkExampleEvtHdlrRecord);
  37. /* Clear the event in case it is pending */
  38. CSL_intcHwControl(hyplnkExampleIntcHnd, CSL_INTC_CMD_EVTCLEAR, NULL);
  39. /* Enable event */
  40. CSL_intcHwControl(hyplnkExampleIntcHnd, CSL_INTC_CMD_EVTENABLE, NULL);
  41. /************************ --- INTC Initializations --- ************************/
  42. /************************ --- CIC Initializations --- ************************/
  43. #define hyplnk_EXAMPLE_INTC_OUTPUT 43
  44. CSL_CPINTC_Handle hnd;
  45. hnd = CSL_CPINTC_open ( 0);
  46. /* Disable all host interrupts. */
  47. CSL_CPINTC_disableAllHostInterrupt(hnd);
  48. /* Configure no nesting support in the CPINTC Module */
  49. CSL_CPINTC_setNestingMode (hnd, CPINTC_NO_NESTING);
  50. /* Clear Hyperlink system interrupt number 111 */
  51. //CSL_INTC0_VUSR_INT_O 是system Interrupt id
  52. CSL_CPINTC_clearSysInterrupt (hnd, CSL_INTC0_VUSR_INT_O);
  53. /* Enable Hyperlink system interrupt number 111 on CIC0 */
  54. CSL_CPINTC_enableSysInterrupt (hnd, CSL_INTC0_VUSR_INT_O);
  55. /* Map System Interrupt to Channel. */注意: 6678 中host interrupt 与 channel 为一一对应的关系 。
  56. 02
  57. /* Note that hyplnk_EXAMPLE_INTC_OUTPUT = 32 + (11 * CoreNumber) = 43 for
  58. Core0*/
  59. CSL_CPINTC_mapSystemIntrToChannel (hnd, CSL_INTC0_VUSR_INT_O,
  60. hyplnk_EXAMPLE_INTC_OUTPUT);
  61. /* Enable the Host Interrupt */
  62. CSL_CPINTC_enableHostInterrupt (hnd, hyplnk_EXAMPLE_INTC_OUTPUT);
  63. CSL_CPINTC_enableAllHostInterrupt(hnd);
  64. /************************ --- CIC Initializations --- ************************/

注意: 6678 中host interrupt 与 channel 为一一对应的关系 。

02


   
   
     
     
     
     
  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include
  7. #include
  8. #include
  9. #define QPEND_IDX 5
  10. #define FIRST_QPEND_QUEUE 662
  11. #define FIRST_QPEND_CIC0_OUT_EVENT 56
  12. /* Function declarations */
  13. void init_interrupt_controllers();
  14. void setup_qpend_interrupt(Uint16 qnum,Uint16 CorePac_event);
  15. /* Global variable declarations */
  16. CSL_IntcContext Intcontext; //For CorePac INTC
  17. CSL_IntcObj intcQmss; //For CorePac INTC
  18. CSL_IntcHandle hIntcQmss[ 6]; //For CorePac INTC
  19. CSL_IntcEventHandlerRecord Record[ 6]; //For CorePac INTC
  20. CSL_CPINTC_Handle cphnd; //For chip-level CIC
  21. Int16 sys_event;
  22. Int16 host_event;
  23. void main(void)
  24. { .
  25. .....
  26. /* Init Interrupt Controllers including chip-level CIC and CorePac INTC.*/
  27. init_interrupt_controllers();
  28. /* Setup ISR for QMSS que pend queue */
  29. /* Queue pending signals are from 662 to 671 to CIC0 */
  30. setup_qpend_interrupt(FIRST_QPEND_QUEUE, FIRST_QPEND_CIC0_OUT_EVENT);
  31. ......
  32. } /
  33. * Perform one-time initialization of chip-level and CorePac
  34. * interrupt controllers.
  35. */
  36. void init_interrupt_controllers()
  37. { C
  38. SL_IntcGlobalEnableState state;
  39. /* Setup the global Interrupt */
  40. Intcontext.numEvtEntries = 6;
  41. Intcontext.eventhandlerRecord = Record;
  42. CSL_intcInit(&Intcontext);
  43. /* Enable NMIs */
  44. CSL_intcGlobalNmiEnable();
  45. /* Enable Global Interrupts */
  46. CSL_intcGlobalEnable(&state);
  47. /* Initialize the chip level CIC CSL handle. */
  48. cphnd = CSL_CPINTC_open( 0);
  49. if (cphnd == 0)
  50. { p
  51. rintf ("Cannot initialize CPINTC\n");
  52. return;
  53. } } /
  54. * This function connects a QMSS Queue Pend interrupt to a core event*/
  55. void setup_qpend_interrupt(Uint16 qnum, Uint16 CorePac_event)
  56. { I
  57. nt16 chan;
  58. CSL_IntcParam vectId1;
  59. /* These are event input index of CIC0 for Que_pend events from Que Manager */
  60. Uint8 events[ 10] = { 134, 135, 136, 137, 138, 139, 140, 141, 142, 175};
  61. /* Step 1: Translate the queue number into the CIC input event. */
  62. /* qnum is expected to be 662..671 */
  63. chan = (qnum - FIRST_QPEND_QUEUE);
  64. if ((chan < 0) || (chan > 10))
  65. { p
  66. rintf ("Invalid Queue Pend queue %d\n", qnum);
  67. return;
  68. } s
  69. ys_event = events[chan];
  70. /* Step 2: Map the CIC input event to the CorePac input event
  71. * (which are 56 to 63). */
  72. CSL_CPINTC_disableAllHostInterrupt(cphnd);
  73. CSL_CPINTC_setNestingMode(cphnd, CPINTC_NO_NESTING);
  74. /* Map the input system event to a channel. Note, the
  75. * mapping from channel to Host event is fixed.*/
  76. CSL_CPINTC_mapSystemIntrToChannel(cphnd, sys_event, 0);
  77. /* Enable the system interrupt */
  78. CSL_CPINTC_enableSysInterrupt(cphnd, sys_event);
  79. host_event = CorePac_event - FIRST_QPEND_CIC0_OUT_EVENT;
  80. /* Enable the channel (output). */
  81. CSL_CPINTC_enableHostInterrupt(cphnd, host_event);
  82. /* Enable all host interrupts. */
  83. CSL_CPINTC_enableAllHostInterrupt(cphnd);
  84. /* Step 3: Hook an ISR to the CorePac input event. */
  85. vectId1 = CSL_INTC_VECTID_12; //4 through 15 are available
  86. hIntcQmss[QPEND_IDX] = CSL_intcOpen(&intcQmss,
  87. CorePac_event, // selected event ID
  88. &vectId1,
  89. NULL);
  90. /* Hook the ISR */
  91. Record[QPEND_IDX].handler = (CSL_IntcEventHandler)&QPEND_USER_DEFINED_ISR;
  92. Record[QPEND_IDX].arg = ( void *)CorePac_event;
  93. CSL_intcPlugEventHandler(hIntcQmss[QPEND_IDX],&(Record[QPEND_IDX]));
  94. /* Clear the Interrupt */
  95. CSL_intcHwControl(hIntcQmss[QPEND_IDX],CSL_INTC_CMD_EVTCLEAR, NULL);
  96. /* Enable the Event & the interrupt */
  97. CSL_intcHwControl(hIntcQmss[QPEND_IDX],CSL_INTC_CMD_EVTENABLE, NULL);
  98. return;
  99. } /
  100. * This function ISR for QPEND interrupts. Note the interrupt is
  101. routed through chip-level CIC */
  102. void QPEND_USER_DEFINED_ISR (Uint32 eventId)
  103. { /
  104. * Disable the CIC0 host interrupt output */
  105. CSL_CPINTC_disableHostInterrupt(cphnd, host_event);
  106. /* Clear the CIC0 system interrupt */
  107. CSL_CPINTC_clearSysInterrupt(cphnd, sys_event);
  108. ......
  109. (service the interrupt at source)
  110. (clear the source interrupt flag is typically the first step in the service)
  111. /* Clear the CorePac interrupt */
  112. CSL_intcHwControl(hIntcQmss[QPEND_IDX],CSL_INTC_CMD_EVTCLEAR, NULL);
  113. /* Enable the CIC0 host interrupt output */
  114. CSL_CPINTC_enableHostInterrupt(cphnd, host_event);
  115. /* Optional: Close the handle if we are remapping with each call. */
  116. CSL_intcClose(&intcQmss);
  117. }

2、sysbios 的中断配置
 

a、 创建HWI线程


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

Example event ID 10 is mapped to interrupt vector 5
 


   
   
     
     
     
     
  1. #
  2. include
  3. #include
  4. Hwi_Handle myHwi;
  5. Int main(Int argc, char* argv[])
  6. { H
  7. wi_Params hwiParams;
  8. Error_Block eb;
  9. Hwi_Params_init(&hwiParams);
  10. Error_init(&eb);
  11. // set the argument you want passed to your ISR function
  12. hwiParams.arg = 1;
  13. // set the event id of the peripheral assigned to this interrupt
  14. hwiParams.eventId = 10;
  15. // don't allow this interrupt to nest itself
  16. hwiParams.maskSetting = Hwi_MaskingOption_SELF;
  17. //
  18. // Configure interrupt 5 to invoke "myIsr".
  19. // Automatically enables interrupt 5 by default
  20. // set params.enableInt = FALSE if you want to control
  21. // when the interrupt is enabled using Hwi_enableInterrupt()
  22. //
  23. myHwi = Hwi_create( 5, myIsr, &hwiParams, &eb);
  24. if ( Error_check(&eb)) {
  25. // handle the error
  26. } }
  27. void myIsr(UArg arg)
  28. { /
  29. / this runs when interrupt # 5 goes offc
  30. }

b、事件联合


EventCombiner支持最高32个事件联合成一个事件,EventCombiner的输出可以连接到映射到任意一个可配置中断上,最高支持 32 * 4 个事件的组合。
支持对每个事件进行使能控制,中断函数。

C66X中断整理 6678中断配置(含例程)_第3张图片

01 


   
   
     
     
     
     
  1. var EventCombiner = xdc. useModule( 'ti.sysbios.family.c64p.EventCombiner');
  2. EventCombiner. events[ 15]. unmask = true;
  3. EventCombiner. events[ 15]. fxn = '&event15Fxn';
  4. EventCombiner. events[ 15]. arg = 0x15;
  5. EventCombiner. events[ 16]. unmask = true;
  6. EventCombiner. events[ 16]. fxn = '&event16Fxn';
  7. EventCombiner. events[ 16]. arg = 0x16

 02


   
   
     
     
     
     
  1. eventId = 4;
  2. EventCombiner_dispatchPlug(eventId, &event4Fxn, arg, TRUE);
  3. EventCombiner_dispatchPlug(eventId + 1, &event5Fxn, arg, TRUE);
  4. Hwi_Params_init(¶ms);
  5. params. arg = (eventId / 32);
  6. params. eventId = (eventId / 32);
  7. params. enableInt = TRUE;
  8. intVector = 8;
  9. Hwi_create(intVector, & EventCombiner_dispatch, ¶ms, 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


   
   
     
     
     
     
  1. // Map system interrupt 15 to host interrupt 8
  2. CpIntc_mapSysIntToHostInt( 0, 15, 8);
  3. // Plug the function for event #15
  4. CpIntc_dispatchPlug( 15, &event15Fxn, 15, TRUE);
  5. // Enable host interrupt #8
  6. CpIntc_enableHostInt( 0, 8); // enable host interrupt 8

 02


   
   
     
     
     
     
  1. /* Map the System Interrupt i.e. the Interrupt Destination 0 interrupt to the DIO
  2. ISR Handler. */
  3. CpIntc_dispatchPlug(CSL_INTC0_INTDST0, (CpIntc_FuncPtr)myDioTxCompletionIsr,
  4. (UArg)hSrioDrv, TRUE);
  5. /* The configuration is for CPINTC0. We map system interrupt 112 to Host
  6. Interrupt 8. */
  7. CpIntc_mapSysIntToHostInt( 0, CSL_INTC0_INTDST0, 8);
  8. /* Enable the Host Interrupt. */
  9. CpIntc_enableHostInt( 0, 8);
  10. /* Enable the System Interrupt */
  11. CpIntc_enableSysInt( 0, CSL_INTC0_INTDST0);
  12. /* Get the event id associated with the host interrupt. */
  13. eventId = CpIntc_getEventId( 8);
  14. Hwi_Params_init(¶ms);
  15. /* Host interrupt value*/
  16. params.arg = 8;
  17. /* Event id for your host interrupt */
  18. params.eventId = eventId;
  19. /* Enable the Hwi */params.enableInt = TRUE;
  20. /* This plugs the interrupt vector 4 and the ISR function. */
  21. /* When using CpIntc, you must plug the Hwi fxn with CpIntc_dispatch */
  22. /* so it knows how to process the CpIntc interrupts.*/
  23. Hwi_create( 4, &CpIntc_dispatch, ¶ms, NULL);

`在这里插入代码片`

你可能感兴趣的:(dsp开发)