我正在尝试开发某种应用。该应用包含以下任务:
KeybReader,它负责从键盘读取输入并将其发送给
显示器,它负责打印出显示数组,
它的问题是,当我尝试仅创建一个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的任务,它将启动,但另一个一个不会。