基于全志Orangepi Zero 2 的语音刷抖音项目

目录

一、硬件连接

二、项目实现功能

三、SU-03T语音模块的配置和烧录

3.1 创建产品:

3.2 设置PIN引脚为串口模式:

3.3 设置唤醒词:

3.4 设置指令语句:

3.5 设置控制详情:

3.6 发音人配置:

3.7 其他设置:

3.7 下载SDK并烧录到语音模块SU-03T:

四、测试语音模块:

4.1 通过语音模块与串口助手连接测试语音模块:

4.2 用代码来测试语音模块:

五、将手机接入香橙派

5.1 查看手机是否接入:

5.2 ADB的认知和常用命令:

5.3 安装ADB:

5.4 设置手机权限:

5.5 使用shell指令来模拟手滑屏幕:

六、编程实现项目功能


一、硬件连接

二、项目实现功能

项目通过语音模块来输出指令控制手机刷抖音,可以实现:上一个、下一个、点赞等功能

  1. 开机播报少刷抖音多看书

  2. 当说出小布小布可以唤醒语音模块,模块回复我在呢

  3. 超过10S没有指令或者说出退下时,模块会进入到休眠模式,并且回复有需要再叫我

  4. 当说出下一个的时候,模块回复好的,并且通过串口发送指令给H616,让手机划到下一个视频

  5. 当说出上一个的时候,模块回复好的,并且通过串口发送指令给H616,让手机划到上一个视频

  6. 当说出点赞的时候,模块回复遵命,并且通过串口发送指令给H616,让手机点赞

  7. 当说出不看了的时候,模块回复拜拜,并且通过串口发送指令给H616,让手机锁屏

三、SU-03T语音模块的配置和烧录

3.1 创建产品:

3.2 设置PIN引脚为串口模式:

SU-03T语音模块的串口引脚是B6和B7,并设置相应的波特率

3.3 设置唤醒词:

3.4 设置指令语句:

3.5 设置控制详情:

3.6 发音人配置:

3.7 其他设置:

3.7 下载SDK并烧录到语音模块SU-03T:

 语音模块配置完成后,大约等待10-30分钟后,将语音模块生成的SDK下载到电脑中,用生成的SDK包中的烧录软件进行烧录:

四、测试语音模块:

4.1 通过语音模块与串口助手连接测试语音模块:

语音模块配置完成后,将语音模块与CH340串口助手链接,然后通过喊语音模块观察串口助手的指令

4.2 用代码来测试语音模块:

/*mySerialTool.c*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>/*打开指定的串口设备,并设置波特率*/
int mySerialOpen(const char *device, const int baud)
{struct termios options; // 串口配置参数speed_t myBaud;         // 波特率int status, fd;         // 状态和文件描述符//根据传入的波特率参数设置相应的波特率switch(baud){case 9600:myBaud = B9600;break;case 115200:myBaud = B115200;break;default:printf("不支持的波特率!\n");return -2;}  //打开串口设备if( (fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY)) == -1){printf("无法打开串口设备\n");return -1;}// 设置文件描述符的标志为读写模式fcntl(fd, F_SETFL, O_RDWR);// 获取当前串口配置tcgetattr(fd, &options);// 设置串口为原始模式,无特殊处理cfmakeraw(&options);// 设置输入波特率cfsetispeed(&options, myBaud);// 设置输出波特率cfsetospeed(&options, myBaud);// 清除标志位并设置数据格式options.c_cflag |= (CLOCAL | CREAD);options.c_cflag &= ~PARENB; // 无奇偶校验位options.c_cflag &= ~CSTOPB; // 1个停止位options.c_cflag &= ~CSIZE; // 清除数据位options.c_cflag |= CS8; // 设置为8位数据位options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // 非规范模式,不执行输入处理options.c_oflag &= ~OPOST; // 输出处理// 设置读取时的超时和最小接收字符数options.c_cc[VMIN] = 0;options.c_cc[VTIME] = 100; // 10秒超时// 应用串口配置tcsetattr(fd, TCSANOW, &options);// 使用ioctl设置串口的DTR和RTS信号ioctl(fd, TIOCMGET, &status);status |= TIOCM_DTR;status |= TIOCM_RTS;ioctl(fd, TIOCMSET, &status);// 短暂延时usleep(10000); // 10毫秒延时return fd; // 返回文件描述符
}/*向指定的串口设备发送字符串*/
void mySerialSendString(const int fd, const char *str)
{int ret;ret = write(fd, str, strlen(str));            // 发送字符串if(ret == -1){printf("串口发送失败!\n");exit(-1);                                 // 发送失败,退出程序}
}/*从指定的串口设备读取字符串*/
int mySerialReadString(const int fd, char *buffer)
{int n_read;n_read = read(fd, buffer, 32);                // 读取串口数据if(n_read == -1){printf("串口读取失败!\n");exit(-1);                                 // 读取失败,退出程序}
}/*从指定的串口设备读取一个字符*/
char mySerialGetChar(const int fd)
{char x;if(read(fd, &x, 1) != 1){printf("串口读取失败!\n");exit(-1);                                 // 读取失败,退出程序}return x;
}
/*mySerial.h*/
/*
* @Author: <NAME> 打开指定的串口设备,并设置波特率
*
* @param device 串口设备名称,如"/dev/ttyUSB0"
* @param baud 波特率,如9600、115200等
* @return 成功返回文件描述符,失败返回-1
*/
int mySerialOpen(const char *device, const int baud);/*
* @Author: 向指定的串口设备发送字符串
*
* @param fd 串口设备文件描述符
* @param str 要发送的字符串 
* @return 无
*/
void mySerialSendString(const int fd, const char *str);/*
* @Author: 从指定的串口设备读取字符串
*
* @param fd 串口设备文件描述符              
* @param buffer 读取到的字符串存放的缓冲区      
* @return 读取到的字符串的长度,失败返回-1
*/
int mySerialReadString(const int fd, char *buffer);/*
* @Author: 从指定的串口设备读取一个字符
*
* @param fd 串口设备文件描述符
* @return 读取到的字符,失败返回-1
*/
char mySerialGetChar(const int fd);
/*mySerialTest2.c*/
#include <stdio.h>         // 包含标准输入输出库头文件
#include <string.h>        // 包含字符串处理库头文件
#include <errno.h>         // 包含错误号头文件
#include <stdlib.h>        // 包含标准库头文件
#include <pthread.h>       // 包含线程库头文件
#include <unistd.h>        // 包含unistd库头文件,用于延时
#include "mySerial.h"      // 包含自定义串口通信头文件int fd;                                                                                      // 串口文件描述符void* readSerial()
{char cmd;while(1){cmd = mySerialGetChar(fd);                                                             // 读取串口数据    switch(cmd){case 'c':printf("上一个\n");            break;case 'h':printf("下一个\n");                                  break;case 'j':printf("点赞\n");                           break;case '^':printf("不看了\n");break;}}
}int main(int argc, char **argv)
{char deviceName[32] = {'\0'};                                                                  // 设备名pthread_t readThread;                                                                         // 读取线程                                                                    // 发送线程   if(argc < 2){printf("Usage: %s /dev/ttyS?\n", argv[0]);return -1;}strcpy(deviceName, argv[1]);                                                               // 拷贝设备名if( (fd = mySerialOpen(deviceName, 115200)) == -1){                                        // 打开串口printf("open %s failed\n", deviceName);}pthread_create(&readThread, NULL, readSerial, NULL);                                       // 创建读取线程while(1){sleep(10);                                                                              // 延时10秒}return 0;
}

五、将手机接入香橙派

将我的手机接入到香橙派,使用一颗TYPE-C的USB线连接到全志的USB2.0接口上

5.1 查看手机是否接入:

dmesg	//查看手机是否接入

输入dmesg指令查看手机接入情况,可见我的OPPO手机已经接入了

5.2 ADB的认知和常用命令:

ADB(Android Debug Bridge)是一种用于与安卓设备通信和调试的命令行工具。它是Android开发工具包(Android SDK)的一部分,用于在开发过程中连接、控制和调试Android设备或模拟器。

ADB提供了一组命令,允许开发者在计算机上执行各种操作,包括安装和卸载应用程序、传输文件、执行Shell命令、查看设备日志等。使用ADB,开发者可以与设备交互,调试应用程序、分析问题并进行性能优化。

ADB可以通过USB连接或通过网络连接到Android设备。通过USB连接,开发者可以直接将设备连接到计算机,并通过ADB命令与设备进行通信。通过网络连接,开发者可以使用无线网络连接到设备,从而无需使用USB线缆。

需要注意的是,ADB在设备上需要开启开发者选项和USB调试模式才能正常使用。此外,ADB还提供了一些高级功能,如端口转发、截屏、录屏等,以支持更丰富的开发和调试需求。

总的来说,ADB是Android开发中非常重要的工具,它简化了与Android设备的通信和调试过程,为开发者提供了更好的开发环境和工作效率。

ADB(Android Debug Bridge)是一个用于在计算机和 Android 设备之间进行通信的命令行工具。它允许开发者执行各种设备操作,例如安装和调试应用程序、访问设备的 Shell、复制文件到设备或从设备复制文件等。ADB 是 Android SDK 的一部分,开发者可以使用它与 Android 设备进行交互。

以下是一些常用的ADB命令:

  • 连接设备:

adb devices
  • 安装应用:

adb install example.apk
  • 卸载应用:

adb uninstall com.example.package
  • 启动应用:

adb shell am start -n com.example.package/.MainActivity
  • 查看设备信息:

adb shell getprop
  • 复制文件到设备:

adb push localfile.txt /sdcard/
  • 从设备复制文件:

adb pull /sdcard/remotefile.txt
  • 启动设备shell:

adb shell
  • 查看日志:

adb logcat

这只是一些常见的 ADB 命令示例,ADB 提供了更多的功能,可以帮助开发者进行 Android 应用程序的开发、调试和测试。请注意,使用 ADB 前需要确保 Android 设备已启用开发者选项和 USB 调试。

5.3 安装ADB:

由于安卓手机的底层也是用Linux系统来操作的,所以可以通过香橙派来直接进入控制手机shell的界面,但需要先安装adb工具

sudo apt-get install adb

安装完成之后,执行adb devices指令连接设备,但是好像发现权限不太对,因此需要在手机上设置权限

5.4 设置手机权限:

  • 报错的本质原因是香橙派系统还不支持USB设备的热拔插UDEV的机制

  • 解决办法:/etc/udev/rules.d 文件夹下创建规则文件:

cd /etc/udev/rules.d/
sudo vim 51-android.rules	

 在文件中添加内容:SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0666"

然后重新拔插手机,然后再次执行adb devices指令:(前提手机已经代开开发者模式中的USB调试)

 然后输入adb shell启动设备shell:

连接手机成功!!!

5.5 使用shell指令来模拟手滑屏幕:

现在可以成功的连入手机内部的系统,关键就在于对于滑动或点击屏幕的指令模拟了:

  • adb shell input swipe <起始x坐标> <起始y坐标> <结束x坐标> <结束y坐标> <滑动持续时间ms>

  • adb shell input keyevent <按键事件的常量>

adb shell input swipe 540 1300 540 500 500 															//下滑
adb shell input swipe 540 500 540 1300 500 															//上滑
adb shell "seq 4 | while read i;do input tap 350 1050 & input tap 350 1050 &sleep 0.05;done;" 		//点赞
adb shell input keyevent 26 																		//锁屏

六、编程实现项目功能

/*mySerialTool.c*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>/*打开指定的串口设备,并设置波特率*/
int mySerialOpen(const char *device, const int baud)
{struct termios options; // 串口配置参数speed_t myBaud;         // 波特率int status, fd;         // 状态和文件描述符//根据传入的波特率参数设置相应的波特率switch(baud){case 9600:myBaud = B9600;break;case 115200:myBaud = B115200;break;default:printf("不支持的波特率!\n");return -2;}  //打开串口设备if( (fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY)) == -1){printf("无法打开串口设备\n");return -1;}// 设置文件描述符的标志为读写模式fcntl(fd, F_SETFL, O_RDWR);// 获取当前串口配置tcgetattr(fd, &options);// 设置串口为原始模式,无特殊处理cfmakeraw(&options);// 设置输入波特率cfsetispeed(&options, myBaud);// 设置输出波特率cfsetospeed(&options, myBaud);// 清除标志位并设置数据格式options.c_cflag |= (CLOCAL | CREAD);options.c_cflag &= ~PARENB; // 无奇偶校验位options.c_cflag &= ~CSTOPB; // 1个停止位options.c_cflag &= ~CSIZE; // 清除数据位options.c_cflag |= CS8; // 设置为8位数据位options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // 非规范模式,不执行输入处理options.c_oflag &= ~OPOST; // 输出处理// 设置读取时的超时和最小接收字符数options.c_cc[VMIN] = 0;options.c_cc[VTIME] = 100; // 10秒超时// 应用串口配置tcsetattr(fd, TCSANOW, &options);// 使用ioctl设置串口的DTR和RTS信号ioctl(fd, TIOCMGET, &status);status |= TIOCM_DTR;status |= TIOCM_RTS;ioctl(fd, TIOCMSET, &status);// 短暂延时usleep(10000); // 10毫秒延时return fd; // 返回文件描述符
}/*向指定的串口设备发送字符串*/
void mySerialSendString(const int fd, const char *str)
{int ret;ret = write(fd, str, strlen(str));            // 发送字符串if(ret == -1){printf("串口发送失败!\n");exit(-1);                                 // 发送失败,退出程序}
}/*从指定的串口设备读取字符串*/
int mySerialReadString(const int fd, char *buffer)
{int n_read;n_read = read(fd, buffer, 32);                // 读取串口数据if(n_read == -1){printf("串口读取失败!\n");exit(-1);                                 // 读取失败,退出程序}
}/*从指定的串口设备读取一个字符*/
char mySerialGetChar(const int fd)
{char x;if(read(fd, &x, 1) != 1){printf("串口读取失败!\n");exit(-1);                                 // 读取失败,退出程序}return x;
}
/*mySerial.h*/
/*
* @Author: <NAME> 打开指定的串口设备,并设置波特率
*
* @param device 串口设备名称,如"/dev/ttyUSB0"
* @param baud 波特率,如9600、115200等
* @return 成功返回文件描述符,失败返回-1
*/
int mySerialOpen(const char *device, const int baud);/*
* @Author: 向指定的串口设备发送字符串
*
* @param fd 串口设备文件描述符
* @param str 要发送的字符串 
* @return 无
*/
void mySerialSendString(const int fd, const char *str);/*
* @Author: 从指定的串口设备读取字符串
*
* @param fd 串口设备文件描述符              
* @param buffer 读取到的字符串存放的缓冲区      
* @return 读取到的字符串的长度,失败返回-1
*/
int mySerialReadString(const int fd, char *buffer);/*
* @Author: 从指定的串口设备读取一个字符
*
* @param fd 串口设备文件描述符
* @return 读取到的字符,失败返回-1
*/
char mySerialGetChar(const int fd);
/*mySerialTest.c*/
#include <stdio.h>         // 包含标准输入输出库头文件
#include <string.h>        // 包含字符串处理库头文件
#include <errno.h>         // 包含错误号头文件
#include <stdlib.h>        // 包含标准库头文件
#include <pthread.h>       // 包含线程库头文件
#include <unistd.h>        // 包含unistd库头文件,用于延时
#include "mySerial.h"      // 包含自定义串口通信头文件int fd;                                                                                      // 串口文件描述符void* readSerial()
{char cmd;while(1){cmd = mySerialGetChar(fd);                                                             // 读取串口数据    switch(cmd){case 'c':printf("上一个\n");system("adb shell input swipe 540 500 540 1300 100");                       break;case 'h':printf("下一个\n");system("adb shell input swipe 540 1300 540 500 100");                                     break;case 'j':printf("点赞\n");system("adb shell \"seq 4 | while read i;do input tap 350 1050 & input tap 350 1050 &sleep 					0.05;done;\"");   // 点赞                                   break;case '^':printf("不看了\n");system("adb shell input keyevent 26");                                              // 不看了 break;}}
}int main(int argc, char **argv)
{char deviceName[32] = {'\0'};                                                                  // 设备名pthread_t readThread;                                                                         // 读取线程                                                                    // 发送线程   if(argc < 2){printf("Usage: %s /dev/ttyS?\n", argv[0]);return -1;}strcpy(deviceName, argv[1]);                                                                 // 拷贝设备名if( (fd = mySerialOpen(deviceName, 115200)) == -1){                                          // 打开串口printf("open %s failed\n", deviceName);}pthread_create(&readThread, NULL, readSerial, NULL);                                       // 创建读取线程while(1){sleep(10);                                                                                // 延时10秒}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/43147.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

atcoder 357 F Two Sequence Queries (线段树板子)

题目&#xff1a; 分析&#xff1a; 线段树 代码&#xff1a; // Problem: F - Two Sequence Queries // Contest: AtCoder - SuntoryProgrammingContest2024&#xff08;AtCoder Beginner Contest 357&#xff09; // URL: https://atcoder.jp/contests/abc357/tasks/abc357_…

华为HCIP Datacom H12-821 卷29

1.多选题 下面关于LSA age字段&#xff0c;描述正确的是∶ A、LSA age的单位为秒&#xff0c;在LSDB中的LSA的LS age随时间增长而增长 B、LSA age的单位为秒&#xff0c;在LSDB中的LSA的LS age随时间增长而减少 C、如果一条LSA的LS age达到了LS RefreshTime&#xff08…

[spring] Spring MVC - security(下)

[spring] Spring MVC - security&#xff08;下&#xff09; callback 一下&#xff0c;当前项目结构如下&#xff1a; 这里实现的功能是连接数据库&#xff0c;大范围和 [spring] rest api security 重合 数据库连接 - 明文密码 第一部分使用明文密码 设置数据库 主要就是…

内存与硬盘(笔记)

文章目录 1. 内存① 笔记② 相关软件 2. 硬盘① 笔记② 相关软件 3. 区别&#xff1a;4. 推荐 1. 内存 ① 笔记 ① 笔记本的内存条和台式机的内存条是不互通的 ② 我们常说的内存其实指的是运行内存(前台后台同时能运行多少APP) ③ 下图来自京东&#xff1a; 解析&#xff1…

ubuntu 分区情况

ubuntu系统安装与分区指南 - Philbert - 博客园 (cnblogs.com)https://www.cnblogs.com/liangxuran/p/14872811.html 详解安装Ubuntu Linux系统时硬盘分区最合理的方法-腾讯云开发者社区-腾讯云 (tencent.com)https://cloud.tencent.com/developer/article/1711884

终于找到了免费的C盘清理软件(极智C盘清理)

搜了很久&#xff0c;终于让我找到了一款 完全免费的C盘清理软件&#xff08;极智C盘清理&#xff09;。 点击前往官网免费使用极智C盘清理软件&#xff1a; C盘清理 用户好评 完全免费的极智C盘清理 用极智C盘清理清理了下系统的临时文件、缓存等无用数据文件&#xff0c;C盘终…

设计资料:520-基于ZU15EG 适配AWR2243的雷达验证底板 高速信号处理板 AWR2243毫米波板

基于ZU15EG 适配AWR2243的雷达验证底板 一、板卡概述 本板卡系北京太速科技自主研发&#xff0c;基于MPSOC系列SOC XCZU15EG-FFVB1156架构&#xff0c;搭载两组64-bit DDR4&#xff0c;每组容量32Gb&#xff0c;最高可稳定运行在2400MT/s。另有1路10G SFP光纤接口、1路40G…

使用F1C200S从零制作掌机之构建debian文件系统

前情&#xff1a;使用buildrootfs构建的文件系统调试了很久NES模拟器&#xff0c;执行InfoNES模拟器的时候一直黑屏&#xff0c;无内容显示&#xff0c;调不通了&#xff0c;所以改用debian系统试试。 一、环境配置 首先下载两个工具&#xff1a;qemu-arm-static和debootstra…

uniapp小程序上传文件

需求 小程序需要上传用户相册图片或拍摄的照片到后端服务器 uniapp官方处理小程序文件方法 选择文件方法&#xff1a;uni.chooseMedia uni-app官网uni-app,uniCloud,serverless,uni.chooseVideo(OBJECT),chooseVideo HarmonyOS 兼容性,uni.chooseMedia(OBJECT),uni.saveVid…

Android:如何绘制View

点击查看Android 如何绘制视图官网 一、简介 Android 框架会在 Activity 获得焦点时请求 Activity 绘制其布局。Android 框架会处理绘制流程&#xff0c;但该 Activity 必须提供其布局层次结构的根节点。 Android 框架会绘制布局的根节点&#xff0c;并测量和绘制布局树。它会…

React@16.x(51)路由v5.x(16)- 手动实现文件目录参考

作为前面几篇文章的参考&#xff1a; 实现 Router实现 Route实现 Switch实现 withRouter实现 Link 和 NavLink 以上。

一.4 处理器读并解释储存在内存中的指令

此刻&#xff0c;hello.c源程序已经被编译系统翻译成了可执行目标文件hello&#xff0c;并被存放在硬盘上。要想在Unix系统上运行该可执行文件&#xff0c;我们将它的文件名输入到称为shell的应用程序中&#xff1a; linux>./hello hello, world linux> shell是一个命令…

一.2.(4)放大电路静态工作点的稳定;

1.Rb对Q点及Au的影响 输入特性曲线&#xff1a;Rb减少&#xff0c;IBQ&#xff0c;UBEQ增大 输出特性曲线&#xff1a;ICQ增大&#xff0c;UCEQ减少 AUUO/Ui分子减少&#xff0c;分母增大&#xff0c;但由于分子带负号&#xff0c;所以|Au|减少 2.Rc对Q点及Au的影响 输入特性曲…

用Vue3和Plotly.js绘制交互式3D小提琴图

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 Vue 中使用 Plotly.js 创建小提琴图 应用场景介绍 小提琴图是一种统计图&#xff0c;用于显示数据的分布和中心趋势。它结合了箱线图和密度图的特点&#xff0c;可以直观地展示数据的分散性和形状。 代码基本…

使用Keil 点亮LED灯 F103ZET6

1.新建项目 不截图了 2.startup_stm32f10x_hd.s Keil\Packs\Keil\STM32F1xx_DFP\2.2.0\Device\Source\ARM 搜索startup_stm32f10x_hd.s 复制到项目路径&#xff0c;双击Source Group 1 3.项目文件夹新建stm32f10x.h&#xff0c; 新建文件main.c #include "stm32f10x…

windows sshkeygen 多平台添加配置

文章目录 .ssh目录生成新的ssh配置添加公钥到仓库验证 .ssh目录 windows下一般为&#xff1a;C:\Users\15237.ssh &#xff0c;其中“15237”为当前登录用户 生成新的ssh .ssh目录下打开“Git Bash Here”&#xff08;如果没有&#xff0c;先安装 Git 软件&#xff09; 执行…

android perfetto使用技巧梳理

1 抓取方法 根据不同的配置参数&#xff0c;会显示不同的功能。 比如有的trace文件就无法显示线程状态信息&#xff0c;有的无法显示锁依赖信息等等&#xff0c;要看你的参数&#xff0c;我这个是很全的&#xff0c;基本够了&#xff0c;如果还想添加&#xff0c;可以命令行看…

腾讯发布2024大模型十大最新趋势!

近日&#xff0c;在2024世界人工智能大会上&#xff0c;腾讯正式发布了《2024大模型十大趋势——走进“机器外脑”时代》报告。目前&#xff0c;这一报告正在AI产业界各大社群快速传播。 报告中&#xff0c;腾讯研究院试图通过10个关键性的趋势&#xff0c;去理解全世界范围内正…

移远BC28_opencpu方案_开发环境搭建

OPEN CPU 代码采用的是 Python 脚本写的 scons 自动化构建工具。从构建这个角度说&#xff0c;它与 GNU make 是同一类的工具。它是一种改进&#xff0c;并跨平台的 gnu make 替代工具&#xff0c;其集成功能类似于 autoconf/automake。 这里给出简单安装方式

[软件安装]linux下安装steam

1、下载安装包到linux系统 SteamTools 发行版 - Gitee.com 2、选择对应的版本 3、解压安装包steam &#xff08;1&#xff09;在opt路径下新建一个文件夹 sudo mkdir steam &#xff08;2&#xff09;进入压缩包路径下&#xff0c;打开终端&#xff0c;执行以下代码进行解压…