void mrubyc(uint8_t *mrbbuf) { struct VM *vm; mrbc_init_alloc(memory_pool, MEMORY_SIZE); init_static(); vm = mrbc_vm_open(NULL); if( vm == 0 ) { fprintf(stderr, "Error: Can't open VM.\n"); return; } if( mrbc_load_mrb(vm, mrbbuf) != 0 ) { fprintf(stderr, "Error: Illegal bytecode.\n"); return; } mrbc_vm_begin(vm); mrbc_vm_run(vm); mrbc_vm_end(vm); mrbc_vm_close(vm); }
/*! execute */ int mrbc_run(void) { while( 1 ) { mrbc_tcb *tcb = q_ready_; if( tcb == NULL ) { // 実行すべきタスクなし hal_idle_cpu(); continue; } // 実行開始 tcb->state = TASKSTATE_RUNNING; int res = 0; #ifndef MRBC_NO_TIMER tcb->vm.flag_preemption = 0; res = mrbc_vm_run(&tcb->vm); #else while( tcb->timeslice > 0 ) { tcb->vm.flag_preemption = 1; res = mrbc_vm_run(&tcb->vm); tcb->timeslice--; if( res < 0 ) break; if( tcb->state != TASKSTATE_RUNNING ) break; } mrbc_tick(); #endif /* ifndef MRBC_NO_TIMER */ // タスク終了? if( res < 0 ) { hal_disable_irq(); q_delete_task(tcb); tcb->state = TASKSTATE_DORMANT; q_insert_task(tcb); hal_enable_irq(); mrbc_vm_end(&tcb->vm); #if MRBC_SCHEDULER_EXIT if( q_ready_ == NULL && q_waiting_ == NULL && q_suspended_ == NULL ) return 0; #endif continue; } // タスク切り替え hal_disable_irq(); if( tcb->state == TASKSTATE_RUNNING ) { tcb->state = TASKSTATE_READY; // タイムスライス終了? if( tcb->timeslice == 0 ) { q_delete_task(tcb); tcb->timeslice = TIMESLICE_TICK; q_insert_task(tcb); // insert task on queue last. } } hal_enable_irq(); } // eternal loop }