示例#1
0
DWORD WINAPI OSTaskW32( LPVOID lpParameter )
{
    OS_TCB *ptcb;
    OS_EMU_STK  *stack;

    ptcb = (OS_TCB*) lpParameter;
    stack = (OS_EMU_STK*) ptcb->OSTCBStkPtr;
    
#ifdef DISABLE_PRIORITY_BOOST
        if( SetThreadPriorityBoost( stack->Handle, TRUE ) == 0 ) {
#ifdef OS_CPU_TRACE
            OS_Printf("Error: SetThreadPriorityBoost\n");
#endif
        }
#endif

    OS_INIT_CRITICAL();

    stack->Task(stack->pData);

    stack->Exit = 1;
    OSTaskDel(ptcb->OSTCBPrio);

    return 0;
}
示例#2
0
/**
 * @brief	Parse and then process the command
 * @author	R.Lillback
 * @date	1-Sep-2015
 *
 * @details	This message calls functions to:
 * 				1.) Split the command into parts
 * 				2.) Look to find the command in the command constant list
 * 				3.) Jump to a multiplexer to validate the command & then execute it
 * 				4.) Look to see if the command worked
 *
 * @param   <none>
 *
 * @returns <void>
 *
 */
void ProcessCmd(char* strCommand)
{
	char strMainCmd[MAX_INPUT_LINE_LEN];  	// Main command
	char strSubCmdOne[MAX_INPUT_LINE_LEN];	// First sub-command
	int iSubCmdOne;						    // Sub-command One is going to be a number
	int i;									// Loop integer
	int iFound = FALSE;						// Did we find the command?
	int lastCommand = FALSE;				// Used to terminate the loop at the last command (defined as '\0')
	DWORD iResult;							// Result of executing the command

	iSubCmdOne = ParseCommands(strCommand, strMainCmd, strSubCmdOne);	// Split the commands apart into multiples

	i=-1;
	while ( (FALSE == lastCommand) && (FALSE == iFound) && (i < MAX_COMMANDS) ){
		i++;
		if ( CLI_COMMANDS[i].strCmd == '\0' ) {
			lastCommand = TRUE;
		}
		else {
			iFound = IsEqual(CLI_COMMANDS[i].strCmd,strMainCmd);
		}
	} // while

	if ( lastCommand ) {	// we parsed through all the commands and hit the end
		OS_Printf("Error....command not found.\n");
	}
	else {	// we found a command
		if ( iFound ) {
			iResult = ExecuteCommand (CLI_COMMANDS[i].iIndex, iSubCmdOne);		// so execute it
			if (iResult != (DWORD)0) {
				OS_Printf("%s command failed.", CLI_COMMANDS[i].strCmd);	    // it failed!
			}
		}
	} // lastCommand

	PRINT_PROMPT;
	OS_Fflush(stdout);

	return;
} // ProcessCmd
示例#3
0
void OSTCBInitHook(OS_TCB *ptcb)
{
    OS_EMU_STK  *stack;
    
    stack = (OS_EMU_STK*) ptcb->OSTCBStkPtr;

    stack->Handle = CreateThread( NULL, 0, OSTaskW32, ptcb, CREATE_SUSPENDED, &stack->Id );
    
#ifdef SET_AFFINITY_MASK
    if( SetThreadAffinityMask( stack->Handle, 1 ) == 0 ) 
	{	
#ifdef OS_CPU_TRACE
        OS_Printf("Error: SetThreadAffinityMask\n");
#endif
    }
#endif
}
示例#4
0
DWORD WINAPI OSTickW32( LPVOID lpParameter )
{
    OS_INIT_CRITICAL();

    while(!OSTerminateTickW32)
    {
        OSTickISR();
#ifdef WIN_MM_TICK
        if( WaitForSingleObject(OSTickEventHandle, 5000) == WAIT_TIMEOUT)
        {
            #ifdef OS_CPU_TRACE
                OS_Printf("Error: MM OSTick Timeout!\n");
            #endif
        }

        ResetEvent(OSTickEventHandle);
#else
        Sleep(1000/OS_TICKS_PER_SEC);
#endif
    }

    return 0;
}
示例#5
0
void OS_EXIT_CRITICAL()
{
#ifdef USE_CRITICAL_SECTION
    LeaveCriticalSection(&OSCriticalSection);
#else
#ifdef ALLOW_CS_RECURSION

    if( Recursion > 0 ) {
        if(--Recursion == 0 ) {
            ThreadID = 0;
            ReleaseSemaphore( OSSemaphore, 1, NULL );
        }
    }
    else {
#ifdef OS_CPU_TRACE
    OS_Printf("Error: OS_EXIT_CRITICAL\n");
#endif
    }

#else
    ReleaseSemaphore( OSSemaphore, 1, NULL );
#endif
#endif
}
示例#6
0
void OSStartHighRdy()
{
    DWORD  dwID;

    OSInitTrace(100000);

    OS_ENTER_CRITICAL();

    OSTaskSwHook();
    ++OSRunning;

    OSCtxSwW32Event  = CreateEvent(NULL,FALSE,FALSE,NULL);
    OSCtxSwW32Handle = CreateThread( NULL, 0, OSCtxSwW32, 0, 0, &dwID );

    SetPriorityClass(OSCtxSwW32Handle,THREAD_PRIORITY_HIGHEST);

#ifdef SET_AFFINITY_MASK
    if( SetThreadAffinityMask( OSCtxSwW32Handle, 1 ) == 0 ) {
#ifdef OS_CPU_TRACE
        OS_Printf("Error: SetThreadAffinityMask\n");
#endif
       }
#endif
    
	SetThreadPriority(OSCtxSwW32Handle,THREAD_PRIORITY_TIME_CRITICAL);

    OSTick32Handle = CreateThread( NULL, 0, OSTickW32, 0, 0, &dwID );
    SetPriorityClass(OSTick32Handle,THREAD_PRIORITY_HIGHEST);

#ifdef SET_AFFINITY_MASK
    if( SetThreadAffinityMask( OSTick32Handle, 1 ) == 0 ) 
	{
#ifdef OS_CPU_TRACE
        OS_Printf("Error: SetThreadAffinityMask\n");
#endif
    }
#endif

	SetThreadPriority(OSTick32Handle,THREAD_PRIORITY_HIGHEST);

#ifdef WIN_MM_TICK
    timeGetDevCaps(&OSTimeCap, sizeof(OSTimeCap));

    if( OSTimeCap.wPeriodMin < WIN_MM_MIN_RES )
        OSTimeCap.wPeriodMin = WIN_MM_MIN_RES;

    timeBeginPeriod(OSTimeCap.wPeriodMin);

    OSTickEventHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
    OSTickTimer       = timeSetEvent((1000/OS_TICKS_PER_SEC),OSTimeCap.wPeriodMin,(LPTIMECALLBACK)OSTickEventHandle, dwID,TIME_PERIODIC|TIME_CALLBACK_EVENT_SET);
#endif
    
    
    SS_SP = (OS_EMU_STK*) OSTCBHighRdy->OSTCBStkPtr;                      /* OSTCBCur = OSTCBHighRdy;     */
                                                                          /* OSPrioCur = OSPrioHighRdy;   */
    ResumeThread(SS_SP->Handle);

    OS_EXIT_CRITICAL();
    
    WaitForSingleObject(OSCtxSwW32Handle,INFINITE);

#ifdef WIN_MM_TICK
    timeKillEvent(OSTickTimer);
    timeEndPeriod(OSTimeCap.wPeriodMin);
    CloseHandle(OSTickEventHandle);
#endif

	CloseHandle(OSTick32Handle);
    CloseHandle(OSCtxSwW32Event);
}
示例#7
0
/**
 * @brief	Create a copy of the object dictionary located at iNode
 * @author	R.Lillback
 * @date	4-Sep-2015
 *
 * @details
 *
 * @param   <none>
 *
 * @returns 0=success, anything else = failure.
 *
 */
DWORD	PopulateObjectDictionary(void)
{
	ECI_RESULT	result		=	ECI_OK;
	DWORD		loopVar		=	0;
	DWORD		outerLoopVar=	0;
	DWORD		myIndex		= 	0x0000;
	BYTE		mySubIndex	=	0x00;
	BYTE		maxIndex	=	0x00;

	BYTE		returnedByte[8];

	DWORD		remoteSZ	= 	0x00000000;  // Remote Object Dictionary Data Size
	DWORD		localSZ		= 	0x00000000;  // Local Object Dictionary Data Size
	DWORD		localDT		= 	0x00000000;  // Local Object Dictionary Data Type
	DWORD		localData	= 	0x00000000;

	WORD		indicies[]	=
	{
			0x2000,
			0x2001,
			0x3001,
			0x5000,
			0x5001,
			0x5002,
			0x5003,
			0xFFFF
	};

	for	(loopVar = 0; loopVar<8; loopVar++)
		returnedByte[loopVar]	=	0x00;

	loopVar		=	0x00;
	outerLoopVar=	0x00;
	myIndex		= 	indicies[outerLoopVar];
	mySubIndex	=	0x00;
	while (0xFFFF 	!= 	myIndex)
	{
		/* Figure out the best way to retrieve the index */
		remoteSZ	=	sizeof(BYTE);
		localSZ		=	0x00000000;
		localDT		=	0x00000000;
		result		=	GetDTValues(myIndex, mySubIndex, &localData, &localDT, &localSZ);
		result		= 	SDO_Upload(iNode, myIndex, mySubIndex, returnedByte);

		if (localSZ  == remoteSZ)	// if the sizes match, then continue on
		{
			if	(returnedByte[0] <= 0x03)	// Do a standard set of transfers if we are 3 elements or less
			{
				maxIndex	=	returnedByte[0];
				loopVar		=	0x01;
				while (loopVar <=	maxIndex)
				{
					result	=	GetDTValues(myIndex, loopVar, &localData, &localDT, &localSZ);	// get the local copy of the table
					result	=	SDO_Upload(iNode, myIndex,	loopVar,	returnedByte);			// get the entry from the remote server node
					if (ECI_OK == result)
					{
						switch (localSZ) // reconstruct the data & store into local copy of Object Dictionary
						{
							case 1: // BYTE
							{
								BYTE	byteData	=	0x00;
								byteData			=	returnedByte[0];
								result	=	SetDTValues(myIndex, loopVar, &byteData, &localDT, &remoteSZ);
								OS_Printf("\nByte Data set index 0x%04X subindex 0x%02X to 0x%02X.\n",myIndex,loopVar,byteData);
								break;
							}
							case 2: // WORD
							{
								WORD	wordData	=	0x0000;
								wordData			=	((WORD)returnedByte[1] << 8) + (WORD)returnedByte[0];
								result	=	SetDTValues(myIndex, loopVar, &wordData, &localDT, &remoteSZ);
								OS_Printf("\nWord Data set index 0x%04X subindex 0x%02X to 0x%04X.\n",myIndex,loopVar,wordData);
								break;
							}
							case 4: // DWORD
							{
								DWORD	dwordData	=	0x00000000;
								dwordData			=	((DWORD)returnedByte[3] << 24) +
														((DWORD)returnedByte[2] << 16) +
														((DWORD)returnedByte[1] << 8)  +
														((DWORD)returnedByte[0]);
								result	=	SetDTValues(myIndex,loopVar,&dwordData,&localDT,&remoteSZ);
								OS_Printf("\nDword data set index 0x%04X subindex 0x%02X to 0x%08X.\n",myIndex,loopVar,dwordData);
								break;
							}
						} // switch on data size

						loopVar++; 		// go onto next one
					} // if SDO_Upload result was good
				} // while loopVar < index size
			} // do a standard set of transfers
			else // do a block transfer
			{
				BYTE	blockData[896];				// Right now, I am limiting the block download to 896 bytes or 128 blocks of 7-byte data...
				DWORD	i					=	0;  // Yeah, my 'generic' loop counter
				for (i = 0;i < 896; i++)					// Initialize blockData
					blockData[i] = 0;
				BYTE	subIndex			=	0x01;
				WORD	bytesOfDataNeeded	= 	0;	// How many data bytes does the LOCAL data table index need?
				WORD	remoteBytesSending	=	0;	// How many data bytes are being sent?
				BYTE	subIndexSz			=	0;
				DWORD	dummy				=	0;
				DWORD	dummy2				=	0;
				DWORD	dummy3				=	0;
				WORD	indexSize			=	0;
				WORD	tempWord			=	0;
				bytesOfDataNeeded			=	CalculateDataTableBytes(myIndex);
				result	=	InitiateBlockUpload(iNode,					//	Which node
						                        myIndex,				//  Which index
												subIndex,				//	Starting sub index number
												returnedByte[0],		//	# of sub indexes
												&remoteBytesSending);	//	Get the number of bytes we are sending
				if	(ECI_OK !=	result)
				{
					OS_Printf("Initiate block upload failed.\n");
					return result;
				}

				if	(bytesOfDataNeeded < remoteBytesSending)
				{
					OS_Printf("Error!  Too few bytes are going to be sent via a block transfer.\n");
					return	~ECI_OK;
				}

				result	=	GetBlockUploadData(iNode, blockData);		// Put the block data into a buffer

				/* Now let's decode the results & put them into order */
				dummy	=	GetDTValues(myIndex, 0x00, &subIndexSz, &dummy2, &dummy3);	// Get the index count
				i		=	0;

				for (subIndex = 0x01; subIndex <= subIndexSz; subIndex++)
				{
					dummy	=	GetDTValues(myIndex, subIndex, &dummy3, &dummy2, &indexSize);
					localDT	=	0;
					switch (indexSize)
					{
						case	1: // BYTE
						{
							result	=	SetDTValues(myIndex, subIndex, &returnedByte[i], &localDT, &indexSize);
							OS_Printf("\nByte Data set index 0x%04X subindex 0x%02X to 0x%02X.\n",myIndex,subIndex,returnedByte[i]);
							i += 1;
							break;
						} // BYTE
						case	2: // WORD
						{
							tempWord	=	(WORD)returnedByte[i];
							tempWord	+=	(WORD)(returnedByte[i+1]) << 8;
							result	=	SetDTValues(myIndex, subIndex, &tempWord, &localDT, &indexSize);
							OS_Printf("\nWord Data set index 0x%04X subindex 0x%02X to 0x%04X.\n",myIndex,subIndex,tempWord);
							i += 2;
							break;
						} // WORD
						case	4:	// DWORD
						{
							dummy	=	(DWORD)returnedByte[i];
							dummy	+=	(DWORD)(returnedByte[i+1]) << 8;
							dummy	+=	(DWORD)(returnedByte[i+2]) << 16;
							dummy	+=	(DWORD)(returnedByte[i+3]) << 24;
							result	=	SetDTValues(myIndex, subIndex, &dummy, &localDT, &indexSize);
							OS_Printf("\nDWord Data set index 0x%04X subindex 0x%02X to 0x%08X.\n",myIndex,subIndex,dummy);
							i += 4;
							break;
						} // DWORD
					} // switch indexSize
				} // for
			}	// do a block transfer
		} // if sizes match
		outerLoopVar++;
		myIndex	=	indicies[outerLoopVar];
	}


	return (DWORD)result;

} // PopulateObjectDictionary
示例#8
0
/**
 * @brief	Perform a change in operating modes on the target node
 * @author	R.Lillback
 * @date	3-Sep-2015
 *
 * @details	This function:
 * 				1.) Validates the command & data
 * 				2.) Sends an NMT message out on the CAN bus to change modes
 * 				3.) Waits for a NODE_STATUS message from the target node.
 * 				4.) Validates that the status has updated to what we expect.
 *
 * 				This function will send the request up to 5 times, and then fail.
 * 				It does this:
 * 					1.) Send the message
 * 					2.) Listen for up to 12 seconds for a correct response.
 * 					3.) Resend the message
 * 					4.) Listen for up to 12 seconds....
 * 					5.) Rinse & repeat for a total of 5 messages sent.
 *
 * @param   subcommand (as in integer), which is the mode you want to change to.
 *
 * @returns 0=success, anything else = failure
 *
 */
DWORD DoModeChange(DWORD subCommand)
{
	BYTE 		tries 	 = 1;				// Count the number of tries
	DWORD 		finished = FALSE;			// Did we get back what we expected?
	DWORD		dwCOB_ID;					// a cob_id to filter for
	s_MESSAGE 	msg = {0};					// Give us a message
	BYTE		cntr;						// just a loop variable
	e_MODES		mode	=	(e_MODES)subCommand;
	ECI_RESULT	result;

	if ( ((BYTE)subCommand >= 0) && ((BYTE)subCommand <= (BYTE)MODE_TESTHW) ) {
		if ( (iNode > 0) && (iNode < 1024) ) {  // Check node
			OS_Printf("Asking Node %u to changed to mode %u - %s\n",
						 iNode,
						 mode,
						 MODE_DESCRIPTION[(e_MODES)subCommand].strDescr);

			dwCOB_ID	= 	(COB_NODE_STATUS << 7); // Looking for a node status message
			dwCOB_ID 	+= 	iNode;					// from this node

			while ( (tries <= MAX_TRIES) && (finished == FALSE) )
			{
				mode 	=	(e_MODES)subCommand;
				result 	= 	ChangeMode( iNode, mode );			// Request the change

				/* Wait for the node status to change coming back */
				OS_Printf("Waiting.");
				OS_Fflush(stdout);

				result 	= 	~ECI_OK;		// Start looping
				cntr	= 	0;				// clear the loop variable

				while ( (ECI_OK != result) && (cntr<48)) {  // 48 loops at 1/4 second a loop = 12 seconds to wait
					OS_Sleep(QUARTER_SECOND);
					result = LookForMessage(&msg);		// Look for a message on the FIFO queue
					if (ECI_OK == result) {	// yes, message on the queue, now is it the one we were looking for?
						if ( (dwCOB_ID  == msg.cob_id) &&
							 (mode		== msg.data[0]) ) {
							// YAY, it is our message
							result 	 = ECI_OK;	// yeah, let's leave this while loop
							finished = TRUE;	// and the outer while loop
							eMode	 = (e_MODES)mode;	// Make sure we set the global mode status, too.
						}
						else {  // it's not our message
							result	= ~ECI_OK;	// yeah, don't leave this loop
						}
					} // there was a message on the queue
					OS_Printf(".");
					OS_Fflush(stdout);
					cntr++;
				} // while not ECI_OK

				tries++;
				OS_Printf("\n");
				OS_Fflush(stdout);

			} // while we are not finished & we haven't reached our maximum try limit
		} // if Targeted node was ok
		else {
			OS_Printf("Targeted Node - %u - out of range 1..1023\n", (WORD)subCommand);
			OS_Printf("Mode **NOT** changed. Please change node number from %u\n",iNode);
		} // Check node
	} // if subCommand is ok
	else {
		OS_Printf("Mode change is out of range. Needs to be from 0..%u\n",(BYTE)MODE_TESTHW);
		OS_Printf("Mode **NOT** changed.");
	}

	if (TRUE == finished) {	// only if we found the result we wanted do we return OK
		result = ECI_OK;
	}
	else {
		result = ~ECI_OK;
	}

	return result;

} // DoModeChange
示例#9
0
/**
 * @brief	Validate and execute the command(s) requested
 * @author	R.Lillback
 * @date	1-Sep-2015
 *
 * @details	This is the main multiplexer to figure out which function(s) get called.
 *
 * @param   command = the command index to run  see CLI_COMMANDS[].iIndex
 * 	        subcommand = the integer value of the subcommand
 *
 * @returns the integer value of the sub command, if any.  If none, it returns 0.
 *
 */
DWORD ExecuteCommand (int command, int subCommand)
{
	DWORD result = TRUE;
	int i 		 = 0;
	int loopDone = FALSE;

	switch(command) {
	    /****************************************************************************************/
		case 0:   // HELP
		{
			loopDone = FALSE;
			i=0;
			while (!loopDone) {
				if (CLI_COMMANDS[i].strCmd == '\0') {
					loopDone = TRUE;	// Loop until you hit the empty command
				} else {
					OS_Printf("%s\n",CLI_COMMANDS[i].strDescr);
				}
				i++;
			} // while
			break;
		} // HELP
		/****************************************************************************************/
		case 1:   // NODE xxx
		{
			if ( ((WORD)subCommand > 0) && ((WORD)subCommand < 1024) ) {
				iNode  = (WORD)subCommand;		// Change the targeted node
				OS_Printf("Targeted Node Changed to: %u\n", iNode);
				return	ECI_OK;
			}
			else {
				OS_Printf("Targeted Node - %u - out of range 1..1023\n", (WORD)subCommand);
				OS_Printf("Targeted Node **NOT** changed.\n");
				return ~ECI_OK;
			}
			break;
		} // NODE
		/****************************************************************************************/
		case 2: // MODE x
		{
			result = DoModeChange(subCommand);				// Call a subroutine to change modes
			if (ECI_OK == result) {
				OS_Printf("Mode change successful.\n");
			}
			break;
		} // MODE
		/****************************************************************************************/
		case 3:  // READALL - Read entire OD
		   {
			   //TODO: Create the ReadBlock SDO command
			   result = PopulateObjectDictionary();			// Call a subroutine to do this
			   break;
		   } // READALL
		/****************************************************************************************/
		case 4:  // OUTON X - Turn on output X
		   {
			   //TODO: Validity check that we are in hardware test mode
			   //TODO: Validity check the Output is in 1..14
			   //TODO: Create the read (both expedited and not) SDO Download
			   //TODO: Be sure to get the complete transaction & await the handshake
			   OS_Printf("Command %s not implemented yet.\n",CLI_COMMANDS[command+1].strCmd);
			   break;
		   } // OUTOFF
		/****************************************************************************************/
		case 5:  // OUTOFF - Turn off output X
		   {
			   //TODO: Validity check that we are in hardware test mode
			   //TODO: Validity check the Output is in 1..14
			   //TODO: Do OUTON first!
			   OS_Printf("Command %s not implemented yet.\n",CLI_COMMANDS[command+1].strCmd);
			   break;
		   } // OUTOFF
		/****************************************************************************************/
		case 6:  // INSTAT - Read and show the status of all inputs
		   {
			   //TODO: Create the UPLOAD request
			   OS_Printf("Command %s not implemented yet.\n",CLI_COMMANDS[command+1].strCmd);
			   break;
		   } // INSTAT
		/****************************************************************************************/
		case 7:  // OUTSTAT - Read and show the status of all outputs
		   {
			   //TODO: Create the UPLOAD request
			   OS_Printf("Command %s not implemented yet.\n",CLI_COMMANDS[command+1].strCmd);
			   break;
		   } // OUTSTAT
	    /****************************************************************************************/
		case 254: // EXIT
			{
				iQuit = TRUE;
				break;
			} // EXIT
		/****************************************************************************************/
		default:
		{
			OS_Printf("How did I get this far in the command switch statement of cmdMultiplex.c ExecuteCommand() o.O?\n");
			break;
		}
		/****************************************************************************************/
	} // switch

	return result;

} //ExecuteCommand