e-tipsmemo

ごった煮

stringとwstringとtstring

Visual Studioで文字列を扱うとき、
以下の設定の違いで

f:id:katakanan:20180616104252p:plain
f:id:katakanan:20180616104219p:plain

TCHARの定義がかわる。
f:id:katakanan:20180616104721p:plain
参考
Tchar.h における汎用テキストのマッピング

typedef std::basic_string<TCHAR> tstring;
typedef std::basic_stringstream<TCHAR> tstringstream;
typedef std::basic_ostringstream<TCHAR> tostringstream;
typedef std::basic_istringstream<TCHAR> tistringstream;

どこかのサイトで見たが、こうしておけばどちらにでも対応できる。
(本当は最初から std::wstring で良かった)

Unicode文字セットのときの、
上の定義でのtstringはstd::wstringと同じであり、
std::stringとの相互変換方法を調べた。

見つかったサイト。
kryozahiro.hateblo.jp

このサイトではwcstombsという関数を使っているが、これはもう古くてでVisual Studio 2017ではエラーがでてしまうので
微修正した。

//std::wstring -> std::string
void narrow(const std::wstring &src, std::string &dest) {
	char *mbs = new char[src.length() * MB_CUR_MAX + 1];
	size_t i;
	wcstombs_s(&i, mbs, src.length() * MB_CUR_MAX + 1, src.c_str(), src.length() * MB_CUR_MAX + 1);

	dest = mbs;
	delete[] mbs;
}
//std::string -> std::wstring
void widen(const std::string &src, std::wstring &dest) {
	wchar_t *wcs = new wchar_t[src.length() + 1];
	size_t i;
	mbstowcs_s(&i, wcs, src.length() + 1, src.c_str(), src.length() + 1);
	dest = wcs;
	delete[] wcs;
}

多分これで良いんじゃないかとおもう。

C++ Rest SDK Visual Studio 2017 E0427 Error

WindowsでWin32のアプリを作っていたとき
http requestとかするときいいライブラリないなみたいな記憶があって
わざわざC++/CLIで、C#のHttpRequestクラスみたいなものをつかてたけども、

MicrosoftのメンテしているC++ Rest SDKという物があったらしい。
(いつのまにか?)
github.com

Visual StudioだとNuget経由で簡単にパッケージの追加と削除が可能になっていてとても良いけども
なぜかメニューバーのツールメニューからNugetの項目が消える。
意味不明だ・・・

なんとかNuget経由で、cpprestsdkをインストールする

そうしたところ、以下のようなエラーがでた。
f:id:katakanan:20180614030219p:plain

調べたところプラットフォームツールセットが新しいのがいけない?

そこで、以下を追加インストールする。
f:id:katakanan:20180614030624p:plain

そしてプロジェクトのプロパティで Visual Studio 2015 (v140)を選択する。

f:id:katakanan:20180614030957p:plain

これでビルドできた。
v141とv140で何が違うんだろうか。

Vivado fsbl build batchmode③

http://e-tipsmemo.hatenablog.com/entry/2018/06/11/000000e-tipsmemo.hatenablog.com

の続きでfsblと言っているが、
device-treeをhsiから作る。

これはそこまで苦労しなかった。

前提

WSLが入っている。とか
WSLが入っているならdevice-tree-compilerが入っているか、とか
hsiへのパスが通っているとか

tcl script


xilinxのdevice-tree-generatorのリポジトリをクローンした場所

このあとにdtcを使えば終了

dts:
	cmd.exe /c 'hsi -mode tcl -source .\dts.tcl'

dtb: dts
	$(shell dtc -I dts -O dtb -o $(dt_dir)/devicetree.dtb $(dt_dir)/system-top.dts)
	$(shell dtc -I dtb -O dts -o $(dt_dir)/devicetree.dts $(dt_dir)/devicetree.dtb)

makeの書き方・・?

Vivado fsbl build batchmode②

前回
e-tipsmemo.hatenablog.com

まだ稚拙だがとりあえず自動化できた
依存の書き方がちょっとよくわからないので、本当は更新していないのに毎回ビルドされる。
それでもSDKをいちいち立ち上げるよりは早い。
いつか直す。

構造
f:id:katakanan:20180606234510p:plain
hsi**はログファイル

makeファイルの書き方がよくわからないけどこんな感じだろうか

$(eval current_dir_name := $(notdir $(shell pwd)))
sdk_dir := "./"$(current_dir_name)".sdk"
fsbl_dir := $(sdk_dir)"/fsbl"
lib_dir := $(fsbl_dir)"/zynq_fsbl_bsp"
release_dir := $(fsbl_dir)"/Release"
USER_SRCS := $(wildcard ../src/*.c) $(wildcard ../src/*.h)
FSBL_SRCS := $(wildcard $(sdk_dir)/*.c) $(wildcard $(sdk_dir)/*.h)

.PHONY: all
all: BOOT.bin

fsbl_project: fsbl.tcl
	cmd.exe /c 'hsi -mode tcl -source .\fsbl.tcl'

libs: fsbl_project
	make -C $(lib_dir) all

executable.elf: libs $(USER_SRCS)
	$(shell cp $(USER_SRCS) ./$(fsbl_dir))
	make -C ./$(fsbl_dir) all

BOOT.bin: executable.elf
	$(shell cp ./$(fsbl_dir)/executable.elf $(release_dir)/fsbl.elf)
	$(shell cp ../bifs/* $(release_dir)/)
	$(shell sh $(release_dir)/bootgen.sh)

clean:
	rm -f $(release_dir)/*
	make -C $(lib_dir) clean
	make -C $(fsbl_dir) clean

また
bootgen,batは考えるのを諦めたので
bootgen.shを別に作ってRelease下で実行させるようにした。

#!/bin/sh
cd `dirname $0`
cmd.exe /c "bootgen.bat -image ./bootbin.bif -arch zynq -o BOOT.bin"

①tclでfsbl. fsbl_bspが生成されて、
②libsをビルドしてから
ソースコードをコピーして
④fsbl自体をビルドして、
⑤Releaseフォルダにいろんな物をコピーして
⑥bootgenでBOOT.binを生成する。

という流れ。

Vivado fsbl build batchmode①

XSDKを毎回起動するのは手間であるので自動でビルドしたいと思うのは当然である。

検索すると以下のものがとても参考になる。
Vivado SDK でZynq FSBL(First Stage Boot Loader)をビルドするTclスクリプト(hsi編)

ここにfsblを編集したものをビルドするということを想定して少し編集する。

環境準備

Windows
Vivado 2017.3(とそのSDK)
Bash on Windows

aptでgcc-arm-none-eabiをインストールしておく。

D:\Xilinx\SDK\2017.3\bin

WindowsのPATHに追加しておく。

前提

プロジェクトがある。
u-boot.elfがある。
bootbin.bifを作っておく。

//arch = zynq; split = false; format = BIN
the_ROM_image:
{
	[bootloader].\fsbl.elf
	..\..\desing_1_wrapper.bit
	.\u-boot.elf
}


VivadoからHardware Exportする。(include bitstream)
コレ自体もtclでできる。
hdfが[project_name].sdkに吐き出される。

f:id:katakanan:20180604012331p:plain
こうなっている。

Scriptの準備(とりあえず手動でコマンド確かめる)

xprがあるところに、
参考サイトのtclを少しだけ変更したtclを書く


が、SDK上でnew applicationからfsblを作成する手順に相当する。

ここに -compileオプションをつけると作成と同時にビルドし始めるが
今回はしない。
修正したfsbl_hooks.cなどをfsblプロジェクトにコピーする行

これを実行すると
f:id:katakanan:20180604010302p:plain
となる。

まずはzynq_fsbl_bsp内で依存するライブラリをビルドする。

$ make -C ./ all

その後、fsblに戻って、再びmakeする

$ make

すると、executable.elfなるELFができるので
これがGUISDKで行ったときにDebugフォルダ内にできるfsbl.elfなどと同じもの。
elfとu-boot.elfとbootbin.bifを
Releaseに移動しておく。

$ cp ./u-boot.elf ./script_build.sdk/fsbl/Release/
$ cp ./script_build.sdk/fsbl/executable.elf ./script_build.sdk/fsbl/Release/fsbl.elf
$ cp ./bootbin.bif ./script_build.sdk/fsbl/Release/

f:id:katakanan:20180604011907p:plain
あとはここで

$ cmd.exe /c "bootgen.bat -image .\bootbin.bif -arch zynq -o .\BOOT.bin"

そうすると、ReleaseのところにBOOT.binが出来上がる。
bifファイル内のパスはこのbootgen.batを起動するパスに依存している。

あとはこれらをMakefileなどにまとめて
WSL上でmakeすればOKのはず。。

fsblはgenerate_appするたびにfsblを上書きするので、編集したソースコードは別においておいて、
ビルドするときにコピーしてくる方法が良いのではないかと思う。

次回はまとめたものを書く。

DataContractJsonSerializerでList<T>をシリアライズ・デシリアライズする。

{
  "TEST": [
    {
      "name": "aaa",
      "hoge": "bbb",
      "foo": "ccc"
    },
    {
      "name": "ddd",
      "hoge": "eee",
      "foo": "fff"
    },
    {
      "name": "ggg",
      "hoge": "hhh",
      "foo": "iii"
    }]
}

こういうJSONがある。
まずこれが正しいのかチェックした
lab.syncer.jp
f:id:katakanan:20180603163359p:plain
OK

次にこれを突っ込むクラスを作るが、以下を利用
json2csharp.com
generateを押す.

public class TEST
{
    public string name { get; set; }
    public string hoge { get; set; }
    public string foo { get; set; }
}

public class RootObject
{
    public List<TEST> TEST { get; set; }
}

今回はC++/CLIで行ったので
これを少し書き換えて、

#pragma once
using namespace System;
using namespace System::Runtime::Serialization;
using namespace System::Runtime::Serialization::Json;

[DataContract]
ref class TEST
{
public:
	[DataMember]
	String^ name;

	[DataMember]
	String^ hoge;

	[DataMember]
	String^ foo;

};

[DataContract]
ref class RootObject
{
public:
	[DataMember]
	System::Collections::Generic::List<TEST^>^ test;
};

といった感じに。

書き出すとき

読み出すとき

Arty MicroBlaze ②GPIO

GPIOプログラム - fpgafpga ページ!

ここと同じではあまり意味がないので
GPIO(LED, SW)かつ
UARTを使う方法

115200にする

まずUARTのボーレートを変えるにはAXI-UARTの方法を変える他ない
f:id:katakanan:20180527232343p:plain

ソースコードに書いてあった。
f:id:katakanan:20180527232407p:plain

新しいプロジェクトを作る。

f:id:katakanan:20180527233917p:plain
Empty Application

GPIO

の使い方を知るために必要
f:id:katakanan:20180527233627p:plain

xli_printfを使うには

f:id:katakanan:20180527234040p:plain
HelloWorldサンプルから
platform.c
platform.h
platform_config.h
をコピーする。
f:id:katakanan:20180527233745p:plain

最終的な形

f:id:katakanan:20180527234123p:plain

main.c

InitializeでAXI GPIOペリフェラルを初期化して
XGpio_SetDataDirectionで出力方向を決めたら
XGpio_DiscreteWriteで出力。

XGpio_WriteRegを使えばAXI Liteのレジスタを直接いじれる。(けどアドレスの計算をするのがめんどくさそう)