gpt4 book ai didi

c - 地址错误中断服务程序

转载 作者:太空宇宙 更新时间:2023-11-04 01:05:20 26 4
gpt4 key购买 nike

我正在尝试在 dsPIC30f3011 微 Controller 上运行和调试 C 程序。当我在 MPLAB 中运行我的代码时,代码总是倾向于在这个 ISR 处停止,我被困在任何变量完全没有输出的情况下,我的代码甚至没有执行。这似乎是某种“陷阱”程序,我认为它是为了捕捉简单的错误(即振荡器故障等)我正在使用 MPLabIDE v8.5,MPLab ICD3 处于 Debug模式。值得一提的是,MPLAB 显示我同时连接到目标(dsPIC)和 ICD3。有人可以告诉我为什么会出现此问题吗?

这是中断服务程序:

void _ISR __attribute__((no_auto_psv))_AddressError(void)
{

INTCON1bits.ADDRERR = 0;
while(1);
}

这是我的代码,首先是初始化,然后是 PID 使用,然后是 DSP 函数,然后是导出语法/算法的实际 DSP 头文件。在我定义 DutyCycle 的地方也存在某种问题。

////////////////////////////初始化////////////////////////////////////////////

  #include "dsp.h"    //see bottom of program


tPID SPR4535_PID; // Declare a PID Data Structure named, SPR4535_PID, initialize the PID object
/* The SPR4535_PID data structure contains a pointer to derived coefficients in X-space and */
/* pointer to controller state (history) samples in Y-space. So declare variables for the */
/* derived coefficients and the controller history samples */
fractional abcCoefficient[3] __attribute__ ((space(xmemory))); // ABC Coefficients loaded from X memory
fractional controlHistory[3] __attribute__ ((space(ymemory))); // Control History loaded from Y memory
/* The abcCoefficients referenced by the SPR4535_PID data structure */
/* are derived from the gain coefficients, Kp, Ki and Kd */
/* So, declare Kp, Ki and Kd in an array */
fractional kCoeffs[] = {0,0,0};
//////////////////////////////////PID variable use///////////////////////////////

void ControlSpeed(void)
{
LimitSlew();
PID_CHANGE_SPEED(SpeedCMD);
if (timer3avg > 0)
ActualSpeed = SPEEDMULT/timer3avg;
else
ActualSpeed = 0;
max=2*(PTPER+1);
DutyCycle=Fract2Float(PID_COMPUTE(ActualSpeed))*max;
// Just make sure the speed that will be written to the PDC1 register is not greater than the PTPER register
if(DutyCycle>max)
DutyCycle=max;
else if (DutyCycle<0)
DutyCycle=0;
}


//////////////////////////////////PID functions//////////////////////////////////

void INIT_PID(int DESIRED_SPEED)
{
SPR4535_PID.abcCoefficients = &abcCoefficient[0]; //Set up pointer to derived coefficients
SPR4535_PID.controlHistory = &controlHistory[0]; //Set up pointer to controller history samples

PIDInit(&SPR4535_PID); //Clear the controller history and the controller output

kCoeffs[0] = KP; // Sets the K[0] coefficient to the KP
kCoeffs[1] = KI; // Sets the K[1] coefficient to the KI
kCoeffs[2] = KD; // Sets the K[2] coefficient to the Kd
PIDCoeffCalc(&kCoeffs[0], &SPR4535_PID); //Derive the a,b, & c coefficients from the Kp, Ki & Kd

SPR4535_PID.controlReference = DESIRED_SPEED; //Set the Reference Input for your controller
}

int PID_COMPUTE(int MEASURED_OUTPUT)
{
SPR4535_PID.measuredOutput = MEASURED_OUTPUT; // Records the measured output
PID(&SPR4535_PID);
return SPR4535_PID.controlOutput; // Computes the control output
}

void PID_CHANGE_SPEED (int NEW_SPEED)
{
SPR4535_PID.controlReference = NEW_SPEED; // Changes the control reference to change the desired speed
}

/////////////////////////////////////dsp.h/////////////////////////////////////////////////

typedef struct {
fractional* abcCoefficients; /* Pointer to A, B & C coefficients located in X-space */
/* These coefficients are derived from */
/* the PID gain values - Kp, Ki and Kd */
fractional* controlHistory; /* Pointer to 3 delay-line samples located in Y-space */
/* with the first sample being the most recent */
fractional controlOutput; /* PID Controller Output */
fractional measuredOutput; /* Measured Output sample */
fractional controlReference; /* Reference Input sample */
} tPID;

/*...........................................................................*/

extern void PIDCoeffCalc( /* Derive A, B and C coefficients using PID gain values-Kp, Ki & Kd*/
fractional* kCoeffs, /* pointer to array containing Kp, Ki & Kd in sequence */
tPID* controller /* pointer to PID data structure */
);

/*...........................................................................*/

extern void PIDInit ( /* Clear the PID state variables and output sample*/
tPID* controller /* pointer to PID data structure */
);


/*...........................................................................*/

extern fractional* PID ( /* PID Controller Function */
tPID* controller /* Pointer to PID controller data structure */
);

最佳答案

dsPIC 陷阱不会免费提供太多信息,因此我倾向于使用一些汇编语言预序来扩充 ISR。 (请注意,堆栈错误陷阱有点复杂,因为它在堆栈已经乱序时使用 RCALL 和 RETURN 指令。)

/**
* \file trap.s
* \brief Used to provide a little more information during development.
*
* The trapPreprologue function is called on entry to each of the routines
* defined in traps.c. It looks up the stack to find the value of the IP
* when the trap occurred and stores it in the _errAddress memory location.
*/

.global __errAddress
.global __intCon1

.global _trapPreprologue

.section .bss

__errAddress: .space 4
__intCon1: .space 2

.section .text

_trapPreprologue:
; Disable maskable interrupts and save primary regs to shadow regs
bclr INTCON2, #15 ;global interrupt disable
push.s ;Switch to shadow registers

; Retrieve the ISR return address from the stack into w0:w1
sub w15, #4, w2 ;set W2 to the ISR.PC (SP = ToS-4)
mov [--w2], w0 ;get the ISR return address LSW (ToS-6) in w0
bclr w0, #0x0 ;mask out SFA bit (w0<0>)
mov [--w2], w1 ;get the ISR return address MSW (ToS-8) in w1
bclr w1, #0x7 ;mask out IPL<3> bit (w1<7>)
ze w1, w1 ;mask out SR<7:0> bits (w1<15..8>)

; Save it
mov #__errAddress, w2 ;Move address of __errAddress into w2
mov.d w0, [w2] ;save the ISR return address to __errAddress

; Copy the content of the INTCON1 SFR into memory
mov #__intCon1, w2 ;Move address of __intCon1 into w2
mov INTCON1, WREG ;Read the trap flags into w0 (WREG)
mov w0, [w2] ;save the trap flags to __intCon1

; Return to the 'C' handler
pop.s ;Switch back to primary registers
return

然后我将所有陷阱 ISR 保存在一个 traps.c 文件中,该文件使用 traps.s 中的前序言。请注意,您的微 Controller 的实际陷阱可能有所不同 - 请查看数据表以了解实现了哪些陷阱。

/**
* \file traps.c
* \brief Micro-controller exception interrupt vectors.
*/

#include <stdint.h>

#include "traps.h" // Internal interface to the micro trap handling.

/* Access to immediate call stack. Implementation in trap.s */

extern volatile unsigned long _errAddress;
extern volatile unsigned int _intCon1;

extern void trapPreprologue(void);

/* Trap information, set by the traps that use them. */

static unsigned int _intCon2;
static unsigned int _intCon3;
static unsigned int _intCon4;

/* Protected functions exposed by traps.h */

void trapsInitialise(void)
{
_errAddress = 0;
_intCon1 = 0;
_intCon2 = 0;
_intCon3 = 0;
_intCon4 = 0;
}


/* Trap Handling */
// The trap routines call the _trapPreprologue assembly routine in traps.s
// to obtain the value of the PC when the trap occurred and store it in
// the _errAddress variable. They reset the interrupt source in the CPU's
// INTCON SFR and invoke the (#defined) vThrow macro to report the fault.

void __attribute__((interrupt(preprologue("rcall _trapPreprologue")),no_auto_psv)) _OscillatorFail(void)
{
INTCON1bits.OSCFAIL = 0; /* Clear the trap flag */
vThrow(_intCon1, _intCon2, _intCon3, _intCon4, _errAddress);
}

void __attribute__((interrupt(preprologue("rcall _trapPreprologue")),no_auto_psv)) _StackError(void)
{
INTCON1bits.STKERR = 0; /* Clear the trap flag */
vThrow(_intCon1, _intCon2, _intCon3, _intCon4, _errAddress);
}

void __attribute__((interrupt(preprologue("rcall _trapPreprologue")),no_auto_psv)) _AddressError(void)
{
INTCON1bits.ADDRERR = 0; /* Clear the trap flag */
vThrow(_intCon1, _intCon2, _intCon3, _intCon4, _errAddress);
}

void __attribute__((interrupt(preprologue("rcall _trapPreprologue")),no_auto_psv)) _MathError(void)
{
INTCON1bits.MATHERR = 0; /* Clear the trap flag */
vThrow(_intCon1, _intCon2, _intCon3, _intCon4, _errAddress);
}

void __attribute__((interrupt(preprologue("rcall _trapPreprologue")),no_auto_psv)) _DMACError(void)
{
INTCON1bits.DMACERR = 0; /* Clear the trap flag */
vThrow(_intCon1, _intCon2, _intCon3, _intCon4, _errAddress);
}

void __attribute__((interrupt(preprologue("rcall _trapPreprologue")),no_auto_psv)) _HardTrapError(void)
{
_intCon4 = INTCON4;
INTCON4 = 0; // Clear the hard trap register
_intCon2 = INTCON2;
INTCON2bits.SWTRAP = 0; // Make sure the software hard trap bit is clear
vThrow(_intCon1, _intCon2, _intCon3, _intCon4, _errAddress);
}

void __attribute__((interrupt(preprologue("rcall _trapPreprologue")),no_auto_psv)) _SoftTrapError(void)
{
_intCon3 = INTCON3;
INTCON3 = 0; // Clear the soft trap register
vThrow(_intCon1, _intCon2, _intCon3, _intCon4, _errAddress);
}

vThrow 宏的实现由您决定。但是,它不应该使用堆栈,因为它可能不可用(所以没有 puts() 调试调用!)在开发过程中,使用带有 NOP 语句的简单无限循环是合理的你可以断点。

(在生产构建中,我的vThrow 宏 将参数记录到 RAM 的保留区域中,该区域在启动时被链接器脚本排除在外,并重置微 Controller 。在启动期间-up 程序检查保留区域,如果它非零,则记录错误事件以进行诊断。)

一旦遇到陷阱,检查 _errAddress 变量的内容将为您提供 ISR 的返回地址,即紧跟在生成中断的指令之后的地址。然后您可以检查您的 MAP 文件以找到例程,如果您真的热衷于检查反汇编以找到特定的指令。之后,调试由您决定。

关于c - 地址错误中断服务程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24633622/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com