精确(不到1ms)的超时等待

forestwind 2005-11-25 04:36:33
我现在在PC上实现一种协议,但是按照要求,连续从串口接受数据,发现连续4个字符的时间没有收到数据,则认为这是一个数据段。问题是,按照串口的速度,连续4个字符的时间还不到一个毫秒。怎么检测这样的超时呢?会不会造成CPU全部被用来检测CPU时钟?
...全文
380 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
taianmonkey 2005-11-30
  • 打赏
  • 举报
回复
timeSetEvent
AthlonxpX86 2005-11-27
  • 打赏
  • 举报
回复
如果你的软件所在进程被操作系统挂起20ms你想象会发生什么样的后果,你被告诉我你的进程不会被挂起
AthlonxpX86 2005-11-27
  • 打赏
  • 举报
回复
我晕,你们咋想都不想就胡来?Windows串口驱动根本就不支持你这样频繁的读或者检测串口,就算定时器能做到也不行,何况定时器性能不行,微秒级的定时器我做过,但很不稳定,很有可能1个间隔变成20ms,不要要求多任务操作系统能够实时的为你服务,就算DOS也没有这样的,串口是用来传输数据的,根本不能够这样用,你还是老老实实的从数据分析来分包吧,我告诉你你的那种方法还是死了那条心吧,不能能实现,就算实现也不稳定,除非你用单片机而且没有操作系统才好做,多数自称实时的操作系统也不能单保不出问题
ghyd 2005-11-27
  • 打赏
  • 举报
回复
接上,使用
LARGE_INTEGER startcounter,currentcounter,fre;
queryperformanceCounter(startcounter)//可以检索到cpu自上电以来的计数值,
sleep(1000);
queryperformanceCounter(currentcounter),

queryperformancefrequncy(fre)//得到你的cpu的频率,然后

(startcounter.QuadPart-currentcounter.quadpart)/fre.QuadPart
这个结果就是你延时1000毫秒后得到的精确计时。可以精确到微妙、
ghyd 2005-11-27
  • 打赏
  • 举报
回复
严重同意楼上的,在windows下完成这么小的实时操作,几乎不可能。或者需要极大的牺牲cpu的利用率。而且做出来的东西还不一定稳定。
oyljerry 2005-11-26
  • 打赏
  • 举报
回复
精度高点,用多媒体定时器等
DrSmart 2005-11-25
  • 打赏
  • 举报
回复
还可以用性能计数器
raidenzxx 2005-11-25
  • 打赏
  • 举报
回复
你可以在串口接收的每字符间,进行看门狗式的计数,判断每字符间流逝的时钟周期后再作相应操作

当接到一个字符后把时间戳计数器的内容装入,当接收到下一个字符,把start_ticks替换成end_ticks,再从end_ticks减去start_ticks,就得到了两次调用期间流逝的时钟周期
forestwind 2005-11-25
  • 打赏
  • 举报
回复
感动中。我仔细读读,谢谢!
jerry 2005-11-25
  • 打赏
  • 举报
回复
TIMEVAL
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* and microseconds */
};

This structure is used in the select function. It is taken from the BSD file sys/time.h.


jerry 2005-11-25
  • 打赏
  • 举报
回复
已回复。这是MSDN上的有关select的说明:


select
The Windows Sockets select function determines the status of one or more sockets, waiting if necessary, to perform synchronous I/O.

int select (
int nfds,
fd_set FAR * readfds,
fd_set FAR * writefds,
fd_set FAR * exceptfds,
const struct timeval FAR * timeout
);

Parameters
nfds
[in] This parameter is ignored; it is included only for compatibility with Berkeley sockets.
readfds
[in/out] An optional pointer to a set of sockets to be checked for readability.
writefds
[in/out] An optional pointer to a set of sockets to be checked for writability
exceptfds
[in/out] An optional pointer to a set of sockets to be checked for errors.
timeout
[in] The maximum time for select to wait, or NULL for blocking operation.
Remarks
The select function is used to determine the status of one or more sockets. For each socket, the caller can request information on read, write or error status. The set of sockets for which a given status is requested is indicated by an FD_SET structure. The sockets contained within the FD_SET structures must be associated with a single service provider. For the purpose of this restriction, sockets are considered to be from the same service provider if the WSAPROTOCOL_INFO structures describing their protocols have the same providerId value. Upon return, the structures are updated to reflect the subset of these sockets that meet the specified condition. The select function returns the number of sockets meeting the conditions. A set of macros is provided for manipulating an FD_SET structure. These macros are compatible with those used in the Berkeley software, but the underlying representation is completely different.

The parameter readfds identifies the sockets that are to be checked for readability. If the socket is currently in the listen state, it will be marked as readable if an incoming connection request has been received such that an accept is guaranteed to complete without blocking. For other sockets, readability means that queued data is available for reading such that a call to recv, WSARecv, WSARecvFrom, or recvfrom is guaranteed not to block.

For connection-oriented sockets, readability can also indicate that a request to close the socket has been received from the peer. If the virtual circuit was closed gracefully, and all data was received, then a recv will return immediately with zero bytes read. If the virtual circuit was reset, then a recv will complete immediately with an error code such as WSAECONNRESET. The presence of out-of-band data will be checked if the socket option SO_OOBINLINE has been enabled (see setsockopt).

The parameter writefds identifies the sockets that are to be checked for writability. If a socket is processing a connect call (nonblocking), a socket is writable if the connection establishment successfully completes. If the socket is not processing a connect call, writability means a send, sendto, or WSASendto are guaranteed to succeed. However, they can block on a blocking socket if the len parameter exceeds the amount of outgoing system buffer space available. It is not specified how long these guarantees can be assumed to be valid, particularly in a multithreaded environment.

The parameter exceptfds identifies the sockets that are to be checked for the presence of out-of-band data (see section DECnet Out-Of-band data for a discussion of this topic) or any exceptional error conditions.

Important Out-of-band data will only be reported in this way if the option SO_OOBINLINE is FALSE. If a socket is processing a connect call (nonblocking), failure of the connect attempt is indicated in exceptfds (application must then call getsockopt SO_ERROR to determine the error value to describe why the failure occurred). This document does not define which other errors will be included.

Any two of the parameters, readfds, writefds, or exceptfds, can be given as NULL. At least one must be non-NULL, and any non-NULL descriptor set must contain at least one handle to a socket.

Summary: A socket will be identified in a particular set when select returns if:

readfds:

If listen has been called and a connection is pending, accept will succeed
Data is available for reading (includes OOB data if SO_OOBINLINE is enabled)
Connection has been closed/reset/terminated
writefds:

If processing a connect call (nonblocking), connection has succeeded
Data can be sent
exceptfds:

If processing a connect call (nonblocking), connection attempt failed
OOB data is available for reading (only if SO_OOBINLINE is disabled)
Four macros are defined in the header file WINSOCK2.H for manipulating and checking the descriptor sets. The variable FD_SETSIZE determines the maximum number of descriptors in a set. (The default value of FD_SETSIZE is 64, which can be modified by defining FD_SETSIZE to another value before including WINSOCK2.H.) Internally, socket handles in an FD_SET structure are not represented as bit flags as in Berkeley Unix. Their data representation is opaque. Use of these macros will maintain software portability between different socket environments. The macros to manipulate and check FD_SET contents are:

FD_CLR(s, *set)
Removes the descriptor s from set.
FD_ISSET(s, *set)
Nonzero if s is a member of the set. Otherwise, zero.
FD_SET(s, *set)
Adds descriptor s to set.
FD_ZERO(*set)
Initializes the set to the NULL set.
The parameter timeout controls how long the select can take to complete. If timeout is a null pointer, select will block indefinitely until at least one descriptor meets the specified criteria. Otherwise, timeout points to a TIMEVAL structure that specifies the maximum time that select should wait before returning. When select returns, the contents of the TIMEVAL structure are not altered. If TIMEVAL is initialized to {0, 0}, select will return immediately; this is used to "poll" the state of the selected sockets. If select returns immediately, then the select call is considered nonblocking and the standard assumptions for nonblocking calls apply. For example, the blocking hook will not be called, and Windows Sockets will not yield.

Note The select function has no effect on the persistence of socket events registered with WSAAsyncSelect or WSAEventSelect.

Return Values
The select function returns the total number of socket handles that are ready and contained in the FD_SET structures, zero if the time limit expired, or SOCKET_ERROR if an error occurred. If the return value is SOCKET_ERROR, WSAGetLastError can be used to retrieve a specific error code.

Error Codes
WSANOTINITIALISED A successful WSAStartup must occur before using this function.
WSAEFAULT The Windows Sockets implementation was unable to allocate needed resources for its internal operations, or the readfds, writefds, exceptfds, or timeval parameters are not part of the user address space.
WSAENETDOWN The network subsystem has failed.
WSAEINVAL The timeout value is not valid, or all three descriptor parameters were NULL.
WSAEINTR A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.
WSAEINPROGRESS A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.
WSAENOTSOCK One of the descriptor sets contains an entry that is not a socket.


QuickInfo
Windows NT: Yes
Windows: Yes
Windows CE: Use version 1.0 and later.
Header: Declared in winsock2.h.
Import Library: Link with ws2_32.lib.

See Also
accept, connect, recv, recvfrom, send, WSAAsyncSelect, WSAEventSelect


forestwind 2005-11-25
  • 打赏
  • 举报
回复
自己up
forestwind 2005-11-25
  • 打赏
  • 举报
回复
多谢。但我不知道怎样设计才能不让CPU一直查询这个、导致机器死到哪里呢?
iriscat 2005-11-25
  • 打赏
  • 举报
回复
如果还需要更高的精度

据我所知就需要奔腾处理器的高精度计时指令了,能精确到纳秒

RDTSC 和它的相关指令,你需要使用内连汇编
forestwind 2005-11-25
  • 打赏
  • 举报
回复
多谢iriscat(猫小) ,“多媒体定时器函数DWORD timeGetTime(void),该函数定时精 度为ms级,返回从Windows启动开始经过的毫秒数。”可是我这个超时总共也不到1ms呀
iriscat 2005-11-25
  • 打赏
  • 举报
回复
用多媒体定时器

timeGetTime

这个精度很高,运用得当不耗费很多CPU资源
forestwind 2005-11-25
  • 打赏
  • 举报
回复
这个select可能正是我需要的,可是我怎么也搜索不到一点点55555555555
forestwind 2005-11-25
  • 打赏
  • 举报
回复
严重感谢krh2001(边城浪子)!什么select函数?愿闻其详
forestwind 2005-11-25
  • 打赏
  • 举报
回复
严重感谢raidenzxx(小强),但我怎样做才能不使CPU被大部分浪费在检测时钟计数器上面呢?我的程序只是一个小库,这台机器同时还要处理大量别的工作。
jerry 2005-11-25
  • 打赏
  • 举报
回复
用select函数可以执行以微秒为单位的等待,就是不知道是否准确
加载更多回复(1)

2,640

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧