中断服务程序

[复制链接]
1054|11
 楼主| engao 发表于 2016-1-31 17:09 | 显示全部楼层 |阅读模式
中断是嵌入式系统中重要的组成部分,但是在标准C 中不包含中断。许多编译开发商在标准C 上增加了对中断的支持,提供新的关键字用于标示中断服务程序(ISR),类似于__interrupt、#program interrupt 等。当一个函数被定义为 ISR 的时候,编译器会自动为该函数增加中断服务程序所需要的中断现场入栈和出栈代码。
 楼主| engao 发表于 2016-1-31 17:09 | 显示全部楼层
中断服务程序需要满足如下要求:

  (1)不能返回值;

  (2)不能向ISR 传递参数;

  (3) ISR 应该尽可能的短小精悍;

  (4) printf(char * lpFormatString,…) 函数会带来重入和性能问题,不能在ISR 中采用。
dianz 发表于 2016-1-31 17:10 | 显示全部楼层
在某项目的开发中,我们设计了一个队列,在中断服务程序中,只是将中断类型添加入该队列中,在主程序的死循环中不断扫描中断队列是否有中断,有则取出队列中的第一个中断类型,进行相应处理。
 楼主| engao 发表于 2016-1-31 17:10 | 显示全部楼层
在主程序循环中判断是否有中断:  
While(1)
{
  If( !IsIntQueueEmpty() )
  {
  intType = GetFirstInt();
  switch(intType) /*  是不是很象WIN32程序的消息解析函数? */
  {
   /*  对,我们的中断类型解析很类似于消息驱动 */
   case xxx: /*  我们称其为"中断驱动"吧? */
    …
    break;
   case xxx:
    …
    break;
   …
  }
  }
}
dianz 发表于 2016-1-31 17:10 | 显示全部楼层
/*  存放中断的队列 */
typedef struct tagIntQueue
{
  int intType; /*  中断类型 */
  struct tagIntQueue *next;
}IntQueue;

IntQueue lpIntQueueHead;

__interrupt ISRexample ()   
{
  int intType;
  intType = GetSystemType();
  QueueAddTail(lpIntQueueHead, intType) ;/*  在队列尾加入新的中断 */
}
 楼主| engao 发表于 2016-1-31 17:11 | 显示全部楼层
硬件驱动模块

    一个硬件驱动模块通常应包括如下函数:

  (1 )中断服务程序ISR

  (2 )硬件初始化
dianz 发表于 2016-1-31 17:11 | 显示全部楼层

  a. 修改寄存器,设置硬件参数(如UART 应设置其波特率,AD/DA设备应设置其采样速率等);

  b. 将中断服务程序入口地址写入中断向量表:
 楼主| engao 发表于 2016-1-31 17:12 | 显示全部楼层
设置CPU 针对该硬件的控制线
dianz 发表于 2016-1-31 17:12 | 显示全部楼层
/*  设置中断向量表 */
m_myPtr = make_far_pointer(0l); /*  返回void far 型指针void far * */   
m_myPtr += ITYPE_UART; /* ITYPE_UART: uart中断服务程序 */
/*  相对于中断向量表首地址的偏移 */
*m_myPtr = &UART _Isr; /* UART _Isr :UART 的中断服务程序 */
 楼主| engao 发表于 2016-1-31 17:14 | 显示全部楼层
如果控制线可作 PIO (可编程I/O)和控制信号用,则设置 CPU 内部对应寄存器使其作为控制信号;
dianz 发表于 2016-1-31 17:14 | 显示全部楼层
设置CPU 内部的针对该设备的中断屏蔽位,设置中断方式(电平触发还是边缘触发)。
 楼主| engao 发表于 2016-1-31 17:15 | 显示全部楼层
提供一系列针对该设备的操作接口函数。例如,对于 LCD,其驱动模块应提供绘制像素、画线、绘制矩阵、显示字符点阵等函数;而对于实时钟,其驱动模块则需提供获取时间、设置时间等函数。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

34

主题

400

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部