小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

痞子衡嵌入式:超級下載算法(RT-UFL)開發(fā)筆記(2) - 識別當(dāng)前i.MXRT型號

 Coder編程 2022-05-25 發(fā)布于北京

  大家好,我是痞子衡,是正經(jīng)搞技術(shù)的痞子。今天痞子衡給大家介紹的是超級下載算法開發(fā)筆記(2)之識別當(dāng)前i.MXRT型號

  文接上篇 《超級下載算法(RT-UFL)開發(fā)筆記(1) - 執(zhí)行在不同CM內(nèi)核下》,我們已經(jīng)解決了超級下載算法能夠在i.MXRT全系列下執(zhí)行的問題,現(xiàn)在我們往前繼續(xù)推進項目。因為這個超級下載算法將來要跑在很多個芯片型號上,有時候因為型號間差異,我們不得不針對性地弄出不同代碼處理分支,而這一切的前提是我們能動態(tài)地獲取當(dāng)前芯片型號。

  本篇是開發(fā)筆記第二篇,咱們就重點聊聊如何讓超級下載算法知道當(dāng)前跑在哪個i.MXRT型號下。

一、尋找i.MXRT家族的ID信息

  恩智浦當(dāng)前MCU產(chǎn)品線眾多,i.MXRT是2018年才開始推出的新系列,在這之前恩智浦主推的MCU是經(jīng)典的Kinetis和LPC系列,痞子衡對這兩個系列產(chǎn)品也非常熟,型號信息在Kinetis和LPC上都有展現(xiàn)。

1.1 回顧Kinetis和LPC

  Kinetis系列有一個專門存放型號信息的寄存器即SIM->SDID,這個寄存器設(shè)計得非常經(jīng)典,其FAMILYID + SUBFAMID + SERIESID區(qū)域組合將Kinetis系列的家族分類特性展示得淋漓盡致。

  LPC系列存放型號信息的寄存器是SYSCON->DEVICE_ID0,這個寄存器是另外一種設(shè)計風(fēng)格,低20bit直接就是LPC系列號的值,比如LPC54114xxx型號其SYSCON->DEVICE_ID0[19:0] = 0x54114,是不是簡單粗暴。

1.2 查找i.MXRT的ID寄存器

  我們知道i.MXRT從架構(gòu)上分為四位數(shù)和三位數(shù)兩大陣營,四位數(shù)源自i.MX應(yīng)用處理器,三位數(shù)源自LPC系列,我們分別來看。

  翻看i.MXRT四位數(shù)典型型號i.MXRT1060的參考手冊,并沒有找到任何有關(guān)型號信息的寄存器,僅有UID寄存器,但UID跟芯片型號無關(guān)。四位數(shù)上找不到型號信息寄存器,也跟其源于i.MX有關(guān),畢竟MPU不像MCU那樣會細(xì)分特別多的型號。

  再看i.MXRT三位數(shù)典型型號i.MXRT600的參考手冊,我們找到了型號信息,在SYSCTL0->PRODUCT_ID寄存器中,細(xì)看其寄存器設(shè)計,還是能看出LPC的影子的,SYSCTL0->PRODUCT_ID[15:4]直接就是系列號的值。

二、確認(rèn)i.MXRT型號的替代方法

  根據(jù)上一節(jié)的分析,我們幾乎不能用傳統(tǒng)Kinetis或LPC上型號信息寄存器那一套方式來統(tǒng)一獲取i.MXRT型號,那有沒有替代方法呢?答案當(dāng)然是有。靈感來自于痞子衡之前研究i.MXRT的ROM API時寫過的一篇文章 《了解i.MXRTxxx系列ROM API及其與i.MXRT1xxx系列的差異》,i.MXRT系列全部都有BootROM,每個型號的ROM區(qū)域內(nèi)容并不盡然相同,我們可以通過讀幾個ROM區(qū)域不同位置的值來定位型號。

2.1 讀SCB->CPUID得到內(nèi)核版本

  i.MXRT四位數(shù)(都是CM7內(nèi)核)的ROM基址是0x200000,而i.MXRT三位數(shù)(都是CM33內(nèi)核)的ROM基址是0x3000000,基址是有差異的,所以我們首先需要先找出一種方法來區(qū)分基址,這里可以借助ARM Cortex-M內(nèi)核模塊SCB里的CPUID寄存器。

  翻看ARM Cortex-M內(nèi)核的Generic User Guide,可以找到如下CPUID寄存器的定義,其中CPUID[PartNo]中記錄了內(nèi)核版本,CM7的值是0xC27,CM33的值是0xD21。

  我們可以很容易寫出如下ufl_get_core_type()函數(shù)。

/* See Part number of core in Cortex-Mx Generic UG */
#define CORE_ID_CM33 (0xD21)
#define CORE_ID_CM7  (0xC27)

typedef enum _core_type
{
    kCoreType_Invalid = 0U,
    kCoreType_CM33    = 1U,
    kCoreType_CM7     = 2U,
} core_type_t;

static core_type_t ufl_get_core_type(void)
{
    core_type_t coreType = kCoreType_Invalid;
    uint32_t coreid = (SCB->CPUID & SCB_CPUID_PARTNO_Msk) >> SCB_CPUID_PARTNO_Pos;

    switch (coreid)
    {
        case CORE_ID_CM33:
            coreType = kCoreType_CM33;
            break;

        case CORE_ID_CM7:
            coreType = kCoreType_CM7;
            break;

        default:
            break;
    }

    return coreType;
}

2.2 通過ROM內(nèi)容定位i.MXRT型號

  有了ufl_get_core_type()函數(shù),我們便可以進一步寫出如下ufl_get_imxrt_chip_id()函數(shù),s_romFingerprint[]結(jié)構(gòu)體數(shù)組預(yù)先存放全部i.MXRT型號的ROM定位信息(此處僅示例了RT600和RT1060),我們選了ROM偏移0x8000、0xa000、0xc000處的四字節(jié)數(shù)據(jù)來定位,如后期隨著型號的增多,出現(xiàn)定位位置處數(shù)據(jù)全部雷同的巧合的話,可以更改定位位置保證定位數(shù)據(jù)一定不相同。

typedef enum _rt_chip_id
{
    kChipId_Invalid = 0xFFU,
    kChipId_RT6xx   = 1U,
    kChipId_RT106x  = 2U,
} rt_chip_id_t;

#define RT_ROM_BASE_CM33 (0x03000000u)
#define RT_ROM_BASE_CM7  (0x00200000u)

#define ROM_FP_OFFSET1 (0x8000)
#define ROM_FP_OFFSET2 (0xa000)
#define ROM_FP_OFFSET3 (0xc000)

typedef struct _rom_fingerprint
{
    uint32_t chipId;
    uint32_t content[3];
} rom_fingerprint_t;

static const rom_fingerprint_t s_romFingerprint[] = {
    {kChipId_RT6xx,  {0xb108f82a, 0x0200f2c5, 0x0070f104} },        // From ROM 2.0rc5.1
    {kChipId_RT106x, {0xb0893000, 0x80dbf000, 0xf2c44100} },        // From ROM 1.0rc3
};

rt_chip_id_t ufl_get_imxrt_chip_id(void)
{
    rt_chip_id_t chipId = kChipId_Invalid;
    core_type_t coreType;
    uint32_t rtRomBase = 0;

    coreType = ufl_get_core_type();
    if (kCoreType_CM33 == coreType)
    {
        rtRomBase = RT_ROM_BASE_CM33;
    }
    else if (kCoreType_CM7 == coreType)
    {
        rtRomBase = RT_ROM_BASE_CM7;
    }
    else
    {}

    do
    {
        uint32_t content[3];
        content[0] = *(uint32_t *)(rtRomBase + ROM_FP_OFFSET1);
        content[1] = *(uint32_t *)(rtRomBase + ROM_FP_OFFSET2);
        content[2] = *(uint32_t *)(rtRomBase + ROM_FP_OFFSET3);

        uint32_t idx = sizeof(s_romFingerprint) / sizeof(rom_fingerprint_t);
        while (idx--)
        {
            if (!memcmp(s_romFingerprint[idx].content, content, sizeof(content)))
            {
                chipId = (rt_chip_id_t)s_romFingerprint[idx].chipId;
                break;
            }
        }
    } while (0);

    return chipId;
}

  至此,超級下載算法開發(fā)筆記(2)之識別當(dāng)前i.MXRT型號痞子衡便介紹完畢了,掌聲在哪里~~~ 

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多