我正在使用文件描述符和posix/unix read()函数从C++中的串口读取字节.在这个例子中,我从串口读取1个字节(为了清楚起见,省略了波特率设置和类似内容):
#include <termios.h>
#include <fcntl.h>
#include <unistd.h>
int main(void)
{
int fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY);
char buf[1];
int bytesRead = read(fd, buf, 1);
close(fd);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果连接到/ dev/ttyS0的设备未发送任何信息,程序将挂起.如何设置超时?
我试过像这样设置一个时间:
struct termios options;
tcgetattr(fd, &options);
options.c_cc[VMIN] = 0;
options.c_cc[VTIME] = 10;
tcsetattr(fd, TCSANOW, &options);
Run Code Online (Sandbox Code Playgroud)
我认为它应该给1秒超时,但它没有任何区别.我想我误解了VMIN和VTIME.什么是VMIN和VTIME用于?
然后我搜索了网络,发现有人在谈论select()函数.这是解决方案,如果是这样,如何将其应用于上面的程序以使1秒超时?
任何帮助表示赞赏.提前致谢 :-)
我从德州仪器购买了Tiva C系列LaunchPad TM4C123G评估套件.该套件包含一个带有ARM Cortex M4F微控制器的小型PCB.现在我想开始为这个微控制器编写软件.我习惯使用Windows上的AVR Studio对AVR 8位微控制器进行编程.我听说在Linux上编写基于ARM的微控制器很容易,而且由于Linux是我的主要平台,我想要一个简单的IDE,它或多或少会像我以前从AVR那样工作.
几天来,我一直在寻找一个好的IDE和工具来完成这项工作.令我惊讶的是,只有少数将在Linux上运行,没有一个是开源或免费软件.这真的可以吗?我不想花几百美元来尝试一些Cortex M4F的编程.我现在也不想学习一个IDE,然后在我发现它不够好或太贵的时候再学习另一个IDE.我已经习惯了Linux和开源的做事方式,我很震惊,似乎没有人在Linux上使用开源工具进行任何严肃的嵌入式ARM编程.如果我错了,请纠正我.
我没有计划在Cortex M4F上运行Linux - 我只是想像普通的微控制器一样编程.
德州仪器(TI)建议在评估套件的封底上使用以下工具链之一:
我也从code_red推荐了Red Studio.
既不是开源的也不是免费的,都有局限性.在我看来,只有Code Composer Studio和Red Studio兼容Linux.
我偶然发现了另一种产品Rowley CrossWorks,它也兼容Linux,但仍然非常商业化和昂贵.
没有开源替代品真的是真的吗?大多数产品似乎都使用Eclipse和GCC,没有这些商业软件包应该可以做到,对吧?我找不到任何教程或指南,解释如何为嵌入式ARM编程设置它.另外,我需要知道如何在编译后对器件进行编程.
我真的很想早点开始.任何建议和想法都非常感激:-)
假设我有一个A类和一个从A派生的B类.现在,我想使用dynamic_cast将const A*(称为"a")强制转换为B*(见下文).如果"a"确实是B*,那么我的结果对象指针应该没问题.如果"a"不是B*,那么我将得到NULL.
const A* a = new B();
const B* b = dynamic_cast<const B*>(a);
Run Code Online (Sandbox Code Playgroud)
出于某种原因,dynamic_cast操作会导致SEGFAULT.如果"a"不是NULL,怎么会发生?我想如果有任何转换问题,dynamic_cast会给我一个NULL指针,而不是SEGFAULT.如果我试图访问"b"并且动态转换不成功,我应该只获得一个SEGFAULT,对吧?我还没有尝试过访问"b".
那么,这怎么可能发生呢?在上面的代码中有什么可以导致dynamic_cast到SEGFAULT,我不知道吗?
提前致谢 :-)
编辑:通过GDB运行我的实际程序给出了这个输出:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) where
#0 0x0000000000000000 in ?? ()
#1 0x00007ffff6c0e612 in __cxxabiv1::__dynamic_cast (src_ptr=<optimized out>,
src_type=0x4fa6b0, dst_type=0x516bb0, src2dst=0)
at /var/tmp/portage/sys-devel/gcc-4.6.3/work/gcc-4.6.3/libstdc++-v3/libsupc++/dyncast.cc:61
Run Code Online (Sandbox Code Playgroud)
输出中的下一行只是指向我的代码中的行,我在那里进行动态转换.
以下C++代码在编译时给出了这些错误:
covariant.cpp:32:22: error: invalid covariant return type for ‘virtual Q<B> C::test()’
covariant.cpp:22:22: error: overriding ‘virtual Q<A> B::test()’
Run Code Online (Sandbox Code Playgroud)
我不想行更改virtual Q<B> test() {}到virtual Q<A> test() {},虽然它移除编译错误.有没有其他方法可以解决这个问题?
template <class T>
class Q
{
public:
Q() {}
virtual ~Q() {}
};
class A
{
public:
A() {}
virtual ~A() {}
};
class B
{
public:
B() {}
virtual ~B() {}
virtual Q<A> test() = 0;
};
class C : public B
{
public:
C() {}
virtual ~C() {}
virtual Q<B> …Run Code Online (Sandbox Code Playgroud) 我正在为标准 PC 串行端口开发“高级”C++ 接口。当我打开端口时,我想清除输入和输出缓冲区,以便不接收或发送以前使用该端口的数据。为此,我使用 tcflush 函数。然而,它不起作用。怎么可能?我的“端口开放”代码如下所示。是的,我使用 C++ 异常,但没有抛出任何异常。这表明 tcflush 返回 0 但它不会清除缓冲区。
我清除输入缓冲区的唯一方法是从中读取字节,直到没有剩余字节为止。这通常需要几秒钟,我不认为这是一个解决方案。
提前致谢 :-)
fd = ::open(port.c_str(), O_RDWR | O_NOCTTY);
if (fd < 0)
{
throw OpenPortException(port);
return;
}
// Get options
tcgetattr(fd, &options);
// Set default baud rate 9600, 1 stop bit, 8 bit data length, no parity
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
// Default timeout (1000 ms)
options.c_cc[VMIN] = 0;
options.c_cc[VTIME] = 10;
// Additional options
options.c_cflag |= (CLOCAL | …Run Code Online (Sandbox Code Playgroud)