如何在协议栈中添加中断处理程序

我们先看一下Z-Stack Mesh协议栈“_hal_uart_isr.c”文件中关于串口0的接收中断处理程序:

  1. /***************************************************************************************************
  2. * @fn halUartRxIsr
  3. * @brief UART Receive Interrupt
  4. * @param None
  5. * @return None
  6. ***************************************************************************************************/
  7. HAL_ISR_FUNCTION( halUart0RxIsr, URX0_VECTOR )
  8. {
  9. uint8 tmp = UxDBUF;
  10. isrCfg.rxBuf[isrCfg.rxTail] = tmp;
  11. // Re-sync the shadow on any 1st byte received.
  12. if (isrCfg.rxHead == isrCfg.rxTail)
  13. {
  14. isrCfg.rxShdw = ST0;
  15. }
  16. if (++isrCfg.rxTail >= HAL_UART_ISR_RX_MAX)
  17. {
  18. isrCfg.rxTail = 0;
  19. }
  20. isrCfg.rxTick = HAL_UART_ISR_IDLE;
  21. }

其中函数头“HAL_ISR_FUNCTION”部分是个宏定义,其直接展开为:

  1. #define HAL_ISR_FUNCTION(f,v) HAL_ISR_FUNC_PROTOTYPE(f,v); HAL_ISR_FUNC_DECLARATION(f,v)

这里面有两部分代码“HAL_ISR_FUNC_PROTOTYPE”和“HAL_ISR_FUNC_DECLARATION”,第一部分代码为“函数声明”,第二部分代码为函数原型。这两部分的代码展开皆为“_PRAGMA(vector=v) near_func interrupt void f(void)”,现在我们将“HAL_ISR_FUNCTION”部分完全展开可得下列程序:

  1. // 函数声明
  2. _PRAGMA(vector= URX0_VECTOR) __near_func __interrupt void halUart0RxIsr (void);
  3. // 函数原型
  4. _PRAGMA(vector= URX0_VECTOR) __near_func __interrupt void halUart0RxIsr (void)
  5. {
  6. uint8 tmp = UxDBUF;
  7. isrCfg.rxBuf[isrCfg.rxTail] = tmp;
  8. // Re-sync the shadow on any 1st byte received.
  9. if (isrCfg.rxHead == isrCfg.rxTail)
  10. {
  11. isrCfg.rxShdw = ST0;
  12. }
  13. if (++isrCfg.rxTail >= HAL_UART_ISR_RX_MAX)
  14. {
  15. isrCfg.rxTail = 0;
  16. }
  17. isrCfg.rxTick = HAL_UART_ISR_IDLE;
  18. }

其中“_PRAGMA”是编译器预定义声明中断服务程序的一个方法,“URX0_VECTOR”是中断编号,其在“ioCC2530.h”文件中定义。“halUart0RxIsr”是“HAL_ISR_FUNCTION(f,v)”中“f”所指的函数,也就是我们的中断服务函数。
_PRAGMA(URX0_VECTOR) // 定义中断向量
near_func // IAR的特殊字
interrupt // 中断函数标志
void halUart0RxIsr(void); // halUart0RxIsr函数名

实例:写一个P1_2的外部中断处理函数

根据协议栈定义串口0接收中断处理函数的方法,我们可以模仿写一个P1_2的外部中断处理函数。

  1. HAL_ISR_FUNCTION( P1_ISR, P1INT_VECTOR )
  2. {
  3. // 进入中断程序,保存 EA 寄存器状态,开启 EA
  4. HAL_ENTER_ISR();
  5. // 清除端口1中断标志
  6. IRCON2 &= ~(1<<3);
  7. // 如果是 P1_2 的中断
  8. if(P1IFG&0x04)
  9. {
  10. // 清除 P1_2 口中断标志
  11. P1IFG &= ~(1<<2);
  12. // 处理 P1_2 中断事件
  13. }
  14. // 退出中断程序,恢复 EA 寄存器状态
  15. HAL_EXIT_ISR();
  16. }

中断向量

ioCC2530.h

  1. /* ------------------------------------------------------------------------------------------------
  2. * Interrupt Vectors
  3. * ------------------------------------------------------------------------------------------------
  4. */
  5. #define RFERR_VECTOR VECT( 0, 0x03 ) /* RF TX FIFO Underflow and RX FIFO Overflow */
  6. #define ADC_VECTOR VECT( 1, 0x0B ) /* ADC End of Conversion */
  7. #define URX0_VECTOR VECT( 2, 0x13 ) /* USART0 RX Complete */
  8. #define URX1_VECTOR VECT( 3, 0x1B ) /* USART1 RX Complete */
  9. #define ENC_VECTOR VECT( 4, 0x23 ) /* AES Encryption/Decryption Complete */
  10. #define ST_VECTOR VECT( 5, 0x2B ) /* Sleep Timer Compare */
  11. #define P2INT_VECTOR VECT( 6, 0x33 ) /* Port 2 Inputs */
  12. #define UTX0_VECTOR VECT( 7, 0x3B ) /* USART0 TX Complete */
  13. #define DMA_VECTOR VECT( 8, 0x43 ) /* DMA Transfer Complete */
  14. #define T1_VECTOR VECT( 9, 0x4B ) /* Timer 1 (16-bit) Capture/Compare/Overflow */
  15. #define T2_VECTOR VECT( 10, 0x53 ) /* Timer 2 (MAC Timer) */
  16. #define T3_VECTOR VECT( 11, 0x5B ) /* Timer 3 (8-bit) Capture/Compare/Overflow */
  17. #define T4_VECTOR VECT( 12, 0x63 ) /* Timer 4 (8-bit) Capture/Compare/Overflow */
  18. #define P0INT_VECTOR VECT( 13, 0x6B ) /* Port 0 Inputs */
  19. #define UTX1_VECTOR VECT( 14, 0x73 ) /* USART1 TX Complete */
  20. #define P1INT_VECTOR VECT( 15, 0x7B ) /* Port 1 Inputs */
  21. #define RF_VECTOR VECT( 16, 0x83 ) /* RF General Interrupts */
  22. #define WDT_VECTOR VECT( 17, 0x8B ) /* Watchdog Overflow in Timer Mode */

qrcode_for_gh_e95b474fcf08_344.jpg