Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1419030
  • 博文数量: 129
  • 博客积分: 1449
  • 博客等级: 上尉
  • 技术积分: 3048
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-24 18:36
文章分类

全部博文(129)

文章存档

2015年(3)

2014年(20)

2013年(65)

2012年(41)

分类: C/C++

2012-12-19 15:33:18

系统启动时硬件将调用首地址为x位置的子例程, 实现语句如下: //4.7.3, P103
(*(void(*)())x)(); 从内向外分析如下:
1. void(*)(): 函数指针类型, 参数和返回值都为空
2. (void(*)())x: 将x强制转换为函数指针类型. x为地址, 即一个函数存在首地址为x的一段区域内
3. (*(void(*)())x): 前面加*, 指针取值, 取x地址开始的一段内容, 即对函数的引用
4. (*(void(*)())x)(): 最后加上(), 函数调用, 你懂的

利用 typedef 更好理解:
typedef void (*pFunction)(void); //定义函数指针类型(函数前带*)
(*(pFunction)x)();

//PC指针指到0x2c处的SVC_Handler函数入口地址,也就是UpdateHandler, 0x2c不就是SVCall handler
(*((void (*)(void))(*(unsigned long *)0x2c)))();

Luminary提供的 interrupt.c 中如下:
// The processor vector table.
#if defined(ewarm)
static __no_init void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void) @ "VTABLE";
#elif defined(sourcerygxx)
static __attribute__((section(".cs3.region-head.ram")))
void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void);
#elif defined(ccs)
#pragma DATA_SECTION(g_pfnRAMVectors, ".vtable")
void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void);
#else
static __attribute__((section("vtable")))
void (*g_pfnRAMVectors[NUM_INTERRUPTS])(void);
#endif

void IntRegister(unsigned long ulInterrupt, void (*pfnHandler)(void))
{
  unsigned long ulIdx, ulValue;

  // Check the arguments.
  ASSERT(ulInterrupt < NUM_INTERRUPTS);

  // Make sure that the RAM vector table is correctly aligned.
  ASSERT(((unsigned long)g_pfnRAMVectors & 0x000003ff) == 0);

  // See if the RAM vector table has been initialized.
  if(HWREG(NVIC_VTABLE) != (unsigned long)g_pfnRAMVectors)
  {
      // Copy the vector table from the beginning of FLASH to the RAM vector table.
      ulValue = HWREG(NVIC_VTABLE);
      for(ulIdx = 0; ulIdx < NUM_INTERRUPTS; ulIdx++)
      {
      g_pfnRAMVectors[ulIdx] = (void (*)(void))HWREG((ulIdx * 4) + ulValue);
      }

      // Point NVIC at the RAM vector table.
      HWREG(NVIC_VTABLE) = (unsigned long)g_pfnRAMVectors;
  }

  // Save the interrupt handler.
  g_pfnRAMVectors[ulInterrupt] = pfnHandler;
}

static void IntDefaultHandler(void)
{
    // Go into an infinite loop.
    while(1) {}
}

void IntUnregister(unsigned long ulInterrupt)
{
    // Check the arguments.
    ASSERT(ulInterrupt < NUM_INTERRUPTS);

    // Reset the interrupt handler.
    g_pfnRAMVectors[ulInterrupt] = IntDefaultHandler;
}
阅读(1685) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~