STM32F4中断管理编译通过

This commit is contained in:
Stone 2016-06-14 07:02:31 +00:00
parent 9152e7f0e9
commit e8fbab24d3
2 changed files with 11 additions and 282 deletions

View File

@ -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("..\\..\\");

View File

@ -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