第六講 串口操作zz

發信人: gdtyy (gdtyy), 信區: Embedded
標  題: 第六講 串口操作
發信站: 水木社區 (Mon Jun 25 23:32:15 2007), 站內

*******************
* 第六講 串口操作 *
*******************
    2007/01/03  [email protected]  www.armecos.com

    串口可以用來監控程序、MODEM控制、GDB通信、數據傳輸......ecos是通過設備文件來
訪問相關串口設備的,再也不必關心底層硬件細節,什麼FIFO、什麼控制寄存器通通不必理
會。ecos抽象串口爲一個設備文件,串口0爲“/dev/ser0”文件,串口1爲“/dev/ser1”文
件,依此類推。ecos自動枚舉串口,能自動識別普通串口和MODEM串口,能自動識別各種版
本的16C55x工業標準,能編譯時配置是否需要RAM緩衝區及其大小(帶緩衝區的自動基於中斷
驅動),系統開發人員只要確定串口寄存器基地址即可,用戶只要操作抽象的串口文件即可

    抽象的串口啥也不用操心了,ecos替我們處理了大部分工作,剩下的只有讀寫真正的數
據和讀寫串口自身的屬性(波特率/停止位等)。其實,不光串口如此,ecos把所有的設備都
抽象爲文件,他們的操作都是類似的,API函數都是同一組。下面以串口操作爲例分別介紹

    cyg_io_lookup(
        設備文件名,
        句柄
    )
    設備使用前要先查找這個設備並將設備名映射到適當的設備句柄並返回。以後操作都用
本次函數得到的句柄。還是老樣子,cyg表示cygnus公司出品,io表示IO設備操作,lookup
是具體操作內容---“查找”,下同。函數名字很容易記憶的。
    cyg_io_write/cyg_io_read(
        句柄,
        緩衝區,
        長度
    )
    從緩衝區向串口寫入/從串口向緩衝區讀入指定長度的數據。
    cyg_io_get_config/cyg_io_set_config(
        句柄,
        配置信息類型,
        緩衝區,
        長度
    )
    運行時(runtime)配置信息的讀取/設置。
    配置信息類型包括:串口屬性信息、內部buffer信息、內部緩衝區操作(清空輸入/輸出
)、阻塞/非阻塞訪問方式設置。
    我們這裏的範例只用到了設置串口屬性信息CYG_IO_SET_CONFIG_SERIAL_INFO操作。函
數調用結束時,緩衝區裏存放的就是串口屬性信息,包括:波特率、停止位、奇偶校驗、字
長、硬件流控。其中:
    字長爲下列四值之一:5、6、7、8。
    波特率爲下述值之一:50、75、110、134.5、150、200、300、600、1200、1800、
2400、3600、4800、7200、9600、14400、19200、38400、57600、115200、234000。
    停止位爲下述值之一:1、1.5、2。(大多數系統中停止位1.5只在字長爲5時纔有效)
    奇偶校驗方式:無、奇、偶、MARK、SPACE。
    硬件流控:有、無。

    好啦,現在根據程序講一下用法。先查找串口0對應的設備文件“/dev/ser0”,再設置
串口屬性(115200/1停止位/無校驗/8字長/無硬件流控),後面就可以用read/write直接讀寫
數據了,簡單吧!專注在想做的事情上,不用再分心考慮細節,串口抽象到最後,就是讀寫
數據和讀寫屬性。缺省的測試是回顯輸入的字符,註釋裏是另一個測試,每隔1秒顯示一個
數字0-9,周而復始。

    到目前爲止,我們已經瞭解了多任務編程、IO操作、中斷編程、網絡編程、串口操作,
那麼現在就可以做一些有價值的事情了。比如:做一個串口轉以太網設備。有了ecos平臺,
您現在需要的只是創意和思路。可以設計一個串口控制協議,完成串口和網絡數據橋接,可
以讓協議棧主動連接,也可以被動等待,還可以多任務併發(把一個串口虛擬成多個),如果
你有其他此類設備上的源碼,不妨移到這個平臺上驗證一下,無論穩定性、速度、可擴展性
、功耗都可以得到ecos平臺的保證。目前提供的這個ecos平臺採用基於中斷的串口,128字
節內部緩衝,FreeBSD完整協議棧,提供串口和網絡模板程序,唯一需要您做的就是提供創
意。您既可以直接利用ecos平臺開發,也可以將其作爲核心思路的快速驗證平臺。
    您現在可以用AT指令操作MODEM,還可以做個FTP客戶端/服務器,SMTP/POP3收發郵件,
亦或作個web server發佈您的個人主頁,這個“刀片式”/“提箱式”服務器比PC機省電^_^
    您可以在ecos平臺上操作USB、硬盤、CF卡等設備,重做所有實驗,是不是感覺編程更
容易了,沒有細節干擾思路更清楚了!當然,ecos內核支持文件系統,連這些細節也可以屏
蔽,抽象成“按名存取”,後面會講文件系統。

/* 串口操作 */
#include <cyg/io/serialio.h>
#include <cyg/io/io.h>
#include <cyg/infra/diag.h>
#include "cyg/kernel/kapi.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SCIF_BAUDRATE CYGNUM_SERIAL_BAUD_115200

#define STACK_SIZE 0x1000

static char stack[STACK_SIZE];
static cyg_thread thread_data;
static cyg_handle_t thread_handle;

void
tmain(cyg_addrword_t p)
{
    static char c,b[]={"1234567890"};
    int res,i;
    cyg_uint32 len;
    cyg_io_handle_t ser;

    cyg_serial_info_t serial_info =
        CYG_SERIAL_INFO_INIT( SCIF_BAUDRATE,
        CYGNUM_SERIAL_STOP_1,
        CYGNUM_SERIAL_PARITY_NONE,
        CYGNUM_SERIAL_WORD_LENGTH_8,
        0 );
    len = sizeof(serial_info);

    cyg_io_lookup("/dev/ser0", &ser);

    res = cyg_io_set_config(ser, CYG_IO_SET_CONFIG_SERIAL_INFO, &serial_info,
&len);
    if (res != ENOERR)
      diag_printf("set_config flow_control returned an error/n");

    printf("Hello/n");
    i=0;

    while(1){
      len = 1;
      cyg_io_read(ser,&c,&len);
      len = 1;
      cyg_io_write(ser, &c, &len);
    }

    /*
    while(1){
      if(i>=10) i=0;
      len = 1;
      c=b[i];
      cyg_io_write(ser, &c, &len);
      cyg_thread_delay(100);
      i++;
    }
    */
}

void
cyg_user_start(void)
{
    // Create a main thread, so we can run the scheduler and have time 'pass'
    cyg_thread_create(6,                // Priority - just a number
                      tmain,          // entry
                      0,                 // entry parameter
                      "sio test",        // Name
                      &stack[0],         // Stack
                      STACK_SIZE,        // Size
                      &thread_handle,    // Handle
                      &thread_data       // Thread data structure
            );
    cyg_thread_resume(thread_handle);  // Start it
}

附錄:
UART串口的歷史  2005/03/22

    很久很久以前,計算機還沒有出現,那時就已經存在了(計算機)史前的串口設備(電傳
打字機,工控測量設備,通信調制解調器),爲了連接這些串口,EIA制定了RS232標準,採
用DB25接插件,支持同步和異步串口,D型的接口可以有效防止插反。標準化給使用帶來了
便利。
    時光荏苒,個人計算機出現了,這些已有的串口設備毫無疑問地成爲了最初的外設,自
然而然地RS232標準被個人計算機採納。但是設備製造商傾向於體積更小,成本更低的接口
,因此,將DB25中未使用的和支持同步模式的引腳去掉,形成DB9。最初的情況相當混亂,
因爲DB9只定義了信號,卻沒有指定信號和引腳的對應關係,各個製造商只能自行定義。幸
運的是,IBM的PC成了工業標準,DB9逐漸統一到IBM的定義上來。
    DB9只有9根線,遵循RS232標準。定義如下:
    DTR,DSR------DTE設備準備好/DCE設備準備好。主流控信號。
    RTS,CTS------請求發送/清除發送。用於半雙工時,收發切換。屬於輔助流控信號。半
雙工的意思是說,發的時候不收,收的時候不發。那麼怎麼區分收發呢?缺省時是DCE向
DTE發送數據,當DTE決定向DCE發數據時,先有效RTS,表示DTE希望向DCE發送,一般DCE不
能馬上轉換收發狀態,DTE就通過監測CTS是否有效來判斷可否發送,這樣避免了DTE在DCE未
準備好時發送所導致的數據丟失。
    全雙工時,這兩個信號一直有效即可。

    隨着計算機的日益普及,很多非RS232的串口也要接入PC機,如果爲每一種新出現的串
口都增加一個新的I/O口顯然不現實,因爲PC後面板位置有限,因此,將RS232串口和非
RS232串口都通過RS232口接入是最佳方案。UART的U(通用)指的就是這個意思。早期ROM
BIOS和DOS裏的通信軟件都是爲RS232設計的,在沒有檢測到DCD有效前不會發送數據,因此
,就連發送一個字符這樣樸素的應用也要給出DCD、DTR、DSR等控制信號。因此,串口接頭
上要將一些控制線短接,或者乾脆繞過系統軟件自己寫通信程序。
    到此,UART的涵義就總結爲:通用的 異步 (串行) I/O口。
    就在UART冠以通用二字,準備一統江湖的時候,製造商們不滿於它的速度、體積和靈活
性(軟件可配置),推出了USB和1394串口。目前,筆記本上的UART串口有被取消的趨勢,因
而有網友發出了“沒有串口,吾誰與歸”的慨嘆,古今多少事,都付笑談中,USB取代UART
是後話,暫且不表。
    話說自從賀氏(Hayes)公司推出了聰明貓(SmartModem),他們制定的MODEM接口就成了業
界標準,自此以後,所有公司製造的兼容貓都符合賀氏標準(連AT指令也兼容,大家一起抄
他唄)。
    細觀賀氏制定的MODEM串口,與RS232標準大不相同。DTR在整個通信過程中一直保持有
效,DSR在MODEM上電後/可以撥號前有效(取決於軟件對DSR的理解),在通信過程的任意時刻
,只要DTR/DSR無效,通信過程立即終止。在某種意義上,這也可以算是流控,但肯定不是
RS232所指的那種主流控。如果拘泥於RS232,你是不會理解DTR和DSR的用途的。
    賀氏不但改了DTR和DSR,竟然連RTS和CTS的涵義也重新定義了。因此,RTS和CTS已經不
具有最開始的意義了。從字面理解RTS和CTS,是用於半雙工通信的,當DTE想從收模式改爲
發模式時,就有效RTS請求發送,DCE收到RTS請求後不能立即完成轉換,需要一段時間,然
後有效CTS通知DTE:DCE已經轉到發模式,DTE可以開始發送了。在全雙工時,RTS和CTS都缺
省置爲有效即可。然而,在賀氏的MODEM串口定義中,RTS和CTS用於硬件流控,和什麼勞什
子的全雙工/半雙工一點關係也沒有。
    注意,硬件流控是靠軟件實現的,之所以強調“硬件”二字,僅僅是因爲硬件流控提供
了用於流量情況指示的硬件連線,並不是說,你只要把線連上,硬件就能自己流控。如果軟
件不支持,光連上RTS和CTS是沒有用的。
    RTS和CTS硬件流控的軟件算法如下:(RTS有效表示PC機可以收,CTS有效表示MODEM可以
收,這兩個信號互相獨立,分別指示一個方向的流量情況。)

    PC端處理:
      發. 當 發現(不一定及時發現) CTS (-3v to -15v)無效時,停止發送,
          當 發現(不一定及時發現) CTS (3v to 15v)有效時,恢復發送;

      收. 0<M<N<LEN_OF_RX_BUFFERS
          當接收buffers中的bytes<M 時,給 RTS 有效信號(+3v to +15v),
          當接收buffers中的bytes>N 時,給 RTS 無效信號(-3v to -15v);

    MODEM端處理:
          同上,但RTS與CTS交換。

    MODEM引腳名稱容易讓人迷惑的原因是因爲學習的是RS232標準,卻使用賀氏標準的貓,
兩個標準風馬牛不相及。
--

※ 來源:·水木社區 http://newsmth.net·[FROM: 61.149.56.*]
 

發佈了29 篇原創文章 · 獲贊 6 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章