• 编写目的:介绍v85X 上E907 的启动环境和AMP 的环境搭建。

  • 使用范围:全志V85X 系列芯片

  • 环境
    A7 SDK:Tina
    E907 SDK:melis

4 SDK 快捷命令说明

这里主要介绍几个下文会用到的命令,并不会介绍全部命令,如果想了解全部命令,可以在lunch
方案后使用hmm打印出所有tina提供的快捷命令。

  1. ckernel, m kernel_menuconfig, mkernel:分别对应进入到内核目录,配置内核,单独编译内核
  2. cboot0, mboot0:进入boot0 目录,单独编译boot0
  3. cmelis, mmelis, mmelis menuconfig:分别对应进入melis 根目录,编译melis,配置melis
  4. make:编译整个tina 除了melis 外的所有东西,如boot0,uboot,内核,跟文件系统等
  5. cconfigs:进入板级配置目录,这里主要存放板级的设备树,分区等配置文件
  6. p:打包命令,将编译后的东西打包成固件

5 E907 启动环境

5.1 预先工作

选择方案

cd tina
source build/envsetup.sh
lunch
选择对应的V85x方案

5.2 配置boot0 启动e907

e907 在boot0 阶段启动,需要对boot0 进行一些配置

cboot0
vim board/sun8iw21p1/common.mk
# 如下图取消注释
保存退出
mboot0 #编译

图5-1: 配置1

5.2.1 关闭RISCV 的IOMMU

本步骤只有需要在boot0 阶段启动E907 的需要配置。打开设备树,注释掉下面2 条属性,因为
e907 在boot0 阶段就启动了,不能打开其IOMMU。

cconfigs
vim ../board.dts

图5-2: 关闭IOMMU

5.3 配置打包e907 固件

cconfigs
cd ../../default/
vim boot_package_nor.cfg # 取消melis-elf选项的注释,如下图
vim boot_package.cfg # 取消melis-elf选项的注释,如下图
保存退出

图5-3: 打包配置

5.4 Linux 配置

ckernel
m kernel_menuconfig
# 如下图选中2个驱动
mkernel -j

图5-4: 补丁下载

mmelis menuconfig # 如下图选中standby支持

图5-5: e907-standby 配置

5.5 编译打包

至此关于E907 启动的配置完成,进行编译烧录即可

make -j16 # 编译tina
mmelis # 编译melis
p
烧录

6 AMP 环境搭建

AMP 环境用于Linux 和E907 间通信,Linux 依赖于2 个驱动,melis 依赖于openamp 驱
动。

  1. remoteproc 驱动:主要用来管理E907 固件的加载器的
  2. rpmsg:在virtio 框架上实现的消息传送框架

6.1 Linux 配置

注意:需要前面的启动环境配置好后,再执行以下操作。
需要打开的配置有:

  1. remoteproc 驱动
  2. rpmsg 驱动

6.1.1 remoteproc 驱动

ckernel
m kernel_menuconfig

选中

图6-1: rproc config

6.1.2 rpmsg 驱动

ckernel
m kernel_menuconfig
# 红框必选,蓝色框为sdk提供的rpmsg demo,视情况而选择
# 建议选上sunxi rpmsg ctrl driver 方便后面测试rpmsg通信功能

选中

图6-2: rpmsg config

6.2 melis 配置

主要进行2 个配置:

  1. msgbox 配置
  2. openamp 配置

6.2.1 msgbox 配置

mmelis menuconfig #选择下面2项

选中

图6-3: msgbox-melis config

6.2.2 openamp 配置

mmelis menuconfig# 红框是必选,蓝框是可选的rpmsg demo

刚刚Linux 端选择了rpmsg hearbeat demo 和ctrl driver,我们这里也选上对应的驱动hearbeatdriver 和client driver。
选中

图6-4: openamp config

为了方便在控制台测试rpmsg 通信,rpmsg client driver 还需开启下面2 个选项

图6-5: rpmsg client config

6.3 打包

make -j16 # 编译tina
mmelis # 编译melis
p
烧录

6.4 测试

本章节介绍一些AMP 提供的控制台命令,用于测试AMP 环境

6.4.1 E907 控制

1.在linux 控制台执行:echo stop > /sys/kernel/debug/remoteproc/remoteproc0/state
(停止e907)

2.在linux 控制台执行:echo start > /sys/kernel/debug/remoteproc/remoteproc0/state
(启动e907)

若控制台出现remoteproc0: remote processor e907_rproc is now up,表明启动e907 成功。
如果使能了rpmsg_heartbeat 和rpmsg_ctrl 驱动,可以在Linux 控制台start 之后会看到如下输出:

图6-6: rproc test

红框里面表示有2 个设备成功创建,代表rpmsg 正常。

6.4.2 rpmsg 通信测试

借助rpmsg_ctrl 驱动帮助我们进行测试

6.4.2.1 名字监听.

平台:melis 控制台
输入如下图命令:
eptdev_bind 命令:监听name=test 的链接,最大连接数5 个

图6-7: rproc test

6.4.2.2 节点创建

平台:Linux 控制台
输入如下图的命令,进行节点创建

图6-8: rpmsg test

图6-9: rpmsg test

根据log 可以看出,创建了一个rpmsg0-4 5 个设备,因为melis 只监听的5 个,故最多只能创建5 个。

6.4.2.3 节点通信

rpmsg 节点支持标准的文件操作,直接读写即可。
Linux 向e907 发数据:

图6-10: rpmsg test

图6-11: rpmsg test

e907 向Linux 发数据:

图6-12: rpmsg test

图6-13: test

6.4.2.4 节点关闭

Linux 主动释放:

图6-14: rpmsg test

图6-15: rpmsg test

e907 主动释放:

图6-16: rpmsg test

图6-17: rpmsg test

e907 端接触监听,会释放所有的链接:

图6-18: rpmsg test

图6-19: rpmsg test

7 开发使用

7.1 rpmsg 内核开发

linux 端请参考driver/rpmsg/rpmsg_client_e907.c 。

melis 端请参考ekernel/subsys/thirdparty/openamp/rpmsg_demo/ 目录下的文件。

7.2 rpmsg 用户层接口

控制台调试命令参考测试章节,这里列举代码使用示例。

Linux 端:

#include <linux/rpmsg.h>
# 创建端点
int fd;
struct rpmsg_ept_info info;
char ept_dev_name[32];
strcpy(info.name, "test");
info.id = 0xfffff; # id由itctl进行更新
fd = open(ctrl_dev, O_RDWR);
ret = ioctl(fd, RPMSG_CREATE_EPT_IOCTL, &info);
# 当ioctl返回值==0时,端点已经创建成功,设备节点会出现在/dev/rpmsg%d(=info.id)下
close(fd);
#读写设备节点
snprintf(ept_dev_name, 32, "/dev/rpmsg%d", info.id);
fd = open(ept_dev_name, O_RDWR);
write,read,poll...
close(fd);
# 关闭节点
fd = open(ctrl_dev, O_RDWR);
ret = ioctl(fd, RPMSG_DESTROY_EPT_IOCTL, &info);
close(fd);

melis 端:

方法1:基于rpmsg_ctrl 驱动,等待主机建立连接

// 头文件
#include <openamp/sunxi_helper/openamp.h>
static int ept_cb(struct rpmsg_endpoint *ept, void *data,
size_t len, uint32_t src, void *priv)
{
// 收到数据
}
int bind_cb(struct rpmsg_ept_client *client)
{
// client绑定,每个client代表一个连接
// client->priv和client->ept->priv 可供用户使用
}
int unbind_cb(struct rpmsg_ept_client *client)
{
// 连接关闭
}
int main()
{
// cnt: 监听的数量,即最多对test创建cnt个连接
// 最后一个参数priv,其实里面设置的是client->priv
rpmsg_client_bind("test", ept_cb, bind_cb, unbind_cb,
cnt, NULL);
// do some things
// 取消绑定会unbind所有与其相关的client
rpmsg_client_unbind("test");
}

具体代码参考ekernel/subsys/thirdparty/openamp/rpmsg_demo/rpmsg_ctrl/test.c;

方法2:基于rpmsg 原生框架,melis 端主动创建连接,触发主机端的rpmsg driver 的probe。

melis 端代码参考:

1.ekernel/subsys/thirdparty/openamp/rpmsg_demo/demo.c

2.ekernel/subsys/thirdparty/openamp/rpmsg_demo/hearbeat.c

Linux 端参考代码:

1.drivers/rpmsg/rpmsg_client_e907.c

2.drivers/rpmsg/rpmsg_client_heart.c

7.3 amp 控制台

SDK 在Linux 端提供了进入E907 控制台的功能,配置步骤如下:

内核配置

ckernel
m kernel_menuconfig # 选择下图配置

图7-1: rpmsg config

Tina 配置

croot
m menuconfig # 选择下图配置

图7-2: amp_shell config

melis 配置

图7-3: amp_shell config

编译& 打包& 下载

mmelis -j32
make -j32
p

使用

在echo start > /sys/kernel/debug/remoteproc/remoteproc0/state 后检查有无rpmsg_ctrl 成功创建的log 或者是否存在/dev/rpmsg_ctrl0 节点。如果正常,直

接在Linux 控制台啊输入amp_shell 即可进入e907 控制台,amp_exit退出控制台。支持执行多次amp_shell,开启多个控制台。

图7-4: amp_shell test

图7-5: amp_shell test

7.4 大数据传输

由于rpmsg 特性,不适合传输大数据量;如需使用大数据传输,请参考本章节。

7.4.1 配置

内核打开rpbuf 驱动:

m kernel_menuconfig
Device Drivers --->RPBuf drivers --->-*- RPBuf device interface<*> RPMsg-based RPBuf service driver<*> Allwinner RPBuf controller driver<*> Allwinner RPBuf sample driver

Note:Allwinner RPBuf sample driver 是一个简单的rpbuf 内核层使用demo,可以不使能。

e907 配置:

Kernel SetupSubsystem supportAllwinner Components SupportRPBuf framework[*] RPMsg-based RPBuf service component[*] RPBuf controller component[*] RPMsg-based RPBuf service component demoOpenAMP Support[*]  RPBuf demo

Tina 打开rpbuf_demo 软件包:

m menuconfig
Allwinner --->RPBuf ---><*> rpbuf_demo<*> rpbuf_test

7.4.2 测试

rpmsg_test:会自动生成随机数据并附带MD5 校验值,另一端收到会重新计算MD5 并与收到的进行对比。

(e907) rpbuf_test -c -N "rpbuf_demo" -L 0x100000 # 创建size=0x100000的buffer
(Linux) rpbuf_test -d 1000 -s -L 0x100000 -N "rpbuf_demo" # 发送测试数据
(Linux) rpbuf_test -r -t 1000 -L 0x100000 -N "rpbuf_demo" # 接收数据
(e907) rpbuf_test -s -L 0x100000 -N "rpbuf_demo" #发送测试数据
(e907) rpbuf_test -N "rpbuf_demo" -d # 删除buffer

出现success 表明校验成功。

过程log 如下:

图7-6: Linux 端log

图7-7: e907 端log

rpbuf_demo:用于在控制台简单传输数据

(e907) rpbuf_demo -c -N "rpbuf_demo" -L 0x1000 # 创建size=4k的buffer
(Linux) rpbuf_demo -d 1000 -L 0x1000 -N "rpbuf_demo" -s "hello" # 发送数据,并在1000ms后释放
buffer
(Linux) rpbuf_demo -r -t 1000 -L 0x1000 -N "rpbuf_demo" # 接收数据
(e907) rpbuf_demo -s "hello" -N "rpbuf_demo" # 发送数据
(e907) rpbuf_demo -N "rpbuf_demo" -d # 删除buffer

图7-8: Linux 端log

图7-9: e907 端log

7.4.3 使用

内核层接口,参考drivers/rpbuf/rpbuf_sample_sunxi.c:
Linux 端使用流程:

  1. 在需要用到rpbuf 接口的驱动的设备树节点种添加一条属性:rpbuf = <&rpbuf_controller0>;,
    可以创建多个controller,当面默认只有一个rpbuf_controller0;

  2. 获取controller:调用controller = rpbuf_get_controller_by_of_node(np, 0);

  3. 创建buffer:调用rpbuf_alloc_buffer(controller, name, len, ops, cbs, priv);

  4. 接收数据:收到数据时候会调用cbd->rx_cb 回调

  5. 判断状态:创建出的buffer 不一样马上可用,需要用判断状态,调用rpbuf_buffer_is_available(buffer)

  6. 发送数据:

  7. buf_va = rpbuf_buffer_va(buffer);

  8. buf_len = rpbuf_buffer_len(buffer);

  9. 直接对buf_va 地址进行写入即可

  10. rpbuf_transmit_buffer(buffer, offset, data_len);

  11. 释放buffer:rpbuf_free_buffer(buffer);

    应用层端口,具体细节可以参考package/allwinner/rpbuf/

    1. 创建buffer
    2. fd = open(0, O_RDWR);
    3. ioctl(fd, RPBUF_CTRL_DEV_IOCTL_CREATE_BUF, &buffer->info);
    4. buf_fd = open(buf_dev_path, O_RDWR);
    5. addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, buf_fd, 0);
    6. 接收数据:
    7. rpbuf_receive_buffer_block(buffer, &offset, &data_len) 阻塞接收
    8. rpbuf_receive_buffer_nonblock(buffer, &offset, &data_len) 非阻塞接收
    9. 发送数据:
    10. buf_va = rpbuf_buffer_va(buffer);
    11. 直接对buf_va 地址进行写入即可
    12. rpbuf_transmit_buffer(buffer, offset, data_len);
    13. 释放buffer:
    14. close(buf_fd);
    15. ioctl(fd, RPBUF_CTRL_DEV_IOCTL_DESTROY_BUF, &buffer->info);
    16. close(fd);

e907 端接口,可以参考ekernel/subsys/aw/rpbuf/rpbuf_demo/rpbuf_demo.c
e907 端使用流程:

  1. 获取controller:调用controller = rpbuf_get_controller_by_id(0); 代码默认提供一个controller,
    这里直接使用
  2. 创建buffer:调用rpbuf_alloc_buffer(controller, name, len, ops, cbs, priv);
  3. 接收数据:收到数据时候会调用cbd->rx_cb 回调
  4. 判断状态:创建出的buffer 不一样马上可用,需要用判断状态,调用rpbuf_buffer_is_available
    (buffer)
  5. 发送数据:
  6. buf_va = rpbuf_buffer_va(buffer);
  7. buf_len = rpbuf_buffer_len(buffer);
  8. 直接对buf_va 地址进行写入即可
  9. rpbuf_transmit_buffer(buffer, offset, data_len);
  10. 释放buffer:rpbuf_free_buffer(buffer);

7.4.4 Note

  1. 关于controller:代码默认已经提供了一个基于rpmsg 实现的controller0 了,正常情况下
    直接使用改controller 即可
  2. 关于rpbuf_alloc_buffer 的ops 参数:controller0 已经基于ion 实现了内存分配函数。如
    无必要,使用controller 的内存分配函数即可,即创建buffer 时,ops 参数置NULL。
  3. 关于互斥:由于通信双方都能拿到的buffer 的地址,难以在驱动实现互斥,所以需要在具体
    应用上自行保证互斥。

8 其他

8.1 rpmsg 需知

  1. 端点是rpmsg 通信的基础;每个端点都有自己的src 和dst 地址,范围(1 - 1023,除了0x35)

  2. rpmsg 每次发送数据最大为512 -16 字节;(数据块大小为512,头部占用16 字节)

  3. rpmsg 使用name server 机制,当E907 创建的端点名,和linux 注册的rpmsg 驱动名一样的时候,rpmsg bus 总线会调用其probe 接口。所以如果需要

Linux 端主动发起创建端点并通知e907,则需要借助上面提到的rpmsg_ctrl 驱动。

  1. rpmsg 是串行调用回调的,故建议rpmsg_driver 的回调中不要调用耗时长的函数,避免影响其他rpmsg 驱动的运行

8.2 rpbuf 简介

rpbuf 全志基于rpmsg 开发的一套通信机制,它主要解决rpmsg 不适合传输大数据量的问题。
其实现原理是使用rpmsg 传输数据的地址,而不是数据的本身,避免了数据的多次拷贝以及每次
传输不能大于496 字节的限制。
rpbuf 中使用名字和长度来唯一标识一个buffer,故不能创建相同名字的buffer。
rpbuf 中的buffer 有3 个状态:

  1. remote_dummy_buffers:该buffer 远端已创建,本地未创建
  2. local_dummy_buffers:该buffer 本地已创建,远端未创建
  3. buffers:远端、本地已创建,此时buffer 才可用

8.3 修改e907 地址

目前在perf1 板子上,给e907 预留的内存为:0x48000000 开始的4M 空间

如果需要修改E907 固件的运行地址和大小,可按如下步骤进行修改:

8.3.1 修改设备树(Linux)

cconfigs
vim ../board.dts
# 找到e907_dram项,修改成想要的地址,例如这里向修改成0x49000000
e907_dram: riscv_memserve {
reg = <0x0 0x49000000 0x0 0x00400000>;
no-map;
};
# 重新编译内核
mkernel

8.3.2 修改配置项(melis)

mmelis menuconfig
# 如下图进行修改;e907没有mmu,故第一项和第二项相等
# 将第一项和第二项改成0x49000000
# 第三项为大小,可按需修改

图8-1: e907 dram config

8.3.3 修改链接脚本(melis)

cmelis
vim source/projects/v853-e907-ver1-board/kernel.lds
# 如下图所示,按照所需修改DRAM_SEG_KRN 项目
mmelis -j16

图8-2: e907 lds config

8.4 添加新板级注意事项

当用户需要添加新的板子时,需要注意修改build/expand_melis.sh 来支持mmelis, cmelis命令。例如,用户在添加了新的板级v853_user,在melis 添加了新的板

级e907_user,则需要对build/expand_melis.sh文件进行如下修改:

图8-3: 新板级配置

8.5 melis 系统

8.5.1 常用命令

  1. help:列出当前系统支持的所有命令
  2. p addr [len]:打印内存数据
  3. m addr value:修改内存数据
  4. top:显示当前系统各个线程CPU 占用率
  5. ps:显示当前系统各个线程状态
  6. free:查看当前系统内存信息

8.5.2 自定义命令

当用户想要在e907 控制台上执行自定义的命令时候,可以用FINSH_FUNCTION_EXPORT_ALIAS导出自定义的函数。例如:

图8-4: 添加自定义命令

图8-5: 执行自定义命令

全志 Tina Linux RISC-V E907核心开发指南支持百问网V85x系列开发板100ask-v853-pro v851s等相关推荐

  1. 全志Tina Linux MPP (多媒体框架)开发指南支持百问网T113 D1-H哪吒DongshanPI-D1s V853-Pro等开发板

    1 简述 整理 MPP sample 使用说明文档的目的是:使 MPP sample 更好用. 2 简介 MPP sample 一般存放在 MPP Middleware 的 sample 目录下.此外 ...

  2. 全志Tina Linux Camera 摄像头模块开发指南 全网最详细版本支持百问网T113-Pro DongshanPI-NezhaD1-H DongshanPI-D1s V853-Pro等开发板

    1 概述 编写目的:介绍camera 模块在sunxi 平台上的开发流程. 适用范围:本文档目前适用于tina3.0 以上具备camera 的硬件平台. 2 模块介绍 2.1 模块功能介绍 用于接收并 ...

  3. 全志 Tina Linux LCD显示屏调试指南 支持MIPI DSI RGB LVDS I8080 SPI等接口,开发板支持百问网T113 D1-H哪吒 DongshanPI-D1s V853

    1 概述 编写目的 本文档将介绍sunxi 平台Display Engine 模块中LCD 的调试方法. LCD 调试方法,调试手段. LCD 驱动编写. lcd0 节点下各个属性的解释. 典型LCD ...

  4. 全志Tina Linux MPP 开发指南

    全志Tina Linux MPP 开发指南支持百问网T113 D1-H哪吒DongshanPI-D1s V853-Pro等开发板 1 简述 整理 MPP sample 使用说明文档的目的是:使 MPP ...

  5. Mastering Embedded Linux Programming 学习 (二)在百问网157开发板上,编译构建u-boot

    Mastering Embedded Linux Programming 学习 (二)在百问网157开发板上,编译构建u-boot 一.下载u-boot源码 git clone https://git ...

  6. Mastering Embedded Linux Programming 学习 (五)在百问网157开发板上,解决网络配置问题

    Mastering Embedded Linux Programming 学习 (五)在百问网157开发板上,解决网络配置问题 思考.参考 搜索发现,需要配置设备树,参考这个链接 修改设备树 找到百问 ...

  7. Mastering Embedded Linux Programming 学习 (三)在百问网157开发板上,编译构建linux内核

    Mastering Embedded Linux Programming 学习 (三)在百问网157开发板上,编译构建linux内核 一.下载内核源码 wget http://ftp.sjtu.edu ...

  8. 基于百问网IMX6ULL_PRO开发板的Uboot移植(Uboot-2017.03)

    文章目录 引言 Uboot下载 Uboot目录分析 目录分析 移植所需要关注的目录 首次编译下载Uboot 编译 下载 方法1 方法2 方法3 现象 移植Uboot 添加自己单板相关文件 添加修改单板 ...

  9. 开发指南专题七:JEECG微云快速开发平台查询HQL过滤器

    开发指南专题七:JEECG微云快速开发平台 HQL过滤器 1. 查询HQL过滤器 1.1. 数据过滤现状分析 项目开发的查询页面都会有很多查询条件,开发追加查询条件的工作繁琐又很浪费时间. 这块工作量 ...

最新文章

  1. Elixir 1.3带来新的语言功能、API和改进后的工具
  2. 前端一HTML:六:标签的关系,分类
  3. Cache模拟器(CacheSim)
  4. CSS中的!important属性用法
  5. linux mysql迁移,Linux 下安装MySQL并迁移备份
  6. Java—List集合详解
  7. 直播预告丨云时代的数据库客户端——CloudQuery最佳实践
  8. [设计模式-结构型]装饰模式(Decorator)
  9. 安装Labview2012 “labview 2012 未定义必须的 NIPathsDir属性 maxAFWDIR”
  10. windows 互斥量内核对象 Mutex
  11. select标签,根据标签的文本值设置选中状态不生效的解决
  12. (机器人学导论--运动学)(三)DH表达法顺向运动学
  13. html img标签的alt属性和title属性(说明)
  14. BroadcastReceiver生命周期探讨
  15. JAVA面试题大全,收藏这一篇就够了
  16. ld-linux-x86-64.so.2挖矿木马,排查操作记录
  17. YY游戏云的AngularJS实践
  18. 算法导论课后题和思考题 第3章
  19. 架构师的工作都干些什么?!想做架构师必看
  20. LeetCode 415.字符串相加

热门文章

  1. 100种思维模型之大脑系统思维模型-52
  2. win8.1计算机无法管理员权限设置,Win8.1系统如何恢复管理员权限
  3. 自动写文章生成器,为你一键生成原创文章!
  4. Android 静态和动态的调用so库(JNI)
  5. 3A链游大作BigTime保姆级研报
  6. on1 effects 2021(照片滤镜调色软件) v15.0.1.9783
  7. 中南财的计算机就业怎么样,“四财一贸”中知名财经类院校的毕业生薪酬怎么样?速来了解下~...
  8. 发布到google Play的app搜索不到问题的解决
  9. girdFS 存储照片,保存照片到硬盘
  10. 串口低频刷卡密码键盘ID卡发卡器YD791开关设置选择