在 python 和 arduino 之间共享枚举
share enum between python and arduino
我在 python 中创建了一个图形用户界面,它允许 arduino 控制的麦克纳姆轮车四处移动。
推车有 8 个不同的移动方向,可以左右旋转。命令通过笔记本电脑(w10,python)和 arduino 之间的串行连接发送。
我在 python 中有一个枚举 class 代表不同的移动方向。
我在 arduino 中有一个相应的枚举来解释来自 python 任务的命令。
为两种编码环境共享一个公共枚举定义的简单方法是什么?
没有。 C/C++ 中的枚举和 python 中的 enum.Enum 是两个截然不同的东西。但是,有一个强大的解决方案。我建议从你的python代码编写C/C++/Arduinoheader。借助 python 强大的内省功能,可以轻松地使用 __dict__
扫描您的 python enum/class 并编写您的 Arduino 代码可以使用的 .h
文件。这就是我生成与相关 python 项目中的枚举和常量相匹配的 Verilog 和 SystemVerilog header 的方式。 运行 python 应用程序生成一个新的 header 文件,始终保持同步。
编辑:一个更明确的例子
我已经为 FPGA-based 微处理器构建了一个汇编器。汇编程序在 python 中,而处理器在 Verilog 中编程。所以我创建了一个 Verilog header 文件,如下所示:
# Compute the 'after' content.
content = '// opcodes.vh\n'
content += '`ifndef _opcodes_vh\n'
content += '`define _opcodes_vh\n'
content += '// DO NOT EDIT -- FILE GENERATED BY ASSEMBLER\n'
content += '// ------------------------------------\n'
content += '// OPCODES\n'
content += '// ------------------------------------\n'
A = Arch
for i in A.__dict__:
if i.startswith('OPC_'):
o = i.replace('OPC_', 'OPCODE_')
s = '`define ' + o
while len(s) < 40:
s = s + ' '
hexval = str(hex(A.__dict__[i])).replace('0x', '')
decval = str(A.__dict__[i])
s = s + "7'h" + hexval + '\t\t// ' + str(decval) + '\n'
content += s
content += '// END OF GENERATED FILE.\n'
content += '`endif'
# Write to very specific location for Vivado to see it.
file = open(self.opcodes_filename, 'w', encoding='utf-8')
file.write(content)
file.close()
最终输出如下所示:
// opcodes.vh
`ifndef _opcodes_vh
`define _opcodes_vh
// DO NOT EDIT -- FILE GENERATED BY ASSEMBLER
// ------------------------------------
// OPCODES
// ------------------------------------
`define OPCODE_LD_GPR_EXPR 7'h0 // 0
`define OPCODE_LD_GPR_GPTR 7'h1 // 1
`define OPCODE_SV_EXPR_GPR 7'h2 // 2
...
`define OPCODE_IO_T 7'h4a // 74
`define OPCODE_TX_T 7'h4b // 75
// END OF GENERATED FILE.
`endif
正如@TomServo 所说,让您的 Python 代码编写 Arduino header。这是使用 aenum 3.0
1 或 Python 3.10 2:
的示例
from aenum import Enum # or "from enum import Enum"
class CHeader(Enum):
def __init_subclass__(cls, **kwds):
# write Enums to C header file
cls_name = cls.__name__
header_path = getattr(cls, '_%s__header' % cls_name)
with open(header_path, 'w') as fh:
fh.write('initial header stuff here\n')
for enum in cls:
fh.write('#define %s %r\n' % (enum.name, enum.value))
class Arduino(CHeader):
#
_order_ = 'ONE TWO' # only if using Python 2
#
__header = './arduino.h'
#
ONE = 1
TWO = 2
这将导致:
initial header stuff here
#define ONE 1
#define TWO 2
1 披露:我是 Python stdlib Enum
, the enum34
backport, and the Advanced Enumeration (aenum
) 库的作者。
2 在 aenum 3.0 和 Python 3.10 中 __init_subclass__
将在 添加枚举成员后被调用到枚举 class(在以前的版本中 __init_subclass__
在 成员被添加之前被调用 )。
我在 python 中创建了一个图形用户界面,它允许 arduino 控制的麦克纳姆轮车四处移动。
推车有 8 个不同的移动方向,可以左右旋转。命令通过笔记本电脑(w10,python)和 arduino 之间的串行连接发送。
我在 python 中有一个枚举 class 代表不同的移动方向。
我在 arduino 中有一个相应的枚举来解释来自 python 任务的命令。
为两种编码环境共享一个公共枚举定义的简单方法是什么?
没有。 C/C++ 中的枚举和 python 中的 enum.Enum 是两个截然不同的东西。但是,有一个强大的解决方案。我建议从你的python代码编写C/C++/Arduinoheader。借助 python 强大的内省功能,可以轻松地使用 __dict__
扫描您的 python enum/class 并编写您的 Arduino 代码可以使用的 .h
文件。这就是我生成与相关 python 项目中的枚举和常量相匹配的 Verilog 和 SystemVerilog header 的方式。 运行 python 应用程序生成一个新的 header 文件,始终保持同步。
编辑:一个更明确的例子
我已经为 FPGA-based 微处理器构建了一个汇编器。汇编程序在 python 中,而处理器在 Verilog 中编程。所以我创建了一个 Verilog header 文件,如下所示:
# Compute the 'after' content.
content = '// opcodes.vh\n'
content += '`ifndef _opcodes_vh\n'
content += '`define _opcodes_vh\n'
content += '// DO NOT EDIT -- FILE GENERATED BY ASSEMBLER\n'
content += '// ------------------------------------\n'
content += '// OPCODES\n'
content += '// ------------------------------------\n'
A = Arch
for i in A.__dict__:
if i.startswith('OPC_'):
o = i.replace('OPC_', 'OPCODE_')
s = '`define ' + o
while len(s) < 40:
s = s + ' '
hexval = str(hex(A.__dict__[i])).replace('0x', '')
decval = str(A.__dict__[i])
s = s + "7'h" + hexval + '\t\t// ' + str(decval) + '\n'
content += s
content += '// END OF GENERATED FILE.\n'
content += '`endif'
# Write to very specific location for Vivado to see it.
file = open(self.opcodes_filename, 'w', encoding='utf-8')
file.write(content)
file.close()
最终输出如下所示:
// opcodes.vh
`ifndef _opcodes_vh
`define _opcodes_vh
// DO NOT EDIT -- FILE GENERATED BY ASSEMBLER
// ------------------------------------
// OPCODES
// ------------------------------------
`define OPCODE_LD_GPR_EXPR 7'h0 // 0
`define OPCODE_LD_GPR_GPTR 7'h1 // 1
`define OPCODE_SV_EXPR_GPR 7'h2 // 2
...
`define OPCODE_IO_T 7'h4a // 74
`define OPCODE_TX_T 7'h4b // 75
// END OF GENERATED FILE.
`endif
正如@TomServo 所说,让您的 Python 代码编写 Arduino header。这是使用 aenum 3.0
1 或 Python 3.10 2:
from aenum import Enum # or "from enum import Enum"
class CHeader(Enum):
def __init_subclass__(cls, **kwds):
# write Enums to C header file
cls_name = cls.__name__
header_path = getattr(cls, '_%s__header' % cls_name)
with open(header_path, 'w') as fh:
fh.write('initial header stuff here\n')
for enum in cls:
fh.write('#define %s %r\n' % (enum.name, enum.value))
class Arduino(CHeader):
#
_order_ = 'ONE TWO' # only if using Python 2
#
__header = './arduino.h'
#
ONE = 1
TWO = 2
这将导致:
initial header stuff here
#define ONE 1
#define TWO 2
1 披露:我是 Python stdlib Enum
, the enum34
backport, and the Advanced Enumeration (aenum
) 库的作者。
2 在 aenum 3.0 和 Python 3.10 中 __init_subclass__
将在 添加枚举成员后被调用到枚举 class(在以前的版本中 __init_subclass__
在 成员被添加之前被调用 )。