Microchip公司16位单片机dsPIC33E/PIC24E系列bootloader的开发(1)

Mikael Gustafsson开 发的bootloader支持Microchip公司8位/16位/32位单片机全系列产品,只可惜到了最新70MHz的dsPIC33E/PIC24E 系列以后,就不再开源,并且开始收费了。如果你决定自己开发一款用在dsPIC33E/PIC24E单片机上的bootloader,我的这系列篇文章将 会给您提供非常好的参考。首先,让我从剖析Mikael Gustafsson的“ds30 Loader”入手。

  1. Bootloader入门:
    Bootloader可以被成为自加载程序,简而言之就是自己对自己编程。bootloader本身就是一段存储在单片机flash中的固件。但不同的 是,bootloader只做一件固定的事情——接受用户的应用代码固件,并将其存放在空余的flash中。除此以外,bootloader不做其他任何 事情,甚至可以被视作不存在。一个含有bootloader的单片机运行起来和不含bootloader、直接通过编程器烧制固件的单片几乎完全一样。对 于bootloader而言,体积小是起码的要求,因为bootloader多少占用你的闪存空间。Bootloader的另一大优势是免去了必须要编程 器烧制固件的麻烦,你只需要第一次用编程器烧制bootloader,之后就可以通过bootloader来烧制新的固件了。当然这也对 bootloader的可靠性提出了非常高的要求——bootloader要保证不会把自己给删除了。
  2. bootloader放在哪里:
    网上对于bootloader的架构有很多不同的见解。“ds30 Loader”这类的产品将bootloader放在闪存区的尾部,而Microchip给出的设计参考“AN1094 – Bootloader for dsPIC30F/33F and PIC24F/24H Devices”则选择紧接着中断向量表的闪存开始部分存放bootloader。我个人倾向于“ds30 Loader”的架构,因为使用闪存尾部的做法无须应用固件开发工程师对开发环境(IDE)进行特殊配置。

    BL1_no_bootloader_cn

    图1. 不含bootloader的单片机闪存使用情况。编译器从最开头可用的空间用起。当芯片启动的时候GOTO指令将引导系统读取用户应用程序。

    BL1_microchip_bootloader_cn

    图2.将bootloader至于闪存头部的设计架构。严格地说,bootloader并非是置于最最前部。因为“GOTO指令”和“RESET地 址”以及中断向量表(IVT,interrupt vector table)处于闪存的最前部,接下来才是用户可用空间。一般而言,这种设计将bootloader放在第二个编程区(program block / erase block)中。因此编译器必须通过配置知道第二编程区已经被占用需要空出。这种设计的另一个缺点是第一编程区(即包含GOTO,RESET以及IVT的 区)未被使用的部分也被浪费了。因为flash在擦除的时候是按照区位做小单位的。第一区有GOTO,RESET和IVT,不得不必须跳过,在接下来的第 二区放置bootloader。同样的道理,第二区有空余也不能被其他程序使用。(注,IVT后面空出来的一区其余闪存可以通过修改复杂的编译器设置来使 用,这里不详述)

    BL1_my_preferred_bootloader_cn

    图3. 将bootloader置于闪存尾部的设计架构。这样的话,编译器按照寻常的做法,从头开始使用flash空间,无需特别配置。当然,对于被 bootloader占用的那块编程区余下部分,则依旧只能浪费。当然你要确保你的应用程序不至于太长(绝大部分情况下是不会发生的)而覆盖掉位于尾端的 bootloader。

至于如何将bootloader烧制到flash中,没办法,这时候你只能用一次编程器,不过你只需要这次用一下它,接下来bootloader就开始帮你烧制固件了。

不要离开,我的下一篇文章将和你深入探讨理解Microchip单片机的二进制hex代码规范

如何手工焊接QFN封装的表面贴片芯片(含视频教程)

首先来看一段视频,一步一步来演示如何手焊QFN封装的芯片!(放大可以看到高清效果)

QFN封装的芯片管脚间隔最小可以达到0.5毫米。更糟糕的是,QFN正如其名所示(no-lead),没有金属管脚伸出来,唯一可以指望的是芯片壁上的引脚盘。

QFN64_dimension

但是即便是这样,手焊照样可以!下面我就用图片和视频来解释一下如何手焊QFN小封装的芯片。

  1. PCB设计时注意事项:
    为了焊接时方便,建议将PCB的管脚稍微向外延长些,这样有足够的的空间可以让焊烙铁接触到。如下图所示,我将管脚略向外延伸0.71毫米左右就足够了。

    QFN64_footpring

  2. 手工焊接QFN封装原则:
    需要记住的是,手焊QFN封装的时候并不是要一个管脚挨一个管脚地焊,因为这也几乎不可能。而是利用助焊剂,让融化的焊锡自然地流到管脚上,焊锡的表面张 力会让焊锡在管脚间自然分开。然后如果焊锡送得太多,还是有可能会把几个管脚焊在一起。这种情况下用焊烙铁或者吸焊带移去多余的焊锡即可。

最后看一下焊接之前和焊好之后的对比:
QFN_before_and_after

把LG Thrill P925裸眼3D摄像头延长到手机外,以及真机拆解图

有一个十分有趣的项目需要将LG Thrill P925的3D裸眼摄像头延伸到手机以外,并要求其依旧能够工作。这有可能吗?就好象是把眼珠子掏出来放到老远的地方……然后你还能继续通过这副眼睛看东西……

LG_extension_watermark

Impossible is nothing!关键就在于能否掏出那个3D摄像头然后延长他的电缆线,接下来就说说我是怎么做的。

1. 一台全新的LG Thrill P925手机,背面装有双摄像头,各500万象素的3D裸眼摄像头,能够摄制立体3D图像:

LG_thrill_back

2. 打开电池仓露出硕大的3.7V锂电池。然后使用#00尺寸的十字螺丝刀旋开塑料壳上的螺丝:

LG_thrill_battery_back

3. 首先取下的是位于机身下方的扬声器模块,因为该模块整个压在塑料壳上:

LG_thrill_speaker

4. 扬声器模块取下以后就很容易可以取下塑料壳:

LG_thrill_unscrewed

5. 打开塑料壳以后,整个手机主板就暴露了出来。可以清晰地看到3D双摄像头垂直地安装在主板中间。摄像头左边是信号/电源接插件;上方压着一个LED作为闪 光灯,供电与控制是从右边过来。摄像头模块的框子是金属做的,LED放在上面正好可以将其作为散热装置使用。那现在看来如果要外置这个摄像头模块,就得想 办法能够延长左边那个接插件。

LG_thrill_stereo_camera_module

6. 翻起LED灯,接下来准备掏出摄像头模块。

LG_thrill_remove_flash

7. 从一侧翻起摄像头模块,这个有一点难度,因为模块底部有胶带,而且模具做得非常紧。

LG_thrill_raise_camera

8. 断开接插件,整个摄像头模块就出来了。

LG_thrill_camera_removed

9. 现在开始真正的挑战来了。摄像头模块取下来了,那如何为它做一跟延长线呢?这根延长线上的插座必须要和手机上现有的匹配。通过一些测量以后不难发现手机主 板和摄像头模块上的接插件规格是40管脚,0.4毫米间隔。可坏消息是寻遍所有店家,均没有相匹配的产品,最后通过LG的维修店了解到这个原装接插件的型 号是 “GB042-40S-H10-E3000”,属LG内部产品……

既然原装的找不到,那索性就买一套不同品牌、但是有相同焊接尺寸的接插件,替代原装的不就行了吗?于是就购买了“DF40C-40DS-0.4V(51)”和“DF40C-40DP-0.4V(51)”这对Hirose产品。

LG_hirose_40_pin_0.4mm_connector

10. 换掉这两个40针、0.4毫米间隔的接插件可不是容易的活,需要一定的焊接、拆焊技术。这里我强烈推荐Chip Quick的拆焊套装“SMD1”。下面的照片已经将主板上的接插件拆掉了。

LG_thrill_camera_connector_removed

11. 再来一张微距照片。尽管我已经十分小心地拆焊,但还是弄伤一个焊盘。不过幸运的是这个焊盘是地(Ground),所以只要从旁边飞一跟线过来就修好了。

LG_thrill_connector_solderpad

12. 把新买的Hirose插座焊上主板倒是要简单很多。

LG_thrill_new_connector_finish

LG_thrill_new_connector

13. 接下来把摄像头模块上的接插件也换成Hirose的。相比主板上的那个,这个也轻松很多。

LG_thrill_stereo_camera_module_separated

14. 主板和摄像头模块上的插座都换好以后,把摄像头插上主板做一下测试,确保摄像头还能继续工作。然后就是真正地要“延长”这个摄像头了。如果可以定做一个 40脚FPC线然两头装上Hirose的接插头,那就十分理想了。但是考虑到定做一个FPC成本太高,对这个试制品,我决定做一块廉价的PCB电路板来做 这个“延长线”。
摄像头端的电路板:

LG_thrill_camera_adapter_circuit

主板端的电路板:

LG_thrill_mother_board_adapter_circuit

15. 将接插件分别焊上两块电路板,下面是成品图。

LG_thrill_mother_board_adapter_2

16. 焊完以后,将电路板插到手机主板上,然后拧紧螺丝保证牢固。下面的图片里可以看到,因为PCB板比较大,我不得不割掉塑料壳的一部分。图中的白色排线是0.5毫米间隔、20针Molex产FPC跳线,跳线的插座是“FPC BackFlip™, Easy-On™”。

LG_thrill_mother_board_adapter

17. 下图是成品的摄像头模块端的电路板。直形FPC插座也是购自Digikey。 你会注意到电路板左端有一排旁路电容,用于为摄像头模块提供稳定的电源。这些电容非常重要,因为当摄像头模块离开了主板以后,原本装在主板上的旁路电容对 摄像头电源的稳定作用越来越小,容易造成像图像感应器这样高速逻辑芯片发生故障。所以必须在离开摄像头近的地方再安装旁路电容。

LG_thrill_camera_adapter_2

LG_thrill_camera_adapter

18. 一切准备就绪,现在把所有的东西连接起来,然后打开电源。现在摄像头就变成外置的了!

LG_thrill_extended_camera_working

那到底延长这个摄像头有何用途呢?看一下下面这张照片:

cell_phone_based_facial_capture_system

《基于智能手机的人脸动画捕捉系统》。http://gl.ict.usc.edu/Research/CellHeadCam/

Microchip 16位 32位单片机 malloc()函数的若干问题

C语言中的malloc()函数用于动态地在内存中分配一块空间来存储数据,对于在程序执行过程中需要动态分配内存的应用来说,这是十分有用的功能。

Microchip的编译器C30(16位单片机)以及C32(32位单片机)在较新的版本中也开始实现了这个函数,这为对RAM本来有些捉襟见肘的单片机编程添加了不少灵活性。不过在实际使用过程中有几个需要注意的地方(以MPLab v8.63为例)。

  1. 需要告知编译器程序中将会使用动态内存分配,不然编译会出错。选项位于 Project -> Build Option -> MPLab xx Link 这个界面里,找到 Heap Size这个框,在旁边输入动态分配可能需要的字节数即可。另外,实际使用中注意到一个现象,就是输入的字节数大小在实际程序的运行中并不能全部分配到, 实际最多只能得到的要比输入的字节数少8个byte的样子,不然malloc返回NULL,即分配空间失败。不知道这是编译器的bug,还是分配空间过程 中的自然损耗。
  2. 程序在第一次分配大空间之前需要“热身”,也就是预分配一次小空间,才能获得设置时设定的最大空间。比如设置时候输入了heap空间为16384 字节(byte),如果跑上来就用malloc函数请求分配这么大的空间,malloc返回NULL,即分配失败。通过反复尝试发现需要在分配大空间之前 先malloc哪怕一个byte的空间,然后在用free释放,再用malloc请求大空间,就不会有任何问题。另外,这里的“大”空间要大到heap空 间输入值的1/2。以上面的16384为例,如果程序一跑上来请求分配小于8192的空间,就不会有“预热身”的需要。