Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: stm32f4discovery виснет раз в неделю
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Страницы: 1, 2
сарматъ
спасибо буду пробовать
сарматъ
наваял код на asm для обработчика __attribute__((noreturn, naked)) void Default_Handler(void) проверил его работоспособность эмулируя в программе сбой стека вот таким вот образом
Код
    asm volatile (
                "LDR R1,=0x08008000        \n"
                "MSR MSP, R1            \n"
            :
            :
            :
            );

в терминале любуюсь на
Код
SP_0x20003858 MSP_0x08008000 PSP_0x20003858 LR_0xFFFFFFFF PC_0x08002660        
CF_0x00040000 HF_0x00000000 DF_0x0000000A AF_0x00000000                        
MA_0xE000ED34 BA_0xE000ED38

убираю из программы эмуляцию сбоя, запускаю в работу, 4-ро суток макетка пашет как положено, на пятые сутки зависает, в терминале - тишина, как будто макетка просто в обморок упала и не дышит...

есть какие то предположения?
AHTOXA
Цитата(сарматъ @ Oct 1 2013, 15:19) *
есть какие то предположения?

Запустить на макетке простейшую мигалку светодиодом, и посмотреть, повиснет ли она.
Сергей Борщ
Подключиться отладчиком "на лету" во время такого зависания и посмотреть, куда ее занесло. Предварительно потренировавшись подключаться к независшей плате.
Возможно проблемы со стеком не дают работать вашему обработчику.

У вас программа с ОС? Вставьте в idle task махание ногой. Возможно это не зависание, а взаимная блокировка (deadlock) и ваша программа продолжает крутиться в idle task пока остальные процессы ждут заблокированные друг другом ресурсы. И в этом случае отладчик поможет найти кто кого и откуда заблокировал, без него будет трудно.
сарматъ
CODE
/*
* main.c
*
* Created on: 01 окт. 2013 г.
* Author: jura
*/


#include <stm32f4xx.h>

GPIO_InitTypeDef GPIO_InitStructure;

void Delay(__IO uint32_t nCount)
{
while(nCount--)
{
}
}



int main(void)
{


/* включаем тактирование порта D */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

/* конфигурируем выводы PD12, PD13, PD14 и PD15 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init(GPIOD, &GPIO_InitStructure);

while (1)
{
/* зажигаем зеленый (PD12) */
GPIO_SetBits(GPIOD, GPIO_Pin_12);

/* Задержка */
Delay(0x3FFFFF);

/* зажигаем оранжевый (PD13) */
GPIO_SetBits(GPIOD, GPIO_Pin_13);

/* Задержка */
Delay(0x3FFFFF);

/* зажигаем красный (PD14) */
GPIO_SetBits(GPIOD, GPIO_Pin_14);

/* Задержка */
Delay(0x3FFFFF);

/* зажигаем синий (PD15) */
GPIO_SetBits(GPIOD, GPIO_Pin_15);

/* Задержка */
Delay(0x7FFFFF);

/* сбрасываем все 4-ре */
GPIO_ResetBits(GPIOD, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);

/* Задержка */
Delay(0xFFFFFF);
}
}


залил вот, это любуюсь как моргают светодиодики, курю бамбук...

Цитата(Сергей Борщ @ Oct 1 2013, 15:57) *
Подключиться отладчиком "на лету" во время такого зависания и посмотреть, куда ее занесло. Предварительно потренировавшись подключаться к независшей плате.
Возможно проблемы со стеком не дают работать вашему обработчику.

У вас программа с ОС? Вставьте в idle task махание ногой. Возможно это не зависание, а взаимная блокировка (deadlock) и ваша программа продолжает крутиться в idle task пока остальные процессы ждут заблокированные друг другом ресурсы. И в этом случае отладчик поможет найти кто кого и откуда заблокировал, без него будет трудно.


а как подключаться к независшей? это без эклипса?

да программка с smcrtos

вообще у меня в паралельной задачке просто моргает светодиод никого не ожидая вот так вот
CODE
OS_PROCESS void TProc4::exec()
{//init_stack_frame();
for(;;)
{
for(;;)
{res_table.uregs[104]=Proc4.stack_slack();
GreenLED::On();
sleep(50);
GreenLED::Off();
sleep(950);
;
}
}
}


соотв когда зависает светодиод не моргает


про подключение на лету: это телнетом на openocd наехать и все регистры и память можно просмотреть? круто...
а я себе голову морочил с обработчиками и уартом

Сергей, вопрос: а можно как то не телнетом а сразу эклипсом цепляться к работающей плате?
там какие то заклинания должны стоять на вкладочке железной отладки?
vlad_new
Быпа у кого то подобная проблемма. Оказалось, что for(;;).Попробуйте заменить на wile(1).
A. Fig Lee
Можно в бесплатном IAR цеплятся JLinkом.
Там и опция есть "Attach".

Сергей Борщ
QUOTE (сарматъ @ Oct 1 2013, 14:22) *
Сергей, вопрос: а можно как то не телнетом а сразу эклипсом цепляться к работающей плате?
там какие то заклинания должны стоять на вкладочке железной отладки?
Да, можно. Но нужно исправить две ошибки в openocd и пересобрать его. В эклипсе на вкладке отладчика "Startup" снять галочки "Reset and Delay", Load Image, можно также снять "Halt". Из скрипта openocd (если таковой используете) убрать команду сброса и команды настройки линии сброса, если они там есть. Для надежности отключить линию сброса от отладчика к плате (я ее вообще не испольщую).

Вот исправления в openocd:
CODE
diff --git a/src/jtag/hla/hla_interface.c b/src/jtag/hla/hla_interface.c
index 0176a48..99d0229 100644
--- a/src/jtag/hla/hla_interface.c
+++ b/src/jtag/hla/hla_interface.c
@@ -137,6 +137,11 @@ int hl_interface_init_reset(void)
jtag_add_reset(0, 1);
hl_if.layout->api->assert_srst(hl_if.fd, 0);
}
+ else
+ {
+ jtag_add_reset(0, 0);
+ hl_if.layout->api->assert_srst(hl_if.fd, 1);
+ }

return ERROR_OK;
}
diff --git a/src/target/hla_target.c b/src/target/hla_target.c
index a65ba80..cd7a127 100644
--- a/src/target/hla_target.c
+++ b/src/target/hla_target.c
@@ -484,6 +484,8 @@ static int adapter_poll(struct target *target)

LOG_DEBUG("halted: PC: 0x%08x", buf_get_u32(armv7m->arm.pc->value, 0, 32));
}
+ else
+ target->state = state;

return ERROR_OK;
}
По прводу первого исправления я не уверен, что его надо вносить именно сюда, еще не разобрался в исходниках. Тут он исправляет только stlink(-v2), а вот как обстоят дела у других отладчиков я не в курсе. Возможно надо jtag_add_reset() вставить в такое место, чтобы оно вызывалось для любого отладчика. Собираюсь попросить совета по этому поводу в списке рассылки, да времени нет сесть и написать туда длинное письмо с объяснением. Если кому-то интересно, объясню смысл этих правок здесь.
сарматъ
спасибо, сегодня попробую пересобрать, как раз новый openocd вышел смотрю
сарматъ
пропатчил, собрал, единственное конфигурировал так
./configure --enable-stlink --enable-jlink --enable-ftdi
без --enable-ftdi почему то не собиралось


вроде работает но как то странно halt происходит на одном и том же месте подозрительно
CODE
> halt
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x0800232c psp: 0x20003124
> resume
> halt
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x0800232c psp: 0x20003124
> resume
> halt
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x0800232c psp: 0x20003124
> resume
> halt
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x0800232c psp: 0x20003124
> resume
Сергей Борщ
QUOTE (сарматъ @ Oct 2 2013, 20:41) *
вроде работает но как то странно halt происходит на одном и том же месте подозрительно
Надо бы подключить gdb и посмотреть. Может это Idle task из одного пустого цикла.
сарматъ
да я завтра на вторую платку просто со светодиодами попробую там помню старая версия openocd там точно разные адреса выдавала

а тут я посмотрел память сохраняет переменные нормально

да адреса остановки меняются
CODE
> halt
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x21000000 pc: 0x080004e0 msp: 0x2001bfd0
> resume
> halt
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x21000000 pc: 0x080004e4 msp: 0x2001bfd0
> resume
> halt
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x21000000 pc: 0x0800051c msp: 0x2001bfd0
> resume
> halt
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x21000000 pc: 0x08000506 msp: 0x2001bfd0


Сергей, а когда эклипсом вы подсоединяетесь на лету, в эклипсе становится возможно устанавливать точки останова?
у меня он подсоединяется но толку от него ноль он не может производить отладку - не может установить точки останова(


о, получилось, чтоб нормально подцепиться к работающей плате надо вначале телнетом поключиться к openocd и дать команду halt, потом можно уже подключаться эклипсом и он в этом случае может производить отладку...

CODE
asm volatile (
"TST LR, #0x4 \n" // Test EXC_RETURN number in LR bit 2"
"ITTEE EQ \n" // if zero (equal) then
"MRSEQ R4, MSP \n" // Main Stack was used, put MSP in R0
"LDREQ R0,[R4,#24] \n" // Get stacked PC from stack
"MRSNE R4, PSP \n" // else, Process Stack was used, put PSP in R0
"LDRNE R0,[R4,#24] \n" // Get stacked PC from stack
"MRS R1, MSP \n"
"MRS R2, PSP \n"
"MOV R3, LR \n"
"deadend1: \n"
"B deadend1 \n"// ; Infinite loop
:
:
:
);


в общем поставил в обработчик исключения такой код, сижу жду когда зависнет
сарматъ
почти неделю работает без зависаний

возможно что причина была в маленьких задержках при чтении флеш было заменено FLASH_ACR_LATENCY_5WS на FLASH_ACR_LATENCY_6WS, частота 168, напряжение питания 2,85

по мануалу не очень понимаю какую задержку надо ставить для этого случая, чисто формально 5вс, но вроде как мои условия - почти граничные для этой задержки, возможно чуть поползло напряжение и куку из флеша читается шлак при попытке ухода в обработчик исключения ошибки то же, как результат блокировка контроллера, хотя повторю это только гипотеза, но в связи с нею вопросы:

1. перемещение векторов прерывания и обработчиков исключений ошибок в озу стабильность системы увеличится?

2. кто либо пытался восстанавливать работоспособность системы из обработчиков исключений ошибок кроме как полным сбросом системы? если восстанавливали поделитесь пожалуйста опытом
adnega
Цитата(сарматъ @ Oct 10 2013, 09:40) *
2. кто либо пытался восстанавливать работоспособность системы из обработчиков исключений ошибок кроме как полным сбросом системы? если восстанавливали поделитесь пожалуйста опытом

По-моему, в режиме Debug исключительные ситуации нужны для отлова багов, в режиме Release - для перезагрузки системы.
Чисто формально я делал один раз эмулятор непрерывной батарееной памяти с использванием MPU.
Т.е. создал некий регион памяти (якобы сужествующей), при доступе к которой возникало исключение.
Анализируя причины усключения (вплоть до ASM-команд), подменял данными из невыровненной батареечной памяти.
Потом отказался от этой затеи.
В этом случае я был готов к исключительной ситуации и ждал ее, знал причины возникновения исключения.
В работающей системе восстановить сбой по-моему не реально (выше я описал вроде бы тривиальный механизм,
но даже его обработка вызывает много вопросов) - главное побыстрее все важное сохранить, все силовое правильно
отключить - и бегом в перезагрузку.
Flexz
Цитата(сарматъ @ Oct 10 2013, 09:40) *
возможно что причина была в маленьких задержках при чтении флеш было заменено FLASH_ACR_LATENCY_5WS на FLASH_ACR_LATENCY_6WS, частота 168, напряжение питания 2,85

по мануалу не очень понимаю какую задержку надо ставить для этого случая, чисто формально 5вс, но вроде как мои условия - почти граничные для этой задержки, возможно чуть поползло напряжение и куку из флеша читается шлак при попытке ухода в обработчик исключения ошибки то же, как результат блокировка контроллера, хотя повторю это только гипотеза, но в связи с нею вопросы:

Из личного опыта, при тех же 3.3В 168Мгц процессор успешно работает на 3WS, на неделю, конечно, не оставлял, но несколько часов - вполне держит. Так же все процессоры, которые пробовал - разгонялись до 250МГц при 7WS, отдельные экземпляры гнались и выше. Так что параметры задержек в доках даны с запасом. Хотя помониторить питание, конечно, стоит.

Если дело действительно в просадке питания, то не забываем, что в ОЗУ нужно располагать не только сами вектора, но и всю таблицу прерываний.
сарматъ
Цитата(adnega @ Oct 10 2013, 11:07) *
главное побыстрее все важное сохранить, все силовое правильно
отключить - и бегом в перезагрузку.


у вас я так понимаю должна быть большая статистика по отказам ваших изделий, поделитесь будьте любезны информацией изза чего возникают отказы по вашему мнению? какие типовые причины? если вы что то сохраняете то видимо память озу хранит актуальные неповрежденные данные? если вы корректно все отключаете то порты ввода вывода тоже работают? периферию надо ли перезагружать если она по видимому тоже функционирует?

Цитата(Flexz @ Oct 10 2013, 12:01) *
Из личного опыта, при тех же 3.3В 168Мгц процессор успешно работает на 3WS

видимо все же это процесс веротяностный - за пару часов нормально работает за неделю вылетает
сарматъ
платка опять повисла, точнее теперь уже ясно что плата не виснет и скорее всего задержки чтения флеш ни при чем - где то в алгоритмах причина, чуть позже переползу в соотв тему, тут пишу для того чтобы сказать

1 плата сама ни при чем она работает без зависаний, исключения ошибок не генерируются
2 метод подключения к плате отладчиком на лету предложенный Сергеем Борщем крайне полезен всем рекомендую

спасибо всем принявшим участие в обсуждении
Сергей Борщ
QUOTE (сарматъ @ Oct 18 2013, 11:55) *
2 метод подключения к плате отладчиком на лету
Кстати, патч hla_target.c из сообщения №58 уже внесен в исходники openocd. Первый пока не собрался послать.
demiurg_spb
Цитата(Сергей Борщ @ Sep 26 2013, 13:51) *
Код
typedef struct
{
    void const * LR;
    uint32_t    PSR;
    void const * Return_address;
    uint32_t    R3;
    uint32_t    R2;
    uint32_t    R1;
    uint32_t    R0;
} stack_frame;

ИМХО у вас ошибка (поля структуры в обратном порядке перечислены и не хватает PC):
http://infocenter.arm.com/help/index.jsp?t...a/Babefdjc.html
Обратите внимание на подпись к рисунку: Decreasing memory address
У меня так сделано, правда я ещё ни разу это не применял в бою.
Код
typedef struct
{
    uint32_t r0;
    uint32_t r1;
    uint32_t r2;
    uint32_t r3;
    uint32_t r12;
    uint32_t lr;   // LR (R14)
    uint32_t pc;
    uint32_t xpsr;
} stack_frame_t;
Ещё наверное про -mapcs-frame для gcc стоит вспомнить.
demiurg_spb
Цитата(сарматъ @ Oct 2 2013, 23:52) *
Код
    asm volatile (
1            "TST LR, #0x4           \n" // Test EXC_RETURN number in LR bit 2"
2            "ITTEE EQ               \n" // if zero (equal) then
3            "MRSEQ R4, MSP          \n" // Main Stack was used, put MSP in R0
4            "LDREQ R0,[R4,#24]      \n" // Get stacked PC from stack
5            "MRSNE R4, PSP          \n" // else, Process Stack was used, put PSP in R0
6            "LDRNE R0,[R4,#24]      \n" // Get stacked PC from stack
7            "MRS R1, MSP              \n"
8            "MRS R2, PSP            \n"
9            "MOV R3, LR                \n"
10            "deadend1:                \n"
11            "B deadend1                \n"//; Infinite loop
12            :
13            :
14            :
            );
в общем поставил в обработчик исключения такой код, сижу жду когда зависнет
Очень странный код:
Cточки 4 и 6 можно заменить одной и вынести за условие.
Строчки 7 и 8 не нужны т.к. в R4 и так будет либо MSP либо PSP.
Строчки 10 и 11 можно заменит на "b ."
Строчки 12-14 тоже не нужны.
ig_z
Я использую такой обработчик Hard_Fault_Handler для вывода в уарт.

CODE
void Hard_Fault_Handler(uint32_t stacked_reg[])
{
DBGS_STR("In HardFault_Handler:");
DBGS_MSG("SCB->HFSR = 0x%08X", SCB->HFSR);

if ((SCB->HFSR & (1 << 30)) != 0)
{
DBGS_STR(" Forced Hard Fault");
DBGS_MSG(" SCB->CFSR= 0x%08X", SCB->CFSR );
if((SCB->CFSR & 0xFFFF0000) != 0)
{
uint32_t CFSRValue = SCB->CFSR >> 16; // right shift to lsb
DBGS_STR(" Usage fault:");
if((CFSRValue & (1 << 9)) != 0) {
DBGS_STR(" Divide by zero");
}
if((CFSRValue & (1 << 8)) != 0) {
DBGS_STR(" Unaligned");
}
if((CFSRValue & (1 << 3)) != 0) {
DBGS_STR(" NOCP");
}
if((CFSRValue & (1 << 2)) != 0) {
DBGS_STR(" INVPC");
}
if((CFSRValue & (1 << 1)) != 0) {
DBGS_STR(" INVSTATE");
}
if((CFSRValue & (1 << 0)) != 0) {
DBGS_STR(" UNDEFINSTR");
}
}
}

DBGS_MSG("R0 = 0x%08X", stacked_reg[0]);
DBGS_MSG("R1 = 0x%08X", stacked_reg[1]);
DBGS_MSG("R2 = 0x%08X", stacked_reg[2]);
DBGS_MSG("R3 = 0x%08X", stacked_reg[3]);
DBGS_MSG("R12= 0x%08X", stacked_reg[4]);
DBGS_MSG("LR = 0x%08X", stacked_reg[5]);
DBGS_MSG("PC = 0x%08X", stacked_reg[6]);
DBGS_MSG("PSR= 0x%08X", stacked_reg[7]);

for(;;)
{
UART0_Put();
}
}

__asm void HardFault_Handler(void)
{
TST lr, #4 // Test for MSP or PSP
ITE EQ
MRSEQ r0, MSP
MRSNE r0, PSP
B __cpp(Hard_Fault_Handler)
}
Сергей Борщ
QUOTE (demiurg_spb @ Oct 18 2013, 14:25) *
ИМХО у вас ошибка (поля структуры в обратном порядке перечислены и не хватает PC):
Пожалуй, насчет порядка я действительно ошибся. Причем сначала ошибся, потом начал исправлять (PSR и LR успел поменять) и меня, вероятно, отвелекли. PC в данном случае есть адрес, где произошло исключение, т.е я его обозвал Return_address. R12 я, действительно, забыл. Или на нем меня отвлекли и я Ctrl-x сделал, а Ctrl-v не успел.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.