命令行方式设置开发环境,虽然灵活但是也有弊端。比如依赖的工具软件,它们会不断版本更新,对于系统工程师维护工作就很复杂,对于使用者也很麻烦,更新后环境就要跟着变,早期oh1开发环境跟oh3就有很大差别。以后系统还要不断发展,所以把开发环境封装在开发工具里就很必要。DevEco Device Tool是现在最好的方式了,现在的IDE环境也很完善,所以首选还是DevEco IED环境。等有一天膨胀了,想搞开发板适配,芯片移植,要频繁检索代码的时候,再搞命令行方式吧。以后都用DevEco Device Tool工具开发例子。
DevEco Device Tool环境搭建真的很简单,没什么好多说的,就是说我遇到几个坑吧:
最好是干净的系统,不要跟命令行环境在一起。pip华为源要先设置好,否者后面装工具会很慢,新版本可能已经弥补这个问题了,我看安装过程好像一闪而过有这项,但是还是先设好吧。
安装VS Code最好用DevEco Device Tool Windows安装工具里自带的,现在新版本可能有兼容问题,VS安装扩展只安装C/C++,其他都不要装,装C插件可以帮助检索代码,其他任何提示都不要装,他会修改Ubuntu里的环境变量,最后编译都不行了,我还不会改回来了,又重做环境。
其他还有什么问题还真没遇到,遇到再说吧。
------------------
OpenHarmony源码目录:
具体编译过程,先HB设置好编译选项,然后一路脚本奔驰,根据选项到各个目录下拣l取需要的部分合在一起编译成最后的二进制文件。就像推着购物车在超市里选购一样,我这个没见过世面的样子,确实很惊奇。
具体源码部分我就不在这里瞎说了,就说hi3861的应用部分。hi3861的业务代码是系统里的一个组件,功能实现放在这个组件里,这个组件跟系统合并编译在一起,最后生成烧录文件。跑起来的功能代码是系统里的一个业务进程。写代码的时候只有看到SYS_RUN();这个入口函数,如果往上追代码的话,上面也是有Main();函数的。这么看系统跟应用几乎完全脱离,就是你只考虑功能的实现,不用考虑底层的问题,这就是有系统的好处啊,只需要专注实现功能,工作就变的很单纯。
对硬件功能的调用,到这里找"//base/iot_hardware/peripheral/interfaces/kits"
hi3861这款芯片如果细研究,挺有意思的,是个很小很强的芯片,他的应用内容是很多的,但是驱动提取出来的部分这么少?看文件名,叫接口组件,这不是驱动的提取,我估计是他们做了一个统一的规范,设想以后写不同的芯片用同样的相似的方法。但是,这个工作多细碎,谁做谁头疼。但也不要以为他们不更新,我看了也不断有新东西。这些接口一般应用也都够了。以后再说上device目录下调驱动。
----------
用这个接口做个声控灯的小实验:
咪头模块,接收声音,如果有声响就点亮小灯。咪头很便宜,但是一次最好买最少2个,有可能有质量问题,小灯用WiFi模块上的信号灯,如果接继电器可以点亮大瓦灯。
代码很简单,循环检测咪头接口,如果发生变化就点亮小灯1秒钟。
#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio.h"
// 设置端口
#define LED_R 13 // 红灯
#define LED_G 12 // 绿灯
#define LED_B 9 // 蓝灯
#define MIC 1 // 咪头
// 任务
static void *VoiceLedTask(const char *arg)
{
(void)arg;
printf("[VoiceLedTask] Start \n");
// 设置小灯的端口
IoTGpioInit(LED_R);
IoTGpioInit(LED_G);
IoTGpioInit(LED_B);
// 设置咪头的端口
IoTGpioInit(MIC);
// 设置小灯端口方向
IoTGpioSetDir(LED_R, IOT_GPIO_DIR_OUT); // 输出
IoTGpioSetDir(LED_G, IOT_GPIO_DIR_OUT); // 输出
IoTGpioSetDir(LED_B, IOT_GPIO_DIR_OUT); // 输出
// 设置咪头端口方向
IoTGpioSetDir(MIC, IOT_GPIO_DIR_IN); // 输入
// 熄灯
IoTGpioSetOutputVal(LED_R, IOT_GPIO_VALUE0);
IoTGpioSetOutputVal(LED_G, IOT_GPIO_VALUE0);
IoTGpioSetOutputVal(LED_B, IOT_GPIO_VALUE0);
// 咪头端口电压
IotGpioValue mic_vol;
while (1)
{
// 获取咪头段入电平值
IoTGpioGetInputVal(MIC, &mic_vol);
// 如果接收到低电平
if(mic_vol == IOT_GPIO_VALUE0)
{
// 灯点亮 三元色 一起亮 呈现白色
IoTGpioSetOutputVal(LED_R, IOT_GPIO_VALUE1);
IoTGpioSetOutputVal(LED_G, IOT_GPIO_VALUE1);
IoTGpioSetOutputVal(LED_B, IOT_GPIO_VALUE1);
// 等待1秒
usleep(1 * 1000 * 1000);
// 熄灯
IoTGpioSetOutputVal(LED_R, IOT_GPIO_VALUE0);
IoTGpioSetOutputVal(LED_G, IOT_GPIO_VALUE0);
IoTGpioSetOutputVal(LED_B, IOT_GPIO_VALUE0);
}
}
printf("[VoiceLedTask] End \n");
return NULL;
}
static void VoiceLedEntry(void)
{
osThreadAttr_t attr;
attr.name = "VoiceLedTask";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = 1024;
attr.priority = 25;
if (osThreadNew((osThreadFunc_t)VoiceLedTask, NULL, &attr) == NULL)
{
printf("[VoiceLedTask] Falied!\n");
}
}
SYS_RUN(VoiceLedEntry);
实际效果:
先写到这,也没目的,也没头绪,简单做个记录,想哪写哪,以后做例子,再来分享。