STM32F4中断管理编译通过
This commit is contained in:
parent
9152e7f0e9
commit
e8fbab24d3
|
@ -21,8 +21,7 @@ namespace NewLife.Reflection
|
|||
{
|
||||
var build = new Builder();
|
||||
build.Init();
|
||||
build.Cortex = 3;
|
||||
build.Output = "F1";
|
||||
build.Cortex = 4;
|
||||
build.AddIncludes("..\\..\\..\\Lib\\CMSIS");
|
||||
build.AddIncludes("..\\..\\..\\Lib\\Inc");
|
||||
build.AddIncludes("..\\", false);
|
||||
|
@ -31,6 +30,7 @@ namespace NewLife.Reflection
|
|||
build.AddIncludes("..\\..\\Kernel");
|
||||
build.AddIncludes("..\\..\\Device");
|
||||
build.AddFiles(".", "*.c;*.cpp;*.s");
|
||||
build.AddFiles("..\\CMSIS", "*.c;*.cpp;*.s");
|
||||
build.Libs.Clear();
|
||||
build.CompileAll();
|
||||
build.BuildLib("..\\..\\");
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
#include "Interrupt.h"
|
||||
//#include "SerialPort.h"
|
||||
|
||||
//#include "Platform\stm32.h"
|
||||
|
||||
TInterrupt Interrupt;
|
||||
#include "..\stm32.h"
|
||||
|
||||
#define IS_IRQ(irq) (irq >= -16 && irq <= VectorySize - 16)
|
||||
|
||||
void TInterrupt::Init() const
|
||||
//#include "..\CMSIS\Interrupt.cpp"
|
||||
|
||||
void TInterrupt::OnInit() const
|
||||
{
|
||||
// 禁用所有中断
|
||||
NVIC->ICER[0] = 0xFFFFFFFF;
|
||||
|
@ -58,111 +58,6 @@ void TInterrupt::Init() const
|
|||
EXTI_DeInit();
|
||||
}
|
||||
|
||||
/*TInterrupt::~TInterrupt()
|
||||
{
|
||||
// 恢复中断向量表
|
||||
#if defined(STM32F1) || defined(STM32F4)
|
||||
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0);
|
||||
#else
|
||||
SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_Flash);
|
||||
#endif
|
||||
}*/
|
||||
|
||||
bool TInterrupt::Activate(short irq, InterruptCallback isr, void* param)
|
||||
{
|
||||
assert_param(IS_IRQ(irq));
|
||||
|
||||
short irq2 = irq + 16; // exception = irq + 16
|
||||
Vectors[irq2] = isr;
|
||||
Params[irq2] = param;
|
||||
|
||||
__DMB(); // asure table is written
|
||||
//NVIC->ICPR[irq >> 5] = 1 << (irq & 0x1F); // clear pending bit
|
||||
//NVIC->ISER[irq >> 5] = 1 << (irq & 0x1F); // set enable bit
|
||||
if(irq >= 0)
|
||||
{
|
||||
NVIC_ClearPendingIRQ((IRQn_Type)irq);
|
||||
NVIC_EnableIRQ((IRQn_Type)irq);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TInterrupt::Deactivate(short irq)
|
||||
{
|
||||
assert_param(IS_IRQ(irq));
|
||||
|
||||
short irq2 = irq + 16; // exception = irq + 16
|
||||
Vectors[irq2] = 0;
|
||||
Params[irq2] = 0;
|
||||
|
||||
//NVIC->ICER[irq >> 5] = 1 << (irq & 0x1F); // clear enable bit */
|
||||
if(irq >= 0) NVIC_DisableIRQ((IRQn_Type)irq);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TInterrupt::Enable(short irq) const
|
||||
{
|
||||
assert_param(IS_IRQ(irq));
|
||||
|
||||
if(irq < 0) return false;
|
||||
|
||||
uint ier = NVIC->ISER[irq >> 5]; // old state
|
||||
//NVIC->ISER[irq >> 5] = 1 << (irq & 0x1F); // set enable bit
|
||||
NVIC_EnableIRQ((IRQn_Type)irq);
|
||||
return (ier >> (irq & 0x1F)) & 1; // old enable bit
|
||||
}
|
||||
|
||||
bool TInterrupt::Disable(short irq) const
|
||||
{
|
||||
assert_param(IS_IRQ(irq));
|
||||
|
||||
if(irq < 0) return false;
|
||||
|
||||
uint ier = NVIC->ISER[irq >> 5]; // old state
|
||||
//NVIC->ICER[irq >> 5] = 1 << (irq & 0x1F); // clear enable bit
|
||||
NVIC_DisableIRQ((IRQn_Type)irq);
|
||||
return (ier >> (irq & 0x1F)) & 1; // old enable bit
|
||||
}
|
||||
|
||||
bool TInterrupt::EnableState(short irq) const
|
||||
{
|
||||
assert_param(IS_IRQ(irq));
|
||||
|
||||
if(irq < 0) return false;
|
||||
|
||||
// return enabled bit
|
||||
return (NVIC->ISER[(uint)irq >> 5] >> ((uint)irq & 0x1F)) & 1;
|
||||
}
|
||||
|
||||
bool TInterrupt::PendingState(short irq) const
|
||||
{
|
||||
assert_param(IS_IRQ(irq));
|
||||
|
||||
if(irq < 0) return false;
|
||||
|
||||
// return pending bit
|
||||
return (NVIC->ISPR[(uint)irq >> 5] >> ((uint)irq & 0x1F)) & 1;
|
||||
}
|
||||
|
||||
void TInterrupt::SetPriority(short irq, uint priority) const
|
||||
{
|
||||
assert_param(IS_IRQ(irq));
|
||||
|
||||
NVIC_SetPriority((IRQn_Type)irq, priority);
|
||||
}
|
||||
|
||||
void TInterrupt::GetPriority(short irq) const
|
||||
{
|
||||
assert_param(IS_IRQ(irq));
|
||||
|
||||
NVIC_GetPriority((IRQn_Type)irq);
|
||||
}
|
||||
|
||||
void TInterrupt::GlobalEnable() const { __enable_irq(); }
|
||||
void TInterrupt::GlobalDisable() const { __disable_irq(); }
|
||||
bool TInterrupt::GlobalState() const { return __get_PRIMASK(); }
|
||||
|
||||
#ifdef STM32F1
|
||||
uint TInterrupt::EncodePriority (uint priorityGroup, uint preemptPriority, uint subPriority) const
|
||||
{
|
||||
|
@ -179,64 +74,11 @@ void TInterrupt::DecodePriority (uint priority, uint priorityGroup, uint* pPreem
|
|||
#pragma arm section code = "SectionForSys"
|
||||
#endif
|
||||
|
||||
#if defined ( __CC_ARM )
|
||||
__ASM uint GetIPSR()
|
||||
{
|
||||
mrs r0,IPSR // exception number
|
||||
bx lr
|
||||
}
|
||||
#elif (defined (__GNUC__))
|
||||
uint32_t GetIPSR(void) __attribute__( ( naked ) );
|
||||
uint32_t GetIPSR(void)
|
||||
{
|
||||
uint32_t result=0;
|
||||
|
||||
__ASM volatile ("MRS r0, IPSR\n\t"
|
||||
"BX lr \n\t" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
#endif
|
||||
|
||||
// 是否在中断里面
|
||||
bool TInterrupt::IsHandler() const { return GetIPSR() & 0x01; }
|
||||
|
||||
#ifdef TINY
|
||||
__ASM void FaultHandler() { }
|
||||
#else
|
||||
|
||||
#if defined(BOOT) || defined(APP)
|
||||
|
||||
void UserHandler()
|
||||
{
|
||||
StrBoot.pUserHandler();
|
||||
}
|
||||
|
||||
void RealHandler()
|
||||
#else
|
||||
void UserHandler()
|
||||
#endif
|
||||
{
|
||||
uint num = GetIPSR();
|
||||
assert_param(num < VectorySize);
|
||||
//assert_param(Interrupt.Vectors[num]);
|
||||
if(!Interrupt.Vectors[num]) return;
|
||||
|
||||
// 内存检查
|
||||
#if DEBUG
|
||||
Sys.CheckMemory();
|
||||
#endif
|
||||
|
||||
// 找到应用层中断委托并调用
|
||||
InterruptCallback isr = (InterruptCallback)Interrupt.Vectors[num];
|
||||
void* param = (void*)Interrupt.Params[num];
|
||||
isr(num - 16, param);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
/* 在GD32F130C8中时常有一个FAULT_SubHandler跳转的错误,
|
||||
经查是因为FAULT_SubHandler和FaultHandler离得太远,导致b跳转无法到达,
|
||||
因此把这两个函数指定到同一个端中,使得它们地址分布上紧挨着
|
||||
因此把这两个函数指定到同一个段中,使得它们地址分布上紧挨着
|
||||
*/
|
||||
void FAULT_SubHandler(uint* registers, uint exception)
|
||||
{
|
||||
|
@ -260,14 +102,14 @@ extern "C"
|
|||
|
||||
TraceStack::Show();
|
||||
|
||||
SerialPort* sp = SerialPort::GetMessagePort();
|
||||
if(sp) sp->Flush();
|
||||
//auto sp = SerialPort::GetMessagePort();
|
||||
//if(sp) sp->Flush();
|
||||
#endif
|
||||
while(true);
|
||||
}
|
||||
|
||||
#if defined ( __CC_ARM )
|
||||
__ASM void FaultHandler()
|
||||
__asm void FaultHandler()
|
||||
{
|
||||
IMPORT FAULT_SubHandler
|
||||
|
||||
|
@ -300,7 +142,7 @@ extern "C"
|
|||
#elif (defined (__GNUC__))
|
||||
void FaultHandler()
|
||||
{
|
||||
__ASM volatile (
|
||||
__asm volatile (
|
||||
#if defined(STM32F0) || defined(GD32F150)
|
||||
"push {r4-r7} \n\t"
|
||||
#else
|
||||
|
@ -313,116 +155,3 @@ extern "C"
|
|||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// 智能IRQ,初始化时备份,销毁时还原
|
||||
SmartIRQ::SmartIRQ(bool enable)
|
||||
{
|
||||
_state = __get_PRIMASK();
|
||||
if(enable)
|
||||
__enable_irq();
|
||||
else
|
||||
__disable_irq();
|
||||
}
|
||||
|
||||
SmartIRQ::~SmartIRQ()
|
||||
{
|
||||
__set_PRIMASK(_state);
|
||||
}
|
||||
|
||||
#pragma arm section code
|
||||
|
||||
/*================================ 锁 ================================*/
|
||||
|
||||
#include "Time.h"
|
||||
|
||||
// 智能锁。初始化时锁定一个整数,销毁时解锁
|
||||
Lock::Lock(int& ref)
|
||||
{
|
||||
Success = false;
|
||||
if(ref > 0) return;
|
||||
|
||||
// 加全局锁以后再修改引用
|
||||
SmartIRQ irq;
|
||||
// 再次判断,DoubleLock双锁结构,避免小概率冲突
|
||||
if(ref > 0) return;
|
||||
|
||||
_ref = &ref;
|
||||
ref++;
|
||||
Success = true;
|
||||
}
|
||||
|
||||
Lock::~Lock()
|
||||
{
|
||||
if(Success)
|
||||
{
|
||||
SmartIRQ irq;
|
||||
(*_ref)--;
|
||||
}
|
||||
}
|
||||
|
||||
bool Lock::Wait(int us)
|
||||
{
|
||||
// 可能已经进入成功
|
||||
if(Success) return true;
|
||||
|
||||
int& ref = *_ref;
|
||||
// 等待超时时间
|
||||
TimeWheel tw(0, 0, us);
|
||||
tw.Sleep = 1;
|
||||
while(ref > 0)
|
||||
{
|
||||
// 延迟一下,释放CPU使用权
|
||||
//Sys.Sleep(1);
|
||||
if(tw.Expired()) return false;
|
||||
}
|
||||
|
||||
// 加全局锁以后再修改引用
|
||||
SmartIRQ irq;
|
||||
// 再次判断,DoubleLock双锁结构,避免小概率冲突
|
||||
if(ref > 0) return false;
|
||||
|
||||
ref++;
|
||||
Success = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*================================ 跟踪栈 ================================*/
|
||||
|
||||
#if DEBUG
|
||||
|
||||
// 使用字符串指针的指针,因为引用的都是字符串常量,不需要拷贝和分配空间
|
||||
static cstring* _TS = nullptr;
|
||||
static int _TS_Len = 0;
|
||||
|
||||
TraceStack::TraceStack(cstring name)
|
||||
{
|
||||
// 字符串指针的数组
|
||||
static cstring __ts[16];
|
||||
_TS = __ts;
|
||||
|
||||
//_TS->Push(name);
|
||||
if(_TS_Len < 16) _TS[_TS_Len++] = name;
|
||||
}
|
||||
|
||||
TraceStack::~TraceStack()
|
||||
{
|
||||
// 清空最后一个项目,避免误判
|
||||
//if(_TS_Len > 0) _TS[--_TS_Len] = "";
|
||||
_TS_Len--;
|
||||
}
|
||||
|
||||
void TraceStack::Show()
|
||||
{
|
||||
debug_printf("TraceStack::Show:\r\n");
|
||||
if(_TS)
|
||||
{
|
||||
for(int i=_TS_Len - 1; i>=0; i--)
|
||||
{
|
||||
debug_printf("\t<=%s \r\n", _TS[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue