Note:Azure IoT SDK with Windows

之前用Mbed OS v5.11.3 整合 Azure IoT SDK 發現其實不太能用, 最後直接用MQTT directly 直接 跟Azure IoTHub 連線, 中間遇到一些問題也是可以從 Azure IoT SDK for C 裡面去找線索, 其實Azure IoT SDK 也就把那些連線的細節包裝成一些API 方便使用而已, 但是剛好 Mbed OS 本身的架構改變關係, 跟他的包裝不太相容, 導致無法直接使用

最近開始另外一個 智慧車流分析的計畫, 後臺一樣是Azure IoTHub, 但是前端系統則是Windows + cuDNN 的設計, 所以需要直接在Windows 上開發對應的services, 又回頭來試試 Azure IoT SDK for C

按照目前官方文件, 是建議透過 vcpkg 來安裝管理 但是如果按照目前下面所述的內容預設是裝上x86-windows 版本需要調整一下, 下面帶 Bold 的屬性就是選擇AMD64 的 architecture 的方法

# Clone vcpkg
git clone https://github.com/Microsoft/vcpkg.git vcpkg_new

# Bootstrap and install Visual Studio integration
pushd vcpkg_new
.\bootstrap-vcpkg.bat -win64
vcpkg integrate install

# Install azure-iot-sdk-c package
vcpkg install azure-iot-sdk-c:x64-windows

# Optional, useful if you need to share or restore a box with the sdk without building it
# Export nuget package locally
vcpkg export azure-iot-sdk-c:x64-windows  --nuget

# Open a C SDK sample (assuming repo was cloned as follows: git clone https://github.com/Azure/azure-iot-sdk-c.git azureiotsdk_sample)
pushd azureiotsdk_sample\iothub_client\samples\iothub_ll_c2d_sample\windows
start iothub_ll_c2d_sample.sln
<hit F5 to build and run>
廣告

Note: CRC16 module of C99 for embedded system

又開始了MCU 相關工作內容, 之前幾乎都是修改 Linux/WinCE 的BSP 跟中間的middelware 的相關工作, 已經很久沒有碰MCU了, 但是最近接了一些IoT相關的工作, 內容都是集中在 MCU 上, 例如用 Mbed OS5 /STM32/BG96 做了一個 NB-IoT 的 PLC monitor system with Azure IoTHub, Mbed OS5 本身已經是module 的設計, 所以也用了很多現成的東西, 整理一些, 因為工作開的 github 上面

最近Microsoft 聯手 avnet 開始撒 Azure Sphere 我也登記了一片花了 NTD 7xx的運費,5%營業稅因為可以退稅就被某公司吸收了

登記這片是預計拿一些工作資源去做一個 PoC project 順便參加 Hackster 的 SecureEverything 要做的題目之前其實已經用golang 做過部分驗證, 其中用了一個好用的 crc16 module (github.com/sigurn/crc16)

開始動手寫 的時候 現在起手式都是先 google 看看有沒有好用的library 可以用, 沒有才開始刻, 不像剛工作時都是先看 datasheet/appnote 看看有啥可以用的撿起來用, 不過這次找了一會沒看到合適的 只好自己花時間 重新寫了一個版本 放到 github 上 https://github.com/KunYi/module_embedded_c 因為是現在寫的, 所以基本上是按 C99 來寫, 目前用VS2019 可以直接測試, 有CRC16/ARC, CRC16/MODBUS, CRC16/KERMIT 驗證過的版本, 要增加其他CRC16算法也不困難, 增加一些參數定義而已

Note: mDNS on Windows 10

mDNS (Multicast DNS) 最早是Apple 為了解決Device Discovery 設計出來的一個區網群播協定(用法語 Bonjour 命名), 既然是群播 在IPv4 時代自然是 224.0.0開頭, 標準化後就是 224.0.0.251 (0xE0.0. 0.0xFB), Port 5353, IPv6的IP則是 ff02::fb, 而因為是群播所以自然也是 UDP

但是Microsoft 自己早在DOS時代開始支援NetBIOS後, 採用SMB (Server Message Block) 協定做類似的功能, 所以一直沒有計畫去支援mDNS, 直到近年幾乎所有的設備都支持mDNS, Windows 10 終於也加入mDNS 的支援, 至於為啥所有設備都支持mDNS 可能是Apple 決定所有支持mDNS的client 都無須付費的關係, 而Apple 的電腦周邊生態又做的不錯

但是事情沒有這樣簡單, 簡單的話我不需要寫這篇筆記, 從Windows 8 開始, Microsoft 為了打開 Windows Phone市場, 開始了 UWP (Universal Windows Platform)計畫, 變成所有的新特色, 幾乎不在本來Win32 API 核心實作, 都移到新的Windows Runtime, 為了做App sandbox 又將UWP 跟傳統Win32 API 做了隔離, 透過.Net 跟Windows runtime, 新的UWP App 基本上都是在一個相對安全的Sandbox 內執行, 這變成新增的功能在傳統開發的程式無法直接使用, UWP 也無法直接執行一些存取硬體的行為, 間接多了很多工作機會 😛

下面兩篇有介紹怎樣在 Win32 環境下去執行UWP 環境下才有的API 分別是OCR and dns-sd(mdns)

Note: Android Application Development

很久沒碰了Android App 開發了, 目前官方的 IDE 環境, 已經是Android Studio 3.4.2
而build tool 也早已經換到Gradle  這個Build tools

Android Studio 裡面會有一個搭配的Gradle Plugin 搭配不同的Gradle Build Tools 版本
例如目前的Stable 的Android Studio 3.4.2 則也會搭配有 gradle plugin 3.4.2 的, 對應支援的Gradle 則是  5.1.1 ( version link )

Android Project  有可能引用許多Packages/Libraries,
現在一般主流都是透過 Maven repository  所以可以看到目前 build.gradle 內部會有許多類似下方的設定, 基本上就是從遠端 repository 去查找對應的package

 implementation 'com.android.support:appcompat-v7:28.0.0'

那要設定Local 的Library 則需要再 settings.gradle 先加入

include ':xxx' // add xxx project into the project

通常 include “:xxx" 如果在該專案的下方有對應 xxx folder 這樣就可以在 build.gradle 引入下面設定即可

implementation ':xxx'

但是倘落 Lib project 是獨立的project 則需要另外設定 path, 一樣先在 settins.gradle 加入

include ':yyy'
project(':yyy').projectDir = File ('../xxx/yyy')

然後再到 build.gradle 去加入

implementation ':yyy'

這樣當你需要分離某些code到不同的git repository 或是修改自己的library 都會方便許多

需要弄Android Application 是在因為透過Nordicsemi 的nRF Connect 在弄某BLE 裝置
透過下圖可以看到BLE Customer Service 這是FLIR 的MeterLink Service “D813BF66-5E61-188C-3D47-2487320A8B6E"
然後可以觀察到 有一個Notify Characteristic “E9A8B8C1-B91E-10A1-5241-C4D951378343″
會有固定的資料格式上傳
Descriptor 固定為 “MeterLink "
66858186_10214693073056345_933681845260779520_n

 

除了文內提到的方法也可以透過Local Maven repository 的方式

handler.maven { url '/path/to/checkout/out/androidx/build/support_repo/' }

ref.

Note: mbed os bootloader example

mbed os v5 在早期有下面兩個範例, 透過bootloader/application分離, 搭配外部儲存空間示範application升級的可能, 不過 目前看起來已經要放棄, 個人覺得還蠻可惜的, 畢竟這種越簡單的越容易學習背後基礎概念

 

目前實際官方支援的bootloader是下面這個, 完善很多, 但是變得複雜, 但是考量到人力資源有限放棄上面簡單的範例也是情有可原, 實際需要產品化的設計應該優先採用這個為基準去裁減修改自己所需要的功能

從舊的 範例內的 bootloader binary  可以看到預設flash 是 128KB大小的設計, 但是實際使用到的空間可能約64KB, 但是配合最新的mbed os v5.13 build出來的bootloader 會一口氣成長到 104KB 左右, 這可能也是 新的Cortex Mx 的flash rom size 開始朝向 2MB邁進的主因之一, 只有這樣才可能不需要另外透過外部的flash 來做application update, 可能就規劃 分成兩個flash partitions 分別放更新前後的application, 不過新的mbed-bootloader 會把系統預設的components 全部覆蓋掉維持在 7xKB 的大小
附上 mbed-os 5.13 的size, 較原本 mbed 5.12.3 大了 743byte的程式碼, 跟RAM多了8Bytes

Link: mbed-bootloader
Elf2Bin: mbed-bootloader
| Module                       |       .text |    .data |      .bss |
|------------------------------|-------------|----------|-----------|
| [fill]                       |     143(+8) |    4(+4) | 2379(-65) |
| [lib]\c.a                    |   29161(+0) | 2472(+0) |    89(+0) |
| [lib]\gcc.a                  |    3168(+0) |    0(+0) |     0(+0) |
| [lib]\misc                   |     224(+0) |    4(+0) |    28(+0) |
| [lib]\nosys.a                |      32(+0) |    0(+0) |     0(+0) |
| [lib]\stdc++.a               |       4(+0) |    0(+0) |     0(+0) |
| mbed-os\components           |    4627(+0) |    0(+0) |     0(+0) |
| mbed-os\drivers              |    2745(+0) |    0(+0) |  1016(+0) |
| mbed-os\features             |    2542(+0) |    4(+0) |   172(+0) |
| mbed-os\hal                  |   1681(+76) |    8(+4) |  130(+64) |
| mbed-os\platform             |   3289(-53) |  260(+0) |   155(+0) |
| mbed-os\targets              | 14930(+704) |   12(+0) |   538(+1) |
| modules\metadata-header      |    1135(+0) |    0(+0) |     0(+0) |
| modules\storage              |    1134(+0) |    0(+0) |    84(+0) |
| source\active_application.o  |    1262(+0) |    0(+0) |     0(+0) |
| source\bootloader_common.o   |     225(+0) |    4(+0) | 16385(+0) |
| source\bootloader_platform.o |      46(+0) |    0(+0) |     0(+0) |
| source\fix-mbed-os-compile   |       0(+0) |   44(+0) |     0(+0) |
| source\kvstore_rot.o         |      66(+0) |    0(+0) |     0(+0) |
| source\main.o                |     712(+0) |    0(+0) |     0(+0) |
| source\upgrade.o             |    1371(+0) |    0(+0) |     8(+0) |
| Subtotals                    | 68497(+735) | 2812(+8) | 20984(+0) |
Total Static RAM memory (data + bss): 23796(+8) bytes
Total Flash memory (text + data): 71309(+743) bytes

不過更神奇的是透過 附上建議的compile profile: tiny.json 可以有戲劇性變化, 程式碼大小只約在30K, data 也少了一些

Link: mbed-bootloader
Elf2Bin: mbed-bootloader
| Module                       |         .text |     .data |          .bss |
|------------------------------|---------------|-----------|---------------|
| [fill]                       |       68(+68) |     3(+3) |   2248(+2248) |
| [lib]\c_nano.a               |     664(+664) | 100(+100) |       12(+12) |
| [lib]\gcc.a                  |     832(+832) |     0(+0) |         0(+0) |
| [lib]\misc                   |     224(+224) |     4(+4) |       28(+28) |
| mbed-os\components           |   3159(+3159) |     0(+0) |         0(+0) |
| mbed-os\drivers              |   2380(+2380) |     0(+0) |   1068(+1068) |
| mbed-os\features             |   2708(+2708) |     4(+4) |     172(+172) |
| mbed-os\hal                  |   1390(+1390) |     8(+8) |     130(+130) |
| mbed-os\platform             |   1044(+1044) |     4(+4) |     147(+147) |
| mbed-os\targets              | 10629(+10629) |   12(+12) |     538(+538) |
| modules\metadata-header      |   1087(+1087) |     0(+0) |         0(+0) |
| modules\minimal-printf       |   1012(+1012) |     1(+1) |     188(+188) |
| modules\storage              |   1134(+1134) |     0(+0) |       84(+84) |
| source\active_application.o  |   1264(+1264) |     0(+0) |         0(+0) |
| source\bootloader_common.o   |     246(+246) |     4(+4) | 16385(+16385) |
| source\bootloader_platform.o |       46(+46) |     0(+0) |         0(+0) |
| source\fix-mbed-os-compile   |         0(+0) |   44(+44) |         0(+0) |
| source\kvstore_rot.o         |       66(+66) |     0(+0) |         0(+0) |
| source\main.o                |     715(+715) |     0(+0) |         0(+0) |
| source\upgrade.o             |   1375(+1375) |     0(+0) |         8(+8) |
| Subtotals                    | 30043(+30043) | 184(+184) | 21008(+21008) |
Total Static RAM memory (data + bss): 21192(+21192) bytes
Total Flash memory (text + data): 30227(+30227) bytes

可以觀察到主要是C RUNTIME被更換成 c_nano.a/gcc.a 跟其它因為optimization level變化的不同

Note: Mbed v5.12.x missed some settings in project

當使用 Mbed OS v5.12.x 時, 因預設使用PSA相關元件, 但是某部分的target 預設值沒有設定好
可以在相關的 mbed_app.json 內, 在自己需要的target 加入下方的設定

“target.extra_labels_add": [ “PSA" ],
“target.macros_add": [ “MBEDTLS_PSA_CRYPTO_C" ],

例如 https://github.com/ARMmbed/mbed-os-example-bootloader (mbed-os v5.12.3, commit id “863d9d6b94e751be0fd9050dcf293545bc1f5304″)

build K64F 會出現問題, 此時可以透過 上述設定避免build error,

另外目前已經release v5.13, 經過實測(K64F) 已經不需要加入上述的修改