今天拿板子过来一试,发现在DllMain函数的载入频繁调用,不知什么原因。
关于动态连接库入口点函数:
如果指定了入口点函数,系统在进程或线程载入或卸载DLL时就会调用入口点函数。
可以用来实现简单的初始化及清除任务。
进程载入DLL时:
对于使用了载入时动态连接的程序,DLL通过进程初始化来载入。
对于使用了运行时连接的程序,DLL在调用LoadLibrary或LoadLibraryEx返回前载入。
进程卸载DLL时:
进程终止或者调用了FreeLibrary函数,同时引用计数为0,则DLL被卸载。
但如果进程作为TerminateProcess或TerminateThread函数的结果终止,系统不会调用入口点函数。
至于为什么会一直创建线程和关闭线程,这就不得而知了。(现在认为是没有添加DisableThreadLibraryCalls函数)
流接口函数FMR_Init
使用LocalAlloc函数申请一段堆栈空间,接下来调用FMRadio_Init函数
关于FMRadio_Init函数
这个函数主要调用了两个函数CreateI2CFile和FMRadioI2CWrite,看来所执行的初始化功能会在这两个函数里面。(现注:无非就是初始化一下I 2C )
关于CreateI2CFile函数
这函数使用了CreateFile,具体见代码和MSDN。只执行打开IIC的文件。
关于FMRadioI2CWrite函数
这函数似乎是对IIC的写?
这里用到i 2c /i 2c .h文件里面的一个结构体
I2CParam.chipAddr = FMRADIO_ADDR; //IIC write address
I2CParam.readOrWrite = IIC_WRITE;
I2CParam.count = 1;
reg = (BYTE)((val>>8)&0xff);
data = (BYTE)(val & 0xff);
I2CParam.regAddr = reg;
I2CParam.pData = &data;
最后调用DeviceIoControl函数
在i 2c /i 2c .h #define IOCRL_I2CTRANSMIT 0x00008000
原来上面的I2CParam结构体赋值是为了这函数里面的一个参数,它的赋值方式可能和I 2C 的设置有关。看得还是晕晕的,特别是不知道这DeviceIoControl什么用,传输一个消息(数据什么的)给设备?(现注:没错,就是对设备的操作信息传输)
综上所述,这就是执行整个初始化所做的工作了。具体以后再作分析。
关于ReadSTO函数
到现在我还是不知道什么是STO,这函数所执行的过程和FMRadioI2CWrite有点类似,大可看为在读一个“STO”的东西。这里是读出data的值,打开设备失败或RMXG为0,都属于失败的情况。
关于FMRadio_SetFreq函数
顾名思义是个设置频率的函数,里面有通过一个公式来计算PCNT(不大清楚是什么东西)。和FMRadio_SetPCNT函数有点类似,主要就差别于一个公式的计算,里面定有蹊跷。
就这函数而谈就是把频率写入寄存器,察看R1,R2。(现注:应该就是换算成一个值,写进寄存器,以后就见多了。嗯,就像下面说的那样)
对于PCNT的理解:它是频率在寄存器上的设置,通过换算之后,就是频率在寄存器上的表现。
FMRadio_SetPCNT函数,没有通过公式计算,也就是说它的参数是经过计算之后的。
关于FMRadio_AutoSearch函数
这函数是里面最为复杂的一个函数,里面的流程是根据硬件介绍上的一个流程图来实现的。
(现注:当时记得是在数据手册上有个流程图)
当执行成功,返回值将是它的频率,如果查找失败,它的返回值将是-1。
关于FMR_IOControl函数
今天总算认识了这一个函数,在DeviceIoControl被执行的时候,它就会被调用。这个函数就是执行我们对设备传送消息时,设备对消息的处理。具体的一些实现细节就在硬件说明书里面(比如识别的数据格式等)。
里面有一些宏定义在#include "../wavdev/2410/wavext.h"里面。上面还需要windev.h
收音机的传输是通过I 2C ,所以数据的一些格式全部都是以I 2C 的形式,它没有自己的一套格式(也可以说是和I 2C 一致)。对寄存器的直接操作。收音机的IO操作是间接通过I 2C 的IO操作来实现的。
上面的驱动算是告一个段落。现在的主要任务就是测试驱动的功能,可能要通过应用程序来测试(也许有其他的方法,现在还不知道)。
测试的应用程序布局:
4个功能按钮:
按钮1:play,用于启动收音机。首先应该打开文件,创造线程。
按钮2:autosearch,自动选频。
按钮3:locked,锁定频率。
按钮4:cancel,退出收音机功能。
定义线程运行实现的功能函数。这作为一个线程实现功能的体现。
今天测试了一下,似乎流接口函数还是可以成功相应,但还是没看出做了一些什么实际的意义。也许是缺少一个可以用来运行的线程吧,现在要凭自己想象一下线程要如何安排:
首先,这个线程必须可以运行FMradio_read,(ReadFile)去读取那个芯片,但是单纯这样的读可以使喇叭发出电台的声音吗?看来还有很长的一段路要执行。其中是否要建立缓冲区?接收到缓冲区之后,如何处理这些数据?(传送到哪里?)
上面错误的解释:之前是不熟悉这些,现在有点明了。其实IIC只是传送个控制信号。对于音频的信号传输等方面它是不干涉的。是有另两条线接入芯片WM8753。目前音频的信号处理对我来说将是透明的。只要控制让收音机芯片运行起来就可以了。
关于IIC的流接口初始化函数I 2C _Init(见I 2C 驱动文件)