Как синхронизировать две задачи с Micro C OS II?
У меня есть эта спецификация:
Задача 0 отправляет целые числа (начиная с 1) в задачу 1. Задача 1 должна умножить числа на -1 и отправить их обратно в задачу 0. Затем задача 0 должна распечатать эти числа на консоли. Для связи между задачей 0 и задачей 1 должен использоваться один общий адрес памяти, то есть и задача 0, и задача 1 читают и записывают в / из этого места! Сохраните файл как SharedMemory.c. Выполнение программы должно дать следующий вывод. Отправка: 1 Получение: -1 Отправка: 2 Получение: -2 ...
Я написал эту программу, но задачи не синхронизируются правильно, я думаю, что, возможно, что-то не так с семафорами или переключением контекста.
Вместо этого я получаю вывод, где число иногда отсчитывается, потому что задачи не синхронизированы правильно:
Receiving 17
Sending : 16
Receiving -16
Sending : -17
Receiving 17
Sending : 16
Receiving -16
Sending : -17
Receiving 17
Sending : 16
Receiving -16
Sending : -17
Receiving 17
Sending : 16
Receiving -16
Sending : -17
Receiving 17
Sending : 16
Receiving -16
Sending : -17
Receiving 17
Sending : 16
Receiving -16
Sending : -17
Receiving 17
Sending : 16
Receiving -16
Sending : -17
Receiving 17
Sending : 16
Receiving -16
Sending : -17
Receiving 17
Sending : 16
Receiving -16
Sending : -17
Receiving 17
Sending : 16
Receiving -16
Sending : -17
Receiving 17
Sending : 16
Receiving -16
Sending : -17
Receiving 17
Sending : 16
Receiving -16
Sending : -17
Receiving 17
Программа, которую мне нужно изменить,
#include <stdio.h>
#include "includes.h"
#include <string.h>
#define DEBUG 0
/* Definition of Task Stacks */
/* Stack grows from HIGH to LOW memory */
#define TASK_STACKSIZE 2048
OS_STK task1_stk[TASK_STACKSIZE];
OS_STK task2_stk[TASK_STACKSIZE];
OS_STK stat_stk[TASK_STACKSIZE];
OS_EVENT *aSemaphore;
/* Definition of Task Priorities */
#define TASK1_PRIORITY 6 // highest priority
#define TASK2_PRIORITY 7
#define TASK_STAT_PRIORITY 12 // lowest priority
int number = 1;
void handle_button_interrupts(void* context, alt_u32 id)
{
volatile int* edge_capture_ptr = (volatile int*) context;
OSIntEnter();
// Read the edge capture register on the button PIO
//*edge_capture_ptr =
//IORD_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE);
OSIntExit();
}
void printStackSize(INT8U prio)
{
INT8U err;
OS_STK_DATA stk_data;
err = OSTaskStkChk(prio, &stk_data);
if (err == OS_NO_ERR)
{
if (DEBUG == 1)
printf("Task Priority %d - Used: %d; Free: %d\n",
prio, stk_data.OSFree, stk_data.OSUsed);
}
else
{
if (DEBUG == 1)
printf("Stack Check Error!\n");
}
}
/* Producer */
void task1(void* pdata)
{
INT8U err;
while (1)
{
char text1[] = "Sending : ";
char text2[] = "Receiving : ";
int i;
OSSemPend(aSemaphore, 0, &err); // Trying to access the key
for (i = 0; i < strlen(text1); i++)
putchar(text1[i]);
printf("%d", number);
putchar('\n');
OSSemPost(aSemaphore); // Releasing the key
OSTimeDlyHMSM(0, 0, 0, 11); // Context Switch to next task
// Task will go to the ready state
// after the specified delay
OSSemPend(aSemaphore, 0, &err); // Trying to access the key
for (i = 0; i < strlen(text1); i++)
putchar(text2[i]);
printf("%d", number);
putchar('\n');
number=-number;
number++;
OSSemPost(aSemaphore); // Releasing the key
OSTimeDlyHMSM(0, 0, 0, 11); // Context Switch to next task
// Task will go to the ready state
// after the specified delay
}
}
/* Consumer */
void task2(void* pdata)
{
INT8U err;
while (1)
{
OSSemPend(aSemaphore, 0, &err); // Trying to access the key
number = -number;
OSSemPost(aSemaphore); // Releasing the key
OSTimeDlyHMSM(0, 0, 0, 4);
}
}
/* Printing Statistics */
void statisticTask(void* pdata)
{
while(1)
{
printStackSize(TASK1_PRIORITY);
printStackSize(TASK2_PRIORITY);
printStackSize(TASK_STAT_PRIORITY);
}
}
/* The main function creates two task and starts multi-tasking */
int main(void)
{
printf("Lab 3 - Handshake\n");
aSemaphore = OSSemCreate(1); // binary semaphore (1 key)
OSTaskCreateExt
(task1, // Pointer to task code
NULL, // Pointer to argument that is
// passed to task
&task1_stk[TASK_STACKSIZE-1], // Pointer to top of task stack
TASK1_PRIORITY, // Desired Task priority
TASK1_PRIORITY, // Task ID
&task1_stk[0], // Pointer to bottom of task stack
TASK_STACKSIZE, // Stacksize
NULL, // Pointer to user supplied memory
// (not needed here)
OS_TASK_OPT_STK_CHK | // Stack Checking enabled
OS_TASK_OPT_STK_CLR // Stack Cleared
);
OSTaskCreateExt
(task2, // Pointer to task code
NULL, // Pointer to argument that is
// passed to task
&task2_stk[TASK_STACKSIZE-1], // Pointer to top of task stack
TASK2_PRIORITY, // Desired Task priority
TASK2_PRIORITY, // Task ID
&task2_stk[0], // Pointer to bottom of task stack
TASK_STACKSIZE, // Stacksize
NULL, // Pointer to user supplied memory
// (not needed here)
OS_TASK_OPT_STK_CHK | // Stack Checking enabled
OS_TASK_OPT_STK_CLR // Stack Cleared
);
if (DEBUG == 1)
{
OSTaskCreateExt
(statisticTask, // Pointer to task code
NULL, // Pointer to argument that is
// passed to task
&stat_stk[TASK_STACKSIZE-1], // Pointer to top of task stack
TASK_STAT_PRIORITY, // Desired Task priority
TASK_STAT_PRIORITY, // Task ID
&stat_stk[0], // Pointer to bottom of task stack
TASK_STACKSIZE, // Stacksize
NULL, // Pointer to user supplied memory
// (not needed here)
OS_TASK_OPT_STK_CHK | // Stack Checking enabled
OS_TASK_OPT_STK_CLR // Stack Cleared
);
}
OSStart();
return 0;
}
Вы можете мне помочь?
2 ответа
Подумайте об этом еще раз: вам, вероятно, понадобятся два семафора:
- один для отправки от производителя к потребителю (sem1)
- один для отправки от потребителя к производителю (sem2)
Вы инициализируете sem1 с 0, sem2 с 1.
- Задача 1 сначала выполняет ожидание в sem2, затем обрабатывает данные и сообщения в sem1. Следующим шагом цикла будет ожидание, пока задача2 не отправит sem2.
- Задача 2 выполняется в sem 1 (таким образом, ожидая первого ввода данных), обрабатывает данные и сообщения в sem2
#include <stdio.h>
#include "includes.h"
#include <string.h>
#define DEBUG 1
/* Definition of Task Stacks */
/* Stack grows from HIGH to LOW memory */
#define TASK_STACKSIZE 2048
OS_STK task1_stk[TASK_STACKSIZE];
OS_STK task2_stk[TASK_STACKSIZE];
OS_STK stat_stk[TASK_STACKSIZE];
/* Decaring the semaphone */
OS_EVENT *aSemaphore;
OS_EVENT *bSemaphore;
int number=0;
/* Definition of Task Priorities */
#define TASK1_PRIORITY 6 // highest priority
#define TASK2_PRIORITY 7
#define TASK_STAT_PRIORITY 12 // lowest priority
void printStackSize(INT8U prio)
{
INT8U err;
OS_STK_DATA stk_data;
err = OSTaskStkChk(prio, &stk_data);
if (err == OS_NO_ERR)
{
if (DEBUG == 1)
printf("Task Priority %d - Used: %d; Free: %d\n",
prio, stk_data.OSFree, stk_data.OSUsed);
}
else
{
if (DEBUG == 1)
printf("Stack Check Error!\n");
}
}
/* Prints a message and sleeps for given time interval */
void task1(void* pdata)
{
INT8U err_bSemaphore;
while (1)
{
OSSemPend(bSemaphore,0,&err_bSemaphore);
number*= -1;
number++;
printf("Sending: %d\n",number);
OSSemPost(aSemaphore);
}
}
/* Prints a message and sleeps for given time interval */
void task2(void* pdata)
{
INT8U err_aSemaphore;
while (1)
{
OSSemPend(aSemaphore,0, &err_aSemaphore);
number*= -1;
printf("Receiving: %d\n", number);
OSSemPost(bSemaphore);
}
}
/* Printing Statistics */
void statisticTask(void* pdata)
{
while(1)
{
printStackSize(TASK1_PRIORITY);
printStackSize(TASK2_PRIORITY);
printStackSize(TASK_STAT_PRIORITY);
}
}
/* The main function creates two task and starts multi-tasking */
int main(void)
{
printf("Lab 1 - Two Tasks using Handshake (Task 2.4)\n");
/* Declaring a binary semaphore */
aSemaphore = OSSemCreate(1);
bSemaphore = OSSemCreate(1);
OSTaskCreateExt
(task1, // Pointer to task code
NULL, // Pointer to argument that is
// passed to task
&task1_stk[TASK_STACKSIZE-1], // Pointer to top of task stack
TASK1_PRIORITY, // Desired Task priority
TASK1_PRIORITY, // Task ID
&task1_stk[0], // Pointer to bottom of task stack
TASK_STACKSIZE, // Stacksize
NULL, // Pointer to user supplied memory
// (not needed here)
OS_TASK_OPT_STK_CHK | // Stack Checking enabled
OS_TASK_OPT_STK_CLR // Stack Cleared
);
OSTaskCreateExt
(task2, // Pointer to task code
NULL, // Pointer to argument that is
// passed to task
&task2_stk[TASK_STACKSIZE-1], // Pointer to top of task stack
TASK2_PRIORITY, // Desired Task priority
TASK2_PRIORITY, // Task ID
&task2_stk[0], // Pointer to bottom of task stack
TASK_STACKSIZE, // Stacksize
NULL, // Pointer to user supplied memory
// (not needed here)
OS_TASK_OPT_STK_CHK | // Stack Checking enabled
OS_TASK_OPT_STK_CLR // Stack Cleared
);
if (DEBUG == 1)
{
OSTaskCreateExt
(statisticTask, // Pointer to task code
NULL, // Pointer to argument that is
// passed to task
&stat_stk[TASK_STACKSIZE-1], // Pointer to top of task stack
TASK_STAT_PRIORITY, // Desired Task priority
TASK_STAT_PRIORITY, // Task ID
&stat_stk[0], // Pointer to bottom of task stack
TASK_STACKSIZE, // Stacksize
NULL, // Pointer to user supplied memory
// (not needed here)
OS_TASK_OPT_STK_CHK | // Stack Checking enabled
OS_TASK_OPT_STK_CLR // Stack Cleared
);`enter code here`
}
OSStart();
return 0;
}