origen_link 0.1.2 → 0.2.0.pre0

Sign up to get free protection for your applications and to get access to all the features.
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