Cortex-M7进入异常中断分析

使用cmbacktrace库,其支持M3,4,7。

1、串口输出异常信息

#define cmb_println(...)    Debug_Printf(__VA_ARGS__)

//cmb_println处理可变参数和格式化字符串
int Debug_Printf(const char *fmt, ...) {
    char buffer[DEBUG_TxBUFLEN];
	INT16U n;
    va_list args;
    va_start(args, fmt);
    int len = vsnprintf(buffer, sizeof(buffer), fmt, args);
    va_end(args);
	for ( n = 0; n < len; n++ )  WriteDebugTxBuffer( buffer[n] );
    return len;
}

//串口查询方式发送,被cm_backtrace_fault调用
void UartDbg_CheckSend(void)
{
#if 1
	INT32U status;

	if ( DebugBuf.PtrTxHead == DebugBuf.PtrTxTail ) return;

	status = LPUART_GetStatusFlags( DEBUG_SIO_BASE );

	if ( status & kLPUART_TxDataRegEmptyFlag )
	{
		LPUART_WriteByte( DEBUG_SIO_BASE, DebugBuf.TxBuffer[ DebugBuf.PtrTxTail ] );
		++DebugBuf.PtrTxTail;
		if ( DebugBuf.PtrTxTail >= DEBUG_TxBUFLEN ) DebugBuf.PtrTxTail = 0;
	}
#endif
}


/**
 * backtrace for fault
 * @note only call once
 *
 * @param fault_handler_lr the LR register value on fault handler
 * @param fault_handler_sp the stack pointer on fault handler
 */
void cm_backtrace_fault(uint32_t fault_handler_lr, uint32_t fault_handler_sp) {
    uint32_t stack_pointer = fault_handler_sp, saved_regs_addr = stack_pointer, tcb_stack_pointer = 0;
    const char *regs_name[] = { "R0 ", "R1 ", "R2 ", "R3 ", "R12", "LR ", "PC ", "PSR" };

#ifdef CMB_USING_DUMP_STACK_INFO
    uint32_t stack_start_addr = main_stack_start_addr;
    size_t stack_size = main_stack_size;
#endif

    CMB_
### Cortex-M7 处理器中断处理机制及配置方法 #### 中断控制器 (NVIC) Cortex-M7 配备了一个嵌套向量中断控制器(NVIC),用于管理和优先级分配多个中断源。NVIC 支持多达 240 个可编程优先级的外部中断线,允许灵活配置不同外设和事件触发的响应顺序[^1]。 #### 中断优先级分组 为了实现更精细的控制,Cortex-M7 提供了中断优先级分组功能。通过设置 `AIRCR` 寄存器中的 PRIGROUP 字段可以调整抢占式优先级(preemptive priority) 和子优先级(subpriority) 的位宽分布。这种设计使得系统能够更好地平衡实时性和资源利用率。 #### 向量表重定位 默认情况下,向量表位于闪存起始地址处;然而,在某些应用场景下可能需要动态改变其位置。为此,可以通过修改 `VTOR` (Vector Table Offset Register)来指定新的基址,从而支持更加复杂的应用需求如多任务调度或安全分区隔离。 #### 软件触发中断 除了硬件产生的中断请求之外,软件也可以主动发起特定编号的异常调用(SWI, Software Interrupt Instruction),这为调试工具以及操作系统内核提供了便利接口。 ```c // 设置全局中断使能 __enable_irq(); // 清除某个具体IRQ通道上的挂起状态 NVIC_ClearPendingIRQ(USART1_IRQn); // 设置某类IRQ对应的回调函数指针 void (* const usart1_handler)(void); usart1_handler = USART1_IRQHandler; // 安装并启用该IRQ通道 NVIC_SetPriority(USART1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); NVIC_EnableIRQ(USART1_IRQn); ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值