当前位置: 首页 > news >正文

MC9S12单片机上电初始化过程及BOOTLOADER分析

上电过程

上电后,CPU从固定的位置读取复位向量。

这个固定的位置就是0xFFFE。是芯片厂商出厂时预设好的。

这个地址是NON_BANKED的。这个位置保存的是复位向量,实际上就是一个函数指针。该函数指针指向_Startup()函数。

map文件:

注意:程序的入口点是_Startup,不是main()。

_Startup函数是存放在0xC000位置。而0xFFFE地址的值就是0xC000.

S19文件:

_Startup()函数分析

打开 Start12.c文件,可以看到_Startup()函数。

/* The function _Startup must be called in order to initialize global variables and to call main */
/* You can adapt this function or call it from your startup code to implement a different startup */
/* functionality. */

/* You should also setup the needed IO registers as WINDEF (HC12A4 only) or the COP registers to run */
/* on hardware */

/* to set the reset vector several ways are possible : */
/* 1. define the function with "interrupt 0" as done below in the first case */
/* 2. add the following line to your prm file : VECTOR ADDRESS 0xfffe _Startup */
/* of course, even more posibilities exists */
/* the reset vector must be set so that the application has a defined entry point */

#if defined(__SET_RESET_VECTOR__)
__EXTERN_C void __interrupt 0 _Startup(void) {
#else
__EXTERN_C void _Startup(void) {
#endif
/*  purpose:    1)  initialize the stack
                2)  initialize the RAM, copy down init data etc (Init)
                3)  call main;
    parameters: NONE
    called from: _PRESTART-code generated by the Linker
                 or directly referenced by the reset vector */

   /* initialize the stack pointer */
   INIT_SP_FROM_STARTUP_DESC(); /*lint !e522 asm code */ /* HLI macro definition in hidef.h */

#if defined(_HCS12_SERIALMON)
   /* for Monitor based software remap the RAM & EEPROM to adhere
      to EB386. Edit RAM and EEPROM sections in PRM file to match these. */
   ___INITRG = 0x00;  /* lock registers block to 0x0000 */
   ___INITRM = 0x39;  /* lock Ram to end at 0x3FFF */
   ___INITEE = 0x09;  /* lock EEPROM block to end at 0x0fff */
#endif

   /* Here user defined code could be inserted, the stack could be used */
#if defined(_DO_DISABLE_COP_)
   _DISABLE_COP();
#endif

   /* Example : Set up WinDef Register to allow Paging */
#ifdef HC812A4 /* HC12 A4 derivative needs WINDEF to configure which pages are available */
#if  (__ENABLE_EPAGE__ != 0 ||  __ENABLE_DPAGE__ != 0 || __ENABLE_PPAGE__ != 0)
   WINDEF= __ENABLE_EPAGE__ | __ENABLE_DPAGE__  | __ENABLE_PPAGE__;
#endif
#endif

#if (defined(__MAP_RAM__) || defined(__MAP_FLASH__) || defined(__MAP_EXTERNAL__)) && !defined(__DO_SET_MMCTL1__)
#define __DO_SET_MMCTL1__
#endif


#if defined(__DO_SET_MMCTL1__)
  /* Set the MMCTL1 byte. Please use for HCS12XE and change the bits according   */
  /* to your configuration.                                                      */
  /* Note: MMCTL1 is write once therefore please adapt this initialization here. */
  /* This has to be done prior to the call to Init.                              */
#define _MMCTL1_ADR (0x00000013)
#define _MMCTL1_BIT_TGMRAMON (1<<7)  /* EEE Tag RAM and FTM SCRATCH RAM visible in the memory map */
#define _MMCTL1_BIT_EEEIFRON (1<<5)  /* EEE IFR visible in the memory map                         */
#define _MMCTL1_BIT_PGMIFRON (1<<4)  /* Program IFR visible in the memory map                     */
#define _MMCTL1_BIT_RAMHM    (1<<3)  /* RAM only in the higher half of the memory map             */
#define _MMCTL1_BIT_EROMON   (1<<2)  /* Enables emulated Flash or ROM memory in the memory map    */
#define _MMCTL1_BIT_ROMHM    (1<<1)  /* FLASH or ROM only in higher Half of Memory Map            */
#define _MMCTL1_BIT_ROMON    (1<<0)  /* Enable FLASH or ROM in the memory map                     */

#define _MMCTL1_SET(value)   ((*(volatile unsigned char*)_MMCTL1_ADR)= (value))

#if defined(__MAP_FLASH__)
  _MMCTL1_SET(_MMCTL1_BIT_ROMON | _MMCTL1_BIT_EROMON);
#elif defined(__MAP_EXTERNAL__)
  _MMCTL1_SET(_MMCTL1_BIT_ROMON | _MMCTL1_BIT_EROMON | _MMCTL1_BIT_ROMHM);
#else /* RAM */
  _MMCTL1_SET(_MMCTL1_BIT_ROMON | _MMCTL1_BIT_EROMON | _MMCTL1_BIT_RAMHM | _MMCTL1_BIT_ROMHM);
#endif    
#endif

#ifndef __ONLY_INIT_SP
   Init(); /* zero out, copy down, call constructors */
#endif

   /* Here user defined code could be inserted, all global variables are initilized */
#if defined(_DO_ENABLE_COP_)
   _ENABLE_COP(1);
#endif

   /* call main() */
   main();
}

其实,删除掉各种define,去繁存精,只干了三件事:设置栈指针SP,调用init(),然后调用main()。

从map文件中也可以验证:

BOOTLOADER设计

在有BOOT的系统中,程序分为两部分:BOOT和APP。

这里面就有两套中断。需要在BOOT中做特殊处理。

在升级过程中,接收到上位机发过来的APP的bin文件时,需要调整中断向量保存的位置。(因为APP工程中生成的中断向量也是保存在0xFF10开始的位置)

上电后,CPU还是先从BOOT开始执行。在BOOT中作一些判断,确认APP正常后,跳转到APP中去执行。但是在跳转前,需要先配置中断向量基地址寄存器(IVBR),确保中断向量指向正确的位置。

注意:IVBR是个8位的寄存器,而中断向量起始地址是16位的,其中低8位默认为0.

相关文章:

  • C++编程:进阶阶段—1内存模型
  • 【机器学习】应用梯度下降法训练线性回归算法模型
  • 玩转python: 深度解析Python高阶函数及推导式
  • 【UCB CS 61B SP24】Lecture 21: Data Structures 5: Priority Queues and Heaps 学习笔记
  • 如何在无图形化界面的服务器上下载百度网盘的超大文件(10GB以上)?
  • RefuseManualStart/Stop增强Linux系统安全性?详解systemd单元保护机制
  • 【时序预测】时间序列有哪些鲁棒的归一化方法
  • PMP项目管理—资源管理篇—5.管理团队
  • PySide(PyQT)的@Slot()、@pyqtSlot()装饰器的作用
  • 【区块链 + 绿色低碳】东方易电城市微电网智能平台 | FISCO BCOS 应用案例
  • 【Java---数据结构】链表 LinkedList
  • 物联网数据中台 数据采集器 边缘盒子三者之间应用思考点
  • Windows10系统构建本地安全私有化的个人知识库——采用DeepSeek+RAGFlow
  • Android中的Content Provider是什么以及它有哪些用途
  • 责任链模式:让请求在链条中流动
  • 数组扩展【ES6】
  • npm、Yarn 与 pnpm:选择最适合你的包管理工具
  • 汽车材料耐候性测试仪器-太阳光模拟器介绍
  • 9道Dubbo面试题
  • 爬虫Incapsula reese84加密案例:Etihad航空
  • 怎么做动态网站/建设网站
  • 织梦网站怎么做404页面模板/女教师遭网课入侵直播
  • 互联网外包公司值得去吗/青岛seo推广
  • 阜宁网站制作收费在线咨询/教你免费申请个人网站
  • 网站做301重定向的作用/东莞做网站公司
  • 如何做网站站内搜索/品牌营销的四大策略