今日ロッテマリーンズが優勝して西村監督が胴上げされました。
応援していたのでとっても嬉しいです。
ちょっと見ていて疲れる試合が多かったけどね。
これからビールかけが始まるようです!
ところで、プログラムをクロス・コンパイルして実行形式ファイルを作成し、H8/3069Fマイコン・ボードのフラッシュROMに書き込む準備はできたわけですが、次なるステップは「Hello World」の文字列を出すだけのプログラムに挑戦です。
結論としては、今コンパイルが通るように頑張っているのだがなかなかできない。。
でもこの段階って案外重要なのだよね。どうして通らないかを解析するためにソースを繰り返し見るよね。
その何回もソースをみる行動は実力アップさせるには案外見過ごせない工程なんだ。
そんなこといってはみるものの早くどうにかなりたい。
とりあえず記述したソースを紹介しそのあとどこで滞っているかをまとめてみます。
#滞りをブログで紹介するなんて恥ずかしいけど
【ソース作成】
内容は本を参照してね。メモを以下に書きます。
①main.c
main関数のなかにputs関数で「Hello World!」を出力するプログラム。
普通のプログラムと違うところは、シリアルデバイスを初期化する関数が先頭で呼ばれているところ。
というのもputs関数は自作しているからです。
②startup.s
アセンブラで書かれているファイルでmain関数が呼ばれる前にいろいろ初期化するスタートアップ。
普段では全く気にしない内容なのだがこのあとに詳細に勉強できるとのこと。
③vector.c
一番最初に実行開始するアドレスを定義。
割込みのためのソースのようで割込みベクタの設定をしています。
リセット・ベクタとも呼ばれています。
④lib.c
⑤lib.h
putc/putsのライブラリ関数を定義。
関数中ではserialに情報を送信するserial_send_byte関数を呼び出しています。
⑥serial.h
⑦serial.c★コンパイル試行錯誤中★
シリアルデバイスドライバの関数を定義。
putc/puts関数中ではserialに情報を送信するserial_send_byte関数を呼び出していますが、その本体などをメインに定義しています。
⑧defines.h
様々な型の定義をしています。
⑩ld.scr
リンカ・スクリプト。
コンパイルして作成される実行形式ファイルのメモリ配置を定義しています。
テキスト領域…コンパイル後の機械語コード
データ領域…変数などを配置
⑪Makefile
コンパイルしてファームウエアを作成するためのmakeコマンド利用のためのファイル。
【問題点】
serial.cのコンパイルが通らない。。
[make]
makeコマンドを実施すると「struct h8_3069f_sci」構造体の記述で以下のようなメッセージが出る。
だれか間違い教えて!

[serial.c]
#include "defines.h"
#include "serial.h"
/* SCIの数 */
#define SERIAL_SCI_NUM 3
/* SCIの定義 */
#define H8_3069F_SCI0 ((volatile struct h8_3069f_sci *)0xffffb0)
#define H8_3069F_SCI1 ((volatile struct h8_3069f_sci *)0xffffb8)
#define H8_3069F_SCI2 ((volatile struct h8_3069f_sci *)0xffffc0)
/* SCIの各種レジスタの定義 */
struct h8_3069f_sci {
volatile uint8 smr;
volatile uint8 brr;
volatile uint8 scr;
volatile uint8 tdr;
volatile uint8 ssr;
volatile uint8 rdr;
volatile uint8 scmr;
};
/* SMRの各ビットの定義 */
#define H8_3069F_SCI_SMR_CKS_PER1 (0<<0)
#define H8_3069F_SCI_SMR_CKS_PER4 (1<<0)
#define H8_3069F_SCI_SMR_CKS_PER16 (2<<0)
#define H8_3069F_SCI_SMR_CKS_PER64 (3<<0)
#define H8_3069F_SCI_SMR_MP (1<<2)
#define H8_3069F_SCI_SMR_STOP (1<<3)
#define H8_3069F_SCI_SMR_OE (1<<4)
#define H8_3069F_SCI_SMR_PE (1<<5)
#define H8_3069F_SCI_SMR_CHR (1<<6)
#define H8_3069F_SCI_SMR_CA (1<<7)
/* SCRの各ビットの定義 */
#define H8_3069F_SCI_SCR_CKE0 (1<<0)
#define H8_3069F_SCI_SCR_CKE1 (1<<1)
#define H8_3069F_SCI_SCR_TEIE (1<<2)
#define H8_3069F_SCI_SCR_MPIE (1<<3)
#define H8_3069F_SCI_SCR_RE (1<<4) /* 受信有効 */
#define H8_3069F_SCI_SCR_TE (1<<5) /* 送信有効 */
#define H8_3069F_SCI_SCR_RIE (1<<6) /* 受信割込み有効 */
#define H8_3069F_SCI_SCR_TIE (1<<7) /* 送信割込み有効 */
/* SSRの各ビットの定義 */
#define H8_3069F_SCI_SSR_MPBT (1<<0)
#define H8_3069F_SCI_SSR_MPB (1<<1)
#define H8_3069F_SCI_SSR_TEND (1<<2)
#define H8_3069F_SCI_SSR_PER (1<<3)
#define H8_3069F_SCI_SSR_FERERS (1<<4)
#define H8_3069F_SCI_SSR_ORER (1<<5)
#define H8_3069F_SCI_SSR_RDRF (1<<6) /* 受信完了 */
#define H8_3069F_SCI_SSR_TDRE (1<<7) /* 送信完了 */
static struct {
volatile struct h8_3069f_sci *sci;
} regs[SERIAL_SCI_NUM]={
{H8_3069F_SCI0},
{H8_3069F_SCI1},
{H8_3069F_SCI2},
};
/* デバイス初期化 */
int serial_init(int index)
{
volatile struct h8_3069f_sci *sci=regs[index].sci;
sci->scr = 0;
sci->smr = 0;
sci->brr = 64; /* 20MHZのクロックから9600BPSを生成(25MHZの場合は80にする) */
sci->scr = H8_3069F_SCI_SCR_RE | H8_3069F_SCI_SCR_TE; /* 送受信可能 */
sci->ssr = 0;
return 0;
}
/* 送信可能か? */
int serial_is_send_enable(int index)
{
volatile struct h8_3069f_sci *sci = regs[index].sci;
return(sci->ssr & H8_3069F_SCI_SSR_TDRE);
}
/* 1文字送信 */
int serial_send_byte(int index, unsigned char c)
{
volatile struct h8_3069f_sci *sci=regs[index].sci;
/* 送信可能になるまで待つ */
while(!serial_is_send_enable(index))
;
sci->tdr=c;
sci->ssr &= ~H8_3069F_SCI_SSR_TDRE; /* 送信開始 */
return 0;
}
応援していたのでとっても嬉しいです。
ちょっと見ていて疲れる試合が多かったけどね。
これからビールかけが始まるようです!
ところで、プログラムをクロス・コンパイルして実行形式ファイルを作成し、H8/3069Fマイコン・ボードのフラッシュROMに書き込む準備はできたわけですが、次なるステップは「Hello World」の文字列を出すだけのプログラムに挑戦です。
結論としては、今コンパイルが通るように頑張っているのだがなかなかできない。。
でもこの段階って案外重要なのだよね。どうして通らないかを解析するためにソースを繰り返し見るよね。
その何回もソースをみる行動は実力アップさせるには案外見過ごせない工程なんだ。
そんなこといってはみるものの早くどうにかなりたい。
とりあえず記述したソースを紹介しそのあとどこで滞っているかをまとめてみます。
#滞りをブログで紹介するなんて恥ずかしいけど
【ソース作成】
内容は本を参照してね。メモを以下に書きます。
①main.c
main関数のなかにputs関数で「Hello World!」を出力するプログラム。
普通のプログラムと違うところは、シリアルデバイスを初期化する関数が先頭で呼ばれているところ。
というのもputs関数は自作しているからです。
②startup.s
アセンブラで書かれているファイルでmain関数が呼ばれる前にいろいろ初期化するスタートアップ。
普段では全く気にしない内容なのだがこのあとに詳細に勉強できるとのこと。
③vector.c
一番最初に実行開始するアドレスを定義。
割込みのためのソースのようで割込みベクタの設定をしています。
リセット・ベクタとも呼ばれています。
④lib.c
⑤lib.h
putc/putsのライブラリ関数を定義。
関数中ではserialに情報を送信するserial_send_byte関数を呼び出しています。
⑥serial.h
⑦serial.c★コンパイル試行錯誤中★
シリアルデバイスドライバの関数を定義。
putc/puts関数中ではserialに情報を送信するserial_send_byte関数を呼び出していますが、その本体などをメインに定義しています。
⑧defines.h
様々な型の定義をしています。
⑩ld.scr
リンカ・スクリプト。
コンパイルして作成される実行形式ファイルのメモリ配置を定義しています。
テキスト領域…コンパイル後の機械語コード
データ領域…変数などを配置
⑪Makefile
コンパイルしてファームウエアを作成するためのmakeコマンド利用のためのファイル。
【問題点】
serial.cのコンパイルが通らない。。
[make]
makeコマンドを実施すると「struct h8_3069f_sci」構造体の記述で以下のようなメッセージが出る。
だれか間違い教えて!

[serial.c]
#include "defines.h"
#include "serial.h"
/* SCIの数 */
#define SERIAL_SCI_NUM 3
/* SCIの定義 */
#define H8_3069F_SCI0 ((volatile struct h8_3069f_sci *)0xffffb0)
#define H8_3069F_SCI1 ((volatile struct h8_3069f_sci *)0xffffb8)
#define H8_3069F_SCI2 ((volatile struct h8_3069f_sci *)0xffffc0)
/* SCIの各種レジスタの定義 */
struct h8_3069f_sci {
volatile uint8 smr;
volatile uint8 brr;
volatile uint8 scr;
volatile uint8 tdr;
volatile uint8 ssr;
volatile uint8 rdr;
volatile uint8 scmr;
};
/* SMRの各ビットの定義 */
#define H8_3069F_SCI_SMR_CKS_PER1 (0<<0)
#define H8_3069F_SCI_SMR_CKS_PER4 (1<<0)
#define H8_3069F_SCI_SMR_CKS_PER16 (2<<0)
#define H8_3069F_SCI_SMR_CKS_PER64 (3<<0)
#define H8_3069F_SCI_SMR_MP (1<<2)
#define H8_3069F_SCI_SMR_STOP (1<<3)
#define H8_3069F_SCI_SMR_OE (1<<4)
#define H8_3069F_SCI_SMR_PE (1<<5)
#define H8_3069F_SCI_SMR_CHR (1<<6)
#define H8_3069F_SCI_SMR_CA (1<<7)
/* SCRの各ビットの定義 */
#define H8_3069F_SCI_SCR_CKE0 (1<<0)
#define H8_3069F_SCI_SCR_CKE1 (1<<1)
#define H8_3069F_SCI_SCR_TEIE (1<<2)
#define H8_3069F_SCI_SCR_MPIE (1<<3)
#define H8_3069F_SCI_SCR_RE (1<<4) /* 受信有効 */
#define H8_3069F_SCI_SCR_TE (1<<5) /* 送信有効 */
#define H8_3069F_SCI_SCR_RIE (1<<6) /* 受信割込み有効 */
#define H8_3069F_SCI_SCR_TIE (1<<7) /* 送信割込み有効 */
/* SSRの各ビットの定義 */
#define H8_3069F_SCI_SSR_MPBT (1<<0)
#define H8_3069F_SCI_SSR_MPB (1<<1)
#define H8_3069F_SCI_SSR_TEND (1<<2)
#define H8_3069F_SCI_SSR_PER (1<<3)
#define H8_3069F_SCI_SSR_FERERS (1<<4)
#define H8_3069F_SCI_SSR_ORER (1<<5)
#define H8_3069F_SCI_SSR_RDRF (1<<6) /* 受信完了 */
#define H8_3069F_SCI_SSR_TDRE (1<<7) /* 送信完了 */
static struct {
volatile struct h8_3069f_sci *sci;
} regs[SERIAL_SCI_NUM]={
{H8_3069F_SCI0},
{H8_3069F_SCI1},
{H8_3069F_SCI2},
};
/* デバイス初期化 */
int serial_init(int index)
{
volatile struct h8_3069f_sci *sci=regs[index].sci;
sci->scr = 0;
sci->smr = 0;
sci->brr = 64; /* 20MHZのクロックから9600BPSを生成(25MHZの場合は80にする) */
sci->scr = H8_3069F_SCI_SCR_RE | H8_3069F_SCI_SCR_TE; /* 送受信可能 */
sci->ssr = 0;
return 0;
}
/* 送信可能か? */
int serial_is_send_enable(int index)
{
volatile struct h8_3069f_sci *sci = regs[index].sci;
return(sci->ssr & H8_3069F_SCI_SSR_TDRE);
}
/* 1文字送信 */
int serial_send_byte(int index, unsigned char c)
{
volatile struct h8_3069f_sci *sci=regs[index].sci;
/* 送信可能になるまで待つ */
while(!serial_is_send_enable(index))
;
sci->tdr=c;
sci->ssr &= ~H8_3069F_SCI_SSR_TDRE; /* 送信開始 */
return 0;
}