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

在一个实际工程的创建和管理中,其众多的各种文件常会因各种原因而分别放在不同的文件目录之下。总而言之,为了清楚有序,开发人员应该为工程设置多个文件目录来存储源代码、编译过程中产生的中间文件及第三方的文件等。设计者应该充分的利用批处理文件和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段代码是实现不了最后的结果的,还需要其他文件。如需资料可评论。

发布了21 篇原创文章 · 获赞 11 · 访问量 1861

猜你喜欢

转载自blog.csdn.net/qq_42455308/article/details/104835280