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

📄 ioctrl_s.cpp

📁 一本叫自己动手写嵌入式操作系统的书的源代码,作者是蓝枫叶,详细介绍了如何写一个嵌入式操作系统,而不是操作系统
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//***********************************************************************/
//    Author                    : Garry
//    Original Date             : Jun,10 2005
//    Module Name               : IOCTRL_S.CPP
//    Module Funciton           : 
//                                This module countains io control application's implemen-
//                                tation code.
//                                This file countains the shell command or application
//                                code,as it's name has ended by "_S".
//    Last modified Author      :
//    Last modified Date        :
//    Last modified Content     :
//                                1.
//                                2.
//    Lines number              :
//***********************************************************************/

#ifndef __STDAFX_H__
#include "..\INCLUDE\StdAfx.h"
#endif

#ifndef __IOCTRL_S_H__
#include "..\INCLUDE\IOCTRL_S.H"
#endif

//
//The IO control application is used to input or output data to or from IO port.
//This application is very powerful,it can support input/output one byte,one word,
//one byte string or one word string from/into device port.
//The following are it's usage(# is the prompt of this application):
// #inputb io_port    //Input a byte from port,which is indicated by io_port.
// #inputw io_port    //Input a word from port,which is indicated by io_port.
// #inputsb io_port str_len  //Input a byte string from port,which is indicated by io_port,
//                           //str_len is the number of bytes to be inputed.
// #inputsw io_port str_len  //The same as inputsb.
// #outputb io_port   //Output a byte to port.
// #outputw io_port   //Output a word to port.
// #outputsb io_port str_len //Output a byte string to port.
// #outputsw io_port str_len //Output a word string to port.
// #memwb mem_addr data      //Write a byte to the memory address 'mem_addr'.
// #memww mem_addr data      //Write a word to the memory address 'mem_addr'.
// #memwd mem_addr data      //Write a dword to the memory.
// #memrb mem_addr           //Read a byte from memory.
// #memrw mem_addr           //Read a word from memory.
// #memrd mem_addr           //Read a dword from memory.
// #exit                     //Exit this application.
// #help                     //Print help information about this application.
//

//
//IO command handler routine's definition.
//Their implementations can be found at below of this file.
//

static DWORD inputb(__CMD_PARA_OBJ*);
static DWORD inputw(__CMD_PARA_OBJ*);
static DWORD inputd(__CMD_PARA_OBJ*);
static DWORD inputsb(__CMD_PARA_OBJ*);
static DWORD inputsw(__CMD_PARA_OBJ*);

static DWORD outputb(__CMD_PARA_OBJ*);
static DWORD outputw(__CMD_PARA_OBJ*);
static DWORD outputd(__CMD_PARA_OBJ*);
static DWORD outputsb(__CMD_PARA_OBJ*);
static DWORD outputsw(__CMD_PARA_OBJ*);

static DWORD memwb(__CMD_PARA_OBJ*);
static DWORD memww(__CMD_PARA_OBJ*);
static DWORD memwd(__CMD_PARA_OBJ*);

static DWORD memrb(__CMD_PARA_OBJ*);
static DWORD memrw(__CMD_PARA_OBJ*);
static DWORD memrd(__CMD_PARA_OBJ*);

static DWORD memalloc(__CMD_PARA_OBJ*);
static DWORD memrels(__CMD_PARA_OBJ*);
static DWORD help(__CMD_PARA_OBJ*);
static DWORD exit(__CMD_PARA_OBJ*);

//
//The following is a map between IO control command and it's handler.
//IO control application will lookup this map to find appropriate handler by command
//name,and call the handler to handle this IO command.
//

static struct __IOCTRL_COMMAND_MAP{
	LPSTR              lpszCommand;                        //Command string.
	DWORD              (*CommandRoutine)(__CMD_PARA_OBJ*); //Handler.
	LPSTR              lpszHelpInfo;                       //Help information string.
}IOCtrlCmdMap[] = {
	{"inputb",    inputb,      "  inputb io_port             : Input a byte from IO port."},
	{"inputw",    inputw,      "  inputw io_port             : Input a word from IO port."},
	{"inputd",    inputd,      "  inputd io_port             : Input a dword from IO port."},
	{"inputsb",   inputsb,     "  inputsb io_port            : Input a byte string from IO port."},
	{"inputsw",   inputsw,     "  inputsw io_port            : Input a word string from IO port."},
	{"outputb",   outputb,     "  outputb io_port val        : Output a byte to IO port."},
	{"outputw",   outputw,     "  outputw io_port val        : Output a word to IO port."},
	{"outputd",   outputd,     "  outputd io_port val        : Output a dword to IO port."},
	{"outputsb",  outputsb,    "  outputsb io_port size addr : Output a byte string to IO port."},
	{"outputsw",  outputsw,    "  outputsw io_port size addr : Output a word string to IO port."},
	{"memwb",     memwb,       "  memwb addr val             : Write a byte to memory location."},
	{"memww",     memww,       "  memww addr val             : Write a word to memory location."},
	{"memwd",     memwd,       "  memwd addr val             : Write a dword to memory location."},
	{"memrb",     memrb,       "  memrb addr                 : Read a byte from memory."},
	{"memrw",     memrw,       "  memrw addr                 : Read a word from memory."},
	{"memrd",     memrd,       "  memrd addr                 : Read a dword from memory."},
	{"memalloc",  memalloc,    "  memalloc                   : Allocate a block of memory."},
	{"memrels",   memrels,     "  memrels addr               : Release the memory allocated by memalloc."},
	{"help",      help,        "  help                       : Print out this screen."},
	{"exit",      exit,        "  exit                       : Exit from this application."},
	{NULL,        NULL,        NULL}                 //End of the map.
};

//
//The following routine is used to print a prompt.
//

static VOID PrintPound()
{
	WORD  wr = 0x0700;
	
	wr += '#';
	ChangeLine();
	GotoHome();
	PrintCh(wr);
}

//
//The following is the entry point of IO control application.
//This routine does the following:
// 1. Get input message from kernel thread message queue,by calling GetMessage;
// 2. If the message is a key down event,and the key is ENTRER,then process the command;
// 3. Form a command parameter object by calling FormParameterObj;
// 4. Lookup the IO command and handler's map,to find appropriate handler;
// 5. Call the handler,command parameter as the handler's parameter;
// 6. If the hander returns IOCTRL_TERMINAL,then exit the application;
// 7. Otherwise,continue the loop.
//

static BYTE strCmdBuffer[MAX_BUFFER_LEN] = {0};  //Command buffer.
DWORD IoCtrlStart(LPVOID)
{
	DWORD                    dwCurrentPtr       = 0L;
	__KERNEL_THREAD_MESSAGE  Msg;
	BYTE                     bt;
	WORD                     wr                 = 0x0700;
	DWORD                    dwMapIndex         = 0L;
	BOOL                     bValidCmd          = FALSE;
	__CMD_PARA_OBJ*          lpParamObj         = NULL;
	DWORD                    dwRetVal           = 0L;

	PrintPound();            //Print out the prompt of this application.

	while(TRUE)
	{
		if(GetMessage(&Msg))
		{
			if(MSG_KEY_DOWN == Msg.wCommand)  //This is a key down event.
			{
				bt = LOBYTE(LOWORD(Msg.dwParam));
				if(VK_RETURN == bt)    //The ENTER key is pressed.
				{
					strCmdBuffer[dwCurrentPtr] = 0;  //Set the end flag.
					dwCurrentPtr               = 0;  //Set the pointer to begin.
					//
					//The following code handles the command.
					//

					lpParamObj = FormParameterObj(&strCmdBuffer[0]);
					if(NULL == lpParamObj)    //Can not create parameter object.
					{
						PrintLine("Fatal error occurs,application exit.");
						goto __TERMINAL;    //Exit the application.
					}
					if(0 != lpParamObj->byParameterNum)  //Valid parameter(s) exits.
					{
						while(IOCtrlCmdMap[dwMapIndex].lpszCommand)
						{
							if(StrCmp(IOCtrlCmdMap[dwMapIndex].lpszCommand,
								lpParamObj->Parameter[0]))
							{
								bValidCmd = TRUE;    //Find the valid command.
								break;
							}
							dwMapIndex ++;
						}
						if(bValidCmd)  //Handle the command.
						{
							dwRetVal = IOCtrlCmdMap[dwMapIndex].CommandRoutine(lpParamObj);
						}
						else
						{
							PrintLine("Unrecognized command.");
						}
					}

					bValidCmd      = FALSE;
					dwMapIndex     = 0L;
					ReleaseParameterObj(lpParamObj);  //Release the parameter object.
					if(IOCTRL_TERMINAL == dwRetVal)
						goto __TERMINAL;
					PrintPound();
				}
				else
				if(VK_BACKSPACE == bt)  //Delete one character.
				{
					if(dwCurrentPtr)
					{
						dwCurrentPtr --;
						GotoPrev();    //Erase one character from screen.
					}
				}
				else  //This only a normal key down event.
				{
					if(dwCurrentPtr < MAX_BUFFER_LEN)  //If the buffer is not overflow.
					{
						strCmdBuffer[dwCurrentPtr] = bt;
						dwCurrentPtr ++;
						wr += bt;
						PrintCh(wr);                   //Print the character to screen.
						wr  = 0x0700;                  //Restore the chatacter's display
						                               //attribute.
					}
				}
			}
		}
	}

__TERMINAL:
	return 0L;
}

//
//The following are the implementations of all command handler.
//The handler's name is the same as command.
//
static DWORD inputb(__CMD_PARA_OBJ* lpCmdObj)
{
	WORD           wInputPort         = 0;
	UCHAR          bt                 = 0;
	DWORD          dwInputPort        = 0L;
	BYTE           strBuffer[15]      = {0};

	if(NULL == lpCmdObj)  //Parameter check.
		return IOCTRL_TERMINAL;

	if(lpCmdObj->byParameterNum < 2)  //Two small parameters.
	{
		PrintLine("Please input the port where to read.");
		return IOCTRL_NORMAL;
	}
	if(!Str2Hex(lpCmdObj->Parameter[1],&dwInputPort))  //Convert the string value to hex.
	{
		PrintLine("Invalid port value.");
		return IOCTRL_NORMAL;
	}

	wInputPort = LOWORD(dwInputPort);  //Now,wInputPort contains the port number.
	ReadByteFromPort(&bt,wInputPort);  //Read one byte from port.

	dwInputPort =  0;
	dwInputPort += bt;

	strBuffer[0] = ' ';
	strBuffer[1] = ' ';
	strBuffer[2] = ' ';
	strBuffer[3] = ' ';

	Hex2Str(dwInputPort,&strBuffer[4]);
	PrintLine(strBuffer);    //Print out the byte.

	return 0L;
}

static DWORD inputw(__CMD_PARA_OBJ* lpCmdObj)
{
	WORD           wInputPort         = 0;
	WORD           wr                 = 0;
	DWORD          dwInputPort        = 0L;
	BYTE           strBuffer[15]      = {0};

	if(NULL == lpCmdObj)  //Parameter check.
		return IOCTRL_TERMINAL;

	if(lpCmdObj->byParameterNum < 2)  //Two small parameters.
	{
		PrintLine("Please input the port where to read.");
		return IOCTRL_NORMAL;
	}
	if(!Str2Hex(lpCmdObj->Parameter[1],&dwInputPort))  //Convert the string value to hex.
	{
		PrintLine("Invalid port value.");
		return IOCTRL_NORMAL;
	}

	wInputPort = LOWORD(dwInputPort);  //Now,wInputPort contains the port number.
	ReadWordFromPort(&wr,wInputPort);  //Read one byte from port.

	dwInputPort =  0;
	dwInputPort += wr;

	strBuffer[0] = ' ';
	strBuffer[1] = ' ';
	strBuffer[2] = ' ';
	strBuffer[3] = ' ';

	Hex2Str(dwInputPort,&strBuffer[4]);
	PrintLine(strBuffer);    //Print out the byte.

	return 0L;
}

//
//The implementation of inputd.
//

static DWORD inputd(__CMD_PARA_OBJ* lpParamObj)
{
	DWORD                dwVal              = 0L;
	WORD                 wPort              = 0;
	BYTE                 strBuffer[15];

	if(NULL == lpParamObj)    //Parameter check.
		return IOCTRL_TERMINAL;

	if(lpParamObj->byParameterNum < 2)    //Not enough parameters.
	{
		PrintLine("Please input the port value.");
		return IOCTRL_NORMAL;
	}

	if(!Str2Hex(lpParamObj->Parameter[1],&dwVal))  //Incorrect port value.
	{
		PrintLine("Please input the port correctly.");
		return IOCTRL_NORMAL;
	}

	wPort = LOWORD(dwVal);

#ifdef __I386               //Read data from port.
	__asm{
		push eax
		push edx
		mov dx,wPort
		in eax,dx
		mov dwVal,eax
		pop edx
		pop eax
	}
#elif
#endif

	strBuffer[0] = ' ';
	strBuffer[1] = ' ';
	strBuffer[2] = ' ';
	strBuffer[3] = ' ';

	Hex2Str(dwVal,&strBuffer[4]);
	PrintLine(strBuffer);    //Print out the byte.

	return 0L;
}

static DWORD inputsb(__CMD_PARA_OBJ* lpCmdObj)
{
	PrintLine("inputsb is handled.");
	return 0L;
}

static DWORD inputsw(__CMD_PARA_OBJ* lpCmdObj)
{
	return 0L;
}

static DWORD outputb(__CMD_PARA_OBJ* lpCmdObj)
{
	UCHAR            bt         = 0;
	WORD             wPort      = 0;
	DWORD            dwPort     = 0;

	if(NULL == lpCmdObj)  //Parameter check.
		return IOCTRL_TERMINAL;

	if(lpCmdObj->byParameterNum < 3)  //Not enough parameters.
	{
		PrintLine("Please input the port and value.");
		return IOCTRL_NORMAL;
	}
	if(!Str2Hex(lpCmdObj->Parameter[1],&dwPort))

⌨️ 快捷键说明

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