Sharing code between Linux kernel and userspace/MCU - c

I have a Linux driver for an external MCU application. The driver and the MCU communicate over a bus using our own protocol.
I would like to share the program code for the protocol features between the kernel module and the MCU but since it's not possible to build a lib for the kernel my only idea so far is to write the code "as kernel as possible" and then just copy the entire .c file between the platforms.
Are there any other ways? Surly I can't be the first to want to do this.
I'm talking about code reuse, not IPC mechanisms.
Thanks!

It requires some hardware abstraction so the code implementing the protocol needs to be generic as possible not requiring any hardware specific details.
The file implementing the protocol could have functions like init, exit, read, write and interrupt. The hardware implementation itself (gpio, memory, bus) can be accessed through function pointers which are registered at time when calling the init function. The directory structure can be set up like #smbear suggested

Related

Using sock_create, accept, bind etc in kernel

I'm trying to implement an echo TCP server as a loadable kernel module.
Should I use sock_create, or sock_create_kern?
Should I use accept, or kernel_accept?
I mean it does make sense that I should use kernel_accept for example; but I don't know why. Can't I use normal sockets in the kernel?
The problem is, you are trying to shoehorn an user space application into the kernel.
Sockets (and files and so on) are things the kernel provides to userspace applications via the kernel-userspace API/ABI. Some, but not all, also have an in-kernel callable, for cases when another kernel thingy wishes to use something provided to userspace.
Let's look at the Linux kernel implementation of the socket() or accept() syscalls, in net/socket.c in the kernel sources; look for SYSCALL_DEFINE3(socket, and SYSCALL_DEFINE3(accept,, SYSCALL_DEFINE4(recv,, and so on.
(I recommend you use e.g. Elixir Cross Referencer to find specific identifiers in the Linux kernel sources, then look up the actual code in one of the official kernel Git trees online; that's what I do, anyway.)
Note how pointer arguments have a __user qualifier: this means the data pointed to must reside in user space, and that the functions will eventually use copy_from_user()/copy_to_user() to retrieve or set the data. Furthermore, the operations access the file descriptor table, which is part of the process context: something that normally only exist for userspace processes.
Essentially, this means your kernel module must create an userspace "process" (enough of one to satisfy the requirements of crossing the userspace-kernel boundary when using kernel interfaces) to "hold" the memory and file descriptors, at minimum. It is a lot of work, and in the end, it won't be any more performant than an userspace application would be. (Linux kernel developers have worked on this for literally decades. There are some proprietary operating systems where doing stuff in "kernel space" may be faster, but that is not so in Linux. The cost to do things in userspace is some context switches, and possibly some memory copies (for the transferred data).)
In particular, the TCP/IP and UDP/IP interfaces (see e.g. net/ipv4/udp.c for UDP/IPv4) do not seem to have any interface for kernel-side buffers (other than directly accessing the rx/tx socket buffers, which are in kernel memory).
You have probably heard of TUX web server, a subsystem patch to the Linux kernel by Ingo Molnár. Even that is not a "kernel module server", but more like a subsystem that an userspace process can use to implement a server that runs mostly in kernel space.
The idea of a kernel module that provides a TCP/IP and/or UDP/IP server, is simply like trying to use a hammer to drive in screws. It will work, after a fashion, but the results won't be pretty.
However, for the particular case of an echo server, it just might be possible to bolt it on top of IPv4 (see net/ipv4/) and/or IPv6 (see net/ipv6/) similar to ICMP packets (net/ipv4/icmp.c, net/ipv6/icmp.c). I would consider this route if and only if you intend to specialize in kernel-side networking stuff, as otherwise everything you'd learn doing this is very specialized and not that useful in practice.
If you need to implement something kernel-side for an exercise or something, I'd recommend steering away from "application"-type ideas (services or similar).
Instead, I would warmly recommend developing a character device driver, possibly implementing some kind of inter-process communications layer, preferably bus-style (i.e., one sender, any number of recipients). Something like that has a number of actual real-world use cases (both hardware drivers, as well as stranger things like kdbus-type stuff), so anything you'd learn doing that would be real-world applicable.
(In fact, an echo character device -- which simply outputs whatever is written to it -- is an excellent first target. Although LDD3 is for Linux kernel 2.6.10, it should be an excellent read for anyone diving into Linux kernel development. If you use a more recent kernel, just remember that the example code might not compile as-is, and you might have to do some research wrt. Linux kernel Git repos and/or a kernel source cross referencer like Elixir above.)
In short sockets are just a mechanism that enable two processes to talk, localy or remotely.
If you want to send some data from kernel to userspace you have to use kernel sockets sock_create_kern() with it's family of functions.
What would be the benefit of TCP echo server as kernel module?
It makes sense only if your TCP server provides data which is otherwise not accessible from userspace, e.g. read some post-mortem NVRAM which you can't read normally and to send it to rsyslog via socket.

UART communication in Linux kernel module

I am programming Linux kernel module for communication with device connected through UART, but I don't know how to access UART from kernel module. I don't want to write my own UART driver, I would like to use the existing one and only add communication layer for my device. I saw something similiar done in userspace-like manner, however I read that kernel modules should not access files like that. I am wondering if it could be done using existing driver's structs and functions, because that's how I have already programmed module, which used I2C. Example of a module reading from UART would be very useful.

How to pass a variable-size array from Windows kernel driver to a user-mode process?

I'm learning Windows kernel programming, and I'm wondering how do I pass a byte array from a kernel driver to my user-mode application, where the kernel driver initiates the call?
If I were to do this among user-mode processes (say, from a service to a GUI app) I'd use a named pipe or a shared memory with a named event and a named mutex for synchronization. But I'm lost what to do on the kernel driver side.
Here's my actual example: I have a kernel callback function that can be called any time with a STRING. I then need to pass the string from within it to my currently running user-mode process and to alert it.
There are tons of ways for kernel-mode to user-mode Inter-Process Communication, and different requirements can suit different techniques.
For starters, you have the option of named pipes (even in kernel-mode). However, there's something you should know... It isn't officially documented for a normal kernel-mode device driver (although there is a documented interface for Filesystem Mini-Filter device drivers).
If you want to use a named pipe from a normal kernel-mode device driver, you'll have to locate the address to NtCreateNamedPipeFile or rely on IoCreateFile (which NtCreateNamedPipeFile relies on internally, using an undocumented structure).
For using a named pipe from a Filesystem Mini-Filter device driver, you have FltCreateNamedPipeFile.
Moving on from the named pipes idea, you have the option of Local Procedure Calls! However, once again, another dead-end in terms of documentation. It is relatively straight forward to do it as a client in kernel-mode though. There's a documented interface for Ports with a Filesystem Mini-Filter device driver though: FltCreateCommunicationPort.
Moving on again, you could attach to the user-mode client and write directly to its memory.
If you really wanted, you could rely on something simple like a shared event to notify the user-mode client that you've just attached to it and written into its virtual memory.

Getting access to Raspberry PI registers in C programming

I am trying to get access to the register of my Raspberry Pi.
To be a bit more specific, http://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf has some Hardware Timers on page 172-173.
I want to use them because I have to write two functions HW_GetTimer() and HW_ClearTimer().
I can't find a good way to communicate with those registers. Is this possible? Is there an existing C function that I don't know about?
First of all, a word of warning: These registers are likely used by the Operating System, so if you fiddle with them, chances are that you break something...
That said, there are two options:
The proper one: write a kernel driver and you'll have plenty of functions to access the hardware in a sane and controlled way. Or chances are that there is already a driver that does exactly what you are trying to do, if that's the case, you just find it and use the interface it exposes. Reading the kernel source is fun!
The easy one: from user-mode land, open /dev/mem and mmap() the addresses you want to access into your process memory. Then you can read/write (use volatile pointers, please!) as you will. Note that you cannot read()/write() from/to /dev/mem, only mmap().
Obviously, for the user-mode thing you have to have the proper permissions or be root.
Guess: You are using linux.
If you are trying to do this in conjunction with Linux, there usually is a driver for (yes even for timers!) which are used internally for scheduling, tasklets and other stuff - in userspace you should use poll or epoll without any filedescriptors and just use the timeout. This will get you as close as it can get to schedulers granularity.
Another way would be to check the kernel code if the timer is used, if not you could simply export it via a kernel module, though that requires at least a basic understanding of the CPU, how the kernel works and how it is implemented without security implications or risk of crash (if not both).
I omit the bare metal way here...

How do I keep code portable while using FreeRTOS

I am hung up on how to move forward with FreeRTOS in my application. Let me propose a simple scenario. Assume I have main and a module which has some hardware specific code. This code could be for controlling a specific motor in a system or a sensor... any bit of hardware with a defined role. Within module.c I have a function called ModuleNameTask. In main I create the task using xTaskCreate and I pass ModuleNameTask. Since my ModuleNameTask is defined in module.c and not main.c, I now have to include bits of FreeRTOS within module.c in order to use functions like vTaskDelay. I don't like the fact that I am including these files within module.c as I feel its no longer portable.
So, how do I handle this? Should I remove that ModuleNameTask from module.c and place it in main.c? Or just accept the fact that I have to include bits of FreeRTOS into module.c. Any advice?
What functionality do you require from FreeRTOS for your module to work. Obviously there are some things or you wouldn't need to include the headers and you wouldn't be calling the functions.
Take these functions and put them in a separate header called os/<operating_sys>/freertos.h and wrap them in your own function names (e.g. my_createtask(<args>).). Now to port to a different OS you will need to provide a new file with new wrappers for your own functions.
If you do this poorly you'll notice that your createtask function looks exactly like the FreeRTOS function and can be easily mapped but when you want to use linux/vxWorks/other OS that the function doesn't have the right arguments.
Your createtask function should only contain the parameters that you care about. The others should be hard coded in the wrapper. This will make it easier to port (you'll have different parameters to hard code in other operating systems).
Abstract both the RTOS and the device layer.
Define an OS interface of your design (this may only be a subset of FreeRTOS functionality or even include higher level interfaces implemented using RTOS primitives) and implement this interface using FreeRTOS.
You then define your entire application including your device layer using only your RTOS abstraction layer interface. When you port your application to another platform or RTOS, you only need change the abstraction layer implementation, being sure to maintain the same semantics as the original implementation. If the device layer is also suitably abstracted so as to be able to be generic across different hardware you can do the same for hardware dependencies (i.e. abstract them from the physical implementation).
I have successfully used this approach for many years, using an RTOS abstraction in C++ that I have ported to FreeRTOS, VxWorks, Segger embOS and Keil RTX and even Windows and Linux (for test and simulation). You need not of course use C++, but it is well suited to the task.
In your abstraction you need to consider the following:
Threading
IPC (queues, pipes, event flags, mailboxes etc.)
Synchronisation (mutex, semaphores)
Timers
Interrupt handlers
Your interface might look very different from FreeRTOS itself, and it may be worth looking at a number of other RTOS interfaces to see what kind of features yours may need.

Resources