linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Interact with a serial device over USB
@ 2020-07-23 15:06 Yannick Schinko
  2020-07-23 17:11 ` Greg KH
  0 siblings, 1 reply; 2+ messages in thread
From: Yannick Schinko @ 2020-07-23 15:06 UTC (permalink / raw)
  To: linux-usb, linux-kernel

Hello,

so before I get into any detail I'd like to make clear that I am not at all familiar with the Linux kernel itself. However I'm not an inexperienced programmer.
Additionally the driver I'm describing here (and that I ultimately plan to create) is not intended to merged into the kernel itself. It's made for a specific piece of hardware that will only be produced in miniscule numbers. In turn that means removing existing modules to replace them with my own is a possibility.

Now, why I am writing here in the first place:
Currently the company I work for is designing an inline UPS for a very specific board (the APU2 series from PC engines). On that UPS there's a microcontroller that communicates over USB with the help of a CH341 chip.
I have already successfully implemented an userland program that communicates with the microcontroller. This works great! However there's two issues that led me to the conclusion that I need to implement this as a kernel module:
- Startup and shutdown times/timings: I noticed early on that the program starts too late on boot and stops too early on shutdown, no matter what I did (excluding very very dirty and impractical solutions that should never be used in any kind of production machine) I could not get it to start early enough and survive the shut down sequence long enough. The only way I can think of to circumvent this is by turning the program into a kernel module as that will allow it to start before the OS and to shutdown after the OS, which would be acceptable.
- Providing sensor data: The microcontroller has voltage sensors and temperature sensors that I would like to make available to userspace through the normal hwmon interfaces. According to my research that is only possible using a kernel module. Funnily enough that part is already implemented and works provided I feed it mocked data.

In consequence I need to create a kernel module (or at least I think so) that listens to data sent by the microcontroller over USB and then sends back some other information in response.
As a secondary functionality it would be amazing if I somehow could still forward that device as a tty (as it currently is) so I can flash firmware using avrdude. I was thinking that as long as nothing is using that tty in userspace, the kernel module listens to the device and sends responses but stops doing that as soon as the tty is in use and also continues listening again as soon as it's no longer in use. While this would be amazing to have it's not required for our use case.

I have looked into the source code for the CH341 driver and have also come across serdev. So I'm thinking of essentially modifying the CH341 driver for my purposes or using serdev to attach to the tty that's created by the CH341 driver itself.
However both are currently a fair bit beyond my understanding and frankly I have no idea how to proceed.

So anyone willing to help me out in this endeavor would be greatly appreciated!

Now the module is licensed under GPLv3 (from my understanding I'm allowed to do that if I'm modifying code licensed under GPLv2. If not, please let me know and I will change it ASAP) and the source is available at https://gitlab.connectingmedia.de/ServiceCockpit/APU-UPS-MicroController/-/tree/master/apusv_sensor if you are interested in it.

Should I have forgotten any important details, don't hesitate to ask.

Kind regards,
Yannick Schinko

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Interact with a serial device over USB
  2020-07-23 15:06 Interact with a serial device over USB Yannick Schinko
@ 2020-07-23 17:11 ` Greg KH
  0 siblings, 0 replies; 2+ messages in thread
From: Greg KH @ 2020-07-23 17:11 UTC (permalink / raw)
  To: Yannick Schinko; +Cc: linux-usb, linux-kernel

On Thu, Jul 23, 2020 at 03:06:51PM +0000, Yannick Schinko wrote:
> Hello,
> 
> so before I get into any detail I'd like to make clear that I am not at all familiar with the Linux kernel itself. However I'm not an inexperienced programmer.
> Additionally the driver I'm describing here (and that I ultimately plan to create) is not intended to merged into the kernel itself. It's made for a specific piece of hardware that will only be produced in miniscule numbers. In turn that means removing existing modules to replace them with my own is a possibility.

We take kernel drivers into the tree for only one piece of hardware in
the world, and one user.  So don't think that we would not take such a
thing, if it were actually needed (see below...)

> 
> Now, why I am writing here in the first place:
> Currently the company I work for is designing an inline UPS for a very specific board (the APU2 series from PC engines). On that UPS there's a microcontroller that communicates over USB with the help of a CH341 chip.
> I have already successfully implemented an userland program that communicates with the microcontroller. This works great! However there's two issues that led me to the conclusion that I need to implement this as a kernel module:
> - Startup and shutdown times/timings: I noticed early on that the program starts too late on boot and stops too early on shutdown, no matter what I did (excluding very very dirty and impractical solutions that should never be used in any kind of production machine) I could not get it to start early enough and survive the shut down sequence long enough. The only way I can think of to circumvent this is by turning the program into a kernel module as that will allow it to start before the OS and to shutdown after the OS, which would be acceptable.

Just fix your system to do this better.  You can start your program
_REALLY_ early at boot, and just never stop running it until you power
down.  That control is up to you, you do not have to be a kernel module
to do that at all.

In fact, you could run your code _before_ kernel modules are loaded, by
putting it into the initramfs, if you really need it.

This isn't a kernel issue, but a userspace configuration issue, that you
have control over fixing.

> - Providing sensor data: The microcontroller has voltage sensors and temperature sensors that I would like to make available to userspace through the normal hwmon interfaces. According to my research that is only possible using a kernel module. Funnily enough that part is already implemented and works provided I feed it mocked data.

Why not use a userspace USB driver to talk to the device and do it that
way?  Why does it have to be a kernel driver?

> In consequence I need to create a kernel module (or at least I think
> so) that listens to data sent by the microcontroller over USB and then
> sends back some other information in response.

Userspace USB code works just fine for this too.

> As a secondary functionality it would be amazing if I somehow could still forward that device as a tty (as it currently is) so I can flash firmware using avrdude. I was thinking that as long as nothing is using that tty in userspace, the kernel module listens to the device and sends responses but stops doing that as soon as the tty is in use and also continues listening again as soon as it's no longer in use. While this would be amazing to have it's not required for our use case.

I don't understand what you mean by this.

In short, I think you should be able to do everything you want/need from
userspace today, no kernel programming needed.

good luck!

greg k-h

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-07-23 17:11 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-23 15:06 Interact with a serial device over USB Yannick Schinko
2020-07-23 17:11 ` Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).