-
Notifications
You must be signed in to change notification settings - Fork 16
Conversation
…for jlinkarm location, clockspeed, and device family. Also some interface cleanup for loading libraries. Linux and OS X will not work with this commit due to statically looking up the .dll files for highlevel and nrfjprog library. This will be fixed shortly.
This reverts commit 4c55a28.
This reverts commit 118d2d7.
# Conflicts: # src/highlevel.cpp # src/highlevel.h # src/highlevel_common.h # src/highlevel_helpers.h # src/platform/linux/libraryloader.cpp # src/platform/osx/libraryloader.cpp
Add timestamps to get an idea on when data is produced on the device.
nrfjprog/include/nrfjprog.h
Outdated
#define micro_version (1) | ||
|
||
|
||
enum NrfjprogErrorCodesType { |
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.
What's wrong with indentation here?
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 file included from nRFjprog. No need to review it.
src/rtt_batons.h
Outdated
uint32_t result; | ||
nrfjprogdll_err_t lowlevelError; | ||
|
||
uv_work_t *req; |
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.
std::unique_ptr would be much safer and simpler.
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.
Will consider it.
src/utility/conversion.cpp
Outdated
|
||
if (justMicrosecondPart) | ||
{ | ||
duration = duration % 1000; |
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 seems to be only the least significant 3 decimal digits of the microseconds part.
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.
That is correct. If you want only the microseconds, you call this function with the last parameter set to true. This is mostly for occasions where you might want to indicate the time as x min, yy s, zzz ms, æææ us
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 don't see such use-case, and by human understanding I'd expect duration % 1e6
as result.
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 agree that the usecase is not there anymore. Will remove this code as well as a couple of conversion functions not needed anymore.
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.
Looks as incomprehensible as the existing nrfjprog-js
code (which is not a bad thing 😉).
LGTM, specially as there are automated tests 👍
Still needs documentation 😞 but that can be done at a later PR.
nrfjprog/include/nrfjprog.h
Outdated
|
||
enum NrfjprogErrorCodesType { | ||
|
||
Success = 0, // Requested operation (operations) were successfully completed. |
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.
Check whitespace. Looks funky.
src/nrfjprogwrapper.cpp
Outdated
return errorcode_t::CouldNotLoadDLL; | ||
} | ||
|
||
if (!load_func_ptr(&dll_function->dll_version, "NRFJPROG_dll_version", nrfJproglibraryHandle)) { |
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.
Since the return value of all these if
s is the same, this might look better as a big chain of newline-separated ||
statements
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.
It would make it slightly harder to debug as it is harder to set break points. Other than that it is a good idea. Will consider into it.
src/rtt.cpp
Outdated
|
||
void RTT::logCallback(const char *msg) | ||
{ | ||
log(msg); |
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.
Wait, what does this do? Just call log()
? Does it work despite logCallback
receiving *msg
and log
receiving std::string
? Couldn't the calls to logCallback
just be renamed into log
???
😕
src/highlevel.cpp
Outdated
CallFunction(info, p, e, nullptr, true); | ||
} | ||
|
||
#include "rtt.h" |
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.
#include
s should be hoisted to the top of the file
src/rtt.cpp
Outdated
RETURN_ERROR_ON_FAIL(dll_function.rtt_start(), RTTCouldNotStartRTT); | ||
|
||
|
||
while (true) { |
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 loop is polling. Plz consider adding something like sleep(25)
.
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.
That would sleep 25 seconds.
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.
s/sleep/usleep
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.
Will fix.
src/rtt.cpp
Outdated
|
||
RETURN_ERROR_ON_FAIL(dll_function.rtt_read_channel_count(&downChannelNumber, &upChannelNumber), RTTCouldNotGetChannelInformation); | ||
|
||
for(uint32_t i = 0; i < downChannelNumber; ++i) |
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 uint32_t
to iterate channel numbers? Are we having more than 65K channels on a RTT? LOL 🤣
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.
uint32_t
covers slightly more then 65K, is it not, or what really is the issue? If the external library uses that type to return channel number, then let it be.
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, as @bencefr also mentions, due to rtt_read_channel_count utilize a uint32_t
. To avoid the loops producing compile time warnings, it is recommended to use the same type in the loop.
|
||
releasenRFjprog(); | ||
|
||
libraryLoaded = false; |
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.
There might be an edge case / race condition here. Are there any instances where cleanup might occur twice in quick succession (in a shorter time than it takes for the DLL stuff to unload)?
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.
You are right in that race conditions may occur. The current implementation expects that the user is nice and never calls a function before the previous callback was completed. Will consider a fix for this.
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.
Have added an execution mutex that locks with a timeout of 10 seconds on all function calls. All race conditions should be handled by that. Two tests were written to test this, and one of them confirms that the guards work by first calling start, and then call read three times in a row. With previous implementation, the reads would return with an error that rtt was not started. Currently they return without error.
Attempting to hit the 10 second timeout for the mutex proved harder. Even with 1M calls to read in a row as fast as possible, you would never get an error. But I have implemented the same functionality for nRFjprog, and when I attempt to program multiple times as fast as possible, the timeout triggers. This can be seen in __tests__/racecondition.test.js
src/rtt_batons.h
Outdated
#include "rtt.h" | ||
#include "rtt_helpers.h" | ||
|
||
#define RTTBATON_CONSTRUCTOR(BatonType, name, returnParameterCount) BatonType() : RTTBaton(returnParameterCount, 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.
I don't think that this macro serves any purpose, besides it also changes order of arguments.
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.
The only reason this has survived is due to initially wanting to keep it as similar to the highlevel implementation as possible as well as pc-ble-driver-js, but it is redundant here, and I will remove it. Will also consider removing it in highlevel implementation as well.
src/rtt_batons.h
Outdated
#include "rtt_helpers.h" | ||
|
||
#define RTTBATON_CONSTRUCTOR(BatonType, name, returnParameterCount) BatonType() : RTTBaton(returnParameterCount, name) {} | ||
#define RTTBATON_DESTRUCTOR(BatonType) ~BatonType() |
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.
Not used.
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.
Will remove.
src/rtt_batons.h
Outdated
bool hasControlBlockLocation; | ||
uint32_t controlBlockLocation; | ||
|
||
std::vector<ChannelInfo *> upChannelInfo; |
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 vectors never seem to be freed, the contents of them I mean. Usage of smart pointers are encouraged.
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.
Will consider it.
src/rtt.cpp
Outdated
while (true) { | ||
bool controlBlockFound = false; | ||
RETURN_ERROR_ON_FAIL(dll_function.rtt_is_control_block_found(&controlBlockFound), RTTCouldNotCallFunction); | ||
std::chrono::high_resolution_clock::time_point attemptedStartupTime = std::chrono::high_resolution_clock::now(); |
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.
Only used if controlBlockFound is false. Move it after break condition along with a sensible sleep.
{ | ||
if (baton->returnFunction != nullptr) | ||
{ | ||
std::vector<v8::Local<v8::Value> > vector = baton->returnFunction(baton); |
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 variable names matching standard typenames I don't suggest in general, misleading to 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.
Will fix.
src/rtt.cpp
Outdated
return RTTSuccess; | ||
}; | ||
|
||
rtt_return_function_t r = [&] (RTTBaton *b) -> returnType { |
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.
returnType
might be a magic that the compiler solves here, but does not allow a readable code. Also again vector
is a name that I would avoid using.
return baton; | ||
}; | ||
|
||
rtt_execute_function_t e = [&] (RTTBaton *b) -> RTTErrorcodes_t { |
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.
rtt_execute_function_t e = [&] (RTTStartBaton *baton)
, so you don't need static_cast
which should not even exist in C++.
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 suggested change results in a compile error, so will keep current implementation.
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 see I was wrong, since the function type requires RTTBaton*, however there are better casts probably for this case. Never mind.
src/rtt.cpp
Outdated
return started; | ||
} | ||
|
||
NAN_METHOD(RTT::Start) |
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.
Waaaaay too long function, split it up, especially the execute part.
src/rtt.cpp
Outdated
for (auto element : baton->downChannelInfo) | ||
{ | ||
Nan::Set(downChannelInfo, Convert::toJsNumber(i), element->ToJs()); | ||
i++; |
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++ is bad practice, no matter how long you can talk about compiler magic. Get used to use ++i.
In my opinion - in the light of the threading issues - it is a bad approach to lock everything out so brutally. Especially that the library load/unload is also part of this (however it was much much more unsafe before). The problem is that we are tackling a problem here which is not the context of this feature PR. Here's what has to be done:
|
In principle, I agree with you @bencefr, there are, however, some other considerations to make.
|
|
index.js
Outdated
@@ -44,3 +44,4 @@ | |||
}); | |||
|
|||
module.exports = instance; | |||
module.exports.RTT = nRFjprog.RTT; |
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.
How about changing this to module.exports.RTT = nRFjprog.RTT()
?
I'd prefer the module exporting a RTT singleton, instead of a RTT constructor.
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.
Agreed. Will fix.
|
|
Good job on the code&review all, looks good. |
Added RTT.
Documentation is not done, will be a separate PR as soon as it is done.