自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

采用TCP協(xié)議實現(xiàn)ethernet bootloader

網(wǎng)絡(luò) 網(wǎng)絡(luò)管理
Microchip TCP/IP Stack是免費的,廣泛應(yīng)用于PIC單片機中。由于有遠(yuǎn)程更新程序的需求,我決定開發(fā)基于TCP協(xié)議的ethernet bootloader, 主要使用了Microchip TCP/IP Stack的TCP模塊。最終我開發(fā)出來的ethernet bootloader 在PIC18F97J60上驗證通過。

TCP/IP Stack

Microchip TCP/IP Stack是免費的,廣泛應(yīng)用于PIC單片機中。由于有遠(yuǎn)程更新程序的需求,我決定開發(fā)基于TCP協(xié)議的ethernet bootloader, 主要使用了Microchip TCP/IP Stack的TCP模塊。最終我開發(fā)出來的ethernet bootloader 在PIC18F97J60上驗證通過。整個實現(xiàn)上分兩部分,一部分是單片機端的基于TCP協(xié)議的bootloader程序,我將其命名為PhnBoot_v2.0, 另外一部分是PC端同樣基于TCP協(xié)議于單片機互動的通信程序,我將其命名為PhnLoader_v2.0。我還定義了PhnBoot_v2.0和PhnLoader_v2.0之間傳輸數(shù)據(jù)的通信協(xié)定。下面將細(xì)說我是如何實現(xiàn)的。

通信協(xié)定

單片機端PhnBoot_v2.0和PC端PhnLoader_v2.0之間的通信數(shù)據(jù)包采用以下協(xié)定

<STX><CMD><ADDRL><ADDRH><ADDRU><LEN><DATA>...<DATA><ETX>

定義如下:

STX - Start of packet indicator

ETX - End of packet indicator

LEN - The length of true data

DATA - General data 16 bytes, only first LEN of datas are true

CMD - Base command

ADDR - Address up to 24 bits ( ADDRL , ADDRH , ADDRH)

具體有以下Base command:

RD-VER: 0x00 -- Read Version Information (最終版本刪除了此命令)

RD_MEM: 0x01 -- Read Program Memory (最終版本刪除了此命令)

ER_MEM: 0x03 -- Erase Program Memory

WR_MEM: 0x02 -- Write Program Memory

WR_CFG: 0x04 -- Write Configuration Registers

PhnLoader_v2.0 功能

定義好了通訊協(xié)定, 接著就按照協(xié)定去實現(xiàn)PhnLoader_v2.0。 PhnLoader_v2.0的具體功能包括選擇IP地址,端口和協(xié)議類型, 目前只支持TCP協(xié)議, 建立TCP服務(wù)器,加載應(yīng)用程序Hex文件,Parse 應(yīng)用程序的Hex文件,一行一行解讀Hex文件,一旦收到連接請求,建立TCP連接,一旦收到應(yīng)用程序跟新請求,立刻按照通訊協(xié)定采用TCP協(xié)議發(fā)送Hex記錄到單片機,接收單片機發(fā)送回來的Response,發(fā)送完畢后斷開TCP連接,發(fā)送期間出現(xiàn)問題就立馬結(jié)束發(fā)送。

PhnLoader_v2.0 主要代碼段

PhnLoader_v2.0是用C#實現(xiàn)的,是我在利用空余時間自學(xué)C#后寫的,上面提到的功能都實現(xiàn)了。

View Code

PhnLoader_v2.0 用戶界面

 

PhnBoot_v2.0 功能

在PhnLoader_v2.0完成后,接著就是完成PhnBoot_v2.0。 PhnBoot_v2.0主要功能就是使用Microchip的TCP/IP Stack建立TCP Client,發(fā)送連接請求,建立連接后發(fā)送更新應(yīng)用程序請求,接收PhnLoader_v2.0傳送過來的Hex記錄。解讀Hex記錄中的啟始位,命名,地址,數(shù)據(jù)和結(jié)束位,將數(shù)據(jù)燒錄到指定的程序存儲器的位置上,然后通過ethernet返回Response消息給PC端PhnLoader_v2.0。

PhnBoot_v2.0 位置

PhnBoot_v2.0放置在程序存儲器的頭部,大小為0x4C00程序字。

 

Interrupt Vector Remap

由于PhnBoot_v2.0位于程序存儲器的頭部,需要對Interrupt Vector進行remap. 代碼如下。

  1. #define APP_START 0x4C00 
  2.  
  3. #define REMAPPED_APP_HIGH_INTERRUPT_VECTOR 0x4C08 
  4.  
  5. #define REMAPPED_APP_LOW_INTERRUPT_VECTOR 0x4C18 
  6.  
  7. #pragma code low_vector_section=0x018 
  8.  
  9. void low_vector (void
  10.  
  11.  
  12. _asm 
  13.  
  14. goto REMAPPED_APP_LOW_INTERRUPT_VECTOR 
  15.  
  16. _endasm 
  17.  
  18.  
  19. #pragma code high_vector_section=0x08 
  20.  
  21. void high_vector (void
  22.  
  23.  
  24. _asm 
  25.  
  26. goto REMAPPED_APP_HIGH_INTERRUPT_VECTOR 
  27.  
  28. _endasm 
  29.  

PhnBoot_v2.0 主要代碼段

PhnBoot_v2.0 是用C語言寫的,Microchip 8-bit C Compiler--MCC18編譯的。

  1. switch (GenState) 
  2.  
  3.  
  4. case SM_HOME: 
  5.  
  6. ARPResolve(&Server.IPAddr); 
  7.  
  8. if (ARPIsResolved(&Server.IPAddr,&Server.MACAddr)) 
  9.  
  10.  
  11. #ifdef STACK_USE_UDP 
  12.  
  13. MySock = UDPOpen(ClientPort,&Server,ServerPort); 
  14.  
  15. #endif 
  16.  
  17. #ifdef STACK_USE_TCP 
  18.  
  19. MySock = TCPOpen((DWORD)&Server, TCP_OPEN_NODE_INFO, ServerPort, 0); 
  20.  
  21. #endif 
  22.  
  23. if (MySock != INVALID_SOCKET) 
  24.  
  25.  
  26. tick = 0x4000; 
  27.  
  28. delay = BOOT_TIMEOUT; 
  29.  
  30. GenState++; 
  31.  
  32.  
  33.  
  34. else 
  35.  
  36.  
  37. tick--; 
  38.  
  39. if (tick==0) 
  40.  
  41.  
  42. tick = 0x4000; 
  43.  
  44. if (delay == 0) 
  45.  
  46.  
  47. delay = BOOT_TIMEOUT; 
  48.  
  49. GenState = SM_CLOSE; 
  50.  
  51.  
  52. delay--; 
  53.  
  54.  
  55.  
  56. break
  57.  
  58. case SM_READY: 
  59.  
  60. #ifdef STACK_USE_UDP 
  61.  
  62. if (UDPIsPutReady(MySock) > BUFFER_MAX) 
  63.  
  64.  
  65. UDPPutString(ok); 
  66.  
  67. UDPFlush(); 
  68.  
  69. GenState++; 
  70.  
  71.  
  72. #endif 
  73.  
  74. #ifdef STACK_USE_TCP 
  75.  
  76. if (TCPIsConnected(MySock)) 
  77.  
  78.  
  79. TCPPutString(MySock,ok); 
  80.  
  81. TCPFlush(MySock); 
  82.  
  83. GenState++; 
  84.  
  85.  
  86. #endif 
  87.  
  88. else 
  89.  
  90.  
  91. tick--; 
  92.  
  93. if (tick==0) 
  94.  
  95.  
  96. tick = 0x4000; 
  97.  
  98. if (delay == 0) 
  99.  
  100.  
  101. delay = BOOT_TIMEOUT; 
  102.  
  103. GenState = SM_CLOSE; 
  104.  
  105.  
  106. delay--; 
  107.  
  108.  
  109.  
  110. break
  111.  
  112. case SM_RESPONSE: 
  113.  
  114. #ifdef STACK_USE_UDP 
  115.  
  116. networkBytes = UDPIsGetReady(MySock); 
  117.  
  118. #endif 
  119.  
  120. #ifdef STACK_USE_TCP 
  121.  
  122. networkBytes = TCPIsGetReady(MySock); 
  123.  
  124. #endif 
  125.  
  126. if (networkBytes >= BUFFER_MAX) 
  127.  
  128.  
  129. #ifdef STACK_USE_UDP 
  130.  
  131. UDPGetArray(line_buffer, BUFFER_MAX); 
  132.  
  133. UDPDiscard(); 
  134.  
  135. #endif 
  136.  
  137. #ifdef STACK_USE_TCP 
  138.  
  139. TCPGetArray(MySock,line_buffer,BUFFER_MAX); 
  140.  
  141. TCPDiscard(MySock); 
  142.  
  143. #endif 
  144.  
  145. if (line_buffer[0] == STX && line_buffer[BUFFER_MAX - 1] == ETX) 
  146.  
  147.  
  148. switch (line_buffer[CMD_INDEX]) 
  149.  
  150.  
  151. case WR_MEM: 
  152.  
  153. EECON1 = PGM_WRITE; 
  154.  
  155. WriteMem(); 
  156.  
  157. break
  158.  
  159. case WR_CFG: 
  160.  
  161. if (!last_block_written&&!CFG_NUM) 
  162.  
  163.  
  164. WriteStart(); 
  165.  
  166. last_block_written = 1; 
  167.  
  168. ResetBlockBuffer(); 
  169.  
  170.  
  171. CFG_NUM++; 
  172.  
  173. EECON1 = CFG_WRITE; 
  174.  
  175. WriteCfg(); 
  176.  
  177. break
  178.  
  179. case ER_MEM: 
  180.  
  181. EECON1 = PGM_ERASE; 
  182.  
  183. EraseMem(); 
  184.  
  185. break
  186.  
  187. case RUN_APP: 
  188.  
  189. if (!last_block_written) 
  190.  
  191.  
  192. WriteStart(); 
  193.  
  194. last_block_written = 1; 
  195.  
  196. ResetBlockBuffer(); 
  197.  
  198.  
  199. GenState++; 
  200.  
  201. default
  202.  
  203. break
  204.  
  205.  
  206. #ifdef STACK_USE_UDP 
  207.  
  208. if (UDPIsPutReady(MySock) >= BUFFER_MAX) 
  209.  
  210.  
  211. UDPPutArray(line_buffer, BUFFER_MAX); 
  212.  
  213. UDPFlush(); 
  214.  
  215.  
  216. #endif 
  217.  
  218. #ifdef STACK_USE_TCP 
  219.  
  220. if (TCPIsPutReady(MySock) >= BUFFER_MAX) 
  221.  
  222.  
  223. TCPPutArray(MySock,line_buffer, BUFFER_MAX); 
  224.  
  225. TCPFlush(MySock); 
  226.  
  227.  
  228. #endif 
  229.  
  230.  
  231.  
  232. else 
  233.  
  234.  
  235. tick--; 
  236.  
  237. if (tick==0) 
  238.  
  239.  
  240. tick = 0x4000; 
  241.  
  242. if (delay == 0) 
  243.  
  244.  
  245. delay = BOOT_TIMEOUT; 
  246.  
  247. GenState = SM_CLOSE; 
  248.  
  249.  
  250. delay--; 
  251.  
  252.  
  253.  
  254. break
  255.  
  256. case SM_CLOSE: 
  257.  
  258. while (!TXSTAbits.TRMT); 
  259.  
  260. TXREG='>'
  261.  
  262. #ifdef STACK_USE_UDP 
  263.  
  264. UDPClose(MySock); 
  265.  
  266. #endif 
  267.  
  268. #ifdef STACK_USE_TCP 
  269.  
  270. TCPDisconnect(MySock); 
  271.  
  272. #endif 
  273.  
  274. MySock = INVALID_SOCKET; 
  275.  
  276. _asm 
  277.  
  278. goto APP_START 
  279.  
  280. _endasm 
  281.  
  282. break
  283.  

如何使用

1. 使用MCC18編譯PhnBoot_v2.0,

2. 使用pickit3燒錄PhnBoot_v2.0的Hex文件到目標(biāo)板中。

3. 拔除pickit3燒錄器

4. 將目標(biāo)板與PC的接入同一局域網(wǎng),并設(shè)置PC的IP地址和目標(biāo)板的IP地址為同一網(wǎng)域,打開PhnLoader_v2.0用戶界面,選擇IP, 端口,和通信協(xié)議。

5. 點擊PhnLoader_v2.0用戶界面上的“.."按鈕加載需要燒錄的應(yīng)用程序Hex文件 (注意:由于PhnBoot_v2.0占用了程序存儲器頭部0x4C00程序字,所以應(yīng)用程序編譯需要設(shè)置Code offset為0x4C00)。

6. 重啟目標(biāo)板,接著立刻在PhnLoader_v2.0界面上點擊Download按鈕。如果超時未點擊Download按鈕,目標(biāo)板會自動跳轉(zhuǎn)到上次燒錄的應(yīng)用程序中去。

7. 燒錄完畢,再次重啟目標(biāo)板, 2秒后目標(biāo)板開始正常運行應(yīng)用程序。

之后每次更新應(yīng)用程序,只需重復(fù)步驟 4 ~ 7 就可以了。

主要特性

本PIC ethernet bootloader有以下主要特性

1. 使用了Microchip免費的TCP/IP Stack,采用TCP協(xié)議。

2. C語言寫的,MCC18 編譯。

3. 非常容易移植。

4. 支持FLASH燒寫, 快速,占用空間小。

5. 不支持EEPROM燒寫。

6. 支持CONFIG BITS/IDLOC 燒寫。

責(zé)任編輯:何妍 來源: 博客園
相關(guān)推薦

2020-06-17 21:39:11

HTTP協(xié)議服務(wù)器

2010-06-13 15:16:02

2020-12-03 08:37:38

TCPIPARP協(xié)議

2013-08-01 10:01:02

網(wǎng)絡(luò)協(xié)議TCP協(xié)議UDP協(xié)議

2019-09-30 09:28:26

LinuxTCPIP

2010-06-19 13:32:36

TCP IP協(xié)議棧

2011-11-08 16:32:24

LinuxFreeBSDTCP

2010-06-19 14:10:35

TCP IP協(xié)議棧

2014-11-21 09:16:23

TCPIP

2014-06-19 14:48:03

TCP

2011-08-19 15:32:06

2010-06-12 15:54:09

TCP IP協(xié)議

2010-06-18 14:37:20

TCP IP協(xié)議

2010-09-08 15:11:36

TCP IP協(xié)議棧

2010-06-08 13:32:19

TCP IP協(xié)議基礎(chǔ)

2010-06-08 14:23:47

TCP IP協(xié)議概念

2018-12-03 05:54:48

Wireshark網(wǎng)絡(luò)協(xié)議TCP

2012-11-16 15:25:22

Outlook 201

2010-06-08 13:50:40

TCP IP協(xié)議族

2010-09-08 15:34:27

TCP IP協(xié)議棧
點贊
收藏

51CTO技術(shù)棧公眾號