This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

sysbios pcie srio 上位机的中断问题

Other Parts Discussed in Thread: SYSBIOS

我使用SYSbios 的例程,C6678的dsp,v7的fpga,C6678通过PCIE与上位机进行通信,C6678通过SRIO与FPGA进行通信,当执行到BIOS_start之后,顺利进入到任务里面,等待上位机的信号量,等到之后,通过读取pcie的BAR上面的地址,执行不同的mode,来配置FPGA,之后操作上位机,将数据下载到ddr上,经过处理之后,srio接收FPGA的中断,发送数据给FGPA。                               

  现在,我遇到的问题是,因为SRIO的hwi优先级高,每次还没有执行到,下载数据的时候,就已经进入到srio的isr中去了,而且,就执行了一次(FPGA每隔20ms发一次doorbell),我尝试修改了,srio的优先级和pcie的优先级都没有成功,有什么解决的办法吗?

main 函数

Int main(Int argc, Char* argv[])
{
UInt32 k[100] = {0};
//clear PCIE interrupt MSI0 and INTA, because boot loader need interrupt to weak up DSP to run.
//Boot loader step :
//1. load section to memory
//2. write MAGIC_ADDR with boot entry address
//3. send interrupt to DSP(MSI0 or INTA etc)
DEVICE_REG32_W(MSI0_IRQ_STATUS, 0x1);
DEVICE_REG32_W(PCIE_LEGACY_A_IRQ_STATUS, 0x1);
DEVICE_REG32_W(PCIE_IRQ_EOI, 0x0);

//时钟初始化
TSC_init();

//unused
DEVICE_REG32_W(0x1087fffc, (uint32_t)&_c_int00);
write_boot_magic_number();
//安装主机中断...........
InitHostInt();

//Srio模块初始化(包括pll,qmss、pktdma、DDR3, TSC,Gpio)
EDMA_init();
//DSP core speed: 100*10/1=1000MHz,仅需主核初始化
//KeyStone_main_PLL_init(100, 10, 1);
KeyStone_main_PLL_init(312.5, 32, 10);
//该函数配置参数需要修改
KeyStone_DDR_init (1000,2, 2, NULL);
//KeyStone_DDR_init (66.66667, 16, 1, NULL);

if(SrioInit() < 0)
{
return -1;
}

/* Initialize the SRIO Driver */
if (Srio_init () < 0)
{
System_printf ("Error: SRIO Driver Initialization Failed\n");
return -1;
}

//maokai:动态加载GPIO初始化
GPIO_init_mk();

//初始化SRIO Socket驱动
InitSrioDriver();

//maokai:translate the BARs to local RAM
ConfigPcieInBound_mk();

//创建任务前必须先进行SRIO\PCIE\EDMA\DDR3等外围接口及设备初始化
CreateTask();

//通知主机DSP初始化完成
DEVICE_REG32_W(0x10800000, 0x0C11FC00);
BIOS_start();
while(1);
return 0;
}

Task的初始化

void CreateTask(Void)
{
Task_Params taskParams;

UInt32 uiCoreNum = 0;
// Create two tasks that share a resource
uiCoreNum = CSL_chipReadReg (CSL_CHIP_DNUM);

if (uiCoreNum == CORE_SYS_INIT)
{
Task_Params_init(&taskParams);
taskParams.priority = 1;
taskParams.stackSize = 8192;
Task_create (TaskMain, &taskParams, NULL);

Task 的函数:

Void TaskMain(UArg arg0, UArg arg1)
{
Int32 i=0,j=0xABAB4145,h=0,q=0;
UInt32 k[100] = {0};
while (1)
{
//SendInterruptToHost();
// Get access to resource
Semaphore_pend(semHostInt, BIOS_WAIT_FOREVER);
Semaphore_reset(semHostInt,0);

//UInt32 Pcie_Mode = DEVICE_REG32_R(0x10800000);
UInt32 Pcie_Mode = DEVICE_REG32_R(0x10800008);//;
UInt32 Cpu_data_length = DEVICE_REG32_R(0x1080000C);//DEVICE_REG32_R(0x8200000C);
UInt32 Cpu_data_srcaddr = 0x82000100;
UInt32 Cpu_data_dstaddr = 0x00000000;

UInt32 DspReadFPGA_srcaddr = DEVICE_REG32_R(0x10800018);
UInt32 DspReadFPGA_dstaddr = 0x10800010;

if(Pcie_Mode == 1)
{
i = 0xABAB4141;
DEVICE_REG32_W(0x10800040,i);
Pciedma_Srio_mk();

MemInt32BRead(k,0x80000000,10);
MemInt32Write(0x10800060,k,10);
//SendInterruptToHost();
ClearInterruptToHost();
InitSrioDriver();
//DEVICE_REG32_W(0x10800060,PCIE_EP_IRQ_CLR);
//SendInterruptToHost();
//BIOS_exit(0);
}
else if(Pcie_Mode == 2)
{

if(Cpu_data_length != 0)
{

DEVICE_REG32_W(0x10800044,j);
WriteFpgaByDioSockets_nwrite_mk (Cpu_data_dstaddr,(Uint8*) Cpu_data_srcaddr,8*Cpu_data_length);
SendInterruptToHost();
}
else
{
j++;
DEVICE_REG32_W(0x10800050,j);
SendInterruptToHost();
}

}
else if(Pcie_Mode == 3)
{
q++;
DEVICE_REG32_W(0x10800048,q);
Dsp_config_fpga_mk();
TSC_delay_ms(1000);
SrioInit();
//InitSrioDriver();
SendInterruptToHost();
}
else if(Pcie_Mode == 4)
{
h++;
DEVICE_REG32_W(0x1080004C,h);
ReadFpgaByDioSockets(DspReadFPGA_srcaddr,(UInt8 *) DspReadFPGA_dstaddr,8);
SendInterruptToHost();
}
}

  • 中断的问题已经解决了,现在的问题是:我的doorbell中断只进入了一次,但是FPGA是每个20ms在发信号,这个是为什么?
    下面是srio的ISR
    Void FpgaDioTxCompletionIsr
    (
    UArg argument
    //UArg arg0, UArg arg1
    )
    {


    count++;

    Uint16 doorbellStatus;
    DEVICE_REG32_W(0x10800080,count);
    /* Pass the control to the driver DIO Tx Completion ISR handler */
    Srio_dioTxCompletionIsr ((Srio_DrvHandle)argument, hSrioCSL);//该行代码DSP应用程序通过直接io方式发送数据时,由中断ISR调用

    //FPGA中断足够快的话是否会丢失中断?
    //g_InterruptCount++;

    CSL_SRIO_GetDoorbellPendingInterrupt (hSrioCSL, 0, &doorbellStatus);


    //UInt32 uiSegNum;
    switch(doorbellStatus)
    {
    case 1:
    DEVICE_REG32_W(0x10800084,0xABAB4141);
    printf("doorbell 1 ok!");
    break;
    case 2:
    DEVICE_REG32_W(0x10800088,0XABAB4142);
    printf("doorbell 2 ok!");
    break;
    case 4:
    DEVICE_REG32_W(0x1080008C,0XABAB4143);
    //System_printf("doorbell 4 ok!");
    break;
    case 8:
    DEVICE_REG32_W(0x10800090,0XABAB4144);
    printf("doorbell 8 ok!");
    break;
    case 16:
    DEVICE_REG32_W(0x10800094,0XABAB4148);
    printf("doorbell 16 ok!");
    break;
    case 32:
    DEVICE_REG32_W(0x10800098,0XABAB4150);
    printf("doorbell 32 ok!");
    break;
    case 64:
    DEVICE_REG32_W(0x1080009C,0XABAB4151);
    printf("doorbell 64 ok!");
    break;
    case 128:
    DEVICE_REG32_W(0x108000A0,0XABAB4153);
    printf("doorbell 128 ok!");
    break;
    default:
    DEVICE_REG32_W(0x108000A4,0XABAB4154);
    printf("doorbell not ok!");
    break;
    }

    // System_printf("waiting for doorbell!\n");
    CSL_SRIO_ClearDoorbellPendingInterrupt (hSrioCSL, 0, doorbellStatus);
    return;
    }

    count是定义在外部变量初始化为0,写入到PCIE的bar地址上,发现count值计数到1,就停止了,这个要怎么改?
  • CSL和SYS/BIOS不要同时使用。
  • 我并没有同时使用,我用的是6678的srio的例程,SRIO_LoopbackDioIsrexampleproject,这个修改用的