TMS320C6678 多核学习 中断分析 实例+解析

  • TMS320C6678
    • 了解c66x内核
      • C66x corepac的位置
      • 内部架构
    • 中断
      • 事件
      • 中断控制器
    • 中断例程
      • 环境
      • 预期结果
      • 运行结果
      • 分析

TMS320C6678

了解c66x内核

C66x corepac的位置

内部架构


可以看到66x corepac的组成模块

  • 一.首当其冲就是C66x DSP,这块的知识可以了解一下C66x DSP的结构图

    ========================= 66x dsp结构图==============================
    1).两组寄存器文件组(A和B)
    2)…L,.S,.M,.D功能单元
    3).两个写入内存的数据通路 ST
    4).两个数据地址通路DA
    5).两个内存转载数据的数据通路LD
    6).寄存器交叉通道1X,2X
  • 二.L1程序存储器控制器 (提供dsp与l1p内存之间的存储通道)L1 数据存储器控制器 (提供DSP与L1D内存的接口)
  • 三.L2 存储器控制器
  • 四.DMA (进行内部与外部数据的迁移)
  • 五.EMC(外部内存控制器)提供与与其他设备的桥接,CFG(访问所有映射在memory的寄存器不能访问dsp或corepac的内部控制器)和sdma 与其他核之间的数据传输
  • 六.XMC (扩展存储器控制器)与MSMC的管理
  • 七.BWM (带宽管理)
  • 八.中断控制器
  • 九.存储器保护架构
  • 十.下电控制器

这就是CorePac的组成

中断

事件

在文档中关于中断是这样描述的

大意就是C6678设备上的CPU中断是通过中断控制来控制的也就是所谓的INTC(上面的corepac可以看到)。中断控制器允许将最多128个系统事件编程为12个CPU中断输入(CPUINT4-CPUINT15)、也就是每个核中的中断控制器最对处理128个系统事件
.
什么是系统事件,就是核上产生的事件和片级产生的事件。这128个系统事件由内部生成的事件(在CorePac内)和芯片级事件组成。

额外的系统事件被路由到每个 C66x CorePac,以提供不需要作为 CPU 中断/异常的芯片级事件作为仿真事件路由到中断控制器。 此外,错误类事件或不经常使用的事件也通过系统事件路由器路由,以卸载 C66x CorePac 中断选择器。 这是通过芯片中断控制器 (CIC) 块实现的。

这里涉及到了CIC(片级中断控制器),看了上面的解释还是有点懵,那就上图

可以看到这里面有四个CIC(0-4),这里主要讨论一下CIC0和1,根据上面的解释最起码明确了一点,一个中断控制器最多接受128个系统事件,那就得知道128个系统事件是谁给他的,这就是CIC的作用。根据图来看一个core会接受 98 + 17 + 5 +8 =128个事件。其中的17和8就是CIC分给他的.

上面解释了core是如何得到这128个系统事件的
接下来分析如何处理这128个系统事件

中断控制器

这128个系统事件最后都是要路由到合适的DSP中断中去的,所以接下来有一个过程就是如和从事件到中断
记住2个概念 interrupt SelectorEvent Combiner

Event Combiner:负责事件打包组合

将4-127的事件通过上图的方法(也可以自己进行配置使用mask和flag)分成组合,然后通过MASK和FLAG生成新的事件0 - 3最终形成128事件

interrupt Selector:负责路由
DSP有12个可屏蔽的中断,可以将128个事件路由到任意一个中断上。当然为了方便我们肯定是在事件打包之后进行路由


路径映射之后,就得设置中断触发源,可以通过设置中断选择寄存器设置。三个复用寄存器正好可以对应12个中断每个寄存器的(0-6,8-14,16-22,24-30)对应要生成的中断。

中断例程

了解了中断的大致原理,就可以上代码了。
我使用的板子是6678里面有8个核,所以用了一个核间通信(IPC)的例子来分析一下中断。

环境

CCS5.5
6678板卡
seed xds200仿真器
win 7

预期结果

core 0给core 1发送信息16,core 1收到后发送给 core 2 ,依次类推

运行结果

分析

main.c
#include <c6x.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>#include <ti/csl/csl_chip.h>
#include <ti/csl/src/intc/csl_intc.h>
#include <ti/csl/csl_cpintcAux.h>#include "ipc_interrupt.h"void main()
{uint32_t i;// 获取内核号uint32_t coreID = CSL_chipReadReg (CSL_CHIP_DNUM);TSCL = 0;//初始化intcInit();  //init the intc CSL global data structures, enable global ISR//注册registerInterrupt(); //register the Host interrupt with the eventfor (i=0; i<1000; i++)asm (" NOP 5");//core 0开始发送信息给下一个核if (0 == coreID){IssueInterruptToNextCore();}while(1){asm(" NOP 9");};
}
ipc_interrupt.c
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>#include <ti/csl/csl_chip.h>
#include <ti/csl/src/intc/csl_intc.h>
#include <ti/csl/csl_cpintcAux.h>#include "ipc_interrupt.h"CSL_IntcGlobalEnableState state;    //使能
CSL_IntcContext context;     //上下文
CSL_IntcEventHandlerRecord Record[CSL_INTC_EVENTID_CNT]; //128个事件句柄
CSL_IntcEventHandlerRecord  EventRecord; //当前事件句柄
uint32_t        coreVector[MAX_CORE_NUM]; //内核表
CSL_IntcObj     intcObj[16]; //中断控制器对象
CSL_IntcHandle  hintc[16]; //中断控制器句柄
volatile Uint32 interruptNumber=0;/* IPCGR Info */
int32_t iIPCGRInfo[CORENUM] = {IPCGR0,IPCGR1,IPCGR2,IPCGR3,IPCGR4,IPCGR5,IPCGR6,IPCGR7};
/* IPCAR Info */
int32_t iIPCARInfo[CORENUM] = {IPCAR0,IPCAR1,IPCAR2,IPCAR3,IPCAR4,IPCAR5,IPCAR6,IPCAR7};interruptCfg intInfo[MAX_SYSTEM_VECTOR] =
{/* core   event   vector*/{  0,     91,     CSL_INTC_VECTID_4, &IPC_ISR},{  1,     91,     CSL_INTC_VECTID_4, &IPC_ISR},{  2,     91,     CSL_INTC_VECTID_4, &IPC_ISR},{  3,     91,     CSL_INTC_VECTID_4, &IPC_ISR},{  4,     91,     CSL_INTC_VECTID_4, &IPC_ISR},{  5,     91,     CSL_INTC_VECTID_4, &IPC_ISR},{  6,     91,     CSL_INTC_VECTID_4, &IPC_ISR},{  7,     91,     CSL_INTC_VECTID_4, &IPC_ISR},
};int32_t intcInit()
{//初始化上下文环境/* INTC module initialization */context.eventhandlerRecord = Record;context.numEvtEntries      = CSL_INTC_EVENTID_CNT;if (CSL_intcInit (&context) != CSL_SOK)return -1;/* Enable NMIs */if (CSL_intcGlobalNmiEnable () != CSL_SOK)return -1;/* Enable global interrupts */if (CSL_intcGlobalEnable (&state) != CSL_SOK)return -1;/* INTC has been initialized successfully. */return 0;
}//注册中断
int32_t registerInterrupt()
{uint32_t i;uint32_t event;uint32_t vector;uint32_t core;uint32_t coreID = CSL_chipReadReg (CSL_CHIP_DNUM);CSL_IntcEventHandler isr;for (i=0; i<MAX_CORE_NUM; i++){coreVector[i] = 0;}//只有为当前内核,将顶一的core信息与中断源绑定for (i=0; i<MAX_SYSTEM_VECTOR; i++){core   = intInfo[i].core;if (coreID == core){event  = intInfo[i].event;vector = intInfo[i].vect;isr    = intInfo[i].isr;if (MAX_CORE_VECTOR <= coreVector[core]){printf("Core %d Vector Number Exceed\n");}hintc[vector] = CSL_intcOpen (&intcObj[vector], event, (CSL_IntcParam*)&vector , NULL);if (hintc[vector] == NULL){printf("Error: GEM-INTC Open failed\n");return -1;}/* Register an call-back handler which is invoked when the event occurs. */EventRecord.handler = isr;EventRecord.arg = 0;if (CSL_intcPlugEventHandler(hintc[vector],&EventRecord) != CSL_SOK){printf("Error: GEM-INTC Plug event handler failed\n");return -1;}/* clear the events. */if (CSL_intcHwControl(hintc[vector],CSL_INTC_CMD_EVTCLEAR, NULL) != CSL_SOK){printf("Error: GEM-INTC CSL_INTC_CMD_EVTCLEAR command failed\n");return -1;}/* Enabling the events. */if (CSL_intcHwControl(hintc[vector],CSL_INTC_CMD_EVTENABLE, NULL) != CSL_SOK){printf("Error: GEM-INTC CSL_INTC_CMD_EVTENABLE command failed\n");return -1;}coreVector[core]++;}}return 0;
}
// BOOT and CONFIG dsp system modules Definitions
#define CHIP_LEVEL_REG  0x02620000
// Boot cfg registers
#define KICK0           *(unsigned int*)(CHIP_LEVEL_REG + 0x0038)
#define KICK1           *(unsigned int*)(CHIP_LEVEL_REG + 0x003C)
#define KICK0_UNLOCK (0x83E70B13)
#define KICK1_UNLOCK (0x95A4F1E0)
#define KICK_LOCK    0void IssueInterruptToNextCore()
{uint32_t CoreNum;uint32_t iNextCore;static uint32_t interruptInfo=0;CoreNum = CSL_chipReadReg (CSL_CHIP_DNUM);iNextCore = (CoreNum + 1)%8; //printf("Set interrupt from Core %x to Core %d, cycle = %d\n", CoreNum, iNextCore, TSCL);interruptInfo +=16;// Unlock ConfigKICK0 = KICK0_UNLOCK;KICK1 = KICK1_UNLOCK;//向下一个核发送信息 ipc中断由两个寄存器ipcGR(生成核的中断)和IPCAR(确认)两个寄存器组成*(volatile uint32_t *) iIPCGRInfo[iNextCore] = interruptInfo;//使能*(volatile uint32_t *) iIPCGRInfo[iNextCore] |= 1;// lock ConfigKICK0 = KICK_LOCK;KICK1 = KICK_LOCK;printf("Interrupt Info %d\n", interruptInfo);}void IPC_ISR()
{volatile uint32_t read_ipcgr;uint32_t CoreNum;uint32_t iPrevCore;CoreNum = CSL_chipReadReg (CSL_CHIP_DNUM);;iPrevCore = (CoreNum - 1)%8;//当前核接收到的信息read_ipcgr = *(volatile Uint32 *) iIPCGRInfo[CoreNum];//清除SRCS位*(volatile uint32_t *) iIPCARInfo[CoreNum] = read_ipcgr; //clear the related source infoprintf("Receive interrupt from Core %d with info 0x%x, cycle = %d\n", iPrevCore, read_ipcgr, TSCL);interruptNumber++;if(CoreNum!=0)//{IssueInterruptToNextCore();}else{printf("IPC test passed!\n");}
}

如果各位需要源码的话可以私聊我…

TMS320C6678 多核学习 中断分析 实例+解析相关推荐

  1. c语言求三个整数的积,反汇编学习-C语言实例解析精粹-实例3求整数之积

    序言 为了提高可读性,我添加了这一段,另外由于我用的是VS2017,会出现一些奇怪的错误,也一并在这里解决. 例如本次出现了这个错误(安全检查错误):错误 C4996 'scanf': This fu ...

  2. opencv自定义深度学习层 官方实例解析 笔记

    环境 Windows,visual studio 15,opencv3.4.2,c++ 1.代码地址 https://docs.opencv.org/3.4.2/dc/db1/tutorial_dnn ...

  3. ANSYS静力学分析实例入门一

    ANSYS 入门学习--静力学分析实例 ANSYS的分析流程 前处理(四种方式创建ANSYS模型) *在ANSYS环境中创建实体模型,然后划分有限元网络 *在其他软件中创建实体模型,然后读入到ANSY ...

  4. R数据分析:孟德尔随机化分析文献解析和实例操练

    最近抽空研读了一篇探讨高血压和肾功能关系的文献,记录下来分享给大家,主要也是想看看孟德尔随机化的统计分析结果在论文中是如何呈现的,之后我会给大家写写孟德尔随机化的统计分析在R语言中的做法,希望可以帮助 ...

  5. python程序格式框架的描述_python 程序语言设计(嵩天)-学习笔记(第二章python 程序实例解析)...

    第 2 章 python 程序实例解析 学习目标: 掌握解决计算问题的一般方法. 掌握python语言的基本语法,包括缩进.变量.命名等. 掌握python语言绘制图形的一般方法. 了解python标 ...

  6. 转 android anr 分析示例,[摘]Android ANR日志分析指南之实例解析

    前文<[摘]Android ANR日志分析指南>也摘抄了如何分析,接下来通过实例解析. 一.主线程被其他线程lock,导致死锁 waiting on <0x1cd570> (a ...

  7. jca 实例 java_jca工具分析was的javacore实例解析

    一朋友打电话求助,问怎样简单方便的分析WAS的JAVACORE文件.我给他做了个实例解析,下面是一个过程记录. 一.工具下载 可从IBM官网下载JCA工具,专门用来分析JAVACORE文件的工具.使用 ...

  8. c语言编程实例解析精粹,C语言实例解析精粹学习笔记——35(报数游戏)

    实例35: 设由n个人站成一圈,分别被编号1,2,3,4,--,n.第一个人从1开始报数,每报数位m的人被从圈中推测,其后的人再次从1开始报数,重复上述过程,直至所有人都从圈中退出. 实例解析: 用链 ...

  9. mysql中10049是什么错误_【学习笔记】Oracle数据库10049用于分析SQL解析笔记案例

    [学习笔记]Oracle数据库10049用于分析SQL解析笔记案例 时间:2016-11-05 13:54   来源:Oracle研究中心   作者:HTZ   点击: 次 天萃荷净 Oracle研究 ...

最新文章

  1. GD32的flash读、擦除、写操作
  2. jdbc在项目中的应用
  3. GPU(CUDA)学习日记(十一)------ 深入理解CUDA线程层次以及关于设置线程数的思考
  4. Python爬虫介绍及实战入门
  5. 4 读写文件_块存储、文件存储、对象存储的区别
  6. 重学TCP协议(9) 半连接队列、全连接队列
  7. 数据可视化系列(六):场景案例显神通
  8. jar k8s 自己的 部署_k8s+jenkins+harbor镜像仓库实现持续集成
  9. 命名集 —— 名字结构
  10. 2019/3/14 软工作业
  11. lambda函数 java_使用 Java 构建 Lambda 函数 - AWS Lambda
  12. win11开机动画关闭教程
  13. 微信小程序UI库组件库合集
  14. 2020美亚杯个人赛头脑风暴
  15. 这可能是最简单,精炼,有效的magisk 安装教程,附boot.img 提取方法
  16. 通讯录AddressBook
  17. 骗术一览,大猫小猫都小心了!【转载】
  18. C语言编程>第十六周 ② 函数fun的功能是:统计长整数test的各位上出现数字5、6、7的次数,并通过外部(全局)变量sum5、sum6、sum7返回主函数。
  19. DCC888 :Instruction Level Parallelism
  20. c语言病毒源码演示,【病毒】震荡波病毒C语言源码

热门文章

  1. 如何提升图片清晰度?有了这4个工具,高糊图片也能变清晰
  2. YOLOv1预测阶段算法精讲为什么输出图像是7x7x30的张量
  3. 一个登录窗口穿越星空来到你面前,很深遂的感觉,运行一下试试。
  4. Html5文字阴影和盒子阴影
  5. Windows10蓝牙驱动丢失,100%解决方案
  6. 群晖NAS 7.X 搭建个人博客网站并发布公网 8/8
  7. 2017年软件工程第十二次作业-版本控制总结
  8. ABBYY FineReader PDF程序安装及注意事项
  9. iOS7完美越狱纯净版详细图文教程
  10. ================各种文字==========