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