maple_wasp
驱动牛犊
驱动牛犊
  • 注册日期2003-10-02
  • 最后登录2009-03-09
  • 粉丝0
  • 关注0
  • 积分100分
  • 威望22点
  • 贡献值0点
  • 好评度22点
  • 原创分0分
  • 专家分0分
阅读:1991回复:6

怪哉!

楼主#
更多 发布于:2004-06-24 11:04
各位大侠好:
偶遇到一个特奇怪的问题:
在父任务中创建子任务用于读串口1的数据,子任务的优先级高于父任务。在大部分的情况下,两个任务均工作正常。偶尔在目标机启动后,程序也正常运行,但是子任务一直处于pend状态,但串口中是有数据的(此时把接到目标机串口1的串口接头拔下接到主机上,用超级终端观察,是有数据的)。此后,子任务就一直处于pend状态了。可以确定接收串口数据的程序没有错误,真是奇怪!
问题:既然串口中有数据,且子任务的优先级也高于父任务,为什么子任务会永远不被执行?
xdjm
驱动中牛
驱动中牛
  • 注册日期2001-04-02
  • 最后登录2024-01-25
  • 粉丝0
  • 关注0
  • 积分34分
  • 威望25点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2004-06-25 19:14
是不是多任务调度没有Enabled。
maple_wasp
驱动牛犊
驱动牛犊
  • 注册日期2003-10-02
  • 最后登录2009-03-09
  • 粉丝0
  • 关注0
  • 积分100分
  • 威望22点
  • 贡献值0点
  • 好评度22点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-06-29 22:11
多任务调度已经Enabled
是不是read( )函数会阻塞?
maple_wasp
驱动牛犊
驱动牛犊
  • 注册日期2003-10-02
  • 最后登录2009-03-09
  • 粉丝0
  • 关注0
  • 积分100分
  • 威望22点
  • 贡献值0点
  • 好评度22点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-07-01 12:50
发现在read()函数处pend之后, 此任务一直处于pend状态了,此后也不会参加任何的调度。想请问高手如何解pend,使其能继续正常工作?
maple_wasp
驱动牛犊
驱动牛犊
  • 注册日期2003-10-02
  • 最后登录2009-03-09
  • 粉丝0
  • 关注0
  • 积分100分
  • 威望22点
  • 贡献值0点
  • 好评度22点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-07-01 13:45
后来用select来读四个串口,但是也遇到了同样的问题。
请高手看附件,急需高手们的解答,谢谢先!
附件名称/大小 下载次数 最后更新
2004-07-01_问题描述.doc (32KB)  3
maple_wasp
驱动牛犊
驱动牛犊
  • 注册日期2003-10-02
  • 最后登录2009-03-09
  • 粉丝0
  • 关注0
  • 积分100分
  • 威望22点
  • 贡献值0点
  • 好评度22点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-07-01 14:10
没串上来,重传一遍。
附件名称/大小 下载次数 最后更新
2004-07-01_问题描述.doc (32KB)  0
maple_wasp
驱动牛犊
驱动牛犊
  • 注册日期2003-10-02
  • 最后登录2009-03-09
  • 粉丝0
  • 关注0
  • 积分100分
  • 威望22点
  • 贡献值0点
  • 好评度22点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-07-01 14:23
传不上来,请看下面:
我已经试过了(void)ioctl(fd,FIONREAD,(int)&nBytes);  但是其中的一个串口在任务刚执行时就在read()处pend了。

值得一提的是:这个串口接收的数据是 (ASCII 码 + 以字节表示的字符),其它三个串口接收的都是ASCII字符。

接收ASCII字符的三个串口出现错误的几率要小于剩下的那个串口。

////////////////////////////////////////////////////////
//串口类的打开串口函数:m_hSerial相当于fd.
//此类的其它函数略。
BOOL CSerial::Open(int nPort, int nBaud)
{
char szPort[32];
if(m_hSerial != ERROR)
{
printf("serial %d already opened.\n", nPort);
return FALSE;
}
sprintf(szPort, "/tyCo/%d", nPort - 1);
if((m_hSerial = open(szPort, O_RDWR, 0)) == ERROR)
{
printf("open serial %d error.\n", nPort);
return FALSE;
}

ioctl(m_hSerial, FIOSETOPTIONS, OPT_RAW);

if((ioctl(m_hSerial, FIOBAUDRATE, nBaud)) == ERROR)
{
printf("set serial %d baud error.\n", nPort);
close(m_hSerial);
return FALSE;
}
if((ioctl(m_hSerial, FIORBUFSET, SERIAL_MAX_BUFFER)) == ERROR)
{
printf("set serial %d read buffer size error.\n", nPort);
close(m_hSerial);
return FALSE;
}
if((ioctl(m_hSerial, FIOWBUFSET, SERIAL_MAX_BUFFER)) == ERROR)
{
printf("set serial %d read buffer size error.\n", nPort);
close(m_hSerial);
return FALSE;
}
printf( "Serial %d open success!\n", nPort );
return TRUE;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//主程序;
简单描述:用select来读四个串口中的数据,然后打印出来。
#include <vxWorks.h>
#include <taskLib.h>
#include <selectLib.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.>
#include "Serial.h"
 
#define MAX_FDS 4
typedef unsigned char byte;
CSerial g_Serial1;
CSerial g_Serial2;
CSerial g_Serial3;
CSerial g_Serial4;

/************************************************************************
* selServer - reads data as it becomes available from four different serials  
*
* Opens four serials fds, reading from whichever becomes available.  
*/
 
STATUS selSerials (void)
  {
struct  fd_set readFds;      /* bit mask of fds to read from */
int fds[MAX_FDS];      /* array of fds on which to pend */
    int     width;            /* number of fds on which to pend */
    int     i;               /* index for fd array */
int len = 0;
   byte    buffer[SERIAL_MAX_BUFFER]; /* buffer for data that is read */
int nBytesUnread = 0;
 
    /* open file descriptors */
    if (g_Serial1.Open (1, 19200) == FALSE)
{
return (ERROR);
}
else
{
fds[0] = g_Serial1.m_hSerial;
}

       if (g_Serial2.Open (2, 4800) == FALSE)
{
return (ERROR);
}
else
{
fds[1] = g_Serial2.m_hSerial;
}

if (g_Serial3.Open (3, 4800) == FALSE)
{
return (ERROR);
}
else
{
fds[2] = g_Serial3.m_hSerial;
}

if (g_Serial4.Open (4, 19200) == FALSE)
{
return (ERROR);
}
else
{
fds[3] = g_Serial4.m_hSerial;
}

/* Discards all the bytes currently in both the input and the output       buffers */
for(i = 0; i < 4; i++)
{
ioctl(fds, FIOFLUSH, 0);
}
 
    /* loop forever reading data and servicing clients */
while(true)
     {
/* clear bits in read bit mask */
   FD_ZERO (&readFds);
 
/* initialize read bit mask */
for(i = 0; i < 4; i++)
{
FD_SET (fds, &readFds);
}

/* initialize write bit mask */
FD_SET (fds[0], &writeFds);
width = fds[0];

for(int j = 1; j < MAX_FDS; j++)
{
if(fds[j] > width)
{
width = fds[j];
}
}
     width++;
 
/* pend, waiting for one or more fds to become ready */
     if (select (width, &readFds, NULL, NULL, NULL) == ERROR)
{
perror("The select of serials is ERROR\n");
return (ERROR);
}
 
/* step through array and read from fds that are ready */
  for (i = 0; i < MAX_FDS; i++)
   {
/* check if this fd has data to read */
if (FD_ISSET (fds, &readFds))
{
/* typically read from fd now that it is ready */
memset(buffer, 0, sizeof(buffer));
ioctl (fds, FIONREAD, int (&nBytesUnread));
if(nBytesUnread == 0)
{
continue;
}

len = read (fds, buffer, SERIAL_MAX_BUFFER);
if(ioctl(fds, FIORFLUSH, 0) == ERROR)
{
return ERROR;
}

if(len <= 0)
{
continue;
}

switch(i)
{
case 0:
printf("\n COM1      %d, %s\n", len, buffer);
break;
case 1:
printf("\n COM2      %d, %s\n", len, buffer);
break;
case 2:
printf("\n COM3      %d, %s\n", len, buffer);
break;
case 3:
printf("\n COM4      %d, %s\n", len, buffer);
break;
default:
break;
}
}
   }
}
}

//程序入口:
extern "C"
{
int zmap()
{

if (taskSpawn("SERIAL_SEL", 90, VX_FP_TASK, 20000,
(FUNCPTR)selSerials, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) != ERROR)
{
return (0);
}
else
{
return (-1);
}

}
}
游客

返回顶部