TMS320C665x嵌入式开发板的PCIe通信开发方法

2025-10-22 19:04:03

1、TMS320C665x Linux系统下通过PCIe加载启动

操作中用到的工程源码在"Demo\PCIe Linux Loader"下。

物理机安装Linux系统

由于PCIe设备需要支持VT-d指令集的硬件及虚拟化软件,才能够映射到虚拟机中使用,所以这里以安装在物理机上的Linux系统完成测试。

可以通过第三方工具检查CPU是否支持VT-d指令集。

TMS320C665x嵌入式开发板的PCIe通信开发方法

2、修改IBL启动模式为PCIe

由于KeyStone I(DSP C665x及DSP C667x)内置的ROM BootLoader在对PCIe启动的配置中缺失或者某些配置项目或者配置值不合适,导致不能被PC正确识别(在Windows系统下会出现无法正确分配资源的错误导致驱动无法正确加载)。所以,需要依赖IIC EEPROM中的IBL辅助配置。

请参阅《TMS320C665x开发例程使用手册》中仿真器加载程序章节内容,将IBL配置参数做出如下修改,启动的时候将拨码开关配置为OFF OFF ON ON ON。

ibl.RomBoot.Enable = TRUE;

ibl.RomBoot.Mode = 0x1809;

关于0x1809的含义,请参阅参考文档《DSP C665x启动模式汇总》。

3、1. C66x DSP TMS320C665x连接DSP板卡到PCIe x4或者x16插槽

KeyStone I DSP支持单个PCIe端口(Port)以及两个PCIe通道(Lane),但是PC上一般只有x1、x4以及x16插槽。

创龙板卡可以直接从PCIe供电,所以请勿额外连接电源适配器。

4、TMS320C665x启动PC到Linux

可能需要在Linux加载内核前复位(Full Reset)板卡,以便可以被系统枚举到。

5、TMS320C665x查询设备

打开终端(Shell),执行lspci命令。可以找到Multimedia controller: Texas Instruments Device b005(rev 01)设备。

TMS320C665x嵌入式开发板的PCIe通信开发方法

6、还可以通过lspci -v命令查看设备详细信息,例如内存映射。

TMS320C665x嵌入式开发板的PCIe通信开发方法

7、在IBL对PCIe启动配置代码中,配置了四组BAR Mask寄存器值

BAR0 Mask=4KB

BAR1 Mask=1MB

BAR2 Mask=1MB

BAR3 Mask=16MB

操作系统在枚举PCIe设备的时候会根据该值为PCIe设备分配内存空间。

IBL相关配置代码如下:

void iblPCIeWorkaround()

{

    UINT32  v, flag_6678 = 0, flag_6670 = 0, flag_6657 = 0, MAGIC_ADDR;

    UINT32  i;

     /* Power up PCIe */

    devicePowerPeriph (TARGET_PWR_PCIE);

    for(i=0; i<1000; i++) asm (" NOP");

    DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_APP_SERDES_CFG0), 0x00062320);  /* ss clock */

    DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_APP_SERDES_CFG1), 0x00022320);  /* ss clock */

      

    /* Wait for PCIe PLL lock */

    while(!(DEVICE_REG32_R(PCIE_STS_REG) & 1));

/* Determine 6670 or 6678 */

    v = *((Uint32 *)DEVICE_JTAG_ID_REG);

    v &= DEVICE_JTAG_ID_MASK;

    if (v == DEVICE_C6678_JTAG_ID_VAL) {

MAGIC_ADDR = 0x87fffc;

flag_6678 = 1;

}

if (v == DEVICE_C6670_JTAG_ID_VAL) {

        MAGIC_ADDR = 0x8ffffc;

flag_6670 = 1;

}

if (v == DEVICE_C6657_JTAG_ID_VAL) {

                MAGIC_ADDR = 0x8ffffc;

                flag_6657 = 1;

        }

    DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_CLASSCODE_REVID), 0x04800001);  /* class 0x04, sub-class 0x80, Prog I/F 0x00, Other multimedia device */

    DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_LINK_STAT_CTRL), 0x10110080);  /* extended sync, slot_clk_cfg = 1 */

    DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_VENDER_DEVICE_ID), 0xb005104c);  /* Vendor and Device ID */

    DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_DEVICE_CAP), 0x288701); /* L0 = 4, L1 = 3 */

DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_APP_OB_SIZE), 0x00000003);     /* OB_SIZE = 8M */

DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_PL_GEN2), 0x0000000F);   /* num_fts = 0xF*/

    DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_APP_CMD_STATUS), 0x0020); /* Set dbi_cs2 to allow access to the BAR registers */

if (flag_6678)  {

/* 6678 */

DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR0), 0x00000FFF);   /* 4K */

DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR1), 0x0007FFFF);   /* 512K */

DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR2), 0x003FFFFF);   /* 4M */

DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR3), 0x00FFFFFF);   /* 16M */

}

if (flag_6670)  {

/* 6670 */

DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR0), 0x00000FFF);   /* 4K */

DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR1), 0x000FFFFF);   /* 1M */

DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR2), 0x001FFFFF);   /* 2M */

DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR3), 0x00FFFFFF);   /* 16M */

     }

if (flag_6657)  {

                /* 6657 */

                DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR0), 0x00000FFF);   /* 4K */

                DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR1), 0x000FFFFF);   /* 1M */

                DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR2), 0x000FFFFF);   /* 1M */

                DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR3), 0x00FFFFFF);   /* 16M */

        }

    DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_APP_CMD_STATUS), 0x0);    /* dbi_cs2=0 */

    DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_STATUS_CMD), 0x00100146); /* ENABLE mem access */

    DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_DEV_STAT_CTRL), 0x0000281F); /* Error control */

    DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_ACCR), 0x000001E0); /* Error control */

    DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR0), 0); /* non-prefetch, 32-bit, mem bar */

    DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_APP_CMD_STATUS), 0x0000007);    /* enable LTSSM, IN, OB */

    while((DEVICE_REG32_R(PCIE_BASE_ADDR + PCIE_DEBUG0) & 0x11)!=0x11);    /* Wait for training to complete */

    /* Wait for the Boot from Host */

    DEVICE_REG32_W(MAGIC_ADDR, 0);

waitForBoot(MAGIC_ADDR);

    /* Will never reach here */

    return;

}

8、TMS320C665x编译驱动

将Linux_Host_Loader目录从光盘中复制到Linux文件系统中的任意目录。路径中不要有空格及非ASCII字符(中文等)。

打开终端并进入该目录,执行make clean及make命令。成功编译后会在当前目录生成PCIeLoader.ko(注意大小写)的驱动模块。请确保x86的gcc编译器安装及配置正确,通常情况下Linux发行版都内置该工具。

TMS320C665x嵌入式开发板的PCIe通信开发方法

9、1. TMS320C665x加载驱动

在终端中执行sudo insmod PCIeLoader.ko命令,然后输入当前用户密码,即可成功加载该驱动。此时,可以看到底板LED循环点亮。

TMS320C665x嵌入式开发板的PCIe通信开发方法

10、在终端中执行dmesg命令,可以看到驱动加载产生的内核日志。驱动的基本流程是先将程序按照段加载到相应的内存区域,然后写_C_int00地址到Boot Magic。由于IBL在一直查询Boot Magic,所以当该地址值变为有效后跳转到该地址,从而完成启动操作。

TMS320C665x嵌入式开发板的PCIe通信开发方法

TMS320C665x嵌入式开发板的PCIe通信开发方法

11、TMS320C665x通过CCS调试

请参阅相关文档安装Linux下的CCS集成开发环境并配置仿真器配置文件,这里以XDS200仿真器为例。

(1) 打开CCS,默认情况下Linux版本CCS安装到/opt/ti目录下,可执行主程序为/opt/ti/ccsv5/eclipse/ccstudio。不需要使用root权限运行。

TMS320C665x嵌入式开发板的PCIe通信开发方法

12、加载仿真器配置文件进入Debug模式。

TMS320C665x嵌入式开发板的PCIe通信开发方法

13、连接DSP C6657核心0。

TMS320C665x嵌入式开发板的PCIe通信开发方法

14、加载程序符号(GPIO_LED.out文件)。

TMS320C665x嵌入式开发板的PCIe通信开发方法

15、加载成功后就可以对该程序进行调试。

TMS320C665x嵌入式开发板的PCIe通信开发方法

TMS320C665x嵌入式开发板的PCIe通信开发方法

TMS320C665x嵌入式开发板的PCIe通信开发方法

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢