1.概述
PionwaySDK和Opal Kelly的FrontPanel SDK的架构和组件名称比较相近,可经过较为简单的代码修改操作完成项目的代码迁移。
2. Pionway SDK系统架构简介
Pionway SDK由PC端的API、USB接口芯片的固件和FPGA端的HDL IP Core组成,其中USB接口芯片的固件是通用的,已经内置在SDK中。用户在代码迁移过程中只需要修改PC端和FPGA工程。
API运行在PC端,由引入库(.lib)、动态链接库(.dll)和头文件(.h)组成。其中引入库和头文件要一并包含在PC端原代码工程,参与程序编译。编译完成后的可执行文件需要在当前路径下包含动态链接库文件来供程序运行时使用。用户在做PC端源代码工程迁移的时候需要注意Pionway SDK与Frontpanel SDK在API类名称和若干类方法名称及原型上的差异。
HDL库所包含的IP Core工作在FPGA端,由一个总控制器(pwHost)及若干endpoint功能模块(pwXXX)组成,总控制器和FPGA的I/O引脚相连接,各个功能模块的输入端都与总控制器相连接,而功能模块的输出端需要先经过pwMUX多路复用器转变成一路信号,再总入总控制器。
用户在做FPGA端的项目代码迁移的时候需要注意Pionway SDK与Frontpanel SDK在HDL IP Core的名称和接口的名称及位宽上的差异,不同种类的Endpoint功能模块有各自的地址空间范围,需要特别注意的是Opal kelly Frontpanel SDK的Pipe和与Block Pipe的Endpoint地址范围是重叠的((Block)Pipe In:0x80-0x9F,(Block)Pipe Out:0xA0-0xBF),而Pionway SDK的这两类功能模块的地址范围是独立的(PipeIn:0x80-0x9F,PipeOut:0xA0-0xBF,BlockPipeIn:0xC0-0xDF,BlockPipeOut:0xE0-0xFF)。
我们以Ramtest项目为例进行FrontPanel SDK到PionwaySDK的代码迁移操作。迁移前后的部分源代码工程可以从Pionway开发者计划网页中获取。
本文以Pionway SDK v1.5.0版本为例,进行Ramtest项目的Opal Kelly Frontpanel SDK到PionwaySDK的代码迁移操作。
3. Ramtest项目简介
Ramtest例程演示了FPGA USB模块从数据产生、数据发送以及数据传输和数据取回的全部流程。包括了数据上传、下发、数据缓冲及中间的流控制。在USB标准中,所有操作都是PC端发起的,XMS6302在这里作为设备端。
例程运行的基本流程是:
- PC首先生成一定量的随机数据。
- PC调用WriteToBlockPipeIn API将上位机上的数据通过USB3.0传输FPGA内部的PipeInBlock IP Core。
- FPGA内部的控制逻辑在PC调用WriteToWireIn API控制下将接收到的数据经过FIFO写入到与之相连接的DDR2 SDRAM中。
- PC调用ReadFromBlockPipeOut API将DDR2 SDRAM的数据通过BlockPipeOut IP Core读回到PC。
- PC随即对发送和接收到的数据进行比对,并输出比对结果。
4.代码迁移操作汇总
4.1 PC端程序迁移
序号 | 迁移过程中的代码修改 | Opalkelly FrontPanelAPI函数原型 | Pionway API函数原型 |
---|---|---|---|
1 | 无需修改 | ErrorCode FlashEraseSector(UINT32 address) | ErrorCode FlashEraseSector(UINT32 address) |
2 | 无需修改 | ErrorCode FlashWrite(UINT32 address, UINT32 length, const UINT8 *buf) | ErrorCode FlashWrite(UINT32 address, UINT32 length, const UINT8 *buf) |
3 | 无需修改 | ErrorCode FlashRead(UINT32 address, UINT32 length, UINT8 *buf) | ErrorCode FlashRead(UINT32 address, UINT32 length, UINT8 *buf) |
4 | 无需修改 | BoardModel GetBoardModel() | BoardModel GetBoardModel() |
5 | 函数原型改变,函数返回值为错误代码,读取结果从输出型参数返回 | intGetDeviceCount() | ErrorCodeGetDeviceCount(int *device_count); |
6 | 无需修改 | BoardModel GetDeviceListModel(int num) | BoardModel GetDeviceListModel(int num) |
7 | 无需修改 | std::string GetDeviceListSerial(int num) | std::string GetDeviceListSerial(int num) |
8 | 无需修改 | ErrorCode OpenBySerial(std::string str = "") | ErrorCode OpenBySerial(std::string str = "") |
9 | 无需修改 | bool IsOpen() | bool IsOpen() |
10 | 无需修改 | void Close() | void Close() |
11 | 被新函数替代,返回值转到了输出参数所指向的结构体中 | std::stringGetSerialNumber() | ErrorCodeGetDeviceInfo(pwTDeviceInfo *info) |
12 | 被新函数替代,返回值转到了输出参数所指向的结构体中 | std::stringGetDeviceID() | ErrorCodeGetDeviceInfo(pwTDeviceInfo *info) |
13 | 被新函数替代,返回值转到了输出参数所指向的结构体中 | boolIsHighSpeed() | ErrorCodeGetDeviceInfo(pwTDeviceInfo *info) |
14 | 无需修改 | void SetDeviceID(const std::string& str) | ErrorCode SetDeviceID(const std::string& str) |
15 | 无需修改 | ErrorCode ConfigureFPGA(const std::string& strFilename) | ErrorCode ConfigureFPGA(const std::string& strFilename) |
16 | 无需修改 | bool IsFrontPanelEnabled() | bool IsPionwayEnabled() |
17 | 无需修改 | ErrorCode UpdateWireIns() | ErrorCode UpdateWireIns() |
18 | 无需修改 | ErrorCode SetWireInValue(int ep, UINT32 val, UINT32 mask = 0xffffffff) | ErrorCode SetWireInValue(int ep, UINT32 val, UINT32 mask = 0xffffffff); |
19 | 无需修改 | ErrorCode UpdateWireOuts() | ErrorCode UpdateWireOuts() |
20 | 函数原型改变,函数返回值为错误代码,读取结果从输出型参数返回 | unsigned longGetWireOutValue(int epAddr) | ErrorCodeGetWireOutValue(int epAddr,UINT32 *val) |
21 | 无需修改 | ErrorCode ActivateTriggerIn(int epAddr, int bit) | ErrorCode ActivateTriggerIn(int epAddr, int bit) |
22 | 无需修改 | ErrorCode UpdateTriggerOuts() | ErrorCode UpdateTriggerOuts() |
23 | 函数原型改变,函数返回值为错误代码,读取结果从输出型参数返回 | boolIsTriggered(int epAddr, UINT32 mask) | ErrorCodeIsTriggered(int epAddr, UINT32 mask,bool *is_triggered) |
24 | 函数原型改变,函数返回值为错误代码,读取结果从输出型参数返回 | longWriteToPipeIn(int epAddr, long length, unsigned char *data) | ErrorCodeWriteToPipeIn(int epAddr, long length, unsigned char *data,long *count) |
25 | 函数原型改变,函数返回值为错误代码,读取结果从输出型参数返回 | longReadFromPipeOut(int epAddr, long length, unsigned char *data) | ErrorCodeReadFromPipeOut(int epAddr, long length, unsigned char*data,long *count) |
26 | 函数原型改变,函数返回值为错误代码,读取结果从输出型参数返回 | longWriteToBlockPipeIn(int epAddr, int blockSize, long length, unsignedchar *data) | ErrorCodeWriteToBlockPipeIn(int epAddr, int blocksize, long length, un-signed char *data,long *count) |
27 | 函数原型改变,函数返回值为错误代码,读取结果从输出型参数返回 | longReadFromBlockPipeOut(int epAddr, int blockSize, long length, unsignedchar *data) | ErrorCodeReadFromBlockPipeOut(int epAddr, int blocksize, long length,unsigned char *data,long *count) |
4.2 FPGA端程序迁移
序号 | Frontpanel HDL | Pionway HDL | 迁移说明 |
---|---|---|---|
1 | okCoreHarness | pwCore | 注意端口信号名称及位宽的差异 |
2 | okWireIn | pwWireIn | 注意端口信号名称及位宽的差异 |
3 | okWireOut | pwWireOut | 注意端口信号名称及位宽的差异 |
4 | okTriggerIn | pwTriggerIn | 注意端口信号名称及位宽的差异 |
5 | okTriggerOut | pwTriggerOut | 注意端口信号名称及位宽的差异 |
6 | okPipeIn | pwPipeIn | 注意端口信号名称及位宽的差异 |
7 | okPipeOut | pwPipeOut | 注意端口信号名称及位宽的差异 |
8 | okBTPipeIn | pwBlockPipeIn | 注意端口信号名称及位宽的差异 |
9 | okBTPipeOut | pwBlockPipeOut | 注意端口信号名称及位宽的差异 |
10 | okRegisterBridge | 使用较少,暂无 | |
11 | okWireOR | pwMUX | 注意端口信号名称及位宽的差异 |
5. Ramtest项目迁移代码修改
完整版步骤请访问Pionway知识库文章链接 http://pionway.cn/support/library/migration.htmlhttp://pionway.cn/support/library/migration.html