① 如何配置camera driver中的mipi信號參數
1:硬體相關:簡單的數字電路要懂,看的懂電路圖(這個很簡單),能根據電路找到相應Camera硬體連接的GPIO,並根據晶元手冊配置GPIO為相應的模式;比如GPIO模式,輸入IO或輸出IO;或配置成PWM模式;不同的模式這個GPIO的工作方式是不同的;
2:Camera驅動:比如ov5640;你要找本linux驅動相關的書看看,比如《linux設備驅動程序》知道簡單的linux設備驅動寫法;當然工作中Camera驅動不需要你寫的,有參考的可以使用,但是參考驅動一般支持實現錄像、拍照功能,別的白平衡、對焦等都需要你去自己調試;
3:你要學習V4L2協議,因為驅動導出/dev/video0介面是通過V4L2協議的;上層C的應用也是通過V4L2協議訪問/dev/video0的;實際V4L2協議就是通過一些標志linux ioctl()函數和底層驅動通信的;V4L2協議是為了屏蔽各種Camera驅動的不同(比如usb攝像頭,mipi介面攝像頭)而提供的統一和攝像頭驅動通信的規范;
4:你要知道C++的class的相關知識,最好能看到C++的代碼,既然你有C的知識,哪把C++的面相對象看懂,知道C++的class就可以了;為什麼要懂C++呢?因為Android Camera HAL訪問/dev/video0都是用C++寫的,二十幾個個xxxx.cpp不同的類相互繼承實現的;而且你要懂Android HAL層的寫法,至少查查資料知道用哪裡看;一般都是CameraMole.cpp或CameraHal.cpp;
5:JNI的寫法最好以知道一些,至少可以抄就可以,因為這些寫法都是固定的,因為調試的過程中有時候你一個人要從java層跟蹤代碼到HAL層再到驅動;
5:你要會用Linux,因為所有的Android源碼都是在Linux下編譯的;你要知道ARM架構,交叉編譯器;比如arm-linux-gcc;知道怎麼編譯Android和kernel源碼;怎麼刷機;怎麼調試;最好買塊帶Camera的Android開發板;
② linux中動態載入驅動的過程是怎麼樣的,能給個詳細的嗎
介紹個動態載入模塊的過程
在該驅動中,我們假設對鍵盤的獲取是以0.2s為周期執行。源代碼如下
static struct timer_list timer;///////我們定義的定時器,也許你會問timer_list是什麼來的,其實一看名稱就應該就知道了,而為什麼要用到list那麼多定時器呢?其實在linux中還有很多相同的定義,比如說信號,我們定義的也是信號集,你可以定義該list是一個元素的,也可以是多個的。所以對於 timer_list就可以這樣描述:在未來某一個特定時刻執行某一系列特定任務的功能。下面我們還會給出內核中timer_list的具體描述,^_^ 好像我的話又說多了
static int Keypad_starttimer(void)
{
init_timer(&timer);//初始化定時器結構
timer.function=Keypad_timer;//超時服務程序
timer.expires=jiffies+20;//當前時刻加0.2s
add_timer(&timer);
return 0;
}
///超時服務程序
static void Keypad_timer(unsigned long data)
{
read_xy();
}
/////////接下來說下timer-list這個數據結構,如果你不感興趣的話可以跳過,該結構在include\linux\timer.h中定義
struct timer_list
{
struct list_head entry;
unsigned long expries;
spinlock_t lock;
unsigned long magic;
void (*function)(unsigned long);
unsigner long data;
struct tvec_t_base_s *base;
}
七.利用等待隊列實現阻塞型I\O
在用戶程序執行讀操作的時候有可能尚且沒有數據可以讀取,為此需要讓read操作等待,直到有數據可以讀取,這就是阻塞型i\o,阻塞型io可以通過使用進程休眠方法實現。在無數據可以讀取的時候,採用等待隊列讓進程休眠,直到有數據到達的時候才喚醒進程完成數據的讀操作。
在本驅動中的read,若循環隊列緩沖區中沒有數據,則進程進入休眠態,定時器函數每隔0.2s讀取鍵值一次,將按鍵狀態放入緩沖並且適時喚醒進程讀取數據。
等待隊列的使用流程如下:
1.聲明一個等待隊列
2.把當前進程加入到等待隊列中
3.把進程的狀態設置為TASK_INTERRUPTIBLE或TASK_UNINTERRUPTIBLE;
4.調用schele,以讓出cpu
5.檢測所需要的資源是否可用,若是,把當前進程從等待隊列中刪除,否則轉3循環
接下來我們在對read中有關等待隊列阻塞實現做具體的解釋
static ssize_t Keypad_read(struct file *filp,char *buf,ssize_t count,loff_t *l)
{
DECLEARE_WAITQUEUE(wait,current);//聲明等待隊列,將當前進程加入到等待隊列中
KEY_EVENT t;
ulong out_buf[2];
if(head==tail)//當前循環隊列中沒有數據可以讀取
{
if(filp->f_flags & O_NONBLOCK)//假如用戶採用的是非堵塞方式讀取
return _EAGAIN;
add_wait_queue(&queue,&wait);//將當前進程加入等待隊列
current->state=TASK_INTERRUPTIBLE;//設置當前進程的狀態
while((head==tail)&&!signal_pending(current))//假若還沒有數據到循環隊列並且當前進程沒有受到信號(該類信號具體來說是未決的休眠)
{
shele();//進程調度
current->state=TASK_INTERRUPTIBLE;
}
current->state=TASK_RUNNING;//該進程恢復執行
remove_wait_queue(&queue,&wait);//移出等待隊列
if(head==tail)
return count;
t=get_data();//調用get_data()函數,得到緩沖區中的數據,下面將給予詳細的 介紹
out_buf[0]=t.status;
out_buf[1]=t.click;
_to_user(buf,&out_buf,sizeof(out_buf));//將得到的鍵值拷貝到用戶數據區
return count;
}
}