欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

记录学习嵌入式遇到的问题(二)复杂工程管理示例

程序员文章站 2022-03-13 17:24:12
...

在一个实际工程的创建和管理中,其众多的各种文件常会因各种原因而分别放在不同的文件目录之下。总而言之,为了清楚有序,开发人员应该为工程设置多个文件目录来存储源代码、编译过程中产生的中间文件及第三方的文件等。设计者应该充分的利用批处理文件和makefile文件的强大功能,负责建立起不同的文件目录,来使整个工程规范有序,来减少不必要的错误。

下面用一个例子来说明批处理文件和 makefile文件在工程管理上的作用。

(1)程序的目录组织
文件目录的层次根据开发人员的风格来定,没有标准的要求,但要尽可能的让别人容易理解!

在本例中第三方的源程序存储在TPS文件夹中,用户自己的源程序以及连接文件存储在SOURCE文件夹中,编译过程中产生的.obj文件复制在OBJ临时文件夹中以备查询,批处理文件和 makefile文件被存放在目录TEST,同时该目录还要负责存放将来创建出来的最终可执行文件TEST.EXE,WORK文件夹也常常被叫做工作目录,其作用就是为编译和连接工作提供一种场所,所以在WORK文件夹中需要访问其他的文件夹,如:SOURCE文件夹等。例如:在WORK文件夹中访问SOURCE,则该目录的路径就为..\SOURCE(因为是在WORK的上一级目录中,若SOURCE在WORK的上上一级目录,则路径就为..\..\SOURCE)其中,WORK以及OBJ文件夹为临时文件夹,在程序编译完成之后会被删除。

此图为运行批处理文件后的文件结构截图:
记录学习嵌入式遇到的问题(二)复杂工程管理示例
最初始的文件结构为:
记录学习嵌入式遇到的问题(二)复杂工程管理示例
(2)批处理文件
批处理文件要负责临时文件目录的创建及删除,同时还要负责 makefile文件的启动。本例批处理文件代码如下:

ECHO OFF
ECHO *******************************************************************************
ECHO *                                  uC/OS-II
ECHO *                           The Real-Time Kernel
ECHO *
ECHO *          (c) Copyright 1992-2002, Jean J. Labrosse, Weston, FL
ECHO *                           All Rights Reserved
ECHO *
ECHO * Filename    : MAKETEST.BAT
ECHO * Description : Batch file to create the application.
ECHO * Output      : TEST.EXE will contain the DOS executable
ECHO * Usage       : MAKETEST
ECHO * Note(s)     : 1) This file assume that we use a MAKE utility.
ECHO *******************************************************************************
ECHO *
ECHO ON
REM 在当前目录的上一级目录创建WORK临时文件夹
MD    ..\WORK                       
REM 在当前目录的上一级目录创建OBJ临时文件夹
MD    ..\OBJ                        
REM 在当前目录的上一级目录创建TPS文件夹
MD    ..\TPS                        
REM 进入WORK文件夹
CD    ..\WORK                       
REM 进入TEST文件夹把连接文件TEST.MAK文件夹复制到WORK文件夹下并命名为TEST.MAK
COPY  ..\TEST\TEST.MAK   TEST.MAK   
REM 启动makefile文件
C:\BC31\BIN\MAKE -f TEST.MAK        
REM 进入TEST文件夹
CD    ..\TEST                      

(3)makefile文件
makefile文件代码如下:

###############################################################################
#                                  uC/OS-II
#                            The Real-Time Kernel
#                         
#              (c) Copyright 2002, Jean J. Labrosse, Weston, FL
#                             All Rights Reserved
#
#
# Filename    : TEST.MAK
###############################################################################
#
#/*$PAGE*/
###############################################################################
#                                   TOOLS
###############################################################################
#

BORLAND=C:\BC31                     # 用BORLAND代替地址C:\BC31

CC=$(BORLAND)\BIN\BCC               # 用CC代替指令BCC
ASM=$(BORLAND)\BIN\TASM             # 用ASM代替指令TASM(汇编编译命令)
LINK=$(BORLAND)\BIN\TLINK           # 用LINK代替指令TLINK
TOUCH=$(BORLAND)\BIN\TOUCH          # 用TOUCH代替指令TOUCH  

###############################################################################
#                                DIRECTORIES
###############################################################################
#

TPS=..\TPS                          # 用TPS代替由当前目录返回上一级目录TPS中
OBJ=..\OBJ                          # 用OBJ代替由当前目录返回上一级目录OBJ中
SOURCE=..\SOURCE                    # 用SOURCE代替由当前目录返回上一级目录SOURCE中
TARGET=..\TEST                      # 用TARGET代替由当前目录返回上一级目录TEST中
WORK=..\WORK                        # 用WORK代替由当前目录返回上一级目录WORK中

OS=\UCOS-II\COMMON\SOURCE           # 用OS代替目录\UCOS-II\COMMON\SOURCE
PC=\UCOS-II\COMMON\BLOCKS\PC\BC31   # 用PC代替目录\UCOS-II\COMMON\BLOCKS\PC\BC31
PORT=\UCOS-II\COMMON\Ix86L\BC31     # 用PORT代替目录\UCOS-II\COMMON\Ix86L\BC31

###############################################################################
#                               COMPILER FLAGS
#
# -1                 Generate 80186 code
# -B                 Compile and call assembler
# -c                 Compiler to .OBJ
# -G                 Select code for speed
# -I                 Path to include   directory
# -k-                Standard stack frame
# -L                 Path to libraries directory
# -ml                Large memory model
# -N-                Do not check for stack overflow
# -n                 Path to object directory
# -O                 Optimize jumps
# -Ob                Dead code elimination
# -Oe                Global register allocation
# -Og                Optimize globally
# -Ol                Loop optimization
# -Om                Invariant code motion
# -Op                Copy propagation
# -Ov                Induction variable
# -v                 Source debugging ON
# -vi                Turn inline expansion ON
# -wpro              Error reporting: call to functions with no prototype
# -Z                 Suppress redundant loads
###############################################################################
#

C_FLAGS=-c -ml -1 -G -O -Ogemvlbpi -Z -d -n..\obj -k- -v -vi- -wpro -I$(BORLAND)\INCLUDE -L$(BORLAND)\LIB
                                    # 用C_FLAGS来代替编译命令
                                    
###############################################################################
#                               ASSEMBLER FLAGS
#
# /MX                Case sensitive on globals
# /ZI                Full debug info
# /O                 Generate overlay code
###############################################################################
#

ASM_FLAGS=/MX /ZI /O                # 用ASM_FLAGS代替汇编程序标志

###############################################################################
#                                LINKER FLAGS
###############################################################################
#
LINK_FLAGS=                         # 用LINK_FLAGS代替连接标志

###############################################################################
#                               MISCELLANEOUS
###############################################################################
#
INCLUDES=      $(SOURCE)\INCLUDES.H  \
               $(SOURCE)\OS_CFG.H    \
               $(PORT)\OS_CPU.H      \
               $(PC)\PC.H            \
               $(OS)\uCOS_II.H                  
                                    # 用INCLUDES代替需要引入的头文件的位置 
###############################################################################
#                          CREATION OF .EXE FILE
###############################################################################

$(TARGET)\TEST.EXE:                  \                        # 进入TEST文件夹生成TEST.EXE文件
               $(WORK)\INCLUDES.H    \                        # 需要的中间文件
               $(OBJ)\OS_CPU_A.OBJ   \   					  # 需要的中间文件
               $(OBJ)\OS_CPU_C.OBJ   \   					  # 需要的中间文件
               $(OBJ)\PC.OBJ         \   					  # 需要的中间文件
               $(OBJ)\TEST.OBJ       \   					  # 需要的中间文件
               $(OBJ)\uCOS_II.OBJ    \   					  # 需要的中间文件
               $(SOURCE)\TEST.LNK        					  # 需要的中间文件
               COPY    $(SOURCE)\TEST.LNK                     # 把TEST.LNK复制到当前文件夹(WORK)        
               $(LINK) $(LINK_FLAGS)     @TEST.LNK            # 执行连接命令
               COPY    $(OBJ)\TEST.EXE   $(TARGET)\TEST.EXE   # 把TEST.EXE复制到TEST文件夹
               COPY    $(OBJ)\TEST.MAP   $(TARGET)\TEST.MAP   # 把TEST.MAP复制到TEST文件夹
               DEL     TEST.MAK        					      # 删除连接文件


###############################################################################
#                        CREATION OF .OBJ (Object) FILES
###############################################################################

$(OBJ)\OS_CPU_A.OBJ:                  \
               $(PORT)\OS_CPU_A.ASM                                            # 需要的中间文件    

               COPY   $(PORT)\OS_CPU_A.ASM  OS_CPU_A.ASM                       # 复制OS_CPU_A.ASM到当前文件夹
	           $(ASM) $(ASM_FLAGS)  $(PORT)\OS_CPU_A.ASM,$(OBJ)\OS_CPU_A.OBJ   # 汇编语言的编译命令


$(OBJ)\OS_CPU_C.OBJ:                  \
               $(PORT)\OS_CPU_C.C     \                                        # 需要的中间文件

               COPY   $(PORT)\OS_CPU_C.C    OS_CPU_C.C                         # 复制
               $(CC)  $(C_FLAGS)            OS_CPU_C.C                         # C语言编译命令


$(OBJ)\PC.OBJ:                        \
               $(PC)\PC.C             \                                        # 需要的中间文件
               $(INCLUDES)                                                     # 需要的中间文件

               COPY   $(PC)\PC.C            PC.C                               # 复制
               $(CC)  $(C_FLAGS)            PC.C                               # C语言编译命令


$(OBJ)\TEST.OBJ:                      \
               $(SOURCE)\TEST.C       \                                        # 需要的中间文件
               $(INCLUDES)                                                     # 需要的中间文件

               COPY   $(SOURCE)\TEST.C      TEST.C                             # 复制
               $(CC)  $(C_FLAGS)            TEST.C                             # C语言编译命令


$(OBJ)\uCOS_II.OBJ:                   \
               $(OS)\uCOS_II.C        \
               $(INCLUDES)

               COPY   $(OS)\uCOS_II.C       uCOS_II.C                          # C语言编译命令
               $(CC)  $(C_FLAGS)            uCOS_II.C                          # C语言编译命令


$(WORK)\INCLUDES.H:                   \
               $(INCLUDES)                                                     # 需要的中间文件

               COPY   $(SOURCE)\INCLUDES.H  INCLUDES.H                         # 复制
               COPY   $(SOURCE)\OS_CFG.H    OS_CFG.H                           # 复制
               COPY   $(PC)\PC.H            PC.H                               # 复制
               COPY   $(PORT)\OS_CPU.H      OS_CPU.H                           # 复制
               COPY   $(OS)\uCOS_II.H       uCOS_II.H                          # 复制

(4)SOURCE文件夹中的部分源码
test.c:

/*
**********************************************
*说明:我的第一个在PC上的uC/OS-II任务        
*By:jack ailson                              
*Time:2013.08.09							 
**********************************************
*/
#include "includes.h"
#define TASK_STK_SIZE 512//任务堆栈的长度
OS_STK MyTaskStk[TASK_STK_SIZE];//定义任务堆栈区
OS_STK YouTaskStk[TASK_STK_SIZE];
INT16S key;//用于退出uC/OS-II的按键
INT8U x=0,y=0;//字符显示的位置
void MyTask(void *pdata);//声明一个自己的任务
void YouTask(void *pdata);
/*
***********************************************
*主函数:void main(void);                      
***********************************************
*/
void main(void)
{
	char* s_M="M";//定义要显示的字符
	OSInit();//初始化uC/OS-II
	PC_DOSSaveReturn();//保存DOS环境
	PC_VectSet(uCOS,OSCtxSw);//安装uC/OS-II任务切换中断向量
	OSTaskCreate(MyTask,s_M,&MyTaskStk[TASK_STK_SIZE-1],0);//创建任务
	OSStart();//启动多任务管理
}
/*
***********************************************
*任务:void MyTask(void *pdata);                
***********************************************
*/
void MyTask(void *pdata)
{
	char *s_Y="Y";
	INT8U lockcal=0;
#if OS_CRITICAL_METHOD==3
	OS_CPU_SR cpu_sr;
#endif
	pdata=pdata;
	OS_ENTER_CRITICAL();//进入临界段(关中断)
	PC_VectSet(0x08,OSTickISR);//安装uC/OS-II时钟中断向量
	PC_SetTickRate(OS_TICKS_PER_SEC);//设置uC/OS-II时钟频率
	OS_EXIT_CRITICAL();//退出临界段(开中断)
	OSStatInit();//初始化uC/OS-II的统计任务
	OSTaskCreate(YouTask,s_Y,&YouTaskStk[TASK_STK_SIZE-1],2);
	for(;;)
	{
		if (lockcal==5)
		{
			OSSchedLock();
		}
		if (lockcal==10)
		{
			lockcal=0;
			OSSchedUnlock();
		}
		lockcal++;
		if (x>27)
		{
			x=0;
			y+=2;
		}
		PC_DispChar(x,y,*(char*)pdata,DISP_BGND_BLACK+DISP_FGND_YELLOW);//字符显示
		x++;
		//如果按下ESC键,则退出uC/OS-II
		if (PC_GetKey(&key)==TRUE)//检查是否有按键按下
		{
			if (key==0x1b)
			{
				PC_DOSReturn();//返回DOS
			}
		}
		OSTimeDlyHMSM(0,0,3,0);//延时3S
	}
}
/*
***********************************************
*任务:void YouTask(void *pdata);                
***********************************************
*/
void YouTask(void *pdata)
{
	INT8U cal=0;
#if OS_CRITICALS_METHOD==3
	OS_CPU_SR cpu_sr;
#endif
	pdata=pdata;
	for(;;)
	{
		if (cal==20)
		{
			OSTaskSuspend(0);
		}
		if (cal==40)
		{
			cal=0;
			OSTaskResume(0);
		}
		cal++;
		if (x>27)
		{
			x=0;
			y+=2;
		}
		PC_DispChar(x,y,*(char*)pdata,DISP_BGND_BLACK+DISP_FGND_GREEN);
		x++;
		OSTimeDlyHMSM(0,0,1,0);
	}
}

(5)运行结果
运行前的文件结构:
记录学习嵌入式遇到的问题(二)复杂工程管理示例
运行前的SOURCE文件夹中的内容:
记录学习嵌入式遇到的问题(二)复杂工程管理示例
运行前的TEST文件夹中的内容:
记录学习嵌入式遇到的问题(二)复杂工程管理示例
运行时的截图:
(1)执行批处理文件
记录学习嵌入式遇到的问题(二)复杂工程管理示例
(2)批处理文件执行成功
记录学习嵌入式遇到的问题(二)复杂工程管理示例
(3)执行test.exe
记录学习嵌入式遇到的问题(二)复杂工程管理示例
(4)执行成功
记录学习嵌入式遇到的问题(二)复杂工程管理示例
运行过程:一行一行的在屏幕上输出MY(M与Y随机),速度比较缓慢。

运行后的文件结构:
记录学习嵌入式遇到的问题(二)复杂工程管理示例
运行后的OBJ文件中的内容:
记录学习嵌入式遇到的问题(二)复杂工程管理示例
运行后的TEST文件夹中的内容:
记录学习嵌入式遇到的问题(二)复杂工程管理示例
运行后的WORK文件夹中的内容:
记录学习嵌入式遇到的问题(二)复杂工程管理示例
注:本文章仅供参考,只用文章中的3段代码是实现不了最后的结果的,还需要其他文件。如需资料可评论。

相关标签: 嵌入式