📄 prompt.c
字号:
/*******************************************************************************
*
* Filename: prompt.c
*
* Instantiation of the interactive loader functions.
*
* Revision information:
*
* 20AUG2004 kb_admin initial creation
* 20SEP2004 kb_admin adapted for RAM monitor functionality
*
* BEGIN_KBDD_BLOCK
* No warranty, expressed or implied, is included with this software. It is
* provided "AS IS" and no warranty of any kind including statutory or aspects
* relating to merchantability or fitness for any purpose is provided. All
* intellectual property rights of others is maintained with the respective
* owners. This software is not copyrighted and is intended for reference
* only.
* END_BLOCK
******************************************************************************/
#include "debug_io.h"
#include "at91rm9200_lowlevel.h"
#include "p_string.h"
#include "xmodem.h"
#include "eeprom.h"
#include "prompt.h"
#include "flash.h"
/* ****************************** GLOBALS *************************************/
/* ********************** PRIVATE FUNCTIONS/DATA ******************************/
static char inputBuffer[MAX_INPUT_SIZE];
static int buffCount;
// argv pointer are either NULL or point to locations in inputBuffer
static char *argv[MAX_COMMAND_PARAMS];
static char backspaceString[] = {0x8, ' ', 0x8, 0};
/*
* .KB_C_FN_DEFINITION_START
* void RestoreSpace(int)
* This private function restores NULL characters to spaces in order to
* process the remaining args as a string. The number passed is the argc
* of the first entry to begin restoring space in the inputBuffer.
* .KB_C_FN_DEFINITION_END
*/
static void RestoreSpace(int startArgc) {
char *cPtr;
for (startArgc++; startArgc < MAX_COMMAND_PARAMS; startArgc++) {
if ((cPtr = argv[startArgc]))
*(cPtr - 1) = ' ';
}
}
/*
* .KB_C_FN_DEFINITION_START
* int BreakCommand(char *)
* This private function splits the buffer into separate strings as pointed
* by argv and returns the number of parameters (< 0 on failure).
* .KB_C_FN_DEFINITION_END
*/
static int BreakCommand(char *buffer) {
int pCount, cCount, state;
state = pCount = 0;
p_bzero((char*)argv, sizeof(argv));
for (cCount = 0; cCount < MAX_INPUT_SIZE; ++cCount) {
if (!state) {
/* look for next command */
if (!p_IsWhiteSpace(buffer[cCount])) {
argv[pCount++] = &buffer[cCount];
state = 1;
} else {
buffer[cCount] = 0;
}
} else {
/* in command, find next white space */
if (p_IsWhiteSpace(buffer[cCount])) {
buffer[cCount] = 0;
state = 0;
}
}
if (pCount >= MAX_COMMAND_PARAMS) {
return (-1);
}
}
return (pCount);
}
/*
* .KB_C_FN_DEFINITION_START
* void ParseCommand(char *)
* This private function executes matching functions.
* .KB_C_FN_DEFINITION_END
*/
static void ParseCommand(char *buffer) {
int argc;
if ((argc = BreakCommand(buffer)) < 1) {
return ;
}
/* all commands listed here are reflected in the help section */
switch (argv[0][0]) {
case 'C':
case 'c': // "c <to> <from> <size in bytes>"
// copy memory
{
char *to, *from;
unsigned size;
if (argc > 3) {
p_ASCIIToHex(argv[1], (unsigned*)&to);
p_ASCIIToHex(argv[2], (unsigned*)&from);
p_ASCIIToHex(argv[3], (unsigned*)&size);
p_memcpy(to, from, size);
}
}
break;
case 'E':
case 'e': // "e <address>"
// execute at address
{
void (*execAddr)(void);
if (argc > 1) {
p_ASCIIToHex(argv[1], (unsigned*)&execAddr);
(*execAddr)();
}
}
break;
case 'f':
case 'F': // "f <operation> <value> ..
// flash operations
// "f e" erase flash chip
// "f e <from> | <to>" erase sectors by address
// "f p <f_addr> <src_addr> <size>" program flash
{
char opChar;
unsigned startAddr, endAddr, srcAddr, size;
if (argc < 2)
break;
opChar = *argv[1];
switch (opChar) {
case 'e': /* erase flash chip */
case 'E':
if (argc < 3)
EraseFlashChip();
else {
p_ASCIIToHex(argv[2], &startAddr);
endAddr = startAddr + 1;
if (argc > 3)
p_ASCIIToHex(argv[3],
&endAddr);
EraseFlashSector(startAddr,
endAddr);
}
break;
case 'p': /* program flash */
case 'P':
if (argc < 5) {
DebugPrint("Missing parameter");
break;
}
p_ASCIIToHex(argv[2], &startAddr);
p_ASCIIToHex(argv[3], &srcAddr);
p_ASCIIToHex(argv[4], &size);
ProgramFlash(startAddr, srcAddr, size);
break;
default:
DebugPrint("Operation not recognized");
}
}
break;
case 'm':
case 'M': // "m"
// display memory bus frequency
DebugPrintValue(GetMasterClockSpeed());
DebugPrint(" Hz");
break;
case 'p':
case 'P': // "p"
// display cpu frequency
DebugPrintValue(GetProcessorClockSpeed());
DebugPrint(" Hz");
break;
case 't':
case 'T': // "t <ee_addr> <src_data_addr> <size>
// program eeprom
{
unsigned eeAddr, srcAddr, size;
if (argc < 4) {
DebugPrint("Missing parameter");
break;
}
p_ASCIIToHex(argv[1], &eeAddr);
p_ASCIIToHex(argv[2], &srcAddr);
p_ASCIIToHex(argv[3], &size);
WriteEEPROM(eeAddr, (char*)srcAddr, size);
}
break;
case 'X':
case 'x': // "x <address>"
// download X-modem record at address
{
char *destAddr;
if (argc > 1) {
p_ASCIIToHex(argv[1], (unsigned*)&destAddr);
xmodem_rx(destAddr);
} else {
xmodem_rx(0);
}
}
break;
case '?':
case 'h':
case 'H':
DebugPrint(" Commands:\n\r\n\r");
DebugPrint("\tcopy memory\n\r");
DebugPrint("\t\tc <to> <from> <size>\n\r");
DebugPrint("\texecute at address\n\r");
DebugPrint("\t\te <address>\n\r");
DebugPrint("\terase flash chip\n\r");
DebugPrint("\t\tf e\n\r");
DebugPrint("\terase sectors defined by address range\n\r");
DebugPrint("\t\tf e <from> | <to>\n\r");
DebugPrint("\tprogram flash using memory range\n\r");
DebugPrint("\t\tf p <flash_addr> <data_src_addr> <size>\n\r");
DebugPrint("\tdisplay memory bus frequency\n\r");
DebugPrint("\t\tm\n\r");
DebugPrint("\tdisplay cpu frequency\n\r");
DebugPrint("\t\tp\n\r");
DebugPrint("\tprogram EEPROM using memory range\n\r");
DebugPrint("\t\tt <ee_addr> <src_data_addr> <size>\n\r");
DebugPrint("\tdownload x-modem record at address\n\r");
DebugPrint("\t\tx <address>\n\r");
DebugPrint("\treport x-modem status\n\r");
DebugPrint("\t\tx\n\r");
break;
default:
break;
}
DebugPrint("\n\r");
}
/*
* .KB_C_FN_DEFINITION_START
* void ServicePrompt(char)
* This private function process each character checking for valid commands.
* This function is only executed if the character is considered valid.
* Each command is terminated with NULL (0) or '\r'.
* .KB_C_FN_DEFINITION_END
*/
static void ServicePrompt(char p_char) {
if (p_char == '\r') {
p_char = 0;
}
if (p_char != 0x8) {
if (buffCount < MAX_INPUT_SIZE-1) {
inputBuffer[buffCount] = p_char;
++buffCount;
DebugPutc(p_char);
}
} else if (buffCount) {
/* handle backspace BS */
--buffCount;
inputBuffer[buffCount] = 0;
DebugPrint(backspaceString);
return ;
}
if (!p_char) {
DebugPrint("\n\r");
ParseCommand(inputBuffer);
p_bzero(inputBuffer, MAX_INPUT_SIZE);
buffCount = 0;
DebugPrint("\n\r>");
}
}
/* ************************** GLOBAL FUNCTIONS ********************************/
/*
* .KB_C_FN_DEFINITION_START
* void RAM_Monitor(void *inputFunction)
* This global function is the entry point for the RAM monitor. If the
* inputFunction pointer is NULL, the monitor input will be serviced from
* the uart. Otherwise, inputFunction is called to get characters which
* the monitor will parse.
* .KB_C_FN_DEFINITION_END
*/
void RAM_Monitor(int(*inputFunction)(char*)) {
char l_char;
int returnValue = 0;
p_bzero((void*)inputBuffer, sizeof(inputBuffer));
buffCount = 0;
if (!inputFunction) {
inputFunction = DebugGetchar;
}
DebugPrint("\n\r>");
while (returnValue >= 0)
if ((returnValue = ((*inputFunction)(&l_char))) > 0)
ServicePrompt(l_char);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -