欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > DSP芯片C6678的SRIO及其中断跳转的配置

DSP芯片C6678的SRIO及其中断跳转的配置

2025/2/26 4:07:27 来源:https://blog.csdn.net/weixin_45830602/article/details/145830592  浏览:    关键词:DSP芯片C6678的SRIO及其中断跳转的配置

C6678SRIO读写测试+门铃中断跳转测试

  • SRIO简述
  • 代码前言
  • SRIO配置
    • 原始代码
    • 1.使能电源
    • 2.初始化SRIO
      • 回环修改
    • 3.SRIO测试
  • Doorbell门铃中断
    • 1.初始化中断函数
    • 2.中断向量表建立
    • 3.中断向量表的链接

本博客基于创龙“678ZH产品线”的SRIO代码,部分参考于网友们的博客,参考文档将在结尾列出

SRIO简述

一句话:高速串行通信协议
有多高速:最高25Gbps≈3G的文件一秒传输完成
什么串行:四组口,可任意配置为用一组还是多用几组(每组最快6.25Gbps)

适合场景:任何高速数据交换场景,但其实小编只在FPGA与DSP之间应用。
例如:FPGA将图像数据传送到DSP,然后DSP经过识别处理后呈现给出结果。

另外小编觉得最神奇的是SRIO是可以直接将数据放入指定位置的,例如FPGA如果需要将数据给到DSP处理,FPGA可以直接设置放入指定的DDR地址,或者其他高速缓存地址,这是小编认为SRIO最好玩的地方。

代码前言

当说明文档太多而不知道看哪些的时候,最好的方法就是直接上代码(尤其是对于这种已经十几年前的芯片)。
笔者当前一共看过了3套C6678的SRIO相关代码,从难到简单的排序是这样的
难:pdk_c667x_2_0_16\packages\MyExampleProjects
中:C6678\STK_C6678\SRIO
易:678ZH产品线\7.案例源码\SRIO的ZYNQ+DSP核间通讯\srio_initiator

TI官方提供的例子是最难的,其次就是TI论坛上基于keystone的例子,然后就是创龙提供的简化版的例子。小编是先看了keystone的例子,必须要对照文档一步步看,因为涉及到的功能很多。然后再看的创龙,创龙的例子太简单了,只有发送和读取,非常适合刚入DSP门的同学学习。
下面SRIO的初始测试就是基于创龙的代码(创龙代码都是使用了TI官方的CSL库进行配置的,用户需要自行用include options来包含(eclipse系列用户应该容易理解),我用的是“pdk_C6678_1_1_2_6\packages\ti\csl”)。

以下创龙demo的例子大家可以去其官网上进行下载哦。

SRIO配置

创龙的代码是直接与FPGA交互,但是稍微一改就可以变成回环测试,非常适合于FPGA端还没有调好的场景。

原始代码

创龙非常贴心的将代码全部放到了main一个文档里面,异常的简洁明了。
我们先来整体看一下

int main(void)
{int8_t   ret;uint32_t core_num;/* enable SRIO PSC */ret = enable_srio();if(ret != 0) {printf("srio psc initialization failed ! \r\n");return -1;}/* configure and enable SRIO subsystem */ret = srio_device_init();if(ret != 0) {printf("srio system initialization failed ! \r\n");return -1;}/* read the DSP Core Number */core_num = CSL_chipReadReg(CSL_CHIP_DNUM);/* srio transmit test: srio write(NWRITE) --> srio read(NREAD) */ret = srio_test(core_num, TARGET_ADDRESS, TARGET_SIZE, Srio_Ftype_WRITE);if(ret != 0) {printf("srio test occur error! \r\n");return -1;}printf("SRIO test %d cycles, " \"errcnt: %d, total size %d KB, ", \LOOP_TIMES, err_count, TARGET_SIZE * LOOP_TIMES / 1024);printf("write type: NWRITE, avg write rate: %.2f Gbps, ", \w_rate_total / LOOP_TIMES);printf("read type: NREAD, avg read rate: %.2f Gbps\r\n\n\n", \r_rate_total / LOOP_TIMES);/* clear var to zero */w_rate_total = 0.0;r_rate_total = 0.0;err_count = 0;/* srio transmit test: srio write(SWRITE) --> srio read(NREAD) */ret = srio_test(core_num, TARGET_ADDRESS, TARGET_SIZE, Srio_Ftype_SWRITE);if(ret != 0) {printf("srio test occur error! \r\n");return -1;}printf("SRIO test %d cycles, " \"errcnt: %d, total size %d KB, ", \LOOP_TIMES, err_count, TARGET_SIZE * LOOP_TIMES / 1024);printf("write type: SWRITE, avg write rate: %.2f Gbps, ", \w_rate_total / LOOP_TIMES);printf("read type: NREAD, avg read rate: %.2f Gbps\r\n\n\n", \r_rate_total / LOOP_TIMES);return 0;
}

以上代码,使能SRIO电源管理、初始化SRIO、SRIO测试,一共三步,就能跑起来测试。

1.使能电源

电源设置非常固定,只要将TI官方csl库包进来然后使用即可。

static int32_t enable_srio (void)
{/* SRIO power domain is turned OFF by default. It needs to be turned on before doing any* SRIO device register access. This not required for the simulator*//* Set SRIO Power domain to ON */CSL_PSC_enablePowerDomain(CSL_PSC_PD_SRIO);/* Enable the clocks too for SRIO */CSL_PSC_setModuleNextState(CSL_PSC_LPSC_SRIO, PSC_MODSTATE_ENABLE);/* Start the state transition */CSL_PSC_startStateTransition(CSL_PSC_PD_SRIO);/* Wait until the state transition process is completed. */while(!CSL_PSC_isStateTransitionDone(CSL_PSC_PD_SRIO));/* Return SRIO PSC status */if((CSL_PSC_getPowerDomainState(CSL_PSC_PD_SRIO) != PSC_PDSTATE_ON) ||(CSL_PSC_getModuleState(CSL_PSC_LPSC_SRIO) != PSC_MODSTATE_ENABLE)) {/* SRIO Power on failed. Return error */return -1;}/* SRIO ON. Ready for use */return 0;
}

2.初始化SRIO

链接: 各部寄存器参数说明
初始化SRIO是用来选择使用几组接口、选择多大速率的一些基本操作
还有最后确认是否建立好了SRIO连接(如果FPGA没写好,那就只能用回环模式通过,否则就会报连接错误)

在这一部分,用户可以将其设置为回环测试,只用修改一个小小的地方即可

static int32_t srio_device_init (void)
{uint32_t             i, wait_time;uint32_t             status;/* Get the CSL SRIO Handle. */hSrio = CSL_SRIO_Open(0);if(hSrio == NULL)return -1;/* Code to disable SRIO reset isolation */if(CSL_PSC_isModuleResetIsolationEnabled(CSL_PSC_LPSC_SRIO))CSL_PSC_disableModuleResetIsolation(CSL_PSC_LPSC_SRIO);/* Disable the SRIO Global block */CSL_SRIO_GlobalDisable(hSrio);/* Disable each of the individual SRIO blocks. */for(i = 0; i <= 9; i++)CSL_SRIO_DisableBlock(hSrio, i);/* BOOT_COMPLETE = 0:  write enabled */CSL_SRIO_SetBootComplete(hSrio, 0);/* Now enable the SRIO block and all the individual blocks also. */CSL_SRIO_GlobalEnable(hSrio);for(i = 0; i <= 9; i++)CSL_SRIO_EnableBlock(hSrio, i);/* Configure SRIO ports mode. */for(i = 0; i <= 3; i++)// CSL_SRIO_SetNormalMode(hSrio, i);CSL_SRIO_SetLoopbackMode(hSrio, i);/* Enable Automatic Priority Promotion of response packets. */CSL_SRIO_EnableAutomaticPriorityPromotion(hSrio);/** Set the SRIO Prescalar select to operate in the range* PERSCALER_SELECT = 0: 44.7 ~ 89.5 MHz*/CSL_SRIO_SetPrescalarSelect(hSrio, 0);/* Unlock the Boot Configuration Kicker */CSL_BootCfgUnlockKicker();/** MPY = 0x50: 10x* ENPLL = 1: PLL Enable* srio_serdes_clock = RefClk(250MHz) * MPY = 2.5GHz*/CSL_BootCfgSetSRIOSERDESConfigPLL(0x51);/** Configure the SRIO SERDES Receive Configuration* ENOC     = 1: Enable offset compensation* EQ       = 1: Fully adaptive equalization* CDR      = 5: First order with fast lock* ALIGN    = 1: Comma alignment enabled* TERM     = 1: Input termination, the only valid value for this field is 0x1* RATE     = 1: Data Rate = 2 * srio_serdes_clock = 5Gbps* BUSWIDTH = 1: Bus width, indicate a 20-bit wide parallel bus to the clock* ENRX     = 1: Enable this receiver*/for(i = 0; i <= 3; i++)CSL_BootCfgSetSRIOSERDESRxConfig(i, 0x00468495);/** Configure the SRIO SERDES Transmit Configuration* MSYNC    = 1:  Enables the channel as the master lane* FIRUPT   = 1:  Transmitter pre and post cursor FIR filter update* TWPST1   = 18: Adjacent post cursor Tap weight* TWPRE    = 1:  Precursor Tap weight* SWING    = 16: Output swing* RATE     = 1:  Data Rate = 2 * srio_serdes_clock = 5Gbps* BUSWIDTH = 1:  Bus width, indicate a 20-bit wide parallel bus to the clock* ENRX     = 1:  Enable this receiver*/for(i = 0; i <= 3; i++)CSL_BootCfgSetSRIOSERDESTxConfig(i, 0x001C8F95);/* Loop around till the SERDES PLL is not locked. */while(1) {/* Get the SRIO SERDES Status */CSL_BootCfgGetSRIOSERDESStatus(&status);if(status & 0x1)break;}/* Lock the Boot Configuration Kicker */CSL_BootCfgLockKicker();/* Clear the LSU pending interrupts. */CSL_SRIO_ClearLSUPendingInterrupt(hSrio, 0xFFFFFFFF, 0xFFFFFFFF);/* Set the 16 bit and 8 bit identifier for the SRIO Device */CSL_SRIO_SetDeviceIDCSR(hSrio, CSR_LOCAL_DEVICEID_8BIT, CSR_LOCAL_DEVICEID_16BIT);/* Configure the Base Routing Register */CSL_SRIO_SetTLMPortBaseRoutingInfo(hSrio, 0, 1, 1, 0, 0);CSL_SRIO_SetTLMPortBaseRoutingPatternMatch(hSrio, 0, 1, REMOTE_DEVICEID1_8BIT, 0xFF);/* Configure the PLM for all the ports */for (i = 0; i <= 3; i++) {/* TODO: We need to ensure that the Port 0 is configured to support both* the 2x and 4x modes. The Port Width field is read only. So here we simply* ensure that the Input and Output ports are enabled */CSL_SRIO_EnableInputPort(hSrio, i);CSL_SRIO_EnableOutputPort(hSrio, i);/** Discovery timer is specified to be 28 msec +/- 4 msec* Discovery timer = RefClk(250MHz) period * PRESCALAR_SRV_CLK * 52429 * DISCOVERY_TIMER*                 = (1 / 250Mhz) * (250 / 10) * 52429 * 5 = 26.2ms*/CSL_SRIO_SetPLMPortDiscoveryTimer(hSrio, i, 0x5);}/* Set the Port link timeout CSR */CSL_SRIO_SetPortLinkTimeoutCSR(hSrio, 0x000FFF);CSL_SRIO_SetPortResponseTimeoutCSR(hSrio, 0xFF0FFF);/* Set the Port General CSR: Only executing as Master Enable */CSL_SRIO_SetPortGeneralCSR(hSrio, 0, 1, 0);/* Clear the sticky register bits */CSL_SRIO_SetLLMResetControl(hSrio, 1);/* Set the Data Streaming MTU */CSL_SRIO_SetDataStreamingMTU(hSrio, 64);/* Configure the path mode 4 for the ports */CSL_SRIO_SetPLMPortPathControlMode(hSrio, 0, 4);/** Set the LLM Port IP Prescalar* PRESCALAR_SRV_CLK = RefClk(250MHz) / 10*/CSL_SRIO_SetLLMPortIPPrescalar(hSrio, 0x19);/* Enable the peripheral */CSL_SRIO_EnablePeripheral(hSrio);/* Configuration has been completed *//* BOOT_COMPLETE = 1:  write to read only registers disabled */CSL_SRIO_SetBootComplete(hSrio, 1);/* This code checks if the ports are operational or not */wait_time = 100;while(wait_time) {if(CSL_SRIO_IsPortOk(hSrio, 0) == TRUE) {break;} else {wait_time --;/* Delay 1 ms */cpu_delaycycles(1000000);}}if(wait_time == 0) {printf("srio system initialization time out!\r\n");return -1;}/* Initialization has been completed */return 0;
}

波特率的计算方式如下:
参考时钟(板卡外部时钟)*倍频得出一个时钟A
时钟A经过RATE的选择,变成实际的通讯时钟
例如:外部时钟为250Mhz,经过10倍频=2.5Ghz,再经过RATE选择half模式就变成了5Gbps。

下图展示了倍频设置,对应代码中的CSL_BootCfgSetSRIOSERDESConfigPLL(0x51);
在这里插入图片描述

下图代表了RATE对应关系,对应代码中的
CSL_BootCfgSetSRIOSERDESRxConfig(i, 0x00468495);和
CSL_BootCfgSetSRIOSERDESTxConfig(i, 0x001C8F95);在这里插入图片描述
还有一些其他需要计算的参数,按照代码中注释计算即可,但是注意要将250Mhz的参考时钟(外部时钟)改为自己板卡上的时钟再进行计算。

回环修改

将CSL_SRIO_SetNormalMode(hSrio, i);改为
CSL_SRIO_SetLoopbackMode(hSrio, i);

3.SRIO测试

在此demo中,SRIO会先将数据发送,然后再回读进行比较。
发送使用的是nwrite——即无响应写入
回读使用的是nread——即无响应读取

这部分代码需要用户对SRIO有一定的了解,会涉及到目的地址与本地地址。在这小编就不做说明了哈。

static int8_t srio_test(uint8_t LSU_Number, uint32_t target_addr,uint32_t transfer_size, Srio_Ftype w_format_type)
{SRIO_LSU_TRANSFER   tparams;uint32_t  main_pll_freq;int32_t   status = 0;uint32_t  i = 0, j = 0, timeout = 0;uint8_t   uiCompletionCode = 0, context = 0;uint8_t   contextBit = 0, transactionID = 0;uint32_t  transStart = 0, transCost = 0;float     w_rate = 0, r_rate = 0;uint32_t  w_time = 0, r_time = 0;uint8_t   *w_buff, *r_buff;uint8_t   *w_buff_global, *r_buff_global, *t_buff_global;uint32_t  *srio_trans_src, *srio_trans_dst;/* initialize variables */TSCL = 0;TSCH = 0;/* Get the cpu freq */main_pll_freq = platform_get_main_pll_freq();/* malloc buffer */w_buff = malloc(transfer_size);if(w_buff == NULL) {status = -1;printf("Failed to alloc meory !\r\n");goto err_alloc_wbuff;}r_buff = malloc(transfer_size);if(r_buff == NULL) {status = -1;printf("Failed to alloc meory !\r\n");goto err_alloc_rbuff;}/* convert the buffer address to global address */w_buff_global = (uint8_t *)Convert_CoreLocal2GlobalAddr((uint32_t)w_buff);r_buff_global = (uint8_t *)Convert_CoreLocal2GlobalAddr((uint32_t)r_buff);t_buff_global = (uint8_t *)target_addr;/* initialize the test data for buffer */for(i = 0; i < transfer_size; i++) {srand(i);w_buff[i] = rand() % 0xFF;;r_buff[i] = 0;}/* Loop times */for(j = 0; j < LOOP_TIMES; j++) {/* wait loopback complete time set as 10ms, base on cpu freq as 1000MHz */timeout = 10000000;/* 1.1 caculate the read and write buffer for srio transfer address */srio_trans_src = (uint32_t *)w_buff_global;srio_trans_dst = (uint32_t *)t_buff_global;/* 1.2 set transfer parameters, srio nwrite test, w_buff -> devmem_buff */memset((void *)&tparams, 0, sizeof(tparams));tparams.rapidIOLSB = (uint32_t)srio_trans_dst;tparams.dspAddress = (uint32_t)srio_trans_src;tparams.bytecount = transfer_size;if(w_format_type == Srio_Ftype_WRITE)tparams.ttype = Srio_Ttype_Write_NWRITE;tparams.ftype = w_format_type;tparams.dstID = REMOTE_DEVICEID1_8BIT;tparams.outPortID = SRIO_PORT;tparams.idSize = 0;/* wait lsu have available shadow register */while(1) {if (CSL_SRIO_IsLSUFull(hSrio, LSU_Number) == FALSE)break;}/* Get the LSU Context and Transaction Information. */CSL_SRIO_GetLSUContextTransaction(hSrio, LSU_Number,&contextBit, &transactionID);transStart = _itoll(TSCH, TSCL);/* start srio transfer */CSL_SRIO_SetLSUTransfer(hSrio, LSU_Number, &tparams);/* wait for a transfer completion interrupt occur */while(timeout) {CSL_SRIO_GetLSUCompletionCode(hSrio, LSU_Number, transactionID,&uiCompletionCode, &context);if(context == contextBit) {/* disable pending transactions */transactionID = 0xFF;contextBit = 0xFF;if(uiCompletionCode != 0) {status = -1;printf("SRIO transfer have error completed code %d\r\n", -(uiCompletionCode));goto err_transfer;}break;} else {timeout--;/* delay 1 cpu cyle */asm (" nop");}}if(timeout == 0) {/* if transfer timeout occurs, return error status */status = -1;printf("SRIO transfer timeout\r\n");goto err_transfer;}/* Calculate srio transfer used time */transCost = _itoll(TSCH, TSCL) - transStart;w_time = transCost;/* Calculate srio transfer write rate */w_rate = (float)transfer_size * main_pll_freq / w_time / 1024 / 1024 / 1024 * 8;/* wait loopback complete time set as 10ms, base on cpu freq as 1000MHz */timeout = 10000000;/* 1.3 caculate the read and write buffer for srio transfer address */srio_trans_src = (uint32_t *)t_buff_global;srio_trans_dst = (uint32_t *)r_buff_global;/* 1.4 set transfer parameters, srio nread test, devmem_buff -> r_buff */memset((void *)&tparams, 0, sizeof(tparams));tparams.rapidIOLSB = (uint32_t)srio_trans_src;tparams.dspAddress = (uint32_t)srio_trans_dst;tparams.bytecount = transfer_size;tparams.ttype = Srio_Ttype_Request_NREAD;tparams.ftype = Srio_Ftype_REQUEST;tparams.dstID = REMOTE_DEVICEID1_8BIT;tparams.outPortID = SRIO_PORT;tparams.idSize = 0;/* wait LSU have available shadow register */while(1) {if (CSL_SRIO_IsLSUFull (hSrio, LSU_Number) == FALSE)break;}/* Get the LSU Context and Transaction Information. */CSL_SRIO_GetLSUContextTransaction(hSrio, LSU_Number,&contextBit, &transactionID);transStart = _itoll(TSCH, TSCL);/* start srio transfer */CSL_SRIO_SetLSUTransfer(hSrio, LSU_Number, &tparams);/* wait for a transfer completion interrupt occur */while(timeout) {CSL_SRIO_GetLSUCompletionCode(hSrio, LSU_Number, transactionID,&uiCompletionCode, &context);if(context == contextBit) {/* disable pending transactions */transactionID = 0xFF;contextBit = 0xFF;if(uiCompletionCode != 0) {status = -1;printf("SRIO transfer have error completed code %d\r\n", -(uiCompletionCode));goto err_transfer;}break;} else {timeout--;/* delay 1 cpu cyle */asm (" nop");}}if(timeout == 0) {/* if transfer timeout occurs, return error status */status = -1;printf("SRIO transfer timeout\r\n");goto err_transfer;}/* Calculate srio transfer used time */transCost = _itoll(TSCH, TSCL) - transStart;r_time = transCost;/* Calculate srio transfer read rate */r_rate = (float)transfer_size * main_pll_freq / r_time / 1024 / 1024 / 1024 * 8;w_rate_total += w_rate;r_rate_total += r_rate;for(i = 0; i < transfer_size; i++) {if(w_buff_global[i] != r_buff_global[i]) {err_count++;if(err_count == 1) {printf("Frist Err occurred src addr: 0x%x, dst addr: 0x%x\r\n", \(uint32_t)&w_buff_global[i], (uint32_t)&r_buff_global[i]);printf("dst val: 0x%x, ", r_buff_global[i]);printf("expet val: 0x%x\r\n", w_buff_global[i]);}}}printf("=== loop times: %d | err_count: %d | ", j, err_count);if(w_format_type == Srio_Ftype_WRITE)printf("trans_size: %d Byte | NWRITE write times: %d ns(%.2f Gbps) | ", \transfer_size, w_time, w_rate);else if(w_format_type == Srio_Ftype_SWRITE)printf("trans_size: %d Byte | SWRITE write times: %d ns(%.2f Gbps) | ", \transfer_size, w_time, w_rate);printf("NREAD read times: %d ns(%.2f Gbps)\r\n", r_time, r_rate);}err_transfer:free(r_buff);
err_alloc_rbuff:free(w_buff);
err_alloc_wbuff:return status;
}

Doorbell门铃中断

门铃中断基于keystone的demo进行修改,会涉及到三个地方
1.初始化中断函数
2.中断向量表建立
3.中断向量表的链接

1.初始化中断函数

中断部分函数是从keystone的SRIO例子中的SRIO_Test.c中摘抄出来的,原版的主要函数有
SRIO_Interrupts_Init();(初始化设置)
SRIO_Doorbell_ISR();(中断跳转函数)
KeyStone_SRIO_Interrupt_init(SRIO_Interrupt_Cfg * interrupt_cfg);(初始化应用)
以下为我这里修改的初始化,因为不需要message中断所以就只保留了doorbell的4中断。

void SRIO_Interrupts_Init(void)
{/*map SRIO doorbell interrupts to INT4.*/gpCGEM_regs->INTMUX1 = (CSL_GEM_INTDST_N_PLUS_16<<CSL_CGEM_INTMUX1_INTSEL4_SHIFT);//enable INT4CPU_interrupt_enable((1<<4));interrupt_cfg.interrupt_map = interrupt_map;interrupt_cfg.uiNumInterruptMap = sizeof(interrupt_map)/sizeof(SRIO_Interrupt_Map);/*interrupt rate control is not used in this test*/interrupt_cfg.interrupt_rate= NULL;interrupt_cfg.uiNumInterruptRateCfg= 0;interrupt_cfg.doorbell_route_ctl= SRIO_DOORBELL_ROUTE_TO_DEDICATE_INT;}

需要注意的是,中断初始化一定记到放到SRIO初始化后面,否则将会一直中断导致程序死掉。按下图放置
在这里插入图片描述
在这里插入图片描述

2.中断向量表建立

其实就是需要新建一个文件,小编直接从keystone里面复制粘贴了出来
在这里插入图片描述
下列代码是SRIO_vectors.asm的原始内容,由于小编不需要message中断,所以下列的.ref SRIO_Message_ISR需要去掉,然后VEC_ENTRY SRIO_Message_ISR ;interrupt 5改为VEC_DUMMY ;interrupt 5

;create interrupt vector table for C6000 DSP
;--------------------------------------------------------------
;This file can be modified to add Interrupt Service Routine(ISR) 
;for an interrupt, the steps are:
;1,reference to the externally defined ISR, for example
;	.ref EDMA_ISR
;2,modify the corresponding entry in the interrupt vector table.
;  For example, if interrupt 8 is used for EDMA, then you should
;  modify the entry number 8 like below:
;	VEC_ENTRY EDMA_ISR     	;interrupt 8 
;--------------------------------------------------------------
;Author: Brighton Feng
;Created on 2010-12-6
;--------------------------------------------------------------;reference to the externally defined ISR.ref _c_int00.ref SRIO_Doorbell_ISR.ref SRIO_Message_ISR.ref Exception_service_routine.ref Nested_Exception_service_routine.ref exception_record.global vectors ;--------------------------------------------------------------.sect ".text"
;create interrupt vector for NMI	
NMI_ISR:STW 	B1,*-B15[1];save some key registers when exception happensMVKL  exception_record,B1MVKH  exception_record,B1STW 	B3, *+B1[0]STW 	A4, *+B1[1]STW 	B4, *+B1[2]STW 	B14, *+B1[3]STW 	B15, *+B1[4];jump to exception service routineMVKL  	Exception_service_routine, B1MVKH  	Exception_service_routine, B1B 	B1LDW 	*-B15[1],B1NOP 	4;--------------------------------------------------------------
;create interrupt vector for reset (interrupt 0)
VEC_RESET .macro addrMVKL  addr,B0MVKH  addr,B0B     B0MVC   PCE1,B0NOP   4.align 32.endm;create interrupt vector for other used interrupts	
VEC_ENTRY .macro addrSTW   B0,*--B15MVKL  addr,B0MVKH  addr,B0B     B0LDW   *B15++,B0NOP   4.align 32.endm;create interrupt vector for unused interrupts	
VEC_DUMMY .macro
unused_int?:B    unused_int? ;dead loop for unused interruptsNOP  5.align 32.endm;--------------------------------------------------------------
;interrupt vector table	.sect "vecs".align 1024vectors:VEC_RESET Nested_Exception_service_routine     		;Nested exception  VEC_ENTRY NMI_ISR	;NMI/ExceptionVEC_DUMMY   		;RSVDVEC_DUMMY   		;RSVDVEC_ENTRY SRIO_Doorbell_ISR   	;interrupt 4VEC_ENTRY SRIO_Message_ISR   	;interrupt 5VEC_DUMMY   		;interrupt 6VEC_DUMMY   		;interrupt 7VEC_DUMMY     		;interrupt 8 VEC_DUMMY   		;interrupt 9VEC_DUMMY   		;interrupt 10VEC_DUMMY   		;interrupt 11VEC_DUMMY   		;interrupt 12VEC_DUMMY   		;interrupt 13VEC_DUMMY   		;interrupt 14VEC_DUMMY   		;interrupt 15.end

3.中断向量表的链接

其实名字不一定叫这个,这块的主要作用就是把第二步的中断表给应用进去。
需要修改的文件为C66X.cmd,没错,是个cmd文件,用CCS建立项目的时候会自动生成。
如果没有这一步,那么生成的中断将会在0x00800000里循环卡死。
在这里插入图片描述
至此,中断完成,跑一下看看结果
在这里插入图片描述

完全没问题,DOORBELL被触发!

参考链接: 如何把中断服务程序加载到ISTP中
参考链接: DSP之SRIO通信之DSP端参数设置

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词