<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mihail</title>
    <description>The latest articles on DEV Community by Mihail (@embedmind).</description>
    <link>https://dev.to/embedmind</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3512491%2F491836af-edc6-49d1-975a-0b0b97ba72eb.png</url>
      <title>DEV Community: Mihail</title>
      <link>https://dev.to/embedmind</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/embedmind"/>
    <language>en</language>
    <item>
      <title>JsonX: Mapping JSON to C Structs on Embedded Systems</title>
      <dc:creator>Mihail</dc:creator>
      <pubDate>Wed, 24 Sep 2025 10:51:34 +0000</pubDate>
      <link>https://dev.to/embedmind/jsonx-mapping-json-to-c-structs-on-embedded-systems-5e0o</link>
      <guid>https://dev.to/embedmind/jsonx-mapping-json-to-c-structs-on-embedded-systems-5e0o</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;JSON is everywhere - from web services to IoT. But here’s the catch: most popular JSON libraries were written with desktops and servers in mind, where nobody cares about a few extra megabytes. On microcontrollers, especially Cortex-M devices, every byte and every millisecond counts.&lt;/p&gt;

&lt;p&gt;Sure, you can push raw C structs around and even write them directly to a config file. It works, but debugging turns into a painful quest.&lt;/p&gt;

&lt;p&gt;At some point I got tired of wrestling with JSON on STM32: writing endless boilerplate to walk through &lt;a href="https://github.com/DaveGamble/cJSON" rel="noopener noreferrer"&gt;cJSON&lt;/a&gt; trees, hunting memory leaks, and guessing where malloc would betray me next. That’s when &lt;a href="https://github.com/embedmind/JsonX?tab=readme-ov-file" rel="noopener noreferrer"&gt;JsonX&lt;/a&gt; was born - a lightweight, minimalistic wrapper around cJSON, designed specifically for MCUs and RTOS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What JsonX Brings to the Table&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Automatic mapping JSON &amp;lt;&amp;gt; C structures via a flat &lt;code&gt;JX_ELEMENT[]&lt;/code&gt; description.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Memory control: no heap required (baremetal) or use your RTOS allocators (ThreadX/FreeRTOS).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Straightforward configuration via jx_config.h.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Less boilerplate when reading/writing configs and reports.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why not just use cJSON?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Good question. &lt;a href="https://github.com/embedmind/JsonX?tab=readme-ov-file" rel="noopener noreferrer"&gt;JsonX&lt;/a&gt; doesn’t replace &lt;a href="https://github.com/DaveGamble/cJSON" rel="noopener noreferrer"&gt;cJSON&lt;/a&gt; - it complements it. Inside, cJSON still does the parsing and builds its object tree. JsonX adds what’s usually missing in embedded projects:&lt;/p&gt;

&lt;p&gt;Mapping instead of manual walking: describe your schema once, JsonX takes care of the rest.&lt;/p&gt;

&lt;p&gt;Centralized memory management: all allocations go through a pool or a custom allocator, so you control fragmentation and leaks.&lt;/p&gt;

&lt;p&gt;RTOS-friendly integration: ThreadX, FreeRTOS, baremetal with static buffers, or even POSIX with custom allocators.&lt;/p&gt;

&lt;p&gt;In short: you keep the ecosystem of cJSON, but without the pain of raw malloc/free on MCUs and without hundreds of lines of repetitive glue code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Config structure&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;typedef struct&lt;br&gt;
{&lt;br&gt;
    char     device_name[32];&lt;br&gt;
    uint32_t baudrate;&lt;br&gt;
    bool     debug;&lt;br&gt;
} config_t;&lt;br&gt;
static config_t config;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Mapping description&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;JX_ELEMENT config_desc[] =&lt;br&gt;
{&lt;br&gt;
    JX_ELEMENT_STR ("device_name", config.device_name),&lt;br&gt;
    JX_ELEMENT_NUM ("baudrate",    config.baudrate),&lt;br&gt;
    JX_ELEMENT_BOOL("debug",       config.debug),&lt;br&gt;
    JX_ELEMENT_END()&lt;br&gt;
};&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Parsing JSON&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;jx_json_to_struct(json_str, config_desc);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Generating JSON&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;char buffer[256];&lt;br&gt;
jx_struct_to_json(config_desc, buffer, sizeof(buffer), JX_FORMAT_PRETTY);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Limitations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Numbers are currently doubles (like in cJSON). A strict int mode is planned.
-Max property name length is fixed via JX_PROPERTY_MAX_SIZE.&lt;/li&gt;
&lt;li&gt;No auto-expansion of element arrays — you define the limit at compile time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Where to Get It&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/embedmind/JsonX?tab=readme-ov-file" rel="noopener noreferrer"&gt;embedmind/JsonX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;STM32 usage example: &lt;a href="https://github.com/embedmind/JsonX/blob/main/src/example.c" rel="noopener noreferrer"&gt;src/example.c&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Roadmap&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Right now JsonX relies on cJSON for parsing and generation. But I’m considering a move towards a custom parser that would:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Work directly with memory pools (ThreadX block pool, FreeRTOS safe allocator).&lt;/li&gt;
&lt;li&gt;Operate fully without malloc/free.&lt;/li&gt;
&lt;li&gt;Reduce overhead and improve predictability in constrained systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whether this happens depends on how much demand JsonX gets from the embedded community.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;JsonX is a way to use cJSON on microcontrollers without unpredictable allocations and endless glue code. It’s especially useful in projects where every byte and millisecond matters — but you still want JSON to be as easy to work with as on a PC.&lt;/p&gt;

</description>
      <category>embedded</category>
      <category>json</category>
      <category>mapping</category>
      <category>microcontrollers</category>
    </item>
  </channel>
</rss>
