main函数以前即启动
- 概述
- 当你打开电源时,启动程序首先运行
- 启动例程的内容
- 初期阶段的确认很重要
- 结束语
概述
在Windows和Linux/UNIX的环境中使用C语言进行编程时,对main函数以后进行编码。但是,程序并不是从main函数开始的。作为其前一阶段,存在着启动程序。
在编入系统中,为了运行程序,需要理解启动程序。如果不把握启动程序在做什么而进行调试,这很有可能是做无用的工作。作为嵌入式软件技术人员开始学习,这是一定要理解的内容。
当你打开电源时,启动程序首先运行
嵌入式程序通常在微型计算机上运行。微型计算机开始动作时的动作根据微型计算机的不同而不同,在此对其中的一个例子进行说明。
嵌入机器开始动作,也就是接通电源,按下复位按钮时,微型计算机就会出现复位造成的强制性中断(图2-1的(1))。该中断对微型计算机说:“不管现在的状态如何,从初始状态开始动作“的强制性指令。当复位的强制中断进入时,微型计算机在某个固定的地址(被称为中断向量区的特别存储区域中,读取被分配给复位的向量地址)的内容。写在那里的内容根据微型计算机的不同而不同,是跳转目标的地址,或者是短的程序。写的内容是跳转目标地址的情况下,控制转移到该地址(图2-1的(2))。另外,写的内容是程序的情况下,执行写在那里的程序,其内容和刚才一样,将控制转移到某个地址。无论如何,程序都会开始运行。此时调用的程序被称为启动例程。
插入机器接通电源后,首先进入(1)复位中断,微型计算机读取中断向量域内的某个固定地址的内容。根据写在那里的内容,
(2)调用启动例行程序。启动例行程序中,(3)进行堆栈的设定和初始化处理,之后(4)呼出main函数。另外,程序执行结束后,(5)返回启动例行程序进行后处理的情况很多。
启动例程的内容
在启动程序中,在执行C程序之前进行必要的初始化。在Windows或Linux/UNIX中开发应用程序时,不会意识到启动程序。这是因为程序的执行环境总是相同的(因为每次都不需要变更),因为C编译器自动地链接了启动程序(用UNIX系统来说,启动程序和标准库一起以crt0.o的名义存在)。但是,在嵌入式编程的情况下,什么样的设备连接在一起呢?装载了多少内存呢?这些都取决于机器.因此,虽说是装置的初始化,根据机器的不同处理也会有所不同.此外,初始化装置时的操作方法也因使用的微型计算机而不同.因此,启动程序变得很重要。如果不能理解启动程序,可以说不能制作嵌入式软件也是不为过的。
在启动程序中,一般进行以下处理(图2-1的(3))
- 堆栈的设置
- 设置执行程序所需的数据将初始值数据从ROM区域传输到RAM区域
- 清除不具有初始值的存储区的0
- 初始化用于使用内置微型计算机的外围功能的各种寄存器
堆栈也出现在前一篇文章的“嵌入式开发基础从启动例程到硬件之程序是如何运行的?”中,是运行程序时所必须的,是用于变量的RAM区域。通过启动程序来定义堆栈区域也是很常见的。
作为程序的执行所必需的东西,除了堆栈以外还有常量和全局变量。需要对这些进行初始化或者清除0。常量的一部分值可能需要参照ROM复制到RAM中。这就是从ROM区域到RAM区域的初始值数据的传输。
另外,在图2-1的(4)中,从启动程序中直接调用C程序的main函数,但是使用C语言的标准库时,需要在调用main函数之前执行标准库的初始化。
这些初始化是在参考微型计算机和硬件手册的同时进行编码的。除了软件本身的执行之外,还需要初始化使用微型计算机和其他硬件的初始化。
在进行了这些下准备之后,终于调用main函数(图2-1的(4))。另外,程序执行结束后返回启动程序(即,程序执行的后处理也记述在启动程序中)的情况也不少(图2-1的(5))。
初期阶段的确认很重要
关于微型计算机和硬件的初始化,要阅读各自的指南并设定。但是,由于各自的功能变得复杂,这是很困难的。因此,在调试程序,动作很奇怪的时候,
经常会有初始化遗漏和设定错误的原因。在初次使用的功能的情况下,有必要让前辈评审设定是否正确,试着进行动作验证等,在开始时需要注意.在组合整体程序进行验证的时候,经常会注意到,由于初始化失败和设置错误,操作很奇怪。
另外,在探讨微型计算机和硬件的初始化时,正是了解如何使用硬件,或者硬件是如何运行的好机会。抓住这样的机会,学习与硬件相关的知识吧。
结束语
启动是进行程序执行的重要的前期准备的地方。如果不知道这些设定,就不能运行程序。从这个意义上说,启动是最初的第一步。另外,调试的时候也是,
意识到启动的设定是很重要的。启动是在编入程序开发中,一直与阴暗面相关的东西。