當(dāng)前位置:首頁 > 單片機(jī) > 單片機(jī)
[導(dǎo)讀]應(yīng)用實例的編寫實際上已經(jīng)不屬于Linux操作系統(tǒng)移植的范疇,但是為了保證本系列文章的完整性,這里提供一系列針對嵌入式Linux開發(fā)應(yīng)用程序的實例。  編寫Linux應(yīng)用程序要用到如下工具: ?。?)編譯器:GCC  GCC

應(yīng)用實例的編寫實際上已經(jīng)不屬于Linux操作系統(tǒng)移植的范疇,但是為了保證本系列文章的完整性,這里提供一系列針對嵌入式Linux開發(fā)應(yīng)用程序的實例。

  編寫Linux應(yīng)用程序要用到如下工具:

  (1)編譯器:GCC

  GCC是Linux平臺下最重要的開發(fā)工具,它是GNU的C和C++編譯器,其基本用法為:gcc [options] [filenames]。

  我們應(yīng)該使用arm-linux-gcc。

 ?。?)調(diào)試器:GDB

  gdb是一個用來調(diào)試C和C++程序的強(qiáng)力調(diào)試器,我們能通過它進(jìn)行一系列調(diào)試工作,包括設(shè)置斷點、觀查變量、單步等。

  我們應(yīng)該使用arm-linux-gdb。

  (3)Make

  GNU Make的主要工作是讀進(jìn)一個文本文件,稱為makefile。這個文件記錄了哪些文件由哪些文件產(chǎn)生,用什么命令來產(chǎn)生。Make依靠此 makefile中的信息檢查磁盤上的文件,如果目的文件的創(chuàng)建或修改時間比它的一個依靠文件舊的話,make就執(zhí)行相應(yīng)的命令,以便更新目的文件。

  Makefile中的編譯規(guī)則要相應(yīng)地使用arm-linux-版本。

  (4)代碼編輯

  可以使用傳統(tǒng)的vi編輯器,但最好采用emacs軟件,它具備語法高亮、版本控制等附帶功能。

  在宿主機(jī)上用上述工具完成應(yīng)用程序的開發(fā)后,可以通過如下途徑將程序下載到目標(biāo)板上運行:

  (1)通過串口通信協(xié)議rz將程序下載到目標(biāo)板的文件系統(tǒng)中(感謝Linux提供了rz這樣的一個命令);

  (2)通過ftp通信協(xié)議從宿主機(jī)上的ftp目錄里將程序下載到目標(biāo)板的文件系統(tǒng)中;

  (3)將程序拷入U盤,在目標(biāo)機(jī)上mount U盤,運行U盤中的程序;

 ?。?)如果目標(biāo)機(jī)Linux使用NFS文件系統(tǒng),則可以直接將程序拷入到宿主機(jī)相應(yīng)的目錄內(nèi),在目標(biāo)機(jī)Linux中可以直接使用。

  1. 文件編程

  Linux的文件操作API涉及到創(chuàng)建、打開、讀寫和關(guān)閉文件。

  創(chuàng)建

int creat(const char *filename, mode_t mode);

  參數(shù)mode指定新建文件的存取權(quán)限,它同umask一起決定文件的最終權(quán)限(mode&umask),其中umask代表了文件在創(chuàng)建時需要去掉的一些存取權(quán)限。umask可通過系統(tǒng)調(diào)用umask()來改變:

int umask(int newmask);

  該調(diào)用將umask設(shè)置為newmask,然后返回舊的umask,它只影響讀、寫和執(zhí)行權(quán)限。

  打開

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

  讀寫

  在文件打開以后,我們才可對文件進(jìn)行讀寫了,Linux中提供文件讀寫的系統(tǒng)調(diào)用是read、write函數(shù):

int read(int fd, const void *buf, size_t length);
int write(int fd, const void *buf, size_t length);

  其中參數(shù)buf為指向緩沖區(qū)的指針,length為緩沖區(qū)的大小(以字節(jié)為單位)。函數(shù)read()實現(xiàn)從文件描述符fd所指定的文件中讀取 length個字節(jié)到buf所指向的緩沖區(qū)中,返回值為實際讀取的字節(jié)數(shù)。函數(shù)write實現(xiàn)將把length個字節(jié)從buf指向的緩沖區(qū)中寫到文件描述符fd所指向的文件中,返回值為實際寫入的字節(jié)數(shù)。

  以O(shè)_CREAT為標(biāo)志的open實際上實現(xiàn)了文件創(chuàng)建的功能,因此,下面的函數(shù)等同creat()函數(shù):

int open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);

  定位

  對于隨機(jī)文件,我們可以隨機(jī)的指定位置讀寫,使用如下函數(shù)進(jìn)行定位:

int lseek(int fd, offset_t offset, int whence);

  lseek()將文件讀寫指針相對whence移動offset個字節(jié)。操作成功時,返回文件指針相對于文件頭的位置。參數(shù)whence可使用下述值:

  SEEK_SET:相對文件開頭
  SEEK_CUR:相對文件讀寫指針的當(dāng)前位置
  SEEK_END:相對文件末尾

  offset可取負(fù)值,例如下述調(diào)用可將文件指針相對當(dāng)前位置向前移動5個字節(jié):

lseek(fd, -5, SEEK_CUR);

  由于lseek函數(shù)的返回值為文件指針相對于文件頭的位置,因此下列調(diào)用的返回值就是文件的長度:

lseek(fd, 0, SEEK_END);

  關(guān)閉

  只要調(diào)用close就可以了,其中fd是我們要關(guān)閉的文件描述符:

int close(int fd);

  下面我們來編寫一個應(yīng)用程序,在當(dāng)前目錄下創(chuàng)建用戶可讀寫文件"example.txt",在其中寫入"Hello World",關(guān)閉文件,再次打開它,讀取其中的內(nèi)容并輸出在屏幕上:

#include
#include
#include
#include
#define LENGTH 100
main()
{
 int fd, len;
 char str[LENGTH];
 fd = open("hello.txt", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); /* 創(chuàng)建并打開文件 */
 if (fd)
 {
  write(fd, "Hello, Software Weekly", strlen("Hello, software weekly"));
  /* 寫入Hello, software weekly字符串 */
  close(fd);
 }

 fd = open("hello.txt", O_RDWR);
 len = read(fd, str, LENGTH); /* 讀取文件內(nèi)容 */
 str[len] = '