CANopen 塊傳輸通訊詳解

2021-08-03 03:37:00 字數 4439 閱讀 7544

這篇文章主要是記錄canopen 塊傳輸協議的基本思路,具體**各位可以根據思路跟進原始碼閱讀,這裡只貼出主要內容**~

目錄

1.塊上傳詳解(讀取)

1).主節點:傳送讀取資料初始化

2).從節點:伺服器端響應」需要讀取的總資料報位元組數」 

3).主節點:收到響應後,傳送命令,表示可以開始傳輸了

4).從節點:開始迴圈向主節點傳送資料報

5).主節點:告訴從節點,我收到了多少條包!

6).從節點:告訴主節點,已經傳送完畢

7).主節點:告訴從節點,我也接收完畢了,整個傳輸完成!

1).主節點:告訴從節點我要寫入多少個位元組數

2).從節點:我準備好了,可以寫入資料

3).主節點:收到響應後,開始逐條傳送資料,無需響應

4).從節點:告訴主節點我收到了多少條

5).主節點:告訴從節點,寫入完畢!

6).從節點:告訴主節點,我知道寫入完畢了

這裡以圖2為例子, 進行說明

假設主節點為01,待讀取節點為0x1b

讀取的資料是

uns8

bbbcccddd111222333444555666777888999aaa\0

";

傳送:

a0 07 20 01 10 00 00 00

data[0] = (5 << 5) | sdo_bcs_initiate_upload_request;

data[1] = index & 0xff;        /* lsb */

data[2] = (index >> 8) & 0xff; /* msb */

data[3] = subindex;

data[4] = sdo_block_size;

for (i = 5 ; i < 8 ; i++)

data[i] = 0;

接收:

c2  07 20 01 27 00 00 00

data[0] = (6 << 5) | (1 << 1) | sdo_bss_initiate_upload_response;

data[1] = index & 0xff;        /* lsb */

data[2] = (index >> 8) & 0xff; /* msb */

data[3] = subindex;

data[4] = (uns8) nbbytes;

data[5] = (uns8) (nbbytes >> 8);

data[6] = (uns8) (nbbytes >> 16);

data[7] = (uns8) (nbbytes >> 24);

傳送:

a3 00 00 00  00 00 00 00

data[0] = (5 << 5) | sdo_bcs_start_upload;

for (i = 1 ; i < 8 ; i++)

data[i] = 0;

接收:

01 62 62 62 63 63 63 64

02 64 64 31 31 31 32 32

03 32 33 33 33 34 34 34

04 35 35 35 36 36 36 37

05 37 37 38 38 38 39 39

86 39 41 41 41 00 00 00

data[0] = seqno;

err = linetosdo(d, line, 7, data + 1);

傳送:

a2 06 10 00  00 00 00 00 

data[0] = (5 << 5) | sdo_bcs_upload_response;

data[1] = d->transfers[line].seqno;

data[2] = sdo_block_size;

data[3] = data[4] = data[5] = data[6] = data[7] = 0;

接收:

cd 00 00 00 00 00 00 00

data[0] = (6 << 5) | ((d->transfers[line].endfield) <

for (i = 1 ; i < 8 ; i++)

data[i] = 0;

傳送:

圖3這裡以圖3為例子, 進行說明

假設主節點為01,待寫入節點為0x1b

假如待寫入的資料是

uuns8 write_net_block_buf =  "

0123456789aaabbbcccddd\0

";

傳送:

c2 07 20 01 18 00 00 00

buf[0] = (6 << 5) | (1 << 1 );   /* ccs = 6 , cc = 0 , s = 1 , cs = 0 */

buf[1] = index & 0xff;        /* lsb */

buf[2] = (index >> 8) & 0xff; /* msb */

buf[3] = subindex;

for (i = 0 ; i < 4 ; i++)

buf[i+4] = (uns8)((count >> (i<<3))); /* i*8 */

接收:

a0 07 20 01 10 00 00 00

data[0] = (5 << 5) | sdo_bss_initiate_download_response;

data[1] = (uns8) index;        /* lsb */

data[2] = (uns8) (index >> 8); /* msb */

data[3] = subindex;

data[4] = sdo_block_size;

data[5] = data[6] = data[7] = 0;

傳送:

01 30 31 32 33 34 35 36

02 37 38 39 61 61 61 62

03 62 62 63 63 63 64 65

84 64 00 00 00 00 00 00

當實際傳送位元組大於7個位元組時:

data[0] = seqno;

err = linetosdo(d, line, 7, data + 1);

剩餘的小於7個位元組的傳送時:

data[0] = 0x80 | seqno;

err = linetosdo(d, line, nbbytes, data + 1); //實際的剩餘位元組

for (i = nbbytes + 1 ; i < 8 ; i++) //多餘的空間填0

data[i] = 0;

接收:

a2 04 10 00 00 00 00 00

data[0] = (5 << 5) | sdo_bss_download_response;

data[1] = d->transfers[line].seqno;

data[2] = sdo_block_size;

data[3] = data[4] = data[5] = data[6] = data[7] = 0;

傳送:

d1 00 00 00  00 00 00 00

data[0] = (6 << 5) | ((d->transfers[line].endfield) << 2) | sdo_bcs_end_download_request;

for (i = 1 ; i < 8 ; i++)

data[i] = 0;

將傳輸結構體裡面的資料拷貝到資料字典裡,並復位sdo傳輸!

接收:

a1 00 00 00 00 00 00 00

data[0] = (5 << 5) | sdo_bss_end_download_response;

for (i = 1 ; i < 8 ; i++)

data[i] = 0;

CanOpen通訊中SDO的使用問題

引數txsdo rxsdo 601 581這些引數都是相對於哪邊來講的。txsdo和rxsdo都是相對於產生sdo報文的節點來講的,比如主節點要寫資料到從節點,它發出rxsdo 600 serverid rx表示要接收資料的意思,從節點發出txsdo 580 clientid tx表示要發出資料的意...

串列埠通訊 傳輸速率和傳輸距離

1.波特率 在序列通訊中,用 波特率 來描述資料的傳輸速率。所謂波特率,即每秒鐘傳送的二進位制位數,其單位為bps bits per second 它是衡量序列資料速度快慢的重要指標。有時也用 位週期 來表示傳輸速率,位週期是波特率的倒數。國際上規定了乙個標準波特率系列 110 300 600 12...

Ymodem傳輸詳解

ymodem簡介 ymodem協議是由xmodem協議演變而來的,每包資料可以達到1024位元組,是乙個非常高效的檔案傳輸協議。ymodem是一種錯誤糾正協議。使用較大資料塊的調製解調採用這種協議,以獲得更高的工作效率。採用ymodem協議的數據機以1024位元組數的塊傳送資料。成功接收的不會被確認...