`
iwebcode
  • 浏览: 2003489 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

熟悉S3C44B0X开发板的开发流程

 
阅读更多

熟悉S3C44B0X开发板的开发流程

一.Bootloader

1.建立Cygwin虚拟linux环境

(1)点击setup.exe开始安装

(2)点击下一步,进入选择安装方法的界面:

1安装界面

图二选择安装途径界面

在这里,如果你的安装文件没有下载到本地,你可以选择从Internet安装。我们选择从本地安装,点击下一步继续。

图三选择安装路径等

图四选择Cygwin安装程序路径

(3)选择好Cygwin安装程序的路径后点击下一步继续安装。

图五选择安装模块

(4)选择好自己需要的模块后,点击下一步继续安装

图六选择自己需要的模块安装

图七拷贝文件过程

8结束安装

接下来Cygwin会进行自解压过程

9Cygwin自解压过程

10环境变量设置

安装好Cygwin后,我们还需要设置一下环境变量。打开系统属性对话框,点击高级-56518.环境变量,打开环境变量设置窗口。

11新建环境变量

点击新建按钮增加一个环境一个用户级的环境变量PATH=C:/Cygwin/bin,将Cygwin/bin目录加入到用户的PATH环境变量中,这样用户可以在任何路径下都可以执行Cygwin/bin目录中的命令。

12设置新的环境变量

至此CygwinWindows下安装就已经OK了。

2.安装基于CygwinARM平台交叉编译器

在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,是由德国的工程师WolfgangDenk从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目录下

tarzxvfu-boot-xxxxxxxx.tar.gz

b)解压后进入u-boot目录,输入makedistclean清除上一次编译的输出文件

C)输入makeITSN_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——配有SST39VF160Flash的学习板使用

44B0X_AMD.ocd——配有AM29LV160Flash的学习板使用

点击FlashID按钮检测一下FlashID能够读取到,以测试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校验(默认是关闭的,也就是说默认不校验)

-DDebug模式(默认关闭)

-C指定配置文件(默认是default.fcd)

-F指定数据文件

-S指定Flash起始地址(十进制方式)

-L指定写入的数据长度(256或者文件的大小,十进制方式)

一般我们使用Fluted.exe的方法如下,

allowio.exeFluted/aAFu-boot.bin-V-S0

此命令将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

Memorydisplay,显示指定地址的值

mm

ModifyMemory,修改内存指定地址的值

mw

MemoryWrite,写内存

cp

数据复制,如果目的地址空间在Flash中,就可以通过cp来写Flash

printenv

显示环境变量,如IP地址等

setenv

设置环境变量

Saveenv

保存环境变量

erase

擦除指定地址的Flash

flinfo

显示Flash的信息

reset

复位CPU

version

显示版本信息

?/help

显示帮助信息

二.uClinux编译与下载

1.建立编译环境

与在WindowsCygwin环境下编译U-BOOT类似,我们在linux下编译运行在ARM上的程序同样需要使用交叉编译工具armtools。将光盘:/工具/编程工具/armtools/linux版本/arm-elf-tools-20040427.sh拷贝到硬盘后执行这个程序将会自动安装此armtools交叉编译器。

2.编译uClinux

uClinux的压缩包拷贝到linux主机上,然后通过下列命令解压缩源码包,这样会在当前的目录下面生成uClinux-dist目录。(在这里,我们通过通过SecureCRT超级终端工具用ssh登陆到Linux主机的,因为在Cygwin的虚拟Linux环境下不能使用makemenuconfig。)

tarzxvfuClinux-dist-xxxxxxxx.tar.gz

进入uClinux-Distru目录执行makemenuconfig,将弹出以下的配置uClinux界面,如下。

选择Vendor/ProductSelection--->进入下级菜单,我们的配置如下:

选择Exit返回上级界面,然后选择Kernel/Library/DefaultsSelection--->,界面如图:在这里我们我们选择了使用的linux内核版本linux-2.4.xLibc版本选择uClibc,然后选中CustomizeKernelSettings(内核配置)CustomizeVendor/UserSettings(NEW)(厂商/用户程序设置)进行更进一步的配置。

退出后选择Yes保存配置信息,如下图。

我们在上面配置的时候选择了CustomizeKernelSettings和CustomizeVendor/UserSettings(NEW)选项。所以程序会自动进入KernelSettings和Vendor/UserSettings界面。

注:makemenuconfig将打开上一次的配置选项,如果希望重新构建一个全新的内核,可以在makemenuconfig之前先运行makemrproper。

KernelSettings,内核配置界面

Vendor/UserSettings界面

这样完成了上面两个配置后,整个uClinux的配置就结束了。接下来编译uClinux。依次执行如下指令:

makedep

makeclean

makelib_only

makeuser_only

makeromfs

makeimage(这一步报错不用管,只要下一步没有错就行)

make

完成所有的操作后,在uClinux-dist/images/目录下将生成uclinux_rom.bin(二进制压缩文件)。接下来我们可以通过U-BOOT配合串口或者网口来将此文件下载到Flash当中。

3.uClinux下载到Flash

我们这里通过U-BOOT提供的几种方式来将编译好的uClinux下载到Flash当中运行。

a)串口下载(下载速度慢):

U-BOOT命令提示符下输入loadb0xC500000命令(0xC500000是下载文件存放的地址,SDRAM)U-BOOT将等待用户传送文件。然后我们启动超级终端的文件发送,点击菜单传送->发送文件,出现发送文件对话框。选择好发送协议为Kermit协议,选择发送的文件,然后点击发送。这时候出现发送进度对话框

文件发送完后,uClinux的压缩的二进制文件就存放在地址0xC500000SDRAM空间)上了。

如果我们要测试新编译的uClinux运行情况,可以直接输入bootm命令,这样U-BOOT就会在当前放置下载的程序的地方(这里是0xC500000)解压缩代码到指定地址,然后跳转到这个地址开始运行程序

接下来我们通过cp命令将数据从0xC500000写入到Flash中的0x50000开始的地方。在复制数据之前,先将Flash对应的区域删除。拷贝数据的长度是按照双字来操作的,所以我们需要将字节长度/4+1来得到最终要输入的长度参数(16进制)。

数据写入到Flash空间的0x50000后,我们可以重启我们的系统,就可以看到这个启动过程了。U-Boot启动后,3秒钟内如果超级终端没有任何输入,就会自动从Flash0x50000(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命令修改,例如:

=>setenvipaddr192.168.1.104//设置本级的IP为192.168.1.104

=>setenvserverip192.168.1.100//设置Server的IP为192.168.1.100

=>setenvbootfileuclinux_rom.bin//设置tftp获取uclinux_rom.bin文件

注意在使用的时候不要使用=,例如setenvipaddr=192.168.1.104是错误。

先将PC机的tftp服务器软件启动,在这里我们使用的CiscoTFTPServer(安装文件在光盘:/工具/FTP软件/tftpserver/TFTPServer1-1-980730.exe)。第一次启动我们需要设置tftp服务器的本地路径,点击view->Options弹出tftp设置窗口,如图6-13所示。在这里我们主要设置tftp的服务器路径(就是包含你需要下载到学习板的文件的目录路径)。单击确定后,tftp服务器就设置好了,这时候我们可以使用U-Boot来下载uclinux到目标板上了。

然后在U-BOOT命令提示符下输入tftp0xC500000命令,下载就开始了。下载完后界面如下:

tftp下载完界面

同时CiscoTFTPServer也将打印相应的信息,如下图。

后续的操作如同串口下载一样,我们可以通过bootm直接解压缩代码执行,也可以先将Flash擦除,然后通过cp命令将压缩代码写入Flash,这样每次U-BOOT都能够在启动的时候自动解压并运行这个程序。

我们也可以使用光盘:/工具/FTP软件/tftpserver/tftpd32.exe这一个tftp服务器端软件,其使用方法很简单,无需安装,直接启动后设置下载文件的服务器路径(此路径包含了我们需要下载的文件)就好了。下载界面参看下图

三.应用程序

lo1Helloworld

建立helloworld应用程序步骤如下:

uClinux-dist/user目录下新建目录:Myapp

11编写Helloworld程序

编写demo.c文件,代码如下:

#include<stdlib.h>

#include<stdio.h>

intmain(void)

{

printf(HelloWorld!Thisismyfirstapplication./n);

return0;

}

保存在Myapp目录下。

12编写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目录下。

13修改user/Makefile

为了让编译器编译上述添加的内容,在user/Makefile中添加一句(一般按照字母

排列):

dir_$(CONFIG_USER_MYAPP_DEMO)+=Myapp

14修改config/config.in

config/config.in文件中添加的内容会在对用户选项进行配置时反映出来。在文件

的最后,增加一条:

###################################################################

mainmenu_optionnext_comment

comment'MyNewApplication'

bool'demo'CONFIG_USER_MYAPP_DEMO

endmenu

###################################################################

输入makemenuconfig

选择

然后exit保存,自动进入下一个画面

选择Myapplication回车,出现

选中,然后退出,保存。

接着执行:

makedep

makeclean

makelib_only

makeuser_only

makeromfs

makeimage

make

下载到开发板,可以通过串口终端在teraterm看到bin下面多了一个demo程序。

输入./demo启动演示程序

输出:HelloWorld!Thisismyfirstapplication.

四.驱动程序的编写

一个简单的驱动程序

一个典型的驱动程序,大体上可以分为以下两个方面:

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>

inttest_major=254;

//读函数,仅向用户缓冲区填入数据1

staticssize_tread_test(structfile*file,char*buf,ssize_tcount,loff_t*f_pos)

{

intleft,ret;

chardata=0x41;

for(left=count;left>0;left--)

{

put_user(data,buf);buf++;}

returncount;

}

//写函数,空操作

staticssize_twrite_test(structfile*file,char*buf,ssize_tcount,loff_t*f_pos)

{returncount;

}

//打开函数

staticintopen_test(structinode*inode,structfile*file)

{

MOD_INC_USE_COUNT;return0;}

//释放函数

staticvoidrelease_test(structinode*inode,structfile*file)

{

MOD_DEC_USE_COUNT;}

structfile_operationstest_fops={

read:read_test,

write:write_test,

open:open_test,

release:release_test,

};

//注册函数

inttest_init(void)

{

intresult;

result=register_chrdev(254,"test",&test_fops);

if(result<0){printk("test:cannotgetmajornumber!/n");

returnresult;}

return0;

}

//撤消函数

voidcleanup_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,添加一行:booltestdeviceCONFIG-TEST

3)修改linux-214.x/driver/char/mem.c在适当位置添加:

#ifdefCONFIG-TEST

externvoidtest-init(void);

#endif

同时在chr-dev-init()函数中添加:

#ifdefCONFIG-TEST

test-init();

#endif

4)修改vendor/Samsung/44bb0/Makefile建立设备节点:

12---35行间,DEVICE部分添加如下内容test,c,254,0

5)makemenuconfig,characterdevice选中testdevice

重新编译内核,在控制台输入

/proc>catdevices

Characterdevices:

1mem

2pty

3ttyp

4ttyS

5cua

10misc

162raw

180usb

254test

Blockdevices:

1ramdisk

31Blkmem

/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()

{

intfd,i,j;

charbuf[10];

fd=open("/dev/test",O_RDWR);

if(fd<0)

{

printf("cannotopenfile/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

ThisprogramdoesAPPTESTthingstoyourbars.

第四步:/config/config.in的适当位置添加以下语句:

boolapptestCONFIG-USER-APPTEST

最后再重新编译内核,makemenuconfig,选中自己的应用程序,完成后在/

bin目录可以看见ap2ptest的可执行文件,通过控制台直接输入该文件名即可

运行该程序!当然也可以在文件vendor/Samsung/44B0/rc中添加文件名

apptest,重新编译,uclinux启动后自动执行该应用程序.

字符设备的另一种做法

(这个设备驱动程序是让蜂鸣器叫)

这里不采用前面提到的file结构中的readwrite等,而使用IOCTL来实现。

首先修改前面给出的test.c,添加Port_init函数,这个函数用来初始化I/O配置寄存器。然

后就是修改

structfile_operationstest_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>

inttest_major=254;

#defineNon_Cache_Start(0x2000000)

#defineNon_Cache_End(0xc000000)

#defineBEEP_CMD_SIGNAL0

/*************************PORTS****************************/

staticintledman_ioctl(structinode*inode,structfile*file,unsignedintcmd,unsignedlongarg);

voidPort_Init(void)

{

(*(volatileunsigned*)S3C44B0X_PCONA)=0x1ff;

(*(volatileunsigned*)S3C44B0X_PDATB)=0x3ff;

(*(volatileunsigned*)S3C44B0X_PCONB)=0x3ff;

(*(volatileunsigned*)S3C44B0X_PDATC)=0xffff;//AllI/OIsHigh

(*(volatileunsigned*)S3C44B0X_PCONC)=0x0f05ff55;

(*(volatileunsigned*)S3C44B0X_PUPC)=0x30f0;//PULLUPRESISTORshouldbeenabledtoI/O

(*(volatileunsigned*)S3C44B0X_PDATD)=0xff;

(*(volatileunsigned*)S3C44B0X_PCOND)=0x0;

(*(volatileunsigned*)S3C44B0X_PUPD)=0x0;

(*(volatileunsigned*)S3C44B0X_PDATE)=0x1ff;

(*(volatileunsigned*)S3C44B0X_PCONE)=0x25568;

(*(volatileunsigned*)S3C44B0X_PUPE)=0x0df;pull-upresistor.

(*(volatileunsigned*)S3C44B0X_PDATF)=0x1ff;//AllI/OIsHigh

(*(volatileunsigned*)S3C44B0X_PCONF)=0x20900a;//AllNCisINPUT

(*(volatileunsigned*)S3C44B0X_PUPF)=0x163;

(*(volatileunsigned*)S3C44B0X_PDATG)=0xff;

(*(volatileunsigned*)S3C44B0X_PCONG)=0x00ff;

(*(volatileunsigned*)S3C44B0X_PUPG)=0x0;//shouldbeenabled

(*(volatileunsigned*)S3C44B0X_SPUCR)=0x7;//D15-D0pull-updisable

(*(volatileunsigned*)S3C44B0X_EXTINT)=0x0;//AllEXTINT0-7Lowlevelinterrupt

(*(volatileunsigned*)S3C44B0X_NCACHBE0)=0;//((Non_Cache_End>>12)<<16)|(Non_Cache_Start>>12);

}

voidBeep(intBeepStatus)

{

//PE5Lowavailable

if(BeepStatus==0)

(*(volatileunsigned*)S3C44B0X_PDATE)=(*(volatileunsigned*)S3C44B0X_PDATE)&0x1df;

else

(*(volatileunsigned*)S3C44B0X_PDATE)=(*(volatileunsigned*)S3C44B0X_PDATE)|0x020;

}

staticintledman_ioctl(

structinode*inode,structfile*file,unsignedintcmd,unsignedlongarg)

{

inti;

if(cmd==BEEP_CMD_SIGNAL){

printk("beep0/n");

Beep(0);

return(0);

}

else

{

printk("beep1/n");

Beep(1);

}

return0;

}

structfile_operationstest_fops={

ioctl:ledman_ioctl,/*ledman_ioctl*/

};

inttest_init(void)

{

intresult;

result=register_chrdev(254,"test",&test_fops);

if(result<0){printk("test:cannotgetmajornumber!/n");

returnresult;}

return0;

}

voidcleanup_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()

{

intfd,i,j;

charbuf[10];

fd=open("/dev/test",O_RDWR);

if(fd<0){printf("cannotopenfile/n");

exit(0);

}

ioctl(fd,1,0);//2个参数1表示喇叭叫,0表示不叫

close(fd);

}

其中把原先的read,write等调用改为IOCTL函数调用。

存盘后,执行makeuser_only进行编译。

<!--EndFragment-->
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics