⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bsp.c

📁 ucos 在ARM7下的移植代码
💻 C
字号:
//app.c

#include <includes.h>

#define  BSP_UNDEF_INSTRUCTION_VECTOR_ADDR   (*(INT32U *)0x00000004L)
#define  BSP_SWI_VECTOR_ADDR                 (*(INT32U *)0x00000008L)
#define  BSP_PREFETCH_ABORT_VECTOR_ADDR      (*(INT32U *)0x0000000CL)
#define  BSP_DATA_ABORT_VECTOR_ADDR          (*(INT32U *)0x00000010L)
#define  BSP_IRQ_VECTOR_ADDR                 (*(INT32U *)0x00000018L)
#define  BSP_FIQ_VECTOR_ADDR                 (*(INT32U *)0x0000001CL)
#define  BSP_IRQ_ISR_ADDR                    (*(INT32U *)0x00000038L)
#define  BSP_FIQ_ISR_ADDR                    (*(INT32U *)0x0000003CL)
#define  AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE  ((unsigned int) 0x0 <<  5) // (AIC) Internal Sources Code Label Level Sensitive

typedef  void (*BSP_PFNCT)(void);

static  void  BSP_DummyISR_Handler(void);
static  void  BSP_IntCtrlInit(void);
static  void  Tmr_TickInit(void);
static  void  Tmr_TickISR_Handler(void);

/********************************************************************************************************
 * 说明:BSP_DummyISR_Handler函数,哑元IRQ句柄,用于处理非法IRQ异常
 * 参数:无
 * 返回值:无
********************************************************************************************************/
static  void  BSP_DummyISR_Handler (void) {
    AT91C_BASE_AIC->AIC_IVR = 0;
}

/*******************************************************************************************************
* 说明: BSP_Init函数,完成初始化,用户的应用程序在调用本模块内其它任何函数之前应先调用本函数。
 * 参数:无
 * 返回值:无
********************************************************************************************************/
void  BSP_Init (void) {
    BSP_IntCtrlInit();                               // 初始化中断控制器
    Tmr_TickInit();                                  // 初始化 uC/OS-II 的节拍速度
    LED_Init();                                      // 初始化用于 LED 的 I/O 端口
}

/********************************************************************************************************
 * 说明:BSP_IntCtrlInit函数,初始化中断控制器。调用本函数将禁止所有中断。
 * 参数:无
 * 返回值:无
********************************************************************************************************/
static  void  BSP_IntCtrlInit (void) {
    INT16U  i;

    BSP_IRQ_VECTOR_ADDR               =  0xE59FF018;               // LDR PC,[PC,#0x18] 指令
    BSP_IRQ_ISR_ADDR                  =  (INT32U)OS_CPU_IRQ_ISR;   // IRQ 异常向量地址
    BSP_FIQ_VECTOR_ADDR               =  0xE59FF018;               // LDR PC,[PC,#0x18] 指令
    BSP_FIQ_ISR_ADDR                  =  (INT32U)OS_CPU_FIQ_ISR;   // FIQ 异常向量地址
    BSP_UNDEF_INSTRUCTION_VECTOR_ADDR =  0xEAFFFFFE;               // 跳转到自身
    BSP_SWI_VECTOR_ADDR               =  0xEAFFFFFE;
    BSP_PREFETCH_ABORT_VECTOR_ADDR    =  0xEAFFFFFE;
    BSP_DATA_ABORT_VECTOR_ADDR        =  0xEAFFFFFE;
    BSP_FIQ_VECTOR_ADDR               =  0xEAFFFFFE;

    AT91C_BASE_AIC->AIC_EOICR         =  0x00000000;               // 结束中断命令

    for (i = 0; i < 32; i++) {                                     // 禁止所有中断
        AT91C_BASE_AIC->AIC_SVR[i] = (INT32U)BSP_DummyISR_Handler;
        AT91C_BASE_AIC->AIC_SMR[i] = 0;
    }
}

/********************************************************************************************************
 * 说明:BSP_IntDisAll函数,调用本函数将禁止所有中断。
 * 参数:无
 * 返回值:无
********************************************************************************************************/
void  BSP_IntDisAll (void) {
    AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF;                         // 禁止所有中断
}

/********************************************************************************************************
 * 说明:LED_Init函数,用户的应用程序在调用本模块内其它任何函数之前应先调用本函数。
 * 参数:无
 * 返回值:无
********************************************************************************************************/
void  LED_Init (void) {
    AT91C_BASE_PIOA->PIO_PER  = BSP_LED4 | BSP_LED3 | BSP_LED2 | BSP_LED1; // 允许寄存器
    AT91C_BASE_PIOA->PIO_OER  = BSP_LED4 | BSP_LED3 | BSP_LED2 | BSP_LED1; // 允许输出
    AT91C_BASE_PIOA->PIO_IDR  = BSP_LED4 | BSP_LED3 | BSP_LED2 | BSP_LED1;
    LED_Off(BSP_LED_ALL);                                                  // 熄灭所有LED
}

/********************************************************************************************************
 * 说明:LED_On函数,用于控制电路板上LED的点亮。
 * 参数:INT8U led
 *              0    点亮所有LED
 *              1-4  点亮 LED1-LED4
 * 返回值:无
********************************************************************************************************/
void  LED_On (INT8U led) {
    switch (led) {
        case 0:
             AT91C_BASE_PIOA->PIO_CODR = BSP_LED4 | BSP_LED3 | BSP_LED2 | BSP_LED1;
             break;
        case 1:
             AT91C_BASE_PIOA->PIO_CODR = BSP_LED1;
             break;
        case 2:
             AT91C_BASE_PIOA->PIO_CODR = BSP_LED2;
             break;
        case 3:
             AT91C_BASE_PIOA->PIO_CODR = BSP_LED3;
             break;
        case 4:
             AT91C_BASE_PIOA->PIO_CODR = BSP_LED4;
             break;
    }
}

/********************************************************************************************************
 * 说明:LED_Off函数,用于控制电路板上LED的或熄灭。
 * 参数:INT8U led
 *              0    熄灭所有LED
 *              1-4  熄灭 LED1-LED4
 * 返回值:无
********************************************************************************************************/
void  LED_Off (INT8U led) {
    switch (led) {
        case 0:
             AT91C_BASE_PIOA->PIO_SODR = BSP_LED4 | BSP_LED3 | BSP_LED2 | BSP_LED1;
             break;
        case 1:
             AT91C_BASE_PIOA->PIO_SODR = BSP_LED1;
             break;
        case 2:
             AT91C_BASE_PIOA->PIO_SODR = BSP_LED2;
             break;
        case 3:
             AT91C_BASE_PIOA->PIO_SODR = BSP_LED3;
             break;
        case 4:
             AT91C_BASE_PIOA->PIO_SODR = BSP_LED4;
             break;
    }
}

/********************************************************************************************************
 * 说明:LED_Toggle函数,用于Toggle(交替点亮或熄灭)LED。
 * 参数:INT8U led
 *              0    Toggle 所有LED
 *              1-4  Toggle LED1-LED4
 * 返回值:无
********************************************************************************************************/
void  LED_Toggle (INT8U led) {
    switch (led) {
        case 0:
             if (AT91C_BASE_PIOA->PIO_ODSR & BSP_LED1) {
                 AT91C_BASE_PIOA->PIO_CODR = BSP_LED1;
             } else {
                 AT91C_BASE_PIOA->PIO_SODR = BSP_LED1;
             }
             if (AT91C_BASE_PIOA->PIO_ODSR & BSP_LED2) {
                 AT91C_BASE_PIOA->PIO_CODR = BSP_LED2;
             } else {
                 AT91C_BASE_PIOA->PIO_SODR = BSP_LED2;
             }
             if (AT91C_BASE_PIOA->PIO_ODSR & BSP_LED3) {
                 AT91C_BASE_PIOA->PIO_CODR = BSP_LED3;
             } else {
                 AT91C_BASE_PIOA->PIO_SODR = BSP_LED3;
             }
             if (AT91C_BASE_PIOA->PIO_ODSR & BSP_LED4) {
                 AT91C_BASE_PIOA->PIO_CODR = BSP_LED4;
             } else {
                 AT91C_BASE_PIOA->PIO_SODR = BSP_LED4;
             }
             break;
        case 1:
             if (AT91C_BASE_PIOA->PIO_ODSR & BSP_LED1) {
                 AT91C_BASE_PIOA->PIO_CODR = BSP_LED1;
             } else {
                 AT91C_BASE_PIOA->PIO_SODR = BSP_LED1;
             }
             break;
        case 2:
             if (AT91C_BASE_PIOA->PIO_ODSR & BSP_LED2) {
                 AT91C_BASE_PIOA->PIO_CODR = BSP_LED2;
             } else {
                 AT91C_BASE_PIOA->PIO_SODR = BSP_LED2;
             }
             break;
        case 3:
             if (AT91C_BASE_PIOA->PIO_ODSR & BSP_LED3) {
                 AT91C_BASE_PIOA->PIO_CODR = BSP_LED3;
             } else {
                 AT91C_BASE_PIOA->PIO_SODR = BSP_LED3;
             }
             break;
        case 4:
             if (AT91C_BASE_PIOA->PIO_ODSR & BSP_LED4) {
                 AT91C_BASE_PIOA->PIO_CODR = BSP_LED4;
             } else {
                 AT91C_BASE_PIOA->PIO_SODR = BSP_LED4;
             }
             break;
    }
}

/********************************************************************************************************
 * 说明:OS_CPU_IRQ_ISR_Handler函数,IRQ中断句柄,由OS_CPU_IRQ_ISR()函数调用,确定中断源并处理。
 * 参数:无
 * 返回值:无
********************************************************************************************************/
void  OS_CPU_IRQ_ISR_Handler (void) {
    BSP_PFNCT  pfnct;
#if 1
    pfnct = (BSP_PFNCT)AT91C_BASE_AIC->AIC_IVR;     // 从AIC中读取中断向量
    if (pfnct != (BSP_PFNCT)0) {                    // 确保没有 NULL 指针
        (*pfnct)();                                 // 执行中断函数
    }
#else
    pfnct = (BSP_PFNCT)AT91C_BASE_AIC->AIC_IVR;     // 从AIC中读取中断向量
    while (pfnct != (BSP_PFNCT)0) {                 // 确保没有 NULL 指针
       (*pfnct)();                                   // 执行中断函数
        pfnct = (BSP_PFNCT)AT91C_BASE_AIC->AIC_IVR; // 从AIC中读取中断向量
    }
#endif
}

/*********************************************************************************************************
 *说明:OS_CPU_FIQ_ISR_Handler函数,FIQ中断句炳,由OS_CPU_IRQ_ISR()函数调用,确定中断源并处理。
 * 参数:无
 * 返回值:无
********************************************************************************************************/
void  OS_CPU_FIQ_ISR_Handler (void) {
    BSP_PFNCT  pfnct;
#if 1
    pfnct = (BSP_PFNCT)AT91C_BASE_AIC->AIC_FVR;     // 从AIC中读取中断向量
    if (pfnct != (BSP_PFNCT)0) {                    // 确保没有 NULL 指针
        (*pfnct)();                                 // 执行中断函数
    }
#else
    pfnct = (BSP_PFNCT)AT91C_BASE_AIC->AIC_FVR;     // 从AIC中读取中断向量
    while (pfnct != (BSP_PFNCT)0) {                 // 确保没有 NULL 指针
      (*pfnct)();                                   // 执行中断函数
        pfnct = (BSP_PFNCT)AT91C_BASE_AIC->AIC_FVR; // 从AIC中读取中断向量
    }
#endif
}

/*********************************************************************************************************
 *说明:Tmr_TickInit函数,用于进行节拍初始化(通常使用一个定时器每1-100ms产生一次中断)。
 * 参数:无
 * 返回值:无
 * 注(1) PIT Interrupt frequency:
 *                         MCLK        1
 *               Freq =    ---- * -----------
 *                          16     (PIV + 1)
 *
 *                         MCLK      1
 *               PIV  =  ( ---- * ------ ) - 1
 *                          16     Freq
 *
 *其中:MCLK = 48 MHz (i.e 48,000,000)
 *      Freq = Desired frequency (i.e. OS_TICKS_PER_SEC)
********************************************************************************************************/
static  void  Tmr_TickInit (void) {
    INT32U  counts;
    // 设置PIT向量地址
    AT91C_BASE_AIC->AIC_SVR[AT91C_ID_SYS] = (INT32U)Tmr_TickISR_Handler;
    AT91C_BASE_AIC->AIC_SMR[AT91C_ID_SYS] = AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE
                                          | AT91C_AIC_PRIOR_LOWEST;
    AT91C_BASE_AIC->AIC_ICCR              = 1 << AT91C_ID_SYS;
    AT91C_BASE_AIC->AIC_IECR              = 1 << AT91C_ID_SYS;
    counts                                = (48000000 / 16 / OS_TICKS_PER_SEC) - 1;
    // #define AT91C_BASE_PITC      ((AT91PS_PITC) 	0xFFFFFD30) // (PITC) Base Address
    AT91C_BASE_PITC->PITC_PIMR            = AT91C_PITC_PITEN | AT91C_PITC_PITIEN | counts;
}


/*********************************************************************************************************
 *说明:Tmr_TickISR_Handler函数,PIT IRQ 句柄。用于处理产生uC/OS-II节拍的PIT中断。
 * 参数:无
 * 返回值:无
*********************************************************************************************************/
static  void  Tmr_TickISR_Handler (void) {
    volatile  INT32U  status;
    status                    = AT91C_BASE_PITC->PITC_PIVR;
    AT91C_BASE_AIC->AIC_IVR   = 0;
    AT91C_BASE_AIC->AIC_ICCR  = AT91C_ID_SYS; // 清除timer0 中断
    AT91C_BASE_AIC->AIC_EOICR = 0;            // 中断结束信号
    OSTimeTick();                             // 通知 uC/OS-II 时钟节拍
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -