mbed-OS 移植到 TivaC TM4123,动态中断处理有问题
mbed-OS porting to TivaC TM4123, Trouple with dynamic interrupt handling
最近我正在尝试将 mbed-OS 移植到 Tiva-C launchpad TM4C123,我遇到了 mbed 提供的文件问题,即 cmsis_nvic.c 和 cmsis_nvic.h
这个模块应该动态分配 OS 定时器的中断处理程序给可寻址函数。(或者据我所知)。
发生的事情是,软件在执行以下行后跳转到“Hard Fault Handler”
vectors[i] = old_vectors[i];
这是我使用的文件
#include "cmsis_nvic.h"
#define NVIC_RAM_VECTOR_ADDRESS (0x02000000) // Vectors positioned at start of RAM
#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) {
uint32_t *vectors = (uint32_t*)SCB->VTOR;
uint32_t i;
// Copy and switch to dynamic vectors if the first time called
if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) {
uint32_t *old_vectors = vectors;
vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS;
for (i=0; i<NVIC_NUM_VECTORS; i++) {
vectors[i] = old_vectors[i];
}
SCB->VTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS;
}
vectors[IRQn + 16] = vector;
}
uint32_t NVIC_GetVector(IRQn_Type IRQn) {
uint32_t *vectors = (uint32_t*)SCB->VTOR;
return vectors[IRQn + 16];
}
这里是cmsis_nvic.h
#ifndef MBED_CMSIS_NVIC_H
#define MBED_CMSIS_NVIC_H
#define NVIC_NUM_VECTORS (154) // CORE + MCU Peripherals
#define NVIC_USER_IRQ_OFFSET 16
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector);
uint32_t NVIC_GetVector(IRQn_Type IRQn);
#ifdef __cplusplus
}
#endif
#endif
我正在打电话
NVIC_SetVector(IRQn_Type IRQn, uint32_t vector)
从文件 us_ticker.c 像这样
NVIC_SetVector(TIMER0A_IRQn, (uint32_t)us_ticker_irq_handler);
(我的编译器是 ARM GCC,我使用 CDT 构建,使用 GDB openOCD 进行调试,并在 Eclipse 上集成了所有这些工具)
谁能告诉我这里出了什么问题?或者至少我应该在哪里调试或阅读以帮助我解决这个问题???
更新
我解决了部分问题,向量没有指向目标 SRAM 的首地址,应该是
#define NVIC_RAM_VECTOR_ADDRESS (0x20000000)
而不是
#define NVIC_RAM_VECTOR_ADDRESS (0x02000000)
所以现在当调用 NVIC_SetVector 时,函数被执行。但是当启用中断时,软件仍然跳转到硬故障,我猜(只是猜测或可能是解决方案的一部分)头文件中的定义配置不正确,有人可以向我解释它们是什么意思吗?以及如何计算向量地址的数量? USER OFFSET 是什么?
我已经解决了这个问题,这是我发现的
1- NVIC_RAM_VECTOR_ADDRESS
不是我的目标 RAM 的第一个地址,它应该是“0x20000000”
2- 应更新链接器文件,以便堆栈指针不应覆盖新复制的向量 table。因此,将 RAM 地址移动向量 table 应占用的字节数。
3-(主要原因)函数 NVIC_SetVector
内,i
被声明为 uint32_t
,然后与小于 255 的预处理器值进行比较。因此,通过比较 uint32_t
和 uint8_t
,编译会感到困惑,通过将 UL
添加到预处理器值,它解决了整个问题。
最近我正在尝试将 mbed-OS 移植到 Tiva-C launchpad TM4C123,我遇到了 mbed 提供的文件问题,即 cmsis_nvic.c 和 cmsis_nvic.h
这个模块应该动态分配 OS 定时器的中断处理程序给可寻址函数。(或者据我所知)。
发生的事情是,软件在执行以下行后跳转到“Hard Fault Handler”
vectors[i] = old_vectors[i];
这是我使用的文件
#include "cmsis_nvic.h"
#define NVIC_RAM_VECTOR_ADDRESS (0x02000000) // Vectors positioned at start of RAM
#define NVIC_FLASH_VECTOR_ADDRESS (0x0) // Initial vector position in flash
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) {
uint32_t *vectors = (uint32_t*)SCB->VTOR;
uint32_t i;
// Copy and switch to dynamic vectors if the first time called
if (SCB->VTOR == NVIC_FLASH_VECTOR_ADDRESS) {
uint32_t *old_vectors = vectors;
vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS;
for (i=0; i<NVIC_NUM_VECTORS; i++) {
vectors[i] = old_vectors[i];
}
SCB->VTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS;
}
vectors[IRQn + 16] = vector;
}
uint32_t NVIC_GetVector(IRQn_Type IRQn) {
uint32_t *vectors = (uint32_t*)SCB->VTOR;
return vectors[IRQn + 16];
}
这里是cmsis_nvic.h
#ifndef MBED_CMSIS_NVIC_H
#define MBED_CMSIS_NVIC_H
#define NVIC_NUM_VECTORS (154) // CORE + MCU Peripherals
#define NVIC_USER_IRQ_OFFSET 16
#include "cmsis.h"
#ifdef __cplusplus
extern "C" {
#endif
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector);
uint32_t NVIC_GetVector(IRQn_Type IRQn);
#ifdef __cplusplus
}
#endif
#endif
我正在打电话
NVIC_SetVector(IRQn_Type IRQn, uint32_t vector)
从文件 us_ticker.c 像这样
NVIC_SetVector(TIMER0A_IRQn, (uint32_t)us_ticker_irq_handler);
(我的编译器是 ARM GCC,我使用 CDT 构建,使用 GDB openOCD 进行调试,并在 Eclipse 上集成了所有这些工具)
谁能告诉我这里出了什么问题?或者至少我应该在哪里调试或阅读以帮助我解决这个问题???
更新
我解决了部分问题,向量没有指向目标 SRAM 的首地址,应该是
#define NVIC_RAM_VECTOR_ADDRESS (0x20000000)
而不是
#define NVIC_RAM_VECTOR_ADDRESS (0x02000000)
所以现在当调用 NVIC_SetVector 时,函数被执行。但是当启用中断时,软件仍然跳转到硬故障,我猜(只是猜测或可能是解决方案的一部分)头文件中的定义配置不正确,有人可以向我解释它们是什么意思吗?以及如何计算向量地址的数量? USER OFFSET 是什么?
我已经解决了这个问题,这是我发现的
1- NVIC_RAM_VECTOR_ADDRESS
不是我的目标 RAM 的第一个地址,它应该是“0x20000000”
2- 应更新链接器文件,以便堆栈指针不应覆盖新复制的向量 table。因此,将 RAM 地址移动向量 table 应占用的字节数。
3-(主要原因)函数 NVIC_SetVector
内,i
被声明为 uint32_t
,然后与小于 255 的预处理器值进行比较。因此,通过比较 uint32_t
和 uint8_t
,编译会感到困惑,通过将 UL
添加到预处理器值,它解决了整个问题。