加嵌入式C语言概述.ppt_第1页
加嵌入式C语言概述.ppt_第2页
加嵌入式C语言概述.ppt_第3页
加嵌入式C语言概述.ppt_第4页
加嵌入式C语言概述.ppt_第5页
已阅读5页,还剩32页未读 继续免费阅读

下载本文档

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

文档简介

嵌入式C语言概述,变量定义的时机,for (loop=1;loop=limit;loop+) for (loop=limit;loop!=0;loop-),目录,任务和模块 中断服务程序 数据指针 数据指针 函数指针 动态内存申请 关键字volatile,多任务还是单任务,(1)从CPU复位时的指定地址开始执行; (2)跳转至汇编代码startup处执行; (3)跳转至用户主程序main执行,在main中完成: a.初试化各硬件设备; b.初始化各软件模块; c.进入死循环(无限循环),调用各模块的处理函数,模块划分,(1) 模块即是一个.c文件和一个.h文件的结合,头文件(.h)中是对于该模块接口的声明; (2) 某模块提供给其它模块调用的外部函数及数据需在.h中文件中冠以extern关键字声明; (3) 模块内的函数和全局变量需在.c文件开头冠以static关键字声明; (4) 永远不要在.h文件中定义变量!定义变量和声明变量的区别在于定义会产生内存分配的操作,一个嵌入式系统通常包括两类模块: (1)硬件驱动模块,一种特定硬件对应一个模块; (2)软件功能模块,其模块的划分应满足低偶合、高内聚的要求,中断服务程序,_interrupt、#program interrupt等,中断服务程序需要满足如下要求: (1)不能返回值; (2)不能向ISR传递参数; (3) ISR应该尽可能的短小精悍; (4) printf(char * lpFormatString,)函数会带来重入和性能问题,不能在ISR中采用。,一个硬件驱动模块通常应包括如下函数: (1)中断服务程序ISR (2)硬件初始化 a.修改寄存器,设置硬件参数(如UART应设置其波特率,AD/DA设备应设置其采样速率等); b.将中断服务程序入口地址写入中断向量表:,(3)设置CPU针对该硬件的控制线 a.如果控制线可作PIO(可编程I/O)和控制信号用,则设置CPU内部对应寄存器使其作为控制信号; b.设置CPU内部的针对该设备的中断屏蔽位,设置中断方式(电平触发还是边缘触发)。 (4)提供一系列针对该设备的操作接口函数。例如,对于LCD,其驱动模块应提供绘制像素、画线、绘制矩阵、显示字符点阵等函数;而对于实时钟,其驱动模块则需提供获取时间、设置时间等函数。,数据指针,函数指针,数组vs.动态申请,在嵌入式系统中动态内存申请存在比一般系统编程时更严格的要求,这是因为嵌入式系统的内存空间往往是十分有限的,不经意的内存泄露会很快导致系统的崩溃。 所以一定要保证你的malloc和free成对出现,,谁申请,就由谁释放,而函数function则接收参数p,如下:,关键字volatile,volatile变量可能用于如下几种情况: (1) 并行设备的硬件寄存器(如:状态寄存器,例中的代码属于此类); (2) 一个中断服务子程序中会访问到的非自动变量(也就是全局变量); (3) 多线程应用中被几个任务共享的变量。,1 使用宏定义 在C语言中,宏是产生内嵌代码的唯一方法。,#define MIN(A,B) (A)= (B) ? (A) : (B) ) /为什么使用宏,不用函数?,2 使用寄存器变量,register是一个“建议“型关键字,3 内嵌汇编,_asm ,其它常用手段,4 利用硬件特性 CPU内部RAM 外部同步RAM 外部异步RAM FLASH/ROM,5 活用位操作,/* 方法1 */ int i,j; i = 879 / 16; j = 562 % 32; /* 方法2 */ int i, j; i = 879 4; j = 562 - (562 5 5);,#define INT_I2_MASK 0x0040 wTemp = inword(INT_MASK); outword(INT_MASK, wTemp ,其它常见问题,汉字和图形的显示 菜单的处理 动画的处理 键盘的处理 时间的处理,II ARM中C和汇编混合编程,1.汇编举例 2.ARM程序组织 3.在C语言中内嵌汇编 5 在C中调用汇编的函数 4.在汇编中使用C定义的全局变量 6.在汇编中调用C的函数,AREA init,CODE,READONLY CODE32 Mode_USR EQU 0x10 ;CPSR中各种处理器模式对应的控制位 I_Bit EQU 0x80 ;CPSR中的中断禁止位 F_Bit EQU 0x40 USR_Stack EQU 0x00203000 ;定义RAM的最高地址,无重映射 ENTRY B InitReset ; 0x00 Reset handler undefvec B undefvec ; 0x04 Undefined Instruction swivec B swivec ; 0x08 Software Interrupt pabtvec B pabtvec ; 0x0C Prefetch Abort dabtvec B dabtvec ; 0x10 Data Abort rsvdvec B rsvdvec ; 0x14 reserved irqvec B irqvec ; 0x18 IRQ fiqvec B fiqvec ; 0x1c FIQ,InitReset MSR CPSR_c,#Mode_USR | I_Bit | F_Bit ;改成用户模式且禁止IRQ和FIQ中断 LDR SP,=USR_Stack BLX _main ;跳转到_main执行,它,例2,3.在C语言中内嵌汇编,内嵌汇编使用的标记是 _asm或者asm关键字,用法如下: _asm instruction ; instruction instruction asm(“instruction ; instruction”);,内嵌汇编注意点,a. 不能直接向PC寄存器赋值,程序跳转要使用B或者BL指令 b. 在使用物理寄存器时,不要使用过于复杂的C表达式,避免物理寄存器冲突 c. R12和R13可能被编译器用来存放中间编译结果,计算表达式值时可能将R0到R3、R12及R14用于子程序调用,因此要避免直接使用这些物理寄存器 d. 一般不要直接指定物理寄存器,而让编译器进行分配,#include void my_strcpy(const char *src, char *dest) char ch; _asm loop: ldrb ch, src, #1 strb ch, dest, #1 cmp ch, #0 bne loop int main() char *a = “forget it and move on!“; char b64; my_strcpy(a, b); printf(“original: %s“, a); printf(“copyed: %s“, b); return 0; ,内嵌汇编举例,C和汇编之间的值传递是用C的指针来实现的, 因为指针对应的是地址,所以汇编中也可以访问。,4在汇编中使用C定义的全局变量,/* cfile.c * 定义全局变量,并作为主调程序 */ #include int gVar_1 = 12; extern asmDouble(void); int main() printf(“original value of gVar_1 is: %d“, gVar_1); asmDouble(); printf(“ modified value of gVar_1 is: %d“, gVar_1); return 0; ,;called by main(in C),to double an integer, a global var defined in C is used. AREA asmfile, CODE, READONLY EXPORT asmDouble IMPORT gVar_1 asmDouble ldr r0, =gVar_1 ldr r1, r0 mov r2, #2 mul r3, r1, r2 str r3, r0 mov pc, lr END,5在C中调用汇编的函数,一是在C中声明函数原型,并加extern关键字; 二是在汇编中用EXPORT导出函数名,并用该函数名作为汇编代码段的标识,最后用mov pc, lr返回。然后,就可以在C中使用该函数了,例:在C中调用汇编的函数,/* cfile.c * in C,call an asm function, asm_strcpy * Sep 9, 2004 */ #include extern void asm_strcpy(const char *src, char *dest); int main() const char *s = “seasons in the sun“; char d32; asm_strcpy(s, d); printf(“source: %s“, s); printf(“ destination: %s“,d); return 0; ,;asm function implementation AREA asmfile, CODE, READONLY EXPORT asm_strcpy asm_strcpy loop ldrb r4, r0, #1 ;address increment after read cmp r4, #0 beq over strb r4, r1, #1 b loop over mov pc, lr END,ATPCS(ARM Thumb Procedure Call Standard),C和汇编之间的参数传递是通过ATPCS(ARM Thumb Procedure Call Standard)的规定来进行的。简单的说就是如果函数有不多于四个参数,对应的用R0-R3来进行传递,多于4个时借助栈,函数的返回值通过R0来返回。,ATPCS是基于arm指令集和thumb指令集过程调用的规范。,ATPCS寄存器的使用规则,寄存器的使用必须满足下面的规则: 1. 子程序间通过寄存器R0 R3来传递参数,这时,寄存器R0R3可以记作A1-A4。被调用的子程序在返回前无需恢复寄存器R0-R3的内容。 2. 在子程序中,使用寄存器R4 R11来保存局部变量这时,寄存器R4-R11可以记作V1-V8。如果在子程序中使用到了寄存器V1-V8中的某些寄存器,子程序进入时必须保存这些寄存器的值,在返回前必须恢复这些寄存器的值;对于子程序中没有用到的寄存器则不必进行这些操作。在Thumb程序中,通常只能使用寄存器R4-R7来保存局部变量。 3. 寄存器R12用作子程序间scratch寄存器(用于保存SP,在函数返回时使用该寄存器出栈),记作ip。在子程序间的连接代码段中常有这种使用规则。 4. 寄存器R13用作数据栈指针,记作sp。在子程序中寄存器R13不能用作其他用途。寄存器sp在进入子程序时的值和退出子程序时的值必须相等。 5. 寄存器R14称为连接寄存器,记作lr。它用于保存子程序的返回地址。如果在子程序中保存了返回地址,寄存器R14则可以用作其他用途。 6. 寄存器R15是程序计数器,记作pc。它不能用作其他用途。,6在汇编中调用C的函数,在汇编中调用C的函数,需要在汇编中IMPORT 对应的C函数名,然后将C的代码放在一个独立的C文件中进行编译,剩下的工作由连接器来处理。,例:在汇编中调用C的函数,;the details of parameters transfer comes from ATPCS ;if there are more than 4 args, stack will be used EXPORT asmfil

温馨提示

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

评论

0/150

提交评论