📄 bombillacore.nc
字号:
/* tab:4 * * * "Copyright (c) 2000-2002 The Regents of the University of California. * All rights reserved. * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose, without fee, and without written * agreement is hereby granted, provided that the above copyright * notice, the following two paragraphs and the author appear in all * copies of this software. * * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, * UPDATES, ENHANCEMENTS, OR MODIFICATIONS." * *//* tab:4 * * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. * By downloading, copying, installing or using the software you * agree to this license. If you do not agree to this license, do * not download, install, copy or use the software. * * Intel Open Source License * * Copyright (c) 2002 Intel Corporation * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * Neither the name of the Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR ITS * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * *//* * Authors: Philip Levis <pal@cs.berkeley.edu> * History: Jul 19, 2002 Created * Aug 20, 2002 Instruction set (sans EEPROM) * Aug 23, 2002 Capsule forwarding * Sep 12, 2002 Race prevention (capsule forcing) * Apr 11, 2003 Re-organization, viral component * *//** * @author Philip Levis <pal@cs.berkeley.edu> */includes AM;includes Bombilla;module BombillaCore { provides { interface StdControl; interface BombillaError; command result_t computeInstruction(BombillaContext* context); command result_t executeContext(BombillaContext* context); event result_t sendDone(); } uses { interface StdControl as StdControlTimer; interface StdControl as StdControlPhoto; interface StdControl as StdControlTemp; interface StdControl as StdControlNetwork; interface Timer as ClockTimer; interface Timer as TimeoutTimer; interface Leds; interface Random; interface Pot; interface ADC as PhotoADC; interface ADC as TempADC; interface SendMsg as SendPacket; interface SendData as SendAdHoc; interface SendMsg as SendError; interface ReceiveMsg as ReceivePacket; command result_t isAdHocActive(); command uint16_t networkActivity(); interface BombillaStacks as Stacks; interface BombillaBuffer as Buffer; interface BombillaLocks as Locks; interface BombillaSynch as Synch; interface BombillaInstruction as Instruction; interface BombillaQueue as Queue; interface BombillaVirus as Virus; }}implementation { BombillaContext clockContext; BombillaContext sendContext; BombillaContext recvContext; BombillaContext onceContext; BombillaState state; /* BombillaCapsuleBuffer capsules[BOMB_CAPSULE_NUM]; BombillaDataBuffer buffer0; BombillaDataBuffer buffer1; BombillaDataBuffer sendrBuffer; BombillaDataBuffer recvBuffer; BombillaStackVariable heap[BOMB_HEAPSIZE]; BombillaLock locks[BOMB_HEAPSIZE]; BombillaQueue sendWaitQueue; BombillaContext* sendingContext; BombillaQueue logWaitQueue; BombillaContext* loggingContext; BombillaQueue senseWaitQueue; BombillaContext* sensingContext; BombillaContext* errorContext; BombillaErrorMsg errorMsg; BombillaQueue sendrWaitQueue; BombillaQueue readyQueue; bool inErrorState; bool errorFlipFlop; // Send to UART or Radio? TOS_Msg forwardingBuffer; bool tryingToForward; uint8_t forwardingCapsule; */ void analyzeCapsuleVars(BombillaCapsuleBuffer* buffers, uint8_t which); void analyzeCapsuleCalls(BombillaCapsuleBuffer* buffers, uint8_t which); void initializeContext(BombillaContext* context) { context->heldSet = 0; context->releaseSet = 0; context->capsule = context->rootCapsule; context->acquireSet = context->capsule->usedVars; context->pc = 0; Stacks.resetStacks(context); if (state.sendingContext == context) { state.sendingContext = NULL; } if (state.loggingContext == context) { state.loggingContext = NULL; } if (state.sendingContext == context) { state.sensingContext = NULL; } context->state = BOMB_STATE_HALT; } bool resumeContext(BombillaContext* caller, BombillaContext* context) { context->state = BOMB_STATE_RESUMING; if (call Synch.isRunnable(context, state.locks)) { call Synch.obtainLocks(caller, context, state.locks); context->state = BOMB_STATE_RUN; call executeContext(context); dbg(DBG_USR2, "VM (%i): Resumption of %i successful.\n", (int)caller->which, (int)context->which); return TRUE; } else { call Queue.enqueue(caller, &state.readyQueue, context); return FALSE; } } /* * The correctness of this code is a little tricky. Basically, what * we need to ensure is that we only check each context for * runnability once. The only way to effectively do this is to keep * track of the first checked context that's still on the queue (if * it was checked and started running, we no longer have a handle on * it). This is where the if (start == NULL) piece of code comes in; * start is set to be the first context that is not made * runnable. If that context is ever encountered again (start == * current), control breaks out of loop. If all contexts are made * runnable, then Queue.empty() will return true and the loop will * terminate (the while clause at the end). * * I fully acknowledge that "tricky" is a bad adjective for code, * and means I'm probably doing this wrong. It works, though... */ void yieldContext(BombillaContext* context) { BombillaContext* start = NULL; BombillaContext* current = NULL; dbg(DBG_USR2, "VM (%i): Yielding.\n", (int)context->which); if (!call Queue.empty(&state.readyQueue)) { do { current = call Queue.dequeue(context, &state.readyQueue); if (!resumeContext(context, current)) { dbg(DBG_USR2, "VM (%i): Context %i not runnable.\n", (int)context->which, (int)current->which); if (start == NULL) { start = current; } else if (start == current) { dbg(DBG_USR2, "VM (%i): Looped on ready queue. End checks.\n", (int)context->which); break; } } } while (!call Queue.empty(&state.readyQueue)); } else { dbg(DBG_USR2, "VM (%i): Ready queue empty.\n", (int)context->which); } } void haltContext(BombillaContext* context) { call Synch.releaseAllLocks(context, context, state.locks); yieldContext(context); context->state = BOMB_STATE_HALT; if ((context->which == BOMB_CAPSULE_SEND_INDEX) && !call Queue.empty(&state.sendrWaitQueue)) { BombillaContext* waiter = call Queue.dequeue(context, &state.sendrWaitQueue); resumeContext(context, waiter); } } void initializeProgram() { int pc = 0; state.capsules[BOMB_CAPSULE_CLOCK_INDEX].capsule.code[pc++] = OPpushc | 1; state.capsules[BOMB_CAPSULE_CLOCK_INDEX].capsule.code[pc++] = OPgetvar | 0; state.capsules[BOMB_CAPSULE_CLOCK_INDEX].capsule.code[pc++] = OPadd; state.capsules[BOMB_CAPSULE_CLOCK_INDEX].capsule.code[pc++] = OPcopy; state.capsules[BOMB_CAPSULE_CLOCK_INDEX].capsule.code[pc++] = OPsetvar | 0; state.capsules[BOMB_CAPSULE_CLOCK_INDEX].capsule.code[pc++] = OPpushc | 7; state.capsules[BOMB_CAPSULE_CLOCK_INDEX].capsule.code[pc++] = OPland; state.capsules[BOMB_CAPSULE_CLOCK_INDEX].capsule.code[pc++] = OPputled; state.capsules[BOMB_CAPSULE_CLOCK_INDEX].capsule.code[pc++] = OPhalt; state.capsules[BOMB_CAPSULE_CLOCK_INDEX].capsule.version = 0; analyzeCapsuleVars(state.capsules, BOMB_CAPSULE_CLOCK_INDEX); analyzeCapsuleVars(state.capsules, BOMB_CAPSULE_SEND_INDEX); analyzeCapsuleVars(state.capsules, BOMB_CAPSULE_RECV_INDEX); } command result_t StdControl.init() { uint16_t i; dbg(DBG_BOOT, "VM: Bombilla initializing.\n"); call Leds.init(); call Random.init(); call StdControlTimer.init(); call StdControlPhoto.init(); call StdControlTemp.init(); /* EEPROM functionality is currently not implemented. */ // call StdControlEEPROM.init(); call StdControlNetwork.init(); state.inErrorState = FALSE; clockContext.rootCapsule = &state.capsules[BOMB_CAPSULE_CLOCK_INDEX]; clockContext.state = BOMB_STATE_HALT; sendContext.rootCapsule = &state.capsules[BOMB_CAPSULE_SEND_INDEX]; sendContext.state = BOMB_STATE_HALT; recvContext.rootCapsule = &state.capsules[BOMB_CAPSULE_RECV_INDEX]; recvContext.state = BOMB_STATE_HALT; onceContext.rootCapsule = &state.capsules[BOMB_CAPSULE_ONCE_INDEX]; onceContext.state = BOMB_STATE_HALT; call Queue.init(&state.sendWaitQueue); state.sendingContext = NULL; call Queue.init(&state.logWaitQueue); state.loggingContext = NULL; call Queue.init(&state.senseWaitQueue); state.sensingContext = NULL; call Queue.init(&state.sendrWaitQueue); call Queue.init(&state.readyQueue); state.buffer0.type = BOMB_DATA_NONE; state.buffer0.size = 0; state.buffer1.type = BOMB_DATA_NONE; state.buffer1.size = 0; clockContext.which = BOMB_CAPSULE_CLOCK; sendContext.which = BOMB_CAPSULE_SEND; recvContext.which = BOMB_CAPSULE_RECV; onceContext.which = BOMB_CAPSULE_ONCE; for (i = 0; i < BOMB_HEAPSIZE; i++) { state.heap[(int)i].type = BOMB_TYPE_VALUE; state.heap[(int)i].value.var = 0; } state.capsules[BOMB_CAPSULE_SUB0].capsule.type = BOMB_CAPSULE_SUB0; state.capsules[BOMB_CAPSULE_SUB1].capsule.type = BOMB_CAPSULE_SUB1; state.capsules[BOMB_CAPSULE_SUB2].capsule.type = BOMB_CAPSULE_SUB2; state.capsules[BOMB_CAPSULE_SUB3].capsule.type = BOMB_CAPSULE_SUB3; state.capsules[BOMB_CAPSULE_CLOCK_INDEX].capsule.type = BOMB_CAPSULE_CLOCK; state.capsules[BOMB_CAPSULE_RECV_INDEX].capsule.type = BOMB_CAPSULE_RECV; state.capsules[BOMB_CAPSULE_SEND_INDEX].capsule.type = BOMB_CAPSULE_SEND; state.capsules[BOMB_CAPSULE_ONCE_INDEX].capsule.type = BOMB_CAPSULE_ONCE; for (i = 0; i < BOMB_CAPSULE_NUM; i++) { //capsules[i].capsule.version = 0; //capsules[i].capsule.options = 0; call Virus.registerCapsule(state.capsules[i].capsule.type, &(state.capsules[i].capsule)); } initializeProgram(); if (TOS_LOCAL_ADDRESS == 1) { state.capsules[BOMB_CAPSULE_CLOCK_INDEX].capsule.version = 3; } return SUCCESS; } uint8_t checkTypes(BombillaContext* context, BombillaStackVariable* var, uint8_t types) { uint8_t rval = (uint8_t)(var->type & types); if (!rval) { dbg(DBG_USR1|DBG_ERROR, "VM: Operand failed type check: type = %i, allowed types = %i\n", (int)var->type, (int)types); call BombillaError.error(context, BOMB_ERROR_TYPE_CHECK); } return rval; } task void ClockTask() { // dbg(DBG_USR1, "VM: Running clock context.\n"); call computeInstruction(&clockContext); if (clockContext.state == BOMB_STATE_RUN) { post ClockTask(); } } task void SendTask() { // dbg(DBG_USR1, "VM: Running send context.\n"); call computeInstruction(&sendContext); if (sendContext.state == BOMB_STATE_RUN) { post SendTask(); } } task void RecvTask() { call computeInstruction(&recvContext);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -