tools: add uart download script
Signed-off-by: liangkangnan <liangkangnan@163.com>pull/1/head
parent
1c51a4e515
commit
ab185de7f5
|
@ -0,0 +1,215 @@
|
|||
'''
|
||||
Copyright 2020 Blue Liang, liangkangnan@163.com
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
'''
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import serial
|
||||
#import serial.tools.list_ports
|
||||
|
||||
'''
|
||||
通过串口下载固件到FPGA开发板,FPGA收到数据后将数据烧写到ROM(Flash)。
|
||||
有两种包类型:包0和其他包。包0用来传输文件名和文件大小,其他包用来传输文件内容。
|
||||
每个包的大小固定为131个字节(1字节包号+128字节数据+2字节CRC)。
|
||||
'''
|
||||
|
||||
# 包0格式
|
||||
# number:0,包序号
|
||||
# data[0] ~ data[59]:文件名
|
||||
# data[60] ~ data[63]:文件大小(字节),其中data[60]为MSB
|
||||
# crc[0]:crc低字节,crc[1]:crc高字节
|
||||
'''
|
||||
0 1 2 ... 128 129 130
|
||||
|-------------------------------------------------------------------|
|
||||
| number | data[0] | data[1] | ... | data[127] | crc[0] | crc[1] |
|
||||
|-------------------------------------------------------------------|
|
||||
'''
|
||||
|
||||
# 包1 ~ n格式
|
||||
# number:包序号
|
||||
# data[0]~data[127]:文件内容
|
||||
# crc[0]:crc低字节,crc[1]:crc高字节
|
||||
'''
|
||||
0 1 2 ... 128 129 130
|
||||
|-------------------------------------------------------------------|
|
||||
| number | data[0] | data[1] | ... | data[127] | crc[0] | crc[1] |
|
||||
|-------------------------------------------------------------------|
|
||||
'''
|
||||
|
||||
|
||||
ACK = bytes([0x6])
|
||||
FIRST_PACKET_LEN = 131
|
||||
FILE_NAME_INDEX = 1
|
||||
FILE_SIZE_INDEX = 61
|
||||
FIRST_PACKET_CRC0_INDEX = 129
|
||||
FIRST_PACKET_CRC1_INDEX = 130
|
||||
OTHER_PACKET_LEN = 131
|
||||
|
||||
|
||||
serial_com = serial.Serial()
|
||||
|
||||
|
||||
# 串口初始化
|
||||
# 串口参数:115200, 8 N 1
|
||||
def serial_init():
|
||||
serial_com.port = sys.argv[1]
|
||||
serial_com.baudrate = 115200
|
||||
serial_com.bytesize = serial.EIGHTBITS
|
||||
serial_com.parity = serial.PARITY_NONE
|
||||
serial_com.stopbits = serial.STOPBITS_ONE
|
||||
serial_com.xonxoff = False
|
||||
serial_com.rtscts = False
|
||||
serial_com.dsrdtr = False
|
||||
|
||||
if serial_com.is_open == False:
|
||||
serial_com.open()
|
||||
if serial_com.is_open:
|
||||
return 0
|
||||
else:
|
||||
return -1
|
||||
|
||||
def serial_deinit():
|
||||
if serial_com.is_open == True:
|
||||
serial_com.close()
|
||||
|
||||
# 串口写数据
|
||||
def serial_write(b):
|
||||
if serial_com.is_open == True:
|
||||
serial_com.write(b)
|
||||
return len(b)
|
||||
else:
|
||||
return 0
|
||||
|
||||
# 串口读数据
|
||||
def serial_read(length, timeout):
|
||||
if (timeout > 0):
|
||||
serial_com.timeout = timeout
|
||||
|
||||
if serial_com.is_open == True:
|
||||
data = serial_com.read(length)
|
||||
if len(data) > 0:
|
||||
return data
|
||||
else:
|
||||
return -1
|
||||
else:
|
||||
return -1
|
||||
|
||||
# CRC计算
|
||||
def calc_crc16(data):
|
||||
crc = 0xFFFF
|
||||
for pos in data:
|
||||
crc ^= pos
|
||||
for i in range(8):
|
||||
if ((crc & 1) != 0):
|
||||
crc >>= 1
|
||||
crc ^= 0xA001
|
||||
else:
|
||||
crc >>= 1
|
||||
return crc
|
||||
|
||||
# 主函数
|
||||
def main():
|
||||
if serial_init() == 0:
|
||||
bin_file_size = os.path.getsize(sys.argv[2])
|
||||
print('bin file size: %d bytes' % bin_file_size)
|
||||
bin_file_name = os.path.basename(sys.argv[2])
|
||||
print('bin file name: ' + bin_file_name)
|
||||
print('Total %d packets to be sent' % (int(bin_file_size / 128) + 1))
|
||||
|
||||
############### 第一个包 ###############
|
||||
print('send #0 packet')
|
||||
packet = [0] * FIRST_PACKET_LEN
|
||||
# 1.包号
|
||||
packet[0] = 0
|
||||
i = FILE_NAME_INDEX
|
||||
# 2.文件名
|
||||
for c in bin_file_name:
|
||||
packet[i] = ord(c)
|
||||
i = i + 1
|
||||
# 3.文件大小
|
||||
packet[FILE_SIZE_INDEX] = (bin_file_size >> 24) & 0xff
|
||||
packet[FILE_SIZE_INDEX + 1] = (bin_file_size >> 16) & 0xff
|
||||
packet[FILE_SIZE_INDEX + 2] = (bin_file_size >> 8) & 0xff
|
||||
packet[FILE_SIZE_INDEX + 3] = (bin_file_size >> 0) & 0xff
|
||||
crc = calc_crc16(packet[1:129])
|
||||
# 4.CRC
|
||||
packet[FIRST_PACKET_CRC0_INDEX] = (crc >> 0) & 0xff
|
||||
packet[FIRST_PACKET_CRC1_INDEX] = (crc >> 8) & 0xff
|
||||
|
||||
#print(packet)
|
||||
# 5.发送
|
||||
serial_write(bytes(packet))
|
||||
# 6.读应答
|
||||
ack = serial_read(1, 3)
|
||||
if (ack != ACK):
|
||||
print('packet0 NACK from slave')
|
||||
return
|
||||
|
||||
############### 剩余包 ###############
|
||||
bin_file = open(sys.argv[2], 'rb')
|
||||
data = bin_file.read(bin_file_size)
|
||||
remain_data_len = bin_file_size
|
||||
remain_data_index = 0
|
||||
# 文件有多少个128字节
|
||||
for i in range(int(bin_file_size / 128) + 1):
|
||||
print('send #%d packet' % (i + 1))
|
||||
packet = [0] * OTHER_PACKET_LEN
|
||||
packet[0] = i + 1
|
||||
j = 1
|
||||
k = remain_data_index
|
||||
if (remain_data_len >= 128):
|
||||
for r in range(128):
|
||||
packet[j] = data[k]
|
||||
j = j + 1
|
||||
k = k + 1
|
||||
crc = calc_crc16(packet[1:129])
|
||||
packet[FIRST_PACKET_CRC0_INDEX] = (crc >> 0) & 0xff
|
||||
packet[FIRST_PACKET_CRC1_INDEX] = (crc >> 8) & 0xff
|
||||
serial_write(bytes(packet))
|
||||
ack = serial_read(1, 3)
|
||||
if (ack != ACK):
|
||||
print('NACK1 from slave')
|
||||
return
|
||||
remain_data_len = remain_data_len - 128
|
||||
remain_data_index = remain_data_index + 128
|
||||
else:
|
||||
for r in range(remain_data_len):
|
||||
packet[j] = data[k]
|
||||
j = j + 1
|
||||
k = k + 1
|
||||
crc = calc_crc16(packet[1:129])
|
||||
packet[FIRST_PACKET_CRC0_INDEX] = (crc >> 0) & 0xff
|
||||
packet[FIRST_PACKET_CRC1_INDEX] = (crc >> 8) & 0xff
|
||||
serial_write(bytes(packet))
|
||||
ack = serial_read(1, 3)
|
||||
if (ack != ACK):
|
||||
print('NACK2 from slave')
|
||||
return
|
||||
|
||||
bin_file.close()
|
||||
|
||||
print('Send successfully...')
|
||||
else:
|
||||
print('!!! serial init failed !!!')
|
||||
|
||||
serial_deinit()
|
||||
|
||||
# 程序入口
|
||||
if __name__ == "__main__":
|
||||
if (len(sys.argv) != 3):
|
||||
print('Usage: python ' + sys.argv[0] + ' COMx ' + 'bin_file')
|
||||
else:
|
||||
main()
|
Loading…
Reference in New Issue