Raisonance Ride7 & ARM Tools (18)2015年03月29日 14時06分58秒

Raisonance Ride7 & RKit-ARM は free でなくなってから Activate しなければ7日しか使うことができなくなった。
ほんとにそうなんだろうかと自分で試してみようと思った。
インストールしたバージョンは忘れたが、インストール後動作確認してその後日付を一ヶ月進め Ride7 を起動した。
”Activate しなければ使えないよ”というメッセージが出て使うことができなかった。

おお!やっぱり使えない。
さて、元の日付に戻して残り7日間いろいろ試してみようと思った。
しかし、元の日付に戻したのに使えなくなっていた。
結局使えたのはインストール後1時間程度だった。
この時、要らん事しなければよかったと後悔した。

それから何年たったろう?今ではその7日間が1ヶ月になったようだ。
でも私の環境では使えない。1度期限が過ぎてしまうとその設定がどこかに残っているのだろう。

さて、問題は使用期限ではなくて新しい RKit-ARM 1.56.15.0007 の話だ。
動かないけど何かおもしろい物はないかと、時々インストールしてみる。
今回、インストールしてみて気になる物があった。
Ride\lib\ARM\ の中にある
STM32Fxx_OptionBytes.c というファイルだ。
今までなかったのに...
そして、リンカースクリプトにも
MEMORY
{
  RAM        (xrw): ORIGIN = 0x20000000, LENGTH = 0x5000
  FLASH      (rx) : ORIGIN = 0x08000000, LENGTH = 0x20000
  STARTFLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x0
  CRPPATCH   (r)  : ORIGIN = 0x00000000, LENGTH = 0
  FLASHPATCH (r)  : ORIGIN = 0x00000000, LENGTH = 0
  ENDFLASH   (rx) : ORIGIN = 0x00000000, LENGTH = 0
  FLASHB1    (rx) : ORIGIN = 0x00000000, LENGTH = 0x0
  CONFIG     (r)  : ORIGIN = 0x1FFFF800, LENGTH = 0x10
  CONFIG2    (r)  : ORIGIN = 0x00000000, LENGTH = 0x0
  EXTMEMB0   (rx) : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB1   (rx) : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB2   (rx) : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB3   (rx) : ORIGIN = 0x00000000, LENGTH = 0
}
CONFIG という項目が追加になっている。
これを調べてみよう。

環境: Ride7 version 7.30.10.0169
    + RKit-ARM version 1.30.10.0356

LPC800 Watchdog Oscillator その後2015年03月28日 12時06分04秒

以前 LPC800 の Watchdog oscillator を使った場合 uart がうまく動かないのは system_LPC8xx.c に原因があるからだと書いた。 それがようやく修正された。 修正されたものは MDK-ARM 5.xx で使われる Software Packs の中の Keil.LPC800_DFP.1.1.0.pack に含まれている。 日付は2014年8月21日になっているからわりと最近だ。 ただ、間違っていたのは WDT Oscillator Setting の FREQSEL だけじゃなく System Oscillator Control のFREQRANGEにも誤りがあったのだ。( Configuration Wizard を使わない場合関係ない。) 今見ていてはじめて気がついた。
しかし、lpc11xx と lpc13xx は、まだ未修正なので使う場合は注意が必要だ。(LPC112x だけ修正済み)
やはり、メーカ純正でないとだめなんだろうと思い Lpcopen を調べてみた。
さすがにこれは間違った値は使ってない。

STM のスタートアップ (3)2015年03月26日 20時31分14秒

BootRAM について、Startup の中にこれが出てくるのはRide7 と TrueSTUDIO のみ。
しかも、stm32f10x と stm32l1xx と stm32w1xx だけ。
そして BootCheck があるのは MDKARM と TrueSTUDIO で、stm32f042x6 と stm32f070x6 のみ。
Vector Table の BootRAM と Reset_Handler の BootCheck はセットになっていてもよさそうだがセットにもなっていない。
調べても結局よく分からなかった。
Vector Table を RAM にも FLASH にもおけることから、使い方のサンプルとしてあるのだという結論にしておこう。

この件はなんか不完全燃焼だ。
もっとも、私自身はこの機能を使うことがないので関係ないのだけど...

Ride7 に Keil *.uvproj project を読みむ (2)2015年03月24日 23時44分47秒

MDK-ARM プロジェクト内の一部の項目が変換できなかった件
*.uvproj の内部が ARM-ADS と ARM-GNU で Tag の名称が異なっていたためだった。
TargetArmAds Cads Aads LDads
TargetArm    Carm Aarm LDarm
もう...めんどくさい。 しょうがないので ARM-GNU の Tag にも対応するように変更。

続いてデバイス名が変換されない件
テストしてみると stm32 系はほとんど変換できるようだ。
変換できないのは NXP の LPC 系が多いような気がする。
確認のためデバイス名を MDK-ARM と同じにしてみた。(LPC810M021) ---> 変換できる。(LPC810M021)
MDK-ARM の デバイス名を LPC81 にしてみる。(LPC81) ---> 変換できる?(LPC812)
MDK-ARM の デバイス名を LPC にしてみる。(LPC) ---> 変換できない。(LPC2478)
MDK-ARM の デバイス名を L にしてみる。(L) ---> 変換できない。(LPC2478)
MDK-ARM の デバイス名を LPC810M0210 にしてみる。(LPC810M0210) ---> 変換できない。(STR7-TEST)
見つからない場合は、全て (STR7-TEST) にしてしまう。

どうやら検索とパターンマッチングのアルゴリズムが関係しているようだ。
頻繁に使うデバイスは MDK-ARM の デバイス名と同じにしておけばよいということにしよう。
そうでなければそのつど手動で設定することにする。
この件はこのくらいでいいだろう。

今気になっているのは Project Settings の Assembler に Defines 項が無いこととか、
Startup が $(RkitLib)\ARM\crt0_*.o or startup_*.o をリンクするのがデフォルトになっていることだ。
このプロジェクト内にソースが無いというのは結構不便だ。


環境: Ride7 version 7.30.10.0169
    + RKit-ARM version 1.30.10.0356

Ride7 に Keil *.uvproj project を読みむ (1)2015年03月22日 17時26分51秒

Ride7 に MDK-ARM *.uvproj project を読みむ
先日の Ride7 に MDK-ARM の *.uvproj project を読み込む件をやってみた。
最新のスクリプトを現在使用中のスクリプトと置き換える。(r627)
さて、stm32cubel0 v1.1.0 で試してみよう。
手順は簡単で Ride7 を立ち上げ、Open Project でプロジェクトを開く。
ただし、そのままでは Ride7 のプロジェクトしか見えないので '*' を入れて全てのファイルが見えるようにする。
拡張子 *.uvproj のファイルを読み込む。

これだけでよい。読み込むとプロジェクトで使用するファイル、デバイス情報などが表示される。
そのプロジェクトを読み込んだ状態が右上のキャプチャー画面だ。
これは、「すばらしい!!」の一言だ。

今まで MDK-ARM のプロジェクトを Ride7 の環境に持ってくる場合、ファイルやパスを一つ一つ
集めて回らなければならなかった。このスクリプトがあれば一発だ。

気をよくして次に私が作成した MDK-ARM のプロジェクトも変換してみた。
え!!
Target unknown
変換できない。
ちょっとがっかり。でも、スクリプトなので変更できるかもしれない。
見てみると、ARM-ADS と MSC-51 だけしか変換対象になっていない。
ARM-GNU の環境が入っていないのだ。一行追加。

確かにね。
私だって自分の想定した手順に従って操作しなければ動かないプログラムしか書けないから...

再度立ち上げてプロジェクト読み込み。
うまく読み込めた。


「うまく読み込めた」と思っていたのに...
ARM-GNU の環境はうまく読み込めていない部分があった。
defines とか path とか デバイス名などである。
そのうち何とかしよう。


環境: Ride7 version 7.30.10.0169
    + RKit-ARM version 1.30.10.0356

STM のスタートアップ (2)2015年03月21日 20時13分38秒

前回の続きになるが、もうひとつ気になっていることがある。
startup_stm32f042x6.s と startup_stm32f070x6.s に挿入してある以下の部分。
/*Check if boot space corresponds to test memory*/
 
    LDR R0,=0x00000004
    LDR R1, [R0]
    LSRS R1, R1, #24
    LDR R2,=0x1F
    CMP R1, R2
    BNE ApplicationStart

 /*SYSCFG clock enable*/

    LDR R0,=0x40021018
    LDR R1,=0x00000001
    STR R1, [R0]

/*Set CFGR1 register with flash memory remap at address 0*/
    LDR R0,=0x40010000
    LDR R1,=0x00000000
    STR R1, [R0]

ApplicationStart:
これはいったい何なんだ?しかも、042x6 と 070x6 だけ。
暇なときに調べてみよう。
こういう気になることが次から次へ出てくるのだからしょうがない。

参照:
 STMicroelectronics

STM のスタートアップ (1)2015年03月20日 22時40分31秒

Cで書くスタートアップのためにいろいろなメーカのスタートアップを探したが中でも STM が気になった。
以前から STM のスタートアップはどれを使ったらよいのか分からないので一々データシートを見るか
MDK-ARM を起動して CPU 型番からスタートアップ名を探していた。
これね
startup_stm32f10x_cl.s
startup_stm32f10x_hd.s
startup_stm32f10x_hd_vl.s
startup_stm32f10x_ld.s
startup_stm32f10x_ld_vl.s
startup_stm32f10x_md.s
startup_stm32f10x_md_vl.s
startup_stm32f10x_xl.s
何とかならないかと思っていたところ、スタートアップの名前が新しくなっていた。
startup_stm32f100xb.s
startup_stm32f100xe.s
startup_stm32f101x6.s
startup_stm32f101xb.s
startup_stm32f101xe.s
startup_stm32f101xg.s
startup_stm32f102x6.s
startup_stm32f102xb.s
startup_stm32f103x6.s
startup_stm32f103xb.s
startup_stm32f103xe.s
startup_stm32f103xg.s
startup_stm32f105xc.s
startup_stm32f107xc.s
種類が増えたが一応名前からスタートアップを選択できる。これは歓迎すべきことだろう。
さて、話はスタートアップのファイル名ではなくてその中身だ。ベクターテーブルを見ていくと
最後に BootRAM が追加されている。確か以前はなかったはずだ。(以前と言ってもずいぶん前だ)
スタートアップにより挿入される位置が異なっている。
0x1CC 0x1E0 0x108 といった具合だ。
また、コードも2種類ある。
0xF108F85F 0xF1E0F85F
調べてみると
F85F F108 ldr.w pc, [pc, #-264]
F85F F1E0 ldr.w pc, [pc, #-480]
ということで所定の位置に挿入されているなら Reset_Handler に飛んでいく機能であるらしい。
そうだとすると startup_stm32f100xb.s と startup_stm32f100xe.s はそれぞれ
0x1CC に 0xF108F85F
0x1E0 に 0xF108F85F
が挿入されるようになるのでこの機能が働かないことになる。
というわけで、もしこの機能を使うなら
startup_stm32f100xb.s の 0x1CC は 0xF1CCF85F
startup_stm32f100xe.s の 0x1E0 は 0xF1E0F85F
でないといけないのではないだろうか?という話なのだった。

私の場合このどうでもいいようなことが気になってしょうがないのだ。
それはそうと、こう種類が増えると IDE のプロジェクトジェネレータをどうしようかということになってくる。
MDK-ARM ならデバイスファイルの CPU 一つ一つにファイル名を書いていくことになる。
Ride7 はどうしよう...

そういえば STM の GCC サンプルはいつの間にか Ride7 から TrueSTUDIO に変わってしまった。
もちろんプロジェクトファイルだけの問題なので
使えないと言うわけじゃないんだけど。

追記:
 stm32f4Cube integration with Ride 7 によると Ride7 には Keil *.uvproj project を読み込んで
 コンバートする機能があるらしい。そういうスクリプトがあるならぜひ試してみたい。

参照:
 STMicroelectronics
 AN0063-How to use STM32Cube library with Ride.pdf

CQ-FRK-NXP-ARM (12) Cで書くスタートアップ (3)2015年03月19日 22時20分43秒

スタートアップ、リンカースクリプト、その他とそろった所で実際にコンパイルしてみよう。
リストの 0020 行が取り除くことができなかった return だ。実害は無いのでよしとしよう。
0040 から 01fc まで空いているのは CRP を入れたためこのようになっている。
以下にそのリストを示す。

 


まあ予定通りうまく行ったという所だろうか。
ジャンプテーブルの部分は以下のような方法(某誌で採用されていた)もある。
void (* const g_pfnVectors[])(void)= {
    0xE59FF018,        // ldr     PC, [PC,#0x0018]
    0xE59FF018,        // ldr     PC, [PC,#0x0018]
    0xE59FF018,        // ldr     PC, [PC,#0x0018]
    0xE59FF018,        // ldr     PC, [PC,#0x0018]
    0xE59FF018,        // ldr     PC, [PC,#0x0018]
    0xE1A00000,        // nop
    0xE59FF018,        // ldr     PC, [PC,#0x0018]
    0xE59FF018,        // ldr     PC, [PC,#0x0018]
    Reset_Handler,
    Undef_Handler,
    SWI_Handler,
    PAbt_Handler,
    DAbt_Handler,
    0,                 // Reserved
    IRQ_Handler,
    FIQ_Handler,
};
しかし、最初の8個を変更する場合ハンドアセンブルしなくてはならないのがいまいちなんだよね。

CQ-FRK-NXP-ARM (12) Cで書くスタートアップ (2)2015年03月18日 22時11分34秒

スタートアップができたので次は linker script だ。
これは当然 LPCXpresso LPC8xx のものをそのまま使わせてもらう。 変更点は
ORIGIN(Flash) とLENGTH(Flash)
ORIGIN(Ram)とLENGTH(Ram)
とりあえずこれだけでいいだろう。
そうそう、CRP も一応入れておこう。

 


あと残りは SystemInit() 、これは mbed の system_LPC23xx.c がそのまま使えるはずだ。
system_LPC23xx.c と system_LPC23xx.h を引っ張ってくるとそのほかに必要なファイルが芋ずる式に出てきた。
上記以外に
core_arm7.h
vector_defns.h
LPC23xx.h
これに main() をくっつければテンプレートプロジェクトの出来上がりだ。
さらに、必要なら LPCXpresso の crp.c crp.h を付け加えて使うこともできる。
それにしても、久しぶりに mbed をのぞいたら対応する CPU が多くなっていて驚いた。
もちろん、あの Renesas RZA1H もサポートされている。


参照:
 LPCXpresso
 mbed

CQ-FRK-NXP-ARM (12) Cで書くスタートアップ (1)2015年03月17日 19時21分02秒

昨年、某誌で「アセンブリ言語は極力使わない!ベクタ・テーブル&スタートアップ・ルーチンはCで書く」
という記事があった。これはおもしろいと、とびついたが期待とは違ってアセンブリが普通に使ってあり
タイトルとは異なっていた。(いや、異なっていたわけではないが...)
そこで、私もやってみようと言うわけだ。やるからには某誌のような手抜きではなくフルサポートをしたい。
Cortex-M シリーズは既にアセンブラを使わないスタートアップが普及しているので ARM7 でやってみる。
ARM7 と言えば、私の手持ちでは CQ-FRK-NXP-ARM (LPC2388) しかないのでこれで進める。
とはいっても何かベースとなるものが必要だ。LPCXpresso の cr_startup_lpc8xx.c と Ride7 の crt0_lpc23x.s を参考にする。
さて、最初の問題はジャンプテーブルだ。安直に関数を作りその中にインラインアセンブラで書いてみた。
Cortex-M シリーズだとアドレスなので配列の中に埋め込んでいけばよい。
ところが、ARM7 はここにインストラクションジャンプテーブルが入るので Cortex-M と同じ方法は取れないのだ。
また、この関数は return する必要が無いのでその部分を削除したかったがその方法が分からない。
というわけで、以下の通り。
void ResetISR(void){
    __asm(" ldr     PC, =Reset_Handler\n");
    __asm(" ldr     PC, =Undef_Handler\n");
    __asm(" ldr     PC, =SWI_Handler\n");
    __asm(" ldr     PC, =PAbt_Handler\n");
    __asm(" ldr     PC, =DAbt_Handler\n");
    __asm(" nop\n");
    __asm(" ldr     PC, =IRQ_Handler\n");
    __asm(" ldr     PC, =FIQ_Handler\n");
}
Cで書いたといっても記述内容はアセンブラそのものだ。他の方法を思いつかなかったのでしょうがない。

次は、Reset_Handler だ。この部分の問題はスタックの設定をしなければならないこと。
Cでは直接レジスタを触ることができないはずだからこの部分もインラインアセンブラで書く。(今の所アセンブラだらけだ)
    __asm("    MSR     CPSR_c, #Mode_ABT|I_Bit|F_Bit\n"
          "    LDR     SP, =_ABT_Stack\n");
    __asm("    MSR     CPSR_c, #Mode_UNDEF|I_Bit|F_Bit\n"
          "    LDR     SP, =_UND_Stack\n");
    __asm("    MSR     CPSR_c, #Mode_SVC|I_Bit|F_Bit\n"
          "    LDR     SP, =_SVC_Stack\n");
    __asm("    MSR     CPSR_c, #Mode_FIQ\n"
          "    LDR     SP, =_FIQ_Stack\n");
    __asm("    MSR     CPSR_c, #Mode_IRQ\n"
          "    LDR     SP, =_IRQ_Stack\n");
    __asm("    MSR     CPSR_c, #Mode_USR\n"
          "    LDR     SP, =_USR_Stack\n");
Mode_... を define で宣言したかったがうまく行かないのでこの宣言部分もインラインアセンブラ。

最後は、データエリアの初期化とクロックの設定。
これは cr_startup_lpc8xx.c のソースがそのまま使えるのではないかと思う。
そしてクロックの設定は SystemInit() を呼び出すことにする。
こうしてできたのが以下のソースだ。思ったより短時間でできたがやはりベクタ・テーブルや
Reset_Handler はCで書くのが難しい。タイトルと内容が異なると言われても仕方が無いかな。

 


今日の所はこの辺で勘弁しておいてやろう!。

残っているのは、リンカースクリプトと SystemInit() 。
Cで書いて移植性をよくするというのが目的だと思うが中身はインラインアセンブラごりごりで
移植性も何も無い感じになってしまった。やはりスタートアップは MPU に依存する部分が多いので
アセンブラで書いても問題ないような気がしてきた。その方が分かりやすいかな?

追記:
__attribute__((noreturn)) ではなく __attribute__ ((naked)) を使えばいいのだった。
これですっきりしたね。上記のソースも修正した。

参照:
 LPCXpresso
 RAISONANCE Ride7