全志平台boot框架中增加设备驱动过程分析
Posted Jarry_le
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了全志平台boot框架中增加设备驱动过程分析相关的知识,希望对你有一定的参考价值。
在boot启动阶段,大家都知道他的主要目的就是引导uboot,uboot在引导内核,从而让整个系统运作起来。全志的boot阶段,对应平板这一块,它会驱动LCD,显示一些开机LOGO,这个过程很快,也就1-2秒钟的时间。然而对于车载行业应用来说,可能需要再boot阶段做一些事情。比如,机器冷启动,大家都知道android启动时间还是比较长的,那么怎么使得客户能快速的用上倒车影像的功能呢?这就需要动脑筋了。/*****************************************************************************************************/
声明:本博内容均由http://blog.csdn.net/edsam49原创,转载请注明出处,谢谢!
/*****************************************************************************************************/
我们可以肯定的是不能等到系统启动完成,应该在最早我们能控制的地方增加我们的特定代码。倒车影像说白了,就是一个视频信号输入到系统,在LCD上再显示出来的事。但是如果要在boot阶段就把视频输入信号正常的显示在LCD上的话,我们需要做什么呢?
首先,我们需要做倒车信号的检测。倒车信号的检测一般来说都是一个GPIO的高低电平来评判,而直接连接倒车线的IC一般是单片机,单片机处理识别以后再告诉主控芯片,告诉的通道其实也就是控制一个GPIO,主控这边来监控这个GPIO的变化,通常是设置成中断模式来检测。全志平台最方便的就是驱动的高度可配置化,非常灵活。我们可以把倒车检测的GPIO配置放在配置文件里面,也就是sys_config.fex文件里面,放在这里面的话就很灵活,不同项目如果使用的IO脚步一样,轻松一配,不用改boot的代码,相当不错。简单示例代码如下:
[cpp] view plain copy- ret = wBoot_script_parser_fetch("custom_design_cfg", "ReverseCarDetectGPIO", (int *)&gpio_reverse, sizeof(user_gpio_set_t)/4);
- if(!ret)
- gpio_reverse.mul_sel = 0; //set input type
- gpio_handle = wBoot_GPIO_Request(&gpio_reverse, 1);
- if(gpio_handle)
- gpio_value = wBoot_GPIO_Read_One_PIN_Value(gpio_handle, 0);
- if(1 == gpio_value)
- //__inf("Reverse signal come\\n");
- return 1;
- else
- __inf("Not enter reverse!!!\\n");
- return 0;
接下来我们就要做倒车显示处理了。做过全志平台的人都知道,里面有一个TVD的module来负责视频输入信号的处理。那么,我们就需要把TVD给打通。为了日后的管理方便,在boot里面这些驱动也都已经模块化,因此我们也要取其精华,把好的做法延续下去。就是单独做一个模块化的驱动。那怎么说呢?我教你,告诉你我也是从它已有的代码堆里模仿处理的,但是里面还是有几个地方要注意了,不要全抄了啊,免得老师发现你考试的卷子把别人的名字都抄过来了就不好了。
言归正传。搭框架,学样子。在boot1目录下的driver目录里,先增加一个tvd驱动的目录。把drv_de目录下的make.cfg、makefile、config.lds、magic.c先直接copy过来。先把make.cfg修改一下,主要是改名字,基本如下:
[plain] view plain copy- #定义生成的目标文件(输出/本地)
- LTARGET = drv_tvd.drv
- TARGET0 = $(WORKSPACEPATH)/wboot/bootfs/drv_tvd.drv
- TARGET1 = $(LICHEEPATH)/wboot/bootfs/drv_tvd.drv
- TARGET2 = $(SDKROOT)/pack/chips/sun7i/wboot/bootfs/drv_tvd.drv
- LOCALTARGET = __image.axf
Makefile写的比较好适配,不用修改。Config.lds这可得说到说到,哥在里面吃了亏的,当时也是直接拷过来的,后面再多个驱动一起运作的时候,工作不正常,查了半天才想起这个破绽,就是程序的加载地址。说出来了,感觉很容易是不是,没搞懂之前那还真不是太好找。就是0x42960000这一串数字,你得看其他模块的这个对应位置的值是多少,根据driver的大小,留一段给上一个程序。Tvd的如下:
[plain] view plain copy- OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
- OUTPUT_ARCH(arm)
- SECTIONS
- . = 0x42960000;
- EGON2_MAGIC : magic.o(.rodata)
- .text : *(.text) *(.rodata)
- .data : *(.data)
- .bss : *(.bss)
剩下的我们就得改magic.c这个文件了,在这个文件里面也就是依葫芦画瓢了。需要改的就是模块的ID编号,其他就是对应改改函数接口的名字,如下:
[plain] view plain copy- const eGon2_mod_t modinfo =
- 'e','G','o','n','2','d','r','v', //.magic
- 0x01000000, //.version
- EGON2_EMOD_TYPE_DRV_TVD, //.mod id
- 0, //.入口地址,驱动(模块)应该填空
- //.mif
- &DRV_TVD_INIT,
- &DRV_TVD_EXIT,
- &DRV_TVD_OPEN,
- &DRV_TVD_CLOSE,
- &DRV_TVD_READ,
- &DRV_TVD_WRITE,
- &DRV_TVD_IOCTRL,
- &DRV_TVD_Standby
- ;
接下来,我们就该写驱动的实体了吧!也即是magic.c里面的各个函数。在这里可以先都只写一行打印信息,其他为空的函数。
格式就按下面的要求来就好了,如下:
[plain] view plain copy- struct eGon2_drv_func
- int (* eGon2_init )(void );
- int (* eGon2_exit )(void );
- unsigned int (* eGon2_open )(unsigned int mid, void * open_arg );
- int (* eGon2_close )(unsigned int hd );
- unsigned int (* eGon2_read )(void *pdata, unsigned int size, unsigned int n , unsigned int hd );
- unsigned int (* eGon2_write )(const void *pdata, unsigned int size, unsigned int n , unsigned int hd );
- int (* eGon2_ioctl )(unsigned int hd , unsigned int cmd , signed int aux, void *pbuffer);
- int (* eGon2_standby)(unsigned int cmd ,void *pbuffer );
- ;
- //eGon2里用到的模块数据结构,里面区分了是一个驱动还是一个应用
- typedef struct _eGon2_mod_section
- char magic[8]; //MAGIC字符,用于标识是eGON2的驱动/应用代码
- unsigned int version; //版本数字
- unsigned int mod_id; //模块的ID,每个elf都应该有一个模块ID,不论驱动还是应用,且各不相同
- int (*main)(int argc, char **argv); //pcb里第一个任务的首地址
- struct eGon2_drv_func demo_func; //驱动函数列表,列出了驱动所必要的7个函数
- eGon2_mod_t;
然后编译一下整个模块,可以加到boot的整体编译里面,也就是在boot目录下的Makefile 里面增加一行 “make -Cboot1/driver/drv_tvd -j8”即可。这样make一下,就会去编译这个新增加的模块,编译没有问题就会有一个二进制文件出来。
这样整个驱动模块的框架是已经搭建好了。可以在bootmain里面去调用这个驱动了。加载驱动也是用的boot框架代码里支持的wBoot_driver_install("c:\\\\drv_tvd.drv");, 当然还有其他ioctl,close这些接口,就不详细在此描述。本文只是重点讲述模块的生成。关于模块的使用,已经TVD怎么工作的,显示控制怎么管理,笔者计划在下一篇文章中再做叙述,敬请关注。
以上是关于全志平台boot框架中增加设备驱动过程分析的主要内容,如果未能解决你的问题,请参考以下文章
全志H3 uboot传参到内核分析,boot.scr文件分析
全志D1开发板 XR829蓝牙 Can‘t get device info: No such device 自我分析及解决方案