230 lines
7.4 KiB
C
230 lines
7.4 KiB
C
// *************Interpreter.c**************
|
|
// Students implement this as part of EE445M Lab 1,2,3,4,5,6
|
|
// high level OS user interface
|
|
// Solution to labs 1,2,3,4,5,6
|
|
// Runs on MSPM0
|
|
// Jonathan W. Valvano 12/29/2025, valvano@mail.utexas.edu
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include "../RTOS_Labs_common/OS.h"
|
|
#include "../RTOS_Labs_common/ST7735_SDC.h"
|
|
#include "../inc/ADC.h"
|
|
#include "../RTOS_Labs_common/RTOS_UART.h"
|
|
#include "../RTOS_Labs_common/LPF.h"
|
|
#include "../RTOS_Labs_common/eDisk.h"
|
|
#include "../RTOS_Labs_common/eFile.h"
|
|
#include "../RTOS_Labs_common/heap.h"
|
|
#include "../RTOS_Labs_common/Interpreter.h"
|
|
|
|
void Lab4(void); // Lab 4 performance data
|
|
void DFT(void); // Discrete Fourier Transform
|
|
void Robot(void); // Robot thread
|
|
|
|
extern Sema4_t LCDFree;
|
|
unsigned int currentDirectory = 0;
|
|
|
|
#define MAX_CMD_LEN 16
|
|
|
|
// readLine reads a line from UART into buf (up to maxLen-1 chars + null terminator)
|
|
// Echoes printable characters, handles backspace, terminates on carriage return
|
|
static void readLine(char *buf, int maxLen){
|
|
int pos = 0;
|
|
while(1){
|
|
char c = UART_InChar();
|
|
if(c == '\r') break;
|
|
if(c == '\b' || c == 127){ // backspace or DEL
|
|
if(pos > 0){
|
|
pos--;
|
|
buf[pos] = 0;
|
|
UART_OutString("\b \b");
|
|
}
|
|
}else if(c >= ' ' && c <= '~'){ // printable ASCII only
|
|
if(pos < maxLen - 1){
|
|
buf[pos] = c;
|
|
pos++;
|
|
UART_OutChar(c);
|
|
}
|
|
}
|
|
}
|
|
buf[pos] = 0;
|
|
UART_OutString("\n");
|
|
}
|
|
|
|
// findArg returns pointer to first character after the first space in line,
|
|
// or 0 if no space found. Null-terminates the command portion.
|
|
static char* findArg(char *line){
|
|
for(int i = 0; line[i]; i++){
|
|
if(line[i] == ' '){
|
|
line[i] = 0;
|
|
return &line[i+1];
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// displayHelp prints all commands to the serial console
|
|
// Input: None
|
|
// Output: None
|
|
static void displayHelp(void){
|
|
UART_OutString("Basic RTOS interpreter commands:\n\n"
|
|
"format Formats the SDC (will lose EVERYTHING)\n\n"
|
|
"cd [directory ID] selects working directory, options are 0 or 1\n\n"
|
|
"ls prints name and contents of working directory\n\n"
|
|
"show [filename] prints contents of file in working directory\n\n"
|
|
"delete [filename] deletes the file named\n\n"
|
|
"Lab4 executes Lab4()\n\n"
|
|
"robot launches the Robot() thread\n\n"
|
|
"dft displays dft data\n\n"
|
|
"clear clears the terminal output and LCD display\n\n"
|
|
"? shows this help menu\n\n");
|
|
}
|
|
|
|
// Takes user input through serial console
|
|
// Loops infinitely, processing commands
|
|
void Interpreter(void){
|
|
char line[MAX_CMD_LEN];
|
|
char *arg;
|
|
while(1){
|
|
UART_OutString("\n> ");
|
|
readLine(line, MAX_CMD_LEN);
|
|
|
|
if(line[0] == 0) continue;
|
|
|
|
arg = findArg(line);
|
|
|
|
switch(line[0]){
|
|
case '?':
|
|
displayHelp();
|
|
break;
|
|
|
|
case 'f': // format
|
|
UART_OutString("Formatting disk...\n");
|
|
OS_bWait(&LCDFree);
|
|
if(eFile_Format()){
|
|
OS_bSignal(&LCDFree);
|
|
UART_OutString("Format failed\n");
|
|
}else if(eFile_Mount()){
|
|
OS_bSignal(&LCDFree);
|
|
UART_OutString("Format complete, mount failed\n");
|
|
}else{
|
|
OS_bSignal(&LCDFree);
|
|
UART_OutString("Format complete\n");
|
|
}
|
|
break;
|
|
|
|
case 'c': // cd or clear
|
|
if(line[1] == 'd'){ // cd
|
|
if(!arg || (arg[0] != '0' && arg[0] != '1') || arg[1] != 0){
|
|
UART_OutString("Usage: cd 0 or cd 1\n");
|
|
}else{
|
|
unsigned char dirID = arg[0] - '0';
|
|
OS_bWait(&LCDFree);
|
|
if(eFile_SelectDirectory(dirID)){
|
|
OS_bSignal(&LCDFree);
|
|
UART_OutString("cd failed\n");
|
|
}else{
|
|
OS_bSignal(&LCDFree);
|
|
currentDirectory = dirID;
|
|
}
|
|
}
|
|
}else if(line[1] == 'l'){ // clear
|
|
UART_OutString("\033[2J\033[H");
|
|
OS_bWait(&LCDFree);
|
|
ST7735_FillScreen(0);
|
|
OS_bSignal(&LCDFree);
|
|
}else{
|
|
UART_OutString("Unknown command. Enter ? for help.\n");
|
|
}
|
|
break;
|
|
|
|
case 'l': // ls or Lab4
|
|
if(line[1] == 's'){ // ls
|
|
OS_bWait(&LCDFree);
|
|
if(eFile_DOpen("")){
|
|
OS_bSignal(&LCDFree);
|
|
UART_OutString("ls failed to open directory\n");
|
|
}else{
|
|
char *name;
|
|
unsigned long size;
|
|
unsigned int num = 0;
|
|
unsigned long total = 0;
|
|
UART_OutString("\nContents of Directory ");
|
|
UART_OutUDec(currentDirectory);
|
|
UART_OutString("\n\n");
|
|
while(eFile_DirNext(&name, &size) == 0){
|
|
UART_OutString("Filename = "); UART_OutString(name); UART_OutString(" ");
|
|
UART_OutString("Size (bytes)= "); UART_OutUDec(size); UART_OutString("\n");
|
|
total += size;
|
|
num++;
|
|
}
|
|
UART_OutString("\nNumber of Files = "); UART_OutUDec(num); UART_OutString("\n");
|
|
UART_OutString("Number of Bytes = "); UART_OutUDec(total); UART_OutString("\n");
|
|
eFile_DClose();
|
|
OS_bSignal(&LCDFree);
|
|
}
|
|
}else{
|
|
UART_OutString("Unknown command. Enter ? for help.\n");
|
|
}
|
|
break;
|
|
|
|
case 'L': // Lab4
|
|
UART_OutString("Lab4 data\n");
|
|
Lab4();
|
|
break;
|
|
|
|
case 's': // show
|
|
if(!arg || arg[0] == 0){
|
|
UART_OutString("Usage: show [filename]\n");
|
|
}else{
|
|
OS_bWait(&LCDFree);
|
|
if(eFile_ROpen(arg)){
|
|
OS_bSignal(&LCDFree);
|
|
UART_OutString("File not found\n");
|
|
}else{
|
|
char data; int status;
|
|
UART_OutString("\n--- Contents of "); UART_OutString(arg); UART_OutString(" ---\n");
|
|
do{
|
|
status = eFile_ReadNext(&data);
|
|
if(status == 0) UART_OutChar(data);
|
|
}while(status == 0);
|
|
eFile_RClose();
|
|
OS_bSignal(&LCDFree);
|
|
UART_OutString("--- End of file ---\n");
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'd': // delete or dft
|
|
if(line[1] == 'e'){ // delete
|
|
if(!arg || arg[0] == 0){
|
|
UART_OutString("Usage: delete [filename]\n");
|
|
}else{
|
|
OS_bWait(&LCDFree);
|
|
if(eFile_Delete(arg)){
|
|
OS_bSignal(&LCDFree);
|
|
UART_OutString("Delete failed\n");
|
|
}else{
|
|
OS_bSignal(&LCDFree);
|
|
UART_OutString("Deleted\n");
|
|
}
|
|
}
|
|
}else if(line[1] == 'f'){ // dft
|
|
UART_OutString("DFT data\n");
|
|
DFT();
|
|
}else{
|
|
UART_OutString("Unknown command. Enter ? for help.\n");
|
|
}
|
|
break;
|
|
|
|
case 'r': // robot
|
|
UART_OutString("Launching Robot\n");
|
|
OS_AddThread(&Robot, 128, 1);
|
|
break;
|
|
|
|
default:
|
|
UART_OutString("Unknown command. Enter ? for help.\n");
|
|
break;
|
|
}
|
|
}
|
|
}
|