通过系留(主机)PC 的串行线路对 Arduino/Atmel328 进行机器编码
Machine coding an Arduino/Atmel328 over a serial line from a tethered (host) PC
我正在尝试为 AVR Atmel 328 芯片编写一个程序,它允许我通过串行线向芯片发送机器代码指令,run/execute 他们在芯片上,并通过读取芯片内存并通过串行线将内容发回来查询结果。这是这个想法的起源:3-instruction Forth by Frank Sergeant.
远程存储和远程获取指令似乎工作正常,但我无法使远程调用指令(XCALL()
函数)工作。 我采用的方法是通过将 16 位地址转换为函数指针将其强制转换为子例程。
下面是 Arduino Nano 上 运行 的代码(在 Arduino IDE 中编译并通过引导加载程序使用 USB 数据线上传)
任何见解将不胜感激! (如果有帮助,我可以添加反汇编代码、我的远程指令等)。
提前致谢!
// Remote serial development platform for machine coding ArduinoNano/ATmel328, AKE, Jun 9, 2020
// global variables
unsigned char byt; // command token from host
unsigned char mem[255]; // memory window under programmatic control
unsigned char dat; // data byte from host
unsigned char adr_lo; // address from host, low byte first
unsigned char adr_hi;
unsigned short adr; // combined 16-bit address
typedef void (*GeneralFunction)(); // template to call memory address (as a subroutine)
void setup() {
Serial.begin(9600); // Turn UART serial protocol ON for comms with host PC
Serial.write(0xFF); // magic number to verify transmission
Serial.write(0xFE);
Serial.write((int) mem); // Informs you of the writeable address space available (LSB, MSB) for tethered memory access
Serial.write((int) mem>>8);
}
char get_byte(void) {
while (!(Serial.available()>0)) { delay(50); }
return Serial.read();
}
short get_adr(void) {
adr_lo=get_byte();
adr_hi=get_byte();
return ( (short)adr_hi<<8 ) | (short)adr_lo;
}
void xstore() { // Instruction 1 = xstore(data,adr_lo,adr_hi). Store byte from host at indicated address in target.
dat=get_byte();
adr=get_adr();
*(char *)adr=dat;
}
void xfetch() { // Instruction 2 = xfetch(adr_lo,adr_hi). Read byte from target memory and return to host.
adr=get_adr();
dat=*(char *)adr;
Serial.write(dat);
}
void xcall() { // Instruction 3 = xcall(adr_lo,adr_hi). Execute subroutine in target memory from indicated address.
// WARNING! User must have stored RET instruction to send control back to serial monitor.
adr=get_adr();
GeneralFunction fGf=adr;
fGf();
}
void loop() {
byt = get_byte(); // user specified instruction token (1,2,3)
if(byt == 0x01 ) { xstore(); }
else if (byt == 0x02) { xfetch(); }
else if (byt == 0x3 ) { xcall(); } // else ignore any other serial inputs
}
你没有告诉我们你芯片的确切名称,但我怀疑你使用的是 ATmega328P。
ATmega328P 无法执行来自RAM 的指令。在执行之前,您需要弄清楚如何将代码写入闪存。您可能想使用 Optiboot 之类的引导加载程序将程序写入闪存,或者您可以研究 Optiboot 以了解其工作原理。请注意,闪光灯的额定循环次数有限 erase/write(通常为 10000)。
此外,您的 C++ 语法有误。要调用一个函数,你总是需要使用括号。所以你会写 fGf()
。而不仅仅是 fGf
.
我正在尝试为 AVR Atmel 328 芯片编写一个程序,它允许我通过串行线向芯片发送机器代码指令,run/execute 他们在芯片上,并通过读取芯片内存并通过串行线将内容发回来查询结果。这是这个想法的起源:3-instruction Forth by Frank Sergeant.
远程存储和远程获取指令似乎工作正常,但我无法使远程调用指令(XCALL()
函数)工作。 我采用的方法是通过将 16 位地址转换为函数指针将其强制转换为子例程。
下面是 Arduino Nano 上 运行 的代码(在 Arduino IDE 中编译并通过引导加载程序使用 USB 数据线上传)
任何见解将不胜感激! (如果有帮助,我可以添加反汇编代码、我的远程指令等)。
提前致谢!
// Remote serial development platform for machine coding ArduinoNano/ATmel328, AKE, Jun 9, 2020
// global variables
unsigned char byt; // command token from host
unsigned char mem[255]; // memory window under programmatic control
unsigned char dat; // data byte from host
unsigned char adr_lo; // address from host, low byte first
unsigned char adr_hi;
unsigned short adr; // combined 16-bit address
typedef void (*GeneralFunction)(); // template to call memory address (as a subroutine)
void setup() {
Serial.begin(9600); // Turn UART serial protocol ON for comms with host PC
Serial.write(0xFF); // magic number to verify transmission
Serial.write(0xFE);
Serial.write((int) mem); // Informs you of the writeable address space available (LSB, MSB) for tethered memory access
Serial.write((int) mem>>8);
}
char get_byte(void) {
while (!(Serial.available()>0)) { delay(50); }
return Serial.read();
}
short get_adr(void) {
adr_lo=get_byte();
adr_hi=get_byte();
return ( (short)adr_hi<<8 ) | (short)adr_lo;
}
void xstore() { // Instruction 1 = xstore(data,adr_lo,adr_hi). Store byte from host at indicated address in target.
dat=get_byte();
adr=get_adr();
*(char *)adr=dat;
}
void xfetch() { // Instruction 2 = xfetch(adr_lo,adr_hi). Read byte from target memory and return to host.
adr=get_adr();
dat=*(char *)adr;
Serial.write(dat);
}
void xcall() { // Instruction 3 = xcall(adr_lo,adr_hi). Execute subroutine in target memory from indicated address.
// WARNING! User must have stored RET instruction to send control back to serial monitor.
adr=get_adr();
GeneralFunction fGf=adr;
fGf();
}
void loop() {
byt = get_byte(); // user specified instruction token (1,2,3)
if(byt == 0x01 ) { xstore(); }
else if (byt == 0x02) { xfetch(); }
else if (byt == 0x3 ) { xcall(); } // else ignore any other serial inputs
}
你没有告诉我们你芯片的确切名称,但我怀疑你使用的是 ATmega328P。
ATmega328P 无法执行来自RAM 的指令。在执行之前,您需要弄清楚如何将代码写入闪存。您可能想使用 Optiboot 之类的引导加载程序将程序写入闪存,或者您可以研究 Optiboot 以了解其工作原理。请注意,闪光灯的额定循环次数有限 erase/write(通常为 10000)。
此外,您的 C++ 语法有误。要调用一个函数,你总是需要使用括号。所以你会写 fGf()
。而不仅仅是 fGf
.