Jump to content
    

1901ВЦ1 в отладке при срабатывании прерывания улетает на адрес 0x1c

Добрый день.  Пытаюсь в дебагере (IAR) посмотреть, что происходит в процессоре. При срабатывании прерывания улетает на адрес 0x1c. В обработчик hard fault не заходит. Пробовал включать тамеры с прерываниями - тоже самое. Причем если прошиться, то в прерывания заходит, диод моргает. Куда копать ?

Код такой :

Spoiler
#include "MDR32FxQI_config.h"
#include "MDR32FxQI_port.h"
#include "MDR32FxQI_rst_clk.h"

#include "Clock.h"
#include "Timer.h"
#include "SystemInterupts.h"

extern uint8_t TimerFlag;

/* Private define ------------------------------------------------------------*/
#define ALL_PORTS_CLK (RST_CLK_PCLK_PORTA | RST_CLK_PCLK_PORTB | \
                       RST_CLK_PCLK_PORTC | RST_CLK_PCLK_PORTD | \
                       RST_CLK_PCLK_PORTE | RST_CLK_PCLK_PORTF)
                                             
/* Private variables ---------------------------------------------------------*/
PORT_InitTypeDef PORT_InitStructure;                                             


void SysTick_Handler(void)
{
    if (TimerFlag) {
     TimerFlag=0;
        PORT_SetBits(MDR_PORTD, PORT_Pin_5 | PORT_Pin_6 | PORT_Pin_7 |
        PORT_Pin_8 | PORT_Pin_9 | PORT_Pin_10);           
    }
    else{
        TimerFlag=1;
        PORT_ResetBits(MDR_PORTD, PORT_Pin_5 | PORT_Pin_6 | PORT_Pin_7 |
        PORT_Pin_8 | PORT_Pin_9 | PORT_Pin_10); 
    }  
  
}

int main(void)
{
 //   Clock_Init_HSE_PLL(1);    

   
    /* Enables the RTCHSE clock on PORTB, PORTC and PORTE */
    RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTD, ENABLE);
    
    PORT_InitStructure.PORT_Pin   = (PORT_Pin_5 | PORT_Pin_6 | PORT_Pin_7 |
                                                                         PORT_Pin_8 | PORT_Pin_9 | PORT_Pin_10);
    PORT_InitStructure.PORT_OE    = PORT_OE_OUT;
    PORT_InitStructure.PORT_FUNC  = PORT_FUNC_PORT;
    PORT_InitStructure.PORT_MODE  = PORT_MODE_DIGITAL;
    PORT_InitStructure.PORT_SPEED = PORT_SPEED_SLOW;

    PORT_Init(MDR_PORTD, &PORT_InitStructure);    
    

    SysTick->LOAD |= (8000000/8000)-1; //значение задержки прерывания при тактовой частоте 8 МГц = 1мс
    SysTick->CTRL &= ~0x4; //источник тактирования HCLK
    SysTick->CTRL |= 0x2;// при досчитывании до нуля таймер генерирует прерывание
    SysTick->CTRL |= 0x1;//включить работу таймера

    while (1) 
    {

    }
}            


    

image.png

Пробую еще раз с таймером 1. Опять hard fault

Edited by haker_fox
Для оформления кода используйте кнопку Code при создании сообщения, и убираем длинный код под спойлер (кнопка с глазом).

Share this post


Link to post
Share on other sites

image.thumb.png.81fdd19a666e63bcb08ed468b38f2a40.png

image.png.48661e2225db451086d8dc934b64ad65.png

Причем диод моргает, если прошить 

Spoiler
void TIMER3_IRQHandler()
{
    if (TIMER_GetITStatus(MDR_TIMER3, TIMER_STATUS_CNT_ZERO) == SET)
    {
          TIMER_ClearITPendingBit(MDR_TIMER3, TIMER_STATUS_CNT_ZERO);

          if (TimerFlag) {
           TimerFlag=0;
              PORT_SetBits(MDR_PORTD, PORT_Pin_5 | PORT_Pin_6 | PORT_Pin_7 |
              PORT_Pin_8 | PORT_Pin_9 | PORT_Pin_10);           
          }
          else{
              TimerFlag=1;
              PORT_ResetBits(MDR_PORTD, PORT_Pin_5 | PORT_Pin_6 | PORT_Pin_7 |
              PORT_Pin_8 | PORT_Pin_9 | PORT_Pin_10); 
          }
    }    
}

void Timer3Init(void)
{
      /* Initializes the TIMERx Counter */
    RST_CLK_PCLKcmd(RST_CLK_PCLK_TIMER3,ENABLE); 
    TIMER_BRGInit(MDR_TIMER3, TIMER_HCLKdiv1);

    sTIM_CntInit.TIMER_Prescaler = 5;
    sTIM_CntInit.TIMER_IniCounter =0x0;
    sTIM_CntInit.TIMER_Period           = 32000;
    sTIM_CntInit.TIMER_CounterMode      = TIMER_CntMode_ClkFixedDir;
    sTIM_CntInit.TIMER_CounterDirection = TIMER_CntDir_Up;
    sTIM_CntInit.TIMER_EventSource      = TIMER_EvSrc_TIM_CLK;
    sTIM_CntInit.TIMER_FilterSampling   = TIMER_FDTS_TIMER_CLK_div_4;
    sTIM_CntInit.TIMER_ARR_UpdateMode   = TIMER_ARR_Update_On_CNT_Overflow;
    sTIM_CntInit.TIMER_ETR_FilterConf   = TIMER_Filter_1FF_at_TIMER_CLK;
    sTIM_CntInit.TIMER_ETR_Prescaler    = TIMER_ETR_Prescaler_None;
    sTIM_CntInit.TIMER_ETR_Polarity     = TIMER_ETRPolarity_NonInverted;
    sTIM_CntInit.TIMER_BRK_Polarity     = TIMER_BRKPolarity_NonInverted;
    TIMER_CntInit (MDR_TIMER3,&sTIM_CntInit);  
    
                              
    __enable_irq();
    TIMER_ITConfig(MDR_TIMER3, TIMER_STATUS_CNT_ZERO, ENABLE);
    
    TIMER_Cmd(MDR_TIMER3, ENABLE);
    NVIC_EnableIRQ(TIMER3_IRQn); 
}

С таймером 3 на чточку останова в обработчике на встает, в окене fault exception ошибок не выдает, в дисасемблере ходит непонятно где. Если прошить, тоже работает моргалка

image.thumb.png.15fd9a579dc911861f41f71070135a1a.png

 

Модератор: используйте для оформления кода кнопку Code (выглядите так <>). Она находится сверху, когда Вы оформляете сообщение. Длинный код прячьте под спойлер (это кнопка с глазом).

Edited by haker_fox
Спрятал код в теги.

Share this post


Link to post
Share on other sites

1 час назад, Konstantin463 сказал:

Пробую еще раз с таймером 1. Опять hard fault

Область флешь (0x08000000) отмаплена на адрес 0 или нет? Заведите нужный уровень на ножку BOOT. А начало таблицы прерываний поместите в VTOR. И разберитесь куда указывают все эти ...IRQHandler из вашей таблицы прерываний (возможно они у вас слинкованы компоновщиком из предположения, что таблица прерываний должна быть с адреса 0, а не 0x08000000).

PS: Содержимое таблицы прерываний нужно смотреть в окне "memory", а не в окне дизассемблера. И нет смысла вываливать сюда кучу скриншотов с дизассемблированным мусором.

Share this post


Link to post
Share on other sites

5 минут назад, Konstantin463 сказал:

Можете пояснить ?

Честно - нет. Вижу нечётные адреса флэш, подозреваю выравнивание)

Share this post


Link to post
Share on other sites

2 часа назад, jcxz сказал:

IRQHandler из вашей таблицы прерываний (возможно они у вас слинкованы компоновщиком из предположения, что таблица прерываний должна быть с адреса 0, а не 0x08000000).

Да в .map файле они не с адреса 0x800 0000. Может быть из - за этого проблема ? 

SysTick_Handler          0x800'544d   0x20  Code  Gb  Main.o [1]
SystemCoreClock         0x2000'0000    0x4  Data  Gb  system_MDR32FG16S1QI.o [1]
SystemInit               0x800'53c1   0x7a  Code  Gb  system_MDR32FG16S1QI.o [1]
TIMER1_IRQHandler        0x800'5191   0x42  Code  Gb  Timer.o [1]
TIMER2_IRQHandler        0x800'51d3   0x42  Code  Gb  Timer.o [1]
TIMER3_IRQHandler        0x800'5215   0x42  Code  Gb  Timer.o [1]

 

2 часа назад, jcxz сказал:

Содержимое таблицы прерываний нужно смотреть в окне "memory", а не в окне дизассемблера.

В этом  окне "Memory" ? Как же тут разобать что тут такое image.thumb.png.e22e329cf2a4c07536e299557ff91395.png

Интересно, как же так получается, что если прошить, то диод моргает по прерываниям 

Share this post


Link to post
Share on other sites

13 минут назад, tgruzd сказал:

Честно - нет. Вижу нечётные адреса флэш, подозреваю выравнивание)

В Cortex-M ядрах младший бит адреса векторов прерываний должен быть ==1. Так как работают они в Thumb-режиме.

6 минут назад, Konstantin463 сказал:

Да в .map файле они не с адреса 0x800 0000. Может быть из - за этого проблема ? 

SysTick_Handler          0x800'544d   0x20  Code  Gb  Main.o [1]
SystemCoreClock         0x2000'0000    0x4  Data  Gb  system_MDR32FG16S1QI.o [1]
SystemInit               0x800'53c1   0x7a  Code  Gb  system_MDR32FG16S1QI.o [1]
TIMER1_IRQHandler        0x800'5191   0x42  Code  Gb  Timer.o [1]
TIMER2_IRQHandler        0x800'51d3   0x42  Code  Gb  Timer.o [1]
TIMER3_IRQHandler        0x800'5215   0x42  Code  Gb  Timer.o [1]

Нет, с адресами ISR всё нормально. С адреса 0x08000000 должна быть расположена сама таблица векторов. Ищите её также в .map. Она должна иметь адрес == 0x08000000.

6 минут назад, Konstantin463 сказал:

В этом  окне "Memory" ? Как же тут разобать что тут такое image.thumb.png.e22e329cf2a4c07536e299557ff91395.png

Нажать кнопку с треугольником вниз и выбрать 32-битное представление данных.

 

PS: Также посмотрите - что у вас отображается по адресу 0? Должна быть копия этой таблицы. Если flash отмаплена на адрес 0.

Share this post


Link to post
Share on other sites

11 минут назад, jcxz сказал:

В Cortex-M ядрах младший бит адреса векторов прерываний должен быть ==1. Так как работают они в Thumb-режиме.

Нет, с адресами ISR всё нормально. С адреса 0x08000000 должна быть расположена сама таблица векторов. Ищите её также в .map. Она должна иметь адрес == 0x08000000.

Нажать кнопку с треугольником вниз и выбрать 32-битное представление данных.

Она есть по адреcу 0x800 0000

  .intvec            ro code   0x800'0000    0xc0  startup_MDR32FG16S1QI.o [1]

 

Edited by Konstantin463

Share this post


Link to post
Share on other sites

1 час назад, Konstantin463 сказал:

Интересно, как же так получается, что если прошить, то диод моргает по прерываниям 

Т.е. - у Вас программа прошита во флешь, и если запустить её включением питания устройства (а не отладчиком), то она стартует и работает нормально? А если запускать под отладчиком, то вылетает в fault?

Если да, то советую посмотреть содержимое регистра DBGMCU.CR (адрес = 0xE0042000). Этот регистр находится в области "IMPLEMENTATION DEFINED" для Cortex-M ядер и назначение битов может отличаться у разных производителей. И на STM32 при неверной установке битов этого регистра наблюдается как раз такое поведение: при включении питания все прерывания работают нормально, но если тот же самый код запустить из под отладчика (даже без перепрошивки флешь, а просто подключившись к МК), то при возникновении первого же прерывания, происходит улёт в fault.

Некоторые биты этого регистра задают источники тактирования при работе CPU в разных режимах, в том числе - в режиме отладки.

Share this post


Link to post
Share on other sites

1 час назад, jcxz сказал:

Т.е. - у Вас программа прошита во флешь, и если запустить её включением питания устройства (а не отладчиком), то она стартует и работает нормально?

Все верно. 

 

1 час назад, jcxz сказал:

А если запускать под отладчиком, то вылетает в fault?

Вот в обратотчики Fault на заходит. Улетает по адресам различным. При работе SysTick вылетат на адрес 0x1C и там висит. В окне Fault exception viewer такое выдает. Как он попадает на эти адреса мне совершенно не понятно 😞 В стеке этот адрес вижу, значение регистра LR = 0xFFFFFFF9 тоже там висит 

The processor has escalated a configurable-priority exception to HardFault.
   An MPU or Execute Never (XN) default memory map access violation has occurred on an instruction fetch (CFSR.IACCVIOL, MMFAR).
Exception occured at PC = 0x4a094b08, LR = 0xfffffff9
See the call stack for more information.

 

1 час назад, jcxz сказал:

Если да, то советую посмотреть содержимое регистра DBGMCU.CR (адрес = 0xE0042000).

К сожалению, ничего ничего похожего в мануале не нашел  😞

Share this post


Link to post
Share on other sites

4 minutes ago, Konstantin463 said:

значение регистра LR = 0xFFFFFFF9

Значит, должен вернуться в основную программу (thread), не в другое прерывание.

5 minutes ago, Konstantin463 said:

К сожалению, ничего ничего похожего в мануале не нашел  😞

Может быть обратиться к разработчику? Они должны, как мне кажется, оказывать техподдержку своим продуктам.

Share this post


Link to post
Share on other sites

1 час назад, Konstantin463 сказал:

Вот в обратотчики Fault на заходит. Улетает по адресам различным. При работе SysTick вылетат на адрес 0x1C и там висит.

Возможно fault, который Вы видите - вторичный. Т.е. - до него произошёл fault, а при входе в ISR этого fault-а произошёл новый. А стек исключений содержал информацию из первичного fault. У меня как раз так и происходило при неверном содержимом DBGMCU.CR. Притом и инфа сохранённая в стеке была искажённой/неполной, как будто стекинг не полностью удался.

1 час назад, Konstantin463 сказал:

В стеке этот адрес вижу, значение регистра LR = 0xFFFFFFF9 тоже там висит

"там", это где? Регистр LR=0xFFFFFFF9 или сохранённое в стеке значение LR=0xFFFFFFF9?

1 час назад, Konstantin463 сказал:

К сожалению, ничего ничего похожего в мануале не нашел  😞

Может как-то по-другому называется или в отдельном документе.

Также Вы ничего не ответили на:

4 часа назад, jcxz сказал:

Также посмотрите - что у вас отображается по адресу 0? Должна быть копия этой таблицы. Если flash отмаплена на адрес 0.

 

1 час назад, haker_fox сказал:

Значит, должен вернуться в основную программу (thread), не в другое прерывание.

Это значит, что ТС не использует РТОС, или она к моменту fault-а ещё не запущена.  :wink:

Share this post


Link to post
Share on other sites

В 18.11.2022 в 20:48, jcxz сказал:

"там", это где? Регистр LR=0xFFFFFFF9 или сохранённое в стеке значение LR=0xFFFFFFF9?

В стеке есть значения есть цифры совпадающие с :

PC = 0x4a094b08, LR = 0xfffffff9
В 18.11.2022 в 20:48, jcxz сказал:

Также Вы ничего не ответили на:

Также посмотрите - что у вас отображается по адресу 0? Должна быть копия этой таблицы. Если flash отмаплена на адрес 0.

image.thumb.png.d18dd92b0b3c29667062ec3b627febc5.png

Вроде, все как нужно... 

В 18.11.2022 в 20:48, jcxz сказал:
В 18.11.2022 в 19:37, Konstantin463 сказал:

К сожалению, ничего ничего похожего в мануале не нашел  😞

Может как-то по-другому называется или в отдельном документе.

В разделе регистры в отладке IAR есть раздел Debug registers. Они, как я понимаю, для всех ARM m3 общие. Даташит только один у производителя и Errata. На сайте деволопер.арм.ком.  про DBGKEY написано  :Debug Key. 0xA05F must be written whenever this register is written. Reads back as status bits [25:16]. If not written as Key, the write operation is ignored and no bits are written into the register. Может с этим как - то связано ?

 

image.thumb.png.e0892e85e03598d3f2f92dafe533e4ba.png

В 18.11.2022 в 20:48, jcxz сказал:

Это значит, что ТС не использует РТОС, или она к моменту fault-а ещё не запущена.

Тут до РТОС еще далеко 😃

Edited by Konstantin463

Share this post


Link to post
Share on other sites

2 часа назад, Konstantin463 сказал:

В стеке есть значения есть цифры совпадающие с :

То, что где-то в памяти есть 0xFFFFFFF9 не говорит ни о чём. Смотреть нужно кадр стека от последнего стекинга. Что такое "стекинг" и как вообще работают прерывания в Cortex-M нужно прочитать в мануале на ядро.

2 часа назад, Konstantin463 сказал:
PC = 0x4a094b08, LR = 0xfffffff9

image.thumb.png.d18dd92b0b3c29667062ec3b627febc5.png

Вроде, все как нужно... 

Как это определили? Где содержимое адреса 0? Не вижу...

2 часа назад, Konstantin463 сказал:

В разделе регистры в отладке IAR есть раздел Debug registers. Они, как я понимаю, для всех ARM m3 общие. Даташит только один у производителя и Errata.

Я вам уже писал:

В 18.11.2022 в 16:58, jcxz сказал:

советую посмотреть содержимое регистра DBGMCU.CR (адрес = 0xE0042000). Этот регистр находится в области "IMPLEMENTATION DEFINED" для Cortex-M ядер и назначение битов может отличаться у разных производителей.

"IMPLEMENTATION DEFINED" - означает: "определяется производителем конкретного МК", а значит документация на ядро никак не может определять эти биты. Описание надо искать в описании на конкретный МК. А то что вы открыли - это вообще другой регистр, не имеющий никакого отношения к DBGMCU.CR.

 

PS: Адрес регистра я указал не совсем корректный. должен быть = 0xE0042004

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...