|
|
  |
stm32f4discovery виснет раз в неделю |
|
|
|
Sep 25 2013, 16:08
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (сарматъ @ Sep 25 2013, 14:58)  а PSP или MSP какая разница? главное чтоб из стека вытянуть адрес команды на которой произошла поломка Угу. вот только для складывания на стек используется текущий на момент возникновения указатель, а внутри обработчика исключения используется (и на R13 отражен) MSP. QUOTE (Golikov A. @ Sep 25 2013, 15:31)  Вроде там ассемблер спрятанный в дефайны... Вот именно. На голом Си, без ассемблера - никак. О чем собственно и писал Джозеф.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 25 2013, 17:30
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата(mdmitry @ Sep 25 2013, 19:32)  LPC микроконтроллеры ARM от NXP ( lpc). Golikov A., возможно, имел ввиду файл core_cmFunc.h из CMSIS от NXP. Да, думаю этот файл я и имел ввиду. А еще помниться то-ли ИАР то-ли Кеил давал как-то к спец регистрам обращаться по спец зарезервированным словам, но может я путаю с другими процессорами. Цитата(сарматъ @ Sep 25 2013, 20:36)  ясно
то есть надо в самом начале обработчика сохранить на асемблере все регистры в какое нибудь укромное место памяти, а потом в цикле эту память слать по уарту? похоже на правду.
|
|
|
|
|
Sep 26 2013, 08:05
|
Частый гость
 
Группа: Участник
Сообщений: 153
Регистрация: 19-11-12
Пользователь №: 74 463

|
можно ли делать инлайн вставками вот так CODE 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) надо делать на чистом ассемблере?
Сообщение отредактировал сарматъ - Sep 26 2013, 08:08
|
|
|
|
|
Sep 26 2013, 09:51
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (сарматъ @ Sep 26 2013, 10:05)  можно ли делать инлайн вставками вот так Можно, не запутает. Но надо сказать компилятору, что вы используете R0 и объявить эту функцию как naked и noreturn, чтобы компилятор не вставил в начало код резервирования стека, сохранения адреса возврата и прочее. И уже из нее можно вызывать нормальную функцию собственно обработчика, в которой компилятор может выделять стек: CODE __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(); } Кроме того, вы же захотите использовать полученное вами значение? Значит компилятору надо сообщить, в какой регистр вы его положили. Точнее, надо дать ему самому возможность выбрать подходящий регистр: CODE __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); } Также вы, вероятно, захотите узнать не только точку возникновения исключения, но и содержимое остальных сложенных на стек регистров. Значит, в обработчик удобнее передавать указатель на стековый кадр: CODE #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-блок, проверьте)...
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 1 2013, 09:19
|
Частый гость
 
Группа: Участник
Сообщений: 153
Регистрация: 19-11-12
Пользователь №: 74 463

|
наваял код на 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 - Oct 1 2013, 18:57
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
|
|
|
|
|
Oct 1 2013, 12:22
|
Частый гость
 
Группа: Участник
Сообщений: 153
Регистрация: 19-11-12
Пользователь №: 74 463

|
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 наехать и все регистры и память можно просмотреть? круто... а я себе голову морочил с обработчиками и уартом Сергей, вопрос: а можно как то не телнетом а сразу эклипсом цепляться к работающей плате? там какие то заклинания должны стоять на вкладочке железной отладки?
Сообщение отредактировал сарматъ - Oct 1 2013, 13:40
|
|
|
|
|
Oct 1 2013, 21:10
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
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() вставить в такое место, чтобы оно вызывалось для любого отладчика. Собираюсь попросить совета по этому поводу в списке рассылки, да времени нет сесть и написать туда длинное письмо с объяснением. Если кому-то интересно, объясню смысл этих правок здесь.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 2 2013, 18:41
|
Частый гость
 
Группа: Участник
Сообщений: 153
Регистрация: 19-11-12
Пользователь №: 74 463

|
пропатчил, собрал, единственное конфигурировал так ./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
Сообщение отредактировал сарматъ - Oct 2 2013, 18:59
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|