Skip to content

Create PWM driver initial version - #12

Open
RuiqiLiu2014 wants to merge 8 commits into
mainfrom
pwm-driver
Open

Create PWM driver initial version#12
RuiqiLiu2014 wants to merge 8 commits into
mainfrom
pwm-driver

Conversation

@RuiqiLiu2014

@RuiqiLiu2014 RuiqiLiu2014 commented May 15, 2026

Copy link
Copy Markdown

Description

Our first draft of the PWM driver, does not have unit tests.

Artifacts for PR #12 (DO NOT CHANGE)

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an initial F Prime Linux sysfs PWM driver component, defining its ports, status enum, events, C++ implementation, and local CMake target.

Changes:

  • Defines the Drv.LinuxPwmDriver passive component and PWM control ports.
  • Implements sysfs-based period, duty cycle, enable, and export handling.
  • Adds a component-level CMake library target, with unit tests left disabled.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 11 comments.

File Description
FlightComputer/Components/PwmDriver/LinuxPwmDriver.hpp Declares the PWM driver component implementation and internal state.
FlightComputer/Components/PwmDriver/LinuxPwmDriver.cpp Implements sysfs PWM export and control handlers.
FlightComputer/Components/PwmDriver/Driver.fpp Defines the FPP component, ports, events, interface, and status enum.
FlightComputer/Components/PwmDriver/CMakeLists.txt Registers the PWM driver library and includes a commented-out unit test target.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +17 to +21
register_fprime_library(
AUTOCODER_INPUTS
"${CMAKE_CURRENT_LIST_DIR}/Driver.fpp"
SOURCES
"${CMAKE_CURRENT_LIST_DIR}/LinuxPwmDriver.cpp"
#ifndef Drv_LinuxPwmDriver_HPP
#define Drv_LinuxPwmDriver_HPP

#include "LinuxPwmDrv/Components/Driver/LinuxPwmDriverComponentAc.hpp"
// \brief cpp file for LinuxPwmDriver component implementation class
// ======================================================================

#include "LinuxPwmDrv/Components/Driver/LinuxPwmDriver.hpp"
Comment on lines +27 to +36
# register_fprime_ut(
# AUTOCODER_INPUTS
# "${CMAKE_CURRENT_LIST_DIR}/Driver.fpp"
# SOURCES
# "${CMAKE_CURRENT_LIST_DIR}/test/ut/DriverTestMain.cpp"
# "${CMAKE_CURRENT_LIST_DIR}/test/ut/DriverTester.cpp"
# DEPENDS
# STest # For rules-based testing
# UT_AUTO_HELPERS
# ) No newline at end of file
Comment on lines +90 to +94
int fd = ::open(exportPath, O_WRONLY);
if (fd < 0) {
// Log the error event using errno to know exactly why it failed (e.g., EACCES)
this->log_WARNING_HI_OpenChannelError(chipNum, channelNum, errno);
return false;
Comment on lines +111 to +115
// 2. Save the base path for our handlers to use later
snprintf(this->m_basePath, sizeof(this->m_basePath), "/sys/class/pwm/pwmchip%u/pwm%u", chipNum, channelNum);

// 3. Mark as opened and log success
this->m_opened = true;
Comment on lines +105 to +113
if (bytesWritten != len) {
// The file opened, but the write failed (e.g., channel already exported or invalid)
this->log_WARNING_HI_OpenChannelError(chipNum, channelNum, errno);
return false;
}

// 2. Save the base path for our handlers to use later
snprintf(this->m_basePath, sizeof(this->m_basePath), "/sys/class/pwm/pwmchip%u/pwm%u", chipNum, channelNum);

Comment on lines +16 to +22
// ----------------------------------------------------------------------
// Component construction and destruction
// ----------------------------------------------------------------------

LinuxPwmDriver ::LinuxPwmDriver(const char* const compName) : LinuxPwmDriverComponentBase(compName) {}

LinuxPwmDriver ::~LinuxPwmDriver() {}
Comment on lines +101 to +107
// Write the string and immediately close the file
ssize_t bytesWritten = ::write(fd, channelStr, len);
::close(fd);

if (bytesWritten != len) {
// The file opened, but the write failed (e.g., channel already exported or invalid)
this->log_WARNING_HI_OpenChannelError(chipNum, channelNum, errno);
Comment on lines +3 to +4
@ A passive driver for Linux sysfs PWM
passive component LinuxPwmDriver {
@h-badams
h-badams requested a review from alexisgmm May 25, 2026 21:48
@h-badams

h-badams commented May 25, 2026

Copy link
Copy Markdown

if you could fix the failing CI checks and review the Copilot suggestions (in particular, making sure that the OS-level driver opens and closes correctly), this would be great.

Adding @alexisgmm as a reviewer since they are writing the ADCS software that will actually use this driver.

Drv::PwmStatus LinuxPwmDriver::open(U32 chipNum, U32 channelNum) {
// 1. Export the channel (Tell Linux we want to use it)
char exportPath[256];
snprintf(exportPath, sizeof(exportPath), "/sys/class/pwm/pwmchip%u/export", chipNum);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Return value should be checked, system calls always have a chance of failing.


Drv::PwmStatus LinuxPwmDriver::open(U32 chipNum, U32 channelNum) {
// 1. Export the channel (Tell Linux we want to use it)
char exportPath[256];

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Magic number, define size as a #define or constexpr U8 somewhere in the header

}

// Convert the channel number to a string to write to the file
char channelStr[32];

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto from above

Comment on lines +99 to +103
int len = snprintf(channelStr, sizeof(channelStr), "%u", channelNum);

// Write the string and immediately close the file
ssize_t bytesWritten = ::write(fd, channelStr, len);
::close(fd);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Return values should be checked and logged for errors

}

// 2. Save the base path for our handlers to use later
snprintf(this->m_basePath, sizeof(this->m_basePath), "/sys/class/pwm/pwmchip%u/pwm%u", chipNum, channelNum);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check return code please

}

Drv::PwmStatus LinuxPwmDriver::writeSysfsInt(const char* file, U32 value) {
char fullPath[512];

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Define size as constant please


Drv::PwmStatus LinuxPwmDriver::writeSysfsInt(const char* file, U32 value) {
char fullPath[512];
snprintf(fullPath, sizeof(fullPath), "%s/%s", this->m_basePath, file);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check return code

Comment on lines +133 to +138
int len = snprintf(valStr, sizeof(valStr), "%u", value);

// Write the buffer directly
ssize_t bytesWritten = ::write(fd, valStr, len);

::close(fd);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These lines seem to be repeated, any chance we can have these put into a function somehow?

U32 m_periodNs = 0;

// Buffer to hold the base path (e.g., "/sys/class/pwm/pwmchip0/pwm1")
char m_basePath[256];

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto from previous comments, change size to constant defined somewhere in this header

// Handler implementations for typed input ports
// ----------------------------------------------------------------------

//! Handler implementation for pwmEnable

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MahirEmran @h-badams @alexisgmm I see that F prime is writing comments inline with the parameters, should we change these to be doxygen (as in, above the function)? My vote is yes considering our pipelines ask for this formatting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants