Forum: Compiler & IDEs Funktion des uCOS Code


von OSler (Gast)


Angehängte Dateien:

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.

1
int main(void)
2
{
3
    OSInit();                                                               
4
5
    OSTaskCreate(TestTask1, (void *) 11, &TestTaskStk1[TASK_STK_SIZE], 11); //Calling sequence -->OSTaskStkInit-->OSTCBInitHook-->OSTaskCreateHook
6
7
    PC_IntVectSet(1, OurIsr1);                                              //Install an interrupt service routine for IRQ 1
8
9
    OSStart();                                                              
10
11
    return 0;
12
}
13
14
15
/*
16
*********************************************************************************************************
17
*                                                First Task (startup task)
18
*********************************************************************************************************
19
*/
20
void TestTask1(void *pdata)
21
{   printf("%4u: First call\n", OSTime);
22
23
#if OS_TASK_STAT_EN > 0
24
    OSStatInit();                                                               //Initialize the statistics task
25
#endif
26
27
    OSTaskCreate(TestTask2, (void *) 22, &TestTaskStk2[TASK_STK_SIZE], 22);     //Create 3 other tasks
28
    OSTaskCreate(TestTask3, (void *) 33, &TestTaskStk3[TASK_STK_SIZE], 33);
29
    OSTaskCreate(TestTask4, (void *) 10, &TestTaskStk4[TASK_STK_SIZE], 10);
30
31
    while (1)
32
    {   printf("%4u: ***** Test Task 11 *****\n", OSTime);
33
34
#ifdef SUSPEND_RESUME
35
        OSTaskSuspend(OS_PRIO_SELF);                                            //Calling sequence -->OSTaskSwHook-->OSCtxSw
36
#else
37
        OSTimeDly(1);                                                           //Calling sequence -->OSTaskSwHook-->OSCtxSw
38
#endif
39
    }
40
}
41
42
/*
43
*********************************************************************************************************
44
*                                                Second Task
45
*********************************************************************************************************
46
*/
47
void TestTask2(void *pdata)
48
{   while (1)
49
    {   printf("%4u: ***** Test Task 22 *****\n", OSTime);
50
51
#ifdef SUSPEND_RESUME
52
        OSTaskSuspend(OS_PRIO_SELF);
53
#else
54
        OSTimeDly(1);
55
#endif
56
    }
57
}
58
59
/*
60
*********************************************************************************************************
61
*                                                Third Task
62
*********************************************************************************************************
63
*/
64
void TestTask3(void *pdata)
65
{   while (1)
66
    {
67
#ifdef SUSPEND_RESUME
68
        printf("%4u: ***** Test Task 33 *****\n", OSTime);
69
        OSTaskResume(11);
70
71
        printf("%4u: ***** Test Task 33 *****\n", OSTime);
72
        OSTaskResume(22);
73
#endif
74
        printf("%4u: ***** Test Task 33 *****\n", OSTime);
75
        OSTimeDly(1);
76
77
        if (_kbhit())
78
  {   OSTaskDel(10);
79
      OSTaskDel(11);
80
      OSTaskDel(22);
81
      exit(0);
82
  }
83
    }
84
}
85
86
/*
87
*********************************************************************************************************
88
*                                                Forth Task
89
*********************************************************************************************************
90
*/
91
void TestTask4(void *pdata)
92
{   while (1)
93
    {
94
        printf("%4u: +++++ Test Task 40 +++++\n", OSTime);
95
        OSTaskSuspend(10);                                      //Suspend yourself
96
    }
97
}
98
99
100
/*
101
*********************************************************************************************************
102
*                                     Interrupt service routine for IRQ 1
103
*                                (use "irqGenerator 1" to trigger this interrupt)
104
*********************************************************************************************************
105
*/
106
void OurIsr1(void)
107
{       OSIntEnter();
108
        printf("##### Interrupt service routine for IRQ 1 #####\n");
109
        OSTaskResume(10);                                       //Trigger task 4
110
        OSIntExit();
111
}


MfG

von Oliver (Gast)


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

von Guest (Gast)


Lesenswert?

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


Task4 beendet sich selbst....

von Karl H. (kbuchegg)


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.

von Guest (Gast)


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?

von Karl H. (kbuchegg)


Lesenswert?

Guest schrieb:

> Wer löst denn den Interrupt 1 aus?


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

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.

von OSler (Gast)


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

von OSler (Gast)


Lesenswert?

Hallo

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

Danke

MfG

1
void Task1(void *pdata)
2
{   
3
    long i;
4
    INT8U err1;
5
6
    while (1)
7
    {    
8
        for (i = 0; i <= 10; i++)
9
        {
10
           if (i == 5)
11
           {
12
             OSSemPend(Sem2, 0, &err1);
13
             OSSemPost(Sem1);
14
             printf("Task1:  %d\n", i); 
15
           }
16
           if (i == 10)
17
           {
18
             OSSemPend(Sem2, 0, &err1);
19
             OSSemPost(Sem1);
20
             printf("Task1:  %d\n", i); 
21
           }     
22
        } 
23
        OSTimeDly(2);
24
    }
25
}
26
27
void Task2(void *pdata)
28
{   
29
    long i;
30
    INT8U err2;
31
    while (1)
32
    {
33
        for (i = 0; i <= 10; i++)
34
        {
35
           if (i == 5)
36
           {           
37
             OSSemPend(Sem1, 0, &err2); 
38
             OSSemPost(Sem2);
39
             printf("Task2:  %d\n", i); 
40
           }
41
           if (i == 10)
42
           {
43
             OSSemPend(Sem1, 0, &err2);
44
             OSSemPost(Sem2);
45
             printf("Task2:  %d\n", i); 
46
           }
47
        } 
48
        OSTimeDly(2);
49
    }
50
}

von Andreas (Gast)


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
1
 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

von Andreas (Gast)


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:
1
UCOSISR(SIG_INTERRUPT0)
2
{
3
  PushRS();
4
  OSIntEnter();
5
  if (OSIntNesting == 1)
6
    OSTCBCur->OSTCBStkPtr = (OS_STK *)SP;
7
  sei();
8
  OSSemPost(Task1Sem);                            // Notify Task1 
9
  OSIntExit();
10
  PopRS();
11
}
12
13
#define UCOSISR(signame)      \
14
void signame (void) __attribute__ ((naked));  \
15
void signame (void)
16
17
/*
18
 * Macros for pushing and popping registers in application ISRs.
19
 *
20
 * Do not use pushregs(), pushrampz(), pushsreg() directly.
21
 *
22
 * Use PushRS() and PopRS() in application programs.
23
 */
24
25
#define pushregs() \
26
        __asm__ __volatile__ ( \
27
        "push   r0"    "\n\t" \
28
        "push   r1"    "\n\t" \
29
        "push   r2"    "\n\t" \
30
        "push   r3"    "\n\t" \
31
        "push   r4"    "\n\t" \
32
        "push   r5"    "\n\t" \
33
        "push   r6"    "\n\t" \
34
        "push   r7"    "\n\t" \
35
        "push   r8"    "\n\t" \
36
        "push   r9"    "\n\t" \
37
        "push   r10"    "\n\t" \
38
        "push   r11"    "\n\t" \
39
        "push   r12"    "\n\t" \
40
        "push   r13"    "\n\t" \
41
        "push   r14"    "\n\t" \
42
        "push   r15"    "\n\t" \
43
        "push   r16"    "\n\t" \
44
        "push   r17"    "\n\t" \
45
        "push   r18"    "\n\t" \
46
        "push   r19"    "\n\t" \
47
        "push   r20"    "\n\t" \
48
        "push   r21"    "\n\t" \
49
        "push   r22"    "\n\t" \
50
        "push   r23"    "\n\t" \
51
        "push   r24"    "\n\t" \
52
        "push   r25"    "\n\t" \
53
        "push   r26"    "\n\t" \
54
        "push   r27"    "\n\t" \
55
        "push   r28"    "\n\t" \
56
        "push   r29"    "\n\t" \
57
        "push   r30"    "\n\t" \
58
        "push   r31"    "\n\t" \
59
        "ldi    r31,0"  "\n\t" \
60
        "mov    r1,r31" "\n\t" \
61
        ::)
62
63
#define pushsreg() __asm__ __volatile__ ( \
64
        "in            r16,__SREG__"    "\n\t" \
65
        "sbr    r16,0x80"    "\n\t" \
66
        "push   r16"    "\n\t" \
67
        ::)
68
69
#define PushRS() {\
70
   pushregs();\
71
   pushsreg();}
72
#endif

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.