{"id":98,"date":"2025-03-26T22:50:40","date_gmt":"2025-03-26T22:50:40","guid":{"rendered":"https:\/\/tech-kid.de\/wp\/?page_id=98"},"modified":"2025-03-27T11:56:37","modified_gmt":"2025-03-27T11:56:37","slug":"stm8-execute-code-from-ram","status":"publish","type":"page","link":"https:\/\/tech-kid.de\/wp\/?page_id=98","title":{"rendered":"STM8 &#8211; Code execution from RAM"},"content":{"rendered":"\n<p>Why do I need code execution from RAM? Well, if executing from RAM, some \u00b5Cs can shutdown the Flash Memory and thus consume a lower avarage current. This is useful for Ultra-low-power \u00b5Cs like my STM8L152, that can reduce the current consumption down to far less than 100\u00b5Amps. Also, in some cases execution from RAM can be faster than execution from Flash.<\/p>\n\n\n\n<p>To execute a function from RAM with SDCC, the function must be copied to a start-address within the RAM area of the microcontroller. <\/p>\n\n\n\n<pre class=\"wp-block-code\" style=\"font-size:12px\"><code>#include &lt;stdint.h&gt;\n\n#define RAMFUN_BUFLEN 25\n\n\/\/ Define a type of function pointer (same as ramfun is)\ntypedef uint8_t (*cbfun)(uint8_t);\n\n\/\/ This is where the function is copied\nchar RAMFUN_BUF&#91;RAMFUN_BUFLEN];\n\n\/\/ This function shall be copied to RAM\nuint8_t ramfun(uint8_t value)\n{\n\treturn value+1;\t\n}\n\n\/\/ Located directly after ramfun (so we can read out the length of \n\/\/ the function we want to copy to RAM\nint main(void)\n{   \n    \/\/ Preset RAMFUN Area with 0xEE (for debugging reasons)\n    for(uint8_t i=0; i&lt;RAMFUN_BUFLEN; i++)RAMFUN_BUF&#91;i]=0xEE;\n    \n    \/\/ Copy RAMFUN Segment to RAM\n    char* src=(char*)&amp;ramfun;\n    char* dst=(char*)RAMFUN_BUF;\n    for(uint16_t i=0; i&lt;((uint16_t)&amp;main - (uint16_t)&amp;ramfun); i++)\n    {\n        *dst++ = *src++;\n    }\n \n    \/\/ Declare Function Pointer\n    cbfun f = (cbfun)(&amp;RAMFUN_BUF&#91;0]);\n \n    \/\/ main (counts until 5)\n    uint8_t i=0;\n    while(1)\n    {\n \tif(i==5) continue;\n\ti=f(i);\n    }\n}<\/code><\/pre>\n\n\n\n<p>The code snippet above replaces the main.c file in the <a href=\"https:\/\/tech-kid.de\/Downloads\/?file=STM8L152_Minimal.tgz\"><strong>Minimal Example .tgz-File<\/strong><\/a>. It can be exchanged and compiled as described <a href=\"https:\/\/tech-kid.de\/wp\/?page_id=14\" data-type=\"page\" data-id=\"14\"><strong>before<\/strong><\/a>.<\/p>\n\n\n\n<p>It is easy to find the start position of the function in Flash, that has to be copied to RAM. For determination of the length of the function, there are several approaches found on the web, some of which use assembly to get the length of a code section. But one can simply find out the length by finding the beginning of the following function. In this case, it is important to have the right order: ramfun is located before main, hence, the length of ramfun is the difference of the addresses of the two functions as in the code snippet below. This method does not need any additional code segments and functionality is sufficient. <\/p>\n\n\n\n<pre class=\"wp-block-code\" style=\"font-size:12px\"><code>uint16_t length = ((uint16_t)&amp;main - (uint16_t)&amp;ramfun);<\/code><\/pre>\n\n\n\n<p>A disadvantage of this setup is that GDB cannot step into the RAM function. (At least, I did not get this managed). But it is not a huge problem because functions can be tested in flash and copied to RAM if they are known to work correctly.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Why do I need code execution from RAM? Well, if executing from RAM, some \u00b5Cs can shutdown the Flash Memory and thus consume a lower avarage current. This is useful for Ultra-low-power \u00b5Cs like my STM8L152, that can reduce the current consumption down to far less than 100\u00b5Amps. Also, in some cases execution from RAM &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/tech-kid.de\/wp\/?page_id=98\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;STM8 &#8211; Code execution from RAM&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":[],"_links":{"self":[{"href":"https:\/\/tech-kid.de\/wp\/index.php?rest_route=\/wp\/v2\/pages\/98"}],"collection":[{"href":"https:\/\/tech-kid.de\/wp\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/tech-kid.de\/wp\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/tech-kid.de\/wp\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tech-kid.de\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=98"}],"version-history":[{"count":11,"href":"https:\/\/tech-kid.de\/wp\/index.php?rest_route=\/wp\/v2\/pages\/98\/revisions"}],"predecessor-version":[{"id":117,"href":"https:\/\/tech-kid.de\/wp\/index.php?rest_route=\/wp\/v2\/pages\/98\/revisions\/117"}],"wp:attachment":[{"href":"https:\/\/tech-kid.de\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=98"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}