Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add missing timeout implementation from #61 and fixed #72 (missing flow-control setting in tests) #74

Merged
merged 7 commits into from
Nov 11, 2020

Conversation

mgkuhn
Copy link
Collaborator

@mgkuhn mgkuhn commented Aug 15, 2020

No description provided.

This test routine claimed in a comment to disable flow control. It
actually requires the serial port to be transparent for all 256 byte
values, which in turn requires deactivation of software flow control,
because otherwise the byte-transparency tests fail for bytes 0x11
(Ctrl-Q, XON) and 0x13 (Ctrl-S, XOFF) on systems such as Ubuntu Linux
where software flow control is active by default.
Added new functions to set and clear cumulative timeouts for blocking
read and write functions, a new `Timeout` exception that will be
thrown, and time-tracking code in calls to the blocking read/write
functions. This way, users can now set overall timeouts on other IO
functions, such as `readuntil`, that make multiple calls to our
blocking functions.
That what other close(::IO) methods in Base do. It looks quite odd in the
REPL to get the entire closed SerialPort object thrown back at you.
also polished some docstrings and fixed a parameter name inconsistency
@samuelpowell
Copy link
Collaborator

(P.S. Nice to see the file renaming, they have always grated slightly!)

The low-level API wrappers now sit in a submodule LibSerialPort.Lib.

The high-level API currently still re-exports a few symbols from that
low-level API module, to preserve backwards compatibility.

This is due to

* my previously started attempt to merge the low and high-level
  APIs for the three functions sp_flush, sp_drain, and sp_output_waiting

* the fact that several high-level APIs currently still refer to
  enum types and constants defined by the low-level API

We may want to phase out either or both in future, for a cleaner
separation, and a more Julian high-level API.
@mgkuhn
Copy link
Collaborator Author

mgkuhn commented Aug 17, 2020

@samuelpowell commented on commit 189cf36:

Module names should be capitalised. Can I suggest Lib rather than Wrap as it more closely follows typical conventions for library wrappers amongst packages, and makes it a bit more clear what it is.

Sure. I have now renamed in the replacement commit 61d1a59 the new module LibSerialPort.wrap into LibSerialPort.Lib, as you suggested. (The file containing that module still remains wrap.jl.)

By the way, is there anywhere a “Style Guide for Julia C wrapper module authors” that collects such conventions?

@samuelpowell
Copy link
Collaborator

This looks really nice, thanks for all your work.

I don't know of any style guide on this topic, and things have changed quite a lot with the advent of JLL packages and autogeneration through Clang.jl. A common pattern for this type of package used to be, e.g., to have the package and Julia API module called SerialPort with submodule LibSerialPort, such that the distinction between the Julia side and the raw C bindings was very clear, and there was notionally some acceptance that the submodule with the name of the C library was a direct (and potentially unsafe) mapping. That was never the case in this repo, not least because of the existence of SerialPorts.jl.

Thus I think this boils down to style. In my view maintaining the Lib in the submodule reinforces the idea that this is clearly low level library access, whereas Wrap or Wrapper leaves some ambiguity with regard to how high- or low-level (or indeed, how safe) the functions in the submodule are.

Would you let us know when you are happy with this PR, I'll try and do some local testing, hopefully others too?

@mgkuhn mgkuhn mentioned this pull request Oct 26, 2020
@IanButterworth
Copy link
Member

Would you let us know when you are happy with this PR

@mgkuhn I had assumed this wasn't ready given this and no reply from you. Sorry for the mixup

I'll give this a test today. Hopefully we can wrap it up and release promptly

@mgkuhn
Copy link
Collaborator Author

mgkuhn commented Oct 26, 2020

Sorry, hadn't spotted the last question. Yes, I'm happy for this PR to be merged. Note that this PR is meant to be backwards compatible to previous versions. However, if you accept this PR, I will then follow it up with another non-backwards-compatible tidy-up PR that at least renames the three pass-through methods

# pass through some methods from the low-level interface
sp_output_waiting(sp::SerialPort) = sp_output_waiting(sp.ref)
sp_flush(sp::SerialPort, args...) = sp_flush(sp.ref, args...)
sp_drain(sp::SerialPort)          = sp_drain(sp.ref)

because if we are now cleanly splitting the low-level and high-level API, they should certainly not be sharing functions, as they do at the moment still thanks to the above three lines (which I added in c903d98 when I still thought we might unify rather than cleanly separate the low-level and high-level API). The sp_* prefix should be reserved entirely for the low-level API. (The difficulty here is that the word "flush" means something quite different in libserialport and Base, see #68.)

@IanButterworth
Copy link
Member

This PR has proven to be stable for me in real-world use

However, on both master and this PR the tests fail with:

OS error code 5: Input/output error
Low level API: Error During Test at /home/ian/.julia/dev/LibSerialPort/test/runtests.jl:37
  Test threw exception
  Expression: test_low_level_api(port, baudrate) == nothing
  libserialport returned SP_ERR_FAIL - Host OS reported a failure.
OS error code 5: Input/output error
High level API: Error During Test at /home/ian/.julia/dev/LibSerialPort/test/runtests.jl:43
  Test threw exception
  Expression: test_high_level_api(port, baudrate) == nothing
  libserialport returned SP_ERR_FAIL - Host OS reported a failure.

Have others found tests to work locally? I have a few serial devices embedded in my system, so cannot try disconnecting them

@IanButterworth
Copy link
Member

Would anybody object to merging and releasing 0.5? If not I will do so at 6pm ET today

@mgkuhn
Copy link
Collaborator Author

mgkuhn commented Nov 10, 2020

Happy for merge. Also happy to look at your test failures (next weekend?) if you open a new issue about it, including a description of what serial devices you have in your test system.

Note that the tests do require connection of a loop-back adapter (i.e. connecting RX and TX with each other), and the tests do not currently make it very clear if there is no suitable test setup present. Initialization of the tests and documentation of the test setup can certainly be improved (all entirely separate issues from this PR).

@mgkuhn
Copy link
Collaborator Author

mgkuhn commented Nov 10, 2020

Other question: how does one join JuliaIO? How does this group/organization work? Is there a mailing list, slack/IRC/etc. channel, Discourse group, web page, video conference, etc. where the JuliaIO crowd hangs out?

I'd be quite interested in helping to drive a number of Julia IO packages forward (audio and serial-port IO are current priorities for me, because both are used in student projects that I supervise, but I'm also interested in other file formats and forms of hardware IO). But the relatively slow merge cycles can be a bit discouraging.

Arm64 builds have long filed, therefore let's allow them to fail in Travis until that problem is fixed, such that PR authors for other issues do not get build errors that they are not responsible for.
@IanButterworth IanButterworth merged commit 83b0506 into JuliaIO:master Nov 11, 2020
@IanButterworth
Copy link
Member

I think responsibility with this repo was just falling through the cracks, largely my fault. Sorry about that.

I'll look into how to add people to JuliaIO. There isn't really a hangout spot I know of, beyond the general julia slack. Perhaps we should set up a dedicated slack channel!

@mgkuhn
Copy link
Collaborator Author

mgkuhn commented Nov 11, 2020

I would have preferred a “Rebase and merge”, which would have simply fast-forwarded my commits, as this PR ended up doing quite a number of different things that would have been worth being preserved separately in the git history on master. I'm keen to put more work into this package, but first need to understand better how contributions should best be made in JuliaIO. If merges happen very rarely (months apart), there is an incentive to put a lot of different things on a single "fixes" branch into a single PR, otherwise I won't myself have a single branch that has all my fixes to use. But then you shouldn't squash them all together into a single commit on master. If I instead open lots of different PRs, one for each issue, that works only if these PRs get reviewed and merged very quickly, within a day or two, as otherwise I will have to juggle with too many branches at my end, and lose track on in which order they remain applicable (especially with bigger changes that involve e.g. renaming or moving content between files).

@IanButterworth
Copy link
Member

Please feel free to request specific types of merges in the future. Conceptually I prefer smaller PRs that address specific issues that can be squashed, so my default is to assume that that is what people want/expect.

And moving forward we can work to be more nimble with changes, keeping PRs smaller, and merge and release quicker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants