Comments
Description
Transcript
ROM
組み込みソフトウェア工学 第9回 プログラムのROM化,LCD・セン サー用関数の仕様 本日の内容 プログラムのROM化 ROM化について ROMのフォーマット ROMの書き込み LED・SW の使い方 LCD・センサー用関数の仕様 実習 プログラムのROM化 エディタ ソース ソース ファイル ソース ファイル ファイル オブジェクト ファイル ライブラリ コンパイラ エラー リスト リンカ 実行モジュール (ロードモジュール) エラー リスト ターゲットシステム ターゲットシス テムのROM へ書き込む 変換 プログラム 書き込みツール 書込用 ファイル インテルHex モトローラS など プログラムのROM化 • コンパイル – ソースプログラムをCPU(MPU)の命令に翻訳し て,機械語(オブジェクトプログラム)を生成する – コンパイラはプログラムの各部分を属性により, コード部,データ部,スタック部などに分ける – コンパイルした時,命令のアドレスは仮のアドレ スが振られている • リンカ – 複数のオブジェクトやライブラリを結合して,実行 モジュールを生成する – 各モジュールにおける命令のアドレスはリンク作 業によりアドレスの調整が行われ,アドレスの再 配置(リロケーション)が行われる プログラムのROM化 #include <stdio.h> main() { printf("hello, world¥n"); } CGROUP DGROUP GROUP GROUP TEXT DATA,BSS TEXT CSEG 0000 0000 DATA DSEG 0000 0000 BSS DSEG 0000 0000 0000 TEXT CSEG 0000 ; #include <stdio.h> Z1のアドレスは 0000 ; main() 0000.つまりまだ 0000 0000 main_:: 確定してない 0000 ; { 0000 ; printf("hello, world¥n"); 0000 B80000 MOV AX,Z1 0003 50 PUSH AX 0004 E80000 CALL printf_ 0007 83C402 ADD SP,2 000A ; } 000A C3 RET 000B printfのアドレスは 000B 0000.つまりまだ 確定してない 000B 0000 0000 68 0001 65 0002 6C 0003 6C 0004 6F 0005 2C 0006 20 0007 77 0008 6F 0009 72 000A 6C 000B 64 000C 0A 000D 00 000E 000E 000E 000E 000E 000E 000E DATA Z1: DSEG EVEN DB DB DB DB DB DB DB DB DB DB DB DB DB DB 104 (h) 101 (e) 108 (l) 108 (l) 111 (o) 44 (,) 32 ( ) 119 (w) 111 (o) 114 (r) 108 (l) 100 (d) 10 (¥n) 0 EXTRN printf_ ;core used: 1123/35648 END リンクによりアドレスを再配置(確定)させる プログラムのROM化 main 関数 printf のアドレ スを呼び出し 00000000 : 4D 5A C1 01 02 00 00 00 20 00 01 00 FF FF 00 00 : MZ...... ....... 00000010 : 00 00 65 7D 00 00 00 00 1E 00 00 00 01 00 00 00 : ..e}............ 00000020 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................ 000001F0 00000200 00000210 00000220 : : : : 00 B8 BA 8B 00 96 20 DA 00 03 00 D1 00 50 EB E3 00 E8 13 FF 00 F9 8B 97 00 FF DA 00 00 83 D1 00 00 C4 E3 4A 00 02 83 83 00 C3 BF FA 00 51 00 00 00 52 00 7D 00 56 00 E7 00 8B 74 BE 00 C8 08 00 : : : : ................ ...P顋.ζ..QRV曲 . ...芹.繝....t. 芹......J・.}鄒. 00000380 00000390 000003A0 000003B0 000003C0 : : : : : C6 5A 6C 79 00 8D 59 64 00 5E 8B 0A 00 80 E5 00 00 8B 5D 6F 72 0E C3 75 00 32 68 74 77 00 65 20 00 E8 6C 6F 77 75 6C 66 00 FE 6F 20 77 E8 2C 6D 2B 7D 20 65 62 FE 77 6D 00 5F 6F 6F 77 5E 72 72 62 : : : : : .洪...2.鑾.閘._^ ZY句].hello, wor ld..out of memor y...r.w.w.w+b.wb . アドレスがリンクに より確定している このデータをターゲットシステムに書き込む どうやって書き込むのか? プログラムのROM化 • ROM化とは – 一般的に組み込みシステムを動作させるプログ ラムはファームウェアと呼ばれる – ファームウェアは最終的に ROM 書かれる – ROM にデータを書く(ROM化)には 専用の装置 (ROM ライタ)を用いる – ROM ライタは指定したROMのアドレスに指定 データを書き込む作業を行う – 指定データに指定アドレスを定義しているファイ ルは特殊な形式となっており,大体2種類に分類 される • モトローラSフォーマット形式 • インテルHEXフォーマット形式 プログラムのROM化 ロードモジュール code ロードモジュールを ROMに書き込む data ROM ROMに書かれ たファームウェア code 命令コード data 初期値のある変数 stack 実行 RAM stackには 実体がない code copy 高速化のためメモリ にコピーして実行す る場合もある data 実行した段 階で実体が 生成される data’ 初期値のない変数 stack スタック領域 プログラムのROM化 モトローラSフォーマット – 複数のレコード形式 – ファイルはプレーンテキスト – 1レコード 1行 スペースを入れて区 切りを分かり易くして いますが,本来はス ペースはありません S0 S2 S2 S2 S2 S2 S2 S2 S2 S2 S2 S2 S2 S2 S2 S2 S2 S8 0E 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 04 0000 73616D706C652020202020 CF 000000 92ED73CEE943A2EFB87E3B89FEB2D26D 000010 965AC3175EF077E199BBE27692E95088 000020 83DD62C6B4CA5308E78180CDF48728E8 000030 B16B70761456AA139CE4D64EEC32695A 000040 BA394E06E75A2BEEEF39E5F384CF66EA 000050 76BB9E91D6D9C7C75B16EEFC0483AFE6 000060 FFA84075CA1AB10A985071E4F6B215DA 000070 AEF35550ECA157649FFA31682202A995 000080 1CD23EFDA5336DC2AA6B2D869257BC22 000090 21BA9D9B9DD5E2523038A77A8ED7DFCF 0000A0 D7605385BFCCE77FEC351FC2A0E7E329 0000B0 97B97F5A339EEEF8D677581B8F2BD9FD 0000C0 FAFA84F6610EA8AA2753518167891257 0000D0 D8980275F42305C0595F4D316F262085 0000E0 4B47DB36D32137A92370CBA93066D214 0000F0 ABFE2FD4298DAE1180998DA574EF3BD1 000000 FB 85 6C 2A 0D 67 87 BC 59 AC 06 B6 0B 57 E8 11 20 データ レコード形式 バイト数 S1 : 2バイトアドレス S2 : 3バイトアドレス S3 : 4バイトアドレス S8 : 終了レコード ロードアドレス 書き込み対象とな る先頭アドレス チェックサム バイトカウントおよ びデータの加算し た結果の1の補数 プログラムのROM化 インテル・HEXフォーマット – 複数のレコード形式 – ファイルはプレーンテキスト – 1レコード 1行 スペースを入れて区 切りを分かり易くして いますが,本来はス ペースはありません :10 :10 :10 :10 :10 :10 :10 :10 :10 :10 :10 :10 :10 :10 :10 :10 :00 0000 0010 0020 0030 0040 0050 0060 0070 0080 0090 00A0 00B0 00C0 00D0 00E0 00F0 0000 レコードの開始 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 92ED73CEE943A2EFB87E3B89FEB2D26D 965AC3175EF077E199BBE27692E95088 83DD62C6B4CA5308E78180CDF48728E8 B16B70761456AA139CE4D64EEC32695A BA394E06E75A2BEEEF39E5F384CF66EA 76BB9E91D6D9C7C75B16EEFC0483AFE6 FFA84075CA1AB10A985071E4F6B215DA AEF35550ECA157649FFA31682202A995 1CD23EFDA5336DC2AA6B2D869257BC22 21BA9D9B9DD5E2523038A77A8ED7DFCF D7605385BFCCE77FEC351FC2A0E7E329 97B97F5A339EEEF8D677581B8F2BD9FD FAFA84F6610EA8AA2753518167891257 D8980275F42305C0595F4D316F262085 4B47DB36D32137A92370CBA93066D214 ABFE2FD4298DAE1180998DA574EF3BD1 FF データ バイト数 ロードアドレス レコード形式 書き込み対象とな る先頭アドレス 8A 71 2F 12 6C 8C C1 5E B1 0B BB 10 5C ED 16 25 00 : データ 01 : 終了 02 : 拡張 03 : エントリアドレス チェックサム バイトカウントから データまでの加算し た結果の2の補数 プログラムのROM化 • ROMデータの書き込み方法(1) – ROMそのものにデータを書き込む 1つのROMに書き込む (大体が実験用) 多数のROMに書き込む (量産用途向け) ターゲット ROMを搭載 ROM プログラムのROM化 • ROMデータの書き込み方法(2) – 通信を通じてデータを書き込む シリアル通信 など CPU ROM 周辺 RAM 内部に ROM が搭載されている このROMにコードと データを直接書き込む 本日の内容 プログラムのROM化 ROM化について ROMのフォーマット ROMの書き込み LED・SW の使い方 LCD・センサー用関数の仕様 実習 SW と共用の LED RB0 - 7 RD0 - 5 通常のLED LED と PORT の関係 PORTB 7 6 5 4 3 2 1 LED #1 #2 #3 #4 #5 #6 #7 bit 7 ~ 1までが LED で使われている なお,SW1~7と共用 1 bit5 ~ 0 が LED で 使われている 0 PORTD 7 LED 6 5 4 3 #8 #9 #10 2 #11 #12 0 #13 LED の点灯 LDE は port D に接続 port D の初期化 /* Set Port D config */ TRISD = 0xC0; // bit 0-5 OUT, bit6-7 IN port D に出力 PORTD = <DATA> & 0x3F; // output to bit 0-5 但し port D は bit 0 ~ 5 までの 6bit が LED の出力に対応 しており,bit 6,7は対応していないので注意 SW の使い方 実習用ボードには SW が9個存在する RC5 Pull-UP 抵抗 RBx RCx SW 1~7 SW 8,9 ・RB1~7 および RC0~1 を in に設定 ・SWx を押すと RxDATA に SW の状況が入る 入力した情報が 1 の時: SW OFF 入力した情報が 0 の時: SW ON SW の使い方 SW は port B に接続,一部 port C も使用 port B および port C の初期化 /* Set Port B*/ ANSELH = 0x00; // AN Disable (RB5-RB0) WPUB = 0x00; // Pull-up disable INTCON = 0x00; // Intrauppt disable IOCB = 0x00; // Intrauppt charge disable CCP1CON = 0x00; CM2CON1 = 0x02; OPTION_REG = 0xFF; // Pull-up disable TRISB = 0xFF; // IN /* Set Port C */ RCSTA = 0x00; SSPCON = 0x00; TRISC = 0x03; PORTC = 0x00; // Serial disable (RC7-6) // Serial disable (RC5-4) // OUT(2-7), IN(0,1) // Low port B の初期化 (入力設定) port C の初期化 (入力および出力設定) SW の使い方 スイッチの状態の読み込み port B は bit 1~7 が SW で使われる <data> = PORTB & 0xFE; <data> = PORTC & 0x03; port C は bit 0~1 が SW で使われる 各SWの状態を調べるには 例えば SW4 の状態を調べたい SW4 は port B の bit 4 である このbitが 1 のとき,SW は OFF,0 のとき,SW は ON SW 7 6 5 4 3 2 1 #7 #6 #5 #4 #3 #2 #1 0 よって bit 4 だけが 1 か 0 かを判断すれば良い if( (PORTB & 0x10) == 0 ) { /* SW4 is ON */ bit 4 以外は 0 に固定し てしまう bit 4 が 0 のとき,SWは ON となる LED をビット毎に制御するには 例えば 6 つある LED の 3 つ目を光らせたい! この LED の 3 つ目は port D の bit 2 である LED --- --- #8 #9 7 6 5 4 #10 #11 #12 #13 3 2 1 0 よって bit 2 だけを 1 にすればよい その他の bit はそのまま変更しないようにする OR 演算子 LED = PORTD | 0x04; // bit 2 is 1, other is condition of Port D PORTD = LED ; bit 2 は 1 にして,それ以 LED に対して出力する 外は前のままとする 本日の内容 プログラムのROM化 ROM化について ROMのフォーマット ROMの書き込み LED・SW の使い方 LCD・センサー用関数の仕様 実習 LCD ・センサー 用関数 lcd_disp.c lcd_disp.h LCD 表示関数用ヘッダファイル sensor.c LCD 表示関数用ファイル timer,ロータリーエンコーダ関数用ファイル sensor.h timer,ロータリーエンコーダ関数用ヘッダファイル 情報工学セミナー 第4回 24 LCD 表示用関数 (lcd_disp) void init_lcd( void ) void disp_number( int number, int x, int y) 液晶のカーソル位置を指定する void write_char( char c ) 液晶に rs 分の文字データを表示させる void locate( int x, int y) 液晶の指定場所に数値を1文字表示させる void write_lcd( int code, int rs ) 液晶表示器を初期化する 液晶に1文字表示させる void write_str( char *s ) 液晶に文字列を表示させる 情報工学セミナー 第4回 25 LCD の表示位置 X 0 Y 0 1 2 3 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 センサー用関数 (sensor) void sensor_init( void ) 各種センサーの状態の初期化 char check_Rotary( void ) ロータリーエンコーダの回転状況を読み取る return : 回転状態の読み取り short check_Tempture( void ) 0 : not move 1 : 時計方向に1クリック動く 2 : 反時計方向に1クリック動く 温度センサーの状態を読み取る return : 温度(℃) void timer0_init( void ) timer0 の初期化 情報工学セミナー 第4回 27 Rotary Encoder の使い方 rot_dir = check_Rotary(); switch( rot_dir ) { case CW: <処理> break; case CCW: <処理> break; default: break; } Rotary エンコーダの状態の読み取り rot_dir に状態が入っている 時計回りで1つ動いたときの処理を記述 反時計回りで1つ動いたときの処理を記述 特に動きが無い時は抜ける timer0 を使った割り込み処理 static void interrupt rtcc_isr( void ) { T0IF = 0; /* Timer Interrupt Flag CLS */ <割り込み処理の記述> } 割り込み処理の記述 void main ( void ) { タイマー0 を動作させる : timer0_init(); /* Timer0 Initilize */ : timer0 による割り込み処理を許可 /* Timer0 Interrupt */ T0IE = 1; /* Enable Interrupt */ GIE = 1; /* Enable Global Interrupt */ } 全体の割り込みを許可 Timer による割り込みについて 16F887 にはタイマーが全部で3つある Timer0 , Timer1 , Timer2 割り込み用許可のレジスタ : INTCON 16F887 仕様書 p.31~p.32 参照 T0IE : Timer0 Overflow Interrupt Flag TMR1IE : Timer1 Overflow Interrupt Enable bit TMR2IE : Timer2 to PR2 Match Interrupt Enable bit TME1IF : Timer1 Overflow Interrupt Flag bit TME2IF : Timer2 to PR2 Interrupt Flag bit 本日の内容・まとめ プログラムのROM化 ROM化について ROMのフォーマット ROMの書き込み LED・SW の使い方 LCD・センサー用関数の仕様 実習 実機の貸し出しについて 木曜日のみ講義後もマイコン機器とプログラム書き 込み用ツールを当日限りで使うことを前提に貸し出 します. 講義後に貸し出しを受けたいグループは申し出て下 さい. グループ番号と貸し出し時間を記載してください.な お貸し出し時間は18時までとします. 貸し出しは木曜日当日のみとなります.必ず返却し て下さい. もし木村が居ない場合,711室の研究生らに返却 をして下さい.