查看: 3942|回复: 3

[分享] 【经验分享】PE生成的代码模块使用架构分析

[复制链接]

该用户从未签到

145

主题

4926

帖子

0

金牌会员

Rank: 6Rank: 6

积分
9267
最后登录
1970-1-1
发表于 2014-3-6 12:49:36 | 显示全部楼层 |阅读模式
本帖转自网名为 wangpengcheng 的网友。
当我第一次用PE生成了一个MDK工程的时候,发现这个东西的架构有点绕,好在也总算整明白了!这里以IO模块为例,发点心得:

1、模块注册
每个模块都有一个初始化函数 ,以IO口为例,它的初始化函数定义如下:
LDD_TDeviceData* Bit1_Init(LDD_TUserData *UserDataPtr)
{
  /* Allocate device structure */
  Bit1_TDeviceDataPtr DeviceDataPrv;
  /* {MQXLite RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */
  DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC;

  DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */

  /* Configure pin as output */
  /* GPIOE_PDDR: PDD|=1 */
  GPIOE_PDDR |= GPIO_PDDR_PDD(0x01);                                   

  /* Set initialization value */
  /* GPIOE_PDOR: PDO&=~1 */
  GPIOE_PDOR &= (uint32_t)~(uint32_t)(GPIO_PDOR_PDO(0x01));                                   

  /* Initialization of Port Control register */
  /* PORTE_PCR0: ISF=0,MUX=1 */
  PORTE_PCR0 = (uint32_t)((PORTE_PCR0 & (uint32_t)~(uint32_t)(
                PORT_PCR_ISF_MASK |
                PORT_PCR_MUX(0x06)
               )) | (uint32_t)(
                PORT_PCR_MUX(0x01)
               ));                                 
  /* Registration of the device structure */
  PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_Bit1_ID,DeviceDataPrv);
  return ((LDD_TDeviceData *)DeviceDataPrv);
}

这个函数的参数LDD_TUserData *UserDataPtr是定义了一个指针,这个指针的作用是引入一个用户数据的指针,一般用于MQXLite系统中,用来传递的是用户的一些参数,这是一种面向对像的使用方法,等到后面我们再分析他的用法。我们在初始化函数中可以找到下面的一行代码:
PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_Bit1_ID,DeviceDataPrv);
在此行代码中PE_LDD_COMPONENT_Bit1_ID是一个常量,而DeviceDataPrv是函数开头定义的一个 Bit1_TDeviceDataPtr 型的指针,并把一个static的变量DeviceDataPrv__DEFAULT_RTOS_ALLOC的地址赋给了DeviceDataPrv。
我们找到PE_LDD_RegisterDeviceStructure的定义,会发现它其实是一个宏(PE_Type.h):
#define PE_LDD_RegisterDeviceStructure(ComponentIndex, DeviceStructure) (PE_LDD_DeviceDataList[ComponentIndex] = DeviceStructure)
这个宏的意思是将参数中的DeviceDataPrv指针(即static变量DeviceDataPrv__DEFAULT_RTOS_ALLOC的地址)赋给一个指针数组PE_LDD_DeviceDataList的PE_LDD_COMPONENT_Bit1_ID序号的空间内。
也就是说在此函数中,注册的时候将一个指针与PE_LDD_COMPONENT_Bit1_ID常量联系起来,并将指针保存下来,保存下来有什么用呢?我们再看看此模块中其它的应用函数:
void Bit1_SetDir(LDD_TDeviceData *DeviceDataPtr, bool Dir);
void Bit1_SetInput(LDD_TDeviceData *DeviceDataPtr);
bool Bit1_GetVal(LDD_TDeviceData *DeviceDataPtr);
void Bit1_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val);
void Bit1_ClrVal(LDD_TDeviceData *DeviceDataPtr);
void Bit1_SetVal(LDD_TDeviceData *DeviceDataPtr);
在此可以看出来这些应用函数有一个共同的特点,他们的第一个参数都是一个LDD_TDeviceData 型的指针,那么,根据我们刚才分析的初始化函数中的指针保存,我们知道了,在使用这些函数的时候,要把刚才保存的那个指针取出来当作参数传给他们。
既然有保存指针的宏,那么肯定有取出指针的宏,我们依然在PE_Type.h文件中找到这个宏:
#define PE_LDD_GetDeviceStructure(ComponentIndex) (PE_LDD_DeviceDataList[ComponentIndex])
这个宏就是取出指针的宏,到此,我们就知道这些函数都怎么应用了,用PE_LDD_COMPONENT_Bit1_ID常量将指针取出来就是了:
Bit1_SetInput( PE_LDD_GetDeviceStructure(PE_LDD_COMPONENT_Bit1_ID) );

到此,我们就能将这些函数应用起来。当然在我们目前的分析看来,其实没发现这个指针有什么用途,下面我们就来分析此指针的用途。
再回到初始化函数的前几行:
/* Allocate device structure */
  Bit1_TDeviceDataPtr DeviceDataPrv;
  /* {MQXLite RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */
  DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC;

  DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */
我们又看到了UserDataPtr,假如我们在此模块中有一些私有的模块数据定义,那么就可以把它强制转换成LDD_TUserData 型的指针,传给初始化函数,然后通过上面几行代码,我们知道,它会把我们定义的私有模块数据的指针给了
DeviceDataPrv__DEFAULT_RTOS_ALLOC结构体中的UserDataPtr指针,而我们在刚才说明的注册中,已经把DeviceDataPrv__DEFAULT_RTOS_ALLOC保存到一个数组指针中了,在使用的时候可以用PE_LDD_GetDeviceStructure宏再将指针取出来,此时我们应该已经明白了,其实这就是把一个静态的变量用指针分离了出来,在我们后面的编程中,可以在任意的模块中使用DeviceDataPrv__DEFAULT_RTOS_ALLOC结构体中的数组,但又跟它没有关系,因为我们可以随时将DeviceDataPrv__DEFAULT_RTOS_ALLOC结构体中的数据进行改动。

到此我们应该明白了,Bit1_TDeviceDataPtr类型的指针,可以将全局的变量进行分离,定义成每个模块的私有变量,而在使用的时候,可以通过Bit1_TDeviceDataPtr指针找到我们需要的数据,真正实现各个模块的分离,移植性能增强。

 
回复

使用道具 举报

该用户从未签到

16

主题

705

帖子

0

金牌会员

Rank: 6Rank: 6

积分
1745
最后登录
1970-1-1
发表于 2014-3-6 12:53:39 | 显示全部楼层

RE:分享:PE生成的代码模块使用架构分析

感谢网友的分享!
回复 支持 反对

使用道具 举报

  • TA的每日心情
    开心
    2018-7-23 21:04
  • 签到天数: 103 天

    连续签到: 1 天

    [LV.6]常住居民II

    228

    主题

    5379

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    16702
    最后登录
    1970-1-1
    发表于 2015-6-19 13:05:48 | 显示全部楼层
    多谢分享,学习了
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    4

    主题

    239

    帖子

    0

    高级会员

    Rank: 4

    积分
    673
    最后登录
    2018-6-8
    发表于 2016-2-19 16:31:38 | 显示全部楼层
    多谢分享
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-22 12:58 , Processed in 0.084746 second(s), 22 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表