Код процесса:
CODE
void vShellThread(HANDLE xPort) {
SHELL xShell = { xPort, xShellCommands };
char pcInputLine[SHELL_MAX_INPUT_LEN];
char *pcToken, *pcNextToken;
char *pcArgs[SHELL_MAX_ARGUMENTS + 1];
char *pcCmd;
uint32_t uiArgsCount = 0;
if (!xSerialIsOpen(xShell.xSerialPort))
assert(!"Serial port for shell not opened.");
// print shell header
xSerialPutString(xShell.xSerialPort, "Shell command interface v0.1.\n",
1000);
// set local echo enabled
xSerialSetEchoEnabled(xPort, pdTRUE);
while (pdTRUE) {
xSerialPutString(xShell.xSerialPort, "shell$ ", 1000);
if (xSerialGetLine(xShell.xSerialPort, pcInputLine,
SHELL_MAX_INPUT_LEN, 6000) != pdPASS) {
xSerialPutString(xShell.xSerialPort,
"\nERR: too long input line.\n", 1000);
//continue;
}
// get command
pcToken = strtok_m(pcInputLine, pcShellSeparators, &pcNextToken);
if (pcToken == NULL)
continue;
pcCmd = pcToken;
uiArgsCount = 0;
// get arguments
while (pcNextToken != NULL) {
pcToken = strtok_m(NULL, pcShellSeparators, &pcNextToken);
if (uiArgsCount > SHELL_MAX_ARGUMENTS) {
xSerialPutString(xShell.xSerialPort,
"\nERR: max arguments limit\n", 1000);
pcCmd = NULL;
break;
}
pcArgs[uiArgsCount++] = pcToken;
}
pcArgs[uiArgsCount] = NULL;
if (pcCmd != NULL) {
if (!prvShellExec(&xShell, pcCmd, uiArgsCount, pcArgs))
xSerialPutString(xPort,
"Unknown cmd. Type help for information.\n", 100);
}
xSerialPutString(xPort, "Unknown cmd. Type help for information.\n",
1000);
}
}
SHELL xShell = { xPort, xShellCommands };
char pcInputLine[SHELL_MAX_INPUT_LEN];
char *pcToken, *pcNextToken;
char *pcArgs[SHELL_MAX_ARGUMENTS + 1];
char *pcCmd;
uint32_t uiArgsCount = 0;
if (!xSerialIsOpen(xShell.xSerialPort))
assert(!"Serial port for shell not opened.");
// print shell header
xSerialPutString(xShell.xSerialPort, "Shell command interface v0.1.\n",
1000);
// set local echo enabled
xSerialSetEchoEnabled(xPort, pdTRUE);
while (pdTRUE) {
xSerialPutString(xShell.xSerialPort, "shell$ ", 1000);
if (xSerialGetLine(xShell.xSerialPort, pcInputLine,
SHELL_MAX_INPUT_LEN, 6000) != pdPASS) {
xSerialPutString(xShell.xSerialPort,
"\nERR: too long input line.\n", 1000);
//continue;
}
// get command
pcToken = strtok_m(pcInputLine, pcShellSeparators, &pcNextToken);
if (pcToken == NULL)
continue;
pcCmd = pcToken;
uiArgsCount = 0;
// get arguments
while (pcNextToken != NULL) {
pcToken = strtok_m(NULL, pcShellSeparators, &pcNextToken);
if (uiArgsCount > SHELL_MAX_ARGUMENTS) {
xSerialPutString(xShell.xSerialPort,
"\nERR: max arguments limit\n", 1000);
pcCmd = NULL;
break;
}
pcArgs[uiArgsCount++] = pcToken;
}
pcArgs[uiArgsCount] = NULL;
if (pcCmd != NULL) {
if (!prvShellExec(&xShell, pcCmd, uiArgsCount, pcArgs))
xSerialPutString(xPort,
"Unknown cmd. Type help for information.\n", 100);
}
xSerialPutString(xPort, "Unknown cmd. Type help for information.\n",
1000);
}
}
Код используемых функций:
CODE
signed portBASE_TYPE xSerialPutString(HANDLE xPort, char *pcString,
portTickType xBlockTime) {
while (*pcString != '\0') {
if (xSerialPutChar(xPort, *pcString++, xBlockTime) != pdPASS)
return pdFAIL;
}
return pdPASS;
}
portTickType xBlockTime) {
while (*pcString != '\0') {
if (xSerialPutChar(xPort, *pcString++, xBlockTime) != pdPASS)
return pdFAIL;
}
return pdPASS;
}
CODE
signed portBASE_TYPE xSerialPutChar(HANDLE xPort, const char cOutChar,
portTickType xBlockTime) {
USART_PORT *port = (USART_PORT*) xPort;
assert (xPort != NULL);
if (xQueueSend(port->xTransmitQueue, &cOutChar, xBlockTime) != pdPASS)
return pdFAIL;
USART_EnableIt(port->xHwPort, US_IER_TXRDY);
return pdPASS;
}
portTickType xBlockTime) {
USART_PORT *port = (USART_PORT*) xPort;
assert (xPort != NULL);
if (xQueueSend(port->xTransmitQueue, &cOutChar, xBlockTime) != pdPASS)
return pdFAIL;
USART_EnableIt(port->xHwPort, US_IER_TXRDY);
return pdPASS;
}
CODE
signed portBASE_TYPE xSerialGetLine(HANDLE xPort, char *pcDest,
uint32_t iMaxLen, portTickType xBlockTime) {
char c;
uint32_t len = 0;
while (xSerialGetChar(xPort, &c, xBlockTime) == pdPASS) {
if ((c != '\n') && (c != '\r') && (c != '\b')) {
if (++len == iMaxLen)
return pdFAIL;
*pcDest++ = c;
} else if ((c == '\b') && (len > 0)) {
pcDest--;
len--;
} else if (c == '\n') {
*pcDest = 0;
return pdPASS;
}
}
return pdFAIL;
}
uint32_t iMaxLen, portTickType xBlockTime) {
char c;
uint32_t len = 0;
while (xSerialGetChar(xPort, &c, xBlockTime) == pdPASS) {
if ((c != '\n') && (c != '\r') && (c != '\b')) {
if (++len == iMaxLen)
return pdFAIL;
*pcDest++ = c;
} else if ((c == '\b') && (len > 0)) {
pcDest--;
len--;
} else if (c == '\n') {
*pcDest = 0;
return pdPASS;
}
}
return pdFAIL;
}
CODE
signed portBASE_TYPE xSerialGetChar(HANDLE xPort, char *pcRxedChar,
portTickType xBlockTime) {
USART_PORT *port = (USART_PORT*) xPort;
assert(xPort != NULL);
if (!(port->uiOpened))
return pdFAIL;
if (xQueueReceive(port->xReciveQueue, pcRxedChar, xBlockTime) == pdPASS) {
if (port->uiEcho)
xSerialPutChar(xPort, *pcRxedChar, xBlockTime);
return pdPASS;
}
return pdFAIL;
}
portTickType xBlockTime) {
USART_PORT *port = (USART_PORT*) xPort;
assert(xPort != NULL);
if (!(port->uiOpened))
return pdFAIL;
if (xQueueReceive(port->xReciveQueue, pcRxedChar, xBlockTime) == pdPASS) {
if (port->uiEcho)
xSerialPutChar(xPort, *pcRxedChar, xBlockTime);
return pdPASS;
}
return pdFAIL;
}
Код прерывания:
CODE
void UART1_IrqHandler(void) {
portBASE_TYPE xHigerPrioritTaskWoken = pdFALSE;
prvSerialExchange(1, &xHigerPrioritTaskWoken);
portEND_SWITCHING_ISR(xHigerPrioritTaskWoken);
}
void prvSerialExchange(uint32_t iPortIndex,
portBASE_TYPE *xHigerPrioritTaskWoken) {
portBASE_TYPE status;
char cChar;
// get status
status = xSerial_ports[iPortIndex].xHwPort->US_CSR;
if ((status & US_CSR_TXRDY) == US_CSR_TXRDY) {
// transmit symbol
if (xQueueReceiveFromISR(xSerial_ports[iPortIndex].xTransmitQueue,
&cChar, xHigerPrioritTaskWoken) == pdTRUE) {
xSerial_ports[iPortIndex].xHwPort->US_THR = cChar;
// disable interrupt if nothing to send anymore
if (xQueueIsQueueEmptyFromISR(
xSerial_ports[iPortIndex].xTransmitQueue))
USART_DisableIt(xSerial_ports[iPortIndex].xHwPort,
UART_IER_TXRDY);
}
}
if ((status & US_CSR_RXRDY) == US_CSR_RXRDY) {
// receive symbol
cChar = xSerial_ports[iPortIndex].xHwPort->US_RHR;
xQueueSendFromISR(xSerial_ports[iPortIndex].xReciveQueue, &cChar, xHigerPrioritTaskWoken);
}
}
portBASE_TYPE xHigerPrioritTaskWoken = pdFALSE;
prvSerialExchange(1, &xHigerPrioritTaskWoken);
portEND_SWITCHING_ISR(xHigerPrioritTaskWoken);
}
void prvSerialExchange(uint32_t iPortIndex,
portBASE_TYPE *xHigerPrioritTaskWoken) {
portBASE_TYPE status;
char cChar;
// get status
status = xSerial_ports[iPortIndex].xHwPort->US_CSR;
if ((status & US_CSR_TXRDY) == US_CSR_TXRDY) {
// transmit symbol
if (xQueueReceiveFromISR(xSerial_ports[iPortIndex].xTransmitQueue,
&cChar, xHigerPrioritTaskWoken) == pdTRUE) {
xSerial_ports[iPortIndex].xHwPort->US_THR = cChar;
// disable interrupt if nothing to send anymore
if (xQueueIsQueueEmptyFromISR(
xSerial_ports[iPortIndex].xTransmitQueue))
USART_DisableIt(xSerial_ports[iPortIndex].xHwPort,
UART_IER_TXRDY);
}
}
if ((status & US_CSR_RXRDY) == US_CSR_RXRDY) {
// receive symbol
cChar = xSerial_ports[iPortIndex].xHwPort->US_RHR;
xQueueSendFromISR(xSerial_ports[iPortIndex].xReciveQueue, &cChar, xHigerPrioritTaskWoken);
}
}