0

I am in 4-day fight with this code:

  unsigned long baudrate = 0;
  unsigned char databits = 0;
  unsigned char stop_bits = 0;

  char parity_text[10];
  char flowctrl_text[4];

  const char xformat[] = "%lu,%hhu,%hhu,%[^,],%[^,]\n";
  const char xtext[] = "115200,8,1,EVEN,NFC\n";
  int res = sscanf(xtext, xformat, &baudrate, &databits, &stop_bits, (char*) &parity_text, (char*) &flowctrl_text);

  printf("Res: %d\r\n", res);
  printf("baudrate: %lu, databits: %hhu, stop: %hhu,   \r\n", baudrate, databits, stop_bits);
  printf("parity: %s \r\n", parity_text);
  printf("flowctrl: %s \r\n", flowctrl_text);

It returns:

Res: 5
baudrate: 115200, databits: 0, stop: 1,
parity:
flowctrl: NFC

Databits and parity missing !

Actually memory under the parity variable is '\0'VEN'\0', looks like the first characters was somehow overwritten by sscanf procedure.

Return value of sscanf is 5, which suggests, that it was able to parse the input.

My configuration:

  • gccarmnoneeabi 7.2.1
  • Visual Studio Code 1.43.2
  • PlatformIO Core 4.3.1
  • PlatformIO Home 3.1.1
  • Lib ST-STM 6.0.0 (Mbed 5.14.1)
  • STM32F446RE (Nucleo-F446RE)

I have tried (without success):

  • compiling with mbed RTOS and without
  • variable types uint8_t, uint32_t
  • gccarm versions: 6.3.1, 8.3.1, 9.2.1
  • using another IDE (CLion+PlatformIO)
  • compiling on another computer (same config)

What actually helps:

  • making the variables static
  • compiling in Mbed online compiler

The behavior of sscanf is as whole very unpredictable, mixing the order or datatype of variables sometimes helps, but most often ends with another flaws in the output.

mixerito
  • 13
  • 3
  • forget about complex format strings!! make it simple, anything more complex is usually not implemented. Libraries have to be small. It is not a PC. No lu no hhu no [^] and no float without special linker options – 0___________ Mar 27 '20 at 16:53
  • As I pointed out: When compiled with Mbed online compiler (compiled with ARMCC Toolchain), everything works like a charm. Same core, same device. What do you mean by special linker options ? – mixerito Mar 27 '20 at 17:30

1 Answers1

0

This took me longer than I care to admit. But like most issues it ended up being very simple.

  char parity_text[10];
  char flowctrl_text[4];

Needs to be changed to:

  char parity_text[10] = {0};
  char flowctrl_text[5] = {0};

The flowctrl_text array is not large enough at size four to hold "EVEN" and the NULL termination. If you bump it to a size of 5 you should have no problem. Just to be safe I would also initialize the arrays to 0.

Once I increased the size I had 0 issues with your existing code. Let me know if this helps.

PatrickOfThings
  • 237
  • 1
  • 9
  • My answer is correct I believe, but I had the variables wrong. flowctrl_text is too small because it cannot hold NFC\n and a NULL terminator. Once this is corrected you should not have issues. – PatrickOfThings Mar 27 '20 at 19:44
  • Wow, you are correct. This explains the overwritten first character in parity_text by NULL terminator. BUT the variable databits still remains 0. Looks like two different problems. Actually using "toolchain-gccarmnoneeabi@1.90201.191206" proved to be helpful in the second half of the issue. – mixerito Mar 27 '20 at 23:55