Title: ISR caused stack overflow? · feilipu/Arduino_FreeRTOS_Library · Discussion #144 · GitHub
Open Graph Title: ISR caused stack overflow? · feilipu/Arduino_FreeRTOS_Library · Discussion #144
X Title: ISR caused stack overflow? · feilipu/Arduino_FreeRTOS_Library · Discussion #144
Description: ISR caused stack overflow?
Open Graph Description: I wonder where is the stack used by ISR. Cortex-M devices have two SP registers so that ISR and tasks use seperate stack spaces. But AVR devices don't seem to have this capability. As for AVR devic...
X Description: I wonder where is the stack used by ISR. Cortex-M devices have two SP registers so that ISR and tasks use seperate stack spaces. But AVR devices don't seem to have this capability. As for AVR d...
Opengraph URL: https://github.com/feilipu/Arduino_FreeRTOS_Library/discussions/144
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"QAPage","mainEntity":{"@type":"Question","name":"ISR caused stack overflow?","text":"\u003cp dir=\"auto\"\u003eI wonder where is the stack used by ISR. Cortex-M devices have two SP registers so that ISR and tasks use seperate stack spaces. But AVR devices don't seem to have this capability. As for AVR devices, I suspect ISR just use the stack of the task interrupted by the ISR, and randomly cause stack overflow.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eI made a fork of this project to support ATmega128, and changed a little code to use TIM2 as tick source. I found that, when I define configCHECK_FOR_STACK_OVERFLOW == 2, the stack overflow alert is triggered more often. The structure of my code is like below:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-c++ notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"\nvoid main_task() {\n // SETUP\n\n Wire.begin();\n\n init_pin();\n init_oled();\n put_something_on_oled();\n\n // LOOP\n\n int counter = 0;\n while(true) {\n put_num_to_oled(counter);\n // crash near here\n ++counter;\n \n xTaskDelay(500ms);\n }\n}\"\u003e\u003cpre class=\"notranslate\"\u003e\u003cspan class=\"pl-k\"\u003evoid\u003c/span\u003e \u003cspan class=\"pl-en\"\u003emain_task\u003c/span\u003e() {\n \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e//\u003c/span\u003e SETUP\u003c/span\u003e\n\n Wire.\u003cspan class=\"pl-c1\"\u003ebegin\u003c/span\u003e();\n\n \u003cspan class=\"pl-c1\"\u003einit_pin\u003c/span\u003e();\n \u003cspan class=\"pl-c1\"\u003einit_oled\u003c/span\u003e();\n \u003cspan class=\"pl-c1\"\u003eput_something_on_oled\u003c/span\u003e();\n\n \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e//\u003c/span\u003e LOOP\u003c/span\u003e\n\n \u003cspan class=\"pl-k\"\u003eint\u003c/span\u003e counter = \u003cspan class=\"pl-c1\"\u003e0\u003c/span\u003e;\n \u003cspan class=\"pl-k\"\u003ewhile\u003c/span\u003e(\u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e) {\n \u003cspan class=\"pl-c1\"\u003eput_num_to_oled\u003c/span\u003e(counter);\n \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e//\u003c/span\u003e crash near here\u003c/span\u003e\n ++counter;\n \n \u003cspan class=\"pl-c1\"\u003exTaskDelay\u003c/span\u003e(500ms);\n }\n}\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eI think it's strange to see that stack overflow occurs after the task has looped some times. The memory requirement for each loop is stable, no malloc, no recursion. And more strangely, when configCHECK_FOR_STACK_OVERFLOW == 1, the task is happy with 300 stack size. However, when configCHECK_FOR_STACK_OVERFLOW == 2, 500 bytes of stack space is still insufficient.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eI used \u003ccode class=\"notranslate\"\u003euxTaskGetStackHighWaterMark()\u003c/code\u003e in the deepest stage of the function call. The result shows the task has more than half the total size of stack space remaining available, and suddenly crashes. Considering the algorithm taken by FreeRTOS core when configCHECK_FOR_STACK_OVERFLOW == 2, there must be something modified the data in stack. I think it is the ISR. When configCHECK_FOR_STACK_OVERFLOW == 1, the risk can't be detected.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003ca target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://private-user-images.githubusercontent.com/45288809/423220559-2ecc8bfe-3de3-47e5-9dcf-2f0bf54e6016.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3ODQ3ODUzOTYsIm5iZiI6MTc4NDc4NTA5NiwicGF0aCI6Ii80NTI4ODgwOS80MjMyMjA1NTktMmVjYzhiZmUtM2RlMy00N2U1LTlkY2YtMmYwYmY1NGU2MDE2LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjA3MjMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwNzIzVDA1MzgxNlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTI4YzBiMDMwOGU0N2NjOTkwZDJmMzljNmI2MGU2YWQwMDkzZWJiOTUzN2JiYTliNjFhMTIxYzgxYjhmZWJhNDYmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JnJlc3BvbnNlLWNvbnRlbnQtdHlwZT1pbWFnZSUyRnBuZyJ9.DKFcRMNhTLz-5K9p5b1gYFSgq_WS9xjHoD45RvpWWzw\"\u003e\u003cimg src=\"https://private-user-images.githubusercontent.com/45288809/423220559-2ecc8bfe-3de3-47e5-9dcf-2f0bf54e6016.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3ODQ3ODUzOTYsIm5iZiI6MTc4NDc4NTA5NiwicGF0aCI6Ii80NTI4ODgwOS80MjMyMjA1NTktMmVjYzhiZmUtM2RlMy00N2U1LTlkY2YtMmYwYmY1NGU2MDE2LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNjA3MjMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjYwNzIzVDA1MzgxNlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTI4YzBiMDMwOGU0N2NjOTkwZDJmMzljNmI2MGU2YWQwMDkzZWJiOTUzN2JiYTliNjFhMTIxYzgxYjhmZWJhNDYmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JnJlc3BvbnNlLWNvbnRlbnQtdHlwZT1pbWFnZSUyRnBuZyJ9.DKFcRMNhTLz-5K9p5b1gYFSgq_WS9xjHoD45RvpWWzw\" alt=\"图片\" style=\"max-width: 100%;\"\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eMy project is build under PlatformIO. If you want more detail, below is all the files. Note that, most comments are written in chinese, and most code is c++, template magic warning.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003e\u003ca href=\"https://github.com/user-attachments/files/19272485/project.zip\"\u003eproject.zip\u003c/a\u003e\u003c/p\u003e","upvoteCount":1,"answerCount":1,"acceptedAnswer":{"@type":"Answer","text":"\u003cblockquote\u003e\n\u003cp dir=\"auto\"\u003eAs for AVR devices, I suspect ISR just use the stack of the task interrupted by the ISR, and randomly cause stack overflow.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp dir=\"auto\"\u003eYes. The stack used during a context switch is the active Task stack. This is why every Task stack must be large enough to support all of the stack used by the Task itself, plus enough free space to enable a context switch to be stored.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThis means that if your Task doesn't reuse dynamic storage properly then sooner or later there will be a crash due to stack overflow. If there is a stack overflow happening, that points to something arising in the Task code itself.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eUsually a Task will be allocated memory by a static allocation solution such as \u003ccode class=\"notranslate\"\u003eheap_1.c\u003c/code\u003e or \u003ccode class=\"notranslate\"\u003eheap_2.c\u003c/code\u003e. But in the case of Arduino_FreeRTOS we've used the standard \u003ccode class=\"notranslate\"\u003emalloc()\u003c/code\u003e code wrapped by \u003ccode class=\"notranslate\"\u003eheap_3.c\u003c/code\u003e as it allows support of various different devices with different memory capacities.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFor professional work I'd suggest not to use \u003ccode class=\"notranslate\"\u003eheap_3.c\u003c/code\u003e as your memory manager. And consider using the static versions of the FreeRTOS API.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eIt also means that you have to assume that a context switch will occur at the most inconvenient time. This is 100% guarenteed to happen over the long run (only several seconds in FreeRTOS world). As an example where this affected me, in the \u003ca href=\"https://github.com/wwarthen/RomWBW/pull/96\" data-hovercard-type=\"pull_request\" data-hovercard-url=\"/wwarthen/RomWBW/pull/96/hovercard\"\u003e8-bit Z80 world the RomWBW\u003c/a\u003e system uses bank switching to access system utilities and interrupt code stored in a separate code page. If (When) a FreeRTOS context switch happens \u003cstrong\u003eduring\u003c/strong\u003e the process of doing the bank switch, then stack space needs to be available for it to complete. For clarity, this is not before the bank switch running in user memory, or after while running in system memory, but during the actual bank switch even though this is a \u003ca href=\"https://github.com/wwarthen/RomWBW/blob/master/Source/HBIOS/hbios.asm#L551-L624\"\u003every short piece of code\u003c/a\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eHope that helps.\u003c/p\u003e","upvoteCount":1,"url":"https://github.com/feilipu/Arduino_FreeRTOS_Library/discussions/144#discussioncomment-12519025"}}}
| route-pattern | /_view_fragments/Voltron::DiscussionsFragmentsController/show/:user_id/:repository/:discussion_number/discussion_layout(.:format) |
| route-controller | voltron_discussions_fragments |
| route-action | discussion_layout |
| fetch-nonce | v2:d2ef50aa-323c-2d21-3de0-2d84dde0aac3 |
| current-catalog-service-hash | 9f0abe34da433c9b6db74bffa2466494a717b579a96b30a5d252e5090baea7be |
| request-id | CD5C:1E2ADA:D4E445:126ABF3:6A61A8C8 |
| html-safe-nonce | 143089d25b6540fbb870b06deac2e1f3dccbfb6940d2f81d55ce369acf02a33d |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJDRDVDOjFFMkFEQTpENEU0NDU6MTI2QUJGMzo2QTYxQThDOCIsInZpc2l0b3JfaWQiOiIxNDU3NDgxMjM2NTMzNTg2MTIwIiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | 40ce6463a965ef07cca8d444edf4a4581a241ef7f1383eac36fced86e168ebf7 |
| hovercard-subject-tag | discussion:8090323 |
| github-keyboard-shortcuts | repository,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/Voltron::DiscussionsFragmentsController/show/feilipu/Arduino_FreeRTOS_Library/144/discussion_layout |
| twitter:image | https://opengraph.githubassets.com/f1b5871c1d7b79978350f0c86046a51e8fbb6bc7576a5343f76c57991a03279c/feilipu/Arduino_FreeRTOS_Library/discussions/144 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/f1b5871c1d7b79978350f0c86046a51e8fbb6bc7576a5343f76c57991a03279c/feilipu/Arduino_FreeRTOS_Library/discussions/144 |
| og:image:alt | I wonder where is the stack used by ISR. Cortex-M devices have two SP registers so that ISR and tasks use seperate stack spaces. But AVR devices don't seem to have this capability. As for AVR devic... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| hostname | github.com |
| expected-hostname | github.com |
| None | 6f4633bcf01c1ad14b73fd07dd39ac31d61f3d3c2578ee08ec1792b7b351eeb9 |
| turbo-cache-control | no-preview |
| go-import | github.com/feilipu/Arduino_FreeRTOS_Library git https://github.com/feilipu/Arduino_FreeRTOS_Library.git |
| octolytics-dimension-user_id | 3955592 |
| octolytics-dimension-user_login | feilipu |
| octolytics-dimension-repository_id | 46898167 |
| octolytics-dimension-repository_nwo | feilipu/Arduino_FreeRTOS_Library |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 46898167 |
| octolytics-dimension-repository_network_root_nwo | feilipu/Arduino_FreeRTOS_Library |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | ac296ae7f21856f1f92adbad22f870b6fbb4b907 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width