C语言嵌入式系统编程修炼之软件架构篇.doc_第1页
C语言嵌入式系统编程修炼之软件架构篇.doc_第2页
C语言嵌入式系统编程修炼之软件架构篇.doc_第3页
C语言嵌入式系统编程修炼之软件架构篇.doc_第4页
C语言嵌入式系统编程修炼之软件架构篇.doc_第5页
已阅读5页,还剩1页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C语言嵌入式系统编程修炼之软件架构篇 - -%o.$T-+Ft 全球最大的中文电子开发论坛模块划分t&v%D0y(6a8t&电子论坛,电子设计论坛,电子开发论坛8o&Z1f2&/s9-g8l电子论坛,电子设计论坛,电子开发论坛模块划分的划是规划的意思,意指怎样合理的将一个很大的软件划分为一系列功能独立的部分合作完成系统的需求。C语言作为一种结构化的程序设计语言,在模块的划分上主要依据功能(依功能进行划分在面向对象设计中成为一个错误,牛顿定律遇到了相对论),C语言模块化程序设计需理解如下概念:u2|*:S1C6E-J%O3X!bB _3J1a&n3V电子开发论坛(1) 模块即是一个.c文件和一个.h文件的结合,头文件(.h)中是对于该模块接口的声明;电子论坛,电子设计论坛,电子开发论坛/y9M)m:B8g#;h+C+K-h(2) 某模块提供给其它模块调用的外部函数及数据需在.h中文件中冠以extern关键字声明;电子论坛,电子设计论坛,电子开发论坛(i1o*g34w3K1b3y6s0g6l&C3Y7,p6D2P)(3) 模块内的函数和全局变量需在.c文件开头冠以static关键字声明;2.U%A9k!t#j%K.p:v 全球最大的中文电子开发论坛4i&!U9#G!j)(4) 永远不要在.h文件中定义变量!定义变量和声明变量的区别在于定义会产生内存分配的操作,是汇编阶段的概念;而声明则只是告诉包含该声明的模块在连接阶段从其它模块寻找外部函数和变量。如:-F3;G1f()BP6q&hA&电子论坛,电子设计论坛,电子开发论坛4rf)m21T(u.x*pdD,_#G;!c-l7f)M5t/*module1.h*/4UX%i6_&q!x.N#rS3b电子论坛,电子设计论坛,电子开发论坛int a = 5; /* 在模块1的.h文件中定义int a */!B0B&3Q7x;A$电子论坛,电子设计论坛,电子开发论坛电子论坛,电子设计论坛,电子开发论坛2g0b)|b:EK+/_/*module1 .c*/)u0U8H;a9D5a)o$r!z$f3g:J#include module1.h /* 在模块1中包含模块1的.h文件 */)C6j*A$N#J3_/C$l:y O)B;z!f#6/*module2 .c*/;6w9a$|0X#include module1.h /* 在模块2中包含模块1的.h文件 */电子开发论坛g!c%d!J(O电子开发论坛_0S$H7o#z2M6c&/*module3 .c*/2N,r5V,r.B3f n3D#include module1.h /* 在模块3中包含模块1的.h文件 */ &C$I;t/X#e&P:X4G(A!H4s8i.i1k电子开发论坛以上程序的结果是在模块1、2、3中都定义了整型变量a,a在不同的模块中对应不同的地址单元,这个世界上从来不需要这样的程序。正确的做法是:;.? P!Ci)V5T.UT*s*b)o电子论坛,电子设计论坛,电子开发论坛9D:w8Y4x9%h(o/f(T/*module1.h*/ 全球最大的中文电子开发论坛(L d)u-;1Dextern int a; /* 在模块1的.h文件中声明int a */电子论坛,电子设计论坛,电子开发论坛3j!E;v1L7;K0K1n1D$C+T#S.L/*module1 .c*/4)p0G;P77电子论坛,电子设计论坛,电子开发论坛#include module1.h /* 在模块1中包含模块1的.h文件 */电子开发论坛 $%r3U)K59q/T%m6p(v*q&?,eint a = 5; /* 在模块1的.c文件中定义int a */ 全球最大的中文电子开发论坛9p)H:d* G6c5o%qz7Y8&U+T1:L!L/*module2 .c*/电子论坛,电子设计论坛,电子开发论坛9z:f1p3z;u2R#include module1.h /* 在模块2中包含模块1的.h文件 */;t&U.k4q!.S电子论坛,电子设计论坛,电子开发论坛0o!2W/y5W+r-o0Y(H/*module3 .c*/电子论坛,电子设计论坛,电子开发论坛E 7Z-P:V6r:b5e#include module1.h /* 在模块3中包含模块1的.h文件 */ .Y-x24k5T4N0_F!J-6($B7N,B 全球最大的中文电子开发论坛 全球最大的中文电子开发论坛8F!r6V$ D5z,o这样如果模块1、2、3操作a的话,对应的是同一片内存单元。$Y)f4a7:F1hA&V3J.I!Q:S,z%e电子开发论坛一个嵌入式系统通常包括两类模块:电子论坛,电子设计论坛,电子开发论坛*E,j#5yy!v9K,电子论坛,电子设计论坛,电子开发论坛2v*R E#u6M4(1)硬件驱动模块,一种特定硬件对应一个模块;7ja2n45U:p$R.I D4f7,u6b&q.f+jl+/b(2)软件功能模块,其模块的划分应满足低偶合、高内聚的要求。电子开发论坛?03C#k%K/)#j3E:M&OI6a多任务还是单任务9O6/h5R7W:m电子论坛,电子设计论坛,电子开发论坛,3I)m05L所谓单任务系统是指该系统不能支持多任务并发操作,宏观串行地执行一个任务。而多任务系统则可以宏观并行(微观上可能串行)地同时执行多个任务。$N4w3+*h:q5W&Q-T2C1K*F/GX%F4V_电子论坛,电子设计论坛,电子开发论坛多任务的并发执行通常依赖于一个多任务操作系统(OS),多任务OS的核心是系统调度器,它使用任务控制块(TCB)来管理任务调度功能。TCB包括任务的当前状态、优先级、要等待的事件或资源、任务程序码的起始地址、初始堆栈指针等信息。调度器在任务被激活时,要用到这些信息。此外,TCB还被用来存放任务的上下文(context)。任务的上下文就是当一个执行中的任务被停止时,所要保存的所有信息。通常,上下文就是计算机当前的状态,也即各个寄存器的内容。当发生任务切换时,当前运行的任务的上下文被存入TCB,并将要被执行的任务的上下文从它的TCB中取出,放入各个寄存器中。#G*P6x4a.m.q(D%_)m+W;t(d3Q7f1_u ?%T电子开发论坛嵌入式多任务OS的典型例子有Vxworks、ucLinux等。嵌入式OS并非遥不可及的神坛之物,我们可以用不到1000行代码实现一个针对80186处理器的功能最简单的OS内核,作者正准备进行此项工作,希望能将心得贡献给大家。电子论坛,电子设计论坛,电子开发论坛8W94b6W!Y2R2j!Y电子论坛,电子设计论坛,电子开发论坛.$l6b8g.B+x5a:8p究竟选择多任务还是单任务方式,依赖于软件的体系是否庞大。例如,绝大多数手机程序都是多任务的,但也有一些小灵通的协议栈是单任务的,没有操作系统,它们的主程序轮流调用各个软件模块的处理程序,模拟多任务环境。 全球最大的中文电子开发论坛;p$u9n.m9a电子论坛,电子设计论坛,电子开发论坛Z5F#V&V#rW,p7单任务程序典型架构*n&b+a6b0Q/YR 9l/w6o*(1)从CPU复位时的指定地址开始执行;:T8Vj3y3k#a&t!T e+M.c)yg0vG-o(2)跳转至汇编代码startup处执行;0e*w,F0+q#o)x9J8w5K0G:e2x!L(3)跳转至用户主程序main执行,在main中完成:电子开发论坛%1T!;g+d;S.W-t 全球最大的中文电子开发论坛6Yh z:7Gy-Ka.初试化各硬件设备; *T-7i%+L;6C&+;C(c0f4l*e4Q:K/m5b.初始化各软件模块;#+J/L:g!x%SV*X5Y8j电子论坛,电子设计论坛,电子开发论坛7R$I0T(;py%J0E%z1i*c.进入死循环(无限循环),调用各模块的处理函数1_!c(c,W!g7i%Y+y%x)P+A!Q2用户主程序和各模块的处理函数都以C语言完成。用户主程序最后都进入了一个死循环,其首选方案是:8Xr49;a3Jc7W3s1x c$U0K&while(1) y$S+N6K2x K5m8K*d%q!X1|4c3q8OV:M+ 0y8M9O+A*x&M电子论坛,电子设计论坛,电子开发论坛9W;(R&*g有的程序员这样写:;j2|)E/c;H38p G#e+f!F(z-Lfor(;)*v0U;M$g0q#y9g(l电子开发论坛/z&V/o!l00 全球最大的中文电子开发论坛 电子开发论坛+l8g#R29U:w-s.G电子论坛,电子设计论坛,电子开发论坛5f,M-|!I:u&d&w!V4V%E这个语法没有确切表达代码的含义,我们从for(;)看不出什么,只有弄明白for(;)在C语言中意味着无条件循环才明白其意。7|*4E3e!Q7e&y2h55r+O*O2p9l5J*I+K电子论坛,电子设计论坛,电子开发论坛下面是几个著名的死循环:2r8Y/r)s6o2h)E电子开发论坛电子论坛,电子设计论坛,电子开发论坛:G3W&9g/h+r(1)操作系统是死循环;,w9e0t8D1Y0j(H/q!O电子开发论坛,b*M0Pt5C/N:7k,A7电子论坛,电子设计论坛,电子开发论坛(2)WIN32程序是死循环;电子论坛,电子设计论坛,电子开发论坛:E,-i8q1ug-r;V&L :4f8电子开发论坛(3)嵌入式系统软件是死循环;5Z13W8cs;r5U-o4w/S#M4p0g 全球最大的中文电子开发论坛(4)多线程程序的线程处理函数是死循环。电子论坛,电子设计论坛,电子开发论坛/Z9q+x,K8H;电子论坛,电子设计论坛,电子开发论坛.O3A+G(b08T你可能会辩驳,大声说:凡事都不是绝对的,2、3、4都可以不是死循环。Yes,you are right,但是你得不到鲜花和掌声。实际上,这是一个没有太大意义的牛角尖,因为这个世界从来不需要一个处理完几个消息就喊着要OS杀死它的WIN32程序,不需要一个刚开始RUN就自行了断的嵌入式系统,不需要莫名其妙启动一个做一点事就干掉自己的线程。有时候,过于严谨制造的不是便利而是麻烦。君不见,五层的TCP/IP协议栈超越严谨的ISO/OSI七层协议栈大行其道成为事实上的标准?+I/z)s1-d+m/f电子开发论坛电子开发论坛9L:d/h26K+L5l&r经常有网友讨论: 全球最大的中文电子开发论坛*w*!L%#R$U(Z8C,F*Lb/r!H 全球最大的中文电子开发论坛printf(%d,%d,+i,i+); /* 输出是什么?*/9.p.i(yR;M;Ic = a+b; /* c=? */ 电子论坛,电子设计论坛,电子开发论坛 K.X&l1L&c$#Q电子开发论坛_.Q3M7x&?,s等类似问题。面对这些问题,我们只能发出由衷的感慨:世界上还有很多有意义的事情等着我们去消化摄入的食物。电子论坛,电子设计论坛,电子开发论坛:_*D*Q8T(%C:s.G.i电子论坛,电子设计论坛,电子开发论坛2I5Z!m(E9%nm实际上,嵌入式系统要运行到世界末日。.E!q,R3s i w.y5电子论坛,电子设计论坛,电子开发论坛4&x8q4E5t3s%r:X4A电子开发论坛中断服务程序电子论坛,电子设计论坛,电子开发论坛!e5W$A3n,#k$b1b,v2n电子论坛,电子设计论坛,电子开发论坛#f6|B1|;p,Q中断是嵌入式系统中重要的组成部分,但是在标准C中不包含中断。许多编译开发商在标准C上增加了对中断的支持,提供新的关键字用于标示中断服务程序(ISR),类似于_interrupt、#program interrupt等。当一个函数被定义为ISR的时候,编译器会自动为该函数增加中断服务程序所需要的中断现场入栈和出栈代码。电子开发论坛)N2M;e*hZ+e7B4k9_)v0E0&V5T*_中断服务程序需要满足如下要求: 全球最大的中文电子开发论坛*i8p/P9C6b7o1j4i9N0q:w7c4Q8L电子论坛,电子设计论坛,电子开发论坛(1)不能返回值;电子论坛,电子设计论坛,电子开发论坛%3nn-h7c/P(w)r(M.j;|9 L(xT:)T电子论坛,电子设计论坛,电子开发论坛(2)不能向ISR传递参数;(q59H8H;!9._&I5M%l(3) ISR应该尽可能的短小精悍; 全球最大的中文电子开发论坛.A6Z3F)0,/7i26h3J*T(4) printf(char * lpFormatString,)函数会带来重入和性能问题,不能在ISR中采用。&c#r,D4B2Y, 全球最大的中文电子开发论坛1D4U8Q1Pu8v4W0x/?!H)在某项目的开发中,我们设计了一个队列,在中断服务程序中,只是将中断类型添加入该队列中,在主程序的死循环中不断扫描中断队列是否有中断,有则取出队列中的第一个中断类型,进行相应处理。-V +Z%Q.S 电子论坛,电子设计论坛,电子开发论坛;I j 9d!E,j/* 存放中断的队列 */7R1o(q!SI-G 全球最大的中文电子开发论坛typedef struct tagIntQueue电子论坛,电子设计论坛,电子开发论坛(vr;I0|-R$W;_!K.F;X6U电子开发论坛+v7s.O1c4j0T.o:wint intType; /* 中断类型 */%u u?*Ks8D;C9J!e电子开发论坛struct tagIntQueue *next; 全球最大的中文电子开发论坛.Q;I4z8Z/N2M0?IntQueue;电子论坛,电子设计论坛,电子开发论坛0M0D(l;t1%k!-电子论坛,电子设计论坛,电子开发论坛9%m/*#0y:IIntQueue lpIntQueueHead; 全球最大的中文电子开发论坛#_%R-q) V0T9eF0F1a;T8T&_$,/J0g电子论坛,电子设计论坛,电子开发论坛_interrupt ISRexample () 7T2w!e+)S3G r电子论坛,电子设计论坛,电子开发论坛0r,n;*p&b+N0E-Aint intType;电子论坛,电子设计论坛,电子开发论坛+V o!Gl7intType = GetSystemType();(h-F4b(S(C!E-y,/QueueAddTail(lpIntQueueHead, intType);/* 在队列尾加入新的中断 */电子开发论坛)B;G/U$z/h%?.4A 电子开发论坛1k3$v/Y&Q)u+S#!B5)d-D)y,A2Q在主程序循环中判断是否有中断: 全球最大的中文电子开发论坛 Y4v,o7f*l 全球最大的中文电子开发论坛;O4Q#rl1w4ZWhile(1) 全球最大的中文电子开发论坛+G0B*y5_5q&3b电子开发论坛j-?1I)o2p%If( !IsIntQueueEmpty() )9W+yZ7_85m*)e2?电子论坛,电子设计论坛,电子开发论坛电子论坛,电子设计论坛,电子开发论坛5,9E:m.j9C%x0intType = GetFirstInt();4C5N3S0G:-k电子开发论坛switch(intType) /* 是不是很象WIN32程序的消息解析函数? */&|(a&m;E&?7x#p%d&!o)h;a*uw+r+g电子开发论坛/* 对,我们的中断类型解析很类似于消息驱动 */电子开发论坛L3j08L-J;Z1/pcase xxx: /* 我们称其为中断驱动吧? */电子论坛,电子设计论坛,电子开发论坛7o&;p/A?电子论坛,电子设计论坛,电子开发论坛.K5p03S/K+Bbreak;4a1t&d;_6T$X+k5case xxx: 全球最大的中文电子开发论坛W9a7Y6K)U.7y%Qd f)u,j65g.Lbreak;$a)?7X8A c& p%I5B电子论坛,电子设计论坛,电子开发论坛2s(B._*(p3A)q/Y(E-E!|2G)V1J;_.s(W2+J6O2*r:X!x#b2%? 2s H!F0hV1m9b0o:y7D 全球最大的中文电子开发论坛9H3g/U Q2Ns按上述方法设计的中断服务程序很小,实际的工作都交由主程序执行了。电子开发论坛&x!s8h(*y:f!s,w-3F-i*Y.H.G 全球最大的中文电子开发论坛硬件驱动模块)H4x2,S0&E9d(#X W5*oe/I*- 全球最大的中文电子开发论坛一个硬件驱动模块通常应包括如下函数:7k#r&Y+7Q2A7d)E6#T2a电子论坛,电子设计论坛,电子开发论坛;K-e3Y3p%y)r-yPP4M(1)中断服务程序ISR电子论坛,电子设计论坛,电子开发论坛3E+sa&;bU3?;a(n+E6b+F2G&J2M:S电子论坛,电子设计论坛,电子开发论坛(2)硬件初始化0M1M%H-?#:I/V4S/B/$O-1_4b/x S.N电子论坛,电子设计论坛,电子开发论坛a.修改寄存器,设置硬件参数(如UART应设置其波特率,AD/DA设备应设置其采样速率等);;c7v*)a+Q&O2t0_3B$V B,| 全球最大的中文电子开发论坛b.将中断服务程序入口地址写入中断向量表:8I%3:w.T4W电子开发论坛+%P,l:y1G06D 全球最大的中文电子开发论坛/* 设置中断向量表 */电子论坛,电子设计论坛,电子开发论坛:4H2x3X!?/w)A4w&A!p)Jm_myPtr = make_far_pointer(0l); /* 返回void far型指针void far * */ 全球最大的中文电子开发论坛H7D*P(H,C(p._:h!Zm_myPtr += ITYPE_UART; /* ITYPE_UART: uart中断服务程序 */+8)G.a;2V+h0J 全球最大的中文电子开发论坛/* 相对于中断向量表首地址的偏移 */0hf,w-Y1j+电子论坛,电子设计论坛,电子开发论坛*m_myPtr = &UART _Isr; /* UART _Isr:UART的中断服务程序 */ -s7n(M$|&u6Q电子论坛,电子设计论坛,电子开发论坛)S6Y(Hp-F(V+R*q%B;Q电子论坛,电子设计论坛,电子开发论坛(3)设置CPU针对该硬件的控制线*Y4W(o.X$L*B/X 全球最大的中文电子开发论坛k&M+R:t9g0J8M$is+x)d电子开发论坛a.如果控制线可作PIO(可编程I/O)和控制信号用,则设置CPU内部对应寄存器使其作为控制信号;9b3r!v,r&$f,8电子开发论坛*J8F-_)t7u8Sb.设置CPU内部的针对该设备的中断屏蔽位,设置中断方式(电平触发还是边缘触发)。电子论坛,电子设计论坛,电子开发论坛9B1A0U0x8|3U%t+C+Y$W 全球最大的中文电子开发论坛|2sY,X8(4)提供一系列针对该设备的操作接口函数。例如,对于LCD,其驱动模块应提供绘制像素、画线、绘制矩阵、显示字符点阵等函数;而对于实时钟,其驱动模块则需提供获取时间、设置时间等函数。电子论坛,电子设计论坛,电子开发论坛3w7$H.Gi.c$K%l.I4?6#2电子开发论坛C的面向对象化&F%O/u0R5I(v9E 全球最大的中文电子开发论坛电子论坛,电子设计论坛,电子开发论坛7D8S/m7Q;4O9Y9o在面向对象的语言里面,出现了类的概念。类是对特定数据的特定操作的集合体。类包含了两个范畴:数据和操作。而C语言中的struct仅仅是数据的集合,我们可以利用函数指针将struct模拟为一个包含数据和操作的

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论