はじめに
Synthesijerで作ったモジュールをMessagePack-RPCで制御する話もいよいよ最終コーナーです。
今回は、Synthesijerで作った MessagePack-RPC サーバーを、ZYNQ+Linux 上のクライアントから呼び出す例を示します。
クライアントには MessagePack-Ruby を使います。他の言語でも出来るかもしれません。
ただ、現在、私の環境(ZYNQ+Debian8(jessie))では、MessagePack-RPC-Ruby のインストールが上手くいかなかったので、今回はMessagePack-RPC-Rubyは使っていません。
準備
次の ruby パッケージが必要です。
- msgpack-ruby
- serialport
これらをインストールします。Debian8(jessie)ではこれらのインストールはgem では失敗するので apt-get を使います。
shell# apt-get install ruby-msgpack
shell# apt-get install ruby-serialport
クライアントのコード例
require 'msgpack'
require 'serialport'
class AccumulatorServer
def initialize
@port = SerialPort.new("/dev/zptty0", 38400)
@port.read_timeout = 1000
@port.flow_control = SerialPort::HARD
@unpacker = MessagePack::Unpacker.new(@port)
@msgid = 0
end
def call(method, args)
@msgid = (@msgid+1) % 256
req = [0, @msgid, method, args].to_msgpack
@port.write(req)
@unpacker.each do |obj|
type, resid, error, result = obj
if (error == nil) then
return result
else
puts error
return nil
end
break
end
end
def get_regs
result = call('$GET', [{"reg" => nil}])
if result != nil
return result[0]["reg"]
else
return nil
end
end
def set_regs(arg)
result = call('$SET', [{"reg" => arg}])
end
def add(arg)
return call('add', [arg])
end
end
テスト用スクリプト
require_relative 'accumulator_server'
acc = AccumulatorServer.new
rnd = Random.new
acc_reg=1
acc.set_regs(acc_reg)
(0..1000).to_a.each do |n|
num = rnd.rand(0..10000)
curr_reg = acc.get_regs
add_reg = acc.add(num)
next_reg = acc.get_regs
acc_reg = acc_reg + num
status = ((acc_reg == next_reg) && (acc_reg == add_reg)) ? "OK" : "NG"
puts "#{status} : reg = #{curr_reg}; add(#{num}) => #{add_reg}; reg = #{next_reg}"
end
acc_reg=1
acc.set_regs(acc_reg)
(0..1000).to_a.each do |n|
num = rnd.rand(-10000..0)
curr_reg = acc.get_regs
add_reg = acc.add(num)
next_reg = acc.get_regs
acc_reg = acc_reg + num
status = ((acc_reg == next_reg) && (acc_reg == add_reg)) ? "OK" : "NG"
puts "#{status} : reg = #{curr_reg}; add(#{num}) => #{add_reg}; reg = #{next_reg}"
end
acc.call("sub", [1])
acc.call("add", 1)
acc.call("add", "a")
test.rb を ruby で実行します。
shell% ruby test.rb
:
(中略)
:
OK : reg = -4898220; add(-3407) => -4901627; reg = -4901627
OK : reg = -4901627; add(-6936) => -4908563; reg = -4908563
NoMethodError
ArgumentError
ArgumentError
参照
MessagePack for VHDL (https://github.com/ikwzm/msgpack-vhdl)
MessagePack for VHDL Examples (https://github.com/ikwzm/msgpack-vhdl-examples)
MessagePack-RPCを使ってFPGAを制御
Synthesijerで作ったモジュールをMessagePack-RPCで制御する(アーキテクチャ編)
Synthesijerで作ったモジュールをMessagePack-RPCで制御する(IP-Package編)
Synthesijerで作ったモジュールをMessagePack-RPCで制御する(ZYNQ論理合成編)
Synthesijerで作ったモジュールをMessagePack-RPCで制御する(TTYドライバ編)