Firefly开源社区

标题: ROC-RK3566安卓RKNN模型例程无法使用,且会导致重启 [打印本页]

作者: zwmasdf    时间: 2021-8-20 15:40
标题: ROC-RK3566安卓RKNN模型例程无法使用,且会导致重启
本帖最后由 zwmasdf 于 2021-8-20 15:45 编辑

如题,安卓RKNN模型无法按照例程跑,主要有以下几个问题
一、rknnrt/examples/rknn_mobilenet_demo下的例程无法编译,按照ReadMe.md的步骤无法完成CMake的编译
       主要修改了:ANDROID_NDK_PATH=......../Android/Sdk,这里不管指向Sdk还是指向Sdk/ndk、21.4.7075529都无法导致编译成功,
       然后尝试修改了19行的cmake为C:/Users/R190095/AppData/Local/Android/Sdk/cmake/3.10.2.4988404/bin/cmake还是无法编译成功,
       提示无法找到....../Android/Sdk/platforms/android-24,然后去Sdk/platforms下找,发现没有android-24的文件夹,至此,放弃该编译方式。
       使用第二种NDK+Cmake编译
二、使用Android Studio新建Native C++工程
       修改app/build.gradle,修改如下:
  1. defaultConfig {
  2.     ......
  3.     externalNativeBuild {
  4.         cmake {
  5.             cppFlags ''
  6.             abiFilters 'armeabi-v7a', "arm64-v8a"
  7.         }
  8.     }

  9.     ndk {
  10.         abiFilters 'armeabi-v7a', "arm64-v8a"
  11.     }
  12. }
复制代码
   然后将rknn相关lib和头文件加到工程中,如图所示
   
    然后修改CMakeList.txt,代码如下:
  1. cmake_minimum_required(VERSION 3.10.2)

  2. project("mytest")

  3. add_library(
  4.         mytest
  5.         SHARED
  6.         native-lib.cpp)

  7. include_directories(${CMAKE_SOURCE_DIR}/include)

  8. add_library(rknn_api_android #这里不管有没有android后缀都一样
  9.         SHARED
  10.         IMPORTED)

  11. set_target_properties(rknn_api_android #这里不管有没有android后缀都一样
  12.         PROPERTIES IMPORTED_LOCATION
  13.         ${CMAKE_SOURCE_DIR}/lib/${ANDROID_ABI}/librknn_api_android.so) #这里不管有没有android后缀都一样

  14. add_library(rknnrt
  15.         SHARED
  16.         IMPORTED)

  17. set_target_properties(rknnrt
  18.         PROPERTIES IMPORTED_LOCATION
  19.         ${CMAKE_SOURCE_DIR}/lib/${ANDROID_ABI}/librknnrt.so)

  20. find_library(
  21.         log-lib
  22.         log)

  23. target_link_libraries(
  24.         mytest

  25.         rknn_api_android  #这里不管有没有android后缀都一样
  26.         rknnrt

  27.         ${log-lib})
复制代码
   接着修改native-lib.cpp代码,内容如下:
   
  1. #include <jni.h>
  2. #include <string>
  3. #include <android/log.h>
  4. #include <pthread.h>

  5. #include "rknn_api.h"

  6. #define TAG "NATIVE_LIB"

  7. #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)

  8. static unsigned char *load_model(const char *filename, int *model_size)
  9. {
  10.     FILE *fp = fopen(filename, "rb");
  11.     if(fp == nullptr) {
  12.         LOGD("fopen %s fail!\n", filename);
  13.         return nullptr;
  14.     }
  15.     fseek(fp, 0, SEEK_END);
  16.     int model_len = ftell(fp);
  17.     unsigned char *model = (unsigned char*)malloc(model_len);
  18.     fseek(fp, 0, SEEK_SET);
  19.     if(model_len != fread(model, 1, model_len, fp)) {
  20.         LOGD("fread %s fail!\n", filename);
  21.         free(model);
  22.         return nullptr;
  23.     }
  24.     *model_size = model_len;
  25.     fclose(fp);
  26.     return model;
  27. }

  28. void* test(void *arg) {
  29.     int model_len = 0;
  30.     unsigned char *model = nullptr;
  31.     rknn_context ctx;
  32.     int ret;

  33.     model = load_model("/vendor/model/mobilenet_v1.rknn", &model_len);
  34.     if(!model) {
  35.         LOGD("load model failed\n");
  36.         return nullptr;
  37.     }
  38.     LOGD("load model ok");
  39.     ret = rknn_init(&ctx, model, model_len, 0, nullptr);
  40.     if(ret < 0) {
  41.         LOGD("rknn_init fail! ret=%d\n", ret);
  42.         return nullptr;
  43.     }
  44.     LOGD("rknn_init ok");
  45.     return nullptr;
  46. }

  47. extern "C" JNIEXPORT jstring JNICALL
  48.         Java_com_example_mytest_MainActivity_stringFromJNI(
  49.     JNIEnv* env,
  50.     jobject /* this */) {
  51.     std::string hello = "Hello from C++";
  52.     LOGD("hello");
  53.     int err;
  54.     pthread_t ntid;
  55.     err = pthread_create(&ntid, nullptr, test, nullptr);
  56.     if (err != 0) {
  57.         LOGD("can't create thread: %s\n", strerror(err));
  58.     }

  59.     return env->NewStringUTF(hello.c_str());
  60. }
复制代码

    然后使用adb root && adb remount激活root(前提是安卓启用开发者并启用root)
    接着把rknn_mobilenet_demo下的model文件夹通过adb push model /vendor/拷贝到开发板内
    接着adb push Android/rknn_server/${BOARD_ARCH}/rknn_server到/vendor/bin目录,这里试了切换不同架构的rknn_server也不行
    然后adb push Android/librknn_api/${BOARD_ARCH}/librknnrt.so到/vendor/lib64(64位系统特有)和/vendor/lib目录,换架构也不行
    然后adb shell进入控制台, 并通过su切换成root, 接下来执行:
           chmod 777 /vendor/bin/rknn_server
           setenforce 0
           /vendor/bin/rknn_server &

    然后编译安卓程序,运行后控制台依次打印hello和load model ok,然后卡住了,app上也没显示Hello from C++
    然后过了几秒钟开发板重启了,尝试切换架构,push不同的文件到开发板,都不行
    后来去/vendor/lib和/vendor/lib64下看librknnrt.so文件属性,发现都是只读的,而且无法删除


以上是尝试调用rknn的过程,但是一直以失败而告终,请求支持


作者: zyk    时间: 2021-8-20 16:29
不建议使用太新的NDK版本,参考脚本的版本android-ndk-r16b
作者: zwmasdf    时间: 2021-8-20 16:37
zyk 发表于 2021-8-20 16:29
不建议使用太新的NDK版本,参考脚本的版本android-ndk-r16b

那问题二重启又是咋回事
作者: zyk    时间: 2021-8-20 17:13
固件是什么版本,跑官方demo是否会重启
作者: zwmasdf    时间: 2021-8-20 17:32
Firefly版本为:
rk3566_roc_pc/Android11.0/V1.0.2106160927/8849e45f60b4
版本号:
rk3566_roc_pc-userdebug 11 RQ1D.210105.003.eng.lzf.20210616.092756 release-keys
跑官方demo直接失败了,demo从:https://www.t-firefly.com/doc/download/103.html#other_478下载下来的
但是跑官方demo也会重启,步骤如下:
adb root
adb remount
adb push ./rknn_ssd_demo /vendor
adb push ./model /vendor
adb shell
su
setenforce 0
/vendor/bin/rknn_server &
cd /vendor
chmod 777 rknn_ssd_demo
./rknn_ssd_demo ./model/ssd_inception_v2.rknn  ./model/road.bmp
作者: zyk    时间: 2021-8-21 08:57
更新到最新的固件试试
作者: zwmasdf    时间: 2021-8-23 08:19
zyk 发表于 2021-8-21 08:57
更新到最新的固件试试

ROC-3566的安卓固件百度云提取码有误
作者: zyk    时间: 2021-8-23 09:15
提取码可以正常操作,请检查输入是否有误

作者: zwmasdf    时间: 2021-8-23 13:34
zyk 发表于 2021-8-23 09:15
提取码可以正常操作,请检查输入是否有误

3566和3568固件通用吗
作者: zwmasdf    时间: 2021-8-23 16:32
zyk 发表于 2021-8-23 09:15
提取码可以正常操作,请检查输入是否有误

现在不会重启了,但是rknn_init()返回-7,不知道是什么原因,换rknn模型也不行
作者: zyk    时间: 2021-8-23 16:54
按wiki教程走一下看一下是否有遗漏的步骤https://wiki.t-firefly.com/ROC-RK3566-PC/usage_npu.html
作者: zwmasdf    时间: 2021-8-24 08:23
zyk 发表于 2021-8-23 16:54
按wiki教程走一下看一下是否有遗漏的步骤https://wiki.t-firefly.com/ROC-RK3566-PC/usage_npu.html

找到问题了,但是文档有自相矛盾的地方,rknnrt/doc/Rockchip_RK356X_User_Guide_RKNN_API_V1.1.0_CN.pdf中3.3.1章节安卓平台要求应用链接librknn_api_android.so,但是实际就是rknn_init返回错误,改成librknn_api.so就不会rknn_init错误了,请问两者有何区别,为什么文档描述的是错误的。
作者: zyk    时间: 2021-8-24 08:56
如文档描述,是否有生成相应的库

  1. /system/lib/librknn_api_android.so
  2. /system/lib/librknnhal_bridge.rockchip.so
  3. /system/lib64/librknn_api_android.so
  4. /system/lib64/librknnhal_bridge.rockchip.so
  5. /vendor/lib64/rockchip.hardware.neuralnetworks@1.0.so
  6. /vendor/lib64/rockchip.hardware.neuralnetworks@1.0-adapter-helper.so
  7. /vendor/lib64/librknnrt.so
  8. /vendor/lib64/hw/rockchip.hardware.neuralnetworks@1.0-impl.so
复制代码



作者: zwmasdf    时间: 2021-8-24 09:48
zyk 发表于 2021-8-24 08:56
如文档描述,是否有生成相应的库

我是直接用下载的资料里的库的,但是按照文档链接librknn_api_android.so是不行的,一定要链接librknn_api.so才行,这是什么原因呢,两者有何区别
作者: zyk    时间: 2021-8-24 10:07
本帖最后由 zyk 于 2021-8-24 10:08 编辑

  1. <div>
  2. <div>#链接librknnrt.so</div></div><div><div>rknn_ssd_demo_Android
  3.     ├── lib
  4.     │&nbsp;&nbsp; ├── librknn_api.so -> librknnrt.so
  5.     │&nbsp;&nbsp; └── librknnrt.so
  6.     ├── model
  7.     │&nbsp;&nbsp; ├── box_priors.txt
  8.     │&nbsp;&nbsp; ├── coco_labels_list.txt
  9.     │&nbsp;&nbsp; ├── road.bmp
  10.     │&nbsp;&nbsp; └── ssd_inception_v2.rknn
  11.     └── rknn_ssd_demo
  12. </div></div>
复制代码





欢迎光临 Firefly开源社区 (https://dev.t-firefly.com/) Powered by Discuz! X3.1