یادداشت

GPIO های Boot Strapping در ESP32 و ESP8266؛ پین هایی که سرنوشت بوت را تعیین می کنند

بعضی از GPIOهای ESP32 و ESP8266 هنگام روشن شدن یا ریست، فقط یک ورودی عادی نیستند و حالت بوت تراشه را تعیین می کنند. اتصال نامناسب رله، سنسور، نمایشگر یا مقاومت به این پین ها می تواند باعث اجرا نشدن برنامه، ورود ناخواسته به حالت پروگرام یا ریست مداوم شود. در این مطلب پین های Boot Strapping، وضعیت صحیح آنها و اصول استفاده ایمن را بررسی می کنیم.

در پروژه های ESP32 و ESP8266 گاهی مدار بدون مشکل پروگرام می شود و حتی ساعت ها درست کار می کند، اما پس از قطع و وصل برق دیگر راه اندازی نمی شود. گاهی نیز برد فقط زمانی بوت می شود که یک ماژول، سنسور یا رله از آن جدا شده باشد.

در بسیاری از این موارد، مشکل از برنامه یا منبع تغذیه نیست؛ بلکه یکی از GPIOهای Boot Strapping در لحظه روشن شدن، در وضعیت نامناسب قرار گرفته است.

GPIO بوت استرپ چیست؟

پین های Boot Strapping یا Strapping Pins گروهی از GPIOها هستند که تراشه در لحظه روشن شدن یا ریست سخت افزاری، سطح منطقی آنها را می خواند. ترکیب صفر و یک این پین ها مشخص می کند که تراشه باید برنامه موجود در حافظه فلش را اجرا کند، وارد حالت پروگرام شود یا بعضی تنظیمات سخت افزاری داخلی را تغییر دهد.

پس از پایان مرحله بوت، این پین ها معمولا آزاد می شوند و می توان از آنها مانند یک GPIO معمولی استفاده کرد. همین موضوع باعث می شود مشکل کمی گمراه کننده باشد: پین پس از راه اندازی درست کار می کند، اما مدار متصل به آن ممکن است در همان چند میلی ثانیه اول، مانع بوت صحیح شود.

GPIOهای بوت استرپ در ESP8266

در ESP8266 سه پین اصلی حالت بوت را تعیین می کنند:

GPIO0 GPIO2 GPIO15

برای اجرای عادی برنامه از حافظه فلش، وضعیت این پین ها هنگام روشن شدن باید به شکل زیر باشد:

GPIO15 = LOW GPIO0 = HIGH GPIO2 = HIGH

برای ورود به حالت پروگرام از طریق UART نیز وضعیت مورد نیاز چنین است:

GPIO15 = LOW GPIO0 = LOW GPIO2 = HIGH

در نتیجه GPIO0 همان پینی است که با پایین نگه داشتن آن هنگام ریست، ESP8266 را وارد حالت پروگرام می کند. کلید FLASH یا BOOT روی بسیاری از بردهای توسعه نیز همین کار را انجام می دهد.

GPIO15 باید هنگام روشن شدن پایین باشد. اگر یک ماژول خارجی این پین را بالا بکشد، تراشه ممکن است به جای اجرای برنامه، وارد یک حالت بوت نامعتبر شود.

GPIO2 نیز برای بوت عادی باید بالا باشد. اتصال مستقیم یک مصرف کننده یا مداری که این پین را در زمان روشن شدن پایین نگه دارد، می تواند مانع اجرای برنامه شود.

معادل این پین ها روی Wemos D1 mini

در برد Wemos D1 mini شماره های چاپ شده با شماره واقعی GPIO یکسان نیستند:

D3 = GPIO0 D4 = GPIO2 D8 = GPIO15

بنابراین D3، D4 و D8 پین های کاملا ممنوع نیستند، اما باید با شناخت کامل از رفتار بوت استفاده شوند.

برای مثال اگر یک ماژول رله، ورودی D8 را هنگام روشن شدن بالا بکشد، ESP8266 ممکن است بوت نشود. همچنین اگر یک سنسور یا کلید، D3 یا D4 را برخلاف وضعیت مورد نیاز نگه دارد، برد ممکن است وارد حالت پروگرام یا یک حالت بوت نامعتبر شود.

GPIOهای بوت استرپ در ESP32 کلاسیک

در ESP32 کلاسیک، از جمله ESP32-WROOM-32 و بردهایی مانند LOLIN D32، پین های زیر Strapping Pin محسوب می شوند:

GPIO0 GPIO2 GPIO5 GPIO12 یا MTDI GPIO15 یا MTDO

این فهرست مخصوص ESP32 کلاسیک است. مدل هایی مانند ESP32-S2، ESP32-S3، ESP32-C3 و ESP32-C6 پین های استرپ متفاوتی دارند و باید دیتاشیت همان تراشه بررسی شود.

GPIO0 در ESP32

مهم ترین پین بوت در ESP32، پین GPIO0 است.

اگر GPIO0 هنگام ریست بالا باشد، برنامه از حافظه فلش اجرا می شود. اگر این پین هنگام ریست پایین نگه داشته شود، ESP32 وارد ROM Serial Bootloader می شود و برای دریافت برنامه جدید منتظر می ماند.

GPIO0 به صورت داخلی Pull-up دارد. با این حال، یک مدار خارجی با مقاومت کم یا خروجی فعال می تواند این Pull-up داخلی را شکست دهد و پین را پایین نگه دارد.

GPIO2 در ESP32

برای ورود مطمئن به حالت پروگرام، GPIO2 باید پایین یا بدون اتصال باشد. هنگامی که GPIO0 بالا و بوت عادی انتخاب شده است، وضعیت GPIO2 تاثیری بر بوت از فلش ندارد.

با وجود این، اگر GPIO2 در مدار پروگرام، کلید BOOT یا مدار ریست خودکار استفاده شود، اتصال یک ماژول خارجی می تواند در فرایند آپلود اختلال ایجاد کند.

GPIO12؛ حساس ترین پین استرپ ESP32

GPIO12 که با نام MTDI نیز شناخته می شود، یکی از حساس ترین پین های ESP32 کلاسیک است.

این پین هنگام ریست، ولتاژ تغذیه حافظه فلش را تعیین می کند:

GPIO12 = LOW یعنی ولتاژ معمول ۳.۳ ولت GPIO12 = HIGH یعنی انتخاب ولتاژ ۱.۸ ولت

در بیشتر ماژول های ESP32-WROOM-32، حافظه فلش با ۳.۳ ولت کار می کند. اگر یک مدار خارجی GPIO12 را هنگام روشن شدن بالا بکشد، ESP32 ممکن است ولتاژ نامناسبی برای فلش انتخاب کند. نتیجه می تواند اجرا نشدن برنامه، خطای خواندن فلش، ریست مداوم یا نمایش پیام Brownout باشد.

به همین دلیل بهتر است GPIO12 برای اتصال به ماژول هایی که در زمان روشن شدن خروجی فعال دارند استفاده نشود. اگر استفاده از آن ضروری است، مدار خارجی نباید بتواند این پین را هنگام ریست بالا نگه دارد.

GPIO15 در ESP32

GPIO15 یا MTDO در زمان بوت، چاپ پیام های ROM روی UART0 را کنترل می کند. حالت پیش فرض آن بالا است و پیام های بوت چاپ می شوند. پایین بودن این پین می تواند پیام های اولیه بوت را خاموش کند.

GPIO15 همراه GPIO5 در تنظیم زمان بندی رابط SDIO Slave نیز نقش دارد. در پروژه های معمولی که از این قابلیت استفاده نمی کنند، مهم ترین نکته این است که مدار خارجی نباید وضعیت پیش فرض این پین را در زمان روشن شدن بدون دلیل تغییر دهد.

GPIO5 در ESP32

GPIO5 نیز یکی از پین های استرپ ESP32 کلاسیک است و حالت پیش فرض آن Pull-up است. این پین همراه GPIO15 در تنظیم زمان بندی SDIO Slave نقش دارد.

در بیشتر پروژه های عادی، تغییر وضعیت GPIO5 باعث ورود مستقیم تراشه به حالت پروگرام نمی شود، اما بهتر است تجهیزات خارجی در زمان ریست آن را با یک خروجی کم مقاومت در وضعیت مخالف قرار ندهند.

تفاوت پین استرپ با پین رزرو شده فلش

هر پین استرپ لزوما همیشه غیرقابل استفاده نیست. این پین ها پس از بوت معمولا می توانند به عنوان GPIO کار کنند.

در مقابل، بعضی پین ها مستقیما به حافظه فلش داخلی ماژول متصل هستند. در ماژول های متداول ESP8266 و ESP32، GPIOهای 6 تا 11 معمولا برای ارتباط با حافظه فلش استفاده می شوند و نباید برای اتصال تجهیزات خارجی انتخاب شوند.

در بعضی مدل های ESP32 دارای PSRAM نیز پین های دیگری توسط حافظه اشغال شده اند. بنابراین همیشه باید علاوه بر نام تراشه، دیتاشیت ماژول مورد استفاده نیز بررسی شود.

چرا مدار روی میز کار می کند اما پس از ساخت نهایی بوت نمی شود؟

در آزمایش اولیه ممکن است ماژول جانبی هنوز تغذیه نشده باشد، ورودی آن در حالت High Impedance قرار داشته باشد یا اتصال آن موقتی باشد. پس از مونتاژ نهایی، همان ماژول می تواند از طریق مقاومت Pull-up، Pull-down، ترانزیستور، LED یا مدار محافظ خود سطح پین استرپ را تغییر دهد.

همچنین فشردن کلید Reset با قطع و وصل کامل برق یکسان نیست. بعضی ماژول های جانبی هنگام روشن شدن رفتار متفاوتی دارند و ممکن است فقط در Cold Boot مشکل ایجاد کنند.

به همین دلیل یک پروژه باید هم با کلید Reset و هم با چند بار قطع و وصل کامل منبع تغذیه آزمایش شود.

اتصال رله به پین های استرپ

بسیاری از ماژول های رله ورودی Active Low دارند و در ورودی آنها مقاومت، اپتوکوپلر یا ترانزیستور قرار گرفته است. این ساختار ممکن است یک پین استرپ را هنگام روشن شدن پایین بکشد.

نتیجه فقط بوت نشدن تراشه نیست. در برخی مدارها ممکن است رله برای لحظه ای فعال شود و یک بار واقعی مانند موتور، پمپ یا هیتر را ناخواسته روشن کند.

برای کنترل رله بهتر است از GPIOهای آزاد و بدون نقش بوت استفاده شود. اگر ناچار به استفاده از پین استرپ هستیم، باید مدار واسط به گونه ای طراحی شود که تا پایان بوت در حالت High Impedance باقی بماند.

اتصال LED، کلید و سنسور

LED متصل به یک پین استرپ می تواند از طریق مقاومت خود سطح منطقی پین را تغییر دهد. جهت LED و محل اتصال مقاومت اهمیت دارد.

کلید نیز نباید در حالت عادی پین را برخلاف وضعیت مورد نیاز بوت نگه دارد. کلید BOOT یک استثنای عمدی است؛ زیرا وظیفه آن پایین کشیدن GPIO0 برای ورود به حالت پروگرام است.

خروجی بعضی سنسورها نیز هنگام روشن شدن مشخص نیست. سنسور ممکن است قبل از پایدار شدن تغذیه، پین را بالا، پایین یا شناور کند. در چنین شرایطی استفاده از یک بافر سه حالته، ترانزیستور، ماسفت یا انتخاب GPIO دیگر راه حل مطمئن تری است.

اصول طراحی ایمن

در صورت وجود پین آزاد، تجهیزات جانبی را به پین های استرپ متصل نکنید.

اگر استفاده از یک پین استرپ ضروری است، وضعیت مورد نیاز آن در زمان بوت را از دیتاشیت بررسی کنید.

مدار خارجی باید هنگام روشن شدن High Impedance باشد یا با وضعیت پیش فرض پین تضاد نداشته باشد.

از اتصال مستقیم خروجی یک میکروکنترلر دیگر به پین استرپ خودداری کنید، مگر اینکه ترتیب روشن شدن و وضعیت خروجی آن کاملا کنترل شده باشد.

مقاومت های Pull-up و Pull-down خارجی را بدون بررسی مدار مرجع اضافه نکنید. یک مقاومت قوی در جهت اشتباه می تواند Pull داخلی تراشه را خنثی کند.

مدار را با پروگرام از طریق USB، ریست سخت افزاری و قطع و وصل کامل برق آزمایش کنید.

آزمایش را با همه ماژول های جانبی متصل و روشن انجام دهید، نه فقط با برد ESP به تنهایی.

نشانه های خطای Boot Strapping

اگر برد فقط با نگه داشتن یا رها کردن یک کلید بوت می شود، ابتدا GPIO0 را بررسی کنید.

اگر ESP8266 پیام boot mode غیرعادی نمایش می دهد، وضعیت GPIO15، GPIO0 و GPIO2 را اندازه گیری کنید.

اگر ESP32 وارد حالت Download Boot می شود و برنامه اجرا نمی شود، GPIO0 و GPIO2 را بررسی کنید.

اگر ESP32-WROOM-32 خطای فلش، ریست متوالی یا رفتار نامشخص دارد، بررسی کنید که GPIO12 هنگام روشن شدن بالا کشیده نشده باشد.

اگر برد بدون یک ماژول جانبی بوت می شود اما با اتصال آن از کار می افتد، ورودی و خروجی همان ماژول را در لحظه روشن شدن اندازه گیری کنید.

برای اندازه گیری بهتر است از اسیلوسکوپ یا Logic Analyzer استفاده شود، زیرا مولتی متر ممکن است تغییرات بسیار کوتاه لحظه بوت را نشان ندهد.

جمع بندی

پین های Boot Strapping فقط GPIOهای معمولی نیستند. آنها در چند میلی ثانیه نخست روشن شدن، درباره نحوه راه اندازی تراشه تصمیم می گیرند و سپس به مدار کاربر تحویل داده می شوند.

در ESP8266 باید به GPIO0، GPIO2 و GPIO15 توجه ویژه داشت. در ESP32 کلاسیک نیز GPIO0، GPIO2، GPIO5، GPIO12 و GPIO15 پین های استرپ هستند؛ به ویژه GPIO12 که بالا بودن آن می تواند ولتاژ حافظه فلش را به ۱.۸ ولت تغییر دهد.

شناخت این پین ها از خطاهایی جلوگیری می کند که معمولا به اشتباه به برنامه، منبع تغذیه یا خرابی برد نسبت داده می شوند. یک انتخاب درست در مرحله طراحی مدار می تواند ساعت ها عیب یابی در مرحله ساخت و راه اندازی را حذف کند.

→ بازگشت به وبلاگ