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代码,部分参考于网友们的博客…...
2025asp.net全栈技术开发学习路线图
2025年技术亮点: Blazor已全面支持WebAssembly 2.0标准 .NET 8版本原生集成AI模型部署能力 Azure Kubernetes服务实现智能自动扩缩容 EF Core新增向量数据库支持特性 ASP.NET 全栈开发关键技术说明(2025年视角) 以下技术分类基于现…...
DeepSeek开源周首日:发布大模型加速核心技术可变长度高效FlashMLA 加持H800算力解码性能狂飙升至3000GB/s
FlashMLA的核心技术特性包括对BF16精度的全面支持,以及采用块大小为64的页式键值缓存(Paged KV Cache)系统,实现更精确的内存管理。在性能表现方面,基于CUDA12.6平台,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、前面的种种都不说了,好不容易运行起来oap-portal项目,运行idm-ui项目死活运行不起来,各种报错,各种安装,各种卸载nodejs,卸载nvm,重装,都不好使。 2、甚至后来运行npm install会…...
Golang 构建学习
Golang 构建学习 如何搭建Golang开发环境 1. 下载GOlang包 https://golang.google.cn/dl/ 在地址上下载Golang 2. 配置包环境 修改全局环境变量,GOPROXY,GOPATH,GOROOT GOPROXYhttps://goproxy.cn,direct GOROOT“” // go二进制文件的路…...
Android Audio实战——音频相关基础概念(附)
Android Audio 开发其实就是媒体源数字化的过程,通过将声波波形信号通过 ADC 转换成计算机支持的二进制的过程叫做音频采样 (Audio Sampling)。采样 (Sampling) 的核心是把连续的模拟信号转换成离散的数字信号。 一、声音的属性 1、响度 (Loudness) 响度是指人类可以感知到的…...
大型装备故障诊断解决方案
大型装备故障诊断解决方案 方案背景 在全球航空工业迅猛发展的背景下,我国在军用和民用飞机自主研发制造领域取得了显著成就。尤其是在国家大力支持下,国内飞机制造企业攻克了诸多关键技术难题,实现了从设计研发到生产制造再到售后保障的完整…...
反向代理模块kfj
1 概念 1.1 反向代理概念 反向代理是指以代理服务器来接收客户端的请求,然后将请求转发给内部网络上的服务器,将从服务器上得到的结果返回给客户端,此时代理服务器对外表现为一个反向代理服务器。 对于客户端来说,反向代理就相当于…...
【Http和Https区别】
概念: 一、Http协议 HTTP(超文本传输协议)是一种用于传输超媒体文档(如HTML)的应用层协议,主要用于Web浏览器和服务器之间的通信。http也是客户端和服务器之间请求与响应的标准协议,客户端通常…...
【llm对话系统】如何快速开发一个支持openai接口的llm server呢
核心思路:使用轻量级 Web 框架,将 OpenAI API 请求转换为你现有推理脚本的输入格式,并将推理脚本的输出转换为 OpenAI API 的响应格式。 快速开发步骤列表: 选择合适的 Web 框架 (快速 & 简单): FastAPI: Python 最佳选择&am…...
数据库的三大范式如何理解?
数据库的三大范式是指数据库设计中用来规范化表结构的规则。其目的是减少数据冗余,提高数据一致性和完整性。三大范式分别是: 第一范式(1NF)—— 原子性 第一范式要求表中的每个字段都必须是原子的,即字段中的值不可…...
Python Seaborn库使用指南:从入门到精通
1. 引言 Seaborn 是基于 Matplotlib 的高级数据可视化库,专为统计图表设计。它提供了更简洁的 API 和更美观的默认样式,能够轻松生成复杂的统计图表。Seaborn 在数据分析、机器学习和科学计算领域中被广泛使用。 本文将详细介绍 Seaborn 的基本概念、常用功能以及高级用法,…...
Android之APP更新(通过接口更新)
文章目录 前言一、效果图二、实现步骤1.AndroidManifest权限申请2.activity实现3.有版本更新弹框UpdateappUtilDialog4.下载弹框DownloadAppUtils5.弹框背景图 总结 前言 对于做Android的朋友来说,APP更新功能再常见不过了,因为平台更新审核时间较长&am…...
JVM生产环境问题定位与解决实战(二):JConsole、VisualVM到MAT的高级应用
生产问题定位指南:几款必备的可视化工具 引言 在上一篇文章中,详细的介绍了JDK自带的一系列命令行工具,,如jps、jmap、jstat、jstack以及jcmd等,这些工具为排查和诊断Java虚拟机(JVM)问题提供…...
wsl2安装的ext4.vhdx瘦身、打包、导入
1.清理APT缓存: Ubuntu使用APT进行软件包管理,它会在安装过程中保留下载的软件包。清理这些缓存可以释放空间: sudo apt-get clean2.删除不必要的软件包: 删除不再需要的软件包和它们的依赖项: sudo apt-get autoremove3.压缩磁盘空间 ex…...
力扣3102.最小化曼哈顿距离
力扣3102.最小化曼哈顿距离 题目 题目解析及思路 题目要求返回移除一个点后的最小的最大曼哈顿距离 最大最小值的题一般直接想到二分 本题有一个简单办法就是利用切比雪夫距离 当正方形转45,即边上点**( x , y ) -> (x y , y - x)时,两点间max(…...
国标28181协议在智联视频超融合平台中的接入方法
一. 国标28181介绍 国标 28181 协议全称是《安全防范视频监控联网系统信息传输、交换、控制技术要求》,是国内视频行业最重要的国家标准,目前有三个版本: 2011 年:推出 GB/T 28181-2011 版本,为安防行业的前端设备、平…...
【学习笔记】LLM+RL
文章目录 1 合成数据与模型坍缩(model collapse),1.1 递归生成数据与模型坍缩1.2 三种错误1.3 理论直觉1.4 PPL指标 2 基于开源 LLM 实现 O1-like step by step 慢思考(slow thinking),ollama,streamlit2.1…...
Linux故障排查和性能优化面试题及参考答案
目录 如何查看 Linux 系统中的 CPU、内存、磁盘等资源使用情况? 什么是 Linux 中的负载(Load Average)?如何解读它? 如何通过 top 和 htop 命令监控系统性能? 如何使用 mpstat 命令来查看 CPU 的利用情况? 如何分析系统 CPU 瓶颈? 如何分析 CPU 瓶颈?如何优化 CP…...
【论文精读】YOLO-World:实时开放词汇目标检测
论文地址: YOLO-World: Real-Time Open-Vocabulary Object Detection 源代码:YOLO-World 摘要 YOLO系列检测器因其高效性和实用性而被广泛认可。然而,它们依赖于预定义和训练过的物体类别,这限制了其在开放场景中的适用性。为了…...
【AI时代】可视化训练模型工具LLaMA-Factory安装与使用
文章目录 安装训练使用 安装 官方地址: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 是一个强大的开源文档编辑平台,支持文档、表格、演示文稿等文件格式的编辑。通过 D…...
将产品照片(form.productPhotos)转为 JSON 字符串发送给后端
文章目录 1. 前端 form.productPhotos 的当前处理a. 组件绑定b. 当前发送逻辑 2. 如何将 form.productPhotos 转为 JSON 字符串发送给后端a. 修改前端 save() 方法b. 确保 esave API 支持接收字符串 基于你提供的 identify-form.vue 代码,我将分析如何将产品照片&a…...
【科研绘图系列】R语言绘制小提琴图、散点图和韦恩图(violin scatter plot Venn)
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包数据下载画图1画图2画图3画图4画图5画图6画图7参考介绍 【科研绘图系列】R语言绘制小提琴图、散点图和韦恩图(violin & scatter plot & Venn) 加载R包 library…...
kotlin 知识点一 变量和函数
在Kotlin中定义变量的方式和Java 区别很大,在Java 中如果想要定义一个变 量,需要在变量前面声明这个变量的类型,比如说int a表示a是一个整型变量,String b表 示b是一个字符串变量。而Kotlin中定义一个变量,只允许在变量…...
科普:你的笔记本电脑中有三个IP:127.0.0.1、无线网 IP 和局域网 IP;两个域名:localhost和host.docker.internal
三个IP 你的笔记本电脑中有三个IP:127.0.0.1、无线网 IP 和局域网 IP。 在不同的场景下,需要选用不同的 IP 地址,如下为各自的特点及适用场景: 127.0.0.1(回环地址) 特点 127.0.0.1 是一个特殊的 IP 地…...
solidity之Foundry安装配置(一)
一门面向合约的高级编程语言,主要用来编写以太坊只能合约。 Solidity受C语言,Python和js影响,但为编译成为以太坊虚拟机字节码在EVM上执行,很多特性和限制都和EVM相关。 Solidity 是静态类型语言,支持继承、库、自定义…...
爬虫解析库:parsel的详细使用
文章目录 1. 安装 Parsel2. 基本用法3. 使用 CSS 选择器提取数据4. 使用 XPath 提取数据5. 链式调用6. 正则表达式提取7. 处理嵌套元素8. 处理默认值9. 结合 Requests 使用10. 处理复杂 HTML11. 性能优化12. 注意事项 引言:本博客详细介绍爬虫解析库parser的详细使用…...
PHP-create_function
[题目信息]: 题目名称题目难度PHP-create_function2 [题目考点]: create_function ( string args , string args , string code )[Flag格式]: SangFor{wWx5dEGHHhDUwmST4bpXwfjSzq43I6cz}[环境部署]: docker-compose.yml文件或者docker …...
