やること
ハード編の続き
作ったFPGAデータをGHRD SDカードで動くようにする。
ターゲットコンパイルで簡単なサンプルを動かす。
ハード編を書いたら思いのほか長くなったので今回は簡単に。
bootloader,u-boot,kernel,device-treeはそのままでLEDを制御する。
SDカードの作成
atlas_sdcard_v1.1.imgをダウンロードしてそのままSDカードに焼く
sudo dd if=atlas_sdcard_v1.1.img of=/dev/sdb bs=1M
FPGAデータを変更する
SDカードのFAT側の
ATLAS_SOC_GHRD/output_files/ATLAS_SOC_GHRD.rbf
をハード編でできたファイルに置き換える
起動する
SDカードをAtlas-SoC(DE0 SoC)ボードに装着して起動する。
ネットワークケーブルを接続しておこう。uartって書いてあるUSB端子をPCにつなぐとminicomでlinuxターミナルを叩ける。
FPGAを変えても普通に起動した。以前調べたように、chip idでmacアドレスを決めてるのが空振るので変なMACアドレスになるかもしれないけど気にしない。
起動するとLEDがついている。たぶんGHRDのペリフェラルだと思って触ったんだろう。device-treeを書き換えれば触らなくなるけど、今回はそのまま。
rootでログインする。
gccをインストールする
ネットワークに繋がるのでソフトをダウンロードできる。これがlinuxのいいところ。
GHRDにはapt-getの代わりにopkgが入ってる。使い方は慣れ親しんだapt-getとあまり変わらない。
opkg update
opkg install gcc
これでgccが入った。
gcc -v
でバージョンが出るか見てみる。
root@atlas_sockit:~# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/gcc/arm-angstrom-linux-gnueabi/4.9.3/lto-wrappr
Target: arm-angstrom-linux-gnueabi
Configured with: /build/jenkins/angstrom-v2014.12/machine/beagleboard/build/tmpa
Thread model: posix
gcc version 4.9.3 20141031 (prerelease) (Linaro GCC 4.9-2014.11)
ちゃんと入ってる。
mmapで制御する
カスタムコンポーネントを追加したLightweight FPGA Slavesのアドレス空間はEmbedded Linux Beginners Guideによると
0xFF20_0000 ~ 0xFF40_0000に現れるようだ。
今回はデバイスドライバを作らずにmmapでこれを直接触ることにする。
ソースコードはサンプルを適当に変更してこんな感じ
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <error.h>
#include <stdint.h>
#include <sys/mman.h>
// The start address and length of the Lightweight bridge
#define HPS_TO_FPGA_LW_BASE 0xFF200000
#define HPS_TO_FPGA_LW_SPAN 0x00020000
int main(int argc, char ** argv)
{
void * lw_bridge_map = 0;
uint32_t *p,adrs,data;
int devmem_fd = 0;
int result, i;
// Check to make sure they entered a valid input value
if(argc!=2 && argc!=3)
{
printf("lw adrs [data]\n");
exit(EXIT_FAILURE);
}
// Open up the /dev/mem device (aka, RAM)
devmem_fd = open("/dev/mem", O_RDWR | O_SYNC);
if(devmem_fd < 0) {
perror("devmem open");
exit(EXIT_FAILURE);
}
// mmap() the entire address space of the Lightweight bridge so we can access our custom module
lw_bridge_map = (uint32_t*)mmap(NULL, HPS_TO_FPGA_LW_SPAN, PROT_READ|PROT_WRITE, MAP_SHARED, devmem_fd, HPS_TO_FPGA_LW_BASE);
if(lw_bridge_map == MAP_FAILED) {
perror("devmem mmap");
close(devmem_fd);
exit(EXIT_FAILURE);
}
sscanf(argv[1], "%x", &adrs);
p = (uint32_t*)(lw_bridge_map + adrs);
if(argc==3) // write
{
sscanf(argv[2], "%x", &data);
*p = data;
printf("write ");
}
else // read
{
data = *p;
printf("read ");
}
printf("adrs:%08x data:%08x\n", adrs, data);
// Unmap everything and close the /dev/mem file descriptor
result = munmap(lw_bridge_map, HPS_TO_FPGA_LW_SPAN);
if(result < 0) {
perror("devmem munmap");
close(devmem_fd);
exit(EXIT_FAILURE);
}
close(devmem_fd);
exit(EXIT_SUCCESS);
}
viとかで書くか、PCで書いた奴をSDカードに入れて、Atlas-SoCの上でコンパイルする。
gcc lw.c -o lw
実行
アプリの使い方は一つ目の引数がアドレス(lightweightでのオフセット)で二つ目があればデータとして書き込み。
./lw 00 00
でLEDを消灯
./lw 00 ff
でLEDが全点灯することが確認できた。
./lw 00
とすると最後に書き込んだデータ(ff)が読み出せた。
このアプリで簡単に自分の作った回路にアクセスできることが確認できた。