timer expire

Hi,

   I have a strange problem. I use a serial port timer to retrieve serial port data. When I compile with debug, the program runs normally, but when I compile with release, the program cannot run properly. Finally, I find out that the reason is that the release version of the program enters the timer_expire (app_timertt * p-time) function and returns true, while the debug version of the program returns false. What is the reason for this? I am using SDK 17.2.

   thanks!

  • Can you show some code snippets for us to review or use to try at our end? Hard to say what is wrong.

    If there is a difference in release and debug version of the code, then it is most likely some issue with the code where some unwanted things being optimized away. 

  • Hi,

    #include "double_uart.h"
    
    #include "nrf_uart.h"
    
    #include "app_uart.h"
    
    #include "app_timer.h"
    
    #include "pca10056.h"
    
    #include "nrf_delay.h"
    
    #include "string.h"
    
    #include "wifi_esp8266.h"
    
    #include "pwm_control.h"
    
    uint8_t data_rec_array[UART_RX_BUF_SIZE], data_array[UART_RX_BUF_SIZE];
    uint8_t data1_rec_array[UART_RX_BUF_SIZE], data1_array[UART_RX_BUF_SIZE];
    bool motor_start_flag = false, motor_end_flag = false, target_pre_send_flag = false, start_wifi_flag = false;
    uint16_t target_wind_pressure = 0, inlet_wind_range = 50, outlet_wind_rang = 50;
    uint16_t operate_cnt = 0;
    bool white_glove = true, operate_order = true, operate_num = true, uart_rec_flag = false;
    uint16_t workpiece_ok_num = 0, workpiece_err_num = 0;
    
    static void uart0_handleEvent(app_uart_evt_t * pEvent);
    static void uart1_handleEvent(app_uart_evt_t * pEvent);
    
    APP_UART_DEF(uart0, 0, UART_RX_BUF_SIZE, uart0_handleEvent);
    APP_UART_DEF(uart1, 1, UART_RX_BUF_SIZE, uart1_handleEvent);
    
    APP_TIMER_DEF(m_rec_timer);
    APP_TIMER_DEF(m_rec1_timer);
    
    /*****************压力表量程设定******************/
    static void pre_rang_set() {
      uint8_t prs_set[8];
      uint16_t prs_crc;
    
      if (outlet_wind_rang != 0) {
        prs_set[0] = FAN_ADD;
        prs_set[1] = WRITE_CODE;
        prs_set[2] = 0xfb;
        prs_set[3] = 0x00;
        prs_set[4] = outlet_wind_rang >> 8;
        prs_set[5] = outlet_wind_rang & 0xff;
        prs_crc = crc16(prs_set, 6);
        prs_set[6] = prs_crc & 0xff;
        prs_set[7] = prs_crc >> 8;
    
        for (uint8_t i = 0; i < 8; i++) {
          while (app_uart0_put(prs_set[i]) != NRF_SUCCESS);
        }
      }
    }
    
    /*****************风机风压485给定控制方式******************/
    void fan_485_conrol() {
      uint8_t twp_cmd[8];
      uint16_t twp_crc;
    
      //if(target_wind_pressure !=0)
      {
        if (target_wind_pressure > outlet_wind_rang) {
          target_wind_pressure = outlet_wind_rang;
        }
        twp_cmd[0] = FAN_ADD;
        twp_cmd[1] = WRITE_CODE;
        twp_cmd[2] = 0xfb;
        twp_cmd[3] = 0x01;
        twp_cmd[4] = target_wind_pressure >> 8;
        twp_cmd[5] = target_wind_pressure & 0xff;
        twp_crc = crc16(twp_cmd, 6);
        twp_cmd[6] = twp_crc & 0xff;
        twp_cmd[7] = twp_crc >> 8;
    
        for (uint8_t i = 0; i < 8; i++) {
          while (app_uart0_put(twp_cmd[i]) != NRF_SUCCESS);
        }
      }
    }
    
    static void recive_timeout_handler(void * p_context) {
      uart_rec_flag = true;
      USART_RX_STA |= 1 << 15;
      operate_cnt = data_array[2];
    
      if (data_array[3] == 0) white_glove = true;
      else white_glove = false;
      if (data_array[4] == 0) operate_order = true;
      else operate_order = false;
      if (data_array[5] == 0) operate_num = true;
      else operate_num = false;
      workpiece_ok_num = (data_array[6] >> 8) | data_array[7];
      workpiece_err_num = (data_array[8] >> 8) | data_array[9];
      memset(data_array, 0, 15);
      memset(data_rec_array, 0, 15);
      USART_RX_STA = 0;
    
    }
    static void clean_uart1_rec_buffer() {
      USART1_RX_STA = 0;
      memset(data1_array, 0, 15);
      memset(data1_rec_array, 0, 15);
    }
    static void recive1_timeout_handler(void * p_context) {
      USART1_RX_STA |= 1 << 15;
      if (data1_array[1] == 0xA5) {
        if (data1_array[13] == 0x04 && data1_array[14] == 0xd2) //身份验证默认为输入1234,然后取消报警
        {
          nrf_gpio_pin_set(LED_G); //正常亮绿灯
          nrf_gpio_pin_clear(LED_R); //故障亮红灯,正常熄灭
          nrf_gpio_pin_clear(BUZZER); //故障响蜂鸣器,正常熄灭
        }
      }
      clean_uart1_rec_buffer();
    }
    /**@brief Function for initializing the timer. */
    void timer_init(void) {
      ret_code_t err_code = app_timer_init();
      APP_ERROR_CHECK(err_code);
      APP_ERROR_CHECK(app_timer_create( & m_rec_timer, APP_TIMER_MODE_SINGLE_SHOT, recive_timeout_handler));
      APP_ERROR_CHECK(app_timer_create( & m_rec1_timer, APP_TIMER_MODE_SINGLE_SHOT, recive1_timeout_handler));
    }
    
    void uart_init(void) {
      ret_code_t err_code;
    
      app_uart_comm_params_t
      const comm_params = {
        .rx_pin_no = RX_PIN_NUMBER,
        .tx_pin_no = TX_PIN_NUMBER,
        .rts_pin_no = RTS_PIN_NUMBER,
        .cts_pin_no = CTS_PIN_NUMBER,
        .flow_control = APP_UART_FLOW_CONTROL_DISABLED,
        .use_parity = false,
        .baud_rate = UART_BAUDRATE_BAUDRATE_Baud9600
      };
    
      uart0.comm_params = & comm_params;
      err_code = app_uart_init( & uart0, & uart0_buffers, APP_IRQ_PRIORITY_LOWEST);
      APP_ERROR_CHECK(err_code);
    
      app_uart_comm_params_t
      const uart1_comm_params = {
        .rx_pin_no = UART1_RX_PIN,
        .tx_pin_no = UART1_TX_PIN,
        .rts_pin_no = UART_PIN_DISCONNECTED,
        .cts_pin_no = UART_PIN_DISCONNECTED,
        .flow_control = APP_UART_FLOW_CONTROL_DISABLED,
        .use_parity = false,
        .baud_rate = UART_BAUDRATE_BAUDRATE_Baud115200
      };
    
      uart1.comm_params = & uart1_comm_params;
      err_code = app_uart_init( & uart1, & uart1_buffers, APP_IRQ_PRIORITY_LOWEST);
      APP_ERROR_CHECK(err_code);
    }
    
    void uart0_handleEvent(app_uart_evt_t * p_event) {
      //uint8_t data;
      switch (p_event -> evt_type) {
        //@snippet [Handling data from UART]
      case APP_UART_DATA_READY:
        if (((USART_RX_STA & (1 << 15)) == 0) && (!rec_data_flag)) {
          if (USART_RX_STA < UART_RX_BUF_SIZE) {
            UNUSED_VARIABLE(app_uart_get( & uart0, & data_rec_array[USART_RX_STA]));
            if ((USART_RX_STA == 0) && (data_rec_array[0] == 0x5A)) {
              app_timer_start(m_rec_timer, APP_TIMER_TICKS(20), NULL); //此时间值设定关乎到目标风压设定值的稳定性,越小越稳定,原因分析:每一秒往屏写运行参数时,屏会回数据,在这个时间段设置风压值,回的数据和设定数据就有可能连起来导致无法识别
            }
            if (data_rec_array[0] == 0x5A) {
              data_array[USART_RX_STA] = data_rec_array[USART_RX_STA];
              USART_RX_STA++;
            }
          } else {
            USART_RX_STA |= 1 << 15;
            memset(data_rec_array, 0, 256);
          }
        }
        break;
      case APP_UART_DATA:
        //UNUSED_VARIABLE(app_uart_get(&data_array[index]));
        //index++;
        //UNUSED_VARIABLE(app_uart_get(&c));
    
        break;
    
        //@snippet [Handling data from UART]
      case APP_UART_COMMUNICATION_ERROR:
        // NRF_LOG_ERROR("Communication error occurred while handling UART.");
        //APP_ERROR_HANDLER(p_event->data.error_communication);
        break;
    
      case APP_UART_FIFO_ERROR:
        // NRF_LOG_ERROR("Error occurred in FIFO module used by UART.");
        APP_ERROR_HANDLER(p_event -> data.error_code);
        break;
    
      default:
        break;
      }
    }
    
    void uart1_handleEvent(app_uart_evt_t * p_event) {
      //uint8_t data;
      switch (p_event -> evt_type) {
        //@snippet [Handling data from UART]
      case APP_UART_DATA_READY:
        if ((USART1_RX_STA & (1 << 15)) == 0) {
          if (USART1_RX_STA < UART_RX_BUF_SIZE) {
            UNUSED_VARIABLE(app_uart_get( & uart1, & data1_rec_array[USART1_RX_STA]));
            if ((USART1_RX_STA == 0) && (data1_rec_array[0] == 0x5A)) {
              app_timer_start(m_rec1_timer, APP_TIMER_TICKS(20), NULL); //此时间值设定关乎到目标风压设定值的稳定性,越小越稳定,原因分析:每一秒往屏写运行参数时,屏会回数据,在这个时间段设置风压值,回的数据和设定数据就有可能连起来导致无法识别
            }
            //UNUSED_VARIABLE(app_uart_get(&uart1,&data1_rec_array[USART1_RX_STA]));
            //UNUSED_VARIABLE(app_uart_get(&data));
            if (data1_rec_array[0] == 0x5A)
            //if(data == 0x01 || data == 0x02)
            {
              data1_array[USART1_RX_STA] = data1_rec_array[USART1_RX_STA];
              USART1_RX_STA++;
            }
          } else {
            USART1_RX_STA |= 1 << 15;
            memset(data_rec_array, 0, 256);
          }
        }
        break;
      case APP_UART_DATA:
        //UNUSED_VARIABLE(app_uart_get(&data_array[index]));
        //index++;
        //UNUSED_VARIABLE(app_uart_get(&c));
    
        break;
    
        //@snippet [Handling data from UART]
      case APP_UART_COMMUNICATION_ERROR:
        //NRF_LOG_ERROR("Communication error occurred while handling UART.");
        //APP_ERROR_HANDLER(p_event->data.error_communication);
        break;
    
      case APP_UART_FIFO_ERROR:
        // NRF_LOG_ERROR("Error occurred in FIFO module used by UART.");
        APP_ERROR_HANDLER(p_event -> data.error_code);
        break;
    
      default:
        break;
      }
    }
    
    /************UART0 接收发送函数重构************/
    uint32_t app_uart0_get(uint8_t * p_byte) {
      return app_uart_get( & uart0, p_byte);
    }
    uint32_t app_uart0_put(uint8_t byte) {
      return app_uart_put( & uart0, byte);
    }
    uint32_t app_uart0_flush() {
      return app_uart_flush( & uart0);
    }
    
    /************UART1 接收发送函数重构************/
    uint32_t app_uart1_get(uint8_t * p_byte) {
      return app_uart_get( & uart1, p_byte);
    }
    uint32_t app_uart1_put(uint8_t byte) {
      return app_uart_put( & uart1, byte);
    }
    uint32_t app_uart1_flush() {
      return app_uart_flush( & uart1);
    }
    
    /******************modbus CRC16 校验******************/
    uint16_t crc16(uint8_t * data, uint8_t length) {
      int i, crc_result = 0xffff;
      while (length--) {
        crc_result ^= * data++;
        for (i = 0; i < 8; i++) {
          if (crc_result & 0x01) crc_result = (crc_result >> 1) ^ 0xa001;
          else crc_result = crc_result >> 1;
        }
      }
      //return (crc_result= ((crc_result&0xff)<<8)|(crc_result>>8));
      return (crc_result);
    }

    this is my  main code.Please see if there are any issues

  • It looks like the app_timer_start is called with some condition inside uart0 event handler. It is hard for me to say when app_timer_start is called.

    1. Is it possible that it is called multiple times before the previous one shot timer expires?
    2. What is the baudrate used? If you run at a lower baudrate, does the debug and release version behave similar?
      1. If yes, then it could be an issue in the way you are starting the timers.
      2. if no, then there could be a harder logic optimization in your code, that is not very obvious from the code review here. Is it possible to attach a similistic project that i can use to reproduce ono the nRf52840 DK?
Related