目次

Newlib

https://sourceware.org/newlib/

ARMの組み込み環境向け標準Cライブラリ RedHat社が管理している フリーのCライブラリ,ライセンスはGPLではいのでこれを組み込んでもソースコードの公開義務は発生しない.

CubeMXでFreeRTOSプロジェクト作った際のNewlibまわりに生じる問題

FreeRTOS Helpers
BUG: CubeMX FreeRTOS projects corrupt memory
http://www.nadler.com/embedded/newlibAndFreeRTOS.html
bug-cubemx-freertos-projects-corrupt-memory
newlib/malloc locking mechanism to be thread-safe

mallocを始めとしたnewlibの関数はリエントラントであり,実装するプラットフォーム側でリエントラントを含めた以下の環境を用意する必要あり

Newlibはここに示すサポート関数が必要. ここで言うサポート関数とはsbrkwrite,readのこと.
UARTなどのペリフェラルの関数にUARTの送受信関数を定義すると,newlibにより提供されるprintfがUARTを使って入出力のやり取りをできるようになる. stm32の場合,syscalls.csysmem.cというファイルでこれを定義してやる.

mallocの最も内側のルーチンでmalloc_rが呼び出される.(これはどんな環境で計測したんだろうか,多分Corex-Mのマイコン(stm32)と思うけど)

newlibをリエントラントにするために必要なもの

CubeMXで生成されたプロジェクトのバグ

  1. CubeMXでFreeRTOSのコードを生成すると__malloc_lock,__malloc_unlockが提供されないのでmallocやfreeのリエントラントをサポートしていない.これらの関数を直接読んだり,STのUSBデバイスを使おうとすると(初期の際に中でmalloc()を呼び出しているので)メモリが破壊される.
  2. mallocなどの関数のためにsbrkが使うヒープ領域が必要になるため,newlibは空き領域が必要になる.けどSTのFreeRTOSのsbrkは動かない.このためスケジューラ起動後のmalloc要求は動かない.

FreeRTOSでのリエントラント

configUSE_NEWLIB_REENTRANTというオプションがFreeRTOSにある。 configUSE_NEWLIB_REENTRANT

configUSE_NEWLIB_REENTRANTは、その値が1に設定されている場合、newlibの reent構造が作成された各タスクに割り当てられます。注Newlibのサポートは一般的な需要に含まれていますが、FreeRTOSメンテナー自身は使用していません。FreeRTOSは、結果として生じるnewlib操作に対して責任を負いません。ユーザーはnewlibに精通している必要があり、必要なスタブのシステム全体の実装を提供する必要があります。(執筆時点で)現在のnewlib設計は、ロックを提供する必要があるシステム全体のmalloc()を実装していることに注意してください。

newlibをリエントラントにするための構造体をタスクごとにくっつける.タスクごとに96byte追加.さらにここにnewlibが追加で割り当てる・ →その分それぞれのタスクのメモリ領域は増やして確保しとけってこと? 機能説いてはは用意してあるけどFreeRTOS側でそのへん責任取らないからよしなに使ってねというニュアンスを感じる.

FreeRTOSはheap_3を使用するときに標準ライブラリmalloc()free()を使う.このためconfigTOTAL_HEAP_SIZEの設定は意味をなさない.ヒープのサイズはリンカで定義.
ここでいう標準ライブラリとはツールチェインに付属している標準ライブラリということでいいのだろうか. ARMならGNU Arm Embedded Toolchainに付属しているnewlibで提供されているmalloc()free()が使われるということ? heap_3はFreeRTOSのスケジューラを一時的に止めることでmallocfreeのスレッドセーフを担保する.

GNU Arm Embedded ToolchainはNewlibが実は2種類ある?

--specs=nano.specsnewlib-nanoをリンク,だけどこれは実装が入っていない. よって下のどちらかで実装を一緒にリンクする必要がある模様.

--specs=nosys.specs libnosys,リンカエラーが出ないようにするだけの最低限の実装. -lnosysをMakefileで追加しておく必要あり?

--specs=rdimon.specs semihosting環境,ホスト環境に標準ライブラリの諸々の処理は任せる.なのでホスト環境にをつないでないと動かないので注意

STのその後の対応

CubeMXのいくつかのバージョンから、用意されているUSBスタック内でのメモリ確保がmallocによる動的なものではなく配列による静的な確保によるものに更新されている
Concern on the usage of malloc() on USB Host MSC driver library
STM32F446 DFU : Hard fault with free() function

参考文献

組み込みシステム開発のための GNUツール
GNU Arm Embedded Toolchainとシステムコールの実装について
How to disable all exceptions code when building with g++
ARM Cortex-M3でのnewlibのmallocの使用.