<strike id="kiyse"></strike>
  • <tr id="kiyse"></tr>
  • <strike id="kiyse"></strike><samp id="kiyse"><tbody id="kiyse"></tbody></samp>
    <strike id="kiyse"><s id="kiyse"></s></strike>
    <tr id="kiyse"></tr>
    <noframes id="kiyse"><code id="kiyse"></code></noframes>
    <th id="kiyse"></th>
    <samp id="kiyse"></samp>
  • <th id="kiyse"><s id="kiyse"></s></th>
  • GPIO應用于Linux LED子系統和輸入事件偵測

     2018-1-4     作者:黃志超         
    文章標簽:C/C++GPIO

      GPIO(General-purpose input/output)即通用輸入輸出,根據名字就能夠了解到在實際應用中可以有很多種用途,最常見的便是用來控制LED燈的亮滅,或用來偵測輸入信號的高低變化。英創工控主板都給用戶提供了豐富的GPIO資源,ESMARC系列的板卡擁有32位GPIO,為了方便用戶能夠更方便的進行開發,英創公司進一步在軟件上也增加了一些實用的功能。在GPIO用作控制LED燈的時候,用戶可以直接使用Linux的LED子系統來對指定的GPIO口進行設置和操作,比如LED的亮滅或者設置觸發方式等。如果是將GPIO設置為輸入狀態偵測輸入信號的高低變化,一旦電平發生變化,內核就會通知應用程序,這時使用select函數就可以接收到內核發出的消息,不用再通過while或者for函數不斷的輪詢,實際的功能已經在ESMARC系列的ESM6800主板上通過測試和驗證了。下面就針對兩個功能來介紹一下具體的使用方法。


      用戶使用GPIO控制LED燈,可以直接調用英創公司提供的API函數,將GPIO置為輸出然后置高或者置低。不過Linux系統將控制LED燈的這部分功能整合起來,設計成了一個標準的LED子系統,對LED子系統的操作在shell環境中就能完成。英創公司也將這部分功能的支持加入到了板卡中,如果熟悉使用LED子系統來控制的用戶,就可以選用這種方式。通過加載一個內核模塊led-emtronix.ko來啟用LED子系統,加載的時候通過參數gpios來設置需要使用LED子系統操作的GPIO,gpios參數為一個32位的整數,代表32位GPIO,1表示enable而0表示disable。所以當我們選用GPIO0~GPIO3時,加載內核模塊的命令如下:insmode led-emtronix.ko gpios=0x0f,加載完成后,用戶可以在/sys/class/leds/目錄下看到新生成了四個對應的文件夾LED1、LED2、LED3和LED4,注意,為了方便用戶區分,LED子文件夾的標號和GPIO的標號是一一對應的,比如GPIO10生成的子文件夾為LED10。


    GPIO在Linux-LED子系統和輸入事件偵測中的應用.gif

    加載內核模塊


      我們選擇LED0這個目錄進入,可以看到里面有許多文件,我們要使用到的文件為brightness和trigger這兩個。


    GPIO在Linux-LED子系統和輸入事件偵測中的應用.gif

    文件列表


      brightness這個文件用來控制LED的開關,對應板卡的GPIO電平高低,當brightness文件的值為0時,GPIO輸出低電平,當brightness文件的值為1時GPIO則輸出高電平,需要注意的是,加載內核模塊后,默認情況為輸出低電平即brightness文件的值為0。在shell中需要查看brightness的值可以使用命令cat brightness:


    GPIO在Linux-LED子系統和輸入事件偵測中的應用.gif

    查看brightness文件


      如果是需要設置brightness文件的值,則可以使用echo命令:


    GPIO在Linux-LED子系統和輸入事件偵測中的應用.gif

    設置brightness文件的值


      另一個文件trigger的作用是設置觸發方式,默認為none即沒有觸發方式。使用cat命令讀取trigger文件可以得到支持的所有觸發方式,如下圖看到有磁盤,定時器,心跳,背光等多種觸發方式:


    GPIO在Linux-LED子系統和輸入事件偵測中的應用.gif

    查看觸發方式


      有方括號的表示為現在的有效觸發方式,如果要選用heartbeat作為觸發方式,還是使用echo命令來進行設置:


    GPIO在Linux-LED子系統和輸入事件偵測中的應用.gif

    設置trigger


      設置之后可以通過示波器看到對應的GPIO像心跳一樣,每秒會進行一次拉高拉底。按照上面所介紹的方法,就能夠使用LED子系統來對板卡的GPIO進行控制。


      接下來介紹一下輸入事件通知的功能,英創板卡的GPIO上電是默認都為輸入狀態(有3.3V上拉),在默認狀態下是不會響應輸入電平變化進行事件通知的。要啟用這一功能,需要調用英創公司提供的,設置GPIO輸入狀態的API來實現。也就是在程序中需要調用一次API,設置GPIO為輸入,才會使能這一位GPIO的輸入事件通知功能,代碼如下:


      int GPIO_OutDisable(int fd, unsigned int dwDisBits)

      {

        int                       rc;

        struct double_pars    dpars;


        dpars.par1 = ESM6800_GPIO_OUTPUT_DISABLE;

        dpars.par2 = dwDisBits;


        rc = write(fd, &dpars, sizeof(struct double_pars));

        return rc;

      }


      rc = GPIO_OutDisable(fd, i1); //set GPIO as input

      if(rc < 0)

      {

        printf("GPIO_OutEnable::failed %d\n", rc);

        return rc;

      }


      當設置完成后,GPIO作為輸入狀態,同時內核會在輸入的電平變化時通知應用層,使用select函數來監聽GPIO的句柄的讀事件就能夠獲取到通知,用戶可以通過多線程的方式來實現,代碼如下:


      while( 1 )

      {

        //設置讀事件

        FD_ZERO(&fdRead);

        FD_SET(fd,&fdRead);


        //設置超時時間

      aTime.tv_sec = 0;

      aTime.tv_usec = 20000;


      ret = select(fd+1,&fdRead,NULL,NULL,&aTime);

      //printf( "select ret = %d\n", ret);

     

                  if (ret < 0 )

                  {

                         printf("error!\n");

                         break;

                  }

     

                  if (ret > 0)

                  {

                         //判斷是否讀事件

                         if (FD_ISSET(fd,&fdRead))

                         {

                                //讀事件觸發,進行相應的動作

                                dwPinState = 0xffffffff;

                                rc = GPIO_PinState(fd, &dwPinState);

                                if(rc < 0)

                                {

                                       printf("GPIO_PinState::failed %d\n", rc);

                                       return rc;

                                }

                                printf("PinState = 0x%08x\n", dwPinState);

                         }

           }

      }


      當輸入電平發生變化,select偵測到讀事件,就可以進行相應的操作,示例代碼只是簡單的讀取了當前GPIO的輸入電平狀態,用戶可以根據實際的應用來修改。當有多路GPIO用于偵測輸入電平變化的時候,在接收到讀事件后,如果需要判斷是哪一位GPIO偵測到電平變化,就要立刻讀取當前GPIO的狀態來以此進行判斷。對于不需要這一功能的用戶也不會有什么影響,當調用函數將GPIO設置為輸入后,不使用select函數去監聽GPIO的句柄即可,其他功能都和原來一致。


      英創公司希望通過增加一些類似的實用功能,讓用戶的開發能夠更加方便,如果在使用過程中遇到任何問題,可以和英創公司的工程師聯系尋求技術支持。

    文章標簽:C/C++GPIO
    国产乱人伦偷精品视频不卡| 精品久久久久久99人妻 | 99re热这里只有精品| 久久99精品久久久久子伦| 亚洲国产成人久久精品99| 国产精品国产三级国产av品爱网| 久久精品国产亚洲av麻豆色欲| 国产69精品久久久久99| 无码精品久久久天天影视| 久9热视频这里只精品18| 精品国产福利在线观看91啪 | 久久se精品一区二区影院| 亚洲国产精品国自产拍电影| www亚洲精品少妇裸乳一区二区| 精品一区二区在线观看| 亚洲国产精品人久久电影| 国产精品成人亚洲| 久久国产乱子精品免费女| 国产乱人伦精品一区二区| 久久午夜无码鲁丝片直播午夜精品| 国产人妻人伦精品1国产盗摄| 九九久久精品国产免费看小说| 亚洲色无码国产精品网站可下载| 久久国产热这里只有精品| 国产精品久久久久久影视| 久久99这里只有精品国产| 久久精品国产亚洲AV嫖农村妇女| 国产人妖乱国产精品人妖| 亚洲中文字幕久久精品无码A | 69国产精品视频免费| 亚洲AⅤ永久无码精品AA| 精品少妇人妻AV免费久久洗澡| 五月天婷婷精品视频| 国产精品女人呻吟在线观看| 成人亚洲国产精品久久| 久久精品www人人爽人人| 国产精品国产三级国产普通话| 天美传媒精品1区2区3区| 精品综合久久久久久99| 亚洲精品美女久久7777777| 亚洲精品V欧洲精品V日韩精品 |