龙芯2K0300是面向嵌入式行业的高性能低功耗处理器,于2024年正式推出,可为产品方案商和研发工程师提供高性价比的优选产品。
龙芯2K0300蜂鸟开发系统是专为嵌入式领域打造的解决方案,因小巧灵活而被命名为“蜂鸟”。系统采用“核心板+配套底板”形式,“小尺寸、组合式”的设计使其在不同场景中广泛应用。用户既可将系统整体应用于产品,也可根据核心板引脚定义自行开发产品底板或接口板,还可在应用其软硬件成果的基础上完全按照个人需求重新开发产品,显著提升龙芯2K0300的应用灵活性,降低开发门槛,缩短产品开发周期。
龙芯2K0300蜂鸟开发系统采用业界常用的U-boot作为启动固件,并适配Linux操作系统,可为开发者提供丰富的功能和强大的性能支持。
将type-c线连接开发板和电脑
电脑上执行 tio /dev/ttyUSB0
开启串口通信,并自动root登陆linux系统
简单查看下系统信息
修改 root 密码
passwd
插入网线,等待几分钟后,执行 ifconfig
查看IP地址,此时无法通过ssh登陆
系统默认使用 dropbear 作为ssh服务端,我改为 openssh 服务端,并开机自动启动
systemctl stop dropbear
systemctl disable dropbear
systemctl start sshd
systemctl enable sshd
修改 sshd 配置允许 root 登陆
vim /etc/sshd/sshd_config
将 PermitRootLogin no
修改为 PermitRootLogin yes
保存,然后 systemctl restart sshd
重启ssh服务
此时就可以使用 ssh 登陆开发板了
ssh root@192.168.1.46
执行 top 看到当前的所有进程,可以发现开机默认会启动 logo_player 进程,吃了很多资源,杀死它释放资源
killall logo_player
logo_player 由启动脚本拉起,可以修改脚本让它不再自动启动吃资源了
vim /root/boot_run.sh
在 http://ftp.loongnix.cn/toolchain/gcc/release/loongarch/gcc8/ 中有 loongarch 交叉编译工具链,选择最新版本下载,解压缩
http://ftp.loongnix.cn/toolchain/gcc/release/loongarch/gcc8/loongson-gnu-toolchain-8.3-x86_64-loongarch64-linux-gnu-rc1.5.tar.xz
将工具链的bin目录加入PATH环境变量
export PATH=loongson-gnu-toolchain-8.3-x86_64-loongarch64-linux-gnu-rc1.5/bin:$PATH
编译hello world程序
loongarch64-linux-gnu-gcc hello.c -o hello
file命令查看hello二进制程序,看到是LoongArch架构
file hello
hello: ELF 64-bit LSB executable, LoongArch, version 1 (SYSV), dynamically linked, interpreter /lib64/ld.so.1, for GNU/Linux 4.15.0, not stripped
scp 上传到开发板
scp hello root@192.168.1.46:/root/
ssh 在开发板上执行程序
[root@LS-GD ~]# ./hello
hello 2k0300
至此,已经成功配置好了编译器和开发环境,我们可以使用这个方法编译任意简单的 C/C++ 工程
ruapu 简介
https://github.com/nihui/ruapu
ruapu单个文件探测CPU指令集信息
ruapu通过执行特定扩展指令,捕获CPU非法指令异常,判断当前CPU是否支持某扩展指令集
这里尝试使用 loongarch 工具链的编译器直接编译 ruapu 测试工具
编译和运行 ruapu 测试
git clone https://github.com/nihui/ruapu
cd ruapu
loongarch64-linux-gnu-gcc main.c -O3 -o ruapu
scp ruapu root@192.168.1.46:/root/
使用 ssh 进入系统,执行 ruapu 打印探测到的扩展指令集,可以看到 2k0300 不支持任何LoongArch的SIMD多媒体扩展
[root@LS-GD ~]# ./ruapu
lsx = 0
lasx = 0
https://github.com/nihui/opencv-mobile
下载最新的源码包
https://github.com/nihui/opencv-mobile/releases/latest/download/opencv-mobile-4.10.0.zip
为 loongarch64 编写 cmake toolchain
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR loongarch64)
if(DEFINED ENV{LOONGARCH64_ROOT_PATH})
file(TO_CMAKE_PATH $ENV{LOONGARCH64_ROOT_PATH} LOONGARCH64_ROOT_PATH)
else()
message(FATAL_ERROR "LOONGARCH64_ROOT_PATH env must be defined")
endif()
set(LOONGARCH64_ROOT_PATH ${LOONGARCH64_ROOT_PATH} CACHE STRING "root path to loongarch64 toolchain")
set(CMAKE_C_COMPILER "${LOONGARCH64_ROOT_PATH}/bin/loongarch64-linux-gnu-gcc")
set(CMAKE_CXX_COMPILER "${LOONGARCH64_ROOT_PATH}/bin/loongarch64-linux-gnu-g++")
set(CMAKE_FIND_ROOT_PATH "${LOONGARCH64_ROOT_PATH}/loongarch64-linux-gnu")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CMAKE_C_FLAGS "-march=loongarch64")
set(CMAKE_CXX_FLAGS "-march=loongarch64")
# cache flags
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" CACHE STRING "c flags")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" CACHE STRING "c++ flags")
编译opencv-mobile
export LOONGARCH64_ROOT_PATH=/home/nihui/osd/loongson-gnu-toolchain-8.3-x86_64-loongarch64-linux-gnu-rc1.5
unzip -q opencv-mobile-4.10.0.zip
cd opencv-mobile-4.10.0
mkdir build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=../loongarch64-linux-gnu.toolchain.cmake -DCMAKE_INSTALL_PREFIX=`pwd`/install `cat ../options.txt` ..
make -j12
make install
编译过程中可以看到,opencv探测到了 loongarch64 lsx 指令支持,并且默认直接开启,这会导致在 2k0300 这种不支持 lsx 的平台上出错
因此,可以添加额外的参数,强制禁用 LSX LASX 优化
cmake -DCMAKE_TOOLCHAIN_FILE=../loongarch64-linux-gnu.toolchain.cmake -DCMAKE_INSTALL_PREFIX=`pwd`/install `cat ../options.txt` -DCPU_BASELINE='' -DCPU_DISPATCH='' ..
make -j12
make install
利用opencv-mobile实现图片读取,缩放,保存图片
新建一个cmake工程,引入刚才编译好的 opencv-mobile
project(opencv-mobile-test)
set(OpenCV_DIR "/home/nihui/osd/opencv-mobile-4.10.0/build/install/lib/cmake/opencv4")
find_package(OpenCV REQUIRED)
add_executable(opencv-mobile-test main.cpp)
target_link_libraries(opencv-mobile-test ${OpenCV_LIBS})
cpp实现:读取 in.jpg 图片,缩放到240x240,保存到 out.jpg
#include
#include
#include
int main()
{
cv::Mat bgr = cv::imread("in.jpg", 1);
cv::resize(bgr, bgr, cv::Size(240, 240));
cv::imwrite("out.jpg", bgr);
return 0;
}
编译为 loongarch64 二进制,上传到开发板
cmake -DCMAKE_TOOLCHAIN_FILE=../loongarch64-linux-gnu.toolchain.cmake ..
make
scp opencv-mobile-test root@192.168.1.46:/root/
scp in.jpg root@192.168.1.46:/root/
此时在开发板上运行程序报错,找不到 libgomp.so.1
[root@LS-GD ~]# ./opencv-mobile-test
./opencv-mobile-test: error while loading shared libraries: libgomp.so.1: cannot open shared object file: No such file or directory
把 loongarch64 工具链里的 libgomp.so.1 上传到开发板上
scp $LOONGARCH64_ROOT_PATH/loongarch64-linux-gnu/sysroot/lib64/libgomp.so.1 root@192.168.1.46:/root/
设置好 LD_LIBRARY_PATH 环境变量再执行,可以正常跑完,并产生 out.jpg 图片
[root@LS-GD ~]# LD_LIBRARY_PATH=. ./opencv-mobile-test
最后把 out.jpg 下载到本地查看,确认图片确实被缩放到了 240x240 分辨率,图片内容正确
scp root@192.168.1.46:/root/out.jpg .
在开发板上查看文件大小,通过 file 命令也可以看到图片缩小了
opencv-mobile 通过调整编译参数,删减部分opencv源码,来最小化编译的 opencv 库
提供了 opencv 常用的功能,如读写图片,处理,矩阵操作等等,版本与上游同步,无第三方依赖
在绝大多数情况下,以 1/10 的体积无痛替换官方 opencv,尤其适合对体积有特殊要求的移动端和嵌入式环境
https://github.com/nihui/opencv-mobile
opencv-mobile 最新版本已支持在 Linux 上适配 MJPG 数据格式的摄像头
复用前面opencv图片缩放的工程,修改新的 main.cpp
测试程序的内容是使用 opencv-mobile 打开摄像头,设置 320x240 分辨率,然后每隔1秒取1帧图像,最后拼接为9格图片,保存到 out.jpg
#include
#include
#include
#include // sleep()
int main()
{
cv::VideoCapture cap;
cap.set(cv::CAP_PROP_FRAME_WIDTH, 320);
cap.set(cv::CAP_PROP_FRAME_HEIGHT, 240);
cap.open(0);
const int w = cap.get(cv::CAP_PROP_FRAME_WIDTH);
const int h = cap.get(cv::CAP_PROP_FRAME_HEIGHT);
fprintf(stderr, "%d x %d\\n", w, h);
cv::Mat bgr[9];
for (int i = 0; i < 9; i++)
{
cap >> bgr[i];
sleep(1);
}
cap.release();
// combine into big image
{
cv::Mat out(h * 3, w * 3, CV_8UC3);
bgr[0].copyTo(out(cv::Rect(0, 0, w, h)));
bgr[1].copyTo(out(cv::Rect(w, 0, w, h)));
bgr[2].copyTo(out(cv::Rect(w * 2, 0, w, h)));
bgr[3].copyTo(out(cv::Rect(0, h, w, h)));
bgr[4].copyTo(out(cv::Rect(w, h, w, h)));
bgr[5].copyTo(out(cv::Rect(w * 2, h, w, h)));
bgr[6].copyTo(out(cv::Rect(0, h * 2, w, h)));
bgr[7].copyTo(out(cv::Rect(w, h * 2, w, h)));
bgr[8].copyTo(out(cv::Rect(w * 2, h * 2, w, h)));
cv::imwrite("out.jpg", out);
}
return 0;
}
编译方式参考上一节,此处省略
将USB摄像头插入 2K0300 蜂鸟开发板的下面的USB接口中,此处注意,插入靠上的USB接口会无法识别摄像头,而下面这个能正常识别到摄像头
测试使用的USB摄像头型号为 M5 AtomS3
执行 opencv-mobile-camera-test 测试程序
[root@LS-GD ~]# LD_LIBRARY_PATH=. ./opencv-mobile-camera-test
稍等片刻,程序退出,查看 out.jpg 确认 opencv-mobile 适配 USB 摄像头正常工作,这为后续实现视觉类应用打下了基础
更多回帖