2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Synthesijerで作ったモジュールをMessagePack-RPCで制御する(MessagePack-Ruby編)

Posted at

##はじめに

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

##クライアントのコード例

accumulator_server.rb
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
```
##テスト用スクリプト

```ruby:test.rb
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)](https://github.com/ikwzm/msgpack-vhdl)
[MessagePack for VHDL Examples (https://github.com/ikwzm/msgpack-vhdl-examples)](https://github.com/ikwzm/msgpack-vhdl-examples)
[MessagePack-RPCを使ってFPGAを制御](http://qiita.com/ikwzm/items/2644c6e50a7049c75d49)
[Synthesijerで作ったモジュールをMessagePack-RPCで制御する(アーキテクチャ編)](http://qiita.com/ikwzm/items/6cb623b057a687ff4a8e)
[Synthesijerで作ったモジュールをMessagePack-RPCで制御する(IP-Package編)](http://qiita.com/ikwzm/items/924fc3fd59bdf7da55a2)
[Synthesijerで作ったモジュールをMessagePack-RPCで制御する(ZYNQ論理合成編)](http://qiita.com/ikwzm/items/0254f1d49602095b5cde)
[Synthesijerで作ったモジュールをMessagePack-RPCで制御する(TTYドライバ編)](http://qiita.com/drafts/533b905f7d1eb2e6c4d5)

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?