Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

os/pm, os/driver/pm: Add pm_timer module #6129

Merged
merged 4 commits into from May 13, 2024

Conversation

ritesh55555
Copy link
Contributor

@ritesh55555 ritesh55555 commented Apr 3, 2024

  • This commit adds pm_timer module in os/pm to use multiple timers for PM operation and PM driver also.
  • It defines a structure for multiple wakeup timers. All the timers are stored in a list and just before system sleeps, the timer with nearest future expiration time is started.

os/include/tinyara/fs/ioctl.h Outdated Show resolved Hide resolved
os/drivers/pm/pm.c Outdated Show resolved Hide resolved
os/include/tinyara/pm/pm.h Outdated Show resolved Hide resolved
os/pm/pm_activity.c Outdated Show resolved Hide resolved
os/pm/pm_timer/pm_timer.h Outdated Show resolved Hide resolved
os/pm/pm_timer/pm_timer_initialize.c Outdated Show resolved Hide resolved
os/pm/pm_timer/pm_timer_create.c Outdated Show resolved Hide resolved
os/pm/pm_timer/pm_timer.h Outdated Show resolved Hide resolved
os/include/tinyara/pm/pm.h Outdated Show resolved Hide resolved
os/drivers/pm/pm.c Outdated Show resolved Hide resolved
os/drivers/pm/pm.c Outdated Show resolved Hide resolved
@edwakuwaku
Copy link
Contributor

edwakuwaku commented Apr 3, 2024

Hi @ritesh55555 ,
Initially, I thought the timer resource manager should be held under /dev/timer, as timer is not only specific to PM module.
In os/board/rtl8730e/src/rtl8730e_boot.c, we initialize the timers w.r.t the timer driver (ie. /dev/timer), . Could you please let me know how are we going to link this pm timer with the lower level timer driver control?
If you check this PR #6064, the final setup for timer is during up_set_pm_timer in os/arch/arm/src/amebasmart/amebasmart_pmhelpers.c. In the ioctl for pm driver, other than state control and dvfs, others are all related to timer operation.
My question is, how do we realise the relation between /dev/timer and /dev/pm?

@ritesh55555
Copy link
Contributor Author

ritesh55555 commented Apr 4, 2024

Hi @ritesh55555 , Initially, I thought the timer resource manager should be held under /dev/timer, as timer is not only specific to PM module. In os/board/rtl8730e/src/rtl8730e_boot.c, we initialize the timers w.r.t the timer driver (ie. /dev/timer), . Could you please let me know how are we going to link this pm timer with the lower level timer driver control? If you check this PR #6064, the final setup for timer is during up_set_pm_timer in os/arch/arm/src/amebasmart/amebasmart_pmhelpers.c. In the ioctl for pm driver, other than state control and dvfs, others are all related to timer operation. My question is, how do we realise the relation between /dev/timer and /dev/pm?

the new modification still uses g_pm_timer, pm_set_timer() and pm_init_handler() as before . The PM LOCK TIMER is same as before. the moment app will request pm_lock with timer, it will set pm_set_timer(PM_LOCK_TIMER, timer_interval) and do the up_set_pm_timer() and start the timer as before.
But we wont be using pm_unlock with timer , that has been removed becuase that didnot make sense.
Here we can add multiple wake up timers (struct pm_wakeup_timer_s) in a list , so whenever board is going to sleep , just before that , we can get the right time , find its delay and then do pm_set_timer(PM_WAKEUP_TIMER, delay).

So /dev/pm uses the os/pm apis , and the final setup for timer is same as before. During up_set_pm_timer in amebasmart_pmhelpers.c .
The only difference is we have multiple timers (struct pm_wakeup_timer_s) in a list in increasing order of their expiration time. Just before sleep, pm module will call an api that will set the appropriate wakeup timer. These all will use one hardware timer.

i hope this explains!

@ritesh55555 ritesh55555 force-pushed the pm_driver_timer branch 8 times, most recently from 49f5138 to 20f6028 Compare April 4, 2024 06:31
@ritesh55555
Copy link
Contributor Author

@edwakuwaku Hi currently for pm_lock with timer , we dont have a way to stop the timer . Suppose we want to stop it inbetween by calling pm_unlock. It will only pm_relax() but it will not stop the timer that was started by pm_lock timer. Then during expiration, it will call pm_relax() again and it will crash.
Can we have an api in amebasmart_pmhelpers to stop the timers. currently there is only up_set_pm_timer() which only starts. I think we need another api to stop the timers also.

@edwakuwaku
Copy link
Contributor

@edwakuwaku Hi currently for pm_lock with timer , we dont have a way to stop the timer . Suppose we want to stop it inbetween by calling pm_unlock. It will only pm_relax() but it will not stop the timer that was started by pm_lock timer. Then during expiration, it will call pm_relax() again and it will crash. Can we have an api in amebasmart_pmhelpers to stop the timers. currently there is only up_set_pm_timer() which only starts. I think we need another api to stop the timers also.

Can you try

void up_stop_pm_timer(void) {
    gtimer_stop(&g_timer1);
    RTIM_INTClear(TIMx[TIMER1]);
}

@edwakuwaku
Copy link
Contributor

edwakuwaku commented Apr 4, 2024

@edwakuwaku Hi currently for pm_lock with timer , we dont have a way to stop the timer . Suppose we want to stop it inbetween by calling pm_unlock. It will only pm_relax() but it will not stop the timer that was started by pm_lock timer. Then during expiration, it will call pm_relax() again and it will crash. Can we have an api in amebasmart_pmhelpers to stop the timers. currently there is only up_set_pm_timer() which only starts. I think we need another api to stop the timers also.

Let me confirm with my understanding, for the stop it in between before pm_unlock, I assume that you do not need this timer to trigger wakeup or handle some other operation. Thus you would like to stop it, so that it will not trigger callback to do pm_relax at the same state more than once, is that correct?

@ritesh55555
Copy link
Contributor Author

@edwakuwaku Hi currently for pm_lock with timer , we dont have a way to stop the timer . Suppose we want to stop it inbetween by calling pm_unlock. It will only pm_relax() but it will not stop the timer that was started by pm_lock timer. Then during expiration, it will call pm_relax() again and it will crash. Can we have an api in amebasmart_pmhelpers to stop the timers. currently there is only up_set_pm_timer() which only starts. I think we need another api to stop the timers also.

Let me confirm with my understanding, for the stop it in between before pm_unlock, I assume that you do not need this timer to trigger wakeup or handle some other operation. Thus you would like to stop it, so that it will not trigger callback to do pm_relax at the same state more than once, is that correct?

yes , i just want to stop it . No callback needed.

@ritesh55555 ritesh55555 force-pushed the pm_driver_timer branch 4 times, most recently from 54c997e to 97f64b1 Compare April 8, 2024 05:10
os/drivers/pm/pm.c Outdated Show resolved Hide resolved
os/pm/pm_timer/pm_timer.h Outdated Show resolved Hide resolved
os/include/tinyara/pm/pm.h Outdated Show resolved Hide resolved
os/pm/pm_changestate.c Show resolved Hide resolved
os/pm/pm_timer/pm_timer_create.c Outdated Show resolved Hide resolved
os/pm/pm_timer/pm_timer_set.c Outdated Show resolved Hide resolved
* Data
****************************************************************************/
static const struct file_operations pm_fops = {
0, /* open */
Copy link
Contributor

Choose a reason for hiding this comment

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

how it works without open? lock, reference count and something else are unnecessary?

os/drivers/pm/pm.c Outdated Show resolved Hide resolved
os/pm/pm_timer/pm_timer_create.c Outdated Show resolved Hide resolved
os/pm/pm_timer/pm_timer_create.c Outdated Show resolved Hide resolved
os/pm/pm_timer/pm_timer_set.c Outdated Show resolved Hide resolved
os/pm/pm_timer/pm_timer_set.c Outdated Show resolved Hide resolved
os/pm/pm_timer/pm_timer_set.c Outdated Show resolved Hide resolved
@ritesh55555 ritesh55555 force-pushed the pm_driver_timer branch 4 times, most recently from d3f8c52 to 29ad25f Compare April 12, 2024 07:19
@ritesh55555 ritesh55555 force-pushed the pm_driver_timer branch 4 times, most recently from 9cd8cde to 7a9907c Compare May 8, 2024 03:18
os/include/tinyara/pm/pm.h Outdated Show resolved Hide resolved
os/pm/pm_sleep.c Outdated Show resolved Hide resolved
int pid; /* id of process that created pm timer */
uint8_t flags; /* See pm timer definations above*/
int delay; /* refers to time of sleep expected */
void (*callback)(struct pm_wakeup_timer_s *timer); /* function to be executed when timer expires */
Copy link
Contributor

Choose a reason for hiding this comment

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

it is some strange..
please check this

os/pm/Kconfig Outdated
@@ -45,6 +45,15 @@ config PM_METRICS_DURATION

endif

config PM_MAX_WAKEUP_TIMER
Copy link
Contributor

Choose a reason for hiding this comment

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

how about PM_MAX_STATIC_TIMER ?

And this pr is having both pm_wakeup_timer and pm_timer.
How about unifying the terms into one?

@ritesh55555 ritesh55555 force-pushed the pm_driver_timer branch 3 times, most recently from c0eb0c5 to c4e911e Compare May 8, 2024 06:53
os/pm/pm_timer/pm_timer_delete.c Outdated Show resolved Hide resolved
os/pm/pm_timer/pm_timer_create.c Outdated Show resolved Hide resolved
os/pm/pm_timer/pm_timer_activity.c Outdated Show resolved Hide resolved
os/pm/pm_timer/pm_timer_delete.c Show resolved Hide resolved
@ritesh55555 ritesh55555 force-pushed the pm_driver_timer branch 2 times, most recently from a89212e to 433556c Compare May 8, 2024 08:41
	1. this commit adds a semaphore variable to the timer
	   structure. This will allow the system to lock the thread
	   before and after pm sleep. Here the "thread" refers to the thread
	   that called pm_sleep api through pm driver.

	2. This commit adds a callback api to the timer
	   structure. Whenever a pm timer expires, this
	   api will be called.
@ritesh55555 ritesh55555 force-pushed the pm_driver_timer branch 2 times, most recently from ceaf664 to 31b6d56 Compare May 8, 2024 10:35
@@ -561,12 +561,11 @@ int tash_execute_cmd(char **args, int argc)
if (tash_cmds_info.cmd[cmd_idx].exec_type == TASH_EXECMD_SYNC) {
/* function call to execute SYNC command */
#ifdef CONFIG_PM
pm_arg_t pm_arg = {PM_IDLE_DOMAIN, PM_NORMAL};
Copy link
Contributor

Choose a reason for hiding this comment

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

Please seperate commit

case PMIOC_SLEEP:
if (arg > 0) {
/* Converting from milliseconds to ticks */
arg = ((arg * CLOCKS_PER_SEC) / 1000);
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we not need to provide an API in milliseconds for kernel functions that use pm_sleep rather than driver?

I think it is better to do this in the pm_sleep() function. And if necessary, please change the name to pm_msleep().

uint8_t timer_type; /* Bits here are set according to the timer that is to be used */
uint32_t timer_interval; /* The interval for whichever timer is to be used */
clock_t last_wifi_alive_send_time; /* Time tick of the last wifi keep alive signal sent time */
struct pm_wakeup_timer_s {
Copy link
Contributor

Choose a reason for hiding this comment

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

We use pm_timer in all APIs, But only in this structure data type, we call it pm_wakeup_timer.

Please change it to pm_timer as well.

Comment that our pm_timer means waking up the main core on time.

if (curr->delay > CONFIG_PM_MIN_SLEEP_TIME) {
pmvdbg("Setting timer and Board will wake up after %d millisecond\n", curr->delay);
/* Converting ticks to nanoseconds */
up_set_pm_timer((curr->delay * 1000000) / CLOCKS_PER_SEC);
Copy link
Contributor

Choose a reason for hiding this comment

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

Please use TICK2NSEC(curr->delay)

/* PM transition will be relaxed here */
if (pid_timerMap[pid] != NULL) {
pm_relax(PM_IDLE_DOMAIN, (enum pm_state_e)state);
wd_delete(pid_timerMap[pid]);
Copy link
Contributor

Choose a reason for hiding this comment

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

Please change PIDHASH(pid)


/* Check if there is already a wdog lock timer running for
* the process */
if (pid_timerMap[pid] != NULL) {
Copy link
Contributor

Choose a reason for hiding this comment

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

If there is already a timer, it is recommended that we do not clear the timer and start again after wd_cancel.

And if timer_interval is entered as 0, please call wd_cancel and wd_delete only(not start).

Copy link
Contributor

Choose a reason for hiding this comment

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

I would be failed when a new thread with the same pid hash comes in.

@ritesh55555 ritesh55555 force-pushed the pm_driver_timer branch 2 times, most recently from 9e43040 to 44244c1 Compare May 13, 2024 09:52
*
************************************************************************/

int pm_msleep(int timer_interval)
Copy link
Contributor

Choose a reason for hiding this comment

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

please change file name to pm_msleep()

os/pm/pm_timer/pm_timer_delete.c Outdated Show resolved Hide resolved
os/pm/pm_timer/pm_timer.h Outdated Show resolved Hide resolved
os/pm/pm_timer/pm_timer.h Outdated Show resolved Hide resolved
os/pm/pm_timer/pm_timer.h Outdated Show resolved Hide resolved
os/pm/pm_timedStay.c Outdated Show resolved Hide resolved
/* This array maps the pid to their respective wdog timer.
* Assumption: when a thread does a timed lock , only the same thread
* can unlock the "timed lock" before it expire */
static WDOG_ID pid_timerMap[CONFIG_MAX_TASKS];
Copy link
Contributor

Choose a reason for hiding this comment

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

Please check coding rule.

g_pid_timer_map[]

ritesh55555 and others added 2 commits May 13, 2024 16:28
	- This commit adds pm_timedstay api that can perform
	  pm state suspend for a given time duration.It also
	  updates pm driver code.
	- this commit updates the pm suspend and pm resume
	  code for SYNC cmd because of the new changes in
	  the pm driver.
@sunghan-chang sunghan-chang merged commit 6a341e0 into Samsung:master May 13, 2024
11 checks passed
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.

None yet

6 participants