第二講 硬件I/O操作zz

發信人: gdtyy (gdtyy), 信區: Embedded
標  題: 第二講 硬件I/O操作
發信站: 水木社區 (Mon Jun 25 23:29:42 2007), 站內

**********************
* 第二講 硬件I/O操作 *
**********************
    2006/12/27  [email protected]  www.armecos.com

    對設備進行訪問和控制時需要訪問I/O寄存器。硬件抽象層提供了一些宏用於I/O寄存器
的讀寫操作。
    之所以不用指針直接操作,目的是爲了可移植性。使用宏的原因是避免函數調用引起的
性能損失。ecos是一種可移植的嵌入式操作系統,它可以移植到16位、32位、64位的各種處
理器平臺上。ecos由各種組件構成,根據具體硬件平臺的需要可以分別將這些組件加入到系
統中來,從而實現各種所需的功能。ecos的這種層次結構的最底層是硬件抽象層(Hardware
Abstraction Layer),通常稱爲HAL。硬件抽象層HAL對處理器結構和系統硬件平臺進行抽象
,當需要在一個新的目標平臺上運行ecos時,只需對底層的硬件抽象層進行修改,便可迅速
地將整個ecos系統移植到新的平臺上。
    常用I/O操作宏:

    讀寄存器值  從寄存器讀數據並將結果存放在存值變量裏
    HAL_READ_UINT8(寄存器地址,存值變量);
    HAL_READ_UINT16(寄存器地址,存值變量);
    HAL_READ_UINT32(寄存器地址,存值變量);

    寫寄存器  向寄存器寫如數值
    HAL_WRITE_UINT8(寄存器地址,值);
    HAL_WRITE_UINT16(寄存器地址,值);
    HAL_WRITE_UINT32(寄存器地址,值);

    這些宏位於頭文件cyg/hal/hal_io.h內,感興趣的讀者可以看看這些宏是怎麼實現的。
    I/O操作宏的定義也是按照ecos的分層原則定義的,HAL表示這是硬件抽象層函數,
READ/WRITE表示具體操作,UINTx表示讀寫寬度,這些宏很容易記憶的,而且見名知意。
    寄存器名稱定義在cyg/hal/plf_io.h中,我們仍然按照ecos命名規則起名,如下:

// GPIO
#define LPC2XXX_GPIO_IO0PIN       0xE0028000
#define LPC2XXX_GPIO_IO0SET       0xE0028004
#define LPC2XXX_GPIO_IO0DIR       0xE0028008
#define LPC2XXX_GPIO_IO0CLR       0xE002800C

    LPC2XXX表示芯片型號,GPIO表示I/O類型,IO-n-ops表示Pn口的操作方式(引腳、方向
、設置、清除)。這樣的命名比枯燥的數字更容易記憶,不重名也不易錯。
    下面是控制GPIO讓蜂鳴器發聲的應用程序,響1秒停1秒,周而復始。線程創建第一講已
經說過,不再重複。

#include <cyg/kernel/kapi.h>
#include <cyg/hal/hal_io.h>
#include <cyg/hal/plf_io.h>

#define STACK_SIZE 4096
#define BEEPCON 0x0000080

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

void taska(cyg_addrword_t data)
{
    int message = (int) data;

    HAL_WRITE_UINT32(LPC2XXX_GPIO_IO0DIR,BEEPCON);

    for(;;)
    {
        HAL_WRITE_UINT32(LPC2XXX_GPIO_IO0SET,BEEPCON);
        cyg_thread_delay(100);
        HAL_WRITE_UINT32(LPC2XXX_GPIO_IO0CLR,BEEPCON);
        cyg_thread_delay(100);
    }
}

void
test(cyg_addrword_t data)
{
    printf("/n/n/n");
    printf("/t    *******************************/n");
    printf("/t    *     Hello! The world.       */n");
    printf("/t    *******************************/n/n/n");

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

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

--

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

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