RISC-V生态开发套件解析(七):LicheeRV 86开发板快速开始Waft应用

简介: 随着RISC-V生态的蓬勃发展,相关开源开发套件也开始逐渐丰富。为了帮助开发者快速了解、玩转新推出的RISC-V开发套件,OCC推出RISC-V生态开发套件解析系列内容,详细讲解生态开发套件的功能特点与上手教程。

编辑语:

随着RISC-V生态的蓬勃发展,相关开源开发套件也开始逐渐丰富。为了帮助开发者快速了解、玩转新推出的RISC-V开发套件,OCC推出RISC-V生态开发套件解析系列内容,详细讲解生态开发套件的功能特点与上手教程。


通过上期内容的介绍,许多开发者已经初步了解了Waft应用的开发,并完成了Waft运行环境的搭建。本期内容旨在加深大家对Waft应用开发的了解,我们将通过拆解Waft应用的开发步骤,手把手教大家创建一个Waft应用。


01 开发环境支持


MacOS,Linux(Windows支持wsl、linux虚拟机)


02 waft开发流程


图片.png


03 安装waft-cli 工具


PS: 权限问题使用sudo执行即可


npm i waft-cli -g


使用 Windows 的开发者,可以安装官方推荐的wsl,推荐安装Linux虚拟机-Ubuntu(18.04、20.04), Linux 的发行版本推荐安装 Ubuntu(18.04、 20.04), 可在微软商店中下载。之后可在对应的 Linux 环境中执行开发所需命令。


wal网址:

https://docs.microsoft.com/en-us/windows/wsl/install?spm=a2cl5.25411629.0.0.2c5a180fdX4SIu



Ubuntu网址:https://www.microsoft.com/zh-cn/p/ubuntu-2004-lts/9n6svws3rx71?spm=a2cl5.25411629.0.0.2c5a180fdX4SIu&rtc=1#activetab=pivot:overviewtab


04 创建项目


通过waft脚手架初始化项目,会引导您进行项目命名等,您将得到一个新project


需要Node 14版本以上


waft init


图片.png

image.gif


这里我们选择第9个模板,平头哥天气Demo


05 启动调试服务


cd my-waft-project
npm run start


REPL命令行模式

启动后自动开启REPL模式,您可以通过.help查询支持哪些命令列表。


打包


waft>.build --aot=true --aotTarget=riscv64


编译后的产物在工程目录的build目录下,产物名称为app.aot,示例视频如下。

图片.png


文件夹及目录说明:


图片.png


06 推送


方式1(adb push):

电脑与开发板用type-c数据线连接,注意使用adb push通道,参考下图标注

image.gif图片.png


adb push build/app.aot /mnt/UDISK/wasm/


方式2(scp):

pc及开发板需要在同一个局域网内。


scp build/app.aot root@172.16.1.36:/mnt/UDISK/wasm


172.16.1.36替换为开发板的ip地址,ssh的登陆密码为:tina。


07 运行waft


通过adb shell或者串口接入开发板,在adb shell终端或者串口工具终端输入如下命令:


waft_app /mnt/UDISK/wasm/app.aot


示例运行界面:


image.gif图片.png


模拟器调试

当前只支持Mac模拟器    部分API不支持


点击面板中的启动模拟器,初次会自动下载模拟器(时间较长,需要等待一会)。


完整可以参考此文档:

https://www.yuque.com/waft/docs/dywumg_wk97d5?spm=a2cl5.25411629.0.0.77da180f7fYw5F


Web调试(Beta)

Web调试是通过将页面跨平台到Web端进行运行和渲染。由于Web端样式一致性仍在建设中,所以尽量以真机和模拟器的效果为准。


可以通过start时提示的链接打开进入。


08 布局和样式


1. 布局写法和数据绑定


Waft基于核心的响应式的数据绑定模块,来实现逻辑层修改数据,就能驱动视图层的更新的效果。


视图代码:


<div>
  <div>{{title}}</div>
  <div onTap="tapMe">示例按钮</div>
</div>


逻辑脚本:


let page: Login;
export class Login extends Page {
  constructor(props: ComponentProps) {
    super(props);
    page = this; // assemblyScript不支持闭包,在闭包中需要先赋给全局变量
    this.addEventListener('tapMe', function () {
      page.setState(`{"title":"Hello Waft"}`);
    });
  }
  onLoad(query: JSONObject): void{
    console.log('onload')
  }
}


如上所示,只要点击示例按钮,就会触发执行tapMe的函数回调,从而进行title字段的状态更新,视图因此会根据状态更新内容。


2.样式写法


Waft支持了主流的css样式,以及web规范的css写法,布局的单位为rpx,示例如下:


.title-div{
  width: 30rpx;
  height: 10rpx;
  background-color: red;
}
.title-text{
  font-size: 20rpx;
  color: #FFFFFF;
}


目前对rules规则如@media,css变量等能力暂未支持,具体可以参考ACSS规范:https://www.yuque.com/waft/docs/taglw5


3. 布局基准


默认框架的布局基准为1024px(指的是布局设计的全屏宽度像素)。


全屏应用:可以在app.json配置中自定义应用的基准。比如天猫精灵全屏的应用可以配置为1024。


{
  "pages": [
    "pages/index/index"
  ],
  "widgets":[
    "widgets/weather/weather"
  ]
  "window": {
    "defaultTitle": "Hello Waft"
  },
  "viewport": 1024
}


widget:需要在具体的某个widget的.json文件下配置,如果样式基准为300px来布局,可以配置viewport字段为300,如下:


{
  "usingComponents": {
    "card-layout": "waft-ui/src/components/card-layout/card-layout"
  },
  "viewport": 300
}


09 页面逻辑写法

页面逻辑的写法示例如下:


1. Function写法


import { JSON, JSONArray, JSONObject } from "waft-json";
import { getDataSource, log, FuncPage } from "waft";
let thisPage: FuncPage;
export function Index(page: FuncPage): void{
  thisPage = page;
  // 设置默认state
  page.setState(getDataSource().toString());
  page.onload = function (query: string) {
    log('--> onload:' + query);
  };
  page.onshow = function (event: string) {
    log('--> onshow:' + event);
  };
  page.onhide = function (event: string) {
    log('--> onhide:' + event);
  };
  page.onunload = function (event: string) {
    log('--> onunload:' + event);
  };
  page.addEventListener('tapTitle', function (event: string) {
    log('--> tapTitle event:' + event);
    thisPage.setState(`{"title":"Hello Waft"}`);
  });
}


2. Class写法


import { JSON, JSONObject } from "waft-json";
import { console, getDataSource, Page, ComponentProps, BaseEvent } from "waft";
let thisPage: Page;
export class Index extends Page {
  constructor(props: ComponentProps){
    super(props);
    thisPage = this;
    // 设置默认的state
    this.setState(JSON.stringify(getDataSource()));
    this.addEventListener('tapTitle', function (event: BaseEvent) {
      console.log('tapTitle event');
      thisPage.setState(`{"title":"Hello Waft"}`);
    });
  }
  onShow(): void{
    // 页面显示
    console.log('page onShow');
  }
  onLoad(query: JSONObject): void{
    // 页面加载后
    console.log('page onLoad:' + JSON.stringify(query));
  }
  onHide(): void{
    // 页面隐藏
    console.log('page onHide');
  }
  onUnLoad(): void{
    // 页面销毁
    console.log('page onUnLoad');
  }
  onMessage(data: JSONObject): void{
    // 信息推送更新
    console.log('page onMessage:' + JSON.stringify(data));
  }
  onError(error: Error): void{
    // 错误
    console.log('page onError');
  }
}


10 Page开发示例


根据模板创建页面

在src/pages下新建页面demo,包含了demo.axml,demo.acss,demo.ts,demo.json4个文件


在app.json中配置页面


{
  "pages": [
    "pages/demo/demo"
  ],
  "window": {
    "defaultTitle": "Hello Waft"
  }
}


【可选】在app.json配置页面渲染基准:

waft支持配置viewport。viewport代表了视觉布局的卡片总宽度基准(手机上都按750px布局),如果你的页面设计宽度总像素是按1024px布局,那只要设置viewport为1024,css即可按照1024rpx来写。(可以不配置,默认waft会按1024px来布局)


{
  "pages": [
    "pages/demo/demo"
  ],
  "window": {
    "defaultTitle": "Hello Waft"
  }
  "viewport": 1024
}


【可选】在mock.json中配置页面mock启动参数:

启动参数包含了以下值:

  • path: 启动页面路径;(默认为首页)
  • query: 启动的query参数
  • dataSource:启动的额外下发数据 (如服务端预先请求完数据,会放到dataSource下)


可以在src目录下的mock.json文件中配置数据,该数据可以在运行环境中通过 getLaunchData() 函数调用。


会在实际下发时按照实际运行,该参数只影响调试环境,不影响生产运行环境。


{
  "path": "pages/demo/demo",
  "query": {
    "id": "123456"
  }
  "dataSource":{
    "title": "hello"
  }
}


在axml文件中开发界面:

开发界面和数据绑定


<div>
  <div>{{title}}</div>
</div>


在ts文件中开发逻辑:

  • 可以在页面初始化时,通过全局的getLaunchData()方法,获取到应用启动的信息

  • 取出其中的dataSource字段,设置到默认的state
  • 在生命周期中,可以进行您的定制操作


import { JSON, JSONObject } from "waft-json";
import { console, getDataSource, WaftPage, ComponentProps } from "waft";
export class Index extends WaftPage {
  constructor(props: ComponentProps){
    super(props);
    this.setState(JSON.stringify(getDataSource()));
  }
  onShow(): void{
    console.log('page onShow');
  }
  onLoad(query: JSONObject): void{
    console.log('page onLoad:' + JSON.stringify(query));
  }
  onHide(): void{
    console.log('page onHide');
  }
  onUnLoad(): void{
    console.log('page onUnLoad');
  }
  onMessage(data: JSONObject): void{
    console.log('page onMessage:' + JSON.stringify(data));
  }
  onError(error: Error): void{
    console.log('page onError');
  }
}


11 waft-router


waft框架提供了多页路由的api。


在目录里新建多个页面,并在app.json中配置

image.gif

图片.png


在app.json中配置页面,和默认启动页

图片.png


在页面中使用history API跳转

push

跳转路由界面


const query = new JSONObject();
query.set("id", 123);
// query可以省略 或用 null 或 new JSONObject()
history.pushState({url : 'pages/detail/detail', query: query });


replace

替换当前页面,换为路由界面


// query可以省略 或用 null 或 new JSONObject()
history.replaceState({url : 'pages/detail/detail', query: JSON.parseObject(`{"id":"123456"}`)});


goBack

返回上一页


history.goBack();


12 waft-store

waft提供了全局状态store。


store数据获取


improt { store } from 'waft';
const globalData = store.getGlobalData();


store设置数据


import { store } from 'waft'
store.dispatch('state', new JSONObject())


store更新订阅

在component或者page中,可以通过this.observer方法监听全局store的更改。


immediate参数标识是否默认立即返回初始的状态。


export class Login extends Page {
  constructor(props: ComponentProps) {
    super(props);
    // 监听全局store变化
    this.observer(['menuData'], (key:string, data: JSONObject)=>{
      console.log('menuData change:' + data.toString());
    }, {
      immediate: true
    });
  }
}


store默认映射到当前页面的state

在component或者page中,可以通过this.connect方法把store中的内容订阅并同步到page的state上。


第二个参数可以传入一个reducer,修改参数再返回。return null时不处理。


export class Login extends Page {
  constructor(props: ComponentProps) {
    super(props);
    // 自动把store的key内容同步到page的state
    this.connect(['menuData']);
    // 监听全局store变化,并修改; 
    this.connect(['menuData'], (key:string, data: JSONObject, oldData: JSONObject | null)=>{
      return data;
    });
  }
}


附:

waft开发手册:https://www.yuque.com/waft/docs/ubi8k4


13 下期预告


本期内容就介绍到这里,下期我们将带大家上手Button的使用,欢迎大家持续关注RISC-V生态开发套件系列内容。

相关文章
|
12月前
|
机器学习/深度学习 文字识别 监控
安全监控系统:技术架构与应用解析
该系统采用模块化设计,集成了行为识别、视频监控、人脸识别、危险区域检测、异常事件检测、日志追溯及消息推送等功能,并可选配OCR识别模块。基于深度学习与开源技术栈(如TensorFlow、OpenCV),系统具备高精度、低延迟特点,支持实时分析儿童行为、监测危险区域、识别异常事件,并将结果推送给教师或家长。同时兼容主流硬件,支持本地化推理与分布式处理,确保可靠性与扩展性,为幼儿园安全管理提供全面解决方案。
535 3
|
人工智能 API 开发者
HarmonyOS Next~鸿蒙应用框架开发实战:Ability Kit与Accessibility Kit深度解析
本书深入解析HarmonyOS应用框架开发,聚焦Ability Kit与Accessibility Kit两大核心组件。Ability Kit通过FA/PA双引擎架构实现跨设备协同,支持分布式能力开发;Accessibility Kit提供无障碍服务构建方案,优化用户体验。内容涵盖设计理念、实践案例、调试优化及未来演进方向,助力开发者打造高效、包容的分布式应用,体现HarmonyOS生态价值。
774 27
|
供应链 项目管理 容器
深入探索 BPMN、CMMN 和 DMN:从定义到应用的全方位解析
在当今快速变化的商业环境中,对象管理组织(OMG)推出了三种强大的建模标准:BPMN(业务流程模型和符号)、CMMN(案例管理模型和符号)和DMN(决策模型和符号)。它们分别适用于结构化流程管理、动态案例处理和规则驱动的决策制定,并能相互协作,覆盖更广泛的业务场景。BPMN通过直观符号绘制固定流程;CMMN灵活管理不确定的案例;DMN以表格形式定义清晰的决策规则。三者结合可优化企业效率与灵活性。 [阅读更多](https://example.com/blog)
深入探索 BPMN、CMMN 和 DMN:从定义到应用的全方位解析
|
人工智能 小程序 前端开发
【一步步开发AI运动小程序】十九、运动识别中如何解析RGBA帧图片?
本文介绍了如何将相机抽取的RGBA帧图像解析为`.jpg`或`.png`格式,适用于体测、赛事等场景。首先讲解了RGBA图像结构,其为一维数组,每四个元素表示一个像素的颜色与透明度值。接着通过`uni.createOffscreenCanvas()`创建离屏画布以减少绘制干扰,并提供代码实现,将RGBA数据逐像素绘制到画布上生成图片。最后说明了为何不直接使用拍照API及图像转换的调用频率建议,强调应先暂存帧数据,运动结束后再进行转换和上传,以优化性能。
|
数据采集 机器学习/深度学习 存储
可穿戴设备如何重塑医疗健康:技术解析与应用实战
可穿戴设备如何重塑医疗健康:技术解析与应用实战
544 4
|
存储 弹性计算 安全
阿里云服务器ECS通用型规格族解析:实例规格、性能基准与场景化应用指南
作为ECS产品矩阵中的核心序列,通用型规格族以均衡的计算、内存、网络和存储性能著称,覆盖从基础应用到高性能计算的广泛场景。通用型规格族属于独享型云服务器,实例采用固定CPU调度模式,实例的每个CPU绑定到一个物理CPU超线程,实例间无CPU资源争抢,实例计算性能稳定且有严格的SLA保证,在性能上会更加稳定,高负载情况下也不会出现资源争夺现象。本文将深度解析阿里云ECS通用型规格族的技术架构、实例规格特性、最新价格政策及典型应用场景,为云计算选型提供参考。
|
人工智能 自然语言处理 算法
DeepSeek大模型在客服系统中的应用场景解析
在数字化浪潮下,客户服务领域正经历深刻变革,AI技术成为提升服务效能与体验的关键。DeepSeek大模型凭借自然语言处理、语音交互及多模态技术,显著优化客服流程,提升用户满意度。它通过智能问答、多轮对话引导、多模态语音客服和情绪监测等功能,革新服务模式,实现高效应答与精准分析,推动人机协作,为企业和客户创造更大价值。
968 5
|
机器学习/深度学习 JSON 算法
淘宝拍立淘按图搜索API接口系列的应用与数据解析
淘宝拍立淘按图搜索API接口是阿里巴巴旗下淘宝平台提供的一项基于图像识别技术的创新服务。以下是对该接口系列的应用与数据解析的详细分析
|
数据可视化 测试技术 API
前后端分离开发:如何高效调试API?有工具 vs 无工具全解析
在前后端分离的开发模式中,API 调试的效率直接影响项目的质量和交付速度。通过本文的对比分析,我们可以看到无工具调试模式虽具备灵活性和代码复用能力,但在操作便利性和团队协作上稍显不足。而传统的外部调试工具带来了可视化、高效协作与扩展性,却可能存在工具切换带来的开发链路断层问题。Apipost-Hepler 融合了两者的优势,让开发者无需离开熟悉的 IDEA 环境,就能享受可视化调试工具的强大功能。
427 5

推荐镜像

更多
  • DNS