Rockchip之RK3288通過NDK手動復位ADC
Rockchip之RK3288通過NDK手動復位ADC
任務需求:
我們的機器採用的是麥克風陣列錄音,其中麥克風陣列錄音板有兩個ADC和一個FPGA,這個麥克風陣列錄音板在靜電比較大的時候會死掉,導致不能錄音,機器陷入不能使用的狀態,當時情況緊急,在不改硬體的情況下使用軟體復位ADC的方發來解決問題.
在這裡我採用的方法是使用NDK通過上層APP給底層驅動發指令讓ADC復位的方法(後續介紹使用自動復位方法).
什麼是NDK開發,怎麼進行NDK開發在這裡我就不再一一細說,在這裡我講述一下NDK開發需要進行的幾個重要步驟:
- 在底層驅動建立裝置節點,並實現服務函式file_operation.
- 撰寫JNI並將JNI整合到APK裡.
- 編寫APK呼叫JNI操作裝置節點,並給裝置節點發指令.
1.建立裝置節點,並實現服務函式
作為一個linux驅動程式設計師建立裝置節點三步曲應該熟練
- register_chrdev
- class_create
- device_create
其中裝置節點名字是device_create函式引數裡定義的名字,在本例中是GP_I2C_DEV_NAME,這是一個巨集
#define GP_I2C_DEV_NAME "i2c_operator_device"
接下來實現file_operation
static struct file_operations gp_fops =
{
.owner = THIS_MODULE,
.open = gp_open,
.release = gp_close,
.read = gp_read,
.write = gp_write,
};
接下來實現介面
重要的是 gp_write這個函式
這個服務函式裡的一個函式copy_from_user,接收上層APP傳送下來的指令,通過這個指令的具體內容,就可以做相應的操作.
2.撰寫JNI,並且整合到APK專案
具體的NDK開發在這裡不細講,這裡只講JNI的編寫,JNI如何和APK的方法聯絡起來並且又如何能和底層驅動練習起來的呢?有以下幾點:
- JNI指定APK原始碼的包名類名
- JNI指定裝置節點的名字
- JNI對映表裡將JNI方法和APK方法一一對應
1.JNI指定APK原始碼的包名類名
jclass clz = env->FindClass("com/hq/lowlevel/ResetNative");
if(clz == NULL)
{
ALOGE(" env->FindClass error\n");
return -1;
}
其中包名類名寫在了FindClass方法裡.
2.JNI指定裝置節點的名字
fd = open("/dev/i2c_operator_device", O_RDWR);
if(fd < 0)
{
ALOGE("open error : %s\n", strerror(errno));
return -1;
}
這裡指定可裝置節點所在路徑以及裝置節點名字,使用open方法去開啟裝置節點,才能對這個裝置節點進行操作.才可以向裝置節點也就是驅動裡寫資料.
到這裡,就將底層驅動和JN聯絡起來了.
3.JNI對映表裡將JNI方法和APK方法一一對應
static JNINativeMethod led_methods[] ={
{"openDev", "()I", (void*)open_jni_Reset},
{"ResetOn", "()I", (void*)Reset_jni_on},
{"closeDev", "()I", (void*)close_jni_Reset},
};
在這個對映表裡,寫明瞭APK的JAVA方法對應JNI的方法,即APK呼叫那個JAVA方法,就會呼叫對應JNI的方法.
到這裡就將APK和JNI聯絡起來了,這樣就實現了從APK層到底層驅動的貫穿,具體的JNI如附件.
3.編寫APK
這個APK僅用於測試,在實際開發專案中會把這些方法合入具體的專案分支,這個測試APK僅僅用到了幾個簡單的方法
- openDev
- ResetOn
- closeDev
經過以上的步驟,就實現上層APP到底層驅動的貫穿連線,上層APK可以通過給驅動發指令來控制ADC復位,但是,你會發現,將以上步驟全部不差的做完,開啟APK你會發現報錯,原因就是JNI去open裝置節點的時候,沒有系統許可權,需要指定這個裝置節點為系統許可權
在system/core/rootdir/ueventd.rc中新增
/dev/i2c_operator_device 0666 root root
這樣就不會報錯,就可以通過上層APK手動復位ADC了.
也可以不使用NDK的方法,另一種方法是將JNI變成so動態庫,APK直接載入動態庫的方法也能實現需求.這時候就需要編寫Android.mk了.在附件我會附上自己編寫的Android.mk以及JNI供參考.