■세마포어


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/*******************************************************************************
**    File:
**
**        06_SEM.c
**
**  Contents:
**        uC/OS-II programming
**
**    History:
**        Date        Name              Description
**        ------------------------------------------------------------------------
**
*******************************************************************************/
#include "includes.h"
    
/* ...........................................................................
 *
 * 태스크 스택 정의
 * ===================
 */
OS_STK TaskStartStk[TASK_STK_SIZE]; /* START task stack */
OS_STK Task1Stk[TASK_STK_SIZE]; /* Task #1 stack */
OS_STK Task2Stk[TASK_STK_SIZE]; /* Task #2 stack */
//OS_STK Task3Stk[TASK_STK_SIZE]; /* Task #3 stack */
//OS_STK Task4Stk[TASK_STK_SIZE]; /* Task #4 stack */
 
/* ...........................................................................
 *
 * 사용자 메모리 정의
 * ===================
 */
TASK_USER_DATA  TaskUserData[7];
 
/* ...........................................................................
 *
 * 이벤트 컨트롤 & 사용자 정의 블럭 정의
 * ===================
 */
OS_EVENT *sem_id;    /* Semaphore Pointer */
 
extern INT32U USE_OSTimeTickHook;
 
/* ...........................................................................
 *
 * 태스크 함수 원형
 * ===================
 */
void  TaskStart(void *pdata); /* Function prototypes of Startup task */
void  spost(void *pdata);
void  Task2(void *pdata);          
void  Task3(void *pdata);
void  Task4(void *pdata);
 
//
// 어플리케이션 메인 루틴
//
int main(void)
{
    OSInit(); /* microC/OS-II 초기화 */
 
    strcpy(TaskUserData[TASK_START_ID].TaskName, "TaskStart");
    
    // TASK CREATE
    OSTaskCreateExt(TaskStart,
                   (void *)0,
                   &TaskStartStk[TASK_STK_SIZE-1],
                   TASK_START_PRIO,
                   TASK_START_ID,
                   &TaskStartStk[0],
                   TASK_STK_SIZE,
                   &TaskUserData[TASK_START_ID],
                   OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
 
    OSStart(); /* start scheduler */
 
    return 0;    
}
 
//
// 태스크 'START'
//
void  TaskStart (void *pdata)
{
    INT8U err;
    int sem_init;
    OS_SEM_DATA sem_val;    // semaphore control
    int loops;
 
    pdata = pdata;                /* 컴파일러 경고를 막기 위함 */
    
    USE_OSTimeTickHook = 0
    
    // 시스템 초기화(UART, LCD, TimeTick)
    InitSystem();    
 
    OSStatInit();                /* Initialize uC/OS-II's 통계 함수 */
 
    // 세마포어 초기값
    sem_init = 1; //초기값이 1이라서 . 을 찍고 시작한다.
 
    /* TODO #1: 
        create a binary semaphore
        use sem_id and sem_init */
#if 1
    sem_id=OSSemCreate(sem_init);
#endif // TODO #1
 
    // 세마포어 쿼리
    err = OSSemQuery(sem_id, &sem_val);
    if (err) printf("OSSemQuery error found, code[0x%X]\n",err);
 
    strcpy(TaskUserData[TASK_1_ID].TaskName, "spost");
 
    // TASK CREATE
    OSTaskCreateExt(spost,
                    (void *)0,
                    &Task1Stk[TASK_STK_SIZE - 1],
                    TASK_1_PRIO,
                    TASK_1_ID,
                    &Task1Stk[0],
                    TASK_STK_SIZE,
                    &TaskUserData[TASK_1_ID],
                    0);
    // loop counter
    loops = 10;
    for(;;) {
        // 세마포어 대기
        OSSemPend(sem_id, 0&err); //대기상태로 빠짐
        printf("."); fflush(stdout);
        err = OSSemQuery(sem_id, &sem_val);
        if (err) printf("OSSemQuery error found, code[0x%X]\n",err);
 
        if(loops == 0)
            break// exit
 
        loops--;
    }
 
    /* TODO #3: 
        delete a semaphore */
#if 0
  OSSemDel(sem_id, OS_DEL_ALWAYS, &err);
#endif // TODO #3
 
    /* delete self task */
    err = OSTaskDel(OS_PRIO_SELF);
    if (err) printf("OSTaskDel(OS_PRIO_SELF) error found, code[0x%X]\n",err);
}
 
//
// 태스크 'spost'
//
void spost(void *pdata)
{
    INT8U err;
    
    pdata = pdata;                /* 컴파일러 경고를 막기 위함 */
 
    printf("spost TASK created,\n");
 
    for(;;) {
    /* TODO #2: 
        post to a semaphore */
#if 1
        err = OSSemPost(sem_id);
#endif // TODO #2
        if (err) printf("OSSemPost error found, code[0x%X]\n",err);
        OSTimeDly(100); //1초마다 깨운다.
     }
}
 
/*-----------------------------------------------------------------------------
 * Program : 06_SEM.C
-----------------------------------------------------------------------------*/
 

cs




ROTS에서 세마포어를 쓸때 예외처리는 매우 중요하다.


■뮤텍스


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
/*******************************************************************************
**    File:
**
**        07_MUTEX.c
**
**  Contents:
**        uC/OS-II programming
**
**    History:
**        Date        Name              Description
**        ------------------------------------------------------------------------
**
*******************************************************************************/
#include "includes.h"
 
/* ...........................................................................
 *
 * 태스크 스택 정의
 * ===================
 */
 
int tickets;        // MAX value( 1000 million )
int backupTickets;
int T1_Ticket=0, T2_Ticket= 0;
 
OS_STK TaskStartStk[TASK_STK_SIZE]; /* START task stack */
OS_STK Task1Stk[TASK_STK_SIZE]; /* Task #1 stack */
OS_STK Task2Stk[TASK_STK_SIZE]; /* Task #2 stack */
//OS_STK Task3Stk[TASK_STK_SIZE]; /* Task #3 stack */
//OS_STK Task4Stk[TASK_STK_SIZE]; /* Task #4 stack */
 
/* ...........................................................................
 *
 * 사용자 메모리 정의
 * ===================
 */
TASK_USER_DATA  TaskUserData[7];
 
/* ...........................................................................
 *
 * 이벤트 컨트롤 & 사용자 정의 블럭 정의
 * ===================
 */
#define TICKET_1BILLION        1000000000
#define TICKET_1MILLION        1000000
#define TICKET_10000        10000
#define TICKET_1000            1000
 
OS_EVENT *mid;
 
extern void seedrand(int seed);
extern int randomnumber(void);
int buyTicket(void);
// 1초마다 콘솔에 동작중을 표시(.)
extern INT32U USE_OSTimeTickHook;
 
/* ...........................................................................
 *
 * 태스크 함수 원형
 * ===================
 */
void  TaskStart(void *pdata); /* Function prototypes of Startup task */
void  Task1(void *pdata);
void  Task2(void *pdata);        
void  Task3(void *pdata);
void  Task4(void *pdata);
 
//
// 어플리케이션 메인 루틴
//
int main(void)
{
    OSInit(); /* microC/OS-II 초기화 */
 
    PC_ElapsedInit(); /* Initialized elapsed time measurement     */
 
    strcpy(TaskUserData[TASK_START_ID].TaskName, "TaskStart");
    
    // TASK CREATE
    OSTaskCreateExt(TaskStart,
                   (void *)0,
                   &TaskStartStk[TASK_STK_SIZE-1],
                   TASK_START_PRIO,
                   TASK_START_ID,
                   &TaskStartStk[0],
                   TASK_STK_SIZE,
                   &TaskUserData[TASK_START_ID],
                   OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
 
    OSStart(); /* start scheduler */
 
    return 0;    
}
 
//
// 태스크 'START'
//
void  TaskStart (void *pdata)
{
    INT8U err;
    OS_MUTEX_DATA mutex_data;    // mutex control
    
    pdata = pdata;                /* 컴파일러 경고를 막기 위함 */
 
    // 시스템 초기화(UART, LCD, TimeTick)
    InitSystem();    
 
    OSStatInit();                /* Initialize uC/OS-II's 통계 함수 */
 
    // 1초마다 콘솔에 동작중을 표시(.)
    USE_OSTimeTickHook = 1// refer to 'OS_CPU_C.C'
 
    /* TODO #1: 
        create a mutex
        use mid and priority= 3*/
#if 1
    mid = OSMutexCreate(3,&err);
    if (err) printf("OSMutexQuery error found, code[0x%X]\n",err);
#endif // TODO #1
 
    // 뮤텍스 쿼리
    err = OSMutexQuery(mid, &mutex_data);
    if (err) printf("OSMutexQuery error found, code[0x%X]\n",err);
 
    //
    // set random seed
    //
    seedrand( 45 );
    
    // Set Tickets
    tickets= backupTickets = 10 * TICKET_1MILLION; // MAX value( 1 million )
 
    // TASK CREATE
    strcpy(TaskUserData[TASK_1_ID].TaskName, "Task1");
    OSTaskCreateExt(Task1,
                    (void *)0,
                    &Task1Stk[TASK_STK_SIZE - 1],
                    TASK_1_PRIO,
                    TASK_1_ID,
                    &Task1Stk[0],
                    TASK_STK_SIZE,
                    &TaskUserData[TASK_1_ID],
                    0);
    if (err) printf("OSTaskCreate error found, code[0x%X]\n",err);
 
    // TASK CREATE
    strcpy(TaskUserData[TASK_2_ID].TaskName, "Task2");
    OSTaskCreateExt(Task2,
                    (void *)0,
                    &Task2Stk[TASK_STK_SIZE - 1],
                    TASK_2_PRIO,
                    TASK_2_ID,
                    &Task2Stk[0],
                    TASK_STK_SIZE,
                    &TaskUserData[TASK_2_ID],
                    0);
    if (err) printf("OSTaskCreate error found, code[0x%X]\n",err);
 
    /* delete self task */
    err = OSTaskDel(OS_PRIO_SELF);
    if (err) printf("OSTaskDel(OS_PRIO_SELF) error found, code[0x%X]\n",err);
}
 
//
// 태스크 1
//
void Task1(void *pdata)
{
    INT8U err;
    OS_MUTEX_DATA mutex_data;    // mutex control
    
    pdata = pdata;                /* 컴파일러 경고를 막기 위함 */
 
    printf("\n\nTask1 TASK created,\n");
 
    while(1) {
        if(buyTicket() <= 0)
        {
            T1_Ticket++;
            printf("\n[TASK1]COUNTER up to %d\n", T1_Ticket);
            /* delete other task */
            err = OSTaskDel(TASK_2_PRIO);
            break;
        }
        T1_Ticket++;
        OSTimeDly(2);
    }
 
    printf("[TASK1]Total Tickets = %d\n", T1_Ticket + T2_Ticket);
 
    if(backupTickets != (T1_Ticket + T2_Ticket))
        printf("Not good. ticket size is different\n");
    else
        printf("Good!. matched\n");
 
    /* TODO #3: 태스크2 에도 같은게 또 있습니다. 작성하세요
        delete a mutex */
#if 0
 
#endif // TODO #3
 
    // 뮤텍스 쿼리
    err = OSMutexQuery(mid, &mutex_data);
    if (err) printf("OSMutexQuery error found, code[0x%X]\n",err);
 
 
    // 1초마다 콘솔 출력 '중지'
    USE_OSTimeTickHook = 0// refer to 'OS_CPU_C.C'
 
    /* delete self task */
    err = OSTaskDel(OS_PRIO_SELF);
    if (err) printf("OSTaskDel(OS_PRIO_SELF) error found, code[0x%X]\n",err);
}
 
//
// 태스크 2
//
void Task2(void *pdata)
{
    INT8U err;
    OS_MUTEX_DATA mutex_data;    // mutex control
    INT32U timeo;
    int i;
 
    pdata = pdata;                /* 컴파일러 경고를 막기 위함 */
 
    printf("Task2 TASK created,\n");
 
    while(1) {
        for(i=0;i<100000;i++)
        {
            if(buyTicket()==0)
            {
                T2_Ticket++;
                printf("\n[TASK2]COUNTER up to %d\n", T2_Ticket);
                /* delete other task */
                err = OSTaskDel(TASK_1_PRIO);
                goto exit;
            }
            T2_Ticket++;
        }
        timeo = randomnumber();
        OSTimeDly(timeo % 3);
    }
 
exit:
    printf("[TASK2]Total Tickets = %d\n", T1_Ticket + T2_Ticket);
 
    if(backupTickets != (T1_Ticket + T2_Ticket))
        printf("Not good. ticket size is different\n");
    else
        printf("Good!. matched\n");
 
    /* TODO #3: 태스크1 에도 같은게 또 있습니다. 작성하세요
        delete a mutex */
#if 0
 
#endif // TODO #3
 
    // 뮤텍스 쿼리
    err = OSMutexQuery(mid, &mutex_data);
    if (err) printf("OSMutexQuery error found, code[0x%X]\n",err);
 
    // 1초마다 콘솔 출력 '중지'
    USE_OSTimeTickHook = 0// refer to 'OS_CPU_C.C'
 
    /* delete self task */
    err = OSTaskDel(OS_PRIO_SELF);
    if (err) printf("OSTaskDel(OS_PRIO_SELF) error found, code[0x%X]\n",err);
}
 
//
// buyTicket
//
int buyTicket(void)
{
    OS_CPU_SR cpu_sr;
    INT8U err;
 
    /* TODO #2: 
        MUTEX 을 이용하여 
        공유변수(tickets)를 보호한다 */
#if 1
    // CRITICAL SECTION(ENTER)
    OSMutexPend(mid,0,&err);
#endif // TODO #2
 
    tickets --;    // ticket count
 
#if 1
    // CRITICAL SECTION(EXIT)
    OSMutexPost(mid);
#endif // TODO #2
 
    return(tickets);
}
 
/*-----------------------------------------------------------------------------
 * Program : 07_MUTEX.C
-----------------------------------------------------------------------------*/
 
cs




■이벤트 플래그

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*******************************************************************************
**    File:
**
**        08_FLAG.c
**
**  Contents:
**        uC/OS-II programming
**
**    History:
**        Date        Name              Description
**        ------------------------------------------------------------------------
**
*******************************************************************************/
#include "includes.h"
    
/* ...........................................................................
 *
 * 태스크 스택 정의
 * ===================
 */
OS_STK TaskStartStk[TASK_STK_SIZE]; /* START task stack */
OS_STK Task1Stk[TASK_STK_SIZE]; /* Task #1 stack */
//OS_STK Task2Stk[TASK_STK_SIZE]; /* Task #2 stack */
//OS_STK Task3Stk[TASK_STK_SIZE]; /* Task #3 stack */
//OS_STK Task4Stk[TASK_STK_SIZE]; /* Task #4 stack */
 
/* ...........................................................................
 *
 * 사용자 메모리 정의
 * ===================
 */
TASK_USER_DATA  TaskUserData[7];
 
/* ...........................................................................
 *
 * 이벤트 컨트롤 & 사용자 정의 블럭 정의
 * ===================
 */
#define ENGINE_OIL_PRES_OK 0x01 
#define ENGINE_OIL_TEMP_OK 0x02 
#define ENGINE_START 0x04 
 
OS_FLAG_GRP *group_id; 
 
/* ...........................................................................
 *
 * 태스크 함수 원형
 * ===================
 */
void  TaskStart(void *pdata); /* Function prototypes of Startup task */
void  Task1(void *pdata);
void  Task2(void *pdata);          
void  Task3(void *pdata);
void  Task4(void *pdata);
 
//
// 어플리케이션 메인 루틴
//
int main(void)
{
    OSInit(); /* microC/OS-II 초기화 */
 
    strcpy(TaskUserData[TASK_START_ID].TaskName, "TaskStart");
    
    // TASK CREATE
    OSTaskCreateExt(TaskStart,
                   (void *)0,
                   &TaskStartStk[TASK_STK_SIZE-1],
                   TASK_START_PRIO,
                   TASK_START_ID,
                   &TaskStartStk[0],
                   TASK_STK_SIZE,
                   &TaskUserData[TASK_START_ID],
                   OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
 
    OSStart(); /* start scheduler */
 
    return 0;    
}
 
//
// 태스크 'START'
//
void  TaskStart (void *pdata)
{
    INT8U err;
    OS_FLAGS flag_value;
    OS_FLAG_GRP *pgrp; // event flag group
    
    pdata = pdata;                /* 컴파일러 경고를 막기 위함 */
 
    // 시스템 초기화(UART, LCD, TimeTick)
    InitSystem();    
 
    OSStatInit();                /* Initialize uC/OS-II's 통계 함수 */
 
    /* TODO #1: 
        create a event flag
        use group_id and initial value= 0*/
#if 1
    group_id=OSFlagCreate(-1,&err);
    if (err) printf("OSFlagQuery error found, code[0x%X]\n",err);
#endif // TODO #1
 
    // 뮤텍스 쿼리
    flag_value = OSFlagQuery(group_id, &err);
    if (err) printf("OSFlagQuery error found, code[0x%X]\n",err);
 
    strcpy(TaskUserData[TASK_1_ID].TaskName, "task1");
 
    // TASK CREATE
    OSTaskCreateExt(Task1,
                    (void *)0,
                    &Task1Stk[TASK_STK_SIZE - 1],
                    TASK_1_PRIO,
                    TASK_1_ID,
                    &Task1Stk[0],
                    TASK_STK_SIZE,
                    &TaskUserData[TASK_1_ID],
                    0);
    if (err) printf("OSTaskCreateExt error found, code[0x%X]\n",err);
 
    for(;;) {
    /* TODO #2:
        get flag 'ENGINE_OIL_PRES_OK' OR 'ENGINE_OIL_TEMP_OK' from TASK2 */
#if 1
        OSFlagPend(group_id,ENGINE_OIL_PRES_OK + ENGINE_OIL_TEMP_OK, OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME,0,&err);
 
#endif // TODO #2
 
        printf("."); fflush(stdout);
    }
 
    // 이벤트 플래그 삭제
    pgrp = OSFlagDel(group_id, OS_DEL_ALWAYS, &err); 
    if (pgrp == (OS_FLAG_GRP *)0) { 
    /* The event flag group was deleted */ 
    } 
 
    /* delete self task */
    err = OSTaskDel(OS_PRIO_SELF);
    if (err) printf("OSTaskDel(OS_PRIO_SELF) error found, code[0x%X]\n",err);
}
 
//
// 태스크 1
//
void Task1(void *pdata)
{
    INT8U err;
      
    pdata = pdata;                /* 컴파일러 경고를 막기 위함 */
 
    printf("\n\nTask1 created,\n");
 
    for(;;) {
    /* TODO #2: 
        post flag 'ENGINE_OIL_PRES_OK' to TASK1 */
#if 1
        OSFlagPost(group_id,ENGINE_OIL_PRES_OK,OS_FLAG_SET,&err);
#endif // TODO #2
 
        OSTimeDly(100);
    }
}
 
/*-----------------------------------------------------------------------------
 * Program : 08_FLAG.C
-----------------------------------------------------------------------------*/
 
cs





■메시지큐

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
/*******************************************************************************
**    File:
**
**        10_QUE.c
**
**  Contents:
**        uC/OS-II programming
**
**    History:
**        Date        Name              Description
**        ------------------------------------------------------------------------
**
*******************************************************************************/
#include "includes.h"
    
/* ...........................................................................
 *
 * 태스크 스택 정의
 * ===================
 */
OS_STK TaskStartStk[TASK_STK_SIZE]; /* START task stack */
OS_STK Task1Stk[TASK_STK_SIZE]; /* Task #1 stack */
OS_STK Task2Stk[TASK_STK_SIZE]; /* Task #2 stack */
//OS_STK Task3Stk[TASK_STK_SIZE]; /* Task #3 stack */
//OS_STK Task4Stk[TASK_STK_SIZE]; /* Task #4 stack */
 
/* ...........................................................................
 *
 * 사용자 메모리 정의
 * ===================
 */
TASK_USER_DATA  TaskUserData[7];
 
/* ...........................................................................
 *
 * 이벤트 컨트롤 & 사용자 정의 블럭 정의
 * ===================
 */
OS_EVENT *qid;    /* Message Queue Pointer */
void *qBuffer[10];
 
extern INT32U USE_OSTimeTickHook;
 
/* ...........................................................................
 *
 * 태스크 함수 원형
 * ===================
 */
void  TaskStart(void *pdata); /* Function prototypes of Startup task */
void  qpend(void *pdata);
void  qpost(void *pdata);          
void  Task3(void *pdata);
void  Task4(void *pdata);
 
//
// 어플리케이션 메인 루틴
//
int main(void)
{
    OSInit(); /* microC/OS-II 초기화 */
 
    strcpy(TaskUserData[TASK_START_ID].TaskName, "TaskStart");
    
    // TASK CREATE
    OSTaskCreateExt(TaskStart,
                   (void *)0,
                   &TaskStartStk[TASK_STK_SIZE-1],
                   TASK_START_PRIO,
                   TASK_START_ID,
                   &TaskStartStk[0],
                   TASK_STK_SIZE,
                   &TaskUserData[TASK_START_ID],
                   OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
 
    OSStart(); /* start scheduler */
 
    return 0;    
}
 
//
// 태스크 'START'
//
void  TaskStart (void *pdata)
{
    void qpend(void *pdata), qpost(void *pdata);
//    long timeout= 200L;            /* Wait Forever */
    INT8U err;
    char *msg;
    OS_Q_DATA qdata;
    
    pdata = pdata;                /* 컴파일러 경고를 막기 위함 */
 
    USE_OSTimeTickHook = 0;
    
    // 시스템 초기화(UART, LCD, TimeTick)
    InitSystem();    
 
    OSStatInit();                /* Initialize uC/OS-II's 통계 함수 */
 
    /* TODO #1: 
        create a Queue
        use qid and qBuffer[] */
#if 1
    qid = OSQCreate(qBuffer,10);
#endif // TODO #1
 
    // 큐(QUEUE) 쿼리 
    err = OSQQuery(qid, &qdata);
    if (err) printf("OSQQuery error found, code[0x%X]\n",err);
 
    strcpy(TaskUserData[TASK_1_ID].TaskName, "qpend");
 
    // TASK CREATE
    OSTaskCreateExt(qpend,
                    (void *)0,
                    &Task1Stk[TASK_STK_SIZE - 1],
                    TASK_1_PRIO,
                    TASK_1_ID,
                    &Task1Stk[0],
                    TASK_STK_SIZE,
                    &TaskUserData[TASK_1_ID],
                    0);
 
    strcpy(TaskUserData[TASK_2_ID].TaskName, "qpost");
 
    // TASK CREATE
    OSTaskCreateExt(qpost,
                    (void *)0,
                    &Task2Stk[TASK_STK_SIZE - 1],
                    TASK_2_PRIO,
                    TASK_2_ID,
                    &Task2Stk[0],
                    TASK_STK_SIZE,
                    &TaskUserData[TASK_2_ID],
                    0);
 
    OSTimeDly(500);
 
    /* TODO #2: 
        broadcast a message to all TASKs
        message : "Do you hear me?[john said]" */
#if 1
    OSQPostOpt(qid,"Do you hear me?[john said]",OS_POST_OPT_BROADCAST);
#endif // TODO #2
 
    printf("\n.\n.\n.\n.\non AIR...\n.\n.\n.\n.\n");
 
    /* delete self task */
    err = OSTaskDel(OS_PRIO_SELF);
    if (err) printf("OSTaskDel(OS_PRIO_SELF) error found, code[0x%X]\n",err);
}
 
//
// 태스크 'qpend'
//
void qpend(void *pdata)
{
    INT8U err;
    char *p;
    long timeout= 200L;            /* for ever */
    
    pdata = pdata;                /* 컴파일러 경고를 막기 위함 */
 
    printf("[qpend]waiting...\n");
 
    // 메시지 큐 '브로드캐스트' 대기
    p = OSQPend(qid, 0&err); /* Wake up By Queue Broadcast */
    if (err) printf("OSQPend error found, code[%d]\n",err);
    printf("[qpend]sync %s\n",p);
 
    for(;;) {
        // 메시지 큐 대기
        p = OSQPend(qid, timeout, &err);
        if (err)
            printf("OSQPend error found, code[0x%X]\n",err);
        else
            printf("get message \"%d\" from TASK qpost\n",*p);
    }
}
 
//
// 태스크 'qpost'
//
void qpost(void *pdata)
{
    INT8U err;
    char *p;
    char msg[80];
    int i;
 
    pdata = pdata;                /* 컴파일러 경고를 막기 위함 */
 
    printf("[qpost]waiting...\n");
 
    // 메시지 큐 '브로드캐스트' 대기
    p = OSQPend(qid, 0&err); /* Wake up By Queue Broadcast */
    if (err) printf("OSQPend error found, code[%d]\n",err);
    printf("[qpost]sync %s\n",p);
 
    for(i=1; i< 10000; i++) {
        msg[0= i; msg[1]= NULL;
 
    /* TODO #3: 
        post a message to TASK qpend
        use msg[] */
#if 1
        OSQPost(qid,msg);
#endif // TODO #3
 
        OSTimeDly(100);
    }
}
 
/*-----------------------------------------------------------------------------
 * Program : 10_QUE.C
-----------------------------------------------------------------------------*/
 
cs





'RTOS' 카테고리의 다른 글

[RTOS_Day5]RTOS 포팅 진행 기록_2  (0) 2018.12.27
[RTOS_Day4]RTOS 포팅 진행 기록  (0) 2018.12.26
[RTOS_Day3]통계 테스크  (0) 2018.12.19
[RTOS_Day2]임계영역 보호  (0) 2018.12.18
[RTOS_Day2]시간관리 함수  (2) 2018.12.18


포팅_2■


RTOS는 타이머 인터럽트가 꼭있어야하기 때문에 미리 만들어 놓으면 좋다.


$ pwd

03.ucos2-timer


$ cp timer.c /home/mds/FreeRTOSv10.1.1/FreeRTOS/Source/portable/GCC/ARM7_AT91FR40008/



1.

makefile 수정

THUMB_SRC = 

../../Source/portable/GCC/ARM7_AT91FR40008/timer.c    추가


컴파일 해보기




2ucon 예제3번 timer.c 참고하여


port.c에 수정


#include "2450addr.h"

#include "option.h"

#include "my_lib.h"


extern unsigned int HandleTIMER0;


#else

//MDS2450's TIMER

/* 

* Timer0 Init 

* Prescaler value : 255, dead zone length = 0

* Divider value : 1/16, no DMA mode

* New frequency : (PCLK/(Prescaler value+1))*Divider value = (66Mhz/(256))*(1/16)

* = 16.113Khz(16113Hz)

*/

rTCFG0 = (0<<8)|(0xff); 

rTCFG1 = (0<<20)|(3); 

/* TCON¼³Á¤ :Dead zone disable,  auto reload on, output inverter off

*  manual update no operation, timer0 stop, TCNTB0=0, TCMPB0 =0

*/

rTCON  = (0<<4)|(1<<3)|(0<<2)|(0<<1)|(0);

rTCNTB0 = 0;

rTCMPB0 = 0;



#if configUSE_PREEMPTION == 1

{

extern void ( vPreemptiveTick )( void );

HandleTIMER0 = (unsigned int)vPreemptiveTick; //register a interrupt vector for timer0

    /* Interrupt Unmasking */

      rINTMSK1 &= ~(1<<10);

}

#else  // else use cooperative scheduler

{

extern void ( vNonPreemptiveTick )( void );

HandleTIMER0 = (unsigned int)vNonPreemptiveTick; //register a interrupt vector for timer0

    /* Interrupt Unmasking */

      rINTMSK1 &= ~(1<<10);

}

#endif


rTCNTB0 = 16113/configTICK_RATE_HZ; //MCU의 16.113*msec를 RTOS에서 비슷하게

rTCON |= (1<<1)|(0);

rTCON &= ~(1<<1);

rTCON |= 1;


#endif


3.

../../Source/portable/GCC/ARM7_AT91FR40008/timer.c    제거



4.

/*    flash.c-Minimal    */


#define ledNUMBER_OF_LEDS ( 1 )         ->    수정


void vStartLEDFlashTasks( UBaseType_t uxPriority )

{

BaseType_t xLEDTask;


/* Create the three tasks. */

for( xLEDTask = 0; xLEDTask < ledNUMBER_OF_LEDS; ++xLEDTask )

{

printf("vStartLEDFlashTasks\n");

/* Spawn the task. */

xTaskCreate( vLEDFlashTask, "LEDx", ledSTACK_SIZE, NULL, uxPriority, ( TaskHandle_t * ) NULL );

}

}

/*    flash.c-Minimal    */

static void vLEDFlashTask( void *pvParameters )

{

xLEDParameters *pxParameters;


/* Queue a message for printing to say the task has started. */

vPrintDisplayMessage( &pcTaskStartMsg );


pxParameters = ( xLEDParameters * ) pvParameters;


for(;;)

{

printf("togle@\n");

/* Delay for half the flash period then turn the LED on. */

vTaskDelay( pxParameters->xFlashRate / ( TickType_t ) 2 );

vParTestToggleLED( pxParameters->uxLED );


/* Delay for half the flash period then turn the LED off. */

vTaskDelay( pxParameters->xFlashRate / ( TickType_t ) 2 );

vParTestToggleLED( pxParameters->uxLED );

}

}



5.

필요없는 소스 삭제


$ pwd

/home/mds/FreeRTOSv10.1.1/FreeRTOS/Source/portable


rm -rf !(Common|GCC|MemMang|ThirdParty|Tasking)


$ pwd

/home/mds/FreeRTOSv10.1.1/FreeRTOS/Source/portable/GCC


rm -r !(ARM7_AT91FR40008)


6.
검색 shift + Ctrl + F 
[\t\s]+swi[\t\s]
boot.s 보기


/*    exception.c    */
void vPortYieldProcessor(void);

HandleSWI    = (unsigned)vPortYieldProcessor;


로 수정



7.

/*   portISR    */ 


#if configUSE_PREEMPTION == 0


/* The cooperative scheduler requires a normal IRQ service routine to 

simply increment the system tick. */

void vNonPreemptiveTick( void ) __attribute__ ((interrupt ("IRQ")));

void vNonPreemptiveTick( void )

{

static volatile uint32_t ulDummy;


/* Clear tick timer interrupt indication. */

//ulDummy = portTIMER_REG_BASE_PTR->TC_SR;  


xTaskIncrementTick();

       /* TODO : Pending Register Clear */

        rSRCPND1 = (1<<10);

        rINTPND1 = (1<<10);


  //      tick++;


/* Acknowledge the interrupt at AIC level... */

//AT91C_BASE_AIC->AIC_EOICR = portCLEAR_AIC_INTERRUPT;

}


#else  /* else preemption is turned on */


/* The preemptive scheduler is defined as "naked" as the full context is

saved on entry as part of the context switch. */

void vPreemptiveTick( void ) __attribute__((naked));

void vPreemptiveTick( void )

{

/* Save the context of the interrupted task. */

portSAVE_CONTEXT();


/* WARNING - Do not use local (stack) variables here.  Use globals

if you must! */

static volatile uint32_t ulDummy;


/* Clear tick timer interrupt indication. */

// ulDummy = portTIMER_REG_BASE_PTR->TC_SR;  


/* Increment the RTOS tick count, then look for the highest priority 

task that is ready to run. */

if( xTaskIncrementTick() != pdFALSE )

{

vTaskSwitchContext();

}


/* Acknowledge the interrupt at AIC level... */

//AT91C_BASE_AIC->AIC_EOICR = portCLEAR_AIC_INTERRUPT;

       /* TODO : Pending Register Clear */

        rSRCPND1 = (1<<10);

        rINTPND1 = (1<<10);


   //     tick++;


/* Restore the context of the new task. */

portRESTORE_CONTEXT();

}


로 수정해서 컴파일하면 LED 깜빡이는 것을 볼 수 있습니다.




<    포팅의 유형    >


1. CS8900 이더넷 컨트롤러를 DM9000 칩으로 변경


2. 블루투스 지원을 하기 위한 소프트웨어를 찾고 이를 이식


3. 커널을 업그레이드


4. 오픈소스(VLC)을 포팅


5. 커널을 커스텀 보드에 이식








포팅■


먼저 사이트에 들어가서 자료를 받습니다.


임베디드 포팅에서는 길을 선택하는것과 같다. 

한번 선택한 길이 꼬이면 처음부터 다시시작하는 마음가짐으로 시작한다.



$ pwd

/home/mds/FreeRTOSv10.1.1


$ tree -L 2

.

├── FreeRTOS

│   ├── Demo

│   ├── License

│   ├── links_to_doc_pages_for_the_demo_projects.url

│   ├── readme.txt

│   └── Source

├── FreeRTOS-Plus

│   ├── Demo

│   ├── readme.txt

│   └── Source

├── New - FreeRTOS+TCP.url

├── New - Stream and Message Buffers.url

├── Quick_Start_Guide.url

├── readme.txt

├── Upgrading-to-FreeRTOS-10.url

└── Upgrading-to-FreeRTOS-9.url


7 directories, 9 files


$ cd FreeRTOS/Demo

$ tree -L 2                ==>파일들 확인



여기서 컴파일을 선택해야하는데 이때 소스를 열어본다(makefile) 선택기준 ->>어떻게 해야 빨리 끝날까?

최대한 분석안하고 빨리 끝내는 것이 중요!




$cd ARM7_AT91FR40008_GCC

$make


arm-elf-gcc -c -Wall -Wextra -D  -D GCC_AT91FR40008 -I. -I../../Source/include -I../Common/include  -mcpu=arm7tdmi -T -Wcast-align  -fomit-frame-pointer -fno-strict-aliasing -fno-dwarf2-cfi-asm ../../Source/portable/GCC/ARM7_AT91FR40008/portISR.c -o ../../Source/portable/GCC/ARM7_AT91FR40008/portISR.o

make: execvp: arm-elf-gcc: Not a directory

make: *** [../../Source/portable/GCC/ARM7_AT91FR40008/portISR.o] Error 127


우선  make 해본다


makefile안에


CC=arm-none-eabi-gcc

OBJCOPY=arm-none-eabi-objcopy

ARCH=arm-none-eabi-ar

로 수정




$ make

arm-none-eabi-gcc -c -Wall -Wextra -D  -D GCC_AT91FR40008 -I. -I../../Source/include -I../Common/include  -mcpu=arm7tdmi -T -Wcast-align  -fomit-frame-pointer -fno-strict-aliasing -fno-dwarf2-cfi-asm ../../Source/portable/GCC/ARM7_AT91FR40008/portISR.c -o ../../Source/portable/GCC/ARM7_AT91FR40008/portISR.o

arm-none-eabi-gcc: GCC_AT91FR40008: No such file or directory

<command-line>:0:1: error: macro names must be identifiers

In file included from ../../Source/include/FreeRTOS.h:62:0,

                 from ../../Source/portable/GCC/ARM7_AT91FR40008/portISR.c:44:

../../Source/include/portable.h:52:24: fatal error: portmacro.h: No such file or directory

compilation terminated.

make: *** [../../Source/portable/GCC/ARM7_AT91FR40008/portISR.o] Error 1



$ grep -rni GCC_AT91FR40008 .

./Makefile:36:CFLAGS=-Wall -Wextra -D $(RUN_MODE) -D GCC_AT91FR40008 -I. -I../../Source/include 



******옵션을주어서 make를 스크립트로 되어있다.


$ chmod +x ram_arm.bat 

$ ./ram_arm.bat 

: command not found 6: make



ram_arm.bat을 수정 (set없애고 한줄로 )

USE_THUMB_MODE=NO DEBUG=-g OPTIM=-O0 RUN_MODE=RUN_FROM_RAM LDSCRIPT=atmel-ram.ld make


$ ./ram_arm.bat 
컴파일이 된다.



$ date +"%y%m%d%H%M"
1812261019
$ mkdir ~/backup

$ date=$(date +"%y%m%d%H%M");tar zcf ~/backup/backup_FreeRTOS_${date}.tar.gz ~/FreeRTOSv10.1.1/FreeRTOS


$ echo alias b='date=$(date +"%y%m%d%H%M");tar zcf ~/backup/backup_FreeRTOS_${date}.tar.gz ~/FreeRTOSv10.1.1/FreeRTOS' >> ~/.bachrc

편하게 alias 등록


$ vim HISTORY
- ARM7_AT91FR40008_GCC compile ok

기록을 남긴다.

$b


$ ll ~/backup/

-rw-r--r--  1 mds adm 14893056 2018-12-26 10:22 backup_FreeRTOS_1812261022.tar.gz
백업



$ cd ucos2/

$ subl .
$ make


Main.o exception.o libc.o Uart.o syscall.o s3c2450_startup.o libs.o
(필수)                                              (필수:부트코드)
여기에 있는 파일들을 옮긴다. 같은이름이 있는지 주의(최소한의 파일만 가져온다.)
(tip. 복사하지 않고 이동시키면 남아있는 파일 보이가 수월)

~/FreeRTOSv10.1.1/FreeRTOS/Demo/ARM7_AT91FR40008_GCC# subl ../../

1. ARM7_AT91FR40008_GCC에서 main.c를 main_org.c로 이름바꾸고 Main.c를 복사해서 넣는다.

2. ARM7_AT91FR40008_GCC으로 s3c2450_startup.S복사해서 넣는다.
makefile 수정
CRT0=s3c2450_startup.S   으로

3. main_org.c를 다시 main.c로 바꾼다.

4. make

5. ARM7_AT91FR40008_GCC으로 2450addr.inc

6. makefile 수정
THUMB_SRC = \
exception.c \
libc.c \
Uart.c \
syscall.c \
libs.S \
main.c \

7.후 에러나는 파일들을 하나씩 가져온다.

8. makefile에서 libs.S \를 지우고

9. ARM7_AT91FR40008_GCC으로 S3C2450-RAM.ld복사후 원래 atmel-ram.ld와 
CRT0=s3c2450_startup.S libs.S 수정
추가

10.ram_arm.bat을 수정

USE_THUMB_MODE=NO DEBUG=-g OPTIM=-O0 RUN_MODE=RUN_FROM_RAM LDSCRIPT=S3C2450-RAM.ld make


11.make clean; ./ram_arm.bat 2>&1 | tee log

log파일로 저장후 검색해서 사용  libs가 .o로 되어있어야한다.


12. 

s3c2450_startup.S:207: Error: garbage following instruction -- `sub sp,sp,#4//reserved for PC'
오류

        sub     sp,sp,#4       //reserved for PC에서

  //reserved for PC를 지운다.


13. 메뉴에 find -> replace

정규식 표현 사용

Find : //(.+)

Replace :/* \1 */

모두 바꿔준다.


14.

CRT0_SRC=s3c2450_startup.S libs.S    수정


CRT0_OBJ=$(CRT0_SRC:.S=.o)    추가


rtosdemo.elf : $(ARM_OBJ) $(THUMB_OBJ) $(CRT0_OBJ) Makefile

$(CC) $(CFLAGS) $(ARM_OBJ) $(THUMB_OBJ) -nostartfiles $(CRT0_OBJ) $(LINKER_FLAGS)    수정


$(CRT0_OBJ) : %.o : %.S $(LDSCRIPT) Makefile

$(CC) -c $(CFLAGS) $< -o $@                추가



15. Main과 main를 바꿔준다.


# make clean ; ./ram_arm.bat 

잘된다.


16. 
OCFLAGS = -O binary -R .note -R .comment -S

$(OBJCOPY) $(OCFLAGS) $(TOPDIR)/MDS2450 $(TOPDIR)/$@
cp $(TOPDIR)/$@ /tftpboot
예제 이부분을 가져와서 makefile에 넣는다.



17. rtosdemo    ->    MDS2450 로 모두 바꾼다.





최종 수정후  makefile 


#/*

# * FreeRTOS Kernel V10.1.1

# * Copyright (C) 2018 Amazon.com, Inc. or its affiliates.  All Rights Reserved.

# *

# * Permission is hereby granted, free of charge, to any person obtaining a copy of

# * this software and associated documentation files (the "Software"), to deal in

# * the Software without restriction, including without limitation the rights to

# * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of

# * the Software, and to permit persons to whom the Software is furnished to do so,

# * subject to the following conditions:

# *

# * The above copyright notice and this permission notice shall be included in all

# * copies or substantial portions of the Software.

# *

# * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

# * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS

# * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR

# * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER

# * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN

# * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

# *

# * http://www.FreeRTOS.org

# * http://aws.amazon.com/freertos

# *

# * 1 tab == 4 spaces!

# */


CC=arm-none-eabi-gcc

OBJCOPY=arm-none-eabi-objcopy

ARCH=arm-none-eabi-ar

CRT0_SRC=s3c2450_startup.S libs.S

#

# CFLAGS common to both the THUMB and ARM mode builds

#

CFLAGS=-Wall -Wextra -D $(RUN_MODE) -D GCC_AT91FR40008 -I. -I../../Source/include \

-I../Common/include $(DEBUG) -mcpu=arm9e -T$(LDSCRIPT) \

-Wcast-align $(OPTIM) -fomit-frame-pointer -fno-strict-aliasing \

-fno-dwarf2-cfi-asm


ifeq ($(USE_THUMB_MODE),YES)

CFLAGS += -mthumb-interwork -D THUMB_INTERWORK

THUMB_FLAGS=-mthumb

endif



LINKER_FLAGS=-o MDS2450 -Xlinker -M -Xlinker -Map=MDS2450.map


#

# Source files that can be built to THUMB mode.

#

THUMB_SRC = \

exception.c \

libc.c \

Uart.c \

syscall.c \

main.c \

serial/serial.c \

ParTest/ParTest.c \

../Common/Minimal/integer.c \

../Common/Minimal/flash.c \

../Common/Minimal/PollQ.c \

../Common/Minimal/comtest.c \

../Common/Minimal/flop.c \

../Common/Minimal/semtest.c \

../Common/Minimal/dynamic.c \

../Common/Minimal/BlockQ.c \

../../Source/tasks.c \

../../Source/queue.c \

../../Source/list.c \

../../Source/portable/MemMang/heap_2.c \

../../Source/portable/GCC/ARM7_AT91FR40008/port.c


#

# Source files that must be built to ARM mode.

#

ARM_SRC = \

../../Source/portable/GCC/ARM7_AT91FR40008/portISR.c \

serial/serialISR.c


#

# Define all object files.

#

ARM_OBJ = $(ARM_SRC:.c=.o)

THUMB_OBJ = $(THUMB_SRC:.c=.o)

CRT0_OBJ=$(CRT0_SRC:.S=.o)

OCFLAGS = -O binary -R .note -R .comment -S


MDS2450.bin : $(ARM_OBJ) $(THUMB_OBJ) $(CRT0_OBJ) Makefile

$(CC) $(CFLAGS) $(ARM_OBJ) $(THUMB_OBJ) -nostartfiles $(CRT0_OBJ) $(LINKER_FLAGS)


$(OBJCOPY) MDS2450 -O binary $@

cp $@ /tftpboot


$(THUMB_OBJ) : %.o : %.c $(LDSCRIPT) Makefile

$(CC) -c $(THUMB_FLAGS) $(CFLAGS) $< -o $@


$(ARM_OBJ) : %.o : %.c $(LDSCRIPT) Makefile

$(CC) -c $(CFLAGS) $< -o $@


$(CRT0_OBJ) : %.o : %.S $(LDSCRIPT) Makefile

$(CC) -c $(CFLAGS) $< -o $@


clean :

touch Makefile

rm $(ARM_OBJ)

rm $(THUMB_OBJ)






이제 디버깅을 시작한다.


필요없는 코드는 주석처리하고 막히는 구간에는 찾아가면서 부팅이 원활하게 되도록 하는 것이다.


디버깅은 led와 시리얼(UART)을 사용한다.


그리고, 예외처리 오류 출력을 잘 활용하자.


예) UART를 활용

Uart_Printf("<TRACE100>\n");

BaseType_t xReturn;


/* Add the idle task at the lowest priority. */

#if( configSUPPORT_STATIC_ALLOCATION == 1 )

{

Uart_Printf("<TRACE101>\n");

StaticTask_t *pxIdleTaskTCBBuffer = NULL;

StackType_t *pxIdleTaskStackBuffer = NULL;

uint32_t ulIdleTaskStackSize;

Uart_Printf("<TRACE102>\n");




<<<    현재 진행중 상황    >>


# cat HISTORY 


- ARM7_AT91FR40008_GCC compile ok


- boot ok, led ok


- printf ok 


- problem in prvSetupTimerInterrupt(port.c)





■통계 테스크



*makefile 옵션 수정




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
#include "../../include/includes.h"
//#include "ui.h"
 
// filename
char* filename = "04_STAT";
 
#define          MSG_QUEUE_SIZE     20                /* Size of message queue used in example         */
 
/* ...........................................................................
 *
 * 태스크 스택 정의
 * ===================
 */
OS_STK           TaskStartStk[TASK_STK_SIZE];         /* Startup    task stack                         */
OS_STK           Task1Stk[TASK_STK_SIZE];             /* Task #1    task stack                         */
OS_STK           Task2Stk[TASK_STK_SIZE];             /* Task #2    task stack                         */
OS_STK           Task3Stk[TASK_STK_SIZE];             /* Task #3    task stack                         */
OS_STK           Task4Stk[TASK_STK_SIZE];             /* Task #4    task stack                         */
OS_STK           Task5Stk[TASK_STK_SIZE];             /* Task #5    task stack                         */
 
/* ...........................................................................
 *
 * 사용자 메모리 정의
 * ===================
 */
TASK_USER_DATA  TaskUserData[7];
 
/* ...........................................................................
 *
 * 이벤트 컨트롤 & 사용자 정의 블럭 정의
 * ===================
 */
OS_EVENT        *MsgQueue;                            /* Message queue pointer                         */
void            *MsgQueueTbl[20];                     /* Storage for messages                          */
// 1초마다 콘솔에 동작중을 표시(.)
extern INT32U USE_OSTimeTickHook;
 
/* ...........................................................................
 *
 * 태스크 함수 원형
 * ===================
 */
void             TaskStart(void *data);               /* Function prototypes of tasks                  */
void             TaskStartCreateTasks(void);
void             TaskClk(void *data);
void             Task1(void *data);
void             Task2(void *data);
void             Task3(void *data);
void             Task4(void *data);
void             Task5(void *data);
 
//
// 어플리케이션 메인 루틴
//
int main (void)
{
    OSInit(); /* microC/OS-II 초기화 */
 
    PC_ElapsedInit(); /* Initialized elapsed time measurement     */
 
    strcpy(TaskUserData[TASK_START_ID].TaskName, "Start");
    OSTaskCreateExt(TaskStart,
                    (void *)0,
                    &TaskStartStk[TASK_STK_SIZE - 1],
                    TASK_START_PRIO,
                    TASK_START_ID,
                    &TaskStartStk[0],
                    TASK_STK_SIZE,
                    &TaskUserData[TASK_START_ID],
                    0);
    OSStart();    //우선순위 0번                                  /* Start multitasking                       */
}
 
//
// 태스크 'START'
//
void  TaskStart (void *data)
{
    INT8U err;
 
    data = data;                                           /* Prevent compiler warning                 */
 
    // 시스템 초기화(UART, LCD, TimeTick)
    InitSystem();    
 
    // Task Statistics Title Display
    TaskStatisticsTitleDisplay(filename);
 
    OSStatInit();
 
    // 1초마다 콘솔에 동작중을 표시(.)
    USE_OSTimeTickHook = 1// refer to 'OS_CPU_C.C'
 
    MsgQueue = OSQCreate(&MsgQueueTbl[0], MSG_QUEUE_SIZE); /* Create a message queue                   */
 
    TaskStartCreateTasks();
 
    /* delete self task */
    err = OSTaskDel(OS_PRIO_SELF);
    if (err) printf("OSTaskDel(OS_PRIO_SELF) error found, code[0x%X]\n",err);
}
 
//
// 태스크 'TaskStartCreateTasks'
//
void  TaskStartCreateTasks (void)
{
    strcpy(TaskUserData[TASK_1_ID].TaskName, "MsgQ Tx");
    OSTaskCreateExt(Task1,
                    (void *)0,
                    &Task1Stk[TASK_STK_SIZE - 1],
                    TASK_1_PRIO,
                    TASK_1_ID,
                    &Task1Stk[0],
                    TASK_STK_SIZE,
                    &TaskUserData[TASK_1_ID],
                    0);
 
    strcpy(TaskUserData[TASK_2_ID].TaskName, "MsgQ Rx#1");
    OSTaskCreateExt(Task2,
                    (void *)0,
                    &Task2Stk[TASK_STK_SIZE - 1],
                    TASK_2_PRIO,
                    TASK_2_ID,
                    &Task2Stk[0],
                    TASK_STK_SIZE,
                    &TaskUserData[TASK_2_ID],
                    0);
 
    strcpy(TaskUserData[TASK_3_ID].TaskName, "MsgQ Rx#2");
    OSTaskCreateExt(Task3,
                    (void *)0,
                    &Task3Stk[TASK_STK_SIZE - 1],
                    TASK_3_PRIO,
                    TASK_3_ID,
                    &Task3Stk[0],
                    TASK_STK_SIZE,
                    &TaskUserData[TASK_3_ID],
                    0);
 
    strcpy(TaskUserData[TASK_4_ID].TaskName, "MboxPostPend");
    OSTaskCreateExt(Task4,
                    (void *)0,
                    &Task4Stk[TASK_STK_SIZE - 1],
                    TASK_4_PRIO,
                    TASK_4_ID,
                    &Task4Stk[0],
                    TASK_STK_SIZE,
                    &TaskUserData[TASK_4_ID],
                    0);
 
    strcpy(TaskUserData[TASK_5_ID].TaskName, "TimeDly");
    OSTaskCreateExt(Task5,
                    (void *)0,
                    &Task5Stk[TASK_STK_SIZE - 1],
                    TASK_5_PRIO,
                    TASK_5_ID,
                    &Task5Stk[0],
                    TASK_STK_SIZE,
                    &TaskUserData[TASK_5_ID],
                    0);
}
 
//
// 태스크 'Task1'
//
void  Task1 (void *data)
{
    char one   = '1';
    char two   = '2';
    char three = '3';
 
    data = data;
    for (;;) {
        OSQPost(MsgQueue, (void *)&one);
        OSTimeDlyHMSM(001,   0);        /* Delay for 1 second                                      */
        OSQPost(MsgQueue, (void *)&two);
        OSTimeDlyHMSM(000500);        /* Delay for 500 mS                                        */
        OSQPost(MsgQueue, (void *)&three);
        OSTimeDlyHMSM(001,   0);        /* Delay for 1 second                                      */
    }
}
 
//
// 태스크 'Task2'
// Description: This task waits for messages sent by task #1.
//
void  Task2 (void *data)
{
    char *msg;
    INT8U  err;
 
    data = data;
    for (;;) {
        msg = (char *)OSQPend(MsgQueue, 0&err);    /* Wait forever for message                      */
        PC_DispChar(149*msg, (INT8U)YELLOW);
        OSTimeDlyHMSM(000500);                  /* Delay for 500 mS                              */
    }
}
 
//
// 태스크 'Task3'
// Description: This task waits for up to 250 mS for a message sent by task #1.
//
void  Task3 (void *data)
{
    INT8U *msg;
    INT8U  err;
 
    data = data;
    for (;;) {
        msg = (INT8U *)OSQPend(MsgQueue, OS_TICKS_PER_SEC / 4&err);  /* Wait up to 250 mS for a msg  */
        if (err == OS_TIMEOUT) {
            PC_DispChar(149'T',  BLUE);
        } else {
            PC_DispChar(149*msg, BLUE);
        }
    }
}
 
//
// 태스크 'Task4'
// Description: This task posts a message to a mailbox and then immediately reads the message.
//
void  Task4 (void *data)
{
    OS_EVENT *mbox;
    INT8U     err;
 
    data = data;
    mbox = OSMboxCreate((void *)0);
    for (;;) {
        OSMboxPost(mbox, (void *)1);             /* Send message to mailbox                            */
        OSMboxPend(mbox, 0&err);               /* Get message from mailbox                           */
        OSTimeDlyHMSM(00010);              /* Delay 10 mS                                        */
    }
}
 
//
// 태스크 'Task5'
// Description: This task simply delays itself.  We basically want to determine how long OSTimeDly() takes
//              to execute
//
void  Task5 (void *data)
{
    data = data;
    for (;;) {
        OSTimeDly(1);
    }
}
 
/*-----------------------------------------------------------------------------
 * Program : 04_STAT.C
-----------------------------------------------------------------------------*/
 
cs




*IDLE 테스크 관련 함수


특징 : 1. 우선순위가 가장 낮다.    =>63

2. 삭제 절대로 되지 않는다.

3. 우선순위 변경 불가능.

4. 하는 일이 없다.    =>void  OS_TaskIdle (void *p_arg)

5. 절대로 휴면 하지 않는다.

즉, 이러한 특징을 이용하여 어떠한 task가 실행되고 있는지 Idle task를 확인하여 측정할 수 있습니다.

밑 소스를 보면 Led를 통해서 어떠한 task가 수행되면 계속해서 빠르게 실행되어 Led의 불이 계속 들어오는 것을 알 수 있고 끝나면 깜빡거리는 것을 알 수 있습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
void  OS_TaskIdle (void *p_arg)
{
#if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register           */
    OS_CPU_SR  cpu_sr = 0;
#endif
 
 
 
    (void)p_arg;                                 /* Prevent compiler warning for not using 'parg'      */
    for (;;) {
        OS_ENTER_CRITICAL();
        OSIdleCtr++;
        OS_EXIT_CRITICAL();
        OSTaskIdleHook();                        /* Call user definable HOOK                           */
    }
}
 
 
#if OS_CPU_HOOKS_EN > 0 && OS_VERSION >= 251
void  OSTaskIdleHook (void)
{
        Led_Display(0);  
//        CPU goes to sleep(LOW POWER)// wjwjsfurahemeh rksmd
}
#endif
 
 
 
 
 
#if (OS_CPU_HOOKS_EN > 0&& (OS_TASK_SW_HOOK_EN > 0)
void  OSTaskSwHook (void)
{
    INT16U          time;
    TASK_USER_DATA *puser;
 
    Led_Display(15);
 
    time  = PC_ElapsedStop();                    /* This task is done                                  */
    PC_ElapsedStart();                           /* Start for next task                                */
 
    /* TODO #1: 
        EXAMPLE "04_STAT.C" 실습 예제
        태스크 사용자 자료 구조(TASK_USER_DATA) 업데이트
        use 'OSTCBCur' : 5 line */
#if 1
    puser = OSTCBCur->OSTCBExtPtr;               /* Point to used data                                 */
    if (puser != (void *)0) {
        puser->TaskID = OSTCBCur->OSTCBId;         /* Task ID */
        puser->TaskCtr++;                        /* Increment task counter                             */
        puser->TaskExecTime     = time;          /* Update the task's execution time                   */
        puser->TaskTotExecTime += time;          /* Update the task's total execution time             */
    }
#endif // TODO #1
}
#endif
cs


'RTOS' 카테고리의 다른 글

[RTOS_Day5]RTOS 포팅 진행 기록_2  (0) 2018.12.27
[RTOS_Day4]RTOS 포팅 진행 기록  (0) 2018.12.26
[RTOS_Day2]임계영역 보호  (0) 2018.12.18
[RTOS_Day2]시간관리 함수  (2) 2018.12.18
[RTOS_Day1]테스크 생성 및 운용  (0) 2018.12.17



임계영역 보호


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
#include "includes.h"
 
 
int tickets;        // MAX value( 1000 million )
int backupTickets;
int T1_Ticket=0, T2_Ticket= 0;
 
/* ...........................................................................
 *
 * 태스크 스택 정의
 * ===================
 */
OS_STK TaskStartStk[TASK_STK_SIZE]; /* START task stack */
OS_STK Task1Stk[TASK_STK_SIZE]; /* Task #1 stack */
OS_STK Task2Stk[TASK_STK_SIZE]; /* Task #2 stack */
//OS_STK Task3Stk[TASK_STK_SIZE]; /* Task #3 stack */
//OS_STK Task4Stk[TASK_STK_SIZE]; /* Task #4 stack */
 
/* ...........................................................................
 *
 * 사용자 메모리 정의
 * ===================
 */
TASK_USER_DATA  TaskUserData[7];
 
/* ...........................................................................
 *
 * 이벤트 컨트롤 & 사용자 정의 블럭 정의
 * ===================
 */
#define TICKET_1BILLION        1000000000
#define TICKET_1MILLION        1000000
#define TICKET_10000        10000
#define TICKET_1000            1000
 
extern void seedrand(int seed);
extern int randomnumber(void);
int buyTicket(void);
 
// 1초마다 콘솔에 동작중을 표시(.)
extern INT32U USE_OSTimeTickHook;
 
/* ...........................................................................
 *
 * 태스크 함수 원형
 * ===================
 */
void  TaskStart(void *pdata); /* Function prototypes of Startup task */
void  Task1(void *pdata);
void  Task2(void *pdata);        
void  Task3(void *pdata);
void  Task4(void *pdata);
 
//
// 어플리케이션 메인 루틴
//
int main(void)
{
    OSInit(); /* microC/OS-II 초기화 */
 
    PC_ElapsedInit(); /* Initialized elapsed time measurement     */
 
    strcpy(TaskUserData[TASK_START_ID].TaskName, "TaskStart");
    
    // TASK CREATE
    OSTaskCreateExt(TaskStart,
                   (void *)0,
                   &TaskStartStk[TASK_STK_SIZE-1],
                   TASK_START_PRIO,
                   TASK_START_ID,
                   &TaskStartStk[0],
                   TASK_STK_SIZE,
                   &TaskUserData[TASK_START_ID],
                   OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
 
    OSStart(); /* start scheduler */
 
    return 0;    
}
 
//
// 태스크 'START'
//
void  TaskStart (void *pdata)
{
    INT8U err;
    
    pdata = pdata;                /* 컴파일러 경고를 막기 위함 */
 
    // 시스템 초기화(UART, LCD, TimeTick)
    InitSystem();    
 
    OSStatInit();                /* Initialize uC/OS-II's 통계 함수 */
 
    //
    // set random seed
    //
    seedrand( 45 );
    
    //
    // Set Tickets
    //
    /* TODO #2: 
        초기 티켓수를 작은수(10,000 ~ 100,000정도) 입력 하여 테스트 한후 
        그 결과를 설명한다 */
#if 1 // No comment
    //tickets= backupTickets = 10 * TICKET_10000; // MAX value( 1 million )
    tickets= backupTickets = 10 * TICKET_1MILLION; // MAX value( 1 million )
#endif // TODO #2
 
    // TASK CREATE
    strcpy(TaskUserData[TASK_1_ID].TaskName, "Task1");
    OSTaskCreateExt(Task1,
                    (void *)0,
                    &Task1Stk[TASK_STK_SIZE - 1],
                    TASK_1_PRIO,
                    TASK_1_ID,
                    &Task1Stk[0],
                    TASK_STK_SIZE,
                    &TaskUserData[TASK_1_ID],
                    0);
    if (err) printf("OSTaskCreate error found, code[0x%X]\n",err);
 
    // TASK CREATE
    strcpy(TaskUserData[TASK_2_ID].TaskName, "Task2");
    OSTaskCreateExt(Task2,
                    (void *)0,
                    &Task2Stk[TASK_STK_SIZE - 1],
                    TASK_2_PRIO,
                    TASK_2_ID,
                    &Task2Stk[0],
                    TASK_STK_SIZE,
                    &TaskUserData[TASK_2_ID],
                    0);
    if (err) printf("OSTaskCreate error found, code[0x%X]\n",err);
 
    /* delete self task */
    err = OSTaskDel(OS_PRIO_SELF);
    if (err) printf("OSTaskDel(OS_PRIO_SELF) error found, code[0x%X]\n",err);
}
 
//
// 태스크 1
//
void Task1(void *pdata)
{
    INT8U err;
    
    pdata = pdata;                /* 컴파일러 경고를 막기 위함 */
 
    printf("\n\nTask1 TASK created,\n");
 
    while(1) {
        if(buyTicket() <= 0)
        {
            T1_Ticket++;
//            printf("[TASK1]COUNTER up to %d\n", T1_Ticket);
            /* delete other task */
            err = OSTaskDel(TASK_2_PRIO);
            break;
        }
        T1_Ticket++;
    /* TODO #1: 
        OSTimeDly() 시간 지연을 적당히 입력하여 티켓 카운트 수가 
        오류가 나도록 만든다 */
#if 1 // No comment
        OSTimeDly(2);    // 주의사항! 2 이상의 값을 입력 할 것
#endif // TODO #1
    }
 
    // 1초마다 콘솔 출력 '중지'
    USE_OSTimeTickHook = 0// refer to 'OS_CPU_C.C'
 
    printf("\n[TASK1]Total Tickets = %d\n", T1_Ticket + T2_Ticket);
 
    if(backupTickets != T1_Ticket + T2_Ticket)
        printf("Not good. expectation(%d)\n", backupTickets);
    else
        printf("Good!. Matched\n");
 
    /* delete self task */
    err = OSTaskDel(OS_PRIO_SELF);
    if (err) printf("OSTaskDel(OS_PRIO_SELF) error found, code[0x%X]\n",err);
}
 
//
// 태스크 2
//
void Task2(void *pdata)
{
    INT8U err;
    INT32U timeo;
    int i;
 
    pdata = pdata;                /* 컴파일러 경고를 막기 위함 */
 
    printf("Task2 TASK created,\n");
 
    printf("please wait");
 
    // 1초마다 콘솔에 동작중을 표시(.)
    USE_OSTimeTickHook = 1// refer to 'OS_CPU_C.C'
 
    while(1) {
        for(i=0;i<100000;i++)
        {
            if(buyTicket()==0)
            {
                T2_Ticket++;
//                printf("[TASK2]COUNTER up to %d\n", T2_Ticket);
                /* delete other task */
                err = OSTaskDel(TASK_1_PRIO);
                goto exit;
            }
            T2_Ticket++;
        }
        timeo = randomnumber();
        OSTimeDly(timeo % 3);
    }
 
exit:
    // 1초마다 콘솔 출력 '중지'
    USE_OSTimeTickHook = 0// refer to 'OS_CPU_C.C'
 
    printf("\n[TASK2]Total Tickets = %d\n", T1_Ticket + T2_Ticket);
 
    if(backupTickets != T1_Ticket + T2_Ticket)
        printf("Not good. expectation(%d)\n", backupTickets);
    else
        printf("Good!. Matched\n");
 
    /* delete self task */
    err = OSTaskDel(OS_PRIO_SELF);
    if (err) printf("OSTaskDel(OS_PRIO_SELF) error found, code[0x%X]\n",err);
}
 
//
// buyTicket
//
int buyTicket(void)
{
    OS_CPU_SR cpu_sr;
 
    /* TODO #3: 
        OS_ENTER_CRITICAL() 과  OS_EXIT_CRITICAL()을 이용하여 
        공유변수(tickets)를 보호한다 */
#if 1
    // CRITICAL SECTION(ENTER)
    OS_ENTER_CRITICAL();
#endif // TODO #3
 
    tickets --;    // ticket count
 
#if 1
    // CRITICAL SECTION(EXIT)
    OS_EXIT_CRITICAL();
#endif // TODO #3
 
    return(tickets);
}
 
/*-----------------------------------------------------------------------------
 * Program : 03_CRITICAL.C
-----------------------------------------------------------------------------*/
 
cs





* TODO 1

현재 2개의 Task가 동작 중이며 task1과 task2는 다른 속도로 실행되고 있다. 

tickets= backupTickets = 10 * TICKET_1MILLION;

현재 티켓의 수로 실행하면 collision(충돌)이 생겨서 동시성 문제가 발생한다.



* TODO 2


이때 티켓의 수를 줄여보면


tickets= backupTickets = 10 * TICKET_10000;


결과를 보면 횟수가 적으면 충돌가능성도 줄어들게 된다.





* TODO 3


OS_ENTER_CRITICAL();

OS_EXIT_CRITICAL();        함수를 이용해 상호 배제를 한면 횟수가 많아도 동시에 진입하지 않습니다. 

즉, 공유 변수를 보호합니다.

그리고 CRITICAL SECTION(임계 영역) 커널 서비스를 자주 호출 하게 되면 그렇지 않을 경우보다 시간이 많이 소요됩니다.






*Critical Section(임계 영역) : 공유 자원을 사용 중인 함수내의 일부 혹은 전체 영역
이 코드의 영역의 실행이 시작되면 적어도 다른 태스크가 이영역을 선점하여 실행하는 일이 없어야 안전합니다.

상호 배제 방법 1. 인터럽트 작동을 잠금
   2. 스케줄링 중단
   3. 세마포어류의 커널서비스    ->많이 사용하는 방법
   4. 공유 자원을 사용하지 않는다(상호배제 사용 x) ->가장 이상적인 방법.

예) 전역변수를 쓰지 않는다.

1
2
3
4
5
6
7
8
int Temp; //전역변수
 
void swap(int *x,int *y)
{
    Temp = *x;
    *= *y;
    *= Temp;
}

cs

    <재진입이 불가능한 경우>

  ▼

1
2
3
4
5
6
7
void swap(int *x,int *y)
{
    int Temp;
    Temp = *x;
    *= *y;
    *= Temp;
}
cs

        <재진입이 가능한 경우>















'RTOS' 카테고리의 다른 글

[RTOS_Day5]RTOS 포팅 진행 기록_2  (0) 2018.12.27
[RTOS_Day4]RTOS 포팅 진행 기록  (0) 2018.12.26
[RTOS_Day3]통계 테스크  (0) 2018.12.19
[RTOS_Day2]시간관리 함수  (2) 2018.12.18
[RTOS_Day1]테스크 생성 및 운용  (0) 2018.12.17

■시간관리 함수


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#include "includes.h"
    
/* ...........................................................................
 *
 * 태스크 스택 정의
 * ===================
 */
OS_STK TaskStartStk[TASK_STK_SIZE]; /* START task stack */
OS_STK Task1Stk[TASK_STK_SIZE]; /* Task #1 stack */
OS_STK Task2Stk[TASK_STK_SIZE]; /* Task #2 stack */
//OS_STK Task3Stk[TASK_STK_SIZE]; /* Task #3 stack */
//OS_STK Task4Stk[TASK_STK_SIZE]; /* Task #4 stack */
 
/* ...........................................................................
 *
 * 사용자 메모리 정의
 * ===================
 */
TASK_USER_DATA  TaskUserData[7];
 
/* ...........................................................................
 *
 * 이벤트 컨트롤 & 사용자 정의 블럭 정의
 * ===================
 */
struct tm {
  int tm_msec;  /* milli seconds */
  int tm_sec;   /* seconds after the minute, 0 to 60
                   (0 - 60 allows for the occasional leap second) */
  int tm_min;   /* minutes after the hour, 0 to 59 */
  int tm_hour;  /* hours since midnight, 0 to 23 */
};
// 1초마다 콘솔에 동작중을 표시(.)
extern INT32U USE_OSTimeTickHook;
 
void OSTimeDlyCustom( struct tm *t );
 
/* ...........................................................................
 *
 * 태스크 함수 원형
 * ===================
 */
void  TaskStart(void *pdata); /* Function prototypes of Startup task */
void  Task1(void *pdata);
void  Task2(void *pdata);       
void  Task3(void *pdata);
void  Task4(void *pdata);
 
//
// 어플리케이션 메인 루틴
//
int main(void)
{
    OSInit(); /* microC/OS-II 초기화 */
 
    PC_ElapsedInit(); /* Initialized elapsed time measurement     */
 
    strcpy(TaskUserData[TASK_START_ID].TaskName, "TaskStart");
    
    // TASK CREATE
    OSTaskCreateExt(TaskStart,
                   (void *)0,
                   &TaskStartStk[TASK_STK_SIZE-1],
                   TASK_START_PRIO,
                   TASK_START_ID,
                   &TaskStartStk[0],
                   TASK_STK_SIZE,
                   &TaskUserData[TASK_START_ID],
                   OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
 
    OSStart(); /* start scheduler */
 
    return 0;    
}
 
//
// 태스크 'START'
//
void  TaskStart (void *pdata)
{
    INT8U err;
    
    pdata = pdata;                /* 컴파일러 경고를 막기 위함 */
 
    // 시스템 초기화(UART, LCD, TimeTick)
    InitSystem();    
 
    OSStatInit();                /* Initialize uC/OS-II's 통계 함수 */
 
    // 1초마다 콘솔에 동작중을 표시(.)
    USE_OSTimeTickHook = 1// refer to 'OS_CPU_C.C'
 
    strcpy(TaskUserData[TASK_1_ID].TaskName, "Task1");
    OSTaskCreateExt(Task1,
                    (void *)0,
                    &Task1Stk[TASK_STK_SIZE - 1],
                    TASK_1_PRIO,
                    TASK_1_ID,
                    &Task1Stk[0],
                    TASK_STK_SIZE,
                    &TaskUserData[TASK_1_ID],
                    0);
 
    if (err) printf("OSTaskCreate error found, code[0x%X]\n",err);
 
#if 1 // No comment
    err = OSTaskSuspend(OS_PRIO_SELF);
        if (err) printf("OSTaskSuspend error found, code[0x%X]\n",err);
#endif // TODO #3
 
    /* delete self task */
    err = OSTaskDel(OS_PRIO_SELF);
    if (err) printf("OSTaskDel(OS_PRIO_SELF) error found, code[0x%X]\n",err);
}
 
//
// 태스크 1
//
void Task1(void *pdata)
{
    INT8U err;
    struct tm time_s;    // USER defined time structure
 
    pdata = pdata;                /* 컴파일러 경고를 막기 위함 */
 
    printf("\n\nTask1 TASK created,\n");
 
    /* TODO #1: 
        Wait 5 Second from now on
        use 'OSTimeDly()' */
    printf("Wait 5 Second From now on\n");
 
#if 1
    OSTimeDly(500);//5 sec
#endif // TODO #1
    printf("finished\n\n");
 
    /* TODO #2: 
        Wait 10 Second from now on
        use 'OSTimeDlyCustom()' : 5 line */
    printf("Wait 10 Second From now on\n");
#if 1
    time_s.tm_msec=0;
    time_s.tm_sec=10;
    time_s.tm_min=0;
    time_s.tm_hour=0;
    OSTimeDlyCustom(&time_s);
#endif // TODO #2
    printf("finished\n");
 
#if 1 // No comment
    err = OSTaskSuspend(OS_PRIO_SELF);
        if (err) printf("OSTaskSuspend error found, code[0x%X]\n",err);
#endif // TODO #3
 
    // 1초마다 콘솔 출력 '중지'
    USE_OSTimeTickHook = 0// refer to 'OS_CPU_C.C'
 
    printf("\n\ntask1 terminated,\n");
    err = OSTaskDel(OS_PRIO_SELF);    /* delete self task */
    if (err) printf("OSTaskDel(OS_PRIO_SELF) error found, code[0x%X]\n",err);
}
 
//
// OSTimeDlyCustom
//
void OSTimeDlyCustomstruct tm *t )
{
    OSTimeDlyHMSM (t->tm_hour, t->tm_min, t->tm_sec, t->tm_msec);
}
 
/*-----------------------------------------------------------------------------
 * Program : 02_TIMER.C
-----------------------------------------------------------------------------*/
 
cs





*Makefile 설정



*TODO 1 , 2


*TODO 3





*OSTaskSuspend(INT8U prio);
=>테스크 일시 중단    prio : 중지시킬 데스크의 우선순위
OSTaskResume()으로 다시 동작할 수 있다.


'RTOS' 카테고리의 다른 글

[RTOS_Day5]RTOS 포팅 진행 기록_2  (0) 2018.12.27
[RTOS_Day4]RTOS 포팅 진행 기록  (0) 2018.12.26
[RTOS_Day3]통계 테스크  (0) 2018.12.19
[RTOS_Day2]임계영역 보호  (0) 2018.12.18
[RTOS_Day1]테스크 생성 및 운용  (0) 2018.12.17

■RTOS


<환경 설정>


<Linux>

$ pwd

/home/mds

$ tar zxf Codesourcery.tar.gz -C /

$ tar zxf ucos2.tar.gz -C ~/

$ echo PATH=$PATH:/opt/CodeSourcery/Sourcery_G++_Lite/bin >> ~/.bashrc







$ cd ucos2/04.ucos2-final/

$ make clean && make




<Tera>
# set bootcmd 'tftp 30000000 MDS2450.bin;go 30000000'
# set bootdelay 1
# save





<Linux>

www.sublimetext.com/3



$ tar jxf sublime_text_3_build_3176_x32.tar.bz2 -C /opt/
$ echo PATH=$PATH:/opt/sublime_text_3/sublime_text >> ~/.bashrc
$ echo alias subl=/opt/sublime_text_3/sublime_text >> ~/.bashrc



$ cd ucos2/04.ucos2-final/
~/ucos2/04.ucos2-final$ subl .

<Ctrl + `> 활성화

https://packagecontrol.io/installation#st3 들어가서 복사


import urllib.request,os,hashlib; h = '6f4c264a24d933ce70df5dedcf1dcaee' + 'ebe013ee18cced0ef93d5f746d80ef60'; pf = 'Package Control.sublime-package'; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); by = urllib.request.urlopen( 'http://packagecontrol.io/' + pf.replace(' ', '%20')).read(); dh = hashlib.sha256(by).hexdigest(); print('Error validating download (got %s instead of %s), please try manual install' % (dh, h)) if dh != h else open(os.path.join( ipp, pf), 'wb' ).write(by)

붙혀 넣기

- 빌드 설정




<Ctrl + b>    =>컴파일
<Ctrl + Shift + f>   =>전체 찾기
<Ctrl + g>    =>라인 이동
<Ctrl + r>    =>함수 목록
<Ctrl + f2>   =>북마크 설정/해제
<f2>          =>북마크 이동





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
#include "includes.h"
#include "ui.h"
 
// filename
char* filename = "01_TASKMAN";
 
/* ...........................................................................
 *
 * 태스크 스택 정의
 * ===================
 */
OS_STK TaskStartStk[TASK_STK_SIZE]; /* START task stack */
OS_STK Task1Stk[TASK_STK_SIZE]; /* Task #1 stack */
OS_STK Task2Stk[TASK_STK_SIZE]; /* Task #2 stack */
//OS_STK Task3Stk[TASK_STK_SIZE]; /* Task #3 stack */
//OS_STK Task4Stk[TASK_STK_SIZE]; /* Task #4 stack */
 
/* ...........................................................................
 *
 * 사용자 메모리 정의
 * ===================
 */
TASK_USER_DATA  TaskUserData[7];
 
/* ...........................................................................
 *
 * 이벤트 컨트롤 & 사용자 정의 블럭 정의
 * ===================
 */
struct Param_types {    /* struct for parameter passing to task */
       char *msg;
       int  P1,P2;
} Param_Tbl; 
int    task1timer,task2timer;
extern void seedrand(int seed);
extern int randomnumber(void);
 
/* ...........................................................................
 *
 * 태스크 함수 원형
 * ===================
 */
void  TaskStart(void *pdata); /* Function prototypes of Startup task */
void  Task1(void *pdata);
void  Task2(struct Param_types *Param);        
void  Task3(void *pdata);
void  Task4(void *pdata);
 
//
// 어플리케이션 메인 루틴
//
int main(void)
{
    OSInit(); /* microC/OS-II 초기화 */
    PC_ElapsedInit(); /* Initialized elapsed time measurement     */
    strcpy(TaskUserData[TASK_START_ID].TaskName, "TaskStart");
    
    // TASK CREATE
    OSTaskCreateExt(TaskStart,
                   (void *)0,
                   &TaskStartStk[TASK_STK_SIZE-1],
                   TASK_START_PRIO,
                   TASK_START_ID,
                   &TaskStartStk[0],
                   TASK_STK_SIZE,
                   &TaskUserData[TASK_START_ID],
                   OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
 
    OSStart(); /* start scheduler */
 
    return 0;    
}
 
//
// 태스크 'START'
//
void  TaskStart (void *pdata)
{
    INT8U err;
    struct Param_types *Param;
 
    pdata = pdata;                /* 컴파일러 경고를 막기 위함 */
 
    // 시스템 초기화(UART, LCD, TimeTick)
    InitSystem();    
 
    // Task Statistics Title Display
    TaskStatisticsTitleDisplay(filename);
 
    OSStatInit();                /* Initialize uC/OS-II's 통계 함수 */
 
    printf("whatmam\n");
    // TASK CREATE
    /* TODO #1: 
        Task1을 생성
        use 'OSTaskCreate' */
#if 1
err = OSTaskCreateExt((void(*)(void *))Task1,
                    (void *)Param,
                    &Task1Stk[TASK_STK_SIZE - 1],
                    TASK_1_PRIO,
                    TASK_1_ID,
                    &Task1Stk[0],
                    TASK_STK_SIZE,
                    &TaskUserData[TASK_1_ID],
                    0);
 
 
#endif // TODO #1
 
    // Set TASK2 parameter
    Param = &Param_Tbl;        /* get parameter tbl addr */
    Param->P1 = 111111;        /* set parameter */
    Param->P2 = 222222;
    strcpy(TaskUserData[TASK_2_ID].TaskName, "task2");
 
    // TASK CREATE
    err = OSTaskCreateExt((void(*)(void *))Task2,
                    (void *)Param,
                    &Task2Stk[TASK_STK_SIZE - 1],
                    TASK_2_PRIO,
                    TASK_2_ID,
                    &Task2Stk[0],
                    TASK_STK_SIZE,
                    &TaskUserData[TASK_2_ID],
                    0);
                    
       if (err) Uart_Printf("OSTaskCreateExt error found, code[0x%X]\n",err);
 
    /* TODO #2: 
        Task1을 중지
        use 'OSTaskSuspend' */
#if 1
       err = OSTaskSuspend(TASK_1_PRIO);
#endif // TODO #2
 
    /* TODO #4: 
        Task1의 우선 순위를 'TASK_3_PRIO' 으로 변경
        use 'OSTaskChangePrio' and 'OSTaskResume' */
#if 1
err = OSTaskChangePrio(TASK_1_PRIO, TASK_3_PRIO);
err = OSTaskResume(TASK_3_PRIO);
#endif // TODO #4
 
    /* delete self task */
    err = OSTaskDel(OS_PRIO_SELF);
 
    if (err) Uart_Printf("OSTaskDel(OS_PRIO_SELF) error found, code[0x%X]\n",err);
}
 
//
// 태스크 1
//
void Task1(void *pdata)
{
    INT8U err;
    OS_TCB task_data;
 
    pdata = pdata;                /* 컴파일러 경고를 막기 위함 */
 
    Uart_Printf("\n\nTask1 TASK created,\n");
 
    err = OSTaskQuery(OS_PRIO_SELF, &task_data);
        if (err) Uart_Printf("OSTaskQuery error found, code[0x%X]\n",err);
 
    Uart_Printf("\n-------  Task1 information -------\n");
    Uart_Printf("task1 id = %d \n",task_data.OSTCBPrio);
    Uart_Printf("task1 priority = %d \n",task_data.OSTCBPrio);
    Uart_Printf("task1 status = %d \n",task_data.OSTCBStat);
    Uart_Printf("----------------------------------\n");
 
    while(1) {
    /* TODO #3: 
        코드를 실행 하여 보고
        OSTimeDly() 코드를 주석 처리한 후 그 결과를 설명한다 */
#if 1 // No comment
        OSTimeDly(100);
        Uart_Printf("a");    fflush(stdout);// 문자 'a' 출력
 
#endif // TODO #3
 
        task1timer++;
    }
}
 
//
// 태스크 2
//
void Task2(struct Param_types *Param)
{
    Uart_Printf("Task2 TASK created,\n");
 
    Uart_Printf("\n-------  Task2 parameter passed from main --------\n");
    Uart_Printf("task2 first parameter = %d \n",Param->P1);
    Uart_Printf("task2 second parameter = %d \n",Param->P2);
    Uart_Printf("--------------------------------------------------\n");
 
    while(1) {
    /* TODO #3: 
        코드를 실행 하여 보고
        OSTimeDly() 코드를 주석 처리한 후 그 결과를 설명한다 */
#if 1 // No comment
        OSTimeDly(100);
        Uart_Printf("b");    fflush(stdout);// 문자 'b' 출력
#endif // TODO #3
 
        task2timer++;
    }
}
 
/*-----------------------------------------------------------------------------
 * Program : 01_TASKMAN.C
-----------------------------------------------------------------------------*/
 
cs




* TODO 1



*TODO 2



*TODO 3



*TODO 4




'RTOS' 카테고리의 다른 글

[RTOS_Day5]RTOS 포팅 진행 기록_2  (0) 2018.12.27
[RTOS_Day4]RTOS 포팅 진행 기록  (0) 2018.12.26
[RTOS_Day3]통계 테스크  (0) 2018.12.19
[RTOS_Day2]임계영역 보호  (0) 2018.12.18
[RTOS_Day2]시간관리 함수  (2) 2018.12.18

+ Recent posts