origen_link 0.3.1 → 0.4.0

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: 04e383bc6244d952b975b37dccb15394a8af97c6
4
- data.tar.gz: d792ff42218863b615f0e21a1b73fb285bbacd41
3
+ metadata.gz: 0d23f0665303afa13e7e60c42dae8931fa93abe3
4
+ data.tar.gz: 53e0c64c2a14c273fac39b100208e0bccfa7b21d
5
5
  SHA512:
6
- metadata.gz: 949b3c98d635f858d2c94cc417dfbbe38126f3e1c08724880a5d859534e7d2f16e814977c3dd3efa42c685ff59e5abf937336ff521efc2cb10b0ee3318be1cd6
7
- data.tar.gz: b661be3f75b4cc051b4545fc1e83460b7a5260be582bfc8e80698e50840ade7f88e8552092ac9390d309bb0e49f086a950a885e0815c3047ee74d91a8cd53577
6
+ metadata.gz: 18d29362fa1d0c1ba23996f7a296342d712e89cfaf0aa321b0cf71f271bf0f8f33c6fa5e936576b8c0070d8bc6e36e152128abb1c0e23ba0686bf20941343356
7
+ data.tar.gz: 96f5d51aef745dff7c49202d0df7bbd2760a32ba78a4fef99b3ee9ffb47c61d8dcafd50cd193fab19d8e3aa65d88d82d1ca6273999252b8e208579d91094cd1a
@@ -3,17 +3,55 @@ $LOAD_PATH.unshift(File.join(File.expand_path(File.dirname(__FILE__)), '..', 'li
3
3
  $LOAD_PATH.unshift(File.join(File.expand_path(File.dirname(__FILE__)), '..', 'config'))
4
4
  require 'socket'
5
5
  require 'origen_link/server/sequencer'
6
+ require 'origen_link/server/jtag'
6
7
  require 'version'
7
8
 
9
+ # method to handle the processing of a jtag message
10
+ def processjtagmessage(message)
11
+ reply = 'Error'
12
+ if message =~ /jtag_configure:/
13
+ # Allow the default io numbers to be overridden
14
+ newios = message.gsub(/\s+/, '').split(':')[1].split(',')
15
+ if newios.size = 4
16
+ $tdiio = newios[0]
17
+ $tdoio = newios[1]
18
+ $tmsio = newios[2]
19
+ $tckio = newios[3]
20
+ reply = "jtag_configure: tdi = #{$tdiio}, tdo = #{$tdoio}, tms = #{$tmsio}, tck = #{$tckio}"
21
+ else
22
+ reply = 'jtag_configure failed, need 4 io numbers, tdi, tdo, tms, tck - in that order'
23
+ end
24
+ elsif message =~ /jtag_reinit/
25
+ $jtag_interpreter.destroy unless $jtag_interpreter.nil?
26
+ $jtag_interpreter = OrigenLink::Server::Jtag.new($tdiio, $tdoio, $tmsio, $tckio)
27
+ reply = 'done'
28
+ else
29
+ $jtag_interpreter = OrigenLink::Server::Jtag.new($tdiio, $tdoio, $tmsio, $tckio) if $jtag_interpreter.nil?
30
+ reply = $jtag_interpreter.processmessage(message)
31
+ end
32
+ reply
33
+ end
34
+
35
+ # General initialization
8
36
  server = TCPServer.open('', 12_777)
9
- pinsequencer = OrigenLink::Server::Sequencer.new
10
- pinsequencer.version = OrigenLink::VERSION
11
37
  remoteuser = ''
12
38
  remotehost = ''
13
39
  sessionactivity = Time.now
14
40
  sessionactive = false
41
+
42
+ # Initialize the pin sequencer object
43
+ pinsequencer = OrigenLink::Server::Sequencer.new
44
+ pinsequencer.version = OrigenLink::VERSION
15
45
  puts "server version #{pinsequencer.version} started"
16
46
 
47
+ # Set default values for the Jtag object
48
+ $tdiio = 116
49
+ $tdoio = 124
50
+ $tmsio = 6
51
+ $tckio = 119
52
+ $jtag_interpreter = nil
53
+
54
+ # Wait for connection requests in an infinite loop
17
55
  loop do
18
56
  client = server.accept
19
57
  thisuser = client.gets.chomp
@@ -41,25 +79,34 @@ loop do
41
79
  response = "\n"
42
80
  end
43
81
 
82
+ # Now we're ready to process the actual message
44
83
  # if this connection is from the active user\host machine, then process the information
45
84
  if (remoteuser.eql? thisuser) && (remotehost.eql? thisremotehost)
46
85
  while (message = client.gets) != "\n"
47
86
  # process the message
48
- # for now only pin_ messages are accepted
49
- if message =~ /session_end/
87
+ if message =~ /session_end/ || message =~ /session_kill/
50
88
  sessionactive = false
51
89
  response = response + "session_end:session_end\n"
90
+ elsif message[0,5] == 'jtag_'
91
+ # jtag messages get routed to the jtag message handler
92
+ sessionactive = true
93
+ response = response + processjtagmessage(message.chomp) + "\n"
52
94
  else
95
+ # default is pin sequencer message handling
53
96
  sessionactive = true
54
97
  response = response + pinsequencer.processmessage(message.chomp) + "\n"
55
98
  end
56
99
  end
57
100
  sessionactivity = Time.now
58
101
  else
102
+ # The connection didn't come from the active user. Only session_kill is allowed.
59
103
  checkmessage = client.gets.chomp
60
104
  if checkmessage =~ /session_kill/
61
105
  sessionactive = false
62
106
  response = response + "Terminated: session from #{remoteuser} at IP address #{remotehost} inactive for #{Time.now - sessionactivity} seconds has been killed\n"
107
+ change_in_user = true unless (remoteuser.eql? thisuser) && (remotehost.eql? thisremotehost)
108
+ remoteuser = thisuser
109
+ remotehost = thisremotehost
63
110
  else
64
111
  response = response + "Busy: server is in use by #{remoteuser} from IP address #{remotehost}\n"
65
112
  end
@@ -1,7 +1,7 @@
1
1
  module OrigenLink
2
2
  MAJOR = 0
3
- MINOR = 3
4
- BUGFIX = 1
3
+ MINOR = 4
4
+ BUGFIX = 0
5
5
  DEV = nil
6
6
 
7
7
  VERSION = [MAJOR, MINOR, BUGFIX].join(".") + (DEV ? ".pre#{DEV}" : '')
@@ -2,35 +2,23 @@ require 'origen_link/server/pin'
2
2
 
3
3
  module OrigenLink
4
4
  module Server
5
- # The Jtag class is not part of the OrigenLink plug-in/server ecosystem.
6
- # It implements standard jtag protocol. It can be used to implement a
7
- # Jtag protocol server (not included in this repository presently).
8
5
  class Jtag
9
- # The value read from TDO during the shift
10
6
  attr_reader :tdoval
11
- # Enable extra output
12
7
  attr_accessor :verbose_enable
13
8
  attr_accessor :anytdofail
14
9
 
15
- # Create the jtag pin objects
16
- def initialize(tdiio = 16, tdoio = 23, tmsio = 19, tckio = 26, tck_period = 0.000001)
10
+ def initialize(tdiio = 116, tdoio = 124, tmsio = 6, tckio = 119)
17
11
  @tdipin = Pin.new(tdiio, :out)
18
12
  @tdopin = Pin.new(tdoio, :in)
19
13
  @tmspin = Pin.new(tmsio, :out)
20
14
  @tckpin = Pin.new(tckio, :out)
21
- @tck_half_period = tck_period / 2
22
15
  @tdoval = 0
23
16
  @tdostr = ''
24
17
  @verbose_enable = true
25
18
  @anytdofail = false
19
+ @pins = {}
26
20
  end
27
21
 
28
- # not needed, no need for wait states between operations
29
- def tck_period=(value)
30
- @tck_half_period = value / 2
31
- end
32
-
33
- # close out file IO objects for the pins
34
22
  def destroy
35
23
  @tdipin.destroy
36
24
  @tdopin.destroy
@@ -40,15 +28,14 @@ module OrigenLink
40
28
  @tdopin = nil
41
29
  @tmspin = nil
42
30
  @tckpin = nil
31
+ @pins.each_value(&:destroy)
43
32
  end
44
33
 
45
- # perform 1 jtag cycle
46
34
  def do_cycle(tdival, tmsval, capturetdo = false)
47
35
  @tdipin.out(tdival)
48
36
  @tmspin.out(tmsval)
49
- sleep @tck_half_period
37
+
50
38
  @tckpin.out(1)
51
- sleep @tck_half_period
52
39
 
53
40
  if capturetdo
54
41
  @tdostr = @tdopin.in + @tdostr
@@ -56,13 +43,11 @@ module OrigenLink
56
43
  @tckpin.out(0)
57
44
  end
58
45
 
59
- # advance state machine to test logic reset, then return to run/test idle
60
46
  def do_tlr
61
47
  8.times { do_cycle(0, 1) }
62
48
  do_cycle(0, 0)
63
49
  end
64
50
 
65
- # shift a value in on tdi, optionall capture tdo
66
51
  def do_shift(numbits, value, capturetdo = false, suppresscomments = false, tdocompare = '')
67
52
  @tdoval = 0
68
53
  @tdostr = ''
@@ -96,20 +81,9 @@ module OrigenLink
96
81
 
97
82
  tdovalstr = @tdoval.to_s(2)
98
83
  tdovalstr = '0' * (numbits - tdovalstr.length) + tdovalstr
99
-
100
- if thiscomparefail
101
- puts '****************************>>>>>>>>>>>>>>>>> TDO failure <<<<<<<<<<<<<<<<<<****************************'
102
- puts 'expected: ' + tdocompare
103
- puts 'received: ' + tdovalstr
104
- else
105
- puts 'TDO compare pass'
106
- puts 'expected: ' + tdocompare
107
- puts 'received: ' + tdovalstr
108
- end
109
84
  end
110
85
  end
111
86
 
112
- # perform an ir-update
113
87
  def do_ir(numbits, value, options = {})
114
88
  defaults = {
115
89
  capturetdo: false,
@@ -118,10 +92,6 @@ module OrigenLink
118
92
  }
119
93
  options = defaults.merge(options)
120
94
 
121
- if !(options[:suppresscomments]) && @verbose_enable
122
- puts " shift IR, #{numbits} bits, value = 0x" + value.to_s(16)
123
- end
124
-
125
95
  if options[:tdocompare] != ''
126
96
  capturetdo = true
127
97
  else
@@ -142,7 +112,6 @@ module OrigenLink
142
112
  do_cycle(0, 0)
143
113
  end
144
114
 
145
- # perform a dr update
146
115
  def do_dr(numbits, value, options = {})
147
116
  defaults = {
148
117
  capturetdo: true,
@@ -150,9 +119,6 @@ module OrigenLink
150
119
  tdocompare: ''
151
120
  }
152
121
  options = defaults.merge(options)
153
- if !(options[:suppresscomments]) && @verbose_enable
154
- puts " shift DR, #{numbits} bits, value = 0x" + value.to_s(16)
155
- end
156
122
 
157
123
  if options[:tdocompare] != ''
158
124
  capturetdo = true
@@ -173,7 +139,6 @@ module OrigenLink
173
139
  do_cycle(0, 0)
174
140
  end
175
141
 
176
- # traverse the pause dr state
177
142
  def pause_dr
178
143
  do_cycle(0, 1)
179
144
  do_cycle(0, 0)
@@ -185,11 +150,102 @@ module OrigenLink
185
150
  do_cycle(0, 0)
186
151
  end
187
152
 
188
- # traverse the pause ir state
189
153
  def pause_ir
190
154
  do_cycle(0, 1)
191
155
  pause_dr
192
156
  end
157
+
158
+ def read_adc(csl)
159
+ channel_list = csl.split(',')
160
+ response = ''
161
+ channel_list.each do |channel|
162
+ file_name = '/sys/bus/iio/devices/'
163
+ case channel
164
+ when 'A0'
165
+ file_name = file_name + 'iio:device0/in_voltage0_raw'
166
+ when 'A1'
167
+ file_name = file_name + 'iio:device0/in_voltage1_raw'
168
+ when 'A2'
169
+ file_name = file_name + 'iio:device0/in_voltage2_raw'
170
+ when 'A3'
171
+ file_name = file_name + 'iio:device0/in_voltage3_raw'
172
+ when 'A4'
173
+ file_name = file_name + 'iio:device1/in_voltage0_raw'
174
+ when 'A5'
175
+ file_name = file_name + 'iio:device1/in_voltage1_raw'
176
+ end
177
+ response = response + ',' unless response.size == 0
178
+ if File.exist?(file_name)
179
+ File.open(file_name, 'r') do |file|
180
+ reading = file.gets
181
+ response = response + reading.strip
182
+ end
183
+ else
184
+ response = response + '-1'
185
+ end
186
+ end
187
+ response
188
+ end
189
+
190
+ def processmessage(message)
191
+ message.strip!
192
+ split_message = message.split(':')
193
+ response = ''
194
+ case split_message[0]
195
+ when 'jtag_ir'
196
+ args = split_message[1].split(',')
197
+ do_ir(args[2].to_i, string_to_val(args[0], args[1]), capturetdo: true, suppresscomments: true)
198
+ response = @tdoval.to_s(16)
199
+ when 'jtag_dr'
200
+ args = split_message[1].split(',')
201
+ do_dr(args[2].to_i, string_to_val(args[0], args[1]), capturetdo: true, suppresscomments: true)
202
+ response = @tdoval.to_s(16)
203
+ when 'jtag_pause_dr'
204
+ pause_dr
205
+ response = 'done'
206
+ when 'jtag_pause_ir'
207
+ pause_ir
208
+ response = 'done'
209
+ when 'jtag_reset'
210
+ do_tlr
211
+ response = 'done'
212
+ when 'jtag_pin_set'
213
+ pinlist = split_message[1].split(',')
214
+ pinlist.each do |pin|
215
+ @pins[pin] = Pin.new(pin, :out) unless @pins.key?(pin)
216
+ @pins[pin].out(1)
217
+ end
218
+ response = 'done'
219
+ when 'jtag_pin_clear'
220
+ pinlist = split_message[1].split(',')
221
+ pinlist.each do |pin|
222
+ @pins[pin] = Pin.new(pin, :out) unless @pins.key?(pin)
223
+ @pins[pin].out(0)
224
+ end
225
+ response = 'done'
226
+ when 'jtag_pin_read'
227
+ pinlist = split_message[1].split(',')
228
+ pinlist.each do |pin|
229
+ @pins[pin] = Pin.new(pin, :in) unless @pins.key?(pin)
230
+ response = response + @pins[pin].in
231
+ end
232
+ response
233
+ when 'jtag_adc_read'
234
+ response = read_adc(split_message[1])
235
+ response
236
+ end
237
+ end
238
+
239
+ def string_to_val(base_indicator, numstr)
240
+ case base_indicator
241
+ when 'h'
242
+ numstr.to_i(16)
243
+ when 'd'
244
+ numstr.to_i(10)
245
+ when 'b'
246
+ numstr.to_i(2)
247
+ end
248
+ end
193
249
  end
194
250
  end
195
251
  end
@@ -202,16 +202,17 @@ module OrigenLink
202
202
  exit 1
203
203
  end
204
204
  tset = options[:timeset].name
205
+ local_repeat = options[:repeat].nil? ? 1 : options[:repeat]
205
206
  if @vector_count > 0
206
207
  # compressing repeats as we go
207
208
  if (programmed_data == @previous_vectordata) && (@previous_tset == tset) && @store_pins.empty?
208
- @vector_repeatcount += 1
209
+ @vector_repeatcount += local_repeat
209
210
  else
210
211
  # all repeats of the previous vector have been counted
211
212
  # time to flush. Don't panic though! @previous_vectordata
212
213
  # is what gets flushed. programmed_data is passed as an
213
214
  # arg to be set as the new @previous_vectordata
214
- flush_vector(programmed_data, tset)
215
+ flush_vector(programmed_data, tset, local_repeat)
215
216
  end
216
217
  else
217
218
  # if this is the first vector of the pattern, insure variables are initialized
@@ -225,7 +226,7 @@ module OrigenLink
225
226
  # flush_vector
226
227
  # Just as the name suggests, this method "flushes" a vector. This is necessary because
227
228
  # of repeat compression (a vector isn't sent until different vector data is encountered)
228
- def flush_vector(programmed_data = '', tset = '')
229
+ def flush_vector(programmed_data = '', tset = '', local_repeat = 1)
229
230
  # prevent server crash when vector_flush is used during debug
230
231
  unless @previous_vectordata == ''
231
232
  if @vector_repeatcount > 1
@@ -261,7 +262,7 @@ module OrigenLink
261
262
  @store_pins = []
262
263
  end
263
264
 
264
- @vector_repeatcount = 1
265
+ @vector_repeatcount = local_repeat
265
266
  @previous_vectordata = programmed_data
266
267
  @previous_tset = tset
267
268
  end
@@ -470,5 +471,49 @@ module OrigenLink
470
471
  true
471
472
  end
472
473
  end
474
+
475
+ # wait a fixed amount of time
476
+ # This method will run the Sleep method to wait rather than generating cycles.
477
+ # Cycle execution time is not predictable with OrigenLink.
478
+ #
479
+ # If you want cycles to be generated by this method include apply_cycles: true
480
+ # in the options hash
481
+ #
482
+ # This method currently doesn't handle match blocks.
483
+ def wait(options = {})
484
+ options = {
485
+ cycles: 0,
486
+ time_in_cycles: 0,
487
+ time_in_us: 0,
488
+ time_in_ns: 0,
489
+ time_in_ms: 0,
490
+ time_in_s: 0,
491
+ match: false, # Set to true to invoke a match loop where the supplied delay
492
+ apply_cycles: false
493
+ # will become the timeout duration
494
+ }.merge(options)
495
+
496
+ fail 'wait(match: true) is not yet implemented on Link' if options[:match]
497
+
498
+ time_delay = 0
499
+ time_delay += (options[:time_in_s])
500
+ time_delay += (options[:time_in_ms]) * 0.001
501
+ time_delay += (options[:time_in_us]) * 0.000001
502
+ time_delay += (options[:time_in_ns]) * 0.000000001
503
+ time_delay += (options[:cycles] + options[:time_in_cycles]) * current_period_in_ns * 0.000000001
504
+
505
+ if options[:apply_cycles]
506
+ cycles = time_delay / 0.00003 # cycle execution time is unpredictable, but ~= 30us
507
+ if options[:cycles] > 0 || options[:time_in_cycles] > 0
508
+ options[:repeat] = options[:cycles] + options[:time_in_cycles]
509
+ else
510
+ options[:repeat] = (cycles > 0) ? cycles : 1
511
+ end
512
+ cycle(options)
513
+ else
514
+ synchronize # ensure all generated cycles are executed before delay is run
515
+ sleep time_delay
516
+ end
517
+ end
473
518
  end
474
519
  end
@@ -14,14 +14,14 @@ Instructions for integrating and using the plug-in with your app.
14
14
 
15
15
  ## How To Import
16
16
 
17
- * Add the following line to your application's GEMFILE:
17
+ ##### Add the following line to your application's GEMFILE:
18
18
 
19
19
  ~~~ruby
20
20
  gem 'origen_link'
21
21
  ~~~
22
22
 
23
23
 
24
- * Add a link environment (./environment/link.rb). See server setup section for more information:
24
+ ##### Add a link environment (./environment/link.rb). See server setup section for more information:
25
25
 
26
26
  ~~~ruby
27
27
  # Note that the field for providing the computer name or IP address is a string
@@ -29,7 +29,7 @@ OrigenLink::VectorBased.new('<ServerComputerName -- or IP_Address>', 12777)
29
29
  ~~~
30
30
 
31
31
 
32
- * Select link as your environment to run a pattern over the link connection when the origen generate command is run:
32
+ ##### Select link as your environment to run a pattern over the link connection when the origen generate command is run:
33
33
 
34
34
  ~~~
35
35
  origen e environment/link.rb
@@ -159,7 +159,7 @@ There are pin methods available to aid debug of an OrigenLink setup.
159
159
 
160
160
  For efficiency vectors that are generated by your app are compressed and stored until the pattern generation is completed. This means that when execution reaches a 'debugger' statement the previously generated vectors may not have been sent to the server yet. There are a handful of ways to make this happen.
161
161
 
162
- * Use the tester.synchronize command from the debugger interface:
162
+ ##### Use the tester.synchronize command from the debugger interface:
163
163
 
164
164
  ~~~
165
165
  # one time synchronize
@@ -170,7 +170,9 @@ For efficiency vectors that are generated by your app are compressed and stored
170
170
  (debugger prompt): disp tester.synchronize
171
171
  ~~~
172
172
 
173
- * Use tester.transaction (makes the most sense to have this in your app's reg read/write methods). Before the transaction method executes the code block provided it will perform a synchronization. Then, the code in the block is executed (which generates new vectors) and a second synchronization is performed. The transaction method returns a boolean indicating whether the vectors generated by the code block passed or failed.
173
+ ##### Use tester.transaction
174
+
175
+ It makes the most sense to have this in your app's reg read/write methods). Before the transaction method executes the code block provided it will perform a synchronization. Then, the code in the block is executed (which generates new vectors) and a second synchronization is performed. The transaction method returns a boolean indicating whether the vectors generated by the code block passed or failed.
174
176
 
175
177
  ~~~ruby
176
178
  result = tester.transaction { dut.jtag.shift_xx (yy) }
@@ -183,7 +185,7 @@ For efficiency vectors that are generated by your app are compressed and stored
183
185
 
184
186
  There are a few methods for observing the actual state of the DUT.
185
187
 
186
- * Capture using tester.capture
188
+ ##### Capture using tester.capture
187
189
 
188
190
  ~~~ruby
189
191
  # example of capturing and programatically using information read from the DUT
@@ -198,7 +200,7 @@ There are a few methods for observing the actual state of the DUT.
198
200
  puts '**************************************************'
199
201
  ~~~
200
202
 
201
- * Capture using mem api
203
+ ##### Capture using mem api
202
204
 
203
205
  This command will read the contents of memory from the DUT and display it.
204
206
 
@@ -216,28 +218,57 @@ This command will read the contents of memory from the DUT and display it.
216
218
  20000008: 1C000898
217
219
  ~~~
218
220
 
219
- * reg.sync!
221
+ ##### reg.sync!
220
222
 
221
223
  This command will read the contents of the register from the DUT and display it by bit field.
222
224
 
223
225
  ~~~
224
- (debugger prompt): dut.reg(:MyReg).sync!
226
+ (debugger prompt): dut.reg(:My_Reg).sync!
227
+
228
+ 0x3B4 - :My_Reg
229
+ ===============================================================================================================
230
+ | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 |
231
+ | unused[16:9] |
232
+ | 0x0 |
233
+ ---------------------------------------------------------------------------------------------------------------
234
+ | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
235
+ | unused[8:1] |
236
+ | 0x0 |
237
+ ---------------------------------------------------------------------------------------------------------------
238
+ | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 |
239
+ | unused[0:0] | result[14:8] |
240
+ | 0x0 | 0x1C |
241
+ ---------------------------------------------------------------------------------------------------------------
242
+ | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
243
+ | result[7:0] |
244
+ | 0x98 |
245
+ ---------------------------------------------------------------------------------------------------------------
225
246
  ~~~
226
247
 
227
- #### When A Shared Server Session Isn't Properly Ended
248
+ ##### When A Shared Server Session Isn't Properly Ended
249
+
250
+ The server is able to handle multiple users. Once a user connects to the server, it will only allow access from that same IP address and user name until the session has ended. The session end command is transmitted when pattern generation is completed. If a user fails to properly end their session (happens when you exit debug mode by typing 'q' instead of 'c'), the server application will continue to lock out access until the time out has expired (20 minutes). Before terminating a running session, check with the user who started the session to make sure they aren't in the middle of debug (the user id and IP address will be displayed when you try to connect).
251
+
252
+ ~~~
253
+ ...origen/work 224$ origen g pattern/sar_debug.rb
254
+ [ERROR] 0.011[0.011] || Busy: server is in use by joshua from IP address 10.84.152.212
255
+ retry in 1 second
256
+ [ERROR] 1.039[1.028] || Busy: server is in use by joshua from IP address 10.84.152.212
257
+ retry in 1 second
258
+ [ERROR] 2.203[1.164] || Busy: server is in use by joshua from IP address 10.84.152.212
259
+ retry in 1 second
260
+ ~~~
228
261
 
229
- The server is able to handle multiple users. Once a user connects to the server, it will only allow access from that same IP address and user name until the session has ended. The session end command is transmitted when pattern generation is completed. If a user fails to properly end their session (happens when you exit debug mode by typing 'q' instead of 'c'), the server application will continue to lock out access until the time out has expired (20 minutes). Before terminating a running session, check with the user who started the session to make sure they aren't in the middle of debug (the user id and IP address will be displayed when you try to connect). If the previous session needs to be manually terminated, this is how you do it (this should be a rare exception to the rule - it's bad manners to forcefully kill another user's session):
262
+ If the previous session needs to be manually terminated, this is how you do it (this should be a rare exception to the rule - it's bad manners to forcefully kill another user's session):
230
263
 
231
264
  ~~~ruby
232
- # run this code to forcefully terminate a session
233
265
  require 'socket'
266
+ require 'etc'
267
+
268
+ user_name = Etc.getlogin
234
269
 
235
270
  TCPSocket.open('udooneo-computer-name', 12777) do |link|
236
- link.puts("session_end\n\n")
237
- while received = link.gets
238
- puts received
239
- end
240
- link.puts("session_kill\n\n")
271
+ link.puts("#{user_name}\nsession_kill\n\n")
241
272
  while received = link.gets
242
273
  puts received
243
274
  end
@@ -255,7 +286,9 @@ This section describes how to setup a new IOT device to serve the OrigenLink pin
255
286
 
256
287
  Here are the steps to take to setup a new UDOO-Neo to run the OrigenLink server application. These instructions are not intended to be exhaustive, but should be good enough to get you up and running.
257
288
 
258
- * Change the name of the computer to something unique (like udooneo-myname). This name is the string that you will enter in your environment ruby file for your app. Your computer running origen g pattern/my_pattern.rb and the UDOO should be attached to the same network (either through USB or ethernet)
289
+ ##### Change the name of the computer to something unique (like udooneo-myname).
290
+
291
+ This name is the string that you will enter in your environment ruby file for your app. Your computer running origen g pattern/my_pattern.rb and the UDOO should be attached to the same network (either through USB or ethernet)
259
292
 
260
293
  ~~~
261
294
  prompt$> sudo nano /etc/hostname
@@ -266,13 +299,13 @@ prompt$> sudo nano /etc/hostname
266
299
  OrigenLink::VectorBased.new('<ServerComputerName -- or IP_Address>', 12777)
267
300
  ~~~
268
301
 
269
- * Disable the M4 core (allows access to all IO's from unix)
302
+ ##### Disable the M4 core (allows access to all IO's from unix)
270
303
 
271
304
  ~~~
272
305
  menu -> preferences -> Udoo web configuration -> Advanced settings
273
306
  ~~~
274
307
 
275
- * Install ruby. This is a decision point. If you want to install the OrigenLink gem, the steps are a bit more complicated.
308
+ ##### Install ruby. This is a decision point. If you want to install the OrigenLink gem, the steps are a bit more complicated.
276
309
 
277
310
  ** Option 1 (I want the gem): You need to install ruby 2.2.
278
311
 
@@ -288,7 +321,7 @@ prompt$> sudo apt-get ruby22
288
321
  prompt$> sudo apt-get ruby
289
322
  ~~~
290
323
 
291
- * Install the OrigenLink server.
324
+ ##### Install the OrigenLink server.
292
325
 
293
326
  ** Option 1 (if you installed ruby22 you can do this). Install origen and origen_link gems.
294
327
 
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.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Derouen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-07 00:00:00.000000000 Z
11
+ date: 2017-08-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: origen