本講座は、ルネサスエレクトロニクス社(以降、ルネサス)のArm® Cortex®-Mプロセッサ内蔵マイコン RAファミリを使った初心者向けのマイコン入門講座であり、超基本的なマイコンに関する知識を既に習得されている方を対象としています。
超基本的なマイコンに関する知識を学ぶ場合は、APSのWebinar「 マイコンとは何?|マイコン超入門【第1部】」から始めて、「 テキスト応用実習|マイコン超入門【第5部】」までを学習してください。
本講座のゴール
- マイコンの基本的な使い方を理解する。
- マイコンの基本的な仕組みを、周辺機能ごとに理解する。
- マイコンの基本的な動作を、周辺機能ごとに理解する。
本講座の構成
第1回:開発ツール
第2回:CPU(Cortex-M)
第3回:汎用I/O
第4回:割り込み
第5回:汎用タイマ
第2回:CPU(Cortex-M)の内容
- そもそもCPUとは何か?を理解する。
- CPUの演算の流れを理解する。
- 演算以外のCPUの仕事の内容を理解する。
使用機材のご案内
本ハンズオンワークショップを実機にて体験いただくためには、EK-RA6M5 評価キットとPCが必要となります。
CPU(Central Processing Unit)
CPUはCentral Processing Unitの略で、日本語で言うと中央処理装置です。入出力機器(周辺機能)を制御してデータを受け取り、演算処理して結果を出力します。
マイコンなどのデジタル回路においては、演算を行う時に、データを一時的に保持する必要があり、レジスタ(Register)と呼ばれる記憶回路が使われます。それは、フリップフロップなどの回路を用いてデータを保持します。メモリもデータを保持するのに使われますが、ある特定の目的に使われる記憶回路をレジスタと呼びます。
CPUの中にあって、演算データを一時的に保管するレジスタには大きく2つの方式があります。汎用レジスタとアキュムレータです。一方、周辺機能(タイマ、UART、A-Dコンバータなど)の設定値や測定結果を格納するレジスタは「周辺レジスタ」などと呼ばれています。呼び方に正式なルールは無く、各マイコンで異なります。ルネサスエレクトロニクスのRAシリーズなどで搭載しているArm社のCortex-Mプロセッサは、汎用レジスタ方式です。
アキュムレータも汎用レジスタと同じく、データを保持する回路です。汎用レジスタの場合は複数のレジスタがあり、ALU(Arithmetic and Logic Unit)などを介してレジスタ間の演算ができますが、アキュムレータは1つしかなく、演算は必ずアキュムレータとメモリ間で行われます。
そして演算結果は、アキュムレータに入ります。マイコンによってはメモリにも入ります。アキュムレータの意味は、「蓄積する人(物)」、「累算器」、「積算器」、「加算器」です。演算結果が必ずアキュムレータに入るので、足し算を繰り返すと、演算結果が順次累積され、この名前が使われるようになりました。汎用レジスタ方式に比べ、回路が簡単になるというメリットがあります。
最近では、汎用レジスタ方式がほとんどのマイコンで採用されていますが、10年から20年前くらいのマイコンでは、アキュムレータ方式が採用されている製品があります。

図2:汎用レジスタ方式とアキュムレータ方式
CPUの内部構成は、各マイコンメーカの企業秘密なので、公開されることはありませんが、ここでは、筆者が過去に設計したCPUの構成を、わかりやすいように簡素化して示しました。さらに、イメージをつかみやすいように、大まかな要素だけ書き出しています。
汎用レジスタ方式とアキュムレータ方式では演算装置(Execution Unit)の内部構成が異なるだけで、その他の構成要素は同じです。違いが分かりやすいように左右に並べてみました。
メモリ(フラッシュ・メモリなど)から読み出された命令コードは一度「FIFO」(プリフェッチバッファ)に格納されます。FIFOとは、First In First Outの頭文字です。読み方は人によって異なり、ファイフォー、フィーフォーなどと読まれることが多いようです。日本語にすると「先入れ先出し」ですが、あまり日本語で使われることはありません。最初に入ってきたものを順番に処理する方式のバッファメモリ、すなわち一時的にデータを保管するメモリです。
プリフェッチバッファのプリフェッチ(pre-fetch)とは、日本語で「事前読み込み/読み出し」です。データを前もって読み出しておき、保管しておくバッファメモリです。高速なメモリを使用して、演算性能の向上を目的としています。
デコーダとは、命令を解読する機能です。FIFOから命令を順番に読み出して、何の命令か判別します。そして、その命令の機能に従って、演算装置に命令信号を出します。
演算装置(Execution Unit)はその名の通り、演算を行う装置です。この装置には汎用レジスタまたはアキュムレータとALUやシフタなどの演算機能が入っています。なお、ALUは算術演算、論理演算を受け持ち、シフタはデータをシフトする(ずらす)操作やローテート(循環)します。

図3:ブロック図
CPUの演算の流れを、汎用レジスタ方式を例にして説明します。演算手順は、次の7つです。
①メモリ(フラッシュ・メモリなど)から命令コードを読み込みます。
②命令コードを解読(デコード)します。
③演算装置に演算指令を出します。
④演算するデータを内部バスに乗せます。
⑤演算を行います。
⑥演算結果を内部バスに乗せます。
⑦演算結果を汎用レジスタかメモリに格納します。

図4:演算の流れ
次に、各手順を順番に説明していきます。
メモリ(フラッシュ・メモリなど)の中にはマイコンが実行する命令が入っています。算術演算なら、足し算、引き算などがあります。論理演算ならAND、OR、XORなどです。
例えば、足し算を行う場合、足し算という命令を二進数の番号(0と1のパターン)で定義します。番号をいくつにするかは、マイコンの開発者が自由に決めることができます。ここでは「足し算をしろ」という番号(命令コード)を「00000001」と決めます。図中で数字の最後についている小文字のbはバイナリ(2進数)の数字の意味です。
次に何と何を足すかを定義します。ここでは足し算の命令コードの次に来る8ビットコードの最初の4ビットと後半の4ビットが汎用レジスタの数字を表すことにします。そして汎用レジスタのレジスタ1とレジスタ2を計算することにします。次に、演算結果をどこに入れるかを定義します。
さらに次の8ビットが演算結果を入れるレジスタの番号を表わすように定義します。ここでは、説明を簡単にするために、これも汎用レジスタにして、レジスタ3に入れることにします。すなわち、メモリの中には次のような順番で二進数の番号(命令コード)が入ります。
・足し算の命令コード : 0000 0001
・計算する数字が入っているレジスタ : 0001 0010
・演算結果を入れるレジスタ : 0000 0011
これらは、最初にメモリから読み出されてFIFO/プリフェッチバッファに格納されます。

図5:演算の流れ(メモリから命令コードを読み込む)
FIFO/プリフェッチバッファに入っている2進数のデータを解読(デコード)します。
・0000 0001は、「足し算をしろ」
・0001 0010は、「レジスタ1とレジスタ2からデータを読み出せ」
・0000 0011は、「レジスタ3に演算結果を入れろ」

図6:演算の流れ(命令コードを解読(デコード)する)
命令に基づき演算装置は次の動作を行います。
・足し算をしろ
⇒ ALUをXOR(足し算モード)にします。
・レジスタ1とレジスタ2からデータを読み出せ
⇒ レジスタ1とレジスタ2の出口を開けて、データをバスに乗せます。
・レジスタ3に演算結果を入れろ
⇒ レジスタ3の入り口を開けてデータをバスから取り込みます。

図7:演算の流れ(演算装置に演算命令を出す)
レジスタ1の値を緑色のバスに乗せます。
レジスタ2の値を青色のバスに乗せます。

図8:演算の流れ(演算するデータを内部バスに乗せる)
ALUは足し算モード(XOR)になって青色のバスの値と緑色のバスの値を足します。

図9:演算の流れ(演算を行う)
ALUは足し算した結果をピンク色のバスに乗せます。

図10:演算の流れ(演算結果を内部バスに乗せる)
レジスタ3の入り口が開いて、濃いピンク色のバスのデータを取り込みます。これで、レジスタ1とレジスタ2を足し算して、レジスタ3に入れる演算が完了です。
アキュムレータ方式の場合は、レジスタが1個なので、レジスタ1がアキュムレータだと考えてください。基本動作は汎用レジスタ方式と同じですが、レジスタ1とメモリの値を演算してレジスタ1に入れると考えてください。

図11:演算の流れ(演算結果を汎用レジスタかメモリに格納する)
今回は入門講座なので、CPUの主な仕事である演算に着目しましたが、その他に、次に書かれた仕事も担っています。
・開発ツールとのインタフェース
・高機能な演算(浮動小数点など)
・セキュリティ管理
・割り込み処理
・メモリ管理
・バスインタフェース
今回はこれらの機能について細かい説明は行いませんが、次の章の「実際のCPU」で、簡単に説明します。
実際のCPU(Cortex-M33)
ここではArm社のオリジナルCPUのCortex-M33を例にして、実際のCPUについて解説します。
下図は、RA6M5 グループユーザーズマニュアル ハードウェア編から抜粋したCortex-M33のブロック図と、概要説明です。Cortex-M33は、機能的な階層に分かれていて、コアの部分が「Cortex-M33コア」、コアに付帯する機能で「Cortex-M33プロセッサ」、さらに、外部とのインタフェース機能でCortex-M33を構成しています。

図12:Cortex-M33のブロック図
演算以外のCPUの仕事は、機能ごとに区切ると下図のようになります。
・開発ツールとのインタフェース
・高機能な演算(浮動小数点など)
・セキュリティ管理
・割り込み処理
・メモリ管理
・バスインタフェース

図13.Cortex-M33の機能説明
ここから、各機能について簡単に説明します。
開発ツールとのインタフェースは、CPUが司ります。JTAG/SWDとはCortex-Mプロセッサ特有の通信インタフェースです。この通信機能を使って、マイコンと開発ツールで、制御信号のやり取りをします。

図14:Cortex-M33の機能説明(開発ツールとのインタフェース)
高機能な演算を行うユニットです。FPUとは浮動小数点演算ユニット(Floating-Point Unit)です。

図15:Cortex-M33の機能説明(高機能な演算)
セキュリティ管理とは、マイコンの内部情報や、メモリに保存されている機密情報などを、外部の攻撃(ハッキング)から守る機能です。

図16:Cortex-M33の機能説明(セキュリティ管理)
割り込みとは 何かしらのイベントをきっかけに CPUが現在実行しているプログラムを一時的に中断してそのイベントに関連する処理を行うことです。

図17:Cortex-M33の機能説明(割り込み処理)
Cortex-Mプロセッサの場合、メモリ管理とは、予期せぬメモリ・アクセスから、メモリデータを守ることです。外部からの攻撃(ハッキング)だけでなく、ユーザーのプログラムミスや、マイコンの誤動作によるアクセスからも防ぎます。

図18:Cortex-M33の機能説明(メモリ管理)
バスインタフェースは、CPUの内部バスとCPU外のマイコンのバスとのインタフェースを制御します。

図19:Cortex-M33の機能説明(バスインタフェース)
実習
CPU演算
ルネサスエレクトロニクスRA6M5シリーズを使って、実際に演算をしてみます開発ツールは、ルネサスエレクトロニクスのe2 studioを使います。
最初に、3つの変数を定義して、各変数がCPUの汎用レジスタに割り当てられていることを確認します。3つの変数を使って演算して、演算結果が汎用レジスタに反映されていることを確認します。
《手順》
- 3つの変数a、b、cを定義します。
- 各変数に初期値を入れます(aに3を、bに2を、cに1を入れる)。
- 汎用レジスタ1(r1)にaが、汎用レジスタ2(r2)にbが、汎用レジスタ3(r3)にcが割り当てられていることを確認します。
- 演算(c=a+b)を行い、cの値、すなわち汎用レジスタ3(r3)の値が初期値1から、演算結果の5に変わる事を確認します。
(注意)e2 studio内で、汎用レジスタは小文字のr(r0~r12)を使って表示されていますが、一般的なCortex-Mプロセッサの説明では大文字のR(R0~R12)が使われています。ここでは、e2 studio内の場合は小文字のrを使い、一般的な説明の場合は大文字のRを使います。
Cortex-Mプロセッサには、32ビットの汎用レジスタが13個(R0~R12)あります。R0~R7を下位レジスタ、R8~R12を上位レジスタと呼んでいます。
プログラム(C言語)で変数を定義すると、各変数は各々汎用レジスタのどれかに割り当てられます。各レジスタの初期値は定まっていないので、最初に初期値を設定する必要があります。

図20:Cortex-Mの汎用レジスタ
Windowsのスタートメニューからe2 studioを開きます。ワークスペースのフォルダを指定する画面が出るので、デフォルトか任意のフォルダを入力します。今回はCPU_trialにします。
Welcome to e2 studioの画面が表示されたら、画面の右上隅にある[隠す]アイコンを選択して画面を隠します。

図21:e2 studioの起動
ここからRenesas RAプロジェクト(RAファミリ用プロジェクト)を作っていきます。
メニューバーの「ファイル」→「新規」→「C/C++ Project」→「Renesas RA」のように移行します。
Templates for Renesas RA Projectという新しいウィンドウが表示されます。
Renesas RA C/C++ Projectを選択し、[次へ(N)>]をクリックしますプロジェクトコンフィギュレータが起動します。プロジェクトの名前を入力します。
Device and Tools Selectionの画面で、ボードを選択します。EK-RA6M5を選択すると、デバイスがR7FA6M5BH3CFCに自動で切り変わります。ツールチェーンは、「GNU Arm Embedded」を選択します。Project Type selectionの画面で、TrustZoneのプロジェクトか、TrustZoneでない (Flat(Non-TrustZone))プロジェクトかを選択できます。今回は、Flat(Non-TrustZone)プロジェクトを選択します。

図22:プロジェクトの作成(1)
Preceding Project or Smart Bundle Selectionの画面ではNoneを選択します。
Build Artifact(アーティファクト) and RTOS Selectionの画面ではExecutable(エクゼキュータブル)を選択し、[No RTOS]を選択します
Project Template Selectionの画面で[Bare Metal – Minimal]を選択します。
パースペクティブを開きます。パースペクティブが開いたら、コードを生成します。
生成されたコードはプロジェクト・エクスプロ―ラの中のsrcを開いて、その中のhal_entry.cをダブルクリックすれば、現れます。/* TODO: add your own code here */の行が有ることを確認してください。

図23:プロジェクトの作成(2)
/* TODO: add your own code here */の下に、次のコードを書き込みます。
volatile int a=3;
volatile int b=2;
volatile int c=1;
c=a+b;
while (1) {}
intは、整数の変数を定義する時に使います。整数の変数aに3を、bに2を、cに1を入れます。aとbを足してcに入れます。Cの初期値1が計算後に5になるはずです。

図24:ユーザーコードを記入する
上部のツールバーにある小さな「ハンマー」記号をクリックするとプロジェクトがビルドされますビルドとはC言語をマシン語に変換することです。
完了するとビルド結果がCDTビルド・コンソールに表示されます。「Build Finished. 0 errors, 1 warnings. (took 838ms)」と書かれていますので、エラー無くビルドされました。Warningが1つありますが、これは「変数cを定義したけど使っていないよ。」という事です。プログラムの動作に影響はありませんので、このままにしておきます。これでプロジェクトを実行する準備が整いました.

図25:プロジェクトのビルド
PCとEK-RA6M5評価ボードをUSBケーブルで接続すると、USBから給電されて、ボードが起動します。新品の場合、動作するとすぐに、あらかじめプログラムされたデモプログラムが実行され、1秒間隔で青色のLED1が10%の光度で点滅します。緑色のLED2は、フル強度で常時オンになり、赤色のLED3はオフになります。
オレンジ色のデバッグLED(LED5)が点滅し続けると、評価キットはJ-Linkドライバを検出できていません。その場合は、まず、USBケーブルをボード右側のデバッグポートJ10に接続されていることを確認してください。左辺のUSB Full SpeedポートJ11に接続されていても、電源が供給されてLEDは同じ動作をしますが、J-Linkがつながりません。
PC側のチェックとしては、デバイスマネージャを開き、Universal Serial Busコントローラツリーを展開して、J-Linkドライバがそこにリストされていることを確認してください。もし、インストールされていない場合は、カスタムインストール機能を使用してプラットフォームインストーラを再実行してください。

図26:EK-RA6M5評価ボードとPCの接続
デバッグ記号の横にある小さな矢印をクリックし ドロップダウンリストボックスから[デバッグの構成]を選択します。
「構成の作成、管理、および実行」の画面で 左側のツリービューのRenesas GDB Hardware Debuggingの下の今回のプロジェクトの名前を選択します。
下部の[デバッグ]をクリックするとデバッガが起動します。

図27:デバッグ(1)
[パースペクティブ切り替えの確認]ダイアログが表示されたら、[切り替え]を選択します
しばらくするとデバッグ画面が開きます再開ボタンをクリックすると プログラムはmain()関数のhal_entry()の呼び出し行まで実行されます再開ボタンをもう一度クリックするとプログラムは実行を継続し演算を行います。

図28:デバッグ(2)
プログラムの実行に使った再開ボタンの隣が、中断ボタンです。これをクリックするとプログラムは一時停止します。そして、下部のレジスタタグをクリックし、汎用レジスタの表示を広げ、各汎用レジスタの値を表示させます。
右上の変数の表示と合わせると、aが汎用レジスタ1(r1)に、bが汎用レジスタ2(r2)、cが汎用レジスタ3(r3)に割り当てられて計算されているのがわかります。

図29:レジスタの確認
以上で実習は終了です
aが汎用レジスタ1(R1)に、bが汎用レジスタ2(R2)、cが汎用レジスタ3(R3)に割り当てられて計算されているのがわかりましたか?

図30.演算結果
「第2回:CPU(Cortex-M)」は、以上です。そもそもCPUは何であり、構成や役割、演算の流れ、使い方が詳しくお分かりいただけたと思います。
次回は「第3回:汎用I/O」です。汎用I/Oの構成や電気的特性、使い方について学び、実際に動作させてみます。







