1. 電路圖
2. 實現原理
採用原子操作開啟驅動裝置的介面如下:
常用原子操作函式舉例:
atomic_t v =
atomic_init(0
);//定義原子變數v並初始化為0
atomic_read
(atomic_t *v)
;//返回原子變數的值
void
atomic_inc
(atomic_t *v)
;//原子變數增加1
void
atomic_dec
(atomic_t *v)
;//原子變數減少1
intatomic_dec_and_test
(atomic_t *v)
;//自減操作後測試其是否為0,為0則返回true,否則返回false。
使用訊號量也可以實現原子操作。
訊號量訊號量(semaphore)是用於保護臨界區的一種常用方法,只有得到訊號量的程序才能執行臨界區**。
當獲取不到訊號量時,程序進入休眠等待狀態。
定義訊號量
struct semaphore sem;
初始化訊號量
void sema_init (
struct semaphore *sem,
int val)
;void
init_mutex
(struct semaphore *sem)
;//初始化為0
獲得訊號量
void
down
(struct semaphore * sem)
;int
down_interruptible
(struct semaphore * sem)
;int
down_trylock
(struct semaphore * sem)
;釋放訊號量
voidup(
struct semaphore * sem)
;
3. 驅動源**(six_drv.c)#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
static
struct class *six_drv_class;
static
struct class_device *six_drv_class_dev;
static
struct fasync_struct *buttons_async;
/* 鍵值:按下時, 0x01, 0x02, 0x03, 0x04
* 鍵值:鬆開時, 0x81, 0x82, 0x83, 0x84
*/typedef
struct
s3c2440_buttons_desc;
s3c2440_buttons_desc pins_desc=
,,,,
};unsigned
int key_val;
/* 等待佇列:
* 當沒有按鍵被按下時,如果有程序呼叫s3c24xx_buttons_read函式,
* 它將休眠
*/static
declare_wait_queue_head
(button_waitq)
;/* 中斷事件標誌, 中斷服務程式將它置1,s3c24xx_buttons_read將它清0 */
static
volatile
int ev_press =0;
static atomic_t canopen =
atomic_init(1
);//定義原子變數v並初始化為1
irqreturn_t buttons_irq
(int irq,
void
*dev_id)
intsix_drv_open
(struct inode *inode,
struct file *file)
request_irq
(irq_eint0, buttons_irq, irqt_bothedge,
"s2"
,&pins_desc[0]
);request_irq
(irq_eint2, buttons_irq, irqt_bothedge,
"s3"
,&pins_desc[1]
);request_irq
(irq_eint11, buttons_irq, irqt_bothedge,
"s4"
,&pins_desc[2]
);request_irq
(irq_eint19, buttons_irq, irqt_bothedge,
"s5"
,&pins_desc[3]
);return0;
}ssize_t six_drv_read
(struct file *file,
char __user *buf, size_t size, loff_t *ppos)
intsix_drv_close
(struct inode *inode,
struct file *file)
unsigned
intsix_drv_poll
(struct file *file,
struct poll_table_struct *wait)
intsix_drv_fsync
(int fd,
struct file *filp,
int on)
static
struct file_operations six_drv_fops =
;static
int major;
static
int __init six_drv_init
(void
)static
void __exit six_drv_exit
(void
)module_init
(six_drv_init)
;module_exit
(six_drv_exit)
;module_license
("gpl"
);
4. 測試程式(testsixdrv.c)#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define dev_device "/dev/buttons_atom"
int fd;
void
get_key_val
(int sig)
intmain
(int argc,
char
*ar**)
fcntl
(fd, f_setown,
getpid()
);//告訴驅動應用的pid
oflag =
fcntl
(fd, f_getfl)
;//獲取舊的標誌
fcntl
(fd, f_setfl, oflag | fasync)
;//設定fasync標誌
while(1
);close
(fd)
;return0;
}
boost atomic原子操作使用
1 boost提供了跨平台的原子操作功能,簡化我們在併發環境中讀寫變數。下面的示例展示了最長用的原子操作。concurrentprogram test.cpp 此檔案包含 main 函式。程式執行將在此處開始並結束。include include include 二進位制操作 int main 下面...
字元驅動第七課 原子操作
當同乙份 產生兩個例項 執行態 時,他們所操作的空間就是同一塊空間,這會造成資料不按預想地被修改,這就是重入問題,避免了這種衝突的 叫可重入 同乙個程序內,乙個函式還沒有執行完就又開始第二次呼叫,這也會引起重入問題。如正在執行add 函式,此時來了個中斷,中斷服務子程式中也要呼叫add 函式,此時可...
驅動程式的併發機制 原子操作
乙個硬體裝置會被多個程序同時使用,這就是併發,併發會導致裝置亂序。例如scull裝置就有可能在a 程序正在執行scull read 函式 但尚未執行完 的時候就被b 程序打斷,而b 程序執行的是scull write 函式,當a 程序再次被執行的時候它讀到的東西就不再是它以前應該讀到的東西。要解決這...