www.mikrocontroller.net

Forum: Compiler & IDEs Funktion des uCOS Code


Autor: OSler (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

ich habe diesen Code gefunden und einmal ausgeführt. Ich kann hier 
irgendwie nicht wirklich nachvollziehen was gemacht wird.

1)Der Task4 wurde als letzter kreiert aber als erster ausgeführt und 
danach wurde er nicht mehr ausgeführt.

2) Danach wurde Task 1 ausgeführt usw....

Mir ist irgendwie unklar wie da vorgegangen wurde.

3) Wieso wurde der Interrupt nie ausgeführt.


4)Wie läuft das genau mit dem System Tick ab. 3 Tasks wurden während 
einem System Tick ausgeführt. Ich habe gedacht dass immer bei einem 
System Tick ein Task ausgeführt wird. Kann das nicht ganz nachvollziehen 
was alles während einem System Tick passiert.


Hoffe ihr könnte mir bisschen helfen. C ist irgendwie verständlicher 
nachzuvollziehen.

int main(void)
{
    OSInit();                                                               

    OSTaskCreate(TestTask1, (void *) 11, &TestTaskStk1[TASK_STK_SIZE], 11); //Calling sequence -->OSTaskStkInit-->OSTCBInitHook-->OSTaskCreateHook

    PC_IntVectSet(1, OurIsr1);                                              //Install an interrupt service routine for IRQ 1

    OSStart();                                                              

    return 0;
}


/*
*********************************************************************************************************
*                                                First Task (startup task)
*********************************************************************************************************
*/
void TestTask1(void *pdata)
{   printf("%4u: First call\n", OSTime);

#if OS_TASK_STAT_EN > 0
    OSStatInit();                                                               //Initialize the statistics task
#endif

    OSTaskCreate(TestTask2, (void *) 22, &TestTaskStk2[TASK_STK_SIZE], 22);     //Create 3 other tasks
    OSTaskCreate(TestTask3, (void *) 33, &TestTaskStk3[TASK_STK_SIZE], 33);
    OSTaskCreate(TestTask4, (void *) 10, &TestTaskStk4[TASK_STK_SIZE], 10);

    while (1)
    {   printf("%4u: ***** Test Task 11 *****\n", OSTime);

#ifdef SUSPEND_RESUME
        OSTaskSuspend(OS_PRIO_SELF);                                            //Calling sequence -->OSTaskSwHook-->OSCtxSw
#else
        OSTimeDly(1);                                                           //Calling sequence -->OSTaskSwHook-->OSCtxSw
#endif
    }
}

/*
*********************************************************************************************************
*                                                Second Task
*********************************************************************************************************
*/
void TestTask2(void *pdata)
{   while (1)
    {   printf("%4u: ***** Test Task 22 *****\n", OSTime);

#ifdef SUSPEND_RESUME
        OSTaskSuspend(OS_PRIO_SELF);
#else
        OSTimeDly(1);
#endif
    }
}

/*
*********************************************************************************************************
*                                                Third Task
*********************************************************************************************************
*/
void TestTask3(void *pdata)
{   while (1)
    {
#ifdef SUSPEND_RESUME
        printf("%4u: ***** Test Task 33 *****\n", OSTime);
        OSTaskResume(11);

        printf("%4u: ***** Test Task 33 *****\n", OSTime);
        OSTaskResume(22);
#endif
        printf("%4u: ***** Test Task 33 *****\n", OSTime);
        OSTimeDly(1);

        if (_kbhit())
  {   OSTaskDel(10);
      OSTaskDel(11);
      OSTaskDel(22);
      exit(0);
  }
    }
}

/*
*********************************************************************************************************
*                                                Forth Task
*********************************************************************************************************
*/
void TestTask4(void *pdata)
{   while (1)
    {
        printf("%4u: +++++ Test Task 40 +++++\n", OSTime);
        OSTaskSuspend(10);                                      //Suspend yourself
    }
}


/*
*********************************************************************************************************
*                                     Interrupt service routine for IRQ 1
*                                (use "irqGenerator 1" to trigger this interrupt)
*********************************************************************************************************
*/
void OurIsr1(void)
{       OSIntEnter();
        printf("##### Interrupt service routine for IRQ 1 #####\n");
        OSTaskResume(10);                                       //Trigger task 4
        OSIntExit();
}


MfG

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OSler schrieb:
> C ist irgendwie verständlicher
> nachzuvollziehen.

Komisch, für mich sieht das nach lupenreinem C aus.

Ansonsten: RTFM
Zur Beantwortung deiner Fragen wird dir nichts anderes übrig blieben, 
als die Doku zu uCOS durchzuarbeiten. Da steht garantiert drin, was uCOS 
im generellen und die benutzten Funktionen im einzelnen so tun.

Oliver

Autor: Guest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void TestTask4(void *pdata)
{   while (1)
    {
        printf("%4u: +++++ Test Task 40 +++++\n", OSTime);
        OSTaskSuspend(10);                                      //Suspend yourself
    }
}


Task4 beendet sich selbst....

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und vor allen Dingen nicht davon ausgehen, dass es irgendeine bevorzugte 
Task Reihenfolge (ausser diejenige die man selbst durch Task-Prioritäten 
festlegt) gibt.


> 1)Der Task4 wurde als letzter kreiert aber als erster ausgeführt

Dafür gibt es sicherlich irgendeine Erklärung, wenn man sich den uCOS 
Code ansieht. Aber im Allgemeinen ist diese Information nutzlos, weil 
man sich in der Multitasking-Programmierung sowieso nicht darauf 
verlassen kann/darf/soll

> und danach wurde er nicht mehr ausgeführt.

Doch ausgeführt wird er eigentlich schon. Der Task hat sich nur selber 
suspendet. Technisch gesehn existiert er noch, nur schläft er die ganze 
Zeit und wartet wie Dornröschen darauf, dass jemand kommt und ihn 
aufweckt (resumed)

> 2) Danach wurde Task 1 ausgeführt usw....

Nicht danach.
Mehr oder weniger zeitgleich.
Wie gesagt: Geh nicht von fixen Reihenfolgen aus. Damit erleidet man in 
der Multitasking Programmierung maximal Schiffbruch.

> 4)Wie läuft das genau mit dem System Tick ab. 3 Tasks wurden
> während einem System Tick ausgeführt. Ich habe gedacht dass immer
> bei einem System Tick ein Task ausgeführt wird.

Nö. Dieser 'System Tick' ist nichts anderes als die Systemuhr. Ein

    {   printf("%4u: ***** Test Task 11 *****\n", OSTime);

ist ja wohl kaum miszuverstehen.
Und das alle Tasks in 1 Zeiteinheit nur 1 mal drann kommen, sollte auch 
nicht verwundern, da sich jeder einzelne dieser Tasks offenbar mittels

        OSTimeDly(1);

für 1 Zeiteinheit schlafen legt.

Das sind aber eigentlich alles ziemlich offensichtliche Dinge, die klar 
und deutlich im Code stehen, wenn man ihn nur genau genug und aufmerksam 
liest.

Autor: Guest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein System Tick ist idR nur die Zeit von 1 ms... ist für OS_TimeDly gut 
zu gebrauchen.

Wer löst denn den Interrupt 1 aus?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guest schrieb:

> Wer löst denn den Interrupt 1 aus?


LOL
@OSler
Steht sogar im Kommentar dieses Beispiels
/*
*********************************************************************************************************
*                                     Interrupt service routine for IRQ 1
*                                (use "irqGenerator 1" to trigger this interrupt)
*********************************************************************************************************
*/

irqGenerator ist enweder ein Hinweis auf einen Funktionsaufruf oder 
überhaupt ein eigenständiges Programm, mit dem man so einen Interrupt 
auslösen kann, so dass dieses Programm dann darauf reagiert.

Autor: OSler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

mich würden noch zwei Sachen interessieren.

1) Wenn uberall die gleiche Priorität ist wieso wird immer nur der erste 
Task ausgelöst obwohl es den längsten Delay hat.


2) Beim System Clock 0 werden da immer alle Tasks ausgelöst in 
Abhängigkeit von der Priorität.

Danke!

MfG

Autor: OSler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

kann mir jemand sagen wieso das Programm hängen bleibt.

Danke

MfG

void Task1(void *pdata)
{   
    long i;
    INT8U err1;

    while (1)
    {    
        for (i = 0; i <= 10; i++)
        {
           if (i == 5)
           {
             OSSemPend(Sem2, 0, &err1);
             OSSemPost(Sem1);
             printf("Task1:  %d\n", i); 
           }
           if (i == 10)
           {
             OSSemPend(Sem2, 0, &err1);
             OSSemPost(Sem1);
             printf("Task1:  %d\n", i); 
           }     
        } 
        OSTimeDly(2);
    }
}

void Task2(void *pdata)
{   
    long i;
    INT8U err2;
    while (1)
    {
        for (i = 0; i <= 10; i++)
        {
           if (i == 5)
           {           
             OSSemPend(Sem1, 0, &err2); 
             OSSemPost(Sem2);
             printf("Task2:  %d\n", i); 
           }
           if (i == 10)
           {
             OSSemPend(Sem1, 0, &err2);
             OSSemPost(Sem2);
             printf("Task2:  %d\n", i); 
           }
        } 
        OSTimeDly(2);
    }
}

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe mich vor längerer Zeit (ca. 4 Jahren) intensiv mit ucos 
beschäftigt. Daher das nachfolgende aus der Erinnerung.

1. Bei ucos muss jedem Task eine Priorität vergeben werden. Diese darf 
nicht identisch mit den anderen sein. ucos unterstützt nicht 
round-robin. Dies steht alles in dem Buch über ucos. War zwar nicht 
preisgünstig aber lohnt sich auf jeden Fall. Hat mir auch unheimlich bei 
der Portierung geholfen.

2. Ich habe Deinen Code jetzt nicht getestet. Kann es sein, dass Dein 
Programm hierdurch
 OSSemPend(Sem1, 0, &err2); 
 hängen bleibt. Soweit ich weiss wird mit OSSemPend die Semaphore 
angefordert. Das geschieht im selben Task 2mal. Wenn jetzt zufällig ein- 
und derselbe Task 2mal hintereinander die Semaphore anfordert und sich 
selber blockiert. Ich kann mich aber nicht daran erinnern, ob ucos das 
abfängt wenn derselbe Task die Semaphore 2mal anfordert.

3. Eine andere Möglichkeit wäre wenn printf über Interrupt ausgeführt 
wird. Genau dieses Problem hatte ich auch. In eigenen Interrupt-Routinen 
müssen noch besondere Verriegelungen erfolgen. Steht aber auch alles in 
dem Buch.

Ucos finde ich hochinteressant. Aber ohne diese Buch ist man meiner 
Meinung nach aufgeschmissen.

Viele Grüße
Andreas

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe mir gerade nochmal Deine Interrupt-Routine angesehen. Das kann 
nicht funktionieren. Ucos legt für jeden Task einen eigenen Stack an. 
Dahin müssen alle Register gesichert werden. Bei mir sieht das so wie 
unten aus und funtkioniert auch:
UCOSISR(SIG_INTERRUPT0)
{
  PushRS();
  OSIntEnter();
  if (OSIntNesting == 1)
    OSTCBCur->OSTCBStkPtr = (OS_STK *)SP;
  sei();
  OSSemPost(Task1Sem);                            // Notify Task1 
  OSIntExit();
  PopRS();
}

#define UCOSISR(signame)      \
void signame (void) __attribute__ ((naked));  \
void signame (void)

/*
 * Macros for pushing and popping registers in application ISRs.
 *
 * Do not use pushregs(), pushrampz(), pushsreg() directly.
 *
 * Use PushRS() and PopRS() in application programs.
 */

#define pushregs() \
        __asm__ __volatile__ ( \
        "push   r0"    "\n\t" \
        "push   r1"    "\n\t" \
        "push   r2"    "\n\t" \
        "push   r3"    "\n\t" \
        "push   r4"    "\n\t" \
        "push   r5"    "\n\t" \
        "push   r6"    "\n\t" \
        "push   r7"    "\n\t" \
        "push   r8"    "\n\t" \
        "push   r9"    "\n\t" \
        "push   r10"    "\n\t" \
        "push   r11"    "\n\t" \
        "push   r12"    "\n\t" \
        "push   r13"    "\n\t" \
        "push   r14"    "\n\t" \
        "push   r15"    "\n\t" \
        "push   r16"    "\n\t" \
        "push   r17"    "\n\t" \
        "push   r18"    "\n\t" \
        "push   r19"    "\n\t" \
        "push   r20"    "\n\t" \
        "push   r21"    "\n\t" \
        "push   r22"    "\n\t" \
        "push   r23"    "\n\t" \
        "push   r24"    "\n\t" \
        "push   r25"    "\n\t" \
        "push   r26"    "\n\t" \
        "push   r27"    "\n\t" \
        "push   r28"    "\n\t" \
        "push   r29"    "\n\t" \
        "push   r30"    "\n\t" \
        "push   r31"    "\n\t" \
        "ldi    r31,0"  "\n\t" \
        "mov    r1,r31" "\n\t" \
        ::)

#define pushsreg() __asm__ __volatile__ ( \
        "in            r16,__SREG__"    "\n\t" \
        "sbr    r16,0x80"    "\n\t" \
        "push   r16"    "\n\t" \
        ::)

#define PushRS() {\
   pushregs();\
   pushsreg();}
#endif


Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.