Shengwen Cheng
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.

      Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

      Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

      Explore these features while you wait
      Complete general settings
      Bookmark and like published notes
      Write a few more notes
      Complete general settings
      Write a few more notes
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.

    Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Explore these features while you wait
    Complete general settings
    Bookmark and like published notes
    Write a few more notes
    Complete general settings
    Write a few more notes
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    3
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    ## I. 概要 [NuttX](https://nuttx.apache.org/) 是一個類 Linux 的即時作業系統,並被 [PX4](https://px4.io/) 所採用,以下是一些簡單的學習筆記。 以下做一些目前接觸以來的直觀感受: **優點:** * POSIX 風格: 不同 OS 平台間可保持良好的可移植性 (FreeRTOS 相對較差) * 內建檔案系統、乙太網路等模組,不需要如 FreeRTOS 自行想辦法引入第三方軟體 * Mutex 支援優先權繼承 **缺點:** * 複雜性較高 (FreeRTOS 簡潔有力) FreeRTOS 作為 Software library 提供了最基本的多工、行程間通訊、同步機制等功能,但 Nuttx 相對起來更像是一個如同 Linux 的現代作業系統。 ## II. 安裝開發工具 1. 安裝基本套件: ``` sudo apt install build-essential git zlib1g-dev libsdl1.2-dev automake* autoconf* \ libtool libpixman-1-dev lib32gcc1 lib32ncurses5 libc6:i386 libncurses5:i386 \ libstdc++6:i386 libusb-1.0.0-dev ninja-build ``` 2. 編譯及安裝 OpenOCD: ``` git clone git://git.code.sf.net/p/openocd/code openocd cd openocd ./bootstrap ./configure --prefix=/usr/local --enable-jlink --enable-amtjtagaccel --enable-buspirate \ --enable-stlink --disable-libftdi echo -e "all:\ninstall:" > doc/Makefile make -j4 sudo make install ``` 3. 下載及安裝 ARM GCC toolchain 9: ``` wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2 tar jxf ./gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2 rm gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2 ``` 4. 編譯及安裝 QEMU: ``` git clone git://git.qemu.org/qemu.git cd qemu git submodule init git submodule update --recursive mkdir build cd build ../configure make -j $(nproc) ``` 5. 開啟 `~/.bashrc` 並在最尾端增加以下指令: ``` PATH=$PATH:${YOUR_PATH}/qemu/build PATH=$PATH:${YOUR_PATH}/gcc-arm-none-eabi-9-2019-q4-major/bin ``` 6. 重新啟動終端機即完成所有流程 ## III. 編譯及使用 QEMU 執行 NuttX NuttX 系統結構分為 Kernel 本體以及 App,可以使用以下指令分別取得: ``` mkdir nuttx-git cd nuttx-git git clone https://github.com/apache/nuttx.git nuttx git clone https://gitbox.apache.org/repos/asf/nuttx-apps.git apps ``` 接著使用以下指令編譯 NuttX: ``` cd nuttx tools/configure.sh stm32f4discovery:nsh #nsh console/UART2 make menuconfig make -j $(nproc) ``` 最終可以使用 QEMU 並將 UART2 重導向至 stdio 進行模擬: ``` qemu-system-arm -M netduinoplus2 -kernel nuttx.bin -serial /dev/null -serial stdio ``` 進入 NSH 後可以測試 `ps` 和 `hello` 指令得到: ``` nsh> ps PID GROUP PRI POLICY TYPE NPX STATE EVENT SIGMASK STACK COMMAND 0 0 0 FIFO Kthread N-- Ready 0000000000000000 001016 Idle_Task 2 2 100 RR Task --- Running 0000000000000000 002016 nsh_main nsh> hello Hello, World!! ``` ## IV. 一些常用功能的實驗 這裡針對一些我有興趣的功能進行測試以及紀錄。 NuttX 提供了許多範例程式碼,因此若要了解各個功能的使用,最快的方式就是瀏覽這些範例。這一點個人認為與 NuttX 抽象化程度高有關,因此許多功能並不直接依賴硬體平台。 [NuttX 官方說明文件](https://nuttx.apache.org/docs/latest/) --- ### 4-1: NuttX Driver * [#048: Overview about NuttX Drivers](https://www.youtube.com/watch?v=L-98aIHbTaY&list=PLd73yQk5Fd8JEsVD-lhwYRQKVu6glfDa8&index=40) 術語: * **Lower half driver**: I2C, SPI, CAN 等週邊驅動程式 * **Upper half driver**: 較高階的驅動程式,如 Network, Graphics, CAN, Serial, SPI Sensors, I2C Sensors, SD/MMC 等 一些常見週邊的使用: * [#007 - Using PWM on NuttX](https://www.youtube.com/watch?v=1DWK77Djg6Y&list=PLd73yQk5Fd8JEsVD-lhwYRQKVu6glfDa8&index=8) * [#019: Reading Analog Input on NuttX](https://www.youtube.com/watch?v=oSowWYLDDRI&list=PLd73yQk5Fd8JEsVD-lhwYRQKVu6glfDa8&index=19) * [#037: How to use USB Console on NuttX](https://www.youtube.com/watch?v=5BznGFvodmg&list=PLd73yQk5Fd8JEsVD-lhwYRQKVu6glfDa8&index=36) * [#038: How to use SDCard on NuttX](https://www.youtube.com/watch?v=H28t4RbOXqI&list=PLd73yQk5Fd8JEsVD-lhwYRQKVu6glfDa8&index=36) --- ### 4-2: Timer 定時器 * [設定啟用 Timer](https://nuttx.apache.org/docs/latest/components/drivers/character/timer.html) * [Timer signal handler 範例](https://github.com/apache/nuttx-apps/blob/master/examples/timer/timer_main.c) 先在 menuconfig 中進行以下設定: ``` System Type -> [*] SysTick timer driver -> STM32 Peripheral Support -> [*] TIM2 Device Drivers -> Timer Driver Support -> [*] Timer Support -> [*] Timer Arch Implementation Application Configuration -> Examples -> [*] Timer example ``` 開機載入 NSH 後執行: ``` nsh> timer ``` --- ### 4-3: 修改開機後預設執行程式 預設情況下開機後會載入 NSH, 若要執行使用者定義的應用程式則須透過 NSH 輸入指令後載入。實際上我們可以在 NuttX 的 menuconfig 中修改預設執行的程式。 見 [How to start directly my application instead starting NSH?](https://nuttx.apache.org/docs/latest/faq/index.html#how-to-start-directly-my-application-instead-starting-nsh) ``` RTOS Features -> Tasks and Scheduling -> (hello_main) Application entry point ``` 理論上可以自行設計一初始化程式,除了建立 NSH 的 Task 外,再載入其他應用程式的 Task。(待實驗後補上) --- ### 4-4: 任務控制 / 行程間通訊 / 同步機制 **官方資料:** * [Task Control Interfaces](https://nuttx.apache.org/docs/latest/reference/user/index.html) * [Named Message Queue Interfaces](https://nuttx.apache.org/docs/latest/reference/user/04_message_queue.html) * [Counting Semaphore Interfaces](https://nuttx.apache.org/docs/latest/reference/user/05_counting_semaphore.html) **範例程式:** * [Message queue 範例程式](https://github.com/shengwen-tw/nuttx-stm32/blob/master/message_queue/my_app.c) * [Semaphore 範例程式](https://github.com/shengwen-tw/nuttx-stm32/blob/master/semaphore/my_app.c) `menuconfig`: ``` Application Configuration -> Examples -> [*] NuttX STM32 Message Queue Example [*] NuttX STM32 Semaphore Example ``` ``` nsh > mqueue nsh > semaphore ``` **優先權繼承:** NuttX 支援優先權繼承,考慮以下情境: * 有高-中-低優先權 Task: A, B, 和 C * Task C 取得了 semaphore, 因此可以存取某個受保護的資源 * 接著 Task C 進入休眠狀態,以讓更高優先權的 Task 被執行 * Task A 接著嘗試取得 semaphore, 但因 semaphore 仍被 Task C 持有,因此必須等到 Task C 釋出後 Task A 才能取得。 * 接著 Task C 被允許繼續執行,但卻被中優先權 Task B 搶佔而再次進入休眠狀態。 像是本例中原本優先權最高的 Task A 卻必須反過來等待其他低優先權 Task (即 B 和 C) 的狀況我們稱為 "**優先權反轉 (Priority Inversion)**"。 要解決這樣的問題可以使用所謂"**優先權繼承**"的機制,一般**教科書**上有兩種做法: 1. **Priority Inheritance Protocol (PIP):** 將 Task C 優先權暫時提高到它阻礙到的其他 Task 中的最大優先權 2. **Priority Ceiling Protocol (PCP):** 將 Task C 的優先權暫時提高到所有可能佔有這個鎖的 Task 的最大優先權 根據文件描述,NuttX 應該是實做了 **Priority Inheritance Protocol (PIP)** 的機制,但也允許開發者自行設計所想要的繼承機制。 --- ### 4-5: 高性能、零延遲中斷 (High Performance, Zero Latency Interrupts) * [High Performance, Zero Latency Interrupts](https://nuttx.apache.org/docs/latest/guides/zerolatencyinterrupts.html) * [範例程式](https://github.com/apache/nuttx/blob/master/boards/arm/stm32/viewtool-stm32f107/src/stm32_highpri.c) --- ### 4-6: Work Queues **官方資料:** * [Work Queues](https://nuttx.apache.org/docs/latest/reference/os/wqueue.html) **範例程式:** * [Work queue 範例程式](https://github.com/shengwen-tw/nuttx-stm32/blob/master/work_queue/my_app.c) `menuconfig`: ``` Application Configuration -> Examples -> [*] NuttX Work Queue Example ``` ``` nsh> work_queue ``` 用於將某些任務卸載 (off-loading) 到多個 Threads 上,可分為: * **High Priority Kernel Work queue:** 中斷 (Interrupt) 觸發 work queue 後,經過一些延時卸載任務到單個或多個 Thread 完成。某些 Driver 的設計會需要這樣的機制。同時也負責 Intterupt 的 Garbage collection。 * **Low Priority Kernel Work Queue:** 處理其他一些擴充性功能用,如 File system clean-up, 記憶體垃圾回收 (Memory garbage collection), 以及 異步 I/O 操作 (asynchronous I/O operations) --- ### 4-7: 透過 Ethernet 進行網路連線 參考但步驟有異: * [#042: How to use Ethernet-over-USB (RNDIS) on NuttX](https://www.youtube.com/watch?v=8noH8v7xNgs&t=158s) 使用 [NUCLEO-746ZG](https://www.st.com/en/evaluation-tools/nucleo-f746zg.html) 進行實驗: ![](https://hackmd.io/_uploads/Skietx323.jpg) ``` cd nuttx-stm32/nuttx/ tools/configure.sh nucleo-144:f746-nsh make menuconfig ``` `menuconfig` 須要進行以下設定 (有些選項有相依性,請依照順序設定): ``` RTOS Features -> Work queue support -> [*] High priority (kernel) worker thread Networking Support -> Networking Support -> [*] Networking support -> Link layer support -> [*] Local loopback -> TCP/IP Networking -> [*] Enable TCP/IP write buffering -> UDP Networking -> [*] UDP Networking -> [*] UDP broadcast Rx support -> ICMP Networking Support -> [*] Enable ICMP networking -> ARP Configuration -> [*] ARP send -> [*] Collect network statistics Application Configuration -> Network Utilities -> [*] Telnet daemon -> Network initialization -> [*] Network initialization thread -> [*] Hardware has no MAC address -> NSH Library -> [*] Have architecture-specific initialization Device Drivers -> [*] Network Device/PHY Support ``` STM32 以及 路由器的 IP 位址以及 遮罩可由 `menuconfig` 進行修改: ``` Application Configuration -> Network Utilities -> Network initialization -> IP Address Configuration -> (0x0a000002) Target IPv4 address -> (0x0a000001) Router IPv4 address ``` 其中 `0x0a000002` 將 STM32 的 IP 位址設定為 `10.0.0.2`,而 `0x0a000001` 將路由器的 IP 位址設定為 `10.0.0.1`。 接著進行編譯以及燒錄韌體: ``` make -j16 cd .. ./flash.sh ``` 將 STM32 透過 RJ45 線材接到 Linux 主機 (在此用作路由器) 後進行以下設定: * Static IPv4 (Manual) * IP Address: 10.0.0.1 ![](https://hackmd.io/_uploads/HkfKoen2h.jpg) 在 Linux 主機上輸入: ``` ping 10.0.0.2 ``` 即可得到如下回應: ``` 64 bytes from 10.0.02: icmp_seq=0 ttl=64 time=0.060 ms 64 bytes from 10.0.02: icmp_seq=1 ttl=64 time=0.053 ms 64 bytes from 10.0.02: icmp_seq=2 ttl=64 time=0.072 ms ... ``` --- ## 參考資料 * [Getting Started with NuttX – STM32F4 Discovery (Unix)](https://cwiki.apache.org/confluence/display/NUTTX/STM32F4DISCOVERY+Unix) * [Write an application on NuttX ](https://hmchung.gitbooks.io/stm32-tutorials/content/write-an-application-on-nuttx.html) * [NuttX guides](https://github.com/micro-ROS/NuttX/issues/2)

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password
    or
    Sign in via Google Sign in via Facebook Sign in via X(Twitter) Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    By signing in, you agree to our terms of service.

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully