Interact with virtual serial device in polling mode in linux C - linux-kernel

I'm trying to enable polling support for a serial over USB driver on an android kernel, so that I can debug it using kgdboc. I based myself on the code from these githubs:
https://github.com/dankex/kgdb-android
https://github.com/jacktang310/KernelDebugOnNexus6P
However, I can't find a way to enable and use char by char polling mode via a C program on userland. Which makes debugging very difficult, since the only thing I can do is to set kgdboc to /dev/ttyGS0 and then send "g" to sysrq-trigger, and pray it works.
In other terms, I need a userland program that triggers the code path which reaches the following operations on the tty_operations structure:
.poll_init = gs_poll_init,
.poll_get_char = gs_poll_get_char,
.poll_put_char = gs_poll_put_char,
Instead, whenever I write to /dev/ttyGS0 I trigger the "write" operation.
Any help will be greatly appreciated.
Thanks!

I ended up creating a driver that exports a sysfs node as Chris Stratton suggested.
I based myself on this tutorial

Related

Where to find device-tree?

Coming form this question yesterday, I decided to port this library to my board. I was aware that I needed to change something, so I compiled the library, call it on a small program and see what happens. The 1st problem is here:
// Check for GPIO and peripheral addresses from device tree.
// Adapted from code in the RPi.GPIO library at:
// http://sourceforge.net/p/raspberry-gpio-python/
FILE *fp = fopen("/proc/device-tree/soc/ranges", "rb");
if (fp == NULL) {
return MMIO_ERROR_OFFSET;
}
This lib is aimed for Rpi, os the structure of the system on my board is not the same. So I was wondering if somebody could tell me where I could find this file or how it looks like so I can find it by my self in order to proceed the job.
Thanks.
You don't necessarily want that "file" (or more precisely /proc node).
The code this is found in is setting up to do direct memory mapped I/O using what appears to be a pi-specific gpio-flavored version of the /dev/mem type of device driver for exposing hardware special function registers to userspace.
To port this to your board, you would need to first determine if there is a /dev/mem or similar capability in your kernel which you can activate. Then you would need to determine the appropriate I/O registers for GPIO pins. The pi-specific code is reading the Device Tree to figure this out, but there are other ways, for example you can manually read the programmer's manual of the SoC on which you are running.
Another approach you can consider is adding some small microcontroller (or yes, barebones ***duino) to the system, and using that to collect information from various sensors and peripherals. This can then be forwarded to the SoC over a UART link, or queried out via I2C or similar - add a small amount of cost and some degree of bottleneck, but also means that the software on the SoC then becomes very portable - to a different comparable chip, or perhaps even to run on a desktop PC during development.

Device Drivers to Read and Write on a Virtual memory on linux

I am working with a SoC Cyclone V board. I want to exchange data between the HPS and FPGA. They share a common RAM, whose address can be seen on Qsys. I would like to Read and write data in this shared Memory, but dont want to use devmem2 every time i do it. I understand that a driver would be much safer. I was thinking of writing a char driver as it is one of the easy drivers to write for the basic read and write operations.
Is there a way to specify the address to be used by the char driver when we build and insert it?
If not, what driver can be written for the this function (to be able to read and write float values on a specific range of virtual address)?
I have found that user io device drivers or block drivers could be good options. But I am new to this area of development and don't know if these are the only options, or are they any more.
I could really use some help in deciding which driver is appropriate, it would be better if it was a char driver where the address can be specified.
Thank you.

Set linux power state from kernel module?

I have a little driver that is handling a gpio that when enabled should tell the system to sleep/wake when a button is pressed. If its held down it should power off.
On WinCE there is a very easy to use mechanism (SetSystemPowerState) but there doesn't appear to be something similar on linux.
We also don't have dbus...
update:
I may have found the answer
Shutdown (embedded) linux from kernel-space
Though it doesn't really say how to sleep but i think I'll be able to figure the rest out. This doesn't seem like the proper way to handle a linux kernel driver since the module is built into the kernel. It doesn't appear that I have all the power states available to switch to without adding packages outside of the kernel.
If you want to suspend your system entirely, you can use /sys/power/state interface like belows.
echo "mem" > /sys/power/state
It calls state_store() function in kernel/power/main.c to suspend your system into memory. Instead of "mem", you can use "standby" or "disk" only if your system supports them.
The most general way would be to initiate the process from kernelspace as a userspace helper:
static const char * const set_power_argv[] =
{ "/bin/echo", "mem", "/sys/power/state", NULL };
call_usermodehelper(shutdown_argv[0], shutdown_argv, NULL, UMH_NO_WAIT);
However, location of echo command and power driver can differ in your system.

Linux UART driver - debugging time taken for __init call

I am a bit new to the Linux kernel and our team is trying to optimize the boot-up time for the device. It was observed that 8250 UART driver takes more than 1 second to complete the __init call. Using printk's and going by the generated console time-stamps prefixed to every log message, I was able to narrow down the function call which takes the extra time:
ret = platform_driver_register(&serial8250_isa_driver);
Being a novice, I was unsure about what more could I do from a debugging standpoint to track down the issue ? I am looking for pointers/suggestions from some of the experienced Kernel developers out there.. Just curious as to what other approach would the Kernel developers, use from their "Debugging Toolbox" ?
Thanks,
Vijay
If I understand correct, the register function is doing stuff with that struct (maybe polling addresses or something). You would need to see if any of the functions defined within are being called by register.
To more answer your question, does the platform you're running on have an 8250 ISA UART? If not, that could well explain why it's taking so long to init (it's timing out).

USBHIDManager HID, getReport() and setReport() On Mac Environment

We are trying to communicate with a USB HIDDevice. This device is working fine in windows, where we can send a report and get a report back using WriteFile() and ReadFile().
On the Mac, we are trying to interface with the device using setReoprt() and getReport(). But getReport() is not returning any data, but an error.
What is the wrong in the application?
In order to make use of asynchronous behavior, the event source obtained using getAsyncEventSource must be added to a run loop.
The above note is part of the comment of setReport. U might need to learn the runloop mechanism of Runloop in Mac OS first.
Since it's impossible to explain the mechanism here. The following functions and orders might help u coding when u get familiar with RunLoop.(Try to search "CFRunLoop" in google)
CFRunLoopGetCurrent();
CFRunLoopRun();
CFRunLoopAddSource(CFRunLoopRef rl, CFRunLoopSourceRef source, CFStringRef mode);
CFRunLoopStop(CFRunLoopRef rl);(i usually call this function in the callback method)

Resources