ベアメタルで高速I/Oに挑戦、LPC1114の実力に迫る「mbed」で始めるARMマイコン開発入門(12)(3/4 ページ)

» 2015年09月11日 07時00分 公開
[今岡通博MONOist]

マシンサイクル検証

 6.87MHzですから一周期が約146nsとなります。LPC1114のクロックが48MHZとすると7サイクルになります。よってこのループを1回実行するのに7サイクル必要だったことになります。

 マシンサイクルの「7」を手掛かりに、上記のCソースからアセンブラのコードを推測してみましょう。下のコードが推測したアセンブラーソースです。

 各レジスターには以下の値が入っているものとします。

 ;RO = GPIO0DATA
 ;R3 = 0x80
 ;R4 = 0x00
 .loop:
 str  r3, [r0, #0]  ;0x80をGPIO2DATAに書き込みますのでPIO0_7がHighになります。
 str  r4, [r0, #0]  ;0x00をGPIO2DATAに書き込みますのでPIO0_7がLowになります。
 b    .loop         ;loopに戻る

 ここで登場するR0、R3、R4はCPU内のレジスタです。C言語でいえば32bit長の変数のようなものです。GPIODATAはGPIO0のDATAレジスタのアドレスを示します。これはポインター変数だと思ってください。

 GPIO0のDATAレジスターの各BitはGPIO0のそれぞれのPINに対応しています。例えばbit7はLPC1114FN28/102の28番ピンに対応しています。GPIO0のDATAレジスタの7bit目を1にすれば28番ピンの出力はHighになります。よってこのレジスタに0x80を書き込めば28番ピンの出力はHighになり、0x00を書き込めば出力はLowになります。

 R0にGPIO0のDATAレジスターのアドレスが入っているものとします。また、R4には0x80、R3には0が入っているものとします。ただしCPU内部のレジスターの割り当てが必ずしもこのようになっているとは限りません。

 .loop:はループの先頭番地のラベルです。str r4, [r0, #0] はR4の内容を[R0,#3]に書き込んでいます。R4には0x80が入っていますので、それを[R0,#3]に書き込むということなのですが、問題は[R0,#0]の解釈です。

 この[]はC言語でいうとポインタのようなのもで、その中身が示すアドレスが指し示す場所を表しています。それではカッコの中身を見てみましょう。”R0,#0”となっています。ROにはGPIO0DATAのアドレスが入っています。それに#0が付いています。#0は配列の添え字のようなものと考えて結構です。

この場合は0ですので、”R0,#0”はGPIO0DATAのアドレスになります。そしてこれに[]が付きますので、GPIO0DATAのアドレスにマッピングされたレジスタを指します。そしてstr命令は左の項を右の項に転送するという命令ですから、R4すなわち0x80をGPIO0DATAにマッピングされたレジスタへ書き込むことになります。結果として、先に説明したようにGPIO0のDATAレジスターのbit7が1になりますので、LPC1114の28番ピンの出力はHighとなります。

 str r3, [r0, #0] は同様にR3に入っている0をGPIO0のDATAレジスターに書き込みますので、LPC1114の28番ピンの出力はLowになります。b .loopは先ほどのループの先頭番地付けたラベルにジャンプします。よって、以下の3つの命令が繰り返されることになります。

 str  r4, [r0, #0]
 str  r3, [r0, #0]
 b    .L1

 ここで各命令を実行する際のクロック数を見ていきます。上の2つのstr命令はそれぞれ2サイクル、bは3サイクルとなります。よってこのループ1回分のクロック数は7クロックとなり、48MHzのクロック動作時には、約146ns周期のループとなるのです。

Copyright © ITmedia, Inc. All Rights Reserved.