2013-10-14 1 views
0

J'ai cette spécification:Comment synchroniser deux tâches avec Micro C OS II?

tâche 0 envoie des nombres entiers (à partir de 1) à la tâche 1. Tâche 1 doit multiplier les nombres avec -1 et les renvoyer à la tâche 0. Tâche 0 est alors imprime ces nombres sur la console. Pour la communication entre la tâche 0 et la tâche 1, vous devez utiliser emplacement de mémoire unique sharedAddress, c'est-à-dire la tâche 0 et la tâche 1 lire et écrire depuis/vers cet emplacement! Enregistrez le fichier en tant que SharedMemory.c. L'exécution du programme doit donner la sortie suivante. Envoi: 1 Réception: -1 Envoyer: 2 Fréquente: -2 ...

J'ai écrit ce programme, mais les tâches ne sont pas synchroniser correctement, je pense que je l'ai fait quelque chose de mal avec les sémaphores ou le contexte commutateur.

je reçois cette sortie au lieu où le nombre compte parfois vers le bas parce que les tâches ne sont pas synchonize correctement:

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 

Le programme que je dois changer est

#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; 
} 

Pouvez-vous me aider ?

+1

Pourquoi fais-tu sommeils? SemPend devrait mettre la tâche dans un état d'attente. Avez-vous essayé d'inverser les priorités des tâches? – LostBoy

Répondre

2

Venez y penser à nouveau: vous aurez probablement besoin de deux sémaphores:

  • un pour l'envoi du producteur au consommateur (SEM1)
  • un pour l'envoi du consommateur au producteur (SEM2)

iNITIALISATION SEM1 avec 0, avec SEM2 1.

  • Tâche 1 d'abord fait un Pend sur SEM2 puis processus données et messages sur sem1. L'étape suivante de la boucle attendra que sem2 soit posté par task2.
  • Tâche 2 Pends sur 1 ETM (en attente ainsi pour la première entrée de données), traite les données et messages sur SEM2
0
#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; 
}