Chino 作業系統開發日誌 (1)

來源:互聯網
上載者:User
引言

很多人都聽說過 IoT (物聯網)這個詞,越來越多的人在裝修時開始選擇智能家居,很多人也購買智能音箱做智能家居控制,想必未來一定是 AI + 物聯網的時代。

一種技術要發展並走向成熟必須要降低門檻,提高迭代速度。傳統的嵌入式開發太片段化,很多時候還在使用代碼複製、粘貼、修改的開發方法。如果不提供一個開箱即用的開發平台,讓磚瓦能一層層疊上去,是很難開發更進階的應用的。

因此需要一個這樣的平台:

  • 提供足夠的硬體抽象能力
  • 提供友好的編程介面和調試介面

同時結合 IoT 的特點還要:

 

  • 靈活控制非標準的定製硬體
  • 適應有限資源的運行裝置

因此 IoT 作業系統應運而生。

目前很多公司已經開始布局 IoT 作業系統,如 RT-Thread,華為的 LiteOS 等。

Chino OS

Chino OS 由包括我在內的Team Dev設計開發的一款開源 IoT 作業系統。GitHub 地址: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 了。

 1 auto access = OA_Read | OA_Write; 2 auto gpio = g_ObjectMgr->GetDirectory(WKD_Device).Open("gpio3", access).MoveAs<GpioController>(); 3 auto pin0 = gpio->OpenPin(0, access); 4 pin0->SetDriveMode(GpioPinDriveMode::Output); 5  6 while (true) 7 { 8     pin0->Write(GpioPinValue::Low); 9     g_ProcessMgr->SleepCurrentThread(1s);10     pin0->Write(GpioPinValue::High);11     g_ProcessMgr->SleepCurrentThread(1s);12 }

程式申請讀寫權限開啟名為 “gpio3” 的 GPIO 控制器,然後開啟第 0 個 Pin,並設定該 Pin 的驅動模式為輸出。

然後間隔 1s 切換輸出高低電平。

這段程式碼後置了硬體具體細節,在任意具有 GPIO 的硬體上無需修改代碼便可運行。

2. 讀寫 Flash
 1 auto flash1 = g_ObjectMgr->GetDirectory(WKD_Device).Open("flash1", access).MoveAs<FlashStorage>(); 2 { 3     gsl::span<const uint8_t> writeBuffers[] = { buffer }; 4     flash1->Write(0, { writeBuffers }); 5 } 6 { 7     gsl::span<uint8_t> readBuffers[] = { buffer }; 8     kassert(flash1->Read(0, { readBuffers }) == std::size(buffer)); 9     g_Logger->PutString("GD25Q128 Read:\n");10     g_Logger->DumpHex(buffer, std::size(buffer));11 }

這段代碼功能很簡單:開啟 flash 之後寫入資料然後讀取資料。唯一需要說明的是 Chino 的 IO 部分均使用 BufferList 來讀寫資料,因此可以支援多個非連續記憶體段讀寫,且沒有複製開銷。

3. TCP Echo
 1 auto eth0 = g_NetworkMgr->InstallNetworkDevice(g_ObjectMgr->GetDirectory(WKD_Device).Open("eth0", OA_Read | OA_Write).MoveAs<EthernetController>()); 2 eth0->SetAsDefault(); 3 eth0->Setup(); 4 g_NetworkMgr->Run(); 5  6 auto bindAddr = std::make_shared<IPEndPoint>(IPAddress::IPv4Any, 80); 7 auto socket = MakeObject<Socket>(AddressFamily::IPv4, SocketType::Stream, ProtocolType::Tcp); 8 socket->Bind(bindAddr); 9 socket->Listen(1);10 11 auto client = socket->Accept();12 while (true)13 {14     const uint8_t text[] = "hello\n";15     gsl::span<const uint8_t> buffers[] = { {text,6} };16 17     try18     {19         client->Send({ buffers });20         g_ProcessMgr->SleepCurrentThread(1s);21     }22     catch (...)23     {24         break;25     }26 }

程式開啟名為 “eth0” 的乙太網路控制器,並註冊到網路子系統。

然後建立一個 Tcp Socket,並監聽 80 連接埠。

接受一個用戶端串連並迴圈輸出 hello,直到串連被關閉則退出迴圈。

系列說明

本文作為 Chino 作業系統開發日誌的第一篇,簡單概述了 Chino 目前的開發進度和基本的編程模型。今後的文章會詳細介紹各個子系統的設計和開發的最新進展。

歡迎大家提出批評和建議,協助 Chino 發展得更好。

 

最後再次附上 Chino 項目地址:github.com/chino-os/chino-os,希望大家多 star,多提 issue。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.