<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Debugging a Hardfualt</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/14037/debugging-a-hardfualt</link><description>My app is generating hardfualts. Based on this post I looked at memory location SP + 0x14, which points to the address that generated the fault. 
 Memory at SP+0x14: 8F 31 02 00, which is address 0x0002318F. Which points to: 
 void on_tx_complete(const</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Mon, 30 May 2016 15:25:49 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/14037/debugging-a-hardfualt" /><item><title>RE: Debugging a Hardfualt</title><link>https://devzone.nordicsemi.com/thread/53679?ContentTypeID=1</link><pubDate>Mon, 30 May 2016 15:25:49 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:a0e69738-8b6e-456f-b394-baf8b83ca7a1</guid><dc:creator>c cook</dc:creator><description>&lt;p&gt;I have Joseph Yiu&amp;#39;s book on order and hopefully, that will help me better understand the clues that I are available. Any additional suggestions would be gratefully appreciated.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Debugging a Hardfualt</title><link>https://devzone.nordicsemi.com/thread/53678?ContentTypeID=1</link><pubDate>Mon, 30 May 2016 15:17:29 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:74ed4eb3-4a63-40e2-80a3-1d2e690aa483</guid><dc:creator>c cook</dc:creator><description>&lt;p&gt;RK -
Short answer - no. My timer function, which was not using scheduler,  is where the majority of my application executes, either in the handler itself, or calls made by the handler. I agree pin-pointing the exact cause is needed.  With your help, I believe the hard fault is being generated while servicing SWI2.  Breaking when the hard fault occurs, the call stack often lists tx_buffer_process().  If tx_buffer_process is not listed, then it&amp;#39;s usually my event handler for BLE events - which in my application, calls tx_buffer_process, and makes multiple calls to sd_ble_gattc_write().
What&amp;#39;s my next step to pin point the cause?  I&amp;#39;ve code in place to check for null pointers, I&amp;#39;ve tried to trace back to offending calls and can&amp;#39;t seem to pinpoint anything. Moving to the timer to use the scheduler seems to have stopped the hard fualts.  Which supports the theory of SWI2.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Debugging a Hardfualt</title><link>https://devzone.nordicsemi.com/thread/53677?ContentTypeID=1</link><pubDate>Sat, 28 May 2016 00:34:18 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:eb992498-4d6e-44d2-b4b0-2ba6a643b6ef</guid><dc:creator>RK</dc:creator><description>&lt;p&gt;but did you actually pinpoint what it was about the timer which was causing the hardfault? Timers are not themselves prone to causing them, if you weren&amp;#39;t calling sd_* functions from the wrong interrupt level that wasn&amp;#39;t it, did you actually work out what the problem was?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Debugging a Hardfualt</title><link>https://devzone.nordicsemi.com/thread/53676?ContentTypeID=1</link><pubDate>Fri, 27 May 2016 03:19:39 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:2f1af973-28e7-4cf5-9fab-b90546289608</guid><dc:creator>RK</dc:creator><description>&lt;p&gt;what&amp;#39;s at 0x01EB40, or an instruction one before that as the PC moves on before the instruction is actually executed and the stacked address is the return PC, which you aren&amp;#39;t actually going to return to.&lt;/p&gt;
&lt;p&gt;What is m_evt_schedule_func in your code, are you using the scheduler?&lt;/p&gt;
&lt;p&gt;What it looks like here is that you&amp;#39;re executing tx_buffer_process() in thread mode when the softdevice interrupt occurs (SWI2), which is fine, it&amp;#39;s taken that interrupt and fallen over in the handler code.&lt;/p&gt;
&lt;p&gt;If you don&amp;#39;t have an event scheduler and are processing events directly inside the SWI2 interrupt then .. it&amp;#39;s not possible to be where you are as you cannot have one interrupt interrupt itself.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Debugging a Hardfualt</title><link>https://devzone.nordicsemi.com/thread/53675?ContentTypeID=1</link><pubDate>Thu, 26 May 2016 12:38:56 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:dfa4bcb0-45d0-41e1-9717-19c192ecfc95</guid><dc:creator>c cook</dc:creator><description>&lt;p&gt;Based on your comments in: How can I distinguish the reason for hardfault? I looked at SP+0x18, which is the PC right?  The word following the program counter is the PSP and has the value of: 0x20000026.  The link register has: 0xFFFFFFF1 - which signifies a return from an interrupt.  Using the last byte of the PSP (0x26) = 38,  38 - 16 = Interrupt 22.  Which is the SWI2_IRQHandler.&lt;/p&gt;
&lt;p&gt;Based on what I know about ARM, is it possible that my code was executing SWI2_IRQHandler, and a higher priority interrupt occurred?&lt;/p&gt;
&lt;p&gt;&lt;img src="https://devzone.nordicsemi.com/cfs-file/__key/communityserver-discussions-components-files/4/ScreenHunter_5F00_26-May.-26-15.42.jpg" alt="image description" /&gt;
&lt;img src="https://devzone.nordicsemi.com/cfs-file/__key/communityserver-discussions-components-files/4/ScreenHunter_5F00_25-May.-26-15.41.jpg" alt="image description" /&gt;&lt;/p&gt;
&lt;p&gt;Now where do I go?
nrf_soc.h defines this software interrupt as:
&amp;#39;#define SD_EVT_IRQHandler                 (SWI2_IRQHandler)&lt;/p&gt;
&lt;p&gt;The interrupt handler is in softdevice_handler.c and looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;void SOFTDEVICE_EVT_IRQHandler(void)
{
    if (m_evt_schedule_func != NULL)
    {
        uint32_t err_code = m_evt_schedule_func();
        APP_ERROR_CHECK(err_code);
    }
    else
    {
        intern_softdevice_events_execute();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So based on ARM&amp;#39;s documentation I think another interrupt with the same or higher priority tried to execute.  What can I look for to verify this is the cause, and how to prevent it?&lt;/p&gt;
&lt;p&gt;My app is a central multilink device.  Often when the fault occurs, I get an 0x3004 error from sd_ble_gattc_write().  I halt trying to write more data until I get a BLE_EVT_TX_COMPLETE event.  I resume calling sd_ble_gattc_write(), the first call returns an error 0x0000, and then the crash occurs.  Could the sd120 stack be generating a second SWI2, while I&amp;#39;m still servicing an earlier SWI2 interrupt.  Because this second interrupt as the same priority, the ARM hard faults?&lt;/p&gt;
&lt;p&gt;EDIT:
RK - thanks for the help! I think I&amp;#39;ve got it fixed.&lt;/p&gt;
&lt;p&gt;I have an application timer that was running in the IRQ.  I installed the the app timer scheduler library and moved the timer to run there.  So far I have not seen any more hard faults.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Debugging a Hardfualt</title><link>https://devzone.nordicsemi.com/thread/53674?ContentTypeID=1</link><pubDate>Thu, 26 May 2016 03:23:47 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:92b72579-639e-48b4-ac7c-9e9a0a15e0f0</guid><dc:creator>RK</dc:creator><description>&lt;p&gt;Start again time. I just read your original post again and noticed SP+0x14, that&amp;#39;s not right, it&amp;#39;s SP+0x18 for the PC, SP+0x14 is the LR at the time of the hardfault, ie where you came from before you hit the routine you hardfaulted in. So actually you hardfaulted in tx_buffer_process(), or possibly in APP_ERROR_CHECK(). Given the DEADBEEF in r2 something fun has happened.&lt;/p&gt;
&lt;p&gt;So .. how about a dump of the 16 32bit words starting at the SP, ie 0x20003fe0 to 0x20004010 and let&amp;#39;s try again.&lt;/p&gt;
&lt;p&gt;It&amp;#39;s hardfault week. I spent a long time on one yesterday, and ended up cursing the memory watch unit on the nRF52.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Debugging a Hardfualt</title><link>https://devzone.nordicsemi.com/thread/53673?ContentTypeID=1</link><pubDate>Wed, 25 May 2016 22:02:44 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:1435257b-5622-400c-b436-117d83c2a254</guid><dc:creator>c cook</dc:creator><description>&lt;p&gt;DK- Thanks for you help.
When hardfult occurs, the PC is pointing to my the hardfault handler.
The 16 bytes before the SP are:
00 00 00 00 F8 60 02 00 A4 600200 9C 60 02 00
In Keil Register window the SP = 0x200045F0
But the memory window, with SP for the address shows: 0x00003004 (04 30 00 00), which is the error code I get back from a call to sd_ble_gattc_write(), just before the fault occurs.  It seems more too much of a coincidence that the memory window shows my error code. Is this a clue as to whats happening?
You stated that the 4 values before the SP are R4-R7.  So the first four bytes is the old R4?  Are these the addresses that where in the SP, LR and PC?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Debugging a Hardfualt</title><link>https://devzone.nordicsemi.com/thread/53669?ContentTypeID=1</link><pubDate>Wed, 25 May 2016 00:31:02 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d68f2a7f-1a00-49f7-9821-583d4239448d</guid><dc:creator>RK</dc:creator><description>&lt;p&gt;Doesn&amp;#39;t look that close to me - but map files aren&amp;#39;t easy to read, especially when all on one line and there could be other entries other places (where&amp;#39;s the heap for a start, perhaps you don&amp;#39;t use a heap). Try the other things on the list, see where you usually return to from that code, see what&amp;#39;s left just off the stack when you hardfault to see if the address is different, or invalid. If you&amp;#39;re sure it&amp;#39;s the pop, and it looks quite plausible, something corrupted the stack.&lt;/p&gt;
&lt;p&gt;As for that post, he gets 0x800 from the fact his stack is 2048 bytes, it&amp;#39;s right there in a comment on the line.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Debugging a Hardfualt</title><link>https://devzone.nordicsemi.com/thread/53671?ContentTypeID=1</link><pubDate>Tue, 24 May 2016 17:14:26 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d4299ad8-d535-4588-bfb2-36ab03433896</guid><dc:creator>c cook</dc:creator><description>&lt;p&gt;I was looking at this &lt;a href="https://devzone.nordicsemi.com/question/41175/stack-tracing-with-softdevice/"&gt;post&lt;/a&gt; and want to use it, in my application. When he calculates stack size it&amp;#39;s stackStart - 0x800.  Where did the 0x800 come from?  Where is my stack size set?  I
FYI: I&amp;#39;m running a nRF51422 with 32K RAM.  SD120 V2.1 and Target settings: IRAM1:0x20002800/0x5800&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Debugging a Hardfualt</title><link>https://devzone.nordicsemi.com/thread/53670?ContentTypeID=1</link><pubDate>Tue, 24 May 2016 16:49:41 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:9f83e1d2-4ff6-4502-9d47-ccd67df4a833</guid><dc:creator>c cook</dc:creator><description>&lt;p&gt;RK - thanks for the response.  I&amp;#39;m using nRF51422QFAC with 32K RAM with S120 V2.1&lt;br /&gt;
The last 3 addresses in my map file are:
m_dfus                                   0x20003140   Data          48  add_gatts.o(.bss)
m_connection_table                        0x20003410   Data          96  device_manager_central_cc.o(.bss)
__libspace_start                             0x200035d4   Data          96  libspace.o(.bss)
__temporary_stack_top$libspace     0x20003634   Data           0  libspace.o(.bss)
I&amp;#39;m not sure if that counts as &amp;quot;just around&amp;quot; 0x20003FE0&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Debugging a Hardfualt</title><link>https://devzone.nordicsemi.com/thread/53672?ContentTypeID=1</link><pubDate>Tue, 24 May 2016 00:01:40 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:39f21747-dd70-4260-bd69-0c4a87e05683</guid><dc:creator>RK</dc:creator><description>&lt;p&gt;First guess would be that your stack&amp;#39;s too small and you&amp;#39;re corrupting the end of it during the tx_buffer_process() code on occasion and so the PC value loaded is wrong and you hardfault. That stack pointer looks low enough to make you wonder.&lt;/p&gt;
&lt;p&gt;Things I&amp;#39;d try next. You probably get to this routine via the same path every time, breakpoint in it and see what the link register is on the way in, or the PC on the way out, is it different from 0x1D1F0 (which should be 0x1D1F1 on the stack) which I think is where you&amp;#39;ve returned to.&lt;/p&gt;
&lt;p&gt;At the point of the hardfault you&amp;#39;ve just popped 4 things off the stack, they should still be in memory just under where the SP is now, what are they? You should recognise the values popped into r4-r6 and the PC. Is the PC value even?&lt;/p&gt;
&lt;p&gt;Look at your memory map. Is any data, or the heap, just around the 0x20003FE0 area, that would point to a stack overflow.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>