Linux Device Driver Tutorial Part 25 – Sending Signal from Linux Device Driver to User Space

This is the Series on Linux Device Driver. The aim of this series is to provide easy and practical examples that anyone can understand. This is the Linux Device Driver Tutorial Part 25 – Sending Signal from Linux Device Driver to User Space.

Prerequisites

In the example section, we explained signals using the interrupt program. So I would recommend you to explore interrupts using the below links before starting this.

  1. Interrupts Concepts
  2. Interrupts Examples Program
  3. IOCTL Tutorial

Signals

Introduction

Generally, A signal is an action that is intended to send a particular message. It can be sound, gesture, event, etc. Below are the normal signals which we are using the day to day life.

  • When we take money in ATM, we will get a message
  • Calling someone by making sound or gesture
  • Microwave oven making a sound when it finishes its job
  • etc.

What about Linux? Signals are a way of sending simple messages which are used to notify a process or thread of a particular event. In Linux, there are many processes that will be running at a time. We can send a signal from one process to another process. Signals are one of the oldest inter-process communication methods. These signals are asynchronous. Like User space signals, can we send a signal to userspace from kernel space? Yes, why not. We will see the complete Signals in upcoming tutorials. In this tutorial, we will learn how to send a signal from Linux Device Driver to User Space.

Sending Signal from Linux Device Driver to User Space

Using the following steps easily we can send the signals.

  1. Decide the signal that you want to send.
  2. Register the user space application with the driver.
  3. Once something happened (in our example we used interrupts) send signals to userspace.
  4. Unregister the user space application when you have done with it.

Decide the signal that you want to send

First, select the signal number which you want to send. In our case, we are going to send signal 44.

Example:

Register the user space application with driver

Before sending the signal, your device driver should know to whom it needs to send the signal. For that, we need to register the process to the driver. So we need to send the PID to the driver first. Then that driver will use the PID and sends the signal. You can register the application PID in anyways like IOCTL, Open/read/write call. In our example, we are going to register using IOCTL.

Example:

Send signals to user space

After registering the application to the driver, then the driver can able to send the signal when it requires. In our example, we will send the signal when we get the interrupt.

Example:

Unregister the user space application

When you are done with your task, you can unregister your application. Here we are unregistering when that application closes the driver.

Example:

Device Driver Source Code

The complete device driver code is given below. In this source code, When we read the /dev/etx_device interrupt will hit (To understand interrupts in Linux go to this tutorial). Whenever interrupt hits, I’m sending the signal to userspace application who registered already. Since it is a tutorial post, I’m not going to do any job in interrupt handler except sending the signal.

driver.c

Makefile:

Application Source Code

This application register with the driver using IOCTL. Once it registered, it will be waiting for the signal from the driver. If we want to close this application we need to press CTRL+C. Because we it will run infinitely. We have installed CTRL+C signal handler.

test_app.c

Building Driver and Application

  • Build the driver by using Makefile (sudo make)
  • Use the below the line in the terminal to compile the user space application.

gcc -o test_app test_app.c

Execution (Output)

As of now, we have driver.ko and test_app. Now we will see the output.

  • Load the driver using sudo insmod driver.ko
  • Run the application (sudo ./test_app)

  • This application will be waiting for the signal
  • To send the signal from driver to app, we need to trigger the interrupt by reading the driver (sudo cat /dev/etx_device).
  • Now see the Dmesg (dmesg)

  • As per the print, the driver has sent the signal. Now check the app.

  • So the application also got the signal.
  • Close the application by pressing CTRL+C
  • Unload the module using sudo rmmod driver

Note: If you use newer version of kernel, then you might face some issues. Please go through the below comments and fix it.

In our next tutorial, we will discuss kernel timer in the Linux device driver.

0 0 vote
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

6 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Mihaita Ivascu
Mihaita Ivascu
February 14, 2019 10:35 AM

Hello,

Interesting post. Could you please share the application as well?
I think the driver code has been copied over.

Thanks,
Mihaita

EmbeTronicx India
EmbeTronicx India
Reply to  Mihaita Ivascu
February 15, 2019 9:34 AM

Hi Mihaita,
Thanks for pointing that. Now we have copied the application code.
Thanks.

swati agarwal
swati agarwal
June 9, 2019 6:01 AM

Getting following error in dmesg logs
do_IRQ: 7.59 No irq handler for vector

while triggering interrupt
sudo cat /dev/etx_device

Tried following steps to get rid of this error

sudo gedit /etc/default/grub
change GRUB_CMDLINE_LINUX_DEFAULT=”quiet splash pci=nomsi,noaer”
3.sudo update-grub

but its not working

kernel version :- 4.14.0-041400-generic

EmbeTronicX
EmbeTronicX
Reply to  swati agarwal
April 1, 2020 5:52 AM

Hi,

You might be using newer kernel than we have used it. Please refer this link to fix that.

shubham Chidrawar
shubham Chidrawar
September 18, 2019 12:47 PM

getting error

/home/bucky/Desktop/new_driver/driver.c: In function ‘irq_handler’:
/home/bucky/Desktop/new_driver/driver.c:65:27: error: storage size of ‘info’ isn’t known
struct kernel_siginfo info;//defined in signal.h

EmbeTronicX
EmbeTronicX
Reply to  shubham Chidrawar
April 1, 2020 6:03 AM

Hi Shubham,
You might be using the newer kernel than we have used it. You should port our old kernel changes to new kernel. We have provided our changes below.

Include this header file (#include "linux/sched/signal.h")
Then typecast the info argument to (struct kernel_siginfo *)

Please apply this patch.

+ #include "linux/sched/signal.h"
- if(send_sig_info(SIGETX, &info, task) < 0) {
+ if(send_sig_info(SIGETX, (struct kernel_siginfo *)&info, task) < 0) {

After applying this you, might face problem with interrupt too. Please refer this link to fix that issue.

6
0
Would love your thoughts, please comment.x
()
x
%d bloggers like this: