hotpower 前辈:
看了你的分析"非典架构",我也遇到了类似的情况, 各种条件正常时丢失中断。 尤其是硬件I2C的中断,稳定性较差。FIQ的外部中断2,丢失较严重。 我用的是LPC2138 + ads1.2 + ucos2 + 中断嵌套(几乎所有的外设中断IRQ) 由于没用过kail,不能直接应用你的文件。 不知如何使用你的"非典架构",修改我目前的文件,来解决问题。
我的 Startup.s文件 ;define the stack size ;定义堆栈的大小 FIQ_STACK_LEGTH EQU 0 IRQ_STACK_LEGTH EQU 9*10 ;every layer need 9 bytes stack , permit 8 layer .每层嵌套需要9个字堆栈,允许8层嵌套 ABT_STACK_LEGTH EQU 0 UND_STACK_LEGTH EQU 0
NoInt EQU 0x80
USR32Mode EQU 0x10 SVC32Mode EQU 0x13 SYS32Mode EQU 0x1f IRQ32Mode EQU 0x12 FIQ32Mode EQU 0x11
IMPORT __use_no_semihosting_swi ;The imported labels ;引入的外部标号在这声明 IMPORT FIQ_Exception ;Fast interrupt exceptions handler 快速中断异常处理程序 IMPORT __main ;The entry point to the main function C语言主程序入口 IMPORT TargetResetInit ;initialize the target board 目标板基本初始化 IMPORT SoftwareInterrupt
;The emported labels ;给外部使用的标号在这声明 EXPORT bottom_of_heap EXPORT StackUsr EXPORT Reset EXPORT __user_initial_stackheap
CODE32
AREA vectors,CODE,READONLY ENTRY
;interrupt vectors ;中断向量表 Reset LDR PC, ResetAddr LDR PC, UndefinedAddr LDR PC, SWI_Addr LDR PC, PrefetchAddr LDR PC, DataAbortAddr DCD 0xb9205f80 LDR PC, [PC, #-0xff0] LDR PC, FIQ_Addr
ResetAddr DCD ResetInit UndefinedAddr DCD Undefined SWI_Addr DCD SoftwareInterrupt PrefetchAddr DCD PrefetchAbort DataAbortAddr DCD DataAbort Nouse DCD 0 IRQ_Addr DCD 0 FIQ_Addr DCD FIQ_Handler
;未定义指令 Undefined B Undefined ;取指令中止 PrefetchAbort B PrefetchAbort
;取数据中止 DataAbort B DataAbort
;快速中断 FIQ_Handler STMFD SP!, {R0-R3, LR} BL FIQ_Exception LDMFD SP!, {R0-R3, LR} SUBS PC, LR, #4
InitStack MOV R0, LR
;Build the SVC stack ;设置中断模式堆栈 MSR CPSR_c, #0xd2 LDR SP, StackIrq ;Build the FIQ stack ;设置快速中断模式堆栈 MSR CPSR_c, #0xd1 LDR SP, StackFiq ;Build the DATAABORT stack ;设置中止模式堆栈 MSR CPSR_c, #0xd7 LDR SP, StackAbt ;Build the UDF stack ;设置未定义模式堆栈 MSR CPSR_c, #0xdb LDR SP, StackUnd ;Build the SYS stack ;设置系统模式堆栈 MSR CPSR_c, #0xdf LDR SP, =StackUsr
MOV PC, R0
ResetInit
BL InitStack ; Initialize the stack 初始化堆栈 BL TargetResetInit ; Initialize the target board 目标板基本初始化 ; Jump to the entry point of C program 跳转到c语言入口 B __main
__user_initial_stackheap LDR r0,=bottom_of_heap ; LDR r1,=StackUsr MOV pc,lr StackIrq DCD IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4 StackFiq DCD FiqStackSpace + (FIQ_STACK_LEGTH - 1)* 4 StackAbt DCD AbtStackSpace + (ABT_STACK_LEGTH - 1)* 4 StackUnd DCD UndtStackSpace + (UND_STACK_LEGTH - 1)* 4
IF :DEF: EN_CRP IF . >= 0x1fc INFO 1,"
The data at 0x000001fc must be 0x87654321.
Please delete some source before this line." ENDIF CrpData WHILE . < 0x1fc NOP WEND CrpData1 DCD 0x87654321 ;/*When the Data is 为0x87654321,user code be protected. 当此数为0x87654321时,用户程序被保护 */ ENDIF
;/* 分配堆栈空间 */ AREA MyStacks, DATA, NOINIT, ALIGN=2
IrqStackSpace SPACE IRQ_STACK_LEGTH * 4 ;Stack spaces for Interrupt ReQuest Mode 中断模式堆栈空间 FiqStackSpace SPACE FIQ_STACK_LEGTH * 4 ;Stack spaces for Fast Interrupt reQuest Mode 快速中断模式堆栈空间 AbtStackSpace SPACE ABT_STACK_LEGTH * 4 ;Stack spaces for Suspend Mode 中止义模式堆栈空间 UndtStackSpace SPACE UND_STACK_LEGTH * 4 ;Stack spaces for Undefined Mode 未定义模式堆栈
AREA Heap, DATA, NOINIT bottom_of_heap SPACE 1
AREA Stacks, DATA, NOINIT StackUsr
END
我的 初始化函数
void TargetResetInit(void) { #ifdef __DEBUG_RAM MEMMAP = 0x2; //remap #endif
#ifdef __DEBUG_FLASH MEMMAP = 0x1; //remap #endif
#ifdef __IN_CHIP MEMMAP = 0x1; //remap #endif
PINSEL0 = (PINSEL0 & 0xFFFF0000) | 0x05 | 0x50;
/* 设置系统各部分时钟 */ /* Set system timers for each component */ PLLCON = 1; #if (Fpclk / (Fcclk / 4)) == 1 VPBDIV = 0; #endif #if (Fpclk / (Fcclk / 4)) == 2 VPBDIV = 2; #endif #if (Fpclk / (Fcclk / 4)) == 4 VPBDIV = 1; #endif
#if (Fcco / Fcclk) == 2 PLLCFG = ((Fcclk / Fosc) - 1) | (0 << 5); #endif #if (Fcco / Fcclk) == 4 PLLCFG = ((Fcclk / Fosc) - 1) | (1 << 5); #endif #if (Fcco / Fcclk) == 8 PLLCFG = ((Fcclk / Fosc) - 1) | (2 << 5); #endif #if (Fcco / Fcclk) == 16 PLLCFG = ((Fcclk / Fosc) - 1) | (3 << 5); #endif PLLFEED = 0xaa; PLLFEED = 0x55; while((PLLSTAT & (1 << 10)) == 0); PLLCON = 3; PLLFEED = 0xaa; PLLFEED = 0x55;
/* 设置存储器加速模块 */ /* Set memory accelerater module*/ MAMCR = 0; #if Fcclk < 20000000 MAMTIM = 1; #else #if Fcclk < 40000000 MAMTIM = 2; #else MAMTIM = 3; #endif #endif MAMCR = 2;
/* 设置串行口 */ /* initialize UART*/ //InitialiseUART0(115200);
/* 设置实时时钟 */ /* initialize RTC*/ CCR = 0x00; ILR = 0x03; //PREINT = Fpclk / 32768 - 1; //PREFRAC = Fpclk - (Fpclk / 32768) * 32768; YEAR=YEAR%100+2000; CCR = 0x12; //CIIR = 0x01; // 设置秒值的增量产生1次中断 ILR = 0x03; CCR = 0x11; // 启动RTC /* initialize VIC*/ VICIntEnClr = 0xffffffff; VICVectAddr = 0; VICIntSelect = 0; //T0IR = 0xffffffff; //T0TCR = 0X02; //T1IR = 0xffffffff; //T1TCR = 0X02; } |