PRODUCT Xiaohong AI · official docs
Product overview Product / Product overviewi18n · The narrative below is the original Chinese reference (technical content — code, commands and logs are universal). A fully translated English edition is in progress.
View Chinese version → # 概述
小鸿 AI 基于海思 WS63 芯片,采用 RISC-V 架构,搭载开源鸿蒙(0penHarmony)操作系统,以“开源鸿蒙+ RISC-V“双开源为核心,集成星闪(NearLink)无线技术,打造出兼具 AI 在线陪伴与星闪智能家居控制功能的 AI 对话助手,满足家庭用户的双重核心需求,实现“一声唤醒,万物响应“的智能生活体验。
# 参数规格
参数详情
主芯片 :海思WS63多模物联网SoC芯片;主频:最高 240MHz(RISC-V架构32位);内存(RAM):SRAM 606KB,ROM 300KB;存储(ROM):片上 4MB Flash,板载外挂16MB语音处理芯片 :启英泰伦CI1302语音识别芯片操作系统 :开源鸿蒙(OpenHarmony)6.0/6.1(轻量系统)显示 :1.54寸TFT屏,分辨率240*240
麦克风阵列 :单麦
Wi-Fi :支持Wi-Fi 6(802.11ax)2.4G,蓝牙 :蓝牙5.2版本,兼容传统蓝牙设备,支持 BLE Mesh星闪(NearLink) :SLE 1.0
扬声器规格 :1X 8Ω1.2W
供电方式 :内置锂电池3.7V/750mAh
产品尺寸 :47mm×47mm×20mm(长×宽×高)
数据接口 :Type-C 2.0接口(支持数据传输+供电)扩展接口 :UARTx1、I2Cx1、GPIOx1(支持外设扩展)控制按键 :电源拨动开关、音量和亮度共用键(+/-)、语音唤醒键(M)
# 产品示意图
xiaohong Was this helpful? 👍 Yes 👎 Needs work
DEV GUIDE Xiaohong AI · official docs
Dev environment setup Dev guide / Dev environment setupi18n · The narrative below is the original Chinese reference (technical content — code, commands and logs are universal). A fully translated English edition is in progress.
View Chinese version → # 搭建Ubuntu环境
NOTE ·
如果没有Ubuntu系统,可在Windows系统中通过虚拟机方式搭建Ubuntu系统。
# 系统要求
Ubuntu系统要求:Ubuntu18.04~22.04版本。推荐使用22.04版本,内存16GB及以上,硬盘200GB及以上。
Ubuntu系统的用户名不能包含中文字符。
# 操作步骤
将Ubuntu Shell环境修改为bash。
步骤一: 执行ls -l /bin/sh命令,确认输出结果为bash。如果输出结果不是bash,根据步骤二,将Ubuntu shell修改为bash。
步骤二: 在终端执行sudo dpkg-reconfigure dash命令,输入密码,然后选择No,将Ubuntu shell由dash修改为bash。
# 搭建Windows环境
# 系统要求
Windows 10 64位系统,推荐内存8GB及以上,硬盘100GB及以上。
下载安装VSCode 。
# 配置远程访问环境
在搭建了Windows和Ubuntu开发环境后,需要通过下述设置,使得Windows可以远程访问Ubuntu,为后续烧录文件的传输做好准备。
Ubuntu侧—安装SSH服务并获取远程访问的IP地址
在Ubuntu系统中,打开终端工具,执行sudo apt-get install openssh-server命令安装SSH服务。执行sudo systemctl start ssh命令,启动SSH服务。执行sudo apt-get install net-tools安装net-tools包来获取ifconfig命令,获取当前用户的IP地址,用于Windows系统远程访问Ubuntu环境。
Windows侧—安装Remote SSH
打开Windows系统下的Visual Studio Code,点击 ,在插件市场的搜索输入框中输入“remote-ssh”。点击Remote-SSH的Install ,安装Remote-SSH。安装成功后,会在Visual Studio Code工作左侧显示Remote-SSH图标 。
# 使用VSCode远程连接Ubuntu环境
打开Windows系统的Visual Studio Code,点击 ,在SSH TARGETS 下,单击+。
在弹出的SSH连接命令输入框中输入“ssh username @ip_address ”,其中ip_address为要连接的远程计算机的IP地址,username为登录远程计算机的帐号。
在弹出的输入框中,选择SSH configuration文件,选择默认的第一选项即可。
在SSH TARGETS中,找到远程计算机,点击 ,打开远程计算机。
在弹出的输入框中,选择Linux ,然后在选择Continue ,然后输入登录远程计算机的密码,连接远程计算机。
连接成功后,等待在远程计算机用户目录下的.vscode-server文件夹下自动安装插件。至此,Windows环境搭建完成,如下图所示,左下角显示远程连接计算机的IP地址。
# 远程访问准备
当在Windows下进行烧录时,开发者需要访问Ubuntu环境下的源码和镜像文件,当前通过Samba服务器进行连接的操作方法。
# 配置Samba服务器
在Ubuntu执行sudo apt-get install samba samba-common命令安装Samba软件包。
执行sudo gedit /etc/samba/smb.conf命令,打开Samba配置文件,在配置文件末尾添加以下配置信息(根据实际需要配置相关内容):
[xiaohong] # 在Windows中映射的根文件夹名称(此处以“Share”为例)
comment = Shared Folder # 共享信息说明
path = /home/xiaohong/xiaohong # 共享目录
valid users = xiaohong # 可以访问该共享目录的用户(Ubuntu的用户名)
directory mask = 0775 # 默认创建的目录权限
create mask = 0775 # 默认创建的文件权限
public = yes # 是否公开
writable = yes # 是否可写
available = yes # 是否可获取
browseable = yes # 是否可浏览
执行sudo smbpasswd -a username命令,添加Samba服务器用户和访问密码。用户名为Ubuntu用户名。输入命令后,根据提示设置密码。
执行sudo service smbd restart命令重启Samba服务。
# 设置Windows映射
右键“计算机/此电脑”选择映射网络驱动器,输入共享文件夹信息。在文件夹输入框填入Ubuntu设备的IP地址和Ubuntu共享文件夹的路径。
输入Samba服务器的访问用户名和密码。完成后即可在Windows下看到Linux的共享目录,并可对其进行访问。
Was this helpful? 👍 Yes 👎 Needs work
DEV GUIDE Xiaohong AI · official docs
Build Xiaohong sources Dev guide / Build Xiaohong sourcesi18n · The narrative below is the original Chinese reference (technical content — code, commands and logs are universal). A fully translated English edition is in progress.
View Chinese version → IMPORTANT ·
以下所有内容均通过VSCode Remote-SSH连接远程Ubuntu,然后在VSCode Terminal中执行。
# 获取小鸿源码
# 前提条件
需要AtomGit平台账号。
使用apt-get命令安装后续操作需要的库和工具:
sudo apt-get update; sudo apt-get install binutils binutils-dev; sudo apt-get install git; sudo apt-get install git-lfs; sudo apt-get install gnupg; sudo apt-get install flex; sudo apt-get install bison; sudo apt-get install gperf; sudo apt-get install build-essential; sudo apt-get install zip; sudo apt-get install curl; sudo apt-get install zlib1g-dev; sudo apt-get install gcc-multilib; sudo apt-get install g++-multilib; sudo apt-get install gcc-arm-linux-gnueabi; sudo apt-get install libc6-dev-i386; sudo apt-get install libc6-dev-amd64; sudo apt-get install lib32ncurses5-dev; sudo apt-get install x11proto-core-dev; sudo apt-get install libx11-dev; sudo apt-get install lib32z1-dev; sudo apt-get install ccache; sudo apt-get install libgl1-mesa-dev; sudo apt-get install libxml2-utils; sudo apt-get install xsltproc; sudo apt-get install unzip; sudo apt-get install m4; sudo apt-get install bc; sudo apt-get install gnutls-bin; sudo apt-get install ruby; sudo apt-get install genext2fs; sudo apt-get install device-tree-compilersudo apt-get install make; sudo apt-get install libffi-dev; sudo apt-get install e2fsprogs; sudo apt-get install pkg-config; sudo apt-get install perl; sudo apt-get install openssl; sudo apt-get install libssl-dev; sudo apt-get install libelf-dev; sudo apt-get install libdwarf-dev; sudo apt-get install u-boot-tools; sudo apt-get install mtd-utils; sudo apt-get install cpio; sudo apt-get install doxygen; sudo apt-get install liblz4-tool; sudo apt-get install openjdk-8-jre; sudo apt-get install gcc; sudo apt-get install g++; sudo apt-get install texinfo; sudo apt-get install dosfstools; sudo apt-get install mtools; sudo apt-get install default-jre; sudo apt-get install default-jdk; sudo apt-get install libncurses5; sudo apt-get install apt-utils; sudo apt-get install wget; sudo apt-get install scons; sudo apt-get install python3.9-distutils; sudo apt-get install tar; sudo apt-get install rsync; sudo apt-get install git-core; sudo apt-get install libxml2-dev; sudo apt-get install lib32z-dev; sudo apt-get install grsync; sudo apt-get install xxd; sudo apt-get install libglib2.0-dev; sudo apt-get install libpixman-1-dev; sudo apt-get install kmod; sudo apt-get install jfsutils; sudo apt-get install reiserfsprogs; sudo apt-get install xfsprogs; sudo apt-get install squashfs-tools; sudo apt-get install pcmciautils; sudo apt-get install quota; sudo apt-get install ppp; sudo apt-get install libtinfo-dev; sudo apt-get install libtinfo5; sudo apt-get install libncurses5-dev; sudo apt-get install libncursesw5; sudo apt-get install libstdc++6; sudo apt-get install gcc-arm-none-eabi; sudo apt-get install vim; sudo apt-get install ssh; sudo apt-get install locales; sudo apt-get install libxinerama-dev; sudo apt-get install libxcursor-dev; sudo apt-get install libxrandr-dev; sudo apt-get install libxi-dev; sudo apt-get install cmake
执行命令sudo apt-get install git git-lfs安装git客户端和git-lfs并配置用户信息。
git config --global user.name "yourname"
git config --global user.email "your-email-address"
git config --global credential.helper store
执行如下命令安装atomgit的repo工具。下述命令中的安装路径以"~/bin"为例,请用户自行创建所需目录。
mkdir ~/bin
curl https://raw.atomgit.com/gitcode-dev/repo/raw/main/repo-py3 -o ~/bin/repo
chmod a+x ~/bin/repo
pip3 install -i https://repo.huaweicloud.com/repository/pypi/simple requests
将repo添加到环境变量。
vim ~/.bashrc # 编辑环境变量
export PATH=~/bin:$PATH # 在环境变量的最后添加一行repo路径信息
source ~/.bashrc # 应用环境变量
# 通过repo + ssh下载
repo init -u git@atomgit.com:xiaohong-ai/manifest.git -b OpenHarmony-6.1.0.31-Release -m default_xiaohong.xml -g ohos:mini --no-repo-verify -v
repo sync -c -j8
repo forall -c 'git lfs pull'
# 通过repo + https下载
从小鸿版本发布Tag节点获取源码。
repo init -u https://atomgit.com/xiaohong-ai/manifest.git -b OpenHarmony-6.1.0.31-Release -m default_xiaohong.xml -g ohos:mini --no-repo-verify -v
repo sync -c -j8
repo forall -c 'git lfs pull'
NOTE ·
提示/usr/bin/env: “python”: 没有那个文件或目录问题,需要执行命令sudo ln -s /usr/bin/python3 /usr/bin/python对python进行软连接设置。
执行bash build/prebuilts_download.sh脚本安装编译器及二进制工具。
# 安装编译工具hb
在Windows侧使用VSCode远程连接Ubuntu,或者直接在Ubuntu中操作。
在源码根目录运行如下命令安装hb并更新至最新版本。
python3 -m pip install --user build/hb
设置环境变量。
vim ~/.bashrc
# 将以下命令拷贝到.bashrc文件的最后一行,保存并退出。
export PATH=~/.local/bin:$PATH
# 执行如下命令更新环境变量。
source ~/.bashrc
在源码目录执行"hb help",界面打印以下信息即表示安装成功。
# 编译小鸿镜像
在Ubuntu环境下进入源码根目录,执行如下命令进行编译:
执行命令hb set设置编译路径。
使用上下键切换编译系统版本,选择mini,然后回车,选择atomgit下的xiaohong回车。
执行hb build -f命令进行编译。
Was this helpful? 👍 Yes 👎 Needs work
DEV GUIDE Xiaohong AI · official docs
Flash image (Windows) Dev guide / Flash image (Windows)i18n · The narrative below is the original Chinese reference (technical content — code, commands and logs are universal). A fully translated English edition is in progress.
View Chinese version → # 前提条件
小鸿源码已编译完成,已形成烧录文件,在~/xiaohong/out/xiaohong/xiaohong/ws63-liteos-app目录下(此目录为你的实际项目路径)可以看到编译的镜像文件。
Windows设备已下载安装BurnTool工具 、USB驱动 、串口终端工具 。
将小鸿通过USB线缆连接到Windows设备。
已完成Ubuntu共享文件映射到Windows。
# 操作步骤
打开BurnTool工具,设置BurnTool参数,根据实际情况选择COM口,勾选“Auto burn”和“Auto disconnect”。
单击Select file在映射驱动中选择烧写文件。
确保COM口选择正确,然后单击Connect后,同时按下小鸿左右按键。 烧录开始后,可以在BurnTool工具下方的控制台区域观察到烧录过程中的打印信息。等待进度条完成后,烧录完成,控制台区域会打印提示"Execution Successful"。
# 开机启动与日志查看
烧录完成后会自动重启,要查看日志,需要打开串口终端工具(如UartAssist),配置串口号、波特率(115200)、校验位(NONE)、数据位(8)、停止位(1)、流控制(NONE),然后点击“打开”按钮。
同时按下小鸿顶部左右按键(音量+和音量-),小鸿重新启动,可在串口调试助手数据日志窗口查看启动后的日志信息。
# 小鸿启动日志分析
日志概览
时间段
阶段
结果
11:19:00.509
早期初始化
正常
11:19:00.571
板级/外设/LCD/射频校准
正常
11:19:00.698
WiFi 驱动与 VAP 初始化
正常
11:19:01.757
显示收到 WiFi 状态更新
正常
11:19:01.836
STA 开始扫描
正常
11:19:03.493
扫描完成,发现 22 个 AP,选定 XXX-2.4G
正常
11:19:04.061
认证/关联/EAPOL 握手
正常
11:19:04.254
连接成功,开始 DHCP
正常
11:19:07.339
DHCP 获取 IP 192.168.77.30,STA 连接完成
成功
NOTE ·
系统从串口、文件系统、板级、WiFi 任务、显示、射频到 *自动连上路由器并拿到 IP* 全流程正常。
逐段解读
1. 早期初始化
APP|dbg uart init ok.
APP|SDK Version: 1.10.106
[UPG] init OK!
APP|init_sle_mac failed!
APP|mac_addr:0xde,0x 0,0x73,0x4e,0x**,0x**,
xo_trim_temp_comp val:0 0
los_at_plt_cmd_register EXCUTE
APP|=========FS MOUNT=========
APP|=========FS READY=========
dbg uart init ok:调试串口初始化成功,后续日志都从这里输出。
SDK Version: 1.10.106:当前运行的是 1.10.106 版本 SDK。
[UPG] init OK!:升级(Upgrade)模块初始化完成。
init_sle_mac failed!:SLE MAC 仍未被写入(NV/工厂区/eFuse 均无),与之前分析一致,主 MAC 已用随机值兜底(本次为 0xde,0x00,0x73,0x4e,…)。
串口、SDK、UPG、文件系统、AT 命令注册均正常。
2. 系统服务与板级
hilog will init. / hievent init success.
Please implement the interface according to the platform!
cpu 0 entering scheduler
APP|cali_is on
APP|btc open
hiview init success.
adc_port_register_irq succeed: 0
[BoardCfg] spi1_init: spi1_inited[0->1]
[BoardCfg] uart2_init: uart2_inited[0->1]
[BoardCfg] board_hw_init: hw_inited[0->1]
3. WiFi 任务与设备初始化
[WiFiTask] -------------------------------
[1302Task] osMessageQueueGet: msg[2]
[RADAR_LOG] radar_timer_init succ
[RADAR_LOG] alg ctrl read from nv [1][2][0][0][1][1][20]
device_main_init: 0!
===hal_initialize_phy===226===
device_module_init:: succ!
lcd_init: st7789
cali_set_cali_mask:old[0x0] -> new[0x1fa2]
fe_rf_initialize
cali_offline_cali_entry enter
cali_set_cali_done_flag:old[0x0] -> new[0x1]
rf cali OK. time cost:22, ret:0
WiFi 任务已启动;1302 语音任务收到 msg[2];雷达、设备主初始化、PHY、设备模块、LCD、射频校准均正常,*rf cali OK* 表示射频可用。
4. WiFi 驱动与 VAP 状态
drv_soc_ioctl ioctl_cmd->cmd=7.
drv_soc_ioctl ioctl_cmd->cmd=9.
...
======= state 5 vap 1=========
drv_soc_ioctl ioctl_cmd->cmd=13.
drv_soc_ioctl ioctl_cmd->cmd=35.
drv_soc_ioctl ioctl_cmd->cmd=2. (x6)
drv_soc_ioctl ioctl_cmd->cmd=41.
drv_soc_ioctl:WiFi 驱动层与 SoC 的 ioctl 调用,完成能力查询、参数设置、信道/功率等配置。
state 5 vap 1:VAP(虚拟 AP/STA 接口)状态机进入状态 5,表示 STA 接口已就绪,可进行扫描与连接。13996909897
5. 显示任务收到 WiFi 状态更新
[LvglTask] osMessageQueueGet: msg[3]
msg[3]对应 eDisp_WiFi_St_Update(在 disp_driver.h 中 eDisp_WiFi_St_Update 为枚举值 3)。
- 表示 WiFi 任务在“自动连接中”或“已连接”时向显示任务发送了状态更新,界面会刷新 WiFi/Vol/Blk/Bat 或配网/连接结果文案。
6. STA 扫描
[wifi_sta] connect_to_hotspot: wifi_sta_scan:
drv_soc_ioctl ioctl_cmd->cmd=14.
======= state 6 vap 1=========
...
hmac_single_hal_device_scan_complete:vap[1] time[1533] chan_cnt[13] chan_0[1] back[0] event[6] mode[0]
======= state 7 vap 1=========
Scan::vap[1] find bss_num[22] in regdomain, other bss_num[0]
Srv:756:receive event = 1
Srv:1957:scan_results cnt 22
wifi_sta_scan:开始扫描。
cmd=14:通常为扫描相关ioctl;state 6 表示扫描进行中。
scan_complete:扫描完成,耗时约 1533 ms,13 个信道,发现 22 个 BSS;state 7 表示扫描结果就绪。
Srv:1957:scan_results cnt 22:服务层拿到 22 个扫描结果,供后续选网使用。
7. 选定 SSID 并发起连接
[wifi_sta] connect_to_hotspot: wifi_sta_connect[XXX-2.4G]
Srv:find ssid[XXX-2.4G] auth type[3] pairwise[1] ft_flag[0]
drv_soc_ioctl ioctl_cmd->cmd=47. (x3)
drv_soc_ioctl ioctl_cmd->cmd=16.
======= state 8 vap 1=========
wifi_sta_connect:从 NV 读取的 SSID 为 XXX-2.4G ,与扫描结果匹配后发起连接。
auth type[3]:一般为 WPA2-PSK(或等同);pairwise[1]:加密套件;ft_flag[0]:无 802.11r 快速切换。
state 8:进入关联/认证阶段。
8. 认证与关联
wifi:tx auth seq 1 alg 0 code 0
======= state 9 vap 1=========
wifi:rx auth seq 2 alg 0 code 0
======= state 11 vap 1=========
wifi:tx assoc req
======= state 12 vap 1=========
wifi:rx assoc rsp code 0
auth seq 1/2:开放系统认证请求与响应成功。
assoc req / assoc rsp code 0:关联请求与关联响应(成功),STA 已与 AP 关联。
9. WPA2 四次握手(EAPOL)
wifi:rx eapol 1/4
drv_soc_ioctl ioctl_cmd->cmd=6. (多次)
wifi:tx eapol 2/4
wifi:rx eapol 3/4
...
wifi:tx eapol 4/4
drv_soc_ioctl ioctl_cmd->cmd=3.
drv_soc_ioctl ioctl_cmd->cmd=1.
+NOTICE:CONNECTED
Srv:756:receive event = 2
[wifi_sta] wifi_connection_changed: Connected
eapol 1/4~4/4:WPA2 四次握手完成,密钥协商成功。
+NOTICE:CONNECTED:驱动/服务层上报“已连接”事件。
wifi_connection_changed: Connected:应用层(net_wifi_station.c 回调)收到连接成功,WiFi 链路层已 up。
10. DHCP 与 IP 获取
[wifi_sta] connect_to_hotspot: DHCP start ...
...
[wifi_sta] connect_to_hotspot: netifapi_dhcp_is_bound OK
server :
server_id : 192.168.77.1
mask : 255.255.255.0, 1
gw : 192.168.77.1
T0 : 1800
T1 : 900
T2 : 1575
clients <1> :
mac_idx mac addr state lease tries rto
0 de00734ec5c2 192.168.77.30 10 0 1 4
[wifi_sta] connect_to_hotspot: End. STA Connected.
netifapi_dhcp_is_bound OK:DHCP 已绑定,设备拿到 IP。
服务器:192.168.77.1,掩码 255.255.255.0,网关 192.168.77.1;租期 T0/T1/T2 为 1800/900/1575 秒。
客户端:MAC de:00:73:4e:c5:c2(与前面 mac_addr 一致),IP 192.168.77.30,state 10 表示已绑定。
End. STA Connected.:connect_to_hotspot() 正常返回,自动连接流程结束。
11. 连接成功后的 UI 与语音
[LvglTask] osMessageQueueGet: msg[3]
[1302Task] osMessageQueueGet: msg[8]
msg[3]:显示任务再次收到 eDisp_WiFi_St_Update,界面会显示“WiFi 连接成功!”并更新状态栏。
msg[8]:1302 任务收到 eAud_NetConned(网络已连接),可播放“已连网”等语音提示。
Was this helpful? 👍 Yes 👎 Needs work
DEV GUIDE Xiaohong AI · official docs
Flash image (macOS) Dev guide / Flash image (macOS)i18n · The narrative below is the original Chinese reference (technical content — code, commands and logs are universal). A fully translated English edition is in progress.
View Chinese version → # 前提条件
小鸿源码已编译完成,已形成烧录文件,在~/xiaohong/out/xiaohong/xiaohong/ws63-liteos-app目录下(此目录为你的实际项目路径)可以看到编译的镜像文件。
macOS设备已下载安装CH341SER_MAC 、串口终端工具sscom 、烧录工具ws63flash 。
将小鸿通过USB线缆连接到macOS设备。
已完成Ubuntu共享文件映射到macOS。
# 工具安装
# CH341SER_MAC安装
解压CH341SER_MAC.ZIP压缩包,点击CH34xVCPDriver.dmg打开安装向导,点击CH34xVCPDriver.cpp图标拖拽到Applications中进行安装。
程序安装完成后,在启动台打开CH34xVCPDriver应用,点击“安装”按钮安装驱动。
驱动安装完成后,需要打开设置 --> 通用 --> 登录项与扩展 --> 驱动程序扩展中CH34xVCPDriver.cpp。
# 串口工具sscom安装
点击下载的sscom.dmg文件打开安装向导,如果没有出现向导窗口,需要点击“访达”页面左侧菜单栏“位置”中的“sscom”打开,然后拖拽sscom.app拖拽到applications中,完成安装在“启动台”打开sscom应用。
# 烧录工具ws63flash
下载ws63flash-0.3.1-macos.zip文件并解压到指定文件夹,并在环境变量配置文件.zshrc或者.bashrc最后一行添加export PATH=~/Tools/ws63flash/0.3.1/bin:$PATH配置全局环境变量,然后再执行source .zshrc或者source .bashrc使环境生效。
# 完成Ubuntu共享文件映射到macOS
在“访达”顶部菜单栏“前往 --> 连接服务器”,打开连接服务器窗口,输入smb://ubuntu服务器地址,点击“连接”按钮,在弹出的窗口中选择具体的文件夹。完成后会在访达左侧菜单栏中显示当前映射的服务器。
# 开始烧录
打开终端,进入服务器中已经编译完成的镜像目录cd /Volumes/Ohos/A_OH60T/out/xiaohong/xiaohong/ws63-liteos-app,小鸿通过USB线缆连接到macOS设备,在终端输入ws63flash --flash /dev/c然后按补全健Tab可以查看当前的串口信息,然后选择自己的设备串口,比如当前应该是cu.wchusbserial110%设备。
接着补全镜像信息。完整的命令是ws63flash --flash /dev/cu.wchusbserial110 ws63-liteos-app_all.fwpkg,然后回车并重启设备,开始烧录。
# 开机启动与日志查看
烧录完成后会自动重启,要查看日志,需要打开串口终端工具(如sscom),配置串口号、波特率(115200)、校验位(NONE)、数据位(8)、停止位(1)、流控制(NONE),然后点击“打开串口”按钮,重启设备会在窗口打印日志信息。如果串口号没有当前设备,需要重启串口工具sscom。
Was this helpful? 👍 Yes 👎 Needs work
HANDS-ON SAMPLES Xiaohong AI · official docs
Samples overview Hands-on samples / Samples overviewi18n · The narrative below is the original Chinese reference (technical content — code, commands and logs are universal). A fully translated English edition is in progress.
View Chinese version → NOTE ·
运行示例前请先阅读:重要:示例运行前要 (环境与前置准备)。
# 案例列表
序号
案例名称
文档链接
00
HelloWorld
案例00 HelloWorld
01
软件定时器 timer
案例01 软件定时器timer
02
延时 delay
案例02 延时delay
03
互斥锁 mutex
案例03 互斥锁mutex
04
信号量 semaphore
案例04 信号量semaphore
05
消息队列 message
案例05 消息队列message
06
SPI Master
案例06 SPI Master
07
Easy WiFi
案例07 Easy WiFi
08
喇叭控制
案例08 喇叭控制
09
PWM
案例09 PWM
10
STA(WiFi 站模式)
案例10 STA
11
事件 event
案例11 事件event
12
双任务信号量同步 Sync Semaphore
案例12 双任务信号量同步Sync Semaphore
13
SLE UART 串口
案例13 SLE UART串口
# 使用说明
源码与编译 :在 OpenHarmony 小鸿工程中,示例源码位于 vendor/atomgit/xiaohong/xiaohong/src/samples/,需在 vendor/atomgit/xiaohong/xiaohong/BUILD.gn 中将对应示例源文件加入 sources 后编译、烧录。
烧录与串口 :烧录步骤、串口波特率(如 115200)及串口工具使用见《小鸿AI 固件烧录与启动指导手册》或各案例文档中的“烧录与验证”部分。
Was this helpful? 👍 Yes 👎 Needs work
HANDS-ON SAMPLES Xiaohong AI · official docs
Pre-flight checklist Hands-on samples / Pre-flight checklisti18n · The narrative below is the original Chinese reference (technical content — code, commands and logs are universal). A fully translated English edition is in progress.
View Chinese version → 本文介绍在小鸿上运行应用/示例前,需要准备的软件环境 ,主要包括:USB 转串口驱动、串口调试助手、烧录工具。完成以下三步后,即可进行固件烧录与串口日志查看。
# 一、CH341 USB 转串口驱动
开发板通过 USB 转串口芯片(如 CH341)与 PC 通信,用于烧录和串口打印。需先安装对应驱动,设备管理器中才会出现 COM 口(Windows)或 /dev/ttyUSB*(Linux)。
# 1.1 Windows 安装
下载:
安装步骤:
下载压缩包并解压。
双击运行 CH341SER.EXE ,按提示完成安装/升级/卸载。
安装完成后,在设备管理器的“端口(COM 和 LPT)”下应出现 USB-SERIAL CH341 (COMx) ,记下 COM 口号(如 COM3),供串口助手和烧录工具使用。
支持系统: Windows 11/10/8.1/8/7/Vista/XP,支持 USB 转 3 线/9 线串口,常见波特率均支持(如 115200)。
# 二、UartAssist 串口调试助手安装
串口助手用于查看开发板上电后的启动日志、应用 printf 输出等,便于调试和验证 Demo 是否运行成功。
# 2.1 下载
小鸿文档仓库(推荐) :UartAssist 串口调试助手
# 2.2 安装与使用特点
将 CH341 驱动装好,用 USB 连接开发板,确认设备管理器中已有对应 COM 口。
打开 UartAssist,在“串口设置”中选择正确 COM 口 ,波特率 设为 115200 (与开发板日志输出一致),数据位 8、停止位 1、校验无、流控无。
点击“打开”串口,然后给开发板上电或复位 ,即可在接收区看到启动与运行日志。
# 2.3 常用设置小结
项目
建议值
波特率
115200
数据位
8
停止位
1
校验
无
流控制
无
接收格式
ASCII
若收不到数据,请确认:COM 口是否选对(多口设备需区分烧录口与日志口)、TX/RX 是否交叉连接、波特率是否与系统配置一致。
编译生成的固件(如 .fwpkg)需通过烧录工具写入开发板。小鸿/WS63 方案常用 BurnTool 或厂商提供的专用烧录工具。
# 3.1 获取与安装
小鸿文档仓库(推荐) :BurnTool 烧录工具
安装方式 :
若为绿色版:解压到任意目录,运行主程序即可。
若为安装包:双击安装程序,按向导完成安装,之后从开始菜单或安装目录启动。
# 3.2 固件路径(小鸿工程)
在小鸿工程中完整编译后,常规固件输出路径为:
out/xiaohong/xiaohong/ws63-liteos-app/ws63-liteos-app_all.fwpkg
烧录时在 BurnTool 中选择上述 ws63-liteos-app_all.fwpkg (或当前工程文档中标注的固件名)进行烧写。
# 3.3 烧录步骤概要
连接 :使用 USB 线连接开发板与 PC(若烧录与日志共用同一 USB 口,则只需一根线;若分开,则按板子说明连接烧录口)。
驱动 :确保 CH341(或板载 USB 转串口芯片)驱动已安装,设备管理器中能看到对应 COM 口。
打开 BurnTool :选择与开发板对应的 串口(COM 口) 和 波特率 (按工具或文档要求,常见为 115200 或更高)。
选择固件 :在工具中指定固件文件路径,如 ws63-liteos-app_all.fwpkg。
进入烧录模式 :按工具提示操作,通常需要 点击“连接/开始”后,短按开发板复位键 ,使板子进入烧录模式。
等待完成 :烧录进度条走完后,按提示再次复位或重新上电,使设备从新固件正常启动。
查看日志 :用 UartAssist 打开日志串口 (若与烧录口不同需切换 COM 口),波特率 115200,复位板子即可查看启动与 Demo 打印。
IMPORTANT ·
具体操作步骤以 烧录小鸿镜像.md 为主 。
# 四、环境自检清单
在运行 Demo 前,建议逐项确认:
项目
说明
CH341 驱动
Windows:设备管理器中可见 COM 口;Linux:ls /dev/ttyUSB* 有设备。
UartAssist
已下载并能打开;串口参数设为 115200、8N1。
BurnTool
已获取并能启动;已知晓固件路径与烧录步骤。
固件已编译
已执行 hb set、hb build -f,且存在 ws63-liteos-app_all.fwpkg。
接线与 COM 口
确认使用的是“日志串口”对应的 COM 口;TX-RX 交叉、GND 共地。
完成以上软件环境搭建后,即可进行“编译 → 烧录 → 串口查看”的完整流程,并对照《在小鸿上运行 00_thread 技术实践》等文档验证 Demo 输出。
文档说明 :本文聚焦运行 Demo 前的软件 环境(驱动、串口助手、烧录工具),硬件接线与板级差异请以具体开发板说明为准。驱动与工具下载链接请以厂商/官网最新页面为准。
Was this helpful? 👍 Yes 👎 Needs work
HANDS-ON SAMPLES Xiaohong AI · official docs
01 · HelloWorld Hands-on samples / 01 · HelloWorldi18n · The narrative below is the original Chinese reference (technical content — code, commands and logs are universal). A fully translated English edition is in progress.
View Chinese version → # 一、背景与目标
# 1.1 小鸿与 HelloWorld 是什么
小鸿 是基于 OpenHarmony + 海思 WS63 方案的设备/工程,其代码位于 vendor/atomgit/xiaohong/xiaohong,使用 CMSIS-RTOS2(LiteOS-M 适配)做多任务调度。
HelloWorld 是小鸿 samples 内的一个最小示例 (目录名为 00_helloworld),在系统启动时通过 APP_FEATURE_INIT 注册初始化函数,在串口打印一行 [HelloWorld] hello world.。将其集成到小鸿上,可以:
快速验证小鸿工程编译、烧录与串口输出是否正常;
作为“第一个可运行 demo”的参考,便于后续添加其他 sample。
# 1.2 本文目标
说明 HelloWorld demo 所在目录与构建方式 (samples/00_helloworld,通过 features 编入);
说明 为能编译并打进镜像需要修改的文件 :vendor 顶层 BUILD.gn、samples/BUILD.gn、config.py、ohos.cmake;
说明如何通过串口查看运行结果;
给出预期日志与“如何判断成功”的结论。
# 二、环境与前置条件
工程 :OpenHarmony + 小鸿 vendor(vendor/atomgit/xiaohong,含主库与 samples ,HelloWorld 位于 samples/00_helloworld );
SDK :WS63 SDK(通过 ws63_sdk.gni 引用);
工具 :串口调试助手(如 UartAssist、Xshell 等),波特率 115200 ;
硬件 :小鸿开发板,通过 USB 转串口连接 PC,TX/RX/GND 正确连接。
# 三、集成步骤(文件放哪里、改哪里能编译)
HelloWorld 以 samples 形式存在,目录为 vendor/atomgit/xiaohong/samples/00_helloworld ,通过 samples/BUILD.gn 的 features 与板级 config.py / ohos.cmake 参与编译并打进 ws63-liteos-app 镜像。以下步骤须全部完成,缺一不可。
# 3.1 目录与源码位置
HelloWorld 已放在小鸿 vendor 包内,无需再拷贝到主库目录:
目录 :vendor/atomgit/xiaohong/samples/00_helloworld/ ;
源文件 :helloworld.c ;
构建目标 :本目录下的 static_library("helloworld") ,由 samples/BUILD.gn 以 feature "00_helloworld:helloworld" 形式编入应用。
完整路径为:
vendor/atomgit/xiaohong/
├── BUILD.gn # 顶层 group,依赖 xiaohong 主库与 samples
└── samples/
├── BUILD.gn # lite_component("app"),通过 features 选择示例
└── 00_helloworld/
├── BUILD.gn # static_library("helloworld")
├── helloworld.c # 演示源码
└── README.md # 操作说明
若从别处拷贝示例,请将 00_helloworld 整个目录放到 vendor/atomgit/xiaohong/samples 下。
# 3.2 步骤 1:检查 vendor 顶层 BUILD.gn(编译前必查)
打开 vendor/atomgit/xiaohong/BUILD.gn ,在 group("xiaohong") 的 deps 中确认包含 "samples:app", 。若缺少该项,samples 下的示例不会参与整包编译。
group("xiaohong") {
deps = [
"xiaohong:xiaohong",
"samples:app",
]
}
# 3.3 步骤 2:在 samples/BUILD.gn 中启用 HelloWorld
修改 vendor/atomgit/xiaohong/samples/BUILD.gn ,在 lite_component("app") 的 features 列表中保留或添加 "00_helloworld:helloworld" (未注释):
lite_component("app") {
features = [
"00_helloworld:helloworld",
# 其他示例按需取消注释
]
}
说明 :以 # 开头的行为注释,不会参与编译 ;需要编进固件的示例须为未注释的一行。
# 3.4 步骤 3:在 config.py 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/build/config/target_config/ws63/config.py 中,找到 'ws63-liteos-app' 配置,在其 'ram_component' 列表中添加 "helloworld" :
说明 :ram_component 声明参与 ws63-liteos-app 镜像链接的组件;未在此列出的 static_library 不会被打进最终 app 镜像。
# 3.5 步骤 4:在 ohos.cmake 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/libs_url/ws63/cmake/ohos.cmake 中,找到 elseif(${TARGET_COMMAND} MATCHES "ws63-liteos-app") 对应的 set(COMPONENT_LIST ...) ,在列表中添加 "helloworld" :
说明 :COMPONENT_LIST 决定参与构建与安装的组件(静态库),需与 步骤 3 的 ram_component 及 samples 内 BUILD.gn 的 target 名称一致。
# 3.6 代码说明(无需再改)
当前 helloworld.c 逻辑非常简单:使用 ohos_init.h 的 APP_FEATURE_INIT 注册一个初始化函数,在系统启动时执行一次 printf:
#include <stdio.h>
#include "ohos_init.h"
static void HelloWorldEntry(void)
{
printf("[HelloWorld] hello world.\r\n");
}
APP_FEATURE_INIT(HelloWorldEntry);
无需额外适配,与 00_thread 使用同一套启动与打印方式。
# 四、运行逻辑简述
系统启动后,通过 APP_FEATURE_INIT(HelloWorldEntry) 调用 HelloWorldEntry ;
HelloWorldEntry 内执行一次 printf("[HelloWorld] hello world.\r\n") ;
串口上会看到一条带 [HelloWorld] 前缀的日志,便于确认 demo 已执行。
# 五、编译
在 OpenHarmony 工程根目录下依次 执行以下命令(建议分步执行,便于排查问题)。
1. 清理上次编译产物 (避免旧 out 与缓存干扰)
rm -fr out/xiaohong/xiaohong/ .ccache/*
2. 选择产品与系统类型
按提示依次选择,最终应显示为:
OHOS Which os_level do you need? mini
OHOS Which product do you need? xiaohong
3. 全量编译并生成固件
编译成功后,固件生成路径为:out/xiaohong/xiaohong/ws63-liteos-app (Windows 下如 Z:\A_OH60T\out\xiaohong\xiaohong\ws63-liteos-app)。
# 六、烧录
以下内容来自《小鸿AI 固件烧录与启动指导手册》固件烧录与启动说明。
# 6.1 烧录前准备
硬件搭建 :使用 Typec 线将板端与 PC 端连接。
55c4feb3c99d6077ec23c8438c3c15da
安装驱动 :安装「CH341SER 驱动」(CH341SER 驱动下载地址 ,若该链接失效或无法下载,可自行搜索下载)。安装前请将单板与 PC 连接,点击安装即可;显示驱动安装成功 代表成功,若显示驱动预安装成功 则代表安装失败。
下载 BurnTool 烧录工具 :下载并解压 BurnTool。
链接:https://atomgit.com/xiaohong-ai/docs/tree/main/tools
打开烧录工具,选择对应的串口;点开 Option 选项,选择对应目标(WS63E 与 WS63 属于同一系列,选 WS63 即可)。
点击 Select file 选择烧录文件(选择 ws63-liteos-app-all.fwpkg ,该文件位于固件路径 Z:\A_OH60T\out\xiaohong\xiaohong\ws63-liteos-app 下)。
勾选 Auto Burn 和 Auto disconnect 选项。
⚠️ 重要:进入烧录方式因板子批次不同
新板子 :点击 Connect 后直接开始烧录 。
旧板子 :点击 Connect 后,需同时按住两个音量/亮度按键约 1.5 秒后松开 ,再开始烧录。
待全部烧录成功后,显示 All images burn successfully 。
673e3245796e6d6497f3e480b2f9bd25
# 七、串口输出与结果分析
# 7.1 串口连接(查看日志)
准备:
烧录完成后,按以下步骤通过串口查看运行日志:
打开 UartAssist ,协议选择 SERIAL ,端口选择小鸿对应的 COM 口;
设置串口参数:波特率 115200 ,数据位 8,停止位 1,无校验、无流控;
先打开串口连接;
再给板子上电或复位,即可抓取完整启动与 HelloWorld 日志。
在串口工具页面查看打印日志
# 7.2 预期出现的日志
阶段
日志特征
系统启动
若干行 APP/SDK 等启动日志
HelloWorld
出现一行:[HelloWorld] hello world.
# 7.3 实际运行日志(节选)
APP|dbg uart init ok.
APP|SDK Version: 1.10.106
...
[HelloWorld] hello world.
...
# 7.4 如何判断“运行成功”
串口波特率 115200 下,在启动日志中能看到 [HelloWorld] hello world. 即表示:
小鸿工程已正确编译并烧录;
HelloWorld demo 已通过 samples/BUILD.gn 的 features 及 config.py / ohos.cmake 纳入编译并打进 ws63-liteos-app 镜像;
系统启动时已执行 HelloWorld 初始化并完成一次日志打印。
# 八、常见问题与排查
现象
建议排查
串口无任何打印
确认 COM 口是否正确(部分板子有烧录口与日志口之分);TX/RX 是否交叉接好;是否先打开串口再上电/复位。
有启动日志但无 [HelloWorld]
确认:(1) vendor/atomgit/xiaohong/BUILD.gn 的 deps 含 "samples:app", ;(2) samples/BUILD.gn 的 features 中含未注释的 "00_helloworld:helloworld" ;(3) config.py 的 ram_component 与 ohos.cmake 的 COMPONENT_LIST 中已添加 "helloworld" 。然后执行清理后重新全量编译并烧录。
乱码
确认波特率为 115200,与系统串口输出配置一致。
# 九、小结
文件放哪里 :HelloWorld demo 位于 vendor/atomgit/xiaohong/samples/00_helloworld/ ,内含 helloworld.c 、BUILD.gn (static_library("helloworld"))及 README。若从别处拷贝,请将 00_helloworld 整目录放到 vendor/atomgit/xiaohong/samples 下。
改哪里能编译并打进镜像 :
1. vendor/atomgit/xiaohong/BUILD.gn :group("xiaohong") 的 deps 中须包含 "samples:app", ;
2. vendor/atomgit/xiaohong/samples/BUILD.gn :features 中须包含未注释的 "00_helloworld:helloworld" ;
3. device/soc/hisilicon/ws63v100/sdkv106/build/config/target_config/ws63/config.py :'ws63-liteos-app' 的 ram_component 中须添加 "helloworld" ;
4. device/soc/hisilicon/ws63v100/sdkv106/libs_url/ws63/cmake/ohos.cmake :ws63-liteos-app 对应的 COMPONENT_LIST 中须添加 "helloworld" 。
编译时先执行 清理 (rm -fr out/xiaohong/xiaohong/ .ccache/*),再 hb set (选择 mini + xiaohong),最后 hb build -f 。烧录后,用串口工具以 115200 波特率连接,上电或复位后看到 [HelloWorld] hello world. 即可判定 HelloWorld demo 在小鸿上运行成功。
文档版本 :与 vendor/atomgit/xiaohong/samples/00_helloworld/README.md 集成与编译步骤保持一致。
相关目录 :vendor/atomgit/xiaohong/samples/00_helloworld/(helloworld.c、BUILD.gn、README.md)。
Was this helpful? 👍 Yes 👎 Needs work
HANDS-ON SAMPLES Xiaohong AI · official docs
02 · Software timer Hands-on samples / 02 · Software timeri18n · The narrative below is the original Chinese reference (technical content — code, commands and logs are universal). A fully translated English edition is in progress.
View Chinese version → # 一、背景与目标
# 1.1 小鸿与 01_timer 是什么
小鸿 是基于 OpenHarmony + 海思 WS63 方案的设备/工程,其代码位于 vendor/atomgit/xiaohong/xiaohong,使用 CMSIS-RTOS2(LiteOS-M 适配)做多任务调度。
01_timer 是小鸿工程内的一个软件定时器示例 ,演示 CMSIS-RTOS2 的周期定时器(osTimerNew、osTimerStart、osTimerStop、osTimerDelete)的创建、启动、回调与停止。在系统启动时通过 APP_FEATURE_INIT 注册初始化函数,创建名为 timer_periodic 的线程,在该线程中创建周期 100ms 的定时器,回调累计 3 次后停止并删除定时器,并通过串口输出 [Timer Test] 日志。将其集成到小鸿上,可以:
验证小鸿工程下软件定时器 API 的编译与运行是否正常;
作为“定时器类 demo”的参考,便于后续做周期任务、超时检测等开发。
# 1.2 本文目标
说明 定时器 demo 所在目录与构建方式 (samples/01_timer,通过 features 编入);
说明 为能编译并打进镜像需要修改的文件 :vendor 顶层 BUILD.gn、samples/BUILD.gn、config.py、ohos.cmake;
说明运行逻辑与串口预期输出;
给出预期日志与“如何判断成功”的结论。
# 二、环境与前置条件
工程 :OpenHarmony + 小鸿 vendor(vendor/atomgit/xiaohong,含主库与 samples ,定时器示例位于 samples/01_timer );
SDK :WS63 SDK(通过 ws63_sdk.gni 引用);
工具 :串口调试助手(如 UartAssist、Xshell 等),波特率 115200 ;
硬件 :小鸿开发板,通过 USB 转串口连接 PC,TX/RX/GND 正确连接。
# 三、集成步骤(文件放哪里、改哪里能编译)
定时器示例以 samples 形式存在,目录为 vendor/atomgit/xiaohong/samples/01_timer ,通过 samples/BUILD.gn 的 features 与板级 config.py / ohos.cmake 参与编译并打进 ws63-liteos-app 镜像。以下步骤须全部完成,缺一不可。
# 3.1 目录与源码位置
本示例已放在小鸿 vendor 包内:
目录 :vendor/atomgit/xiaohong/samples/01_timer/ ;
源文件 :timer.c ;
构建目标 :本目录下的 static_library("timer_demo") ,由 samples/BUILD.gn 以 feature "01_timer:timer_demo" 形式编入应用。
完整路径为:
vendor/atomgit/xiaohong/
├── BUILD.gn
└── samples/
├── BUILD.gn
└── 01_timer/
├── BUILD.gn # static_library("timer_demo")
├── timer.c # 演示源码
└── README.md
若从别处拷贝示例,请将 01_timer 整个目录放到 vendor/atomgit/xiaohong/samples 下。
# 3.2 步骤 1:检查 vendor 顶层 BUILD.gn(编译前必查)
打开 vendor/atomgit/xiaohong/BUILD.gn ,在 group("xiaohong") 的 deps 中确认包含 "samples:app", 。若缺少该项,samples 下的示例不会参与整包编译。
group("xiaohong") {
deps = [
"xiaohong:xiaohong",
"samples:app",
]
}
# 3.3 步骤 2:在 samples/BUILD.gn 中启用定时器示例
修改 vendor/atomgit/xiaohong/samples/BUILD.gn ,在 lite_component("app") 的 features 列表中保留或添加 "01_timer:timer_demo" (未注释):
lite_component("app") {
features = [
"01_timer:timer_demo",
# 其他示例按需取消注释
]
}
说明 :以 # 开头的行为注释,不会参与编译 ;需要编进固件的示例须为未注释的一行。
# 3.4 步骤 3:在 config.py 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/build/config/target_config/ws63/config.py 中,找到 'ws63-liteos-app' 配置,在其 'ram_component' 列表中添加 "timer_demo" :
说明 :ram_component 声明参与 ws63-liteos-app 镜像链接的组件;未在此列出的 static_library 不会被打进最终 app 镜像。
# 3.5 步骤 4:在 ohos.cmake 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/libs_url/ws63/cmake/ohos.cmake 中,找到 elseif(${TARGET_COMMAND} MATCHES "ws63-liteos-app") 对应的 set(COMPONENT_LIST ...) ,在列表中添加 "timer_demo" :
说明 :COMPONENT_LIST 决定参与构建与安装的组件(静态库),需与 步骤 3 的 ram_component 及 samples 内 BUILD.gn 的 target 名称一致。
# 3.6 代码介绍
本小节说明 timer.c 的编写思路与关键实现:通过 APP_FEATURE_INIT 注册启动任务,在任务中创建线程,在线程内使用 CMSIS-RTOS2 的 osTimerNew / osTimerStart / osTimerStop / osTimerDelete 完成周期定时器的创建、启动、回调计数与停止删除,并用串口打印 [Timer Test] 日志。核心代码如下(头文件与许可证从略,工程中以完整文件为准)。
/*
* Copyright (C) 2024 HiHope Open Source Organization .
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
static int times = 0;
/* 定时器周期回调:每次被调用时 times 自增 */
void cb_timeout_periodic(void *arg)
{
(void)arg;
times++;
}
/* 线程入口:创建周期定时器,启动后每 100ms 打印 times,满 3 次后停止并删除定时器 */
void timer_periodic(void)
{
osTimerId_t periodic_tid = osTimerNew(cb_timeout_periodic, osTimerPeriodic, NULL, NULL);
const uint32_t DelayTimeMs = 100;
const uint32_t DelayTime = 3;
if (periodic_tid == NULL) {
printf("[Timer Test] osTimerNew(periodic timer) failed.\r\n");
return;
} else {
printf("[Timer Test] osTimerNew(periodic timer) success, tid: %p.\r\n", periodic_tid);
}
osStatus_t status = osTimerStart(periodic_tid, 100);
if (status != osOK) {
printf("[Timer Test] osTimerStart(periodic timer) failed.\r\n");
return;
} else {
printf("[Timer Test] osTimerStart(periodic timer) success, wait a while and stop.\r\n");
}
while (times < DelayTime) {
printf("[Timer Test] times:%d.\r\n", times);
osDelay(DelayTimeMs);
}
status = osTimerStop(periodic_tid);
printf("[Timer Test] stop periodic timer, status :%d.\r\n", status);
status = osTimerDelete(periodic_tid);
printf("[Timer Test] kill periodic timer, status :%d.\r\n", status);
}
/* 启动任务:创建名为 timer_periodic 的线程 */
static void TimerTestTask(void)
{
osThreadAttr_t attr;
attr.name = "timer_periodic";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = 0x1000;
attr.priority = osPriorityNormal;
if (osThreadNew((osThreadFunc_t)timer_periodic, NULL, &attr) == NULL) {
printf("[TimerTestTask] Falied to create timer_periodic!\n");
}
}
APP_FEATURE_INIT(TimerTestTask);
要点简述:
cb_timeout_periodic :定时器周期回调,仅对全局 times 自增,供线程内判断是否已执行 3 次。
timer_periodic :线程函数。先 osTimerNew(..., osTimerPeriodic, ...) 创建周期定时器,再 osTimerStart(periodic_tid, 100) 以 100 tick(约 100ms)为周期启动;循环中每 100ms 打印当前 times,当 times >= 3 后调用 osTimerStop、osTimerDelete 并打印状态。
TimerTestTask :通过 APP_FEATURE_INIT(TimerTestTask) 在系统启动时执行,配置线程属性后调用 osThreadNew 创建 timer_periodic 线程。
与 00_thread、helloword 相同,使用 ohos_init.h 与串口 printf,无需额外适配。
# 四、运行逻辑简述
系统启动后,通过 APP_FEATURE_INIT(TimerTestTask) 调用 TimerTestTask ;
TimerTestTask 创建线程 timer_periodic ,线程入口为 timer_periodic ;
timer_periodic 内:
1. 创建周期定时器,周期 100 tick(约 100ms),回调 cb_timeout_periodic (每次 times++);
2. 启动定时器;
3. 循环中每 100ms 打印 [Timer Test] times:x,直到 times >= 3(即打印 times:0、1、2);
4. 停止并删除定时器,打印 stop/delete 的 status。
串口上会看到多行带 [Timer Test] 前缀的日志,便于确认 demo 已执行且定时器行为正确。
# 五、编译
在 OpenHarmony 工程根目录下依次 执行(建议分步执行):1. 清理 rm -fr out/xiaohong/xiaohong/ .ccache/*;2. 选择产品 hb set(按提示选择 mini 、xiaohong );3. 全量编译 hb build -f。编译成功后,固件生成路径为 out/xiaohong/xiaohong/ws63-liteos-app (Windows 下如 Z:\A_OH60T\out\...)。
# 六、烧录
以下内容与 HelloWorld 等 demo 通用,参见《小鸿AI 固件烧录与启动指导手册》或同仓库烧录说明。
# 6.1 烧录前准备
硬件搭建 :使用 Typec 线将板端与 PC 端连接。
55c4feb3c99d6077ec23c8438c3c15da
安装驱动 :安装「CH341SER 驱动」(CH341SER 驱动下载地址 ,若该链接失效或无法下载,可自行搜索下载)。安装前请将单板与 PC 连接,点击安装即可;显示驱动安装成功 代表成功,若显示驱动预安装成功 则代表安装失败。
下载 BurnTool 烧录工具 :下载并解压 BurnTool。
链接:https://atomgit.com/xiaohong-ai/docs/tree/main/tools
打开烧录工具,选择对应的串口;点开 Option 选项,选择对应目标(WS63E 与 WS63 属于同一系列,选 WS63 即可)。
点击 Select file 选择烧录文件(选择 ws63-liteos-app-all.fwpkg ,该文件位于固件路径 Z:\A_OH60T\out\xiaohong\xiaohong\ws63-liteos-app 下)。
勾选 Auto Burn 和 Auto disconnect 选项。
⚠️ 重要:进入烧录方式因板子批次不同
新板子 :点击 Connect 后直接开始烧录 。
旧板子 :点击 Connect 后,需同时按住两个音量/亮度按键约 1.5 秒后松开 ,再开始烧录。
待全部烧录成功后,显示 All images burn successfully 。
673e3245796e6d6497f3e480b2f9bd25
# 七、串口输出与结果分析
# 7.1 串口连接(查看日志)
准备:
烧录完成后,按以下步骤通过串口查看运行日志:
打开 UartAssist ,协议选择 SERIAL ,端口选择小鸿对应的 COM 口;
设置串口参数:波特率 115200 ,数据位 8,停止位 1,无校验、无流控;
先打开串口连接;
再给板子上电或复位,即可抓取完整启动与 01_timer 日志。
在串口工具页面查看打印日志
# 7.2 预期出现的日志(01_timer 相关)
阶段
日志特征
定时器创建
[Timer Test] osTimerNew(periodic timer) success, tid: 0x...
定时器启动
[Timer Test] osTimerStart(periodic timer) success, wait a while and stop.
回调执行计数
[Timer Test] times:0.、times:1.、times:2.(共 3 次)
定时器停止
[Timer Test] stop periodic timer, status :0.
定时器删除
[Timer Test] kill periodic timer, status :0.
其中 status :0 表示 osOK,即接口调用成功。
# 7.3 实际运行日志(节选)
APP|dbg uart init ok.
APP|SDK Version: 1.10.106
...
[Timer Test] osTimerNew(periodic timer) success, tid: 0xa148e0.
[Timer Test] osTimerStart(periodic timer) success, wait a while and stop.
[Timer Test] times:0.
[Timer Test] times:1.
[Timer Test] times:2.
[Timer Test] stop periodic timer, status :0.
[Timer Test] kill periodic timer, status :0.
# 7.4 如何判断“运行成功”
串口波特率 115200 下,在启动日志中能看到上述 [Timer Test] 系列输出,且 stop/delete 的 status 为 0 ,即表示:
小鸿工程已正确编译并烧录;
01_timer demo 已通过 samples/BUILD.gn 的 features 及 config.py / ohos.cmake 纳入编译并打进 ws63-liteos-app 镜像;
系统启动时已执行 TimerTestTask,创建线程与周期定时器,回调执行 3 次后定时器被正确停止与删除。
# 八、常见问题与排查
现象
建议排查
串口无任何打印
确认 COM 口、TX/RX 接线;是否先打开串口再上电/复位。
有启动日志但无 [Timer Test]
确认:(1) vendor/atomgit/xiaohong/BUILD.gn 的 deps 含 "samples:app", ;(2) samples/BUILD.gn 的 features 中含未注释的 "01_timer:timer_demo" ;(3) config.py 的 ram_component 与 ohos.cmake 的 COMPONENT_LIST 中已添加 "timer_demo" 。然后执行清理后重新全量编译并烧录。
乱码
确认波特率为 115200。
只看到 osTimerNew 成功,无 times
多为其他任务占用 CPU 或调度延迟,可稍等或复位再观察;若仍无,检查是否烧录为最新固件。
# 九、小结
文件放哪里 :定时器 demo 位于 vendor/atomgit/xiaohong/samples/01_timer/ (含 timer.c、BUILD.gn、README)。若从别处拷贝,请将 01_timer 整目录放到 vendor/atomgit/xiaohong/samples 下。
改哪里能编译并打进镜像 :(1) vendor/atomgit/xiaohong/BUILD.gn 的 deps 须含 "samples:app", ;(2) samples/BUILD.gn 的 features 须含 "01_timer:timer_demo" ;(3) config.py (sdkv106 下)的 ram_component 须含 "timer_demo" ;(4) ohos.cmake (sdkv106 下)的 COMPONENT_LIST 须含 "timer_demo" 。
编译:先清理,再 hb set (mini + xiaohong),最后 hb build -f 。烧录后以 115200 波特率连接串口,看到完整 [Timer Test] 日志且 stop/delete status 为 0,即可判定 01_timer(软件定时器)demo 在小鸿上运行成功。
文档版本 :与 vendor/atomgit/xiaohong/samples/01_timer/README.md 集成与编译步骤保持一致。
相关目录 :vendor/atomgit/xiaohong/samples/01_timer/。
Was this helpful? 👍 Yes 👎 Needs work
HANDS-ON SAMPLES Xiaohong AI · official docs
03 · Delay Hands-on samples / 03 · Delayi18n · The narrative below is the original Chinese reference (technical content — code, commands and logs are universal). A fully translated English edition is in progress.
View Chinese version → # 一、背景与目标
# 1.1 小鸿与 02_delay 是什么
小鸿 是基于 OpenHarmony + 海思 WS63 方案的设备/工程,其代码位于 vendor/atomgit/xiaohong/xiaohong,使用 CMSIS-RTOS2(LiteOS-M 适配)做多任务调度。
02_delay 是小鸿工程内的一个延时 API 示例 ,演示 CMSIS-RTOS2 的 osDelay(相对延时)与 osDelayUntil(绝对截止时间延时)的用法,以及 osKernelGetTickCount 获取系统 tick。在系统启动时通过 APP_FEATURE_INIT 注册初始化函数,创建名为 rtosv2_delay_main 的线程,在该线程中依次执行 100 tick 的 osDelay 和基于当前 tick 的 osDelayUntil,并通过串口输出 [Delay Test] 日志。将其集成到小鸿上,可以:
验证小鸿工程下延时与系统 tick API 的编译与运行是否正常;
作为“任务调度与延时”类 demo 的参考,便于后续做周期任务、超时控制等开发。
# 1.2 本文目标
说明 延时 demo 所在目录与构建方式 (samples/02_delay,通过 features 编入);
说明 为能编译并打进镜像需要修改的文件 :vendor 顶层 BUILD.gn、samples/BUILD.gn、config.py、ohos.cmake;
说明运行逻辑与串口预期输出;
给出实际运行日志与“如何判断成功”的结论。
# 二、环境与前置条件
工程 :OpenHarmony + 小鸿 vendor(vendor/atomgit/xiaohong,含主库与 samples ,延时示例位于 samples/02_delay );
SDK :WS63 SDK(通过 ws63_sdk.gni 引用);
工具 :串口调试助手(如 UartAssist、Xshell 等),波特率 115200 ;
硬件 :小鸿开发板,通过 USB 转串口连接 PC,TX/RX/GND 正确连接。
# 三、集成步骤(文件放哪里、改哪里能编译)
延时示例以 samples 形式存在,目录为 vendor/atomgit/xiaohong/samples/02_delay ,通过 samples/BUILD.gn 的 features 与板级 config.py / ohos.cmake 参与编译并打进 ws63-liteos-app 镜像。以下步骤须全部完成,缺一不可。
# 3.1 目录与源码位置
本示例已放在小鸿 vendor 包内:
目录 :vendor/atomgit/xiaohong/samples/02_delay/ ;
源文件 :delay.c ;
构建目标 :本目录下的 static_library("delay_demo") ,由 samples/BUILD.gn 以 feature "02_delay:delay_demo" 形式编入应用。
完整路径为:
vendor/atomgit/xiaohong/
├── BUILD.gn # 顶层 group,依赖 xiaohong 主库与 samples
└── samples/
├── BUILD.gn # lite_component("app"),通过 features 选择示例
└── 02_delay/
├── BUILD.gn # static_library("delay_demo")
├── delay.c # 演示源码
└── README.md # 操作说明
若从别处拷贝示例,请将 02_delay 整个目录放到 vendor/atomgit/xiaohong/samples 下。
# 3.2 步骤 1:检查 vendor 顶层 BUILD.gn(编译前必查)
打开 vendor/atomgit/xiaohong/BUILD.gn ,在 group("xiaohong") 的 deps 中确认包含 "samples:app", 。若缺少该项,samples 下的示例不会参与整包编译。
group("xiaohong") {
deps = [
"xiaohong:xiaohong",
"samples:app",
]
}
# 3.3 步骤 2:在 samples/BUILD.gn 中启用延时示例
修改 vendor/atomgit/xiaohong/samples/BUILD.gn ,在 lite_component("app") 的 features 列表中保留或添加 "02_delay:delay_demo" (未注释):
lite_component("app") {
features = [
"02_delay:delay_demo",
# 其他示例按需取消注释
]
}
说明 :以 # 开头的行为注释,不会参与编译 ;需要编进固件的示例须为未注释的一行。
# 3.4 步骤 3:在 config.py 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/build/config/target_config/ws63/config.py 中,找到 'ws63-liteos-app' 配置,在其 'ram_component' 列表中添加 "delay_demo" :
说明 :ram_component 声明参与 ws63-liteos-app 镜像链接的组件;未在此列出的 static_library 不会被打进最终 app 镜像。
# 3.5 步骤 4:在 ohos.cmake 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/libs_url/ws63/cmake/ohos.cmake 中,找到 elseif(${TARGET_COMMAND} MATCHES "ws63-liteos-app") 对应的 set(COMPONENT_LIST ...) ,在列表中添加 "delay_demo" :
说明 :COMPONENT_LIST 决定参与构建与安装的组件(静态库),需与 步骤 3 的 ram_component 及 samples 内 BUILD.gn 的 target 名称一致。
# 3.6 代码说明(无需再改)
当前 delay.c 主要逻辑:
线程入口 :rtosv2_delay_main 先打印当前系统 tick(osKernelGetTickCount()),再调用 osDelay(100) 延时 100 个 tick,返回后打印 status 与新的 tick;随后取当前 tick 并加 100 作为目标,调用 osDelayUntil(tick) 延时到该绝对时刻,再打印 status 与 tick。
注册 :通过 APP_FEATURE_INIT(DelayTestTask) 在启动时执行 DelayTestTask,创建线程 rtosv2_delay_main。
与 01_timer、helloword 使用同一套 ohos_init.h 与串口打印方式,无需额外适配。
# 四、运行逻辑简述
系统启动后,通过 APP_FEATURE_INIT(DelayTestTask) 调用 DelayTestTask ;
DelayTestTask 创建线程 rtosv2_delay_main ,线程入口为 rtosv2_delay_main ;
rtosv2_delay_main 内:
1. 打印当前系统 tick;
2. 调用 osDelay(100) ,阻塞约 100 tick(约 100ms)后返回,打印 status 与新的 tick(预期增加约 100);
3. 取当前 tick,加 100 得到目标 tick,调用 osDelayUntil(目标 tick) ,阻塞到该绝对时刻,打印 status 与当前 tick(预期再增加约 100)。
串口上会看到多行带 [Delay Test] 前缀的日志,且 tick 呈“初始 → +100 → 再 +100”的递进,便于确认 demo 已执行且延时 API 行为正确。
# 五、编译
在 OpenHarmony 工程根目录下依次 执行:1. 清理 rm -fr out/xiaohong/xiaohong/ .ccache/*;2. 选择产品 hb set(按提示选择 mini 、xiaohong );3. 全量编译 hb build -f。编译成功后,固件生成路径为 out/xiaohong/xiaohong/ws63-liteos-app (Windows 下如 Z:\A_OH60T\out\...)。
# 六、烧录
以下内容与 HelloWorld、01_timer 等 demo 通用,参见《小鸿AI 固件烧录与启动指导手册》或同仓库烧录说明。
# 6.1 烧录前准备
硬件搭建 :使用 Typec 线将板端与 PC 端连接。
55c4feb3c99d6077ec23c8438c3c15da
安装驱动 :安装「CH341SER 驱动」(CH341SER 驱动下载地址 ,若该链接失效或无法下载,可自行搜索下载)。安装前请将单板与 PC 连接,点击安装即可;显示驱动安装成功 代表成功,若显示驱动预安装成功 则代表安装失败。
下载 BurnTool 烧录工具 :下载并解压 BurnTool。
链接:https://atomgit.com/xiaohong-ai/docs/tree/main/tools
打开烧录工具,选择对应的串口;点开 Option 选项,选择对应目标(WS63E 与 WS63 属于同一系列,选 WS63 即可)。
点击 Select file 选择烧录文件(选择 ws63-liteos-app-all.fwpkg ,该文件位于固件路径 Z:\A_OH60T\out\xiaohong\xiaohong\ws63-liteos-app 下)。
勾选 Auto Burn 和 Auto disconnect 选项。
⚠️ 重要:进入烧录方式因板子批次不同
新板子 :点击 Connect 后直接开始烧录 。
旧板子 :点击 Connect 后,需同时按住两个音量/亮度按键约 1.5 秒后松开 ,再开始烧录。
待全部烧录成功后,显示 All images burn successfully 。
673e3245796e6d6497f3e480b2f9bd25
# 七、串口输出与结果分析
# 7.1 串口连接(查看日志)
准备:
烧录完成后,按以下步骤通过串口查看运行日志:
打开 UartAssist ,协议选择 SERIAL ,端口选择小鸿对应的 COM 口;
设置串口参数:波特率 115200 ,数据位 8,停止位 1,无校验、无流控;
先打开串口连接;
再给板子上电或复位,即可抓取完整启动与 02_delay 日志。
在串口工具页面查看打印日志
# 7.2 预期出现的日志(02_delay 相关)
阶段
日志特征
初始 tick
[Delay Test] Current system tick: <初始值>.
osDelay 调用
[Delay Test] osDelay, status: 0.
osDelay 后 tick
[Delay Test] Current system tick: <初始+约100>.
osDelayUntil
[Delay Test] osDelayUntil, status: 0.
osDelayUntil 后
[Delay Test] Current system tick: <再+约100>.
其中 status: 0 表示 osOK,即接口调用成功;tick 递增约 100、再约 100 可验证延时生效。
# 7.3 实际运行日志(节选)
根据在小鸿板上的实测,02_delay 相关输出如下(系统启动日志已省略):
APP|dbg uart init ok.
APP|SDK Version: 1.10.106
...
[Delay Test] Current system tick: 5.
...
[Delay Test] osDelay, status: 0.
[Delay Test] Current system tick: 105.
[Delay Test] osDelayUntil, status: 0.
[Delay Test] Current system tick: 205.
可见:初始 tick 为 5,osDelay(100) 后 tick 为 105(增加 100),osDelayUntil 后 tick 为 205(再增加 100),与预期一致。
# 7.4 如何判断“运行成功”
串口波特率 115200 下,在启动日志中能看到上述 [Delay Test] 系列输出,且:
osDelay、osDelayUntil 的 status 均为 0 ;
系统 tick 呈“初始 → +100 → 再 +100”的递进 ;
即表示:
小鸿工程已正确编译并烧录;
02_delay demo 已通过 samples/BUILD.gn 的 features 及 config.py / ohos.cmake 纳入编译并打进 ws63-liteos-app 镜像;
系统启动时已执行 DelayTestTask,线程内 osDelay 与 osDelayUntil 均按预期工作。
# 八、常见问题与排查
现象
建议排查
串口无任何打印
确认 COM 口、TX/RX 接线;是否先打开串口再上电/复位。
有启动日志但无 [Delay Test]
确认:(1) vendor/atomgit/xiaohong/BUILD.gn 的 deps 含 "samples:app", ;(2) samples/BUILD.gn 的 features 中含未注释的 "02_delay:delay_demo" ;(3) config.py 的 ram_component 与 ohos.cmake 的 COMPONENT_LIST 中已添加 "delay_demo" 。然后执行清理后重新全量编译并烧录。
乱码
确认波特率为 115200。
tick 递进不明显或间隔异常
系统负载或其它任务可能影响调度;可多次复位观察,或确认已烧录最新固件。
# 九、小结
文件放哪里 :延时 demo 位于 vendor/atomgit/xiaohong/samples/02_delay/ (含 delay.c、BUILD.gn、README)。若从别处拷贝,请将 02_delay 整目录放到 vendor/atomgit/xiaohong/samples 下。
改哪里能编译并打进镜像 :(1) vendor/atomgit/xiaohong/BUILD.gn 的 deps 须含 "samples:app", ;(2) samples/BUILD.gn 的 features 须含 "02_delay:delay_demo" ;(3) config.py (sdkv106 下)的 ram_component 须含 "delay_demo" ;(4) ohos.cmake (sdkv106 下)的 COMPONENT_LIST 须含 "delay_demo" 。
编译:先清理,再 hb set (mini + xiaohong),最后 hb build -f 。烧录后以 115200 波特率连接串口,看到完整 [Delay Test] 日志且 osDelay/osDelayUntil status 为 0、tick 按约 100 递进,即可判定 02_delay(延时)demo 在小鸿上运行成功。
文档版本 :与 vendor/atomgit/xiaohong/samples/02_delay/README.md 集成与编译步骤保持一致。
相关目录 :vendor/atomgit/xiaohong/samples/02_delay/。
Was this helpful? 👍 Yes 👎 Needs work
HANDS-ON SAMPLES Xiaohong AI · official docs
04 · Mutex Hands-on samples / 04 · Mutexi18n · The narrative below is the original Chinese reference (technical content — code, commands and logs are universal). A fully translated English edition is in progress.
View Chinese version → # 一、背景与目标
# 1.1 小鸿与 03_mutex 是什么
小鸿 是基于 OpenHarmony + 海思 WS63 方案的设备/工程,其代码位于 vendor/atomgit/xiaohong/xiaohong,使用 CMSIS-RTOS2(LiteOS-M 适配)做多任务调度。
03_mutex 是小鸿工程内的一个互斥锁(Mutex)API 示例 ,演示 CMSIS-RTOS2 的 osMutexNew、osMutexAcquire、osMutexRelease、osMutexGetOwner、osMutexDelete 等用法。通过 APP_FEATURE_INIT 注册初始化函数,创建线程 rtosv2_mutex_main,在该线程中创建互斥锁和三个子线程(Thread_1/2/3),三个线程竞争对全局变量 g_test_value 的递增并打印奇偶;主线程延时后查询当前持有锁的线程并打印,最后终止子线程并删除互斥锁。将其集成到小鸿上,可以:
验证小鸿工程下互斥锁与多线程同步 API 的编译与运行是否正常;
作为“多线程与互斥”类 demo 的参考。
# 1.2 本文目标
说明 互斥锁 demo 所在目录与构建方式 (samples/03_mutex,通过 features 编入);
说明 为能编译并打进镜像需要修改的文件 :vendor 顶层 BUILD.gn、samples/BUILD.gn、config.py、ohos.cmake;
说明运行逻辑与串口预期输出;
给出如何判断运行成功的结论。
# 二、环境与前置条件
工程 :OpenHarmony + 小鸿 vendor(vendor/atomgit/xiaohong,含主库与 samples ,互斥锁示例位于 samples/03_mutex );
SDK :WS63 SDK(通过 ws63_sdk.gni 引用);
工具 :串口调试助手(如 UartAssist、Xshell 等),波特率 115200 ;
硬件 :小鸿开发板,通过 USB 转串口连接 PC,TX/RX/GND 正确连接。
# 三、集成步骤(文件放哪里、改哪里能编译)
互斥锁示例以 samples 形式存在,目录为 vendor/atomgit/xiaohong/samples/03_mutex ,通过 samples/BUILD.gn 的 features 与板级 config.py / ohos.cmake 参与编译并打进 ws63-liteos-app 镜像。以下步骤须全部完成,缺一不可。
# 3.1 目录与源码位置
本示例已放在小鸿 vendor 包内:
目录 :vendor/atomgit/xiaohong/samples/03_mutex/ ;
源文件 :mutex.c ;
构建目标 :本目录下的 static_library("mutex_demo") ,由 samples/BUILD.gn 以 feature "03_mutex:mutex_demo" 形式编入应用。
完整路径为:
vendor/atomgit/xiaohong/
├── BUILD.gn # 顶层 group,依赖 xiaohong 主库与 samples
└── samples/
├── BUILD.gn # lite_component("app"),通过 features 选择示例
└── 03_mutex/
├── BUILD.gn # static_library("mutex_demo")
├── mutex.c # 演示源码
└── README.md # 操作说明
若从别处拷贝示例,请将 03_mutex 整个目录放到 vendor/atomgit/xiaohong/samples 下。
# 3.2 步骤 1:检查 vendor 顶层 BUILD.gn(编译前必查)
打开 vendor/atomgit/xiaohong/BUILD.gn ,在 group("xiaohong") 的 deps 中确认包含 "samples:app", 。若缺少该项,samples 下的示例不会参与整包编译。
group("xiaohong") {
deps = [
"xiaohong:xiaohong",
"samples:app",
]
}
# 3.3 步骤 2:在 samples/BUILD.gn 中启用互斥锁示例
修改 vendor/atomgit/xiaohong/samples/BUILD.gn ,在 lite_component("app") 的 features 列表中保留或添加 "03_mutex:mutex_demo" (未注释):
lite_component("app") {
features = [
"03_mutex:mutex_demo",
# 其他示例按需取消注释
]
}
说明 :以 # 开头的行为注释,不会参与编译 ;需要编进固件的示例须为未注释的一行。
# 3.4 步骤 3:在 config.py 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/build/config/target_config/ws63/config.py 中,找到 'ws63-liteos-app' 配置,在其 'ram_component' 列表中添加 "mutex_demo" :
说明 :ram_component 声明参与 ws63-liteos-app 镜像链接的组件;未在此列出的 static_library 不会被打进最终 app 镜像。
# 3.5 步骤 4:在 ohos.cmake 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/libs_url/ws63/cmake/ohos.cmake 中,找到 elseif(${TARGET_COMMAND} MATCHES "ws63-liteos-app") 对应的 set(COMPONENT_LIST ...) ,在列表中添加 "mutex_demo" :
说明 :COMPONENT_LIST 决定参与构建与安装的组件(静态库),需与 步骤 3 的 ram_component 及 samples 内 BUILD.gn 的 target 名称一致。
# 3.6 代码说明(无需再改)
当前 mutex.c 主要逻辑:
主线程 rtosv2_mutex_main:创建互斥锁 → 创建 Thread_1/2/3(入口均为 number_thread,传入互斥锁 id)→ 延时 17ms → 调用 osMutexGetOwner 打印当前持锁线程 → 再延时 17ms → 终止三个子线程并删除互斥锁。
子线程 number_thread:循环中 osMutexAcquire(超时 100ms)→ 对 g_test_value 加一并按奇偶打印 → osMutexRelease → osDelay(5)。
注册 :通过 APP_FEATURE_INIT(MutexTestTask) 在启动时执行 MutexTestTask,创建线程 rtosv2_mutex_main。
与 02_delay 使用同一套 ohos_init.h 与 CMSIS-RTOS2,无需额外适配。
# 四、运行逻辑简述
系统启动后,通过 APP_FEATURE_INIT(MutexTestTask) 调用 MutexTestTask ;
MutexTestTask 创建线程 rtosv2_mutex_main ;
rtosv2_mutex_main 内:
1. osMutexNew 创建互斥锁,打印创建成功/失败;
2. newThread 创建 Thread_1、Thread_2、Thread_3,各打印创建成功及 thread id;
3. osDelay(17) 后调用 osMutexGetOwner ,打印当前持锁线程 id 与名字;
4. 再 osDelay(17) 后 osThreadTerminate 三个子线程,osMutexDelete 删除互斥锁。
三个子线程在运行期间会交替获得互斥锁,对 g_test_value 递增并打印 [Mutex Test] Thread_x gets an even/odd value N。
串口上会看到 [Mutex Test] 前缀的日志:创建互斥锁、创建线程、持锁者信息,以及多行 “Thread_x gets an even/odd value N”。
# 五、编译
在 OpenHarmony 工程根目录下依次 执行:1. 清理 rm -fr out/xiaohong/xiaohong/ .ccache/*;2. 选择产品 hb set(按提示选择 mini 、xiaohong );3. 全量编译 hb build -f。编译成功后,固件生成路径为 out/xiaohong/xiaohong/ws63-liteos-app (Windows 下如 Z:\A_OH60T\out\...)。
# 六、烧录
以下内容与 HelloWorld、01_timer、02_delay 等 demo 通用,参见《小鸿AI 固件烧录与启动指导手册》或同仓库烧录说明。
# 6.1 烧录前准备
硬件搭建 :使用 Typec 线将板端与 PC 端连接。
55c4feb3c99d6077ec23c8438c3c15da
安装驱动 :安装「CH341SER 驱动」(CH341SER 驱动下载地址 ,若该链接失效或无法下载,可自行搜索下载)。安装前请将单板与 PC 连接,点击安装即可;显示驱动安装成功 代表成功,若显示驱动预安装成功 则代表安装失败。
下载 BurnTool 烧录工具 :下载并解压 BurnTool。
链接:https://atomgit.com/xiaohong-ai/docs/tree/main/tools
打开烧录工具,选择对应的串口;点开 Option 选项,选择对应目标(WS63E 与 WS63 属于同一系列,选 WS63 即可)。
点击 Select file 选择烧录文件(选择 ws63-liteos-app-all.fwpkg ,该文件位于固件路径 Z:\A_OH60T\out\xiaohong\xiaohong\ws63-liteos-app 下)。
勾选 Auto Burn 和 Auto disconnect 选项。
⚠️ 重要:进入烧录方式因板子批次不同
新板子 :点击 Connect 后直接开始烧录 。
旧板子 :点击 Connect 后,需同时按住两个音量/亮度按键约 1.5 秒后松开 ,再开始烧录。
待全部烧录成功后,显示 All images burn successfully 。
673e3245796e6d6497f3e480b2f9bd25
# 七、串口输出与结果分析
# 7.1 串口连接(查看日志)
准备:
烧录完成后,按以下步骤通过串口查看运行日志:
打开 UartAssist ,协议选择 SERIAL ,端口选择小鸿对应的 COM 口;
设置串口参数:波特率 115200 ,数据位 8,停止位 1,无校验、无流控;
先打开串口连接;
再给板子上电或复位,即可抓取完整启动与 03_mutex 日志。
在串口工具页面查看打印日志
# 7.2 预期出现的日志(03_mutex 相关)
阶段
日志特征
创建互斥锁
[Mutex Test]osMutexNew, create mutex success.
创建线程
[Mutex Test]osThreadNew(Thread_1) success, thread id: ...(Thread_1/2/3 各一行)
子线程竞争
多行 [Mutex Test]Thread_x gets an even value N. 或 ... gets an odd value N.
查询持锁者
[Mutex Test]osMutexGetOwner, thread id: ..., thread name: Thread_x.
若在终止子线程前某一时刻没有线程持锁,osMutexGetOwner 可能返回 NULL,此时可能打印 (nil) / (null),也属正常。
# 7.3 如何判断“运行成功”
串口波特率 115200 下,在启动日志中能看到上述 [Mutex Test] 系列输出,且:
osMutexNew 打印 create mutex success ;
osThreadNew(Thread_1/2/3) 均打印 success ;
出现多行 Thread_x gets an even/odd value N (N 递增);
出现 osMutexGetOwner 的打印(持锁线程 id 与名字,或 nil/null);
即表示:
小鸿工程已正确编译并烧录;
03_mutex demo 已通过 samples/BUILD.gn 的 features 及 config.py / ohos.cmake 纳入编译并打进 ws63-liteos-app 镜像;
系统启动时已执行 MutexTestTask,互斥锁与多线程竞争逻辑按预期工作。
# 八、常见问题与排查
现象
建议排查
串口无任何打印
确认 COM 口、TX/RX 接线;是否先打开串口再上电/复位。
有启动日志但无 [Mutex Test]
确认:(1) vendor/atomgit/xiaohong/BUILD.gn 的 deps 含 "samples:app", ;(2) samples/BUILD.gn 的 features 中含未注释的 "03_mutex:mutex_demo" ;(3) config.py 的 ram_component 与 ohos.cmake 的 COMPONENT_LIST 中已添加 "mutex_demo" 。然后执行清理后重新全量编译并烧录。
乱码
确认波特率为 115200。
只看到创建互斥锁/线程,无 even/odd
子线程可能很快被 Terminate,属正常;可观察是否有若干行 even/odd 输出。
# 九、小结
文件放哪里 :互斥锁 demo 位于 vendor/atomgit/xiaohong/samples/03_mutex/ (含 mutex.c、BUILD.gn、README)。若从别处拷贝,请将 03_mutex 整目录放到 vendor/atomgit/xiaohong/samples 下。
改哪里能编译并打进镜像 :(1) vendor/atomgit/xiaohong/BUILD.gn 的 deps 须含 "samples:app", ;(2) samples/BUILD.gn 的 features 须含 "03_mutex:mutex_demo" ;(3) config.py (sdkv106 下)的 ram_component 须含 "mutex_demo" ;(4) ohos.cmake (sdkv106 下)的 COMPONENT_LIST 须含 "mutex_demo" 。
编译:先清理,再 hb set (mini + xiaohong),最后 hb build -f 。烧录后以 115200 波特率连接串口,看到完整 [Mutex Test] 日志即可判定 03_mutex(互斥锁)demo 在小鸿上运行成功。
文档版本 :与 vendor/atomgit/xiaohong/samples/03_mutex/README.md 集成与编译步骤保持一致。
相关目录 :vendor/atomgit/xiaohong/samples/03_mutex/。
Was this helpful? 👍 Yes 👎 Needs work
HANDS-ON SAMPLES Xiaohong AI · official docs
05 · Semaphore Hands-on samples / 05 · Semaphorei18n · The narrative below is the original Chinese reference (technical content — code, commands and logs are universal). A fully translated English edition is in progress.
View Chinese version → # 一、背景与目标
# 1.1 小鸿与 04_semaphore 是什么
小鸿 是基于 OpenHarmony + 海思 WS63 方案的设备/工程,其代码位于 vendor/atomgit/xiaohong/xiaohong,使用 CMSIS-RTOS2(LiteOS 适配)做多任务调度。
04_semaphore 是小鸿工程内的一个信号量(Semaphore)API 示例 ,演示 CMSIS-RTOS2 的 osSemaphoreNew、osSemaphoreAcquire、osSemaphoreRelease、osSemaphoreDelete 等用法。本样例为经典的生产者-消费者 问题:通过 empty_id、filled_id 两个信号量控制“空位”与“已生产数量”,实现 3 个生产者线程与 2 个消费者线程的协同。将其集成到小鸿上,可以:
验证小鸿工程下信号量与多线程同步 API 的编译与运行是否正常;
作为“多线程与信号量”类 demo 的参考。
# 1.2 本文目标
说明 信号量 demo 所在目录与构建方式 (samples/04_semaphore,通过 features 编入);
说明 为能编译并打进镜像需要修改的文件 :vendor 顶层 BUILD.gn、samples/BUILD.gn、config.py、ohos.cmake;
说明运行逻辑与串口预期输出;
给出如何判断运行成功的结论。
# 二、环境与前置条件
工程 :OpenHarmony + 小鸿 vendor(vendor/atomgit/xiaohong,含主库与 samples ,信号量示例位于 samples/04_semaphore );
SDK :WS63 SDK(通过 ws63_sdk.gni 引用);
工具 :串口调试助手(如 UartAssist、Xshell 等),波特率 115200 ;
硬件 :小鸿开发板,通过 USB 转串口连接 PC,TX/RX/GND 正确连接。
# 三、集成步骤(文件放哪里、改哪里能编译)
信号量示例以 samples 形式存在,目录为 vendor/atomgit/xiaohong/samples/04_semaphore ,通过 samples/BUILD.gn 的 features 与板级 config.py / ohos.cmake 参与编译并打进 ws63-liteos-app 镜像。以下步骤须全部完成,缺一不可。
# 3.1 目录与源码位置
本示例已放在小鸿 vendor 包内:
目录 :vendor/atomgit/xiaohong/samples/04_semaphore/ ;
源文件 :semp.c ;
构建目标 :本目录下的 static_library("semp_demo") ,由 samples/BUILD.gn 以 feature "04_semaphore:semp_demo" 形式编入应用。
完整路径为:
vendor/atomgit/xiaohong/
├── BUILD.gn # 顶层 group,依赖 xiaohong 主库与 samples
└── samples/
├── BUILD.gn # lite_component("app"),通过 features 选择示例
└── 04_semaphore/
├── BUILD.gn # static_library("semp_demo")
├── semp.c # 演示源码
└── README.md # 操作说明
若从别处拷贝示例,请将 04_semaphore 整个目录放到 vendor/atomgit/xiaohong/samples 下。
# 3.2 步骤 1:检查 vendor 顶层 BUILD.gn(编译前必查)
打开 vendor/atomgit/xiaohong/BUILD.gn ,在 group("xiaohong") 的 deps 中确认包含 "samples:app", 。若缺少该项,samples 下的示例不会参与整包编译。
group("xiaohong") {
deps = [
"xiaohong:xiaohong",
"samples:app",
]
}
# 3.3 步骤 2:在 samples/BUILD.gn 中启用信号量示例
修改 vendor/atomgit/xiaohong/samples/BUILD.gn ,在 lite_component("app") 的 features 列表中保留或添加 "04_semaphore:semp_demo" (未注释):
lite_component("app") {
features = [
"04_semaphore:semp_demo",
# 其他示例按需取消注释
]
}
说明 :以 # 开头的行为注释,不会参与编译 ;需要编进固件的示例须为未注释的一行。
# 3.4 步骤 3:在 config.py 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/build/config/target_config/ws63/config.py 中,找到 'ws63-liteos-app' 配置,在其 'ram_component' 列表中添加 "semp_demo" :
说明 :ram_component 声明参与 ws63-liteos-app 镜像链接的组件;未在此列出的 static_library 不会被打进最终 app 镜像。
# 3.5 步骤 4:在 ohos.cmake 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/libs_url/ws63/cmake/ohos.cmake 中,找到 elseif(${TARGET_COMMAND} MATCHES "ws63-liteos-app") 对应的 set(COMPONENT_LIST ...) ,在列表中添加 "semp_demo" :
说明 :COMPONENT_LIST 决定参与构建与安装的组件(静态库),需与 步骤 3 的 ram_component 及 samples 内 BUILD.gn 的 target 名称一致。
# 3.6 代码说明(无需再改)
当前 semp.c 主要逻辑:
主线程 rtosv2_semp_main:创建 empty_id、filled_id 两个信号量 → 创建 3 个生产者线程(producer1/2/3)、2 个消费者线程(consumer1/2)→ osDelay(50) → 终止所有子线程 → 删除两个信号量。
生产者 producer_thread:循环内 osSemaphoreAcquire(empty_id) → product_number++ 并打印 → osSemaphoreRelease(filled_id),生产满 10 次后退出。
消费者 consumer_thread:循环内 osSemaphoreAcquire(filled_id) → product_number-- 并打印 → osSemaphoreRelease(empty_id),消费满 10 次后退出。
注册 :通过 APP_FEATURE_INIT(SempTestTask) 在启动时执行 SempTestTask,创建线程 rtosv2_semp_main。
与 02_delay、03_mutex 使用同一套 ohos_init.h 与 CMSIS-RTOS2,无需额外适配。
# 四、运行逻辑简述
系统启动后,通过 APP_FEATURE_INIT(SempTestTask) 调用 SempTestTask ;
SempTestTask 创建线程 rtosv2_semp_main ;
rtosv2_semp_main 内:
1. osSemaphoreNew 创建 empty_id(初始 BUFFER_SIZE)、filled_id(初始 0);
2. newThread 创建 producer1、producer2、producer3、consumer1、consumer2,各打印创建成功及 thread id;
3. osDelay(50) 期间,生产者与消费者交替运行,打印 “produces a product” / “consumes a product” 及当前 product_number;
4. 50ms 后 osThreadTerminate 五个子线程,osSemaphoreDelete 删除两个信号量。
串口上会看到 [Semp Test] 前缀的日志:线程创建成功、生产者/消费者交替生产与消费及当前产品数量。
# 五、编译
在 OpenHarmony 工程根目录下依次 执行:1. 清理 rm -fr out/xiaohong/xiaohong/ .ccache/*;2. 选择产品 hb set(按提示选择 mini 、xiaohong );3. 全量编译 hb build -f。编译成功后,固件生成路径为 out/xiaohong/xiaohong/ws63-liteos-app (Windows 下如 Z:\A_OH60T\out\...)。
# 六、烧录
以下内容与 HelloWorld、01_timer、02_delay、03_mutex 等 demo 通用,参见《小鸿AI 固件烧录与启动指导手册》或同仓库烧录说明。
# 6.1 烧录前准备
硬件搭建 :使用 Typec 线将板端与 PC 端连接。
55c4feb3c99d6077ec23c8438c3c15da
安装驱动 :安装「CH341SER 驱动」(CH341SER 驱动下载地址 ,若该链接失效或无法下载,可自行搜索下载)。安装前请将单板与 PC 连接,点击安装即可;显示驱动安装成功 代表成功,若显示驱动预安装成功 则代表安装失败。
下载 BurnTool 烧录工具 :下载并解压 BurnTool。
链接:https://atomgit.com/xiaohong-ai/docs/tree/main/tools
打开烧录工具,选择对应的串口;点开 Option 选项,选择对应目标(WS63E 与 WS63 属于同一系列,选 WS63 即可)。
点击 Select file 选择烧录文件(选择 ws63-liteos-app-all.fwpkg ,该文件位于固件路径 Z:\A_OH60T\out\xiaohong\xiaohong\ws63-liteos-app 下)。
勾选 Auto Burn 和 Auto disconnect 选项。
⚠️ 重要:进入烧录方式因板子批次不同
新板子 :点击 Connect 后直接开始烧录 。
旧板子 :点击 Connect 后,需同时按住两个音量/亮度按键约 1.5 秒后松开 ,再开始烧录。
待全部烧录成功后,显示 All images burn successfully 。
673e3245796e6d6497f3e480b2f9bd25
# 七、串口输出与结果分析
# 7.1 串口连接(查看日志)
准备:
烧录完成后,按以下步骤通过串口查看运行日志:
打开 UartAssist ,协议选择 SERIAL ,端口选择小鸿对应的 COM 口;
设置串口参数:波特率 115200 ,数据位 8,停止位 1,无校验、无流控;
先打开串口连接;
再给板子上电或复位,即可抓取完整启动与 04_semaphore 日志。
在串口工具页面查看打印日志
# 7.2 预期出现的日志(04_semaphore 相关)
阶段
日志特征
创建线程
[Semp Test]osThreadNew(producer1) success, thread id: ...(producer1/2/3、consumer1/2 各一行)
生产者生产
多行 [Semp Test]producerx produces a product, now product number: N.
消费者消费
多行 [Semp Test]consumerx consumes a product, now product number: N.
因消费速度略快(osDelay(3))于生产(osDelay(4)),且各有 10 次退出条件,日志中会交替出现 producer 与 consumer 的打印,product number 在 0~BUFFER_SIZE(5) 附近波动。
# 7.3 如何判断“运行成功”
串口波特率 115200 下,在启动日志中能看到上述 [Semp Test] 系列输出,且:
osThreadNew(producer1/2/3、consumer1/2) 均打印 success 及 thread id;
出现多行 produces a product 与 consumes a product ,且 product number 在合理范围内变化;
即表示:
小鸿工程已正确编译并烧录;
04_semaphore demo 已通过 samples/BUILD.gn 的 features 及 config.py / ohos.cmake 纳入编译并打进 ws63-liteos-app 镜像;
系统启动时已执行 SempTestTask,信号量与生产者-消费者逻辑按预期工作。
# 八、常见问题与排查
现象
建议排查
串口无任何打印
确认 COM 口、TX/RX 接线;是否先打开串口再上电/复位。
有启动日志但无 [Semp Test]
确认:(1) vendor/atomgit/xiaohong/BUILD.gn 的 deps 含 "samples:app", ;(2) samples/BUILD.gn 的 features 中含未注释的 "04_semaphore:semp_demo" ;(3) config.py 的 ram_component 与 ohos.cmake 的 COMPONENT_LIST 中已添加 "semp_demo" 。然后执行清理后重新全量编译并烧录。
链接报错 -llibwebsockets_interface
在 ws63 config.py 的 ram_component 中注释掉 "libwebsockets" ,再全量编译。
乱码
确认波特率为 115200。
# 九、小结
文件放哪里 :信号量 demo 位于 vendor/atomgit/xiaohong/samples/04_semaphore/ (含 semp.c、BUILD.gn、README)。若从别处拷贝,请将 04_semaphore 整目录放到 vendor/atomgit/xiaohong/samples 下。
改哪里能编译并打进镜像 :(1) vendor/atomgit/xiaohong/BUILD.gn 的 deps 须含 "samples:app", ;(2) samples/BUILD.gn 的 features 须含 "04_semaphore:semp_demo" ;(3) config.py (sdkv106 下)的 ram_component 须含 "semp_demo" ;(4) ohos.cmake (sdkv106 下)的 COMPONENT_LIST 须含 "semp_demo" 。
编译:先清理,再 hb set (mini + xiaohong),最后 hb build -f 。烧录后以 115200 波特率连接串口,看到完整 [Semp Test] 日志即可判定 04_semaphore(信号量)demo 在小鸿上运行成功。
文档版本 :与 vendor/atomgit/xiaohong/samples/04_semaphore/README.md 集成与编译步骤保持一致。
相关目录 :vendor/atomgit/xiaohong/samples/04_semaphore/。
Was this helpful? 👍 Yes 👎 Needs work
HANDS-ON SAMPLES Xiaohong AI · official docs
06 · Message queue Hands-on samples / 06 · Message queuei18n · The narrative below is the original Chinese reference (technical content — code, commands and logs are universal). A fully translated English edition is in progress.
View Chinese version → # 一、背景与目标
# 1.1 小鸿与 05_message 是什么
小鸿 是基于 OpenHarmony + 海思 WS63 方案的设备/工程,其代码位于 vendor/atomgit/xiaohong/xiaohong,使用 CMSIS-RTOS2(LiteOS 适配)做多任务调度。
05_message 是小鸿工程内的一个消息队列(Message Queue)API 示例 ,演示 CMSIS-RTOS2 的 osMessageQueueNew、osMessageQueuePut、osMessageQueueGet、osMessageQueueGetCapacity、osMessageQueueGetMsgSize、osMessageQueueGetCount、osMessageQueueGetSpace、osMessageQueueDelete 等用法。本样例通过一个容量为 3 的消息队列,由 3 个发送线程向队列中放入消息(线程 ID + 计数),2 个接收线程从队列中取消息并打印,实现多线程间通过消息队列通信。将其集成到小鸿上,可以:
验证小鸿工程下消息队列与多线程通信 API 的编译与运行是否正常;
作为“多线程与消息队列”类 demo 的参考。
# 1.2 本文目标
说明 消息队列 demo 所在目录与构建方式 (samples/05_message,通过 features 编入);
说明 为能编译并打进镜像需要修改的文件 :vendor 顶层 BUILD.gn、samples/BUILD.gn、config.py、ohos.cmake;
说明运行逻辑与串口预期输出;
给出如何判断运行成功的结论。
# 二、环境与前置条件
工程 :OpenHarmony + 小鸿 vendor(vendor/atomgit/xiaohong,含主库与 samples ,消息队列示例位于 samples/05_message );
SDK :WS63 SDK(通过 ws63_sdk.gni 引用);
工具 :串口调试助手(如 UartAssist、Xshell 等),波特率 115200 ;
硬件 :小鸿开发板,通过 USB 转串口连接 PC,TX/RX/GND 正确连接。
# 三、集成步骤(文件放哪里、改哪里能编译)
消息队列示例以 samples 形式存在,目录为 vendor/atomgit/xiaohong/samples/05_message ,通过 samples/BUILD.gn 的 features 与板级 config.py / ohos.cmake 参与编译并打进 ws63-liteos-app 镜像。以下步骤须全部完成,缺一不可。
# 3.1 目录与源码位置
本示例已放在小鸿 vendor 包内:
目录 :vendor/atomgit/xiaohong/samples/05_message/ ;
源文件 :message.c ;
构建目标 :本目录下的 static_library("message_demo") ,由 samples/BUILD.gn 以 feature "05_message:message_demo" 形式编入应用。
完整路径为:
vendor/atomgit/xiaohong/
├── BUILD.gn # 顶层 group,依赖 xiaohong 主库与 samples
└── samples/
├── BUILD.gn # lite_component("app"),通过 features 选择示例
└── 05_message/
├── BUILD.gn # static_library("message_demo")
├── message.c # 演示源码
└── README.md # 操作说明
若从别处拷贝示例,请将 05_message 整个目录放到 vendor/atomgit/xiaohong/samples 下。
# 3.2 步骤 1:检查 vendor 顶层 BUILD.gn(编译前必查)
打开 vendor/atomgit/xiaohong/BUILD.gn ,在 group("xiaohong") 的 deps 中确认包含 "samples:app", 。若缺少该项,samples 下的示例不会参与整包编译。
group("xiaohong") {
deps = [
"xiaohong:xiaohong",
"samples:app",
]
}
# 3.3 步骤 2:在 samples/BUILD.gn 中启用消息队列示例
修改 vendor/atomgit/xiaohong/samples/BUILD.gn ,在 lite_component("app") 的 features 列表中保留或添加 "05_message:message_demo" (未注释):
lite_component("app") {
features = [
"05_message:message_demo",
# 其他示例按需取消注释
]
}
说明 :以 # 开头的行为注释,不会参与编译 ;需要编进固件的示例须为未注释的一行。
# 3.4 步骤 3:在 config.py 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/build/config/target_config/ws63/config.py 中,找到 'ws63-liteos-app' 配置,在其 'ram_component' 列表中添加 "message_demo" :
说明 :ram_component 声明参与 ws63-liteos-app 镜像链接的组件;未在此列出的 static_library 不会被打进最终 app 镜像。
# 3.5 步骤 4:在 ohos.cmake 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/libs_url/ws63/cmake/ohos.cmake 中,找到 elseif(${TARGET_COMMAND} MATCHES "ws63-liteos-app") 对应的 set(COMPONENT_LIST ...) ,在列表中添加 "message_demo" :
说明 :COMPONENT_LIST 决定参与构建与安装的组件(静态库),需与 步骤 3 的 ram_component 及 samples 内 BUILD.gn 的 target 名称一致。
# 3.6 代码说明(无需再改)
当前 message.c 主要逻辑:
主线程 rtosv2_msgq_main:创建容量为 QUEUE_SIZE(3) 、消息大小为 sizeof(message_entry) 的消息队列 → 创建 2 个接收线程(recevier1、recevier2)、3 个发送线程(sender1/2/3)→ osDelay(20) 后调用 osMessageQueueGetCapacity/GetMsgSize/GetCount/GetSpace 并打印 → osDelay(80) 后终止所有子线程并删除消息队列。
发送者 sender_thread:循环内将当前线程 ID 与 count 填入 message_entry,osMessageQueuePut 放入队列并打印,发送满 100 次后退出。
接收者 receiver_thread:循环内 osMessageQueueGet 取出一条消息,打印来自哪个线程、计数值,接收满 100 次后退出。
注册 :通过 APP_FEATURE_INIT(MessageTestTask) 在启动时执行 MessageTestTask ,创建线程 rtosv2_msgq_main 。
日志 :本 demo 使用 WS63 SDK 提供的 osal_printk 输出,串口会看到 [Message Test] 前缀的日志。
与 03_mutex、04_semaphore 使用同一套 ohos_init.h 与 CMSIS-RTOS2,无需额外适配。
# 四、运行逻辑简述
系统启动后,通过 APP_FEATURE_INIT(MessageTestTask) 调用 MessageTestTask ;
MessageTestTask 创建线程 rtosv2_msgq_main ;
rtosv2_msgq_main 内:
1. osMessageQueueNew 创建消息队列(容量 3,单条消息为 message_entry);
2. newThread 创建 recevier1、recevier2、sender1、sender2、sender3;
3. osDelay(20) 后打印 osMessageQueueGetCapacity (容量)、GetMsgSize (消息大小)、GetCount (当前消息数)、GetSpace (剩余空间);
4. osDelay(80) 后 osThreadTerminate 五个子线程,osMessageQueueDelete 删除消息队列。
串口上会看到 [Message Test] 前缀的日志:线程创建成功、发送/接收消息的打印,以及队列容量、消息大小、当前数量、剩余空间的统计信息。
# 五、编译
在 OpenHarmony 工程根目录下依次 执行:1. 清理 rm -fr out/xiaohong/xiaohong/ .ccache/*;2. 选择产品 hb set(按提示选择 mini 、xiaohong );3. 全量编译 hb build -f。编译成功后,固件生成路径为 out/xiaohong/xiaohong/ws63-liteos-app (Windows 下如 Z:\A_OH60T\out\...)。
# 六、烧录
以下内容与 HelloWorld、01_timer、02_delay、03_mutex、04_semaphore 等 demo 通用,参见《小鸿AI 固件烧录与启动指导手册》或同仓库烧录说明。
# 6.1 烧录前准备
硬件搭建 :使用 Typec 线将板端与 PC 端连接。
55c4feb3c99d6077ec23c8438c3c15da
安装驱动 :安装「CH341SER 驱动」(CH341SER 驱动下载地址 ,若该链接失效或无法下载,可自行搜索下载)。安装前请将单板与 PC 连接,点击安装即可;显示驱动安装成功 代表成功,若显示驱动预安装成功 则代表安装失败。
下载 BurnTool 烧录工具 :下载并解压 BurnTool。
链接:https://atomgit.com/xiaohong-ai/docs/tree/main/tools
打开烧录工具,选择对应的串口;点开 Option 选项,选择对应目标(WS63E 与 WS63 属于同一系列,选 WS63 即可)。
点击 Select file 选择烧录文件(选择 ws63-liteos-app-all.fwpkg ,该文件位于固件路径 Z:\A_OH60T\out\xiaohong\xiaohong\ws63-liteos-app 下)。
勾选 Auto Burn 和 Auto disconnect 选项。
⚠️ 重要:进入烧录方式因板子批次不同
新板子 :点击 Connect 后直接开始烧录 。
旧板子 :点击 Connect 后,需同时按住两个音量/亮度按键约 1.5 秒后松开 ,再开始烧录。
待全部烧录成功后,显示 All images burn successfully 。
673e3245796e6d6497f3e480b2f9bd25
# 七、串口输出与结果分析
# 7.1 串口连接(查看日志)
准备:
烧录完成后,按以下步骤通过串口查看运行日志:
打开 UartAssist ,协议选择 SERIAL ,端口选择小鸿对应的 COM 口;
设置串口参数:波特率 115200 ,数据位 8,停止位 1,无校验、无流控;
先打开串口连接;
再给板子上电或复位,即可抓取完整启动与 05_message 日志。
在串口工具页面查看打印日志
# 7.2 预期出现的日志(05_message 相关)
阶段
日志特征
创建线程
[Message Test] osThreadNew(recevier1) success, thread id: ...(recevier1/2、sender1/2/3 各一行)
发送消息
多行 [Message Test] senderx send N to message queue.
接收消息
多行 [Message Test] recevierx get N from sendery by message queue.
队列状态
[Message Test] osMessageQueueGetCapacity, capacity: 3.、GetMsgSize, size: 8.、GetCount, count: ...、GetSpace, space: ...
因接收者消费较快(osDelay(3))、发送者较慢(osDelay(5)),且各有 100 次退出条件,日志中会交替出现 send 与 get,并在约 20ms 时打印一次队列的容量、消息大小、当前消息数、剩余空间。
# 7.3 如何判断“运行成功”
串口波特率 115200 下,在启动日志中能看到上述 [Message Test] 系列输出,且:
osThreadNew(recevier1/2、sender1/2/3) 均打印 success 及 thread id;
出现多行 send N to message queue 与 get N from senderx by message queue ;
出现 osMessageQueueGetCapacity (capacity: 3)、GetMsgSize (size: 8)、GetCount 、GetSpace 的打印;
即表示:
小鸿工程已正确编译并烧录;
05_message demo 已通过 samples/BUILD.gn 的 features 及 config.py / ohos.cmake 纳入编译并打进 ws63-liteos-app 镜像;
系统启动时已执行 MessageTestTask,消息队列与多线程通信逻辑按预期工作。
# 八、常见问题与排查
现象
建议排查
串口无任何打印
确认 COM 口、TX/RX 接线;是否先打开串口再上电/复位。
有启动日志但无 [Message Test]
确认:(1) vendor/atomgit/xiaohong/BUILD.gn 的 deps 含 "samples:app", ;(2) samples/BUILD.gn 的 features 中含未注释的 "05_message:message_demo" ;(3) config.py 的 ram_component 与 ohos.cmake 的 COMPONENT_LIST 中已添加 "message_demo" 。然后执行清理后重新全量编译并烧录。
链接报错 -llibwebsockets_interface
在 ws63 config.py 的 ram_component 中注释掉 "libwebsockets" ,再全量编译。
编译报错找不到 osal_printk
确认工程已正确引用 WS63 SDK(ws63_sdk.gni),SDK 中 kernel/osal 会提供 osal_printk;若仍不可用,可将 message.c 中 osal_printk 改为 printf 并重新编译。
乱码
确认波特率为 115200。
# 九、小结
文件放哪里 :消息队列 demo 位于 vendor/atomgit/xiaohong/samples/05_message/ (含 message.c、BUILD.gn、README)。若从别处拷贝,请将 05_message 整目录放到 vendor/atomgit/xiaohong/samples 下。
改哪里能编译并打进镜像 :(1) vendor/atomgit/xiaohong/BUILD.gn 的 deps 须含 "samples:app", ;(2) samples/BUILD.gn 的 features 须含 "05_message:message_demo" ;(3) config.py (sdkv106 下)的 ram_component 须含 "message_demo" ;(4) ohos.cmake (sdkv106 下)的 COMPONENT_LIST 须含 "message_demo" 。
编译:先清理,再 hb set (mini + xiaohong),最后 hb build -f 。烧录后以 115200 波特率连接串口,看到完整 [Message Test] 日志即可判定 05_message(消息队列)demo 在小鸿上运行成功。
文档版本 :与 vendor/atomgit/xiaohong/samples/05_message/README.md 集成与编译步骤保持一致。
相关目录 :vendor/atomgit/xiaohong/samples/05_message/。
Was this helpful? 👍 Yes 👎 Needs work
HANDS-ON SAMPLES Xiaohong AI · official docs
07 · SPI Master Hands-on samples / 07 · SPI Masteri18n · The narrative below is the original Chinese reference (technical content — code, commands and logs are universal). A fully translated English edition is in progress.
View Chinese version → # 一、背景与目标
# 1.1 小鸿与 06_spi 是什么
小鸿 是基于 OpenHarmony + 海思 WS63 方案的设备/工程,其代码位于 vendor/atomgit/xiaohong/xiaohong,使用 CMSIS-RTOS2(LiteOS-M 适配)做多任务调度。
06_spi 是小鸿工程内的 SPI Master 示例 ,来源于 WS63 SDK 的 application/samples/peripheral/spi,已适配为通过 APP_FEATURE_INIT 注册、在独立线程中周期执行 SPI 发送与接收,并通过串口输出 [SPI Demo] 日志。将其集成到小鸿上,可以:
验证小鸿工程下 SPI 主模式 API(uapi_spi_init、uapi_spi_master_write / uapi_spi_master_read)的编译与运行是否正常;
作为“外设 SPI”类 demo 的参考,便于后续对接 SPI 从设备(Flash、传感器、屏等)。
# 1.2 本文目标
说明 SPI demo 所在目录与构建方式 (samples/06_spi,通过 features 编入);
说明 为能编译并打进镜像需要修改的文件 :vendor 顶层 BUILD.gn、samples/BUILD.gn、config.py、ohos.cmake;
说明运行逻辑、串口预期输出及 与 LCD 共用 SPI1 时的注意点 ;
特别说明 屏幕黑的原因 :并非改坏了别的文件,而是 SPI Demo 与屏幕共用同一条 SPI 总线(SPI1)。
# 二、环境与前置条件
工程 :OpenHarmony + 小鸿 vendor(vendor/atomgit/xiaohong,含主库与 samples ,SPI 示例位于 samples/06_spi );
SDK :WS63 SDK(通过 ws63_sdk.gni 引用);
工具 :串口调试助手(如 UartAssist、Xshell 等),波特率 115200 ;
硬件 :小鸿开发板,通过 USB 转串口连接 PC,TX/RX/GND 正确连接。
# 三、集成步骤(文件放哪里、改哪里能编译)
SPI 示例以 samples 形式存在,目录为 vendor/atomgit/xiaohong/samples/06_spi ,通过 samples/BUILD.gn 的 features 与板级 config.py / ohos.cmake 参与编译并打进 ws63-liteos-app 镜像。以下步骤须全部完成,缺一不可。
# 3.1 目录与源码位置
本示例已放在小鸿 vendor 包内:
目录 :vendor/atomgit/xiaohong/samples/06_spi/ ;
源文件 :spi_master_demo.c (可选 spi_demo_config.h 等);
构建目标 :本目录下的 static_library("spi_demo") ,由 samples/BUILD.gn 以 feature "06_spi:spi_demo" 形式编入应用。
完整路径为:
vendor/atomgit/xiaohong/
├── BUILD.gn # 顶层 group,依赖 xiaohong 主库与 samples
└── samples/
├── BUILD.gn # lite_component("app"),通过 features 选择示例
└── 06_spi/
├── BUILD.gn # static_library("spi_demo")
├── spi_master_demo.c # 演示源码
├── spi_demo_config.h # 可选配置
└── README.md # 操作说明
若从别处拷贝示例,请将 06_spi 整个目录放到 vendor/atomgit/xiaohong/samples 下。
# 3.2 步骤 1:检查 vendor 顶层 BUILD.gn(编译前必查)
打开 vendor/atomgit/xiaohong/BUILD.gn ,在 group("xiaohong") 的 deps 中确认包含 "samples:app", 。若缺少该项,samples 下的示例不会参与整包编译。
group("xiaohong") {
deps = [
"xiaohong:xiaohong",
"samples:app",
]
}
# 3.3 步骤 2:在 samples/BUILD.gn 中启用 SPI 示例
修改 vendor/atomgit/xiaohong/samples/BUILD.gn ,在 lite_component("app") 的 features 列表中保留或添加 "06_spi:spi_demo" (未注释):
lite_component("app") {
features = [
"06_spi:spi_demo",
# 其他示例按需取消注释
]
}
说明 :以 # 开头的行为注释,不会参与编译 ;需要编进固件的示例须为未注释的一行。
# 3.4 步骤 3:在 config.py 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/build/config/target_config/ws63/config.py 中,找到 'ws63-liteos-app' 配置,在其 'ram_component' 列表中添加 "spi_demo" :
说明 :ram_component 声明参与 ws63-liteos-app 镜像链接的组件;未在此列出的 static_library 不会被打进最终 app 镜像。
# 3.5 步骤 4:在 ohos.cmake 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/libs_url/ws63/cmake/ohos.cmake 中,找到 elseif(${TARGET_COMMAND} MATCHES "ws63-liteos-app") 对应的 set(COMPONENT_LIST ...) ,在列表中添加 "spi_demo" :
说明 :COMPONENT_LIST 决定参与构建与安装的组件(静态库),需与 步骤 3 的 ram_component 及 samples 内 BUILD.gn 的 target 名称一致。
# 3.6 板级配置与代码说明
板级配置(xiaohong_ws63_v1) :在 BOARD_XH_WS63_V1 下,spi_demo_config.h 会引用 board_config.h,使用板级已定义的 SPI 总线(SPI_IDX = 1,即 SPI1)、管脚(SPI_CLK_PIN、SPI_MOSI_PIN、SPI_MISO_PIN、SPI_GPIO_PIN_MODE)及 Demo 片选(CONFIG_SPI_CS_MASTER_PIN = 10,GPIO10,仅 demo 使用)。
代码说明(无需再改) :当前 spi_master_demo.c 通过 APP_FEATURE_INIT(SpiMasterDemoEntry) 在系统启动时注册,在独立线程 SpiMasterTask 中周期执行 SPI 初始化、发送与接收,并通过串口打印 [SPI Demo] 日志,运行逻辑详见第四节。
# 四、运行逻辑简述
系统启动时,APP_FEATURE_INIT(SpiMasterDemoEntry) 被调用;
SpiMasterDemoEntry 创建名为 SpiMasterTask 的线程;
该线程中依次执行:
1. app_spi_init_pin() :配置 SPI 相关 GPIO 模式;
2. app_spi_master_init_config() :调用 uapi_spi_init 初始化 SPI1;
3. 进入 while(1) 循环,每隔约 500ms :
调用 uapi_spi_master_write 发送 8 字节(0x00~0x07);
调用 uapi_spi_master_read 接收 8 字节;
通过 printf 将接收数据打印到串口。
串口上会周期出现带 [SPI Demo] 前缀的日志,便于确认 demo 已执行且 SPI 收发正常。
# 五、编译
在 OpenHarmony 工程根目录下依次 执行:1. 清理 rm -fr out/xiaohong/xiaohong/ .ccache/*;2. 选择产品 hb set(按提示选择 mini 、xiaohong );3. 全量编译 hb build -f。编译成功后,固件生成路径为 out/xiaohong/xiaohong/ws63-liteos-app (Windows 下如 Z:\A_OH60T\out\...)。
# 六、烧录
以下内容与 HelloWorld、01_timer、02_delay、03_mutex、04_semaphore、05_message 等 demo 通用,参见《小鸿AI 固件烧录与启动指导手册》或同仓库烧录说明。
# 6.1 烧录前准备
硬件搭建 :使用 Typec 线将板端与 PC 端连接。
55c4feb3c99d6077ec23c8438c3c15da
安装驱动 :安装「CH341SER 驱动」(CH341SER 驱动下载地址 ,若该链接失效或无法下载,可自行搜索下载)。安装前请将单板与 PC 连接,点击安装即可;显示驱动安装成功 代表成功,若显示驱动预安装成功 则代表安装失败。
下载 BurnTool 烧录工具 :下载并解压 BurnTool。
链接:https://atomgit.com/xiaohong-ai/docs/tree/main/tools
打开烧录工具,选择对应的串口;点开 Option 选项,选择对应目标(WS63E 与 WS63 属于同一系列,选 WS63 即可)。
点击 Select file 选择烧录文件(选择 ws63-liteos-app-all.fwpkg ,该文件位于固件路径 Z:\A_OH60T\out\xiaohong\xiaohong\ws63-liteos-app 下)。
勾选 Auto Burn 和 Auto disconnect 选项。
⚠️ 重要:进入烧录方式因板子批次不同
新板子 :点击 Connect 后直接开始烧录 。
旧板子 :点击 Connect 后,需同时按住两个音量/亮度按键约 1.5 秒后松开 ,再开始烧录。
待全部烧录成功后,显示 All images burn successfully 。
# 这个烧完设备是黑屏的,屏幕黑不是因为改坏了别的文件,而是 SPI Demo 和屏幕共用同一条 SPI 总线(SPI1)
# 七、串口输出与结果分析
# 7.1 串口连接(查看日志)
准备:
烧录完成后,按以下步骤通过串口查看运行日志:
打开 UartAssist ,协议选择 SERIAL ,端口选择小鸿对应的 COM 口;
设置串口参数:波特率 115200 ,数据位 8,停止位 1,无校验、无流控;
先打开串口连接;
再给板子上电或复位,即可抓取完整启动与 06_spi 日志。
# 7.2 预期出现的日志(06_spi 相关)
阶段
日志特征
任务创建
[SPI Demo] SpiMasterTask created
主任务启动
[SPI Demo] master task start, bus_id=1
发送开始
[SPI Demo] master send start
发送成功
[SPI Demo] master send succ
接收开始
[SPI Demo] master receive start
接收成功与数据
[SPI Demo] master receive succ, data: xx xx xx xx xx xx xx xx
无外接从机或 MISO 悬空时,接收数据常为 ff ff ff ff ff ff ff ff (浮空读高);
将 MISO 与 MOSI 短接 做回环时,可收到与发送一致的 00 01 02 03 04 05 06 07 ,用于验证收发是否正常。
# 7.3 实际运行日志(节选)
成功运行时,串口会周期出现类似日志:
[SPI Demo] SpiMasterTask created
[SPI Demo] master task start, bus_id=1
[SPI Demo] master send start
[SPI Demo] master send succ
[SPI Demo] master receive start
[SPI Demo] master receive succ, data: ff ff ff ff ff ff ff ff
回环(MISO–MOSI 短接)时,接收数据为:data: 00 01 02 03 04 05 06 07。
# 7.4 如何判断“运行成功”
串口波特率 115200 下,在启动日志中能看到上述 [SPI Demo] 系列输出,且周期性出现 master send start/succ 、master receive start/succ, data: ... ,即表示:
小鸿工程已正确编译并烧录;
06_spi demo 已通过 samples/BUILD.gn 的 features 及 config.py / ohos.cmake 纳入编译并打进 ws63-liteos-app 镜像;
系统启动时已执行 SpiMasterDemoEntry,SPI 主模式收发逻辑按预期工作。
回环验证 :MISO–MOSI 短接时,接收数据为 00 01 02 03 04 05 06 07 ,可判定 SPI 主模式收发正常。
与 01_timer、02_delay 等 demo 一致:看到完整 [SPI Demo] 日志且收发流程正常(无从机时为 0xFF,回环时为 0x00~0x07),即可判定 06_spi(SPI Master)demo 在小鸿上运行成功。
# 八、重要说明:屏幕黑的原因(SPI Demo 与屏幕共用 SPI1)
# 8.1 现象
开启 06_spi demo 并参与编译、烧录后,可能出现:串口 SPI 日志正常,但小鸿屏幕为黑屏 。
# 8.2 原因说明(并非改坏了别的文件)
屏幕黑的原因,不是“改坏了别的文件”,而是:SPI Demo 和屏幕共用同一条 SPI 总线(SPI1)。
具体而言:
小鸿板级 在 board_config.c 的 board_hw_init() 里会调用 spi1_init() ,用一套参数(时钟、模式等)初始化 SPI1 ,供 LCD 显示 和 Flash 使用;
06_spi demo 在 SpiMasterTask 里又会调用 app_spi_init_pin() 和 app_spi_master_init_config() ,其中 app_spi_master_init_config() 会再次调用 uapi_spi_init(SPI_IDX, ...) ,即对 同一条 SPI1 做一次重新初始化 ;
Demo 使用的参数(如 2MHz 工作频率等)与板级为 LCD 配置的参数不一致,重新初始化会覆盖原有 SPI1 配置 ,导致 LCD 无法再正常通过 SPI1 通信,从而出现黑屏 。
因此:
没有修改 main.c、task_entry.c、显示/LVGL、板级配置或 LCD 驱动等其它业务文件;
仅新增 了 src/samples/06_spi/ 下文件,并在主 BUILD.gn 中增加了 sources 与 include_dirs ;
黑屏是“SPI 资源冲突”导致的现象 ,而不是因为改坏了别的代码。
# 8.3 如何恢复屏幕
若需要先恢复屏幕 ,可暂时不编译 06_spi demo:
在 vendor/atomgit/xiaohong/xiaohong/BUILD.gn 中:
- 从 sources 中删除:"src/samples/06_spi/spi_master_demo.c" ;
- 从 include_dirs 中删除:"src/samples/06_spi" ;
保存后全量编译、重新烧录 ,屏幕应恢复正常。
# 8.4 若既要屏幕又要跑 SPI Demo
若希望同时保留显示并运行 SPI 示例 ,需要避免 demo 对 SPI1 做二次初始化,例如:
修改 demo,不再调用 uapi_spi_init ,仅使用板级已初始化好的 SPI1 做 write/read (需注意与 LCD/Flash 的访问时序、片选等不要冲突);或
使用另一路 SPI 总线 (若硬件存在)专门跑 demo,而不与 LCD 共用 SPI1。
# 九、常见问题与排查
现象
建议排查
串口无任何打印
确认 COM 口、TX/RX 接线;是否先打开串口再上电/复位。
有启动日志但无 [SPI Demo]
确认:(1) vendor/atomgit/xiaohong/BUILD.gn 的 deps 含 "samples:app", ;(2) samples/BUILD.gn 的 features 中含未注释的 "06_spi:spi_demo" ;(3) config.py 的 ram_component 与 ohos.cmake 的 COMPONENT_LIST 中已添加 "spi_demo" 。然后执行清理后重新全量编译并烧录。
乱码
确认波特率为 115200。
串口有 SPI 日志但屏幕黑屏
参见 第八节 :SPI Demo 与屏幕共用 SPI1,demo 重新初始化导致 LCD 异常;按 8.3 从 BUILD.gn 中移除 demo 可恢复屏幕。
接收数据全是 0xff
无外接从机或 MISO 悬空时属正常;可短接 MISO–MOSI 做回环验证,应收到 00 01 02 03 04 05 06 07。
# 十、小结
文件放哪里 :SPI demo 位于 vendor/atomgit/xiaohong/samples/06_spi/ (含 spi_master_demo.c、BUILD.gn、README 等)。若从别处拷贝,请将 06_spi 整目录放到 vendor/atomgit/xiaohong/samples 下。
改哪里能编译并打进镜像 :(1) vendor/atomgit/xiaohong/BUILD.gn 的 deps 须含 "samples:app", ;(2) samples/BUILD.gn 的 features 须含 "06_spi:spi_demo" ;(3) config.py (sdkv106 下)的 ram_component 须含 "spi_demo" ;(4) ohos.cmake (sdkv106 下)的 COMPONENT_LIST 须含 "spi_demo" 。
运行效果 :串口周期打印 [SPI Demo] 发送/接收日志;无从机时多为 0xFF,回环时为 0x00~0x07。
屏幕黑的原因 :不是改坏了别的文件 ,而是 SPI Demo 与屏幕共用同一条 SPI 总线(SPI1) ,demo 重新初始化 SPI1 覆盖了 LCD 所用配置。
恢复屏幕 :在 samples/BUILD.gn 的 features 中注释掉 "06_spi:spi_demo" ,并在 config.py / ohos.cmake 中移除 "spi_demo" ,重新编译烧录。
编译:先清理,再 hb set (mini + xiaohong),最后 hb build -f 。烧录后以 115200 波特率连接串口,看到完整 [SPI Demo] 日志且收发正常即可判定 06_spi(SPI Master)demo 在小鸿上运行成功。
文档版本 :与 vendor/atomgit/xiaohong/samples/06_spi/README.md 集成与编译步骤保持一致。
相关目录 :vendor/atomgit/xiaohong/samples/06_spi/。
Was this helpful? 👍 Yes 👎 Needs work
HANDS-ON SAMPLES Xiaohong AI · official docs
08 · Easy Wi-Fi Hands-on samples / 08 · Easy Wi-Fii18n · The narrative below is the original Chinese reference (technical content — code, commands and logs are universal). A fully translated English edition is in progress.
View Chinese version → 本文档说明在小鸿工程中编译、烧录 第一块板(AP 热点端) 与 第二块板(STA 连接端) 时,需要修改和注释的全部位置 ,以及两版固件的差异,便于按 01_timer、02_delay 等 demo 的同一套编译与烧录流程完成双板配置与验证。
# 一、背景与目标
# 1.1 小鸿与 07_easy_wifi 双板烧录是什么
小鸿 是基于 OpenHarmony + 海思 WS63 方案的设备/工程,其代码位于 vendor/atomgit/xiaohong/xiaohong,使用 CMSIS-RTOS2(LiteOS-M 适配)做多任务调度。
07_easy_wifi 是小鸿工程内的 WiFi 示例 ,支持 AP(热点) 与 STA(连接热点) 两种角色。因同一份工程需分别烧录到两块板子 (一块开热点、一块连热点),故需通过 BUILD.gn 中注释/取消注释不同 demo 源文件 生成两版固件:第一块板(AP 热点端) 与 第二块板(STA 连接端) 。将其理清并文档化,可以:
避免烧错固件导致两块板角色颠倒或无法组网;
与 01_timer、02_delay、03_mutex、04_semaphore、05_message、06_spi 等 demo 共用同一套编译、烧录与串口验证流程。
两版差异概览 :
项目
第一块板(第一版固件)
第二块板(第二版固件)
角色
AP(WiFi 热点)
STA(连接 AP 的终端)
入口源文件
wifi_hotspot_demo.c
wifi_connect_demo.c
依赖的底层
wifi_starter.c(开热点)
wifi_connecter.c(连热点)
串口观察重点
热点是否启动成功
是否连上 AP、是否拿到 IP
两版共用 的源文件(无需按板切换):wifi_connecter.c、wifi_starter.c 两版都会参与编译,通过只编译其中一个 demo 源文件 来区分 AP/STA 行为。
# 1.2 本文目标
说明 Easy WiFi demo 所在目录与构建方式 (samples/07_easy_wifi,通过 features 编入,需同时启用 wifi_demo 与 easy_wifi );
说明 为能编译并打进镜像需要修改的文件 :vendor 顶层 BUILD.gn、samples/BUILD.gn、config.py、ohos.cmake;
说明 第一块板(AP) 与 第二块板(STA) 各自在 demo/BUILD.gn 中应编译哪个源文件;
说明编译、烧录及串口验证方式,与其它 demo 保持一致。
# 二、环境与前置条件
工程 :OpenHarmony + 小鸿 vendor(vendor/atomgit/xiaohong,含主库与 samples ,Easy WiFi 示例位于 samples/07_easy_wifi );
SDK :WS63 SDK(通过 ws63_sdk.gni 引用);
工具 :串口调试助手(如 UartAssist、Xshell 等),波特率 115200 ;BurnTool 烧录工具(与 01_timer 等 demo 通用);
硬件 :两块小鸿开发板,分别通过 USB 转串口连接 PC,TX/RX/GND 正确连接。
# 三、集成步骤(文件放哪里、改哪里能编译)
Easy WiFi 示例以 samples 形式存在,目录为 vendor/atomgit/xiaohong/samples/07_easy_wifi (含 demo 与 src 子目录),通过 samples/BUILD.gn 的 features 与板级 config.py / ohos.cmake 参与编译并打进 ws63-liteos-app 镜像。以下步骤须全部完成,缺一不可;且 ram_component / COMPONENT_LIST 中需同时 添加 wifi_demo 与 easy_wifi 两个组件。
# 3.1 目录与源码位置
本示例已放在小鸿 vendor 包内:
目录 :vendor/atomgit/xiaohong/samples/07_easy_wifi/ (下含 demo 、src 子目录);
演示源码 :demo 目录下(如 wifi_hotspot_demo.c、wifi_connect_demo.c);库源码 :src 目录下(如 wifi_connecter.c、wifi_starter.c);
构建目标 :demo 下 static_library("wifi_demo") 与 src 下 static_library("easy_wifi") ,由 samples/BUILD.gn 以 feature "07_easy_wifi/demo:wifi_demo" 、"07_easy_wifi/src:easy_wifi" 形式编入应用(两项须同时启用)。
完整路径为:
vendor/atomgit/xiaohong/
├── BUILD.gn # 顶层 group,依赖 xiaohong 主库与 samples
└── samples/
├── BUILD.gn # lite_component("app"),通过 features 选择示例
└── 07_easy_wifi/
├── demo/ # static_library("wifi_demo")
│ ├── BUILD.gn
│ ├── wifi_hotspot_demo.c
│ └── wifi_connect_demo.c
├── src/ # static_library("easy_wifi")
│ ├── BUILD.gn
│ └── ...
└── README.md
若从别处拷贝示例,请将 07_easy_wifi 整个目录(含 demo、src)放到 vendor/atomgit/xiaohong/samples 下。
# 3.2 步骤 1:检查 vendor 顶层 BUILD.gn(编译前必查)
打开 vendor/atomgit/xiaohong/BUILD.gn ,在 group("xiaohong") 的 deps 中确认包含 "samples:app", 。若缺少该项,samples 下的示例不会参与整包编译。
group("xiaohong") {
deps = [
"xiaohong:xiaohong",
"samples:app",
]
}
# 3.3 步骤 2:在 samples/BUILD.gn 中启用 Easy WiFi
修改 vendor/atomgit/xiaohong/samples/BUILD.gn ,在 lite_component("app") 的 features 列表中保留或添加 "07_easy_wifi/demo:wifi_demo" 与 "07_easy_wifi/src:easy_wifi" (两项均未注释):
lite_component("app") {
features = [
"07_easy_wifi/demo:wifi_demo",
"07_easy_wifi/src:easy_wifi",
# 其他示例按需取消注释
]
}
说明 :WiFi 示例依赖 demo (应用入口)与 src (底层库),两项须同时 保留未注释;以 # 开头的行为注释,不会参与编译。
# 3.4 步骤 3:在 config.py 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/build/config/target_config/ws63/config.py 中,找到 'ws63-liteos-app' 配置,在其 'ram_component' 列表中分别 添加 "wifi_demo" 与 "easy_wifi" :
说明 :ram_component 声明参与 ws63-liteos-app 镜像链接的组件;未在此列出的 static_library 不会被打进最终 app 镜像。本示例两个库均需加入。
# 3.5 步骤 4:在 ohos.cmake 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/libs_url/ws63/cmake/ohos.cmake 中,找到 elseif(${TARGET_COMMAND} MATCHES "ws63-liteos-app") 对应的 set(COMPONENT_LIST ...) ,在列表中分别 添加 "wifi_demo" 与 "easy_wifi" :
说明 :COMPONENT_LIST 决定参与构建与安装的组件(静态库),需与 步骤 3 的 ram_component 及 samples 内 BUILD.gn 的 target 名称一致。
# 四、第一块板(AP 热点端)—— 第一版
# 4.1 修改 demo 编译的源文件(AP 端)
文件路径 :vendor/atomgit/xiaohong/samples/07_easy_wifi/demo/BUILD.gn
第一块板(AP)时,sources 中保留 wifi_hotspot_demo.c ,注释掉 wifi_connect_demo.c (前面加 #),使当前固件只编译热点 demo。
# 4.2 第一块板不需要改动的文件
wifi_hotspot_demo.c 内 SSID/KEY 为热点参数,默认即可(如 HiSpark_AP / 123456789)。
wifi_connect_demo.c 第一版不参与编译,其内容与第一版无关。
编译:在工程根目录依次 执行 清理 rm -fr out/xiaohong/xiaohong/ .ccache/*、hb set (选择 mini + xiaohong)、hb build -f 。编译成功后,固件路径为 out/xiaohong/xiaohong/ws63-liteos-app 。
将生成的固件按 第八节 烧录步骤烧录到第一块板 。
# 五、第二块板(STA 连接端)—— 第二版
# 5.1 修改 demo 编译的源文件(STA 端)
文件路径 :vendor/atomgit/xiaohong/samples/07_easy_wifi/demo/BUILD.gn
第二块板(STA)时,sources 中注释掉 wifi_hotspot_demo.c ,保留 wifi_connect_demo.c ,使当前固件只编译连接 demo。STA 端连接参数(SSID/密码等)在 vendor/atomgit/xiaohong/samples/07_easy_wifi/demo/wifi_connect_demo.c 中按需修改。
修改后 demo/BUILD.gn 中 sources 示意 (第二块板):
sources = [
# "wifi_hotspot_demo.c",
"wifi_connect_demo.c",
]
保存后同样在工程根目录依次 执行 清理 、hb set (mini + xiaohong)、hb build -f ,固件路径同上。将新生成的固件按 第八节 烧录步骤烧录到第二块板 。
# 六、两版差异汇总表(修改 / 注释一览)
位置
第一版(第一块板 AP)
第二版(第二块板 STA)
samples/07_easy_wifi/demo/BUILD.gn 中 sources
wifi_hotspot_demo.c 参与编译,wifi_connect_demo.c 注释
wifi_connect_demo.c 参与编译,wifi_hotspot_demo.c 注释
wifi_connect_demo.c 内 SSID/KEY
不编译,可不关心
必须与 AP 的 SSID/KEY 一致
samples/BUILD.gn 的 features (07_easy_wifi/demo:wifi_demo、07_easy_wifi/src:easy_wifi)及 config.py / ohos.cmake 的 wifi_demo 、easy_wifi 两版完全相同 ,无需切换。
# 七、与主工程符号冲突的已处理说明(仅作记录)
小鸿主工程里 net_wifi_station.c 与 07_easy_wifi 的 wifi_connecter.c 存在同名符号,已在 wifi_connecter.c 中做重命名,避免重复定义:
get_match_network → easy_wifi_get_match_network
g_iface → easy_wifi_g_iface
以上修改已固化在 wifi_connecter.c 中,编译第一版或第二版都无需再改。
# 八、烧录与验证
以下烧录步骤与 01_timer、02_delay、03_mutex、04_semaphore、05_message、06_spi 等 demo 通用 ,第一块板与第二块板均按同一套流程烧录对应固件。
# 8.1 烧录前准备
硬件搭建 :使用 Typec 线将板端与 PC 端连接。
55c4feb3c99d6077ec23c8438c3c15da
安装驱动 :安装「CH341SER 驱动」(CH341SER 驱动下载地址 ,若该链接失效或无法下载,可自行搜索下载)。安装前请将单板与 PC 连接,点击安装即可;显示驱动安装成功 代表成功,若显示驱动预安装成功 则代表安装失败。
下载 BurnTool 烧录工具 :下载并解压 BurnTool。
链接:https://atomgit.com/xiaohong-ai/docs/tree/main/tools
打开烧录工具,选择对应的串口;点开 Option 选项,选择对应目标(WS63E 与 WS63 属于同一系列,选 WS63 即可)。
点击 Select file 选择烧录文件(选择 ws63-liteos-app-all.fwpkg ,该文件位于固件路径 Z:\A_OH60T\out\xiaohong\xiaohong\ws63-liteos-app 下)。
勾选 Auto Burn 和 Auto disconnect 选项。
⚠️ 重要:进入烧录方式因板子批次不同
新板子 :点击 Connect 后直接开始烧录 。
旧板子 :点击 Connect 后,需同时按住两个音量/亮度按键约 1.5 秒后松开 ,再开始烧录。
待全部烧录成功后,显示 All images burn successfully 。
673e3245796e6d6497f3e480b2f9bd25
# 8.3 串口验证(开机启动与日志查看)
烧录完成后,通过串口查看运行日志以验证第一块板/第二块板是否工作正常:
CH341 USB 转串口驱动 :若已安装过 CH341_USB 转串口 Windows/Linux 驱动程序 ,此处可跳过。
串口工具 :从仓库下载 UartAssist 并解压使用。协议选择 SERIAL ,端口选择小鸿对应的 COM 口;设置波特率 115200 ,数据位 8,停止位 1,无校验、无流控。先打开串口连接,再给板子上电或复位,即可抓取完整启动与 07_easy_wifi 日志。
# 8.4 07_easy_wifi 双板验证要点
第一块板 :按 第四节 改好 BUILD.gn(只编 wifi_hotspot_demo.c),hb build -f 后按 8.1、8.2 烧录;串口应看到 StartHotspot success!。
第二块板 :按 第五节 改好 BUILD.gn(只编 wifi_connect_demo.c)并核对 wifi_connect_demo.c 的 SSID/KEY,再次 hb build -f 后按 8.1、8.2 烧录;串口应看到 Connect success.、STA IP x.x.x.x 等。
看「是否连上 AP」时,接第二块板(STA) 的串口即可。
# 九、快速切换检查清单
要烧第一块板时,请确认:
[ ] BUILD.gn 中 wifi_hotspot_demo.c 这一行没有 被注释
[ ] BUILD.gn 中 wifi_connect_demo.c 这一行已被 注释(行首有 #)
要烧第二块板时,请确认:
[ ] BUILD.gn 中 wifi_hotspot_demo.c 这一行已被 注释(行首有 #)
[ ] BUILD.gn 中 wifi_connect_demo.c 这一行没有 被注释
[ ] wifi_connect_demo.c 里 SSID、KEY 与第一块板热点一致
# 十、小结
第一块板(AP) :在 BUILD.gn 中保留 wifi_hotspot_demo.c 参与编译,注释 wifi_connect_demo.c;hb set、hb build -f 后烧录,串口见 StartHotspot success!。
第二块板(STA) :在 BUILD.gn 中注释 wifi_hotspot_demo.c,保留 wifi_connect_demo.c 参与编译,并保证 wifi_connect_demo.c 内 SSID/KEY 与第一块板热点一致;再次编译烧录,串口见 Connect success.、STA IP x.x.x.x 等。
编译与烧录流程与 01_timer、02_delay、03_mutex、04_semaphore、05_message、06_spi 等 demo 一致;固件路径为 Z:\A_OH60T\out\xiaohong\xiaohong\ws63-liteos-app ,串口波特率 115200 。
文档版本 :基于小鸿工程与 07_easy_wifi 双板烧录实际集成与运行结果整理。
相关目录 :vendor/atomgit/xiaohong/xiaohong/src/samples/07_easy_wifi/(demo、src、本文档)。
Was this helpful? 👍 Yes 👎 Needs work
HANDS-ON SAMPLES Xiaohong AI · official docs
09 · Speaker control Hands-on samples / 09 · Speaker controli18n · The narrative below is the original Chinese reference (technical content — code, commands and logs are universal). A fully translated English edition is in progress.
View Chinese version → 本文档说明在小鸿工程中集成 08 喇叭控制 Demo 时的文件放置、BUILD.gn 与主任务/CI1302 的修改方式,以及编译、烧录与串口验证流程,与 01_timer、02_delay、07_easy_wifi 等 demo 采用同一套实践结构。
# 一、背景与目标
# 1.1 小鸿与 08 喇叭控制 Demo 是什么
小鸿 是基于 OpenHarmony + 海思 WS63 方案的设备/工程,其代码位于 vendor/atomgit/xiaohong/xiaohong,使用 CMSIS-RTOS2(LiteOS-M 适配)做多任务调度。
小鸿板载喇叭由 CI1302 语音模块驱动,主控(WS63)通过 UART 向 CI1302 发送指令即可触发播放不同提示音。08 喇叭控制 Demo 实现:
触发方式 :用户双击唤醒键 (约 1.5 秒内按两次),或 CI1302 识别到配置好的语音指令后下发 0x20 ,即触发一次「完整播报序列」。
播报内容 :依次播放 5 条提示音(唤醒 → 音量加 → 音量减 → 网络已连接 → 网络断开),每条间隔约 700ms。
不自动播放 :上电不自动跑,与现有音量键/唤醒键单次播报不重复。
防抖/节流 :上次播报结束后 5 秒内再次触发会被忽略,避免连续多次触发。
# 1.2 本文目标
说明 喇叭 demo 所在目录与构建方式 (samples/08_speaker_demo,通过 features 编入);
说明 为能编译并打进镜像需要修改的文件 :vendor 顶层 BUILD.gn、samples/BUILD.gn、config.py、ohos.cmake;
说明与主任务联动(main.c、触发队列等)时的可选修改;
说明编译、烧录及串口验证方式,与其它 demo 保持一致。
# 二、环境与前置条件
工程 :OpenHarmony + 小鸿 vendor(vendor/atomgit/xiaohong,含主库与 samples ,喇叭示例位于 samples/08_speaker_demo );
SDK :WS63 SDK(通过 ws63_sdk.gni 引用);
工具 :串口调试助手(如 UartAssist、Xshell 等),波特率 115200 ;
硬件 :小鸿开发板,通过 USB 转串口连接 PC,TX/RX/GND 正确连接。
# 三、集成步骤(文件放哪里、改哪里能编译)
喇叭示例以 samples 形式存在,目录为 vendor/atomgit/xiaohong/samples/08_speaker_demo ,通过 samples/BUILD.gn 的 features 与板级 config.py / ohos.cmake 参与编译并打进 ws63-liteos-app 镜像。以下步骤须全部完成,缺一不可。
# 3.1 目录与源码位置
本示例已放在小鸿 vendor 包内:
目录 :vendor/atomgit/xiaohong/samples/08_speaker_demo/ ;
源文件 :speaker_demo.c ;
构建目标 :本目录下的 static_library("speaker_demo") ,由 samples/BUILD.gn 以 feature "08_speaker_demo:speaker_demo" 形式编入应用。
完整路径为:
vendor/atomgit/xiaohong/
├── BUILD.gn # 顶层 group,依赖 xiaohong 主库与 samples
└── samples/
├── BUILD.gn # lite_component("app"),通过 features 选择示例
└── 08_speaker_demo/
├── BUILD.gn # static_library("speaker_demo")
├── speaker_demo.c # 演示源码
└── README.md # 操作说明
若从别处拷贝示例,请将 08_speaker_demo 整个目录放到 vendor/atomgit/xiaohong/samples 下。
# 3.2 步骤 1:检查 vendor 顶层 BUILD.gn(编译前必查)
打开 vendor/atomgit/xiaohong/BUILD.gn ,在 group("xiaohong") 的 deps 中确认包含 "samples:app", 。若缺少该项,samples 下的示例不会参与整包编译。
group("xiaohong") {
deps = [
"xiaohong:xiaohong",
"samples:app",
]
}
# 3.3 步骤 2:在 samples/BUILD.gn 中启用喇叭示例
修改 vendor/atomgit/xiaohong/samples/BUILD.gn ,在 lite_component("app") 的 features 列表中保留或添加 "08_speaker_demo:speaker_demo" (未注释):
lite_component("app") {
features = [
"08_speaker_demo:speaker_demo",
# 其他示例按需取消注释
]
}
说明 :以 # 开头的行为注释,不会参与编译 ;需要编进固件的示例须为未注释的一行。
# 3.4 步骤 3:在 config.py 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/build/config/target_config/ws63/config.py 中,找到 'ws63-liteos-app' 配置,在其 'ram_component' 列表中添加 "speaker_demo" :
说明 :ram_component 声明参与 ws63-liteos-app 镜像链接的组件;未在此列出的 static_library 不会被打进最终 app 镜像。
# 3.5 步骤 4:在 ohos.cmake 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/libs_url/ws63/cmake/ohos.cmake 中,找到 elseif(${TARGET_COMMAND} MATCHES "ws63-liteos-app") 对应的 set(COMPONENT_LIST ...) ,在列表中添加 "speaker_demo" :
说明 :COMPONENT_LIST 决定参与构建与安装的组件(静态库),需与 步骤 3 的 ram_component 及 samples 内 BUILD.gn 的 target 名称一致。
# 3.6 喇叭 demo 与主任务联动(可选)
若需通过双击唤醒键 或 CI1302 下发 0x20 触发播报,需在主工程中增加触发队列并在 main.c 中创建队列、在按键/CI1302 回调中向队列投递消息。以下为可选修改说明。
# 3.7 修改:主任务 main.c
路径 :vendor/atomgit/xiaohong/xiaohong/src/main.c
改动 1:头文件与宏
增加:#include "cmsis_os2.h"
增加:#define SPEAKER_DEMO_DOUBLETAP_MS (1500)
改动 2:喇叭 demo 触发队列
增加全局变量:osMessageQueueId_t g_speaker_demo_trigger_qid = NULL;
在 MainTask() 中创建队列处增加:
g_speaker_demo_trigger_qid = osMessageQueueNew(MSG_QUEUE_SIZE, sizeof(uint8_t), NULL);
(与 g_audx_event_qid 等队列一起创建。)
改动 3:双击唤醒键触发 demo
在 MainTask() 的 while(1) 前增加:static uint32_t last_wakeup_short_tick = 0;
将原来的 case eKey_Wakeup_ShortPressed: 改为带逻辑的代码块:
用 osKernelGetTickCount() 与 last_wakeup_short_tick 计算两次短按间隔;
若间隔 < SPEAKER_DEMO_DOUBLETAP_MS,视为双击,向 g_speaker_demo_trigger_qid 投递消息(并打印 [MainTask] wakeup double-tap -> trigger speaker demo),并清零 last_wakeup_short_tick;
否则视为单击,更新 last_wakeup_short_tick,并执行原有逻辑(向 g_audx_event_qid 投递 eAud_WakeUp、向 g_disp_event_qid 投递 eDisp_Blk_On)。
# 3.4 修改:CI1302 语音处理 ci1302_task.c
路径 :vendor/atomgit/xiaohong/xiaohong/src/audio/ci1302/ci1302_task.c
改动 1:声明喇叭 demo 触发队列
在文件顶部 extern 区增加:
extern osMessageQueueId_t g_speaker_demo_trigger_qid;
改动 2:语音指令 0x20 触发 demo
在 process_input_voice() 的 switch (recv_cmd) 中增加:
case 0x20:
printf("[1302Task] voice cmd recv 0x20 -> trigger speaker demo (put to g_speaker_demo_trigger_qid)\r\n");
msg_send = 1;
if (g_speaker_demo_trigger_qid != NULL) {
osMessageQueuePut(g_speaker_demo_trigger_qid, (const void *) &msg_send, 0, 0);
} else {
printf("[1302Task] g_speaker_demo_trigger_qid is NULL, skip trigger\r\n");
}
break;
含义:当 CI1302 通过 UART 上报 recv_cmd == 0x20 时(需在 CI1302 端配置某条语音指令对应 0x20),向 g_speaker_demo_trigger_qid 投递消息,由喇叭 demo 任务执行完整播报序列。
# 四、数据流与运行逻辑
触发源:
[1] 用户双击唤醒键 → MainTask 检测到 eKey_Wakeup_ShortPressed 且间隔 < 1.5s
→ osMessageQueuePut(g_speaker_demo_trigger_qid)
[2] 用户说出口令 → CI1302 识别并下发 0x20 → process_input_voice() case 0x20
→ osMessageQueuePut(g_speaker_demo_trigger_qid)
喇叭 Demo 任务(SpeakerDemoTask):
osMessageQueueGet(g_speaker_demo_trigger_qid) 取到消息
→ 节流判断:若距上次播报 < 5s 则忽略
→ run_playback_sequence():依次向 g_audx_event_qid 投递 eAud_WakeUp / eAud_VolUp / eAud_VolDw / eAud_NetConned / eAud_NetDisConn,每次后 osDelay(700)
CI1302 任务(Ci1302Task):
从 g_audx_event_qid 取到事件 → process_send_cmd(0x04/0x08/0x07/0x12/0x11) 通过 UART 发给 CI1302 → 板载喇叭播放对应提示音
# 五、喇叭控制指令表(播报用)
应用层事件(audio_config.h)与下发给 CI1302 的 cmd(ci1302_task.c 中 process_send_cmd(cmd))对应关系:
事件枚举
数值
下发给 CI1302 的 cmd
说明
eAud_WakeUp
0
0x04
唤醒提示音
eAud_VolUp
1
0x08
音量加提示
eAud_VolDw
2
0x07
音量减提示
eAud_NetConned
3
0x12
网络已连接提示音
eAud_NetDisConn
4
0x11
网络断开提示音
UART 帧格式(process_send_cmd):固定 11 字节,第 7、9 字节为 0x00 + cmd。
# 六、编译
喇叭 demo 已通过 samples/BUILD.gn 的 features 及 config.py / ohos.cmake 纳入编译。在 OpenHarmony 工程根目录下依次 执行:1. 清理 rm -fr out/xiaohong/xiaohong/ .ccache/*;2. 选择产品 hb set(按提示选择 mini 、xiaohong );3. 全量编译 hb build -f。编译成功后,固件生成路径为 out/xiaohong/xiaohong/ws63-liteos-app (Windows 下如 Z:\A_OH60T\out\...)。
# 七、烧录
以下内容与 HelloWorld、01_timer、02_delay、03_mutex、04_semaphore、05_message、06_spi 等 demo 通用,参见《小鸿AI 固件烧录与启动指导手册》或同仓库烧录说明。
# 7.1 烧录前准备
硬件搭建 :使用 Typec 线将板端与 PC 端连接。
55c4feb3c99d6077ec23c8438c3c15da
安装驱动 :安装「CH341SER 驱动」(CH341SER 驱动下载地址 ,若该链接失效或无法下载,可自行搜索下载)。安装前请将单板与 PC 连接,点击安装即可;显示驱动安装成功 代表成功,若显示驱动预安装成功 则代表安装失败。
下载 BurnTool 烧录工具 :下载并解压 BurnTool。
链接:https://atomgit.com/xiaohong-ai/docs/tree/main/tools
打开烧录工具,选择对应的串口;点开 Option 选项,选择对应目标(WS63E 与 WS63 属于同一系列,选 WS63 即可)。
点击 Select file 选择烧录文件(选择 ws63-liteos-app-all.fwpkg ,该文件位于固件路径 Z:\A_OH60T\out\xiaohong\xiaohong\ws63-liteos-app 下)。
勾选 Auto Burn 和 Auto disconnect 选项。
⚠️ 重要:进入烧录方式因板子批次不同
新板子 :点击 Connect 后直接开始烧录 。
旧板子 :点击 Connect 后,需同时按住两个音量/亮度按键约 1.5 秒后松开 ,再开始烧录。
待全部烧录成功后,显示 All images burn successfully 。
673e3245796e6d6497f3e480b2f9bd25
# 八、串口输出与结果分析
# 8.1 串口连接(查看日志)
准备:
烧录完成后,按以下步骤通过串口查看运行日志:
打开 UartAssist ,协议选择 SERIAL ,端口选择小鸿对应的 COM 口;
设置串口参数:波特率 115200 ,数据位 8,停止位 1,无校验、无流控;
先打开串口连接;
再给板子上电或复位,即可抓取完整启动与 08 喇叭控制 demo 日志。
在串口工具页面查看打印日志
6facb5cf-8fa7-4a98-a73f-2c811bd6cc4e
# 8.2 预期出现的日志(08 喇叭控制 Demo 相关)
阶段
日志特征
上电
[SpeakerDemo] trigger queue ready, task block on g_speaker_demo_trigger_qid (voice 0x20 or key).
双击唤醒键触发
[MainTask] wakeup double-tap -> trigger speaker demo、[SpeakerDemo] >>> trigger received (trigger=1), run playback sequence.、[SpeakerDemo] ----- playback sequence start -----
播报中
每条提示音对应一行 send eAud_xxx -> CI1302 cmd 0xxx ...
播报结束
[SpeakerDemo] ----- playback sequence end -----、[SpeakerDemo] >>> one round done, throttle 5000 ms, wait next trigger.
5 秒内再次触发
[SpeakerDemo] throttle: ignore trigger (elapsed xxx ms < 5000 ms),且不会再次播报
# 8.3 可调参数(speaker_demo.c)
宏
默认值
含义
SPEAKER_DEMO_DELAY_MS
700
每条提示音之间间隔(ms)
SPEAKER_DEMO_THROTTLE_MS
5000
播报结束后在此时间内忽略再次触发(ms)
主任务中双击判定间隔由 main.c 的 SPEAKER_DEMO_DOUBLETAP_MS(1500)决定。
# 九、修改文件汇总表
文件路径
操作
要点
samples/08_speaker_demo/ (speaker_demo.c、BUILD.gn、README.md)
已有
喇叭 demo 源码与 static_library("speaker_demo")
vendor/atomgit/xiaohong/BUILD.gn
检查
deps 中须含 "samples:app",
samples/BUILD.gn
修改
features 中须含 "08_speaker_demo:speaker_demo"
config.py (sdkv106 下 ws63)
修改
ram_component 中须含 "speaker_demo"
ohos.cmake (sdkv106 下 ws63)
修改
COMPONENT_LIST 中须含 "speaker_demo"
xiaohong/src/main.c
可选
触发队列、双击唤醒键逻辑(若需按键/语音触发)
xiaohong/src/audio/ci1302/ci1302_task.c
可选
0x20 触发 demo(若需语音触发)
未修改:audio_config.h、key_config.c、板级配置等;唤醒词/语音指令内容在 CI1302 端配置,本工程仅约定 0x20 触发 demo。
# 十、扩展建议
新增一条提示音 :在 audio_config.h 增加枚举,在 ci1302_task.c 的 switch (msg_recv) 中增加对应 process_send_cmd(xx),在 run_playback_sequence() 中追加一次 osMessageQueuePut(g_audx_event_qid, ...)。
其他触发方式 :在任意能访问 g_speaker_demo_trigger_qid 的地方对队列执行 osMessageQueuePut(..., &val, 0, 0) 即可触发一次完整播报(仍受 5 秒节流限制)。
# 十一、小结
文件放哪里 :喇叭 demo 位于 vendor/atomgit/xiaohong/samples/08_speaker_demo/ (含 speaker_demo.c、BUILD.gn、README)。若从别处拷贝,请将 08_speaker_demo 整目录放到 vendor/atomgit/xiaohong/samples 下。
改哪里能编译并打进镜像 :(1) vendor/atomgit/xiaohong/BUILD.gn 的 deps 须含 "samples:app", ;(2) samples/BUILD.gn 的 features 须含 "08_speaker_demo:speaker_demo" ;(3) config.py (sdkv106 下)的 ram_component 须含 "speaker_demo" ;(4) ohos.cmake (sdkv106 下)的 COMPONENT_LIST 须含 "speaker_demo" 。若需双击唤醒键或语音 0x20 触发,另按上文修改 main.c 、ci1302_task.c 。
运行效果 :双击唤醒键或语音指令 0x20 触发后,依次播放 5 条提示音,串口见 [SpeakerDemo] 、[MainTask] wakeup double-tap 等日志;5 秒内再次触发会被节流忽略。
编译:先清理,再 hb set (mini + xiaohong),最后 hb build -f 。烧录与 01_timer、07_easy_wifi 等 demo 一致;串口波特率 115200 。
文档版本 :与 vendor/atomgit/xiaohong/samples/08_speaker_demo/README.md 集成与编译步骤保持一致。
相关目录 :vendor/atomgit/xiaohong/samples/08_speaker_demo/。
Was this helpful? 👍 Yes 👎 Needs work
HANDS-ON SAMPLES Xiaohong AI · official docs
10 · PWM Hands-on samples / 10 · PWMi18n · The narrative below is the original Chinese reference (technical content — code, commands and logs are universal). A fully translated English edition is in progress.
View Chinese version → 本文档说明在小鸿工程中集成 09 PWM Demo 时的文件放置、BUILD.gn 修改方式,以及编译、烧录与串口验证流程,与 01_timer、02_delay、08_喇叭控制等 demo 采用同一套实践结构。
# 一、背景与目标
# 1.1 小鸿与 09 PWM Demo 是什么
小鸿 是基于 OpenHarmony + 海思 WS63 方案的设备/工程,其代码位于 vendor/atomgit/xiaohong/xiaohong,使用 CMSIS-RTOS2(LiteOS-M 适配)做多任务调度。
小鸿主控 WS63 提供多路 PWM 输出能力,可用于背光调节、蜂鸣器、LED 调光等场景。09 PWM Demo 包含两部分:
(1)PWM 通道 0 方波 Demo(pwm_demo.c)
上电自动运行 :系统启动时通过 SYS_RUN(PwmDemo) 注册,自动创建 PwmDemoTask 任务。
输出参数 :使用 PWM 通道 0 (group 0),输出约 2kHz 频率、50% 占空比的方波,持续约 3 秒 后停止并反初始化。
通道隔离 :与背光使用的 通道 2 (group 1)不冲突,可安全并行。
硬件可选 :若板级将 PWM0 接到 LED 或无源蜂鸣器,可直观看到亮灯或听到蜂鸣;未接外设时仅运行逻辑也可验证软件流程。
(2)呼吸灯 Demo(breathing_led_demo.c)
上电自动运行 :通过 SYS_RUN(BreathingLedDemo) 注册,创建 BreathingLedTask 任务。
实现方式 :利用 LCD 背光 (PWM 通道 2)做亮度渐变,循环 1→100→1 的占空比,实现呼吸灯效果;演示约 5 轮 后恢复默认背光并停止。
适用场景 :若板子上仅有背光/充电灯接在该路 PWM,即可看到呼吸效果。
编译条件 :依赖 disp_driver(背光接口),仅在产品配置中 启用 LVGL + LCD 时参与编译(见下文 3.2)。
# 1.2 本文目标
说明 PWM demo 所在目录与构建方式 (samples/09_pwm_demo,通过 features 编入);
说明 为能编译并打进镜像需要修改的文件 :vendor 顶层 BUILD.gn、samples/BUILD.gn、config.py、ohos.cmake;
说明 PWM 初始化、配置、输出与关闭的完整数据流;
说明编译、烧录及串口验证方式,与其它 demo 保持一致。
# 二、环境与前置条件
工程 :OpenHarmony + 小鸿 vendor(vendor/atomgit/xiaohong,含主库与 samples ,PWM 示例位于 samples/09_pwm_demo );
SDK :WS63 SDK(通过 ws63_sdk.gni 引用);
工具 :串口调试助手(如 UartAssist、Xshell 等),波特率 115200 ;
硬件 :小鸿开发板,通过 USB 转串口连接 PC,TX/RX/GND 正确连接。
# 三、集成步骤(文件放哪里、改哪里能编译)
PWM 示例以 samples 形式存在,目录为 vendor/atomgit/xiaohong/samples/09_pwm_demo ,通过 samples/BUILD.gn 的 features 与板级 config.py / ohos.cmake 参与编译并打进 ws63-liteos-app 镜像。以下步骤须全部完成,缺一不可。
# 3.1 目录与源码位置
本示例已放在小鸿 vendor 包内:
目录 :vendor/atomgit/xiaohong/samples/09_pwm_demo/ ;
源文件 :pwm_demo.c (可选 breathing_led_demo.c 等);
构建目标 :本目录下的 static_library("pwm_demo") ,由 samples/BUILD.gn 以 feature "09_pwm_demo:pwm_demo" 形式编入应用。
完整路径为:
vendor/atomgit/xiaohong/
├── BUILD.gn # 顶层 group,依赖 xiaohong 主库与 samples
└── samples/
├── BUILD.gn # lite_component("app"),通过 features 选择示例
└── 09_pwm_demo/
├── BUILD.gn # static_library("pwm_demo")
├── pwm_demo.c # 演示源码
└── README.md # 操作说明
若从别处拷贝示例,请将 09_pwm_demo 整个目录放到 vendor/atomgit/xiaohong/samples 下。
# 3.2 步骤 1:检查 vendor 顶层 BUILD.gn(编译前必查)
打开 vendor/atomgit/xiaohong/BUILD.gn ,在 group("xiaohong") 的 deps 中确认包含 "samples:app", 。若缺少该项,samples 下的示例不会参与整包编译。
group("xiaohong") {
deps = [
"xiaohong:xiaohong",
"samples:app",
]
}
# 3.3 步骤 2:在 samples/BUILD.gn 中启用 PWM 示例
修改 vendor/atomgit/xiaohong/samples/BUILD.gn ,在 lite_component("app") 的 features 列表中保留或添加 "09_pwm_demo:pwm_demo" (未注释):
lite_component("app") {
features = [
"09_pwm_demo:pwm_demo",
# 其他示例按需取消注释
]
}
说明 :以 # 开头的行为注释,不会参与编译 ;需要编进固件的示例须为未注释的一行。
# 3.4 步骤 3:在 config.py 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/build/config/target_config/ws63/config.py 中,找到 'ws63-liteos-app' 配置,在其 'ram_component' 列表中添加 "pwm_demo" :
说明 :ram_component 声明参与 ws63-liteos-app 镜像链接的组件;未在此列出的 static_library 不会被打进最终 app 镜像。
# 3.5 步骤 4:在 ohos.cmake 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/libs_url/ws63/cmake/ohos.cmake 中,找到 elseif(${TARGET_COMMAND} MATCHES "ws63-liteos-app") 对应的 set(COMPONENT_LIST ...) ,在列表中添加 "pwm_demo" :
说明 :COMPONENT_LIST 决定参与构建与安装的组件(静态库),需与 步骤 3 的 ram_component 及 samples 内 BUILD.gn 的 target 名称一致。
# 3.6 PWM Demo 目录与源码说明(可选阅读)
路径 :vendor/atomgit/xiaohong/samples/09_pwm_demo/
文件
说明
pwm_demo.c
PWM 通道 0 方波 Demo:SYS_RUN(PwmDemo) 在系统启动时执行,创建线程 PwmDemoTask ;任务内调用 uapi_pwm_init → uapi_pwm_open → uapi_pwm_set_group → uapi_pwm_start,输出 DEMO_RUN_MS 毫秒后 uapi_pwm_stop_group → uapi_pwm_close → uapi_pwm_deinit。宏:DEMO_PWM_CHANNEL=0、DEMO_PWM_GROUP=0、DEMO_PWM_FREQ_HZ=2000、DEMO_PWM_DUTY_PCT=50、DEMO_RUN_MS=3000。
breathing_led_demo.c
呼吸灯 Demo:SYS_RUN(BreathingLedDemo) 创建 BreathingLedTask ,循环调用 disp_set_backlight_level(level) 使背光从 1→100→1 渐变,演示 BREATH_CYCLES 轮后恢复默认亮度。宏:BREATH_STEP=5、BREATH_DELAY_MS=40、BREATH_CYCLES=5。依赖 disp_driver.h,仅在 config_lvgl_enable = true 时参与编译。
BUILD.gn
独立 static_library("pwm_demo") 的构建定义;当前主工程采用直接合入源码 方式,未通过 deps 引用此 target。
README.md
使用说明:依赖、集成方式、频率/占空比/持续时间修改、使用其他通道说明。
技术博客_09_PWM_Demo在小鸿上实现.md
本文档。
pwm_demo.c 关键逻辑摘要 :
PwmDemo() :SYS_RUN 注册的入口,创建名为 PwmDemoTask、栈 0x800、普通优先级的线程,线程函数为 PwmDemoTask。
PwmDemoTask() :
1. uapi_pwm_init() 初始化 PWM 子系统;
2. uapi_pwm_get_frequency(ch) 获取通道时钟频率,据此计算周期 period_cyc = clk_hz / DEMO_PWM_FREQ_HZ 和高电平计数 high_cyc = period_cyc * DEMO_PWM_DUTY_PCT / 100;
3. 填充 pwm_config_t(low_time、high_time、offset_time、cycles、repeat),uapi_pwm_open(ch, &cfg) 打开通道;
4. uapi_pwm_clear_group、uapi_pwm_set_group 将通道加入 group,uapi_pwm_start(ch) 启动输出;
5. osDelay(DEMO_RUN_MS) 持续输出指定时长;
6. uapi_pwm_stop_group、uapi_pwm_close、uapi_pwm_deinit 停止并释放资源,打印 [PwmDemo] done.。
breathing_led_demo.c 关键逻辑摘要 :
BreathingLedDemo() :SYS_RUN 注册的入口,创建名为 BreathingLedTask、栈 0x600、优先级略低于普通的线程。
BreathingLedTask() :循环 BREATH_CYCLES 轮;每轮内先渐亮(level 1→100,步进 BREATH_STEP,每步 osDelay(BREATH_DELAY_MS)),再渐暗(100→1);结束后调用 disp_set_backlight_level(LCD_BLK_PWM_DUTY_DEF) 恢复默认背光并退出。背光由 disp_driver 的 PWM 通道 2 控制。
# 3.7 修改:主工程 BUILD.gn(可选,若需呼吸灯或非 samples 方式)
路径 :vendor/atomgit/xiaohong/xiaohong/BUILD.gn
改动 1 :在 static_library("xiaohong") 的 sources 中增加 PWM 方波 demo 源文件(无条件编译):
sources += [
"src/samples/09_pwm_demo/pwm_demo.c",
]
插入位置:在 src/audio/ci1302/ci1302_task.c 所在 sources 块之后、include_dirs += [ 之前。
改动 2 :在 if (config_lvgl_enable) 块内增加呼吸灯 demo 源文件(仅当启用 LVGL + LCD 时编译):
if (config_lvgl_enable) {
defines += [ "SUPPORT_LVGL" ]
sources += [
"src/display/disp_driver.c",
...
"src/samples/09_pwm_demo/breathing_led_demo.c", // 呼吸灯 demo,依赖背光接口
]
...
}
产品配置中需满足 config_lvgl_enable = true 且具备背光驱动(如 config_lcd_panel = "lcd_ST7789S_240x240"),呼吸灯 demo 才会参与编译。小鸿工程默认在 config.gni 中已开启上述配置。
主工程已具备 WS63 SDK 的 include/driver(含 pwm.h)及 errcode.h 等头文件路径,无需额外 include_dirs。
# 四、数据流与运行逻辑
系统启动
→ SYS_RUN(PwmDemo) 被调用
→ PwmDemo() 创建线程 PwmDemoTask
PwmDemoTask:
uapi_pwm_init()
→ uapi_pwm_get_frequency(0) 获取通道 0 时钟
→ 计算 period_cyc、high_cyc(2kHz、50% 占空比)
→ uapi_pwm_open(0, &cfg)
uapi_pwm_clear_group(0) → uapi_pwm_set_group(0, &ch, 1)
→ uapi_pwm_start(0)
osDelay(3000) // 输出约 3 秒
uapi_pwm_stop_group(0) → uapi_pwm_close(0) → uapi_pwm_deinit()
printf("[PwmDemo] done.")
PWM 通道与 Group 对应关系 (便于改用其他通道时参考):
通道
Group
0, 1
0
2, 3
1(背光常用通道 2)
4, 5
2
6, 7
3
呼吸灯 Demo 数据流 :
系统启动
→ SYS_RUN(BreathingLedDemo) 被调用
→ BreathingLedDemo() 创建线程 BreathingLedTask
BreathingLedTask:
for (cycle = 0; cycle < BREATH_CYCLES; cycle++)
渐亮:level 1→100,步进 BREATH_STEP,每步 disp_set_backlight_level(level) + osDelay(BREATH_DELAY_MS)
渐暗:level 100→1,同上
disp_set_backlight_level(LCD_BLK_PWM_DUTY_DEF) // 恢复默认背光
printf("[BreathingLed] done, backlight restored to default")
背光由 disp_driver.c 的 disp_set_backlight() 驱动,内部使用 PWM 通道 2 (LCD_BLK_PWM_PORT)。
# 五、WS63 uapi_pwm 接口简要说明
Demo 使用的核心接口(来自 WS63 SDK pwm.h / 底层驱动):
接口
说明
uapi_pwm_init()
初始化 PWM 子系统
uapi_pwm_deinit()
反初始化
uapi_pwm_get_frequency(ch)
获取通道 ch 的时钟频率(Hz),用于计算周期
uapi_pwm_open(ch, &cfg)
打开通道 ch,配置周期与占空比(cfg:low_time、high_time、repeat 等)
uapi_pwm_close(ch)
关闭通道
uapi_pwm_clear_group(group)
清空该 group 内的通道
uapi_pwm_set_group(group, ch_array, cnt)
将通道加入 group
uapi_pwm_start(ch)
启动通道输出
uapi_pwm_stop_group(group)
停止该 group 下所有通道
返回值通过 errcode.h 的 ERRCODE_SUCC / ERRCODE_FAIL 等判断。
# 六、编译
PWM demo 已通过 samples/BUILD.gn 的 features 及 config.py / ohos.cmake 纳入编译。在 OpenHarmony 工程根目录下依次 执行:1. 清理 rm -fr out/xiaohong/xiaohong/ .ccache/*;2. 选择产品 hb set(按提示选择 mini 、xiaohong );3. 全量编译 hb build -f。编译成功后,固件生成路径为 out/xiaohong/xiaohong/ws63-liteos-app (Windows 下如 Z:\A_OH60T\out\...)。
# 七、烧录
以下内容与 HelloWorld、01_timer、02_delay、03_mutex、04_semaphore、05_message、06_spi、08_喇叭控制等 demo 通用,参见《小鸿AI 固件烧录与启动指导手册》或同仓库烧录说明。
# 7.1 烧录前准备
硬件搭建 :使用 Typec 线将板端与 PC 端连接。
55c4feb3c99d6077ec23c8438c3c15da
安装驱动 :安装「CH341SER 驱动」(CH341SER 驱动下载地址 ,若该链接失效或无法下载,可自行搜索下载)。安装前请将单板与 PC 连接,点击安装即可;显示驱动安装成功 代表成功,若显示驱动预安装成功 则代表安装失败。
下载 BurnTool 烧录工具 :下载并解压 BurnTool。
链接:https://atomgit.com/xiaohong-ai/docs/tree/main/tools
打开烧录工具,选择对应的串口;点开 Option 选项,选择对应目标(WS63E 与 WS63 属于同一系列,选 WS63 即可)。
点击 Select file 选择烧录文件(选择 ws63-liteos-app-all.fwpkg ,该文件位于固件路径 Z:\A_OH60T\out\xiaohong\xiaohong\ws63-liteos-app 下)。
勾选 Auto Burn 和 Auto disconnect 选项。
⚠️ 重要:进入烧录方式因板子批次不同
新板子 :点击 Connect 后直接开始烧录 。
旧板子 :点击 Connect 后,需同时按住两个音量/亮度按键约 1.5 秒后松开 ,再开始烧录。
待全部烧录成功后,显示 All images burn successfully 。
673e3245796e6d6497f3e480b2f9bd25
# 八、串口输出与结果分析
# 8.1 串口连接(查看日志)
准备:
烧录完成后,按以下步骤通过串口查看运行日志:
打开 UartAssist ,协议选择 SERIAL ,端口选择小鸿对应的 COM 口;
设置串口参数:波特率 115200 ,数据位 8,停止位 1,无校验、无流控;
先打开串口连接;
再给板子上电或复位,即可抓取完整启动与 09 PWM demo 日志。
在串口工具页面查看打印日志
aef237bf-fc1c-4ecc-9468-0d959b5cf346
# 8.2 预期出现的日志(09 PWM Demo 相关)
上电后 demo 自动执行,串口应依次看到类似输出:
阶段
日志特征
初始化
[PwmDemo] init channel 0, freq 2000 Hz, duty 50%
输出中
[PwmDemo] PWM output for 3000 ms
结束
[PwmDemo] done.
若初始化失败(如时钟或打开通道失败),会打印 uapi_pwm_get_frequency failed 或 uapi_pwm_open failed 等并直接返回。
# 8.3 预期出现的日志(呼吸灯 Demo,需启用 LVGL+LCD)
当产品配置中 config_lvgl_enable = true 且背光驱动已编入时,上电后还会看到呼吸灯任务日志:
阶段
日志特征
启动
[BreathingLed] start, use LCD backlight (PWM ch2)
结束
[BreathingLed] done, backlight restored to default
背光会先渐亮再渐暗,循环约 5 轮后恢复默认亮度。若未启用 LVGL/LCD,则不会编译 breathing_led_demo.c,无上述日志。
# 8.4 可调参数(pwm_demo.c)
宏
默认值
含义
DEMO_PWM_CHANNEL
0
PWM 通道号(0–7)
DEMO_PWM_GROUP
0
通道所属 group(0–3,见第四节表)
DEMO_PWM_FREQ_HZ
2000
输出频率(Hz)
DEMO_PWM_DUTY_PCT
50
占空比(0–100)
DEMO_RUN_MS
3000
输出持续时间(毫秒)
可调参数(breathing_led_demo.c) :
宏
默认值
含义
BREATH_STEP
5
每步亮度变化量(1–100)
BREATH_DELAY_MS
40
每步延时(ms),越小呼吸越快
BREATH_CYCLES
5
呼吸轮数,结束后恢复默认背光
# 8.5 使用其他通道
将 DEMO_PWM_CHANNEL 改为 1/2/3/4/5/6/7 之一,并相应修改 DEMO_PWM_GROUP(0、1→0;2、3→1;4、5→2;6、7→3)。若需在具体引脚观测波形,需在板级将该通道对应 GPIO 配置为 PWM 功能(可参考 board_config.c 中背光引脚 uapi_pin_set_mode(..., 1) 的用法)。
# 九、修改文件汇总表
文件路径
操作
要点
xiaohong/src/samples/09_pwm_demo/pwm_demo.c
新增
PWM 通道 0 方波 Demo:init → open → set_group → start → delay → stop → close → deinit
xiaohong/src/samples/09_pwm_demo/breathing_led_demo.c
新增
呼吸灯 Demo:背光 1→100→1 渐变,依赖 disp_driver,仅在 config_lvgl_enable 时编译
xiaohong/src/samples/09_pwm_demo/BUILD.gn
新增
pwm_demo 静态库定义(可选,当前未通过 deps 使用)
xiaohong/src/samples/09_pwm_demo/README.md
新增
使用说明与参数、通道说明
xiaohong/BUILD.gn
修改
sources 中增加 pwm_demo.c;在 if (config_lvgl_enable) 内增加 breathing_led_demo.c
未修改:main.c、板级配置等;PWM 驱动由 WS63 SDK / 主工程已链接的底层提供。呼吸灯依赖 config.gni 中 config_lvgl_enable = true 与 LCD 背光驱动。
# 十、扩展建议
循环或按键触发 :可将 PwmDemoTask 改为在 while(1) 中等待消息队列或信号量,收到触发后再执行一轮 init → output → deinit,实现按需输出。
多通道/多组 :需要同时驱动多路 PWM 时,可对多个通道分别 uapi_pwm_open,并按 group 规则 set_group 后统一 start,注意同一 group 内通道的协同关系(参见 SDK 文档)。
呼吸灯 :已通过 breathing_led_demo.c 实现,利用 LCD 背光(PWM 通道 2)做占空比渐变;可调整 BREATH_STEP、BREATH_DELAY_MS、BREATH_CYCLES 改变速度与轮数。若需常驻呼吸或由按键/充电状态触发,可在该任务中增加循环或消息队列触发逻辑。
# 十一、小结
文件放哪里 :PWM demo 位于 vendor/atomgit/xiaohong/samples/09_pwm_demo/ (含 pwm_demo.c、BUILD.gn、README 等)。若从别处拷贝,请将 09_pwm_demo 整目录放到 vendor/atomgit/xiaohong/samples 下。
改哪里能编译并打进镜像 :(1) vendor/atomgit/xiaohong/BUILD.gn 的 deps 须含 "samples:app", ;(2) samples/BUILD.gn 的 features 须含 "09_pwm_demo:pwm_demo" ;(3) config.py (sdkv106 下)的 ram_component 须含 "pwm_demo" ;(4) ohos.cmake (sdkv106 下)的 COMPONENT_LIST 须含 "pwm_demo" 。
运行效果 :上电自动运行 PWM 通道 0 方波 demo (约 3 秒),串口见 [PwmDemo] 日志;若产品启用 LVGL+LCD 且编入呼吸灯,背光渐变约 5 轮后恢复默认。
编译:先清理,再 hb set (mini + xiaohong),最后 hb build -f 。烧录与 01_timer、08_喇叭控制等 demo 一致;串口波特率 115200 。
文档版本 :与 vendor/atomgit/xiaohong/samples/09_pwm_demo/README.md 集成与编译步骤保持一致。
相关目录 :vendor/atomgit/xiaohong/samples/09_pwm_demo/。
Was this helpful? 👍 Yes 👎 Needs work
HANDS-ON SAMPLES Xiaohong AI · official docs
11 · STA (Wi-Fi station) Hands-on samples / 11 · STA (Wi-Fi station)i18n · The narrative below is the original Chinese reference (technical content — code, commands and logs are universal). A fully translated English edition is in progress.
View Chinese version → 本文档说明在小鸿工程中集成 10 STA 实现自动连接 Demo (10_sta_demo)时的文件放置、配置与 BUILD.gn 修改方式,以及编译、烧录、串口验证与界面状态栏(NC/OK)更新流程,与 01_timer、07_easy_wifi、08_喇叭控制、09_PWM 等 demo 采用同一套实践结构。
# 一、背景与目标
# 1.1 小鸿与 10 STA 实现自动连接 Demo 是什么
小鸿 是基于 OpenHarmony + 海思 WS63 方案的设备/工程,其代码位于 vendor/atomgit/xiaohong/xiaohong,使用 CMSIS-RTOS2(LiteOS-M 适配)做多任务调度。小鸿主控 WS63 提供 Wi-Fi STA(Station)能力,可连接无线路由器并获取 IP,与 HiSpark 软件开发指南中的 STA 功能流程一致。
10 STA 实现自动连接 Demo (代码目录名为 10_sta_demo)是一个最小化 STA 演示 ,只做一件事:
上电后 :等待系统完成 Wi-Fi 驱动初始化,然后开启 STA → 扫描 → 连接预先配置的 SSID/密码 对应 AP → DHCP 获取 IP。
串口 :按阶段打印 [STA_DEMO] wait wifi init...、wifi init ok、STA enabled, scan...、scan done、found AP, connect...、STA connected、STA connect success. (DHCP OK) 及获取到的 IP 信息。
界面 :通过 set_wifi_status() 通知显示任务,状态栏由 NC (未连接)→ ## (连接中)→ OK (已连接),与完整应用的“连上 WiFi 就变 OK”逻辑一致;失败时恢复为 NC 。
本 Demo 通过 config.gni 中的 config_sta_simple_demo 开关控制是否启用:设为 true 时,WiFi 任务仅执行本 demo(不跑热点、配网等);设为 false 时恢复完整应用行为。
# 1.2 本文目标
说明 STA demo 所在目录与构建方式 (samples/10_sta_demo,通过 features 编入);
说明 为能编译并打进镜像需要修改的文件 :vendor 顶层 BUILD.gn、samples/BUILD.gn、config.py、ohos.cmake;
说明 STA 初始化、扫描、连接、DHCP 与界面状态更新的完整数据流;
说明编译、烧录及串口验证方式,与其它 demo 保持一致。
# 二、环境与前置条件
工程 :OpenHarmony + 小鸿 vendor(vendor/atomgit/xiaohong,含主库与 samples ,STA 示例位于 samples/10_sta_demo );
SDK :WS63 SDK(通过 ws63_sdk.gni 引用);
工具 :串口调试助手(如 UartAssist、Xshell 等),波特率 115200 ;
硬件 :小鸿开发板,通过 USB 转串口连接 PC,TX/RX/GND 正确连接;如需验证 STA 连接,需确保周围有可连接的 2.4G Wi-Fi 热点并已知 SSID 与密码。
# 三、集成步骤(文件放哪里、改哪里能编译)
STA 示例以 samples 形式存在,目录为 vendor/atomgit/xiaohong/samples/10_sta_demo ,通过 samples/BUILD.gn 的 features 与板级 config.py / ohos.cmake 参与编译并打进 ws63-liteos-app 镜像。以下步骤须全部完成,缺一不可。
# 3.1 目录与源码位置
本示例已放在小鸿 vendor 包内:
目录 :vendor/atomgit/xiaohong/samples/10_sta_demo/ ;
源文件 :sta_simple_demo.c ;
构建目标 :本目录下的 static_library("sta_demo") ,由 samples/BUILD.gn 以 feature "10_sta_demo:sta_demo" 形式编入应用。
完整路径为:
vendor/atomgit/xiaohong/
├── BUILD.gn # 顶层 group,依赖 xiaohong 主库与 samples
└── samples/
├── BUILD.gn # lite_component("app"),通过 features 选择示例
└── 10_sta_demo/
├── BUILD.gn # static_library("sta_demo")
├── sta_simple_demo.c # 演示源码
└── README.md # 操作说明
若从别处拷贝示例,请将 10_sta_demo 整个目录放到 vendor/atomgit/xiaohong/samples 下。
# 3.2 步骤 1:检查 vendor 顶层 BUILD.gn(编译前必查)
打开 vendor/atomgit/xiaohong/BUILD.gn ,在 group("xiaohong") 的 deps 中确认包含 "samples:app", 。若缺少该项,samples 下的示例不会参与整包编译。
group("xiaohong") {
deps = [
"xiaohong:xiaohong",
"samples:app",
]
}
# 3.3 步骤 2:在 samples/BUILD.gn 中启用 STA 示例
修改 vendor/atomgit/xiaohong/samples/BUILD.gn ,在 lite_component("app") 的 features 列表中保留或添加 "10_sta_demo:sta_demo" (未注释):
lite_component("app") {
features = [
"10_sta_demo:sta_demo",
# 其他示例按需取消注释
]
}
说明 :以 # 开头的行为注释,不会参与编译 ;需要编进固件的示例须为未注释的一行。
# 3.4 步骤 3:在 config.py 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/build/config/target_config/ws63/config.py 中,找到 'ws63-liteos-app' 配置,在其 'ram_component' 列表中添加 "sta_demo" :
说明 :ram_component 声明参与 ws63-liteos-app 镜像链接的组件;未在此列出的 static_library 不会被打进最终 app 镜像。
# 3.5 步骤 4:在 ohos.cmake 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/libs_url/ws63/cmake/ohos.cmake 中,找到 elseif(${TARGET_COMMAND} MATCHES "ws63-liteos-app") 对应的 set(COMPONENT_LIST ...) ,在列表中添加 "sta_demo" :
说明 :COMPONENT_LIST 决定参与构建与安装的组件(静态库),需与 步骤 3 的 ram_component 及 samples 内 BUILD.gn 的 target 名称一致。
# 3.6 新增:10_sta_demo 目录与源码说明(可选阅读)
路径 :vendor/atomgit/xiaohong/samples/10_sta_demo/
文件
说明
sta_simple_demo.c
Demo 主逻辑:提供 run_sta_simple_demo()。流程:set_wifi_status(eWifi_St_AutoConnecting) → 等待 wifi_is_wifi_inited() → wifi_register_event_cb → wifi_sta_enable → wifi_sta_scan → 延时后 wifi_sta_get_scan_info(封装在 demo_find_ap)→ wifi_sta_connect → 轮询 wifi_sta_get_ap_info 直至 WIFI_CONNECTED → netifapi_netif_find("wlan0") → netifapi_dhcp_start → 轮询 netifapi_dhcp_is_bound → 打印 DHCP 信息 → set_wifi_status(eWifi_St_Connected)。任一失败则 set_wifi_status(eWifi_St_Disconnected) 并 return。宏:DEMO_SSID、DEMO_PSWD、DEMO_SCAN_WAIT_MS、DEMO_CONN_POLL_MS、DEMO_CONN_POLL_TIMES、DEMO_DHCP_WAIT_MS、DEMO_DHCP_POLL_TIMES、DEMO_IFNAME。
README.md
使用说明:修改 SSID/密码、打开 config_sta_simple_demo、编译烧录、预期串口输出、恢复完整应用。
技术博客_10_STA实现自动连接demo在小鸿上实现.md
本文档。
sta_simple_demo.c 关键逻辑摘要 :
run_sta_simple_demo() :入口。先 set_wifi_status(eWifi_St_AutoConnecting) 使状态栏显示“连接中”;再等待 wifi_is_wifi_inited() == 1;注册扫描/连接回调;调用 wifi_sta_enable()、wifi_sta_scan(),延时 DEMO_SCAN_WAIT_MS 后通过 demo_find_ap() 从扫描结果中匹配 DEMO_SSID 并填充 wifi_sta_config_stru;调用 wifi_sta_connect(&bss),轮询 wifi_sta_get_ap_info() 直至 conn_state == WIFI_CONNECTED;对 wlan0 做 netifapi_dhcp_start 并轮询 netifapi_dhcp_is_bound;成功则 netifapi_netif_common(..., dhcp_clients_info_show, NULL) 打印 IP,并 set_wifi_status(eWifi_St_Connected) 使状态栏显示 OK。所有错误路径均调用 set_wifi_status(eWifi_St_Disconnected)。
demo_find_ap() :内部调用 wifi_sta_get_scan_info() 获取列表,按 SSID 匹配后填充 expected_bss(ssid、bssid、security_type、pre_shared_key、ip_type=DHCP)。
# 3.7 修改:config.gni(可选,若需仅跑 STA demo)
路径 :vendor/atomgit/xiaohong/xiaohong/config.gni
改动 :在 declare_args() 中增加 10 STA 实现自动连接 Demo 开关:
# 设为 true 时仅跑 STA 简单 demo(改 SSID/密码请编辑 src/samples/10_sta_demo/sta_simple_demo.c)
config_sta_simple_demo = ture
config_sta_simple_demo = true:WiFi 任务只执行 run_sta_simple_demo(),适合单独验证 STA 连接与界面 NC/OK;
config_sta_simple_demo = false:保持完整应用(热点、配网、显示等),与未接 demo 时一致。
# 3.8 修改:主工程 BUILD.gn(可选,若采用 config_sta_simple_demo 方式)
路径 :vendor/atomgit/xiaohong/xiaohong/BUILD.gn
改动 :在 network 相关 sources 与 include_dirs 块中,按条件加入 STA demo 源文件与宏。
在 sources += [ "src/network/net_wifi_task.c", ... ] 所在块内增加:
if (config_sta_simple_demo) {
defines += [ "STA_SIMPLE_DEMO" ]
sources += [ "src/samples/10_sta_demo/sta_simple_demo.c" ]
}
当 config_sta_simple_demo = true 时,编译会定义 STA_SIMPLE_DEMO 并参与编译 sta_simple_demo.c ;
include_dirs 已包含 src/network,demo 中 #include "net_wifi_config.h" 可正常解析;无需额外增加 src/samples/10_sta_demo(demo 无单独头文件)。
# 3.9 修改:WiFi 任务 net_wifi_task.c
路径 :vendor/atomgit/xiaohong/xiaohong/src/network/net_wifi_task.c
改动 1 :在 WiFiTask() 开头增加 10 STA 实现自动连接 Demo 分支:
#ifdef STA_SIMPLE_DEMO
extern void run_sta_simple_demo(void);
#endif
void WiFiTask(void)
{
#ifdef STA_SIMPLE_DEMO
printf("[WiFiTask] run STA simple demo.\r\n");
run_sta_simple_demo();
return;
#endif
// 以下为原有完整应用逻辑
...
}
当编译定义了 STA_SIMPLE_DEMO 时,WiFi 任务仅调用 run_sta_simple_demo()(即 10 STA 实现自动连接 Demo)后 return,不再执行后续配网、消息循环等逻辑。
# 3.10 修改:net_wifi_config.h 与 net_wifi_task.c(set_wifi_status 导出)
路径 :vendor/atomgit/xiaohong/xiaohong/src/network/net_wifi_config.h
改动 :在 get_wifi_status() 声明后增加:
void set_wifi_status(uint8_t status); /* 供 10_sta_demo 等通知界面刷新 WiFi 状态(NC/OK) */
路径 :vendor/atomgit/xiaohong/xiaohong/src/network/net_wifi_task.c
改动 :将 set_wifi_status 从 static 改为全局函数(去掉 static),以便 sta_simple_demo.c 调用。set_wifi_status() 内部会更新 g_wifi_state 并向 g_disp_event_qid 发送 eDisp_WiFi_St_Update,显示任务根据 get_wifi_status() 将状态栏更新为 NC / ## / OK。
# 四、数据流与运行逻辑
系统启动
→ MainTask 创建 WiFiTask(WiFiTaskEntry)
→ WiFiTask() 被调用
若定义了 STA_SIMPLE_DEMO:
→ printf("[WiFiTask] run STA simple demo.")
→ run_sta_simple_demo()
→ set_wifi_status(eWifi_St_AutoConnecting) // 状态栏 ##
→ while (!wifi_is_wifi_inited()) osal_msleep(100)
→ wifi_register_event_cb(&s_demo_wifi_events)
→ wifi_sta_enable()
→ wifi_sta_scan() → osal_msleep(DEMO_SCAN_WAIT_MS)
→ demo_find_ap() 内部 wifi_sta_get_scan_info() 匹配 DEMO_SSID
→ wifi_sta_connect(&bss)
→ 轮询 wifi_sta_get_ap_info() 直至 WIFI_CONNECTED
→ netifapi_netif_find("wlan0") → netifapi_dhcp_start()
→ 轮询 netifapi_dhcp_is_bound()
→ dhcp_clients_info_show 打印 IP
→ set_wifi_status(eWifi_St_Connected) // 状态栏 OK,界面刷新
→ return(任务不再循环)
若未定义 STA_SIMPLE_DEMO:
→ 原有逻辑:等待 wifi_is_wifi_inited → get_wifi_config → connect_to_hotspot → set_wifi_status → while(1) 消息循环(配网/成功/失败)
界面状态与 set_wifi_status 对应关系 (lvgl_ui_layout.c 中状态栏文案):
set_wifi_status 传入
状态栏 WiFi 显示
eWifi_St_Disconnected
NC
eWifi_St_AutoConnecting / eWifi_St_Connecting
##
eWifi_St_Connected
OK
# 五、WS63 WiFi STA 接口简要说明
Demo 使用的核心接口(来自 WS63 SDK wifi_device.h、wifi_event.h 及 lwIP netifapi.h):
接口
说明
wifi_is_wifi_inited()
返回 1 表示 Wi-Fi 驱动已初始化,可进行 STA/SoftAP 操作
wifi_register_event_cb(&cb)
注册扫描完成、连接状态变化等回调
wifi_sta_enable()
开启 STA 模式
wifi_sta_scan()
触发扫描(非阻塞,需延时后再取结果)
wifi_sta_get_scan_info(result, &num)
获取扫描结果列表
wifi_sta_connect(&bss)
按 bss(ssid、bssid、security_type、pre_shared_key、ip_type)连接 AP
wifi_sta_get_ap_info(&link_info)
查询当前连接状态(如 link_info.conn_state == WIFI_CONNECTED)
netifapi_netif_find("wlan0")
获取 STA 对应 netif
netifapi_dhcp_start(netif)
启动 DHCP 客户端
netifapi_dhcp_is_bound(netif)
判断是否已获取到 IP
netifapi_netif_common(netif, dhcp_clients_info_show, NULL)
打印 DHCP 获得的 IP、网关等
返回值通过 errcode.h 的 ERRCODE_SUCC / ERRCODE_FAIL 等判断;lwIP 使用 ERR_OK。
# 六、编译
STA demo 已通过 samples/BUILD.gn 的 features 及 config.py / ohos.cmake 纳入编译。若采用 config_sta_simple_demo 方式仅跑 STA,需先在 config.gni 中设置 config_sta_simple_demo = true 。在 OpenHarmony 工程根目录下依次 执行:1. 清理 rm -fr out/xiaohong/xiaohong/ .ccache/*;2. 选择产品 hb set(按提示选择 mini 、xiaohong );3. 全量编译 hb build -f。编译成功后,固件生成路径为 out/xiaohong/xiaohong/ws63-liteos-app (Windows 下如 Z:\A_OH60T\out\...)。
# 七、烧录
以下内容与 HelloWorld、01_timer、02_delay、03_mutex、04_semaphore、05_message、06_spi、08_喇叭控制、09_PWM 等 demo 通用,参见《小鸿AI 固件烧录与启动指导手册》或同仓库烧录说明。
# 7.1 烧录前准备
硬件搭建 :使用 Typec 线将板端与 PC 端连接。
55c4feb3c99d6077ec23c8438c3c15da
安装驱动 :安装「CH341SER 驱动」(CH341SER 驱动下载地址 ,若该链接失效或无法下载,可自行搜索下载)。安装前请将单板与 PC 连接,点击安装即可;显示驱动安装成功 代表成功,若显示驱动预安装成功 则代表安装失败。
下载 BurnTool 烧录工具 :下载并解压 BurnTool。
链接:https://atomgit.com/xiaohong-ai/docs/tree/main/tools
打开烧录工具,选择对应的串口;点开 Option 选项,选择对应目标(WS63E 与 WS63 属于同一系列,选 WS63 即可)。
点击 Select file 选择烧录文件(选择 ws63-liteos-app-all.fwpkg ,该文件位于固件路径 Z:\A_OH60T\out\xiaohong\xiaohong\ws63-liteos-app 下)。
勾选 Auto Burn 和 Auto disconnect 选项。
⚠️ 重要:进入烧录方式因板子批次不同
新板子 :点击 Connect 后直接开始烧录 。
旧板子 :点击 Connect 后,需同时按住两个音量/亮度按键约 1.5 秒后松开 ,再开始烧录。
待全部烧录成功后,显示 All images burn successfully 。
673e3245796e6d6497f3e480b2f9bd25
# 八、串口输出与结果分析
# 8.1 串口连接(查看日志)
准备:
烧录完成后,按以下步骤通过串口查看运行日志:
打开 UartAssist ,协议选择 SERIAL ,端口选择小鸿对应的 COM 口;
设置串口参数:波特率 115200 ,数据位 8,停止位 1,无校验、无流控;
先打开串口连接;
再给板子上电或复位,即可抓取完整启动与 10 STA 实现自动连接 demo 日志。
# 8.2 预期出现的日志(10 STA 实现自动连接 Demo 相关)
当 config_sta_simple_demo = true 且已修改 DEMO_SSID / DEMO_PSWD 为可用热点时,串口应依次出现类似输出:
阶段
日志特征
任务入口
[WiFiTask] run STA simple demo.
等待驱动
[STA_DEMO] wait wifi init... → [STA_DEMO] wifi init ok.
扫描
[STA_DEMO] STA enabled, scan... → [STA_DEMO] scan done.
连接
[STA_DEMO] found AP, connect... → [STA_DEMO] connected. / [STA_DEMO] STA connected.
DHCP
[STA_DEMO] STA connect success. (DHCP OK),随后打印 server_id、mask、gw、clients 及本机 IP(如 192.168.x.x)
若某步失败,会打印对应错误(如 wifi_sta_scan fail、AP "xxx" not found、connect timeout、dhcp_start fail、DHCP timeout),并调用 set_wifi_status(eWifi_St_Disconnected),状态栏保持或恢复为 NC 。
# 8.3 界面表现
连接过程中 :状态栏 WiFi 显示 ## (连接中);
连接并 DHCP 成功 :状态栏变为 OK ,主界面可显示“WiFi 连接成功!”等(与完整应用一致);
任意步骤失败 :状态栏为 NC 。
# 8.4 可调参数(sta_simple_demo.c)
宏
默认值
含义
DEMO_SSID
"my_softAP"(示例,请改为实际热点名)
要连接的 Wi-Fi 名称
DEMO_PSWD
"my_password"(示例,请改为实际密码)
要连接的 Wi-Fi 密码
DEMO_SCAN_WAIT_MS
2000
扫描后等待时间(ms),再取扫描结果
DEMO_CONN_POLL_MS
500
轮询连接状态间隔(ms)
DEMO_CONN_POLL_TIMES
10
轮询连接状态最大次数
DEMO_DHCP_WAIT_MS
500
轮询 DHCP 间隔(ms)
DEMO_DHCP_POLL_TIMES
20
轮询 DHCP 最大次数
DEMO_IFNAME
"wlan0"
STA 网卡名,一般不需改
# 8.5 如何判断“运行成功”
串口波特率 115200 下,在启动日志中能看到上述 [STA_DEMO] 、[WiFiTask] run STA simple demo 等输出,且出现 [STA_DEMO] STA connect success. (DHCP OK) 及本机 IP 信息,状态栏由 NC → ## → OK ,即表示:
小鸿工程已正确编译并烧录;
10 STA 实现自动连接 Demo 已通过 samples/BUILD.gn 的 features 及 config.py / ohos.cmake 纳入编译并打进 ws63-liteos-app 镜像(若采用 config_sta_simple_demo 则 WiFi 任务仅跑本 demo);
WiFi 任务已执行 run_sta_simple_demo(),完成 STA 扫描、连接与 DHCP,界面状态栏已更新为 OK。
# 九、常见问题与排查
现象
建议排查
串口无任何打印
确认 COM 口、TX/RX 接线;是否先打开串口再上电/复位。
有启动日志但无 [STA_DEMO]
确认:(1) vendor/atomgit/xiaohong/BUILD.gn 的 deps 含 "samples:app", ;(2) samples/BUILD.gn 的 features 中含未注释的 "10_sta_demo:sta_demo" ;(3) config.py 的 ram_component 与 ohos.cmake 的 COMPONENT_LIST 中已添加 "sta_demo" 。若采用仅跑 STA 方式,另确认 config.gni 中 config_sta_simple_demo = true 。然后执行清理后重新全量编译并烧录。
一直卡在 wait wifi init...
等待更长时间或检查 Wi-Fi 驱动是否正常初始化。
AP "xxx" not found 或扫描不到热点
确认 DEMO_SSID 与周围 2.4G 热点名称一致,热点已开启且信号可用。
连接超时或 DHCP 失败
检查 DEMO_PSWD 是否正确;适当增大 DEMO_CONN_POLL_TIMES 、DEMO_DHCP_POLL_TIMES 。
乱码
确认波特率为 115200。
# 十、修改文件汇总表
文件路径
操作
要点
xiaohong/src/samples/10_sta_demo/sta_simple_demo.c
新增
10 STA 实现自动连接 Demo:wait init → enable → scan → find AP → connect → DHCP → set_wifi_status(Connected),失败则 set_wifi_status(Disconnected)
xiaohong/src/samples/10_sta_demo/README.md
新增
使用步骤、SSID/密码修改、config 开关、预期串口输出
xiaohong/config.gni
修改
增加 config_sta_simple_demo = false
xiaohong/BUILD.gn
修改
config_sta_simple_demo 为 true 时 defines += STA_SIMPLE_DEMO,sources += sta_simple_demo.c
xiaohong/src/network/net_wifi_task.c
修改
#ifdef STA_SIMPLE_DEMO 时调用 run_sta_simple_demo() 并 return;set_wifi_status 去掉 static
xiaohong/src/network/net_wifi_config.h
修改
声明 set_wifi_status(uint8_t status)
未修改:main.c、板级配置、LVGL 等;WiFi 驱动与 lwIP 由 WS63 SDK / 主工程已链接的库提供。
# 十一、扩展建议
自动重连 :可在 run_sta_simple_demo() 末尾加 while(1) { osal_msleep(60000); ... },或根据 wifi_sta_get_ap_info() 检测断线后再执行一轮扫描+连接,实现断线重连。
多 SSID/密码 :可将 DEMO_SSID/DEMO_PSWD 改为从 NV 或配网接口读取,实现“配网成功后下次上电直连”的完整流程。
与 07_easy_wifi 对比 :07 为完整业务(热点 + 配网 + 连接),10 STA 实现自动连接 Demo 仅做“单次 STA 连接 + 状态栏 OK”,适合快速验证 STA 与界面联动;需要配网流程时仍使用完整应用或 07 相关逻辑。
# 十二、小结
文件放哪里 :STA demo 位于 vendor/atomgit/xiaohong/samples/10_sta_demo/ (含 sta_simple_demo.c、BUILD.gn、README)。若从别处拷贝,请将 10_sta_demo 整目录放到 vendor/atomgit/xiaohong/samples 下。
改哪里能编译并打进镜像 :(1) vendor/atomgit/xiaohong/BUILD.gn 的 deps 须含 "samples:app", ;(2) samples/BUILD.gn 的 features 须含 "10_sta_demo:sta_demo" ;(3) config.py (sdkv106 下)的 ram_component 须含 "sta_demo" ;(4) ohos.cmake (sdkv106 下)的 COMPONENT_LIST 须含 "sta_demo" 。若需仅跑 STA 不跑热点/配网,另设 config.gni 中 config_sta_simple_demo = true 并配合 net_wifi_task.c 修改。
运行效果 :上电后自动连接 DEMO_SSID 对应热点并获取 IP,串口见 [STA_DEMO] ... STA connect success. (DHCP OK) 及 IP 信息;状态栏由 NC → ## → OK 。
编译:先清理,再 hb set (mini + xiaohong),最后 hb build -f 。烧录与 01_timer、08_喇叭控制等 demo 一致;串口波特率 115200 。
文档版本 :与 vendor/atomgit/xiaohong/samples/10_sta_demo/README.md 集成与编译步骤保持一致。
相关目录 :vendor/atomgit/xiaohong/samples/10_sta_demo/。
Was this helpful? 👍 Yes 👎 Needs work
HANDS-ON SAMPLES Xiaohong AI · official docs
12 · Event flags Hands-on samples / 12 · Event flagsi18n · The narrative below is the original Chinese reference (technical content — code, commands and logs are universal). A fully translated English edition is in progress.
View Chinese version → # 一、背景与目标
# 1.1 小鸿与 11_event 是什么
小鸿 是基于 OpenHarmony + 海思 WS63 方案的设备/工程,其代码位于 vendor/atomgit/xiaohong/xiaohong,使用 CMSIS-RTOS2(LiteOS-M 适配)做多任务调度。
11_event (11_event_sample)是小鸿工程内的一个基于 OSAL 事件的生产者-消费者示例 ,演示 OSAL(Operating System Abstraction Layer)事件机制的典型用法。通过 app_run(event_example_entry) 注册运行入口,在入口中初始化事件对象、创建生产者与消费者两个任务:生产者周期产生数据(1~5)并置位“数据就绪”事件,消费者等待该事件后读取共享数据并处理、再清除事件。串口按阶段输出 [EventSample] 前缀日志。将其集成到小鸿上,可以:
验证小鸿工程下 OSAL 事件 API(osal_event_init、osal_event_write、osal_event_read、osal_event_clear)与任务创建(osal_kthread_*)的编译与运行是否正常;
作为“任务间同步与通知”类 demo 的参考,便于后续做传感器就绪通知、驱动完成通知等开发。
# 1.2 本文目标
说明 事件 demo 所在目录与构建方式 (samples/11_event_sample,通过 features 编入);
说明 为能编译并打进镜像需要修改的文件 :vendor 顶层 BUILD.gn、samples/BUILD.gn、config.py、ohos.cmake;
说明运行逻辑与串口预期输出;
给出预期日志与“如何判断成功”的结论。
# 二、环境与前置条件
工程 :OpenHarmony + 小鸿 vendor(vendor/atomgit/xiaohong,含主库与 samples ,事件示例位于 samples/11_event_sample );
SDK :WS63 SDK(通过 ws63_sdk.gni 引用);
工具 :串口调试助手(如 UartAssist、Xshell 等),波特率 115200 ;
硬件 :小鸿开发板,通过 USB 转串口连接 PC,TX/RX/GND 正确连接。
# 三、集成步骤(文件放哪里、改哪里能编译)
事件示例以 samples 形式存在,目录为 vendor/atomgit/xiaohong/samples/11_event_sample ,通过 samples/BUILD.gn 的 features 与板级 config.py / ohos.cmake 参与编译并打进 ws63-liteos-app 镜像。以下步骤须全部完成,缺一不可。
# 3.1 目录与源码位置
本示例已放在小鸿 vendor 包内:
目录 :vendor/atomgit/xiaohong/samples/11_event_sample/ ;
源文件 :event_sample.c ;
构建目标 :本目录下的 static_library("event_sample") ,由 samples/BUILD.gn 以 feature "11_event_sample:event_sample" 形式编入应用。
完整路径为:
vendor/atomgit/xiaohong/
├── BUILD.gn # 顶层 group,依赖 xiaohong 主库与 samples
└── samples/
├── BUILD.gn # lite_component("app"),通过 features 选择示例
└── 11_event_sample/
├── BUILD.gn # static_library("event_sample")
├── event_sample.c # 演示源码
└── README.md # 操作说明
若从别处拷贝示例,请将 11_event_sample 整个目录放到 vendor/atomgit/xiaohong/samples 下。
# 3.2 步骤 1:检查 vendor 顶层 BUILD.gn(编译前必查)
打开 vendor/atomgit/xiaohong/BUILD.gn ,在 group("xiaohong") 的 deps 中确认包含 "samples:app", 。若缺少该项,samples 下的示例不会参与整包编译。
group("xiaohong") {
deps = [
"xiaohong:xiaohong",
"samples:app",
]
}
# 3.3 步骤 2:在 samples/BUILD.gn 中启用事件示例
修改 vendor/atomgit/xiaohong/samples/BUILD.gn ,在 lite_component("app") 的 features 列表中保留或添加 "11_event_sample:event_sample" (未注释):
lite_component("app") {
features = [
"11_event_sample:event_sample",
# 其他示例按需取消注释
]
}
说明 :以 # 开头的行为注释,不会参与编译 ;需要编进固件的示例须为未注释的一行。
# 3.4 步骤 3:在 config.py 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/build/config/target_config/ws63/config.py 中,找到 'ws63-liteos-app' 配置,在其 'ram_component' 列表中添加 "event_sample" :
说明 :ram_component 声明参与 ws63-liteos-app 镜像链接的组件;未在此列出的 static_library 不会被打进最终 app 镜像。
# 3.5 步骤 4:在 ohos.cmake 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/libs_url/ws63/cmake/ohos.cmake 中,找到 elseif(${TARGET_COMMAND} MATCHES "ws63-liteos-app") 对应的 set(COMPONENT_LIST ...) ,在列表中添加 "event_sample" :
说明 :COMPONENT_LIST 决定参与构建与安装的组件(静态库),需与 步骤 3 的 ram_component 及 samples 内 BUILD.gn 的 target 名称一致。
# 3.6 代码说明
本小节说明 event_sample.c 的编写思路与关键实现。示例使用事件(Event) 做任务间“数据就绪”通知:生产者任务 周期性写共享变量 g_data(1~5),并调用 osal_event_write(&g_event, DATA_READY_EVENT) 置位事件;消费者任务 调用 osal_event_read(..., OSAL_WAIT_FOREVER, ...) 阻塞等待事件,返回后读取 g_data 并处理,再调用 osal_event_clear 清除事件位。入口 event_example_entry 通过 app_run(event_example_entry) 注册,在系统启动时被调用,内部完成 osal_event_init、osal_kthread_lock、创建生产者/消费者任务并设置优先级、osal_kthread_unlock,并打印 [EventSample] event init ok、all tasks created and running。核心 API:osal_event_init、osal_event_write、osal_event_read、osal_event_clear;osal_kthread_create、osal_kthread_set_priority。与 01_timer、02_delay 等 demo 采用同一套串口打印方式([EventSample] 前缀),无需额外适配。
# 四、运行逻辑简述
系统启动后,框架调用通过 app_run(event_example_entry) 注册的 event_example_entry ;
event_example_entry 内:初始化 g_event,锁调度,创建生产者任务与消费者任务并设置优先级(如 24/25),解锁,两任务开始参与调度;
生产者任务 :循环 5 次,每次写 g_data = count+1 → osal_event_write(DATA_READY_EVENT) → osal_msleep(1000) ;
消费者任务 :循环 5 次,每次 osal_event_read(..., OSAL_WAIT_FOREVER, ...) 阻塞直到事件置位,返回后打印并处理 g_data,再 osal_event_clear(DATA_READY_EVENT) ;
串口上会看到多行带 [EventSample] 前缀的日志(event init ok、all tasks created、producer/consumer 交替的 data 1~5 与 data_ready event sent / got data_ready / process data),便于确认事件与任务协作正常。
# 五、编译
在 OpenHarmony 工程根目录下依次 执行:1. 清理 rm -fr out/xiaohong/xiaohong/ .ccache/*;2. 选择产品 hb set(按提示选择 mini 、xiaohong );3. 全量编译 hb build -f。编译成功后,固件生成路径为 out/xiaohong/xiaohong/ws63-liteos-app (Windows 下如 Z:\A_OH60T\out\...)。
# 六、烧录
以下内容与 HelloWorld、01_timer、02_delay、03_mutex、04_semaphore、05_message、06_spi、08_喇叭控制、09_PWM、10_STA 等 demo 通用,参见《小鸿AI 固件烧录与启动指导手册》或同仓库烧录说明。
# 6.1 烧录前准备
硬件搭建 :使用 Typec 线将板端与 PC 端连接。
55c4feb3c99d6077ec23c8438c3c15da
安装驱动 :安装「CH341SER 驱动」(CH341SER 驱动下载地址 ,若该链接失效或无法下载,可自行搜索下载)。安装前请将单板与 PC 连接,点击安装即可;显示驱动安装成功 代表成功,若显示驱动预安装成功 则代表安装失败。
下载 BurnTool 烧录工具 :下载并解压 BurnTool。
链接:https://atomgit.com/xiaohong-ai/docs/tree/main/tools
打开烧录工具,选择对应的串口;点开 Option 选项,选择对应目标(WS63E 与 WS63 属于同一系列,选 WS63 即可)。
点击 Select file 选择烧录文件(选择 ws63-liteos-app-all.fwpkg ,该文件位于固件路径 Z:\A_OH60T\out\xiaohong\xiaohong\ws63-liteos-app 下)。
勾选 Auto Burn 和 Auto disconnect 选项。
⚠️ 重要:进入烧录方式因板子批次不同
新板子 :点击 Connect 后直接开始烧录 。
旧板子 :点击 Connect 后,需同时按住两个音量/亮度按键约 1.5 秒后松开 ,再开始烧录。
待全部烧录成功后,显示 All images burn successfully 。
673e3245796e6d6497f3e480b2f9bd25
# 七、串口输出与结果分析
# 7.1 串口连接(查看日志)
准备:
烧录完成后,按以下步骤通过串口查看运行日志:
打开 UartAssist ,协议选择 SERIAL ,端口选择小鸿对应的 COM 口;
设置串口参数:波特率 115200 ,数据位 8,停止位 1,无校验、无流控;
先打开串口连接;
再给板子上电或复位,即可抓取完整启动与 11_event 日志。
# 7.2 预期出现的日志(11_event 相关)
阶段
日志特征
事件初始化与任务创建
[EventSample] event init ok、[EventSample] all tasks created and running
生产者启动
[EventSample] producer task start
消费者启动
[EventSample] consumer task start、[EventSample] consumer: wait data_ready...
生产者发数据
[EventSample] producer: data 1~data 5、[EventSample] producer: data_ready event sent(每轮一次)
消费者收事件并处理
[EventSample] consumer: got data_ready、[EventSample] consumer: process data 1~process data 5(与生产者交替出现)
顺序可能因调度略有交错,但应能看到“事件初始化 → 任务创建 → 生产者发 1~5 → 消费者等事件并处理 1~5”的完整闭环。
# 7.3 实际运行日志(节选)
[EventSample] event init ok
[EventSample] all tasks created and running
[EventSample] producer task start
[EventSample] producer: data 1
[EventSample] producer: data_ready event sent
[EventSample] consumer task start
[EventSample] consumer: wait data_ready...
[EventSample] consumer: got data_ready
[EventSample] consumer: process data 1
[EventSample] consumer: wait data_ready...
[EventSample] producer: data 2
[EventSample] producer: data_ready event sent
[EventSample] consumer: got data_ready
[EventSample] consumer: process data 2
...
[EventSample] producer: data 5
[EventSample] producer: data_ready event sent
[EventSample] consumer: got data_ready
[EventSample] consumer: process data 5
# 7.4 如何判断“运行成功”
串口波特率 115200 下,在启动日志中能看到上述 [EventSample] 系列输出,且出现 event init ok 、all tasks created and running 以及生产者 data 1~5 、data_ready event sent 与消费者 got data_ready 、process data 1~5 的交替序列,即表示:
小鸿工程已正确编译并烧录;
11_event demo 已通过 samples/BUILD.gn 的 features 及 config.py / ohos.cmake 纳入编译并打进 ws63-liteos-app 镜像;
系统启动时已执行 event_example_entry,完成事件初始化与双任务创建,生产者与消费者通过事件与共享变量协作正常。
# 八、常见问题与排查
现象
建议排查
串口无任何打印
确认 COM 口、TX/RX 接线;是否先打开串口再上电/复位。
有启动日志但无 [EventSample]
确认:(1) vendor/atomgit/xiaohong/BUILD.gn 的 deps 含 "samples:app", ;(2) samples/BUILD.gn 的 features 中含未注释的 "11_event_sample:event_sample" ;(3) config.py 的 ram_component 与 ohos.cmake 的 COMPONENT_LIST 中已添加 "event_sample" 。然后执行清理后重新全量编译并烧录。
乱码
确认波特率为 115200;建议终端编码设为 UTF-8,或保持示例中的英文日志。
编译报错找不到 app_init.h
在 BUILD.gn 的 include_dirs 中增加 "${ws63_sdk_path}/middleware/utils/app_init" (或工程实际路径)。
只有 producer 或只有 consumer 日志
多为调度或优先级导致一方未及时运行,可稍等或复位再观察;若仍无,检查是否烧录为最新固件。
# 九、小结
文件放哪里 :事件 demo 位于 vendor/atomgit/xiaohong/samples/11_event_sample/ (含 event_sample.c、BUILD.gn、README)。若从别处拷贝,请将 11_event_sample 整目录放到 vendor/atomgit/xiaohong/samples 下。
改哪里能编译并打进镜像 :(1) vendor/atomgit/xiaohong/BUILD.gn 的 deps 须含 "samples:app", ;(2) samples/BUILD.gn 的 features 须含 "11_event_sample:event_sample" ;(3) config.py (sdkv106 下)的 ram_component 须含 "event_sample" ;(4) ohos.cmake (sdkv106 下)的 COMPONENT_LIST 须含 "event_sample" 。
编译:先清理,再 hb set (mini + xiaohong),最后 hb build -f 。烧录后以 115200 波特率连接串口,看到完整 [EventSample] 日志即可判定 11_event(事件)demo 在小鸿上运行成功。
文档版本 :与 vendor/atomgit/xiaohong/samples/11_event_sample/README.md 集成与编译步骤保持一致。
相关目录 :vendor/atomgit/xiaohong/samples/11_event_sample/。
Was this helpful? 👍 Yes 👎 Needs work
HANDS-ON SAMPLES Xiaohong AI · official docs
13 · Two-task sync semaphore Hands-on samples / 13 · Two-task sync semaphorei18n · The narrative below is the original Chinese reference (technical content — code, commands and logs are universal). A fully translated English edition is in progress.
View Chinese version → # 一、背景与目标
# 1.1 小鸿与 12_sync_semaphore 是什么
小鸿 是基于 OpenHarmony + 海思 WS63 方案的设备/工程,其代码位于 vendor/atomgit/xiaohong/xiaohong,使用 CMSIS-RTOS2(LiteOS-M 适配)做多任务调度。
12_sync_semaphore 是小鸿工程内的一个基于 CMSIS-RTOS2 信号量的双任务同步示例 ,演示二值信号量在“单生产者-单消费者”场景下的用法。通过 app_run(kernel_sync_semaphore_example) 注册运行入口,在入口中创建二值信号量(最大计数值 1、初始 0)及 Task1(消费者)、Task2(生产者):Task2 周期性释放信号量并打印,Task1 阻塞等待并获取信号量后打印并延时。串口上会看到交替的 “Release =====>” 与 “Acquire <=====” 输出。将其集成到小鸿上,可以:
验证小鸿工程下 CMSIS-RTOS2 信号量 API(osSemaphoreNew、osSemaphoreAcquire、osSemaphoreRelease)与 app_run 入口的编译与运行是否正常;
作为“任务间信号量同步”类 demo 的参考,与 04_semaphore(多生产者多消费者)、11_event(OSAL 事件)形成互补。
# 1.2 本文目标
说明 双任务信号量同步 demo 所在目录与构建方式 (samples/12_sync_semaphore,通过 features 编入);
说明 为能编译并打进镜像需要修改的文件 :vendor 顶层 BUILD.gn、samples/BUILD.gn、config.py、ohos.cmake;
说明运行逻辑与串口预期输出;
给出如何判断运行成功的结论。
# 二、环境与前置条件
工程 :OpenHarmony + 小鸿 vendor(vendor/atomgit/xiaohong,含主库与 samples ,双任务信号量同步示例位于 samples/12_sync_semaphore );
SDK :WS63 SDK(通过 ws63_sdk.gni 引用);
工具 :串口调试助手(如 UartAssist、Xshell 等),波特率 115200 ;
硬件 :小鸿开发板,通过 USB 转串口连接 PC,TX/RX/GND 正确连接。
# 三、集成步骤(文件放哪里、改哪里能编译)
双任务信号量同步示例以 samples 形式存在,目录为 vendor/atomgit/xiaohong/samples/12_sync_semaphore ,通过 samples/BUILD.gn 的 features 与板级 config.py / ohos.cmake 参与编译并打进 ws63-liteos-app 镜像。以下步骤须全部完成,缺一不可。
# 3.1 目录与源码位置
本示例已放在小鸿 vendor 包内:
目录 :vendor/atomgit/xiaohong/samples/12_sync_semaphore/ ;
源文件 :sync_semaphore.c ;
构建目标 :本目录下的 static_library("sync_semaphore") ,由 samples/BUILD.gn 以 feature "12_sync_semaphore:sync_semaphore" 形式编入应用。
完整路径为:
vendor/atomgit/xiaohong/
├── BUILD.gn # 顶层 group,依赖 xiaohong 主库与 samples
└── samples/
├── BUILD.gn # lite_component("app"),通过 features 选择示例
└── 12_sync_semaphore/
├── BUILD.gn # static_library("sync_semaphore")
├── sync_semaphore.c # 演示源码
└── README.md # 操作说明
若从别处拷贝示例,请将 12_sync_semaphore 整个目录放到 vendor/atomgit/xiaohong/samples 下。
# 3.2 步骤 1:检查 vendor 顶层 BUILD.gn(编译前必查)
打开 vendor/atomgit/xiaohong/BUILD.gn ,在 group("xiaohong") 的 deps 中确认包含 "samples:app", 。若缺少该项,samples 下的示例不会参与整包编译。
group("xiaohong") {
deps = [
"xiaohong:xiaohong",
"samples:app",
]
}
# 3.3 步骤 2:在 samples/BUILD.gn 中启用双任务信号量示例
修改 vendor/atomgit/xiaohong/samples/BUILD.gn ,在 lite_component("app") 的 features 列表中保留或添加 "12_sync_semaphore:sync_semaphore" (未注释):
lite_component("app") {
features = [
"12_sync_semaphore:sync_semaphore",
# 其他示例按需取消注释
]
}
说明 :以 # 开头的行为注释,不会参与编译 ;需要编进固件的示例须为未注释的一行。
# 3.4 步骤 3:在 config.py 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/build/config/target_config/ws63/config.py 中,找到 'ws63-liteos-app' 配置,在其 'ram_component' 列表中添加 "sync_semaphore" :
说明 :ram_component 声明参与 ws63-liteos-app 镜像链接的组件;未在此列出的 static_library 不会被打进最终 app 镜像。
# 3.5 步骤 4:在 ohos.cmake 中登记组件
在 device/soc/hisilicon/ws63v100/sdkv106/libs_url/ws63/cmake/ohos.cmake 中,找到 elseif(${TARGET_COMMAND} MATCHES "ws63-liteos-app") 对应的 set(COMPONENT_LIST ...) ,在列表中添加 "sync_semaphore" :
说明 :COMPONENT_LIST 决定参与构建与安装的组件(静态库),需与 步骤 3 的 ram_component 及 samples 内 BUILD.gn 的 target 名称一致。
# 3.6 代码说明(无需再改)
当前 sync_semaphore.c 主要逻辑:
Task1(消费者) :循环内 osSemaphoreAcquire(Semaphore_ID, osWaitForever) 阻塞等待 → 获取成功后打印 "Task 1 osSemaphore Acquire <=====" → osDelay(100)。
Task2(生产者) :循环内 osSemaphoreRelease(Semaphore_ID) → 打印 "Task 2 osSemaphore Release =====>" → osDelay(200)。
入口 kernel_sync_semaphore_example():osSemaphoreNew(1, 0, NULL) 创建二值信号量(最大 1、初始 0)→ 配置线程属性(栈 0x2000、普通优先级)→ osThreadNew 创建 Task1、Task2 → 打印各对象创建成功信息。
注册 :通过 app_run(kernel_sync_semaphore_example) 将上述入口注册为“运行阶段”初始化,系统启动时会在合适时机调用,无需在 main 里显式调用。
与 04_semaphore 使用同一套 CMSIS-RTOS2 信号量 API,但 04_semaphore 使用 APP_FEATURE_INIT + ohos_init.h,本示例使用 app_run + app_init.h ,与 11_event_sample 的注册方式一致。核心 API 对应关系如下:
API
作用
osSemaphoreNew(max_count, initial_count, attr)
创建信号量。本示例 (1, 0, NULL):最大 1、初始 0,即二值且初始无资源。
osSemaphoreAcquire(sem_id, timeout)
获取信号量,计数值减一;osWaitForever 表示永久等待直到可用。
osSemaphoreRelease(sem_id)
释放信号量,计数值加一,可唤醒正在等待的线程。
# 四、运行逻辑简述
系统启动后,框架调用所有通过 app_run 注册的入口,其中包含 kernel_sync_semaphore_example ;
kernel_sync_semaphore_example 内:
1. osSemaphoreNew(1, 0, NULL) 创建信号量(二值、初始 0);
2. 配置线程属性(栈 0x2000、普通优先级),osThreadNew 创建 Task1、Task2,两任务开始参与调度;
3. Task1 首次进入循环即 osSemaphoreAcquire ,因初始计数值为 0 而阻塞;
4. Task2 循环内先 osSemaphoreRelease ,使信号量变为 1,唤醒 Task1,打印 "Release =====>",再 osDelay(200) ;
5. Task1 被唤醒后打印 "Acquire <=====",再 osDelay(100) ,然后再次进入循环并阻塞;如此反复,串口上看到交替的 Release / Acquire 输出。
先有 Release,后有 Acquire 被满足,二者通过二值信号量形成稳定的“释放-获取”同步关系。
# 五、编译
在 OpenHarmony 工程根目录下依次 执行:1. 清理 rm -fr out/xiaohong/xiaohong/ .ccache/*;2. 选择产品 hb set(按提示选择 mini 、xiaohong );3. 全量编译 hb build -f。编译成功后,固件生成路径为 out/xiaohong/xiaohong/ws63-liteos-app (Windows 下如 Z:\A_OH60T\out\...)。
# 六、烧录
以下内容与 HelloWorld、01_timer、02_delay、03_mutex、04_semaphore 等 demo 通用,参见《小鸿AI 固件烧录与启动指导手册》或同仓库烧录说明。
# 6.1 烧录前准备
硬件搭建 :使用 Typec 线将板端与 PC 端连接。
55c4feb3c99d6077ec23c8438c3c15da
安装驱动 :安装「CH341SER 驱动」(CH341SER 驱动下载地址 ,若该链接失效或无法下载,可自行搜索下载)。安装前请将单板与 PC 连接,点击安装即可;显示驱动安装成功 代表成功,若显示驱动预安装成功 则代表安装失败。
下载 BurnTool 烧录工具 :下载并解压 BurnTool。
链接:https://atomgit.com/xiaohong-ai/docs/tree/main/tools
打开烧录工具,选择对应的串口;点开 Option 选项,选择对应目标(WS63E 与 WS63 属于同一系列,选 WS63 即可)。
点击 Select file 选择烧录文件(选择 ws63-liteos-app-all.fwpkg ,该文件位于固件路径 Z:\A_OH60T\out\xiaohong\xiaohong\ws63-liteos-app 下)。
勾选 Auto Burn 和 Auto disconnect 选项。
⚠️ 重要:进入烧录方式因板子批次不同
新板子 :点击 Connect 后直接开始烧录 。
旧板子 :点击 Connect 后,需同时按住两个音量/亮度按键约 1.5 秒后松开 ,再开始烧录。
待全部烧录成功后,显示 All images burn successfully 。
673e3245796e6d6497f3e480b2f9bd25
# 七、串口输出与结果分析
# 7.1 串口连接(查看日志)
准备:
烧录完成后,按以下步骤通过串口查看运行日志:
打开 UartAssist ,协议选择 SERIAL ,端口选择小鸿对应的 COM 口;
设置串口参数:波特率 115200 ,数据位 8,停止位 1,无校验、无流控;
先打开串口连接;
再给板子上电或复位,即可抓取完整启动与 12_sync_semaphore 日志。
在串口工具页面查看打印日志
b8478a9d-202a-485a-b99e-24145742d5d0
# 7.2 预期出现的日志(12_sync_semaphore 相关)
阶段
日志特征
信号量创建
ID = xxx, Create Semaphore_ID is OK!
任务创建
ID = xxx, Create Task1_ID is OK!、ID = xxx, Create Task2_ID is OK!
生产者释放
多行 Task 2 osSemaphore Release =====>
消费者获取
多行 Task 1 osSemaphore Acquire <=====
Release 与 Acquire 交替出现,顺序可能因调度略有交错,属正常现象。
# 7.3 实际运行日志(节选)
ID = xxx, Create Semaphore_ID is OK!
ID = xxx, Create Task1_ID is OK!
ID = xxx, Create Task2_ID is OK!
Task 2 osSemaphore Release =====>
Task 1 osSemaphore Acquire <=====
Task 2 osSemaphore Release =====>
Task 1 osSemaphore Acquire <=====
Task 2 osSemaphore Release =====>
Task 1 osSemaphore Acquire <=====
...
# 7.4 如何判断“运行成功”
串口波特率 115200 下,在启动日志中能看到上述信号量创建成功 → 两个任务创建成功 → 持续交替的 Release / Acquire 输出,即表示:
小鸿工程已正确编译并烧录;
12_sync_semaphore demo 已通过 samples/BUILD.gn 的 features 及 config.py / ohos.cmake 纳入编译并打进 ws63-liteos-app 镜像;
系统启动时已执行 kernel_sync_semaphore_example,双任务信号量同步运行正常。
# 八、常见问题与排查
现象
建议排查
串口无任何打印
确认 COM 口、TX/RX 接线;是否先打开串口再上电/复位。
有启动日志但无 12_sync_semaphore 相关输出
确认:(1) vendor/atomgit/xiaohong/BUILD.gn 的 deps 含 "samples:app", ;(2) samples/BUILD.gn 的 features 中含未注释的 "12_sync_semaphore:sync_semaphore" ;(3) config.py 的 ram_component 与 ohos.cmake 的 COMPONENT_LIST 中已添加 "sync_semaphore" 。然后执行清理后重新全量编译并烧录。
编译报错 app_init.h: No such file or directory
在 BUILD.gn 的 include_dirs 中增加 "${ws63_sdk_path}/middleware/utils/app_init" 。
乱码
确认波特率为 115200。
# 九、小结
文件放哪里 :双任务信号量同步 demo 位于 vendor/atomgit/xiaohong/samples/12_sync_semaphore/ (含 sync_semaphore.c、BUILD.gn、README)。若从别处拷贝,请将 12_sync_semaphore 整目录放到 vendor/atomgit/xiaohong/samples 下。
改哪里能编译并打进镜像 :(1) vendor/atomgit/xiaohong/BUILD.gn 的 deps 须含 "samples:app", ;(2) samples/BUILD.gn 的 features 须含 "12_sync_semaphore:sync_semaphore" ;(3) config.py (sdkv106 下)的 ram_component 须含 "sync_semaphore" ;(4) ohos.cmake (sdkv106 下)的 COMPONENT_LIST 须含 "sync_semaphore" 。
编译:先清理,再 hb set (mini + xiaohong),最后 hb build -f 。烧录后以 115200 波特率连接串口,看到信号量与两任务创建成功、持续交替的 Release/Acquire 输出即可判定 12_sync_semaphore(双任务信号量同步)demo 在小鸿上运行成功。
文档版本 :与 vendor/atomgit/xiaohong/samples/12_sync_semaphore/README.md 集成与编译步骤保持一致。
相关目录 :vendor/atomgit/xiaohong/samples/12_sync_semaphore/。
Was this helpful? 👍 Yes 👎 Needs work
HANDS-ON SAMPLES Xiaohong AI · official docs
14 · SLE UART tunnel Hands-on samples / 14 · SLE UART tunneli18n · The narrative below is the original Chinese reference (technical content — code, commands and logs are universal). A fully translated English edition is in progress.
View Chinese version → # 一、案例简介
本案例演示如何使用小鸿开发板实现基于SLE(星闪低功耗)协议的UART透传通信。通过两个小鸿开发板,一个作为Server端,一个作为Client端,实现双向数据透明传输。
# 功能特点
自动连接 :Server端启动后自动广播,Client端启动后自动搜索并连接
握手确认 :连接建立后自动进行握手确认,确保通信链路正常
双向透传 :握手完成后,UART数据双向透明传输
低功耗 :基于SLE协议,适合低功耗物联网场景
# 通信流程
Server端启动 → 开始广播
↓
Client端启动 → 搜索并连接Server
↓
配对完成
↓
Server发送 "Hello Client"
↓
Client收到并回复 "Hello Server"
↓
握手完成,启用UART透传
↓
双向数据透明传输
# 二、环境准备
# 2.1 硬件准备
设备
数量
说明
小鸿开发板
2块
一块作为Server,一块作为Client
USB转串口线
2根
用于烧录和串口调试
串口调试工具
1个
如UartAssist、SecureCRT等
# 2.2 软件准备
OpenHarmony开发环境
Python 3.7+
hb 编译工具
# 三、代码获取
将代码克隆到 vendor/atomgit/xiaohong 目录:
cd vendor/atomgit/xiaohong
git clone <repository_url>
# 四、编译配置
# 4.1 配置 BUILD.gn
编辑 vendor/atomgit/xiaohong/samples/BUILD.gn 文件:
编译 Server 镜像:
group("samples") {
deps = [
# ... 其他案例 ...
"13_sle_uart:sle_uart_server", # 开启此项
# "13_sle_uart:sle_uart_client", # 注释此项
]
}
编译 Client 镜像:
group("samples") {
deps = [
# ... 其他案例 ...
# "13_sle_uart:sle_uart_server", # 注释此项
"13_sle_uart:sle_uart_client", # 开启此项
]
}
# 4.2 配置 config.py
编辑 device/soc/hisilicon/ws63v100/sdkv106/build/config/target_config/ws63/config.py 文件:
Server 端配置:
'ram_component': [
# ... 其他组件 ...
"lvgl",
"xiaohong",
"sle_uart_server", # 配置为 sle_uart_server
],
Client 端配置:
'ram_component': [
# ... 其他组件 ...
"lvgl",
"xiaohong",
"sle_uart_client", # 配置为 sle_uart_client
],
# 4.3 配置 ohos.cmake
编辑 device/soc/hisilicon/ws63v100/sdkv106/libs_url/ws63/cmake/ohos.cmake 文件:
Server 端配置:
set(COMPONENT_LIST
# ... 其他组件 ...
"xiaohong"
"sle_uart_server" # 配置为 sle_uart_server
)
Client 端配置:
set(COMPONENT_LIST
# ... 其他组件 ...
"xiaohong"
"sle_uart_client" # 配置为 sle_uart_client
)
# 五、编译镜像
# 5.1 编译 Server 镜像
按照上述配置完成后,执行编译:
编译成功后,镜像文件位于:
out/xiaohong/xiaohong/Hi3861_wifiiot_app_allinone.bin
将此镜像保存为 sle_uart_server.bin。
# 5.2 编译 Client 镜像
修改配置后,重新编译:
将生成的镜像保存为 sle_uart_client.bin。
# 六、烧录镜像
# 6.1 烧录 Server 端
连接第一块小鸿开发板到电脑
使用烧录工具烧录 sle_uart_server.bin
烧录完成后,断开连接
# 6.2 烧录 Client 端
连接第二块小鸿开发板到电脑
使用烧录工具烧录 sle_uart_client.bin
烧录完成后,断开连接
# 七、运行测试
# 7.1 连接串口
使用串口调试工具连接两个开发板:
开发板
串口参数
Server端
波特率: 115200, 数据位: 8, 停止位: 1, 无校验
Client端
波特率: 115200, 数据位: 8, 停止位: 1, 无校验
# 7.2 启动顺序
重要:必须先启动Server端,再启动Client端!
启动 Server 端
- 给 Server 端开发板上电
- 观察串口输出,等待广播启动
启动 Client 端
- 给 Client 端开发板上电
- Client 会自动搜索并连接 Server
# 7.3 观察握手过程
Server 端日志:
[sle uart server] sle adv enable result:0
[sle uart server] pair complete conn_id:xx, status:0
[sle uart server] sending handshake: Hello Client
[sle uart server] received data: Hello Server
[sle uart server] handshake completed! UART data transfer enabled.
Client 端日志:
[sle uart client] sle connect complete
[sle uart client] received data: Hello Client
[sle uart client] received handshake from server, replying...
[sle uart client] handshake completed! UART data transfer enabled.
# 7.4 数据透传测试
握手完成后,可以进行双向数据透传测试:
Server → Client:
1. 在 Server 端串口发送数据(如 "Hello Server")
2. Client 端串口会收到相同的数据
Client → Server:
1. 在 Client 端串口发送数据(如 "Hello Client")
2. Server 端串口会收到相同的数据
# 八、代码结构
vendor/atomgit/xiaohong/samples/13_sle_uart/
├── BUILD.gn # 主构建文件
├── sle_uart.c # 主程序入口,包含握手逻辑
├── sle_uart_server/ # Server 端实现
│ ├── BUILD.gn
│ ├── sle_uart_server.c # Server 端 SLE 服务实现
│ ├── sle_uart_server.h
│ └── sle_uart_server_adv.c # Server 端广播实现
└── sle_uart_client/ # Client 端实现
├── BUILD.gn
├── sle_uart_client.c # Client 端 SLE 客户端实现
└── sle_uart_client.h
# 九、关键代码说明
# 9.1 握手消息定义
#define SLE_HANDSHAKE_SERVER_MSG "Hello Client"
#define SLE_HANDSHAKE_CLIENT_MSG "Hello Server"
# 9.2 握手完成标志
static uint8_t g_handshake_completed = 0;
# 9.3 Server 端握手发送
配对完成后,Server 端发送握手消息:
static void sle_uart_server_send_handshake(void)
{
errcode_t ret = sle_uart_server_send_report_by_handle(
(const uint8_t *)SLE_HANDSHAKE_SERVER_MSG,
strlen(SLE_HANDSHAKE_SERVER_MSG));
}
# 9.4 Client 端握手响应
Client 端收到握手消息后回复:
void sle_uart_notification_cb(...)
{
if (strstr((const char *)data->data, SLE_HANDSHAKE_SERVER_MSG) != NULL) {
// 发送握手响应
ssapc_write_req(0, g_sle_uart_conn_id, sle_uart_send_param);
g_handshake_completed = 1;
}
}
# 9.5 UART 数据处理
只有在握手完成后才处理 UART 数据:
static void sle_uart_server_read_int_handler(const void *buffer, uint16_t length, bool error)
{
if (g_handshake_completed == 0) {
return; // 握手未完成,忽略数据
}
// 发送数据到对端
sle_uart_server_send_report_by_handle(buffer, length);
}
# 十、常见问题
# Q1: Client 无法连接 Server?
解决方案:
1. 确保先启动 Server,再启动 Client
2. 检查两个开发板距离是否过远(建议 1 米以内)
3. 确认 Server 端已正常启动广播
# Q2: 握手失败?
解决方案:
1. 查看串口日志,确认配对是否成功
2. 检查 SLE 连接状态
3. 尝试重新上电两个设备
# Q3: 数据无法透传?
解决方案:
1. 确认握手是否完成(查看日志)
2. 检查 UART 配置是否正确(波特率 115200)
3. 确认发送的数据格式正确
# Q4: 编译失败?
解决方案:
1. 检查三个配置文件是否都已正确修改
2. 确认 BUILD.gn 中只开启了一个目标(server 或 client)
3. 清除编译缓存后重新编译:rm -rf out && hb build -f
# 十一、总结
本案例完整演示了基于 SLE 协议的 UART 透传通信实现,包括:
自动连接机制 :Server 广播,Client 自动搜索连接
握手确认机制 :确保通信链路可靠建立
双向透传机制 :握手完成后实现数据双向透明传输
通过本案例,开发者可以学习到:
- SLE 协议的基本使用方法
- Server/Client 架构的设计模式
- 握手确认机制的实现方式
- UART 与 SLE 的数据透传实现
# 十二、参考资料
Was this helpful? 👍 Yes 👎 Needs work
FAQ Xiaohong AI · official docs
FAQ 01 · Image / sync FAQ / FAQ 01 · Image / synci18n · The narrative below is the original Chinese reference (technical content — code, commands and logs are universal). A fully translated English edition is in progress.
View Chinese version → # 拉镜像出现以下问题
usr/bin/repo:681: Deprecationarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a futurersion. Use timezone-aware objects to represent datetimes in UTc: datetime. datetime.now(datetime. UTC).now = datetime.datetime.utcnow()
Downloading Repo source from https://gerrit.googlesource.com/git-repo
Cloning git repository https://gerrit.googlesource.com/git-repo
fatal: Cannotget https://gerrit.googlesource.com/git-repo/clone.bundle
fatal: error [Error 110] Connection timed out
fatal: double check your --repo-rev setting.
fatal: cloning the git-repo repository failed, will remove '.repo/repo'
解决方法需要在环境变量中加入国内repo镜像地址:export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo'。
Was this helpful? 👍 Yes 👎 Needs work
FAQ Xiaohong AI · official docs
FAQ 02 · Build i18n · The narrative below is the original Chinese reference (technical content — code, commands and logs are universal). A fully translated English edition is in progress.
View Chinese version → # ccache: error: Could not find compiler "riscv32-linux-musl-gcc" in PATH
该问题是在编译过程中在环境变量中未找到riscv32-linux-musl-gcc工具链,需要将~/xiaohong/device/soc/hisilicon/ws63v100/sdkv106/tools/bin/compiler/riscv/cc_riscv32_musl_105/cc_riscv32_musl/bin路径添加到环境变量PATH中。
vim ~/.bashrc
# 在最后一行添加
export PATH=~/xiaohong/device/soc/hisilicon/ws63v100/sdkv106/tools/bin/compiler/riscv/cc_riscv32_musl_105/cc_riscv32_musl/bin:$PATH
# 生效
source ~/.bashrc
Was this helpful? 👍 Yes 👎 Needs work