Another Pros question

I know this one is a weird one but I have a debug app that I am trying to make that can talk to the cortex and get results with a serial connection through the programming port of the vex controller.

void operatorControl() {
	
	char * a;

	while (1) {
		
		delay(20);
		
		fgets(a, 120, stdin);

	}
}

so far this only crashes the cortex, did I make a mistake or is pros not good at this communication?

You have unfortunately not allocated the necessary memory in order for the call to fgets() to store the characters being read in from stdin. This immediately causes a segfault and the cortex to crash.

I have included below a correct version of your exact code:


void operatorControl() {
	
        // malloc enough memory for 120 chars as defined in your fgets call
        // adjust to the amount you are actually reading.
	char * a = (char *)malloc(sizeof(char) * 120);      

	while (1) {
		
		delay(20);
		
		fgets(a, 120, stdin);

	}
}

Ahhh that’s not surprising. Thank you for giving me the heads up.

-Jaxon

I’ve been working on this again and it seems like if I type one character into either pros ide or putty its continues to run but if I type another the loop stops. Any idea about this?

	char * a = (char *)malloc(sizeof(char) * 120);
	int i = 0;

	while (1) {
		delay(20);

		fgets(a, 120, stdin);

		fprintf(stdout, "You pressed %s \n\r", a);

	}

-Jaxon

Ok so time finally permitted and I was able to sit down and investigate your code. Let’s take a close look at the call to fgets:


fgets(a, 120, stdin);

You are reading into string a, expecting to read 120 characters from stdin. With that I believe the issue you are experiencing is due to the fact that you are sending >= 120 characters at a time. Lets take a look at fgets implementation:


// fgets - Read a string from the specified stream
char* fgets(char *str, int num, FILE *stream) {
	// Required by standard
	char *ptr = str;
	int value;
	if (feof(stream)) return NULL;
	// Read at most num-1 characters
	for (; num > 1 && (value = fgetc(stream)) != EOF; num--) {
		*ptr++ = (char)value;
		// Exit loop (including new line) when a new line is found
		if ((char)value == '\n') break;
	}
	// Add null terminator
	*ptr = '\0';
	return str;
}

When you pass the value of 120 the for loop will run 119 iterations calling fgetc to read from the specified stream. This is due to fact that every C string is null terminated and that character resides in the last position of the string. So specifying 120 means you get a string with 119 visible characters. In addition fgetc as specified in API.h is a blocking call (see below)


/**
 * Reads and returns one character from the specified stream, blocking until complete.
 *
 * Do not use fgetc() on a VEX LCD port; deadlock may occur.
 *
 * @param stream the stream to read (stdin, uart1, uart2, or an open file in Read mode)
 * @return the next character from 0 to 255, or -1 if no character can be read
 */

So if you sent >=120 characters you push 1 or more characters onto the next call to fgets and it will hold on the call to fgetc expecting more characters due to the value that you passed into fgets. I would adjust the length of the string you are sending or change the num parameter accordingly so that you do not trigger another call to fgets due to trailing characters.