{"id":652,"date":"2013-08-04T14:19:57","date_gmt":"2013-08-04T14:19:57","guid":{"rendered":"http:\/\/blog.bachi.net\/?p=652"},"modified":"2013-08-04T15:57:58","modified_gmt":"2013-08-04T15:57:58","slug":"avr","status":"publish","type":"post","link":"https:\/\/blog.bachi.net\/?p=652","title":{"rendered":"AVR: avr-libc Internals"},"content":{"rendered":"<h3>pgm_read_byte()<\/h3>\n<h4>Abstract<\/h4>\n<p>The <code>pgm_read_byte()<\/code> is a macro that reads a byte of data stored in a specified address(PROGMEM area).<\/p>\n<h4>Source Code<\/h4>\n<p>The <code>pgm_read_byte()<\/code> is defined in <code>hardware\/tools\/avr\/avr\/include\/avr\/pgmspace.h<\/code> as below.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n#define pgm_read_byte(address_short)    pgm_read_byte_near(address_short)\r\n<\/pre>\n<p>The input is <code>address_short<\/code> and calls the <code>pgm_read_byte_near()<\/code> macro.<\/p>\n<h3>pgm_read_byte_near()<\/h3>\n<h4>Abstract<\/h4>\n<p>The <code>pgm_read_byte_near()<\/code> is a macro that reads a byte of data stored in a specified address(PROGMEM area).<\/p>\n<h4>Source Code<\/h4>\n<p>The <code>pgm_read_byte_near()<\/code> is defined in <code>hardware\/tools\/avr\/avr\/include\/avr\/pgmspace.h<\/code> as below.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n#define pgm_read_byte_near(address_short) __LPM((uint16_t)(address_short))\r\n<\/pre>\n<p>The input is <code>address_short<\/code> and the macro converts the <code>address_short<\/code> to <code>uint16_t<\/code>, then calls <code>__LPM()<\/code> macro.<\/p>\n<h3>__LPM()<\/h3>\n<h4>Abstract<\/h4>\n<p>The <code>__LPM()<\/code> is a macro that reads a byte of data stored in a specified address(PROGMEM area).<\/p>\n<h4>Source Code<\/h4>\n<p>The <code>__LPM()<\/code> is defined in <code>hardware\/tools\/avr\/avr\/include\/avr\/pgmspace.h<\/code> as below.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n#define __LPM(addr)         __LPM_enhanced__(addr)\r\n<\/pre>\n<p>The input is <code>addr<\/code> and just calls <code>__LPM_enhanced__()<\/code>.<br \/>\nSee <a href=\"http:\/\/de.wikipedia.org\/wiki\/Intrinsische_Funktion\">Intrinsic Functions<\/a><\/p>\n<h3>__LPM_enhanced__()<\/h3>\n<h4>Abstract<\/h4>\n<p>The <code>__LPM_enhanced()<\/code> is an assembler code that reads a byte of data stored in a specified address(PROGMEM area).<\/p>\n<h4>Source Code<\/h4>\n<p>The <code>__LPM_enhanced()<\/code> is defined in <code>hardware\/tools\/avr\/avr\/include\/avr\/pgmspace.h<\/code> as below.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n#define __LPM_enhanced__(addr)  \\\r\n(__extension__({                \\\r\n    uint16_t __addr16 = (uint16_t)(addr); \\\r\n    uint8_t __result;           \\\r\n    __asm__                     \\\r\n    (                           \\\r\n        &quot;lpm %0, Z&quot; &quot;\\n\\t&quot;      \\\r\n        : &quot;=r&quot; (__result)       \\\r\n        : &quot;z&quot; (__addr16)        \\\r\n    );                          \\\r\n    __result;                   \\\r\n}))\r\n<\/pre>\n<p>or newer avr-libc<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n#define __LPM_classic__(addr)   \\\r\n(__extension__({                \\\r\n    uint16_t __addr16 = (uint16_t)(addr); \\\r\n    uint8_t __result;           \\\r\n    __asm__                     \\\r\n    (                           \\\r\n        &quot;lpm&quot; &quot;\\n\\t&quot;            \\\r\n        &quot;mov %0, r0&quot; &quot;\\n\\t&quot;     \\\r\n        : &quot;=r&quot; (__result)       \\\r\n        : &quot;z&quot; (__addr16)        \\\r\n        : &quot;r0&quot;                  \\\r\n    );                          \\\r\n    __result;                   \\\r\n}))\r\n<\/pre>\n<p>The <code>lpm<\/code>, short for Load Program Memory, is a instruction that reads a byte of data from PROGMEM area. It substitue a data at <code>addr<\/code> for <code>__result<\/code>, then returns the <code>__result<\/code>.<\/p>\n<p>Sources:<br \/>\n<a href=\"http:\/\/garretlab.web.fc2.com\/en\/arduino\/inside\/avr\/pgmspace.h\/pgm_read_byte.html\">pgm_read_byte() marco<\/a><br \/>\n<a href=\"http:\/\/garretlab.web.fc2.com\/en\/arduino\/inside\/avr\/pgmspace.h\/pgm_read_byte_near.html\">pgm_read_byte_near() marco<\/a><br \/>\n<a href=\"http:\/\/garretlab.web.fc2.com\/en\/arduino\/inside\/avr\/pgmspace.h\/__LPM.html\">__LPM() marco<\/a><br \/>\n<a href=\"http:\/\/garretlab.web.fc2.com\/en\/arduino\/inside\/avr\/pgmspace.h\/__LPM_enhanced__.html\">__LPM_enhanced__() marco<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>pgm_read_byte() Abstract The pgm_read_byte() is a macro that reads a byte of data stored in a specified address(PROGMEM area). Source Code The pgm_read_byte() is defined in hardware\/tools\/avr\/avr\/include\/avr\/pgmspace.h as below. #define pgm_read_byte(address_short) pgm_read_byte_near(address_short) The input is address_short and calls the pgm_read_byte_near() macro. pgm_read_byte_near() Abstract The pgm_read_byte_near() is a macro that reads a byte of data stored [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[19],"tags":[],"class_list":["post-652","post","type-post","status-publish","format-standard","hentry","category-avr"],"_links":{"self":[{"href":"https:\/\/blog.bachi.net\/index.php?rest_route=\/wp\/v2\/posts\/652","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.bachi.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.bachi.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.bachi.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.bachi.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=652"}],"version-history":[{"count":13,"href":"https:\/\/blog.bachi.net\/index.php?rest_route=\/wp\/v2\/posts\/652\/revisions"}],"predecessor-version":[{"id":673,"href":"https:\/\/blog.bachi.net\/index.php?rest_route=\/wp\/v2\/posts\/652\/revisions\/673"}],"wp:attachment":[{"href":"https:\/\/blog.bachi.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=652"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.bachi.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=652"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.bachi.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=652"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}