sách gpt4 ai đã đi

Làm thế nào để phục hồi lỗi phần cứng/sử dụng/bus Cortex-M3?

In lại 作者:行者123 更新时间:2023-11-30 16:53:25 30 4
mua khóa gpt4 Nike

我正在开发 cortex-m3 的微内核。我创建了一个故意导致错误的小型测试应用程序。

现在我不确定如何从故障中返回。我知道堆栈可能需要使用不同函数的地址进行更新。我也知道在某些情况下从错误返回可能是一个坏主意,但我的内核是相应编写的。

这是一些示例代码:

#include "core_cm3.h"

// PSR flags

// EPSR flags
#define TFLG (1<<24)
#define puts printk
#define printf printk
#define error printk
// APSR flags
#define NFLG (1<<31)
#define ZFLG (1<<30)
#define CFLG (1<<29)
#define VFLG (1<<28)
#define QFLG (1<<27)
// IPSR flags
#define ISR_THREADMODE 0
#define ISR_NMI 2
#define ISR_HARDFAULT 3
#define ISR_MEMMANAGE 4
#define ISR_BUSFAULT 5
#define ISR_USAGEFAULT 6
#define ISR_SVCALL 11
#define ISR_PENDSV 14
#define ISR_SYSTICK 15
#define ISR_IRQ0 16

// HFSR flags
#define VECTTBL (1<<1)
#define FORCED (1<<30)
#define DEBUGEVT (1<<31)

// CFSR flags

// BFSR flags
#define IBUSERR (1<<0)
#define PRECISERR (1<<1)
#define IMPRECISERR (1<<2)
#define UNSTKERR (1<<3)
#define STKERR (1<<4)
#define BFARVALID (1<<7)

// UFSR flags
#define UNDEFINSTR (1<<0)
#define INVSTATE (1<<1)
#define INVPC (1<<2)
#define NOCP (1<<3)
#define UNALIGNED (1<<8)
#define DIVBYZERO (1<<9)

// MMFSR flags
#define IACCVIOL (1<<0)
#define DACCVIOL (1<<1)
#define MUNSTKERR (1<<3)
#define MSTKERR (1<<4)
#define MMARVALID (1<<7)

// DFSR
#define EXTERNAL (1<<4)
#define VCATCH (1<<3)
#define DWTTRAP (1<<2)
#define BKPT (1<<1)
#define HALTED (1<<0)

/** Hard Fault Handler code comes from these spots:
*
* http://blog.frankvh.com/2011/12/07/cortex-m3-m4-hard-fault-handler/
* http://blog.feabhas.com/2013/02/developing-a-generic-hard-fault-handler-for-arm-cortex-m3cortex-m4/
*/

/**
* This is the actual handler, which sets up the data to be used by the C function, then calls it.
*/
void __attribute__((naked)) HardFault_Handler(void)
{
__asm__(
".thumb \n"
" tst lr, #4 \n" // for priv/non-priv, test for msp or psp in return (thread or handler mode)
" ite eq \n"
" mrseq r0, MSP \n" // move main stack pointer into r0
" mrsne r0, PSP \n" // move process stack pointer into r0
" b hard_fault_handler \n" // jump to the c function
:
:
:
);
}

/**
* Here we print out the junk in the stack and some special registers to help with debugging.
*/
void hard_fault_handler(unsigned int *hardfault_args)
{
unsigned int stacked_r0;
unsigned int stacked_r1;
unsigned int stacked_r2;
unsigned int stacked_r3;
unsigned int stacked_r12;
unsigned int stacked_lr;
unsigned int stacked_pc;
unsigned int stacked_psr;
unsigned int cfsr, bfsr, ufsr, mmfsr;
//unsigned int control;

stacked_r0 = ((unsigned long) hardfault_args[0]);
stacked_r1 = ((unsigned long) hardfault_args[1]);
stacked_r2 = ((unsigned long) hardfault_args[2]);
stacked_r3 = ((unsigned long) hardfault_args[3]);

stacked_r12 = ((unsigned long) hardfault_args[4]);
stacked_lr = ((unsigned long) hardfault_args[5]);
stacked_pc = ((unsigned long) hardfault_args[6]);
stacked_psr = ((unsigned long) hardfault_args[7]);
//control = __get_CONTROL();

// TODO 2: Eliminate printf

puts("\n\n[Hard fault]\n");
printf("R0 = 0x%08x\n", stacked_r0);
printf("R1 = 0x%08x\n", stacked_r1);
printf("R2 = 0x%08x\n", stacked_r2);
printf("R3 = 0x%08x\n", stacked_r3);
printf("R12 = 0x%08x\n", stacked_r12);
printf("LR [R14] = 0x%08x subroutine call return address.\n", stacked_lr);
printf("PC [R15] = 0x%08x program counter\n", stacked_pc);

// PSR
printf("PSR = 0x%04x ", stacked_psr);
if (stacked_psr & NFLG) printf("N");
if (stacked_psr & ZFLG) printf("Z");
if (stacked_psr & CFLG) printf("C");
if (stacked_psr & VFLG) printf("V");
if (stacked_psr & QFLG) printf("Q");
puts(" ");
unsigned int isrnum = (stacked_psr & 0xff);
switch (isrnum) {
case ISR_THREADMODE:
puts("Thread mode ");
phá vỡ;
case ISR_NMI:
puts("NMI ");
phá vỡ;
case ISR_HARDFAULT:
puts("HardFault ");
phá vỡ;
case ISR_MEMMANAGE:
puts("MemManage ");
phá vỡ;
case ISR_BUSFAULT:
puts("BusFault ");
phá vỡ;
case ISR_USAGEFAULT:
puts("UsageFault ");
phá vỡ;
case ISR_SVCALL:
puts("SVCall ");
phá vỡ;
case ISR_PENDSV:
puts("PendSV ");
phá vỡ;
case ISR_SYSTICK:
puts("SysTick ");
phá vỡ;
case ISR_IRQ0:
puts("IRQ0 ");
phá vỡ;
}
printf(" ");
if (stacked_psr & TFLG)
printf("thumb");
khác
printf("non-thumb");
puts("\n");

// CONTROL (not sure this works...)
//printf("CONTROL = 0x%04x ", control);
//printf("\n");

// HFSR
printf("HFSR = 0x%08x ", SCB->HFSR);
if (SCB->HFSR & DEBUGEVT) printf("DEBUGEVT ");
if (SCB->HFSR & FORCED) printf("Forced Hard fault ");
if (SCB->HFSR & VECTTBL) printf("VECTTBL ");
puts("\n");
// CFSR
printf("CFSR = 0x%08x\n", SCB->CFSR);
cfsr = SCB->CFSR;
ufsr = (cfsr>>16);
printf("UFSR = 0x%04x ", ufsr);
if (ufsr & DIVBYZERO) printf("Divide by zero UsageFault ");
if (ufsr & UNALIGNED) printf("Unaligned access UsageFault ");
if (ufsr & NOCP) printf("No coprocessor UsageFault ");
if (ufsr & INVPC) printf("Invalid PC load UsageFault ");
if (ufsr & INVSTATE) printf("Invalid state UsageFault ");
if (ufsr & UNDEFINSTR) printf("Undefined instruction UsageFault ");
puts("\n");

// BFSR
bfsr = ((cfsr >> 8) & 0xff);
printf("BFSR = 0x%02x ", bfsr);
if ((bfsr & IBUSERR) != 0) printf("IBUSERR ");
if ((bfsr & PRECISERR) != 0) printf("Precise Data Bus Error ");
if ((bfsr & IMPRECISERR) != 0) printf("Imprecise Data Bus Error ");
if (bfsr & UNSTKERR) printf("Unstacking Error ");
if (bfsr & STKERR) printf("Stacking error ");
if (bfsr & BFARVALID) printf("Bus Fault Address Register Valid ");
printf("\n");
// BFAR
//The value of SCB->BFAR indicates the memory address that caused a Bus Fault and is valid if the bit BFARVALID in the
//SCB->CFSR register is set.
puts("BFAR = ");
if (bfsr & BFARVALID) {
printf("0x%08x\n", SCB->BFAR);
} khác {
puts("invalid\n");
}

// MMFSR
mmfsr = (cfsr & 0xff);
printf("MMFSR = 0x%02x ", mmfsr);
if (mmfsr & IACCVIOL) printf("Instruction Access Violation ");
if (mmfsr & DACCVIOL) printf("Data Access Violation ");
if (mmfsr & MUNSTKERR) printf("Memory Unstacking Error ");
if (mmfsr & MSTKERR) printf("Memory Stacking Error ");
if (mmfsr & MMARVALID) printf("MMARVALID ");
puts("\n");
// MMFAR
// The value of SCB->MMFAR indicates the memory address that caused a Memory Management Fault and is valid if the bit
// MMARVALID in the SCB->CFSR register is set.
puts("MMFAR = ");
if (mmfsr & MMARVALID) {
printf("0x%08x ", SCB->MMFAR);
} khác {
printf("invalid\n");
}

// DFSR
printf("DFSR = 0x%08lx ", SCB->DFSR);
if (SCB->DFSR & EXTERNAL) printf("EXTERNAL ");
if (SCB->DFSR & VCATCH) printf("VCATCH ");
if (SCB->DFSR & DWTTRAP) printf("DWTTRAP ");
if (SCB->DFSR & BKPT) printf("BKPT ");
if (SCB->DFSR & HALTED) printf("HALTED ");
puts("\n");

printf("AFSR = 0x%08lx\n", SCB->AFSR);
printf("SHCSR = 0x%08lx\n", SCB->SHCSR);
__asm volatile("BKPT #01\n"); // <-- **I want to return here**
while (1);
}

/*
void HardFault_Handler(void) {
while(1);
error("\n\n%% Hard Fault %%\n");
}
*/

void UsageFault_Handler(void) {
error("\n\n%% Usage Fault %%\n");
}

void BusFault_Handler() {
error("\n\n%% Bus Fault %%\n");
}

void MemMang_Handler() {
error("\n\n%% MemMang Fault %%\n");
}

我已经标记了要返回的行。我目前禁用了使用/总线/内存故障,但可以根据需要启用它们。

1 Câu trả lời

您需要的所有信息都可以在 ARM cortex M3 技术引用手册中找到。

您可以查询发出导致故障的指令的PC、导致故障的取指地址、原因等。您可以重建故障发生之前的确切处理器状态。例如,这就是按需分页的实现方式。

但是,如果遇到“硬故障”,则无法保证系统的其余部分(包括硬件外设和总线基础设施)能够以任何有意义的方式继续运行。你的总线仲裁器可能被锁定;您的内存 Controller 可能已损坏,您的代码内存可能已损坏。您可能经历过电力供应不足,并且某些逻辑出现了问题。有无数的事情可能是错误的,您无法知道也无法真正从中恢复。

关于c - 如何从 Cortex-M3 硬/使用/总线故障中恢复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40855088/

30 4 0
行者123
Hồ sơ cá nhân

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá Didi Taxi miễn phí
Mã giảm giá Didi Taxi
Giấy chứng nhận ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com