新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM Cortex―M0/M0+單片機的指針變量替換方法

        ARM Cortex―M0/M0+單片機的指針變量替換方法

        作者: 時間:2016-09-12 來源:網絡 收藏

        摘要:32位ARM Cortex-M0/M0+內核定位于“全面替代”各類8/16位微控制器(MCU)內核,其硬件設計支持使用16位短指針變量。目前主流的ARM編譯器僅使用32位長指針變量,這對于資源有限的MCU來說十分浪費。為了優化指針變量的使用方式、節約資源,本文給出一種替換長指針的方法,并以運行μC/OS-II為例,說明替換效果。

        本文引用地址:http://www.104case.com/article/201609/304500.htm

        引言

        Cortex—M0/M0+是RISC類型的低端ARM內核,其指令集與高端ARM兼容,在性能、功耗和價格方面遠優于傳統的以8051、68S08/12等為代表的8/16位CISC(復雜指令流)CPU。目前,各半導體廠商紛紛以之替代原有的8/16位MCU內核,32位ARM MCU全面替代8/16位MCU已是大勢所趨。

        Cortex—M0+將Cortex—M0的3級流水線簡化為2級,并進一步降低功耗、提高性能,這些優點使得Cortex—M0+成為目前8/16位處理器較好的替代者。不過替代8/16位MCU的低端ARM往往內存資源非常有限,目前典型的Cortex—M0/M0+MCU往往僅有2 KB、4 KB或8 KB,最多16 KB片內,Flash一般也不大于64KB。對這類MCU編程,使用短指針變量就夠了。而目前ARM處理器的集成開發環境(IDE)中的C編譯器,延續Cortex—M3/M4的使用傳統,仍使用32位長指針變量。這無形中多占用了1倍的資源。這里以飛思卡爾ARM Cortex—M0+處理器中的Kine tis系列MCU為例,說明如何使用16位短指針替代32位長指針,以便在將原有的以8/16位MCU為核心的產品升級到采用32位ARM內核時,不增加系統開銷。特別是若使用了實時操作系統,系統的內存會更加緊張。在專門面向Cortex—M0/M0+的集成開發環境(IDE)推出前,可使用本文提供的替換方法,以降低系統的RAM開銷,提升系統的性能。

        1 原理

        32位ARM內核的內部寄存器都是32位的,其尋址空間可以達到4 GB,通常也應使用32位的地址指針。但在數據空間、程序空間和I/O空間都不大于64 KB的情況下,可以采用1個32位基地址加1個16位偏移量的方法,合成ARM需要的長指針。

        以Cortex—M0+為內核的MCU,其SRAM、FLASH很少超過64 KB,一般使用16位的偏移量指針就能滿足需要。

        以Freescale公司的KL25Z128 MCU為例,有16 KBSRAM和128 KB FLASH存儲空間。其SRAM的地址范圍是0x1FFF_F000~0x2000_2FFF,使用16位的偏移量指針便可以滿足尋址范圍的要求。

        圖1說明了長方法的基本原理,通過使用一個32位的RAM基地址,完成原始32位絕對地址與相對基地址的16位相對偏移地址的相互轉化。

        ARM Cortex—M0/M0+單片機的指針變量替換方法

        其轉化關系如下所示:

        Address_32bits=Address_16bits+Address_base (1)

        Address_16bits=Address_32bits_Address_base (2)

        對于KL25Z128,Address_base基地址值可選擇為0x1FFF F000。通過以上方法的轉化,32位的地址空間0x1FFF_F000~0x2000_2FFF(16 KB)可以轉化為16位的地址空間0x0000~0x3FFF(16 KB)。

        2 方案

        2.1 常量形式實現方案

        以下使用Freescale公司推薦的IDE CodeWarriorv10.5予以說明。

        ARM Cortex—M0/M0+單片機的指針變量替換方法

        程序中利用宏定義了一個32位常數的基地址,顯然也可以使用一個全局變量或寄存器變量來存儲基地址。在將長指針變量pt_addr_32轉化為16位地址“指針”時,需先將指針變量pt_addr_32做強制類型轉化,變為32位無符號數后再進行基地址扣除的計算。該段代碼還聲明了一個16位無符號數的數據類型pointer_16,用來定義或存儲16位地址偏移量,例如使用如下語句來定義一個16位的指針變量:

        pointer_16 ptl6_data=addr_16(data);

        ptl6_data的值便是指向data的16位“指針”(轉化而成的16位地址偏移量值),編譯器編譯出的匯編代碼如下所示:

        ARM Cortex—M0/M0+單片機的指針變量替換方法

        需要將16位地址轉化為長指針時,以下面的整型數據賦值操作為例:

        int temp=*(int*)(addr_32(ptl6_data));

        數據data的值賦值給了變量temp,其中int數據類型可以替換成任意其他的數據類型(例如unsigned int、unsigrted short、short、unsigned char、char等)。

        2.2 高組寄存器優化方案

        Cortex—M系列內核是專門為ARM MCU設計的,僅支持無條件執行的Thumb指令。Cortex—M0/M0+使用ARMv6指令集,而Cortex-M3/M4使用ARMv7指令集。ARMv6對ARMv7做了高度簡化,僅保留了其中56條指令。指令中除個別32位指令外,都是16位指令。Cortex—M0/M0+的內部寄存器結構與高端ARM兼容,但低端MCU應用往往不需要那么多寄存器,Cortex—M0/M0+僅提供了R0~R12共13個通用寄存器。這些通用寄存器分為兩部分:低組寄存器(Low registers,R0~R7),高組寄存器(High registers,R8~R12)。Cortex—M0/M0+犧牲了大量面向高組寄存器的指令,盡量減少32位指令的使用。實際上Cortex—M0/M0+的指令集中僅有以下3條指令支持高組寄存器R8~R12:

        MOV ;寄存器間數據傳送

        ADD ;基地址+偏移量

        CMP ;地址的比較

        這里Rd和Rm之一可以是高組寄存器。可以看出,對于高組寄存器,ARMv6僅保留了高低組寄存器間數據傳遞、不影響標志位的加法運算和單獨的地址比較這3種操作,其用處顯然是為了支持將高組寄存器用于地址運算。

        目前基于gcc的主流ARMC編譯器對Cortex—M0/M0+的高組寄存器采取盡量不予使用的策略,在定義指針變量時,僅使用長指針。而分析ARMv6指令集的設計初衷,顯然應該用高組寄存器和相關指令。這對于旨在替代8/16位MCU的低成本ARM器件非常必要。


        上一頁 1 2 下一頁

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 郓城县| 毕节市| 乌鲁木齐市| 长治县| 濉溪县| 瓦房店市| 高密市| 兴城市| 泸溪县| 巴里| 北川| 定南县| 青川县| 棋牌| 宁蒗| 阜康市| 民勤县| 甘洛县| 罗甸县| 贵定县| 海丰县| 东宁县| 抚宁县| 商洛市| 延川县| 弥勒县| 宿州市| 苏尼特右旗| 鹤壁市| 元江| 安仁县| 定襄县| 蕲春县| 哈巴河县| 颍上县| 余庆县| 秦安县| 吴江市| 思南县| 麻江县| 岚皋县|