📄 bombillacore.nc
字号:
if (recvContext.state == BOMB_STATE_RUN) { post RecvTask(); } } task void OnceTask() { call computeInstruction(&onceContext); if (onceContext.state == BOMB_STATE_RUN) { post OnceTask(); } } command result_t executeContext(BombillaContext* context) { if (context->state != BOMB_STATE_RUN) {return FAIL;} switch(context->which) { case BOMB_CAPSULE_CLOCK: return post ClockTask(); case BOMB_CAPSULE_SEND: return post SendTask(); case BOMB_CAPSULE_RECV: return post RecvTask(); case BOMB_CAPSULE_ONCE: return post OnceTask(); case BOMB_CAPSULE_OUTER: default: dbg(DBG_ERROR, "VM: Tried to run context not yet supported: %i\n", context->which); return FAIL; } return FAIL; } command result_t StdControl.start() { result_t res1, res2, res3, res4; dbg(DBG_BOOT, "VM: Bombilla starting.\n"); res1 = call StdControlTimer.start(); res2 = call StdControlPhoto.start(); res3 = call StdControlTemp.start(); /* EEPROM functionality is currently not implemented. */ // call StdControlEEPROM.start(); res4 = call StdControlNetwork.start(); call ClockTimer.start(TIMER_REPEAT, 1024); return rcombine3(res1, res2, rcombine(res3, res4)); } command result_t StdControl.stop() { result_t res1, res2, res3, res4; res1 = call StdControlTimer.stop(); res2 = call StdControlPhoto.stop(); res3 = call StdControlTemp.stop(); /* EEPROM functionality is currently not implemented. */ // call StdControlEEPROM.stop(); res4 = call StdControlNetwork.stop(); return rcombine3(res1, res2, rcombine(res3, res4)); } command result_t BombillaError.error(BombillaContext* context, uint8_t cause) { state.inErrorState = TRUE; dbg(DBG_ERROR|DBG_USR1, "VM: Entering ERROR state. Context: %i, cause %i\n", (int)context->which, (int)cause); call Leds.redOn(); call Leds.greenOn(); call Leds.yellowOn(); state.errorContext = context; state.errorMsg.context = context->which; state.errorMsg.reason = cause; state.errorMsg.capsule = context->capsule->capsule.type; state.errorMsg.instruction = context->pc - 1; return SUCCESS; } task void ClockErrorTask() { dbg(DBG_USR1|DBG_ERROR, "VM: ERROR\n"); call Leds.redToggle(); call Leds.greenToggle(); call Leds.yellowToggle(); nmemcpy(state.errorContext->msg.data, &state.errorMsg, sizeof(BombillaErrorMsg)); if (state.errorFlipFlop) { call SendError.send(TOS_UART_ADDR, sizeof(BombillaErrorMsg), (TOS_MsgPtr)&(state.errorContext->msg)); } else { call SendError.send(TOS_BCAST_ADDR, sizeof(BombillaErrorMsg), (TOS_MsgPtr)&(state.errorContext->msg)); } state.errorFlipFlop = !state.errorFlipFlop; } task void ClockEventTask() { if (clockContext.state == BOMB_STATE_HALT) { initializeContext(&clockContext); resumeContext(&clockContext, &clockContext); } else { // Can log a clock miss error here, but probably // not a good idea } } event result_t ClockTimer.fired() { //dbg(DBG_USR1|DBG_TEMP, "VM: Clock event fired: %lli\n", //tos_state.tos_time); if (state.inErrorState) { post ClockErrorTask(); } else { post ClockEventTask(); } return SUCCESS; } void analyzeCapsuleVars(BombillaCapsuleBuffer* buffers, uint8_t which) { int i; BombillaCapsuleBuffer* buf = &(state.capsules[(int)which]); buf->usedVars = 0; for (i = 0; i < BOMB_PGMSIZE; i++) { if (call Instruction.isVClass(buf->capsule.code[i])) { uint8_t arg = (buf->capsule.code[i]) & VARG_MASK; buf->usedVars |= (1 << arg); } } } void analyzeCapsuleCalls(BombillaCapsuleBuffer* buffers, uint8_t which) { int i; BombillaCapsuleBuffer* buf = &(state.capsules[(int)which]); for (i = 0; i < BOMB_PGMSIZE; i++) { if ((buf->capsule.code[i] & 0xfc) == OPcall0) { uint8_t arg = (buf->capsule.code[i]) & 0x3; buf->usedVars |= buffers[(int)arg].usedVars; } } } void executeSense(BombillaContext* context, uint8_t type) { BombillaQueue* queue = &state.senseWaitQueue; // cli()/sei() is safe because we are always in task context here cli(); if (state.sensingContext != NULL) { call Stacks.pushValue(context, type); context->state = BOMB_STATE_SENSE_WAIT; call Queue.enqueue(context, queue, context); sei(); } else { sei(); switch(type) { // Be sure to handle sensingContext/senseQueue properly // so that sense done events don't traverse a null pointer. case BOMB_DATA_PHOTO: dbg(DBG_USR1, "VM (%i): Sensing photo.\n", (int)context->which); if (call PhotoADC.getData() == SUCCESS) { state.sensingContext = context; context->state = BOMB_STATE_SENSE; } else { // re-issue the instruction call Stacks.pushValue(context, type); context->pc--; } break; case BOMB_DATA_TEMP: dbg(DBG_USR1, "VM (%i): Sensing temperature.\n", (int)context->which); if (call TempADC.getData() == SUCCESS) { state.sensingContext = context; context->state = BOMB_STATE_SENSE; } else { // re-issue the instruction call Stacks.pushValue(context, type); context->pc--; } break; default: dbg(DBG_ERROR, "VM (%i): Sensor type %i not supported yet.\n", (int)context->which, (int)type); call BombillaError.error(context, BOMB_ERROR_INVALID_TYPE); } } } void executeAdd(BombillaContext* context, BombillaStackVariable* arg1, BombillaStackVariable* arg2) { if ((arg1->type == BOMB_TYPE_VALUE) && (arg2->type == BOMB_TYPE_VALUE)) { dbg(DBG_USR1, "VM (%i): Executing add of two values: %i + %i == %i\n", (int)context->which, (int)arg1->value.var, (int)arg2->value.var, (int)arg1->value.var + arg2->value.var); call Stacks.pushValue(context, arg1->value.var + arg2->value.var); } else if (arg1->type == BOMB_TYPE_BUFFER) { if (arg2->type != BOMB_TYPE_BUFFER) { dbg(DBG_USR1, "VM (%i): Prepend value onto buffer.\n", (int)context->which); call Buffer.prepend(context, arg1->buffer.var, arg2); } else { dbg(DBG_USR1, "VM (%i): Concatenating buffers.\n", (int)context->which); call Buffer.concatenate(context, arg2->buffer.var, arg1->buffer.var); } call Stacks.pushBuffer(context, arg1->buffer.var); } else if (arg2->type == BOMB_TYPE_BUFFER) { call Buffer.append(context, arg2->buffer.var, arg1); call Stacks.pushBuffer(context, arg2 ->buffer.var); } else { call BombillaError.error(context, BOMB_ERROR_TYPE_CHECK); dbg(DBG_USR1, "VM (%i): Invalid add.\n", (int)context->which); } } void executeSendr(BombillaContext* context, BombillaStackVariable* arg) { if ((context->which != BOMB_CAPSULE_SEND) || (!checkTypes(context, arg, BOMB_VAR_V))) { context->state = BOMB_STATE_HALT; return; } else { uint16_t addr = arg->value.var; uint8_t size; arg = call Stacks.popOperand(context); if (!checkTypes(context, arg, BOMB_VAR_B)) {return;} size = arg->buffer.var->size; size += sizeof(arg->buffer.var->type); size += sizeof(arg->buffer.var->size); nmemcpy(context->msg.data, arg->buffer.var, size); if (call SendPacket.send(addr, size, &context->msg)) { state.sendingContext = context; context->state = BOMB_STATE_SENDING; } else { // Back up context so on being resumed it will try to send again context->pc--; call Stacks.pushOperand(context, arg); call Stacks.pushValue(context, addr); call Queue.enqueue(context, &state.sendWaitQueue, context); context->state = BOMB_STATE_SEND_WAIT; } } call Synch.releaseLocks(context, context, state.locks); yieldContext(context); return; } bool areEqual(BombillaStackVariable* arg1, BombillaStackVariable* arg2) { if (arg1->type != arg2->type) {return FALSE;} if (arg1->type == BOMB_TYPE_SENSE) { return ((arg1->sense.type == arg2->sense.type) && (arg1->sense.var == arg2->sense.var)); } else if (arg1->type == BOMB_TYPE_VALUE) { return (arg1->value.var == arg2->value.var); } else if (arg1->type == BOMB_TYPE_BUFFER) { return (arg1->buffer.var == arg2->buffer.var); } else { return FALSE; } } bool typeEqual(BombillaStackVariable* arg1, BombillaStackVariable* arg2) { return (arg1->type == arg2->type); } void ledOP(uint16_t arg) { uint8_t op = (arg >> 3) & 3; uint8_t led = arg & 7; switch (op) { case 0: /* set */ if (led & 1) call Leds.redOn(); else call Leds.redOff(); if (led & 2) call Leds.greenOn(); else call Leds.greenOff(); if (led & 4) call Leds.yellowOn(); else call Leds.yellowOff(); break; case 1: /* OFF 0 bits */ if (!(led & 1)) call Leds.redOff(); if (!(led & 2)) call Leds.greenOff(); if (!(led & 4)) call Leds.yellowOff(); break; case 2: /* on 1 bits */ if (led & 1) call Leds.redOn(); if (led & 2) call Leds.greenOn(); if (led & 4) call Leds.yellowOn(); break; case 3: /* TOGGLE 1 bits */ if (led & 1) call Leds.redToggle(); if (led & 2) call Leds.greenToggle(); if (led & 4) call Leds.yellowToggle(); break; default: dbg(DBG_ERROR, ("VM: LED command had unknown operations.\n")); } } event result_t TimeoutTimer.fired() { return SUCCESS; } inline result_t senseReady(uint16_t datum) { BombillaContext* senser; BombillaQueue* queue = &state.senseWaitQueue; dbg(DBG_USR1, "VM: Sensor reading: %i\n", (int)datum); if (state.sensingContext != NULL) { // Resume the sensing context state.sensingContext->state = BOMB_STATE_RUN; resumeContext(state.sensingContext, state.sensingContext); call Stacks.pushReading(state.sensingContext, BOMB_DATA_PHOTO, datum); state.sensingContext = NULL; } if (!call Queue.empty(queue)) { senser = call Queue.dequeue(&clockContext, queue); if (senser->state != BOMB_STATE_SENSE_WAIT) { call BombillaError.error(senser, BOMB_ERROR_QUEUE_INVALID); } senser->state = BOMB_STATE_RUN; resumeContext(senser, senser); } return SUCCESS; } event result_t PhotoADC.dataReady(uint16_t datum) { return senseReady(datum); } event result_t TempADC.dataReady(uint16_t datum) { return senseReady(datum); } /* Acceleration sensor not supported yet event result_t AccelXADC.dataReady(uint16_t data) { return SUCCESS; } event result_t AccelYADC.dataReady(uint16_t data) { return SUCCESS; } */ event result_t SendPacket.sendDone(TOS_MsgPtr msg, result_t success) { BombillaContext* sender = state.sendingContext; dbg(DBG_USR1, "VM: SendPacket.sendDone event fired.\n"); if (sender == NULL) {return FAIL;} state.sendingContext = NULL; if (sender->state != BOMB_STATE_SENDING) { call BombillaError.error(sender, BOMB_ERROR_QUEUE_INVALID); return FAIL; } resumeContext(sender, sender); return SUCCESS; } event result_t SendAdHoc.sendDone(uint8_t* buffer, result_t success) { BombillaContext* sender = state.sendingContext; dbg(DBG_USR1, "VM: Ad hoc send completed with code %i\n", (int)success); if (sender == NULL) {return FAIL;} state.sendingContext = NULL; if (sender->state != BOMB_STATE_SENDING) { call BombillaError.error(sender, BOMB_ERROR_QUEUE_INVALID); return FAIL; } resumeContext(sender, sender); return SUCCESS; } event result_t SendError.sendDone(TOS_MsgPtr msg, result_t success) { return SUCCESS; } /** * Install a new capsule and compute locks sets for all caspules * possibly modified by this installation. */ void capsuleAnalysis(uint8_t which) { state.inErrorState = FALSE; dbg(DBG_USR1, "VM: Analyzing new capsule: %i\n", (int)which); if (which <= BOMB_CAPSULE_SUB3) { int i; initializeContext(&clockContext); initializeContext(&sendContext); initializeContext(&recvContext);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -