
OpenHarmony PWM Core 原创 精华
PWM Core
在上一篇中中,我们使用到了pwm_if.h,将我们实现的pwm驱动注册到pwm核心层,本文就来介绍这个pwm core是如何实现的,以及这个核心层的作用。
PwmDev
在pwm core中,定义了一个PwmDev,它是对所有pwm外设的一个抽象的描述:
该对象在pwm core中起到承上启下的作用,可以通过PwmMethod对象来调用底层的pwm驱动,实现方波的配置。对于上层,则在驱动的基础上,增加了busy标志以及自旋锁,并封装了对底层驱动服务的订阅操作,简化了内核驱动使用pwm的步骤。(省去了订阅驱动服务)
PWM 核心层接口
在上一篇中,我们会调用PwmDeviceAdd()函数,将我们定义的PWM驱动注册到核心层,其实现是非常简单的:
主要的工作就是初始化自旋锁,以及将pwmdev对象和驱动服务互相绑定。
还记得核心层如何和底层pwm驱动通信吗?我们实现了一个PwmMethod的对象,这个对象会在核心层被频繁的调用,使用该对象里的函数。上一篇中,我们实现了setConfig方法,我们来看在核心层中,它是如何被使用的。具体而言,是在pwm_core.c中的PwmSetConfig():
核心层的其他函数最终也是调用PwmSetConfig()来完成与底层驱动的沟通。
在对上层应用的处理上,核心层引入了PwmOpen()和PwmClose()来限制进程对pwm驱动的并发访问。当一个应用打算使用某一个pwm驱动时,它必须要先调用PwmOpen()来获取pwm驱动的使用权,在使用完成pwm驱动后,应该及时的调用PwmClose()来释放pwm驱动,以免造成资源的长期独占。
这么做的目的是,pwm的使用往往是有严格的时间要求,应用程序必须在这个时间内对pwm完全占有其使用权,否则pwm产生的方波就有可能出现噪声,导致应用出错。
PwmOpen()是如何实现对pwm驱动的独占呢,下面注释给出答案:
通过busy标志,来实现对pwm驱动的互斥使用。这里的自旋锁,是防止在多线程同时访问pwm->busy变量,导致程序出现严重错误。
PwmGetDevByNum()函数实现了对pwm驱动服务的获取。我们在实现芯片的pwm底层驱动时,在配置中,必须将pwm驱动服务的名称设置为“HDF_PLATFORM_PWM_x”,x=0,1,2,3…,这样我们才能正确的接入pwm核心层。通过pwm驱动服务,我们就能获取到PwmDev对象。
PWM Core的优势
以往的stm32编程中,都是直接使用pwm 库函数,为何OpenHarmony要引入一个核心层呢?我们来思考加入这个东西后,有什么优势。
首先就是芯片驱动和设备驱动的解耦。假设我写了一个呼吸灯的驱动程序,它会调用pwm_if.h中的函数,在某一个芯片平台上,它能够正常的运行。这时我要换一个芯片平台,因为有pwm核心层对芯片驱动的解耦,我不需要重新写一个呼吸灯的驱动程序。因为对于呼吸灯驱动来说,它调用的接口都是pwm_if.h,这个文件在所有OpenHarmony系统上都是相同的。只要新的芯片平台实现了底层的pwm驱动,那么我的呼吸灯驱动就能完美的运行。这也是OpenHarmony一次开发,多端部署的体现。
其次是加入了对PWM的互斥访问。单片机程序往往不需要考虑多进程共享访问的问题,而OpenHarmony是一个面向众多设备的操作系统,其有运行环境可能是多线程的。pwm核心层加入互斥锁以及busy变量,能有效的防止互斥访问的问题。
