{"action":"created","issue":{"url":"https://api.github.com/repos/zephyrproject-rtos/zephyr/issues/11261","repository_url":"https://api.github.com/repos/zephyrproject-rtos/zephyr","labels_url":"https://api.github.com/repos/zephyrproject-rtos/zephyr/issues/11261/labels{/name}","comments_url":"https://api.github.com/repos/zephyrproject-rtos/zephyr/issues/11261/comments","events_url":"https://api.github.com/repos/zephyrproject-rtos/zephyr/issues/11261/events","html_url":"https://github.com/zephyrproject-rtos/zephyr/issues/11261","id":379192920,"node_id":"MDU6SXNzdWUzNzkxOTI5MjA=","number":11261,"title":"ARM Cortex-M4 (EFR32FG1P) MCU fails to wake up from sleep within _sys_soc_suspend()","user":{"login":"mnkp","id":28196316,"node_id":"MDQ6VXNlcjI4MTk2MzE2","avatar_url":"https://avatars0.githubusercontent.com/u/28196316?v=4","gravatar_id":"","url":"https://api.github.com/users/mnkp","html_url":"https://github.com/mnkp","followers_url":"https://api.github.com/users/mnkp/followers","following_url":"https://api.github.com/users/mnkp/following{/other_user}","gists_url":"https://api.github.com/users/mnkp/gists{/gist_id}","starred_url":"https://api.github.com/users/mnkp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mnkp/subscriptions","organizations_url":"https://api.github.com/users/mnkp/orgs","repos_url":"https://api.github.com/users/mnkp/repos","events_url":"https://api.github.com/users/mnkp/events{/privacy}","received_events_url":"https://api.github.com/users/mnkp/received_events","type":"User","site_admin":false},"labels":[{"id":700753051,"node_id":"MDU6TGFiZWw3MDA3NTMwNTE=","url":"https://api.github.com/repos/zephyrproject-rtos/zephyr/labels/area:%20ARM","name":"area: ARM","color":"ededed","default":false},{"id":700751250,"node_id":"MDU6TGFiZWw3MDA3NTEyNTA=","url":"https://api.github.com/repos/zephyrproject-rtos/zephyr/labels/area:%20Kernel","name":"area: Kernel","color":"ededed","default":false},{"id":700756535,"node_id":"MDU6TGFiZWw3MDA3NTY1MzU=","url":"https://api.github.com/repos/zephyrproject-rtos/zephyr/labels/area:%20Power%20Management","name":"area: Power Management","color":"ededed","default":false},{"id":383053976,"node_id":"MDU6TGFiZWwzODMwNTM5NzY=","url":"https://api.github.com/repos/zephyrproject-rtos/zephyr/labels/bug","name":"bug","color":"e99695","default":true},{"id":636351516,"node_id":"MDU6TGFiZWw2MzYzNTE1MTY=","url":"https://api.github.com/repos/zephyrproject-rtos/zephyr/labels/priority:%20low","name":"priority: low","color":"c2e0c6","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":10,"created_at":"2018-11-09T14:54:21Z","updated_at":"2018-12-17T23:22:15Z","closed_at":null,"author_association":"COLLABORATOR","body":"I'm implementing power management features on SiLabs efr32_slwstk6061a board with EFR32FG1P ARM Cortex-M4 MCU. To put the device to sleep I'm using vendor provided em_emu library module.\r\n\r\nAfter performing all the tedious configuration of Energy Management Unit the em_emu library puts the device to sleep via the WFI instruction. Unfortunately, despite correctly configured wake up event the device never wakes up.\r\n\r\nThe power management is performed within _sys_soc_suspend() function as described in [System Power Management](https://docs.zephyrproject.org/latest/subsystems/power_management.html#system-power-management) chapter of Zephyr's documentation. At this point, the kernel has disabled interrupts.\r\n\r\nThe culprit is the kernel method of disabling interrupts which in case of ARM Cortex-M4 architecture is done using BASEPRI register. Since the wake up event has an interrupt priority equal to or lower than the value in BASEPRI register the CPU never sees it. To disable interrupts and allow CPU to wake up the kernel should use the PRIMASK register.\r\n\r\nFrom the ARM \"Cortex™-M4 Devices Generic User Guide\" chapter \"2.5.2 Wakeup from sleep mode\":\r\n\r\n> #### Wakeup from WFI or sleep-on-exit\r\n> Normally, the processor wakes up only when it detects an exception with sufficient priority to\r\ncause exception entry. Some embedded systems might have to execute system restore tasks after\r\nthe processor wakes up, and before it executes an interrupt handler. To achieve this set the\r\nPRIMASK bit to 1 and the FAULTMASK bit to 0. If an interrupt arrives that is enabled and has\r\na higher priority than current exception priority, the processor wakes up but does not execute the\r\ninterrupt handler until the processor sets PRIMASK to zero.\r\n\r\nIn case the interrupts are disabled using the PRIMASK method before putting the EFR32FG1P MCU to sleep the device wakes up correctly."},"comment":{"url":"https://api.github.com/repos/zephyrproject-rtos/zephyr/issues/comments/448036817","html_url":"https://github.com/zephyrproject-rtos/zephyr/issues/11261#issuecomment-448036817","issue_url":"https://api.github.com/repos/zephyrproject-rtos/zephyr/issues/11261","id":448036817,"node_id":"MDEyOklzc3VlQ29tbWVudDQ0ODAzNjgxNw==","user":{"login":"mnkp","id":28196316,"node_id":"MDQ6VXNlcjI4MTk2MzE2","avatar_url":"https://avatars0.githubusercontent.com/u/28196316?v=4","gravatar_id":"","url":"https://api.github.com/users/mnkp","html_url":"https://github.com/mnkp","followers_url":"https://api.github.com/users/mnkp/followers","following_url":"https://api.github.com/users/mnkp/following{/other_user}","gists_url":"https://api.github.com/users/mnkp/gists{/gist_id}","starred_url":"https://api.github.com/users/mnkp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mnkp/subscriptions","organizations_url":"https://api.github.com/users/mnkp/orgs","repos_url":"https://api.github.com/users/mnkp/repos","events_url":"https://api.github.com/users/mnkp/events{/privacy}","received_events_url":"https://api.github.com/users/mnkp/received_events","type":"User","site_admin":false},"created_at":"2018-12-17T23:22:15Z","updated_at":"2018-12-17T23:22:15Z","author_association":"COLLABORATOR","body":"> 3\\. On return from either function, **the IRQ lock is assumed to have been internally released**.\r\n\r\nI was wondering if this may be the case but then there was the obvious hindrance\r\n\r\n> among other things, the \"key\" returned by irq_lock(), which is required to be passed back to unlock in all other cases, never gets handed to the idle code\r\n\r\nDoesn't it imply that the current API design is broken?\r\n\r\n> So that tells you that on entry to _sys_soc_suspend(), BASEPRI will be nonzero and PRIMASK has all interrupts unmasked (i.e. it's unused by zephyr). On exit, BASEPRI must be zero and PRIMASK must be unchanged.\r\n\r\nWe are forcing user to deal with low level, critical, implementation specific parts of the kernel code. This is really non obvious and not easy to infer.\r\n\r\n> And there's no reason you can't add the ~4 instructions it would take to set and unset PRIMASK appropriately to your requirements.\r\n\r\nThis code is common to all implementations of `_sys_soc_suspend()` function for Cortex-M3 and higher devices. Even from the 'clean code' point of view it should be implemented by the calling function.\r\n\r\nThe design would be cleaner if either the kernel didn't lock the interrupts before calling `_sys_soc_suspend()` function or if we locked the interrupts in the proper manner. Locking the interrupts the wrong way on ARM devices just because the kernel code was written for other architectures where it doesn't cause any issues is not a good approach."}}
{"actor":{"display_login":"mnkp"}}