-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlpc2388-monbios.txt
472 lines (402 loc) · 21.3 KB
/
lpc2388-monbios.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
これは、NXP LPC2388 (ARM7TDMI) 用のファームウェア(モニタプログラム兼BIOS兼ランタイム)と、そのファームウェア上で動作するアプリケーションを作成するSDKです。シリアル経由でメインRAMにユーザープログラムをロードして実行する機能を持っています。
ファームウェア(モニタプログラム)は、多くの機能をAPIとしてユーザープログラムに提供します。ユーザープログラムは多くの機能をAPI呼び出しで済ませることができるため、コードサイズを非常に小さくできます。
APIの中には、FatFsによるSDカードアクセス機能や、SC1602互換のキャラクタLCDを操作
する機能が含まれています。
謝辞:
このモニタプログラムはbitcraftさんの LPC2388_gccmon.lzh をベースにさせていただきました。
http://bitcraft.web.fc2.com/embedded/arm7/armlpc2388.html
上記プログラムに、以下の方々のプログラムを追加したり、コードをコピーして使わせていただいています。
中村晋一郎さん( https://www.cubeatsystems.com/ntshell/ )
ねむいさん ( http://nemuisan.blog.bai.ne.jp/?eid=155799 )
ChaNさん ( http://elm-chan.org/fsw.html )
宮前さん ( http://miyakeng.web.fc2.com/arm/arm.htm )
Sakazumeさん ( http://219.117.208.26/~saka/ham/LCD2/ )
また、以下の方々の情報を参考にさせていただきました。
がた老さん ( http://gataro-avr-ken.cocolog-nifty.com )
irukaさん ( https://github.com/iruka-/ATMEL_AVR/blob/master/md/ARM.md )
SYSLAB blogさん ( http://syslab.asablo.jp/blog/ )
秋田純一さん( http://akita11.jp/diary/archives/2007/11/arm7.html )
HRA!さん ( http://www5d.biglobe.ne.jp/~hra/note/arm/index.htm )
------------------------------------------------------------------------------
* ディレクトリ構成 *
lpc2388-bios/
│
├ doc/ ■ ドキュメント
│
└ sdk/ ■ ファームウェアとアプリケーション開発用SDK
│
├ firmware.hex ・ファームウェアのファイル
│
├ application/ ・アプリケーションのデモサンプル
│ │
│ ├ dir/ SDカード上のディレクトリ一覧表示デモ
│ ├ fat/ SDカード上のファイルの読み書きデモ
│ ├ heap/ malloc2388のデモ
│ ├ isr/ 割り込みのデモ
│ ├ lcd_timer/ SC1602 LCD とタイマー割り込みを使ったデモ
│ └ testall/ LCD/malloc/浮動小数点/標準mathライブラリのデモ
│
├ firmware/ ・ファームウェアのソース
│
├ include/ ・アプリケーション開発用ヘッダ
│
└ lib/ ・アプリケーション開発用ライブラリ
------------------------------------------------------------------------------
* 周辺機器のサポート *
本ファームウェアは、LCD (SC1602互換) と SD/MMC アクセスをサポートする。
これらの周辺機器は必ずしも必要ない(無くても動作する)が、LPC2388 の以下の
ピンへ接続することで API からアクセス可能である。
LCD の接続
SC1602 - LPC2388
------- --------
D[4] - P3[0]
D[5] - P3[1]
D[6] - P3[2]
D[7] - P3[3]
EN - P3[4]
R/W - P3[5]
RS - P3[6]
SD/MMC の接続(各ピンにプルアップ/プルダウン抵抗も必要)
SD/MMC - LPC2388 - Pull Up / Pull Down
-------- -------- -----------------------------
DAT0/DO - P0[22] - 15k ohm to 3.3V
CD - P0[21] - 15k ohm to 3.3V (or fix to GND)
CMD/DI - P0[20] - 15k ohm to 3.3V
CLK - P0[19] - 15k ohm to GND
WP - P0[18] - 15k ohm to 3.3V (or fix to GND)
DAT3/CS - P2[13] - 15k ohm to 3.3V
DAT2 - P2[12] - 15k ohm to 3.3V
DAT1 - P2[11] - 15k ohm to 3.3V
------------------------------------------------------------------------------
* ファームウェアの書き込み *
ファームウェア(sdk/firmware.hex)をlpcwrtでLPC2388のフラッシュに書き込む方法。
lpcwrt.exe, lpcsp.exe, arm-none-eabi-objcopy.exe を準備。
CQ-FRK-NXP-ARM基板を、JP1とJP2をショートした状態で電源ON(CP2012側USBを接続)。
基板のJP1をオープンにすることでリセットを解除。
lpcwrtを起動して、以下を設定:
Configureセクション
COM Port : LPC2388のUART0 (CQ-FRK-NXP-ARM基板のCP2012側USB仮想COM)
Baud Rate : 115200
Oscillator: 12000 KHz
control DT/RTS はチェックしない。
lpcsp をチェックし、[Browse]ボタンで lpcsp.exe を指定
objcopy をチェックし、[Browse]ボタンで arm-none-eabi-objcopy.exe を指定
Flashセクション
HEX/BIN File に firmware.hex (sdk にある)を指定
以上を設定したら、CQ-FRK-NXP-ARM基板のJP2をOPENにして[Convert and Write]。
リセット後、TeraTermで接続しEnterで「LPC2388 MON>」が表示されれば成功。
起動中は、基板上のLED (Pin P1[18]) が5秒周期で点滅する。
なお、ファームウェアのソースファイルは sdk/firmware/ 配下にある。ビルドするには GNU Arm Embedded Toolchain と、make や cat 等のLinuxコマンドが使える環境(Linux, MSYS, Cygwin 等)が必要。
------------------------------------------------------------------------------
* 技術資料 *
==========================
= メモリマップ =
==========================
0x00000000 - 0x0007ffff : モニタプログラム(FLASH ROM)
0x40000000 - 0x40000cff : モニタプログラム用静的変数
0x40000d00 - 0x400014ff : モニタプログラム用スタック
0x40001500 - 0x400016ff : 例外処理用スタック
0x40001700 - 0x40001eff : ヒープ
0x40001f00 - 0x40001fff : 空き
0x40002000 - 0x4000fdff : ユーザープログラム領域
0x4000fe00 - 0x4000fff8 : ユーザープログラム用スタック
プログラム領域(0x0~0x00080000)内の有用な関数へのポインタを include/bios.def に定義している。これらはモニタプログラムの内部機能だが、各機能を直接呼び出すことでBIOSのような利用が可能。浮動小数点演算やSDカードの読み書き機能を含む、様々な関数をユーザープログラムから呼び出せる。
利用可能な関数については、本ドキュメント末尾の「モニタ BIOS API 一覧」を参照。
モニタプログラムはワーキングメモリとして0x40000000~0x40001f00の範囲を使う。ユーザーのブログラムは0x40002000以降の任意の領域に配置して実行できる。
================================
= モニタコマンドリファレンス =
================================
? : ヘルプ
コマンド一覧と簡易ヘルプを表示する。
なお、ほとんどのコマンドは引数が必須であり、引数なしで実行すると
コマンドのUsageを表示する。
info : システムの情報を表示する
info sys | info ver
dump : メモリダンプ
dump <memfrom> [<memto>]
アドレス<memfrom>から<memto>の間のデータを表示。
<memto>を省略した場合は<memfrom>から64バイト分を表示。
なお、<memfrom>,<memto>の値は16バイト単位に丸められる。
例:
LPC2388 MON>dump 0x4000a000
LPC2388 MON>dump 0x4000a000 0x4000a020
setm : セットメモリ
setm <mem>
アドレス<mem>から1バイトずつデータを入力する。
入力は2桁の16進数で、可能な文字は 0~9, a~f, A~F のみ。
2文字入力する毎に自動的にメモリに書き込まれてアドレスをインクリメントする。
なお、1文字入力後にEnterキーを押すと1桁の16進数データを書き込んでアドレス
をインクリメントする。
r, u, ↑キーの何れかを入力すると前のアドレスに戻れる。
n, v, ↓キーの何れかを入力すると次のアドレスへ進める。
入力を終えるには q または . または Ctrl-C
例:
LPC2388 MON>setm 0x4000a000
load : メモリにデータをロード
load < または load <filename>
引数 < のときはホストから送られるヘキサデータをメモリにロードする。
データはMotorola Sレコード形式のテキストで与える。
例えばTeraTermを使う場合、「load <」を実行直後にTeraTermの「ファイル(F)」-
「ファイル送信(S)」メニューからSレコード形式のファイルを選択すれば、
LPC2388へデータが送信されてメモリに書き込まれる。
例:
LPC2388 MON>load <
start loading address = 0x40002000
END. bytes loaded = 0x00001B24
call : 任意アドレスをサブルーチンコール
call <mem>
アドレス<mem>をサブルーチンとして呼び出す。
Main RAMにロードしたプログラムも実行できる。必ずしもリターンしなくてよい。
もし、サブルーチン実行後にリターンできた場合、その返り値を表示する。
例:
LPC2388 MON>call 0x40002000
exec : ファイルからプログラムをロードして実行
exec <filename> [arguments ...]
モトローラ形式のファイルをメモリにロードし、そのアドレスをcallする。
ファイル名の後に引数が与えられた場合、それらはプログラムのエントリー
ポイントに渡され、main(int argc, char **argv) のように参照可能。
例:
LPC2388 MON>exec prog.mot 1 2 3
list : ファイルの一覧表示
list <directory>
SDカード上の<directory>内にある全てのファイルの情報を表示する。
表示されるファイル情報は、ファイルのタイムスタンプ、サイズ、ファイル名。
サブディレクトリの中を再帰的に表示することはしない。
例:
LPC2388 MON>list /
del : ファイル/ディレクトリの削除
del <path>
SDカード上のファイルまたは空のディレクトリを削除する。
空ではないディレクトリの削除はできない。
例:
LPC2388 MON>del temp.bin
move : ファイル/ディレクトリのリネームまたは移動
move <oldpath> <newpath>
SDカード上のファイルまたはディレクトリをリネームまたは移動する。
例:
LPC2388 MON>move prog.mot prog.bak
==========================
= モニタ BIOS API 一覧 =
==========================
以下 (1)~(7) の API が関数として提供される。このうち、(7) は GNU Arm Embedded Toolchain に付属の標準ライブラリ(Newlib)のサブセットである。
(1) bios2388.h:
基本機能を実装したもの。
char uart0_dataReady(void) UART0の文字受信状況
char uart0_getc(void) UART0から1文字読み取り
void uart0_putc(char) UART0へ1文字出力
long xstrncpy_n(char *,char *,long) 文字列のコピー
int xstrcmp(char *,char *) 文字列の比較
long xstrlen(char *) 文字列の長さ
void exit(unsigned long) exit()。マクロで sys_exit() に置換
uintptr_t current_sp(void) 現在のSPレジスタの値
unsigned long gcc_current_pc(void) 現在のPCレジスタの値
d2sf(char *, double, int, int) doubleから文字列(小数表現)へ変換
d2se(char *, double, int, int) doubleから文字列(指数表現)へ変換
d2sg(char *, double, int, int) doubleから文字列(自動選択)へ変換
使い方 d2s[f/e/g](buf, val, wid, prec)
buf : 変換後の文字列を保存するバッファへのポインタ
val : 変換する数値
wid : 変換後の文字列長
prec : 変換後の文字列の小数点以下の桁数
(2) malloc2388.h:
ヒープ管理(malloc)の独自実装。詳細は sdk/include/malloc2388.h を参照。
セクタ単位で管理し、メインメモリの他にUSBメモリとEthメモリも利用することで、
トータルで87KBの大容量メモリを利用できる(ただし連続サイズの最大は約55KB)。
unsigned long malloc2388_init(s, flag) ヒープ管理の初期化(必須)
void *malloc2388(size) malloc(size)相当の関数
void free2388(void *) free(void *)相当の関数
最初にユーザープログラム内でmalloc2388_init()を実行する必要がある(必須)。
確保されメモリ領域は、ファームウェアのワーク領域とは異なる場所にあるため、
ユーザープログラム終了時に解放されていなくても構わない。
(3) lcd1602.h:
キャラクタ液晶SC1602互換の制御用。ピンアサインは以下のとおり。
SC1602 LPC2388
------- --------
D[4..7] P3[0..3]
RS P3[6]
R/W P3[5]
EN P3[4]
CPUのクロックが72MHzであることを想定している。これよりクロックが速いと
LCDが応答しない恐れがある。
void LCD_Init() APIの初期化とLCDの初期化
void LCD_Clear() LCD画面の消去&カーソル左上
void LCD_Putc(c) LCDへ1文字出力(マクロ版)
void LCD_PutChar(ch) LCDへ1文字出力(関数版)
void LCD_ReturnHome() カーソルを左上へ移動
void LCD_DisplayOn() ディスプレイOn&カーソルOff
void LCD_DisplayOff() ディスプレイOff
void LCD_CursorOn() カーソルOn(ディスプレイOn)
void LCD_CursorOff() カーソルOff(ディスプレイOn)
void LCD_BlinkOn() カーソルブリンクOn
void LCD_Write(rs, data) rsで示すレジスタに1バイト書き込み
void LCD_PutHex(data, len) 数値dataを16進表示。lenは表示桁数
void LCD_ShiftDisp(n) 画面n回右シフト(nが負なら左シフト)
void LCD_ShiftCursor(n) カーソルn回右シフト(nが負なら左)
LCD_wait_msec(t) おおよそ t [msec] だけウェイト
(4) xprintf.h:
ChaNさんによるprintfの実装。使う前に xdev_out(func) で出力先putc関数、
xdev_in(func)で入力元getc関数を登録する必要がある。lpc2388のリセット時は
uart0_putc() と uart0_getc() が登録されている。
void xputc(char c)
void xputs(const char* str)
void xfputs(void (*func)(unsigned char), const char* str)
void xprintf(const char* fmt, ...)
void xsprintf(char* buff, const char* fmt, ...)
void xfprintf(void (*func)(unsigned char), const char* fmt, ...)
void put_dump(const void* buff, unsigned long addr, int len, int width)
unsigned char (*xfunc_in)(void)
int xgets (char* buff, int len)
int xfgets (unsigned char (*func)(void), char* buff, int len)
int xatoi (char** str, long* res)
(5) ff.h, diskio.h:
ChaNさんによるFatFsの実装。詳しくはFatFsの資料およびサンプルプログラムを参照。
LPC2388のMCI端子に接続されたSDカードを読み書きする機能を提供する。
アクセス時にドライブの指定は不要(ドライブが一つしかないため)。
SD/MMC LPC2388 Pull Up / Pull Down
------- -------- -----------------------------
DAT0/DO P0[22] 15k ohm to 3V
CD P0[21] 15k ohm to 3V (or fix to GND)
CMD/DI P0[20] 15k ohm to 3V
CLK P0[19] 15k ohm to GND
WP P0[18] 15k ohm to 3V (or fix to GND)
DAT3/CS P2[13] 15k ohm to 3V
DAT[2:1] P2[12:11] 15k ohm to 3V
(6) vic_lpc23xx.h:
ねむいさんによる割り込み実装をベースに、VICの初期化や割り込みハンドラの登録等
を行う機能を実現したもの。詳細はサンプルプログラム(isr)を参照。
void VIC_Init() VICの初期化
uint32_t Reg_IRQ(IntSrc, *ISR, pri) ISRの登録。priは優先度
void Enable_IRQ(IntSrc) IRQの有効化
void Disable_IRQ(IntSrc) IRQの無効化
ARMアーキテクチャは、IRQハンドラを呼び出すときにCPUをIRQモードに切り替える。
割り込みハンドラをC言語で書く場合、IRQモードで実行可能なコードが生成される
ように、ハンドラのプロトタイプ宣言に __attribute__ ((interrupt ("IRQ"))) を
付けておく必要がある(参考: application/isr/isr_timer.h)。
ARMのIRQモードは多重割り込み対応ではないので、多重割り込みを実現するには、
ハンドラの中で以下のように多重割り込みを許可したい処理を _IRQ_*_CONTEXT() で
挟む必要がある。挟まれた部分は、通常の実行モードであるスーパーバイザー(SVC)
モードで実行される。
_IRQ_SAVE_CONTEXT(); /* レジスタ退避とSVCモードへの切り替え */
~
(この部分はSVCモードで実行。多重割り込みを受け付ける)
~
_IRQ_RESTORE_CONTEXT(); /* IRQモードへの復帰とレジスタ復元 */
(7) 標準ライブラリ
GNU Arm Embedded Toolchain に付属している標準ライブラリ(newlib)のサブセット。
以下の関数をサポートしている。標準ライブラリのヘッダファイルを利用可能。
■ 入出力ライブラリ
・バッファへの書式付き変換出力
sprintf() [注意] 浮動小数点を扱う場合は工夫が必要
vsprintf() [注意] 浮動小数点は扱えない
※ sprintf() で浮動小数点を扱う場合、double 型を正しく変換できないこと
がある。おそらく sprintf() 関数が double を正しく受け取っていない。
その場合は、double を下位32bitと上位32bitに分けて sprintf の引数の
4番目と5番目になるように渡すとうまくいく。
例:
#include "bios2388.h"
d2ul_t val; // double を上下32bitずつに分割して保持する型
val.d = sqrt(2.0); // 文字列に変換したい値
sprintf(buf,"%s%lf", "", val.l[0], val.l[1]); // 32bitずつ与える
この方法を使った、倍精度浮動小数点から文字列へ変換する以下のツールを
bios2388.h で提供しているので、そちらの利用を推奨。
d2sf(), d2se(), d2sg()
■ 文字列処理ライブラリ
・文字列長の取得
strlen()
・文字列の比較
strcmp()
strncmp()
memcmp()
・文字列のコピー
strcpy()
strncpy()
memcpy()
・文字列の連結
strcat()
strncat()
・文字の検索、取り出し、チェック
strchr()
strrchr()
strstr()
memchr()
strtok()
strspn()
strcspn()
・文字列から数値へ変換
atoi()
atof()
atol()
strtod()
strtof()
strtol()
strtoul()
・その他
memmove()
memset()
■ 文字処理ライブラリ
isalnum()
isalpha()
isdigit()
isxdigit()
isgraph()
isprint()
ispunct()
isupper()
islower()
toupper()
tolower()
iscntrl()
isspace()
■ 数学ライブラリ
・三角関数
sin()
asin()
sinh()
cos()
acos()
cosh()
tan()
atan()
atan2()
tanh()
・絶対値
fabs()
copysign()
・剰余
fmod()
・整数化、小数部分取得
ceil()
floor()
round()
trunc()
rint()
modf()
・累乗、指数、対数
sqrt()
cbrt()
hypot()
pow()
exp()
expm1()
scalbn()
log()
log10()
・ガウス誤差関数
erf()
erfc()
・その他
nan()
nanf()
■ 動的メモリ管理
※ 利用可能なヒープ領域はモニタ管理下の2KB(0x40001700-0x40001f00)のみ。
主にsprintf()等の標準ライブラリが利用するため、ユーザープログラムで
大規模なヒープが必要な場合は malloc2388() を使用すること。
malloc()
free()
■ 一般
・検索、ソート
bsearch()
qsort()
・乱数
rand()
srand()