Atlas-SoC 最小構成 ソフト編

# やること
[ハード編](http://qiita.com/new3bon/items/4fa422c7d63205ae9e4e)の続き
作ったFPGAデータをGHRD SDカードで動くようにする。
ターゲットコンパイルで簡単なサンプルを動かす。
ハード編を書いたら思いのほか長くなったので今回は簡単に。
bootloader,u-boot,kernel,device-treeはそのままでLEDを制御する。
# SDカードの作成
[atlas_sdcard_v1.1.img](http://releases.rocketboards.org/release/2015.10/atlas/atlas_sdcard_v1.1.img.tgz)をダウンロードしてそのまま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を変えても普通に起動した。[以前調べたように](http://qiita.com/new3bon/items/134a75793f0d36ecdeef)、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](http://rocketboards.org/foswiki/view/Documentation/EmbeddedLinuxBeginnerSGuide)によると
![map](http://rocketboards.org/foswiki/pub/Documentation/EmbeddedLinuxBeginnerSGuide/igp_540e4d3797fa4c88fceb4a756b355fd0_11-addresesspace.png)
![adrs](http://rocketboards.org/foswiki/pub/Documentation/EmbeddedLinuxBeginnerSGuide/igp_a81299ea09191720d4db92631ecf4c93_11-baseaddresses.png)

0xFF20_0000　～　0xFF40_0000に現れるようだ。
今回はデバイスドライバを作らずにmmapでこれを直接触ることにする。
ソースコードはサンプルを適当に変更してこんな感じ

``` lw.c
#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)が読み出せた。
このアプリで簡単に自分の作った回路にアクセスできることが確認できた。