面试嵌入式测试的准备总结

总结

第一段:声明和定义
定义为创建了一个对象并为这个对象分配了内存,声明并没有分配内存。
第二段:关键字
auto ---编译器在缺省时,默认定义变量是auto类型
register ---最快的关键字,请求编译器尽可能的将变量存在CPU内部寄存器中,不需要通过内存寻址访问。所以            无法使用&取地址符访问该寄存器类型变量。
static ---- 作用一:修饰变量,变量分为局部变量和全局变量。static定义局部变量,变量被存入全局区,在哪            个函数体内被定义就只能在哪个函数体内使用。当这个函数体结束时变量也不会被释放。
            修饰全局变量,变量存入全局区,它作用是声明该变量只能被本文件使用。
            作用二:修饰函数,该函数不能被其它文件调用。这样就不用担心该函数是否会和其它文件内函数重             名。
            static体验如下,实现动态输出。不过整个过程还需要定时器实现。

void fun(void)
{
   static int a=1;
   switch (a)
   {  case 1: printf("lele fly ren");break;
      case 0: printf("lele     ren");break;

   }
   a=!a;

}

   这里再扩展程序内存管理部分
   内存分配给程序的存储区有如下几种:
   1、栈 stack --- 它是存储局部变量
   2、堆  ---  内存分配方式是链表
   3、静态区 ---   存储全局变量和静态变量,又分为已初始化的静态区和未初始化的静态区
   4、文字常量区 --- 常量和字符串放在这里
   5、程序代码区 ---  存放函数体二进制代码

sizeof ----
const ----- 给所修饰的值加上只读属性。这个关键字一位管理员说过如下一句话。在程序界摸爬了几年要是还没有弄明白这个,那就是
            悲哀。(我汗颜,我曾经是悲哀,现在应该不是了。)
            const 关键字告诉你一些很重要的信息,比如判定输入参数和输出参数。大多数输入参数都不希望被改所以用const限定。
           
            const int a;   限定变量a只读
            int const a;   限定变量a只读
            const int *a;  限定*a只读
            int * const a; 限定a只读
            int const * a const; a只读,*a也只读

volatile---- C语言编译器会对用户书写的代码进行优化,譬如如下代码:

             int a,b,c;
             a = inWord(0x100); /*读取I/O空间0x100端口的内容存入a变量*/
             b = a;
             a = inWord (0x100); /*再次读取I/O空间0x100端口的内容存入a变量*/
             c = a;
           很可能被编译器优化为:

             int a,b,c;
             a = inWord(0x100); /*读取I/O空间0x100端口的内容存入a变量*/
             b = a;
             c = a;
           但是这样的优化结果可能导致错误,如果I/O空间0x100端口的内容在执行第一次读操作后被其它程序写入新值,则其实第2次读             操作读出的内容与第一次不同,b和c的值应该不同。在变量a的定义前加上volatile关键字可以防止编译器的类似优化,正确的             做法是:

             volatile int a;
           volatile变量可能用于如下几种情况:

           (1) 并行设备的硬件寄存器(如:状态寄存器,例中的代码属于此类);

           (2) 一个中断服务子程序中会访问到的非自动变量(也就是全局变量);

           (3) 多线程应用中被几个任务共享的变量。

第三段 指针和数组

int *string=NULL;和 *string=NULL;两者的区别。
int *string=NULL; 定义一个 指针,指向的内存里存储的整型数据,同时将该指针初始化为0x00
*string=NULL; 将该指针所指向的内存里的数据初始化为NULL。
func()
{
   int *p;
   printf("%p,%p,%d",&p,p,*p);
   *p=NULL;
   printf("%p,%p,%d",&p,p,*p);
}
你可以两次输出看到地址相同,数据不同。&p的结果和p的结果不同。&p得到的是指针本身的地址,p里面存放的是指针变量里存放的地址,也就是指针变量所指向的地址。

数组的首地址和数组首元素的首地址
当我们定义一个数组a时,编译器根据指定的元素个数和元素的类型分配确定大小的一块内存,并把这块
内存的名字命名为a。
sizeof(a)的值为sizeof(int)*5
sizeof(a[0])的值为sizeof(int)
sizeof(&a[0])的值为 一个指针变量分配内存的值
sizeof(&a)的值为 一个指针变量分配的内存值
定义一个数组a[20], a理解为指向数组a[20]内存区的首地址的指针。&a 就是取该指针的地址。

指针与数组之间的瓜葛
访问一个内存可以以指针的模式和下标的模式。 两种模式相互迷惑,其实只是两件衣服而已。


第四段 嵌入式C语言的涉略

软件结构是软件的灵魂!结构混乱的程序面目可憎,调试、测试、维护、升级都极度困难。

一个高尚的程序员应该是写出如艺术作品般程序的程序员。(我已经体会到了,被震了一下的感觉)


嵌入式的硬件平台 embedded

Flash ---------------     --------------晶震 crystal oscillator
RAM   --------------- CPU --------------UART
RTC   ---------------     |  --------------键盘控制器
NVRAM ---------------  |  --------------显示控制器
                                 |
                       双端口的RAM 

Flash 用来存储应用程式
RAM 存储数据和指令
实时钟 提供系统时间
NVRAM (非易失去性随机存储器)用来存储重要的setting 。
晶震 提供时钟信号(触发器,逻辑运算)
UART Universal Asynchronous Receiver/Transmitter,通用异步接收/发送装置

嵌入式系统需要良好的软件开发环境的支持,由于嵌入式系统的目标机资源受限,不可能在其上建立庞大、复杂的开发环境,
因而其开发环境和目标运行环境相互分离。因此,嵌入式应用软件的开发方式一般是,在宿主机(Host)上建立开发环境,
进行应用程序编码和交叉编译,然后宿主机同目标机(Target)建立连接,将应用程序下载到目标机上进行交叉调试,
经过调试和优化,最后将应用程序固化到目标机中实际运行。


软件架构
1、模块的划分,一个.h的头文件和.c的文件组成了一个模块。头文件是对于该模块接口的声明。
2、某模块提供给其它模块调用的外部函数及数据需在.h文件中冠以extern关键字声明。
3、模块内的函数和全局变量需要在.c文件开头冠以static关键字声明。
4、不要在头文件里定义变量。

单任务程序典型架构

  (1)从CPU复位时的指定地址开始执行;

  (2)跳转至汇编代码startup处执行;

  (3)跳转至用户主程序main执行,在main中完成:

  a.初试化各硬件设备;

  b.初始化各软件模块;

  c.进入死循环(无限循环),调用各模块的处理函数

 在某项目的开发中,我们设计了一个队列,在中断服务程序中,只是将中断类型添加入该队列中,
在主程序的死循环中不断扫描中断队列是否有中断,有则取出队列中的第一个中断类型,进行相应处理。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值