• / 9
  • 下载费用:10 金币  

linux-pwm-framework(1)-简介和api描述.docx

关 键 词:
linux pwm framework 简介 api 描述
资源描述:
LINUXPWMFRAMEWORK1_简介和API描述作者WOWO发布于201510111545分类通信类协议HTTP//WWWWOWOTECHNET/COMM/PWM_OVERVIEWHTML1前言PWM是PULSEWIDTHMODULATION(脉冲宽度调制)的缩写,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,其本质是一种对模拟信号电平进行数字编码的方法。在嵌入式设备中,PWM多用于控制马达、LED、振动器等模拟器件。PWMFRAMEWORK是KERNEL为了方便PWMDRIVER开发、PWM使用而抽象出来的一套通用API,之所以要分析该FRAMEWORK,原因如下1)PWM接口,本质上一种通信协议,和I2C、SPI、USB、WIFI等没有任何差别。因此,本文将会是KERNEL通信协议有关FRAMEWORK的分析文章的第一篇。2)它太简单了但是,虽然简单,思路却大同小异,因而非常适合做第一篇。3)我计划整理显示子系统的分析文章,而PWM,是显示子系统中最基础的那一个。闲话少说,言归正传2软件框架及API汇整PWMFRAMEWORK非常简单,但它同样具备FRAMEWORK的基本特性对上,为内核其它DRIVER(CONSUMER)提供使用PWM功能的统一接口;对下,为PWMDRIVER(PROVIDER)提供DRIVER开发的通用方法和API;内部,抽象并实现公共逻辑,屏蔽技术细节。下面我们通过它所提供的API,进一步认识PWMFRAMEWORK。21向PWMCONSUMER提供的APIS对CONSUMER而言,关注PWM的如下参数1)频率PWM的频率决定了所模拟出来的模拟电平的平滑度,通俗的讲,就是逼真度。不同的模拟器件,对期待的频率是有要求的,因此需要具体情况具体对待。另外,人耳能感知的频率范围是20HZ16KHZ,因此要注意PWM的频率不要落在这个范围,否则可能会产生莫名其妙的噪声。2)占空比占空比,决定了一个周期内PWM信号高低的比率,进而决定了一个周期内的平均电压,也即所模拟的模拟电平的电平值。3)极性简单的说,一个PWM信号的极性,决定了是高占空比的信号输出电平高,还是低占空比信号输出电平高。假设一个信号的占空比为100,如果为正常极性,则输出电平最大,如果为翻转的极性,则输出电平为0。4)开关控制PWM信号是否输出。基于上述需求,LINUXPWMFRAMEWORK向CONSUMER提供了如下API1/INCLUDE/LINUX/PWMH/23/4PWM_CONFIGCHANGEAPWMDEVICECONFIGURATION5/6INTPWM_CONFIGSTRUCTPWM_DEVICEPWM,INTDUTY_NS,INTPERIOD_NS78/9PWM_ENABLESTARTAPWMOUTPUTTOGGLING10/11INTPWM_ENABLESTRUCTPWM_DEVICEPWM1213/14PWM_DISABLESTOPAPWMOUTPUTTOGGLING15/16VOIDPWM_DISABLESTRUCTPWM_DEVICEPWM1718/19PWM_SET_POLARITYCONFIGURETHEPOLARITYOFAPWMSIGNAL20/21INTPWM_SET_POLARITYSTRUCTPWM_DEVICEPWM,ENUMPWM_POLARITYPOLARITYPWM_CONFIG,用于控制PWM输出信号的频率和占空比,其中频率是以周期(PERIOD_NS)的形式配置的,占空比是以有效时间(DUTY_NS)的形式配置的。PWM_ENABLE/PWM_DISABLE,用于控制PWM信号输出与否。PWM_SET_POLARITY,可以更改PWM信号的极性,可选参数包括NORMAL(PWM_POLARITY_NORMAL)和INVERSED(极性翻转,PWM_POLARITY_INVERSED)两种。上面的API都以STRUCTPWM_DEVICE类型的指针为操作句柄,该指针抽象了一个PWM设备(CONSUMER不需要关心其内部构成),那么怎么获得PWM句柄呢使用如下的API注1本文只介绍基于DTS的、新的PWMREQUEST系列接口,对于那些旧接口,让它随风而去吧。1/INCLUDE/LINUX/PWMH/23STRUCTPWM_DEVICEPWM_GETSTRUCTDEVICEDEV,CONSTCHARCON_ID4STRUCTPWM_DEVICEOF_PWM_GETSTRUCTDEVICE_NODENP,CONSTCHARCON_ID5VOIDPWM_PUTSTRUCTPWM_DEVICEPWM67STRUCTPWM_DEVICEDEVM_PWM_GETSTRUCTDEVICEDEV,CONSTCHARCON_ID8STRUCTPWM_DEVICEDEVM_OF_PWM_GETSTRUCTDEVICEDEV,STRUCTDEVICE_NODENP,9CONSTCHARCON_ID10VOIDDEVM_PWM_PUTSTRUCTDEVICEDEV,STRUCTPWM_DEVICEPWMPWM_GET/DEVM_PWM_GET,从指定设备(DEV)的DTS节点中,获得对应的PWM句柄。可以通过CON_ID指定一个名称,或者会获取和该设备绑定的第一个PWM句柄。设备的DTS文件需要用这样的格式指定所使用的PWMDEVICE(具体的形式,还依赖PWMDRIVER的具体实现,后面会再介绍)BLBACKLIGHT{PWMSPWMNAMES“BACKLIGHT“}如果“CON_ID”为NULL,则返回DTS中“PWMS”字段所指定的第一个PWMDEVICE;如果“CON_ID”不为空,如是“BACKLIGHT”,则返回和“PWMNAMES”字段所指定的NAME对应的PWMDEVICE。上面“PWMS”字段各个域的含义如下1)16STRUCTLIST_HEADLIST17CONSTSTRUCTPWM_OPSOPS18INTBASE19UNSIGNEDINTNPWM2021STRUCTPWM_DEVICEPWMS2223STRUCTPWM_DEVICEOF_XLATESTRUCTPWM_CHIPPC,24CONSTSTRUCTOF_PHANDLE_ARGSARGS25UNSIGNEDINTOF_PWM_N_CELLS26BOOLCAN_SLEEP27}DEV,该PWMCHIP对应的设备,一般由PWMDRIVER对应的PLATFORM驱动指定。必须提供OPS,操作PWM设备的回调函数,后面会详细介绍。必须提供NPWM,该PWMCHIP可以支持的PWMCHANNEL(也可以称作PWMDEVICE由STRUCTPWM_DEVICE表示)个数,KERNEL会根据该NUMBER,分配相应个数的STRUCTPWM_DEVICE结构,保存在PWMS指针中。必须提供PWMS,保存所有PWMDEVICE的数组,KERNEL会自行分配,不需要DRIVER关心。BASE,在将该CHIP下所有PWMDEVICE组成RADIXTREE时使用,只有旧的PWM_REQUEST接口会使用,因此忽略它吧,编写PWMDRIVER不需要关心。OF_PWM_N_CELLS,该PWMCHIP所提供的DTSNODE的CELL,一般是2或者3,例如为3时,CONSUMER需要在DTS指定PWMNUMBER、PWMPERIOD和PWMFLAG三种信息(如21中的介绍);为2时,没有FLAG信息。OF_XLATE,用于解析CONSUMER中指定的、PWM信息的DTSNODE的回调函数(如21中介绍的,PWMS)。注2一般情况下,OF_PWM_N_CELLS取值为3,或者2(不关心极性),OF_XLATE则可以使用KERNEL提供的OF_PWM_XLATE_WITH_FLAGS(解析OF_PWM_N_CELLS为3的CHIP)或者OF_PWM_SIMPLE_XLATE(解析OF_PWM_N_CELLS为2的情况)。具体的DRIVER可以根据实际情况修改上述规则,但不到万不得已的时候,不要做这种非标准的、掏力不讨好的事情(有关OF_XLATE的流程,会在下一篇流程分析的文章中介绍。)CAN_SLEEP,如果OPS回调函数中,CONFIG,ENABLE或者DISABLE操作会SLEEP,则要设置该变量。222PWMOPSSTRUCTPWM_OPS结构是PWMDEVICE有关的操作函数集,如下1/2STRUCTPWM_OPSPWMCONTROLLEROPERATIONS3REQUESTOPTIONALHOOKFORREQUESTINGAPWM4FREEOPTIONALHOOKFORFREEINGAPWM5CONFIGCONFIGUREDUTYCYCLESANDPERIODLENGTHFORTHISPWM6SET_POLARITYCONFIGURETHEPOLARITYOFTHISPWM7ENABLEENABLEPWMOUTPUTTOGGLING8DISABLEDISABLEPWMOUTPUTTOGGLING9DBG_SHOWOPTIONALROUTINETOSHOWCONTENTSINDEBUGFS10OWNERHELPSPREVENTREMOVALOFMODULESEXPORTINGACTIVEPWMS11/12STRUCTPWM_OPS{13INTREQUESTSTRUCTPWM_CHIPCHIP,14STRUCTPWM_DEVICEPWM15VOIDFREESTRUCTPWM_CHIPCHIP,16STRUCTPWM_DEVICEPWM17INTCONFIGSTRUCTPWM_CHIPCHIP,18STRUCTPWM_DEVICEPWM,19INTDUTY_NS,INTPERIOD_NS20INTSET_POLARITYSTRUCTPWM_CHIPCHIP,21STRUCTPWM_DEVICEPWM,22ENUMPWM_POLARITYPOLARITY23INTENABLESTRUCTPWM_CHIPCHIP,24STRUCTPWM_DEVICEPWM25VOIDDISABLESTRUCTPWM_CHIPCHIP,26STRUCTPWM_DEVICEPWM27IFDEFCONFIG_DEBUG_FS28VOIDDBG_SHOWSTRUCTPWM_CHIPCHIP,29STRUCTSEQ_FILES30ENDIF31STRUCTMODULEOWNER32}这些回调函数的操作对象是具体的PWMDEVICE(由STRUCTPWM_DEVICE类型的指针表示),包括CONFIG,配置PWMDEVICE的频率、占空比。必须提供ENABLE/DISABLE,使能/禁止PWM信号输出。必须提供REQUEST/FREE,不再使用。SET_POLARITY,设置PWM信号的极性。可选,具体需要参考OF_PWM_N_CELLS的定义。223PWMDEVICESTRUCTPWM_DEVICE是PWMDEVICE的操作句柄,CONSUMER的API调用,会中转到PROVIDER的PWMOPS回调函数上,PROVIDER(及PWMDRIVER)根据PWMDEVICE的信息,进行相应的寄存器操作。如下1STRUCTPWM_DEVICE{2CONSTCHARLABEL3UNSIGNEDLONGFLAGS4UNSIGNEDINTHWPWM5UNSIGNEDINTPWM6STRUCTPWM_CHIPCHIP7VOIDCHIP_DATA89UNSIGNEDINTPERIOD/INNANOSECONDS/10UNSIGNEDINTDUTY_CYCLE/INNANOSECONDS/11ENUMPWM_POLARITYPOLARITY12}PWMDRIVER比较关心的字段是HWPWM,该PWMDEVICE对应的HARDWAREPWMNUMBER,可用于寄存器的寻址操作。PERIOD、DUTY_CYCLE、POLARITY,PWM信号的周期、占空比、极性等信息。224PWMCHIP_ADD/PWMCHIP_REMOVE初始化完成后的PWMCHIP可以通过PWMCHIP_ADD接口注册到KERNEL中,之后的事情,PWMDRIVER就不用操心了。该接口的原型如下1INTPWMCHIP_ADDSTRUCTPWM_CHIPCHIP2INTPWMCHIP_REMOVESTRUCTPWM_CHIPCHIP3API使用指南31CONSUMER使用PWM的步骤基于21章节描述的API,可以得到PWMCONSUMER(如PWMBACKLIGHTDRIVER)使用PWMFRAMEWORK的方法和步骤如下1)查看PWMPROVIDER所提供的PWMDTSBINDING信息(一般会在“DOCUMENTATION/DEVICETREE/BINDINGS/PWM”目录中),并以此在该DEVICE所在的DTSNODE中添加“PWMS”以及“PWMNAMES”相关的配置。例如/ARCH\ARM\BOOT\DTS\IMX23EVKDTS/BACKLIGHT{COMPATIBLE“PWMBACKLIGHT“PWMSBRIGHTNESSLEVELSDEFAULTBRIGHTNESSLEVEL}其中,REGCLOCKSPWMCELLSFSL,PWMNUMBERSTATUS“DISABLED“}/ARCH\ARM\BOOT\DTS\IMX23EVKDTS/PWMPWM80064000{PINCTRLNAMES“DEFAULT“PINCTRL0STATUS“OKAY“}2)定义一个PWMCHIP变量3)注册相应的PLATFORMDRIVER,并在DRIVER的PROBE接口中,初始化PWMCHIP变量,至少要包括如下字段DEV,使用PLATFORMDEVICE中的DEV指针即可;NPWM;OPS,至少包括CONFIG、ENABLE、DISABLE三个回调函数。如果该PWMCHIP支持额外的FLAG(如PWM极性,或者自定义的FLAG),将PWMCELL指定为3(OF_PWM_N_CELLS),OF_XLATE指定为OF_PWM_XLATE_WITH_FLAGS。初始化完成调用PWMCHIP_ADD接口,将CHIP添加到KERNEL中。4)每当CONSUMER有API调用时,KERNEL会以PWMDEVICE为参数,调用PWMDRIVER提供的PWMOPS,相应的回调函数可以从PWMDEVICE中取出PWMNUMBER(该NUMBER的意义DRIVER自行解释),并操作对应的寄存器即可。原创文章,转发请注明出处。蜗窝科技,WWWWOWOTECHNET。标签LINUXDRIVERPWM«ARM64的启动过程之(二)创建启动阶段的页表|ARM64的启动过程之(一)内核第一个脚印»评论LINUX_ROCK201702241852楼主,你好。我在DTS中加了一个PWM控制风扇FANFAN{COMPATIBLE“PWMFAN“PWMS//PWMNAMES“PWMFAN“}但驱动中用DEVM_PWM_GET每次都获取不到PWM结构体指针,但背光那个却可以PBPWMDEVM_PWM_GETPBDEV,NULLIFIS_ERRPBPWM{DEV_ERRPBDEV,“UNABLETOREQUESTPWM,TRYINGLEGACYAPI\N“RETPTR_ERRPBPWMGOTOERR_GPIO}回复WOWO201702242236LINUX_ROCK跟一下代码吧,总能找到原因的回复MODULE_LICENSE201706052252LINUX_ROCK请问您找到问题的原因了么,我虽然没有碰到,但很好奇。回复LINUX_ROCK201706061012MODULE_LICENSE}应该把PWM1打开的,一开始没有打开,所以获取不到PWM结构体指针回复MODULE_LICENSE201706061600LINUX_ROCK非常感谢您的共享回复MYWAY201702080852博主你好,我想问一下,PWM驱动是从哪里获取到GPIO信息的回复WOWO201702080959MYWAY如果是标准的实现的话,当然是从PINCTRLSUBSYSTEM了,例如/ARCH\ARM\BOOT\DTS\IMX23EVKDTS/PWMPWM80064000{PINCTRLNAMES“DEFAULT“PINCTRL0STATUS“OKAY“}只要把PINCTRL配好,哪个PWM从哪个GPIO出,就固定了。回复LINUX_EMB201512241730麻雀虽小,五脏俱全。回复USHINEME201510311115啊呀呀呀,要整理显示子系统了吗,我就是刚毕业在一个手机公司学习LCD的驱动,好期待回复WOWO201510311213USHINEME是在准备,不过还没有开始呢,最近事情比较多,就耽搁了。回复USHINEME201510311618WOWO嗯嗯,知道啦,我会慢慢等的回复发表评论
展开阅读全文
  麦档网所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
0条评论

还可以输入200字符

暂无评论,赶快抢占沙发吧。

关于本文
本文标题:linux-pwm-framework(1)-简介和api描述.docx
链接地址:https://www.maidoc.com/p-1583.html

当前资源信息

t****e

编号: 20180301224643996582

类型: 共享资源

格式: DOCX

大小: 56.87KB

上传时间: 2018-03-01

关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

[email protected] 2018-2020 maidoc.com版权所有  文库上传用户QQ群:3303921 

麦档网为“文档C2C模式”,即用户上传的文档所得金币直接给(下载)用户,本站只是中间服务平台,本站所有文档下载所得的金币归上传人(含作者)所有。
备案号:蜀ICP备17040478号-3  
川公网安备:51019002001290号 

本站提供办公文档学习资料考试资料文档下载


收起
展开