From a27cb5bd8c67f23a4db003fc91460cd2c8090d8e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mattias=20F=C3=A4lt?= <mattiasf@control.lth.se>
Date: Thu, 24 Aug 2017 16:26:10 +0200
Subject: [PATCH] Precompilation and restructuring

---
 .../example.jl => Examples/testLED.jl         |  7 +++-
 src/BeagleBone/BeagleBone.jl                  | 29 +++++++++++---
 src/BeagleBone/Debug.jl                       |  9 +++++
 src/BeagleBone/GPIO.jl                        |  7 +++-
 src/BeagleBone/SysLED.jl                      |  6 ++-
 src/BeagleBone/precompile.jl                  | 34 +++++++++++++++++
 src/Computer/BeagleBoneStream.jl              | 22 +++--------
 src/Computer/{server.jl => Computer.jl}       |  0
 src/Computer/Device.jl                        | 15 ++++++--
 src/Computer/SysLED.jl                        |  4 +-
 src/LabConnection.jl                          | 18 ++++++++-
 test/testtime.jl                              | 38 +++++++++++++++++++
 12 files changed, 155 insertions(+), 34 deletions(-)
 rename src/Computer/example.jl => Examples/testLED.jl (83%)
 create mode 100644 src/BeagleBone/Debug.jl
 create mode 100644 src/BeagleBone/precompile.jl
 rename src/Computer/{server.jl => Computer.jl} (100%)
 create mode 100644 test/testtime.jl

diff --git a/src/Computer/example.jl b/Examples/testLED.jl
similarity index 83%
rename from src/Computer/example.jl
rename to Examples/testLED.jl
index 5a9b15e..ef13179 100644
--- a/src/Computer/example.jl
+++ b/Examples/testLED.jl
@@ -1,4 +1,9 @@
-include("server.jl")
+#On beaglebone, run:
+# include("LabConnection/src/LabConnection.jl")
+# using LabConnection.BeagleBone
+# run_server()
+
+using LabConnection.Computer
 
 stream = BeagleBoneStream(ip"192.168.7.2")
 led2 = SysLED(2)
diff --git a/src/BeagleBone/BeagleBone.jl b/src/BeagleBone/BeagleBone.jl
index a6a0150..934bf47 100644
--- a/src/BeagleBone/BeagleBone.jl
+++ b/src/BeagleBone/BeagleBone.jl
@@ -2,11 +2,12 @@
 # write!(::T, identifier, val)
 # read(::T, identifier)
 
+include("Debug.jl")
 include("SysLED.jl")
 include("GPIO.jl")
 
 #List of available devices and their constructors
-const DEVICES = Dict("sysled" => SysLED(), "gpio" => GPIO())
+const DEVICES = Dict("debug" => Debug(), "sysled" => SysLED(), "gpio" => GPIO())
 
 """
     dev = getdev(devname)
@@ -58,11 +59,27 @@ Run a server on `port` that listens for commands from computer
 function run_server(port=2001)
     server = listen(port)
     @async while isopen(server)
-        sock = accept(server)
-        @async while isopen(sock)
-            l = deserialize(sock);
-            println("deserialize: $l")
-            bbparse(l)
+        try
+            sock = accept(server)
+            @async while isopen(sock)
+                try
+                    l = deserialize(sock);
+                    println("deserialize: $l")
+                    bbparse(l)
+                catch err
+                    if !isopen(sock) && isa(err, Base.EOFError)
+                        println("Connection to server closed")
+                    else
+                        throw(err)
+                    end
+                end
+            end
+        catch err
+            if isa(err,Base.UVError) && err.prefix == "accept"
+                println("Server closed successfully")
+            else
+                throw(err)
+            end
         end
     end
     return server
diff --git a/src/BeagleBone/Debug.jl b/src/BeagleBone/Debug.jl
new file mode 100644
index 0000000..f2e47f5
--- /dev/null
+++ b/src/BeagleBone/Debug.jl
@@ -0,0 +1,9 @@
+"""
+    Debug
+Type for debugging and precompile
+"""
+
+type Debug
+end
+write!(::Debug, ind::Int32, val, debug::Bool=false) = nothing
+read(::Debug, ind::Int32, debug::Bool=false) = -1
diff --git a/src/BeagleBone/GPIO.jl b/src/BeagleBone/GPIO.jl
index e1d748a..1258e4c 100644
--- a/src/BeagleBone/GPIO.jl
+++ b/src/BeagleBone/GPIO.jl
@@ -63,7 +63,9 @@ channels =[
     "gpio7"
 ]
 
-function write!(::GPIO, index::Int32, operation::Int32, entry::Bool)
+function write!(::GPIO, index::Int32, args::Tuple{Int32,Bool}, debug::Bool=false)
+    debug && return
+    operation, entry = args[1], args[2]
     (index <= 0 || index > length(channels)) && error("Invalid GPIO index: $index")
     (operation <= 0 || operation > length(writeOperations)) && error("Invalid GPIO operation: $operation")
     filename = "/sys/class/gpio/$(channels[index])/$(writeOperations[operation]["dir"])"
@@ -76,7 +78,8 @@ function write!(::GPIO, index::Int32, operation::Int32, entry::Bool)
     return
 end
 
-#function Base.read(::SysLED, ind::Int32)
+#function Base.read(::SysLED, ind::Int32, debug::Bool=false)
+#    debug && return
 #    (ind < 0 || ind > length(channels)) && error("Invalid SysLEND ind: $ind")
 #    println("not yet supported")
 #    l = 0
diff --git a/src/BeagleBone/SysLED.jl b/src/BeagleBone/SysLED.jl
index 45589f9..472fd5d 100644
--- a/src/BeagleBone/SysLED.jl
+++ b/src/BeagleBone/SysLED.jl
@@ -4,7 +4,8 @@ The on-board leds with id ∈ [1,2,3,4]
 struct SysLED
 end
 
-function write!(::SysLED, ind::Int32, val::Bool)
+function write!(::SysLED, ind::Int32, val::Bool, debug::Bool=false)
+    debug && return
     ind ∉ [1,2,3,4] && error("Invalid SysLEND ind: $ind")
     filename = "/sys/class/leds/beaglebone:green:usr$(ind-1)/brightness"
     file = open(filename, "r+")
@@ -12,7 +13,8 @@ function write!(::SysLED, ind::Int32, val::Bool)
     close(file)
     return
 end
-function Base.read(::SysLED, ind::Int32)
+function read(::SysLED, ind::Int32, debug::Bool=false)
+    debug && return
     ind ∉ [1,2,3,4] && error("Invalid SysLEND ind: $ind")
     filename = "/sys/class/leds/beaglebone:green:usr$(ind-1)/brightness"
     file = open(filename, "r")
diff --git a/src/BeagleBone/precompile.jl b/src/BeagleBone/precompile.jl
new file mode 100644
index 0000000..1c5a24d
--- /dev/null
+++ b/src/BeagleBone/precompile.jl
@@ -0,0 +1,34 @@
+function precompile_bb()
+    #Start server
+    server = run_server(3001)
+
+    #Pretend to be Computer
+    clientside = connect(3001)
+
+    #Precompile serialize
+    serialize(clientside, (true, Int32(1), ("debug", Int32(1), true), ("debug", Int32(1), (1,2.0,"asd"))))
+    serialize(clientside, (true, Int32(2), ("debug", Int32(1), Int32(1)),
+                                    ("debug", Int32(1), 1.0)))
+    serialize(clientside, (false, Int32(2),    ("debug", Int32(1)),
+                                        ("debug", Int32(1))))
+
+
+    close(clientside)
+    #Close server
+    close(server)
+
+    debug = true
+    #Precompile SysLED
+    led = SysLED()
+    write!(led, Int32(1), true, debug)
+    read(led, Int32(1), debug)
+
+    # Precompile GPIO
+    gpio = GPIO()
+    write!(gpio, Int32(1), (Int32(2), true), debug)
+    #read(gpio, ind, args, debug)
+
+    try getdev("nonexistent")       catch end
+    try bbparse("Invalid input")    catch end
+    try bbparse(("Invalid input"))  catch end
+end
diff --git a/src/Computer/BeagleBoneStream.jl b/src/Computer/BeagleBoneStream.jl
index 204db80..557da8f 100644
--- a/src/Computer/BeagleBoneStream.jl
+++ b/src/Computer/BeagleBoneStream.jl
@@ -1,3 +1,5 @@
+export BeagleBoneStream, init_devices!, send!
+
 struct BeagleBoneStream <: LabStream
     devices::Array{Device,1}
     stream::TCPSocket
@@ -9,7 +11,7 @@ function BeagleBoneStream(addr::IPAddr, port::Int64=2001)
 end
 
 #For BeagleBoneStream we can directly serialize the data, other streams might want to send binary data
-Base.serialize(bbstream::BeagleBoneStream, cmd) = serialize(bbstream.stream, cmd)
+serialize(bbstream::BeagleBoneStream, cmd) = serialize(bbstream.stream, cmd)
 
 function init_devices!(bbstream::BeagleBoneStream, devs::Device...)
     for dev in devs
@@ -40,7 +42,7 @@ function send!(stream::BeagleBoneStream)
     end
     return
 end
-function Base.read(stream::BeagleBoneStream)
+function read(stream::BeagleBoneStream)
     cmds = Tuple[]
     for dev in stream.devices
         cmd, devstream = safe_getreadcommand(dev)
@@ -57,22 +59,10 @@ function Base.read(stream::BeagleBoneStream)
     end
     return
 end
-function init_devices!(bbstream::BeagleBoneStream, devs::Device...)
-    for dev in devs
-        if dev ∉ bbstream.devices
-            setstream!(dev, bbstream)
-            push!(bbstream.devices, dev)
-            initialize(dev)
-        else
-            warn("Device $dev already added to a stream")
-        end
-    end
-    return
-end
 
-function Base.close(bbstream::BeagleBoneStream)
+function close(bbstream::BeagleBoneStream)
     cmds = Tuple[]
-    for dev in stream.devices
+    for dev in bbstream.devices
         close(dev)
     end
     close(bbstream.stream)
diff --git a/src/Computer/server.jl b/src/Computer/Computer.jl
similarity index 100%
rename from src/Computer/server.jl
rename to src/Computer/Computer.jl
diff --git a/src/Computer/Device.jl b/src/Computer/Device.jl
index 0274302..96c299c 100644
--- a/src/Computer/Device.jl
+++ b/src/Computer/Device.jl
@@ -1,8 +1,10 @@
+export initialize, getstream, setstream!, send!, set!, getsetvalue
+
 ###### Defaults for Device
 #What to do when connecting
 initialize(::Device) = nothing
 #What to do when disconnecting
-Base.close(::Device) = nothing
+close(::Device) = nothing
 #Which stream is the Device connected to
 getstream(dev::Device) = dev.stream
 #Set the stream the Device is connected to
@@ -32,12 +34,17 @@ end
 function send!(dev::Device, val)
     cmd, stream = safe_getwritecommand(dev, val)
     #TODO This is not very general
-    serialize(stream, (true, Int32(1), cmd))
+    allcmds = (true, Int32(1), cmd)
+    println("Sending single command: $allcmds")
+    serialize(stream, allcmds)
     return
 end
-function Base.read(dev::Device)
+function read(dev::Device)
     cmd, stream = safe_getreadcommand(dev)
-    serialize(stream, (false, Int32(1), cmd))
+    allcmds = (false, Int32(1), cmd)
+    println("Sending single command: $allcmds")
+    serialize(stream, allcmds)
+
     #TODO get, wait for and return response
     return
 end
diff --git a/src/Computer/SysLED.jl b/src/Computer/SysLED.jl
index dc90891..94a6962 100644
--- a/src/Computer/SysLED.jl
+++ b/src/Computer/SysLED.jl
@@ -1,3 +1,5 @@
+export SysLED
+
 mutable struct SysLED <: Device
     i::Int32
     nextout::Bool
@@ -12,7 +14,7 @@ set!(led::SysLED, val::Bool) = led.nextout = val
 #Get the value from set! back for use
 getsetvalue(led::SysLED) = led.nextout
 #Get value that was read erlier
-Base.get(led::SysLED) = led.latestread
+get(led::SysLED) = led.latestread
 
 #No definition for IOBox since there are no LEDs
 #Stream specific methods
diff --git a/src/LabConnection.jl b/src/LabConnection.jl
index e5dbcae..2dc20ef 100644
--- a/src/LabConnection.jl
+++ b/src/LabConnection.jl
@@ -1,5 +1,19 @@
 module LabConnection
 
-# package code goes here
+    module BeagleBone
+        export run_server
+        import Base: read
+        println("Initializing BB")
+        include(joinpath("BeagleBone","BeagleBone.jl"))
+        include(joinpath("BeagleBone","precompile.jl"))
+        println("Precompiling BB")
+        precompile_bb()
+        return
+    end
 
-end # module
+    module Computer
+        import Base: read, close, get, serialize, set!
+        println("Initializing Computer")
+        include(joinpath("Computer","Computer.jl"))
+    end
+end
diff --git a/test/testtime.jl b/test/testtime.jl
new file mode 100644
index 0000000..9344e0b
--- /dev/null
+++ b/test/testtime.jl
@@ -0,0 +1,38 @@
+#BB side
+function startbb()
+    @async begin
+        server = listen(2001)
+        while true
+            sock = accept(server)
+            println("accepted")
+            @async while isopen(sock)
+                l = deserialize(sock);
+                println(typeof(l))
+                #print("Read: ");
+                println(l);
+                serialize(sock,l)
+            end
+        end
+    end
+end
+
+#Computer side
+clientside = connect(ip"192.168.7.2", 2001)
+function getminor(t)
+    println(Int64(t))
+    t2 = UInt64(floor(UInt64,t/1e9)*1e9)
+    tsmall = Int32(t-t2)
+end
+
+function runcomp(clientside)
+    @async while isopen(clientside)
+        l = deserialize(clientside)::Int32;
+        #print("Read:");
+        t = time_ns()
+        #println(t)
+        t2 = getminor(t)
+        println((t2-l)/1e6)
+    end
+end
+serialize(clientside, getminor(time_ns()))
+end # module
-- 
GitLab