BUS FAULT when working with ASYNC UART

Good Day.

When working with the UART in asynchronous mode, I occasionally get this error:

E: ***** BUS FAULT *****
E:   Precise data bus error
E:   BFAR Address: 0x20040000
E: r0/a1:  0x20000e90  r1/a2:  0x00000000  r2/a3:  0x0003f11e
E: r3/a4:  0x20000ee2 r12/ip:  0x20000380 r14/lr:  0x00000a51
E:  xpsr:  0x21000012
E: s[ 0]:  0x00008048  s[ 1]:  0x000125a4  s[ 2]:  0x00000000  s[ 3]:  0x00008048
E: s[ 4]:  0x40002000  s[ 5]:  0x00000000  s[ 6]:  0x20000118  s[ 7]:  0x00000a8f
E: s[ 8]:  0x00000a71  s[ 9]:  0x000073c9  s[10]:  0x20000ee2  s[11]:  0x00000005
E: s[12]:  0x00000000  s[13]:  0x00000000  s[14]:  0x00000000  s[15]:  0x00000000
E: fpscr:  0x00008048
E: Faulting instruction address (r15/pc): 0x000009e0
E: >>> ZEPHYR FATAL ERROR 25: Unknown error on CPU 0
E: Fault during interrupt handling

E: Current thread: 0x20000380 (unknown)
E: Resetting system<CR>*** Booting nRF Connect SDK v2.5.99-dev1 ***

Please tell me what this is related to and how to fix it.

Thank you.

Parents
  • Hello,

    The bus fault occurs during the UARTE0 interrupt, likely within the callback. Please use addr2line on the 'Faulting instruction address' to determine the corresponding code line.

    You can do this from the terminal in vs code. In vs code, press Ctrl+Shift+P and select 'nRF Connect: Open Toolchain Terminal Profile'. Then from the terminal, navigate to your project source directory and run the command below.

    $ arm-zephyr-eabi-addr2line -e build/zephyr/zephyr.elf  0x9e0

    Best regards,

    Vidar

  • Hi Vidar

    After entering a command, I get this error:

    $ : The name "$" is not recognized........

    + $ arm-zephyr-eabi-addr2line -e build/zephyr/zephyr.elf 0x9e0
    + ~
    + CategoryInfo : ObjectNotFound: ($:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

  • Hi,

    Please remove the '$' character at the beginning of the command. 

  • Thanks. After entering the command I get the following response:

    C:\nordic\myapps\customblinky\build/../src/main.c:65

    If I understand correctly, it points to an error in line 65?

    In the program code at line 65 I check the condition if(rx_buf[i] == '$') and look for the beginning of the line in the NMEA packet received from GNSS.

    I can't understand why this error occurs.

  • If I understand correctly, it points to an error in line 65?

    Yes, correct. Could you post the code surrounding this line as well? Based on this and the BFAR address, it appears that the rx_buf is pointing to an invalid memory address (RAM ends at 0x20040000). 

  • /* Receive buffer */
    static uint8_t rx_buf[512] = {0};
    /* Buffer for NMEA sentence*/
    volatile static uint8_t sentence[82] = {0};

    The algorithm of the program is as follows:

    I receive data from GNSS until the buffer is completely filled. In the UART_RX_BUF_RELEASED event, I run the getStrFromRxBuffer() function which finds the $GNRMC string in the rx_buf receive buffer. Then I run the work to parsing the found string - k_work_submit 

    case UART_RX_BUF_RELEASED:
    	getStrFromRxBuffer();
    	k_work_submit(&gnss_work);
    	break;

    Function getStrFromRxBuffer():

    char * getStrFromRxBuffer(void){
    	volatile bool waitingForStrBegin = true;
    	volatile bool waitingReadySentence = false;
    	volatile static int index = 0; /* index inside sentence buffer */
    	volatile static int i = 0; /* index inside rx_buf */
    
    while(!waitingReadySentence){
    
    	while(waitingForStrBegin){
    		if(rx_buf[i] == '$'){    // is line 65 in the original program code
    			index = 0;
    			sentence[index++] = rx_buf[i++];
    			waitingForStrBegin = false;
    		}
    		else{
    			i++;
    		}
    	}
    
    	while(rx_buf[i] != '\n'){
    		sentence[index++] = rx_buf[i++];
    	}
    
    	sentence[index] = '\0';
    
    	const char * prefix = "$GNRMC";
    	if(strncmp(sentence, prefix, strlen(prefix)) == 0){
    		waitingReadySentence = true;
    		return sentence;
    		}
    		else {
    		memset(sentence, 0, sizeof(sentence));
    		index = 0;
    		waitingForStrBegin = true;
    		}
    	}
    }

    Inside the work function, I clear the sentence and rx_buf buffers and then turn on the UART receiver and everything repeats again.

    static void gnss_work_cb (struct k_work *work){
    
    struct minmea_sentence_rmc frame;
    if(minmea_parse_rmc(&frame, sentence)){
                    LOG_DBG("\n Latitude: %f\n Longitude: %f\n Speed: %f\n",
                            minmea_tocoord(&frame.latitude),
                            minmea_tocoord(&frame.longitude),
                            minmea_tofloat(&frame.speed));
                }
                else {
                     LOG_DBG(INDENT_SPACES "$GNRMC sentence is not parsed\n");
                }
    	memset(sentence, 0, sizeof(sentence));
    	memset(rx_buf, 0, sizeof(rx_buf));
    	uart_rx_enable(uart, rx_buf, sizeof(rx_buf), RECEIVE_TIMEOUT);
    }

  • Thanks for the additional information. I don't see anything that would prevent 'rx_buf' from overrunning in cases where the '$' might not be found. The 'i' index will just keep incrementing until it triggers a fault.

Reply Children
Related