HEXIWEAR---SDK架構

這裏寫圖片描述

首先SDK由platform平臺代碼和FreeRTOS操作系統代碼組成

1.platform平臺代碼下,我們先分析CMSIS和devices,對應下圖中倒數第二層:CMSIS-CORE and CMSIS-DSP

這裏寫圖片描述
CMSIS:
● Cortex-M3內核及其設備文件(core_cm0.h + core_cm0.c)
─ 訪問Cortex-M0內核及其設備:NVIC等
─ 訪問Cortex-M0的CPU寄存器和內核外設的函數

devices:
● 微控制器專用頭文件(device.h) - MK64F12.h
─ 指定中斷號碼(與啓動文件一致)
─ 外設寄存器定義(寄存器的基地址和佈局)
─ 控制微控制器其他特有的功能的函數(可選)
note:這裏除了MK64F12.h,還有MK64F12_extension.h和MK64F12_features.h 。

MK64F12.h定義處理器各個外設的首地址和對應的寄存器訪問宏定義

 /** ADC - Register accessors */
#define ADC_SC1_REG(base,index)                  ((base)->SC1[index])
#define ADC_SC1_COUNT                            2
#define ADC_CFG1_REG(base)                       ((base)->CFG1)
#define ADC_CFG2_REG(base)                       ((base)->CFG2)
#define ADC_R_REG(base,index)                    ((base)->R[index])
#define ADC_R_COUNT                              2
#define ADC_CV1_REG(base)                        ((base)->CV1)
#define ADC_CV2_REG(base)                        ((base)->CV2)
#define ADC_SC2_REG(base)                        ((base)->SC2)
#define ADC_SC3_REG(base)                        ((base)->SC3)
#define ADC_OFS_REG(base)                        ((base)->OFS)
#define ADC_PG_REG(base)                         ((base)->PG)
#define ADC_MG_REG(base)                         ((base)->MG)
#define ADC_CLPD_REG(base)                       ((base)->CLPD)
#define ADC_CLPS_REG(base)                       ((base)->CLPS)
#define ADC_CLP4_REG(base)                       ((base)->CLP4)
#define ADC_CLP3_REG(base)                       ((base)->CLP3)
#define ADC_CLP2_REG(base)                       ((base)->CLP2)
#define ADC_CLP1_REG(base)                       ((base)->CLP1)
#define ADC_CLP0_REG(base)                       ((base)->CLP0)
#define ADC_CLMD_REG(base)                       ((base)->CLMD)
#define ADC_CLMS_REG(base)                       ((base)->CLMS)
#define ADC_CLM4_REG(base)                       ((base)->CLM4)
#define ADC_CLM3_REG(base)                       ((base)->CLM3)
#define ADC_CLM2_REG(base)                       ((base)->CLM2)
#define ADC_CLM1_REG(base)                       ((base)->CLM1)
#define ADC_CLM0_REG(base)                       ((base)->CLM0)

MK64F12_features.h 主要用宏對處理器上的外設的一些特性進行定義。拿ADC16來看,就是定義ADC16有沒有FIFO,有沒有PGA,有沒有DMA等。

 /** ADC16 module features */

/* @brief Has Programmable Gain Amplifier (PGA) in ADC (register PGA). */
#define FSL_FEATURE_ADC16_HAS_PGA (0)
/* @brief Has PGA chopping control in ADC (bit PGA[PGACHPb] or PGA[PGACHP]). */
#define FSL_FEATURE_ADC16_HAS_PGA_CHOPPING (0)
/* @brief Has PGA offset measurement mode in ADC (bit PGA[PGAOFSM]). */
#define FSL_FEATURE_ADC16_HAS_PGA_OFFSET_MEASUREMENT (0)
/* @brief Has DMA support (bit SC2[DMAEN] or SC4[DMAEN]). */
#define FSL_FEATURE_ADC16_HAS_DMA (1)
/* @brief Has differential mode (bitfield SC1x[DIFF]). */
#define FSL_FEATURE_ADC16_HAS_DIFF_MODE (1)
/* @brief Has FIFO (bit SC4[AFDEP]). */
#define FSL_FEATURE_ADC16_HAS_FIFO (0)
/* @brief FIFO size if available (bitfield SC4[AFDEP]). */
#define FSL_FEATURE_ADC16_FIFO_SIZE (0)
/* @brief Has channel set a/b multiplexor (bitfield CFG2[MUXSEL]). */
#define FSL_FEATURE_ADC16_HAS_MUX_SELECT (1)
/* @brief Has HW trigger masking (bitfield SC5[HTRGMASKE]. */
#define FSL_FEATURE_ADC16_HAS_HW_TRIGGER_MASK (0)
/* @brief Has calibration feature (bit SC3[CAL] and registers CLPx, CLMx). */
#define FSL_FEATURE_ADC16_HAS_CALIBRATION (1)
/* @brief Has HW averaging (bit SC3[AVGE]). */
#define FSL_FEATURE_ADC16_HAS_HW_AVERAGE (1)
/* @brief Has offset correction (register OFS). */
#define FSL_FEATURE_ADC16_HAS_OFFSET_CORRECTION (1)
/* @brief Maximum ADC resolution. */
#define FSL_FEATURE_ADC16_MAX_RESOLUTION (16)
/* @brief Number of SC1x and Rx register pairs (conversion control and result registers). */
#define FSL_FEATURE_ADC16_CONVERSION_CONTROL_COUNT (2)

MK64F12_extension.h 根據各個外設的各個寄存器的功能,定義對應於寄存器功能位的具體操作宏定義。
比如:
#define ADC_RD_SC1_DIFF(base, index) ((ADC_SC1_REG(base, index) & ADC_SC1_DIFF_MASK) >> ADC_SC1_DIFF_SHIFT)
就是讀取ADC_SC1寄存器對應diff的位域的值。

#define ADC_INSTANCE_COUNT (2U) /*!< Number of instances of the ADC module. */
#define ADC0_IDX (0U) /*!< Instance number for ADC0. */
#define ADC1_IDX (1U) /*!< Instance number for ADC1. */


/*!
 * @name Constants and macros for entire ADC_SC1 register
 */
/*@{*/
#define ADC_RD_SC1(base, index)  (ADC_SC1_REG(base, index))
#define ADC_WR_SC1(base, index, value) (ADC_SC1_REG(base, index) = (value))
#define ADC_RMW_SC1(base, index, mask, value) (ADC_WR_SC1(base, index, (ADC_RD_SC1(base, index) & ~(mask)) | (value)))
#define ADC_SET_SC1(base, index, value) (ADC_WR_SC1(base, index, ADC_RD_SC1(base, index) |  (value)))
#define ADC_CLR_SC1(base, index, value) (ADC_WR_SC1(base, index, ADC_RD_SC1(base, index) & ~(value)))
#define ADC_TOG_SC1(base, index, value) (ADC_WR_SC1(base, index, ADC_RD_SC1(base, index) ^  (value)))
/*@}*/

● 微控制器專用系統文件(system_device.c) – system_MK64F12.h + system_MK64F12 .c
─ 函數SystemInit,用來初始化微控制器
–函數 void SystemCoreClockUpdate (void); 用於獲取內核時鐘頻率
─SystemCoreClock,該值代表系統時鐘頻率
─ 微控制器的其他功能(可選)

● 編譯器啓動代碼(彙編或者C)(startup_device.s) - startup_MKL25Z4.s for Keil
─ 微控制器專用的中斷處理程序列表(與頭文件一致)
─ 弱定義(Weak)的中斷處理程序默認函數(可以被用戶代碼覆蓋)

2.分析drivers驅動層和hal硬件抽象層的區別和關聯,這兩個合起來對應於下圖的Peripheral Drivers這一層。

這裏寫圖片描述

這裏寫圖片描述
這裏寫圖片描述

hal下的代碼是硬件抽象層代碼,他通過調用MK64F12.h,還有MK64F12_extension.h裏的寄存器操作宏定義來實現以下具體功能,比如初始化ADC16模塊,配置通道等。

void ADC16_HAL_Init(ADC_Type * base)
{
    ADC_WR_CFG1(base, 0U);
    ADC_WR_CFG2(base, 0U);
    ADC_WR_CV1(base, 0U);
    ADC_WR_CV2(base, 0U);
    ADC_WR_SC2(base, 0U);
    ADC_WR_SC3(base, 0U);
#if FSL_FEATURE_ADC16_HAS_PGA
    ADC_WR_PGA(base, 0U);
#endif  /** FSL_FEATURE_ADC16_HAS_PGA */
}

drivers下的代碼是對硬件抽象層hal代碼的進一步抽象提升。
我們可以比較以下drivers和hal文件夾下的子目錄
這裏寫圖片描述
你會發現drivers比hal少了dmamux llwu mcg osc port rcm sim smc.
你會發現這些是adc16等這些共有模塊或多或少都要交互依賴的模塊。Adc16也需要時鐘,所以要使ADC正常使用,我們必須設計osc mcg sim 時鐘的設置。

adc16_status_t ADC16_DRV_Init(uint32_t instance, const adc16_converter_config_t *userConfigPtr)
{
    assert(instance < ADC_INSTANCE_COUNT);
    ADC_Type * base = g_adcBase[instance];

    if (!userConfigPtr)
    {
        return kStatus_ADC16_InvalidArgument;
    }
     /** Enable clock for ADC. */
    CLOCK_SYS_EnableAdcClock(instance);

     /** Reset all the register to a known state. */
    ADC16_HAL_Init(base);
    ADC16_HAL_ConfigConverter(base, userConfigPtr);

     /** Enable ADC interrupt in NVIC level.*/
    INT_SYS_EnableIRQ(g_adcIrqId[instance] );

    return kStatus_ADC16_Success;
}

從上面可以看到,ADC的正常初始化,不僅需要hal下adc的初始化 通道初始化,還需要時鐘設置和中斷設置。

3.FreeRTOS

這裏寫圖片描述
操作系統應該調用驅動來實現對硬件的控制,上圖中竟然平齊,這是什麼道理???

操作系統其實不會調用驅動。而是由操作系統輪詢的各個task會調用API。操作系統用到的硬件資源有timer。可以在工程裏查找xPortStartScheduler這個函數,這裏面會配置操作系統用到的定時器。這個定時器就不能它用了。

詳細的FreeRTOS任務切換解析可以參考下面的博客:
http://blog.sina.com.cn/s/blog_5f0bed160100tqnu.html

main()
{

 prvSetupHardware();//初始化硬件(處理器IO,初始化等)

//創建第一個任務  vTestTask.任務創建參考----FreeRTOS任務管理與控制--------
 xTaskCreate( vTestTask, ( signed portCHAR *) "Test", configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY+1), NULL);

//開啓內核運行,調度便由此開始。
vTaskStartScheduler();

}
void main()
{
  /** initialize the hardware */
  PE_low_level_init();

  /** disable write buffering end enable ARM exceptions */
  HEXIWEAR_EnableExceptions();

  /** initialize the startup task */
  HEXIWEAR_Init();

  /** start RTOS scheduler */
  HEXIWEAR_Start();

  while (1) {}
}



這裏寫圖片描述

4.時鐘-中斷-功耗 管理

這裏寫圖片描述

發佈了51 篇原創文章 · 獲贊 26 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章