想了解更多关于开源的内容,请访问:51CTO 开源基础软件社区https://ost.51cto.com本文简要介绍对比基于linux内核开发PWM平台驱动的方案,在平台驱动开发完成后可以合入HDF框架作为Openharmony底层驱动方案,之前写完驱动GPIO方案LINUX驱动基础以及合入openharmony的文章后有同学问其他的外设怎么合入,有没有更简单易用的方法开发陌生的linux开发板和系统,本章接着介绍PWM接口技术,以及设备树构造技术来进行简单解析。
在常用的芯片中对应不同的寄存器,但是核心逻辑还是在于TMR寄存器和PR寄存器,例如在STM32中预置器寄存器又叫做TIMx_ARR定时器重载控制器,需要读者仔细甄别。寄存器具体作用方式如下:首先在定时器以PWM模式工作时会将计数器计数模式设置为向上计数模式,并使能计时器。(此处为示意代码)。// 将定时器设置为PWM模式
TMRx->CCP |= TMR_CCP_PWM;
// 设置计数模式为向上计数模式
TMRx->CON &= ~TMR_CON_CM_MASK;
TMRx->CON |= TMR_CON_CM_UP;
// 使能定时器
TMRx->CON |= TMR_CON_TEN;// 设置定时器的时钟分频系数
TMRx->PSC = prescaler_value;
// 设置PWM周期的长度
TMRx->PR = period_value;
// 设置PWM波形的占空比
TMRx->PWM = pulse_value;// 启动定时器
TMRx->CON |= TMR_CON_TEN;// 定义定时器TMRx
struct meson_pwm *pwm_dev = (struct meson_pwm *)PWM_BASE;
// 计算PWM周期和占空比的值
uint32_t period_value;
uint32_t pulse_value;
period_value = PWM_CLOCK_RATE / 4000 - 1; // PWM周期 = PWM时钟频率 / 频率 - 1
pulse_value = period_value / 2; // PWM波形的占空比 = Pulse / (Period + 1)
// 配置PWM时钟频率
pwm_dev->pre_divider = 0; // PWM时钟频率 = 24MHz / (2 * (pre_divider + 1))
pwm_dev->divider = 0;
// 配置PWM输出通道
pwm_dev->enables = 1 << PWM_CHANNEL; // 使能PWM输出
pwm_dev->hi_time[PWM_CHANNEL] = pulse_value;
pwm_dev->lo_time[PWM_CHANNEL] = pulse_value;
// 启动PWM输出
pwm_dev->config = 1; // 启动PWM输出#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>
#define DRIVER_NAME "my_pwm_driver" // 驱动程序名称
static struct pwm_device *pwm_dev; // PWM设备指针
static int duty_cycle_percent = 50; // 占空比(默认50%)
static int my_pwm_driver_probe(struct platform_device *pdev) // 驱动程序的probe函数
{
struct device *dev = &pdev->dev;
struct pwm_args args; // PWM参数结构体
args.period = 1000000; // PWM周期(1ms)
args.duty_cycle = 500000; // PWM占空比(50%)
args.polarity = PWM_POLARITY_NORMAL; // PWM极性
// 请求PWM设备,返回PWM设备指针
pwm_dev = pwm_request(dev, 0, DRIVER_NAME);
if (IS_ERR(pwm_dev)) { // 如果请求PWM设备失败
dev_err(dev, "Failed to request PWM device\n"); // 打印错误信息
return PTR_ERR(pwm_dev); // 返回错误码
}
pwm_init(pwm_dev, &args); // 初始化PWM设备
pwm_enable(pwm_dev); // 启用PWM设备
return 0; // 返回成功
}
static int my_pwm_driver_remove(struct platform_device *pdev) // 驱动程序的remove函数
{
pwm_disable(pwm_dev); // 关闭PWM输出
pwm_free(pwm_dev); // 释放PWM设备
return 0; // 返回成功
}
static struct platform_driver my_pwm_driver = { // 平台驱动程序结构体
.probe = my_pwm_driver_probe, // 驱动程序的probe函数
.remove = my_pwm_driver_remove, // 驱动程序的remove函数
.driver = {
.name = DRIVER_NAME, // 驱动程序名称
},
};
module_platform_driver(my_pwm_driver); // 注册平台驱动程序
MODULE_LICENSE("GPL"); // 许可证信息
MODULE_DESCRIPTION("PWM driver for my platform"); // 驱动程序描述信息$ make
$ insmod my_pwm_driver.komy_pwm_device {
compatible = "my_pwm_driver"; //关键的设备树配置 需要和驱动中的驱动名一致
};
pwm_ef : pwm@86c0 {
compatible ="amlogic,meson8-pwm","amlogic,meson8b-pwm";
reg=<0x86c0 0x10>;
#pwm-cells =<3>;
status ="disabled";
} //完整的设备树配置pwm1: pwm@f0038000 {
compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm"; // 兼容性字符串
reg = <0x0 0xf0038000 0x0 0x4000>; // PWM控制器寄存器地址和大小
interrupts = <0x0 0x38 0x4>; // PWM控制器的中断号
clocks = <0x1 0x7d>; // PWM控制器的时钟
clock-names = "ipg"; // PWM控制器时钟名称
#pwm-cells = <0x2>; // 每个PWM单元包含两个细胞
pinctrl-names = "default"; // 引脚控制器名称
pinctrl-0 = <0x41>; // 引脚控制器配置编号
};$ echo 1 > /sys/class/pwm/pwmchip0/export
$ echo 5000000 > /sys/class/pwm/pwmchip0/pwm0/period
$ echo 2500000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle
$ echo 1 > /sys/class/pwm/pwmchip0/pwm0/enable#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>
static struct pwm_device *pwm_dev;
static int __init my_pwm_init(void)
{
int ret;
struct platform_device *pdev;
struct pwm_args args = {
.period = 1000000, // 1MHz
.duty_cycle = 500000, // 50% duty cycle
};
// 创建一个平台设备
pdev = platform_device_alloc("my_pwm_device", -1);
if (!pdev) {
printk(KERN_ERR "Failed to allocate platform device\n");
return -ENOMEM;
}
// 注册平台设备
ret = platform_device_add(pdev);
if (ret) {
printk(KERN_ERR "Failed to add platform device\n");
goto err_free_device;
}
// 获取PWM设备
pwm_dev = pwm_request(0, "my_pwm_driver");
if (IS_ERR(pwm_dev)) {
ret = PTR_ERR(pwm_dev);
printk(KERN_ERR "Failed to request PWM device: %d\n", ret);
goto err_remove_device;
}
// 配置PWM设备
ret = pwm_apply_args(pwm_dev, &args);
if (ret) {
printk(KERN_ERR "Failed to apply PWM arguments: %d\n", ret);
goto err_free_pwm;
}
// 使能PWM输出
ret = pwm_enable(pwm_dev);
if (ret) {
printk(KERN_ERR "Failed to enable PWM device: %d\n", ret);
goto err_free_pwm;
}
printk(KERN_INFO "PWM driver loaded successfully\n");
return 0;
err_free_pwm:
pwm_free(pwm_dev);
err_remove_device:
platform_device_unregister(pdev);
err_free_device:
platform_device_put(pdev);
return ret;
}
static void __exit my_pwm_exit(void)
{
// 禁用PWM输出
pwm_disable(pwm_dev);
// 释放PWM设备
pwm_free(pwm_dev);
// 移除平台设备
platform_device_unregister(pwm_dev->chip->pdev);
printk(KERN_INFO "PWM driver unloaded successfully\n");
}
module_init(my_pwm_init);
module_exit(my_pwm_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Example PWM driver");$ echo 0 > /sys/class/pwm/pwmchip0
$ echo 0 > /sys/class/pwm/pwmchip2$ echo 1 > /sys/class/pwm/pwmchip0/pwm0/enabled
$ echo 0 > /sys/class/pwm/pwmchip0/pwm0/enabled$ echo 10000000 > /sys/class/pwm/pwmchip0/pwm0/period$ echo 5000000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle$ echo normal > /sys/class/pwm/pwmchip0/pwm0/polarity
$ echo inversed > /sys/class/pwm/pwmchip0/pwm0/polarity
## 代码实现版本-实现简单呼吸灯
详细代码见附件
```C
//接口函数如下
int init_pwm(int channel);
int set_period(int channel,int period); //设置周期
int set_duty_cycle(int channel,int dutycycle); //设置高电平
int set_pwm_polarity(int channel, int polarity); //设置极性
int set_enable(int channel,int enable_s); //使能状态uint32 T = 1600; // 周期(脉冲宽度)
uint32 i=0,m=0,n=0,t=0;
pwm1ES= 1; // 输出使能
pwm1AT = 1; // 灭
while (1)
{
for (i=0;i<T;i++)
{
pwm1AT = 0; // 亮
for (m=0;m<t;m++);
pwm1AT = 1; // 灭
for (n=0;n<T-t;n++);
t++;
if (t >= T)
{
for (i=0;i<T;i++)
{
pwm1AT = 0; // 亮
for (m=0;m<t;m++);
pwm1AT = 1; // 灭
for (n=0;n<T-t;n++);
t--;
}
}
}
}按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。问题1)我想知道rubyonrails是否有功能类似于primefaces的gem。我问的原因是如果您使用primefaces(http://www.primefaces.org/showcase-labs/ui/home.jsf),开发人员无需担心javascript或jquery的东西。据我所知,JSF是一个规范,基于规范的各种可用实现,prim
本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01 客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02 数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit
Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图
我想开始使用“Sinatra”框架进行编码,但我找不到该框架的“MVC”模式。是“MVC-Sinatra”模式或框架吗? 最佳答案 您可能想查看Padrino这是一个围绕Sinatra构建的框架,可为您的项目提供更“类似Rails”的感觉,但没有那么多隐藏的魔法。这是使用Sinatra可以做什么的一个很好的例子。虽然如果您需要开始使用这很好,但我个人建议您将它用作学习工具,以对您来说最有意义的方式使用Sinatra构建您自己的应用程序。写一些测试/期望,写一些代码,通过测试-重复:)至于ORM,你还应该结帐Sequel其中(imho
Linux操作系统——网络配置与SSH远程安装完VMware与系统后,需要进行网络配置。第一个目标为进行SSH连接,可以从本机到VMware进行文件传送,首先需要进行网络配置。1.下载远程软件首先需要先下载安装一款远程软件:FinalShell或者xhell7FinalShellxhell7FinalShell下载:Windows下载http://www.hostbuf.com/downloads/finalshell_install.exemacOS下载http://www.hostbuf.com/downloads/finalshell_install.pkg2.配置CentOS网络安装好
文章目录一基础定义二创建逻辑卷2-1准备物理设备2-2创建物理卷2-3创建卷组2-4创建逻辑卷2-5创建文件系统并挂载文件三扩展卷组和缩减卷组3-1准备物理设备3-2创建物理卷3-3扩展卷组3-4查看卷组的详细信息以验证3-5缩减卷组四扩展逻辑卷4-1检查卷组是否有可用的空间4-2扩展逻辑卷4-3扩展文件系统五删除逻辑卷5-1备份数据5-2卸载文件系统5-3删除逻辑卷5-4删除卷组5-5删除物理卷六LVM逻辑卷缩容6-1缩容注意事项6-2标准缩容步骤一基础定义LVM,LogicalVolumeManger,逻辑卷管理,Linux磁盘分区管理的一种机制,建立在硬盘和分区上的一个逻辑层,提高磁盘分
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。我一直在Rails上做两个项目,它们运行良好,但在这个过程中重新发明了轮子,自来水(和热水)和止痛药,正如我随后了解到的那样,这些已经存在于框架中。那么基本上,正确了解框架中所有智能部分的最佳方法是什么,这将节省时间而不是自己构建已经实现的功能?从第1页开始阅读文档?是否有公开所有内容的特定示例应用程序?一个特定的开源项目?所有的rails交通?还是完全
如何在Ruby中获取linux系统(这必须适用于Fedora、Ubuntu等)的软件/硬件信息? 最佳答案 Chef背后的优秀人才,拥有一颗名为Ohai的优秀gemhttps://github.com/opscode/ohai以散列形式返回系统信息,例如操作系统、内核、规范、fqdn、磁盘、空间、内存、用户、接口(interface)、sshkey等。它非常完整,非常好。它还会安装命令行二进制文件(也称为ohai)。 关于ruby-如何在Ruby中获取linux系统信息,我们在Stack
我在LinuxMint17.2上。我最近使用apt-getpurgeruby删除了ruby。然后我安装了rbenv然后rbenvinstall2.3.0所以现在,~/.rbenv/versions/2.3.0/bin/ruby存在。但是现在,我无法执行geminstallrubocop。我明白了:$geminstallrubocoprbenv:gem:commandnotfoundThe`gem'commandexistsintheseRubyversions:2.3.0但是我可以~/.rbenv/versions/2.3.0/bin/geminstallrubocop。但是,
我是Ruby和RoR的新手。我有一个带有Ubuntu镜像的干净Linode实例,我想从源代码编译Ruby而不是使用apt-get。我已经在谷歌上搜索了执行此操作的说明,但经过一些尝试后,当我尝试运行一些教程示例时,我不断收到有关缺少zlib和其他一些包的错误。任何人都可以给我详细的说明(或链接),教我如何在从源代码编译Ruby之前安装必要的必备包吗?我的目的是编译Ruby的最新稳定版本,然后安装Rubygems和Rails。提前感谢您的帮助!!! 最佳答案 Thisblogpost涵盖从源代码编译ruby所需的包和安装过程;它引