注意,虽然是开发程序,但是这块处理器涉及到TPU,且官方的基本环境以及教程没出完,导致这块处理器的开发SDK其实是分化的。分为常规APP开发以及TPU开发。开发TPU可以兼容APP。
其次,这颗处理器刨开RiscV和ARM V53的二选一。它还包含一个700Mhz的大MUC核,一个8051的小MCU小核。
但是很不幸,相比于CV1800B,这颗处理器的协同核开发SDK还没制作完毕。它的freertos大核毫无资料。小核8051也只给了个JTAG接口,甚至和主核的通信资料都没给出。
更离谱的事很多时候它的资料仍然和CV18XX的资料共用。导致很多库和资源现在根本对不上。
首先官方给出了基本APP的sdk,那就是host-tools。
但是,你查过它的例程才会知道,它默认编译选项用的库版本不对!你需要特意选择你对应的核版本。因此你的CFLAGS和CXXFLAGS(注意,大部分库都会同时识别CXXFLAGS和CPPFLAGS,但是个别奇葩库只认CPPFLAGS)
CFLAGS="-mcpu=c906fdv -march=rv64imafdcv0p7xthead -mcmodel=medany -mabi=lp64d"
CFLAGS和CXXFLAGS在这部分的设置是完全一样的。
根据我现在编译的库。大部分库和2024/03/17时候各官方库公布的最新版本是一样的。下载时候记得看看版本公布时间。
官方默认固件使用的gcc host版本为riscv64-unknown-linux-musl
对于部分不认基础环境变量的库,和需要双编译的库需要特殊处理。但是大部分库使用下面代码可以安全编译过去
export TOOLCHAIN=/home/host-tools/gcc/riscv64-linux-musl-x86_64/bin PREFIX=/home/host-tools/gcc/riscv64-linux-musl-x86_64/sysroot/usr TARGET=riscv64-unknown-linux-musl CC=TOOLCHAIN/riscv64-unknown-linux-musl-gcc CXX=TOOLCHAIN/riscv64-unknown-linux-musl-g++ NM=TOOLCHAIN/riscv64-unknown-linux-musl-nm RANLIB=TOOLCHAIN/riscv64-unknown-linux-musl-ranlib LD=TOOLCHAIN/riscv64-unknown-linux-musl-ld AR=TOOLCHAIN/riscv64-unknown-linux-musl-ar STRIP=TOOLCHAIN/riscv64-unknown-linux-musl-strip CPATH=PREFIX/include LIBRARY_PATH=PREFIX/lib CFLAGS="-fPIC --sysroot=PREFIX/../ -mcpu=c906fdv -march=rv64imafdcv0p7xthead -mcmodel=medany -mabi=lp64d" CXXFLAGS="-fPIC --sysroot=PREFIX/../ -mcpu=c906fdv -march=rv64imafdcv0p7xthead -mcmodel=medany -mabi=lp64d" CPPFLAGS="-fPIC --sysroot=PREFIX/../ -mcpu=c906fdv -march=rv64imafdcv0p7xthead -mcmodel=medany -mabi=lp64d" LDFLAGS="-LPREFIX/lib -Wl,-rpath-link=PREFIX/lib -mcpu=c906fdv -march=rv64imafdcv0p7xthead -mcmodel=medany -mabi=lp64d" SYSROOT=$PREFIX/../ MAKEFLAGS="-j24"
自己的环境需要做如下改动:
首先TOOLCHAIN
是你的编译器基本地址,也就是编译器bin目录所在位置。
第二是PREFIX
是你库安装位置。官方给做了sysroot
,你直接加紧sysroot按照标准隔离环境做就行。没必要强行分。到时候多版本编译它会自动加入版本尾号的so文件。这是linux应对多版本的一个方法,可以自行查询。
对于MAKEFLAGS
来说就是你编译代码用几个线程。和make -j n
的-j n
的作用一样。根据电脑性能自己改。
其他变量都是根据TOOLCHAIN
和PREFIX
生成出来的。但是也要注意,因为第一次运行这俩变量其实不存在。因此想要完整加载这些变量,需要将这个export的代码 在bash中连续运行2次 。
本人是在docker中进行的编译。因此清除这些变量最好的办法就是直接退出docker命令行重新进入。对于真机编译的勇士,或者没有条件使用隔离环境的同志。这些设置的所有变量系统默认都是空的。因此对上卖弄每一个设置的环境变量进行unset NAME
就能清空这些环境变量。
比如说:
json-c 0.17
glib 2.80.0
由于几乎系统除了json-c库,其实几乎只提供了std库和libc库,所以大部分款本自己开心就好了。
注意,系统镜像额外提供了glib。但是和2.80能兼容
对于绝大多数情况,这点库文件消耗内存不足一提。因此加载自己的独立库系统也可以。但是记住别一个APP加载一套。因为这个处理器的内存实在是太捉襟见肘了。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include <glib-2.0/glib.h>
#include <linux/gpio.h>
#define LOG_TAG "main"
#include <elog.h>
#include <json-c/json.h>
#include "IdHelper.h"
gboolean callback(gpointer argv){
log_i("run a task");
return true;
}
int main(int argc, char* argv[]){
// setbuf(stdout, NULL);
elog_init();
elog_set_fmt(ELOG_LVL_ASSERT, ELOG_FMT_ALL);
elog_set_fmt(ELOG_LVL_ERROR, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
elog_set_fmt(ELOG_LVL_WARN, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
elog_set_fmt(ELOG_LVL_INFO, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
elog_set_fmt(ELOG_LVL_DEBUG, ELOG_FMT_ALL & ~ELOG_FMT_FUNC);
elog_set_fmt(ELOG_LVL_VERBOSE, ELOG_FMT_ALL & ~ELOG_FMT_FUNC);
elog_set_text_color_enabled(true);
elog_start();
g_print("Hello World glib!\n");
log_a("Hello EasyLogger Assert!");
log_e("Hello EasyLogger Error!");
log_w("Hello EasyLogger Warning!");
log_i("Hello EasyLogger Info!");
log_d("Hello EasyLogger Debug!");
log_v("Hello EasyLogger Verbose!");
// elog_raw("Hello EasyLogger!");
// 必须检查g_thread是否能用。否则将无法进入main_loop。新版本glib自动做了这部分呢
//if (g_thread_supported() == 0){
// g_thread_init(NULL);
//}else{
// return EXIT_FAILURE;
//} // if g_thread_supported
GMainLoop* loop = g_main_loop_new(NULL, false);
g_timeout_add(1000, callback, NULL);
g_main_loop_run(loop);
GString* test_str = g_string_new("test glib string\n");
g_string_append(test_str, "test append str\n");
g_print("test g_print: %s\n", test_str->str);
g_string_free(test_str, true);
GString* str = Get_Id_64();
g_print("create2 nanoid: %s\n", str->str);
g_print("list size: %04ld\n", Get_64_list_size());
Clear_64_list();
g_print("list size: %04ld\n", Get_64_list_size());
for (int index=0; index<1; index++) {
struct json_object *obj = json_object_new_object();
json_object_object_add(obj, "name", json_object_new_string("xiaoming"));
json_object_object_add(obj, "age", json_object_new_int(20));
log_d(json_object_to_json_string(obj));
json_object_put(obj);
sleep(1);
}
g_main_loop_unref(loop);
return EXIT_SUCCESS;
}
上面示例代码太简单了。如果真有零基础的,有问题直接问。留言私信都行!偶尔没看到每次来耍测评区的时候绝对会看到!。我的其他测评部分也能看到这部分讲解。
上面用到的库是easyLogger。直接去github搜就能搜到这个库,挺完善维护挺久的一个库。找最大的那个基本上不会被迷惑。
本项目我使用cmake做的。如果想用makefile也没问题。甚至因为涉及到你之前编译过glib,你直接用meson也可以。不过这个系统谷歌私有,用起来确实麻烦,效果大部分系统没感觉像宣传的那么简单。好多环境变量设置做的还不够完善,尤其是对交叉编译不太友好,因为谷歌给他用在了通用组件编译上。其交叉编译系统就像是个补丁一样贴在上面。
更多回帖