From 144f1c98684669f52b00177e63dab2aa020ab1f9 Mon Sep 17 00:00:00 2001 From: Wendal Chen Date: Wed, 26 Feb 2020 10:05:29 +0800 Subject: [PATCH] =?UTF-8?q?update:=20=E6=9B=B4=E6=96=B0README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 69 +++++++++++++++++++++++++++++++++++++++++++++++++----- logo.jpg | Bin 0 -> 16141 bytes 2 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 logo.jpg diff --git a/README.md b/README.md index fadce6022..628a10af9 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,15 @@ -# LuatOS + +

LuatOS logo

+ +

[![license](https://img.shields.io/github/license/openLuat/LuatOS)](/LICENSE) [![rtt-w60x ci](https://github.com/openLuat/LuatOS/workflows/rtt-w60x/badge.svg)](https://github.com/openLuat/LuatOS/actions?query=workflow%3Artt-w60x) [![qemu ci](https://github.com/openLuat/LuatOS/workflows/qemu-vexpress-a9/badge.svg)](https://github.com/openLuat/LuatOS/actions?query=workflow%3Aqemu-vexpress-a9) +
[![issue](https://img.shields.io/github/issues/openLuat/LuatOS)](https://github.com/openLuat/LuatOS/issues) - +
+

LuatOS是运行在嵌入式硬件的实时操作系统,只需要少量内存的flash空间就能运行,用户编写lua代码就可完成各种功能 Lua base RTOS, build for many embedded systems @@ -16,13 +21,65 @@ Lua base RTOS, build for many embedded systems 5. 在线升级 6. 可裁剪,可扩展 -QQ群: 1061642968 +**QQ群: 1061642968** ---------------------------------------------------------------------------------- ## 总体架构 ![总体架构](system.jpg) +## 代码示例节选 + +详细代码请查阅 [script/app/playit/main.lua](script/app/playit/main.lua) + +```lua +local sys = require("sys") + +sys.subscribe("WLAN_READY", function () + print("!!! wlan ready event !!!") + -- 马上进行时间同步 + socket.ntpSync() +end) + +disp.init("ssd1306") +display_str("Booting ...") + +-- 配网回调 +sys.subscribe("WLAN_PW_RE", function(ssid, password) + if ssid then + log.info(TAG, "airkiss GOT", ssid, password) + local conf = {ssid=ssid,password=password} + json.encodeFile(conf, "/wlan.json") + else + log.info(TAG, "airkiss fail") + end +end) + +-- 业务流程, 联网后定时发送温度数据到服务器 +sys.taskInit(function() + while 1 do + if wlan.ready() == 1 then + sys.wait(1000) + local temp = (sensor.ds18b20(28) or "") + display_str("Temp: " .. temp .. " rssi:" .. tostring(wlan.rssi())) + local t = {"GET /api/w60x/report/ds18b20?mac=", wlan.get_mac(), "&temp=", temp, " HTTP/1.0\r\n", + "Host: site0.cn\r\n", + "User-Agent: LuatOS/0.1.0\r\n", + "\r\n"} + socket.tsend("site0.cn", 80, table.concat(t)) + log.info("network", "tsend complete, sleep 5s") + sys.wait(5000) + else + log.warn("main", "wlan is not ready yet") + sys.waitUntil("WLAN_READY", 30000) + end + end +end) + +-- 主循环, 必须加 +sys.run() +``` + ---------------------------------------------------------------------------------- ## 资源 @@ -39,11 +96,11 @@ TODO: 构建工具链,IDE,刷机工具,等等 ## 使用到的开源项目 -* [rt-thread](https://github.com/RT-Thread/rt-thread) 国产rtos +* [rt-thread](https://github.com/RT-Thread/rt-thread) 国产rtos, 非常好用 * [rtt-ds18b20](https://github.com/willianchanlovegithub/ds18b20) 在RT-Thread环境下读取ds18b20 * [LuaTask](https://github.com/openLuat/Luat_2G_RDA_8955) 合宙LuaTask -* [iRTU](https://github.com/hotdll/iRTU) 基于Luat的DTU -* [airkissOpen](https://github.com/heyuanjie87/airkissOpen) +* [iRTU](https://github.com/hotdll/iRTU) 基于Luat的DTU, 稀饭大神 +* [airkissOpen](https://github.com/heyuanjie87/airkissOpen) 参考其实现思路 ## 授权协议 diff --git a/logo.jpg b/logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8bf6961680bf128c8ccc9f6ce1e2117b5565af88 GIT binary patch literal 16141 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 !SR9ioN zd*|dzv9=M;^jzP1zV64EU|YVo^v-DtjNwQPp2UayP}lf8mq?jM(>L~5eh93Hua4D! z3~7#77`5|$E0{1|1l)+~Y-w=yhNnfGVXt}EvyW-?_|>{?*Dw8-pinp8nyYj!