{"id":2739,"date":"2024-08-15T08:21:55","date_gmt":"2024-08-15T08:21:55","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=2739"},"modified":"2024-08-15T08:21:58","modified_gmt":"2024-08-15T08:21:58","slug":"cache-in-arm-cortex-m7-mpu-configuration","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=2739","title":{"rendered":"Cache in ARM Cortex M7: MPU Configuration"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"586\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/fig2.png-4-1024x586.webp\" alt=\"\" class=\"wp-image-2740\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/fig2.png-4-1024x586.webp 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/fig2.png-4-300x172.webp 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/fig2.png-4-768x440.webp 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/fig2.png-4-1150x658.webp 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/fig2.png-4-750x429.webp 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/fig2.png-4-400x229.webp 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/fig2.png-4-250x143.webp 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/fig2.png-4.webp 1310w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>In this guide, we shall configure the MPU to disable cache for certain region in order to get DMA operate normally.<\/p>\n\n\n\n<p>In this guide, we shall configure the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Creating the project.<\/li><li>Modification of linkerscript.<\/li><li>Results before MPU configuration.<\/li><li>MPU configuration.<\/li><li>Results after MPU configuration.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">8. Creating the project:<\/h2>\n\n\n\n<p>First, start STM32CubeIDE and select your workspace.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"572\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-01-26_06-24-03-2048x1143-1-1024x572.jpg\" alt=\"\" class=\"wp-image-2709\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-01-26_06-24-03-2048x1143-1-1024x572.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-01-26_06-24-03-2048x1143-1-300x167.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-01-26_06-24-03-2048x1143-1-768x429.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-01-26_06-24-03-2048x1143-1-1536x857.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-01-26_06-24-03-2048x1143-1-1150x642.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-01-26_06-24-03-2048x1143-1-750x419.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-01-26_06-24-03-2048x1143-1-400x223.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-01-26_06-24-03-2048x1143-1-250x141.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-01-26_06-24-03-2048x1143-1.jpg 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Select your STM32H7 based MCU, in my case STM32H747XI.<\/p>\n\n\n\n<p>Give a name to the project like cache or any other name.<\/p>\n\n\n\n<p>From System Core, select Cortex_M7 and enable both D and I cache.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"493\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-09-52-1024x493.jpg\" alt=\"\" class=\"wp-image-2710\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-09-52-1024x493.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-09-52-300x144.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-09-52-768x369.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-09-52-1536x739.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-09-52-2048x985.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-09-52-1150x553.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-09-52-750x361.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-09-52-400x192.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-09-52-250x120.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Next, from the DMA, add M2M (Memory to Memory) DMA as following:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"494\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-10-43-1024x494.jpg\" alt=\"\" class=\"wp-image-2711\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-10-43-1024x494.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-10-43-300x145.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-10-43-768x371.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-10-43-1536x741.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-10-43-2048x989.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-10-43-1150x555.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-10-43-750x362.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-10-43-400x193.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-10-43-250x121.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Keep the setting as default.<\/p>\n\n\n\n<p>Save the project and this will generate the code.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>In user code begin PV (Private variable):<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#define dataSize 10\n\nuint8_t txData[dataSize]__attribute__ ((section (&quot;.Txbuffer&quot;)));\nuint8_t rxData[dataSize]__attribute__ ((section (&quot;.Rxbuffer&quot;)));\n\n\nuint8_t counter;<\/pre><\/div>\n\n\n\n<p>Declare a symbolic name to hold the data size which is 10 in this.<\/p>\n\n\n\n<p>Tx and Rx data with attribute to push these variable to certain address.<\/p>\n\n\n\n<p>counter to indicate changing the variable over time.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">9. Linker Script Modification:<\/h2>\n\n\n\n<p>Open STM32H747XIHX_FLASH.ld file.<\/p>\n\n\n\n<p>Add the following after the discard section:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">.buffer (NOLOAD):\n {\t\n  . = ALIGN(1);\n  . = ABSOLUTE(0x30000000);\n   *(.Txbuffer)\n  \n  . = ABSOLUTE(0x30000040);\n   *(.Rxbuffer)\n  \n  } &gt; RAM_D2<\/pre><\/div>\n\n\n\n<p>This will put Tx buffer in address 0x30000000 and Rx buffer into address 0x30000040.<\/p>\n\n\n\n<p>These will be in RAM_D2 region of STM32H747XI.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Save the project.<\/p>\n\n\n\n<p>Build the project  and you should see RAM_D2 has ben occupied by 74 Bytes as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"27\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-15-at-11.03.53\u202fAM-1024x27.png\" alt=\"\" class=\"wp-image-2741\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-15-at-11.03.53\u202fAM-1024x27.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-15-at-11.03.53\u202fAM-300x8.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-15-at-11.03.53\u202fAM-768x20.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-15-at-11.03.53\u202fAM-1536x41.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-15-at-11.03.53\u202fAM-1150x31.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-15-at-11.03.53\u202fAM-750x20.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-15-at-11.03.53\u202fAM-400x11.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-15-at-11.03.53\u202fAM-250x7.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-15-at-11.03.53\u202fAM.png 1578w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>We have successfully move a variable from RAM_D1 to RAM_D2.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>In user code begin 3 while 1 loop: <\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\t  \/*CPU writes to SRAM1*\/\n\t  for (int i=0;i&lt;dataSize;i++)\n\t  {\n\t\t  txData[i]=counter;\n\t  }\n\n\n\t  \/*Start DMA*\/\n\t  HAL_DMA_Start(&amp;hdma_memtomem_dma1_stream0, (uint32_t)txData, (uint32_t)rxData, dataSize);\n\n\t  \/*Wait a little bit before aborting DMA*\/\n\t  HAL_Delay(100);\n\n\t  \/*Abort the DMA*\/\n\t  HAL_DMA_Abort(&amp;hdma_memtomem_dma1_stream0);\n\n\t  counter++;\n\t  HAL_Delay(100);<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">10. Results without MPU Configuration:<\/h2>\n\n\n\n<p>Save the project and start debug session:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"31\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-53-02-1024x31.jpg\" alt=\"\" class=\"wp-image-2712\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-53-02-1024x31.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-53-02-300x9.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-53-02-768x23.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-53-02-1536x46.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-53-02-1150x34.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-53-02-750x22.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-53-02-400x12.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-53-02-250x7.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-03_17-53-02.jpg 1872w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Add both tx and rx data to the live expression.<\/p>\n\n\n\n<p>Run the project and notice the rxData, it doesn\u2019t update as shown here:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"677\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/ezgif-5-1b335839b8.gif\" alt=\"\" class=\"wp-image-2713\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>As you can see, the TX data is updating but not the RX data. This means that we are facing cache coherency issue.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">11. MPU Configuration:<\/h2>\n\n\n\n<p>Open your .ioc file and select Cortex M7 and enable the MPU as following:<\/p>\n\n\n\n<p>The MPU shall be configured as following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>MPU Control Mode: Background Region Privileged accesses only + MPU disabled during hard faults.<\/li><li>MPU region to be enabled.<\/li><li>Region based address is 0x30000000 (RAM_D2 address).<\/li><li>MPU Region size: Since the size used by DMA is 74 bytes, the next available size is 128B.<\/li><li>TEX field to 0.<\/li><li>All access permitted.<\/li><li>Instruction access to enabled.<\/li><li>Sharable since both CPU and DMA will access to this region.<\/li><li>Disable the cache since it is the source of the problem.<\/li><li>Bufferable.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"587\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-15_11-11-03-1024x587.jpg\" alt=\"\" class=\"wp-image-2742\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-15_11-11-03-1024x587.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-15_11-11-03-300x172.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-15_11-11-03-768x440.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-15_11-11-03-1536x881.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-15_11-11-03-2048x1174.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-15_11-11-03-1150x659.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-15_11-11-03-750x430.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-15_11-11-03-400x229.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/2024-08-15_11-11-03-250x143.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Save the project and this will generate the code.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">12. Results with MPU:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>Build and debug the project and run it, this time, the rxData is being updated using the DMA.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"672\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2024\/08\/ezgif-5-9283a28761.gif\" alt=\"\" class=\"wp-image-2715\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>As you can see, the rx data is updating without the need to manually invalidate nor clean the cache every time.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Happy coding \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this guide, we shall configure the MPU to disable cache for certain region in order to get DMA operate normally. In this guide, we shall configure the following: Creating the project. Modification of linkerscript. Results before MPU configuration. MPU configuration. Results after MPU configuration. 8. Creating the project: First, start STM32CubeIDE and select your [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,11,12],"tags":[],"class_list":["post-2739","post","type-post","status-publish","format-standard","hentry","category-embedded-systems","category-peripheral-drivers","category-stm32"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2739"}],"collection":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2739"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2739\/revisions"}],"predecessor-version":[{"id":2743,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2739\/revisions\/2743"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2739"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2739"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2739"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}