Access USART from kernel to send and recive - linux

Hy i wanted to Use the USART3 from my STM32MP157-DK1 Module. i wanted to write a simple driver witch listens on the RX and writes it as Kernel Log and the TX to send an a every send. To my question whats the common whay to access the uart.
What i have tried was to add the USART in the device tree so the tty driver makes it usable. But i wanted to read and write then ofer the dev/tty* file and what i know it is not recomended to open files from Kernel Space. Can someone tell me how the common way is. An example would also be helpfull. Sorry for the question but i am new in this area.

In my case i looked it up how the TTY Driver from the System does it and i do it now like this way (drivers/tty/serial/stm32-usart.c). I also found out i could use the secend CPU and share the invormations with Interrupts.
The example code can be found here:
stm32.usart.c

Related

Audio driver base address, DMA and IRQ

In the old days you would look at finding the base addr, DMA and IRQ to communicate with a device. I'm kinda looking for the equiviant.
I'm looking to communicate directly with an audio device, not through a driver, in Linux. Time isn't an issue, but I am struggling to find the information that I need and I know there is a possibility of needing a lot of code, that's fine.
I was wondering if anyone could point me in the right direction to achieving this.
Thankyou very much.
As far as I was aware you couldn't use IRQs or DMA if you're in a user-mode process from linux and this guide (heading 3) seems to confirm that, however after checking I managed to find this Linux driver (udmabuf) that lets you access DMA buffers through the user space; maybe this is what you are looking for?
Otherwise I would mabye try and write a similar, but more customized version of (udmabuf), specific to your purpose.
I'm not sure entirely what you are planning on using it for, but the first thing I would look for is building a driver for what you wanted to do (here's how to get started for ALSA just as an example). At least to communicate at this level, unless you wanted to do some of your own OS development? (I think this would be the way in the end if you really couldn't use drivers for whatever purpose)
I feel bad by answering this myself, WoodyDev, thankyou for pointing me in the right direction.
You are right, a driver is the best way to go.
The best solution is to read the PCI Address Space, the first 64 bytes contain all the data needed.
https://www.safaribooksonline.com/library/view/linux-device-drivers/0596000081/ch15.html

How to send a simple message from kernel to user space?

I have a very simple (I think) problem.
I have a very simple kernel module, which handling an interrupt coming from my hardware (its all described in my device tree). I get the interrupt in kernel. Now I want to send a message (just 64 Bit, two uint32_t) to a program in user space. It will also be ok if I can "wake" up my program (there are serveral threads in there, so one thread could sleep until it will woke up by kernel module).
My problem is: What is the easiest and clearest solution? I read about netlink, using the proc filesystem, but
either I cannot find some clear examples out there
the messageing is only from user to kernel space
examples are outdated for the kernel I use (4.4).
Does anybody have a very clear example or a how to do such things?
P.S. I don't want to handle all the things following on the interrupt in kernel space. It's ok if some messages getted lost.

Read/Write block directly to disk in linux kernel

As the title has said, I'm looking for how I can read/write blocks directly to disk in linux kernel space (bypassing the file system) and directly interact with block IO layer.
After reading through some kernel codes, I realize bio is the structure I should be using to achieve such goal in block IO layer. But I don't quite understand the structures of bio and haven't figure out how exactly I can do that.
Any helps? Thank you
If you're only doing something simple, you don't really need to mess with BIO. What you can do instead is to simply open the block device (/dev/whatever) as if it was a file. The kernel will do the right thing and will give you the "thin" wrapper for read/write operations.
In regard to opening the file from the kernel space, there are few questions here, already answered, like this one:
How to read/write files within a Linux kernel module?
If you want to do anything more fancy, you will have to study the sources of the FS drivers (in the fs/ subdirectory) to hunt for examples.
In case anyone is interested in doing this with Node.js, we released a native add on yesterday with helpers for opening and working with block devices: https://github.com/ronomon/direct-io

How can I get edge events via GPIO on Linux without a busy-loop?

I'm working an a system with embedded Linux (Kernel 2.6.31).
It is a AT91SAM9G20 chip inside, and some of the Pins are forwarded to the outside.
Now I want to use them as GPIO Inputs.
I read the gpio.txt documentation about using the GPIOs via filesystem, and that works very well 'til here. I connected some switches to the gpio-pins and I can see the result in /sys/class/gpio/gpioX/value. But now I'd like to react on a change without busy-waiting in a loop. (i.e echo "Switch1 was pressed").
I guess I need interrupts here, but I couldn't find out how to use them without writing my own kernel driver. I'm relatively new to Linux and C (I normally program in Java), so I'd like to handle the Interrupts via sysfs too. But my problem is, that there is no "edge"-file in my GPIO directory (I guess because this is only since Kernel version 2.6.33+). Is that right? Instead of "edge" I've got a uevent file in there, which is not described in gpio.txt.
In the gpio.txt documentation there was a Standard Kernel Driver mentioned: "gpio_keys". Is it possible to use this for my problem?
I guess it would be better to work with this driver than allowing a userspace program to manipulate kernel tasks.
I found a lot of codesnippets for writing my own driver, but I wasn't even able to find out which of the 600 gpio.h files to include, and how to refer to the library (cross compiler couldn't find the gpio.h file).
Sorry for newbie questions, I hope you could give me some advices.
Thanks in advance
See this for an example on how to do that. Basically, the thing you're missing is the usage of the select or poll system calls.

how to monitor the syslog(printk) in a LKM

deal all,
i am a newbie for writing Linux Kernel Module.
i used printk function in linux kernel source code (2.4.29) for debugging and display messages.
now, i have to read all the messages i added via httpd.
i tried to write the messages into a file instead of printk function, so i can read the file directly.
but it's not work very well.
so, i have a stupid question...
is it possible to write a LKM to monitor the syslog and rewrite into another file??
i mean is that possible to let a LKM the aware the messages when each time the linux kernel execute "printk"??
thanks a lot
That is the wrong way to do it, because printk already does this : it writes in the file /proc/kmsg.
What you want is klogd, a user space utility dealing with /proc/kmsg.
Another options is to use dmesg, which will output the whole content of the kernel buffers holding the printk messages, but I suggest you first read the linked article
You never, ever, ever want to try to open a file on a user space mounted block file system from within the kernel. Imagine if the FS aborted and the kernel was still trying to write to it .. kaboom (amongst MANY other reasons why its a bad idea) :) As shodanex said, for your purposes, its much better to use klogd.
Now, generally speaking, you have several ways to communicate meaningful data to userspace programs, such as:
Create a character device driver that causes userspace readers to block while waiting for data. Provide an ioctl() interface to it which lets other programs find out how many messages have been sent, etc.
Create a node in /proc/yourdriver to accomplish the same thing
Really, the most practical means is to just use printk()

Resources