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生态开发套件系列内容。

相关文章
|
8天前
|
存储 缓存 搜索推荐
Lazada淘宝详情API的价值与应用解析
在电商行业,数据是驱动业务增长的核心。Lazada作为东南亚知名电商平台,其商品详情API对电商行业影响深远。本文探讨了Lazada商品详情API的重要性,包括提供全面准确的商品信息、增强平台竞争力、促进销售转化、支持用户搜索和发现需求、数据驱动决策、竞品分析、用户行为研究及提升购物体验。文章还介绍了如何通过Lazada提供的API接口、编写代码及使用第三方工具实现实时数据获取。
25 3
|
2天前
|
测试技术 开发者 Python
深入浅出:Python中的装饰器解析与应用###
【10月更文挑战第22天】 本文将带你走进Python装饰器的世界,揭示其背后的魔法。我们将一起探索装饰器的定义、工作原理、常见用法以及如何自定义装饰器,让你的代码更加简洁高效。无论你是Python新手还是有一定经验的开发者,相信这篇文章都能为你带来新的启发和收获。 ###
6 1
|
3天前
|
监控 安全 Serverless
"揭秘D2终端大会热点技术:Serverless架构最佳实践全解析,让你的开发效率翻倍,迈向技术新高峰!"
【10月更文挑战第23天】D2终端大会汇聚了众多前沿技术,其中Serverless架构备受瞩目。它让开发者无需关注服务器管理,专注于业务逻辑,提高开发效率。本文介绍了选择合适平台、设计合理函数架构、优化性能及安全监控的最佳实践,助力开发者充分挖掘Serverless潜力,推动技术发展。
9 1
|
6天前
|
传感器 监控 安全
|
6天前
|
数据中心
|
6天前
|
人工智能 资源调度 数据可视化
【AI应用落地实战】智能文档处理本地部署——可视化文档解析前端TextIn ParseX实践
2024长沙·中国1024程序员节以“智能应用新生态”为主题,吸引了众多技术大咖。合合信息展示了“智能文档处理百宝箱”的三大工具:可视化文档解析前端TextIn ParseX、向量化acge-embedding模型和文档解析测评工具markdown_tester,助力智能文档处理与知识管理。
|
7天前
|
存储 Java API
详细解析HashMap、TreeMap、LinkedHashMap等实现类,帮助您更好地理解和应用Java Map。
【10月更文挑战第19天】深入剖析Java Map:不仅是高效存储键值对的数据结构,更是展现设计艺术的典范。本文从基本概念、设计艺术和使用技巧三个方面,详细解析HashMap、TreeMap、LinkedHashMap等实现类,帮助您更好地理解和应用Java Map。
24 3
|
1天前
|
存储 人工智能 大数据
拼多多详情API的价值与应用解析
拼多多作为中国电商市场的重要参与者,其开放平台提供的商品详情API接口为电商行业带来了新的机遇和挑战。该接口允许开发者通过编程方式获取商品的详细信息,包括标题、价格、描述、图片、规格参数和库存等,推动了电商运营的智能化和高效化。本文将深入解析拼多多详情API的价值与应用,帮助商家和开发者更好地理解和利用这一宝贵资源。
6 0
|
2天前
|
供应链 安全 分布式数据库
探索区块链技术:从原理到应用的全面解析
【10月更文挑战第22天】 本文旨在深入浅出地探讨区块链技术,一种近年来引起广泛关注的分布式账本技术。我们将从区块链的基本概念入手,逐步深入到其工作原理、关键技术特点以及在金融、供应链管理等多个领域的实际应用案例。通过这篇文章,读者不仅能够理解区块链技术的核心价值和潜力,还能获得关于如何评估和选择适合自己需求的区块链解决方案的实用建议。
8 0
|
7天前
|
网络协议 数据中心 网络架构

推荐镜像

更多