《嵌入式系统C 语言编程.pdf》由会员分享,可在线阅读,更多相关《嵌入式系统C 语言编程.pdf(21页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、11嵌入式系统 C 语言编程嵌入式系统 C 语言编程凌 明 南京博芯电子技术有限公司2006年9月22006-9-15Copyright 2005 Prochip Electronics Co,ltd.All Rights Reserved.Not to be reproduced by any means without prior written consent.目 录目 录大家都学过C吧掌握嵌入式系统C语言编程的切入点了解嵌入式系统C编程环境了解存储器了解C程序的调试了解基于C语言的软件项目组织语法语法232006-9-15Copyright 2005 Prochip Electroni
2、cs Co,ltd.All Rights Reserved.Not to be reproduced by any means without prior written consent.#include“stdlib.h”char*test(char*ptr)unsigned char i;char buf8*1024;char*p,*q;for(i=0;i=8*1024;i+)bufi=0 x0;p=malloc(1024);if(p=NULL)return NULL;q=malloc(2048);if(q=NULL)return NULL;memcpy(p,ptr,1024);memcp
3、y(q,ptr,2048);memcpy(buf,p,1024);buf=buf+1024;memcpy(buf,q,2048);free(p);free(q);return buf;应该为应该为应该为应该为unsigned int i;局部变量太大了,容易造成堆栈溢出局部变量太大了,容易造成堆栈溢出;应该为应该为i Child;pwnd!=NULL;pwnd=pwnd-Sibling)FreeWindowTree(pwnd);if(Root-strWndTitle!=NULL)FreeMemory(Root-strWndTitle);FreeMemory(Root);PwndPwnd已经被释
4、放了,但是在已经被释放了,但是在已经被释放了,但是在已经被释放了,但是在forfor循环中被再次引用循环中被再次引用循环中被再次引用循环中被再次引用242006-9-15Copyright 2005 Prochip Electronics Co,ltd.All Rights Reserved.Not to be reproduced by any means without prior written consent.关于动态内存关于动态内存总是检查动态内存分配是否成功后再引用该指针!在分配struct空间是总是使用sizeof分配内存时宁滥勿缺(别忘了加一)总是Free由malloc()函数
5、返回的指针按照ANSI C 标准Free函数是没有返回值的错误处理时不要忘了其他已分配空间的释放1325了解C程序的调试了解C程序的调试262006-9-15Copyright 2005 Prochip Electronics Co,ltd.All Rights Reserved.Not to be reproduced by any means without prior written consent.Bugs vs DebuggingBugs vs Debugging没有Bug的就不是软件核心的问题是:怎样发现程序错误的根源?怎样在软件中自动地查出这个错误?怎样修正这个错误?怎样避免这个
6、错误?14272006-9-15Copyright 2005 Prochip Electronics Co,ltd.All Rights Reserved.Not to be reproduced by any means without prior written consent.初学者的困惑初学者的困惑在错误面前一筹莫展拼命的单步,但却不知道该关心什么?根本就不单步跟踪程序,或者不敢往下层函数跟踪总是发现编译器的“Bug”随便的,没有目的的修改代码,祈求奇迹的出现282006-9-15Copyright 2005 Prochip Electronics Co,ltd.All Rights
7、Reserved.Not to be reproduced by any means without prior written consent.Debugging的手段和工具Debugging的手段和工具一般的Debug工具都提供以下功能断点与数据观测点(Break point and Watch point)单步(Step)寄存器的观察与修改(Register)变量的观察与修改(Watch)内存观察与修改(Memory)调用栈(Call Stack)程序的可观测性与程序的可观测性与程序的可观测性与程序的可观测性与可控制性可控制性可控制性可控制性15292006-9-15Copyright
8、2005 Prochip Electronics Co,ltd.All Rights Reserved.Not to be reproduced by any means without prior written consent.Bug的定位关注接口Bug的定位关注接口好的软件架构总是基于层次性的架构,通过相对单纯的数据结构和接口函数与外界交互。应用程序应用程序应用程序应用程序应用程序应用程序APIAPI以及接口数据结构以及接口数据结构以及接口数据结构以及接口数据结构OSOS内核内核内核内核文件系统文件系统GUIGUI网络系统网络系统底层硬件驱动底层硬件驱动底层硬件驱动底层硬件驱动用户编程接
9、口用户编程接口文件系统的核心文件系统的核心硬件的驱动接口硬件的驱动接口FlashFlash驱动驱动MMCMMC卡驱动卡驱动302006-9-15Copyright 2005 Prochip Electronics Co,ltd.All Rights Reserved.Not to be reproduced by any means without prior written consent.Bug的定位关注接口Bug的定位关注接口因次Bug的定位首先应该从上层逐渐往下层排查,将断点设在上层函数的入口,单步执行跟踪程序的流程,特别关注底层函数的执行是否正确(主要是观察他的返回值是否正确),将搜
10、索的方位逐渐缩小,最后定位在一个函数内部。16312006-9-15Copyright 2005 Prochip Electronics Co,ltd.All Rights Reserved.Not to be reproduced by any means without prior written consent.Bug的定位关注内存的访问越界Bug的定位关注内存的访问越界C语言的灵活性,指针的应用,以及C语法的宽容性很容易造成代码的错误,这其中最主要的就是内存单元的溢出堆栈溢出缓冲区溢出数组越界因此在将错误局限在一个函数中的时候,应该关注内存的问题了322006-9-15Copyrigh
11、t 2005 Prochip Electronics Co,ltd.All Rights Reserved.Not to be reproduced by any means without prior written consent.其他的其他的已用空间已用空间堆栈溢出堆栈溢出已用已用已用已用堆栈堆栈堆栈堆栈空间空间空间空间高地址高地址低地址低地址SPSP堆栈指针堆栈指针剩余的剩余的栈空间栈空间堆栈的底部堆栈的底部堆栈溢出冲掉了其他数据堆栈溢出冲掉了其他数据堆栈溢出冲掉了其他数据堆栈溢出冲掉了其他数据假设假设假设假设:我们的堆栈是满递减堆栈我们的堆栈是满递减堆栈我们的堆栈是满递减堆栈我们的堆
12、栈是满递减堆栈主要原因主要原因主要原因主要原因:1,1,任务的堆栈预留的太小任务的堆栈预留的太小任务的堆栈预留的太小任务的堆栈预留的太小2,2,任务中开设了大的临时变量任务中开设了大的临时变量任务中开设了大的临时变量任务中开设了大的临时变量3,3,过深的函数递归过深的函数递归过深的函数递归过深的函数递归,消耗了堆栈消耗了堆栈消耗了堆栈消耗了堆栈主要现象主要现象主要现象主要现象:1,1,某些全局变量莫名其妙被改某些全局变量莫名其妙被改某些全局变量莫名其妙被改某些全局变量莫名其妙被改2,2,其他任务工作不正常其他任务工作不正常其他任务工作不正常其他任务工作不正常,比如比如比如比如:函数调用不正常函
13、数调用不正常函数调用不正常函数调用不正常(PrefechPrefech Abort)Abort)局部变量莫名其妙被改局部变量莫名其妙被改局部变量莫名其妙被改局部变量莫名其妙被改其他所有的死机与崩溃其他所有的死机与崩溃其他所有的死机与崩溃其他所有的死机与崩溃17332006-9-15Copyright 2005 Prochip Electronics Co,ltd.All Rights Reserved.Not to be reproduced by any means without prior written consent.堆栈的缓冲区溢出堆栈的缓冲区溢出SPSP堆栈指针堆栈指针传入传入传
14、入传入参数参数参数参数返回地址返回地址返回地址返回地址保存的保存的保存的保存的寄存器寄存器寄存器寄存器A4A4高地址高地址低地址低地址A3A3A2A2A1A1A0A0临时变量临时变量数组数组A A5 5A5A5A6A6A7A7A8A8返回地址和保存返回地址和保存的寄存器值被冲的寄存器值被冲主要现象主要现象主要现象主要现象:1,1,某些局部变量莫名其妙被改某些局部变量莫名其妙被改某些局部变量莫名其妙被改某些局部变量莫名其妙被改2,2,函数返回的时候崩溃函数返回的时候崩溃函数返回的时候崩溃函数返回的时候崩溃主要原因主要原因主要原因主要原因:1,1,临时数组变量越界临时数组变量越界临时数组变量越界临
15、时数组变量越界2,2,注意注意注意注意 strcpy();sprintfstrcpy();sprintf();();memcpymemcpy()()函数的目的缓冲区函数的目的缓冲区函数的目的缓冲区函数的目的缓冲区是否越界,是否越界,是否越界,是否越界,strycpystrycpy()()函数的函数的函数的函数的原字符串是否正常以原字符串是否正常以原字符串是否正常以原字符串是否正常以 0 0 结结结结束;束;束;束;memcpymemcpy()()函数的拷贝数函数的拷贝数函数的拷贝数函数的拷贝数是否正常是否正常是否正常是否正常342006-9-15Copyright 2005 Prochip E
16、lectronics Co,ltd.All Rights Reserved.Not to be reproduced by any means without prior written consent.全局变量和动态缓冲区溢出全局变量和动态缓冲区溢出A0A0A1A1A2A2A3A3A4A4高地址高地址低地址低地址其他全局其他全局其他全局其他全局变量变量变量变量A8A8A7A7A6A6A5A5其他全局其他全局变量被冲变量被冲主要现象主要现象主要现象主要现象:1,1,某些全局变量莫名其妙被改某些全局变量莫名其妙被改某些全局变量莫名其妙被改某些全局变量莫名其妙被改2,2,如果被冲的部分是动态分配的
17、如果被冲的部分是动态分配的如果被冲的部分是动态分配的如果被冲的部分是动态分配的缓冲区,一方面会造成其他数据缓冲区,一方面会造成其他数据缓冲区,一方面会造成其他数据缓冲区,一方面会造成其他数据的错误;另一方面会造成无法释的错误;另一方面会造成无法释的错误;另一方面会造成无法释的错误;另一方面会造成无法释放被冲的动态内存从而造成内存放被冲的动态内存从而造成内存放被冲的动态内存从而造成内存放被冲的动态内存从而造成内存泄漏泄漏泄漏泄漏主要原因主要原因主要原因主要原因:1,1,全局数组变量越界全局数组变量越界全局数组变量越界全局数组变量越界2,2,注意注意注意注意 strcpy();sprintfstr
18、cpy();sprintf();();memcpymemcpy()()函数的目的缓冲区函数的目的缓冲区函数的目的缓冲区函数的目的缓冲区是否越界,是否越界,是否越界,是否越界,strycpystrycpy()()函数的函数的函数的函数的原字符串是否正常以原字符串是否正常以原字符串是否正常以原字符串是否正常以 0 0 结结结结束;束;束;束;memcpymemcpy()()函数的拷贝数函数的拷贝数函数的拷贝数函数的拷贝数是否正常是否正常是否正常是否正常18352006-9-15Copyright 2005 Prochip Electronics Co,ltd.All Rights Reserved
19、.Not to be reproduced by any means without prior written consent.关注边界情况关注边界情况程序中需要考虑的边界情况数组的上限循环的次数链表的头部和尾部在插入新节点,或删除的情况下的特殊处理输入参数的极限情况(0,指针为空,复数,最大的情况等等)362006-9-15Copyright 2005 Prochip Electronics Co,ltd.All Rights Reserved.Not to be reproduced by any means without prior written consent.Bug的修正Bug
20、的修正别急着改,想想,再想想,想清楚了再动手。考虑所作的修改可能会对系统造成的新的影响是什么?我的修改会对其他人的代码造成影响吗?是否会对全局的数据结构或者函数接口定义作修改?如果是,如何通知所有的其他人?修改完了,应该有详细的文档,代码注释,并对修改过的代码进行回归测试1937了解基于C语言的软件项目组织了解基于C语言的软件项目组织382006-9-15Copyright 2005 Prochip Electronics Co,ltd.All Rights Reserved.Not to be reproduced by any means without prior written con
21、sent.一个简单的项目-myproject一个简单的项目-myprojectFile1.CFile1.hFile2.CFile2.hFile3.CFile3.hCALLCALLCALLCALLIncludeIncludeIncludeIncludeFile1.oFile1.oFile2.oFile2.oFile3.oFile3.oIncludeIncludemylib.libmylib.libmyproject.outmyproject.outLinkLinkFile1.oFile1.o依赖于依赖于依赖于依赖于File1.cFile1.cFile1.hFile1.hFile2.hFile2.
22、hMyProject.outMyProject.out依赖于:依赖于:依赖于:依赖于:File1.oFile1.oFile2.oFile2.oFile3.oFile3.oMylib.libMylib.lib20392006-9-15Copyright 2005 Prochip Electronics Co,ltd.All Rights Reserved.Not to be reproduced by any means without prior written consent.如何生成myproject?如何生成myproject?编译File1.C-File1.o编译File2.C-Fil
23、e2.o编译File3.C-File3.o连接File1.o File2.o File3.omylib.lib问题:问题:问题:问题:1 1、如果不仅仅是这几个文件,而是上百个文件怎么办?一个一个编译?、如果不仅仅是这几个文件,而是上百个文件怎么办?一个一个编译?、如果不仅仅是这几个文件,而是上百个文件怎么办?一个一个编译?、如果不仅仅是这几个文件,而是上百个文件怎么办?一个一个编译?回答:回答:回答:回答:只要编译修改过的文件就可以了。但是如果我们修改了只要编译修改过的文件就可以了。但是如果我们修改了只要编译修改过的文件就可以了。但是如果我们修改了只要编译修改过的文件就可以了。但是如果我们修
24、改了File2.h,File2.h,是不是要是不是要是不是要是不是要重新编译重新编译重新编译重新编译File1.C?File1.C?有没有办法解决这种复杂的相互依赖关系?有没有办法解决这种复杂的相互依赖关系?有没有办法解决这种复杂的相互依赖关系?有没有办法解决这种复杂的相互依赖关系?回答:回答:回答:回答:MAKEMAKE文件文件文件文件IDEIDE中的项目管理中的项目管理中的项目管理中的项目管理再问?如果我们修改了再问?如果我们修改了再问?如果我们修改了再问?如果我们修改了File2.C,File2.C,而没有修改而没有修改而没有修改而没有修改File2.h,File2.h,是否要重新编译是
25、否要重新编译是否要重新编译是否要重新编译File1.C?File1.C?402006-9-15Copyright 2005 Prochip Electronics Co,ltd.All Rights Reserved.Not to be reproduced by any means without prior written consent.MAKE文件MAKE文件MAKE实际上是一个批处理程序,该程序通过解释特定格式的MAKE脚本(MAKE文件),完成一个项目相关文件的编译,汇编与连接MAKE脚本一般描述了整个项目中各个文件的相互依赖关系,MAKE通过调用脚本中指定编译器,汇编器和连接器,按照项目个文件的依赖关系进行处理。常见的MAKE程序:MS nmakeGcc make21412006-9-15Copyright 2005 Prochip Electronics Co,ltd.All Rights Reserved.Not to be reproduced by any means without prior written consent.Contact me at:You Can Download this slides at: