Chino 操作系统开发日志 (1) - 为 IoT 而生
引言
很多人都听说过 IoT (物联网)这个词,越来越多的人在装修时开始选择智能家居,很多人也购买智能音箱做智能家居控制,想必未来一定是 AI + 物联网的时代。
一种技术要发展并走向成熟必须要降低门槛,提高迭代速度。传统的嵌入式开发太碎片化,很多时候还在使用代码复制、粘贴、修改的开发方法。如果不提供一个开箱即用的开发平台,让砖瓦能一层层叠上去,是很难开发更高级的应用的。
因此需要一个这样的平台:
- 提供足够的硬件抽象能力
- 提供友好的编程接口和调试接口
同时结合 IoT 的特点还要:
- 灵活控制非标准的定制硬件
- 适应有限资源的运行设备
因此 IoT 操作系统应运而生。
目前很多公司已经开始布局 IoT 操作系统,如 RT-Thread,华为的 LiteOS 等。
Chino OS
Chino OS 由包括我在内的开发团队设计开发的一款开源 IoT 操作系统。GitHub 地址:https://github.com/chino-os/chino-os
Chino 主要使用 C++ 语言编写,配有专用的 GNU 工具链和 C 运行库,使用 DeviceTree 描述硬件配置。目前系统具有以下特性:
- 多任务 (6 个优先级, Round robin 调度)
- 线程同步 (Mutex, Recurisve Mutex, Semaphore, Event)
- 进程间通信 (Mailslot)
- 统一的驱动模型
- 网络支持 (基于 LwIP 的 Socket API)
Chino 预定义了一组驱动接口,为应用开发者提供了一个统一的 API 层,使得开发者的大部分需求不用关心具体硬件差异。部分设备抽象如下表:
| 类别 | 子类 | 示例驱动 |
| 中断控制器 | cortex-m3, nvic | |
| IO / 总线 | GPIO | stm32f10x, gpio |
| I²C | stm32f10x, i2c | |
| SPI | stm32f10x, spi | |
| 串行 | stm32f10x, uart | |
| SDIO | stm32f10x, sdio | |
| 存储 | EEPROM | AT24C02 |
| Flash | GD25Q128 | |
| SD 内存卡 | SD V2.0 大容量存储 | |
| 显示 | TFT LCD | ILI9486L |
| 网络 | 以太网 | ENC28J60 |
| 传感器 | 加速度计 | ADXL345 |
Chino 目前支持 x86_64、Cortex-M3 架构,可运行在 PC 和 STM32 开发板上。未来计划支持 ESP32、RISCV32/64 等更多架构。

Chino 在 STM32F103 开发板上的运行截图
代码示例
1. GPIO 亮小灯
亮小灯可以说是嵌入式开发的 Hello World 了。
auto access = OA_Read | OA_Write;
auto gpio = g_ObjectMgr->GetDirectory(WKD_Device).Open("gpio3", access).MoveAs<GpioController>();
auto pin0 = gpio->OpenPin(, access);
pin0->SetDriveMode(GpioPinDriveMode::Output); while (true)
{
pin0->Write(GpioPinValue::Low);
g_ProcessMgr->SleepCurrentThread(1s);
pin0->Write(GpioPinValue::High);
g_ProcessMgr->SleepCurrentThread(1s);
}
程序申请读写权限打开名为 “gpio3” 的 GPIO 控制器,然后打开第 0 个 Pin,并设置该 Pin 的驱动模式为输出。
然后间隔 1s 切换输出高低电平。
这段代码隐藏了硬件具体细节,在任意具有 GPIO 的硬件上无需修改代码便可运行。
2. 读写 Flash
auto flash1 = g_ObjectMgr->GetDirectory(WKD_Device).Open("flash1", access).MoveAs<FlashStorage>();
{
gsl::span<const uint8_t> writeBuffers[] = { buffer };
flash1->Write(, { writeBuffers });
}
{
gsl::span<uint8_t> readBuffers[] = { buffer };
kassert(flash1->Read(, { readBuffers }) == std::size(buffer));
g_Logger->PutString("GD25Q128 Read:\n");
g_Logger->DumpHex(buffer, std::size(buffer));
}
这段代码功能很简单:打开 flash 之后写入数据然后读取数据。唯一需要说明的是 Chino 的 IO 部分均使用 BufferList 来读写数据,因此可以支持多个非连续内存段读写,且没有复制开销。
3. TCP Echo
auto eth0 = g_NetworkMgr->InstallNetworkDevice(g_ObjectMgr->GetDirectory(WKD_Device).Open("eth0", OA_Read | OA_Write).MoveAs<EthernetController>());
eth0->SetAsDefault();
eth0->Setup();
g_NetworkMgr->Run();
auto bindAddr = std::make_shared<IPEndPoint>(IPAddress::IPv4Any, );
auto socket = MakeObject<Socket>(AddressFamily::IPv4, SocketType::Stream, ProtocolType::Tcp);
socket->Bind(bindAddr);
socket->Listen();
auto client = socket->Accept();
while (true)
{
const uint8_t text[] = "hello\n";
gsl::span<const uint8_t> buffers[] = { {text,} };
try
{
client->Send({ buffers });
g_ProcessMgr->SleepCurrentThread(1s);
}
catch (...)
{
break;
}
}
程序打开名为 “eth0” 的以太网控制器,并注册到网络子系统。
然后创建一个 Tcp Socket,并监听 80 端口。
接受一个客户端连接并循环输出 hello,直到连接被关闭则退出循环。
系列说明
本文作为 Chino 操作系统开发日志的第一篇,简单概述了 Chino 目前的开发进度和基本的编程模型。今后的文章会详细介绍各个子系统的设计和开发的最新进展。
欢迎大家提出批评和建议,帮助 Chino 发展得更好。
最后再次附上 Chino 项目地址:https://github.com/chino-os/chino-os,希望大家多 star,多提 issue。
Chino 操作系统开发日志 (1) - 为 IoT 而生的更多相关文章
- 《Invert》开发日志05:终止
今天终于看了久闻大名的<独立游戏大电影>,然后我就做了一个坑爹的决定:终止“Invert”项目的开发.没错,在还没正式开工之前,我就决定停掉这个项目,而且是永久终止.做这个决定并不是因为觉 ...
- [课程设计]任务进度条&开发日志目录
任务进度条&开发日志目录 周期 时间 任务 Sprint One 11.14 ● Scrum团队分工及明确任务1.0 Sprint One 11.15 ● Scr ...
- NET-SNMP开发——日志输出
NET-SNMP开发——日志输出 net-snmp的日志输出功能是很强大的,与日志输出相关函数声明在net-snmp-5.7.3\include\net-snmp\library\snmp_loggi ...
- 仿酷狗音乐播放器开发日志十九——CTreeNodeUI的bug修复二(附源码)
转载请说明原出处,谢谢 今天本来打算把仿酷狗播放列表的子控件拖动插入功能做一下,但是仔细使用播放列表控件时发现了几个逻辑错误,由于我的播放 列表控件是基于CTreeViewUI和CTreeNodeUI ...
- Linux操作系统log日志日志分别指什么
Linux操作系统log日志日志分别指什么 2019-04-20 20:41:05 一.一般的日志 /var/log/messages —包括整体系统信息,其中也包含系统启动期间的日志.此外,m ...
- .NET Core开发日志——Entity Framework与PostgreSQL
Entity Framework在.NET Core中被命名为Entity Framework Core.虽然一般会用于对SQL Server数据库进行数据操作,但其实它还支持其它数据库,这里就以Po ...
- .NET Core开发日志——RequestDelegate
本文主要是对.NET Core开发日志--Middleware的补遗,但是会从看起来平平无奇的RequestDelegate开始叙述,所以以其作为标题,也是合情合理. RequestDelegate是 ...
- 《Orange’s 一个操作系统的实现》1.搭建操作系统开发环境
书中给出了两种环境:windows和linux,平台选择根据自己喜好.本人这里选择ubuntu10.04+virtualbox作为开发平台. 1.下载.安装VirtualBox http:// ...
- C#实现多级子目录Zip压缩解压实例 NET4.6下的UTC时间转换 [译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了 asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程 asp.net core异步进行新增操作并且需要判断某些字段是否重复的三种解决方案 .NET Core开发日志
C#实现多级子目录Zip压缩解压实例 参考 https://blog.csdn.net/lki_suidongdong/article/details/20942977 重点: 实现多级子目录的压缩, ...
随机推荐
- PL/SQL编程基础——PL/SQL简介
课程教师:李兴华 课程学习者:阳光罗诺 日期:2018-07-28 知识点: 1. 了解PL/SQL的主要特点 2. 掌握PL/SQL块的基本结构 PL/SQL PL/SQL是Oracle在关系数据库 ...
- django的orm操作的补充
---恢复内容开始--- 你在建立一个登陆的时候需要用到auth这个用户登陆模块 这个时候就需要用到user表中的信息你就可以继承 这个时候我们的用户表中继承我们user继承的表 ABstractUs ...
- [Swift] 使用Playground
使用Playground 1. 新建Playground 2. 写最简单的代码
- 细嚼慢咽C++primer(5)——顺序容器
1 顺序容器的定义 容器是容纳特定类型对象的集合. 顺序容器:将单一类型元素聚集起来成为容器,然后根据位置来存储和访问这些元素,这就是顺序容器. 标准库的三种顺序容器类型:vector, list 和 ...
- 沉淀再出发:Spring的架构理解
沉淀再出发:Spring的架构理解 一.前言 在Spring之前使用的EJB框架太庞大和重量级了,开发成本很高,由此spring应运而生.关于Spring,学过java的人基本上都会慢慢接触到,并且在 ...
- Retrieving failed records after an SqlBulkCopy exception
Let me start by saying that the idea I used in this article is not originally mine, but since I have ...
- C/S架构的性能测试
很多人关心LR在C/S架构上如何实施性能测试,我想根本原因在于两个方面,一是很多时候脚本无法录制,即LR无法成功调用被测的应用程序,二是测试脚本即使录制下来,可读性不强,往往不能运行通过,调试时无从下 ...
- opencv python3.6安装和测试
安装: 命令行 pip install D:\python3.6.1\Scriptsopencv_python-3.2.0-cp36-cp36m-win_amd64.whl 测试代码: import ...
- java String 常用方法集合
String a = "abc";String b = "abc";a==b ;//返回true,因为a,b指向的是同一个地址 String a = new S ...
- 阿里嘉年华ADC Workshop PPT分享
前段时间在阿里嘉年华的workshop做了一些关于memcache高可用和MMM Mod的分享. 下面是相关的PPT,特此分享. ADC官网直接在线查看:http://adc.alibabatech. ...