文章目录
- 前言
- [1. 头文件引入](#1. 头文件引入)
- [2. 导出PWM通道 pwm_export](#2. 导出PWM通道 pwm_export)
- [3. 取消导出PWM通道 pwm_unexport](#3. 取消导出PWM通道 pwm_unexport)
- [4. 启用/禁用PWM pwm_enable/pwm_disable](#4. 启用/禁用PWM pwm_enable/pwm_disable)
- [5. 配置周期和占空比 pwm_config](#5. 配置周期和占空比 pwm_config)
- [6. 设置极性 pwm_polarity](#6. 设置极性 pwm_polarity)
- 7.龙芯2K1000适配说明
-
- [7.1 硬件特性](#7.1 硬件特性)
- 7.2关键问题与优化建议
- 7.3完整优化示例
- 7.4应用场景示例
- 8.总结
前言
本文简单介绍了龙芯2k1000中的PWM生成。
1. 头文件引入
c
#include <stdio.h> // 标准输入输出(如printf)
#include <stdlib.h> // 系统调用(如open/close)
#include <time.h> // 时间相关函数(未直接使用)
#include <fcntl.h> // 文件控制选项(如O_WRONLY)
#include <unistd.h> // POSIX API(如write/close)
#include <sys/mman.h> // 内存映射(未直接使用)
作用
作用:提供文件操作和系统调用的基础支持。
2. 导出PWM通道 pwm_export
c
int pwm_export(unsigned int pwm) {
int fd;
// 根据pwm编号选择对应的sysfs路径
if (pwm == 0) {
fd = open("/sys/class/pwm/pwmchip0/export", O_WRONLY);
} else if (pwm == 1) {
fd = open("/sys/class/pwm/pwmchip1/export", O_WRONLY);
} // ... 其他pwm编号类似
if (fd < 0) {
printf("Failed export PWM%d\n", pwm);
return -1;
}
write(fd, "0", 2); // 导出通道0(假设每个pwmchip只有一个通道)
close(fd);
return 0;
}
功能
功能:通过写入export文件激活PWM通道。
关键点
假设每个pwmchip仅支持一个通道(pwm0 )。
写入"0"表示导出该芯片的通道0。
问题
write(fd, "0", 2) 中的长度参数应为1(仅写入字符'0'),多出的\0可能导致内核解析错误。
缺少对pwm参数的合法性检查(如传入pwm=4会导致未定义行为)。
3. 取消导出PWM通道 pwm_unexport
c
int pwm_unexport(unsigned int pwm) {
// 类似pwm_export,操作unexport文件
write(fd, "0", 2); // 取消导出通道0
}
作用
作用:清理已导出的PWM通道。
注意
注意:需与pwm_export配对使用。
4. 启用/禁用PWM pwm_enable/pwm_disable
c
int pwm_enable(unsigned int pwm) {
// 打开对应通道的enable文件
write(fd, "1", 2); // 启用PWM输出
}
功能
功能:通过写入1或0控制PWM输出开关。
改进建议
使用write(fd, "1", 1)避免多余的空字符。
检查write返回值确保操作成功。
5. 配置周期和占空比 pwm_config
c
int pwm_config(unsigned int pwm, unsigned int period, unsigned int duty_cycle) {
// 写入周期(单位:纳秒)
write(fd, buf_p, len_p);
// 写入占空比(单位:纳秒)
write(fd, buf_d, len_d);
}
作用
作用:设置PWM波形参数。
关键点
period为完整周期时间,duty_cycle为高电平时间。
需确保duty_cycle <= period,否则配置失败。
示例
示例:若period=20000000(20ms),duty_cycle=1500000(1.5ms),则占空比为7.5%。
6. 设置极性 pwm_polarity
c
int pwm_polarity(int pwm, int polarity) {
if (polarity == 1) {
write(fd, "normal", 6); // 正常极性(高电平有效)
} else if (polarity == 0) {
write(fd, "inversed", 8); // 反向极性(低电平有效)
}
}
功能
功能:控制PWM信号的极性。
潜在问题
字符串"inversed"可能是拼写错误,某些驱动要求"inverted"。
需确认龙芯2K1000的PWM驱动支持的极性模式。
7.龙芯2K1000适配说明
7.1 硬件特性
PWM控制器数量
PWM控制器数量:假设支持4个独立PWM控制器(pwmchip0~pwmchip3)。
通道支持
通道支持:每个控制器可能仅支持单通道(pwm0),需参考《龙芯2K1000硬件手册》。
7.2关键问题与优化建议
问题1:写入长度错误
write(fd, "0", 2); // 错误:多写入一个空字符
修复
修复:改为write(fd, "0", 1),仅写入字符'0'。
问题2:路径生成冗余
c
优化:提取公共路径生成逻辑:
const char* get_pwm_path(int pwm, const char* file) {
static char path[128];
snprintf(path, sizeof(path), "/sys/class/pwm/pwmchip%d/pwm0/%s", pwm, file);
return path;
}
问题3:错误处理不足
c
增强:检查所有系统调用的返回值:
if (write(fd, buf, len) != len) {
perror("Write failed");
return -1;
}
问题4:参数合法性校验
c
if (pwm < 0 || pwm > 3) {
printf("Invalid PWM chip number: %d\n", pwm);
return -1;
}
7.3完整优化示例
c
// 辅助函数:生成PWM路径
const char* get_pwm_path(int pwm, const char* file) {
static char path[128];
snprintf(path, sizeof(path), "/sys/class/pwm/pwmchip%d/pwm0/%s", pwm, file);
return path;
}
// 导出PWM通道(优化后)
int pwm_export(unsigned int pwm) {
if (pwm > 3) { // 校验参数合法性
printf("Invalid PWM chip: %d\n", pwm);
return -1;
}
char export_path[64];
snprintf(export_path, sizeof(export_path), "/sys/class/pwm/pwmchip%d/export", pwm);
int fd = open(export_path, O_WRONLY);
if (fd < 0) {
perror("Failed to open export file");
return -1;
}
if (write(fd, "0", 1) != 1) { // 修正写入长度
perror("Failed to export PWM");
close(fd);
return -1;
}
close(fd);
return 0;
}
7.4应用场景示例
c
int main() {
pwm_export(0); // 导出PWM0
pwm_config(0, 20000000, 1500000); // 20ms周期,1.5ms高电平
pwm_polarity(0, 1); // 正常极性
pwm_enable(0); // 启动PWM输出
sleep(5);
pwm_disable(0); // 停止输出
pwm_unexport(0); // 清理
return 0;
}
8.总结
功能
功能:完整控制PWM的初始化、参数配置和输出管理。
优势
优势:基于sysfs接口,代码简洁,兼容性强。
改进方向
- 修复写入长度和拼写错误。
- 提取公共逻辑减少冗余。
- 增强错误处理和参数校验。
- 支持多通道(若硬件允许)。