2015年01月28日

NUCLEO-F411RE ボードでシンプル・マルチタスク・スケジューラ

NUCLEO-F411RE ボードでシンプル・マルチタスク・スケジューラ
* はじまり
STM32CubeF4ドライバが最新版(V1.4.0)になったので、
勉強のため、このHALドライバを使ってベタで書いてみた。

STM32CubeF4
http://www.st.com/web/en/catalog/tools/PF259243

勉強内容: :D
(1) シンプル・マルチタスクスケジューラを動かしてみる。
    ここら辺と同じ。
    STM32F0 Discovery: シンプル・スケジューラ
    ARM: Cortex-M3/M0: シンプル・スケジューラ
(2) UARTの設定と送受信の動作。
    115200bps
(3) ChaNさんのxprintfで文字列出力。
(4) FPUを使う設定の確認。
(5) Makefileを使ってスタートアップコードからコンパイルと
    動作確認。
(6) システムクロック周りの確認。
(7) 最新のSTM32CubeF4 HALドライバの構成、動作確認。
(8) GPIOでLEDを点灯。
(9) Newlib nano で浮動小数ありなしオプションで且つ、ハードFPU有効な動作。
(10) 標準のNewlibで以下同上。
(11) syscalls.cでリターゲットの確認。

(注) xprintf()以外のprintf()を使う時は、タスクのスタック容量を5000byte以上に
    設定しないと動かない。

* 使用ボード
NUCLEO-F411RE
http://developer.mbed.org/platforms/ST-Nucleo-F411RE/
システムクロック(内蔵クロックベース)とSRAM容量を NUCLEO-F401REレベルに設定
(Systemclock=84MHz, SRAM=96KByte)
したので、NUCLEO-F401REでも動作する可能性があるけど、
持ってないので不明。:D

* コンパイル
コマンドライン:
    MinGW/MSysコンソール
    Cygwinコンソール
    Linuxコンソール
のどれかの環境。
コンパイラ:
    ARM gcc
    https://launchpad.net/gcc-arm-embedded
    arm-none-eabi-gcc.exeに実行パスを通しておいてください。
    v4.8.4で動作確認。

コンパイル方法:
Makefileがあるトップフォルダで「make 一発」。 xD
実際には「make -j4」とかが現実的。

* 動作確認
*.binファイルをNUCLEO-F411REボード用に見えるドライブにコピーするだけ。
(mbedと同じやり方)
*.hexをSTLINK経由で書き込んでも良い。
UARTターミナルに1から9の数字を打てば、LEDホアンホアン xD 速度が変わる。

* Download
v02:
    タスク・スタックを200バイトに増量
    nucleo-f411re-scheduler-2015-01-v02.7z
v01:
    nucleo-f411re-scheduler-2015-01.7z
    な、なんと gcc-arm-embedded の最新gcc v4.9.3だと動かない! xD。
    え"?!
    調べるか。 orz
    orz
    原因判明。
    タスク用のスタックをケチり過ぎた。
    200バイトでOK.


* ハマリポイント :D
HALドライバの作法に慣れていないのもあるけど、
UARTの割込み送受信が分りにくくて動くまでorzだった。
キーワードは以下。
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
void USART2_IRQHandler(void) {
    HAL_UART_IRQHandler(&huart2);       
}
HAL_UART_Transmit_IT( &huart2, &c, 1); 
HAL_UART_Receive_IT( &huart2, &rcvData, 1); 
Web検索しても分りにくくて結構困ってる人多いみたい。 スケジューラのUART部分は、あくまで自分用のデモなので、xD 実際にはリングバッファ等を使うのがいいと思う。
posted by Copyright (C) avrin All Rights Reserved. at 00:00| Comment(0) | ARM系 | このブログの読者になる | 更新情報をチェックする

2014年04月03日

STM32F4:Cortex-M4F:FPU: "__FPU_USED=1"は誰が定義したのか? メモ

STM32F4:Cortex-M4F:FPU: "__FPU_USED=1"は誰が定義したのか? メモ
(注)この内容は継続探査中につき注意が必要。

* はじまり
STM32F4(Cortex-M4F)は浮動小数点計算をハードウエアで行うFPUを内蔵している。
STM32F4の場合、
system_stm32f4xx.c
のSystemInit()の先頭でFPUを有効にする#if文があり、ここでFPUを有効にしなければ
ならない。(注1)
void SystemInit(void)
{
    /* FPU settings ------------------------------------------------------------*/
    #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
        SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
    #endif
    ......  
上の#if文がめんどくさい場合はコメントアウトしてしまうのが一番確実で楽。 一応、定石の様なものがあるらしく、最初の 「__FPU_PRESENT=1」だけコンパイル・スイッチ等で定義してやれば、 FPUが有効になるのです。 * __FPU_USED=1 は誰がどこで定義したのか? で、自分のソースコード上やコンパイル・スイッチ等のどこにも もう一方の「__FPU_USED=1」を定義していないのにFPUが有効になるんです。 プリプロセス結果を出してみると、確かに「__FPU_USED=1」が定義されていたのです。 これを一体、誰がどこで定義しているのかを探してみました。 「core_cm4.h」の以下で定義されていました、
......
#elif defined ( __GNUC__ )
  #if defined (__VFP_FP__) && !defined(__SOFTFP__)
    #if (__FPU_PRESENT == 1)
      #define __FPU_USED       1
    #else
      #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
      #define __FPU_USED       0
    #endif
  #else
    #define __FPU_USED         0
  #endif
  .....
「__FPU_PRESENT=1」は自分で定義するので、今度は「__VFP_FP__」の定義が謎です。 * __VFP_FP__ は誰がどこで定義したのか? 今度は「__VFP_FP__」がどこで定義されているのか探してみました。 コンパイラのインストール先、(Launchpad gcc) [arm-none-eabi-gcc]\lib\gcc\arm-none-eabi\4.8.3\plugin\include\config\arm\arm.h にありました。 また、プリプロセッサ「cc」のバイナリ内にもハードコードされていました。 このファイルはマイコン側のソースコードにどこからもインクルードされていません。 プリプロセッサ側が使う物と思われます。
......
#define TARGET_VFP        (arm_fpu_desc->model == ARM_FP_MODEL_VFP)
......
    if (TARGET_VFP)                    \
      builtin_define ("__VFP_FP__");        \
......
で、最終的に「ARM_FP_MODEL_VFP」はどこで定義されるかになるわけですが、 これはコンパイルオプションのCPU名等から決まるものと思われます。 * __SOFTFP__ の定義タイミングは ? これは未探査なものの、下記の組合わせを守れば特に問題は起きないだろうと いう予想。 * 結論 「__FPU_USED=1」という定義はプリプロセッサが定義する「__VFP_FP__」で有効になる。 「__VFP_FP__」は、 コンパイル時にコンパイルオプションにもとづきプリプロセッサが自動設定している。 話は変わって、 * 「-mfloat-abi=sotffp」や「-mfloat-abi=hard」を付ける場所 Cortex-M4FのFPUを有効にする時は、少なくとも
(A) -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softp
というオプションを追加しないといけないことは分った。 「softfp」と「hard」の違いは以前このあたりに書いた。 浮動小数点オプション が、忘れていた。:D 結論: から言うと上の(A)オプションの形を コンパイル時、リンク時共に同じものを指定しなければならない のだった。 orz リンク時に黄色い部分の指定を忘れていて、ライブラリが混在してちょっとハマリました。 orz (i) 正しく動作するが無駄な組合わせ (注3) コンパイル時: -mfpu=fpv4-sp-d16 -mfloat-abi=softp リンク時: 無指定 この場合、標準ライブラリはデフォルトの「-mfloat-abi=soft」がリンクされ、 「softfp」と互換があるので問題なく動作するが、 ライブラリ側はFPU機能を使わないので能力を無駄にしてしまう。 orz この組合わせの必要性は今ひとつ思い浮かばない :D 標準ライブラリがFPU未対応な場合は有効。 (ii) 正しく動作する組合わせ コンパイル時: -mfpu=fpv4-sp-d16 -mfloat-abi=softp リンク時: -mfpu=fpv4-sp-d16 -mfloat-abi=softp FPUをライブラリ側も使う。 「hard」に比べると呼び出し規約の互換性を保つため、無駄なコードが生成される。 (iii) 一番良い組合わせ (注2) コンパイル時: -mfpu=fpv4-sp-d16 -mfloat-abi=hard リンク時: -mfpu=fpv4-sp-d16 -mfloat-abi=hard これが、FPUを一番有効に使うコンパイル方法。 但し、外部から「*.o」、「lib*.a」などを持ってきてリンクする場合は、 それらも「hard」オプション付でコンパイルされている必要がある。 そうでなければリンク時にエラーとなる。 RTOS 対応: RTOSを使う時はディスパッチャ側でTCBにFPUレジスタを保存、復帰する処理が必要。 これがないと、一見動いているように見えても、 FPU計算中に他のFPU計算が必要なタスクに切り替わった時に計算が メチャメチャになる。 が、OSを移植するとか、作るとかでなければOS側でちゃんと対応済なはず。 。。。 移植しました。 orz * スタック待避量の増加 (注意)この項目は、ねむいさんにコメント頂いた様にLayzy Stackingに付いての記述が抜けているので、 後で修正します。 詳細はこの文書を参照して下さい。 http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0298a/DAFGGBJD.html FPU側は、 S0〜S31 ( 4byte x32個 ) という32個の単精度レジスタを持っていて、これを D0〜D15 ( 8byte x16個 ) という16個の倍精度レジスタとしてアクセスすることもできる。 割込み時は、 FPUがない場合のレジスタ保存に加えて、S0〜S15とFPSCRレジスタが自動保存される。 従って、少なくとも4byte x (16 + 2) = 72byte 余分にスタックを消費する。 ということは、 さらに割込み内、又は、割込みから呼ばれる関数内でFPUを使用すれば、 必要に応じて最大で残りのS16〜S31が保存される。 従って、最大4byte x (16 + 16 + 2) = 136byte 余分にスタックを消費する。 割込み時のレジスタ待避・復帰の増加サイクル数は、VSTM命令を見ると 待避時に最大、 1 + 32個 + 2個(FPSCR) = 35サイクル 復帰時も同じサイクルかかるので、 168MHz動作なら、(1/168MHz) * 35 * 2 = 約0.4usecの増加。 72MHzなら (1/72MHz) * 35 * 2 = 約1usec の増加となる。 ARM to C calling convention, registers to save http://stackoverflow.com/questions/261419/arm-to-c-calling-convention-registers-to-save http://ja.scribd.com/josephyen/d/6546078-ARM-Architecture-Procedure-Call-Standard#page=15 (注1) 「FPUを使うなら」だけど。 (注2) 一番良いと思うかどうかは個人差があります。xD (注3) 無駄と思うかどうかは個人差があります。 :D 参考: Embedded 脇見運転 さんのページ STM32F4 Discoveryへの移植を断念 http://d.hatena.ne.jp/suikan+embedded/20111123/1322053766 ARM compilation error, VPF registered used by executable, not object file http://stackoverflow.com/questions/9753749/arm-compilation-error-vpf-registered-used-by-executable-not-object-file ねむいさんのぶろぐ http://nemuisan.blog.bai.ne.jp/
posted by Copyright (C) avrin All Rights Reserved. at 00:00| Comment(2) | TrackBack(0) | ARM系 | このブログの読者になる | 更新情報をチェックする

2014年03月24日

STM32F4Cube orz

ねむいさんところでも言及されている
STM32F4Cube
という新しいペリフェラル・ドライバライブラリ。

最下層のレイヤで
Systick_Handlerを使っちゃってるので、mbedのF4シリーズでSTM32F4Cubeを使うと
RTX OSと競合して詰んだ。orz

本家も放置中の様子。
本家が対応するまで待とう。orz
posted by Copyright (C) avrin All Rights Reserved. at 23:05| Comment(0) | TrackBack(0) | ARM系 | このブログの読者になる | 更新情報をチェックする

2013年11月30日

驚愕の @80円の32bit ARM/8ピンDIPマイコン LPC810が出た時のメモ 2013

驚愕の @80円の32bit ARM/8ピンDIPマイコン LPC810が出た時のメモ 2013
LPCマイコン LPC810M021FN8 
http://akizukidenshi.com/catalog/g/gI-07191/

「32bitマイコンの8ピンDIP品」が@80円なんて驚きだ。(O O)
自分が知らないだけかもしれないけど、過去に聞いたことがない。
しかも、30MIPSなのにFlashが4096バイト、SRAMが1024バイト。
ポッチだ :D
でも爆速だ。

競合する工作用マイコンですぐ頭に浮かぶのが、
PIC12F1822 @80円 8pin DIP で8MIPS。
このマイコン、周辺I/O盛りだくさんでかなり良いイメージ。
(PIC12F/16F系のorz orz orzなコア・アーキテクチャを除く)
http://akizukidenshi.com/catalog/g/gI-04557/

あとは、AVRのTiny25系列。
秋月では入手できないのと値段が高かったので、ほとんど無縁だったが、調べてみると
マルツで一通り入手できる様だ。
AVR Tiny85 @225円 8pin DIP で約13MIPS(3.3V)。
http://www.marutsu.co.jp/shohin_40455/

* LPC810M021FN8メモ
1. ROM API でFlash消費を低減
   内蔵ROMにUART/I2C/IAP/Bootローダ/パワーコントロール関係の関数を持っているので、
   Flashの消費が少し抑えられる。
   これは良い。これがないと辛いというか、競争力的につらいところだろう。

2. A/D変換モジュールなし。 orz orz
 ソフト的に実現する方法が提示されているものの、容量食いそう。
 LPC800のコンパレータとソフトウェアで 10-bit ΣΔ ADCを実現する方法 
 http://www.lpcware.com/content/nxpfile/an11329-implementing-sigma-delta-adc-lpc800-comparator
 5ビットのコンパレータがあるから、それで我慢するか。

3. EEPROM的にFlashを使う
 IAP関数を使って64バイト(1ページ)単位で書き込み消去が可能。
 注意ポイント:
 詳しくは以下にあるが、
  LPC800 IAPの使い方
  http://www.lpcware.com/content/nxpfile/an11388-using-lpc800-application-programming
  (a) IAP時の消去時間は、一律(いつでも)100msec必要。
      書き込み時間は、1msec。
  (b) 割り込みテーブルがFlash上にある場合、IAPの消去・書き込みの前に、割り込みを禁止しなければならない。
      ただし、割り込みテーブルと割り込みハンドラをSRAMにリマップしておくなら、割り込みの実行は可能。
  (c) IAP時には、IAPルーチンがスタックの先頭(最高番地)から32バイトをワークエリアとして使うので、
      この部分を使わないように、リンカスクリプトを変更する必要がある。
  (d) IAP実行時に、IAPルーチンがスタックを148バイト128バイト(注1)消費するので、
  スタックの残りが少ない時は危険。

4. EEPROM的な部分はFlash(マイコン・ファーム)書き換え時に、消えないの?
  普通にマイコンファームを書き換えた時に、せっかくのEEPROM的ページも一緒に消去されてしまうかも、
  と、思ったが、(AVRのEESAVEの様な感じ)
  FlashMagicを使う限り大丈夫そうだ。
  [Step2 - Erase]のオプションで「Erase block used by Hex File」にチェックを入れれば良さそう。
  LPCXpressoのLPC-linkの場合に同じことができるかは、未確認。

5. マイコンライター(書き込み器)不要
   (a) UART経由でマイコン書き込みできる。
   (b) SWD経由でも書き込み可能。

6. SWDデバッグ可能
   SWD with LPC-linkでハードウエア・デバッグできる。
   使用可能ピンが減ってしまうが、PICだってPickit経由でデバッグ可能なわけだから必須。

* Cortex-M0+は、ミスター・スミスになるのか? (爆
 映画Matrixで、いつの間にか周りが全部ミスター・スミスになっているシーンを思い出した。:D
 15年くらい経つと、8ビットマイコン市場は劇縮小し、中身がミスター・スミス(Cortex-M0+)に
 入れ替わってしまうのだろうか。(爆
 ARMの戦略通りになるのか。

 今始まったばかりなのだった。

ちなみに、@80円なので、ついでの時に3個くらいは買って置こうと思います。

* 今後、Cortex-M0+ DIP版に期待されること、
 1. A/D変換器の追加。 これ追加しないと嫌う人多いと思う。
 2. 14pin,16pin,18pin,20pin,28pin,40pinのDIPマイコンを出すべき。(当然 300mil xD )
    電子工作的に喜ばれること間違いなし。(爆
 3. 十年後のラインナップは、これに太刀打ちできるくらいのバリエーションを期待する。:D
    http://akizukidenshi.com/catalog/c/cpic16f_dI_ssp/
    http://akizukidenshi.com/catalog/c/cpic18f_dI_ssp/
    それにしても、秋月のPICの品揃えって歴史的経緯があるとはいえ、「スゴイ」、といつも思う。
    ポイントを押さえればもっと少なくても良いね。

さらに、ちなむと、
FlashMagicの最新版に未発表の
LPC11U67: Cortex-M0, Flash=128kbyte, SRAM=20kbyte
LPC11U68: Cortex-M0, Flash=256kbyte, SRAM=36kbyte
が追加されていた。
大容量、高速、高機能、低価格のCortex-M0にも期待したい。




(注1) ねむいさんにコメントいただきました。感謝。




posted by Copyright (C) avrin All Rights Reserved. at 00:00| Comment(2) | TrackBack(0) | ARM系 | このブログの読者になる | 更新情報をチェックする

2013年07月20日

LPCOpen: NXPの新しいライブラリ群でちゃった!

LPCOpen: NXPの新しいライブラリ群でちゃった!
NXPが新たに、LPCマイコン用のペリフェラル・ライブラリを発表したようだ。

SYSLAB blog
LPC800 (18) API ROM driver (3) 
http://syslab.asablo.jp/blog/2013/07/18/6906435
上記のページで知りました。

LPCマイコン用としては、既にCMSISのペリフェラル・ドライバ・ライブラリが存在するので、
微妙な感じがするものの、ライセンスが単純明快なのが好印象。(後述)

* LPCOpen Platform
正式には、「LPCOpen Platform」というらしいが、ここではLPCOpenと記述する。
日本語ページ
http://www.nxp-lpc.com/lpc_software/lpcopen/
英語ページ
http://www.lpcware.com/content/nxpfile/lpcopen-platform
発見したばかりなのと、CMSISペリフェラル・ドライバ・ライブラリに対するメリット、
デメリットの記述を敢えて避けている様な感じなので、詳細はちょっと不明なものの、
わざわざ新しく作った訳だけだから、それなりのメリットはあるのだろう。:D
というか、LPC800/LPC13xx等々も統合されている点ですかね。

* 改変、再配布が可能なライセンス
これが、今のところ個人的には最大のメリットと思われる。:D
CMSISペリフェラル・ドライバ・ライブラリのv1系,v2系のライセンスは非常に冗長で難解、
海外でもオープンソースとの適合性について、あちこちで疑問が投げかけられているのも事実。
(v3系は投げてしまったので、どうなったか不明 xD)
で、
LPCOpenのライセンスを以下に示す。
Copyright(C) NXP Semiconductors, 2012
All rights reserved.

Software that is described herein is for illustrative purposes only
which provides customers with programming information regarding the
LPC products.  This software is supplied "AS IS" without any warranties of
any kind, and NXP Semiconductors and its licensor disclaim any and 
all warranties, express or implied, including all implied warranties of 
merchantability, fitness for a particular purpose and non-infringement of 
intellectual property rights.  NXP Semiconductors assumes no responsibility
or liability for the use of the software, conveys no license or rights under any
patent, copyright, mask work right, or any other intellectual property rights in 
or to any products. NXP Semiconductors reserves the right to make changes
in the software without notification. NXP Semiconductors also makes no 
representation or warranty that such application will be suitable for the
specified use without further testing or modification.

Permission to use, copy, modify, and distribute this software and its 
documentation is hereby granted, under NXP Semiconductors' and its 
licensor's relevant copyrights in the software, without fee, provided that it 
is used in conjunction with NXP Semiconductors microcontrollers.  This 
copyright, permission, and disclaimer notice must appear in all copies of 
this code.
前半は、今まででも記述されていた文言(もんごん)系だ。 前半だけで終わってしまうと、一般的には、改変、及び再配布は不可ととらえるのが常識的なところ。 で、 後半の、黄色い部分。 ここで、ソースコードの改変と再配布(ドキュメントも含む)が許可されています。 ただし、黄色い部分に書いてある条件に従うこと。 で、 MIT/BSD系ライセンスのコードとは親和性があるものの、GPLとは相容れない部分がある。 それは、「NXPのマイコンを使う場合に限る」という部分。 GPLには、改変や再配布も含め、利用や使用範囲を狭める方向のいかなる制限条件をも付加してはならないという、 厳しい掟(おきて)があるのだった。xD GPLでも自前のコードを全てスクラッチから書いて例外条項を付加すれば成立するものの、 既存のGPL'edされたコードを混ぜるのは、基本的には不可能だろう。 ちなみに、LPCOpenのファイル群は、他のライセンスが適用されたライブラリも含むので 再配布するときは個々のライセンスにも従う必要がある。 おしまいっ! (オイ
posted by Copyright (C) avrin All Rights Reserved. at 00:00| Comment(0) | TrackBack(0) | ARM系 | このブログの読者になる | 更新情報をチェックする