【问题标题】:Sending hex via UART from raspberry pi通过 UART 从树莓派发送十六进制
【发布时间】:2017-04-28 01:07:37
【问题描述】:

我有一个 NRF52 芯片连接到我的树莓派。我想通过 UART 将 hex 文件从我的树莓派发送到 NRF,这样我就可以制作一个甜蜜的引导加载程序。我正在编写一个 python 脚本,它逐行读取 hex 文件并将其发送过来。我现在的问题是:020000040000FA 之类的行作为 0x3A、0x30、0x32 等发送。我不想发送 ASCII 我想发送原始数据。所以 0x02、0x00 等。我想本质上是 0x2 而不是 0x30, 0x32 但不知道如何... 任何人都可以提供帮助或提供一些想法吗? 我的 python 技能远低于标准...我尝试添加 line[1]+line[2] 并将其编码为十六进制,但它只给出 3032...这是我现在拥有的代码。任何想法或帮助都会很棒。

干杯,

埃里克

 1 #! /usr/bin/python
 2 import binascii
 3 import time
 4 import serial
 5 import codecs
 6
 7 PORT = '/dev/ttyUSB0'
 8 BAUD_RATE = 9600
 9
 10 print 'opening serial port'
 11 time.sleep(1)
 12 myshit = []
 13 ser = serial.Serial(PORT, BAUD_RATE)
 14 i = 1
 15 with open("blinkybootloader.hex", "rb") as file:
 16         for line in file:
 18                 for l in line:
 19                         print line[i],
 20
 21                         i+=1
 22                         time.sleep(.5)
 23                 print line
 24                 time.sleep(.1)
 25                 ser.write(myshit)   

~

【问题讨论】:

    标签: python uart


    【解决方案1】:

    我不确定我是否正确理解了您的问题。但是您似乎想要获取每一行文本 :XXxxXXxxxXX... 并将每行第一个字符之后的所有字符解释为十六进制字符对,然后将它们转换为字符串然后您可以通过串行端口将字节发送到您的 Raspberry Pi。

    在这种情况下,我会使用正则表达式包来“编译”以下正则表达式:

    import re
    chunk = re.compile('..')
    # ... chunk.findall(x) returns a sequence of x broken into 2-character chunks
    

    然后在您的示例中的第 16 行之后,我将执行以下操作:

    for line in file:
        data = b''.join(chr(int(x, 16)) for x in chunk.findall(line[1:])])
        print data
        ser.write(data)
        time.sleep(0.1)
    

    注意将行的切片分块成数字对的技巧,然后使用 int() 函数的额外(可选)base= 参数将它们从文本转换为整数,并使用生成的整数作为内置 chr()(转换为字符)函数的参数。

    此连接的 b'' 文字语法是指定这是一个 byte 字符串。这在 Python 2.7 中并不是特别重要(在 Python 2.7 之前甚至不支持)。对于旧版本的 Python,您可以只使用普通的旧字符串。但在 Python 3.x 中,您必须使用字节字符串或 bytearray 对象,因为 Python 3 的“字符串”是 Unicode 并且必须显式编码和解码。

    【讨论】:

    • 我通常不会使用正则表达式来“分块”一个序列;但这是迄今为止将字符串分块成固定大小的小子字符串的最紧凑的语法方式。
    • 嗨,吉姆,我想我没有解释清楚,我的错。我仍然认为你能够回答我的问题。我回家后会试试这个,但需要额外说明。十六进制文件的布局将是这样的:020000040000FA; : = intel 格式 0x02 = 记录中的数据字节数 0x0000 = 存储数据的地址 0x04 = 记录类型 0x0000 = 数据 0xFA = 校验和。我想在对象中组合两个字符串,然后发送该字节,而不是分别发送 0 和 2,我想加入它们并发送 0x02。
    • 如果前两个十六进制数字(半字节)是长度,接下来的四个是地址,其余是数据,那么我的代码可能会围绕行分解进行调整,例如 lgth, addr, data = line[1:2], line[3:8], line[9:] .. . 然后使用变量名lgth(不与len() 内置函数冲突)、addrdata。 (这假设我们也跳过了每行前缀的文字 :)。
    • 嗨,吉姆。上面的代码产生了预期的结果。线分解不是超级必要的,因为这只是一个测试。我正在开发一个无线引导加载程序。第一步是让它在串行上工作,然后移动到空中。我只是希望能够从 hex 文件中发送一行,然后让我的 mcu 将其拾取并计算校验和等。我真的不想将数据从 ASCII 转换为原始数据。非常感谢你的帮助! (:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-15
    • 1970-01-01
    • 2018-12-23
    相关资源
    最近更新 更多