origen_link 0.1.2 → 0.2.0.pre0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7b819630a6b626e6c330114c40f70108f7850657
4
- data.tar.gz: 51a6ddf9796af5b1569c3b61a9e8f8d2b3c955c9
3
+ metadata.gz: b3d2af884ce3e644373c8823c0411d1822eef7a0
4
+ data.tar.gz: a89e4bc1a123d78896fb60f7bb5acecd50b88752
5
5
  SHA512:
6
- metadata.gz: 379e3b256c9becd833c2d2fd76fcfba2c3b1b7c3f4922986e6ca8523eb0bda24919366189c06695577aea979be102a7a2a0fb84e4b8f55973d22cd14927b6117
7
- data.tar.gz: 222fdaf6916110972cacb9a25f1f2cf0b60ba8406770f8518f8777b00e771c1755eff011ecc46465c4dac7f5035e5ff19eb57ed8dd1a4acf60a423d4db174941
6
+ metadata.gz: b1e98d576f6ccd3f59f2cc08b26cd4572b72bd458a7ef1449851d0cf4e2d143329c6381f608a7e15d5d2e29a39721f702feb0d5b2907e3c1b19dda4817dbd482
7
+ data.tar.gz: 55aff1223d4ed62bf407c5fa6c68e5c51a4be44c315df30b39344aa9f5e94cd2abf00f39f895326cce1c005101a29f1becd0a5ff2aaa2462abccf11486eee5cb
@@ -6,14 +6,60 @@ require 'origen_link/server/sequencer'
6
6
  server = TCPServer.open('', 12_777)
7
7
  puts 'server started'
8
8
  pinsequencer = OrigenLink::Server::Sequencer.new
9
+ remoteuser = ''
10
+ remotehost = ''
11
+ sessionactivity = Time.now
12
+ sessionactive = false
9
13
 
10
14
  loop do
11
15
  client = server.accept
12
- response = ''
13
- while (message = client.gets) != "\n"
14
- # process the message
15
- # for now only pin_ messages are accepted
16
- response = response + pinsequencer.processmessage(message.chomp) + "\n"
16
+ thisuser = client.gets.chomp
17
+ thisremotehost = client.peeraddr[3]
18
+
19
+ # for now assume that any session lasting longer than 20 minutes has timed out (will happen if the origen side app is killed or stopped at a breakpoint with no activity)
20
+ if (Time.now - sessionactivity) > 1200
21
+ sessionactive = false
22
+ end
23
+
24
+ change_in_user = false
25
+
26
+ # if there is no active session running allow one to start
27
+ unless sessionactive
28
+ #flag any change in host machine or user for collision detection
29
+ change_in_user = true unless (remoteuser.eql? thisuser) && (remotehost.eql? thisremotehost)
30
+ remoteuser = thisuser
31
+ remotehost = thisremotehost
32
+ end
33
+
34
+ # always return whether or not the user has been changed (for collision detection)
35
+ if change_in_user
36
+ response = "user_change:user_change\n"
37
+ else
38
+ response = "\n"
39
+ end
40
+
41
+ # if this connection is from the active user\host machine, then process the information
42
+ if (remoteuser.eql? thisuser) && (remotehost.eql? thisremotehost)
43
+ while (message = client.gets) != "\n"
44
+ # process the message
45
+ # for now only pin_ messages are accepted
46
+ if message =~ /session_end/
47
+ sessionactive = false
48
+ response = response + "session_end:session_end\n"
49
+ else
50
+ sessionactive = true
51
+ response = response + pinsequencer.processmessage(message.chomp) + "\n"
52
+ end
53
+ end
54
+ sessionactivity = Time.now
55
+ else
56
+ checkmessage = client.gets.chomp
57
+ if checkmessage =~ /session_kill/
58
+ sessionactive = false
59
+ response = response + "Terminated: session from #{remoteuser} at IP address #{remotehost} inactive for #{Time.now - sessionactivity} seconds has been killed\n"
60
+ else
61
+ response = response + "Busy: server is in use by #{remoteuser} from IP address #{remotehost}\n"
62
+ end
17
63
  end
18
64
  client.write(response)
19
65
  client.close
@@ -40,6 +40,10 @@ class OrigenLinkApplication < Origen::Application
40
40
 
41
41
  config.semantically_version = true
42
42
 
43
+ config.shared = {
44
+ command_launcher: 'config/shared_commands.rb'
45
+ }
46
+
43
47
  # An example of how to set application specific LSF parameters
44
48
  #config.lsf.project = "msg.te"
45
49
 
@@ -0,0 +1,40 @@
1
+ # The requested command is passed in here as @command
2
+ case @command
3
+
4
+ when "link:listen"
5
+ t = Thread.new do
6
+ OrigenLink::Listener.run!
7
+ end
8
+ Thread.new do
9
+ # Get the current host
10
+ host = `hostname`.strip.downcase
11
+ if Origen.os.windows?
12
+ domain = '' # Not sure what to do in this case...
13
+ else
14
+ domain = `dnsdomainname`.strip
15
+ end
16
+ port = 20020
17
+ puts ''
18
+ sleep 0.5
19
+ puts
20
+ puts
21
+ puts "*************************************************************"
22
+ puts "Point your OrigenLink app to: http://#{host}#{domain.empty? ? '' : '.' + domain}:#{port}"
23
+ puts "*************************************************************"
24
+ puts
25
+ puts
26
+ end
27
+
28
+ # Fall through to the Origen interactive command to open up a console
29
+ @command = "interactive"
30
+
31
+ # Always leave an else clause to allow control to fall back through to the Origen command handler.
32
+ # You probably want to also add the command details to the help shown via 'origen -h',
33
+ # you can do this bb adding the required text to @plugin_commands before handing control back to
34
+ # Origen.
35
+ else
36
+ @plugin_commands << <<-EOT
37
+ link:listen Open a console and listen for OrigenLink requests over http (i.e. from a GUI)
38
+ EOT
39
+
40
+ end
@@ -1,8 +1,8 @@
1
1
  module OrigenLink
2
2
  MAJOR = 0
3
- MINOR = 1
4
- BUGFIX = 2
5
- DEV = nil
3
+ MINOR = 2
4
+ BUGFIX = 0
5
+ DEV = 0
6
6
 
7
7
  VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
8
8
  end
@@ -1,4 +1,4 @@
1
1
  require 'origen'
2
2
  require 'socket'
3
-
4
3
  require 'origen_link/vector_based'
4
+ require 'origen_link/listener'
@@ -0,0 +1,78 @@
1
+ require 'sinatra/base'
2
+ module OrigenLink
3
+ class Listener < Sinatra::Base
4
+ def self.port
5
+ @port || 20_020
6
+ end
7
+
8
+ def self.environment
9
+ @environment || :production
10
+ end
11
+
12
+ def self.target_object
13
+ @target_object || dut
14
+ end
15
+
16
+ def self.run!(options = {})
17
+ @port = options[:port]
18
+ @environment = options[:environment]
19
+ @target_object = options[:dut]
20
+ super
21
+ end
22
+
23
+ def target_object
24
+ self.class.target_object
25
+ end
26
+
27
+ def expand_path(path)
28
+ path.split('.').each do |p|
29
+ if p =~ /(.*)\[(\d+)(:(\d+))?\]$/
30
+ msb = Regexp.last_match(2).to_i
31
+ lsb = Regexp.last_match(4).to_i if Regexp.last_match(4)
32
+ yield Regexp.last_match(1)
33
+ if lsb
34
+ yield '[]', msb..lsb
35
+ else
36
+ yield '[]', msb
37
+ end
38
+ else
39
+ yield p
40
+ end
41
+ end
42
+ end
43
+
44
+ get '/hello_world' do
45
+ 'Hello there'
46
+ end
47
+
48
+ get '/dut_class' do
49
+ target_object.class.to_s
50
+ end
51
+
52
+ post '/register' do
53
+ t = target_object
54
+ expand_path(params[:path]) do |method, arg|
55
+ if arg
56
+ t = t.send(method, arg)
57
+ else
58
+ t = t.send(method)
59
+ end
60
+ end
61
+ t.write!(params[:data].to_i)
62
+ nil
63
+ end
64
+
65
+ get '/register' do
66
+ t = target_object
67
+ expand_path(params[:path]) do |method, arg|
68
+ if arg
69
+ t = t.send(method, arg)
70
+ else
71
+ t = t.send(method)
72
+ end
73
+ end
74
+ t.sync
75
+ t.data.to_s
76
+ end
77
+ end
78
+ end
@@ -2,41 +2,7 @@
2
2
  # using exported file objects. If the pin is not exported, it
3
3
  # will be exported when a pin is initialized
4
4
  #
5
- # initialize:
6
- # description - This method will execute system command
7
- # "sudo echo ionumber > /sys/class/gpio/export"
8
- # to create the IO file interface. It will
9
- # set the direction, initial pin state and initialize
10
- # instance variables
11
- # ionumber - required, value indicating the pin number (BCM IO number,
12
- # not the header pin number)
13
- # direction - optional, specifies the pin direction. A pin is
14
- # initialized as an input if a direction isn't specified.
15
- #
16
- #
17
- # out:
18
- # description - Sets the output state of the pin. If the pin
19
- # is setup as an input, the direction will first
20
- # be changed to output.
21
- #
22
- #
23
- # in:
24
- # description - Reads and returns state of the pin. If the pin
25
- # is setup as an output, the direction will first
26
- # be changed to input.
27
- #
28
- #
29
- # update_direction:
30
- # description - Sets the pin direction
31
- #
32
- # direction - specifies the pin direction. A pin is
33
- # initialized as an input if a direction isn't specified.
34
- #
35
- # Valid direction values:
36
- # :in - input
37
- # :out - output
38
- # :out_high - output, initialized high
39
- # :out_low - output, initialized low
5
+
40
6
  module OrigenLink
41
7
  module Server
42
8
  class Pin
@@ -47,6 +13,17 @@ module OrigenLink
47
13
 
48
14
  attr_reader :gpio_valid
49
15
 
16
+ # initialize:
17
+ # description - This method will execute system command
18
+ # "sudo echo ionumber > /sys/class/gpio/export"
19
+ # to create the IO file interface. It will
20
+ # set the direction, initial pin state and initialize
21
+ # instance variables
22
+ # ionumber - required, value indicating the pin number (BCM IO number,
23
+ # not the header pin number)
24
+ # direction - optional, specifies the pin direction. A pin is
25
+ # initialized as an input if a direction isn't specified.
26
+ #
50
27
  def initialize(ionumber, direction = :in)
51
28
  @ionumber = Integer(ionumber)
52
29
  @pin_dir_name = "#{Server.gpio_dir}/gpio#{@ionumber}/direction"
@@ -83,6 +60,11 @@ module OrigenLink
83
60
  end
84
61
  end
85
62
 
63
+ # out:
64
+ # description - Sets the output state of the pin. If the pin
65
+ # is setup as an input, the direction will first
66
+ # be changed to output.
67
+ #
86
68
  def out(value)
87
69
  if @gpio_valid
88
70
  if @direction == :in
@@ -93,6 +75,11 @@ module OrigenLink
93
75
  end
94
76
  end
95
77
 
78
+ # in:
79
+ # description - Reads and returns state of the pin. If the pin
80
+ # is setup as an output, the direction will first
81
+ # be changed to input.
82
+ #
96
83
  def in
97
84
  if @gpio_valid
98
85
  if @direction == :out
@@ -108,6 +95,15 @@ module OrigenLink
108
95
  end
109
96
  end
110
97
 
98
+ # update_direction:
99
+ # description - Sets the pin direction
100
+ #
101
+ # direction - specifies the pin direction. A pin is
102
+ # initialized as an input if a direction isn't specified.
103
+ #
104
+ # Valid direction values:
105
+ # :in - input
106
+ # :out - output
111
107
  def update_direction(direction)
112
108
  if @gpio_valid
113
109
  @pin_dir_obj.pos = 0
@@ -17,23 +17,46 @@ module OrigenLink
17
17
  def send_cmd(cmdstr, argstr)
18
18
  # objects have to be created outside of the block
19
19
  # to be accessible outside of the block
20
+ t1 = 0
20
21
  t2 = 0
21
22
  t3 = 0
22
23
  t4 = 0
23
24
  t5 = 0
24
25
  response = ''
25
- t1 = Time.now
26
+ user_status = ''
27
+ success = false
26
28
 
27
- # open a connection to the server, send the command and wait for a response
28
- TCPSocket.open(@address, @port) do |link|
29
- t2 = Time.now
30
- link.write(cmdstr + ':' + argstr + "\n\n")
31
- t3 = Time.now
32
- response = link.gets
33
- t4 = Time.now
29
+ until success
30
+ t1 = Time.now
31
+
32
+ # open a connection to the server, send the command and wait for a response
33
+ TCPSocket.open(@address, @port) do |link|
34
+ t2 = Time.now
35
+ link.write(@user_name + "\n" + cmdstr + ':' + argstr + "\n\n")
36
+ t3 = Time.now
37
+ user_status = link.gets
38
+ response = link.gets
39
+ t4 = Time.now
40
+ end
41
+
42
+ t5 = Time.now
43
+
44
+ if @initial_comm_sent && ((user_status =~ /user_change/) || (response =~ /Busy:/))
45
+ # there has been a collision
46
+ Origen.log.error 'A collision (another user interrupted your link session) has occured'
47
+ Origen.log.error "When using debug mode ensure that you don't exceed the 20 minute communication time out"
48
+ exit
49
+ end
50
+
51
+ if response =~ /Busy:/
52
+ Origen.log.error response + ' retry in 1 second'
53
+ sleep(1)
54
+ else
55
+ success = true
56
+ @initial_comm_sent = true
57
+ end
34
58
  end
35
59
 
36
- t5 = Time.now
37
60
  @total_comm_time += (t5 - t1)
38
61
  if @max_packet_time < (t5 - t1)
39
62
  @max_packet_time = (t5 - t1)
@@ -50,23 +73,47 @@ module OrigenLink
50
73
  end
51
74
 
52
75
  def send_batch(vector_batch)
53
- t2 = 0
54
- t3 = 0
55
- t4 = 0
56
- t5 = 0
57
- response = []
58
- t1 = Time.now
59
- TCPSocket.open(@address, @port) do |link|
60
- t2 = Time.now
61
- vector_batch_str = vector_batch.join("\n") + "\n\n"
62
- link.write(vector_batch_str)
63
- t3 = Time.now
64
- while line = link.gets
65
- response << line.chomp
76
+ vector_batch_str = @user_name + "\n" + vector_batch.join("\n") + "\n\n"
77
+ user_status = ''
78
+ success = false
79
+
80
+ until success
81
+ t1 = 0
82
+ t2 = 0
83
+ t3 = 0
84
+ t4 = 0
85
+ t5 = 0
86
+ response = []
87
+ t1 = Time.now
88
+ TCPSocket.open(@address, @port) do |link|
89
+ t2 = Time.now
90
+ link.write(vector_batch_str)
91
+ t3 = Time.now
92
+ while line = link.gets
93
+ response << line.chomp
94
+ end
95
+ t4 = Time.now
96
+ end
97
+ t5 = Time.now
98
+
99
+ user_status = response.delete_at(0)
100
+ if @initial_comm_sent && ((user_status =~ /user_change/) || (response[0] =~ /Busy:/))
101
+ # there has been a collision
102
+ Origen.log.error 'A collision (another user interrupted your link session) has occured'
103
+ Origen.log.error "When using debug mode ensure that you don't exceed the 20 minute communication time out"
104
+ exit
66
105
  end
67
- t4 = Time.now
106
+
107
+ if response[0] =~ /Busy:/
108
+ Origen.log.error response[0] + ' retry in 1 second'
109
+ sleep(1)
110
+ else
111
+ success = true
112
+ @initial_comm_sent = true
113
+ end
114
+
68
115
  end
69
- t5 = Time.now
116
+
70
117
  @total_comm_time += (t5 - t1)
71
118
  @total_connect_time += (t2 - t1)
72
119
  @total_xmit_time += (t3 - t2)
@@ -1,3 +1,4 @@
1
+ require 'etc'
1
2
  require 'origen_testers'
2
3
  require 'origen_link/server_com'
3
4
  require 'origen_link/capture_support'
@@ -39,6 +40,7 @@ module OrigenLink
39
40
  attr_reader :fail_count, :vector_count, :total_comm_time, :total_connect_time, :total_xmit_time
40
41
  attr_reader :total_recv_time, :total_packets, :vector_repeatcount, :tsets_programmed, :captured_data
41
42
  attr_reader :vector_batch, :store_pins_batch, :comment_batch
43
+ attr_reader :user_name, :initial_comm_sent
42
44
 
43
45
  def initialize(address, port, options = {})
44
46
  @address = address
@@ -68,6 +70,8 @@ module OrigenLink
68
70
  @batch_vectors = true
69
71
  @pattern_link_messages = []
70
72
  @pattern_comments = {}
73
+ @user_name = Etc.getlogin
74
+ @initial_comm_sent = false
71
75
  end
72
76
 
73
77
  # push_comment
@@ -288,6 +292,7 @@ module OrigenLink
288
292
  def finalize_pattern(output_file)
289
293
  Origen.log.debug('Pattern generation completed. Sending all stored vector data')
290
294
  synchronize(output_file)
295
+ send_cmd('', 'session_end')
291
296
  # for debug, report communication times
292
297
  Origen.log.debug("total communication time: #{@total_comm_time}")
293
298
  Origen.log.debug("total connect time: #{@total_connect_time}")
@@ -316,6 +321,7 @@ module OrigenLink
316
321
  file.puts(@pattern_link_messages[index])
317
322
  file.puts(@pattern_comments[index]) if @pattern_comments.key?(index)
318
323
  end
324
+ file.puts(':session_end')
319
325
  end
320
326
  end
321
327
 
@@ -6,11 +6,17 @@
6
6
 
7
7
  ### Purpose
8
8
 
9
- This application...
9
+ This is a plug-in for Origen that enables live silicon debug directly from origen source.
10
10
 
11
11
  ### How To Use
12
12
 
13
- Add quickstart documentation here...
13
+ Add the following line to your application's GEMFILE:
14
+
15
+ * gem 'origen_link'
16
+
17
+ Add the following line to your application:
18
+
19
+ * require 'origen_link'
14
20
 
15
21
  ### How To Setup the Application Environment
16
22
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: origen_link
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0.pre0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Derouen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-11 00:00:00.000000000 Z
11
+ date: 2016-07-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: origen
@@ -39,47 +39,25 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.6.1
41
41
  - !ruby/object:Gem::Dependency
42
- name: origen_jtag
42
+ name: sinatra
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: 0.12.0
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
45
+ - - "~>"
53
46
  - !ruby/object:Gem::Version
54
- version: 0.12.0
55
- - !ruby/object:Gem::Dependency
56
- name: origen_doc_helpers
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
47
+ version: '1'
59
48
  - - ">="
60
49
  - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
50
+ version: 1.4.7
51
+ type: :runtime
63
52
  prerelease: false
64
53
  version_requirements: !ruby/object:Gem::Requirement
65
54
  requirements:
66
- - - ">="
55
+ - - "~>"
67
56
  - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: test-unit
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
57
+ version: '1'
80
58
  - - ">="
81
59
  - !ruby/object:Gem::Version
82
- version: '0'
60
+ version: 1.4.7
83
61
  description:
84
62
  email:
85
63
  - paul.derouen@nxp.com
@@ -92,11 +70,13 @@ files:
92
70
  - config/application.rb
93
71
  - config/boot.rb
94
72
  - config/commands.rb
73
+ - config/shared_commands.rb
95
74
  - config/version.rb
96
75
  - lib/origen_link.rb
97
76
  - lib/origen_link/callback_handlers.rb
98
77
  - lib/origen_link/capture_support.rb
99
78
  - lib/origen_link/configuration_commands.rb
79
+ - lib/origen_link/listener.rb
100
80
  - lib/origen_link/server/jtag.rb
101
81
  - lib/origen_link/server/pin.rb
102
82
  - lib/origen_link/server/sequencer.rb