本帖最后由 wuliangu 于 2024-10-22 17:28 编辑
#申请原创#@21小跑堂
《iCatch学习笔记》如何点亮一盏LED灯? 也许对于接触过或会编程的人而言,不就是点亮一盏LED的事,这也太简单了吧!没必要拿出来说了吧?但是对于不会的、没接触过的、没实践过的初学者来说,这是有必要来了解下的,因为好多事情自己先去了解了或经别人提示了,这样才会有方向的去摸索,才不会多走弯路,所以会节约一些学习时间,增加学习效率。作者个人在网上没有找到这方面的资料,所以也是自己摸索着去学习。因个人理解有限,不足之处还请指出,同时希望通过这个笔记,能够对人有所帮助。 好了,这里所用的硬件是iCatch的V39M主控芯片(CPU为单核ARM Cortex-A7),所要实验的IO口是LMI27,如下图(一):
图(一)
LMI27这个IO口要配置成高电平时才能将LED灯点亮。那么在软件中究竟要怎么配置这个IO呢? 问题抛出了,那就要拿一个SDK来实际操作,不过在操作前我们还是先来看看这SDK的资源结构。我们拿到SDK解压出来的第一层文件夹里面包含的内容如下图(二):
图(二) sphost : 这个文件夹中包含主机应用程序源文件,程序的编译就是在这个文件夹中进 行的。 tool : 这个文件夹里面包含构建 SPCA 5K basefw 的所有工具, 在改软件时可以先不用管。 tool.linux : 这个文件夹里面包含的是linux相关的工具,在改软件时可以先不用管。 v37 : 这个文件夹里面放的是v37系列硬件平台相关的SPCA 5K basefw资源。 V39M芯片用的就是V37的资源。 readme : 这个是说明文件,里面有编译时怎么输入命令的说明。
下面我们再进入sphost目录下看看,如图(三):
图(三) sphost目录下有编译时需要用到的config.sh和makefile文件,对软件如何编译我在《初学iCatch方案的软件编译》链接:https://bbs.21ic.com/icview-3398084-1-1.html 这篇文章中有说明。 sphost目录下的“_WDV4K37”文件夹是经过./config.sh wdv4k37命令后所生成的。用USB来烧录的文件就在这个文件夹中,其目录为\sphost\_WDV4K37\download,双击该目录下的“FRM”文件就可以进行烧录了。烧录界面如下图(四):
图(四) (注:烧录前要将PGPIO10这个IO引脚拉低再插USB到电脑上,这样才能进入USB烧录模式。)
customization : 默认主机源代码。 include : 默认主机包含文件。 lib : 库的源代码。 linker_script : 工具链的链接器脚本,客户不应修改。 project : 项目定义。 resource : 主机资源文件。
SDK的资源结构暂时了解上面这些,知道在哪里编译,我们用到的程序源文件大概在哪里就可以了。 先奔着点亮一盏LED的目标去了解。 V39M的软件架构是消息驱动类架构,其基本框架如下图(五):
图(五)
初步了解了SDK的结构后,我们再来了解下这程序的运行过程是怎么样的?这里用source Insight工具来打开SDK软件,进去一看就有点眼花和摸不着头脑了,感觉也太复杂了吧!惯性思维首先是找main函数,如下图(六):
图(六)
不好意思!main函数虽然找到了,但从串口信息上来看,这main函数程序是在第151行出现的,说明程序不是从这个main函数开始运行的。
图(七)
这里插一句:我们在看程序运行情况时可以在相应的地方加上打印信息,若串口信息上有打印,则说明程序跑到了这里,哪个信息优先出现则说明那个是先跑的。再者是在程序中搜索打印信息的关键字,看在哪个打印函数里出现。
程序中能找到的main函数就是下面如图(八)这些,但都不是程序入口。
图(八)
下图(九)是程序开始时的信息,
图(九)
在程序中我能追溯到的是第4行,这个打印信息是在\sphost\customization\arch\v37目录下的dev_init.c文件中添加的,如图(十):
图(十)
再前面就追溯不到了,猜可能是在底层封装了,所以看不到1到3行的打印信息。不过不要紧,对初学而言能追溯到这里也可以了,不必再花时间深究。
我们学一个东西,最快的方法是模仿/复制/理解再到自主,所以还是打开例程先看下别人是怎么点灯的。 如图(十一)和图(十二)中是LED灯控制定义的走向,
图(十一)
图(十二)
点LED灯的功能实现是在\sphost\customization\hostfw\device路径下的app_led.c文件中,头文件app_led.h是在\sphost\customization\hostfw\include目录下。 在app_led.c文件中实现了灯的打开和关闭,还有灯的闪烁功能。从控制定义的走向图中可以看出,点亮一盏灯所涉及的文件有:app_led.c , app_led.h, gpio_custom_wdv4k.h,app_gpio_HW_WDV4K_V37.h, ap5k_global_api.h, global_def.h 。它们是通过#define层层定义转化,最终实现所需功能。 另外如下图(十三)是点亮LED的IO输出定义,
图(十三)
我们可以在\sphost\customization\drivers\io目录下的HW_WDV4K_V37.io文件中进行IO输出的配置,如我们要在这里用LMI27这个IO口来点亮红灯,所以在文件中就可以写上“LED_RED out lmi 27 1 ”,表示LMI27这个IO输出高电平。
下面就来实际操作一遍吧。 首先,在app_led.c文件中添加好要点亮的是红LED灯的函数,如图(十四): 分打开和关闭两部分。
图(十四)
其次,对一下图(十一)和图(十二)中的定义走向, 看下哪部分没有RED灯相关的,如gpio_custom_wdv4k.h这个文件中没有“#define LED_RED_ON IO_LED_RED_SET(1)”这行的话,那就要我们自己补上这行。相关实现函数基本上这些在程序中是做好的了,我们要做的就是在程序中的哪部分放上RED_LED_ON或RED_LED_OFF这两句来打开或关闭LED,然后在HW_WDV4K_V37.io这个文件中配置使用的是哪个IO来实现这个功能。 最后,进行编译烧录验证。 下图(十五)是闪灯的函数RED_LED_FLICKER(a),a的单位是毫秒,表示灯按多少毫秒来闪,若想要闪灯, 就将这函数添加到相应的位置就是了。
图(十五)
总结:在实验中只要在HW_WDV4K_V37.io这个文件中配置好了IO的输出,那么系统一上电LED就会被点亮了。在实验一上电就让LED闪的过程中发现,将LED闪烁函数放在dev_init.c这个文件中时,编译时会出错,如下图(十六):
图(十六)
在dev_init.c文件中加上头文件#include”app_led.h”后又会报如下错误: make: *** 没有规则可制作目标“_WDV4K37/_v37/customization/arch/v37/dev_init.d”,由“_WDV4K37/_v37/customization/arch/v37/dev_init.o” 需求。 停止。 这个错误不是现在能够处理得了的,毕竟才刚学,而本次学习的目的是能点亮LED灯就可以了,这个涉及到config或makefile的相关知识,只能是以后再来探究了。 既然闪烁程序放在dev_init.c中不行,那就放在其它文件中吧,后面咨询了下同事,说放在app_video_view.c这个文件中,所以这里将函数放在这个文件下的 UINT32 _VideoCheckDiskReady(void); 函数中,这样就可以实现闪灯了。当然,放在其它地方也有实现的。重点是要放在IO初始化完成之后的地方。
前面也说到这种软件架构是消息驱动型的,所以对这方面的知识欠缺也是对理解这些功能的实现有所影响。 再者还是需要多练多查看代码,因为每一次的接触都会有新的理解,对于一时不懂的,当下次来看时说不定就顿悟了。 谢谢观阅!
|
从硬件到软件,逐行代码讲解如何在iCatch的V39M主控芯片上点亮一颗LED灯