熟悉S3C44B0X開發板的開發流程
熟悉S3C44B0X開發板的開發流程
一.Bootloader
1.建立Cygwin虛擬linux環境
(1)點擊setup.exe開始安裝
(2)點擊下一步,進入選擇安裝方法的界面:
圖1 安裝界面
圖二 選擇安裝途徑界面
在這里,如果你的安裝文件沒有下載到本地,你可以選擇從Internet安裝。我們選擇從本地安裝,點擊下一步繼續。
圖三 選擇安裝路徑等
圖四 選擇Cygwin安裝程序路徑
(3)選擇好Cygwin安裝程序的路徑后點擊下一步繼續安裝。
圖五 選擇安裝模塊
(4)選擇好自己需要的模塊后,點擊下一步繼續安裝
圖六 選擇自己需要的模塊安裝
圖七 拷貝文件過程
圖8 結束安裝
接下來Cygwin會進行自解壓過程
圖9 Cygwin自解壓過程
圖10 環境變量設置
安裝好Cygwin后,我們還需要設置一下環境變量。打開系統屬性對話框,點擊高級-56518 .環境變量,打開環境變量設置窗口。
圖11 新建環境變量
點擊新建按鈕增加一個環境一個用戶級的環境變量 PATH=C:/Cygwin/bin,將Cygwin/bin目錄加入到用戶的PATH環境變量中,這樣用戶可以在任何路徑下都可以執行Cygwin/bin目錄中的命令。
圖12設置新的環境變量
至此Cygwin在Windows下安裝就已經OK了。
2.安裝基于Cygwin的ARM平臺交叉編譯器
在Windows下安裝好Cygwin后,我們需要建立編譯arm程序的環境,也即安裝arm-tools工具。
將光盤目錄 光盤:/工具/編程工具/armtools/windows版本 復制到本地硬盤(在這里我們在D:盤建立一個armtools的目錄,然后將光盤:/工具/編程工具/armtools/windows版本復制到這里),然后在dos環境下進入此目錄,執行unpack.bat 批處理命令,解壓縮過程開始,不用關心在解壓縮的最后出現錯誤提示。請參看以下截圖:
最后添加將armtools的命令路徑添加到Windows的環境變量Path 中。注意在上一步解壓的過程中,armtools被解壓到Cygwin的安裝目錄下,在這里Cygwin是安裝在 C:/ 根目錄下的。這樣armtools交叉編譯環境就安裝好了。
3.u-boot簡介
U-BOOT 是一個開源bootloader,是由德國的工程師Wolfgang Denk從8XXROM代碼發展而來的,它支持很多處理器,比如PowerPC、ARM、MIPS和x86。目前,U-BOOT源代碼在sourceforge網站的社區服務器中,Internet上有一群自由開發人員對其進行維護和開發,它的項目主頁是http://sourceforge.net/projects/U-BOOT。U-BOOT的最新版本源代碼可以在Sourceforge的CVS服務器中匿名獲得。由于其成熟和穩定,已經在許多嵌入式系統開發過程中被采用。
為什么我們需U-BOOT?顯然可以將ucLinux 直接燒入flash,從而不需要額外的引導裝載程序(bootloader)。但是從軟件升級的角度以及程序修補的來說,軟件的自動更新非常重要。
4.編譯u-boot
a) 在linux(或其他linux虛擬環境下,如cygwin)解壓源碼包,在這里我們選擇在Windows系統下的Cygwin環境下來編譯。先將光盤中的u-boot包拷貝到系統的一個目錄下,在這里我們拷貝到D:盤的s3c44b0目錄下
tar zxvf u-boot-xxxxxxxx.tar.gz
b)解壓后進入u-boot目錄,輸入make distclean清除上一次編譯的輸出文件
C)輸入 make ITSN_s3c44b0_config,以產生一些編譯配置文件(.mk 文件)和相應的一些頭文件(.h文件)
d)編譯,執行 make。
這一步驟生成了三個文件,其中:
u-boot,ELF文件格式,使用Flashpgm工具來打開此文件編程到Flash當中
u-boot.bin 是二進制文件,使用Fluted工具來將此文件編程到Flash當中
5.U-BOOT下載
在這里我們介紹兩種方法來將編譯好的U-Boot編程Flash,一種是使用Flashpgm工具,另外一種是Fluted工具。
a)FlashPgm
FlashPgm是什么公司的,是一個GUI界面的Flash編成工具。由于其友好的編程界面, 更快的編程速度和更高的編程成功率使其被大家普遍使用。 在使用FlashPgm編程Flash的時候注意使用JTAG板的Wiggler接口連接到目標板上, FlashPgm不支持STD的JTAG接口。打開Configuration菜單下的Communications可以設置 設置FlashPgm的連接方式,在這里我使用, 同時確保JTAG板的J5條線到Wiggler接口 狀態。
們
點擊菜單File-Open選擇 .ocd文件。Ooc文件是一個硬件系統的配置文件,設置了CPU,Flash類型,Flash接口的位寬等具體的參數,可通過FlashPgm生成。光盤上已經帶有兩個已經配置好的.ocd 文件,在光盤:/工具/Flash編程工具/ 目錄,其中包含兩個.ocd文件。
44B0X_SST.ocd —— 配有SST39VF160 Flash的學習板使用
44B0X_AMD.ocd —— 配有AM29LV160 Flash的學習板使用
點擊Flash ID按鈕檢測一下Flash ID能夠讀取到,以測試JTAG連接是否正常。如果能夠正常讀取出來,表示JTAG連接沒有問題
點擊Program按鈕,在出現的對話框中選擇編譯好的u-boot文件(ELF格式的),然后選擇在編程前先擦除選型,點擊Program。首先將會擦除相應的Flash區域,然后編程和校驗。進度條將顯示當前編程進度。
正在擦除Flash
編程,校驗成功
這時候超級中斷將顯示U-BOOT打印輸出,通過FlashPgm成功的將U-BOOT燒寫到 Flash當中。
B)Fluted.exe
Fluted.exe是一個基于命令行方式的Flash編程工具,其只支持STD方式的JTAG鏈接。 以下是其運行的參數:
命令:(大小寫無關)
R —— 讀Flash
W —— 寫Flash
E —— 擦除Flash
V —— 校驗Flash
T —— 測試掃描線
A —— 擦除 + 寫 Flash
選項: (大小寫無關)
-V 校驗(默認是關閉的,也就是說默認不校驗)
-D Debug模式 (默認關閉)
-C 指定配置文件 (默認是default.fcd)
-F 指定數據文件
-S 指定Flash起始地址(十進制方式)
-L 指定寫入的數據長度 (256或者文件的大小,十進制方式)
一般我們使用Fluted.exe的方法如下,
allowio.exe Fluted /a A –F u-boot.bin -V -S 0
此命令將 u-boot.bin文件(二進制)寫入到Flash,從地址0開始,使用默認的default.fcd 文件,通常編寫將上述命令放在一個.bat批處理文件來方便執行。
Fluted.exe工具編程的速度相對FlashPgm要慢得多,參看下圖實際的編程過程。
Fluted.exe工具編程過程
6.U-BOOT的使用
系統上電后,U-BOOT開始執行,在串口超級終端軟件上將有答應輸出,在3秒鐘內按任意鍵,將進入U-BOOT命令提示符,如下圖。其中輸出信息提示SDRAM是8M字節,Flash是2M字節。
執行help指令,將顯示U-BOOT支持命令,常用U-BOOT指令有:
|
命令 |
功能 |
|
go |
執行指定地址上的程序 |
|
bootm |
引導應用程序或者操作系統(壓縮格式) |
|
tftp |
通過太網調入指定的文件到指定的內存地址 |
|
loadb |
通過串口以kermit方式下載文件 |
|
md |
Memory display,顯示指定地址的值 |
|
mm |
Modify Memory,修改內存指定地址的值 |
|
mw |
Memory Write,寫內存 |
|
cp |
數據復制,如果目的地址空間在Flash中,就可以通過cp來寫Flash |
|
printenv |
顯示環境變量,如IP地址等 |
|
setenv |
設置環境變量 |
|
Saveenv |
保存環境變量 |
|
erase |
擦除指定地址的Flash |
|
flinfo |
顯示Flash的信息 |
|
reset |
復位CPU |
|
version |
顯示版本信息 |
|
?/ help |
顯示幫助信息 |
二.uClinux編譯與下載
1.建立編譯環境
與在Windows的Cygwin環境下編譯U-BOOT類似,我們在linux下編譯運行在ARM上的程序同樣需要使用交叉編譯工具armtools。將光盤:/工具/編程工具/armtools/linux版本/ arm-elf-tools-20040427.sh拷貝到硬盤后執行這個程序將會自動安裝此armtools交叉編譯器。
2. 編譯 uClinux
將uClinux的壓縮包拷貝到linux主機上,然后通過下列命令解壓縮源碼包,這樣會在當前的目錄下面生成uClinux-dist 目錄。(在這里,我們通過通過SecureCRT超級終端工具用 ssh 登陸到 Linux 主機的, 因為在Cygwin的虛擬Linux環境下不能使用make menuconfig。)
tar zxvf uClinux-dist-xxxxxxxx.tar.gz
進入uClinux-Distru目錄執行 make menuconfig,將彈出以下的配置uClinux界面,如下。
選擇Vendor/Product Selection ---> 進入下級菜單,我們的配置如下:
選擇Exit返回上級界面,然后選擇Kernel/Library/Defaults Selection --->,界面如圖:在這里我們我們選擇了使用的linux內核版本 linux-2.4.x,Libc 版本選擇 uClibc,然后選中Customize Kernel Settings(內核配置) 和Customize Vendor/User Settings (NEW)(廠商/用戶程序設置)進行更進一步的配置。
退出后選擇Yes保存配置信息,如下圖。
我們在上面配置的時候選擇了Customize Kernel Settings和Customize Vendor/User Settings (NEW)選項。所以程序會自動進入Kernel Settings 和 Vendor/User Settings界面。
注:make menuconfig將打開上一次的配置選項,如果希望重新構建一個全新的內核,可以在make menuconfig之前先運行 make mrproper。
Kernel Settings ,內核配置界面
Vendor/User Settings界面
這樣完成了上面兩個配置后,整個uClinux的配置就結束了。接下來編譯uClinux。依次執行如下指令:
make dep
make clean
make lib_only
make user_only
make romfs
make image (這一步報錯不用管,只要下一步沒有錯就行)
make
完成所有的操作后,在uClinux-dist/images/目錄下將生成uclinux_rom.bin(二進制壓縮文件)。接下來我們可以通過U-BOOT配合串口或者網口來將此文件下載到Flash當中。
3. 將uClinux下載到Flash
我們這里通過U-BOOT提供的幾種方式來將編譯好的uClinux下載到Flash當中運行。
a)串口下載(下載速度慢):
在U-BOOT命令提示符下輸入 loadb 0xC500000命令(0xC500000是下載文件存放的地址,SDRAM中),U-BOOT將等待用戶傳送文件。然后我們啟動超級終端的文件發送,點擊菜單 傳送->發送文件,出現發送文件對話框。選擇好發送協議為 Kermit協議,選擇發送的文件,然后點擊發送。這時候出現發送進度對話框
文件發送完后,uClinux的壓縮的二進制文件就存放在地址0xC500000(SDRAM空間)上了。
如果我們要測試新編譯的uClinux運行情況,可以直接輸入 bootm 命令,這樣U-BOOT就會在當前放置下載的程序的地方(這里是0xC500000)解壓縮代碼到指定地址,然后跳轉到這個地址開始運行程序
接下來我們通過cp命令將數據從0xC500000寫入到Flash 中的0x50000開始的地方。在復制數據之前,先將Flash對應的區域刪除。拷貝數據的長度是按照雙字來操作的,所以我們需要將字節長度/4 + 1 來得到最終要輸入的長度參數(16進制)。
數據寫入到Flash空間的0x50000后,我們可以重啟我們的系統,就可以看到這個啟動過程了。U-Boot啟動后,3秒鐘內如果超級終端沒有任何輸入,就會自動從Flash 0x50000(0x50000這個地址是U-B0OT程序編程固定的,可以根據需要修改)的地址上將壓縮的uClinux解壓縮到0xc008000(SDRAM)上,然后跳轉到這個地址上,開始uClinux的啟動。
b)網口下載(下載速度快):
網口下載是通過tftp協議的,在下載之前先確認一下U-BOOT的環境變量配置是否正確,在U-BOOT的命 令提示符下輸入 printenv 顯示環境變量(啟動參數),如下圖:
其主要的環境參數包括:
bootcmd —— 啟動命令,也就是U-Boot啟動后如果在指定時間內沒有按下任何按鍵后執 行的指令。
bootdelay —— 指定自動啟動的等待時間,單位為秒
baudrate —— 串口波特率
etheaddr —— 以太網芯片的MAC地址
stdin —— 指定標準輸入設備
stdout —— 指定標準輸出設備
stderr —— 指定標準錯誤輸出設備
bootfile —— 通過tftp從服務器上獲取的文件名
ipaddr —— 本機(S3C44B0板)的IP地址
serverip —— 運行tftp服務器程序的PC機IP地址
我們在使用tftp下載的時候要關心的參數是 bootfile, ipaddr, serverip三個。
需要保證服務器的IP與目標板的IP在同一個網段內。如果需要修改參數可以通過 setenv命令修改,例如:
=>setenv ipaddr 192.168.1.104 //設置本級的IP為192.168.1.104
=>setenv serverip 192.168.1.100 //設置Server的IP為192.168.1.100
=>setenv bootfile “uclinux_rom.bin”//設置tftp獲取uclinux_rom.bin文件
注意在使用的時候不要使用“=”,例如 setenv ipaddr=192.168.1.104是錯誤。
先將PC機的tftp服務器軟件啟動,在這里我們使用的Cisco TFTP Server(安裝文件在 光盤:/工具/FTP軟件/tftp server/TFTPServer1-1-980730.exe)。第一次啟動我們需要設置tftp服務器的本地路徑,點擊 view->Options彈出tftp設置窗口,如圖6-13所示。在這里我們主要設置tftp的服務器路徑(就是包含你需要下載到學習板的文件的目錄路徑)。單擊確定后,tftp服務器就設置好了,這時候我們可以使用U-Boot來下載uclinux到目標板上了。
然后在U-BOOT命令提示符下輸入tftp 0xC500000 命令,下載就開始了。下載完后界面如下:
tftp下載完界面
同時Cisco TFTP Server 也將打印相應的信息,如下圖。
后續的操作如同串口下載一樣,我們可以通過bootm 直接解壓縮代碼執行,也可以先將Flash擦除,然后通過cp命令將壓縮代碼寫入Flash,這樣每次U-BOOT都能夠在啟動的時候自動解壓并運行這個程序。
我們也可以使用 光盤:/工具/FTP軟件/tftp server/tftpd32.exe 這一個tftp服務器端軟件,其使用方法很簡單,無需安裝,直接啟動后設置下載文件的服務器路徑(此路徑包含了我們需要下載的文件)就好了。下載界面參看下圖
三.應用程序
lo1. Helloworld
建立 helloworld 應用程序步驟如下:
在 uClinux-dist/user 目錄下新建目錄:Myapp
1.1 編寫Helloworld 程序
編寫 demo.c 文件,代碼如下:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
printf(“Hello World! This is my first application./n”);
return 0;
}
保存在Myapp 目錄下。
1. 2 編寫Makefile 文件
內容如下:
EXEC = demo
OBJS = demo.o
all: $(EXEC)
$(EXEC): $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS)
romfs:
$(ROMFSINST) /bin/$(EXEC)
clean:
-rm -f $(EXEC) *.elf *.gdb *.o
同樣放在Myapp 目錄下。
1. 3 修改user/Makefile
為了讓編譯器編譯上述添加的內容,在user/Makefile 中添加一句(一般按照字母
排列):
dir _$(CONFIG_USER_MYAPP_DEMO) +=Myapp
1. 4 修改config/config.in
config/config.in 文件中添加的內容會在對用戶選項進行配置時反映出來。在文件
的最后,增加一條:
###################################################################
mainmenu_option next_comment
comment 'My New Application'
bool 'demo' CONFIG_USER_MYAPP_DEMO
endmenu
###################################################################
輸入 make menuconfig
選擇
然后 exit 保存,自動進入下一個畫面
選擇 My application 回車,出現
選中,然后退出,保存。
接著執行:
make dep
make clean
make lib_only
make user_only
make romfs
make image
make
下載到開發板,可以通過串口終端在teraterm 看到bin 下面多了一個demo 程序。
輸入 ./demo 啟動演示程序
輸出:Hello World! This is my first application.
四.驅動程序的編寫
一個簡單的驅動程序
一個典型的驅動程序,大體上可以分為以下兩個方面:
1) 注冊設備:在系統初啟時,必須將設備登記到相應的設備數組,例如 : 對于字符驅動設備來說,要使用register - chrdev() 來注冊設備的驅動號,然后對這個設備的所有調用都用這個設備號來實現;
2) 定義功能函數:對于每一個驅動函數來說,都有一些和此設備密切相關的功能函數,就最常用的字符設備來說,都存在著諸如open() 、read () 、write() 、ioctrol ( ) 這一類的操作。當系統調用這些操作時,將自動的使用file - operations 結構中對應的函數來實現具體的操作; 在編寫驅動程序前,不得不提file - operations 這個結構,每個設備都有自己的file - operations 結構,它定義了設備的基本入口
點,即上面提到的功能函數。下面以一個簡單的演示例子,說明編寫字符設備驅動程序的具體過程,設備取名為“test”,設備號定為254 ,當然這個設備并沒有涉及真正的硬件,僅是從內核空間拷貝了一些特定數據到用戶空間。
第一步: 在目錄/ linux - 2.4.x/ drives/ char 編寫源
程序test . c ,源碼如下:
頭文件和全局變量:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <asm/uaccess.h>
int test_major=254;
//讀函數,僅向用戶緩沖區填入數據1
static ssize_t read_test(struct file *file,char * buf,ssize_t count,loff_t *f_pos)
{
int left,ret;
char data=0x41;
for(left=count;left>0;left--)
{
put_user(data,buf);buf++;}
return count;
}
//寫函數,空操作
static ssize_t write_test(struct file *file,char *buf,ssize_t count,loff_t *f_pos)
{return count;
}
//打開函數
static int open_test(struct inode *inode,struct file *file)
{
MOD_INC_USE_COUNT;return 0;}
//釋放函數
static void release_test(struct inode *inode,struct file *file)
{
MOD_DEC_USE_COUNT;}
struct file_operations test_fops={
read:read_test,
write:write_test,
open:open_test,
release:release_test,
};
//注冊函數
int test_init(void)
{
int result;
result=register_chrdev(254,"test",&test_fops);
if(result<0){printk("test:cannot get major number!/n");
return result;}
return 0;
}
//撤消函數
void cleanup_module(void)
{unregister_chrdev(test_major,"test");}
第二步:添加設備;
1)修改linux - 2.4. x/ driver/ char/Makefile 在適當位置添加一行: obj - $(CONFIG- TEST) + = test .o
2)linux - 214. x/ driver/ char/ Config. in , 添加一行: bool ’test device’CONFIG- TEST
3)修改linux - 214. x/ driver/ char/ mem. c 在適當位置添加:
# ifdef CONFIG- TEST
extern void test - init (void) ;
# endif
同時在chr - dev- init () 函數中添加:
# ifdef CONFIG- TEST
test - init () ;
# endif
4) 修改vendor/ Samsung/ 44bb0/Makefile建立設備節點:
在12 - - - 35 行間,DEVICE 部分添加如下內容test ,c ,254 ,0
5) make menuconfig ,在character device 選中testdevice
重新編譯內核,在控制臺輸入
/proc> cat devices
Character devices:
1 mem
2 pty
3 ttyp
4 ttyS
5 cua
10 misc
162 raw
180 usb
254 test
Block devices:
1 ramdisk
31 Blkmem
/proc>
就包含了名為“test”的設備驅動,下面的例子是用于驗證這個設備驅動程序.
B. 應用程序的編寫
在μCLinux 的/ user 目錄下提供許多資源供開發者參考。下面以上節提到的源程序為例, 說明在μCLinux 中加入自己應用程序的過程。第一步:首先在/ user/ 目錄下建立自己的文件夾如,取名apptest ,然后在新建文件夾(apptest) 下編輯自己的應用程序apptest . c (源碼為上面的設備驅動驗證程序) ,然后參照user 目錄下其他應用程序編寫自己的makefile ,同樣保存
在文件apptest 下;
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
main()
{
int fd,i,j;
char buf[10];
fd=open("/dev/test",O_RDWR);
if(fd<0)
{
printf("can not open file/n");
exit(0);
}
j=read(fd,buf,10);
for(i=0;i<j;i++)
printf("%d /n",buf[i]);
close(fd);
}
第二步:在/ user/Makefile 中適當位置加入下行語句:
dir - $(CONFIG- USER- APPTEST) += apptest
第三步:在/ config/ Configure. help 的適當位置添加以下語句:
CONFIG- USER- APPTEST
This program does APPTEST things to your bars.
第四步:在/ config/ config. in 的適當位置添加以下語句:
bool ’apptest ’ CONFIG- USER- APPTEST
最后再重新編譯內核,在make menuconfig 時,選中自己的應用程序,完成后在/
bin 目錄可以看見ap2ptest 的可執行文件,通過控制臺直接輸入該文件名即可
運行該程序! 當然也可以在文件vendor/ Samsung/ 44B0/ rc 中添加文件名
apptest ,重新編譯, 在uclinux 啟動后自動執行該應用程序.
字符設備的另一種做法
(這個設備驅動程序是讓蜂鳴器叫)
這里不采用前面提到的 file 結構中的read write 等,而使用IOCTL 來實現。
首先修改前面給出的 test.c,添加Port_init 函數,這個函數用來初始化I/O 配置寄存器。然
后就是修改
struct file_operations test_fops={
ioctl: ledman_ioctl, /* ledman_ioctl */
};
去除原先的內部結構,最后定義ledman_ioctl 函數。整個驅動程序的結構如下,
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <asm/uaccess.h>
#include <asm/arch/s3c44b0x.h>
int test_major=254;
#define Non_Cache_Start (0x2000000)
#define Non_Cache_End (0xc000000)
#define BEEP_CMD_SIGNAL 0
/************************* PORTS ****************************/
static int ledman_ioctl(struct inode * inode, struct file * file,unsigned int cmd, unsigned longarg);
void Port_Init(void)
{
(*(volatile unsigned *)S3C44B0X_PCONA)=0x1ff;
(*(volatile unsigned *)S3C44B0X_PDATB)=0x3ff;
(*(volatile unsigned *)S3C44B0X_PCONB)=0x3ff;
(*(volatile unsigned *)S3C44B0X_PDATC)=0xffff; //All I/O Is High
(*(volatile unsigned *)S3C44B0X_PCONC)=0x0f05ff55;
(*(volatile unsigned *)S3C44B0X_PUPC)=0x30f0; //PULL UP RESISTOR should beenabled to I/O
(*(volatile unsigned *)S3C44B0X_PDATD)=0xff;
(*(volatile unsigned *)S3C44B0X_PCOND)= 0x0;
(*(volatile unsigned *)S3C44B0X_PUPD) = 0x0;
(*(volatile unsigned *)S3C44B0X_PDATE)=0x1ff;
(*(volatile unsigned *)S3C44B0X_PCONE)=0x25568;
(*(volatile unsigned *)S3C44B0X_PUPE)=0x0df; pull-up resistor.
(*(volatile unsigned *)S3C44B0X_PDATF)=0x1ff; //All I/O Is High
(*(volatile unsigned *)S3C44B0X_PCONF)=0x20900a;//All NC is INPUT
(*(volatile unsigned *)S3C44B0X_PUPF)=0x163;
(*(volatile unsigned *)S3C44B0X_PDATG)=0xff;
(*(volatile unsigned *)S3C44B0X_PCONG)=0x00ff;
(*(volatile unsigned *)S3C44B0X_PUPG)=0x0; //should be enabled
(*(volatile unsigned *)S3C44B0X_SPUCR)=0x7; //D15-D0 pull-up disable
(*(volatile unsigned *)S3C44B0X_EXTINT)=0x0; //All EXTINT0-7 Low level interrupt
(*(volatile unsigned *)S3C44B0X_NCACHBE0)=0;//((Non_Cache_End>>12)<<16)|(Non_Cache_Start>>12);
}
void Beep(int BeepStatus)
{
//PE5 Low available
if (BeepStatus==0)
(*(volatile unsigned *)S3C44B0X_PDATE)=(*(volatile unsigned *)S3C44B0X_PDATE)&0x1df;
else
(*(volatile unsigned *)S3C44B0X_PDATE)=(*(volatile unsigned *)S3C44B0X_PDATE)|0x020;
}
static int ledman_ioctl(
struct inode * inode,struct file * file,unsigned int cmd,unsigned long arg)
{
int i;
if (cmd == BEEP_CMD_SIGNAL) {
printk("beep0/n");
Beep(0);
return(0);
}
else
{
printk("beep1/n");
Beep(1);
}
return 0;
}
struct file_operations test_fops={
ioctl: ledman_ioctl, /* ledman_ioctl */
};
int test_init(void)
{
int result;
result=register_chrdev(254,"test",&test_fops);
if(result<0){printk("test:cannot get major number!/n");
return result;}
return 0;
}
void cleanup_module(void)
{unregister_chrdev(test_major,"test");}
其余文件不要動,將 test.c 存盤到44b0 當前目錄下的/linux-xxx/driver/char 然后在44b0 目
錄下面Make 進行編譯。
接著修改應用程序 apptest,這個比較簡單,程序如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
main()
{
int fd,i,j;
char buf[10];
fd=open("/dev/test",O_RDWR);
if(fd<0){printf("can not open file/n");
exit(0);
}
ioctl(fd, 1, 0); //第2 個參數1 表示喇叭叫,0 表示不叫
close(fd);
}
其中把原先的read ,write 等調用改為IOCTL 函數調用。
存盤后,執行 make user_only 進行編譯。
浙公網安備 33010602011771號