搜索
bottom↓
回复: 16

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

[复制链接]

出0入0汤圆

发表于 2014-3-5 11:59:41 | 显示全部楼层 |阅读模式
当我第一次用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指针找到我们需要的数据,真正实现各个模块的分离,移植性能增强。

阿莫论坛20周年了!感谢大家的支持与爱护!!

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。

出0入0汤圆

 楼主| 发表于 2014-3-5 12:00:32 | 显示全部楼层
写的有点乱,不明白的可以发问,呵呵!语言组织能力有待提高啊!

出0入0汤圆

发表于 2014-3-6 09:26:29 | 显示全部楼层
楼主辛苦啊,对PE入门的盆友还是很有帮助的!!

出0入0汤圆

 楼主| 发表于 2014-3-6 10:31:40 | 显示全部楼层
FSL_TICS_ZP 发表于 2014-3-6 09:26
楼主辛苦啊,对PE入门的盆友还是很有帮助的!!

用KL、KE芯片的有很多朋友都是从8位机转过来的,C语言都是自己在研究,我碰到好几个客户都是这样,介绍他们用PE,结果他们说看不明白,呵呵

出0入0汤圆

发表于 2014-3-6 10:39:57 | 显示全部楼层
楼主能不能分析一下,使用PE是节省了时间,还是浪费了时间?

出0入0汤圆

 楼主| 发表于 2014-3-6 10:42:53 | 显示全部楼层
ideality0214 发表于 2014-3-6 10:39
楼主能不能分析一下,使用PE是节省了时间,还是浪费了时间?

如果整个公司以后都使用飞思卡尔的平台,那么熟悉一下PE从长远来看,是节省时间的!另外,相对去看全英文的DataSheet,我觉得用PE还是省一点时间,个人感觉!

出0入0汤圆

发表于 2014-3-6 10:49:44 | 显示全部楼层
wangpengcheng 发表于 2014-3-6 10:42
如果整个公司以后都使用飞思卡尔的平台,那么熟悉一下PE从长远来看,是节省时间的!另外,相对去看全英文 ...

确实理解PE的架构后。对以后的软件开发确实节省不少时间及精力,感谢楼主使用飞思卡尔产品,有问题欢迎论坛中讨论!!

出0入0汤圆

发表于 2014-3-19 22:13:38 | 显示全部楼层
学习了           

出0入0汤圆

发表于 2014-6-4 11:19:04 | 显示全部楼层
在使用PE对其生成的代码看都看不懂 看来我C语言水平差到一定水平了

出0入0汤圆

发表于 2014-12-29 15:28:09 | 显示全部楼层
typedef void LDD_TDeviceData;
typedef void* LDD_TDeviceDataPtr;
这两条怎么理解

出0入0汤圆

发表于 2014-12-29 15:30:18 | 显示全部楼层
没用过PE~感谢分享

出0入0汤圆

发表于 2014-12-29 16:43:17 | 显示全部楼层
过来学习PE是怎么用的  

出0入0汤圆

发表于 2014-12-29 17:20:40 | 显示全部楼层
又学习到了

出0入0汤圆

发表于 2014-12-29 19:23:34 | 显示全部楼层
使用PE工具 ,可以快速生成代码

出0入0汤圆

发表于 2014-12-30 12:07:59 来自手机 | 显示全部楼层
模块化的方法,值得学习

出0入0汤圆

发表于 2014-12-30 13:19:39 | 显示全部楼层
xiaowei196964 发表于 2014-12-29 15:28
typedef void LDD_TDeviceData;
typedef void* LDD_TDeviceDataPtr;
这两条怎么理解

试着回答一下:

typedef void LDD_TDeviceData;       //!< 定义一个“void”数据类型,名字叫LDD_TDeviceData
typedef void* LDD_TDeviceDataPtr; //!< 定义一个“void指针”数据类型,名字叫LDD_TDeviceDataPtr

出100入101汤圆

发表于 2015-1-1 15:26:18 | 显示全部楼层
PE使用入门,收藏!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-10-3 00:22

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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