在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > ARM的嵌入式Linux移植體驗之設(shè)備驅(qū)動

            ARM的嵌入式Linux移植體驗之設(shè)備驅(qū)動

            作者: 時間:2012-11-13 來源:網(wǎng)絡(luò) 收藏
              設(shè)備驅(qū)動程序是操作系統(tǒng)內(nèi)核和機器硬件之間的接口,它為應(yīng)用程序屏蔽硬件的細節(jié),一般來說,Linux的設(shè)備驅(qū)動程序需要完成如下功能:

              ·設(shè)備初始化、釋放;

              ·提供各類設(shè)備服務(wù);

              ·負責內(nèi)核和設(shè)備之間的數(shù)據(jù)交換;

              ·檢測和處理設(shè)備工作過程中出現(xiàn)的錯誤。

              Linux下的設(shè)備驅(qū)動程序被組織為一組完成不同任務(wù)的函數(shù)的集合,通過這些函數(shù)使得Windows的設(shè)備操作猶如文件一般。在應(yīng)用程序看來,硬件設(shè)備只是一個設(shè)備文件,應(yīng)用程序可以象操作普通文件一樣對硬件設(shè)備進行操作,如open ()、close ()、read ()、write () 等。

              Linux主要將設(shè)備分為二類:字符設(shè)備和塊設(shè)備。字符設(shè)備是指設(shè)備發(fā)送和接收數(shù)據(jù)以字符的形式進行;而塊設(shè)備則以整個數(shù)據(jù)緩沖區(qū)的形式進行。在對字符設(shè)備發(fā)出讀/寫請求時,實際的硬件I/O一般就緊接著發(fā)生了;而塊設(shè)備則不然,它利用一塊系統(tǒng)內(nèi)存作緩沖區(qū),當用戶進程對設(shè)備請求能滿足用戶的要求,就返回請求的數(shù)據(jù),如果不能,就調(diào)用請求函數(shù)來進行實際的I/O操作。塊設(shè)備主要針對磁盤等慢速設(shè)備。

              1.內(nèi)存分配

              由于Linux驅(qū)動程序在內(nèi)核中運行,因此在設(shè)備驅(qū)動程序需要申請/釋放內(nèi)存時,不能使用用戶級的malloc/free函數(shù),而需由內(nèi)核級的函數(shù)kmalloc/kfree () 來實現(xiàn),kmalloc()函數(shù)的原型為:

              void kmalloc (size_t size ,int priority);

              參數(shù)size為申請分配內(nèi)存的字節(jié)數(shù),kmalloc最多只能開辟128k的內(nèi)存;參數(shù)priority說明若kmalloc()不能馬上分配內(nèi)存時用戶進程要采用的動作:

            GFP_KERNEL 表示等待,即等kmalloc()函數(shù)將一些內(nèi)存安排到交換區(qū)來滿足你的內(nèi)存需要,GFP_ATOMIC 表示不等待,如不能立即分配到內(nèi)存則返回0 值;函數(shù)的返回值指向已分配內(nèi)存的起始地址,出錯時,返回0。

              kmalloc ()分配的內(nèi)存需用kfree()函數(shù)來釋放,kfree ()被定義為:

            # define kfree (n) kfree_s( (n) ,0)

              其中kfree_s () 函數(shù)原型為:

            void kfree_s (void * ptr ,int size);

              參數(shù)ptr為kmalloc()返回的已分配內(nèi)存的指針,size是要釋放內(nèi)存的字節(jié)數(shù),若為0 時,由內(nèi)核自動確定內(nèi)存的大小。

              2.中斷

              許多設(shè)備涉及到中斷操作,因此,在這樣的設(shè)備的驅(qū)動程序中需要對硬件產(chǎn)生的中斷請求提供中斷服務(wù)程序。與注冊基本入口點一樣,驅(qū)動程序也要請求內(nèi)核將特定的中斷請求和中斷服務(wù)程序聯(lián)系在一起。在Linux中,用requeST_IRq()函數(shù)來實現(xiàn)請求:

            int request_irq (unsigned int irq ,void( * handler) int ,unsigned lONg type ,char * name);

            參數(shù)irq為要中斷請求號,參數(shù)handler為指向中斷服務(wù)程序的指針,參數(shù)type 用來確定是正常中斷還是快速中斷(正常中斷指中斷服務(wù)子程序返回后,內(nèi)核可以執(zhí)行調(diào)度程序來確定將運行哪一個進程;而快速中斷是指中斷服務(wù)子程序返回后,立即執(zhí)行被中斷程序,正常中斷type 取值為0 ,快速中斷type 取值為SA_INTERRUPT),參數(shù)nAME是設(shè)備驅(qū)動程序的名稱。

              4.塊設(shè)備驅(qū)動

              塊設(shè)備驅(qū)動程序的編寫是一個浩繁的工程,其難度遠超過字符設(shè)備,上千行的代碼往往只能搞定一個簡單的塊設(shè)備,而數(shù)十行代碼就可能搞定一個字符設(shè)備。因此,非得有相當?shù)幕竟Σ拍芡瓿纱隧椆ぷ?。下面先給出一個實例,即mtdblock塊設(shè)備的驅(qū)動。我們通過分析此實例中的代碼來說明塊設(shè)備驅(qū)動程序的寫法(由于篇幅的關(guān)系,大量的代碼被省略,只保留了必要的主干):

            #include Linux/config.h>
            #include Linux/devfs_fs_kernel.h>
            staTIc void mtd_notify_add(struct mtd_info* mtd);
            static void mtd_notify_remove(struct mtd_info* mtd);
            static struct mtd_notifier notifier = {
             mtd_notify_add,
             mtd_notify_remove,
             NULL
            };
            static devfs_handle_t devfs_dir_handle = NULL;
            static devfs_handle_t devfs_rw_handle[MAX_MTD_deviceS];

            static struct mtdblk_dev {
             struct mtd_info *mtd; /* Locked */
             int count;
             struct semaphore cache_sem;
             unsigned char *cache_data;
             unsigned long cache_offset;
             unsigned int cache_size;
             enum { STATE_EMPTY, STATE_CLEAN, STATE_DIRTY } cache_state;
            } *mtdblks[MAX_MTD_DEVICES];

            static spinlock_t mtdblks_lock;
            /* this lock is used just in kernels >= 2.5.x */
            static spinlock_t mtdblock_lock;

            static int mtd_sizes[MAX_MTD_DEVICES];
            static int mtd_blksizes[MAX_MTD_DEVICES];

            static void erase_callback(struct erase_info *done)
            {
             wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv;
             wake_up(wait_q);
            }

            static int erase_write (struct mtd_info *mtd, unsigned long pos,
            int len, const char *buf)
            {
             struct erase_info erase;
             DECLARE_WAITQUEUE(wait, current);
             wait_queue_head_t wait_q;
             size_t retlen;
             int ret;

             /*
             * First, let's erase the flash block.
             */

             init_waitqueue_head(wait_q);
             erase.mtd = mtd;
             erase.callback = erase_callback;
             erase.addr = pos;
             erase.len = len;
             erase.priv = (u_long)wait_q;

             set_current_state(TASK_INTERRUPTIBLE);
             add_wait_queue(wait_q, wait);

             ret = MTD_ERASE(mtd, erase);
             if (ret) {
              set_current_state(TASK_RUNNING);
              remove_wait_queue(wait_q, wait);
              printk (KERN_WARNING "mtdblock: erase of region [0x%lx, 0x%x] " "on /"%s/" failed/n",
            pos, len, mtd->name);
              return ret;
             }

             schedule(); /* Wait for erase to finish. */
             remove_wait_queue(wait_q, wait);

             /*
             * Next, writhe data to flash.
             */

             ret = MTD_WRITE (mtd, pos, len, retlen, buf);
             if (ret)
              return ret;
             if (retlen != len)
              return -EIO;
             return 0;
            }

            linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)

            linux相關(guān)文章:linux教程



            上一頁 1 2 3 下一頁

            關(guān)鍵詞: ARM 嵌入式 Linux移植

            評論


            相關(guān)推薦

            技術(shù)專區(qū)

            關(guān)閉