最低优先级的任务已正确创建,但未启动

时间:2019-02-15 14:36:43

标签: real-time ucos

我正在尝试开发某种应用。该应用包含以下任务:

  • KeybReader,它负责从键盘读取输入并将其发送给

  • 显示器,它负责打印出显示数组,

  • 编辑器,负责收集其他任务中的所有数据,对其进行处理并修改disp数组,
  • 加载任务只是为了人为地负担系统。它们用不同的方法控制,到目前为止仅实现了一种(taskV),但事实并非如此。

它的问题是,当我尝试仅创建一个taskV实例时,它会成功创建,但无法启动。

整个应用程序均基于示例1,它与µcos一起提供。我试图弄乱优先级,得出的结论是,创建的优先级低于或等于4的任务没有执行(如果降低,我的意思是4、5、6 ...等等)没有执行,即使它们创建正确。 我不知道为什么,我也试过弄乱堆栈大小,这没有帮助,在这一点上我想寻求帮助。

以下是一些使用的全局变量和宏:

#define  TASK_STK_SIZE                 512       /* Size of each task's    stacks (# of WORDs)            */

#define SCREENWIDTH 80
#define SCREENHEIGHT 20

#define CHARBUFFSIZE 11  //size of char buffer, enough size for writing 4 294 967 295 which is max value for 32 bit uint

#define INPUT_AREA 0, CHARBUFFSIZE, 0, SCREENHEIGHT 

#define LOADQSIZE 15 //size of load queue
#define INITLOAD 20  //initial load of tasks

#define KEYBREADER_STK 256
#define DISPLAYER_STK 256
#define EDITOR_STK 512

OS_STK TaskStartStk[TASK_STK_SIZE];
OS_STK KeybSTK[KEYBREADER_STK]; //stos KeybReadera
OS_STK DisplayerSTK[DISPLAYER_STK];
OS_STK EditorSTK[EDITOR_STK];
OS_STK taskSTK[15][128]; //Stacks

OS_EVENT *displayerSem; //Semaphore used for locking data stored in mailbox
OS_EVENT *editorInput; //input Queue for editor
OS_EVENT *loadVSem; //semaphore used for locking contents of load variable
OS_EVENT *loadQ; //queue
OS_EVENT *loadMbox[5]; //Mailboxes for load tasks

//report struct
typedef struct report  
{
  INT8U task_num; //number of task
  INT32U task_load; //current load variable of a task
  INT32U task_entry_count; //how many times task was entered?
  INT32U task_chksum;
  char type;
} report;

OS_MEM *partition;
report partition_memblock[18][sizeof(report)];

void *editorInputMsg[20];
void *loadMsg[LOADQSIZE]; //buffer of loadQ queue

INT32S load = INITLOAD; //load level variable

当然,所有OS_EVENTS都已初始化(在main()中),我已经仔细检查过这一点,所以现在我将其省略,在代码TaskStartCreatTasks的后半部分中,它的代码是:

static  void  TaskStartCreateTasks (void)
{
    INT8U  i;
    INT8U  k;   
    //my tasks

    //load tasks



    OSTaskCreate(&KeybReader, (void *)0, &KeybSTK[KEYBREADER_STK-1], 1);
    OSTaskCreate(&Editor, (void *)0, &EditorSTK[EDITOR_STK-1], 2);
    OSTaskCreate(&Displayer, (void *)0, &DisplayerSTK[DISPLAYER_STK-1], 3);

    if(OSTaskCreate(&taskV, (void*)0, &taskSTK[0][127], 4) != OS_NO_ERR ) PC_DOSReturn(); //this does not happen, so it is created correctly
      }
}

我不确定这是否重要,但是我会粘贴以防万一。 KeybReader任务:

void KeybReader(void *pdata)
{

  INT16S key; //keycode
  report *keyAddr = NULL; //pointer to typed char
  INT8U err;//debug
  OS_TCB deb;
  char str[20];
  pdata=pdata;
  PC_DispChar(3, 1, 'K', DISP_FGND_YELLOW + DISP_BGND_BLUE);
  for(;;)
    {
        if(PC_GetKey(&key) == TRUE)
    {
       keyAddr = OSMemGet(partition, &err);
        if(keyAddr != NULL)
        {
            keyAddr->task_load = key;
            keyAddr->type = 'R';
            err = OSQPost(editorInput, (void *)keyAddr); //send msg with kycode to queue, err for debug
            keyAddr = NULL;
        }
    }
     err = OSTaskQuery(3, &deb);
     sprintf(str, "status %d error %d" , deb.OSTCBStat, OS_NO_ERR);
     PC_DispStr(30, 1, str, DISP_FGND_YELLOW + DISP_BGND_BLUE);
     OSTimeDly(1);      
}
}

编辑器任务:

void Editor(void *pdata)
{
    char feedline[CHARBUFFSIZE]; //edited line, will be written to disp[0]
    char str[60];
    char status[15];

    INT8U i=0,j;
        INT8U nl=0; //new line flag
    INT16S c; //char aquired from queue
    INT32U newLoad, curLoad = INITLOAD, chksum = 0;
    INT8U err;//debug
    report task[15];
    report *newReportPtr;

    PC_DispChar(2, 1, 'E', DISP_FGND_YELLOW + DISP_BGND_BLUE);
    feedline[0]='\0';

    //reset task[]
    for(j=0; j<15; j++) //task tab init
      {
        task[j].task_num=j;
        task[j].task_load=0;
        task[j].task_entry_count=0;
        task[j].type = 'N';
        task[j].task_chksum = 0;
      }

    pdata=pdata;

    sprintf(str, "Type Number Load      entrCounter delta      status");
    putDispPaddled(CHARBUFFSIZE , 0, str, ' ', 80);

     for(j = 0; j < 15; j++)
        {
          sprintf(str, "   %c %6d %10lu %10lu %10lu %s",
              task[j].type,
              task[j].task_num,
              task[j].task_load,
              task[j].task_entry_count,
              0,
              "N/A!");
          putDispPaddled(CHARBUFFSIZE, 1+j, str, ' ', 80);
        }

    for(;;)
    {
      //getting message
      newReportPtr = (report*) OSQPend(editorInput, 0, NULL);
      if(newReportPtr->type == 'R')
        {
          c = (INT16S) newReportPtr -> task_load;
          PC_DispChar(0, 1, i+'0', DISP_FGND_YELLOW + DISP_BGND_BLUE);
          switch(c) //select action depending on c
        {
        case 0x1B: //escape pressed
          PC_DOSReturn();
          break;
        case 0x08: //backspace pressed
          if(i>0) i--;
          feedline[i]='\0';
          break;

        case 0x53: //delete pressed
          i=0;
          feedline[0]='\0';
          break;

        case 0x0D: //enter pressed
          feedline[i]='\0';
          i=0;
          nl=1; //new line flag set
          break;

        default:
          if(i<CHARBUFFSIZE-1)
            {
              feedline[i++]=(char) c; //place new character in feedline
              feedline[i]='\0'; //place \0 after last character
            }
          break;
        }
          if(nl == 1)
        {
          newLoad = strtoul(feedline, NULL, 10);
          movDispUp(INPUT_AREA);
          putDispPaddled(0, 19, feedline, ' ', CHARBUFFSIZE);
          feedline[0] = '\0';
          nl = 0;
        }
          putDispPaddled(0, 19, feedline, '#', CHARBUFFSIZE);
        }
      else if(newReportPtr->type == 'V' || newReportPtr->type == 'Q' || newReportPtr->type == 'M')  //report from one of load tasks
        {
          task[newReportPtr->task_num] = *newReportPtr;
        }
      else PC_DOSReturn();
      OSMemPut(partition, newReportPtr);
      newReportPtr = NULL;

      for(j = 0; j < 15; j++) //print status of tasks
        {
          if(task[j].type == 'N')
        {
          sprintf(status, "N/A!");
        }
          else if(task[j].task_chksum < chksum)
        {
          sprintf(status, "miss %d", chksum - task[j].task_chksum);
        }
          else
        {
          sprintf(status, "ok");
        }
          sprintf(str, "   %c %6d %10lu %10lu %s",
              task[j].type,
              task[j].task_num,
              task[j].task_load,
              task[j].task_entry_count,

              status);
          putDispPaddled(CHARBUFFSIZE, 1+j, str, ' ', 80);
        }

    }
}

编辑器中使用的功能:

void putDispPaddled(INT8U x, INT8U y, const char *line, char pad, INT8U size)
{
  INT8U stringSize  = strlen(line);
  INT8U fill = 0;
  INT8U i;
  if(x >= SCREENWIDTH || y >= SCREENHEIGHT) return;
  if(size == 0)
    {
      if(x + stringSize > SCREENWIDTH) //if array bounds would be exceeded
    {
      stringSize = SCREENWIDTH - x;
    }
    }
  else //size > 0
    {
      if(x + size > SCREENWIDTH)
    {
      size = SCREENWIDTH - x;
    }

      if(size < stringSize) //string is longer than size
    {
      stringSize = size;
    }
      else
    {
      fill = size - stringSize;
    }
    }

  OSSemPend(displayerSem, 0, NULL);
  memcpy(disp[y] + x, line, stringSize);
  for(i = 0; i < fill; i++)
    {
      disp[y][x+i+stringSize] = pad;
    }
  OSSemPost(displayerSem);
}

void movDispUp(INT8U xbeg, INT8U xend, INT8U ybeg, INT8U yend)
{
  int i;
  if(xbeg > xend || xend > SCREENWIDTH  || ybeg > yend || yend > SCREENHEIGHT) return;
  OSSemPend(displayerSem, 0, NULL);
  for(i = 0; i < yend - 1; i++)
    {
      memcpy(disp[ybeg+i]+xbeg, disp[ybeg+i+1]+xbeg, xend-xbeg);
    }
  OSSemPost(displayerSem);  
}

taskV:

void taskV(void *pdata)
{
    INT32U q=INITLOAD; //local copy of load
    INT8U num =(INT8U)pdata; //number of task
    INT32U i;
    INT32U in=0; //number of times the task was entered
    INT32U chksum = 0;
    INT32U x; //dummy load
    report *out = NULL;
    INT8U err;

    for(;;)
      {
        if(OSSemAccept(loadVSem)==1) //new value load
          {
        PC_DispStr(10, 1, "changed", DISP_FGND_YELLOW + DISP_BGND_BLUE);
        if(q!=load)
          {
            q=load; //get new value of load if is aviable
            chksum++;
          }
        OSSemPost(loadVSem);
          }

        for(i=0; i<q; i++) x++; //dummy load incrementation
        in++;
        out = OSMemGet(partition, &err);
        if(out == NULL) PC_DispStr(5, 1, "allocation fault", DISP_FGND_YELLOW + DISP_BGND_BLUE);
        else
          {
        out->task_num = num; //write task number to report
        out->task_load = q; //write current load to report
        out->task_entry_count = in; //write entry count to report
        out->task_chksum = chksum;
        out->type = 'V';
        err = OSQPost(editorInput, out);
          }



        out = NULL;
        OSTimeDly(1); //smallest possible dly
    }
}

最后,是OS_CFG.H的一部分

#define OS_MAX_EVENTS             30    /* Max. number of event control blocks in your application ...  */
                                       /* ... MUST be > 0                                              */
#define OS_MAX_FLAGS              15    /* Max. number of Event Flag Groups    in your application ...  */
                                       /* ... MUST be > 0                                              */
#define OS_MAX_MEM_PART           5    /* Max. number of memory partitions ...                         */
                                       /* ... MUST be > 0                                              */
#define OS_MAX_QS                 5    /* Max. number of queue control blocks in your application ...  */
                                       /* ... MUST be > 0                                              */
#define OS_MAX_TASKS              63    /* Max. number of tasks in your application ...                 */
                                       /* ... MUST be >= 2                                             */

#define OS_LOWEST_PRIO           63    /* Defines the lowest priority that can be assigned ...         */
                                       /* ... MUST NEVER be higher than 63!                            */

#define OS_TASK_IDLE_STK_SIZE   512    /* Idle task stack size (# of OS_STK wide entries)              */

#define OS_TASK_STAT_EN           1    /* Enable (1) or Disable(0) the statistics task                 */
#define OS_TASK_STAT_STK_SIZE   512   /* Statistics task stack size (# of OS_STK wide entries)        */

如果这还不够,请使用完整代码链接到pastebin https://pastebin.com/EkbcLr59

即使已经正确创建了taskV,它也不会启动,如果我将其优先级更改为1,并将其优先级赋予最初具有等于1的任务,它将启动,但另一个一个不会。

0 个答案:

没有答案