运行C程序的步骤与方法详解——基于一个DSP工程文件(附头文件、源文件等作用说明)

运行C程序的步骤与方法(结合DSP工程)

这是一个28355的CPU定时器的工程
一个CPU定时器的工程里面的文件这么多,光TI提供的源文件就一大堆。还有成堆的头文件。以及cmd文件等等。这些文件各自的作用是什么?然后这些C程序又是如何联系起来,最终执行的?我想在本文里面来阐述一下。而叙述的顺序就按照谭浩强老师书中说的运行C程序的步骤与方法来一条条叙述。

1.源程序的编辑

这里我们先明白一个问题。为何这个工程中会有这么多的.c文件即源文件。这个我在之前的博文谭浩强老师《C程序设计》——学习笔记1中已经有过阐述。即这是模块化编程思想的体现。也正是因为有了这么多已经定义好了的实现不同功能的模块,或者说实现不同特定功能的源文件,我们才可以在编程的时候,对应一些常规的操作,仅用一句代码便轻而易举的实现了。
源文件中包含的内容
这个图里面就给出了TI提供的源文件,可以看出每个源文件便对应于一个特定的功能模块,即提供了对某一底层硬件的相关操作。但是并没有包含用户的逻辑也就是main函数所在的主函数文件。这个主函数文件需要开发者根据实际情况来编写。

2.对源程序进行编译

编译预处理

在对源程序进行编译之前,要先用C编译系统提供的“预处理器”(又称“预处理程序”或“预编译器”)对源程序中的预处理指令进行编译预处理。即程序代码前为“#”的语句就是在预处理期间进行作用的。预处理指令举例如下:
#define 宏名 字符串
#include “文件名”(或<文件名>)
这些预处理指令是由C标准建议的,但是它不是C语言本身的组成部分,不能用C编译系统直接对他们进行编译(因为不认识)。所以要在编译之前进行预处理,把这些指令转换成相应的C程序语句。所以预处理阶段将把程序中的注释全部删除;对预处理指令进行处理,如把#include指令指定的头文件的内容复制到#include指令处;对#define指令进行指定的字符替换。C提供的预处理功能常用的有以下3种:
(1)宏定义
(2)文件包含
(3)条件编译
这里我们主要来看一下每个源程序所包含的头文件中的内容。
头文件中包含的内容1
头文件中包含的内容2
这里面的头文件构成了DSP芯片寄存器的完整框架。即为了对一个外设进行编程,通常只需要对其控制寄存器的整体或者相应的位进行编程。更直接的话可以直接把一个是十六进制的数值写到外设所对应存储器地址;但在多次操作并且写不同控制值的时候,这样的写方式重复度很高且效率低。所以为了使源程序更加简洁、模块化,往往把一些寄存器的描述、全局变量、结构体、一些模块化定义的参数放在头文件中,并且在多个源程序中都可以进行应用,从而方便编程和程序的修改调试。F28335DSP中C代码的头文件有C函数、宏、外设的结构及变量定义等
(1)所有外设的名字(例如CpuTimer0Regs,一般是每个单词的首字母大写)、结构(包含控制寄存器、状态寄存器、输入/输出端口);
(2)所有的寄存器名字(例如TCR、TIM、TPR,一般全是大写字母);
(3)寄存器各个位的说明(例如POL、TOG、TSS,一般全是大写字母);
(4)寄存器的地址。
定义外设名字、寄存器名字、寄存器各个位说明

定义寄存器地址
定义相应的段
在nonBIOS.cmd文件中
将定义的段映射到对应的存储器地址中去

在这种方式下,寄存器和它们的位用结构体和共用体来进行预定义,并使用C代码编写的函数和宏进行结构体的初始化,通过2个cmd文件实现和实际存储空间的映射,本质上即对寄存器的相应位进行操作。

编译

编译的作用首先是对源程序进行检查,判断它有无语法方面的错误。然后通过编译器将源程序转换为汇编语言源程序。再通过汇编器将汇编语言代码转换为二进制形式的机器语言即**.obj目标文件**。
这里需要说明的是,经过编译所得到的二进制目标文件(.obj文件)还不能供计算机直接执行。一个C程序中包含很多的源文件程序,而编译是以源程序文件为对象的,一次编译只能得到与一个源程序文件相对应的目标文件(也称目标模块)。
编译是以源程序文件为对象的

3.进行连接处理

只有将所有的编译后得到的目标模块连接装配起来,再与函数库相连接成一个整体,才能生成一个可供计算机执行的目标程序,即为可执行程序(TI DSP上是COFF格式,一般是.out二进制文件)。该文件中包含了程序的机器代码和数据,以及其他用来链接和加载该程序所需的信息。
这个工作通过链接器来完成。在连接的过程中,链接器同时根据内存地址的分配对各目标文件进行重定位,并解析外部参考。例如在一个源程序中引用了另一个源程序中定义的变量就可以理解为外部参考。假如一个目标文件中引用了一个未定义的符号(symbol,指一些变量、函数名字等),则链接器搜索其他目标文件中定义的全局符号,找到匹配的符号修补指令,否则报告一个错误。所以,如果链接器提示symbol未定义,说明对应的文件没有加入到工程里面。

4.运行可执行程序,得到运行结果

总结:以上过程其实就可以归纳到下面的一张图中

运行C程序的步骤与方法

猜你喜欢

转载自blog.csdn.net/qq_39529052/article/details/105814923
今日推荐