Сразу хочу извиниться дизасм сделал гнусным objdump, так как кейловским fromelf пользоваться не очень умею. В принципе разницы быть не должно, так как исходный файл в elf формате.
hard fault был после вызова по адресу 1324c, так как в r0 была ересь, которая попала туда из r5.
Самое примечательное, что до той строчки внутри функции все было ок, то есть в r5 ереси не было. Сама функция uart_irq_handler является прерывание, но с низким приоритетом, то есть ее вытеснить и испоганить r5 могло только прерывание с высоким приоритетом. r5 нигде не пишется кроме адреса 13174.
Сам код собственно даже не наш, а взят из SDK Nordic.
CODE
#if defined(UART_IN_USE)
__STATIC_INLINE void uart_irq_handler()
{
13170: e92d 4bff stmdb sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, fp, lr}
if (nrf_uart_int_enable_check(NRF_UART0, NRF_UART_INT_MASK_ERROR) &&
13174: 4d43 ldr r5, [pc, #268]; (13284 <uart_irq_handler+0x114>)
}
#if defined(UART_IN_USE)
__STATIC_INLINE void uart_irq_handler()
{
13176: f10d 0b2c add.w fp, sp, #44; 0x2c
if (nrf_uart_int_enable_check(NRF_UART0, NRF_UART_INT_MASK_ERROR) &&
1317a: f44f 7100 mov.w r1, #512; 0x200
1317e: 4628 mov r0, r5
13180: f7fc f920 bl f3c4 <nrf_uart_int_enable_check>
13184: 2701 movs r7, #1
nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_ERROR))
{
nrf_drv_uart_event_t event;
nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_ERROR);
nrf_uart_int_disable(NRF_UART0, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR);
if (!m_cb.rx_enabled)
13186: 4c40 ldr r4, [pc, #256]; (13288 <uart_irq_handler+0x118>)
if (nrf_uart_int_enable_check(NRF_UART0, NRF_UART_INT_MASK_ERROR) &&
nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_ERROR))
{
nrf_drv_uart_event_t event;
nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_ERROR);
nrf_uart_int_disable(NRF_UART0, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR);
13188: f44f 7801 mov.w r8, #516; 0x204
1318c: 2600 movs r6, #0
#if defined(UART_IN_USE)
__STATIC_INLINE void uart_irq_handler()
{
if (nrf_uart_int_enable_check(NRF_UART0, NRF_UART_INT_MASK_ERROR) &&
1318e: b318 cbz r0, 131d8 <uart_irq_handler+0x68>
nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_ERROR))
13190: f44f 7192 mov.w r1, #292; 0x124
13194: 4628 mov r0, r5
13196: f7fc f907 bl f3a8 <nrf_uart_event_check>
1319a: b1e8 cbz r0, 131d8 <uart_irq_handler+0x68>
1319c: f8c5 6124 str.w r6, [r5, #292]; 0x124
131a0: f8c5 8308 str.w r8, [r5, #776]; 0x308
{
nrf_drv_uart_event_t event;
nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_ERROR);
nrf_uart_int_disable(NRF_UART0, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR);
if (!m_cb.rx_enabled)
131a4: 7ea0 ldrb r0, [r4, #26]
131a6: b900 cbnz r0, 131aa <uart_irq_handler+0x3a>
131a8: 606f str r7, [r5, #4]
{
nrf_uart_task_trigger(NRF_UART0, NRF_UART_TASK_STOPRX);
}
event.type = NRF_DRV_UART_EVT_ERROR;
131aa: 2002 movs r0, #2
131ac: f80b 0c2c strb.w r0, [fp, #-44]
131b0: f8d5 0480 ldr.w r0, [r5, #1152]; 0x480
131b4: f8c5 0480 str.w r0, [r5, #1152]; 0x480
event.data.error.error_mask = nrf_uart_errorsrc_get_and_clear(NRF_UART0);
131b8: f84b 0c20 str.w r0, [fp, #-32]
event.data.error.rxtx.bytes = m_cb.rx_buffer_length;
131bc: 7de0 ldrb r0, [r4, #23]
131be: f80b 0c24 strb.w r0, [fp, #-36]
event.data.error.rxtx.p_data = m_cb.p_rx_buffer;
131c2: 68e0 ldr r0, [r4, #12]
131c4: f84b 0c28 str.w r0, [fp, #-40]
//abort transfer
m_cb.rx_buffer_length = 0;
131c8: 75e6 strb r6, [r4, #23]
m_cb.rx_secondary_buffer_length = 0;
131ca: 7626 strb r6, [r4, #24]
m_cb.handler(&event,m_cb.p_context);
131cc: e9d4 1200 ldrd r1, r2, [r4]
131d0: f1ab 002c sub.w r0, fp, #44; 0x2c
131d4: 4790 blx r2
}
131d6: e024 b.n 13222 <uart_irq_handler+0xb2>
else if (nrf_uart_int_enable_check(NRF_UART0, NRF_UART_INT_MASK_RXDRDY) &&
131d8: 2104 movs r1, #4
131da: 4628 mov r0, r5
131dc: f7fc f8f2 bl f3c4 <nrf_uart_int_enable_check>
131e0: b1f8 cbz r0, 13222 <uart_irq_handler+0xb2>
nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_RXDRDY))
131e2: f44f 7184 mov.w r1, #264; 0x108
131e6: 4628 mov r0, r5
131e8: f7fc f8de bl f3a8 <nrf_uart_event_check>
131ec: b1c8 cbz r0, 13222 <uart_irq_handler+0xb2>
{
rx_byte();
131ee: f7fe f89b bl 11328 <rx_byte>
if (m_cb.rx_buffer_length == m_cb.rx_counter)
131f2: 7de0 ldrb r0, [r4, #23]
131f4: 7e61 ldrb r1, [r4, #25]
131f6: 4288 cmp r0, r1
131f8: d113 bne.n 13222 <uart_irq_handler+0xb2>
{
if (m_cb.rx_secondary_buffer_length)
131fa: 7e22 ldrb r2, [r4, #24]
131fc: b13a cbz r2, 1320e <uart_irq_handler+0x9e>
{
uint8_t * p_data = m_cb.p_rx_buffer;
uint8_t rx_counter = m_cb.rx_counter;
131fe: 7e60 ldrb r0, [r4, #25]
13200: 68e1 ldr r1, [r4, #12]
//Switch to secondary buffer.
m_cb.rx_buffer_length = m_cb.rx_secondary_buffer_length;
13202: 75e2 strb r2, [r4, #23]
m_cb.p_rx_buffer = m_cb.p_rx_secondary_buffer;
13204: 6922 ldr r2, [r4, #16]
m_cb.rx_secondary_buffer_length = 0;
13206: 60e2 str r2, [r4, #12]
13208: 7626 strb r6, [r4, #24]
m_cb.rx_counter = 0;
1320a: 7666 strb r6, [r4, #25]
rx_done_event(rx_counter, p_data);
}
1320c: e007 b.n 1321e <uart_irq_handler+0xae>
else
{
if (!m_cb.rx_enabled)
1320e: 7ea0 ldrb r0, [r4, #26]
13210: b900 cbnz r0, 13214 <uart_irq_handler+0xa4>
13212: 606f str r7, [r5, #4]
13214: f8c5 8308 str.w r8, [r5, #776]; 0x308
{
nrf_uart_task_trigger(NRF_UART0, NRF_UART_TASK_STOPRX);
}
nrf_uart_int_disable(NRF_UART0, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR);
m_cb.rx_buffer_length = 0;
13218: 75e6 strb r6, [r4, #23]
rx_done_event(m_cb.rx_counter, m_cb.p_rx_buffer);
1321a: 7e60 ldrb r0, [r4, #25]
1321c: 68e1 ldr r1, [r4, #12]
//Switch to secondary buffer.
m_cb.rx_buffer_length = m_cb.rx_secondary_buffer_length;
m_cb.p_rx_buffer = m_cb.p_rx_secondary_buffer;
m_cb.rx_secondary_buffer_length = 0;
m_cb.rx_counter = 0;
rx_done_event(rx_counter, p_data);
1321e: f7fe f8a3 bl 11368 <rx_done_event>
rx_done_event(m_cb.rx_counter, m_cb.p_rx_buffer);
}
}
}
if (nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_TXDRDY))
13222: f44f 718e mov.w r1, #284; 0x11c
13226: 4628 mov r0, r5
13228: f7fc f8be bl f3a8 <nrf_uart_event_check>
1322c: b158 cbz r0, 13246 <uart_irq_handler+0xd6>
{
if (m_cb.tx_counter < (uint16_t) m_cb.tx_buffer_length)
1322e: 8aa1 ldrh r1, [r4, #20]
13230: 7da0 ldrb r0, [r4, #22]
13232: 4281 cmp r1, r0
13234: d202 bcs.n 1323c <uart_irq_handler+0xcc>
{
tx_byte();
13236: f7ff fea1 bl 12f7c <tx_byte>
1323a: e004 b.n 13246 <uart_irq_handler+0xd6>
1323c: f8c5 611c str.w r6, [r5, #284]; 0x11c
}
else
{
nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_TXDRDY);
if (m_cb.tx_buffer_length)
13240: b108 cbz r0, 13246 <uart_irq_handler+0xd6>
{
tx_done_event(m_cb.tx_buffer_length);
13242: f7ff feb5 bl 12fb0 <tx_done_event>
}
}
}
if (nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_RXTO))
13246: f44f 71a2 mov.w r1, #324; 0x144
1324a: 4628 mov r0, r5
1324c: f7fc f8ac bl f3a8 <nrf_uart_event_check>
13250: 46dd mov sp, fp
13252: 2800 cmp r0, #0
13254: b08b sub sp, #44; 0x2c
13256: d013 beq.n 13280 <uart_irq_handler+0x110>
13258: f8c5 6144 str.w r6, [r5, #324]; 0x144
{
nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_RXTO);
// RXTO event may be triggered as a result of abort call. In th
if (m_cb.rx_enabled)
1325c: 7ea0 ldrb r0, [r4, #26]
1325e: b100 cbz r0, 13262 <uart_irq_handler+0xf2>
13260: 602f str r7, [r5, #0]
{
nrf_uart_task_trigger(NRF_UART0, NRF_UART_TASK_STARTRX);
}
if (m_cb.rx_buffer_length)
13262: 7de0 ldrb r0, [r4, #23]
13264: 46dd mov sp, fp
13266: 2800 cmp r0, #0
13268: b08b sub sp, #44; 0x2c
1326a: d009 beq.n 13280 <uart_irq_handler+0x110>
{
m_cb.rx_buffer_length = 0;
1326c: 75e6 strb r6, [r4, #23]
rx_done_event(m_cb.rx_counter, m_cb.p_rx_buffer);
1326e: 7e60 ldrb r0, [r4, #25]
13270: 68e1 ldr r1, [r4, #12]
13272: b004 add sp, #16
13274: e8bd 4bf0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, fp, lr}
13278: f7fe b876 b.w 11368 <rx_done_event>
1327c: 46dd mov sp, fp
1327e: b08b sub sp, #44; 0x2c
}
}
}
13280: e8bd 8bff ldmia.w sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, fp, pc}
13284: 40002000 .word 0x40002000
13288: 200011d8 .word 0x200011d8
Цитата(jcxz @ Jun 21 2016, 16:19)

Посмотрите размер стека прерываний.
Ассемблерные вставки есть?
На стек 1024 байта выделили, так что по идее должно хватить, тем более модель памяти держим сходящуюся. Глобальные переменные с одного края памяти, стек с другого, так что даже при превышении размера стека, проедем по неиспользуемой памяти.
Ассемблерные вставки не используем.