RapidIO规范《RapidIO_Rev_2.2_Specification》
书籍《RapidIO The Embedded System Interconnect》
系列博客SRIO学习
系列博客RapidIO(还介绍了TSI721)
Xilinx zynq zynqMP RapidIO SRIO
IDT CPS1848 SRIO交换芯片使用
直接看RapidIO的初始化,一些底层的比如物理层链路层之类的不需要关心,用到了再去看,毕竟都是基于芯片或者IP来开发,从顶层了解这个过程。
上面提到的最优路径,就是所谓的枚举算法的目的,可以是最短路径同时包含一些用户约束,。
系统初始化之后,所有器件都会拥有一个ID,在系统初始化之前,按照下面设置。RapidIO系统应该只有一个引导代码器件。
枚举过程中,将给每个endpoint分配唯一的器件ID,为了增强容错性,RapidIO系统可以有两个host,经过竞争,最终只有一个host来完成枚举,如果主机枚举过程失败并发生超时事件,则另一主机重新枚举。枚举算法根据器件ID大小设置优先级,ID大的host竞争获胜,在枚举同一个endpoint时会发生竞争,失败host主动退出枚举,枚举结束之后,其他主机可以通过被动发现(passively discovery)收集网络中的路由拓扑信息。所以host的ID可以设置为0x00(0x0000)和0x01(0x0001),其中0x01的优先级更高。host应当将自己的主机使能位置1,switch没有这个位,当host释放对失败主机的锁定时,枚举完成,失败host自己检测是否被锁定和释放锁定。在开放式(open)8位器件ID系统中,如果host枚举失败,那么失败主机重新枚举时,必须等待15秒。在闭合式(closed)或者16位器件ID系统中,超时等待时间需要设计。
以Xilinx zynq说明,
这里只考虑Switch是CPS1848的情况,TSI578原理是一致。
现在拓扑关系已经搜索出来了。下面就是配置路由,因为上述搜索过程的路由配置不一定是最优配置,也不满足用户的需求。 所以现在需要按照设计需求,生成路由表然后写到各个Switch。
这里实现Linux用户态的驱动,数据结构定义,
struct srioEndpoint
{
unsigned int devId;
unsigned int hopCnt;
struct srioSwitch* pSw;
unsigned int port;
};
#define SRIO_SW_MAX_PORT 18//get from cps1848
struct srioSwitch
{
unsigned int hopCnt;
unsigned int componentTag;//component tag
unsigned int portNum;
struct srioEndpoint* pEp[SRIO_SW_MAX_PORT];//port connected
unsigned int epNum;
unsigned int portEp[SRIO_SW_MAX_PORT];//for get ep info for certain port fastly
struct srioSwitch* pSw[SRIO_SW_MAX_PORT];//switch connected, complicate and will be implenmented laterly
unsigned int swNum;
unsigned int portSw[SRIO_SW_MAX_PORT];//for get sw info for certain port fastly
struct srioSwitch* pSwParent;
unsigned int portParent;
};
#define SRIO_SYS_MAX_EP_NUM 64
#define SRIO_SYS_MAX_SW_NUM 4
struct srioSystem
{
struct srioEndpoint epInfo[SRIO_SYS_MAX_EP_NUM];
unsigned int epNum;
struct srioSwitch swInfo[SRIO_SYS_MAX_SW_NUM];
unsigned int swNum;
};