bombilla.nc

来自「用于传感器网络的节点操作系统 TinyOS 结构设计非常有意思」· NC 代码 · 共 1,584 行 · 第 1/4 页

NC
1,584
字号
    capsules[BOMB_CAPSULE_CLOCK_INDEX].capsule.version = 0;    analyzeCapsuleVars(capsules, BOMB_CAPSULE_CLOCK_INDEX);    analyzeCapsuleVars(capsules, BOMB_CAPSULE_SEND_INDEX);    analyzeCapsuleVars(capsules, BOMB_CAPSULE_RECV_INDEX);        res1 = call StdControlPhoto.start();    res2 = call StdControlTemp.start();    /* EEPROM functionality is currently not implemented. */    //    call StdControlEEPROM.start();    res3 = call StdControlNetwork.start();    call ClockTimer.start(TIMER_REPEAT, 1024);    call PropagateTimer.start(TIMER_REPEAT, BOMB_PROPAGATE_TIMER);    return rcombine3(res1, res2, res3);  }  command result_t StdControl.stop() {    result_t res1, res2, res3;        res1 = call StdControlPhoto.stop();    res2 = call StdControlTemp.stop();    /* EEPROM functionality is currently not implemented. */    //    call StdControlEEPROM.stop();    res3 = call StdControlNetwork.stop();    return rcombine3(res1, res2, res3);  }    command result_t BombillaError.error(BombillaContext* context, uint8_t cause) {    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();    errorContext = context;    errorMsg.context = context->which;    errorMsg.reason = cause;    errorMsg.capsule = context->capsule->capsule.type;    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(errorContext->msg.data, &errorMsg, sizeof(BombillaErrorMsg));    if (errorFlipFlop) {      call SendError.send(TOS_UART_ADDR, sizeof(BombillaErrorMsg), (TOS_MsgPtr)&errorContext->msg);    }    else {      call SendError.send(TOS_BCAST_ADDR, sizeof(BombillaErrorMsg), (TOS_MsgPtr)&errorContext->msg);    }    errorFlipFlop = !errorFlipFlop;  }      task void clockEventTask() {    if (clockContext.state == BOMB_STATE_HALT) {      initializeContext(&clockContext);      resumeContext(&clockContext, &clockContext);    }    else {      uint8_t code = 0;      if (clockContext.state == BOMB_STATE_SENSE_WAIT) {	code = 1;      }      else if (clockContext.state == BOMB_STATE_LOCK_WAIT) {	code = 2;      }      else if (clockContext.state == BOMB_STATE_SEND_WAIT) {	code = 3;      }      //if (code & 0x1) {call Leds.redToggle();}      //if (code & 0x2) {call Leds.greenToggle();}    }  }  event result_t ClockTimer.fired() {    dbg(DBG_USR1, "VM: Clock event fired.\n");    if (inErrorState) {      post clockErrorTask();    }    else {      post clockEventTask();    }    return SUCCESS;  }  void analyzeCapsuleVars(BombillaCapsuleBuffer* buffers, uint8_t which) {    int i;    BombillaCapsuleBuffer* buf = &(buffers[(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]) & 0xf;	buf->usedVars |= (1 << arg);      }    }  }  void analyzeCapsuleCalls(BombillaCapsuleBuffer* buffers, uint8_t which) {    int i;    BombillaCapsuleBuffer* buf = &(buffers[(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 = &senseWaitQueue;    cli();    if (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) {	  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) {	  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);      }    }  }  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)) {	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, &sendWaitQueue, context);	context->state = BOMB_STATE_SEND_WAIT;      }    }    call Synch.releaseLocks(context, context, 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"));    }  }    result_t forwardCapsule(uint8_t which) {    // Capsule does nothing ... don't forward it    if ((capsules[which].capsule.code[0] == OPhalt) ||	((capsules[which].capsule.options & BOMB_OPTION_FORWARD) == 0)) {      return SUCCESS;    }    else {      nmemcpy(forwardingBuffer.data, &(capsules[which].capsule), sizeof(BombillaCapsule));      dbg(DBG_USR3, "VM: Forwarding capsule %i.\n");      return call SendCapsule.send(TOS_BCAST_ADDR, sizeof(BombillaCapsule), &forwardingBuffer);    }  }    /**   *  Decides whether to forward a capsule, forwarding if necessary.   *   * Compute a random number. Take lower 7 bits (0-127). Measure   * network activity; take 64 and subtract it; this gives a rough   * estimate of the network business, with low numbers being busy. If   * the random number is lower than the business number, forward a   * capsule.   *   */  task void forwardCapsuleTask() {    uint16_t activity = call networkActivity();    uint16_t randVal = call Random.rand();     if (!tryingToForward) {      activity = BOMB_MAX_NET_ACTIVITY - activity;            if (activity <= 0) {activity = 1;}      if ((randVal & 0x7f) >= activity){return;} // Too busy -- don't forward          // Which capsule?      randVal = call Random.rand();      randVal %= BOMB_CAPSULE_NUM;      forwardingCapsule = randVal;    }        if (forwardCapsule(forwardingCapsule) == SUCCESS) {      tryingToForward = FALSE;    }    else {      tryingToForward = TRUE;    }  }  event result_t PropagateTimer.fired() {    post forwardCapsuleTask();    return SUCCESS;  }  event result_t TimeoutTimer.fired() {    return SUCCESS;  }  inline result_t senseReady(uint16_t datum) {    BombillaContext* senser;    BombillaQueue* queue = &senseWaitQueue;    dbg(DBG_USR1, "VM: Sensor reading: %i\n", (int)datum);    if (sensingContext != NULL) {      // Resume the sensing context      sensingContext->state = BOMB_STATE_RUN;      resumeContext(sensingContext, sensingContext);      call Stacks.pushReading(sensingContext, BOMB_DATA_PHOTO, datum);      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 SendCapsule.sendDone(TOS_MsgPtr msg, result_t success) {    BombillaContext* sender = sendingContext;    dbg(DBG_USR1, "VM: SendCapsule.sendDone event fired.\n");    if (sender == NULL) {return FAIL;}    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 SendPacket.sendDone(TOS_MsgPtr msg, result_t success) {    BombillaContext* sender = sendingContext;    dbg(DBG_USR1, "VM: SendPacket.sendDone event fired.\n");    if (sender == NULL) {return FAIL;}    sendingContext = NULL;    if (sender->state != BOMB_STATE_SENDING) {      call BombillaError.error(sender, BOMB_ERROR_QUEUE_INVALID);      return FAIL;    }    resumeContext(sender, sender);    return SUCCESS;  }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?