⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c_cmd.h

📁 乐高机器人的源码,开发平台是IAR_for_AVR.
💻 H
📖 第 1 页 / 共 2 页
字号:

//
//Internal states of the VM
//VM_IDLE: Just sitting around.  Request to run program will lead to ONE of the VM_RUN* states.
//VM_RUN_FREE: Attempt to run as many instructions as possible within our timeslice
//VM_RUN_SINGLE: Run exactly one instruction per timeslice
//VM_RUN_PAUSE: Program still "active", but someone has asked us to pause
//VM_RESET2: Final clean up and return to IDLE
//VM_RESET1: Initialize state variables and some I/O devices -- executed when programs end
//
typedef enum
{
  VM_IDLE,
  VM_RUN_FREE,
  VM_RUN_SINGLE,
  VM_RUN_PAUSE,
  VM_RESET1,
  VM_RESET2,
} VM_STATE;

//
// VARSCMD: Private state data for active program and VM system
//
//pCodespace: pointer for flat codespace (stored in flash, includes all clumps)
//CodespaceCount: count of code words
//
//pAllClumps: Pointer to list of CLUMP_RECs
//AllClumpsCount: Count of CLUMP_RECs in list
//
//RunQ: Head and tail of run queue (elements in-place in AllClumps list)
//ScratchPC: Temp PC value for control flow instructions
//
//pDataspaceTOC: Pointer to DSTOC entries (stored in flash)
//DataspaceCount: Count of entries in DSTOC
//pDataspace: Base pointer of actual dataspace
//DataspaceSize: Size, in bytes, of dataspace
//DSStaticSize: Size, in bytes, of static portion of the dataspace (used as an offset to the dynamic dataspace)
//
//VMState: Internal state of VM's loader/scheduler (cCmdCtrl())
//
//MemMgr: Contains data to manage dynamic arrays
//
//PoolSize: Current size of main memory pool, in bytes.
//Pool: Static pool of bytes for stashing all program run-time data
//
//ActiveProgHandle: Handle of the program that is currently running
//ActiveProgName: Stashed name of currently running program, if any
//
//FileHandleTable: Table of file names opened by program while running.
// First byte of each record is 'r' or 'w' (read or write).
//
//MessageQueues: Message buffer tracking data
//
//CommStat, CommStatReset, CommCurrConnection, DirtyComm: Helper data for interfacing to c_comm module
//
//DirtyDisplay: Boolean reminding us to re-initialize the display if program used it
//
//StartTick: MS tick stashed when program started.  Used for relative time measurements.
//
//Further notes on the memory pool:
// The main memory pool is used for all clump records, dataspace tracking data,
// and the dataspace itself.  In other words, pAllClumps and
// pDataspace must all point to memory within the pool.  Watch for NXT_ASSERTs
// to enforce safe indexing into the pool.
//
typedef struct
{
  CODE_WORD*    pCodespace;
  CLUMP_REC*    pAllClumps;
  DS_TOC_ENTRY* pDataspaceTOC;
  UBYTE*        pDataspace;
  UBYTE*        Pool;

  ULONG     PoolSize;
  UWORD     CodespaceCount;
  CLUMP_ID  AllClumpsCount;
  UWORD     DataspaceCount;
  UWORD     DataspaceSize;
  UWORD     DSStaticSize;

  VM_STATE VMState;

  MEM_MGR   MemMgr;

  CLUMP_Q    RunQ;
  CODE_INDEX ScratchPC;
  CLUMP_ID   CallerClump;

  UBYTE ActiveProgHandle;
  UBYTE ActiveProgName[FILENAME_LENGTH + 1];

  UBYTE FileHandleTable[MAX_HANDLES][FILENAME_LENGTH + 2];

  MESSAGE_QUEUE MessageQueues[MESSAGE_QUEUE_COUNT];

  SWORD CommStat;
  SWORD CommStatReset;
  UBYTE CommCurrConnection;

  UBYTE DirtyComm;
  UBYTE DirtyDisplay;

  ULONG StartTick;

#if VM_BENCHMARK
  ULONG InstrCount;
  ULONG Average;
  ULONG OverTimeCount;
  ULONG MaxOverTimeLength;
  ULONG CmdCtrlCount;
  ULONG CompactionCount;
  ULONG LastCompactionTick;
  ULONG MaxCompactionTime;
  ULONG OpcodeBenchmarks[OPCODE_COUNT][4];
  ULONG SyscallBenchmarks[SYSCALL_COUNT][4];
  UBYTE Buffer[256];
#endif

#if defined ARM_DEBUG
  UBYTE AssertFlag;
  ULONG AssertLine;
#endif
} VARSCMD;

//
//Activation
//

//Activate new program by filename (open file and inflate run-time data)
NXT_STATUS cCmdActivateProgram(UBYTE * pFileName);

//Deactivate currently active program (re-init run-time data and close file)
void cCmdDeactivateProgram();

//Reset various device state variables
void cCmdResetDevices(void);

//Parse activation record file header information
typedef struct
{
  UWORD DSTOC;
  UWORD DSDefaults;
  UWORD DSDefaultsSize;
  UWORD DynamicDefaults;
  UWORD DynamicDefaultsSize;
  UWORD Clumps;
  UWORD Codespace;
} PROG_FILE_OFFSETS;

NXT_STATUS cCmdReadFileHeader(UBYTE* pData, ULONG DataSize,
            PROG_FILE_OFFSETS* pFileOffsets);

NXT_STATUS cCmdInflateDSDefaults(UBYTE* pDSDefaults, UWORD *pDefaultsOffset, DS_ELEMENT_ID DSElementID);


//
//Clump management
//

//Clump queuing
void cCmdEnQClump(CLUMP_Q * Queue, CLUMP_ID NewClump);
void cCmdDeQClump(CLUMP_Q * Queue, CLUMP_ID Clump);
void cCmdRotateQ(CLUMP_Q * Queue);
UBYTE cCmdIsClumpOnQ(CLUMP_Q * Queue, CLUMP_ID Clump);
UBYTE cCmdIsQSane(CLUMP_Q * Queue);

//Mutex queuing
NXT_STATUS cCmdAcquireMutex(MUTEX_Q * Mutex, CLUMP_ID Clump);
NXT_STATUS cCmdReleaseMutex(MUTEX_Q * Mutex, CLUMP_ID Clump);

//Conditionally schedule dependents of given clump (Begin and End specify subset of list)
NXT_STATUS cCmdSchedDependents(CLUMP_ID Clump, SWORD Begin, SWORD End);

//Conditionally schedule TargetClump
NXT_STATUS cCmdSchedDependent(CLUMP_ID Clump, CLUMP_ID TargetClump);

//Test if ClumpID is sane at run-time (valid for indexing AllClumps)
UBYTE cCmdIsClumpIDSane(CLUMP_ID Clump);

//
//Code stream management
//

//Instruction masking macros -- get the interesting bits out of an encoded instruction word
#define COMP_CODE(pInstr)   ((UBYTE)((((pInstr)[0]) & 0x0700) >> 8))
#define INSTR_SIZE(pInstr)  ((UBYTE)((((pInstr)[0]) & 0xF000) >> 12))

#ifdef USE_SHORT_OPS
//!!! IS_SHORT_OP and SHORT_OP_CODE do not check for insane (out of bounds) data. Accessor function would be safer.
#define IS_SHORT_OP(pInstr)   ((UBYTE)((((pInstr)[0]) & 0x0800) >> 8) == 8)
#define SHORT_OP_CODE(pInstr) COMP_CODE(pInstr)
#define SHORT_ARG(pInstr)     ((SBYTE) (((pInstr)[0]) & 0x00FF))
//ShortOpMap defined in c_cmd_bytecodes.h
#define OP_CODE(pInstr)       (IS_SHORT_OP(pInstr) ? ShortOpMap[SHORT_OP_CODE(pInstr)] : (UBYTE) (((pInstr)[0]) & 0x00FF))
#else
#define OP_CODE(pInstr)       ((UBYTE) (((pInstr)[0]) & 0x00FF))
#endif

//Access count of codewords belonging to Clump. If no clump specified, return count of all codewords in program.
CODE_INDEX cCmdGetCodespaceCount(CLUMP_ID Clump);

//
//Memory pool management
//

//Initialize entire memory pool with default value
void cCmdInitPool(void);

//Resize dataspace array specified by DSElementID and Offset.
NXT_STATUS cCmdDSArrayAlloc(DS_ELEMENT_ID DSElementID, UWORD Offset, UWORD NewCount);
//Resize dataspace array specified by DVIndex.  In most cases, call higher-level cCmdDSArrayAlloc instead.
NXT_STATUS cCmdDVArrayAlloc(DV_INDEX DVIndex, UWORD NewCount);

NXT_STATUS cCmdAllocSubArrayDopeVectors(DS_ELEMENT_ID DSElementID, UWORD Offset);
NXT_STATUS cCmdFreeSubArrayDopeVectors(DS_ELEMENT_ID DSElementID, UWORD Offset);
NXT_STATUS cCmdAllocDopeVector(DV_INDEX *pIndex, UWORD ElemSize, UWORD BackPtr);
NXT_STATUS cCmdFreeDopeVector(DV_INDEX DVIndex);
NXT_STATUS cCmdGrowDopeVectorArray(UWORD NewCount);
NXT_STATUS cCmdCompactDopeVectorArray(void);

UWORD cCmdCalcArrayElemSize(DS_ELEMENT_ID DSElementID);

NXT_STATUS cCmdMemMgrMoveToTail(DV_INDEX DVIndex);
NXT_STATUS cCmdMemMgrInsertAtTail(DV_INDEX DVIndex);

//Utility function to check sanity of MemMgr data structure.  Boolean result.
UBYTE cCmdVerifyMemMgr();

NXT_STATUS cCmdDSCompact(void);

//
// Message Queue management
//

NXT_STATUS cCmdMessageWrite(UWORD QueueID, UBYTE * pData, UWORD Length);
NXT_STATUS cCmdMessageRead(UWORD QueueID, UBYTE * pData, UWORD Length, UBYTE Remove);
NXT_STATUS cCmdMessageGetSize(UWORD QueueID, UWORD * Size);

//
//Dataspace management
//

#define IS_AGGREGATE_TYPE(TypeCode) ((TypeCode == TC_ARRAY) || (TypeCode == TC_CLUSTER))
#define IS_SIGNED_TYPE(TypeCode) (((TypeCode) == TC_SBYTE) || ((TypeCode) == TC_SWORD) || ((TypeCode) == TC_SLONG))

//Test if DS_ELEMENT_ID is sane at run-time (valid for indexing DS TOC)
UBYTE cCmdIsDSElementIDSane(DS_ELEMENT_ID Index);

DS_ELEMENT_ID cCmdGetDataspaceCount(void);
TYPE_CODE cCmdDSType(DS_ELEMENT_ID DSElementID);

//Pointer accessors to resolve actual data locations in RAM
void* cCmdDSPtr(DS_ELEMENT_ID DSElementID, UWORD Offset);
void* cCmdDVPtr(DV_INDEX DVIndex);

//Helper to walk the DSTOC to the next entry at the same aggregate nesting level as CurrID
DS_ELEMENT_ID cCmdNextDSElement(DS_ELEMENT_ID CurrID);

//Recursively compare two complete data type descriptors
UBYTE cCmdCompareDSType(DS_ELEMENT_ID DSElementID1, DS_ELEMENT_ID DSElementID2);

//Functions for managing data flattened to byte arrays
UWORD cCmdCalcFlattenedSize(DS_ELEMENT_ID DSElementID, UWORD Offset);
NXT_STATUS cCmdFlattenToByteArray(UBYTE * pByteArray, UWORD * pByteOffset, DS_ELEMENT_ID DSElementID, UWORD Offset);
NXT_STATUS cCmdUnflattenFromByteArray(UBYTE * pByteArray, UWORD * pByteOffset, DS_ELEMENT_ID DSElementID, UWORD Offset);

//Comparison evaluation.  Comparison codes defined in c_cmd_bytecodes.h.
//cCmdCompare operates on scalars passed as ULONGs -- type-specific comparisons done inside function.
UBYTE cCmdCompare(UBYTE CompCode, ULONG Val1, ULONG Val2, TYPE_CODE TypeCode1, TYPE_CODE TypeCode2);
//cCmdCompareAggregates does polymorphic comparisons (with recursive helper function).
NXT_STATUS cCmdCompareAggregates(UBYTE CompCode, UBYTE *ReturnBool, DATA_ARG Arg2, UWORD Offset2, DATA_ARG Arg3, UWORD Offset3);
NXT_STATUS cCmdRecursiveCompareAggregates(UBYTE CompCode, UBYTE *ReturnBool, UBYTE *Finished, DATA_ARG Arg2, UWORD Offset2, DATA_ARG Arg3, UWORD Offset3);

//Cluster functions
UWORD cCmdClusterCount(DS_ELEMENT_ID DSElementID);

//Array functions
#define ARRAY_ELEM_OFFSET(DVIndex, Index) ((UWORD)(DV_ARRAY[(DVIndex)].Offset + DV_ARRAY[(DVIndex)].ElemSize * (Index)))
UWORD cCmdGetDVIndex(DS_ELEMENT_ID DSElementID, UWORD Offset);
UWORD cCmdArrayCount(DS_ELEMENT_ID DSElementID, UWORD Offset);
TYPE_CODE cCmdArrayType(DS_ELEMENT_ID DSElementID);

//!!! Usage of these DATA_ARG masks is untested and unsupported in officially released firmware!
#define DATA_ARG_ADDR_MASK 0x3FFF
#define DATA_ARG_IMM_MASK 0x7FFF

//General data accessors (DS and IO Map)
void * cCmdResolveDataArg(DATA_ARG DataArg, UWORD Offset, TYPE_CODE * TypeCode);
ULONG cCmdGetVal(void * pVal, TYPE_CODE TypeCode);
void cCmdSetVal(void * pVal, TYPE_CODE TypeCode, ULONG NewVal);
UWORD cCmdSizeOf(TYPE_CODE TypeCode);

//
//Interpreter functions
//

//Clump-based "master" interpreter
NXT_STATUS cCmdInterpFromClump(CLUMP_ID Clump);

//Function pointer typedef for sub-interpreters
typedef NXT_STATUS (*pInterp)(CODE_WORD * const);

//Sub-interpreter dispatch functions
NXT_STATUS cCmdInterpNoArg(CODE_WORD * const pCode);
NXT_STATUS cCmdInterpUnop1(CODE_WORD * const pCode);
NXT_STATUS cCmdInterpUnop2(CODE_WORD * const pCode);
NXT_STATUS cCmdInterpBinop(CODE_WORD * const pCode);
NXT_STATUS cCmdInterpOther(CODE_WORD * const pCode);

#define INTERP_COUNT 5

//Polymorphic interpreter functions
NXT_STATUS cCmdInterpPolyUnop2(CODE_WORD const Code, DATA_ARG Arg1, UWORD Offset1, DATA_ARG Arg2, UWORD Offset2);
ULONG cCmdUnop2(CODE_WORD const Code, ULONG Operand, TYPE_CODE TypeCode);

NXT_STATUS cCmdInterpPolyBinop(CODE_WORD const Code, DATA_ARG Arg1, UWORD Offset1, DATA_ARG Arg2, UWORD Offset2, DATA_ARG Arg3, UWORD Offset3);
ULONG cCmdBinop(CODE_WORD const Code, ULONG LeftOp, ULONG RightOp, TYPE_CODE LeftType, TYPE_CODE RightType);

//
//Support functions for lowspeed (I2C devices, i.e. ultrasonic sensor) communications
//

NXT_STATUS cCmdLSCheckStatus(UBYTE Port);
UBYTE cCmdLSCalcBytesReady(UBYTE Port);
NXT_STATUS cCmdLSWrite(UBYTE Port, UBYTE BufLength, UBYTE *pBuf, UBYTE ResponseLength);
NXT_STATUS cCmdLSRead(UBYTE Port, UBYTE BufLength, UBYTE * pBuf);

//
//Support for OP_SYSCALL
//

//
//Each cCmdWrap<SysCallName> funtion below implements one system call.
//The OP_SYSCALL interpreter wrangles the argument vector, ArgV,
// then calls the appropriate wrapper function according to the SysCallID.
//Wrapper functions write directly back into the dataspace via ArgV.
//
#define MAX_CALL_ARGS 16

typedef NXT_STATUS (*pSysCall)(UBYTE * ArgV[]);

NXT_STATUS cCmdWrapFileOpenRead(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapFileOpenWrite(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapFileOpenAppend(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapFileRead(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapFileWrite(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapFileClose(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapFileResolveHandle (UBYTE * ArgV[]);
NXT_STATUS cCmdWrapFileRename (UBYTE * ArgV[]);
NXT_STATUS cCmdWrapFileDelete (UBYTE * ArgV[]);
NXT_STATUS cCmdWrapSoundPlayFile(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapSoundPlayTone(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapSoundGetState(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapSoundSetState(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapDrawText(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapDrawPoint(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapDrawLine(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapDrawCircle(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapDrawRect(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapDrawPicture(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapSetScreenMode(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapReadButton(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapCommLSWrite(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapCommLSRead(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapCommLSCheckStatus(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapRandomNumber(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapGetStartTick(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapMessageWrite(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapMessageRead(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapCommBTCheckStatus(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapCommBTWrite(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapCommBTRead(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapKeepAlive(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapIOMapRead(UBYTE * ArgV[]);
NXT_STATUS cCmdWrapIOMapWrite(UBYTE * ArgV[]);

//Handler for remote control protocol packets -- called from comm module via IO map function pointer
UWORD cCmdHandleRemoteCommands(UBYTE * pInBuf, UBYTE * pOutBuf, UBYTE * pLen);

#ifdef SIM_NXT
//
// Helper functions to provide simulator library access to VM internals
//
SWORD cCmdGetCodeWord(CLUMP_ID Clump, CODE_INDEX Index);
UBYTE * cCmdGetDataspace(UWORD *DataspaceSize);
DOPE_VECTOR * cCmdGetDopeVectorPtr(void);
ULONG cCmdGetPoolSize(void);
MEM_MGR cCmdGetMemMgr(void);
#endif

#else //!ENABLE_VM

//Placeholder VARSCMD for alternate implementation (see bottom of c_cmd.c for usage notes)
typedef struct
{
  UBYTE         Tmp;
} VARSCMD;

#endif //ENABLE_VM

#endif //C_CMD

⌨️ 快捷键说明

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