generally Im not tagging helpers :) but I really need a help. thanks alot.
You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
shifting handling in matlab with for loop
12 views (last 30 days)
Show older comments
Hi guys, could anyone please instruct me how I can implement this function that I attached it down in matlab? exactly the if condition and bit left shifting and bitwise and in matlab..
here's my function in c++: ( Im not professionaly in matlab and would be appreciated for any help) ..this function gets two input, one is crcData which it's uint8_t(byte type), second is two bytes type (uint16_t)
thanks alot !
uint16_t calcCRC(uint8_t crcData, uint16_t crcReg)
{
uint8_t i;
for (i = 0; i < 8; i++)
{
if (((crcReg & 0x8000) >> 8) ^ (crcData & 0x80))
{
crcReg = (crcReg << 1) ^ CRC16_POLY;
}
else
{
crcReg = (crcReg << 1);
}
crcData <<= 1;
}
return crcReg;
}
5 Comments
Walter Roberson
on 7 Aug 2020
Why were you unable to use any of the three File Exchange Contributions I recommended earlier, or the Signal Processing Toolbox crc generation function that I linked to?
You appear to have special needs for your CRC, and until we understand why your needs are different than what are already available, we will not be able to provide you with an answer that works for your circumstances.
Jimmy cho
on 7 Aug 2020
Hi walter, yes I have visted what you attached me before but it didn't help, here Im calculating crc according to my chip requirements, it's not general formula like what you attached in previous crc links in order to calculate crc16 ..
here I just made the formulas according to what my hardware chip supports, so it would be really if could you help me to code this function in matlab code , appreciated.
Walter Roberson
on 7 Aug 2020
https://www.mathworks.com/help/comm/ref/crc.generator.html permits you to input your own polynomial.
Jimmy cho
on 8 Aug 2020
so how do I write by what you forwarded an equivalent code in matlab to what I've wrote in c++ ? thanks alot.
yes it seems the crc.generator make sense to what I've written in c++ but still not familiar with parametrs of it .. could you please help me how do I write the same crcCalc (that I wrote in c++) in matlab code by using what you forwarded? thanks
Answers (1)
Walter Roberson
on 8 Aug 2020
function crcReg = calcCRC(crcData, crcReg, CRC16_POLY)
for i = 0 : 7
if bitxor( bitshift( bitand(crcReg, 0x8000), -8), ...
bitand( crcData, 0x0080 ) )
crcReg = bitxor( bitshift(crcReg, 1), CRC16_POLY );
else
crcReg = bitshift(crcReg, 1);
end
crcData = bitshft(crcData, 1);
end
Are you sure about the formula? The result is always going to be even, because the shifts are not circular and the final shift will always be a left shift by 1 bit, which is always going to introduce a 0 bit at the end.
16 Comments
Jimmy cho
on 9 Aug 2020
Yup, the variable CRC16_POLY is CRC16_POLY =0x8005 and it's constant value ..not an input ..you can assume it's input but it's a constant input as CRC16_POLY =0x8005;
why would the result be always even? didn't frankly get you, once again maybe Im wrong ..but didn't get your point why the result would be always even
Walter Roberson
on 9 Aug 2020
function crcReg = calcCRC(crcData, crcReg,)
CRC16_POLY = 0x8005;
for i = 0 : 7
if bitxor( bitshift( bitand(crcReg, 0x8000), -8), ...
bitand( crcData, 0x0080 ) )
crcReg = bitxor( bitshift(crcReg, 1), CRC16_POLY );
else
crcReg = bitshift(crcReg, 1);
end
crcData = bitshift(crcData, 1);
end
Walter Roberson
on 9 Aug 2020
why would the result be always even?
What is the last operation done in the calculation? This:
crcData <<= 1;
According to https://docs.microsoft.com/en-us/cpp/cpp/left-shift-and-right-shift-operators-input-and-output?view=vs-2019
The left-shift operator causes the bits in shift-expression to be shifted to the left by the number of positions specified by additive-expression. The bit positions that have been vacated by the shift operation are zero-filled. A left shift is a logical shift (the bits that are shifted off the end are discarded, including the sign bit).
So <<= 1 would be a left shift by 1 bit, with the bottom bit filled with a 0. When you are using 2's complement representation, any number that has a least significant bit of 0 is an even number, including when the number is negative.
Your code never, under any circumstances, xor or or a value in after the final crcData <<= 1 that is done when i = 7, and the << operator is not a circular shift. Therefore we can be certain that after the code, the last bit of crcData will be 0.
Jimmy cho
on 10 Aug 2020
Edited: Jimmy cho
on 10 Aug 2020
@Walter Roberson I understand you, you're right ..but in my case Im calling that function from another function (attaching it down) and Im doing bitwise with checksum .. so at the end the result is OK and works fine.
my other function that I implemented in c++ is : (frankly I came from world of programming c/c++/java and not knowing much matlab (still newbie) .. generally not using matlab and just for first time and as "one time" I want to use matlab and will not use it again .. because all what I implement is with c/c++/java).
the other function that I call inside it the previous function is: its input is a string , array of chars ..
void deBin(const std::string& rx) {
unsigned int ByteConvertRxBuffer[35] = { 0 }; // starting array with size 35 which all its values are zero
uint8_t rxBuffer[35]; // starting array with size 35
size_t ireal = 0; //starting variable with 0 value
uint16_t checksum; //declaring variable
bool crcOK = false; //declaring boolean variable
uint8_t i;
CRC_INIT=0xFFFF;
checksum = CRC_INIT;
int byteSize=8;
for (size_t i = 0; i < rx.length(); i += byteSize) { //here I take every 8bit from my string input rx
char nibble[byteSize]; // this variable for storing 8bit that I extract from my rx string
for (int j = 0; j < byteSize; j++) nibble[j] = rx[i + j];
std::cout << valueOf(nibble); // storing the value of each Byte-8bit inside ByteConvertRxBuffer.
ByteConvertRxBuffer[ireal++] = valueOf(nibble); //valueof function I attached it down, it's take 8bit binary string that I extracted from rx and convert it to unsigned integer
if (i + byteSize != rx.length()) ;
}
for (int i = 0; i < countof(ByteConvertRxBuffer); i++)
{
rxBuffer[i] = ByteConvertRxBuffer[i];
}
for (i = 0; i < sizeof(rxBuffer); i++)
{
checksum = calcCRC(rxBuffer[i], checksum);
}
PacketIndex++;
if (checksum == 0)
{
disp(PacketIndex); %this is for displaying the current packetNumber that Im currently dealing with...may get more than one packet
crcOK = true; % your packet number PacketIndex is Valid
}
else
{
disp(PacketIndex);
crcOK = false;% your packet number PacketIndex is Valid
}
}
So I want to implement that function(deBin) in matlab in parallel to what I've done in c++,
I've done down this matlab code for implementing that function:
function boolean crcOK=deBin(const std::string& rx)
{
unsigned int ByteConvertRxBuffer(35)= { 0 }; // starting array with size 35 which all its values are zero
uint8_t rxBuffer(35); // starting an empty array with size 35
size_t ireal = 0;
uint16_t checksum;
bool crcOK = false;
uint8_t i;
CRC_INIT=0xFFFF;
checksum = CRC_INIT;
int byteSize=8;
for i = 0::i += byteSize:i < rx.length
{
char nibble[byteSize];
for (int j = 0 : j++ :j < byteSize) nibble(j) = rx(i + j); end //after it finishes 8 iterations then out from the current loop
std::cout << valueOf(nibble); // storing the value of each Byte-8bit inside ByteConvertRxBuffer by calling to other Function
ByteConvertRxBuffer(ireal++) = valueOf(nibble);
if (i + byteSize != rx.length()) ;
}
for (int i = 0: i++ : i < ByteConvertRxBuffer.length)
{
rxBuffer[i] = ByteConvertRxBuffer[i];
}
for (i = 0:i++: rxBuffer.length())
{
checksum = calcCRC(rxBuffer[i], checksum);
}
PacketIndex++;
if (checksum == 0)
{
disp(PacketIndex); %this is for displaying the packetNumber that Im currently dealing with...may get more than one packet
crcOK = true; % your packet number PacketIndex is Valid
}
else
{
disp(PacketIndex);
crcOK = false;% your packet number PacketIndex is Valid
}
}
that function above has a compilation error and wrong Outputs , may you please help me to implement correctly that function in matlab?! thanks for your help and appreciated your assistance for me.
the function valueOf I've done in matlab and it's : (this function works fine and compiles in matlab without errors)
function total=valueOf(substring)
byteSize = 8;
retChar = '\0';
total = uint8(0); % This variable is unsigned integer of 8 bit
counter = 1;
for k = byteSize : -1 : 0
if substring(k-1) == '1'
total = total + counter;
end
if substring(k-1) ~= ' '
counter = counter * 2;
end
end
Walter Roberson
on 10 Aug 2020
We have been telling you that MATLAB does not use { } for control flow. MATLAB uses { } for two purposes:
- To form the composite data structure known as cell arrays. If you see a list of literal values such as {'skidoo', 23} then that is creating a cell array
- To index composite data structures, primarily cell arrays but also string objects and table objects.
As far as MATLAB is concerned, your code
for (i = 0:i++: rxBuffer.length())
{
checksum = calcCRC(rxBuffer[i], checksum);
}
says that a for loop is to be created, and that the first statement inside the for loop is that a cell array should be created, and that the first element inside the cell array should be calculated by the expression
checksum = calcCRC(rxBuffer[i], checksum);
However, in MATLAB, you can never have an assignment ( = operator) in the middle of an expression [there is in one sense an exception for certain symbolic engine constructs that are coded inside character vectors or string objects.]
Refer to the function that you already coded, and see that there is no { } anywhere there: the flow of control is
if CONDITION
statements
end
By the way:
byteSize = 8;
for k = byteSize : -1 : 0
The first value of k would be 8, then 7, 6, 5, 4, 3, 2, 1, 0 (a total of 9 values)
if substring(k-1) == '1'
If substring has at least 7 elements, then the substring(k-1) would be valid when k = 8 where it would access substring(7); it would be valid for k = 7, k = 6, k = 5, k =4, k=3, k=2 where it would access substring(2-1) = substring(1) . Then when k = 1, the code would attempt to access substring(0) but that is not a valid MATLAB index. If somehow you managed to get through that, it would continue on to k = 0, where you would attempt to access substring(0-1) = substring(-1) and that is certainly not valid -- not even in C.
Is there a reason you are not using dec2bin() instead of your existing code?
Or you could use
function total = valueOf(substring)
total = sum((substring - '0') .* 2.^(length(substring)-1:-1:0));
Jimmy cho
on 10 Aug 2020
thanks for your assistance, the function valueOf is working fine for me I succeeded, but the problem is the implemenation of debBin(attached it down) that I've done in c++ but in matlab still getting confused and wrong /error compilation/outputs.
Appreciate in advance your help to fix my function implementation in matlab.
Matlab code for deBin that I implemented:
function boolean crcOK=deBin(const std::string& rx)
unsigned int ByteConvertRxBuffer(35)= { 0 }; %starting array with size 35 which all its %values are zero
uint8_t rxBuffer(35); % starting an empty array with size 35
size_t ireal = 0;
uint16_t checksum;
bool crcOK = false;
uint8_t i;
CRC_INIT=0xFFFF;
checksum = CRC_INIT;
int byteSize=8;
for i = 0: i += byteSize :i < rx.length
char nibble[byteSize];
for (int j = 0 : j++ :j < byteSize) nibble(j) = rx(i + j); end %after it finishes 8 iterations then out from the current loop
std::cout << valueOf(nibble); // storing the value of each Byte-8bit inside ByteConvertRxBuffer by calling to other Function
ByteConvertRxBuffer(ireal++) = valueOf(nibble);
if (i + byteSize != rx.length()) ;
for (int i = 0: i++ : i < ByteConvertRxBuffer.length)
rxBuffer(i) = ByteConvertRxBuffer(i);
for (i = 0:i++: rxBuffer.length())
{
checksum = calcCRC(rxBuffer(i), checksum);
}
PacketIndex++;
if (checksum == 0)
{
disp(PacketIndex); %this is for displaying the packetNumber that Im currently dealing with...may get more than one packet
crcOK = true; % your packet number PacketIndex is Valid
}
else
{
disp(PacketIndex);
crcOK = false;% your packet number PacketIndex is Valid
}
}
Walter Roberson
on 10 Aug 2020
for (i = 0:i++: rxBuffer.length())
{
checksum = calcCRC(rxBuffer(i), checksum);
}
Why are you trying to construct a cell array at that point? Why are you trying to do an assignment inside a cell array?
MATLAB never uses {} to indicate code block boundaries.
unsigned int ByteConvertRxBuffer(35)= { 0 }; %starting array with size 35 which all its %values are zero
In MATLAB, that command would be interpreted as
unsigned( 'int', 'ByteConvertRxBuffer(35)=', '{ 0 }' )
which would be an attempt to call a function named unsigned() with three arguments that are character vectors.
This is because MATLAB has "command function duality". When the first thing at the beginning of a MATLAB statement is a valid identifier, and then there is whitespace, and the next non-whitespace character is not a "(" or "=", then MATLAB interprets the result of the line up to the first not-quoted ";" as being a request to call a function named according to the identifier, passing in the whitespace-delimited parts as quoted character vectors.
Thus for example,
ls *.png
is the same thing as calling
ls('*.png')
and is not a request to multiply a variable named "ls" by something.
So every one of your lines such as
uint16_t checksum;
is being interpreted as a request to call a function, as-if you had coded
uint16_t('checksum')
It is unlikely you have defined any functions by those names. The only one you use which MATLAB has predefined is
char nibble[byteSize];
as indicated, that would be equivalent to calling
char('nibble[byteSize]')
which will just happen to give the result 'nibble[byteSize]'
All of which is a to say
MATLAB DOES NOT USE VARIABLE DECLARATIONS
in MATLAB, if you want a variable to have a particular size and type, then assign it a value of that size and type. Such as replacing
uint16_t checksum
with
checksum = uint16(0);
Jimmy cho
on 10 Aug 2020
I've re-updated my function but still not getting correct output in matlab, much is compilation error ..
here's the last edition of my function:
function boolean crcOK=deBin(const std::string& rx)
unsigned( 'int', 'ByteConvertRxBuffer(35)=', '{ 0 }' ); %starting array with size 35 which all its %values are zero
uint8_t rxBuffer(35); % starting an empty array with size 35
size_t ireal = 0;
checksum = uint16(0);;
bool crcOK = false;
uint8_t i;
CRC_INIT=0xFFFF;
checksum = CRC_INIT;
int byteSize=8;
for i = 0: i += byteSize :i < rx.length
char('nibble[byteSize]')
for (int j = 0 : j++ :j < byteSize) nibble(j) = rx(i + j); end %after it finishes 8 iterations then out from the current loop
std::cout << valueOf(nibble); // storing the value of each Byte-8bit inside ByteConvertRxBuffer by calling to other Function
ByteConvertRxBuffer(ireal++) = valueOf(nibble);
if (i + byteSize != rx.length()) ;
for (int i = 0: i++ : i < ByteConvertRxBuffer.length)
rxBuffer(i) = ByteConvertRxBuffer(i);
for (i = 0:i++: rxBuffer.length())
checksum = calcCRC(rxBuffer(i), checksum);
PacketIndex++;
if (checksum == 0)
disp(PacketIndex); %this is for displaying the packetNumber that Im currently dealing with...may get more than one packet
crcOK = true; % your packet number PacketIndex is Valid
else
disp(PacketIndex);
crcOK = false;% your packet number PacketIndex is Valid
end
end
regarding to your question:
for (i = 0:i++: rxBuffer.length())
{
checksum = calcCRC(rxBuffer(i), checksum);
}
Why are you trying to construct a cell array at that point? Why are you trying to do an assignment inside a cell array?
I want to loop over the rxBuffer on its values and at every value call calcCRC function with it gets two inputs one is the current value and the other input is current checksum, that's why at every iteration Im updating the checksum with the returned value of calcCRC, and also at every iteration I update the rxBuffer value corresponding to index i (rxBuffer(i) is running on the whole values of rxBuffer array).
So If I can't do assignment inside the loop .. how do I implement what I want in matlab ?! thanks alot.
Walter Roberson
on 11 Aug 2020
Sigh.
I tried to make the code Bug-for-bug compatible https://en.wikipedia.org/wiki/Bug_compatibility . It isn't pretty. You would never write MATLAB code this way, but I wanted you to see that the implementation was directly taken from the original code. In my opinion, the original code is broken, but the MATLAB code attempts to replicate the same broken implementation, as you indicate that as far as you are concerned, the original code works perfectly, so you must have turned the bugs into features.
In order to replicate the C++ code, the following code MUST be defined as a nested function within another function that defines CRC_INIT and PacketIndex.
The initial value of CRC_INIT does not matter, because the code always writes a new value to it, but the class CRC_INIT is defined outside is important (and to be honest, I did not bother making it bug-for-bug compatible with the assignment of the constant value to CRC_INIT).
The initial value and class of PacketIndex do matter, as the code updates it. The code takes care to wrap the counters like C++ would do.
I put in some code to try to replicate the buffer overflows that are in the C++ code, but for practical reasons, I gave up after deliberately overwriting two of the variables. MATLAB does not have buffer overflows like C++ does, and it is inconvenient to replicate the way that C++ will systematically destroy all the local variables one by one as your buffer overflow proceeds.
I did make concerted attempts to replicate the multiple infinite loops that exist in your C++ code.
Under no circumstances would I actually use the below MATLAB code: I would file bug reports with the authors of the C++ code until they either fixed the bugs or else declared that a particular implementation was the reference implementation and they nailed down the C++ code to exactly match the reference implementation... and then I would write the MATLAB code to match the boundaries they defined.
Did I mention that you absolutely MUST define this as a nested function inside code that defined CRC_INIT and PacketIndex?
Did I mention that this code must not return crcOK, and has no way of conveying the result of the CRC check to the calling function or to the user?
The C++ code would never have passed one of my code reviews, but you insist that the C++ code is 100% correct for your purpose, so I had to struggle a fair bit to make the MATLAB code behave in exactly the same way, no matter what my opinion is of the C++ code being correct.
%Bug-for-bug compatibility with the C++ source code is the purpose of this code.
%
% No experienced MATLAB programmer would ever write code like this,
% but the person who supplied the C++ code insists that the C++ is correct
% FOR THEIR PURPOSE
% function does not return anything because the reference C++ code is void
% in particular, returning crcOK is an incorrect implementation for the C++ code.
% the C++ code computes crcOK and then does nothing with it.
% void deBin(const std::string& rx)
function deBin(rx)
% no return from function.
% function must be passed a string, not a character vector
assert(isstring(rx) && isscalar(rx), 'rx must be scalar string. Not character vector')
% unsigned int ByteConvertRxBuffer[35]
ByteConvertRxBuffer = zeros(1,35,'uint8'); %starting array with size 35 which all its %values are zero
% uint8_t rxBuffer[35];
rxBuffer = zeros(1,35, 'uint8'); % starting an empty array with size 35
% size_t ireal = 0
ireal = uint64(0);
% uint16_t checksum;
checksum = uint16(0); %#ok<NASGU>
% bool crcOK = false;
% the C++ code initializes it, but always overwrites it
crcOK = false; %#ok<NASGU>
% uint8_t i;
i = uint8(0);
% CRC_INIT=0xFFFF
% No type declaration is specified for this. If it were C, then
% this would potentially be a default type of int, but in C++ there
% are no default types. This is therefore invalid C++ code, UNLESS
% CRC_INIT has been defined in file scope. But MATLAB does not
% have file scope. So we will do the best we can
if ~exist('CRC_INIT', 'var')
fprintf(2, 'In order to exactly replicate the C++ code for CRC_INIT\n');
fprintf(2, 'this function must be defined (nested) inside another function\n');
fprintf(2, 'and that enclosing function must define CRC_INIT\n');
fprintf(2, 'because when we assign to CRC_INIT here, the value in the\n');
fprintf(2, 'file scope must be changed if we are to match the C++ code\n');
error('CRC_INIT Scope error');
end
CRC_INIT = typecast(0xFFFF, class(CRC_INIT));
checksum = unit16(CRC_INIT);
% int byteSize=8;
%warning: some of the below code becomes invalid if byteSize exceeds 32767
byteSize = int32( 8 );
i_saved = i; %i is going to become local, but is used again later
i = uint64(0); %#ok<NASGU> %size_t i inside block
if ~isempty(rx{1})
for i = uint64(0) : uint64(byteSize) : uint64(length(rx{1}) - 1)
% char nibble[byteSize];
nibble = char(zeros(1,byteSize));
j = int32(0); %#ok<NASGU> %int j inside block
for j = int32(0) : int32(1) : int32(byteSize - 1)
idx64 = i + uint64(j) + 1; %promotion of datatypes like C++
nibble(j+1) = rx{1}(idx64);
end %after it finishes 8 iterations then out from the current loop
clear j %int j was local to block
% std::cout << valueOf(nibble);
% notice that cout does not put spaces between values and does
% no put in carriage returns, so we have to replicate that.
fprintf('%g', valueOf(nibble)); %// storing the value of each Byte-8bit inside ByteConvertRxBuffer by calling to other Function
% ByteConvertRxBuffer[ireal++] = valueOf(nibble);
valnib = uint16(valueOf(nibble));
if ireal < length(ByteConvertRxBuffer)
ByteConvertRxBuffer(ireal+1) = valnib;
else
overflow_size = ireal - ByteConvertRxBuffer + 2;
if overflow_size < length(rxBuffer) - 1
rxBuffer(overflow_size : overflow_size + 1) = typecast(valnib, 'uint8');
else
ireal = valnib;
fprintf(2, 'Sorry, weakness in reproducing the buffer overflows in the C++ code\n');
end
end
ireal = ireal + 1;
if (i + byteSize ~= length(rx{1}))
%code does nothing if the test is or is not true
end
end
end
clear i %size_t i was local to block
i = int32(0); %int i within block
ByteConvertRxBufferSize = length(ByteConvertRxBuffer);
while i < ByteConvertRxBufferSize
if i < 0 || i >= length(rxBuffer)
fprintf(2, 'Sorry, weakness in reproducing the buffer overflows in the C++ code\n');
end
rxBuffer(uint64(i)+1) = ByteConvertRxBuffer(uint64(i)+1);
if i == intmax(class(i))
i = intmin(class(i));
else
i = i + 1;
end
end
clear i %int i was local to block
i = i_saved; %#ok<NASGU> %no longer within a block that defines i locally, so it goes back to uint8_t i;
%i has reverted to uint8_t but the buffer size might be more than 256,
%so we have to replicate the fact that a uint8 counter would wrap in C++
%... And yes, I DID test that, and C++ really will infinite loop if you ask
%a for loop to run uint8 to a limit beyond 255.
i = uint64(0);
while i < length(rxBuffer) - 1
checksum = calcCRC(rxBuffer(i+1), checksum);
if i == intmax('uint8')
i = intmin('uint8');
else
i = i + 1;
end
end
% No type declaration or initializer is specified for PacketIndex++. If it were C,
% then this would potentially be a default type of int, and default initializer
% of 0, but in C++ thereare no default types. This is therefore invalid C++ code, UNLESS
% PacketIndex has been defined in file scope. But MATLAB does not
% have file scope. So we will do the best we can
if ~exist('PacketIndex', 'var')
fprintf(2, 'In order to exactly replicate the C++ code for PacketIndex\n');
fprintf(2, 'this function must be defined (nested) inside another function\n');
fprintf(2, 'and that enclosing function must define PacketIndex\n');
fprintf(2, 'because when we increment PacketIndex here, the value in the\n');
fprintf(2, 'file scope must be changed if we are to match the C++ code\n');
error('PacketIndex Scope error');
end
if PacketIndex == intmax(class(PacketIndex))
PacketIndex = intmin(class(PacketIndex)); %#ok<NODEF>
else
PacketIndex = PacketIndex + 1; %#ok<NODEF>
end
if (checksum == 0)
disp(PacketIndex); %this is for displaying the packetNumber that Im currently dealing with...may get more than one packet
crcOK = true; %#ok<NASGU> % your packet number PacketIndex is Valid
else
disp(PacketIndex);
crcOK = false;%#ok<NASGU> % your packet number PacketIndex is Valid
end
%for compatibility with the C++ code, crcOK must NOT be returned
end
Jimmy cho
on 11 Aug 2020
Appreciated, thanks alot for your explanation !
Regarding to my c++ code, I've reviewed it more than 100 times, it works fine with different inputs, and I'm ready to explain what's confusing me because what's matter not the code itself or copying code from others, the matter is to understand and to help each other as much as we could.
if you're having a concrete example that demonstrate that my c++ code is wrong, it would be appreciated to attach me that example.
thanks
Walter Roberson
on 11 Aug 2020
The C++ code does not return a value.
The C++ code uses uint8 and int variables as indices for objects that could potentially require the full size_t .
The C++ code does not make sense unless there is file scope for the identifiers CRC_INIT and PacketIndex.
The C++ code does not take into account that the data remaining in the buffer might not provide a full 8 bits, so it overruns the input buffer.
The C++ code overruns the end of RxBuffer when it writes to it. RxBuffer needs to be allocated dynamically according to the length of the input buffer divided by byteSize, or else the C++ code needs to error out when the input buffer is longer than the supported length. The C++ code needs to assume that the input buffer could be up to size_t long (or more practically, that the input buffer occupies all available memory.
We know that the input can cause all these problems because there is no documentation in the function that puts on pre-conditions. Any restriction that is not documented mustbe considered to not exist, as far as the programmer responsible for coding this function is concerned: if the interface specification does not document a 2 gigabyte buffer limit, then there is no 2 gigabyte buffer limit and the programmer of the function must accept any size that fits within size_t.
Jimmy cho
on 12 Aug 2020
Edited: Walter Roberson
on 12 Aug 2020
I will make sure to answer you about your last comment sooner today !
Moreover , this function that you wrote:
function crcReg = calcCRC(crcData, crcReg,)
CRC16_POLY = 0x8005;
for i = 0 : 7
if bitxor( bitshift( bitand(crcReg, 0x8000), -8), ...
bitand( crcData, 0x0080 ) )
crcReg = bitxor( bitshift(crcReg, 1), CRC16_POLY );
else
crcReg = bitshift(crcReg, 1);
end
crcData = bitshift(crcData, 1);
end
isn't working for me in matlab, it tells me:
Parse error at x8005: usage might be invalid MATLAB syntax, Invalid expression. Check for missing multiplication operator, missing or unbalanced delimiters, or other syntax error. To
construct matrices, use brackets instead of parentheses.
So what should I do to fix that? it sounds that the syntax error in hexa writtings ..matlab isn't recognized to this 0x..?
thanks
Walter Roberson
on 12 Aug 2020
>> CRC16_POLY = 0x8005
CRC16_POLY =
uint16
32773
Not a parse error.
Unless, that is, you have an MATLAB version that is old enough that it does not support that feature??
At a risk of giving you more responses that you cannot use as your MATLAB version might be too old, then take note:
uint16(hex2dec('8005'))
uint16(sscanf('8005','%x'))
Jimmy cho
on 12 Aug 2020
Edited: Jimmy cho
on 12 Aug 2020
thanks alot !
I used CRC16_POLY=uint16(hex2dec('8005')); it works fine without using sscanf ..
for my porpuse , what does sscanf mean in your example? is it the same as say hex2dec('8005')?
appreciated.
Walter Roberson
on 12 Aug 2020
sscanf() is like fscanf() except that it does not read from a file and then interpret the characters read according the given format: instead it gets characters from the character vector that is passed to it, and interprets the characters according to the given format.
hex2dec() has a quite different implementation that is designed to work on arrays of data.
sscanf() calls into the fundamental I/O libraries to do its work.
In general, the main advantage of sscanf() is that you can say exactly how many digits at a time you want to read. For example,
sscanf('789ABC', '%3x')
will pull out 3 characters at a time and translate them to decimal, instead of having to do
hex2dec(reshape('789ABC', 3, []).')
... except worse because for the reshape() one you have to pad out to a multiple of 3 first, but the sscanf() version can handle strings that are not full multiples...
See Also
Categories
Find more on Floating-Point Specification in MATLAB in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)