当前位置: 首页 > article >正文

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端参数设置

相关文章:

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

C6678SRIO读写测试门铃中断跳转测试 SRIO简述代码前言SRIO配置原始代码1.使能电源2.初始化SRIO回环修改 3.SRIO测试 Doorbell门铃中断1.初始化中断函数2.中断向量表建立3.中断向量表的链接 本博客基于创龙“678ZH产品线”的SRIO代码&#xff0c;部分参考于网友们的博客&#xf…...

2025asp.net全栈技术开发学习路线图

2025年技术亮点‌&#xff1a; Blazor已全面支持WebAssembly 2.0标准 .NET 8版本原生集成AI模型部署能力 Azure Kubernetes服务实现智能自动扩缩容 EF Core新增向量数据库支持特性 ‌ASP.NET 全栈开发关键技术说明&#xff08;2025年视角&#xff09;‌ 以下技术分类基于现…...

DeepSeek开源周首日:发布大模型加速核心技术可变长度高效FlashMLA 加持H800算力解码性能狂飙升至3000GB/s

FlashMLA的核心技术特性包括对BF16精度的全面支持&#xff0c;以及采用块大小为64的页式键值缓存&#xff08;Paged KV Cache&#xff09;系统&#xff0c;实现更精确的内存管理。在性能表现方面&#xff0c;基于CUDA12.6平台&#xff0c;FlashMLA在H800SXM5GPU上创下了显著成绩…...

01 冲突域和广播域的划分

目录 1、冲突域和广播域的划分 1.1、冲突域 1.2、广播域 1.3、对比总结 1.4、冲突域与广播域个数计算例题 2、交换机和路由器的结构 2.1、交换机的结构 2.2、路由器的结构 1、冲突域和广播域的划分 1.1、冲突域 冲突域是指网络中可能发生数据帧冲突的物理范围。当多…...

nodejs npm install、npm run dev运行的坎坷之路

1、前面的种种都不说了&#xff0c;好不容易运行起来oap-portal项目&#xff0c;运行idm-ui项目死活运行不起来&#xff0c;各种报错&#xff0c;各种安装&#xff0c;各种卸载nodejs&#xff0c;卸载nvm&#xff0c;重装&#xff0c;都不好使。 2、甚至后来运行npm install会…...

Golang 构建学习

Golang 构建学习 如何搭建Golang开发环境 1. 下载GOlang包 https://golang.google.cn/dl/ 在地址上下载Golang 2. 配置包环境 修改全局环境变量&#xff0c;GOPROXY&#xff0c;GOPATH&#xff0c;GOROOT GOPROXYhttps://goproxy.cn,direct GOROOT“” // go二进制文件的路…...

Android Audio实战——音频相关基础概念(附)

Android Audio 开发其实就是媒体源数字化的过程,通过将声波波形信号通过 ADC 转换成计算机支持的二进制的过程叫做音频采样 (Audio Sampling)。采样 (Sampling) 的核心是把连续的模拟信号转换成离散的数字信号。 一、声音的属性 1、响度 (Loudness) 响度是指人类可以感知到的…...

大型装备故障诊断解决方案

大型装备故障诊断解决方案 方案背景 在全球航空工业迅猛发展的背景下&#xff0c;我国在军用和民用飞机自主研发制造领域取得了显著成就。尤其是在国家大力支持下&#xff0c;国内飞机制造企业攻克了诸多关键技术难题&#xff0c;实现了从设计研发到生产制造再到售后保障的完整…...

反向代理模块kfj

1 概念 1.1 反向代理概念 反向代理是指以代理服务器来接收客户端的请求&#xff0c;然后将请求转发给内部网络上的服务器&#xff0c;将从服务器上得到的结果返回给客户端&#xff0c;此时代理服务器对外表现为一个反向代理服务器。 对于客户端来说&#xff0c;反向代理就相当于…...

【Http和Https区别】

概念&#xff1a; 一、Http协议 HTTP&#xff08;超文本传输协议&#xff09;是一种用于传输超媒体文档&#xff08;如HTML&#xff09;的应用层协议&#xff0c;主要用于Web浏览器和服务器之间的通信。http也是客户端和服务器之间请求与响应的标准协议&#xff0c;客户端通常…...

【llm对话系统】如何快速开发一个支持openai接口的llm server呢

核心思路&#xff1a;使用轻量级 Web 框架&#xff0c;将 OpenAI API 请求转换为你现有推理脚本的输入格式&#xff0c;并将推理脚本的输出转换为 OpenAI API 的响应格式。 快速开发步骤列表&#xff1a; 选择合适的 Web 框架 (快速 & 简单): FastAPI: Python 最佳选择&am…...

数据库的三大范式如何理解?

数据库的三大范式是指数据库设计中用来规范化表结构的规则。其目的是减少数据冗余&#xff0c;提高数据一致性和完整性。三大范式分别是&#xff1a; 第一范式&#xff08;1NF&#xff09;—— 原子性 第一范式要求表中的每个字段都必须是原子的&#xff0c;即字段中的值不可…...

Python Seaborn库使用指南:从入门到精通

1. 引言 Seaborn 是基于 Matplotlib 的高级数据可视化库,专为统计图表设计。它提供了更简洁的 API 和更美观的默认样式,能够轻松生成复杂的统计图表。Seaborn 在数据分析、机器学习和科学计算领域中被广泛使用。 本文将详细介绍 Seaborn 的基本概念、常用功能以及高级用法,…...

Android之APP更新(通过接口更新)

文章目录 前言一、效果图二、实现步骤1.AndroidManifest权限申请2.activity实现3.有版本更新弹框UpdateappUtilDialog4.下载弹框DownloadAppUtils5.弹框背景图 总结 前言 对于做Android的朋友来说&#xff0c;APP更新功能再常见不过了&#xff0c;因为平台更新审核时间较长&am…...

JVM生产环境问题定位与解决实战(二):JConsole、VisualVM到MAT的高级应用

生产问题定位指南&#xff1a;几款必备的可视化工具 引言 在上一篇文章中&#xff0c;详细的介绍了JDK自带的一系列命令行工具&#xff0c;&#xff0c;如jps、jmap、jstat、jstack以及jcmd等&#xff0c;这些工具为排查和诊断Java虚拟机&#xff08;JVM&#xff09;问题提供…...

wsl2安装的ext4.vhdx瘦身、打包、导入

1.清理APT缓存: Ubuntu使用APT进行软件包管理&#xff0c;它会在安装过程中保留下载的软件包。清理这些缓存可以释放空间&#xff1a; sudo apt-get clean2.删除不必要的软件包: 删除不再需要的软件包和它们的依赖项&#xff1a; sudo apt-get autoremove3.压缩磁盘空间 ex…...

力扣3102.最小化曼哈顿距离

力扣3102.最小化曼哈顿距离 题目 题目解析及思路 题目要求返回移除一个点后的最小的最大曼哈顿距离 最大最小值的题一般直接想到二分 本题有一个简单办法就是利用切比雪夫距离 当正方形转45&#xff0c;即边上点**( x , y ) -> (x y , y - x)时&#xff0c;两点间max(…...

国标28181协议在智联视频超融合平台中的接入方法

一. 国标28181介绍 国标 28181 协议全称是《安全防范视频监控联网系统信息传输、交换、控制技术要求》&#xff0c;是国内视频行业最重要的国家标准&#xff0c;目前有三个版本&#xff1a; 2011 年&#xff1a;推出 GB/T 28181-2011 版本&#xff0c;为安防行业的前端设备、平…...

【学习笔记】LLM+RL

文章目录 1 合成数据与模型坍缩&#xff08;model collapse&#xff09;,1.1 递归生成数据与模型坍缩1.2 三种错误1.3 理论直觉1.4 PPL指标 2 基于开源 LLM 实现 O1-like step by step 慢思考&#xff08;slow thinking&#xff09;&#xff0c;ollama&#xff0c;streamlit2.1…...

Linux故障排查和性能优化面试题及参考答案

目录 如何查看 Linux 系统中的 CPU、内存、磁盘等资源使用情况? 什么是 Linux 中的负载(Load Average)?如何解读它? 如何通过 top 和 htop 命令监控系统性能? 如何使用 mpstat 命令来查看 CPU 的利用情况? 如何分析系统 CPU 瓶颈? 如何分析 CPU 瓶颈?如何优化 CP…...

【论文精读】YOLO-World:实时开放词汇目标检测

论文地址&#xff1a; YOLO-World: Real-Time Open-Vocabulary Object Detection 源代码&#xff1a;YOLO-World 摘要 YOLO系列检测器因其高效性和实用性而被广泛认可。然而&#xff0c;它们依赖于预定义和训练过的物体类别&#xff0c;这限制了其在开放场景中的适用性。为了…...

【AI时代】可视化训练模型工具LLaMA-Factory安装与使用

文章目录 安装训练使用 安装 官方地址&#xff1a;https://github.com/hiyouga/LLaMA-Factory 创建虚拟环境 conda create -n llama-factory conda activate llama-factory安装 git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git cd LLaMA-Factory pip in…...

Docker 部署 OnlyOffice 文档服务器

Docker 部署 OnlyOffice 文档服务器 前言一、准备工作二、设置变量和目录结构三、创建并运行 OnlyOffice 容器四、访问 OnlyOffice 文档服务器五、配置和管理总结 前言 OnlyOffice 是一个强大的开源文档编辑平台&#xff0c;支持文档、表格、演示文稿等文件格式的编辑。通过 D…...

将产品照片(form.productPhotos)转为 JSON 字符串发送给后端

文章目录 1. 前端 form.productPhotos 的当前处理a. 组件绑定b. 当前发送逻辑 2. 如何将 form.productPhotos 转为 JSON 字符串发送给后端a. 修改前端 save() 方法b. 确保 esave API 支持接收字符串 基于你提供的 identify-form.vue 代码&#xff0c;我将分析如何将产品照片&a…...

【科研绘图系列】R语言绘制小提琴图、散点图和韦恩图(violin scatter plot Venn)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包数据下载画图1画图2画图3画图4画图5画图6画图7参考介绍 【科研绘图系列】R语言绘制小提琴图、散点图和韦恩图(violin & scatter plot & Venn) 加载R包 library…...

kotlin 知识点一 变量和函数

在Kotlin中定义变量的方式和Java 区别很大&#xff0c;在Java 中如果想要定义一个变 量&#xff0c;需要在变量前面声明这个变量的类型&#xff0c;比如说int a表示a是一个整型变量&#xff0c;String b表 示b是一个字符串变量。而Kotlin中定义一个变量&#xff0c;只允许在变量…...

科普:你的笔记本电脑中有三个IP:127.0.0.1、无线网 IP 和局域网 IP;两个域名:localhost和host.docker.internal

三个IP 你的笔记本电脑中有三个IP&#xff1a;127.0.0.1、无线网 IP 和局域网 IP。 在不同的场景下&#xff0c;需要选用不同的 IP 地址&#xff0c;如下为各自的特点及适用场景&#xff1a; 127.0.0.1&#xff08;回环地址&#xff09; 特点 127.0.0.1 是一个特殊的 IP 地…...

solidity之Foundry安装配置(一)

一门面向合约的高级编程语言&#xff0c;主要用来编写以太坊只能合约。 Solidity受C语言&#xff0c;Python和js影响&#xff0c;但为编译成为以太坊虚拟机字节码在EVM上执行&#xff0c;很多特性和限制都和EVM相关。 Solidity 是静态类型语言&#xff0c;支持继承、库、自定义…...

爬虫解析库:parsel的详细使用

文章目录 1. 安装 Parsel2. 基本用法3. 使用 CSS 选择器提取数据4. 使用 XPath 提取数据5. 链式调用6. 正则表达式提取7. 处理嵌套元素8. 处理默认值9. 结合 Requests 使用10. 处理复杂 HTML11. 性能优化12. 注意事项 引言&#xff1a;本博客详细介绍爬虫解析库parser的详细使用…...

PHP-create_function

[题目信息]&#xff1a; 题目名称题目难度PHP-create_function2 [题目考点]&#xff1a; create_function ( string args , string args , string code )[Flag格式]: SangFor{wWx5dEGHHhDUwmST4bpXwfjSzq43I6cz}[环境部署]&#xff1a; docker-compose.yml文件或者docker …...