00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <avr/io.h>
00013 #include <avr/interrupt.h>
00014
00015 #include "os.h"
00016 #include "kernel.h"
00017 #include "error_code.h"
00018
00019
00020
00021
00022
00023 extern int main();
00024
00025
00026 extern const unsigned char PPP[];
00027
00028
00029 extern const unsigned int PT;
00030
00031
00032 static task_descriptor_t* cur_task = NULL;
00033
00034
00035 static volatile uint16_t kernel_sp;
00036
00037
00038 static task_descriptor_t task_desc[MAXPROCESS + 1];
00039
00040
00041 static task_descriptor_t* idle_task = &task_desc[MAXPROCESS];
00042
00043
00044 static volatile kernel_request_t kernel_request;
00045
00046
00047 static volatile create_args_t kernel_request_create_args;
00048
00049
00050 static volatile int kernel_request_retval;
00051
00052
00053 static volatile EVENT* kernel_request_event_ptr;
00054
00055
00056 static queue_t dead_pool_queue;
00057
00058
00059 static uint8_t num_events_created = 0;
00060
00061
00062 static queue_t rr_queue;
00063
00064
00065 static queue_t system_queue;
00066
00067
00068 static queue_t event_queue[MAXEVENT];
00069
00070
00071 static uint8_t ticks_remaining = 0;
00072
00073
00074 static uint8_t slot_task_finished = 0;
00075
00076
00077 static int slot_name_index = 0;
00078
00079
00080 static task_descriptor_t* name_to_task_ptr[MAXNAME + 1];
00081
00082
00083 static uint8_t name_in_PPP[MAXNAME + 1];
00084
00085
00086 static uint8_t volatile error_msg = ERR_RUN_1_USER_CALLED_OS_ABORT;
00087
00088
00089
00090
00091 static void kernel_main_loop(void);
00092 static void kernel_dispatch(void);
00093 static void kernel_handle_request(void);
00094
00095 static void exit_kernel(void) __attribute((naked));
00096 static void enter_kernel(void) __attribute((naked));
00097 void TIMER1_COMPA_vect(void) __attribute__ ((signal, naked));
00098
00099 static int kernel_create_task();
00100 static void kernel_terminate_task(void);
00101
00102 static void kernel_event_wait(void);
00103 static void kernel_event_signal(uint8_t is_broadcast, uint8_t and_next);
00104
00105
00106 static void enqueue(queue_t* queue_ptr, task_descriptor_t* task_to_add);
00107 static task_descriptor_t* dequeue(queue_t* queue_ptr);
00108
00109 static void kernel_update_ticker(void);
00110 static void check_PPP_names(void);
00111 static void idle (void);
00112 static void _delay_25ms(void);
00113
00114
00115
00116
00117
00118
00119
00120 static void idle (void)
00121 {
00122 for(;;)
00123 {};
00124 }
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 static void kernel_main_loop(void)
00142 {
00143 for(;;)
00144 {
00145 kernel_dispatch();
00146
00147 exit_kernel();
00148
00149
00150
00151
00152 kernel_handle_request();
00153 }
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 static void kernel_dispatch(void)
00166 {
00167
00168
00169
00170
00171 if(cur_task->state != RUNNING || cur_task == idle_task)
00172 {
00173 if(system_queue.head != NULL)
00174 {
00175 cur_task = dequeue(&system_queue);
00176 }
00177 else if(!slot_task_finished && name_to_task_ptr[PPP[slot_name_index]] != NULL)
00178 {
00179
00180 cur_task = name_to_task_ptr[PPP[slot_name_index]];
00181 }
00182 else if(rr_queue.head != NULL)
00183 {
00184 cur_task = dequeue(&rr_queue);
00185 }
00186 else
00187 {
00188
00189 cur_task = idle_task;
00190 }
00191
00192 cur_task->state = RUNNING;
00193 }
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 static void kernel_handle_request(void)
00206 {
00207 switch(kernel_request)
00208 {
00209 case NONE:
00210
00211 break;
00212
00213 case TIMER_EXPIRED:
00214 kernel_update_ticker();
00215
00216
00217 if(cur_task->level == RR && cur_task->state == RUNNING)
00218 {
00219 cur_task->state = READY;
00220 enqueue(&rr_queue, cur_task);
00221 }
00222 break;
00223
00224 case TASK_CREATE:
00225 kernel_request_retval = kernel_create_task();
00226
00227
00228
00229
00230 if(kernel_request_retval)
00231 {
00232
00233 if(kernel_request_create_args.level == SYSTEM && cur_task->level != SYSTEM)
00234 {
00235 cur_task->state = READY;
00236 }
00237
00238
00239 if(cur_task->level == RR &&
00240 kernel_request_create_args.level == PERIODIC &&
00241 PPP[slot_name_index] == kernel_request_create_args.name)
00242 {
00243 cur_task->state = READY;
00244 }
00245
00246
00247 if(cur_task->level == RR && cur_task->state == READY)
00248 {
00249 enqueue(&rr_queue, cur_task);
00250 }
00251 }
00252 break;
00253
00254 case TASK_TERMINATE:
00255 if(cur_task != idle_task)
00256 {
00257 kernel_terminate_task();
00258 }
00259 break;
00260
00261 case TASK_NEXT:
00262 switch(cur_task->level)
00263 {
00264 case SYSTEM:
00265 enqueue(&system_queue, cur_task);
00266 break;
00267
00268 case PERIODIC:
00269 slot_task_finished = 1;
00270 break;
00271
00272 case RR:
00273 enqueue(&rr_queue, cur_task);
00274 break;
00275
00276 default:
00277 break;
00278 }
00279
00280 cur_task->state = READY;
00281 break;
00282
00283 case TASK_GET_ARG:
00284
00285 break;
00286
00287 case EVENT_INIT:
00288 kernel_request_event_ptr = NULL;
00289 if(num_events_created < MAXEVENT)
00290 {
00291
00292
00293
00294
00295 kernel_request_event_ptr = (EVENT *)(uint16_t)(num_events_created + 1);
00296
00297
00298
00299
00300 ++num_events_created;
00301 }
00302 else
00303 {
00304 kernel_request_event_ptr = (EVENT *)(uint16_t)0;
00305 }
00306 break;
00307
00308 case EVENT_WAIT:
00309
00310 if(cur_task != idle_task)
00311 {
00312 kernel_event_wait();
00313 }
00314
00315 break;
00316
00317 case EVENT_SIGNAL:
00318 kernel_event_signal(0 , 0 );
00319 break;
00320
00321 case EVENT_BROADCAST:
00322 kernel_event_signal(1 , 0 );
00323 break;
00324
00325 case EVENT_SIGNAL_AND_NEXT:
00326 if(cur_task->level == PERIODIC)
00327 {
00328 slot_task_finished = 1;
00329 }
00330
00331 kernel_event_signal(0 , 1 );
00332
00333 break;
00334
00335 case EVENT_BROADCAST_AND_NEXT:
00336 if(cur_task->level == PERIODIC)
00337 {
00338 slot_task_finished = 1;
00339 }
00340
00341 kernel_event_signal(1 , 1 );
00342 break;
00343
00344 default:
00345
00346 error_msg = ERR_RUN_8_RTOS_INTERNAL_ERROR;
00347 OS_Abort();
00348 break;
00349 }
00350
00351 kernel_request = NONE;
00352 }
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 #define SAVE_CTX_TOP() asm volatile (\
00368 "push r31 \n\t"\
00369 "in r31,__SREG__ \n\t"\
00370 "cli \n\t"::);
00371
00372 #define STACK_SREG_SET_I_BIT() asm volatile (\
00373 "ori r31, 0x80 \n\t"::);
00374
00375 #define SAVE_CTX_BOTTOM() asm volatile (\
00376 "push r31 \n\t"\
00377 "push r30 \n\t"\
00378 "push r29 \n\t"\
00379 "push r28 \n\t"\
00380 "push r27 \n\t"\
00381 "push r26 \n\t"\
00382 "push r25 \n\t"\
00383 "push r24 \n\t"\
00384 "push r23 \n\t"\
00385 "push r22 \n\t"\
00386 "push r21 \n\t"\
00387 "push r20 \n\t"\
00388 "push r19 \n\t"\
00389 "push r18 \n\t"\
00390 "push r17 \n\t"\
00391 "push r16 \n\t"\
00392 "push r15 \n\t"\
00393 "push r14 \n\t"\
00394 "push r13 \n\t"\
00395 "push r12 \n\t"\
00396 "push r11 \n\t"\
00397 "push r10 \n\t"\
00398 "push r9 \n\t"\
00399 "push r8 \n\t"\
00400 "push r7 \n\t"\
00401 "push r6 \n\t"\
00402 "push r5 \n\t"\
00403 "push r4 \n\t"\
00404 "push r3 \n\t"\
00405 "push r2 \n\t"\
00406 "push r1 \n\t"\
00407 "push r0 \n\t"::);
00408
00409
00410
00411
00412 #define SAVE_CTX() SAVE_CTX_TOP();SAVE_CTX_BOTTOM();
00413
00414
00415
00416
00417 #define RESTORE_CTX() asm volatile (\
00418 "pop r0 \n\t"\
00419 "pop r1 \n\t"\
00420 "pop r2 \n\t"\
00421 "pop r3 \n\t"\
00422 "pop r4 \n\t"\
00423 "pop r5 \n\t"\
00424 "pop r6 \n\t"\
00425 "pop r7 \n\t"\
00426 "pop r8 \n\t"\
00427 "pop r9 \n\t"\
00428 "pop r10 \n\t"\
00429 "pop r11 \n\t"\
00430 "pop r12 \n\t"\
00431 "pop r13 \n\t"\
00432 "pop r14 \n\t"\
00433 "pop r15 \n\t"\
00434 "pop r16 \n\t"\
00435 "pop r17 \n\t"\
00436 "pop r18 \n\t"\
00437 "pop r19 \n\t"\
00438 "pop r20 \n\t"\
00439 "pop r21 \n\t"\
00440 "pop r22 \n\t"\
00441 "pop r23 \n\t"\
00442 "pop r24 \n\t"\
00443 "pop r25 \n\t"\
00444 "pop r26 \n\t"\
00445 "pop r27 \n\t"\
00446 "pop r28 \n\t"\
00447 "pop r29 \n\t"\
00448 "pop r30 \n\t"\
00449 "pop r31 \n\t"\
00450 "out __SREG__, r31 \n\t"\
00451 "pop r31 \n\t"::);
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469 static void exit_kernel(void)
00470 {
00471
00472
00473
00474
00475 SAVE_CTX();
00476
00477
00478
00479
00480 kernel_sp = SP;
00481
00482
00483
00484
00485 SP = (uint16_t)(cur_task->sp);
00486
00487
00488
00489
00490 RESTORE_CTX();
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501 asm volatile ("ret\n"::);
00502 }
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514 static void enter_kernel(void)
00515 {
00516
00517
00518
00519
00520 SAVE_CTX();
00521
00522
00523
00524
00525 cur_task->sp = (uint8_t*)SP;
00526
00527
00528
00529
00530 SP = kernel_sp;
00531
00532
00533
00534
00535 RESTORE_CTX();
00536
00537
00538
00539
00540
00541
00542
00543 asm volatile ("ret\n"::);
00544 }
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561 void TIMER1_COMPA_vect(void)
00562 {
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574 SAVE_CTX_TOP();
00575
00576 STACK_SREG_SET_I_BIT();
00577
00578 SAVE_CTX_BOTTOM();
00579
00580 cur_task->sp = (uint8_t*)SP;
00581
00582
00583
00584
00585
00586
00587 SP = kernel_sp;
00588
00589
00590
00591
00592 kernel_request = TIMER_EXPIRED;
00593
00594
00595
00596
00597 OCR1A += TICK_CYCLES;
00598
00599
00600
00601
00602 SP = kernel_sp;
00603
00604
00605
00606
00607 RESTORE_CTX();
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617 asm volatile ("ret\n"::);
00618 }
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632 static int kernel_create_task()
00633 {
00634
00635 task_descriptor_t *p;
00636 uint8_t* stack_bottom;
00637
00638
00639 if (dead_pool_queue.head == NULL)
00640 {
00641
00642 return 0;
00643 }
00644
00645 if(kernel_request_create_args.level == PERIODIC &&
00646 (kernel_request_create_args.name == IDLE ||
00647 kernel_request_create_args.name > MAXNAME))
00648 {
00649
00650 error_msg = ERR_2_CREATE_NAME_OUT_OF_RANGE;
00651 OS_Abort();
00652 }
00653
00654 if(kernel_request_create_args.level == PERIODIC &&
00655 name_in_PPP[kernel_request_create_args.name] == 0)
00656 {
00657 error_msg = ERR_5_NAME_NOT_IN_PPP;
00658 OS_Abort();
00659 }
00660
00661 if(kernel_request_create_args.level == PERIODIC &&
00662 name_to_task_ptr[kernel_request_create_args.name] != NULL)
00663 {
00664
00665 error_msg = ERR_4_PERIODIC_NAME_IN_USE;
00666 OS_Abort();
00667 }
00668
00669
00670 if(kernel_request_create_args.level == NULL)
00671 {
00672 p = &task_desc[MAXPROCESS];
00673 }
00674
00675 else
00676 {
00677 p = dequeue(&dead_pool_queue);
00678 }
00679
00680 stack_bottom = &(p->stack[WORKSPACE-1]);
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691 uint8_t* stack_top = stack_bottom - (32 + 1 + 2 + 2);
00692
00693
00694
00695
00696
00697
00698 stack_top[2] = (uint8_t) 0;
00699
00700 stack_top[32] = (uint8_t) _BV(SREG_I);
00701
00702
00703
00704
00705
00706
00707
00708
00709 stack_top[34] = (uint8_t)((uint16_t)(kernel_request_create_args.f) >> 8);
00710 stack_top[35] = (uint8_t)(uint16_t)(kernel_request_create_args.f);
00711 stack_top[36] = (uint8_t)((uint16_t)Task_Terminate >> 8);
00712 stack_top[37] = (uint8_t)(uint16_t)Task_Terminate;
00713
00714
00715
00716
00717
00718 p->sp = stack_top;
00719
00720 p->state = READY;
00721 p->arg = kernel_request_create_args.arg;
00722 p->level = kernel_request_create_args.level;
00723 p->name = kernel_request_create_args.name;
00724
00725 switch(kernel_request_create_args.level)
00726 {
00727 case PERIODIC:
00728
00729 name_to_task_ptr[kernel_request_create_args.name] = p;
00730 break;
00731
00732 case SYSTEM:
00733
00734 enqueue(&system_queue, p);
00735 break;
00736
00737 case RR:
00738
00739 enqueue(&rr_queue, p);
00740 break;
00741
00742 default:
00743
00744 break;
00745 }
00746
00747
00748 return 1;
00749 }
00750
00751
00752
00753
00754
00755 static void kernel_terminate_task(void)
00756 {
00757
00758 cur_task->state = DEAD;
00759 if(cur_task->level == PERIODIC)
00760 {
00761 name_to_task_ptr[cur_task->name] = NULL;
00762 }
00763 enqueue(&dead_pool_queue, cur_task);
00764 }
00765
00766
00767
00768
00769
00770 static void kernel_event_wait(void)
00771 {
00772
00773 uint8_t handle = (uint8_t)((uint16_t)(kernel_request_event_ptr) - 1);
00774
00775 if(handle >= num_events_created)
00776 {
00777
00778 error_msg = ERR_RUN_5_WAIT_ON_BAD_EVENT;
00779 OS_Abort();
00780 }
00781 else if(cur_task->level == PERIODIC)
00782 {
00783 error_msg = ERR_RUN_7_PERIODIC_CALLED_WAIT;
00784 OS_Abort();
00785 }
00786 else
00787 {
00788
00789 cur_task->state = WAITING;
00790 enqueue(&event_queue[handle], cur_task);
00791 }
00792 }
00793
00794
00795
00796
00797
00798
00799
00800
00801 static void kernel_event_signal(uint8_t is_broadcast, uint8_t and_next)
00802 {
00803
00804 uint8_t handle = (uint8_t)((uint16_t)(kernel_request_event_ptr) - 1);
00805
00806 if(handle >= num_events_created)
00807 {
00808
00809 error_msg = ERR_RUN_4_SIGNAL_ON_BAD_EVENT;
00810 OS_Abort();
00811 }
00812 else
00813 {
00814 uint8_t make_ready = 0;
00815
00816
00817 if(and_next)
00818 {
00819 make_ready = 1;
00820 }
00821
00822 while(event_queue[handle].head != NULL)
00823 {
00824
00825 task_descriptor_t* task_ptr = dequeue(&event_queue[handle]);
00826 task_ptr->state = READY;
00827
00828 switch(task_ptr->level)
00829 {
00830 case SYSTEM:
00831 enqueue(&system_queue, task_ptr);
00832 break;
00833 case PERIODIC:
00834 break;
00835 case RR:
00836 enqueue(&rr_queue, task_ptr);
00837 break;
00838 default:
00839 break;
00840 }
00841
00842
00843 if(cur_task != idle_task && !make_ready)
00844 {
00845 if(cur_task->level != SYSTEM && task_ptr->level == SYSTEM)
00846 {
00847 make_ready = 1;
00848 }
00849 else if(cur_task->level == RR &&
00850 slot_task_finished == 0 &&
00851 task_ptr == name_to_task_ptr[PPP[slot_name_index]])
00852 {
00853 make_ready = 1;
00854 }
00855 }
00856
00857 if(!is_broadcast)
00858 {
00859 break;
00860 }
00861 }
00862
00863 if(make_ready && cur_task != idle_task)
00864 {
00865 cur_task->state = READY;
00866 if(cur_task->level == RR)
00867 {
00868 enqueue(&rr_queue, cur_task);
00869 }
00870 }
00871 }
00872 }
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885 static void enqueue(queue_t* queue_ptr, task_descriptor_t* task_to_add)
00886 {
00887 task_to_add->next = NULL;
00888
00889 if(queue_ptr->head == NULL)
00890 {
00891
00892 queue_ptr->head = task_to_add;
00893 queue_ptr->tail = task_to_add;
00894 }
00895 else
00896 {
00897
00898 queue_ptr->tail->next = task_to_add;
00899 queue_ptr->tail = task_to_add;
00900 }
00901 }
00902
00903
00904
00905
00906
00907
00908
00909
00910 static task_descriptor_t* dequeue(queue_t* queue_ptr)
00911 {
00912 task_descriptor_t* task_ptr = queue_ptr->head;
00913
00914 if(queue_ptr->head != NULL)
00915 {
00916 queue_ptr->head = queue_ptr->head->next;
00917 task_ptr->next = NULL;
00918 }
00919
00920 return task_ptr;
00921 }
00922
00923
00924
00925
00926
00927
00928
00929 static void kernel_update_ticker(void)
00930 {
00931
00932
00933 if(PT > 0)
00934 {
00935 --ticks_remaining;
00936
00937 if(ticks_remaining == 0)
00938 {
00939
00940 if(cur_task != NULL && cur_task->level == PERIODIC && slot_task_finished == 0)
00941 {
00942
00943 error_msg = ERR_RUN_3_PERIODIC_TOOK_TOO_LONG;
00944 OS_Abort();
00945 }
00946
00947 slot_name_index += 2;
00948 if(slot_name_index >= 2 * PT)
00949 {
00950 slot_name_index = 0;
00951 }
00952
00953 ticks_remaining = PPP[slot_name_index + 1];
00954
00955 if(PPP[slot_name_index] == IDLE || name_to_task_ptr[PPP[slot_name_index]] == NULL)
00956 {
00957 slot_task_finished = 1;
00958 }
00959 else
00960 {
00961 slot_task_finished = 0;
00962 }
00963 }
00964 }
00965 }
00966
00967
00968
00969
00970
00971 static void check_PPP_names(void)
00972 {
00973 uint8_t i;
00974 uint8_t name;
00975
00976 for(i = 0; i < 2 * PT; i += 2)
00977 {
00978 name = PPP[i];
00979
00980
00981 if(name <= MAXNAME)
00982 {
00983 name_in_PPP[name] = 1;
00984 }
00985 else
00986 {
00987 error_msg = ERR_1_PPP_NAME_OUT_OF_RANGE;
00988 OS_Abort();
00989 }
00990 }
00991
00992 }
00993
00994 #undef SLOW_CLOCK
00995
00996 #ifdef SLOW_CLOCK
00997
00998
00999
01000
01001
01002
01003 static void kernel_slow_clock(void)
01004 {
01005 TCCR1B &= ~(_BV(CS12) | _BV(CS10));
01006 TCCR1B |= (_BV(CS11));
01007 }
01008 #endif
01009
01010
01011
01012
01013
01014
01015 void OS_Init()
01016 {
01017 int i;
01018
01019
01020 CLOCK8MHZ();
01021
01022 TCCR1B &= ~(_BV(CS12) | _BV(CS11));
01023 TCCR1B |= (_BV(CS10));
01024
01025 #ifdef SLOW_CLOCK
01026 kernel_slow_clock();
01027 #endif
01028
01029 check_PPP_names();
01030
01031
01032
01033
01034
01035
01036 for (i = 0; i < MAXPROCESS - 1; i++)
01037 {
01038 task_desc[i].state = DEAD;
01039 name_to_task_ptr[i] = NULL;
01040 task_desc[i].next = &task_desc[i + 1];
01041 }
01042 task_desc[MAXPROCESS - 1].next = NULL;
01043 dead_pool_queue.head = &task_desc[0];
01044 dead_pool_queue.tail = &task_desc[MAXPROCESS - 1];
01045
01046
01047 kernel_request_create_args.f = (voidfuncvoid_ptr)idle;
01048 kernel_request_create_args.level = NULL;
01049 kernel_create_task();
01050
01051
01052 kernel_request_create_args.f = (voidfuncvoid_ptr)main;
01053 kernel_request_create_args.level = SYSTEM;
01054 kernel_create_task();
01055
01056
01057 cur_task = task_desc;
01058 cur_task->state = RUNNING;
01059 dequeue(&system_queue);
01060
01061
01062 if(PT > 0)
01063 {
01064 ticks_remaining = PPP[1];
01065 }
01066
01067
01068 TIMSK1 |= _BV(OCIE1A);
01069 OCR1A = TCNT1 + 40000;
01070
01071 TIFR1 = _BV(OCF1A);
01072
01073
01074
01075
01076 kernel_main_loop();
01077 }
01078
01079
01080
01081
01082
01083
01084
01085 static void _delay_25ms(void)
01086 {
01087 uint16_t i;
01088
01089
01090 asm volatile ("1: sbiw %0,1" "\n\tbrne 1b" : "=w" (i) : "0" (50000));
01091 }
01092
01093
01094
01095
01096 void OS_Abort(void)
01097 {
01098 uint8_t i, j;
01099 uint8_t flashes, mask;
01100
01101 Disable_Interrupt();
01102
01103
01104 DDRD = LED_RED_MASK | LED_GREEN_MASK;
01105
01106 if(error_msg < ERR_RUN_1_USER_CALLED_OS_ABORT)
01107 {
01108 flashes = error_msg + 1;
01109 mask = LED_GREEN_MASK;
01110 }
01111 else
01112 {
01113 flashes = error_msg + 1 - ERR_RUN_1_USER_CALLED_OS_ABORT;
01114 mask = LED_RED_MASK;
01115 }
01116
01117
01118 for(;;)
01119 {
01120 PORTD = (uint8_t)(LED_RED_MASK | LED_GREEN_MASK);
01121
01122 for(i = 0; i < 100; ++i)
01123 {
01124 _delay_25ms();
01125 }
01126
01127 PORTD = (uint8_t) 0;
01128
01129 for(i = 0; i < 40; ++i)
01130 {
01131 _delay_25ms();
01132 }
01133
01134
01135 for(j = 0; j < flashes; ++j)
01136 {
01137 PORTD = mask;
01138
01139 for(i = 0; i < 10; ++i)
01140 {
01141 _delay_25ms();
01142 }
01143
01144 PORTD = (uint8_t) 0;
01145
01146 for(i = 0; i < 10; ++i)
01147 {
01148 _delay_25ms();
01149 }
01150 }
01151
01152 for(i = 0; i < 20; ++i)
01153 {
01154 _delay_25ms();
01155 }
01156 }
01157 }
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177 int Task_Create(void (*f)(void), int arg, unsigned int level, unsigned int name)
01178 {
01179 int retval;
01180 uint8_t sreg;
01181
01182 sreg = SREG;
01183 Disable_Interrupt();
01184
01185 kernel_request_create_args.f = (voidfuncvoid_ptr)f;
01186 kernel_request_create_args.arg = arg;
01187 kernel_request_create_args.level = (uint8_t)level;
01188 kernel_request_create_args.name = (uint8_t)name;
01189
01190 kernel_request = TASK_CREATE;
01191 enter_kernel();
01192
01193 retval = kernel_request_retval;
01194 SREG = sreg;
01195
01196 return retval;
01197 }
01198
01199
01200
01201
01202
01203 void Task_Next()
01204 {
01205 uint8_t sreg;
01206
01207 sreg = SREG;
01208 Disable_Interrupt();
01209
01210 kernel_request = TASK_NEXT;
01211 enter_kernel();
01212
01213 SREG = sreg;
01214 }
01215
01216
01217
01218
01219
01220 void Task_Terminate()
01221 {
01222 uint8_t sreg;
01223
01224 sreg = SREG;
01225 Disable_Interrupt();
01226
01227 kernel_request = TASK_TERMINATE;
01228 enter_kernel();
01229
01230 SREG = sreg;
01231 }
01232
01233
01234
01235
01236 int Task_GetArg(void)
01237 {
01238 int arg;
01239 uint8_t sreg;
01240
01241 sreg = SREG;
01242 Disable_Interrupt();
01243
01244 arg = cur_task->arg;
01245
01246 SREG = sreg;
01247
01248 return arg;
01249 }
01250
01251
01252
01253
01254
01255
01256 EVENT *Event_Init(void)
01257 {
01258 volatile EVENT* event_ptr;
01259 uint8_t sreg;
01260
01261 sreg = SREG;
01262 Disable_Interrupt();
01263
01264 kernel_request = EVENT_INIT;
01265 enter_kernel();
01266
01267 event_ptr = kernel_request_event_ptr;
01268
01269 SREG = sreg;
01270
01271 return event_ptr;
01272 }
01273
01274
01275
01276
01277
01278
01279
01280 void Event_Wait(EVENT *e)
01281 {
01282 uint8_t sreg;
01283
01284 sreg = SREG;
01285 Disable_Interrupt();
01286
01287 kernel_request = EVENT_WAIT;
01288 kernel_request_event_ptr = e;
01289 enter_kernel();
01290
01291 SREG = sreg;
01292 }
01293
01294
01295
01296
01297
01298
01299
01300
01301 void Event_Signal(EVENT *e)
01302 {
01303 uint8_t sreg;
01304
01305 sreg = SREG;
01306 Disable_Interrupt();
01307
01308 kernel_request = EVENT_SIGNAL;
01309 kernel_request_event_ptr = e;
01310 enter_kernel();
01311
01312 SREG = sreg;
01313 }
01314
01315
01316
01317
01318
01319
01320
01321
01322 void Event_Broadcast(EVENT *e)
01323 {
01324 uint8_t sreg;
01325
01326 sreg = SREG;
01327 Disable_Interrupt();
01328
01329 kernel_request = EVENT_BROADCAST;
01330 kernel_request_event_ptr = e;
01331 enter_kernel();
01332
01333 SREG = sreg;
01334 }
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348 void Signal_And_Next(EVENT *e)
01349 {
01350 uint8_t sreg;
01351
01352 sreg = SREG;
01353 Disable_Interrupt();
01354
01355 kernel_request = EVENT_SIGNAL_AND_NEXT;
01356 kernel_request_event_ptr = e;
01357 enter_kernel();
01358
01359 SREG = sreg;
01360 }
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371 void Broadcast_And_Next(EVENT *e)
01372 {
01373 uint8_t sreg;
01374
01375 sreg = SREG;
01376 Disable_Interrupt();
01377
01378 kernel_request = EVENT_BROADCAST_AND_NEXT;
01379 kernel_request_event_ptr = e;
01380 enter_kernel();
01381
01382 SREG = sreg;
01383 }
01384