<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # C語言方式(mmap) 這里提供接近單片機寄存器操作的一種應用層GPIO操作方式,也封裝成庫給大家使用。 ## GPIO 寄存器介紹 在[V3S datasheet](http://lichee.jicm.cn/doc/V3S/Allwinner_V3s_Datasheet_V1.0.pdf)第224頁是GPIO控制器的相關介紹。 V3S從有PB/C/E/F/G 五個GPIO端口,每個都是32位端口(實際引腳沒有引出那么多), 也是32位寄存器。 每個端口由以下幾個寄存器組成: (n=1,2,4,5,6;寄存器基址為0x01C20800) |Register Name|Offset)|Description|詳細描述| |---|----|---|--| |Pn_CFG0|n*0x24+0x00|Port n Configure Register 0 (n=1,2,4,5,6)| 每個腳4bit,最高位保留。000 輸入 ; 001 輸出 ; 010 外設功能1 ; 011 外設功能2 ; 100 外設功能3 ; 101 外設功能4 ; 110 EINT中斷 ; 111 IO失能 | |Pn_CFG1|n*0x24+0x04|Port n Configure Register 1 |同上| |Pn_CFG2|n*0x24+0x08|Port n Configure Register 2 |同上| |Pn_CFG3|n*0x24+0x0C|Port n Configure Register 3 |同上| |Pn_DAT|n*0x24+0x10|Port n Data Register |每位代表輸入輸出值| |Pn_DRV0|n*0x24+0x14|Port n Multi-Driving Register 0 |0~3逐級遞增| |Pn_DRV1|n*0x24+0x18|Port n Multi-Driving Register 1 |同上| |Pn_PUL0|n*0x24+0x1C|Port n Pull Register 0 |0浮空,1上拉,2下拉,3保留| |Pn_PUL1|n*0x24+0x20|Port n Pull Register 1 |同上| |Pn_INT_CFG0|0x200+n*0x20+0x00|PIO Interrrupt Configure Register0|0上升,1下降,2高電平,3低電平,4雙邊沿| |Pn_INT_CFG1|0x200+n*0x20+0x04|PIO Interrrupt Configure Register1|同上| |Pn_INT_CFG2|0x200+n*0x20+0x08|PIO Interrrupt Configure Register2|同上| |Pn_INT_CFG3|0x200+n*0x20+0x0C|PIO Interrrupt Configure Register3|同上| |Pn_INT_CTL|0x200+n*0x20+0x10|PIO Interrupt Control Register|0失能,1使能| |Pn_INT_STA|0x200+n*0x20+0x14|PIO Interrupt Status Register|0未發生中斷,1發生中斷。寫1清除| |Pn_INT_DEB|0x200+n*0x20+0x18|PIO Interrupt Debounce Register|bit0,選擇中斷時鐘,0,32Khz 低速時鐘;1,24MHz主時鐘。bit6:4,去抖時鐘分頻,選擇的時鐘源2^n分頻,即最大256分頻。| |寄存器|地址| |---|----| |PB配置|1C20824| |PC配置|1C20848| |PE配置|1C20890| |PF配置|1C208B4| |PG配置|1C208D8| ## mmap簡介 mmap簡單來說就是把一片物理內存空間(或者文件)映射到應用的虛擬內存空間,這樣,直接在應用層就能操作 CPU的寄存器,類似于單片機的寄存器操作。我們只要封裝好寄存器操作的庫函數,就能在以后的程序里簡單調用了~ 詳細的mmap介紹可以參考附錄的鏈接。 為了操作寄存器,我們需要用到/dev/mem設備,這個設備是是物理內存的全映像,可以用來訪問物理內存,一般用法是open("/dev/mem",O_RDWR|O_SYNC),然后mmap,接著就可以用mmap的地址來訪問物理內存,這實際上就是實現用戶空間驅動的一種方法。 ~~~ #include <sys/mmap.h> void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset); //start: 映射區的起始地址,0的話由接口自動返回 //length: 映射區的長度 //prot: 內存保護標志,不能與文件的打開模式沖突。以下值可以 或 組合。 //PROT_EXEC 頁內容可以被執行 //PROT_READ 頁內容可以被讀取 //PROT_WRITE 頁可以被寫入 //PROT_NONE 頁不可訪問 //flag: 指定映射對象的類型,是否可以共享等。 //fd: 文件描述符 //oft: 被映射對象內容的起點偏移。映射物理內存的話,就是物理內存地址。**必須頁對齊。** int munmap(void *start, size_t length); //start: 前面獲得的地址 //length: 映射區的大小。 int msync ( void * addr , size_t len, int flags) //一般說來,進程在映射空間的對共享內容的改變并不直接寫回到磁盤文件中,往往在調用munmap()后才執行該操作。可以通過調用msync()實現磁盤上文件內容與共享內存區的內容一致。 //但是對于映射物理內存來說是直接作用的。 ~~~ 代碼片段: ~~~ #include <sys/mmap.h> char dev_name[] = "/dev/mem"; GPIO_REGISTER *gpio_base; fd = open(dev_name,O_RDWR); if(fd<0){ printf("open %s is error\n",dev_name); return -1 ; } gpio_base = (GPIO_REGISTER *)mmap( 0, 0x32, PROT_READ | PROT_WRITE, MAP_SHARED,fd, 0x40060000 ); if(gpio_base == NULL){ printf("gpio base mmap is error\n"); close(fd); return -1; } //后面就是對寄存器操作了 //結束后解除映射 munmap(gpio_base, 0x32); ~~~ 我基于mmap寫了個應用層調試寄存器的小程序,reg-dbger, 在github上可以下載使用。 使用方法為: ~~~ reg-dbger r reg_addr //讀寄存器 reg-dbger rb reg_addr bit_oft bit_cnt //讀寄存器的bit_oft開始的bit_cnt位 reg-dbger w reg_addr value //寫寄存器 reg-dbger wb reg_addr bit_oft bit_cnt value //寫寄存器的bit_oft開始的bit_cnt位 reg-dbger dump reg_addr cnt //批量dump出cnt個寄存器值 ~~~ 比如操作gpio寄存器,點亮熄滅Zero上的綠色LED: ~~~ # PG0 # 配置寄存器 0x01C20800+6*0x24+0=1C208D8 # 數據寄存器 0x01C20800+6*0x24+0x10 = 1C208E8 reg-dbger r 1C208D8 reg-dbger r 1C208E8 reg-dbger wb 1C208D8 0 3 1 #輸出狀態 reg-dbger wb 1C208E8 0 1 0 #輸出0,點亮 ~~~ 同樣基于mmap寫了個應用層操作GPIO的小程序,lpi-gpio, 在github上可以下載使用。 使用方法為: ~~~ lpi-gpio set PG0 out/in 0/1/2 //設置為輸出的話,0低電平,1,2高電平;設置為輸入,0下拉,1上拉,2浮空。 lpi-gpio r PG0 lpi-gpio w PG0 0/1 lpi-gpio pwm PG0 100 200 //PG0 pwm輸出,兩個參數分別表示高低電平的微秒數(>60us) lpi-gpio test PG0 //測試PG0用函數翻轉IO的最大速率,結果為1.85MHz lpi-gpio tfast PG0 //測試PG0用軟件翻轉IO的最大速率,結果為10MHz ~~~ 為方便在C語言里調用,我生成了gpio操作的動態庫**libgpio.so**,大家可以在c程序中調用。 ~~~ int lpi_gpio_initlib(void); int lpi_gpio_init(int port, int pin, int dir, int val); ////PG0: port=6, pin=0 //val: 設置為輸出的話,0低電平,1,2高電平;設置為輸入,0下拉,1上拉,2浮空。 int lpi_gpio_r(int port, int pin); void lpi_gpio_w(int pin, int pin, int val); void lpi_gpio_deinitlib(void); ~~~ 這里是一個簡單的使用例程: ~~~ #include "lpi_gpio.h" #define USLEEP_T 61 int main() { lpi_gpio_initlib(); lpi_gpio_init(6, 0, 1, 0); while(1) { //generate 1KHz PWM lpi_gpio_w(6, 0, 1); usleep(500-USLEEP_T); lpi_gpio_w(6, 0, 0); usleep(500-USLEEP_T); } lpi_gpio_deinitlib(); return; } ~~~ ~~~ //gcc -fPIC -shared -o libgpio.so lib_gpio.c //編譯生成動態庫 gcc test_gpio.c -L. -lgpio -o test_gpio //編譯生成應用程序 LD_LIBRARY_PATH=. ./test_gpio //運行應用程序,手工指定動態庫位置 //or add libgpio.so to /etc/ld.so.conf, ldconfig ~~~ ## 附錄 mmap參考資料:http://blog.chinaunix.net/uid-26669729-id-3077015.html linux動態庫:http://www.cnblogs.com/jiqingwu/p/linux_dynamic_lib_create.html linux靜態庫:http://www.cnblogs.com/jiqingwu/p/4325382.html
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看