概览
考虑到开发环境使用linux,对于我这种初学者还不太习惯使用,而且还需要安装虚拟机。个人感觉挺麻烦的,于是我使用以下方案,达到再Windows下使用开发的目的。
主要思路是:使用WSL(Windows Subsystem for Linux)用来开发,有点便是无需搭建虚拟机,电脑功耗低,运行速度快,占用资源少。在WSL搭建Samba服务,然后使用在Windows资源管理器中映射WSL中的开发目录。就可方便的使用VS Code进行开发。
本人目前还是学生,还需要学习很多,错误在所难免,尽情指出。可联系微信katsu119
WSL安装及配置
打开Microsoft Store,搜索Ubuntu,下载安装即可。可自定义安装位置,参考网络文章即可。
安装完成之后,命令行输入wsl,显示内容如下,表明安装完成。
因为每次启动WSL可能导致wsl的IP地址变化,这不便于我们使用samba服务访问wsl内的文件夹。所以建立以下的bat批处理命令,用于固定住wsl的IP地址,并且启动samba服务和ssh服务(前提是已安装好这两个服务)。可以根据自己的需求修改此bat文件来改写wsl的IP地址。
wsl --shutdown
wsl -u root service smbd start
wsl -u root service ssh start
wsl -d Ubuntu -u root ip addr del $(ip addr show eth0 ^| grep 'inet\b' ^| awk '{print $2}' ^| head -n 1) dev eth0
wsl -d Ubuntu -u root ip addr add 192.168.50.2/24 broadcast 192.168.50.255 dev eth0
wsl -d Ubuntu -u root ip route add 0.0.0.0/0 via 192.168.50.1 dev eth0
wsl -d Ubuntu -u root echo nameserver 192.168.50.1 ^> /etc/resolv.conf
powershell -c "Get-NetAdapter 'vEthernet (WSL)' | Get-NetIPAddress | Remove-NetIPAddress -Confirm:$False;"
powershell -c "New-NetIPAddress -IPAddress 192.168.50.1 -PrefixLength 24 -InterfaceAlias 'vEthernet (WSL)'; "
powershell -c "Get-NetNat | ? Name -Eq WSLNat | Remove-NetNat -Confirm:$False;"
powershell -c "New-NetNat -Name WSLNat -InternalIPInterfaceAddressPrefix 192.168.50.0/24;"
使用Windows资源管理器访问WSL
如下图所示,这里以win11为例,其他window系统操作类似。打开Windows资源管理器,然后选择“映射网络驱动器”,填写网络位置(IP+文件夹名),如图中所示。具体网络位置的填写和samba服务的配置有关,具体见后文。
samba服务配置
如没有安装 samba服务
课参考这篇文章https://zhuanlan.zhihu.com/p/50753833进行安装
vim /etc/samba/smb.conf
#在文件最后添加如下内容,其中分享的目录path需要自行修改,valid users也需修改。
#方括号内的内容就是上文添加网络驱动器的文件夹地址
[OpenHarmonyOS_Code]
path = /home/katsu
available = yes
valid users = katsu
read only = no
browsable = yes
public = yes
writeable = yes
然后重启samba服务程序 sudo /etc/init.d/smbd restart
,就可通过window添加网络驱动器来像本地磁盘一样,访问xr806的开发文件目录了
下载开发相关文件请参考官方教程
使用vscode编写代码
进入添加的网络驱动器,右击XR806鸿蒙开发目录,使用选择使用Vscode打开
同时可使用Ctrl + \`可以调出终端,在其中输入wsl,便可以进行编译等操作,下载仍然需要使用PhoenixMC工具进行。
项目示例
项目示例文件,在/device/xradio/xr806/ohosdemo
可根据各种示例文件进行学习。下面演示PWM生成,来闪烁LED灯。外设相关的接口文件在\base\iot_hardware\peripheral\interfaces\kits
中,可以浏览相关文件,了解接口函数的功能,来驱动相关外设。
吐槽一下,我是根据B站小熊派来学习鸿蒙的。这块板子还无法使用CMSIS接口系统函数,如osThreadNew函数等等,会编译错误。需要使用xr-skylark的原生SDK来进行开发。使用的是/device/xradio/xr806/xr_skylark/include/kernel/os
的头文件。
下列使用按键控制LED闪烁频率,并创建两个任务
#include <stdio.h>
#include <stdint.h>
//#include "cmsis_os2.h" //无法使用
#include "kernel/os/os.h" // 使用原生的SDK进行RTOS操作
#include "iot_gpio.h"
#include "iot_pwm.h"
#include "ohos_init.h"
#define GPIO_LED_PIN 21
#define GPIO_PWM_LED 2
#define GPIO_KEY_PIN 11
void led_init();
void pwm_led_init();
void led_toggle();
void key_init();
void task1(void *argument);
void task2(void *argument);
// void led_init()
// {
// IoTGpioInit(GPIO_LED_PIN);
// IoTGpioSetDir(GPIO_LED_PIN, IOT_GPIO_DIR_OUT);
// IoTGpioSetOutputVal(GPIO_LED_PIN, IOT_GPIO_VALUE0);
// }
// void led_toggle()
// {
// static char pin_state = IOT_GPIO_VALUE0;
// IoTGpioSetOutputVal(GPIO_LED_PIN, pin_state);
// pin_state = !pin_state;
// }
void pwm_led_init()
{
IoTPwmInit(GPIO_PWM_LED);
IoTPwmStart(GPIO_PWM_LED, 50, 8);
}
void key_init()
{
IoTGpioInit(GPIO_KEY_PIN);
IoTGpioSetDir(GPIO_KEY_PIN, IOT_GPIO_DIR_IN);
}
void pwm_freq_set(uint8_t freq)
{
IoTPwmStart(GPIO_PWM_LED, 50, freq);
}
uint8_t key_read()
{
IotGpioValue ret = IOT_GPIO_VALUE1;
IoTGpioGetInputVal(GPIO_KEY_PIN, &ret);
return ret;
}
void task1(void *argument)
{
uint32_t i = 0;
while (1)
{
printf("Task 1 : %d\r\n", i++);
OS_MSleep(1000);
}
}
void task2(void *argument)
{
uint32_t i = 0;
while (1)
{
printf("Task 2 : %d\r\n", i++);
OS_MSleep(1500);
}
}
static OS_Thread_t htask1;
static OS_Thread_t htask2;
int my_app()
{
printf("Hello Wolrd!\r\n");
pwm_led_init();
key_init();
if (OS_ThreadCreate(&htask1, "Task1", task1, NULL, OS_PRIORITY_NORMAL, 1024) != OS_OK)
printf("Create Task1 Failed!\r\n");
if (!OS_ThreadIsValid(&htask2))
if (OS_ThreadCreate(&htask2, "Task2", task2, NULL, OS_PRIORITY_NORMAL, 1024) != OS_OK)
printf("Create Task2 Failed!\r\n");
uint8_t freq = 1;
while (1)
{
if (key_read() == IOT_GPIO_VALUE0)
{
pwm_freq_set(freq++);
}
if (freq > 15)
freq = 1;
OS_MSleep(100);
}
return 0;
}
SYS_RUN(my_app);