赞
踩
libamp_virnetdrv 可以方便的移植到各种平台,为 AMP 架构提供简单、高效的核间通信机制。下面以 T3 AMP(SylixOS + SylixOS)为例介绍具体的移植过程。
1、驱动支持
虚拟网卡包含 libamp_virnetdrv与 libamp_virnetdrv_config 两个部分。T3 是 ARM 平台,因此首先拷贝 libamp_virnetdrv\src\demo\arm_aarch64 下的四个文件到 T3 每个系统的 BSP 目录 bspallwinnert3\SylixOS\driver\virnet 下,如下图所示。
分别在各系统的 Makefile 中添加源文件 virnet.c,如下:
对 virnet.c 进行定制化修改。
1) 修改系统映射表定义 _G_virNetCoreOsMap
- static __VIRNET_CORE_OS_MAP _G_virNetCoreOsMap[4] =
- {
- {OS_TYPE_SYLIXOS, 0, 0},
- {OS_TYPE_SYLIXOS, 1, 1},
- };
系统映射表结构如下:
- struct core_os_map {
- UINT32 u32OsType; /* 操作系统类型 */
- UINT32 u32OsId; /* 操作系统编号 */
- UINT32 u32OsInt; /* 操作系统的中断号 */
- };
- typedef struct core_os_map __VIRNET_CORE_OS_MAP;
- typedef struct core_os_map *__PVIRNET_CORE_OS_MAP;
-
操作系统类型:目前能够支持的选项为: OS_TYPE_LINUX、 OS_TYPE_SYLIXOS;
操作系统编号:需要从 0 开始, 依次递增;
操作系统的中断号:为当前核能够响应的核间中断编号;
例子中 T3 的 4 个核只用了 2 个核, 每个核为一个 SylixOS, 对应核间中断号为 0、 1, 则配置如下:
- static __VIRNET_CORE_OS_MAP _G_virNetCoreOsMap[2] = \
- {
- {OS_TYPE_SYLIXOS, 0, 0},
- {OS_TYPE_SYLIXOS, 1, 1},
- };
2)获取当前系统分配的系统 ID
各系统核代码中需要声明宏 CONFIG_VIRNET_OS_ID,其值为当前的系统 ID。
- #define CONFIG_VIRNET_OS_ID (0)/* CPU0 运行系统 0 */
- #define CONFIG_VIRNET_OS_ID (1)/* CPU1 运行系统 1 */
CONFIG_VIRNET_OS_ID 会在如下接口中被调用。
- INT multiVirNetConfigOwnOsIdGet (VOID)
- {
- return CONFIG_VIRNET_OS_ID;
- }
3) 相关地址配置
相关的地址包括如下几个:
配置空间: 用于存储配置信息的空间, 多个系统之间共享, 多个系统的地址需统一。
控制空间: 用于存储控制信息的空间, 会被划分给多个系统使用, 用于存储网卡状态等。
通信空间: 用于存储通信报文的空间, 会把划分为多个通道, 用于系统两两通信存储报文。
需要分配一块足够大小的共享内存供这三种空间使用:
- /*
- * 虚拟网卡空间
- */
- #define BSP_VIRTUAL_NET_MEM_BASE (BSP_CORES_BOOT_SYNC_BASE + BSP_CORES_BOOT_SYNC_SIZE)
- #define BSP_VIRTUAL_NET_MEM_SIZE (10U * 1024 * 1024)
配置空间基地址定义,返回指定的物理内存地址。
- addr_t multiVirNetConfigBaseGet (VOID)
- {
- return (BSP_VIRTUAL_NET_MEM_BASE);
- }
-
配置空间大小定义,填写指定的物理内存大小, 当大小不足时, 初始化时会有错误提示。
- size_t multiVirNetConfigSizeGet (VOID)
- {
- return 0x400000;
- }
控制空间基地址定义,填写指定的物理内存地址。
- addr_t multiVirNetControlBaseGet (VOID)
- {
- return (BSP_VIRTUAL_NET_MEM_BASE + 0x400000);
- }
控制空间大小定义,填写指定的物理内存大小, 当大小不足时, 初始化时会有错误提示。
- size_t multiVirNetControlSizeGet (VOID)
- {
- return 0x100000;
- }
通信空间基地址定义,填写指定的物理内存地址。
- addr_t multiVirNetMessageBaseGet (VOID)
- {
- return (BSP_VIRTUAL_NET_MEM_BASE + 0x400000 + 0x100000);
- }
通信空间大小定义,填写指定的物理内存大小, 当大小不足时, 初始化时会有错误提示。
- size_t multiVirNetMessageSizeGet (VOID)
- {
- return 0x400000;
- }
3)核间中断相关函数
核间中断触发函数,在该接口中根据传入的 中断号 或 系统号 触发对应的核间中断
- VOID multiVirNetIsrOccur (INT iOsInt, INT iOsId)
- {
- VOID bspMpInt(ULONG ulCPUId);
- bspMpInt(iOsInt);
- }
核间中断使能函数
- VOID multiVirNetIsrEnable (INT iOsInt)
- {
- INT armGicIrqAffinitySet (ULONG ulVector, UINT64 ullMpidr, BOOL bForce);
- INT armGicIrqPrioritySet (ULONG ulVector, UINT32 uiPriority);
- VOID armGicIrqEnable (ULONG ulVector);
- armGicIrqAffinitySet(ARM_SW_INT_VECTOR(iOsInt), iOsInt, LW_TRUE);
- armGicIrqPrioritySet(ARM_SW_INT_VECTOR(iOsInt), ARM_SW_INT_PRIORITY);
- armGicIrqEnable(ARM_SW_INT_VECTOR(iOsInt));
- }
核间中断禁能函数
- VOID multiVirNetIsrDisable (INT iOsInt)
- {
- VOID armGicIrqDisable (ULONG ulVector);
- armGicIrqDisable(ARM_SW_INT_VECTOR(iOsInt));
- }
2、创建虚拟网卡设备
编译 libamp_virnetdrv与 libamp_virnetdrv_config 这两个库,生成静态库文件。
在编译各 AMP 系统 BSP 时链接此文件:
- LOCAL_DEPEND_LIB := \
- -lfdt \
- -l:libamp_virnetdrv_config.a \
- -l:libamp_virnetdrv.a
- LOCAL_DEPEND_LIB_PATH := \
- -L"$(SYLIXOS_BASE_PATH)/libsylixos/$(Output)" \
- -L"$(LIBAMP_VIRNETDRV_CONFIG_DIR)" \
- -L"$(LIBAMP_VIRNETDRV_DIR)"
在每个系统 BSP 的 halNetifAttch 中调用如下接口:
- multiVirNetDevSymbolInit();
- API_VirNetNdCreate();
在 0 号系统 BSP 的 usrStartup 中调用如下接口,需要保证此接口在所有系统调用创建虚拟网卡前调用,且需要在调用 halStdFileInit() 后:
API_VirNetConfig();
3、使用
编译各系统镜像烧录后,如果虚拟网卡创建成功则可以在 ifocnfig 看到对应设备:
使用 vnconfig 命令可以查看虚拟网卡配置的信息:
使用 virnet 命令可以查看当前虚拟网卡的信息:
成功在各系统上创建虚拟网卡后即可通过 socket 接口进行核间通信。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。