ecos在EASYARM2200和SMARTARM2200上的應用合集zz

發信人: gdtyy (gdtyy), 信區: Embedded
標  題: ecos在EASYARM2200和SMARTARM2200上的應用合集
發信站: 水木社區 (Mon Jun 25 23:28:55 2007), 站內

ecos增值軟件包的詳細使用說明
    2006/12/27  [email protected]  www.armecos.com

    一些網友來信反映說ecos增值軟件包的範例比較少,不太會用,希望增加詳細的使用說
明。其實很多關於ecos的書上都有使用方法的介紹,不過考慮到很多用戶第一次使用ecos,
我還是覺得有必要再給出一些詳細的使用說明。因爲網友的問題重複的比較多,就不一一回
信了,統一寫成文檔共享。主要想說明線程、IO操作、中斷、TCP/IP協議棧、文件系統、
GUI等的使用方法及其他感覺有必要闡述的內容。

    在開始前先回答網友的幾個問題。
    1、ecos for smartarm2200經常死機的原因是PSRM讀寫速度比較慢(它內部用SDRAM,外
部是SRAM接口,性價比高?),用較高速度訪問時容易出現採樣錯誤,把PSRAM讀寫訪問長度
各增加1個時鐘週期後,系統就很穩定了,不再出現死機現象,升級版本已經提供。
    2、關於在裸機上跑ping、TFTP、xmodem,我沒有單獨做過,不過redboot本身就是不帶
內核的ecos應用程序,其源碼可以直接用在裸機上,這部分源碼在ecos中已經提供了,自己
看看吧。您發來的程序,我實在沒時間分析了:-(
    3、關於單片機實現“TELNET服務端”方面的程序資料,我沒有具體的文字資料,不過
redboot支持telnet,建議直接看源碼。
    4、關於monitor監控程序的實現原理,主要就是用軟件中斷指令替換斷點處的語句,引
發異常中斷後進入處理程序,收集現場信息,然後通過通信接口部分傳送到宿主機顯示出來
。難點是單步step調試斷點的插入需要知道下一條語句的位置,不過好在有跟蹤T標誌,實
現就容易多了。GDB的使用和串行通信協議見《Debugging with GDB》。軟件包裏提供了全
部實現源碼。

    *********************
    * 第一講 多任務編程 *
    *********************
    第一次使用ecos,當然要先編個hello程序啦。那就編個多任務的,恩,3個線程任務同
時打印信息,A線程每秒打印一次,B線程每3秒打印一次,C線程每6秒打印一次。
    這個程序在ucos51演示程序中也有,就是demo1。現在來比較一下二者的異同。
    從總體看,ecos和ucos的應用程序大同小異,都有線程/任務創建、線程/任務函數、堆
棧等內容,只是API函數名字不同。
    ecos應用程序沒有從main開始,而是從cyg_start啓動,在cyg_start中創建test線程,
再在test中創建3個實際的工作線程。
    ecos的命名規則很有層次感,比如:cyg_thread_delay(),cyg表示cygnus公司出品,
thread表示這個函數是與線程相關的(如:線程創建、延時),delay表示延時。怎麼樣?是
不是很好記憶。比ucos的OSTimeDly好記吧!所有cygnus公司提供的API函數前面都帶cyg前
綴,你自己寫的函數可以加上你的標識前綴,如我自己定義的函數前加yy前綴。

    cyg_thread_create(//創建線程
        線程優先級,
        線程函數指針,
        線程函數參數,//對應線程函數的(cyg_addrword_t data)入口參數
        線程名,      //用於調試目的
        堆棧基址,
        堆棧大小,
        線程句柄,
        保存此線程內核數據結構的存儲空間
        );

    cyg_thread_resume(線程句柄);   //線程恢復

    cyg_thread_delay(延時時間);    //以10ms爲單位

    cyg_scheduler_start();         //啓動調度器開始工作。該函數被調用後不會返回
,類似ucos中的OSStart();

    好了,第一個程序就是這麼簡單,跟ucos很像吧,其實,所有的RTOS都差不多的,只是
函數名字不同罷了。ecos和ucos一樣都是直接使用平板內存,沒有特權概念,不過,ecos比
ucos更高級,包含了TCP/IP棧、文件系統、GUI,功能也更強大,可以用C++開發。這個演示
應用程序可以不加修改地用在任何支持ecos的平臺上,例如:EASYARM2200和SMARTARM2200上
的運行效果是一樣的,這就是OS的好處,不用再關心定時器初始化,串口編程,抹平了硬件差
異,令編程如此簡單,EASY。

    下面是測試程序運行結果,Demo程序創建了3個任務A、B、C,優先級全爲10,A每秒顯
示一次,B每3秒顯示一次,C每6秒顯示一次。從顯示結果看,顯示3個A後顯示1個B,顯示6
個A和2個B後顯示1個C,結果顯然正確。

RedBoot> lo -b 0x81010000 -r -m xmodem
*Raw file loaded 0x81010000-0x810252cb, assumed entry at 0x81010000
xyzModem - CRC mode, 679(SOH)/0(STX)/0(CAN) packets, 2 retries
RedBoot> go 0x81010000
+


            *******************************
            *     Hello! The world.       *
            *******************************


        AAAAAA111111 is active.thread data is 1.
        BBBBBB333333 is active.thread data is 2.
        CCCCCC666666 is active.thread data is 3.
        AAAAAA111111 is active.thread data is 1.
        AAAAAA111111 is active.thread data is 1.
        BBBBBB333333 is active.thread data is 2.
        AAAAAA111111 is active.thread data is 1.
        AAAAAA111111 is active.thread data is 1.
        AAAAAA111111 is active.thread data is 1.
        CCCCCC666666 is active.thread data is 3.
        BBBBBB333333 is active.thread data is 2.
        ......


完整的測試源程序如下:demo1.c

#include <cyg/kernel/kapi.h>

#define STACK_SIZE 4096

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

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

    for(;;)
    {
        printf("/tAAAAAA111111 is active.thread data is %d./n",message);
        cyg_thread_delay(100);
    }
}

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

    for(;;)
    {
        printf("/tBBBBBB333333 is active.thread data is %d./n",message);
        cyg_thread_delay(300);
    }
}

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

    for(;;)
    {
        printf("/tCCCCCC666666 is active.thread data is %d./n",message);
        cyg_thread_delay(600);
    }
}

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

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

    // Create a main thread, so we can run the scheduler and have time 'pass'
    cyg_thread_create(10,                // Priority - just a number
                      taskc,             // entry
                      3,                 // entry parameter
                      "taskc",           // Name
                      &stack[3],         // Stack
                      STACK_SIZE,        // Size
                      &thread_handle[3], // Handle
                      &thread_data[3]    // Thread data structure
            );
    cyg_thread_resume(thread_handle[3]); // 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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章