1.內聯彙編
# 內聯彙編的語法
asm asm-qualifiers (AssemblerTemplate
:OutputOperands
[:InputOperands
[:Clobbers]])
int add(int a,int b)
{
int sum;
__asm__ volatile(
"add %0, %1, %2"
:"=r"(sum)
:"r"(a),"r"(b)
:"cc"
);
return sum;
}
ATPCS 的具體語法(https://baike.baidu.com/item/ATPCS/10695243?fr=aladdin)
- asm : 也可以寫作 “asm”, 表示這是一段內聯彙編
- asm-qualifiers 有 3 個取值:volatile、inline、goto。
volatile 的意思是易變的、不穩定的,用來告訴編譯器不要隨便優化這段代碼,否則可能出問題。比
如彙編指令“mov r0, r0”,它把 r0 的值複製到 r0,並沒有實際做什麼事情,你的本意可能是用這條指令
來延時。編譯器看到這指令後,可能就把它去掉了。加上 volatile 的話,編譯器就不會擅自優化。- AssemblerTemplate
彙編指令,用雙引號包含起來,每條指令用“\n”分開- OutputOperands
輸出操作數,內聯彙編執行時,輸出的結果保存在哪裏。
格式如下,當有多個變量時,用逗號隔開:
[ [asmSymbolicName] ] constraint (cvariablename)- InputOperands
輸入操作數,內聯彙編執行前,輸入的數據保存在哪裏。
格式如下,當有多個變量時,用逗號隔開:
[ [asmSymbolicName] ] constraint (cexpression)- Clobbers
在彙編代碼中,對於“OutputOperands”所涉及的寄存器、內存,肯定是做了修改。但是彙編代碼中,
也許要修改的寄存器、內存會更多。比如在計算過程中可能要用到 r3 保存臨時結果,我們必須在“Clobbers”
中聲明 r3 會被修改
Clobbers | 描述 |
---|---|
cc | 表示彙編代碼會修改“flags register” |
memory | 表示彙編代碼中,除了“InputOperands”和“OutputOperands”中指定的之外,還會會讀、寫更多的內存 |
2. atomic 實現
ATOMIC_OP 在 UP 系統中的實現,代碼路徑(arch\arm\include\asm\atomic.h)
對於 ARMv6 以下的 CPU 系統,不支持 SMP。原子變量的操作簡單粗暴:關中斷
ARMv6 及以上的 CPU,有一些特殊的彙編指令來實現原子操作,不再需要關中斷
在 ARMv6 及以上的架構中,原子操作的執行過程是可以被打斷的,但是它的效果符合“原子”的定義:
一個完整的“讀、修改、寫入”原子的,不會被別的程序打斷。它的思路很簡單:如果被別的程序打斷了,
那就重來,最後總會成功的
3.原子變量對外的 API
類型定義 include\linux\types.h
函數名 | 作用 |
---|---|
atomic_read(v) | 讀出原子變量的值,即 v->counter |
atomic_set(v,i) | 設置原子變量的值,即 v->counter = i |
atomic_inc(v) | v->counter++ |
atomic_dec(v) | v->counter-- |
atomic_add(i,v) | v->counter += i |
atomic_sub(i,v) | v->counter -= i |
atomic_inc_and_test(v) | 先加 1,再判斷新值是否等於 0;等於 0 的話,返回值爲 1 |
atomic_dec_and_test(v) | 先減 1,再判斷新值是否等於 0;等於 0 的話,返回值爲 1 |
使用方法
static atomic_t valid = ATOMIC_INIT(1);
static ssize_t gpio_key_drv_open (struct inode *node, struct file *file)
{
if (atomic_dec_and_test(&valid))
{
return 0;
}
atomic_inc(&valid);
return -EBUSY;
}
static int gpio_key_drv_close (struct inode *node, struct file *file)
{
atomic_inc(&valid);
return 0;
}
關於原子位操作
基本實現是和原子操作是一樣的,只是操作的是一位,所有速度會快。