Many serial devices allow multiple commands to run at once, and | return their results as they finish. To make use of this, | multiple commands needs to read and write to the serial port at | once, and the return values must somehow be sorted and returned | back to the callers.
- serialManager :: Handle -> String -> String -> IO SerialManager
- closeSerialManager :: SerialManager -> IO ()
- wrapCommand :: String -> (String -> Bool) -> SerialManager -> IO String
- wrapCommandWithCallback :: String -> (String -> Bool) -> (String -> IO ()) -> SerialManager -> IO ThreadId
- data SerialManager
- type SerialCommand = (String, String -> Bool, MVar String)
Documentation
:: Handle | the handle to wrap |
-> String | the termination string for commands received from the port |
-> String | the termination string for command send to the port |
-> IO SerialManager |
serialManager
takes produces a structure around a Handle
to
| handle multiple callers to the serial port. The return value is
| the channel to which all commands will flow. Users should use
| the wrapCommand
function to access it instead of trying to
| access its details directly.
closeSerialManager :: SerialManager -> IO ()Source
Having multiple serial managers running on the same port is a disaster waiting
to happen. When you're done with a SerialManager
, run closeSerialManager
on
it to shut it down.
:: String | The command to send |
-> (String -> Bool) | The predicate to recognize the returning value |
-> SerialManager | The serial port to access |
-> IO String | The response from the port |
All the commands to operate a SerialManager
should be
specializations of wrapCommand
, created by applying it to the
first three arguments, then using that thereafter as the command to
the serial port.
For example, the Olympus IX-81 requires a login command from the
user (2LOG IN
) followed by rn
as an end of line. The
response will be 2LOG +
followed by r
. So a login command
would look like
p = ("2LOG" `isPrefixOf`)
login mgr = wrapCommand "\r\n" "2LOG IN" p
wrapCommand
uses functions of type 'String -> Bool' users can choose
whether or not to match any given command based upon its contents,
rather than just blindly saying whether it matches or not.
:: String | The command to send |
-> (String -> Bool) | The predicate to recognize the returning value |
-> (String -> IO ()) | The callback to run when the command returns |
-> SerialManager | The serial port to access |
-> IO ThreadId | The thread id in which the command is being run |
Sometimes we don't want the current thread to block, but we still
want some action when the a command returns from the serial port. To
that end, wrapCommandWithCallback
lets us pass a function of type
'String -> IO ()' to be executed when a response is recognized
by the predicate.
data SerialManager Source