This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Exception when using printk with CONFIG_CBPRINTF_FP_SUPPORT=y enabled in NCS 1.4.99-dev

I'm trying to port some code from FreeRTOS to Zephyr using a Nordic nRF52840.    (I've used FreeRTOS for quite a while, but am a novice with Zephyr.)   

I'm using k_poll() (in Zephyr) to implement the same functionality as xTaskNotifyWait (in FreeRTOS).  I got this to work in one thread, but found that the code crashed (exception when executing k_poll()) in a second thread (with a different signal, etc.).   This was while using Nordic NCS 1.4.0.    It looked like something that was (bad) happening in Zephyr code, so I upgraded to NCS 1.4.1, then NCS 1.4.2 and neither would compile (due to a Macro expansion error (see below)).   (Code compiles in 1.4.0, but not in 1.4.1 or 1.4.2)

So I tried the "latest" 1.4.99-dev" and the code compiles and the k_poll() issue appears to have been resolved.     

However, a new issue appears.    If I enable Floating Point in printk's (using CONFIG_CBPRINTF_FP_SUPPORT=y), printk statements cause an exception when executing "str_out".      Is this a known issue?

I should clarify that the CONFIG_CBPRINTF_FP_SUPPORT is used to enable floating point for printf (and variants).   I use it to sprintf() (using %f)  to a string variable that is then printed as a string using printk().

But enabling CONFIG_CBPRINTF_FP_SUPPORT seems to affect printk() (even those that only print strings other places in the code)!

BTW, this CONFIG didn't seem to be necessary in NCS 1.4.0 (as sprintf handled floating point without the need for a CONFIG enable)

Thanks!

Parents
  • Hello Ed Hepler.

    Could you please attach the code snippet that uses sprintf using %f. I would quickly test to see why it fails in the latest NCS.

  • Hi Susheel,

    Here is a snippet of code where sprintf is used:

        } else if(tempEventConditions[0].signal->result == TEMP_EVENT_DATA) {
          // Data transfer completed; process the data and send it
          int16_t tempCRaw = ((readBuf[0] << 8) | readBuf[1]) / 32;
          float tempC = (float)tempCRaw * 0.125;
          float tempF = (tempC * 1.8) + 32;
          // Put data into appropriate characteristic (rotate through 4)
          tempData[tempCharCntr].tempAmbient=           tempCRaw;
          tempData[tempCharCntr].tempObjectKelvin=      tempCRaw;
          tempData[tempCharCntr].tempObjectCelsius=     tempC;
          tempData[tempCharCntr].tempObjectFahrenheit=  tempF;
          //char strBuf[30];
          sprintf(tempData[tempCharCntr].tempString,"Temp F: %f   Temp C: %f\n",tempF,tempC);
    //printk("%s",tempData[tempCharCntr].tempString);
          // Populate the queue item
          tempQueueItem[tempCharCntr].fifo_reserved     = NULL;
          tempQueueItem[tempCharCntr].conn              = bleCurrentConnection;
          tempQueueItem[tempCharCntr].characteristic    = (struct bt_gatt_attr *)&tempService.attrs[5];
          tempQueueItem[tempCharCntr].len               = sizeof(tempDataCharacteristic);
          tempQueueItem[tempCharCntr].data              = (void *)&tempData[tempCharCntr];
          // Send the queue item via the FIFO to the send thread
          k_fifo_put(&notifyQueue,&tempQueueItem[tempCharCntr]);
          // Update tempCharCntr
          tempCharCntr= (tempCharCntr + 1) & NUM_TEMP_BUFFERS_MASK;
        }

    As mentioned earlier, this worked in NCS 1.4.0, but I couldn't get 1.4.1 or 1.4.2 to compile due to the MACRO expansion issue shown in the original post.

    When 1.4.99-dev is used, sprintf doesn't recognize "%f" as a conversion token (so "%f" is output literally).    The CONFIG: CONFIG_CBPRINTF_FP_SUPPORT seems to be needed for this to be overcome, but causes printk (even earlier printk statements that have nothing to do with floating point) to fail in the function str_out().

Reply
  • Hi Susheel,

    Here is a snippet of code where sprintf is used:

        } else if(tempEventConditions[0].signal->result == TEMP_EVENT_DATA) {
          // Data transfer completed; process the data and send it
          int16_t tempCRaw = ((readBuf[0] << 8) | readBuf[1]) / 32;
          float tempC = (float)tempCRaw * 0.125;
          float tempF = (tempC * 1.8) + 32;
          // Put data into appropriate characteristic (rotate through 4)
          tempData[tempCharCntr].tempAmbient=           tempCRaw;
          tempData[tempCharCntr].tempObjectKelvin=      tempCRaw;
          tempData[tempCharCntr].tempObjectCelsius=     tempC;
          tempData[tempCharCntr].tempObjectFahrenheit=  tempF;
          //char strBuf[30];
          sprintf(tempData[tempCharCntr].tempString,"Temp F: %f   Temp C: %f\n",tempF,tempC);
    //printk("%s",tempData[tempCharCntr].tempString);
          // Populate the queue item
          tempQueueItem[tempCharCntr].fifo_reserved     = NULL;
          tempQueueItem[tempCharCntr].conn              = bleCurrentConnection;
          tempQueueItem[tempCharCntr].characteristic    = (struct bt_gatt_attr *)&tempService.attrs[5];
          tempQueueItem[tempCharCntr].len               = sizeof(tempDataCharacteristic);
          tempQueueItem[tempCharCntr].data              = (void *)&tempData[tempCharCntr];
          // Send the queue item via the FIFO to the send thread
          k_fifo_put(&notifyQueue,&tempQueueItem[tempCharCntr]);
          // Update tempCharCntr
          tempCharCntr= (tempCharCntr + 1) & NUM_TEMP_BUFFERS_MASK;
        }

    As mentioned earlier, this worked in NCS 1.4.0, but I couldn't get 1.4.1 or 1.4.2 to compile due to the MACRO expansion issue shown in the original post.

    When 1.4.99-dev is used, sprintf doesn't recognize "%f" as a conversion token (so "%f" is output literally).    The CONFIG: CONFIG_CBPRINTF_FP_SUPPORT seems to be needed for this to be overcome, but causes printk (even earlier printk statements that have nothing to do with floating point) to fail in the function str_out().

Children
No Data
Related