位域KEIL hardfault后重新启动 [英] Bit fields keil hardfault after restarting

查看:540
本文介绍了位域KEIL hardfault后重新启动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我用这个结构只是闪光装置效果很好后,但在重新启动使用此结构(开/关电源)后(分配给任何位)导致HardFault IRQ。我使用的Keil uVision与STM32F205。为什么不工作?和我应该怎么更改/删除/添加到解决这个问题?直接使用GPIOC-> ODR不会引起任何问题,什么是错的,在凯尔位域?

 的#pragma anon_unions工会的typedef {
      结构{
        __IO uint16_t Data_Bus:8; // 0-7数据总线
        __IO uint16_t Ctr_Pins:6; // 8-13控制引脚
        __IO uint16_t:2; // 14-15不用在这里
    };
    结构{
        __IO uint16_t D0:1; // 0数据总线引脚
        __IO uint16_t D1:1; // 1数据总线引脚
        __IO uint16_t D2:1; // 2数据总线引脚
        __IO uint16_t D3:1; // 3数据总线引脚
        __IO uint16_t D4:1; // 4数据总线引脚
        __IO uint16_t D5:1; // 5的数据总线引脚
        __IO uint16_t D6:1; // 6数据总线引脚
        __IO uint16_t D7:1; // 7数据总线引脚
        // --------------------------------
        __IO uint16_t RS:1; // 8复位
        __IO uint16_t CS:1; // 9片选
        __IO uint16_t CD:1; // 10控制/数据
        __IO uint16_t RD:1; // 11读刻度
        __IO uint16_t WR:1​​; // 12剔写
        __IO uint16_t EN:1; // 13使得显示
        // ---------------------------------
        __IO uint16_t:1; // 14未使用
        __IO uint16_t LD:1; // 15个LED
    };
} * PC_STRUCT_PTR,PC_STRUCT;PC_STRUCT_PTR __TMP =(PC_STRUCT_PTR)(GPIOC_BASE + 0×14);
#定义引脚配置(* __ TMP)

它的使用是这样的:

 无效WRITE_REG(无符号字符命令)
{
    PINOUTS.CD = 0; PINOUTS.RD = 1; PINOUTS.CS = 0; PINOUTS.WR = 0;
    PINOUTS.Data_Bus =命令;等待();
    PINOUTS.WR = 1; PINOUTS.CS = 1; PINOUTS.CD = 1;等待();
}


解决方案

在文件'startup_stm32f20x.s,请确保您有以下一段code的:

  EXTERN H​​ardFault_Handler_C;这个声明可能缺失__tx_vectors;这个声明可能是有
    DCD HardFault_Handler

然后,在同一文件中,添加以下中断处理程序(所有其他处理程序位于):

  PUBWEAK HardFault_Handler
    .text段:code:REORDER(1)
HardFault_Handler
    TST LR,#4
    ITE EQ
    MRSEQ R0,MSP
    MRSNE R0,PSP
    乙HardFault_Handler_C

然后,在文件'stm32f2xx.c,添加以下ISR:

 无效HardFault_Handler_C(unsigned int类型* hardfault_args)
{
    的printf(R0 =为0x%.8X \\ r \\ n,hardfault_args [0]);
    的printf(R1 =为0x%.8X \\ r \\ n,hardfault_args [1]);
    的printf(R2 =为0x%.8X \\ r \\ n,hardfault_args [2]);
    的printf(R3 =为0x%.8X \\ r \\ n,hardfault_args [3]);
    的printf(R12 =为0x%.8X \\ r \\ n,hardfault_args [4]);
    的printf(LR =为0x%.8X \\ r \\ n,hardfault_args [5]);
    的printf(PC =为0x%.8X \\ r \\ n,hardfault_args [6]);
    的printf(PSR =为0x%.8X \\ r \\ n,hardfault_args [7]);
    的printf(BFAR =为0x%.8X \\ r \\ n,*(unsigned int类型*)0xE000ED38);
    的printf(CFSR =为0x%.8X \\ r \\ n,*(unsigned int类型*)0xE000ED28);
    的printf(HFSR =为0x%.8X \\ r \\ n,*(unsigned int类型*)0xE000ED2C);
    的printf(DFSR =为0x%.8X \\ r \\ n,*(unsigned int类型*)0xE000ED30);
    的printf(AFSR =为0x%.8X \\ r \\ n,*(unsigned int类型*)0xE000ED3C);
    的printf(SHCSR =为0x%.8X \\ r \\ n,SCB-> SHCSR);
    而(1);
}

如果您可以在执行时,这个特定的硬盘故障中断时不能使用的printf 的点,然后保存所有上述数据在全球缓冲区,而不是,这样你就可以到达后查看它的而(1)

然后,请参阅Cortex-M的故障异常和寄存器在 HTTP部分: //www.keil.com/appnotes/files/apnt209.pdf 为了如果你想进一步援助,以了解这里的问题,或发布的输出。

When I use this struct just after flashing device it works well, but after restarting (power on/off) using this struct(assign to any bit) cause a HardFault irq. I use Keil uVision with STM32F205. Why it not works? and what should I change/remove/add to fix it? Direct using GPIOC->ODR don't cause any problems what is wrong with bitfields in Kail?

#pragma anon_unions

typedef union {
      struct {
        __IO uint16_t Data_Bus:8; // 0-7    data bus
        __IO uint16_t Ctr_Pins:6; // 8-13   control pins
        __IO uint16_t         :2; // 14-15  unused here
    };
    struct {
        __IO uint16_t D0:1; // 0   data bus pin
        __IO uint16_t D1:1; // 1   data bus pin
        __IO uint16_t D2:1; // 2   data bus pin
        __IO uint16_t D3:1; // 3   data bus pin
        __IO uint16_t D4:1; // 4   data bus pin
        __IO uint16_t D5:1; // 5   data bus pin
        __IO uint16_t D6:1; // 6   data bus pin
        __IO uint16_t D7:1; // 7   data bus pin
        // --------------------------------
        __IO uint16_t RS:1; // 8   reset
        __IO uint16_t CS:1; // 9   chip select
        __IO uint16_t CD:1; // 10  control / data
        __IO uint16_t RD:1; // 11  read tick
        __IO uint16_t WR:1; // 12  write tick
        __IO uint16_t EN:1; // 13  enable display
        // ---------------------------------
        __IO uint16_t   :1; // 14  unused
        __IO uint16_t LD:1; // 15  led
    };
} *PC_STRUCT_PTR, PC_STRUCT;

PC_STRUCT_PTR __TMP = (PC_STRUCT_PTR)(GPIOC_BASE+0x14);
#define PINOUTS (*__TMP)

it's used like this:

void Write_Reg(unsigned char command)
{
    PINOUTS.CD = 0; PINOUTS.RD = 1; PINOUTS.CS = 0; PINOUTS.WR = 0;
    PINOUTS.Data_Bus = command; wait();
    PINOUTS.WR = 1; PINOUTS.CS = 1; PINOUTS.CD = 1; wait();
}

解决方案

In file 'startup_stm32f20x.s', make sure that you have the following piece of code:

EXTERN  HardFault_Handler_C        ; this declaration is probably missing

__tx_vectors                       ; this declaration is probably there
    DCD     HardFault_Handler

Then, in the same file, add the following interrupt handler (where all other handlers are located):

    PUBWEAK HardFault_Handler
    SECTION .text:CODE:REORDER(1)
HardFault_Handler
    TST LR, #4
    ITE EQ
    MRSEQ R0, MSP
    MRSNE R0, PSP
    B HardFault_Handler_C

Then, in file 'stm32f2xx.c', add the following ISR:

void HardFault_Handler_C(unsigned int* hardfault_args)
{
    printf("R0    = 0x%.8X\r\n",hardfault_args[0]);         
    printf("R1    = 0x%.8X\r\n",hardfault_args[1]);         
    printf("R2    = 0x%.8X\r\n",hardfault_args[2]);         
    printf("R3    = 0x%.8X\r\n",hardfault_args[3]);         
    printf("R12   = 0x%.8X\r\n",hardfault_args[4]);         
    printf("LR    = 0x%.8X\r\n",hardfault_args[5]);         
    printf("PC    = 0x%.8X\r\n",hardfault_args[6]);         
    printf("PSR   = 0x%.8X\r\n",hardfault_args[7]);         
    printf("BFAR  = 0x%.8X\r\n",*(unsigned int*)0xE000ED38);
    printf("CFSR  = 0x%.8X\r\n",*(unsigned int*)0xE000ED28);
    printf("HFSR  = 0x%.8X\r\n",*(unsigned int*)0xE000ED2C);
    printf("DFSR  = 0x%.8X\r\n",*(unsigned int*)0xE000ED30);
    printf("AFSR  = 0x%.8X\r\n",*(unsigned int*)0xE000ED3C);
    printf("SHCSR = 0x%.8X\r\n",SCB->SHCSR);                
    while (1);
}

If you can't use printf at the point in the execution when this specific Hard-Fault interrupt occurs, then save all the above data in a global buffer instead, so you can view it after reaching the while (1).

Then, refer to the 'Cortex-M Fault Exceptions and Registers' section at http://www.keil.com/appnotes/files/apnt209.pdf in order to understand the problem, or publish the output here if you want further assistance.

这篇关于位域KEIL hardfault后重新启动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆