Skip to content

os/pm: Add PM stop/status control and split code#6979

Open
seokhun-eom24 wants to merge 6 commits intoSamsung:masterfrom
seokhun-eom24:250924-add-pm-stop
Open

os/pm: Add PM stop/status control and split code#6979
seokhun-eom24 wants to merge 6 commits intoSamsung:masterfrom
seokhun-eom24:250924-add-pm-stop

Conversation

@seokhun-eom24
Copy link
Copy Markdown
Contributor

@seokhun-eom24 seokhun-eom24 commented Sep 24, 2025

1. os/pm: Fix typo and convention in pm_initialize.c

Fix typo in pm_clock_initialize and pm_start
Fix function brace convention to enter after function name.

2. os/pm: add PMIOC_STOP ioctl to disable pm

Add PMIOC_STOP ioctl command and pm_stop function to support disable pm.

3. pm/pm_procfs: Add stopped status to /proc/power/state

Add stopped status to /proc/power/state.
It returns "stopped" when PM is stopped and PM states when PM is running.

[Example]

TASH>>cat state
* STOPPED
  NORMAL
  SLEEP

4. os/pm: Split source files for each functions

Extract pm_start(), pm_stop(), and pm_clock_initialize() functions from pm_initialize.c into separate source files.
Update Makefile to include new source files.

5. apps/examples/power: Add pm stop and status example

Add "power stop" command to stop power example.
Add "power status" command to get pm status.
Extract _pm_stop, _pm_start, _pm_status for ioctl communication.

6. os/pm: Add pm_lock function and update Makefile

Add new pm_lock function to lock the pm module.
This function automatically retries if interrupted by a signal (EINTR).

@seokhun-eom24 seokhun-eom24 force-pushed the 250924-add-pm-stop branch 2 times, most recently from ebae5c7 to a7ae0e3 Compare September 24, 2025 07:07
Comment thread apps/examples/power/power_main.c Outdated
Comment on lines +313 to +318
pid = task_create("stop_pm_test", 100, 1024, stop_pm_test, argv + 1);
if (pid < 0) {
printf("Fail to create stop_pm_test task(errno %d)\n", get_errno());
is_running = true;
return -1;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

we don't need stop_pm_test task

it is requred only calling stop ioctl.

	if(ioctl(fd, PMIOC_STOP, 0) < 0) {
		printf("Fail to pm start(errno %d)\n", get_errno());
		close(fd);
		return -1;
	}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

And how about make each testing function like below? (start / stop)

we can move log of start and stop to actually start and end entry point.

static int pm_start(void) 
{
	if(ioctl(fd, PMIOC_START, 0) < 0) ~~
}

static int pm_stop(void)
{
	if(ioctl(fd, PMIOC_STOP, 0) < 0) ~~
}


....

	if (strncmp(argv[1], "start", 6) == 0) {
		...

		is_running = true;
		printf("######################### PM LONG TERM TEST START #########################\n");
		pm_stop();

	} else if (strncmp(argv[1], "stop", 5) == 0) {
		...

		pm_stop();
		printf("######################### PM LONG TERM TEST END #########################\n");
		is_running = true;
	}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thank you for suggest.
I updated to print start and stop log inside _pm_start and _pm_stop.

Comment thread os/pm/pm_initialize.c Outdated
Comment on lines +123 to +126
void pm_stop(void)
{
g_pmglobals.is_running = false;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good to me this stop fucntion.

Comment thread os/include/tinyara/fs/ioctl.h Outdated
#define PMIOC_METRICS _PMIOC(0x0007)
#define PMIOC_SUSPEND_COUNT _PMIOC(0x0008)
#define PMIOC_START _PMIOC(0x0009)
#define PMIOC_STOP _PMIOC(0x0010)
Copy link
Copy Markdown
Member

@pcs1265 pcs1265 Sep 24, 2025

Choose a reason for hiding this comment

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

0x10 is not a next value of 0x09.
Please change this value to 0x0A

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed. Thank you.

Comment thread os/pm/pm_procfs.c Outdated
{
enum pm_state_e pm_state;

readprint("PM %s\n\n", (g_pmglobals.is_running) ? "RUNNING" : "STOPPED");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

procfs is not only for information.
sometimes application should parse data from procfs, so it shoul memcpy data to buffer.
Hence if you want reveal running state, then you should create additional directory, not here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I updated this PR not to use procfs.
Thank you for review.

Comment thread os/pm/pm_initialize.c Outdated

void pm_stop(void)
{
g_pmglobals.is_running = false;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

pm_ioctl doesn't use semaphore, so I think this is not 'thread-safe'

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I updated to protect g_pmglobals.is_running using semaphore.
Thank you.

Comment thread apps/examples/power/power_main.c Outdated

fd = open(PM_DRVPATH, O_WRONLY);
if (fd < 0) {
printf("Fail to open pm start(errno %d)", get_errno());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It's open pm driver, not open pm start.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed. Thank you.
And I modified other open error message too.

Comment thread apps/examples/power/power_main.c Outdated
}

if(ioctl(fd, PMIOC_STOP, 0) < 0) {
printf("Fail to pm start(errno %d)\n", get_errno());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

looks fail to stop pm, not start

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

Comment thread apps/examples/power/power_main.c Outdated
return -1;
}

if(ioctl(fd, PMIOC_STOP, 0) < 0) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

space.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed this line and also in start_pm_test

Comment thread apps/examples/power/power_main.c Outdated

is_running = false;

pid = task_create("stop_pm_test", 100, 1024, stop_pm_test, argv + 1);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could you let me know why you give argv + 1?
In help message, the stop command does not have any following argument.

And the task creation for start also give it, but is it right with +1? not +2?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, stop_pm_test doesn't need any argument.
So I fixed argv + 1 to NULL.

argv + 1 is the correct value to use because argv is a pointer to the first element of the command argument.

When the command line is something like:

power start -t

the argv array is initialized as:

argv[0] = "power"
argv[1] = "start"
argv[2] = "-t"
argv[3] = NULL

To pass only the part after the program name(i.e.,{"start", "-t"}), need to give the pointer that starts at argv[1]. So argv + 1 is right.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@seokhun-eom24 You already check the argv[1] with start.

	if (strncmp(argv[1], "start", 6) == 0) {
		if (is_running) {
			printf("power test is already running\n");
			return 0;
		}
		is_running = true;
		pid = task_create("start_pm_test", 100, 1024, start_pm_test, argv + 1);

The task is created for start. Why do you need to give start argument to the task?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Right. We don't need to pass argv + 1, it's start.
I updated to pass argv + 2.
Thank you.

Comment thread apps/examples/power/power_main.c Outdated
pid = task_create("stop_pm_test", 100, 1024, stop_pm_test, argv + 1);
if (pid < 0) {
printf("Fail to create stop_pm_test task(errno %d)\n", get_errno());
is_running = true;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If you set the variable to false after this creation, what happen?
I mean
do you need to set it to false always and then revert it with failure case?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

In start_pm_test, is_running should be set first and start task,
but as you said in stop_pm_test reset is_running can handled after create task.
So I modified the flow to reset after create task.

Comment thread os/pm/pm_initialize.c Outdated
*
****************************************************************************/

void pm_stop(void)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This file is pm_initialize. Let's add this with new file.
same for pm_start

Copy link
Copy Markdown
Contributor Author

@seokhun-eom24 seokhun-eom24 Jan 28, 2026

Choose a reason for hiding this comment

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

I separated pm_start, pm_stop, and pm_clock_initialize from pm_initialize.c with new files.

Comment thread apps/examples/power/power_main.c Outdated
return 0;
}

pid = task_create("stop_pm_test", 100, 1024, stop_pm_test, NULL);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is there any reason why we should do start and stop test in separate tasks?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We don't need to separate tasks to stop.
I updated code.

Comment thread apps/examples/power/power_main.c Outdated
return -1;
}

if (ioctl(fd, PMIOC_STOP, 0) < 0) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This code can be called first than "start_pm_test" task termination

like

call resume(10)
######################### PM LONG TERM TEST END #########################
call suspend(10)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I updated to print log after _pm_stop.

@gidori98
Copy link
Copy Markdown
Contributor

LGTM

@seokhun-eom24 seokhun-eom24 changed the title os/pm: Add PMIOC_STOP to stop pm and show state in pm_procfs os/pm: Add PM stop/status control and split code Jan 28, 2026
@seokhun-eom24 seokhun-eom24 force-pushed the 250924-add-pm-stop branch 4 times, most recently from a947978 to 0eba68b Compare February 2, 2026 04:26
Comment thread os/pm/pm_getstatus.c Outdated
Comment on lines +48 to +57
int pm_getstatus(void)
{
int status;

pm_lock();
status = g_pmglobals.is_running ? PM_STATUS_RUNNING : PM_STATUS_STOPPED;
pm_unlock();

return status;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

we don't need to provide status using api.
how about add it to procfs?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I added a new procfs /proc/power/running.
The reason for creating /power/running separately from /power/status is based on Taejun-Kwon's comment.
Procfs is not only for information but also allows applications to fetch data via memcpy, which is why the new procfs was added.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Modified to use "/proc/power/state" together as we discussed.

@seokhun-eom24 seokhun-eom24 force-pushed the 250924-add-pm-stop branch 3 times, most recently from 83054cb to 39edc21 Compare February 13, 2026 05:49
Fix typo in `pm_clock_initialize` and `Pm_start`.
Fix function brace convention to enter after function name.

Signed-off-by: seokhun-eom <seokhun.eom@samsung.com>
Add `PMIOC_STOP` ioctl command and `pm_stop` function to support disable pm.

Signed-off-by: seokhun-eom <seokhun.eom@samsung.com>
Add stopped status to /proc/power/state.
It returns "stopped" when PM is stopped and PM states when PM is running.

[Example]
```
TASH>>cat state
* STOPPED
  NORMAL
  SLEEP
```

Signed-off-by: seokhun-eom <seokhun.eom@samsung.com>
Extract `pm_start()`, `pm_stop()`, and `pm_clock_initialize()` functions from `pm_initialize.c` into separate source files.
Update `Makefile` to include new source files.

Signed-off-by: seokhun-eom <seokhun.eom@samsung.com>
Add "power stop" command to stop power example.
Add "power status" command to get pm status.
Extract `_pm_stop`, `_pm_start`, `_pm_status` for ioctl communication.

Signed-off-by: seokhun-eom <seokhun.eom@samsung.com>
Add new `pm_lock` function to lock the pm module.
This function automatically retries if interrupted by a signal (EINTR).

Signed-off-by: seokhun-eom <seokhun.eom@samsung.com>
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.

6 participants