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

Hardfault at CDC

My PC is windows 7 64-bit. I use SDK16 with softdevice. I am porting CDC code  to my application as follows. It has 2 issues. 1st: It will cause hardfault if I call the function of displayMainScreen in main function. (Just power on step). It will work fine if I remove displayMainScreen function in main function. If I send 5120 bytes from PC to nrf52840 and programming the data (5120 bytes) to my device, it is success. But I want to send 5120 bytes from PC to nrf52840 again. It will cause hardfault. 2nd: I cannot see the UART port if I open TeraTerm first (UART Rx/Tx application at PC) then power on the nrf52840. I can see the UART port if I open power on nrf52840 first then run the application of TeraTerm. How to solve these issues? Does Anyone can help me?


#define NRFX_USBD_EPSIZE 64
#define NRF_DRV_USBD_EPSIZE NRFX_USBD_EPSIZE

uint8_t m_tx_buffer[NRF_DRV_USBD_EPSIZE];

#define SEND_UART_STRING(a) \
do { \
size_t b = strlen((char*)m_tx_buffer); \
sysg_send_uart_string_to_device(a, b); \
}while(0)

/**
* @brief User event handler @ref app_usbd_cdc_acm_user_ev_handler_t (headphones)
* */
static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
app_usbd_cdc_acm_user_event_t event)
{
app_usbd_cdc_acm_t const * p_cdc_acm = app_usbd_cdc_acm_class_get(p_inst);

switch (event)
{
case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN:
{
//bsp_board_led_on(LED_CDC_ACM_OPEN);
NRF_LOG_INFO("APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN");
sysgApp_task.uart_connected = true;
/*Setup first transfer*/
ret_code_t ret = app_usbd_cdc_acm_read(&m_app_cdc_acm, m_rx_buffer, READ_SIZE);
UNUSED_VARIABLE(ret);
break;
}
case APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE:
//bsp_board_led_off(LED_CDC_ACM_OPEN);
NRF_LOG_INFO("APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE");
sysgApp_task.uart_connected = false;
break;

case APP_USBD_CDC_ACM_USER_EVT_TX_DONE:
//bsp_board_led_invert(LED_CDC_ACM_TX);
NRF_LOG_INFO("APP_USBD_CDC_ACM_USER_EVT_TX_DONE");
break;

case APP_USBD_CDC_ACM_USER_EVT_RX_DONE:
{
NRF_LOG_INFO("APP_USBD_CDC_ACM_USER_EVT_RX_DONE");
ret_code_t ret;
do
{
uart_data_parse(m_rx_buffer[0]);
/* Fetch data until internal buffer is empty */
ret = app_usbd_cdc_acm_read(&m_app_cdc_acm, m_rx_buffer, 1);
} while (ret == NRF_SUCCESS);
break;
}

default:
break;
}
}

void displayMainScreen(void)
{
sprintf((char*)m_tx_buffer, "\033[2J"); //clear screen
SEND_UART_STRING(m_tx_buffer);

sprintf((char*)m_tx_buffer, "\033[H"); //move the cursor to home position
SEND_UART_STRING(m_tx_buffer);

sprintf((char*)m_tx_buffer, "MKW01 TPMS OTA Testing v%d.%02d \r\n", FW_VER_MAJOR, FW_VER_MINOR);
SEND_UART_STRING(m_tx_buffer);

sprintf((char*)m_tx_buffer, "Options: %3dMHz, Try %2d, flash size: 0x%4x, erase: 0xD400, LFID: 0x%4x\r\n"
,CARRIER_FREQ, TRY_TIMES, DEST_CODE_SIZE-4, LF_WAKEUP_ID_APP);
SEND_UART_STRING(m_tx_buffer);

sprintf((char*)m_tx_buffer, "entry_key: (%c%c%c%c%c%c%c%c%c%c) %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\r\n",
BootEntryKey[4], BootEntryKey[5], BootEntryKey[6], BootEntryKey[7], BootEntryKey[8],
BootEntryKey[9], BootEntryKey[10],BootEntryKey[11],BootEntryKey[12],BootEntryKey[13],
BootEntryKey[4], BootEntryKey[5], BootEntryKey[6], BootEntryKey[7], BootEntryKey[8],
BootEntryKey[9], BootEntryKey[10],BootEntryKey[11],BootEntryKey[12],BootEntryKey[13]);
SEND_UART_STRING(m_tx_buffer);

sprintf((char*)m_tx_buffer, "TPMSID: 0xFF 0xFF 0xFF 0xFF\r\n");
SEND_UART_STRING(m_tx_buffer);

sprintf((char*)m_tx_buffer, ">>Press SW1 for FLASH PROGRAM command\r\n");
SEND_UART_STRING(m_tx_buffer);

sprintf((char*)m_tx_buffer, ">>Press SW2 for ERASE FLASH command\r\n");
SEND_UART_STRING(m_tx_buffer);

sprintf((char*)m_tx_buffer, "Please upload firmware(binary format) to kw01\r\n");
SEND_UART_STRING(m_tx_buffer);
}

void sysg_send_uart_string_to_device(uint8_t* pdata, uint8_t len)
{
ret_code_t ret;
if(sysgApp_task.system_setting.usb_mode == OUTPUT_USB)
{
if(sysgApp_task.uart_connected)
{
do {
ret = app_usbd_cdc_acm_write(&m_app_cdc_acm, pdata, len);
} while(ret == NRF_ERROR_BUSY);
}
}
}

int main(void)
{
...
displayMainScreen();
....
}

Parents
  • Hello,

    You say that you run into a hardfault? I suspect that you mean an app_error? What does it look like? Does the log say anything?

    2: When the application isn't running, then the USB is not enumerated, so the computer will not detect it as a USB device before it is running. Usually, USB devices will get power from the USB port, so it will start the application once you plug it in.

    BR,

    Edvin

  •  Sorry to bother you. It seems the code cause the hardfault as follows. The code prints too long, it prints about 77 characters. But the m_tx_buffer has only 64 bytes. I need to do more test. Thank you very much.

    sprintf((char*)m_tx_buffer, "Options: %3dMHz, Try %2d, flash size: 0x%4x, erase: 0xD400, LFID: 0x%4x\r\n"
    ,CARRIER_FREQ, TRY_TIMES, DEST_CODE_SIZE-4, LF_WAKEUP_ID_APP);
    SEND_UART_STRING(m_tx_buffer); 

Reply
  •  Sorry to bother you. It seems the code cause the hardfault as follows. The code prints too long, it prints about 77 characters. But the m_tx_buffer has only 64 bytes. I need to do more test. Thank you very much.

    sprintf((char*)m_tx_buffer, "Options: %3dMHz, Try %2d, flash size: 0x%4x, erase: 0xD400, LFID: 0x%4x\r\n"
    ,CARRIER_FREQ, TRY_TIMES, DEST_CODE_SIZE-4, LF_WAKEUP_ID_APP);
    SEND_UART_STRING(m_tx_buffer); 

Children
  • Yes. That sounds like a possible issue. If you write too long byte arrays into smaller sized buffers, then you will continue to write after the buffer address, changing whatever is behind that in flash. It can typically lead to hard faults. Try increasing the size of the buffer, or lowering the size of the string that you write.

    Best regards,

    Edvin

Related