-->
Page 1 of 2

format strings in printf/sprintf in freertos sdk not working

PostPosted: Sat Apr 18, 2015 6:27 pm
by sensored
hi,
i've got some code (simplified) like:
Code: Select allLOCAL uint8_t sensors[] = { 0x20, 0x21 };
uint16_t readingBytes[2] = {0x00FF, 0x00FF};
uint8_t x = 0;
printf("%i %i %i\n", sensors[x], readingBytes[0],  readingBytes[1]);

all i get on the serial port is 2 spaces and a newline (no "32 255 255" as expected).
sprintf is doing the same thing.

this was working fine in the non-freertos sdk.

any ideas why this is? i'm completely stumped why sprintf and printf aren't working properly.

i'm using the esp-open-sdk gcc compiler if that matters.

thanks,
-matt

Re: format strings in printf/sprintf in freertos sdk not wor

PostPosted: Sat Apr 18, 2015 7:01 pm
by sensored
in testing, it looks like they work OK in user_init, but this is being called inside of a sys_thread_new() thread that is called from within a xTaskCreate() task

here is the full code for context:
Code: Select all#include "esp_common.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "lwip/api.h"
#include "uart.h"

#define SERVER_PORT 31337
#define SERVER_TIMEOUT 5
#define SSID "ssid"
#define PASSWORD "password"

#define I2C_SDA 1
#define I2C_SCL 2
#define I2C_SPEED 1000

#define NONE_SLEEP_T 0

#define SERVER_TASK_PRIORITY         (tskIDLE_PRIORITY + 2)

#define SERVER_TASK_STACK_SIZE       (256)

LOCAL uint8_t sensors[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27};

void server_request(void *pvParameters)
{
   struct netconn *conn;
   struct netbuf *inbuf;
   char *buf;
   uint16_t buflen;

   conn = pvParameters;

   printf("entered server_request\n");

   char readingString[64];
   uint16_t readingBytes[2];
   uint8_t x;
   for (x = 0; x < sizeof(sensors); x++) {
      memset(readingString, 0x00, sizeof(readingString));
      i2c_master_start();
      i2c_master_writeByte(sensors[x] << 1);
      i2c_master_checkAck();
      i2c_master_writeByte(0x00);
      i2c_master_checkAck();
      i2c_master_start();
      i2c_master_writeByte((sensors[x] << 1) | 0x01);
      i2c_master_checkAck();
      readingBytes[0] = i2c_master_readByte() << 8;
      i2c_master_send_ack();
      readingBytes[0] |= i2c_master_readByte();
      i2c_master_send_nack();
      i2c_master_start();
      i2c_master_writeByte(sensors[x] << 1);
      i2c_master_checkAck();
      i2c_master_writeByte(0x03);
      i2c_master_checkAck();
      i2c_master_stop();
      WRITE_PERI_REG(0x60000914, 0x73);
      vTaskDelay(100);
      i2c_master_start();
      i2c_master_writeByte(sensors[x] << 1);
      i2c_master_checkAck();
      i2c_master_writeByte(0x04);
      i2c_master_checkAck();
      i2c_master_start();
      i2c_master_writeByte((sensors[x] << 1) | 0x01);
      i2c_master_checkAck();
      readingBytes[1] = i2c_master_readByte() << 8;
      i2c_master_send_ack();
      readingBytes[1] |= i2c_master_readByte();
      i2c_master_send_nack();
      i2c_master_stop();

      WRITE_PERI_REG(0x60000914, 0x73);

      printf("%i %i %i\n", sensors[x], readingBytes[0],
             readingBytes[1]);

      sprintf(readingString, "%i %i %i\n", sensors[x],
         readingBytes[0], readingBytes[1]);

      netconn_write(conn, readingString,
               sizeof(readingString), NETCONN_COPY);
   }

   netconn_close(conn);

   netbuf_delete(inbuf);

   netconn_delete(conn);

   vTaskDelete(NULL);
}

static void server_task(void *pvParameters)
{
   struct netconn *conn, *newconn;
   err_t err;

   conn = netconn_new(NETCONN_TCP);
   if (conn == NULL) {
      printf("server_task: invalid conn\n");

      vTaskDelete(NULL);
   }

   netconn_bind(conn, NULL, SERVER_PORT);

   netconn_listen(conn);

   do {
      err = netconn_accept(conn, &newconn);
      if (err == ERR_OK) {
         if (NULL ==
             sys_thread_new("server_request", server_request,
                  newconn, SERVER_TASK_STACK_SIZE,
                  SERVER_TASK_PRIORITY)) {
            printf("sys_thread_new error\n");
            netconn_close(newconn);
            netconn_delete(newconn);
         }
      }
   } while (err == ERR_OK);

   netconn_close(conn);
   netconn_delete(conn);

   vTaskDelete(NULL);
}

void ICACHE_FLASH_ATTR user_init(void)
{
   char ssid[32] = SSID;
   char password[64] = PASSWORD;
   struct station_config stationConf;
   struct ip_info info;

   UART_SetBaudrate(0, BIT_RATE_115200);

   printf("init\n");

   IP4_ADDR(&info.ip, 10, 0, 0, 109);
   IP4_ADDR(&info.gw, 10, 0, 0, 1);
   IP4_ADDR(&info.netmask, 255, 255, 255, 0);

   wifi_set_ip_info(STATION_IF, &info);

   wifi_set_opmode(STATION_MODE);
   wifi_set_sleep_type(NONE_SLEEP_T);

   memcpy(&stationConf.ssid, ssid, 32);
   memcpy(&stationConf.password, password, 32);
   wifi_station_set_config(&stationConf);
   wifi_station_connect();

   i2c_master_gpio_init(I2C_SDA, I2C_SCL, I2C_SPEED);

   xTaskCreate(server_task, (const signed char *const)"server",
          SERVER_TASK_STACK_SIZE, NULL, SERVER_TASK_PRIORITY,
          NULL);
}

thanks,
-matt

Re: format strings in printf/sprintf in freertos sdk not wor

PostPosted: Sun Apr 19, 2015 2:34 am
by www.freertos.org
Which compiler are you using?

What is implementing printf/sprintf? (the library that comes with the compiler or something else?)

Which FreeRTOS port are you using (what is the architecture of the chip running FreeRTOS?)

Are you using an official version of FreeRTOS from the FreeRTOS download, or something else?

If you are using GCC then printf() can uses masses of stack - do you have stack overflow detection turned on: http://www.freertos.org/Stacks-and-stac ... cking.html ?

Where is the output of printf sent? Are you doing anything to ensure mutual exclusion on calls to printf() or the peripheral that is outputing the text?

Which version of FreeRTOS are you using, and do you have configASSERT() defined: http://www.freertos.org/a00110.html#configASSERT ?

Re: format strings in printf/sprintf in freertos sdk not wor

PostPosted: Sun Apr 19, 2015 12:16 pm
by sensored
hi,

i am using esp-open-sdk (https://github.com/pfalcon/esp-open-sdk) xtensa-lx106-elf-gcc, "gcc version 4.8.2 (crosstool-NG 1.20.0)"

i believe printf/sprintf is being implemented by the espressif c library, in their file libmain.a (from grep) but i'm not 100% sure. i see two references in headers:
./include/espressif/esp_libc.h:int sprintf(char *out, const char *format, ...);
./extra_include/stdio.h:int _EXFUN(sprintf, (char *, const char *, ...));

the freertos port is the one provided by espressif via their git repository, https://github.com/espressif/esp_iot_rtos_sdk
architecture is xtensa lx106. from ./include/freertos/FreeRTOSConfig.h it is version 7.5.2

it's not the official freertos directly from freertos.org, it is the one provided by espressif via their git (see above)

according to ./include/freertos/FreeRTOSConfig.h, #define configCHECK_FOR_STACK_OVERFLOW 2

the output of printf/sprintf is just the ascii (non special characters) in the format string. for example, "%i %i %i\n" comes out as " \n"

i'm not sure if configASSERT is defined, it isn't clear from FreeRTOSConfig.h/FreeRTOS.h

thanks for your help! btw, i got the portable snprintf from samba (https://ftp.samba.org/pub/unpacked/ccac ... snprintf.c) compiled into my project and it works perfectly fine!