1. 程式人生 > >核心和使用者空間非同步通訊

核心和使用者空間非同步通訊

非同步通訊主要又兩種方式:訊號和netlink。下面例子主要是講述驅動通過中斷方式非同步通知使用者程式:

1、驅動

/* 
*
* dsp p6a interrupt
* author: helb
* date: 2018-08-08
* 
*/


#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <linux/interrupt.h>

#define DRIVER_NAME 			"p6a"
#define P6A_IOC_MAGIC 			'A'
#define P6A_IOCDTBSIZE 			_IO(P6A_IOC_MAGIC, 0)
#define P6A_IOCGETDTB 			_IO(P6A_IOC_MAGIC, 1)

#define DSP_P6A_PHYS_ADDR 		0xfb007400
#define IOREMAP_SIZE 			1024

struct irq_dev {
	char *name;
	unsigned int irq;
	void *reg_base;
};

static struct fasync_struct *p6a_async;
struct irq_dev p6airq= {"p6airq", 9};

static int p6a_open(struct inode *inode, struct file *file)
{
	printk("Do nothing\n");
	return 0;
}

static int p6a_release(struct inode *inode, struct file *file)
{
	printk("Do nothing\n");
	return 0;
}

static ssize_t p6a_write(struct file *file, const char __user *data, size_t len, loff_t *ppos)
{
	printk("Do nothing\n");
	return 0;
}

static long p6a_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	printk("Do nothing\n");
	return 0;
}

static int p6a_fasync(int fd, struct file *filp, int on)
{
	printk("p6a fasync\n");
	return fasync_helper(fd, filp, on, &p6a_async);
}

static irqreturn_t p6a_interrupt(int irq, void *dev)
{
	u32 reg;
	reg = readl(p6airq.reg_base + 0x50);
	reg &= ~(1<<0);
	writel(reg, p6airq.reg_base + 0x50);
	kill_fasync(&p6a_async, SIGIO, POLL_IN);
	return IRQ_HANDLED;
}

/*
 *    Kernel Interfaces
 */

static struct file_operations p6a_fops = {
    .owner        = THIS_MODULE,
    .llseek        = no_llseek,
    .write        = p6a_write,
    .unlocked_ioctl = p6a_unlocked_ioctl,
    .open        = p6a_open,
    .release    = p6a_release,
	.fasync 	= p6a_fasync,
};

static struct miscdevice p6a_miscdev = {
    .minor        = MISC_DYNAMIC_MINOR,
    .name        = DRIVER_NAME,
    .fops        = &p6a_fops,
};

static int __init p6a_init(void)
{
    int ret = 0;

    ret = misc_register(&p6a_miscdev);
    if(ret) {
        printk (KERN_ERR "cannot register miscdev (err=%d)\n", ret);
		return ret;
    }

	p6airq.reg_base = ioremap(DSP_P6A_PHYS_ADDR, IOREMAP_SIZE);
	if(p6airq.reg_base == NULL){
		printk("p6a ioremap:%#x failed\n", DSP_P6A_PHYS_ADDR);
		goto error;
	}
		
	ret = request_irq(p6airq.irq, p6a_interrupt, IRQF_SHARED, p6airq.name, (void *)&p6airq);
	if(ret < 0){
		printk("p6a request_irq failed\n");
		goto error;
	}

	return 0;
error:
    misc_deregister(&p6a_miscdev);
	return -1;
}

static void __exit p6a_exit(void)
{    
	iounmap(p6airq.reg_base);
	free_irq(p6airq.irq, (void *)&p6airq);
    misc_deregister(&p6a_miscdev);
}

module_init(p6a_init);
module_exit(p6a_exit);

MODULE_AUTHOR("Byavs");
MODULE_DESCRIPTION("Byavs p6a irq event Device Driver");
MODULE_LICENSE("GPL");

2、使用者測試用例

#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<fcntl.h>

#define DEV_NAME 		"/dev/p6a"

void sig_handler(int sig)
{
	if(sig == SIGIO){
		printf("Receive io signal from kernel!\n");
	}
}

int main(void)
{
	int fd;
	
	signal(SIGIO, sig_handler);
	fd = open(DEV_NAME, O_RDWR);
	if(fd < 0){
		printf("open %s failed\n", DEV_NAME);
		return -1;
	}

	fcntl(fd, F_SETOWN, getpid());
	fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) |  FASYNC);
	printf("waiting p6a interrupt\n");
	while(1){
		sleep(1);
	}

	return 0;
}

相關推薦

核心使用者空間非同步通訊

非同步通訊主要又兩種方式:訊號和netlink。下面例子主要是講述驅動通過中斷方式非同步通知使用者程式: 1、驅動 /* * * dsp p6a interrupt * author: helb * date: 2018-08-08 * */ #include &

Linux核心使用者空間應用程式的介面—系統呼叫

系統呼叫 就是使用者空間應用程式和核心提供的服務之間的一個介面。由於服務是在核心中提供的,因此無法執行直接呼叫;相反,您必須使用一個程序來跨越使用者空間與核心之間的界限。在特定架構中實現此功能的方法會有所不同。因此,本文將著眼於最通用的架構 —— i386。 在本文中

嵌入式核心及驅動開發之學習筆記(十) 非同步通訊+中斷實現讀取資料

對於linux一切都是檔案,驅動裝置在應用層也是以檔案的形式進行讀寫。之前學了阻塞、非阻塞、多路複用的方式讀裝置,它們都需要應用主動讀取。那麼應用層有沒有一種方式,當底層將資料準備好了,應用程式自動處理這些資料?通過非同步通訊可以實現,這有寫類似硬體層的中斷概念 驅動層(準備好了資料) --&g

使用 AMQP Vert.x 實現微服務間的非同步通訊

微服務是大多數新型現代軟體解決方案中的首選架構。它們(大多數)被設計成去做一件事,它們必須相互協作去完成業務用例。微服務之間的所有通訊都是通過網路呼叫進行的;這種模式避免了服務之間的緊耦合而且提供了更好的模組分離。 這裡基本上有兩種通訊方式:同步和非同步。正確應

大資料之storm(一) --- storm簡介,核心元件,工作流程,安裝部署,電話通訊案例分析,叢集執行,單詞統計案例分析,調整併發度

一、storm簡介 --------------------------------------------------------- 1.開源,分散式,實時計算 2.實時可靠的處理無限資料流,可以使用任何語言開發 3.適用於實時分析,線上機器學習

Linux中Netlink實現熱插拔監控——核心與使用者空間通訊

1、什麼是NetLink?  它 是一種特殊的 socket,它是 Linux 所特有的,由於傳送的訊息是暫存在socket接收快取中,並不被接收者立即處理,所以netlink是一種非同步通訊機制。 系統呼叫和 ioctl 則是同步通訊機制。Netlink是面向資料包的服務

使用/proc實現核心與使用者空間通訊

1. 前言 Linux核心空間與使用者空間的通訊可通過"/proc"目錄的檔案讀寫來實現,如果只是控制核心中的引數而不是傳輸較多資料的話,用“/proc”是很合適的。另外一種核心與使用者空間通訊方式方式是使用核心裝置的讀寫或IOCTL來實現,以後再介紹。 2. /

通訊機制之非同步通訊同步通訊

同步通訊原理     同步通訊是一種連續序列傳送資料的通訊方式,一次通訊只傳送一幀資訊。這裡的資訊幀與非同步通訊中的字元幀不同,通常含有若干個資料字元。     採用同步通訊時,將許多字元組成一個資訊組,這樣,字元可以一個接一個地傳輸,但是,在每組資訊(通常稱為幀)的

linux下用多執行緒實現socket伺服器客戶端的非同步通訊

前面介紹了用select函式來實現socket的非同步收發資料,但是select函式也有一些缺陷,要使socket能持續地通訊,select必須不停地檢測,這樣程序就會一直阻塞在這裡,限制了功能的擴充套件,這裡我們用多執行緒的方式,另建立兩個執行緒用來發送/接收

Vue核心技術-19,兄弟元件通訊跨級元件通訊

一,前言 上一篇介紹了元件通訊的父子元件通訊,在實際開發中元件通訊的場景有很多 根據元件關係可以分為父子元件通訊,兄弟元件通訊和跨級元件通訊 這一篇我們就介紹如何實現兄弟元件通訊和跨級元件通訊 備註:暫時不介紹Vue1.0的通訊方式 二,兄弟和跨級元件

作業系統核心空間使用者空間的互訪問

前面寫了很多的文章來說明了這個問題,並且在文章中均舉了一些例子,如果為了解決具體問題,那麼那些就已經足夠了,但是如果想實現一個作業系統,這些就遠遠不夠了。 硬體是軟體的底層,這是一個前提,硬體是舞臺,軟體都是舞者,作業系統是應用程式的底層,作業系統是舞臺,應用程式是舞者

JAVA NIO非同步通訊框架MINA選型使用的幾個細節(概述入門,UDP, 心跳)

Apache MINA 2 是一個開發高效能和高可伸縮性網路應用程式的網路應用框架。它提供了一個抽象的事件驅動的非同步 API,可以使用 TCP/IP、UDP/IP、串列埠和虛擬機器內部的管道等傳輸方式。Apache MINA 2 可以作為開發網路應用程式的一個良好基礎。

核心空間使用者空間資料交換一

debugfs 核心開發者經常需要向用戶空間應用輸出一些除錯資訊,在穩定的系統中可能根本不需要這些除錯資訊,但是在開發過程中,為了搞清楚核心的行為,除錯資訊非常必要,printk可能是用的最多的,但它並不是最好的,除錯資訊只是在開發中用於除錯,而printk將

虛擬核心程序地址空間

地址空間和記憶體         地址空間和記憶體是不同概念,地址空間是CPU所能管理記憶體的範圍,4GB地址空間不表示4GB實體記憶體。但4G大小虛擬地址空間的資料肯定會對應4G大小實體記憶體的資料。按32位Windows來說,虛擬地址空間是4GB,虛擬記憶體地址的最大值是4GB-1,並不是一開始就有4GB

Linux核心空間使用者空間傳遞資料

1.access_ok() 函式原型:int access_ok(int type,unsigned long addr,unsigned long size) 函式access_ok()用於檢查指定地址是否可以訪問。引數type為訪問方式,可以為VERIFY_READ(可讀),VERIFY_WRITE(可

UART的同步通訊非同步通訊通訊方式,多機通訊,流控

    大致對UART做了一個簡單的整理。 非同步通訊: 同步通訊: 序列的單工,半雙工,全雙工: 串列埠的多機通訊: UART的RTS, CTS: 一、流控,顧名思義就是流量控制的意思。目的是協調收發雙方,使資料不會丟失。 二、

char *char陣列的區別(深拷貝淺拷貝的觀點)以及核心訪問使用者空間

From :  http://blog.csdn.net/dog250/article/details/5303372 char *和char陣列真的相同嗎?我們以例項為證: typedef struct  {     char * s1;     char

核心空間使用者空間的資料交換

 對裝置的讀操作是將資料從Linux的核心空間複製到使用者空間; 寫操作是將資料從Linux的使用者空間複製到核心空間。 因為Linux的核心空間和使用者空間是隔離的,所以要實現資料的拷貝

(一)Oracle學習筆記—— 表空間

最大 更改 默認 oracle spa mil 步驟 font lte 1. 表空間 一個數據庫可以有多個表空間,一個表空間裏可以有多個表。表空間就是存多個表的物理空間;可以指定表空間的大小位置等。 1.1 創建表空間語句 create tablespace t

Lebesgue空間Riemann空間

區別 教學 sgu 計算 曾經 數值 ann 分類 思想 “它(指勒貝格積分)與黎曼積分的主要區別在於前者是對函數的函數值區域進行劃分;後者是對函數定義域進行劃分。對此Lebesgue自己曾經作過一個比喻,他說:假如我欠人家一筆錢,要還,此時按鈔票的面值的大小分類,然後計算