当前位置:首页 > 嵌入式C
  • MMU,cache,裸机嵌入式C编程还有带操作系统的编程

     通过CMSIS-utrealos项目中的CTBUG调试,使我对裸机C编程加深了认识。那个BUG调试,现象是出现hard fault,但是fault出现地的汇编指令看着貌似没啥问题,解决一处的fault后,其他处又出现fault了。最后我看到原来是fault出现地的指令中源地址错误了,源地址应该在数据段中,却意外地落到了代码段中。这个现象我忙活了半天才找到。 然后通过看那奇怪的源地址,对照它四周的现象代码,最终才发现是我的demo C文件中的头文件包含错误了(这个错误显然易见,但是在review代码时却没发现)。导致该问题指令的那个源地址计算错误,落到了代码段中。 调试时间花了不少,最后这段调试经历使我对裸机C编程发生了兴趣,从而认真读了armcm3编程权威指南一书。 还有王SAN那个栈溢出调试,王SAN本来还想研究是否是内存分配方面的错误,但是和我最后讨论后,结果用arm权威指南及我们组项目笔记文章中的那个栈溢出调试方法,很快就找出BUG原因了。 我的那个BUG调试告诉我ARMCM3上没有MMU那种保护功能,也没有操作系统(linux操作系统中的那种开启MMU保护以及虚存访问权限检查的功能这里没有)。虽然有MPU,但是这个是可选器件。 linux下的MMU及虚存保护,使得我们PC机编程中,可以不用C指针时,及时将其置为空从而起到保护程序的作用,但是回到裸机下,尤其没MMU部件时,空指针的作用意义在这里都消失了。这也就是嵌入式编程的复杂性。 但是通过嵌入式编程,尤其王san那个BUG调试,毕竟能加深对C编程底层调试的认识。比如现在嵌入式调试,可以直接通过观看内存地址处的数据信息是否异常,各个汇编指令和cpu寄存器值变化是否异常,嵌入式调试使人真正回到了二进制时代。 不可否认,MMU和虚拟存储的设计,真正简化了上层程序的设计,提供给用户一个好的开发应用程序的界面。详情见uclinux与linux的不同一文。 但是由于MMU的存在必要,这延缓了CPU访问内存的速度。为了解决这一问题,又带来cache,还有TLB(之前作linux性能检证搞过TLB的性能分析一文可以参考)。而ARM CM3中没有这一切,毕竟cortex-m3和A5的应用范围是不同的。

    时间:2018-06-20 关键词: mmu cache 嵌入式c

  • 嵌入式C实现延时程序的不同变量的区别

    在嵌入式系统中,延时是经常需要使用的一种手段,延时的方法可以通过使用类似于"NOP"的指令来实现,但是如果延时的时间比较 长,如果使用太多的"NOP"指令则会消耗过多的储存空间,最好的方法是使用子程序(汇编语言中)或子函数(高级语言中)。当然这里并不打算讨论如果使用 定时器中断来实现延时。下面就在C语言中使用子函数实现延时的几个问题做些讨论,当然讨论高级语言的延时就需要考虑编译器和处理器,这里为了讨论的方便, 而且不失一般性,可以用标准51单片机作处理器和uVision2作为编译环境,晶振为12MHz,这样一个标准的机器周期即为1uS。其他的情况则可以据此类推。先看一段延时程序:其中Delay1()与Delay2()两者的型参类型不同。将上述的Delay1(100)(变量为unsignedint类型)或Delay2(100)(变量为unsignedchar类型)分别在两次过程中执行,便会得到了下述的执行结果:断点B减去断点A的时间为810uS,这个时间即为执行Delay1(100)所花费的时间;断点B减去断点A的时间为608uS,这个时间即为执行Delay2(100)所花费的时间;由此可见,作为unsignedint变量类型来传递延时函数的参数,会增长延时的时间,而使用unsignedchar变量类型则会得到短的延时时 间。我们都知道C语言经过编译后是要转化成汇编语言的,只有汇编语句才有精确的执行时间,所以要知道这两者结果的不同,原因就在于他们经过编译之后汇编语 句的不同的地方。

    时间:2018-06-15 关键词: 嵌入式开发 嵌入式系统 51单片机 uvision2 嵌入式c

发布文章

技术子站