前言
在开发TM4C123的时候,我看到ROM函数和非ROM函数。例如ROM_FPUEnable()和FPUEnable()函数,这两个就只是前缀不一样。有什么区别和不同?
相同点
ROM函数和非ROM函数的作用起始是一样的,比如上面的例子ROM_FPUEnable()和FPUEnable()这两个函数都是用于使能浮点单元。他们两个从运行结果上来看,效果是相同的。
不同点
官方解释
(1)ROM版的是内嵌在BOOT ROM中的,而普通版本的,是以库形式提供的。
(2)所以,ROM版的好处在于,可以节省程序空间,但缺点是调用时需要一个wait states,影响执行效率;而普通版的正好相反。
(3)如何取舍取决于具体应用。如果对程序的大小要求比较严苛,就使用ROM版的;而对执行效率要求比较高的话,就选择普通版的。
ROM_FPUEnable()函数实现
(1)如下是ROM_FPUEnable()的实际函数实现。我们查阅芯片手册可以知道0x01000000是ROM的起始地址。
(2)而ROM包含如下四个元素
<1>TivaWare™引导加载程序和向量表
<2>TivaWare外设驱动库(DriverLib)发布的特定产品外设和接口
<3>高级加密标准(AES)加密表
<4>循环冗余检查(CRC)错误检测功能
(3)下面也介绍到,ROM中的外设驱动程序库api可以被应用程序调用,减少了对Flash内存的需求,并将Flash内存释放出来用于其他用途(例如应用程序中的其他特性)。
(4)所以说,ROM函数是直接调用ROM中的数据,这样可以有效的节约Flash负载。
#define ROM_FPUEnable ((void (*)(void))ROM_FPUTABLE[0]) #define ROM_FPUTABLE ((uint32_t *)(ROM_APITABLE[26])) #define ROM_APITABLE ((uint32_t *)0x01000010)
FPUEnable()函数实现
我们可以看到,他就是直接对寄存器进行操作。我们查手册知道,他这个就是直接对对应的寄存器进行操作。所以会会编写进入代码段,也就会进入Flash中
#define HWREG(x) (*((volatile uint32_t *)(x))) #define NVIC_CPAC 0xE000ED88 // Coprocessor Access Control #define NVIC_CPAC_CP10_M 0x00300000 // CP10 Coprocessor Access #define NVIC_CPAC_CP11_M 0x00C00000 // CP11 Coprocessor Access #define NVIC_CPAC_CP10_FULL 0x00300000 // Full Access #define NVIC_CPAC_CP11_FULL 0x00C00000 // Full Access void FPUEnable(void) { // // Enable the coprocessors used by the floating-point unit. // HWREG(NVIC_CPAC) = ((HWREG(NVIC_CPAC) & ~(NVIC_CPAC_CP10_M | NVIC_CPAC_CP11_M)) | NVIC_CPAC_CP10_FULL | NVIC_CPAC_CP11_FULL); }
建议
(1)从我个人的角度来看,我建议一些初始化的程序,也就是while(1)之前的函数都采用ROM函数。这样能够尽可能的节约程序空间。
(2)while(1)之中的程序可以根据需求来选择是ROM还是非ROM版本。如果while(1)中程序很多,就采用ROM版本,如果并不多,还是采用非ROM版本更好。
(3)中断程序中,最好使用非ROM版本的函数,因为中断程序要求快速响应。