corrupt pointer causes ImpreciseErr HardFault

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

corrupt pointer causes ImpreciseErr HardFault

1,294 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Telemetry on Fri May 31 06:20:46 MST 2013
For a graduation project I'm designing a datalogging system with telemetry functionality based on the LPC1768.

Datalogging: Data from various sensors is written to a SD-card.
Telemetry  : Data from various sensors is periodically send through an ethernet connection.

The system is capable of performing both of these functionalities.
I have run in to a problem. I tested both these functionalities together in an early stage of the software development. I temporarily commented out the telemetry part of the code to focus on the datalogging. Since I'm testing the telemetry part again. I keep getting HardFault exceptions (ImpreciseErr). It seems like a pointer gets corrupted with data from one of the global buffers and points in to an invalid memory location.

To increase the bandwidth of the datalogging I use a HUGE buffer.
The buffer is split into two parts. One part takes op the entire 32 KiB AHB SRAM space. The other part takes op 16KiB of local SRAM.
The total size of the bss is less than 21KiB of the available 32KiB local SRAM. Plenty left for stack I presume.

This is where the error occurs:
 
if (fs) { 
  fs->fs_type = 0; //error occurs here


Disassembler:
1984                            if (fs) {
00004438: f_mount+20             cbz r1, 0x4440 <f_mount+28>
1985                             fs->fs_type = 0;   /* Clear new fs object */
0000443a: f_mount+22             mov.w r3, #0
0000443e: f_mount+26             strb r3, [r1, #0]


The pointer fs is supposed to hold the address 0x10004334.

R1=0
R3=0x3c3d1a1c (the same data is found in a global buffer)

This is the entire function:

RESULT f_mount (
 uint8_t vol,  /* Logical drive number to be mounted/unmounted */
 FATFS *fs  /* Pointer to new file system object (NULL for unmount)*/
)
{
 FATFS *rfs;
 
 if (vol >= _VOLUMES)   /* Check if the drive number is valid */
  return FR_INVALID_DRIVE;
 rfs = FatFs[vol];    /* Get current fs object */
 if (rfs) {
#if _FS_SHARE
  clear_lock(rfs);
#endif
#if _FS_REENTRANT     /* Discard sync object of the current volume */
  if (!ff_del_syncobj(rfs->sobj)) return FR_INT_ERR;
#endif
  rfs->fs_type = 0;   /* Clear old fs object */
 }
 if (fs) {
  fs->fs_type = 0;   /* Clear new fs object */
#if _FS_REENTRANT     /* Create sync object for the new volume */
  if (!ff_cre_syncobj(vol, &fs->sobj)) return FR_INT_ERR;
#endif
 }
 FatFs[vol] = fs;    /* Register new fs object */
 return FR_OK;
}


FatFs[0] is initialized with zero, yet it contains the value 0x3c3d1a1c after a while. The variable is only changed in one part of the code, so it has to be corrupted by a pointer error or a crash between the stack and the heap or something.

Is there a way to find out where and when a certain variable is changed(data breakpoint)?

By the way debugging takes a lot of time since recovering from the hardfault requires multiple restarts of the debugger. Is there a way to restart the debugger more quickly?
0 Kudos
Reply
2 Replies

1,130 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by sylvio on Fri Jun 03 02:06:31 MST 2016
I had the same problem... if it could help anybody, the cause was another one :
Because of a misconfiguration of the project in the compiler the global variables were not initialized to zero... so "rfs" was not null and on first call of the function if(rfs) was true and rfs->fs_type = 0; pointed to a random address !
0 Kudos
Reply

1,130 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Telemetry on Mon Jun 03 03:19:08 MST 2013
I've found the source of the problem!

It turns out the problem was in the (use of) the udp library.

I used the udp library of Aart Janse van den Bosch found in an example written by user Zero (LPC17_UDPIPsample22032012.zip).

The problem is that the library doesn't check the size of the ethernet packet arrays when copying data to it. The size of ETH_FRAG_SIZE has to be at least UDP_DATA_OFS + udp data. The udp udpipSend() function now exits when ETH_FRAG_SIZE is incorrect.

 
[FONT=Fixedsys]uint16_t udpipSend(uint8_t idx, void* buf, uint16_t len){[/FONT]
 
 
 
 
 
[FONT=Fixedsys]   uint16_t  index;[/FONT]
 
 
[FONT=Fixedsys]    uint16_t  next_index;[/FONT]
 
 
[FONT=Fixedsys]    uint8_t*  txbuf;[/FONT]
 
 
 
 
 
[FONT=Fixedsys]  if(idx>=UDPIP_SERVICES) return -1;[/FONT]
 
 
 
 
 
[FONT=Fixedsys]    if(len==0) return -3; //no data[/FONT]
 
 
[FONT=Fixedsys]    if(ETH_FRAG_SIZE<(UDP_DATA_OFS+len)) return -4;//packet doesn't fit in [/FONT]
[FONT=Fixedsys]array[/FONT]


ps; two questions:
0 ) Why do the code-tags screw up the code style? Every new line is removed.
1 ) Why are forum topics sorted by descending order? This doesn't make any sense. If I click on first it shows the last post and vice versa!
0 Kudos
Reply