cc2640蓝牙芯片软件开发指导说明文件 - 图文 下载本文

3. 当手动修改ICALL_RAM0_ADDR之后发生了连接错误,验证每个工程是否有足够的RAM调

用空间

3.11.5 动态内存调用

该系统使用了两个堆来实现动态内存调用。因此明白每个堆的用法很重要,这样应用开发者就可以最大限度的使用提供的内存了。

RTOS配置了一个小的堆在appBLE.cfgRTOS配置文件中:

var HeapMem = xdc.useModule('xdc.runtime.HeapMem'); BIOS.heapSize = 1668;

这个堆(“heapMEM”)用于初始化RTOS实体和分配BLE协议栈任务的运行时间的栈。这个堆的大小需要选择以适应系统初始化的要求。因为该堆的小尺寸,不允许调用RTOS堆的内存空间给一般应用使用。要获得关于TI-RTOS堆配置的更多信息,请看SYS/BIOS用户指导中的堆的实现章节

相反,这里有一个单独的堆是留给应用使用的。Icall模块直接初始化一个应用的RAM,heapmgrHeapstore,这个区域可以被各种任务使用。这个Icall堆的大小是在应用进程宏HEAPMGR_SIZE定义的,SimpleBLEPeripheral工程中默认设为2672。尽管Icall堆在应用工程中定义,但是同样与BLE协议栈共享。为了增加Icall堆的大小,需要在应用工程中调整预处理符HEAPMGR_SIZE的值

为了确定Icall堆使用的数量,定义应用工程中的HEAPMGR_METRICS预处理符。参考$BLE_INSTALL$\\Components\\applib\\heap中heapmgr.h文件提供的堆度量。 这里有个关于动态在Icall堆中调用一个可变长度队列的例子:

//define pointer uint8_t *pArray;

// Create dynamic pointer to array.

if (pArray = (uint8_t*)ICall_malloc(n*sizeof(uint8_t))) {

//fill up array } else {

//not able to allocate }

这里是一个关于释放上面的队列的例子: Icall_free(pMsg->payLoad);

3.11.6 关于初始化RTOS实体的一个主意

因为RTOS的堆的大小是有限制的,所以强烈要求构建而不是创建RTOS实体。为了阐明这点,考虑Clock_construct()和Clock_create()函数之间的区别。这里是它们来自SYS/BIOS接口中的定义:

通过声明一个静态的Clock_Struct实体并发送这个实体到Clock_construct()中,这个真实的Clock_Struct的.DATA区域开始使用。不是限制的RTOS堆。相反,Clock_create()将会导

致RTOS为Clock_Struct分配RTOS的限制堆。

一般而言要尽可能的在贯穿整个工程中初始化时钟和RTOS实体。如果必须使用创建RTOS实体,那么RTOS堆就可能需要在appBLE.cfg中进行调整大小。

3.12使用边界工具来调节RAM & Flash的边界配置

边界工具(boundary.exe)在调整各自的预处理符时非常实用,ICALL_STACK0_ADDR(flash)和ICALL_RAM0_ADDR(RAM),这些边界都是在应用和栈工程之间共享的。边界工具可以通过调整边界来把没有用到的flash或者RAM的空间分配给应用工程。该工具消除了工作在双工程环境下手动调整RAM和Flash边界的必要。

边界工具不会修改工程文件。另外,边界工具也不会修改任何源代码或任何编译/链接的优化表现。该工具只是基于对工程映射和链接配置文件的分析后简单的调整RAM和Flash各自的边界地址。

边界工具安装路径为:

C:\\Program Files (x86)\\Texas Instruments\\Boundary

该路径下有个ReadMe.txt文件,该文件包含了该工具的其他信息。

3.12.1 配置边界工具

边界工具使用一个XML文件,BoundaryConfig.xml,位于工具的安装路径,用来配置默认的工具操作。要求保持这些默认值。

每个SDK中的工程都有一系列的配置文件,这些文件由IDE的连接器和编译器使用来设置或调整Flash和RAM各自的值。这些配置文件位于各自工程的如下位置:

$BLE_INSTALL$\\Projects\\ble\\\\CC26xx\\\\Config 当是工程(如SimpleBLEPeripheral)并且是IAR或CCS.

1. 边界连接器配置文件:IAR-Boundary.xcl [IAR] or ccsLinkerDefines.cmd [CCS].用于定义

ICALL_STACK0_ADDR和ICALL_RAM0_ADDR边界地址。这个文件位于TOOLS IDE文件夹下面并且在有调节需求是由边界工具更新。

2. 边界C的定义文件IAR-Boundary.cdef [IAR] or ccsCompilerDefines.bcfg [CCS].限于IAR或

CCS连接器的限制,ICALL_STACK0_ADDR必须在该文件中的定义与连接器中的配置文件中的定义一致。这个文件位于TOOLS IDE文件夹,当有调节需求时由边界工具更新。

3.12.2 边界工具操作

边界工具(boundary.exe)被作为一个栈工程IDE编译后的操作。如果需要对RAM和/或Flash的边界进行调整,边界工具会更新连接器或编译器各自的配置文件并生成一个编译后的错误来通知一个变化应经发生。为了配合配置值的更新,在应用和栈工程中各执行一个“Project

??Rebuild All”。

除了代码和内存的大小外,边界工具也会在计算ICALL_STACK0_ADDR的值时考虑预留下来的flash页。flash保留页的例子包含在CCA页。flash预留页在栈工程连接器配置文件中定义。 一个使用边界工具的先决条件就是应用和栈工程第一次编译必须是成功的。如果产生一个连接器错误,首先应验证本次的改变有没有超出设备flash和/或RAM内存的最大值。典型的连接器错误是当栈工程配置为使用要求外部flash内存的特性。依据错误是否由flash或RAM空间造成,在各自的连接器和编译器配置文件中手动调整flash和/或RAM的边界。一旦工程可以连接成功,边界工具会重新调整各自的边界值为最佳值。然后按照要求执行“Rebuild All”。

注意:除非IAR配置为展示所有的编译消息,否则是不会给出为什么边界工具会产生一个编译错误的原因的。当IAR配置为显示所有的编译消息,“TheProject Boundary Address Has Been Moved”就会显示在编译输出窗口。在IAR中设置Tools ??Options ??Messages ??Show Build Messages to “All”.

一个关于执行了边界修改的编译消息的例子如下:

/////////////////////////////////////////////////////////////////////// Boundary Operation Complete

/////////////////////////////////////////////////////////////////////// <<< WARNING >>>

The Project Boundary Address Has Been Moved Or A Config File Change Is Required Rebuild This Project For The Address Or Config File Change To Take Effect ///////////////////////////////////////////////////////////////////////

3.12.3 禁止使用边界工具

为了禁能边界工具,打开栈工程的工程操作项选择“Build Actions”(IAR)或者“Steps”在CCS Build window(CCS),然后想下图所示一处编译后命令行。最好提前对该命令进行备份以便后面会用到边界工具。一旦边界工具被禁能了,连接器和编译器各自的配置文件就可以像3.10.3和3.11.4节中的步骤进行手动编辑了。

4 应用

这一章经描述SimpleBLEPeipheral工程的应用部分,这些应用部分都包含: 1. Pre-RTOS初始化;

2. SimpleBLEPeripheral任务:这是个应用任务,是系统中优先级最低的任务。该任务的

代码包含在编译器IDE文件夹“Application”中的simpleBLEPeripheral.c和simpleBLEPeripheral.h文件中。

3. Icall:一个抽象了的栈和其他任务之间的通讯接口模块。

注意:GAPRole任务也是应用工程工作空间的一部分。但是这个任务的功能性更接近于协议栈所以在5.2章中描述。 4.1 Start-up in main()

main()函数在IDE “Startup”文件下的main.c文件中,是整个运行时间的开始点。这里也是板子提出中断禁能和驱动初始化的地方。同样在这个函数中,电源管理也会初始化,任务会构建或创建。在最后一步,使能中断,SYS/BIOS内核调度通过调用BIOS_start()启动,没有返回,看第8张获取main()函数到达前的启动顺序:

Void main() {

PIN_init(BoardGpioInitTable); //enable iCache prefetching VIMSConfigure(VIMS_BASE, TRUE, TRUE); // Enable cache

VIMSModeSet(VIMS_BASE, VIMS_MODE_ENABLED); #ifndef POWER_SAVING