Hello all,
I am doing a learning exercise I like to do where I take open source programs others have written and reverse engineer them. It's a really useful for understanding code and learning some of the tricks other programmers use. I am currently tearing apart Marlin, an open-source firmware for 3D printers. Specifically I'm currently working on the void get_command() function that is called once in the main loop and nowhere else.
I have hit a portion of code that seems like it shouldn't work; I use this configuration of Marlin on two of my 3D printers, so I know it works. I must not be understanding the code correctly. I'm having trouble with the static int serial_count variable. The code goes approximately like this:
//private variables
static int SERIAL_COUNT = 0;
void get_command(){
if(!card.sdprinting || SERIAL_COUNT != 0){
return;
}
if(serial_char == '\n' || serial_char == '\r' || (serial_char == ':' && comment_mode == false) || SERIAL_COUNT >= (MAX_CMD_SIZE - 1)||n==-1){
if(somethingIrrelevantToThisPost){
doSomethingIrrelevantToThisPost();
}
if(!SERIAL_COUNT){
comment_mode = false;
return;
}
cmdbuffer[bufindw][SERIAL_COUNT] = 0;
fromsd[bufindw] = true;
buflen += 1;
bufindw = (bufindw + 1)%BUFSIZE;
comment_mode = false;
SERIAL_COUNT = 0;
}else{
if(serial_char == ';') comment_mode = true;
if(!comment_mode) cmdbuffer[bufindw][SERIAL_COUNT++] = serial_char;
}
}
I have put each instance of the serial_count variable in CAPS.
Follow me for a minute:
-
serial_count is a static int that is either zero or some integer; initialized as 0
and serial_count is not called anywhere outside the void get_command() function (that I can find) -
when the get_command() function is called the first thing is an IF conditional
if(!card.sdprinting || serial_count != 0){
return;
-
ignoring the first condition for now, if serial_count is not 0 then we get kicked back out to the the main loop, if it is 0 then we can move on down the line (holding the assumption that serial_count is zero)
-
then we encounter the second if conditional
if(serial_char == '\n' || serial_char == '\r' || (serial_char == ':' && comment_mode == false) || SERIAL_COUNT >= (MAX_CMD_SIZE - 1)||n==-1){
5.1) first let's assume we didn't trigger this conditional; we would jump down to
}else{
if(serial_char == ';') comment_mode = true;
if(!comment_mode) cmdbuffer[bufindw][SERIAL_COUNT++] = serial_char;
where serial_count is increased by 1. This would mean the next time round when we hit the if conditional
if(!card.sdprinting || SERIAL_COUNT != 0){
return;
we will automatically get kicked back out to the main loop
5.2) now let's assume we triggered the second conditional so we would hit the line
if(!SERIAL_COUNT){
comment_mode = false;
return;
}
so if serial_count is 0, we get kicked back out to the main loop
- it seems to me that the code below this point:
cmdbuffer[bufindw][SERIAL_COUNT] = 0;
fromsd[bufindw] = true;
buflen += 1;
bufindw = (bufindw + 1)%BUFSIZE;
comment_mode = false;
SERIAL_COUNT = 0;
is completely inaccessable
I have been thinking about this for several days, the only thing I can think of is that I must be reading the code wrong somewhere...
Can anyone point out my (probably stupid) mistake?
Direct answers are always welcome, but suggestions for resources are good too (i.e. go read this chapter of this book)
Thanks All!
J