登入帳戶  | 訂單查詢  | 購物車/收銀台( 0 ) | 在線留言板  | 付款方式  | 運費計算  | 聯絡我們  | 幫助中心 |  加入書簽
會員登入 新用戶登記
HOME新書上架暢銷書架好書推介特價區會員書架精選月讀2023年度TOP分類瀏覽雜誌 臺灣用戶
品種:超過100萬種各類書籍/音像和精品,正品正價,放心網購,悭钱省心 服務:香港台灣澳門海外 送貨:速遞郵局服務站

新書上架簡體書 繁體書
暢銷書架簡體書 繁體書
好書推介簡體書 繁體書

三月出版:大陸書 台灣書
二月出版:大陸書 台灣書
一月出版:大陸書 台灣書
12月出版:大陸書 台灣書
11月出版:大陸書 台灣書
十月出版:大陸書 台灣書
九月出版:大陸書 台灣書
八月出版:大陸書 台灣書
七月出版:大陸書 台灣書
六月出版:大陸書 台灣書
五月出版:大陸書 台灣書
四月出版:大陸書 台灣書
三月出版:大陸書 台灣書
二月出版:大陸書 台灣書
一月出版:大陸書 台灣書

『簡體書』嵌入式软件设计入门与进阶——基于Kinetis K60/K64

書城自編碼: 2922764
分類:簡體書→大陸圖書→計算機/網絡软件工程/开发项目管理
作者: 杨熙、苏勇、刘屹霄
國際書號(ISBN): 9787302442073
出版社: 清华大学出版社
出版日期: 2016-11-01
版次: 1 印次: 1
頁數/字數: 197/3210000
書度/開本: 16开 釘裝: 平装

售價:HK$ 58.5

我要買

 

** 我創建的書架 **
未登入.


新書推薦:
多卖三倍
《 多卖三倍 》

售價:HK$ 54.0
哲学思维:清晰思考的12条关键原则
《 哲学思维:清晰思考的12条关键原则 》

售價:HK$ 82.8
海盗之书
《 海盗之书 》

售價:HK$ 81.6
亲美与反美:战后日本的政治无意识
《 亲美与反美:战后日本的政治无意识 》

售價:HK$ 69.6
亲爱的安吉维拉:或一份包含15条建议的女性主义宣言
《 亲爱的安吉维拉:或一份包含15条建议的女性主义宣言 》

售價:HK$ 58.8
理想国译丛064:狼性时代:第三帝国余波中的德国与德国人,1945—1955
《 理想国译丛064:狼性时代:第三帝国余波中的德国与德国人,1945—1955 》

售價:HK$ 122.4
海外中国研究·明清中国的经济结构
《 海外中国研究·明清中国的经济结构 》

售價:HK$ 153.6
理想国译丛018:活着回来的男人:一个普通日本兵的二战及战后生命史(2024版)
《 理想国译丛018:活着回来的男人:一个普通日本兵的二战及战后生命史(2024版) 》

售價:HK$ 110.4

 

編輯推薦:
书中总结了一些使用Kinetis控制器进行嵌入式软件开发过程中用到的实用技术,以*视角讲述一线工程师的应用心得,实用价值高。但本书内容绝不只限于Kinetis系列控制器,其中很多内容都是所有嵌入式开发工程师经常碰到的。? 在结构上以相对独立的主题划分章节,每个主题围绕一个具体的话题展开。减轻了读者连续阅读的负担,便于利用工作的时间间隙欣赏一个个实用的技术小品。? 在内容上取材于实际的开发经验,从宏观和微观上对问题都有一定的把握。在宏观上介绍问题的背景知识和研究方向;在微观上根据实际项目给出具体、可行的解决方案。
內容簡介:
本书以ARM CortexM4为内核的恩智浦NXPKinetis系列微控制器作为硬件平台,从嵌入式软件工程师的实践角度出发,阐述了基于MCU的嵌入式软件开发中的若干细节问题。与目前的入门类书籍中对片上外设及固件库软件的说明指导相比,书中对实际开发中的具体问题进行了更为详细的分析:从零开始搭建软件开发平台,不仅描述了工程模板的创建,还具体分析了芯片的软硬件启动过程,尤其对链接过程及典型应用进行了详述; 介绍了几种典型的嵌入式系统开发框架,根据具体的应用场景选择程序的组织方式; 在低功耗和DMA的相关章节中介绍了降低产品功耗与优化性能的典型做法及思路; 而作为运行在单片机上的命令行系统、CMSISDSP运算库及git版本管理系统,都是软件工程人员常用的功能调试与代码维护的常用工具,对这些内容也进行了介绍。
本书可作为通信工程、电子信息工程、计算机、微电子等专业相关课程的教材,也可供具有专业背景并有一定C语言及嵌入式开发基础的在校大学生、研究生以及对嵌入式技术感兴趣的读者参考。
關於作者:
杨熙,嵌入式应用工程师,现就职于恩智浦半导体公司。 一位电子技术及计算机技术的爱好者,利用业余时间学习了大量电子技术及计算机相关知识,曾开设超核电子嵌入式学习论坛 。
苏勇,嵌入式软件工程师,现就职于恩智浦半导体公司,主要进行固件库软件的开发。从读研期间参加飞思卡尔大学计划项目与Kinetis系列单片机结缘,参与了大量飞思卡尔单片机的开发及推广,曾参加过多本教材的编写写工作。同时也是一名电子发烧友,常年混迹于各大电子论坛,喜欢自己DIY电子产品并乐于分享。
目錄
目录
第1章Kinetis平台概述
1.1ARMCortex系列简介
1.1.1ARM CortexA
1.1.2ARM CortexR
1.1.3ARM CortexM
1.2恩智浦NXPKinetis系列MCU简介
1.2.1Kinetis产品家族介绍
1.2.2Kinetis系列芯片的命名规则及选型
1.3开发平台硬件电路分析
1.3.1MCU
1.3.2复位
1.3.3时钟
1.3.4调试接口
1.3.5LED
1.3.6串口
1.3.7SPI Flash
1.4软件环境搭建
1.4.1MDK安装下载
1.4.2串口驱动
1.4.3Jlink驱动安装
1.4.4下载本书的示例代码
1.5编译实例HelloWorld工程
1.6新建工程
1.7本章小结
第2章从零开始
2.1样例程序
2.2芯片上电
2.3启动软件系统
2.3.1分配堆和栈的空间
2.3.2中断向量表
2.3.3 Flash配置选项
2.3.4复位中断入口到用户main函数
2.4分散加载文件
2.5本章小结
嵌入式软件设计入门与进阶基于Kinetis K60K64
第3章链接命令文件
3.1命令方式存在的链接配置参数
3.2创建sct文件模板
3.3SCF应用直接在RAM中调试程序
3.4SCF应用将程序复制到RAM中执行
3.5本章小结
第4章嵌入式系统软件的典型开发框架
4.1概述
4.2裸机嵌入式系统的组成
4.3典型的裸机软件系统实现框架
4.3.1基本的超循环结构
4.3.2使用中断的前后台结构
4.3.3完全依赖中断的事件驱动系统
4.3.4状态机驱动系统
4.4本章小结
第5章低功耗应用设计
5.1概述
5.2K64中的低功耗模式介绍
5.3功耗状态机模型的运作
5.3.1进入STOP模式操作序列
5.3.2退出STOP模式操作序列
5.3.3中断进入STOP模式
5.4低功耗所涉及的模块详解
5.4.1ARM核的系统控制寄存器
5.4.2系统模式控制器
5.4.3低功耗模式下的频率限制
5.4.4低漏唤醒单元
5.5低功耗应用开发典型模式
5.6K64低功耗编程心得
5.7本章小结
第6章DMA的基本概念
6.1DMA的基本概念
6.2DMA的工作原理
6.3K64的DMA介绍
6.3.1TCD
6.3.2主循环和子循环
6.3.3eDMA通道请求使能开关
6.3.4DMA的触发源
6.3.5DMA传输完成的判断
6.3.6关于SMOD和DMOD周期性地址传输
6.3.7关于DREQ位
6.4使用DMA实现内存间搬运的实例
6.4.1DMA TCD的配置
6.4.2等待DMA传输完成
6.4.3实验效果
6.5本章小结
第7章DMA在串行通信总线中的应用
7.1通过DMA来进行串口数据收发
7.1.1DMA触发条件的确定
7.1.2DMA TCD的配置
7.2使用DMA进行SPI通信
7.2.1SPI通信的一般模型
7.2.2DMA触发条件的确定
7.2.3DMA TCD的配置
7.3本章小结
第8章DMA实现ADC扫描触发链
8.1从应用案例开始
8.1.1明确需求
8.1.2围绕ADC的软触发特性设计触发链
8.2触发链的设计与实现
8.2.1DMA0ADC0: 实现DMA0自动搬运命令字触发ADC转换
8.2.2ADC0DMA1: 实现ADC转换完成后触发DMA1自动搬运
转换结果
8.2.3PIT0DMA0: 实现PIT0定期触发DMA0控制转换的节奏
8.2.4见缝插针,自定义更加丰富的操作接口
8.3本章小结
第9章使用命令行来帮助开发
9.1概述
9.2Shell的引入
9.2.1单片机中的Shell
9.2.2单片机Shell的输入和输出
9.3简单的Shell软件设计
9.3.1构建Shell命令结构体
9.3.2获取输入命令
9.3.3解析命令
9.3.4调用对应的函数并返回结果
9.4应用实例
9.5本章小结
第10章使用CMSISDSP数学运算库
10.1什么是数字信号处理
10.2浮点运算与定点运算
10.3CMSISDSP简介
10.4CMSISDSP初探
10.4.1DSP库的分类
10.4.2使用CMSISDSP库
10.5基础数学函数
10.5.1向量绝对值运算
10.5.2向量加法运算
10.5.3向量点积
10.5.4向量元素乘积
10.5.5逆向量反向量
10.5.6向量平移
10.5.7向量扩围
10.6快速功能函数
10.6.1快速余弦函数Cosine
10.6.2快速正弦函数Sine
10.6.3快速平方根Square Root
10.7本章小结
第11章专业的软件版本控制系统git
11.1git的诞生
11.1.1git的诞生
11.1.2git的核心数据库
11.1.3远程数据库和本地数据库
11.2git入门笔记
11.2.1下载安装git
11.2.2初始化代码仓库
11.2.3添加文件并提交修改
11.2.4增删改查git仓库中的文件
11.2.5退回到某一个commit
11.2.6使用远程仓库
11.2.7克隆远程库
11.3本章小结
后记
参考文献
內容試閱
前言
在经典的51单片机时代诞生了许多实用的技术书籍,覆盖了从硬件架构到软件应用的方方面面,这些作品培养了大量单片机工程师,对单片机技术的发展提供了非常大的助力。现如今,随着ARM单片机的兴起和繁荣,相关的书籍不断涌现。然而,从作者的学习经历来看,目前关于ARM单片机书籍的描述,重点还是放在参考手册和固件库上,也就是说,书中的内容直接或间接地来源于单片机原厂的参考手册或是固件库。诚然,这些知识对于单片机开发非常重要,它们是使用ARM单片机进行开发的基础。但是,随着ARM单片机的普及和开发门槛的降低,单片机工程师们对ARM技术书籍的需求远不止于此,在实践中,还有更广阔的空间需要探索。本书作者曾经也是单片机开发的初学者,经过了多年对ARM单片机的学习和实践,在不断解决问题的过程中,积累了一些心得和体会。这些源自于实践的经验,不同于手册中已有的内容,更多的是通过实验和具体的应用而进行的总结,具有比较高的实用价值,对具体的项目应用有直接的参考意义。本书由来提及作者学习ARM单片机的过程,就不得不聊一点飞思卡尔杯智能汽车比赛的经历。2011年,作者其中之一带队参加第六届飞思卡尔杯智能车比赛电磁组,开始在项目中使用K60单片机,这是由飞思卡尔半导体公司推出的全球首款基于ARM CortexM4内核的单片机,在之后的几年里广为流行。作者在参加比赛的过程中受益颇多,在明确的项目目标更快、更稳的驱动下,将所有相关的知识整合起来,全面地解决小车系统中的每一个具体问题,这刚好是一个完整的单片机工程师从入门到成熟的学习过程。在制作和调试小车的过程中,仅仅依赖芯片手册的信息不足以解决所有问题,更多的问题还需要搜集信息、思考、测试、再思考、再测试的反复过程才能取得最终的解决方案。这些通过实践积累下来的经验总结是最宝贵的财富。早年对开发问题的总结,也催生了撰写一本关于开发单片项目经验书籍的念头。参加工作后,作者有幸继续使用Kinetis系列单片机的开发平台进行单片机系统软件的设计工作。作为常年工作在Kinetis微控制器底层驱动和操作系统接口层的应用工程师,本着进一步对芯片功能的使用和理解的目的,将近几年在工作岗位和项目中的技术细节整理出来。为了方便使用Kinetis产品的广大读者和应用工程师,作者对各类实际工作中看似模棱两可的功能性配置过程做了较为详细的解释,从系统上电启动的最初步骤到进入应用系统之后的环节都进行了较为详细的演示,这样做的目的是为了方便读者在遇到一些未知的故障时能够通过本书中讲解的内容快速将故障定位,从而缩短产品开发周期,为应用开发奠定基础。同时本书还介绍了嵌入式软件开发过程的一些辅助工具,通过对这些工具的了解可以帮助读者在单片机开发工作中锦上添花。
本书特色本书从NXP Kinetis系列产品的综合介绍开始,对Kinetis芯片的一些功能细节做了较为详细的介绍。书中引用了作者团队开发和使用多年的CHK开源Kinetis产品驱动库,读者可以自行在网络上下载并使用,这些完全免费。CHK开源驱动软件库开发至今多年,在业界有着较好的口碑,可以帮助有MCU开发经验的用户几乎零时间进入Kinetis产品的应用开发工作,到目前为止,CHK软件库已经可以支持多个系列Kinetis的衍生型号开发,其他一些子型号只要稍加修改便可使用。嵌入式软件设计入门与进阶基于Kinetis K60K64
由于目前市面上已经有较多关于恩智浦Kinetis系列单片机的书籍,但大多是针对入门学习者或是刚接触Kinetis单片机的工程师,着重偏向外设模块介绍,如简单的GPIO使用、点亮小灯等。再例如串口通信,只是介绍收发数据的相关寄存器,然后以打印或接收一些串口数据作为示例,强调快速见效。而本书主要面向具有一定经验的嵌入式开发者,根据作者实际的开发经验,在书中总结了一些使用Kinetis控制器进行嵌入式软件开发过程中用到的实用技术,以第一视角讲述一线工程师的应用心得,实用价值高。另外,本书内容绝不只限于Kinetis系列控制器,其中很多是所有嵌入式开发工程师经常碰到的问题。本书对技术点的描述深入细致,内容丰富,是一本可读性强的读物。在内容的组织形式上,本书并未采用传统教科书式的顺序结构,而是以主题组织材料,将每个章节整理成一个个技术小品。每个技术小品相当于是一个解决问题的小故事,将相关信息放在一起说明中心问题,这种内容组织的方式直接来源于作者在项目开发过程中整理的开发笔记。这样做,对于读者而言,也可以减轻阅读压力,每阅读完一个章节,就可以了解到一个主题。对于闲暇时间有限的单片机工程师来说,这样组织内容的方式非常便于利用零星的时间进行阅读。本书读者对象本书主要面向有一定编程基础的嵌入式MCU工程师、高校师生、创客以及所有热爱嵌入式技术的朋友们。本书特别介绍了大量关于Kinetis系列产品的入门及应用知识,包括常用外设的编程方法、寄存器,以及飞思卡尔系列单片机一些特有的功能等,这些知识对于想了解该系列产品的朋友来说具有很好的参考价值。
特别提醒读者的是,鉴于本书完稿之时正处于飞思卡尔半导体公司和恩智浦半导体合并过程中,所以以前的飞思卡尔Kinetis系列在本书出版时已经更替为恩智浦NXP Kinetis系列。
CHKLIB Kinetis驱动固件库是由本书作者自行开发的针对Kinetis的底层驱动库,支持数十种Kinetis微控制器型号,使用简单并配套详细的使用例程,可以帮助用户以极短的时间入手Kinetis系列微控制器的应用编程,大大缩短开发周期,CHKLIB驱动库已经开发多年,历经时间检验,稳定可靠。它与目前NXP官方的SDK 2.0互为补充,SDK 2.0侧重与以芯片为中心,大而全的设计驱动API,而CHKinetis固件库则以应用为中心来设计驱动API,讲究实用简单,砍掉了一些不常用的外设功能。API也比官方的SDK 2.0少很多。目前,CHKinetis依然在持续更新中。读者可以前往开源中国OS China进行下载,地址链接如下:http:git.oschina.netyandldCHKLib。本书的作者团队来自于单片机开发领域,包括面向产品的应用软件工程师以及致力于提供固件库服务的系统软件工程师,由于常年与程序代码和开发板为伍,但是作为技术书籍的作者尚显文笔生疏,书中所用描述之辞,如有不当之处恳请见谅。仅以此书献给曾经的飞思卡尔和一代藉由飞思卡尔智能车比赛成长起来的年轻工程师们!
作者2016年5月


第3章 链接命令文件
续接前章,Keil中的分散加载文件,也就是通常的链接命令文件,在实际的嵌入式软件开发当中扮演着非常重要的角色。经验丰富的工程师在创建可执行文件时,会明确地安排好代码在芯片存储空间的位置,并且能够根据具体的设计需要灵活地控制代码和数据存放在指定区域。本章中,笔者根据自己的应用经验,对链接命令的几种实用用法进行介绍。3.1命令方式存在的链接配置参数默认的工程设置下,Keil会通过链接命令自动生成一个sct文件。例如HelloWorld在工程配置对话框中自定义生成链接命令,如图31所示。
图31Keil Linker选项
此时,这个sct文件并不是真的存在,而是直接作用到链接器中了。对于链接器来说,这里省略了从实体的sct文件中解析参数的过程,是最高效的方式。作为默认的配置,直接使用链接命令参数可以让普通的开发者根本不需要感觉到sct文件曾经存在过,从而减少了很多麻烦,便于快速上手。然而,这对于需要深度定制系统的高级应用开发者来说,不利之处也是显而易见的,本书就是不能够根据特别的需要更改其中的内容,对系统进行订制的灵活性可能满足不了需求。例如,要把一段数据放在指定的某个存储区域,怎么办?因此,对于深爱着代码的软件工程师来说,更希望看见的是一个实实在在的sct文件,可以以文本的方式进行编辑,这样就可以很方便地自行安排存储区的使用,也方便添加注释以利于维护。3.2创建sct文件模板若是需要定制专用的sct文件,首先需要一个能够正常使用的sct文件,在此基础上,结合应用需要进行更改。可以通过对Keil工程的配置,让Keil把命令形式的链接命令导出成sct文件。具体操作方法如下。打开工程配置对话框后,在Target标签页下设定IROMInternal ROM,也就是Flash存储空间和IRAMInternal RAM,也就是SRAM存储空间的地址和大小,如图32所示。
图32配置芯片的ROM和RAM范围
然后切换到Linker标签页下,勾选Use Memory Layout from Target Dialog,使用在上图对话框中设定的内容作为存储映像配置,如图33所示。此时,读者就会发现Linker control string文本框中的内容发生了变化,对应将在Build之后生成一个sct文件。
图33选择User Memory Layout from Target Dialog
这个时候只要Build一下工程,就会在输出编译结果的目录下找到.sct文件。使用文本编辑器查看这个由Keil导出的文件的内容如下。
; * ************************************************************
; * ** Scatter-Loading Description File generated by uVision * **
; *********************************************************** **
LR_IROM1 0x00000000 0x00100000 {; load region size_region
ER_IROM1 0x00000000 0x00100000 { ; load address = execution address
*.o RESET,First
*InRoot$$Sections
.ANY RO
}
RW_IRAM1 0x20000000 0x00030000 { ; RW data
.ANY RWZI
}
}
编译产生的映像文件一般是由域region组成的,域最多由三个输出段组成RO、RW、ZI组成,输出段又由输入段组成。所谓域,指的就是整个bin映像文件所处的区域,它又分为加载域和运行域。加载域就是映像文件被静态存放的工作区域,一般来说Flash里整个bin文件所在的地址空间就是加载域,当然程序一般都不会放在Flash里执行,会搬动到SDRAM里运行工作,它们再被搬到SDRAM里工作所处的地址空间就是运行域。向其中输入的代码,一般有代码部分和数据部分,这就是所谓的输入段,经过编译后就变成了bin文件中RO段和RW段,还有所谓的ZI段,这就是输出段。对于加载域中的输出段,一般来说RO段后面紧跟着RW段,RW段后面紧跟着ZI段。在运行域中这些输出段并不连续,但RW和ZI一定是连着的。ZI段和RW段中的数据其实可以是RW属性。这里简单说明这个sct文件中的内容。1 分号; 是注释符号,在该行内,分号之后的内容都是不被解析的。通过实验发现,使用C语言的*和*进行多行注释也是有效的。2 IROM1和IRAM1是同Target标签页中的文本框属性对应的存储段。3 前缀LR_是Load Region的缩写,表示载入域。编译生成的映像文件最终要写到芯片内部的Flash存储器上,哪怕是SRAM内存中变量的初值,也是在程序启动的过程中通过烧写到Flash中的程序从Flash搬运到SRAM中的。链接命令文件描述的是映像文件的存储分配,其管理的所有内容自然也都是在载入域中,同载入域相对应,在程序启动完成后,SRAM中的变量也被展开,这个时候,Flash中只有程序部分的存储空间是有效的,此时被称为运行域,也就是ER_前缀的缩写,Execution Region。RW_前缀是Read & Write的缩写,对应可读可写的RAM区域。4 LR_IROM1、ER_IROM1和RW_IRAM1后面的两个数字,前者为存储区域的起始地址,后者为存储区域的长度,以字节为单位。5 分析ER_IROM1存储区中包含的内容:*.o RESET,First中的RESET是一个Section的名字,它与startup_xxx.s文件中的语句AREA RESET, DATA, READONLY相对应。而 First是一个配置属性,这里的意思是说,一定要把RESET段中的内容放在ER_IROM1存储区中最开始的地方。*InRoot$$Sections指代所有必须放在根区域的Section,例如main.o、scatter*.o、dc*.o及* Region$Table等。.ANY RO指代任何Any的只读ReadOnly,RO段的内容,其中RO段主要存放程序代码的二进制内容。6 分析RW_IRAM1存储区中包含的内容:.ANY RWZI指代任何的可许可写ReadWrite,RW和将被初始化为零ZeroInit,ZI段的内容,其中RW段对应的是内部的SRAM存储区,ZI段中存放RW段中要被初始化为零的变量。结合编译工程后生成的map文件具体了解一下各段中的内容。
=====================================================================
Memory Map of the image
Image Entry point : 0x00000411
Load Region LR_IROM1 Base: 0x00000000, Size: 0x00000e10, Max: 0x00100000, ABSOLUTE
Execution Region ER_IROM1 Base: 0x00000000, Size: 0x00000e04, Max: 0x00100000, ABSOLUTE
Base AddrSizeTypeAttrIdxE Section NameObject
0x000000000x00000400DataRO66RESETstartup_mk64f12.o
0x000004000x00000010CodeRO67.ARM.__at_0x400 startup_mk64f12.o
0x000004100x00000000CodeRO 238 *.ARM.Collect$$$$00000000 mc_w.lentry.o
0x000004100x00000004CodeRO 508.ARM.Collect$$$$00000001 mc_w.lentry2.o
0x000004140x00000004CodeRO 511.ARM.Collect$$$$00000004 mc_w.lentry5.o
0x000004180x00000000CodeRO 513.ARM.Collect$$$$00000008 mc_w.lentry7b.o
0x000004180x00000000CodeRO 515.ARM.Collect$$$$0000000A mc_w.lentry8b.o
0x000004180x00000008CodeRO 516.ARM.Collect$$$$0000000B mc_w.lentry9a.o
0x000004200x00000000CodeRO 518.ARM.Collect$$$$0000000D mc_w.lentry10a.o
0x000004200x00000000CodeRO 520.ARM.Collect$$$$0000000F mc_w.lentry11a.o
0x000004200x00000004CodeRO 509.ARM.Collect$$$$00002712 mc_w.lentry2.o
0x000004240x00000074CodeRO1.textmain.o
0x000004980x00000024CodeRO37.textinit_board.o
0x000004bc0x0000001eCodeRO52.textstdio_adapter.o
0x000004da0x00000002PAD
0x000004dc0x00000030CodeRO68.textstartup_mk64f12.o
0x0000050c0x000000c8CodeRO78.textbsp_config.o
0x000005d40x00000270CodeRO 125.textsystem_mk64f12.o
0x000008440x00000340CodeRO 155.textfsl_frdm_k64.libfsl_sim.o
0x00000b840x00000100CodeRO 211.textfsl_frdm_k64.libfsl_uart.o
0x00000c840x00000024CodeRO 537.textmc_w.linit.o
0x00000ca80x00000020CodeRO 314i.__0printf$2mc_w.lprintf2.o
0x00000cc80x0000000eCodeRO 549i.__scatterload_copy mc_w.lhandlers.o
0x00000cd60x00000002CodeRO 550i.__scatterload_null mc_w.lhandlers.o
0x00000cd80x0000000eCodeRO 551i.__scatterload_zeroinit mc_w.lhandlers.o
0x00000ce60x000000d6CodeRO 321i._printf_core mc_w.lprintf2.o
0x00000dbc0x00000004CodeRO 241i.getc mc_w.lgetc.o
0x00000dc00x00000004CodeRO 243i.putc mc_w.lputc.o
0x00000dc40x00000008DataRO38.constdata init_board.o
0x00000dcc0x00000018DataRO 212.constdata fsl_frdm_k64.libfsl_uart.o
0x00000de40x00000020DataRO 547Region$$Tableanon$$obj.o
Execution Region RW_IRAM1 Base: 0x20000000, Size: 0x00000410, Max: 0x00030000, ABSOLUTE
Base AddrSize TypeAttr IdxE Section NameObject
0x200000000x00000004DataRW 126.datasystem_mk64f12.o
0x200000040x00000004DataRW 245.datamc_w.lstdin.o
0x200000080x00000004DataRW 246.datamc_w.lstdout.o
0x2000000c0x00000004PAD
0x200000100x00000400ZeroRW64STACKstartup_mk64f12.o
在map文件中的Memory Map of the image部分中,可以看到,各个编译生成的对象Object实体对应的Attr即为在前面提到的RO和RW的属性,RO属性的对象的类型Type多是代码Code和常量.constdata,而RW属性的对象类型则多为数据.data。关于RW段有比较有意思的东西,PAD是存储对齐空出来的空间,可以看到,对齐是为紧接下来的栈空间STACK段服务的,而这个STACK段,具备了Zero的属性,刚好对应ZI段属性。这个文件仅仅是编译工程的输出文件,要把它设定为编译工程的输入文件,才能通过修改其中的内容管理编译工程中的链接行为。为了防止在后面的编译过程中覆盖到此处编辑好的sct文件,先将生成的MyProject.sct文件复制到工程根目录下。再次打开工程配置对话框,切换到Linker标签页,取消Linker control string的勾选项,然后在Scatter file文本框中填入备份处理的sct文件,此时,备份的sct文件即作为链接器的输入文件,对其的更改也将在之后的链接过程中发挥作用。下面针对sct文件的应用讲解两个具体且常用的例程。3.3SCF应用直接在RAM中调试程序在本例中,将创建一个HelloWorld_RAM工程,专门用于实现在RAM中调试程序。当启动Keil的调试功能时,不再像通常那样将可执行程序下载到芯片内部的Flash存储器中,而是直接将程序内容载入到芯片内部的RAM并在其中运行。这样的做法可以减少调试过程中对Flash的擦写次数,延长芯片的使用寿命。不过当今大多数MCU的Flash性能都有很大提升,擦写几十万次都是没有问题的。1. 修改scf文件,将映像内容映射到SRAM所在的地址空间首先如前文所述,生成对应的SCT文件之后,修改LR_IROM1、ER_IROM1及RW_IRAM1的地址范围,使其映射到芯片内部SRAM的地址空间。K64的SRAM大小为256KB,在0x20000000地址之前有64KB的SRAM_L存储块,在0x20000000地址之后有192KB的SRAM_U地址块,此时可选择SRAM_U作为RAM映像文件的载入空间。将SRAM的前128KB作为ROM使用,后64KB当作RAM使用。对应的,修改之后的uart_hello.sct文件内容如下:
; *********************************************************** **
; * ** Scatter-Loading Description File generated by uVision * **
; *********************************************************** **
LR_IROM1 0x20000000 0x00020000 {; load region size_region
ER_IROM1 0x20000000 0x00020000{ ; load address = execution address
*.o RESET,First
*InRoot$$Sections
.ANY RO
}
RW_IRAM1 0x200200000x00030000 { ; RW data
.ANY RWZI
}
}
2. 编写调试器命令文件在工程根目录下创建RunRAM.ini文件作为调试命令文件,这个文件中的命令将在RAM中载入程序映像后启动调试时被执行,完成在RAM中调试程序的准备工作,其配置内容包括:1 从RAM中的向量表首项获取栈初值,载入CPU内部的SP寄存器中。2 从RAM中的向量表次项获取PC初值,载入CPU内部的PC寄存器中。3 重定位向量表的基址,将内核向量表的寻址空间映射到RAM中的向量表。4 最后将用户调试的起点设定到main函数,一直执行到main函数再开始调试。RunRAM.ini文件的内容如下:
FUNC void setupvoid
{
SP = _RDWORD0x20000000; * 从中断向量表中读取SP值 *
PC = _RDWORD0x20000004; * 从中断向量表中读取PC值 *
_WDWORD0xE000ED08, 0x20000000; * 将中断向量表重定向到RAM中 *
}
* 将镜像文件加载到RAM中 *
LOAD .\output\uart_hello.axf INCREMENTAL
setup;
g, main * 运行main函数 *
3. 配置工程选项1 启用RAM_TARGET宏,如图34所示。
图34定义RAM_TARGET
在图34中,启动RAM_TARGET宏是为了取消向Flash配置寄存器中填写密钥。因为只是将程序载入到RAM中,不需要对Flash存储器进行编程,因此不需要考虑加密的情况。在startup_MK64F12.s文件中有关于在Flash配置寄存器中载入Flash密钥的代码,如下所示。
IF:LNOT::DEF:RAM_TARGET
AREA|.ARM.__at_0x400|, CODE, READONLY
DCB BackDoorK0, BackDoorK1, BackDoorK2, BackDoorK3
DCB BackDoorK4, BackDoorK5, BackDoorK6, BackDoorK7
DCB FPROT0,FPROT1,FPROT2,FPROT3
DCB FSEC,FOPT,FEPROT, FDPROT
ENDIF
2 配置使用调试命令文件
如图35所示,这里的配置是让编译器在编译过程中加载经过修改的MyProject.sct分散加载文件。
图35选择sct文件
3 配置调试属性将之前准备的RunRAM.ini文件配置到Initialzation File文本框中,同时注意取消勾选Load Application at Startup选项,如图36所示。
图36选择RAM初始化文件
然后在选择使用JlinkJTRACE Cortex作为调试器的同时,单击Settings按钮,弹出配置调试驱动对话框。在Flash Download标签页中,移除对应于芯片的Flash编程算法选项,如图37所示。
图37选择Flash编程逻辑
4 启动调试程序此时直接启动调试程序,就能够体验到飞一般的下载和调试功能,而且再也不用担心对Flash的频繁擦写会降低Flash存储器的寿命了。切记不要进行程序下载的操作,因为即使下载成功,要开始执行程序,也只能通过复位触发,而一旦执行复位操作,芯片执行的将是保存在Flash中的程序,原来下载到RAM中的程序将被清空。3.4SCF应用将程序复制到RAM中执行有的时候希望能将某些关键的程序搬运到RAM中运行,这是因为CPU访问SRAM存储器的速度比访问Flash存储区快很多。不同于在RAM中调试程序时只能下载一次,芯片在实际工作时,上电启动后,就希望程序代码已经转移到RAM中了。没问题,scf文件也能搞定。在sct文件中加入一个.relocate_code段的定义,并把它放在RAM中,如下面加粗的部分:
; *********************************************************** **
; * ** Scatter-Loading Description File generated by uVision * **
; *********************************************************** **
LR_IROM1 0x00000000 0x80000 {; load region size_region
ER_IROM1 0x00000000 0x80000 { ; load address = execution address
*.o RESET,First
*InRoot$$Sections
.ANY RO
}
RW_IRAM1 0x20000000 0x00010000 { ; RW data
*.relocate_code
.ANY RWZI
}
}
在main.c文件中编写一个ToggleLed函数,然后使用pragma arm section编译器指令将这个函数放置在.relocate_code段中。当然,这些已经在sct文件中将.relocate_code段定义到RW_IRAM1中了,也就是说,ToggleLed函数将被放置在RAM中的.relocate_code段中。注意: 在函数后面要用#pragma arm section编译器指令恢复缺省的定位,使后面的程序仍然放在Flash存储器中。
#pragma arm section code = ".relocate_code"
void ToggleLedvoid
{
GPIO_TogglePinLogicBSP_GPIO_LED3_PORT, BSP_GPIO_LED3_PIN;
}
#pragma arm section code
编译工程,在生成的map文件中,可以看到之前的设置起作用了。在符号表中,ToggleLed符号表示的就是ToggleLed函数的指针,值为0x20000001,位于main.o对象中的.relocate_code的内容。而在RW_IRAM1存储区的内容分布描述表中,在0x20000000地址开始的12字节存储区中,存放的数据类型为Code,属性为RO,段名为.relocate_code,来源于main.o。这些信息充分说明了ToggleLed函数已经被链接到RAM中了。
Global Symbols
Symbol NameValueOv TypeSizeObjectSection
...
ToggleLed0x20000001Thumb Code12 main.o.relocate_code
...
Execution Region RW_IRAM1 Base: 0x20000000, Size: 0x00001028, Max: 0x00010000, ABSOLUTE
Base AddrSizeTypeAttrIdxE Section NameObject
0x200000000x0000000cCodeRO1.relocate_code main.o
0x2000000c0x0000000aVenRO 586Veneer$$Codeanon$$obj.o
0x200000160x00000002PAD
0x200000180x00000004DataRW88.datasystem_mk60d10.o
0x2000001c0x00000004DataRW 275.datamc_w.lstdin.o
0x200000200x00000004DataRW 551.datamc_w.lstdout.o
0x200000240x00000004PAD
0x200000280x00001000ZeroRW73STACKstartup_mk60d10.o
作为验证,还是把这个映像文件下载到板子上运行一下。按下复位按键,ToggleLed函数正常运行。3.5本章小结在本章中,从实用的角度对在Keil集成开发环境中使用链接命令文件进行了比较详细的介绍,开发者基于Keil自动创建的sct文件进行定制,以满足应用程序的特别需要。本章描述了两种典型的与定制sct文件相关的实例: 通过修改链接命令参数重定位全部程序代码在RAM中,以实现在RAM中,调试程序的功能,这样可以在调试功能阶段减少对Flash的擦写次数,同时让程序运行得更快; 将部分函数的代码重映射到RAM区,以加速某些函数的运行。

 

 

書城介紹  | 合作申請 | 索要書目  | 新手入門 | 聯絡方式  | 幫助中心 | 找書說明  | 送貨方式 | 付款方式 香港用户  | 台灣用户 | 大陸用户 | 海外用户
megBook.com.hk
Copyright © 2013 - 2024 (香港)大書城有限公司  All Rights Reserved.