-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Task 3, libSMCE console #51
base: master
Are you sure you want to change the base?
Conversation
Added SMCE_Client, a terminal interface for libSMCE.
Implemented a way to handle more then one input, to make it possible for example sending message
NOT WORKING! KNOWN BUG.
Move SMCE_Client to its own folder, created a CMakeLists that installs SMCE_Client.exe and copys the SMCE.dll from the path of enviroment variable SMCE_ROOT.
Fixed bugg with recompile causing thread to crash. Added termcolor library to set color for uart messages. Added mute for uart messages.
Added functionality to set Arduino root folder Added functionality to set SMCE_RESOURCE at runtime
Added so incoming uart messages can be written to a file instead of console. Set at start by setting the start argument -u or --file to true.
Codecov Report
@@ Coverage Diff @@
## master #51 +/- ##
===========================================
+ Coverage 40.08% 63.26% +23.18%
===========================================
Files 33 82 +49
Lines 1497 2986 +1489
===========================================
+ Hits 600 1889 +1289
- Misses 897 1097 +200
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code is barely readable; reformat it (ClangFormat is your friend).
Also the general conditional complexity in main
tends to be overwhelming; try factorizing it out using lookup tables, functions, etc...
@@ -129,7 +129,7 @@ target_sources (HostUDD PRIVATE | |||
) | |||
|
|||
|
|||
add_library (objSMCE OBJECT) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Superfluous change
@@ -153,6 +153,7 @@ target_sources (objSMCE PRIVATE | |||
include/SMCE/SketchConf.hpp | |||
include/SMCE/internal/BoardDeviceSpecification.hpp | |||
) | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Superfluous change
client/CMakeLists.txt
Outdated
) | ||
FetchContent_MakeAvailable(Termcolor Lyra) | ||
|
||
include_directories(${PROJECT_SOURCE_DIR}/src) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Never use global include_directories
; see target_include_directories
for a pure alternative
target_include_directories (${PROJECT_NAME} PUBLIC | ||
"${termcolor_SOURCE_DIR}/include/termcolor" | ||
"${lyra_SOURCE_DIR}/include/lyra" | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would be incredibly surprised that the termcolor::termcolor
and bfg::Lyra
targets don't already provide those directories in their interface properties
client/README.md
Outdated
To be able to build SMCE_client, the enviroment variable SMCE_ROOT needs to point to a current installed release of libSMCE. | ||
These can be found under releases on git. Or it can be build directly from the source code with the commands below. | ||
These should be ran in the libSMCE folder. | ||
```shell | ||
cmake -S . -B build/ | ||
cmake --build build/ | ||
cmake --build build/ --config Release | ||
cmake --install build/ --prefix <path to installation folder> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These instructions are both wrong and misplaced; this README is in a subfolder of the libSMCE project, so it stands to reason that readers have already read the top-level README
client/SMCE_Client.cpp
Outdated
|
||
}else if (input.starts_with("-ra ")){ | ||
bool read = true; | ||
int index_pin = stoi(input.substr(3)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const
-incorrect
client/SMCE_Client.cpp
Outdated
|
||
}else if (input.starts_with("-rd ")){ | ||
bool read = true; | ||
int index_pin = stoi(input.substr(3)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const
-incorrect
client/src/UartToFile.cpp
Outdated
@@ -0,0 +1,28 @@ | |||
#include <UartToFile.hpp> | |||
#include <ctime> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use <chrono>
's stuff
client/src/UartToFile.cpp
Outdated
#include <fstream> | ||
#include <iostream> | ||
|
||
using namespace std; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you are trying to give me a heart attack, this is definitely the way to go
client/src/UartToFile.cpp
Outdated
int uart_to_file(std::string message, std::string path){ | ||
ofstream file; | ||
file.open(path, std::ios_base::app); | ||
file << get_time() +": " +message + "\n"; | ||
file.close(); | ||
return 0; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opening/closing a file every time you need to write to it should be a definition of inefficiency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Focus on parting everything into components, just constantly ask yourself, "how would I test this", "could someone reuse this code as a library" and stuff like that.
- Sketch path: Relative or absolute path to the sketch to run | ||
|
||
### Start arguments | ||
-f,--fqbn <fqbn> -> <fqbn> = Fully qualified board name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just a note in general, fqbn is basically deprecated, so I would default this parameter
client/src/UartToFile.cpp
Outdated
std::string get_time(){ | ||
time_t currentTime; | ||
struct tm *localTime; | ||
|
||
time( ¤tTime ); | ||
localTime = localtime( ¤tTime ); | ||
|
||
int hour = localTime->tm_hour; | ||
int min = localTime->tm_min; | ||
int sec = localTime->tm_sec; | ||
return(to_string(hour)+":"+to_string(min)+":"+to_string(sec)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this use the way better library:
https://en.cppreference.com/w/cpp/chrono#Clocks
client/src/UartToFile.cpp
Outdated
#include <fstream> | ||
#include <iostream> | ||
|
||
using namespace std; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using std is a bad practice
client/src/UartToFile.cpp
Outdated
int uart_to_file(std::string message, std::string path){ | ||
ofstream file; | ||
file.open(path, std::ios_base::app); | ||
file << get_time() +": " +message + "\n"; | ||
file.close(); | ||
return 0; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a highly specifically named module and a highly specifically named function name even though all it does write to a file. I would generalize this, also, this is one of the cases where you might want to keep the file open for the duration of the program as constantly opening a file is not very nice.
client/SMCE_Client.cpp
Outdated
void print_help(const char* argv0){ | ||
std::cout << "Usage: " << argv0 << " <fully-qualified-board-name> <path-to-sketch>" << std::endl; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stuff like this can just be in the main function
client/SMCE_Client.cpp
Outdated
print_menu(); | ||
|
||
}else if (input == "-p"){ //pause or resume | ||
if(!suspended){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better read the state from the board instead of keeping track of it yourself
client/SMCE_Client.cpp
Outdated
}else if (input == "-rc"){ //recompile | ||
std::cout << "Recompiling.." << std::endl; | ||
t_lock.lock(); // aquire lock before recompiling, so uart_listener is forced to wait | ||
compile_and_start(sketch,toolchain,board,arduino_root_dir); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a function like this just makes things opaque imo, why not have a compile function and a start function that you just calls after each other? they dont need to be composed.
client/SMCE_Client.cpp
Outdated
std::cout << "Complete" << std::endl; | ||
|
||
}else if (input.starts_with("-m ")){ //send message on uart | ||
std::string message = input.substr(3); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
needless clone
client/SMCE_Client.cpp
Outdated
if(!apin.exists()){ | ||
std::cout << "Pin does not exist!" << std::endl; | ||
write=false; | ||
} | ||
if(!apin.can_write()){ | ||
std::cout << "Can't write to pin!" << std::endl; | ||
write=false; | ||
} | ||
if(write){ | ||
apin.write(value); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if () else if() else { ::write }
client/SMCE_Client.cpp
Outdated
if(value == 0){ | ||
apin.write(false); | ||
}else if(value == 1){ | ||
apin.write(true); | ||
}else{ | ||
std::cout << "Value must be 0 or 1 for digital pins" << std::endl; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tbh apin.write(value > 0), it works like this internally as well
client/SMCE_Client.cpp
Outdated
static std::atomic_bool mute_uart = false; | ||
static std::mutex t_lock; | ||
//Listen to the uart input from board, writes what it read to terminal | ||
void uart_listener(smce::VirtualUart uart,bool file_write,std::string path){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah as discussed, taking the VirtualUart by value and reusing it across recompilations is completely wrong and likely reads invalid memory
Focused on the smaller problems from the pull request review. Still has several bugs / changes that needs to be done.
}else if (input.starts_with("-rd ")){ | ||
bool read = true; | ||
int index_pin = stoi(input.substr(3)); | ||
}else if (!pin.can_read()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just because the board cannot read does not mean the user should not be able to see the value
client/SMCE_Client.cpp
Outdated
} | ||
if(!pin.can_read()){ | ||
}else if (!pin.can_read()) { | ||
std::cout << "Can't read from pin!" << std::endl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above
std::cout << "Value from pin " << index_pin << " is " << pin.read() << std::endl; | ||
} | ||
|
||
}else if (input == "-q"){ //power off and quit | ||
} else if (input == "-q") { // power off and quit | ||
std::cout << "Quitting..." << std::endl; | ||
run_threads = false; | ||
board.stop(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Board::stop
may fail
We are aware that the code is in need of refactoring, but we are not sure how we should go about it and also what to prioritize.