皆さん こんにちは。
今回は2つ目のソースコードに入れ替えて動作確認してみます。
第2部4章のタイトルは「起動処理のプログラムでひとまずhello,worldを表示」です。
UARTを使って文字列を送信し、PCのターミナルソフトで受信して表示します。
今回もOSには関わらない下準備の作業になります。
ラズピコはディスプレイがないのでUARTによる文字列出力はデバッグの常套手段になります。
ぜひ動かしておきましょう。
この記事は開発環境を構築することを前提にしています。
開発環境を構築したい方は ゼロから作るOS 環境構築編 をご覧になってください。
この記事はインターフェース誌2023年7月号の「ゼロから作るOS」を参考にしています。
まずは書籍の本章を読んで予習しておくことをお薦めします。
ソースコードを入れ替える
これから前回製作したソースを削除するので、必要ならバックアップをとっておいてください。
Project Explorerでpico_tryknlのツリー下のフォルダを全て選択し、右クリックして Delete を選択して削除します。

次にソースファイルをIDEにコピーします。
C:\DevTools\src\IF2307TK\part_2\sect_4 下にある以下のフォルダを全て選択して、IDEの Project Explorer の pico_tryknl にドラッグ&ドロップします。
(書籍 第2部4章のソースファイルになります)
次のウィンドウが出るので、そのままOKを押してコピーします。

前回はなかった kernel フォルダが追加になっています。
コピーしたフォルダを展開し、フォルダ下にもファイルがコピーされていれば成功です。

Project – Build Project でビルドしてエラーがないことを確認しておきます。
svdファイルパスを設定する
デフォルトのままではPeripherals(周辺機能)レジスタを参照することができません。
ラズピコのマイコン用の RP2040.svd というファイルをIDEで指定してあげるとPeripheralsレジスタを参照することができるようになります。
SDKをダウンロードしている方はご自身のPC上で探せば見つかると思います。
もしわからなければ rp2040.svd からダウンロードしてお使いください。
以下の赤枠部分をクリックしてダウンロードします。

ダウンロードしたファイルをフォルダに保存した後、
Run – Debug Configurations で SVD Pathのタブを選択し、Browseボタンから RP2040.svd を指定します。
(私の場合はSDKをインストールしているので以下のように設定しました)

PC側でTera Termの設定を行う
PCアプリのTera Termを起動し新しい接続画面でシリアルを選択し、ポートに適切なCOMポートを選択します。
お持ちでない方はサイトからダウンロードしてインストールしてください。

設定 – シリアルポート でスピートを 115200 に設定します。(それ以外は以下の設定)

プログラムを動かしてみる
Run – Debug History から pico_tryknl Debug を選択しResumeボタンが緑色になったらボタン(またはF8キー)を押してプログラムを実行します。
Tera Termに hello,world と表示されれば成功です。

UARTの解説
今回は kernelフォルダとその下にsyslib.cが追加になっています。
syslib.cにはUART0の関数が記述されているので見ていきましょう。
資料は RP2040データシート をご覧になってください。
UARTはデータシートの4.2項を参照してください。
/* UART0の初期化 */
void tm_com_init(void)
{
out_w(UART0_BASE+UARTx_IBRD, 67); /* ボーレート設定 */
out_w(UART0_BASE+UARTx_FBRD, 52);
out_w(UART0_BASE+UARTx_LCR_H, 0x70); /* データ形式設定 */
out_w(UART0_BASE+UARTx_CR, UART_CR_RXE|UART_CR_TXE|UART_CR_EN); /* 通信イネーブル */
}
UARTの各レジスタについては 4.2.8 List of Registers をご覧になってください。
67 , 52 の値は通信速度を 119,200bpsにする際の設定値になります。
ただしペリフェラルの動作クロックを125MHzとした場合です。
クロックは boot フォルダ下の reset_hdr.c – init_clock()関数で 125MHz を設定しています。
UARTx_IBRD : クロックを割る数値の整数部を指定します。
UARTx_FBRD : クロックを割る数値の実数部を指定します。
計算のイメージは 4.2.7.1 Baud Rate Calculation の項が参考になります。
UARTx_LCR_H : 0x70 は データ長 8ビット、FiFo イネーブル パリティなし を指定しています。
UARTx_CR : UART及び送受信を有効に設定しています。
/* デバッグ用UART出力 */
UINT tm_putstring(char* str)
{
UINT cnt = 0;
while(*str) {
while((in_w(UART0_BASE+UARTx_FR) & UART_FR_TXFF)!= 0); /* 送信FIFOの空き待ち */
out_w(UART0_BASE+UARTx_DR, *str++); /* データ送信 */
cnt++;
}
return cnt;
}
送信前にフラグレジスタの TXFF ビット(FiFo Full)を見て、フル(いっぱい)であれば待ちます。
out_w()はデータレジスタに1バイトずつデータを書き込んでいます。
ペリフェラルレジスタの参照
svdファイルを指定することでペリフェラルレジスタの値を参照することができます。
Window – Show View – Peripherals を選択すると右側のペインに Peripherals が表示されるので UART0 にチェックを入れます。
そうすると下のペインのMemoryタブに UART0 のレジスタが出てきます。
値を確認したいレジスタの左の > をクリックすると値を確認することができます。
ボーレート設定した値は10進数です。表示が16進数の場合には注意が必要です。

もしMemoryタブが表示されない場合には、Window – Show View – Memory を選択してください。
いかがでしたか?
皆さんの環境では、Tera Termに表示することができましたか?
お疲れさまでした。
この記事のつづきは こちら です。