arduino - 不能从 C 中断 Arduino Uno 的引导加载程序
问题描述
我正在尝试让 Arduino 进入编程模式。我想检查闪存以查看我的软件是否已安装,然后根据需要上传几个二进制文件之一。为了测试,我有一个简单的草图,它在循环中什么都不做,但在设置时通过串行端口发送“常规模式”。
切换 DTR/RTS 确实会重置 Arduino,但发送同步请求不会执行任何操作,并且引导加载程序超时并将控制权传递给草图。
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/io.h>
#include <sys/ioctl.h>
#include <termios.h>
int main()
{
static const uint8_t bSyncString [] = {0x30, 0x20}; // {CMD_STK_GET_SYNC, SYNC_CRC_EOP};
uint8_t bBuffer [256];
unsigned int ctl;
struct termios tty;
int iFd = open ("/dev/ttyACM0", O_RDWR | O_NOCTTY);
if (iFd >= 0)
{
// From STK500 spec: 115.2kbps, 8 data bits, 1stop bits, no parity
if (tcgetattr (iFd, &tty) == 0)
{
cfsetospeed(&tty, B115200);
cfsetispeed(&tty, B115200);
tty.c_cflag |= CS8|CSTOPB;
tty.c_cflag &= ~(PARENB|PARODD);
if (tcsetattr(iFd, TCSANOW|TCSADRAIN, &tty) == 0)
printf ("Attributes set\n");
}
if (ioctl (iFd, TIOCMGET, &ctl) >= 0) // Get current line states
{
ctl &= ~(TIOCM_DTR|TIOCM_RTS);
if (ioctl(iFd, TIOCMSET, &ctl) >= 0) // DTR and RTS low
{
usleep (50 * 1000);
ctl |= TIOCM_DTR|TIOCM_RTS;
if (ioctl(iFd, TIOCMSET, &ctl) >= 0) // DTR and RTS high
{
usleep (50 * 1000);
if (write (iFd, bSyncString, 2) == 2)
if (read (iFd, bBuffer, sizeof (bBuffer)) > 0)
printf ("Received %s\n", bBuffer);
}
}
}
close (iFd);
}
}
解决方案
知道了。我获取了 avrdude 的来源,提取了相关的部分,然后将它们切到骨头上,来回粘贴功能直到它起作用。
我的一些串行设置已关闭,并且发送写入之前的延迟太短,因此最小设置如下:
int main()
{
static const uint8_t bSyncString [] = {0x30, 0x20}; // {CMD_STK_GET_SYNC, SYNC_CRC_EOP};
uint8_t bBuffer [256];
unsigned int ctl;
struct termios tty;
int iFd = open ("/dev/ttyACM0", O_RDWR | O_NOCTTY);
if (iFd >= 0)
{
// From STK500 spec: 115.2kbps, 8 data bits, 1stop bits, no parity
if (tcgetattr (iFd, &tty) == 0)
{
tty.c_iflag = IGNBRK;
tty.c_oflag = 0;
tty.c_lflag = 0;
tty.c_cflag = (CS8 | CREAD | CLOCAL);
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 0;
cfsetospeed(&tty, B115200);
cfsetispeed(&tty, B115200);
if (tcsetattr(iFd, TCSANOW, &tty) == 0)
printf ("Attributes set\n");
}
if (ioctl (iFd, TIOCMGET, &ctl) >= 0) // Get current line states
{
ctl &= ~(TIOCM_DTR|TIOCM_RTS);
if (ioctl(iFd, TIOCMSET, &ctl) >= 0) // DTR and RTS low
{
usleep (50 * 1000);
ctl |= TIOCM_DTR|TIOCM_RTS;
if (ioctl(iFd, TIOCMSET, &ctl) >= 0) // DTR and RTS high
usleep (250 * 1000);
}
}
if (write (iFd, bSyncString, 2) == 2)
{
int iRead = read (iFd, bBuffer, sizeof (bBuffer));
if (iRead > 0)
{
printf ("Received %s\n", bBuffer);
for (int i = 0; i < iRead; i++)
printf ("%02x ", bBuffer [i]);
printf ("\n");
}
}
close (iFd);
}
}
推荐阅读
- kotlin - TornadoFX 加载多个 FXML 文件
- sql - ON 子句中的未知列
- javascript - 如何用猫鼬替换文档中的文本?
- struct - SwiftUI - 更改 ForEach 中的结构数据集?
- wordpress - NGinx/wordpress - Letsencrypt 无法创建证书
- amazon-web-services - AWS 保护 accessKeyId 和 secretAccessKey
- regex - 如何断言文本以量角器中的数字结尾
- html - 在图像上放置可点击的小框 - html
- firebase - 第 3 方 cookie 和 Google OAUTH
- sql - T-SQL:三天内两个日期之间的差异百分比