libmodbus4r 0.3.0 → 2.0.0
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.
- data/README +24 -41
- data/examples/use_tcp_master.rb +17 -11
- data/ext/extconf.rb +2 -7
- data/lib/modbus4r.so +0 -0
- data/spec/tcp_master_spec.rb +27 -36
- metadata +6 -33
- data/NEWS +0 -18
- data/examples/use_rtu_master.rb +0 -43
- data/examples/use_rtu_slave.rb +0 -24
- data/examples/use_tcp_slave.rb +0 -21
- data/ext/errors.c +0 -81
- data/ext/errors.h +0 -24
- data/ext/master.c +0 -215
- data/ext/master.h +0 -37
- data/ext/modbus.c +0 -1959
- data/ext/modbus.h +0 -347
- data/ext/modbus4r.c +0 -115
- data/ext/modbus4r.h +0 -26
- data/ext/rtu_master.c +0 -36
- data/ext/rtu_master.h +0 -21
- data/ext/rtu_slave.c +0 -131
- data/ext/rtu_slave.h +0 -23
- data/ext/slave.c +0 -215
- data/ext/slave.h +0 -44
- data/ext/tcp_master.c +0 -29
- data/ext/tcp_master.h +0 -20
- data/ext/tcp_slave.c +0 -134
- data/ext/tcp_slave.h +0 -21
- data/lib/modbus4r.rb +0 -15
- data/spec/rtu_master_spec.rb +0 -21
- data/spec/rtu_slave_spec.rb +0 -16
- data/spec/tcp_slave_spec.rb +0 -95
data/README
CHANGED
@@ -1,46 +1,29 @@
|
|
1
|
-
== About
|
1
|
+
== About
|
2
2
|
|
3
|
-
|
3
|
+
Binding use *libmodbus* (free implementation of modbus for Linux\MacOS) for Ruby.
|
4
4
|
|
5
|
-
==
|
5
|
+
== Futures
|
6
6
|
|
7
|
-
* Use
|
8
|
-
*
|
9
|
-
* ModBus TCP and RTU master(client);
|
10
|
-
* ModBus TCP and RTU slave(server);
|
7
|
+
* Use C library *libmodbus*;
|
8
|
+
* ModBus TCP master(client);
|
11
9
|
* Support functions:
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
==
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
==
|
31
|
-
|
10
|
+
* * read coil status (0x01)
|
11
|
+
* * read input status (0x02)
|
12
|
+
* * read holding registers (0x03)
|
13
|
+
* * read input registers (0x04)
|
14
|
+
* * force single coil (0x05)
|
15
|
+
* * preset single register (0x06)
|
16
|
+
* * force multiple coils (0x0F)
|
17
|
+
* * preset multiple registers (0x10)
|
18
|
+
|
19
|
+
== Install
|
20
|
+
|
21
|
+
1. Install last release ruby 1.9.1 from http://ruby-lang.org
|
22
|
+
2. Install libmodbus-2.0.3 from https://launchpad.net/libmodbus
|
23
|
+
3. Install libmodbus4r
|
24
|
+
*$ sudo rake install*
|
25
|
+
or
|
26
|
+
*$ gem install flipback-libmodbus4r --source http://gems.github.com
|
27
|
+
|
28
|
+
== AUTHORS
|
32
29
|
Aleksey Timin <atimin@gmail.com>
|
33
|
-
|
34
|
-
== References
|
35
|
-
|
36
|
-
Home page projects : http://flipback.github.com/libmodbus4r/
|
37
|
-
|
38
|
-
Hosting on RubyForge : http://rubyforge.org/projects/libmodbus4r
|
39
|
-
|
40
|
-
Hosting on GitHub : http://github.com/flipback/libmodbus4r/tree/master
|
41
|
-
|
42
|
-
Ruby site : http://ruby-lang.org
|
43
|
-
|
44
|
-
libmobus on Launchpad : https://launchpad.net/libmodbus
|
45
|
-
|
46
|
-
ModBus community: http://www.modbus-ida.org
|
data/examples/use_tcp_master.rb
CHANGED
@@ -5,36 +5,42 @@ end
|
|
5
5
|
|
6
6
|
require 'modbus4r'
|
7
7
|
|
8
|
-
mstr = ModBus::TCPMaster.new('127.0.0.1',
|
9
|
-
1502, #port
|
10
|
-
1) #slave id
|
8
|
+
mstr = ModBus::TCPMaster.new('127.0.0.1', 1502)
|
11
9
|
mstr.connect
|
12
10
|
# Reads the coils status in the slave
|
13
|
-
puts mstr.read_coil_status(
|
11
|
+
puts mstr.read_coil_status(1, #slave id
|
12
|
+
0, #start address
|
14
13
|
10) #number
|
15
14
|
# Reads the input status in the slave
|
16
|
-
puts mstr.read_input_status(
|
15
|
+
puts mstr.read_input_status(1, #slave id
|
16
|
+
0, #start address
|
17
17
|
10) #number
|
18
18
|
# Reads the holding registers in the slave
|
19
|
-
puts mstr.read_holding_registers(
|
19
|
+
puts mstr.read_holding_registers(1, #slave id
|
20
|
+
0, #start address
|
20
21
|
5) #number
|
21
22
|
# Reads the input registers in the slave
|
22
|
-
puts mstr.read_input_registers(
|
23
|
+
puts mstr.read_input_registers(1, #slave id
|
24
|
+
0, #start address
|
23
25
|
5) #number
|
24
26
|
# Turns a single coil in the slave
|
25
|
-
mstr.force_single_coil(
|
27
|
+
mstr.force_single_coil(1, #slave id
|
28
|
+
0, #coil address
|
26
29
|
true) #state
|
27
30
|
|
28
31
|
# Sets a value in one holding register in the slave
|
29
|
-
mstr.preset_single_register(
|
32
|
+
mstr.preset_single_register(1, #slave id
|
33
|
+
0, #reg address
|
30
34
|
0xa0a0) #value
|
31
35
|
|
32
36
|
# Sets\reset the coils in the slave
|
33
|
-
mstr.force_multiple_coils(
|
37
|
+
mstr.force_multiple_coils(1, #slave id
|
38
|
+
0, #start address
|
34
39
|
[true, false, true]) #data
|
35
40
|
|
36
41
|
#Copies the values in th slave
|
37
|
-
mstr.preset_multiple_registers(
|
42
|
+
mstr.preset_multiple_registers(1, #slave id
|
43
|
+
0, #start address
|
38
44
|
[1, 0xdf, 2]) #data
|
39
45
|
|
40
46
|
mstr.close
|
data/ext/extconf.rb
CHANGED
data/lib/modbus4r.so
ADDED
Binary file
|
data/spec/tcp_master_spec.rb
CHANGED
@@ -1,23 +1,15 @@
|
|
1
1
|
require 'modbus4r'
|
2
|
+
require 'socket'
|
2
3
|
|
3
4
|
describe ModBus::TCPMaster do
|
4
5
|
|
5
6
|
before(:all) do
|
6
|
-
@
|
7
|
-
@sl.coil_status = [false, false, false, false,
|
8
|
-
false, false, false, false]
|
9
|
-
@sl.input_status = [false, false, false, false,
|
10
|
-
false, false, false, false]
|
11
|
-
@sl.holding_registers = [0, 0, 0, 0, 0, 0, 0, 0, 0]
|
12
|
-
@sl.input_registers = [0, 0, 0, 0, 0, 0, 0, 0, 0]
|
13
|
-
@sl.start
|
14
|
-
|
15
|
-
@mstr = ModBus::TCPMaster.new('127.0.0.1', 1502, 1)
|
7
|
+
@mstr = ModBus::TCPMaster.new('127.0.0.1', 1502)
|
16
8
|
@mstr.connect
|
17
9
|
end
|
18
10
|
|
19
11
|
it "should raise exception if have'n connected with slave" do
|
20
|
-
mstr = ModBus::TCPMaster.new('127.0.0.1', 1503
|
12
|
+
mstr = ModBus::TCPMaster.new('127.0.0.1', 1503)
|
21
13
|
mstr.closed?.should == true
|
22
14
|
lambda { mstr.connect }.should raise_error(ModBus::Errors::ModBusError, "Connection refused")
|
23
15
|
end
|
@@ -28,102 +20,101 @@ describe ModBus::TCPMaster do
|
|
28
20
|
|
29
21
|
# Read coil status
|
30
22
|
it "should read coil status" do
|
31
|
-
@mstr.read_coil_status(0, 4).should == [false, false, false, false]
|
23
|
+
@mstr.read_coil_status(0x11, 0, 4).should == [false, false, false, false]
|
32
24
|
end
|
33
25
|
|
34
26
|
it "should raise exception if illegal data address" do
|
35
|
-
lambda { @mstr.read_coil_status(0, 501) }.should raise_error(ModBus::Errors::IllegalDataAddress, "Illegal data address (-2)")
|
27
|
+
lambda { @mstr.read_coil_status(0x11, 0, 501) }.should raise_error(ModBus::Errors::IllegalDataAddress, "Illegal data address (-2)")
|
36
28
|
end
|
37
29
|
|
38
30
|
|
39
31
|
it "should raise exception if too many data" do
|
40
|
-
lambda { @mstr.read_coil_status(0, 0x07D1) }.should raise_error(ModBus::Errors::ModBusError, "
|
32
|
+
lambda { @mstr.read_coil_status(0x11, 0, 0x07D1) }.should raise_error(ModBus::Errors::ModBusError, "Too many data (-15)")
|
41
33
|
end
|
42
34
|
|
43
35
|
# Read input status
|
44
36
|
it "should read discrete inputs" do
|
45
|
-
@mstr.read_input_status(0, 4).should == [false, false, false, false]
|
37
|
+
@mstr.read_input_status(0x11, 0, 4).should == [false, false, false, false]
|
46
38
|
end
|
47
39
|
|
48
40
|
it "should raise exception if illegal data address" do
|
49
|
-
lambda { @mstr.read_input_status(0, 501) }.should raise_error(ModBus::Errors::IllegalDataAddress, "Illegal data address (-2)")
|
41
|
+
lambda { @mstr.read_input_status(0x11, 0, 501) }.should raise_error(ModBus::Errors::IllegalDataAddress, "Illegal data address (-2)")
|
50
42
|
end
|
51
43
|
|
52
44
|
|
53
45
|
it "should raise exception if too many data" do
|
54
|
-
lambda { @mstr.read_input_status(0, 0x07D1) }.should raise_error(ModBus::Errors::ModBusError, "
|
46
|
+
lambda { @mstr.read_input_status(0x11, 0, 0x07D1) }.should raise_error(ModBus::Errors::ModBusError, "Too many data (-15)")
|
55
47
|
end
|
56
48
|
|
57
49
|
# Read holding registers
|
58
50
|
it "should read discrete inputs" do
|
59
|
-
@mstr.read_holding_registers(0, 4).should == [0, 0, 0, 0]
|
51
|
+
@mstr.read_holding_registers(0x11, 0, 4).should == [0, 0, 0, 0]
|
60
52
|
end
|
61
53
|
|
62
54
|
it "should raise exception if illegal data address" do
|
63
|
-
lambda { @mstr.read_holding_registers(402, 99) }.should raise_error(ModBus::Errors::IllegalDataAddress, "Illegal data address (-2)")
|
55
|
+
lambda { @mstr.read_holding_registers(0x11, 402, 99) }.should raise_error(ModBus::Errors::IllegalDataAddress, "Illegal data address (-2)")
|
64
56
|
end
|
65
57
|
|
66
58
|
|
67
59
|
it "should raise exception if too many data" do
|
68
|
-
lambda { @mstr.read_holding_registers(0, 0x007E) }.should raise_error(ModBus::Errors::ModBusError, "
|
60
|
+
lambda { @mstr.read_holding_registers(0x11, 0, 0x007E) }.should raise_error(ModBus::Errors::ModBusError, "Too many data (-15)")
|
69
61
|
end
|
70
62
|
|
71
63
|
# Read input registers
|
72
64
|
it "should read discrete inputs" do
|
73
|
-
@mstr.read_input_registers(0, 4).should == [0, 0, 0, 0]
|
65
|
+
@mstr.read_input_registers(0x11, 0, 4).should == [0, 0, 0, 0]
|
74
66
|
end
|
75
67
|
|
76
68
|
it "should raise exception if illegal data address" do
|
77
|
-
lambda { @mstr.read_input_registers(402, 99) }.should raise_error(ModBus::Errors::IllegalDataAddress, "Illegal data address (-2)")
|
69
|
+
lambda { @mstr.read_input_registers(0x11, 402, 99) }.should raise_error(ModBus::Errors::IllegalDataAddress, "Illegal data address (-2)")
|
78
70
|
end
|
79
71
|
|
80
72
|
it "should raise exception if too many data" do
|
81
|
-
lambda { @mstr.read_input_registers(0, 0x007E) }.should raise_error(ModBus::Errors::ModBusError, "
|
73
|
+
lambda { @mstr.read_input_registers(0x11, 0, 0x007E) }.should raise_error(ModBus::Errors::ModBusError, "Too many data (-15)")
|
82
74
|
end
|
83
75
|
|
84
76
|
# Force single coil
|
85
77
|
it "should force single coil" do
|
86
|
-
@mstr.force_single_coil(4, true).should == @mstr
|
87
|
-
@mstr.read_coil_status(4, 4).should == [true, false, false, false]
|
78
|
+
@mstr.force_single_coil(0x11, 4, true).should == @mstr
|
79
|
+
@mstr.read_coil_status(0x11, 4, 4).should == [true, false, false, false]
|
88
80
|
end
|
89
81
|
|
90
82
|
it "should raise exception if illegal data address" do
|
91
|
-
lambda { @mstr.force_single_coil(501, true) }.should raise_error(ModBus::Errors::IllegalDataAddress, "Illegal data address (-2)")
|
83
|
+
lambda { @mstr.force_single_coil(0x11, 501, true) }.should raise_error(ModBus::Errors::IllegalDataAddress, "Illegal data address (-2)")
|
92
84
|
end
|
93
85
|
|
94
86
|
# Preset single register
|
95
87
|
it "should preset single register" do
|
96
|
-
@mstr.preset_single_register(4, 0x0AA0).should == @mstr
|
97
|
-
@mstr.read_holding_registers(4, 1).should == [0x0AA0]
|
88
|
+
@mstr.preset_single_register(0x11, 4, 0x0AA0).should == @mstr
|
89
|
+
@mstr.read_holding_registers(0x11, 4, 1).should == [0x0AA0]
|
98
90
|
end
|
99
91
|
|
100
92
|
it "should raise exception if illegal data address" do
|
101
|
-
lambda { @mstr.preset_single_register(501, 0x0AA0) }.should raise_error(ModBus::Errors::IllegalDataAddress, "Illegal data address (-2)")
|
93
|
+
lambda { @mstr.preset_single_register(0x11, 501, 0x0AA0) }.should raise_error(ModBus::Errors::IllegalDataAddress, "Illegal data address (-2)")
|
102
94
|
end
|
103
95
|
|
104
96
|
# Force multiple coils
|
105
97
|
it "should force multiple coils" do
|
106
|
-
@mstr.force_multiple_coils(
|
107
|
-
@mstr.read_coil_status(
|
98
|
+
@mstr.force_multiple_coils(0x11, 14, [false, true, false, true]).should == @mstr
|
99
|
+
@mstr.read_coil_status(0x11, 13, 5).should == [false, false, true, false, true]
|
108
100
|
end
|
109
101
|
|
110
102
|
it "should raise exception if illegal data address" do
|
111
|
-
lambda { @mstr.force_multiple_coils(501, [true, false]) }.should raise_error(ModBus::Errors::IllegalDataAddress, "Illegal data address (-2)")
|
103
|
+
lambda { @mstr.force_multiple_coils(0x11, 501, [true, false]) }.should raise_error(ModBus::Errors::IllegalDataAddress, "Illegal data address (-2)")
|
112
104
|
end
|
113
105
|
|
114
106
|
# Preset multiple registers
|
115
107
|
it "should preset multiple registers" do
|
116
|
-
@mstr.preset_multiple_registers(
|
117
|
-
@mstr.read_holding_registers(
|
108
|
+
@mstr.preset_multiple_registers(0x11, 14, [1, 2, 3, 0xAACC]).should == @mstr
|
109
|
+
@mstr.read_holding_registers(0x11, 13, 5).should == [0, 1, 2, 3, 0xAACC]
|
118
110
|
end
|
119
111
|
|
120
112
|
it "should raise exception if illegal data address" do
|
121
|
-
lambda { @mstr.preset_multiple_registers(501, [1, 2]) }.should raise_error(ModBus::Errors::IllegalDataAddress, "Illegal data address (-2)")
|
113
|
+
lambda { @mstr.preset_multiple_registers(0x11, 501, [1, 2]) }.should raise_error(ModBus::Errors::IllegalDataAddress, "Illegal data address (-2)")
|
122
114
|
end
|
123
115
|
|
124
116
|
after(:all) do
|
125
117
|
@mstr.close unless @mstr.closed?
|
126
|
-
@sl.stop unless @sl.stoped?
|
127
118
|
end
|
128
119
|
|
129
120
|
end
|
metadata
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: libmodbus4r
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- A.Timin
|
8
8
|
autorequire: libmodbus4r
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-07-30 00:00:00 +06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
16
16
|
description:
|
17
|
-
email:
|
17
|
+
email:
|
18
18
|
executables: []
|
19
19
|
|
20
20
|
extensions:
|
@@ -22,39 +22,12 @@ extensions:
|
|
22
22
|
extra_rdoc_files:
|
23
23
|
- README
|
24
24
|
- LICENSE
|
25
|
-
- NEWS
|
26
25
|
files:
|
27
|
-
- lib/modbus4r.
|
28
|
-
- examples/use_rtu_slave.rb
|
29
|
-
- examples/use_tcp_slave.rb
|
30
|
-
- examples/use_rtu_master.rb
|
26
|
+
- lib/modbus4r.so
|
31
27
|
- examples/use_tcp_master.rb
|
32
|
-
- spec/rtu_master_spec.rb
|
33
28
|
- spec/tcp_master_spec.rb
|
34
|
-
- spec/rtu_slave_spec.rb
|
35
|
-
- spec/tcp_slave_spec.rb
|
36
|
-
- ext/errors.h
|
37
|
-
- ext/slave.c
|
38
|
-
- ext/modbus.h
|
39
|
-
- ext/master.h
|
40
|
-
- ext/modbus4r.h
|
41
|
-
- ext/rtu_master.c
|
42
|
-
- ext/extconf.rb
|
43
|
-
- ext/slave.h
|
44
|
-
- ext/rtu_master.h
|
45
|
-
- ext/errors.c
|
46
|
-
- ext/master.c
|
47
|
-
- ext/rtu_slave.c
|
48
|
-
- ext/rtu_slave.h
|
49
|
-
- ext/tcp_master.h
|
50
|
-
- ext/tcp_slave.c
|
51
|
-
- ext/tcp_slave.h
|
52
|
-
- ext/modbus.c
|
53
|
-
- ext/tcp_master.c
|
54
|
-
- ext/modbus4r.c
|
55
29
|
- README
|
56
30
|
- LICENSE
|
57
|
-
- NEWS
|
58
31
|
has_rdoc: true
|
59
32
|
homepage:
|
60
33
|
licenses: []
|
@@ -83,7 +56,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
83
56
|
requirements: []
|
84
57
|
|
85
58
|
rubyforge_project:
|
86
|
-
rubygems_version: 1.3.
|
59
|
+
rubygems_version: 1.3.4
|
87
60
|
signing_key:
|
88
61
|
specification_version: 3
|
89
62
|
summary: Binding use *libmodbus* (free implementation of modbus for Linux\MacOS) for Ruby.
|
data/NEWS
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
libmodbus4r 0.3.0 (2009-09-21)
|
2
|
-
===========================
|
3
|
-
- Added support slave for TCP and RTU protocol
|
4
|
-
- Migrated on libmodbus 0.2.2
|
5
|
-
- Added source of libmodbus in project
|
6
|
-
- Compatibility with ruby-1.8.7
|
7
|
-
|
8
|
-
libmodbus4r 0.2.2 (2009-08-16)
|
9
|
-
===========================
|
10
|
-
- Fixed bug in Master::read_input_registers
|
11
|
-
|
12
|
-
libmodbus4r 0.2.1 (2009-08-10)
|
13
|
-
===========================
|
14
|
-
- Fixed bug in Master::read_input_coils
|
15
|
-
|
16
|
-
libmodbus4r 0.2.0 (2009-07-30)
|
17
|
-
===========================
|
18
|
-
- First public release
|
data/examples/use_rtu_master.rb
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
begin
|
2
|
-
require 'rubygems'
|
3
|
-
rescue
|
4
|
-
end
|
5
|
-
|
6
|
-
require 'modbus4r'
|
7
|
-
|
8
|
-
mstr = ModBus::RTUMaster.new('/dev/ttyS0', # device
|
9
|
-
9600, # baud: 9600, 19200, etc
|
10
|
-
"none", # parity: "even", "odd", "none"
|
11
|
-
8, # data bits: 5, 6, 7, 8
|
12
|
-
1, # stop bits: 1, 2
|
13
|
-
1) # slave id
|
14
|
-
mstr.connect
|
15
|
-
# Reads the coils status in the slave
|
16
|
-
puts mstr.read_coil_status(0, #start address
|
17
|
-
10) #number
|
18
|
-
# Reads the input status in the slave
|
19
|
-
puts mstr.read_input_status(0, #start address
|
20
|
-
10) #number
|
21
|
-
# Reads the holding registers in the slave
|
22
|
-
puts mstr.read_holding_registers(0, #start address
|
23
|
-
5) #number
|
24
|
-
# Reads the input registers in the slave
|
25
|
-
puts mstr.read_input_registers(0, #start address
|
26
|
-
5) #number
|
27
|
-
# Turns a single coil in the slave
|
28
|
-
mstr.force_single_coil(0, #coil address
|
29
|
-
true) #state
|
30
|
-
|
31
|
-
# Sets a value in one holding register in the slave
|
32
|
-
mstr.preset_single_register(0, #reg address
|
33
|
-
0xa0a0) #value
|
34
|
-
|
35
|
-
# Sets\reset the coils in the slave
|
36
|
-
mstr.force_multiple_coils(0, #start address
|
37
|
-
[true, false, true]) #data
|
38
|
-
|
39
|
-
#Copies the values in th slave
|
40
|
-
mstr.preset_multiple_registers(0, #start address
|
41
|
-
[1, 0xdf, 2]) #data
|
42
|
-
|
43
|
-
mstr.close
|
data/examples/use_rtu_slave.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
begin
|
2
|
-
require 'rubygems'
|
3
|
-
rescue
|
4
|
-
end
|
5
|
-
|
6
|
-
require 'modbus4r'
|
7
|
-
|
8
|
-
sl = ModBus::RTUSlave.new('/dev/ttyS0', # device
|
9
|
-
9600, # baud: 9600, 19200, etc
|
10
|
-
"none", # parity: "even", "odd", "none"
|
11
|
-
8, # data bits: 5, 6, 7, 8
|
12
|
-
1, # stop bits: 1, 2
|
13
|
-
1) # slave id
|
14
|
-
|
15
|
-
sl.coil_status = [false, false, false, false, false]
|
16
|
-
sl.input_status = [false, false, false, false, false]
|
17
|
-
sl.holding_registers = [0, 0, 0, 0, 0, 0, 0, 0]
|
18
|
-
sl.input_registers = [0, 0, 0, 0, 0, 0, 0, 0]
|
19
|
-
|
20
|
-
sl.start
|
21
|
-
|
22
|
-
sl.join
|
23
|
-
|
24
|
-
sl.stop
|