本節(jié)說明如何使用Maxim/Dallas Semiconductor提供的Microcontroller Tool Kit (MTK)工具將IAR編譯器生成的hex文件裝載到TINIm400驗證模塊中。目前可用的MTK版本僅支持Windows。如果您的開發(fā)環(huán)境不是Windows?,需要使用JavaKit應(yīng)用程序來裝載和執(zhí)行應(yīng)用程序。要使用JavaKit,您必須具備Java Runtime Environment1 (版本至少為1.2),并且安裝了Java Communications API2。JavaKit工具包含在MxTNI軟件開發(fā)包中。請下載MxTNI SDK。在撰寫本文時,發(fā)布的最新固件版本是1.15。運行JavaKit的指導(dǎo)說明可在TINI SDK docs目錄下的Running_JavaKit.txt文件中找到。如果您在運行MTK或JavaKit時遇到問題,可能其他人已經(jīng)遇到過類似問題并已在Dallas Semiconductor討論組公布。您可以在討論組搜索現(xiàn)有文章(和新發(fā)表的文章)。
在此可下載最新版本的應(yīng)用程序。要安裝MTK,請運行安裝文件并按照提示操作。成功安裝后,將會添加一個新的菜單組:Start→All Programs→Dallas Semiconductor MTK。MTK啟動后,會出現(xiàn)圖4. 所示的對話框。
?
圖4. 啟動時 MTK選項。
選擇TINI選項,以操作TINIm400評估板。
選擇了TINI之后,會打開MTK主窗口。從Options→Configure Serial Port菜單選項中選擇您用來與TINIm400通信的串口。然后,選擇Tini→Tini Options 菜單,就會出現(xiàn)下面的對話框。選擇DSTINIm400按鈕,配置MTK用于和TINIm400板通訊。圖5顯示了帶有DSTINIm400按鈕的對話框。
?
圖5. 選擇TINIm400配置選項。
選擇Tini→Open COMx在xxx baud菜單選項打開串口。接著選擇Tini→Reset 選項復(fù)位評估板。會出現(xiàn)DS80C400的裝載提示,如下所示:
DS80C400 Silicon Software - Copyright (C) 2002 Maxim Integrated Products
Detailed product information available at http://www.maxim-ic.com
Welcome to the TINI DS80C400 Auto Boot Loader 1.0.1
>
從File菜單中選擇Load HEX File。找到并選擇我們剛才生成的hello_world.hex文件。加載程序后,有兩種方法運行它。因為我們將程序加載到40區(qū),您可以輸入:
> B40
> X
要選擇40區(qū)并運行那里的代碼,您也可以輸入:
> E
這會使ROM查找可執(zhí)行代碼。它查找一個標識當(dāng)前區(qū)具有可執(zhí)行代碼的特定標簽。此標簽由文本'TINI'和隨后的當(dāng)前區(qū)號碼組成,并位于當(dāng)前區(qū)的0x0002地址。應(yīng)用程序的起始代碼采用下面幾行聲明該標簽:
?VECTOR_TABLE:
sjmp ?INIT
DB 'TINI' ; Tag for TINI Environment 1.02c
; or later (ignored in 1.02b)
DB high(?INIT) ; Target bank
注意sjmp ?INIT語句位于0x40區(qū)的0x0000地址。其后緊跟著可執(zhí)行標簽{ 'T', 'I', 'N', 'I', 0h},由于sjmp語句為兩個字節(jié),所以該標簽地址位于0x0002處。當(dāng)您鍵入E時,ROM從C0h區(qū)開始向下搜索可執(zhí)行代碼。如果您鍵入E時,執(zhí)行了其它代碼,則意味著ROM在一個比您的代碼裝載位置0x400000更高的地址找到了一個可執(zhí)行標簽。如果出現(xiàn)這種情況,您可能需要找到此標簽的位置,并刪除那個區(qū)的內(nèi)容。
與ROM以及IAR ROM庫接口
在高速微控制器用戶指南DS80C4003補充資料中說明了在匯編語言中調(diào)用ROM函數(shù)的過程。但是,在C中調(diào)用這些ROM函數(shù)會復(fù)雜一些。必須將參數(shù)從IAR C編譯器的規(guī)則轉(zhuǎn)換成ROM使用的規(guī)則。IAR編譯器通過硬件堆棧和寄存器相結(jié)合的方式傳遞參數(shù)。ROM函數(shù)以多種不同方式接受參數(shù)。例如,socket函數(shù)接收存儲在一個參數(shù)緩沖器中的參數(shù)。相反,許多功能函數(shù)接收由特殊功能寄存器或堆棧存儲器傳遞的參數(shù)。為了從IAR調(diào)用方式轉(zhuǎn)換為ROM參數(shù)方式,Dallas Semiconductor已經(jīng)編寫了訪問ROM函數(shù)的庫。
在您的C程序中使用ROM函數(shù)只需包含一個頭文件并與相應(yīng)的庫文件連接即可。用于IAR編譯器的ROM庫包括:
ROM初始化程序
DHCP客戶端
進程調(diào)度
Sockets (TCP、UDP和Multicast)
TFTP客戶端
功能函數(shù)(CRC16, 隨機數(shù))
在撰寫本文時,還沒有為IAR編譯器提供包括文件系統(tǒng)、郵件客戶端和HTTP服務(wù)器之類的擴展庫。請關(guān)注IAR庫主頁上的DS80C4004升級信息,我們會添加更多支持IAR的庫。
簡單應(yīng)用: HTTP服務(wù)器
這里編寫了一個簡單的http服務(wù)器說明如何使用一些ROM庫函數(shù),特別是socket和進程調(diào)度庫。該示例應(yīng)用程序由兩個模塊組成:一個HTTP服務(wù)器和一個SNTP客戶端。主程序生成一個新的子任務(wù)來運行http服務(wù)器,用于處理80端口上的客戶連接。父任務(wù)每60秒會試圖通過時間服務(wù)器同步當(dāng)前時間。
SNTP客戶端模塊
以下代碼實現(xiàn)SNTP客戶端模塊的核心功能。
socket_handle = socket(0, SOCKET_TYPE_DATAGRAM, 0);
for (i=0;i<256;i++)
buffer[i] = 0;
// set a timeout of about 2 seconds
buffer[0] = 0x0;
buffer[1] = 0x0;
buffer[2] = 0x8;
buffer[3] = 0x0;
setsockopt(socket_handle, 0, SO_TIMEOUT, buffer, 200);
buffer[2] = 0; //reset since we used this in call to setsockopt
buffer[0] = 0x23; // No warning/NTP Ver 4/Client
address.sin_addr[12] = TIME_NIST_GOV_IP_MSB;
address.sin_addr[13] = TIME_NIST_GOV_IP_2;
address.sin_addr[14] = TIME_NIST_GOV_IP_3;
address.sin_addr[15] = TIME_NIST_GOV_IP_LSB;
address.sin_port = htons(NTP_PORT) // port number
sendto(socket_handle, buffer, 48, 0, &address, sizeof(struct sockaddr));
recvfrom(socket_handle, buffer, 256, 0, &address, sizeof(struct sockaddr));
//IAR uses little Endian for storing data, so reorganize the data before //converting it to long
buffer[0]=buffer[43];
buffer[1]=buffer[42];
buffer[2]=buffer[41];
buffer[3]=buffer[40];
timeStamp = *(unsigned long *)(&buffer[0]);
formatTimeString(timeStamp, "London", last_time_reading_1);
formatTimeString(timeStamp - (6 * SECONDS_PER_HOUR), "Dallas", last_time_reading_2);
formatTimeString(timeStamp + (5 * SECONDS_PER_HOUR) + (30 * SECONDS_PER_MINUTE), "Bangalore", last_time_reading_3);
formatTimeString(timeStamp - (10 * SECONDS_PER_HOUR), "Honolulu",
last_time_reading_4);
last_reading_seconds = getTimeSeconds();
closesocket(socket_handle);
SNTP客戶端模塊是通過RFC 1361實現(xiàn)的。SNTP模塊通過使用UDP協(xié)議和time.nist.gov通信,并請求一個時間標記。需注意撰寫本應(yīng)用筆記時還不能提供DNS查找支持,因此time.nist.gov的IP地址是人工設(shè)定的。
首先,創(chuàng)建一個數(shù)據(jù)包socket并分配一個大約2秒(0x800==2048毫秒)的超時。這樣會保證如果和我們選中的服務(wù)器通信失敗,我們不會無休止地等待響應(yīng)。
接下來的一行用來設(shè)置請求選項。在RFC 1361的第3節(jié)對這些位進行了說明。0x23在一個閏秒不產(chǎn)生告警,要求使用版本4 NTP,并聲明模式為Client。我們使用普通數(shù)據(jù)包函數(shù)sendto和recvfrom請求發(fā)送并接收響應(yīng)后,將時間標記的秒賦予變量timeStamp,然后調(diào)整至參考日期1970年1月1號。用函數(shù)formatTimeString將時間標記轉(zhuǎn)換成一個可讀字符串,比如說"In London it is 05:33:19 on May 11, 2005"。
用函數(shù)getTimeSeconds 確定基于DS80C400內(nèi)部時鐘的最后一次更新時間。由于程序大約每60秒更新一次,HTML網(wǎng)頁time.html將會使用該數(shù)值來報告上一次時間更新后已經(jīng)過了多長時間。最后,關(guān)閉socket,SNTP客戶端進入另一個60秒的休眠期。
評論
查看更多