Задача с наименьшим приоритетом создана правильно, но не запускается - PullRequest
0 голосов
/ 15 февраля 2019

Я пытаюсь создать какое-то приложение.Это приложение состоит из следующих задач:

  • KeybReader, который отвечает за чтение ввода с клавиатуры и отправку его,

  • Дисплей, который отвечает зараспечатывая массив disp,

  • Редактор, который отвечает за сбор всех данных из других задач, обработку их и изменение массива disp,
  • загрузка задач, предназначенных просто для искусственного обременениясистема.Они управляются разными методами, реализован только один тип (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)        */

Если этого недостаточно, вот ссылка на вставку с целым кодом https://pastebin.com/EkbcLr59

Задача V не запускается, даже если онасозданный правильно, если бы я изменил его приоритет, скажем, 1, и отдал бы приоритет задаче, которая изначально имела приоритет, равный 1, он запустился бы, но другой - нет.

...