嵌入式課程:實驗1——OK6410開發之點亮LED


實驗一:OK6410開發之點亮LED

一、實驗目的

1. 掌握開發板Linux的燒錄過程,感受與單片機燒錄程序的不同

2. 熟悉Linux開發環境,學習Linux系統指令

3.從初步的點燈開始對ARM底層編寫進行更深入了解

二、實驗設備

開發機環境 操作系統:ubuntu 20.04

交叉編譯環境:arm-linux-gcc 4.3.2 6410

板子內核源碼:linux-3.0.1

目標板環境:OK6410-A linux-3.0.1

編譯驅動之前要先在 ubuntu 下編譯開發板的內核,這里用的內核版本是 linux-3.0.1 如何編譯內核,具體見上一篇實驗內容:

嵌入式課程:實驗0——OK6410開發板Linux環境搭建

三、實驗內容(原理)

1. 通過SD卡一鍵燒錄Linux到OK6410開發板上

SW2引腳號 Pin 8 Pin 7 Pin 8 Pin 8 Pin 8 Pin 8 Pin 2 Pin 1
引腳定義 SELNAND OM4 OM3 OM2 OM1 GPN15 GPN14 GPN13
Nandflash 啟動 1 0 0 1 1 x x x
SD卡啟動 x 1 1 1 1 0 0 0

注:

(1)SW2開關ON時為”1”;OFF時為”0”,”X”為高電平或者低電平

(2)OK6410開發板出廠默認設置為NAND FLASH啟動方式

從這里我們可以知道如何進行SD卡啟動進行燒錄。

2. 在Linux上編寫LED驅動文件,Makefile文件,測試文件並拷貝到開發板上進行測試運行

2.1 硬件部分:

我們先看硬件電路:

www.icode9www.icode9

3.3v已經硬件接在PN結正極,輸出端接負極。說明當輸出端輸出低電平時LED即可導通被點亮。以下是對應引腳:

LED1 -GPM0

LED2 -GPM1

LED3 -GPM2

LED4 -GPM3

2.2 寄存器部分

我們看ARM芯片手冊,注意操作哪些寄存器可以完成LED的點亮,這里主要關注的就是芯片的GPIO章節,具體關注的就是怎么操作GPM0-GPM3 四個引腳,先來截一個圖,清楚的看到GPM的三個寄存器:控制寄存器、數據寄存器、上拉下拉寄存器,此外還給出的寄存器的地址和初始值,這里重點關注下配置寄存器和數據寄存器的地址,等下我們要通過這個地址來操作。

嵌入式Linux 筆記基於(OK6410開發板)-----------6.使用匯編偽指令點亮LED教程

接下來再看下GPMCON寄存器中的每一位的作用,這里只截取了GPM0-GPM3,從下表中可以看出GPMCON寄存器的每四位對應一個GPM引腳的狀態,當設置為0000時為輸入模式,當設置為0001時為輸出模式……………其余的暫時不管。這里很明顯我們需要設置為輸出模式。

img

接着就是GPMDAT寄存器,這里描述的很清楚,當端口被配置為輸入模式時,我們可以直接從端口引腳獨處相應的狀態,當端口被配置為輸出模式時,端口引腳的狀態就會根據我們是定的值而發生改變,這里我們肯定是要GPM0-GPM3都輸出低電平。

嵌入式Linux 筆記基於(OK6410開發板)-----------6.使用匯編偽指令點亮LED教程

看完這些我們就基本知道點燈的基本步驟了,后面程序會體現:

步驟1:

配置GPMCON寄存器為0x0001使LED0引腳為輸出模式0x1111就是四個LED引腳為輸出模式)

步驟2:

配置GPMDAT寄存器位為0x0U輸出低電平使LED導通點亮

四、實驗步驟

1.SD卡一鍵Linux燒錄開發板

1.1 准備文件

准備好上一個實驗配置好的文件:

mmc.bin (/root/forlinx/uboot1.1.6)

uboot.bin (/root/forlinx/uboot1.1.6)

zImage (/root/forlinx/linux-3.0.1/arch/arm/boot)

mkyaffs2image-nand2g (/root/forlinx)

1.2 制作SD系統卡

首先格式化SD卡

然后以管理員身份運行SD_Writer軟件,正常情況下應該是這樣的:

image-20211219145055119

我一開始沒有Format這個選項,后面查了下發現需要右鍵屬性在兼容性里勾上這個“以兼容模式運行這個程序”

image-20211219144933586

點擊"Scan"軟件會自動掃描SD卡位置,我的是H。"SD_Type"選擇"Auto","OS_Type"選“Linux||Android”。

最后點擊"Select Boot",把制作好的"mmc.bin"放進去,點擊"Program"。出現"It's OK"就說明系統卡制作完成。

image-20211219150620159

Quit退出。

1.3 燒錄Linux到開發板上

將准備好的四個文件(其實三個就行,mmc.bin已經不需要了)拷貝到SD上

將SD卡插到開發板SD卡槽里,撥碼開關撥成0x1f,打開電源,可以看到四盞LED均被點亮,系統正在燒錄。

IMG20211219154945

燒錄完成后的界面如下:

IMG20211219154028

此時會出現蜂鳴器響和流水燈提示燒錄完成,有些板子蜂鳴器壞了可能不會響。

關閉電源,將撥碼開關撥成0x19,重啟就可以看到系統已經在板子上運行了。

IMG20211219170037

2. LED程序編寫

2.1 driver_led.c 驅動文件編寫

主要是如實驗原理說的GPMCON寄存器與GPMDAT寄存器的配置

2.1.1 GPMCON寄存器配置
//GPMCON寄存器配置
        unsigned tmp;     
	    tmp = readl(S3C64XX_GPMCON);     
	    tmp = (tmp & ~(0x7U<<1))|(0x1U);  
	    writel(tmp, S3C64XX_GPMCON); 

先讀取GPMCON寄存器的值,將tmp變成0x01再寫到GPMCON寄存器上,使LED0的GPM端為輸出模式。

2.1.2 GPMDAT寄存器配置
//GPMDAT寄存器
	void Led_on(unsigned LEDx)?
        {
            unsigned  tmp;	  
            tmp = readl(S3C64XX_GPMDAT);
            tmp &=~ (LEDx);
            writel(tmp,S3C64XX_GPMDAT);
	}
    void Led_off(unsigned LEDx)
        {
            unsigned  tmp;	  
            tmp = readl(S3C64XX_GPMDAT);
            tmp |= (LEDx);
            writel(tmp,S3C64XX_GPMDAT);
        }

也是一樣,先讀取GPMDAT寄存器的值,將tmp變成設置值再寫到GPMDAT寄存器上。

這里我寫了開關函數控制led開關。

2.1.3 led_write函數
//led_write函數
ssize_t led_write (struct file *filp, const char __user *buf, size_t count,loff_t *f_pos)  
	{  
	    char wbuf[10];  
	    printk("#########write######\n");  
	    copy_from_user(wbuf,buf,count);  
	    switch(wbuf[0])
	    {
		    case 0:
			    Led_on(LED0);
			    break;

		    case 1:
			    Led_on(LED1);
                break;
		    case 2:
			    Led_on(LED2);
                break;
		    case 3:
			    Led_on(LED3);
                break;
		    case 4:
			    Led_off(LED0);
                break;
		    case 5:
			    Led_off(LED1);
                break;
		    case 6:
			    Led_off(LED2);
                break;
		    case 7:
			    Led_off(LED3);
                break;

        }

我這里是寫了一個流水燈,其實這里是一個類似於重載函數的函數,會重載這個源碼文件的write函數,下面test.c文件會體現。

2.2 test函數編寫

//輪詢函數      
     while(1)	  
	    {
		    for(i=0;i<8;++i)
		    {
			    write(fd,&buf[i],1);
			    sleep(1);
		    }
	    } 

這里的write其實是之前驅動文件的led_write函數,會按順序實現led_write里流水燈的功能,copy_from_user(wbuf,buf,count);就是去打開文件重載。

2.3 Makefile文件編寫

這里不贅述了,主要關注這個:

KDIR := /root/forlinx/linux-3.0.1

這里是把驅動文件包含的意思,導入這里的驅動文件。

3. 編譯程序

Linux下打開自己寫的led程序位置

cd led
make
arm-linux-gcc test.c -o test

編譯好后大致這個樣子,我之前已經編譯過了,第一次的make會長一點。

image-20211219192249350

4. 運行程序

將led程序make跟gcc編譯后所有文件拷貝到SD卡,再將SD卡插到開發板上。

打開開發板上的終端

然后在里面輸入

cd sdcard/ #打開SD卡文件夾
insmod  driver_led.ko #加載驅動
mknod  /dev/my_led  c   240  0 #創建設備文件
./test #運行測試

我們就可以看到流水燈了。

五、實驗程序(包括流程圖)

5.1 流程圖

image-20211219205614358

5.2 實驗代碼

具體實驗代碼文件見我的github:

實驗代碼

六、實驗演示

6.1 點燈演示:

QQ圖片20211219203947

6.2 流水燈演示:

視頻我也在GitHub上傳了:

流水燈

七、心得體會

此次實驗無論是從硬件驅動底層還是上位機系統管理都有了很深刻的學習,簡單的點燈讓我熟悉了Linux開發環境,簡單學習Linux系統指令,同時對ARM的底層有了學習,總之學到很多,收獲頗豐。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM