IAR仿真中断的调试实现 ——简单介绍Simulator仿真中断的调试实现过程

以添加一个串口设备的中断处理函数为例,简单介绍Simulator仿真中断的调试实现过程。

一、建立工程
  创建一个新工程叫project1,并向其中添加Interrupt.c和utilities.c文件,均可在IARARM的安装文件tutor下找到。Interrupt.c是一个进行中断处理的C语言源文件,其中中断处理函数从串行口接收寄存器(RBRTHR)读取数据,然后输出其值。主程序允许中断并在等待中断过程中开始输出点号‘.’。
Interrupt.c源文件见附件
在工作区中选择项目文件夹project1—Debug,然后选择Project-Options菜单项,在弹出的读话框中对Linker等都使用默认配置。

二、设置仿真环境
   C-SPY中断系统基于一个周期计数器,在产生一个中断之前,用户可以指定该周期数。仿真UART输入,需要从文本文件InputData.txt中读取数据,其中包括Fibonacci数列,在UART接收寄存器UARTRBRTHR上设置一个‘直接读取断点’,然后将其连接到一个用户定义的宏函数Access(),该宏函数即可从文本文件中读取Fibonacci数列。无论何时产生中断,中断服务程序都要读取UARTRBRTHR寄存器,继而触发断点,执行Access()宏函数并将Fibonacci数列导入UART接收寄存器。‘直接读取断点’将在处理器读取UARTRBRTHR寄存器前触发中断,从而使宏函数 Access()得以运行,并将通过指令直接读入的数据存入寄存器中。
以下是模拟器实现串口中断仿真的步骤
1. 编写C-SPY宏文件
用户可以在启动C-SPY 时注册自定义文件,并自动执行该文件中的宏函数。本例采用 C-SPY宏文件SetupSimple.mac, 也可在IARARM的安装文件tutor下找到。
__var _fileHandle;
execUserSetup()
{
  __message "execUserSetup() called\n";
// Open the text file for ASCII reading
  // Put in the appropriate path to the InputData.txt file
  _fileHandle = __openFile( "$TOOLKIT_DIR$\\tutor\\InputData.txt", "r" );
  if( !_fileHandle )
  {
    __message "could not open file" ;
  }
}

Access()
{
  __message "Access() called\n";
// In this tutorial we read the fib values from a file
  __var _fibValue;
  if( 0 == __readFile( _fileHandle, &_fibValue ) )
  {
    UARTRBRTHR = _fibValue;
  }
  else
  {
    __message "error reading value from file";
  }
  __message "UARTRBR = 0x", _fibValue:%X,"\n";
}
execUserReset()
{
  __message "execUserReset() called\n";
if( _fileHandle )
  {
    __resetFile( _fileHandle );
  }
}
execUserExit()
{
  __message "execUserExit() called\n";
  __closeFile( _fileHandle );
}
宏文件中首先定义了一个宏函数exeUserSetup(),它将在启动C-SPY并完成应用程序下载到目标系统之后自动运行,用来创建仿真环境。然后定义一个Access()宏函数,它将从InputData.txt文件中读取Fibonacci数列,并将这些数值分配给接收寄存器地址。用户需要将Access()宏函数连接到一个‘立即读取断点’。

2. 设置C-SPY选项
 在工作区窗口选择文件夹project1—Debug,然后选择Project-Options菜单项,在弹出对话框的选择Category 列表框中选择Debugger项,在Setup 选项卡的Driver下拉列表框中选择Simulator,并选择Run to 复选框,并通过浏览按钮确认宏文件SetupSimple.mac的存放路径。C-SPY中断系统需要部分中断定义,这些定义在设备描述文件中提供,在Device description file选项区域内选择Override defaut复选框,并通过浏览按钮确认合适的设备描述文件,如下图1所示。设置完成后执行Project菜单中的Make命令,编译并链接项目。

3. 启动C-SPY模拟器
 选择project—Debug菜单项,启动IAR C-SPY调试器进入模拟器模拟调试状态,运行project1项目,并使Interrupt.c出现在源代码窗口中。然后检查Debug log(调试日志)窗口,确认已经加载SetupSimple.mac宏文件,并且execUserSetup宏函数也已被调用。
1.jpg
2012-4-8 09:26:30 上传
下载附件(53.83 KB)

图1
4.
设置中断仿真
指定一个中断,使它循环2000次后模拟一次中断。选择Simulator-Interrupts菜单项,弹出如图2所示对话框,
在其中单击New按钮,弹出图3对话框。按以下内容对其中断进行设置。
 Interrup  : 填入IRQ用于指定所采用的中断。
Description:这里IAR软件会自动填好相应的内容使仿真器能够正确模拟中断,用户在使用时请不要修改。
2.jpg
2012-4-8 09:26:31 上传
下载附件(22.86 KB)

图2
3.jpg
2012-4-8 09:26:33 上传
下载附件(24.64 KB)

图3
First activation:填入4000,其是指定首次激活中断的时间,当周期计数器达到指定值时中断被激活。
Repeat interval:填入2000,其是中断的重复间隔,以时钟周期为单位。
Hold time:选择Infinite,功能是保持时间。
Probability%:填入100,功能是指定产生中断的可能性,100%表示将按指定的频率产生中断,采用其他百分数将按随机频率产生中断。在运行过程中,C-SPY处于等待状态,直到循环计数器超过激活时间而产生依次中断,每循环2000次重复产生中断。

5. 设置立即断点
 采用定义一个宏函数并将其链接到一个立即断点的方法,可以用宏函数来模拟硬件设备,如本例使用的UART串行口。立即断点不会中断程序运行,而仅仅是使程序临时挂起以便检查是否UART输入是用一个设置在UARTRBRTHR地址上的立即读取断点,与宏文件中已定义的Access()宏函数相链接来模拟实现的。
选择View—Breakpoint菜单项打开中断窗口,右击该窗口,在弹出的快捷菜单中选择New Breakpoint—Immediate项,打开如图4所示的对话框。
4.jpg
2012-4-8 09:26:35 上传
下载附件(23.28 KB)
  图4
在该对话框中输入如图4中的参数:
Break at:填入UARTRBRTHR,其用于接收缓冲器地址
Access Type:填入Read,说明断点类型(Read or Write)
Action:Access(),用于链接到断点的宏
  在执行过程中,当C-SPY在UARTRBRTHR地址上检测到一个读取访问时,会暂时挂起仿真进程而执行Access()宏函数,从InputData.txt文件中读取数值,并将其写入UARTRBRTHR,C-SPY在读取UARTRBRTHR接收缓冲器的值后将恢复仿真进程。

三、运行仿真中断
   单步运行程序到While()循环处暂停,等待输入。在Interrupt.c源代码窗口中找到irqHandler()函数,并在“++callCount;”语句行设置一个断点。全速运行程序,到达断点时程序将暂停,Terminal I/O对话框将显示Fibonacci数列,如图5。
5.jpg
2012-4-8 09:26:28 上传
下载附件(117.84 KB)


C-SPY提供了2个系统宏函数__setSimBreak和__orderInterrupt,可在设置宏函数execUserSetup()中调用,用于自动设置断点和中断定义,避免用户进行手动配置。为此可以采用宏文件SetupAdvanced.mac取代前面的SetupSimple.mac.这样在C-SPY启动时将自动设置断点,完成中断定义,用户还不必手动在Interrupts和Breakpoints对话框中进行输入。注意,在加载SetupAdvanced.mac宏文件之前,应该先去除以前定义的断点和中断。
SetupAdvanced.mac宏文件源程序见后。
Interrupt.c源文件如下:
#pragma language=extended
#include <stdio.h>
#include <inarm.h>
#include <arm_interrupt.h>
#include <ioml674001.h>
#include "Utilities.h"
const unsigned int RESET_VEC_ADDR = 0x0;
__irq __arm void irqHandler(void);
/*
* Function: install_handler
*
* Input: vector - interrupt vector location
*  function - address to function
*
* Returns: old contents of vector
*
* Description:
* installs the function 'function' at the vector address 'vector'.
* A branch instruction to the function will be placed at the vector
* address, the old contents at the vector location will be returned
* by install_handler and can be used to chain another handler.
*/
static unsigned int install_handler(unsigned int *vector, unsigned int function)
{
  unsigned int vec, old_vec, vectoraddr;
  old_vec = *vector;
  vectoraddr = 4*(vector-resetvec) + RESET_VEC_ADDR;
  vec = ((function - vectoraddr - 8) >> 2);
  vec |= 0xea000000; /* add opcode for B instruction */
  *vector = vec;
  old_vec &= ~0xea000000;
  old_vec = ( old_vec << 2 ) + vectoraddr + 8;
  return(old_vec);
}
/*
* Inputs:      None.
* Outputs:     UART setup registers are modified.
* Returns:     Nothing.
* Description: This routine initialises the UART on the ML674001.
*/
static void InitUart(void)
{
  UARTFCRIIR_bit.FCR0  = 0;           // Unbuffered operation
  UARTLCR_bit.LCR10 = 3;              // 8-bit character
  UARTLCR_bit.LCR2  = 0;              // 1 stop bit
  UARTLCR_bit.LCR3  = 0;              // No parity
  UARTLCR_bit.LCR7  = 1;              // Enable access to UARTDLL/DLH
  UARTDLL = 0xD7;                     // 9600 baud at 33MHz CCLK
  UARTDLM = 0x00;
  UARTLCR_bit.LCR7  = 0;              // Enable access to UARTRBR/THR
  UARTIER_bit.IER0  = 1;              // Enable received data available
                                      // interrupt.
  ILC1_bit.ILR9 = 4;                  // Set UART interrupt priority
                                      // level
}

// The showstopper
int callCount = 0;

// to have something to do, while waiting for interrupts
static void do_foreground_process( void )
{
  putchar('.');
}
// IRQ handler
__irq __arm void irqHandler(void)
{
  unsigned int fib;
  // We only use UART receive interrupts, so we
  // do not need to check the interrupt source.
  // read fib value from UART receive buffer
  fib = UARTRBRTHR;
  put_fib(fib);
  // increment the show stopper
  ++callCount;
// Clear current interrupt level
  CILCL = 0;
}

// Main program for Interrupt simulation tutorial.
// Prints the Fibonacci numbers.
void main( void )
{
  // initalize the UART and fibonacci numbers
  init_fib();
  InitUart();
  // install irqHandler function at vector irqvec
  install_handler(irqvec, (unsigned int)irqHandler);
  __enable_interrupt();
  /* now loop 'forever', taking input when interrupted */
  while (callCount < MAX_FIB)
  {
    do_foreground_process();
  }
}

SetupAdvanced.mac宏文件源程序如下:
_var _fileHandle;
__var _interruptID;
__var _breakID;
execUserSetup()
{
  __message "execUserSetup() called\n";
  // Call the simulation setup
  SimulationSetup ();
}

execUserReset()
{
  __message "execUserReset() called\n";
  if( _fileHandle )
  {
    __resetFile( _fileHandle );
  }
}

execUserExit()
{
  __message "execUserExit() called\n";
  // Call the Simulation shutdown
  SimulationShutdown();
}

SimulationSetup()
{
  // Open the text file for ASCII reading
  // Put in the appropriate path to the InputData.txt file
  _fileHandle = __openFile( "$TOOLKIT_DIR$\\tutor\\InputData.txt", "r" );
  if( !_fileHandle )
  {
    __message "could not open file" ;
  }
  _interruptID = __orderInterrupt( "IRQ", 4000, 2000, 0, 0, 0, 100 );
  if( -1 == _interruptID )
  {
    __message "ERROR: syntax error in interrupt description";
  }
  // Set up the immediate breakpoint
  _breakID = __setSimBreak( "UARTRBRTHR", "R", "Access()" );
}

Access()
{
  __message "Access() called\n";
  // In this tutorial we read the fib values from a file
  __var _fibValue;
  if( 0 == __readFile( _fileHandle, &_fibValue ) )
  {
    UARTRBRTHR = _fibValue;
  }
  else
  {
    __message "error reading value from file";
  }
  __message "UARTRBR = 0x", _fibValue:%X,"\n";
}

SimulationShutdown()
{
  __cancelInterrupt( _interruptID );
  __clearBreak( _breakID );
  __closeFile( _fileHandle );
}
  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值