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

Using IOCTL for GPIO control #96

Open
falcon35180 opened this issue Sep 17, 2023 · 4 comments
Open

Using IOCTL for GPIO control #96

falcon35180 opened this issue Sep 17, 2023 · 4 comments

Comments

@falcon35180
Copy link

I have built modbusd for an embedded NVR with an ARM CPU (HiSilicon Hi3520D V300) and am using it to communicate with a PV inverter.

The kernel module for GPIO control exposes an IOCTL interface to set pin state and direction - no sysfs file interface, unfortunately.

I figured out the correct commands to control the appropriate pin through reverse engineering (disassembling, decompiling, writing test programs).

This particular driver takes a structure pointer as an IOCTL argument; there may be others out there that take int/long arguments.

I made a slight modification to tty.c for this purpose and it works well for my case. It would be great to find a way to implement this in a more generic way.

I haven't forked the repo to publish the code since it's not really ready yet. I may work on it some more when I get a chance, but I'm mentioning it in case someone else wants to take it on.

Happy to assist in any way I can in the meantime.

@3cky
Copy link
Owner

3cky commented Sep 20, 2023

Thanks for the information. Still not sure how to incorporate IOCTL GPIO controls in mbusd in a generic way, but this functionality indeed can be helpful for someone. A good first step will probably be to create a pull request with your changes to make them accessible to anyone.

@falcon35180
Copy link
Author

I have some ideas for the design of the feature to make it versatile. An example configuration could be:

trx_control = ioctl
trx_sysfile = /dev/gpio_ctl
trx_ioctl_req = 0x4
trx_ioctl_arg_type = struct

# 1 when RTS set, 0 when clear
# rts_inv for inverse
trx_ioctl_val_1 = rts

I think this could be a good starting point, allowing for future extensions without breaking compatibility. More configuration values could be added, such as:

trx_ioctl_set_req
trx_ioctl_clr_req

trx_ioctl_set_val_<n>
trx_ioctl_clr_val_<n>

As I said, I'll do some more work on the code when I get a chance. What I have so far is just a quick hack to adapt the program to my needs.

@falcon35180
Copy link
Author

Update, in case people are wondering:

I have implemented as per the first part of my previous comment. I'll do some more refinement regarding memory allocation/freeing and safety testing (I really want to minimise chances of issuing random IOCTLs to drivers!) before uploading the code and submitting a pull request.

Rest assured that work is in progress!

@falcon35180
Copy link
Author

Update - I have done a bit more work on my code. It's been pushed to my own fork and a PR has been submitted.

It seems to work well and is in use on my own system.

I even managed to fix an unrelated bug while I was at it.

I would encourage everyone to review it themselves before putting it to work, but it looks OK so far.

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

No branches or pull requests

2 participants