1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/personality/example/main.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1104 @@
1.4 +// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32test\personality\example\main.cpp
1.18 +// Test code for example RTOS personality.
1.19 +//
1.20 +//
1.21 +
1.22 +#include <kernel/kern_priv.h>
1.23 +#include <personality/example/personality.h>
1.24 +
1.25 +#ifdef __cplusplus
1.26 +extern "C" {
1.27 +#endif
1.28 +
1.29 +#define OC_TASK 0
1.30 +#define L2_TASK 1
1.31 +#define RR_TASK 2
1.32 +#define NONEXISTENT_TASK 3
1.33 +#define TM_TASK 4
1.34 +#define TASK1 6
1.35 +#define TASK2 7
1.36 +#define TASK3 8
1.37 +#define TASK4 9
1.38 +#define L1_TASK 10
1.39 +
1.40 +void oo_overall_control(void);
1.41 +void l1_task_entry(void);
1.42 +void l2_task_entry(void);
1.43 +void rr_task_entry(void);
1.44 +void tm_task_entry(void);
1.45 +void task1_entry(void);
1.46 +void task2_entry(void);
1.47 +void task3_entry(void);
1.48 +void task4_entry(void);
1.49 +
1.50 +typedef void (*isr_entry)(unsigned);
1.51 +
1.52 +extern int start_random_isr(isr_entry vector);
1.53 +extern void stop_random_isr(void);
1.54 +
1.55 +const taskinfo task_list[] =
1.56 + {
1.57 +
1.58 + /* entry_pt, priority, stack_size, task_id, auto_start */
1.59 +
1.60 + { &oo_overall_control, 120, 1024, OC_TASK, 1 },
1.61 + { &l2_task_entry, 236, 1024, L2_TASK, 0 },
1.62 + { &rr_task_entry, 224, 1024, RR_TASK, 0 },
1.63 + { &tm_task_entry, 240, 1024, TM_TASK, 0 },
1.64 + { &task1_entry, 112, 1024, TASK1, 0 },
1.65 + { &task2_entry, 112, 1024, TASK2, 0 },
1.66 + { &task3_entry, 112, 1024, TASK3, 0 },
1.67 + { &task4_entry, 112, 1024, TASK4, 0 },
1.68 + { &l1_task_entry, 244, 1024, L1_TASK, 0 },
1.69 + /* terminator */
1.70 + { 0, 0, 0, 0, 0 }
1.71 + };
1.72 +
1.73 +const poolinfo pool_list[] =
1.74 + {
1.75 + /* block size, block count */
1.76 + { 32, 256 },
1.77 + { 64, 256 },
1.78 + { 128, 128 },
1.79 + { 256, 64 },
1.80 + { 512, 32 },
1.81 + /* terminator */
1.82 + { 0, 0 }
1.83 + };
1.84 +
1.85 +const int timer_count = 8;
1.86 +const int semaphore_count = 2;
1.87 +
1.88 +#define TM_TIMER 0
1.89 +
1.90 +#define TM_INIT_DELAY 1000
1.91 +#define TM_PERIOD 2
1.92 +
1.93 +volatile unsigned next_random_id = 0;
1.94 +volatile unsigned random_sem_signal_interval = 0;
1.95 +volatile unsigned random_sem_signal_count = 0;
1.96 +volatile unsigned random_send_interval = 0;
1.97 +volatile unsigned random_send_count = 0;
1.98 +volatile unsigned tmcount = 0;
1.99 +volatile int t1func = 0;
1.100 +volatile int t2func = 0;
1.101 +volatile int t3func = 0;
1.102 +volatile int t4func = 0;
1.103 +
1.104 +#define TEST_SEM 0
1.105 +#define ISR_SEM 1
1.106 +
1.107 +#define MSG_ID_INIT 1
1.108 +#define MSG_ID_RUN 2
1.109 +#define MSG_ID_RUN_P 3
1.110 +#define MSG_ID_RND_ISR 4
1.111 +#define MSG_ID_DONE 5
1.112 +#define MSG_ID_DATA 6
1.113 +#define MSG_ID_FLUSH 7
1.114 +#define MSG_ID_SEM_RPT 8
1.115 +#define MSG_ID_RCV_RPT 9
1.116 +#define MSG_ID_TM_RPT 10
1.117 +
1.118 +typedef struct _run_msg
1.119 + {
1.120 + msghdr header;
1.121 + int task_id;
1.122 + unsigned tmcount;
1.123 + int parameter;
1.124 + } run_msg;
1.125 +
1.126 +typedef struct _random_isr_msg
1.127 + {
1.128 + msghdr header;
1.129 + unsigned random_isr_number;
1.130 + unsigned extra;
1.131 + } random_isr_msg;
1.132 +
1.133 +typedef struct _data_msg
1.134 + {
1.135 + msghdr header;
1.136 + int length;
1.137 + unsigned char checksum;
1.138 + unsigned char data[1];
1.139 + } data_msg;
1.140 +
1.141 +typedef struct _report_msg
1.142 + {
1.143 + msghdr header;
1.144 + int pad;
1.145 + unsigned count;
1.146 + unsigned ok_count;
1.147 + unsigned bad_count;
1.148 + } report_msg;
1.149 +
1.150 +void busy_wait(unsigned ticks)
1.151 + {
1.152 + unsigned t0 = tmcount;
1.153 + while ((tmcount - t0) < ticks)
1.154 + {}
1.155 + }
1.156 +
1.157 +void send_run_signal()
1.158 + {
1.159 + run_msg* m = (run_msg*)alloc_mem_block(sizeof(run_msg));
1.160 + assert(m);
1.161 + m->header.msg_id = MSG_ID_RUN;
1.162 + m->task_id = current_task_id();
1.163 + m->tmcount = tmcount;
1.164 + int r = send_msg(OC_TASK, &m->header);
1.165 + assert(r == OK);
1.166 + }
1.167 +
1.168 +void send_run_signal_p(int parameter)
1.169 + {
1.170 + run_msg* m = (run_msg*)alloc_mem_block(sizeof(run_msg));
1.171 + assert(m);
1.172 + m->header.msg_id = MSG_ID_RUN_P;
1.173 + m->task_id = current_task_id();
1.174 + m->tmcount = tmcount;
1.175 + m->parameter = parameter;
1.176 + int r = send_msg(OC_TASK, &m->header);
1.177 + assert(r == OK);
1.178 + }
1.179 +
1.180 +void tsend_run_signal_p(int task_id, int parameter)
1.181 + {
1.182 + run_msg* m = (run_msg*)alloc_mem_block(sizeof(run_msg));
1.183 + assert(m);
1.184 + m->header.msg_id = MSG_ID_RUN_P;
1.185 + m->task_id = current_task_id();
1.186 + m->tmcount = tmcount;
1.187 + m->parameter = parameter;
1.188 + int r = send_msg(task_id, &m->header);
1.189 + assert(r == OK);
1.190 + }
1.191 +
1.192 +void check_no_signal()
1.193 + {
1.194 + msghdr* m = NULL;
1.195 + int r = recv_msg(&m, NO_WAIT);
1.196 + assert(r == TIMED_OUT);
1.197 + }
1.198 +
1.199 +unsigned check_for_signal(int task_id)
1.200 + {
1.201 + msghdr* m = NULL;
1.202 + int r = recv_msg(&m, NO_WAIT);
1.203 + assert(r == OK);
1.204 + assert(m->msg_id == MSG_ID_RUN);
1.205 + run_msg* rm = (run_msg*)m;
1.206 + assert(rm->task_id == task_id);
1.207 + unsigned tmc = rm->tmcount;
1.208 + free_mem_block(m);
1.209 + return tmc;
1.210 + }
1.211 +
1.212 +int check_for_signal_p(int task_id, int task_id2, unsigned* pt)
1.213 + {
1.214 + msghdr* m = NULL;
1.215 + int r = recv_msg(&m, NO_WAIT);
1.216 + assert(r == OK);
1.217 + assert(m->msg_id == MSG_ID_RUN_P);
1.218 + run_msg* rm = (run_msg*)m;
1.219 + assert(rm->task_id == task_id);
1.220 + assert(m->sending_task_id == task_id2);
1.221 + r = rm->parameter;
1.222 + if (pt)
1.223 + *pt = rm->tmcount;
1.224 + free_mem_block(m);
1.225 + return r;
1.226 + }
1.227 +
1.228 +int wait_for_signal_p(int task_id, unsigned* pt)
1.229 + {
1.230 + msghdr* m = NULL;
1.231 + int r = recv_msg(&m, WAIT_FOREVER);
1.232 + assert(r == OK);
1.233 + assert(m->msg_id == MSG_ID_RUN_P);
1.234 + run_msg* rm = (run_msg*)m;
1.235 + assert(rm->task_id == task_id);
1.236 + r = rm->parameter;
1.237 + if (pt)
1.238 + *pt = rm->tmcount;
1.239 + free_mem_block(m);
1.240 + return r;
1.241 + }
1.242 +
1.243 +void resume_4(int t1, int t2, int t3, int t4)
1.244 + {
1.245 + if (t1>=0)
1.246 + assert(resume_task(t1)==OK);
1.247 + if (t2>=0)
1.248 + assert(resume_task(t2)==OK);
1.249 + if (t3>=0)
1.250 + assert(resume_task(t3)==OK);
1.251 + if (t4>=0)
1.252 + assert(resume_task(t4)==OK);
1.253 + }
1.254 +
1.255 +void check_signal_4(int t1, int t2, int t3, int t4)
1.256 + {
1.257 + if (t1>=0)
1.258 + check_for_signal(t1);
1.259 + else
1.260 + check_no_signal();
1.261 + if (t2>=0)
1.262 + check_for_signal(t2);
1.263 + else
1.264 + check_no_signal();
1.265 + if (t3>=0)
1.266 + check_for_signal(t3);
1.267 + else
1.268 + check_no_signal();
1.269 + if (t4>=0)
1.270 + check_for_signal(t4);
1.271 + else
1.272 + check_no_signal();
1.273 + }
1.274 +
1.275 +void check_for_multiple_signals(int task_id, int count)
1.276 + {
1.277 + unsigned t = check_for_signal(task_id);
1.278 + while (--count)
1.279 + {
1.280 + unsigned t2 = check_for_signal(task_id);
1.281 + assert(t2 - t >= 1);
1.282 + t = t2;
1.283 + }
1.284 + }
1.285 +
1.286 +int flush_signals(void)
1.287 + {
1.288 + int c = 0;
1.289 + for (;;)
1.290 + {
1.291 + msghdr* m = NULL;
1.292 + int r = recv_msg(&m, NO_WAIT);
1.293 + if (r == TIMED_OUT)
1.294 + break;
1.295 + assert(r == OK);
1.296 + assert(m->msg_id == MSG_ID_RUN);
1.297 + free_mem_block(m);
1.298 + ++c;
1.299 + }
1.300 + return c;
1.301 + }
1.302 +
1.303 +void test_mem_pool(size_t size, int count, void** chain)
1.304 + {
1.305 + int i, fill;
1.306 + void *b, *bb, *c;
1.307 + c = *chain;
1.308 + for (i=0; i<count; ++i)
1.309 + {
1.310 + b = alloc_mem_block(size);
1.311 + assert(b != NULL);
1.312 + fill = (int)(size>>5);
1.313 + fill += 29;
1.314 + fill *= fill;
1.315 + fill &= 0xff;
1.316 + memset(b, fill, size);
1.317 + *(void**)b = c;
1.318 + ((int*)b)[1] = (int)size;
1.319 + c = b;
1.320 + }
1.321 + bb = alloc_mem_block(size);
1.322 + assert(bb == NULL);
1.323 + *chain = c;
1.324 + }
1.325 +
1.326 +void check_blocks(void* chain)
1.327 + {
1.328 + void* p = chain;
1.329 + while (p)
1.330 + {
1.331 + unsigned char *q, *qq;
1.332 + int size, fill, x;
1.333 + size = ((int*)p)[1];
1.334 + fill = (size>>5)+29;
1.335 + fill = (fill*fill)&0xff;
1.336 + q = (unsigned char*)p + sizeof(void*) + sizeof(int);
1.337 + qq = (unsigned char*)p + size;
1.338 + x = 0;
1.339 + while (q<qq)
1.340 + x |= (*q++ ^ fill);
1.341 + assert(x==0);
1.342 + p = *(void**)p;
1.343 + }
1.344 + }
1.345 +
1.346 +int free_blocks(void* chain)
1.347 + {
1.348 + void* p = chain;
1.349 + int c = 0;
1.350 + while (p)
1.351 + {
1.352 + void* n = *(void**)p;
1.353 + free_mem_block(p);
1.354 + p = n;
1.355 + ++c;
1.356 + }
1.357 + return c;
1.358 + }
1.359 +
1.360 +void test_mem_mgr(void)
1.361 + {
1.362 + void* chain = NULL;
1.363 + const poolinfo* pi = pool_list;
1.364 + int nblocks = 0;
1.365 + int nfreed = 0;
1.366 + for (; pi->block_size; ++pi)
1.367 + {
1.368 + nblocks += pi->block_count;
1.369 + test_mem_pool(pi->block_size, pi->block_count, &chain);
1.370 + }
1.371 + check_blocks(chain);
1.372 + nfreed = free_blocks(chain);
1.373 + assert(nfreed == nblocks);
1.374 + chain = NULL;
1.375 + for (--pi; pi >= pool_list; --pi)
1.376 + test_mem_pool(pi->block_size, pi->block_count, &chain);
1.377 + check_blocks(chain);
1.378 + nfreed = free_blocks(chain);
1.379 + assert(nfreed == nblocks);
1.380 + chain = NULL;
1.381 + kprintf("Memory Manager Test OK");
1.382 + }
1.383 +
1.384 +void test_suspend_1(void)
1.385 + {
1.386 + unsigned t1, t2, t3;
1.387 + int r;
1.388 + t1 = tmcount;
1.389 + delay(5*TM_PERIOD);
1.390 + t2 = tmcount;
1.391 + assert( ((int)t2)-((int)t1) >= 5 );
1.392 + r = suspend_task(TM_TASK);
1.393 + assert(r == OK);
1.394 + t1 = tmcount;
1.395 + delay(5*TM_PERIOD);
1.396 + t2 = tmcount;
1.397 + assert(t2==t1);
1.398 + r = resume_task(TM_TASK);
1.399 + assert(r == OK);
1.400 + t3 = tmcount;
1.401 + assert( ((int)t3)-((int)t2) >= 5 );
1.402 +
1.403 + r = suspend_task(TM_TASK);
1.404 + assert(r == OK);
1.405 + r = suspend_task(TM_TASK);
1.406 + assert(r == OK);
1.407 + t1 = tmcount;
1.408 + delay(5*TM_PERIOD);
1.409 + t2 = tmcount;
1.410 + assert(t2==t1);
1.411 + r = resume_task(TM_TASK);
1.412 + assert(r == OK);
1.413 + t3 = tmcount;
1.414 + assert(t3==t2);
1.415 + r = resume_task(TM_TASK);
1.416 + assert(r == OK);
1.417 + t3 = tmcount;
1.418 + assert( ((int)t3)-((int)t2) >= 5 );
1.419 +
1.420 + r = suspend_task(-1);
1.421 + assert(r == BAD_TASK_ID);
1.422 + r = suspend_task(300);
1.423 + assert(r == BAD_TASK_ID);
1.424 + r = suspend_task(NONEXISTENT_TASK);
1.425 + assert(r == BAD_TASK_ID);
1.426 + r = resume_task(-1);
1.427 + assert(r == BAD_TASK_ID);
1.428 + r = resume_task(300);
1.429 + assert(r == BAD_TASK_ID);
1.430 + r = resume_task(NONEXISTENT_TASK);
1.431 + assert(r == BAD_TASK_ID);
1.432 +
1.433 + kprintf("test_suspend_1 OK");
1.434 + }
1.435 +
1.436 +void test_priority_scheduling(void)
1.437 + {
1.438 + int init_pri = get_task_priority(current_task_id());
1.439 + resume_4(TASK1, TASK2, TASK3, TASK4);
1.440 + delay(80*TM_PERIOD);
1.441 + check_for_multiple_signals(TASK1, 50); // check no timeslicing
1.442 + assert(flush_signals()<=31);
1.443 + suspend_task(TASK1);
1.444 + delay(80*TM_PERIOD);
1.445 + check_for_multiple_signals(TASK2, 50); // check no timeslicing
1.446 + assert(flush_signals()<=31);
1.447 + suspend_task(TASK2);
1.448 + delay(80*TM_PERIOD);
1.449 + check_for_multiple_signals(TASK3, 50); // check no timeslicing
1.450 + assert(flush_signals()<=31);
1.451 + suspend_task(TASK3);
1.452 + delay(1);
1.453 + check_for_signal(TASK4);
1.454 + assert(flush_signals()<=1);
1.455 +
1.456 + t1func = 1;
1.457 + t2func = 1;
1.458 + t3func = 1;
1.459 + t4func = 1;
1.460 +
1.461 + resume_4(TASK1, TASK2, TASK3, TASK4);
1.462 + delay(10);
1.463 + flush_signals();
1.464 +
1.465 + resume_4(TASK3, TASK2, TASK4, TASK1);
1.466 + delay(10);
1.467 + check_signal_4(TASK3, TASK2, TASK4, TASK1);
1.468 + check_no_signal();
1.469 + resume_4(TASK1, TASK2, TASK3, TASK4);
1.470 + check_no_signal(); // all lower priority so don't run
1.471 + set_task_priority(TASK2, 255); // higher than current task so run immediately
1.472 + check_for_signal(TASK2);
1.473 + set_task_priority(TASK4, 116);
1.474 + check_no_signal(); // all lower priority so don't run
1.475 + delay(10);
1.476 + check_for_signal(TASK4);
1.477 + check_for_signal(TASK1);
1.478 + check_for_signal(TASK3);
1.479 + set_task_priority(TASK1, 116);
1.480 + set_task_priority(TASK2, 116);
1.481 + set_task_priority(TASK3, 116);
1.482 + set_task_priority(TASK4, 116);
1.483 + resume_4(TASK1, TASK2, TASK3, TASK4);
1.484 + set_task_priority(current_task_id(), 112); // drop current task priority
1.485 + assert(get_task_priority(current_task_id())==112);
1.486 + check_signal_4(TASK1, TASK2, TASK3, TASK4);
1.487 + set_task_priority(current_task_id(), init_pri);
1.488 + assert(get_task_priority(current_task_id())==init_pri);
1.489 +
1.490 + kprintf("test_priority_scheduling OK");
1.491 + }
1.492 +
1.493 +unsigned sem_test(int task_id)
1.494 + {
1.495 + int r = semaphore_signal(TEST_SEM);
1.496 + assert(r==OK);
1.497 + return check_for_signal(task_id);
1.498 + }
1.499 +
1.500 +unsigned sem_test_p(int task_id, int parameter)
1.501 + {
1.502 + unsigned t;
1.503 + int r = semaphore_signal(TEST_SEM);
1.504 + assert(r==OK);
1.505 + r = check_for_signal_p(task_id, task_id, &t);
1.506 + assert(r == parameter);
1.507 + return t;
1.508 + }
1.509 +
1.510 +unsigned sem_test_pt(int task_id, int parameter)
1.511 + {
1.512 + unsigned t;
1.513 + int r = semaphore_signal(TEST_SEM);
1.514 + assert(r==OK);
1.515 + r = check_for_signal_p(task_id, task_id, &t);
1.516 + assert(r == parameter);
1.517 + return t;
1.518 + }
1.519 +
1.520 +void test_semaphore(void)
1.521 + {
1.522 + unsigned t1, t2, t3;
1.523 + int r;
1.524 + int init_pri = get_task_priority(current_task_id());
1.525 + set_task_priority(TASK1, 128);
1.526 + set_task_priority(TASK2, 128);
1.527 + set_task_priority(TASK3, 128);
1.528 + set_task_priority(TASK4, 128);
1.529 + t1func = 2;
1.530 + t2func = 2;
1.531 + t3func = 2;
1.532 + t4func = 2;
1.533 + resume_4(TASK1, TASK2, TASK3, TASK4);
1.534 + delay(10); // let tasks wait on semaphore
1.535 + check_no_signal();
1.536 + sem_test(TASK1); // test they are released in same order
1.537 + sem_test(TASK2);
1.538 + sem_test(TASK3);
1.539 + sem_test(TASK4);
1.540 + check_no_signal();
1.541 + set_task_priority(TASK3, 132); // test highest priority is released first
1.542 + sem_test(TASK3);
1.543 + sem_test(TASK3);
1.544 + suspend_task(TASK3); // test suspended task doesn't contend for semaphore
1.545 + sem_test(TASK1);
1.546 + sem_test(TASK2);
1.547 + sem_test(TASK4);
1.548 + sem_test(TASK1);
1.549 + suspend_task(TASK2);
1.550 + sem_test(TASK4);
1.551 + sem_test(TASK1);
1.552 + sem_test(TASK4);
1.553 + set_task_priority(TASK2, 136); // change priority while suspended
1.554 + sem_test(TASK1);
1.555 + sem_test(TASK4);
1.556 + sem_test(TASK1);
1.557 + resume_task(TASK2);
1.558 + sem_test(TASK2);
1.559 + sem_test(TASK2); // test new highest priority task acquires semaphore first
1.560 + delay(100*TM_PERIOD);
1.561 + check_no_signal(); // check waits don't time out
1.562 +
1.563 + t2func = 3; // switch over to timed waits for task 2
1.564 + t1 = sem_test(TASK2); // get one last message of previous type
1.565 + delay(5*TM_PERIOD);
1.566 + t2 = sem_test_p(TASK2, OK); // signal after half the timeout and check OK
1.567 + delay(11*TM_PERIOD); // wait for > timeout
1.568 + r = check_for_signal_p(TASK2, TASK2, &t3);
1.569 + assert(r == TIMED_OUT);
1.570 + kprintf("t2-t1=%d t3-t2=%d", t2-t1, t3-t2);
1.571 + assert(t2-t1 >= 5);
1.572 + assert(t3-t2 >= 10);
1.573 + sem_test_p(TASK2, OK);
1.574 + resume_task(TASK3);
1.575 +
1.576 + set_task_priority(current_task_id(), 176); // raise current task priority
1.577 + semaphore_signal(TEST_SEM); // signal semaphore 4 times - should release all 4 waiting threads
1.578 + semaphore_signal(TEST_SEM);
1.579 + semaphore_signal(TEST_SEM);
1.580 + semaphore_signal(TEST_SEM);
1.581 + set_task_priority(current_task_id(), init_pri); // let tasks run
1.582 + r = check_for_signal_p(TASK2, TASK2, NULL);
1.583 + assert(r == OK);
1.584 + check_for_signal(TASK3);
1.585 + check_for_signal(TASK4);
1.586 + check_for_signal(TASK1);
1.587 + set_task_priority(current_task_id(), 176); // raise current task priority
1.588 + busy_wait(11); // let semaphore wait time out
1.589 + t1func = 4; // switch all threads over
1.590 + t2func = 4; //
1.591 + t3func = 4; //
1.592 + t4func = 4; //
1.593 + semaphore_signal(TEST_SEM); // signal semaphore 3 times - should release other 3 waiting threads
1.594 + semaphore_signal(TEST_SEM);
1.595 + semaphore_signal(TEST_SEM);
1.596 + set_task_priority(current_task_id(), init_pri); // let tasks run
1.597 + r = check_for_signal_p(TASK2, TASK2, NULL);
1.598 + assert(r == TIMED_OUT);
1.599 + check_for_signal(TASK3);
1.600 + check_for_signal(TASK4);
1.601 + check_for_signal(TASK1);
1.602 +
1.603 + kprintf("test_semaphore OK");
1.604 + }
1.605 +
1.606 +void test_message_queue(void)
1.607 + {
1.608 + unsigned t1, t2, t3, t4;
1.609 + int tid, p, r;
1.610 + int init_pri = get_task_priority(current_task_id());
1.611 + p = 0;
1.612 + t1 = 0;
1.613 + for (tid = TASK1; tid <= TASK4; ++tid)
1.614 + {
1.615 + for (p = 1; p; p<<=1)
1.616 + {
1.617 + tsend_run_signal_p(tid, p);
1.618 + r = check_for_signal_p(OC_TASK, tid, NULL);
1.619 + assert(r == p);
1.620 + }
1.621 + }
1.622 + check_no_signal();
1.623 + set_task_priority(current_task_id(), 176); // raise current task priority
1.624 + set_task_priority(TASK4, 144); // change task priorities while they are waiting
1.625 + set_task_priority(TASK3, 140);
1.626 + set_task_priority(TASK2, 136);
1.627 + set_task_priority(TASK1, 132);
1.628 + t1func = 5; // switch task 1 to timed waits
1.629 + for (tid = TASK1; tid <= TASK4; ++tid)
1.630 + {
1.631 + for (p = 0; p<0x40000000; p+=(0x413b9cb+tid))
1.632 + {
1.633 + tsend_run_signal_p(tid, p); // let multiple messages accumulate on the queues
1.634 + }
1.635 + }
1.636 + check_no_signal();
1.637 + set_task_priority(current_task_id(), init_pri); // let tasks run
1.638 + kprintf("init_pri=%d",init_pri);
1.639 + for (tid = TASK4; tid >= TASK1; --tid)
1.640 + {
1.641 + for (p = 0; p<0x40000000; p+=(0x413b9cb+tid))
1.642 + {
1.643 + r = check_for_signal_p(OC_TASK, tid, &t1);
1.644 + assert(r == p);
1.645 + }
1.646 + }
1.647 +
1.648 + delay(5*TM_PERIOD);
1.649 + tsend_run_signal_p(TASK1, p); // send after half timeout
1.650 + r = check_for_signal_p(OC_TASK, TASK1, &t2);
1.651 + assert(r == p);
1.652 + delay(11*TM_PERIOD); // wait for > timeout
1.653 + tsend_run_signal_p(TASK1, ~p); // send after timeout
1.654 + r = check_for_signal_p(TASK1, TASK1, &t3);
1.655 + assert(r == TIMED_OUT);
1.656 + kprintf("t2-t1=%d t3-t2=%d", t2-t1, t3-t2);
1.657 + assert(t2-t1 >= 5);
1.658 + assert(t3-t2 >= 10);
1.659 + r = check_for_signal_p(OC_TASK, TASK1, &t4);
1.660 + assert(r == ~p);
1.661 + assert(t4-t3 <= 1);
1.662 + t1func = 6; // switch task 1 to timed semaphore wait
1.663 + t2func = 7; // switch task 2 to timed queue wait
1.664 + t3func = 8; //
1.665 + t4func = 8; //
1.666 + for (tid = TASK1; tid <= TASK4; ++tid)
1.667 + {
1.668 + tsend_run_signal_p(tid, 0);
1.669 + r = check_for_signal_p(OC_TASK, tid, NULL);
1.670 + assert(r == 0);
1.671 + }
1.672 + check_no_signal();
1.673 +
1.674 + kprintf("test_message_queue OK");
1.675 + }
1.676 +
1.677 +void random_isr(unsigned n)
1.678 + {
1.679 + random_isr_msg* m;
1.680 + unsigned extra = 1;
1.681 + unsigned count = 1;
1.682 + int r;
1.683 + if (!(n%11))
1.684 + ++count;
1.685 + if (!(n%13))
1.686 + ++count;
1.687 + while (count--)
1.688 + {
1.689 + m = (random_isr_msg*)alloc_mem_block(sizeof(random_isr_msg));
1.690 + m->header.msg_id = MSG_ID_RND_ISR;
1.691 + m->random_isr_number = n;
1.692 + extra *= n;
1.693 + m->extra = extra;
1.694 + r = send_msg(L1_TASK, &m->header);
1.695 + }
1.696 + if (random_sem_signal_count && !--random_sem_signal_count)
1.697 + {
1.698 + random_sem_signal_count = random_sem_signal_interval;
1.699 + semaphore_signal(ISR_SEM);
1.700 + }
1.701 + }
1.702 +
1.703 +void flush_queue(msghdr** f, msghdr** l, msghdr* tm)
1.704 + {
1.705 + msghdr* m = *f;
1.706 + *f = NULL;
1.707 + *l = NULL;
1.708 + send_to_epoc(tm);
1.709 + while (m)
1.710 + {
1.711 + msghdr* n = m->next;
1.712 + send_to_epoc(m);
1.713 + m = n;
1.714 + }
1.715 + }
1.716 +
1.717 +void l1_task_entry(void)
1.718 + {
1.719 + msghdr* first = NULL;
1.720 + msghdr* last = NULL;
1.721 + unsigned state = 0;
1.722 + unsigned extra_count = 0;
1.723 + unsigned extra_value = 0;
1.724 + assert(current_task_id() == L1_TASK);
1.725 + kprintf("L1_TASK running");
1.726 + for (;;)
1.727 + {
1.728 + msghdr* m = NULL;
1.729 + int r = recv_msg(&m, WAIT_FOREVER);
1.730 + assert(r == OK);
1.731 + switch (m->msg_id)
1.732 + {
1.733 + case MSG_ID_RND_ISR:
1.734 + {
1.735 + random_isr_msg* rm = (random_isr_msg*)m;
1.736 + assert(m->sending_task_id == TASK_ID_ISR);
1.737 + assert(rm->random_isr_number == next_random_id);
1.738 + if (state == 0)
1.739 + {
1.740 + extra_count = 0;
1.741 + if (!(next_random_id % 11))
1.742 + ++extra_count;
1.743 + if (!(next_random_id % 13))
1.744 + ++extra_count;
1.745 + extra_value = next_random_id;
1.746 + }
1.747 + else if (state > 0)
1.748 + {
1.749 + extra_value *= next_random_id;
1.750 + }
1.751 + assert(rm->extra == extra_value);
1.752 + if (++state > extra_count)
1.753 + state = 0;
1.754 + if (state == 0)
1.755 + ++next_random_id;
1.756 + if (rm->random_isr_number == 0)
1.757 + send_msg(OC_TASK, m), m=NULL;
1.758 + if (state == 1 && extra_count == 2 && m)
1.759 + {
1.760 + flush_queue(&first, &last, m);
1.761 + m = NULL;
1.762 + }
1.763 + if (random_send_count && !--random_send_count)
1.764 + {
1.765 + random_send_count = random_send_interval;
1.766 + if (m)
1.767 + send_msg(TASK2, m), m=NULL;
1.768 + }
1.769 + break;
1.770 + }
1.771 + case MSG_ID_DATA:
1.772 + m->next = NULL;
1.773 + if (last)
1.774 + last->next = m;
1.775 + else
1.776 + first = m;
1.777 + last = m;
1.778 + m = NULL;
1.779 + break;
1.780 + case MSG_ID_FLUSH:
1.781 + flush_queue(&first, &last, m);
1.782 + m = NULL;
1.783 + break;
1.784 + default:
1.785 + kprintf("L1<-%08x",m->msg_id);
1.786 + break;
1.787 + }
1.788 + if (m)
1.789 + free_mem_block(m);
1.790 + }
1.791 + }
1.792 +
1.793 +void l2_task_entry(void)
1.794 + {
1.795 + assert(current_task_id() == L2_TASK);
1.796 + kprintf("L2_TASK running");
1.797 + for (;;)
1.798 + {
1.799 + msghdr* m = NULL;
1.800 + int r = recv_msg(&m, WAIT_FOREVER);
1.801 + assert(r == OK);
1.802 + switch (m->msg_id)
1.803 + {
1.804 + case MSG_ID_DATA:
1.805 + {
1.806 + data_msg* dm = (data_msg*)m;
1.807 + int i;
1.808 + unsigned char cs = 0;
1.809 + for (i=0; i<dm->length; ++i)
1.810 + cs = (unsigned char)(cs + dm->data[i]);
1.811 + dm->checksum = cs;
1.812 + send_msg(L1_TASK, m);
1.813 + m=NULL;
1.814 + break;
1.815 + }
1.816 + default:
1.817 + kprintf("L2<-%08x",m->msg_id);
1.818 + break;
1.819 + }
1.820 + if (m)
1.821 + free_mem_block(m);
1.822 + }
1.823 + }
1.824 +
1.825 +void rr_task_entry(void)
1.826 + {
1.827 + assert(current_task_id() == RR_TASK);
1.828 + kprintf("RR_TASK running");
1.829 + for (;;)
1.830 + {
1.831 + msghdr* m = NULL;
1.832 + int r = recv_msg(&m, WAIT_FOREVER);
1.833 + assert(r == OK);
1.834 + switch (m->msg_id)
1.835 + {
1.836 + case MSG_ID_DATA:
1.837 + send_msg(L2_TASK, m);
1.838 + m=NULL;
1.839 + break;
1.840 + default:
1.841 + kprintf("RR<-%08x",m->msg_id);
1.842 + break;
1.843 + }
1.844 + if (m)
1.845 + free_mem_block(m);
1.846 + }
1.847 + }
1.848 +
1.849 +void tm_task_entry(void)
1.850 + {
1.851 + assert(current_task_id() == TM_TASK);
1.852 + kprintf("TM_TASK running");
1.853 + for (;;)
1.854 + {
1.855 + msghdr* m = NULL;
1.856 + int r = recv_msg(&m, WAIT_FOREVER);
1.857 + assert(r == OK);
1.858 + switch (m->msg_id)
1.859 + {
1.860 + case MSG_ID_TIMEOUT:
1.861 + tmcount = ((timer_msg*)m)->count;
1.862 + assert(m->sending_task_id == TASK_ID_ISR);
1.863 + if (!(tmcount & 255))
1.864 + {
1.865 + report_msg* rpt = (report_msg*)alloc_mem_block(sizeof(report_msg));
1.866 + rpt->header.msg_id = MSG_ID_TM_RPT;
1.867 + rpt->count = tmcount;
1.868 + rpt->ok_count = 0;
1.869 + rpt->bad_count = 0;
1.870 + send_to_epoc(&rpt->header);
1.871 + }
1.872 + break;
1.873 + default:
1.874 + kprintf("TM<-%08x",m->msg_id);
1.875 + break;
1.876 + }
1.877 + free_mem_block(m);
1.878 + }
1.879 + }
1.880 +
1.881 +void generic_task(volatile int* f)
1.882 + {
1.883 + int r;
1.884 + msghdr* m;
1.885 + unsigned t1, t2;
1.886 + unsigned count = 0;
1.887 + unsigned ok_count = 0;
1.888 + unsigned bad_count = 0;
1.889 + while (*f==0)
1.890 + {
1.891 + send_run_signal();
1.892 + busy_wait(1);
1.893 + }
1.894 + while (*f==1)
1.895 + {
1.896 + send_run_signal();
1.897 + suspend_task(current_task_id());
1.898 + }
1.899 + while (*f==2)
1.900 + {
1.901 + r = semaphore_wait(TEST_SEM, WAIT_FOREVER);
1.902 + assert(r == OK);
1.903 + send_run_signal();
1.904 + }
1.905 + while (*f==3)
1.906 + {
1.907 + r = semaphore_wait(TEST_SEM, 10*TM_PERIOD);
1.908 + assert(r==OK || r==TIMED_OUT);
1.909 + send_run_signal_p(r);
1.910 + }
1.911 + while (*f==4)
1.912 + {
1.913 + r = recv_msg(&m, WAIT_FOREVER);
1.914 + assert(r==OK);
1.915 + assert(m->sending_task_id == OC_TASK);
1.916 + r = send_msg(OC_TASK, m);
1.917 + assert(r == OK);
1.918 + }
1.919 + while (*f==5)
1.920 + {
1.921 + r = recv_msg(&m, 10*TM_PERIOD);
1.922 + assert(r==OK || r==TIMED_OUT);
1.923 + if (r == OK)
1.924 + {
1.925 + assert(m->sending_task_id == OC_TASK);
1.926 + r = send_msg(OC_TASK, m);
1.927 + assert(r == OK);
1.928 + }
1.929 + else
1.930 + send_run_signal_p(r);
1.931 + }
1.932 + while (*f==6)
1.933 + {
1.934 + t1 = tick_count();
1.935 + r = semaphore_wait(ISR_SEM, 5);
1.936 + t2 = tick_count() - t1;
1.937 + if (r == TIMED_OUT && t2<5)
1.938 + {
1.939 + kprintf("SEM timed out too soon: %d", t2);
1.940 + ++bad_count;
1.941 + }
1.942 + if (r == OK)
1.943 + ++ok_count;
1.944 + ++count;
1.945 + if (!(count & 0xff))
1.946 + {
1.947 + report_msg* rpt = (report_msg*)alloc_mem_block(sizeof(report_msg));
1.948 + rpt->header.msg_id = MSG_ID_SEM_RPT;
1.949 + rpt->count = count;
1.950 + rpt->ok_count = ok_count;
1.951 + rpt->bad_count = bad_count;
1.952 + send_to_epoc(&rpt->header);
1.953 + }
1.954 + }
1.955 + while (*f==7)
1.956 + {
1.957 + t1 = tick_count();
1.958 + r = recv_msg(&m, 5);
1.959 + t2 = tick_count() - t1;
1.960 + if (r == TIMED_OUT && t2<5)
1.961 + {
1.962 + kprintf("RECV timed out too soon: %d", t2);
1.963 + ++bad_count;
1.964 + }
1.965 + if (r==OK)
1.966 + ++ok_count, free_mem_block(m);
1.967 + ++count;
1.968 + if (!(count & 0xff))
1.969 + {
1.970 + report_msg* rpt = (report_msg*)alloc_mem_block(sizeof(report_msg));
1.971 + rpt->header.msg_id = MSG_ID_RCV_RPT;
1.972 + rpt->count = count;
1.973 + rpt->ok_count = ok_count;
1.974 + rpt->bad_count = bad_count;
1.975 + send_to_epoc(&rpt->header);
1.976 + }
1.977 + }
1.978 + kprintf("Task %d finished", current_task_id());
1.979 + for(;;)
1.980 + suspend_task(current_task_id());
1.981 + }
1.982 +
1.983 +void task1_entry(void)
1.984 + {
1.985 + assert(current_task_id() == TASK1);
1.986 + generic_task(&t1func);
1.987 + }
1.988 +
1.989 +void task2_entry(void)
1.990 + {
1.991 + assert(current_task_id() == TASK2);
1.992 + generic_task(&t2func);
1.993 + }
1.994 +
1.995 +void task3_entry(void)
1.996 + {
1.997 + assert(current_task_id() == TASK3);
1.998 + generic_task(&t3func);
1.999 + }
1.1000 +
1.1001 +void task4_entry(void)
1.1002 + {
1.1003 + assert(current_task_id() == TASK4);
1.1004 + generic_task(&t4func);
1.1005 + }
1.1006 +
1.1007 +
1.1008 +
1.1009 +void oo_overall_control(void)
1.1010 + {
1.1011 + int r;
1.1012 + msghdr* m;
1.1013 + random_isr_msg* rm;
1.1014 + unsigned t1, t2, rss_interval;
1.1015 + kprintf("OC_TASK running");
1.1016 + assert(current_task_id() == OC_TASK);
1.1017 + resume_task(L2_TASK);
1.1018 + resume_task(RR_TASK);
1.1019 + resume_task(TM_TASK);
1.1020 + test_mem_mgr();
1.1021 +
1.1022 + kprintf("Wait for init msg");
1.1023 + r = recv_msg(&m, WAIT_FOREVER);
1.1024 + assert(r == OK);
1.1025 + assert(m->msg_id == MSG_ID_INIT);
1.1026 + assert(m->sending_task_id == TASK_ID_UNKNOWN);
1.1027 + free_mem_block(m);
1.1028 + kprintf("Received init msg");
1.1029 +
1.1030 + r = start_periodic_timer(TM_TIMER, TM_TASK, TM_INIT_DELAY, TM_PERIOD, NULL);
1.1031 + assert(r == OK);
1.1032 + delay(TM_INIT_DELAY-10);
1.1033 + assert(tmcount == 0);
1.1034 + delay(10*TM_PERIOD+20);
1.1035 + assert(tmcount > 0);
1.1036 + test_suspend_1();
1.1037 + test_priority_scheduling();
1.1038 + test_semaphore();
1.1039 + test_message_queue();
1.1040 +
1.1041 + resume_task(L1_TASK);
1.1042 + r = start_random_isr(&random_isr);
1.1043 + if (r != OK)
1.1044 + goto no_random_isr;
1.1045 +
1.1046 + r = recv_msg(&m, WAIT_FOREVER);
1.1047 + assert(r == OK);
1.1048 + assert(m->msg_id == MSG_ID_RND_ISR);
1.1049 + assert(m->sending_task_id == L1_TASK);
1.1050 + rm = (random_isr_msg*)m;
1.1051 + assert(rm->random_isr_number == 0);
1.1052 + free_mem_block(m);
1.1053 + t1 = next_random_id;
1.1054 + delay(1024);
1.1055 + t2 = next_random_id;
1.1056 + kprintf("%d random ISRs in 1024 ticks", t2-t1);
1.1057 + rss_interval = (5*(t2-t1)+512)/1024;
1.1058 + set_task_priority(TASK1, 196); // needs to be higher than DfcThread1
1.1059 + set_task_priority(TASK2, 196);
1.1060 + random_sem_signal_interval = rss_interval;
1.1061 + random_sem_signal_count = rss_interval;
1.1062 + random_send_interval = rss_interval;
1.1063 + random_send_count = rss_interval;
1.1064 +
1.1065 +no_random_isr:
1.1066 + m = (msghdr*)alloc_mem_block(sizeof(msghdr));
1.1067 + m->msg_id = MSG_ID_DONE;
1.1068 + send_to_epoc(m);
1.1069 + kprintf("All tests completed OK");
1.1070 + for (;;)
1.1071 + {
1.1072 + int r = recv_msg(&m, WAIT_FOREVER);
1.1073 + assert(r == OK);
1.1074 + switch (m->msg_id)
1.1075 + {
1.1076 + case MSG_ID_DATA:
1.1077 + send_msg(RR_TASK, m);
1.1078 + m=NULL;
1.1079 + break;
1.1080 + case MSG_ID_FLUSH:
1.1081 + send_msg(L1_TASK, m);
1.1082 + m=NULL;
1.1083 + break;
1.1084 + case MSG_ID_DONE:
1.1085 + stop_random_isr();
1.1086 + stop_timer(TM_TIMER);
1.1087 + suspend_task(L1_TASK);
1.1088 + suspend_task(L2_TASK);
1.1089 + suspend_task(RR_TASK);
1.1090 + suspend_task(TM_TASK);
1.1091 + suspend_task(TASK1);
1.1092 + suspend_task(TASK2);
1.1093 + suspend_task(TASK3);
1.1094 + suspend_task(TASK4);
1.1095 + break;
1.1096 + default:
1.1097 + kprintf("OC<-%08x",m->msg_id);
1.1098 + break;
1.1099 + }
1.1100 + if (m)
1.1101 + free_mem_block(m);
1.1102 + }
1.1103 + }
1.1104 +
1.1105 +#ifdef __cplusplus
1.1106 +}
1.1107 +#endif