s32k144 isystem linux,S32k144 简易 Bootloader
TOPS
原创版权,转载请注明出处!
内容目录
一、理论
1、 复位流程
在离开复位状态后,Cortex-M 做的第一件事就是读取下列两个 32 位整数的值:
1、从地址 0x0000,0000 处取出 MSP 的初始值。
2、从地址 0x0000,0004 处取出 PC 的初始值——这个值是复位向量,LSB 必须是1,然后从这个值所对应的地址处取指。
图 1.1 复位序列.jpg
在 0 地址处提供 MSP 的初始值,然后紧跟着就是向量表。向量表中的数值是 32位的地址,而不是跳转指令。向量表的第一个条目指向复位后应执行的第一条指令。
图 1.2 初始化MSP及PC初始化一个范例.jpg
因为 Cortex-M 使用的是向下生长的满栈,所以 MSP 的初始值必须是堆栈内存的末地址加1。举例来说,如果你的堆栈区域在 0x20007C00-0x20007FFF 之间,那么 MSP 的初始值就必须是 0x20008000。
向量表跟随在 MSP 的初始值之后——也就是第 2 个表目。要注意因为 cortex-m 是在Thumb 态下执行,所以向量表中的每个数值都必须把 LSB 置1(也就是奇数)。正是因为这个原因,图 3.18 中使用 0x101 来表达地址 0x100。当 0x100 处的指令得到执行后,就正式开始了程序的执行。在此之前初始化 MSP 是必需的,因为可能第1条指令还没来得及执行,就发生了 NMI 或是其它 fault。MSP 初始化好后就已经为它们的服务例程准备好了堆栈。
2、 内存分布
图 1.3 flash 内存分配图.jpg
需要修改工程中内存分配的脚本实现以上效果,这里是使用两个工程设计,一个为 bootloader 工程,一个为 app 工程。
二、 实战 — boot
1、 工具:keil JLINK
使用 S32DS 开发也可以,但是 S32DS 使用 jlink 下载程序的时候,芯片容易锁死,而且飞思卡尔的芯片锁死之后,解锁都比较麻烦,所以暂时选择 keil 开发。
2、 新建工程
使用 keil 建立 s32k144 工程并不难,只是 s32k144 与其他的芯片稍微有点不一样,除了有一个汇编文件的启动文件之外,还有几个源文件,源文件的作用主要是从 flash 复制代码到 ram 中,初始化 bss 段,关闭看门狗,配置时钟等。
图 2.1 新建工程.jpg
图 2.2 保存工程.jpg
图 2.3 选择芯片类型.jpg
图 2.4 选择固件以及启动代码.jpg
上图红色部分务必勾选。
图 2.5 工程目录结构.jpg
红色框部分即使内存分配脚本,这是待会儿需要修改的。工程建立好了之后,还需要进行一些配置。
图 2.6 内存配置.jpg
在搞 STM32 的时候,有时候修改的就是这里,这里可以修改内存分配,但是我们这次使用的是用户脚本,不是默认内存配置,所以这里不需要修改。当然还有生成 hex 文件、调试工具的选择、输出目录等配置也需要进行,这里就不一一列举了,
图 2.7 用户脚本选择.jpg
红色部分不要勾选,紫色部分需要手动找到这个脚本,我们把代码下载到 flash 就选择 flash 脚本,下载到 ram 就选择 ram 脚本。
图 2.8 下载配置.jpg
红色部分最好不勾选,因为如果直接使用在 keil 下载的话,这个选项在下载 app 代码的时候,会全部擦除 flash,这时候 boot 会遭殃,会导致起不来,配置基本配置好了,接下来就是修改脚本了。
3、 修改脚本
Boot 的脚本基本不用怎么修改,就是修改一下 Boot 结束地址,这里开辟给 boot 的大小是 0x4000,相当于 16K 的大小。
#if (defined(__ram_vector_table__))
#define __ram_vector_table_size__ 0x00000400
#else
#define __ram_vector_table_size__ 0x00000000
#endif
#define m_interrupts_start 0x00000000
#define m_interrupts_size 0x00000400
#define m_flash_config_start 0x00000400
#define m_flash_config_size 0x00000010
#define m_text_start 0x00000410
//#define m_text_size 0x0007FBF0
#define m_text_size 0x00002000
#define m_interrupts_ram_start 0x1FFF8000
#define m_interrupts_ram_size __ram_vector_table_size__
#define m_data_start (m_interrupts_ram_start+m_interrupts_ram_size)
#define m_data_size (0x00008000 - m_interrupts_ram_size)
#define m_data_2_start 0x20000000
#define m_data_2_size 0x00007000
4、 修改代码
代码的修改主要是集中在,跳转函数,需要定义一个函数指针类型,还要注意 Cortex-m 复位跳转序列。
#include "S32K144.h" /* include peripheral declarations S32K144 */
#include "clocks_and_modes.h"
#include "gpio_led.h"
#define APP_ADDR 0x00004000
/******************************************************************************
*Local variables
******************************************************************************/
typedef void (*bootloader_fun)(void);
bootloader_fun jump2app;
void delay(volatile int cycles)
{
/* Delay function - do nothing for a number of cycles */
while(cycles--);
}
int main(void)
{
SOSC_init_8MHz(); /* Initialize system oscilator for 8 MHz xtal */
SPLL_init_160MHz(); /* Initialize SPLL to 160 MHz with 8 MHz SOSC */
NormalRUNmode_80MHz(); /* Init clocks: 80 MHz sysclk & core, 40 MHz bus, 20 MHz flash */
LED_PORT_init();
for(;;){
for(int i = 0;i < 5;i++){
led_triggle(2,1); /* turn on red LED */
led_triggle(1,0); /* turn on green LED */
led_triggle(0,0); /* turn on blue LED */
delay(720000);
delay(720000);
led_triggle(2,0); /* turn on red LED */
led_triggle(1,0); /* turn on green LED */
led_triggle(0,0); /* turn on blue LED */
delay(720000);
delay(720000);
}
jump2app = (bootloader_fun)*(uint32_t*)(APP_ADDR + 4);
jump2app();
}
return 0;
}
重点应该就是这句话:
jump2app = (bootloader_fun)(uint32_t)(APP_ADDR + 4);
APP 地址加上 4 ,就是因为 CORTEX-M 复位序列的 PC 指针位置的偏移量就是偏移 4,(uint32_t)(APP_ADDR + 4) 进行强制类型转换,(bootloader_fun)(uint32_t*)(APP_ADDR+4) 取址,相当于取 0x4004 地址的值,放到 PC 指针,可能需要主义的还有一个就是 C 语言的语法,C 语言里面,函数名称就是函数的入口地址,也就是说函数名称其实也是一个指针,所以后面一句:jump2app();就是相当于执行一个函数。这样就可以跳转了。
5、 编译下载
编译就没啥问题,下载就有两种方式,一种是直接在keil 上下载,这个很简单了,例外一个就是单独打开 segger 下载,这时候需要配置一下这个软件:
图 2.9 segger 配置.jpg
图 2.10 选择芯片.jpg
然后把编译生成的 hex 文件,直接拖到页面里面就可以了,按 F5 就可以下载了,boot的下载没有什么特别的要求,两个都可以下载。
图 2.11 编译完成.jpg
6、现象
下载之后,可以看到小灯闪了 5 下就不闪了,说明执行到了后面的跳转程序。
三、 实战 — app
1、 新建工程
建立工程和 boot 一样的过程,这里就不再赘述了。
图 3.1 app 目录结构.jpg
2、 修改脚本
脚本位置:$(工程目录)144_app\RTE\Device\S32K144UAxxxLLx 下
#if (defined(__ram_vector_table__))
#define __ram_vector_table_size__ 0x00000400
#else
#define __ram_vector_table_size__ 0x00000000
#endif
//#define m_interrupts_start 0x00000000
#define m_interrupts_start 0x00004000
#define m_interrupts_size 0x00000400
//#define m_flash_config_start 0x00000400
#define m_flash_config_start 0x00004400
#define m_flash_config_size 0x00000010
//#define m_text_start 0x00000410
#define m_text_start 0x00004410
//#define m_text_size 0x0007FBF0
#define m_text_size 0x0002FBF0
#define m_interrupts_ram_start 0x1FFF8000
#define m_interrupts_ram_size __ram_vector_table_size__
#define m_data_start (m_interrupts_ram_start + m_interrupts_ram_size)
#define m_data_size (0x00008000 - m_interrupts_ram_size)
#define m_data_2_start 0x20000000
#define m_data_2_size 0x00007000
App 脚本的修改稍微多一点,每个对应的偏移地址都需要改,向量表的地址,text 段的地址等。
3、 修改代码
代码基本就是正常的代码,不用做任何的操作就可以了。
4、 编译下载
编译和 boot 一样,下载的话,如果没勾选 erase full chip ,可以直接下载,也可以使用 segger 下载。
5、 在线仿真
如果 app 的代码只是下载,那每次调试都会比较麻烦,都得编译成 hex 文件再下载才能验证,因为脚本修改了向量表的地址,直接在线调试是不行的,这样就很不方便开发了,网路上有网友通过修改一个脚本,让 keil 识别到我们已经修改过的向量表的地址,在工程目录新建 flashoffset.ini 文件,内容如下:
图 3.2 app 在线调试脚本.jpg
在 keil 配置里面导入这个文件
图 3.3 导入在线调试脚本.jpg
这样就可以就行在线调试了,就和正常开发一样方便了。
注意:
每个工程编译完了之后,最好是查看 .map 文件,看一下内存分配是否都在划定的内存里面
图 3.4 app 工程的 .map 文件.jpg
也算是一种调试信息手段吧。
问题:
这个 bootloader 整个流程虽然可以走通,但是还有问题,如果 app 工程开启了中断,app 的程序会跑飞。原因是什么呢?这个就是第一节说的 cortex-m 复位序列。
1、 boot 中断未关;
2、接收升级文件驱动未提供;
3、Flash 驱动未提供;
4、App 程序重新定位向量表的基地址未修改。
总结
参考文献:
《Cortex-M3 权威指南》
微信公众号:
微信公众号
s32k144 isystem linux,S32k144 简易 Bootloader相关推荐
- s32k144 isystem linux,S32K144之时钟配置
一般来说,时钟精度.稳定性取决于所采用的时钟源,就MCU S32K来说如内部振荡器SIRC,FIRC,128KLPO,外部晶振等,跟所使用的外设(FTM, LPIT,LPT,RTC等)和哪一路输出时钟 ...
- SAMSUNG S3C2440的简易BootLoader ㈢
SAMSUNG S3C2440的简易BootLoader ㈢ 2010年06月05日 [b]SAMSUNG S3C2440的简易BootLoader ㈢[/b] [b][/b] [b]第三部分:源代码 ...
- linux进度条脚本,Linux下简易进度条的实现代码
在生活中,进度条是很常见的,那么,进度条是如何实现的呢? 首先,进度条的动态是利用人眼视觉暂留效果的.实际上是如下过程: 先输出:[= ]表示进度是1%,刷新之后 再输出:[== ].. ...
- linux根文件系统的移植 课程设计,linux课程设计bootloader的移植.doc
linux课程设计bootloader的移植 嵌 入 式 Linux 课 程 设 计 报 告 课题:嵌入式Linux下的bootloader之u-boot的移植 姓名: 胡欢 专业班级: 电信三班 学 ...
- linux服务器安装gmt,linux GMT简易安装
linux GMT简易安装 近来无事,研究下GMT吧,windows,linux或OS都可以安装GMT,各有千秋,都挺麻烦,不搞得你晕头转向,誓不罢休!好了,闲话少叙,回归正题! 我就把我倒腾的lin ...
- linux系统需要占多大的内存,linux启动过程Bootloader、kernel
256M可以推1080P屏幕 128M可以基本运行并安装 256M可以勉强开启特效 512M流畅运行特效 当然内存越大越好,特效与显卡也有关系 和windows相比,当然linux对内存的需求小 Bo ...
- chroot环境怎么重启linux,linux下简易chroot环境的塔建
有些人想利用chroot来提高系统的安全性,但chroot后的目录也需要一个linux/unix的环境,最直接的方法就是copy整个系统到chroot后的目录,但这样很容易copy大量不需要的东西,而 ...
- LINUX下简易网站压力测试--Webbench小记
Webbench是一款小巧实用的网站压力测试工具,它是由 Lionbridge公司开发的.它的标准测试主要有两项内容:每秒钟相应请求数和每秒钟传输数据量.它最多可以模拟3万个并发连接去测试网站的负载能 ...
- QQ for Linux试用简易报告(yksoft1版)
飞鸽传书 新闻来源:yksoft's system home 年初曾经发过QQ for Mac早期版本的试用报告,在7月的最后一天,我也准备写写有关QQ for Linux最新公开版的体验报告. 我现 ...
最新文章
- 让UpdatePanel支持文件上传(2):服务器端组件
- 汇编: 在代码中安排自己定义的数据,栈空间
- 如何实现tm同时监控多个状态的改变_广电机房监控系统【斯必得智慧机房】
- lstm代码_只需5行代码!LSTM时间序列建模以及预测
- 保存到redis的字符串类型出现斜杆_深入浅出Redis:这次从Redis底层数据结构开始...
- 键盘事件与JS Filter
- Oracle 分析函数row_number() over (partition by order by )
- 信息系统综合知识二 信息化基础知识
- 新手指南|欢迎来到CSDN
- 低代码大势所趋,RDP报表3.0应运而生
- swfobject2.2参数详解
- android倒计时服务,Android倒计时器——CountDownTimer
- FreeCAD源码分析:TechDraw模块
- “大数据”查询平台利用抖音导流,存个人信息泄露或倒卖风险
- 简单Python爬取链接二手房信息
- html: a标签中的href的作用
- iOS微信小程序网页请求走error问题
- 在win10本地开发springboot项目能上传图片,并能通过URL直接从浏览器访问,但是部署到服务器上后能上传文件,但是通过浏览器无法访问图片
- taptap模拟器在电脑上能用吗?
- LTE学习:PHICH(二)