Перейти к содержанию
    

stm32f4discovery виснет раз в неделю

а PSP или MSP какая разница? главное чтоб из стека вытянуть адрес команды на которой произошла поломка
Угу. вот только для складывания на стек используется текущий на момент возникновения указатель, а внутри обработчика исключения используется (и на R13 отражен) MSP.

 

Вроде там ассемблер спрятанный в дефайны...
Вот именно. На голом Си, без ассемблера - никак. О чем собственно и писал Джозеф.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ясно

 

то есть надо в самом начале обработчика сохранить на асемблере все регистры в какое нибудь укромное место памяти, а потом в цикле эту память слать по уарту?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

LPC микроконтроллеры ARM от NXP (lpc). Golikov A., возможно, имел ввиду файл core_cmFunc.h из CMSIS от NXP.

 

Да, думаю этот файл я и имел ввиду.

 

А еще помниться то-ли ИАР то-ли Кеил давал как-то к спец регистрам обращаться по спец зарезервированным словам, но может я путаю с другими процессорами.

 

 

 

ясно

 

то есть надо в самом начале обработчика сохранить на асемблере все регистры в какое нибудь укромное место памяти, а потом в цикле эту память слать по уарту?

 

похоже на правду.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

можно ли делать инлайн вставками вот так

 

void Default_Handler(void)
{
asm volatile (
		"TST LR, #0x4;Test EXC_RETURN number in LR bit 2\n"
		"ITTEE EQ;if zero (equal) then\n"
		"MRSEQ R0, MSP;Main Stack was used, put MSP in R0\n"
		"LDREQ R0,[R0,#24];Get stacked PC from stack.\n"
		"MRSNE R0, PSP;else, Process Stack was used, put PSP in R0\n"
		"LDRNE R0,[R0,#24];Get stacked PC from stack.\n"

 

или "asm volatile (" будет рассматриваться как вызов функции и запутает стек и обработчик Default_Handler(void) надо делать на чистом ассемблере?

Изменено пользователем сарматъ

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

можно ли делать инлайн вставками вот так
Можно, не запутает. Но надо сказать компилятору, что вы используете R0 и объявить эту функцию как naked и noreturn, чтобы компилятор не вставил в начало код резервирования стека, сохранения адреса возврата и прочее. И уже из нее можно вызывать нормальную функцию собственно обработчика, в которой компилятор может выделять стек:

__attribute__((noreturn))
void handler();

__attribute__((noreturn, naked))
void Default_Handler(void)
{
    asm volatile (
            "TST LR, #0x4           \r\n" // Test EXC_RETURN number in LR bit 2"
            "ITTEE EQ               \r\n" // if zero (equal) then
            "MRSEQ R0, MSP          \r\n" // Main Stack was used, put MSP in R0
            "LDREQ R0,[R0,#24]      \r\n" // Get stacked PC from stack
            "MRSNE R0, PSP          \r\n" // else, Process Stack was used, put PSP in R0
            "LDRNE R0,[R0,#24]      \r\n" // Get stacked PC from stack
            :
            :
            :"r0"
            );
    handler();
}

Кроме того, вы же захотите использовать полученное вами значение? Значит компилятору надо сообщить, в какой регистр вы его положили. Точнее, надо дать ему самому возможность выбрать подходящий регистр:

__attribute__((noreturn))
void handler(void * stack_frame);

__attribute__((noreturn, naked))
void Default_Handler(void)
{
    void * Return_addr;
    asm volatile (
            "TST LR, #0x4               \r\n" // Test EXC_RETURN number in LR bit 2"
            "ITE EQ                     \r\n" // if zero (equal) then
            "MRSEQ %[Reg], MSP          \r\n" // Main Stack was used, put MSP in R0
            "MRSNE %[Reg], PSP          \r\n" // else, Process Stack was used, put PSP in R0
            "LDR   %[Reg],[%[Reg],#24]  \r\n" // Get stacked PC from stack
            :[Reg]"=r"(Return_addr)
            :
            :
            );
    handler(Return_addr);
}

Также вы, вероятно, захотите узнать не только точку возникновения исключения, но и содержимое остальных сложенных на стек регистров. Значит, в обработчик удобнее передавать указатель на стековый кадр:

#include    <stdint.h>
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;

__attribute__((noreturn))
void handler(stack_frame const *);

__attribute__((noreturn, naked))
void Default_Handler(void)
{
    stack_frame const * pStack_frame;
    asm volatile (
            "TST LR, #0x4               \r\n" // Test EXC_RETURN number in LR bit 2"
            "ITE EQ                     \r\n" // if zero (equal) then
            "MRSEQ %[Reg], MSP          \r\n" // Main Stack was used, put MSP in R0
            "MRSNE %[Reg], PSP          \r\n" // else, Process Stack was used, put PSP in R0
            :[Reg]"=r"(pStack_frame)
            :
            :
            );
    handler(pStack_frame);
}

Как-то так (не уверен, что в последних двух примерах правильно написал IT-блок, проверьте)...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

наваял код на 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-ро суток макетка пашет как положено, на пятые сутки зависает, в терминале - тишина, как будто макетка просто в обморок упала и не дышит...

 

есть какие то предположения?

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

есть какие то предположения?

Запустить на макетке простейшую мигалку светодиодом, и посмотреть, повиснет ли она.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Подключиться отладчиком "на лету" во время такого зависания и посмотреть, куда ее занесло. Предварительно потренировавшись подключаться к независшей плате.

Возможно проблемы со стеком не дают работать вашему обработчику.

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

/*
* 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);
 }
}

 

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

 

Подключиться отладчиком "на лету" во время такого зависания и посмотреть, куда ее занесло. Предварительно потренировавшись подключаться к независшей плате.

Возможно проблемы со стеком не дают работать вашему обработчику.

 

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

 

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

 

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

 

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

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 наехать и все регистры и память можно просмотреть? круто...

а я себе голову морочил с обработчиками и уартом

 

Сергей, вопрос: а можно как то не телнетом а сразу эклипсом цепляться к работающей плате?

там какие то заклинания должны стоять на вкладочке железной отладки?

Изменено пользователем сарматъ

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Быпа у кого то подобная проблемма. Оказалось, что for(;;).Попробуйте заменить на wile(1).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно в бесплатном IAR цеплятся JLinkом.

Там и опция есть "Attach".

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сергей, вопрос: а можно как то не телнетом а сразу эклипсом цепляться к работающей плате?

там какие то заклинания должны стоять на вкладочке железной отладки?

Да, можно. Но нужно исправить две ошибки в openocd и пересобрать его. В эклипсе на вкладке отладчика "Startup" снять галочки "Reset and Delay", Load Image, можно также снять "Halt". Из скрипта openocd (если таковой используете) убрать команду сброса и команды настройки линии сброса, если они там есть. Для надежности отключить линию сброса от отладчика к плате (я ее вообще не испольщую).

 

Вот исправления в openocd:

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 происходит на одном и том же месте подозрительно

> 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

Изменено пользователем сарматъ

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...