ساخت Message، هدرها، Extended Message و Chunking در USB Power Delivery
در مقاله هفتم وارد لایه Protocol میشویم و یاد میگیریم یک USB PD Message چگونه ساخته میشود، فیلدهای هدر چه معنایی دارند، پیامهای بزرگ چگونه با Extended Header توصیف میشوند و انتقال Chunked / Unchunked در سطح بایت چه تفاوتی دارد.
دامنه این مقاله
محتوای این مقاله فقط بر بخشهای 6.1 تا 6.2.1.2.5.2 و صفحات ۱۱۴ تا ۱۲۷ سند USB Power Delivery Specification, Revision 3.2, Version 1.1, 2024-10 استوار است. فهرست و رفتار تکتک Control Messageها از Section 6.3 آغاز میشود و برای مقاله ۸ محفوظ مانده است. ساختار Data Objectهای توان، Request، BIST و VDM نیز در مقالههای بعدی مجموعه بررسی خواهد شد.
از Packet فیزیکی به Message قابل تفسیر
لایه Protocol داده خام را به واحدی تبدیل میکند که نقش، نوع، ترتیب و اندازه آن قابل تشخیص باشد.
در مقالههای ۴ تا ۶ دیدیم که PHY چگونه Preamble، Ordered Set، کدگذاری 4b5b، سیگنال BMC، CRC و EOP را روی لاین CC مدیریت میکند. با این حال، تشخیص صحیح یک Packet هنوز بهتنهایی مشخص نمیکند فرستنده چه درخواستی دارد. برای دانستن اینکه Packet یک GoodCRC، Source_Capabilities، Request یا پیام امنیتی است، باید بخش ساختهشده توسط Protocol Layer تفسیر شود.
Protocol Layer نخست یک Message Header شانزدهبیتی میسازد. این هدر اعلام میکند Message از نوع معمولی یا Extended است، چه تعداد Data Object دارد، MessageID آن چیست، از کدام نقش توان و داده صادر شده و با کدام Revision استاندارد کار میکند. اگر پیام Extended باشد، یک Extended Message Header شانزدهبیتی دیگر نیز اندازه کل Data Block و اطلاعات Chunking را مشخص میکند.
بنابراین باید میان سه واژه تمایز روشنی ایجاد کنیم. Message محتوایی است که Protocol Layer میسازد؛ Packet پوشش فیزیکی کامل شامل Preamble، SOP*، Message، CRC و EOP است؛ و Data Block داده واقعی یک Extended Message است که ممکن است یکجا یا در چند Chunk منتقل شود. مخلوطکردن این سه سطح، علت رایج خطا در خواندن Captureهای USB PD است.
Protocol Layer چه مسئولیتهایی دارد؟
Chapter 6 فقط درباره چیدمان چند بیت نیست. استاندارد دامنه Protocol Layer را شامل ساخت و استفاده از Message، Timerها و Timeoutها، شمارنده Message و Retry، عملیات Reset، مدیریت خطا و رفتار State میداند. مقاله حاضر فقط نخستین بخش این زنجیره، یعنی ساخت Message را پوشش میدهد؛ Timer، Reset و Stateها در مقالات ۱۵ تا ۱۷ بهصورت مستقل بررسی خواهند شد.
در مسیر ارسال، Message در Protocol Layer ایجاد و به PHY تحویل میشود. PHY پوشش لازم برای انتقال روی لاین CC را اضافه میکند. در مسیر دریافت، PHY ابتدا Packet را بازیابی و اعتبار فیزیکی آن را کنترل میکند و سپس بخش Message را به Protocol Layer میدهد. به همین دلیل Message Header جزو داده Protocol است، اما Preamble، SOP*، CRC و EOP اجزای PHY باقی میمانند.
فقط یک Message Header شانزدهبیتی دارد و برای مدیریت جریان پیام یا تبادلهایی استفاده میشود که Data Object جداگانه نمیخواهند.
پس از هدر، یک تا هفت Data Object سیودوبیتی حمل میکند و طول Message آن از ۴۸ تا ۲۴۰ بیت تغییر میکند.
علاوه بر Message Header یک Extended Header دارد و برای Data Blockهایی تا ۲۶۰ بایت بهکار میرود.
سه قالب اصلی Message داخل Packet
تمام Messageها از یک Message Header و یک بخش داده با طول متغیر، حتی طول صفر، تشکیل میشوند. در Control Message بخش داده صفر است. در Data Message پس از Header از یک تا هفت Data Object قرار میگیرد. در Extended Message، Extended Header پیش از Data Block میآید و طول داده میتواند از صفر تا ۲۶۰ بایت باشد.
هر سه قالب وقتی به Packet تبدیل میشوند، در سمت چپ خود Preamble و SOP* و در سمت راست CRC و EOP دارند. CRC روی محتوای Message اعمال میشود، اما خودش توسط PHY افزوده میشود. این تفکیک هنگام ساخت Analyzer اهمیت دارد: Decoder فیزیکی باید ابتدا مرز Packet و صحت CRC را بهدست آورد و بعد Decoder پروتکل، Header و Payload را معنا کند.
قالب Control Message؛ بخش Protocol فقط از Message Header تشکیل میشود و هیچ Data Object ندارد.
قالب Data Message؛ پس از Message Header از یک تا هفت Data Object سیودوبیتی حمل میشود.
قالب Extended Message؛ Extended Header اندازه و وضعیت Chunking داده را پیش از Data Block توصیف میکند.
| نوع Message | بخش Protocol Layer | اندازه داده | کاربرد نمونه |
|---|---|---|---|
| Control | Message Header | صفر Data Object؛ کل Message برابر ۱۶ بیت | مدیریت جریان ارتباط |
| Data | Message Header + 1..7 Data Objects | ۴۸ تا ۲۴۰ بیت | Capabilities، مذاکره توان، BIST و VDM |
| Extended | Message Header + Extended Header + Data | Data Block تا ۲۶۰ بایت | اطلاعات Source و باتری، Security، Firmware Update و VDEM |
Message Header؛ نقشه شانزدهبیتی هر پیام
Message Header نخستین جزء هر Message است و اطلاعات پایه لازم برای Decode را در خود دارد. برخی بیتها برای تمام SOP*ها یکساناند و بعضی بیتها بر اساس مقصد Packet معنای متفاوت میگیرند. مهمترین نکته این است که Decoder نباید یک فیلد را بدون دانستن SOP، Extended و Number of Data Objects تفسیر کند.
| بیتها | دامنه SOP | نام فیلد | نقش در Decode |
|---|---|---|---|
| 15 | SOP* | Extended | تفکیک Message معمولی از Extended Message |
| 14..12 | SOP* | Number of Data Objects | تعداد Data Object یا فیلد Reserved در Extended Unchunked |
| 11..9 | SOP* | MessageID | شماره ترتیبی سهبیتی از شمارنده چرخشی |
| 8 | SOP | Port Power Role | ۰ برای Sink و ۱ برای Source |
| 8 | SOP' / SOP'' | Cable Plug | تشخیص صدور پیام از Port یا Cable Plug/VPD |
| 7..6 | SOP* | Specification Revision | Revision مورد استفاده برای همان Message |
| 5 | SOP | Port Data Role | ۰ برای UFP و ۱ برای DFP |
| 5 | SOP' / SOP'' | Reserved | باید مطابق قواعد Reserved مدیریت شود |
| 4..0 | SOP* | Message Type | کد نوع پیام پس از تعیین Control، Data یا Extended |
Table 6.1 - Message Header
Extended و Number of Data Objects؛ اولین تصمیم Decoder
بیت Extended اگر صفر باشد، Message یا Control است یا Data. در این حالت مقدار Number of Data Objects تعیینکننده است: صفر یعنی هیچ Data Object بعد از Header وجود ندارد و Message از نوع Control است؛ مقدار یک تا هفت یعنی همان تعداد Data Object سیودوبیتی بعد از Header آمده و Message از نوع Data است.
اگر Extended برابر یک باشد، پس از Message Header حتماً Extended Message Header میآید. در حالت Chunked، فیلد Number of Data Objects تعداد Data Objectهای همین Message را پس از Padding تا مرز چهار بایت نشان میدهد و Extended Header نیز بخشی از نخستین Data Object محسوب میشود. در حالت Unchunked این فیلد Reserved است و طول واقعی تنها از Data Size داخل Extended Header بهدست میآید.
نتیجه عملی آن است که Number of Data Objects همیشه طول کل Data Block را نشان نمیدهد. در Data Message معمولی تعداد Objectهای همان Message است؛ در Extended Chunked فقط طول Chunk حاضر را توصیف میکند؛ و در Extended Unchunked اصلاً مرجع طول نیست. Decoder باید ابتدا Extended و سپس Chunked را بخواند و بعد درباره معنای NDO تصمیم بگیرد.
Extended=0 + NDO=1..7 → Data
Extended=1 → Extended Header decides Chunking and Data Size
MessageID؛ شمارنده چرخشی برای ترتیب و پذیرش پیام
MessageID یک فیلد سهبیتی است و از شمارندهای میآید که فرستنده نگهداری میکند. سه بیت فقط مقادیر صفر تا هفت را پوشش میدهند؛ بنابراین شمارنده پس از هفت دوباره به صفر بازمیگردد. هدف این فیلد ساخت شماره یکتای دائمی نیست، بلکه فراهمکردن شناسه ترتیبی کوتاه در چارچوب ارتباط جاری است.
MessageIDCounter در Power-on و همچنین در نتیجه Soft Reset یا Hard Reset با صفر مقداردهی اولیه میشود. شمارنده زمانی افزایش مییابد که دریافت موفق Message با GoodCRC تأیید شده باشد. بنابراین صرف قرارگرفتن Packet روی لاین CC یا پایان ارسال، دلیل افزایش شمارنده نیست؛ تأیید دریافت موفق نقطه تغییر آن است.
در Capture، تکرار همان MessageID لزوماً به معنی خرابی شمارنده نیست؛ ممکن است انتقال قبلی GoodCRC نگرفته و دوباره ارسال شده باشد. از طرف دیگر، مشاهده پرش بیدلیل ID پس از انتقال ناموفق میتواند نشان دهد پیادهسازی فرستنده موفقیت را زودتر از زمان صحیح ثبت کرده است. Reset نیز باید در تحلیل لحاظ شود، زیرا بازگشت ناگهانی به صفر پس از Soft Reset یا Hard Reset رفتار مورد انتظار است.
Power Role، Data Role و Cable Plug؛ یک بیت با معناهای وابسته به SOP
در Packet نوع SOP، بیت ۸ Power Role فعلی Port را نشان میدهد: صفر برای Sink و یک برای Source. برخی Messageها ذاتاً فقط از یک نقش صادر میشوند؛ برای مثال Request از Sink و Get_Sink_Cap_Extended از Source میآید. بااینحال، استاندارد تصریح میکند گیرنده نباید نادرستی Power Role یک Message دریافتی را بهتنهایی مبنای Soft Reset، Hard Reset یا Error Recovery قرار دهد.
هنگام Power Role Swap و Fast Role Swap تغییر این بیت دقیقاً با مرحله تغییر نقش هماهنگ میشود. Initial Source در PS_RDY که خاموششدن منبع خود را اعلام میکند، Power Role را Sink میگذارد. Initial Sink نیز پس از دریافت PS_RDY از Initial Source، در Messageهایی که Policy Engine آغاز میکند خود را Source معرفی میکند. یک ظرافت مهم در FRS این است که GoodCRC پاسخ به PS_RDY هنوز با Power Role برابر Sink ارسال میشود، زیرا GoodCRC را Protocol Layer آغاز میکند؛ Messageهای بعدی Policy Engine نقش Source را نشان میدهند.
بیت ۵ در SOP، Data Role است: صفر UFP و یک DFP. اگر USB Type-C Port پیامی غیر از GoodCRC با Data Role برابر نقش داده فعلی خودش دریافت کند، باید عملیات USB Type-C Error Recovery اجرا شود. پس از Attachment یا Hard Reset، Port دارای Rd به UFP و Port دارای Rp به DFP بازمیگردد. برای Port فاقد توانایی USB Communications نیز Source به DFP و Sink به UFP پیشفرض میشود.
همین جایگاههای بیت در SOP' و SOP'' معنای Port ندارند. بیت ۸ به Cable Plug تبدیل میشود: صفر یعنی Message از DFP یا UFP آمده و یک یعنی از Cable Plug یا VPD صادر شده است. بیت ۵ نیز Reserved است. پس تفسیر Header بدون تشخیص Ordered Set ابتدایی ممکن است نقشهای کاملاً ساختگی تولید کند.
Specification Revision؛ انتخاب زبان مشترک Portها و کابل
فیلد دوبیتی Specification Revision چهار مقدار دارد: 00b برای Revision 1.0 که Deprecated است، 01b برای Revision 2.0، 10b برای Revision 3.x و 11b که Reserved است و نباید استفاده شود. داده هر Message باید با Revision درجشده در Header همان Message سازگار باشد؛ استفاده از یک Header نسخه ۲ برای ساختار مختص نسخه ۳ یک ناسازگاری واقعی است.
پس از Attach فیزیکی یا منطقی، Portها Revision مشترک را کشف میکنند و تا Detach، Hard Reset یا Error Recovery همان سطح را نگه میدارند. Source ابتدا Source_Capabilities را با بالاترین Revision قابل پشتیبانی خود میفرستد. Sink در Request بالاترین Revision پشتیبانیشدهای را انتخاب میکند که از مقدار Source بالاتر نباشد. سپس هر دو Port همان Revision درجشده در Request را برای ارتباطات بعدی بهکار میبرند.
مذاکره با Cable Plug مسیر جداگانهای دارد. پیش از First Explicit Contract، VCONN Source یک Discover Identity REQ روی SOP' با بالاترین Revision خود میفرستد و Cable Plug با بالاترین Revision پشتیبانیشدهای پاسخ میدهد که از مقدار دریافتی بیشتر نباشد. تا تشکیل Explicit Contract، مقدار پایینتر مبنای ارتباط است؛ پس از Contract، ترکیب Revision دو Port و Cable Plug مطابق جدول Interoperability تعیین میشود.
فیلد Revision در GoodCRC معنای اطلاعاتی مستقل ندارد و گیرنده آن را don't care در نظر میگیرد. پاسخ به Message نسخه ۲ باید Revision 2.0 داشته باشد؛ پاسخ به Message نسخه ۳ میتواند 2.0 یا 3.x باشد. Cable Plug نیز وضعیت توافق Revision را ذخیره نمیکند و هر بار بر اساس Message دریافتی پاسخ مناسب میدهد. در کابل دو سر، هر دو Cable Plug باید برای SOP' و SOP'' از یک Revision استفاده کنند.
| Revision پورت ۱ | Revision کابل | Revision پورت ۲ | Port-to-Port | Port-to-Cable |
|---|---|---|---|---|
| 2 | 2 | 2 | 2 | 2 |
| 2 | 2 | 3 | 2 | 2 |
| 2 | 3 | 2 | 2 | 2 |
| 2 | 3 | 3 | 2 | 2 |
| 3 | 2 | 2 | 2 | 2 |
| 3 | 2 | 3 | 3 | 2 |
| 3 | 3 | 2 | 2 | 2 |
| 3 | 3 | 3 | 3 | 3 |
Table 6.2 - Revision Interoperability during an Explicit Contract
Message Type؛ چرا پنج بیت بهتنهایی کافی نیست؟
فیلد Message Type پنج بیت دارد، اما یک مقدار عددی بدون Context کامل نیست. برای Messageهای غیر Extended ابتدا Number of Data Objects بررسی میشود: اگر صفر باشد، کد پنجبیتی از جدول Control Messageها Decode میشود؛ اگر غیرصفر باشد، همان کد باید در جدول Data Messageها جستوجو شود. بنابراین یک Code میتواند در دو فضای معنایی متفاوت به دو Message مختلف اشاره کند.
برای Extended Message، Extended برابر یک است و کد Message Type در فهرست پیامهای Extended معنا پیدا میکند. این طراحی اجازه میدهد فضای پنجبیتی کدها در چند خانواده مجدداً استفاده شود. در Analyzer نیز ترتیب صحیح Decode باید چنین باشد: SOP*، Extended، NDO یا Extended Header، سپس Message Type. نمایش نام Message فقط بر اساس پنج بیت انتهایی Header میتواند خروجی اشتباه اما ظاهراً معتبر بسازد.
Extended Message Header؛ اندازه کل و وضعیت Chunk
وقتی Extended در Message Header یک باشد، شانزده بیت بعدی Extended Message Header هستند. این هدر چهار اطلاعات اصلی میدهد: آیا انتقال Chunked است، شماره Chunk حاضر یا درخواستی چیست، Message یک Chunk Request است یا پاسخ حاوی داده، و Data Block کامل چند بایت دارد. بیت ۹ Reserved است.
Extended Message ممکن است کل Data Block را در یک Message حمل کند یا آن را به مجموعهای از Chunkها تقسیم نماید. در انتقال Chunked، همه Chunkها بهجز آخرین Chunk دارای MaxExtendedMsgChunkLen بایت داده هستند و آخرین Chunk باقیمانده را حمل میکند. اگر طول نهایی روی مرز چهار بایت قرار نگیرد، Padding صفر افزوده میشود تا Payload با Data Objectهای ۳۲ بیتی همراستا شود.
| بیتها | نام فیلد | معنا |
|---|---|---|
| 15 | Chunked | صفر برای Unchunked و یک برای انتقال مبتنی بر Chunk |
| 14..11 | Chunk Number | شماره Chunk حاضر یا Chunk درخواستی، از صفر تا حداکثر ۹ |
| 10 | Request Chunk | یک برای درخواست Chunk و صفر برای Message حاوی Chunk |
| 9 | Reserved | فاقد معنای تعریفشده در این Revision |
| 8..0 | Data Size | تعداد کل بایتهای Data Block، نه فقط داده Chunk حاضر |
Table 6.3 - Extended Message Header
انتخاب Chunked یا Unchunked چگونه انجام میشود؟
Port Partnerها هنگام مذاکره Explicit Contract، بیت Unchunked Extended Messages Supported را در Source_Capabilities و Request مبادله میکنند. فقط اگر هر دو طرف پشتیبانی Unchunked را یک اعلام کنند، Extended Messageها با Chunked=0 منتقل میشوند. اگر حتی یکی از دو طرف مقدار صفر داشته باشد، Chunked=1 مبنای تمام Extended Messageها خواهد بود.
در حالت Chunked، مکانیزم درخواست و پاسخ Chunk فعال است، Padding اعمال میشود و Number of Data Objects طول همین Message را بیان میکند. در حالت Unchunked، کل Data Block در یک Message میآید، درخواست Chunk وجود ندارد، Padding این مثالها استفاده نمیشود و NDO در Message Header Reserved است؛ Data Size تنها مرجع طول داده خواهد بود.
این تصمیم تا Detach، Hard Reset، Error Recovery یا حذف توان Source معتبر میماند؛ استثنا مربوط به حذف برنامهریزیشده توان در Power Role Swap و Fast Role Swap است. ارتباط Extended با Cable Plug محدودتر است: VCONN Source فقط Extended Messageهای Chunked برای Cable Plug میفرستد و Cable Plug نیز پیامهای بزرگتر از طول Legacy را Chunked ارسال میکند. در هر حال، پیادهسازیای که Extended Message را پشتیبانی میکند باید Chunking را نیز پشتیبانی کند.
| پشتیبانی Unchunked در Sink | پشتیبانی Unchunked در Source | مقدار Chunked | روش انتقال |
|---|---|---|---|
| 0 | 0 | 1 | Chunked |
| 0 | 1 | 1 | Chunked |
| 1 | 0 | 1 | Chunked |
| 1 | 1 | 0 | Unchunked |
Table 6.4 - Use of Unchunked Message Supported bit
Chunk Number، Request Chunk و Data Size؛ سه فیلد با سه مقیاس متفاوت
Chunk Number فقط وقتی معتبر است که Chunked برابر یک باشد. در Message حاوی داده، شماره Chunk از صفر شروع میشود و برای هر Chunk یک واحد افزایش مییابد. حداکثر مقدار تعریفشده ۹ است؛ یعنی یک Data Block میتواند در مجموع تا ده Chunk، شماره صفر تا نه، منتقل شود. اگر Chunked صفر باشد، Chunk Number نیز باید صفر قرار گیرد.
نخستین Chunk یعنی Chunk 0 بدون درخواست جداگانه ارسال میشود. از Chunk 1 به بعد، فرستنده فقط پس از دریافت Chunk Request متناظر اجازه دارد Chunk را برگرداند. درخواستکننده نیز باید همیشه Chunk بعدی در توالی را درخواست کند، نه یک شماره دلخواه یا Chunkی که هنوز نوبت آن نرسیده است. Request و Response باید مقدار Message Type یکسان داشته باشند تا ارتباط آنها مشخص باقی بماند.
Request Chunk اگر یک باشد، Message داده Extended واقعی حمل نمیکند و Data Size باید صفر باشد. اگر Request Chunk صفر باشد، Message پاسخ حاوی Chunk است. Data Size در پاسخ، اندازه کل Data Block را اعلام میکند و در همه Chunkها همان اندازه کامل باقی میماند؛ برای مثال در Chunk 1 یک پاسخ ۳۰ بایتی، Data Size همچنان ۳۰ است، حتی اگر Chunk حاضر فقط چهار بایت پایانی را حمل کند.
اگر Data Size از مقدار مورد انتظار یک نوع Message بیشتر، اما همچنان حداکثر برابر MaxExtendedMsgLen باشد، گیرنده باید فیلدهای مورد انتظار را پردازش و فیلدهای اضافی را Ignore کند. این قاعده به سازگاری نسخههای آینده کمک میکند، زیرا اضافهشدن داده انتهایی الزاماً Parser قدیمیتر را از کار نمیاندازد.
مثال Unchunked؛ درخواست ۷ بایتی و پاسخ ۳۰ بایتی در یک Message
استاندارد برای مقایسه روشن دو روش، یک Host و Charger را در نظر میگیرد. Host یک Security_Request با Data Size برابر ۷ بایت میفرستد و Charger یک Security_Response با Data Size برابر ۳۰ بایت برمیگرداند. این اندازهها صرفاً آموزشیاند و قرار نیست قالب واقعی محتوای Security را تعریف کنند.
وقتی هر دو Port از Unchunked پشتیبانی میکنند، Chunked در هر دو Message صفر است. درخواست ۷ بایتی بهصورت Message Header، Extended Header و هفت بایت B0 تا B6 منتقل میشود؛ Number of Data Objects صفر و Reserved است و Padding وجود ندارد. Data Size=7 مرز داده را مشخص میکند.
پاسخ ۳۰ بایتی نیز در یک Message میآید. پس از دو Header، بایتهای B0 تا B29 بدون شکستن به Chunk و بدون Padding منتقل میشوند. NDO همچنان صفر و Reserved است و Data Size=30 طول را تعیین میکند. هر Message مستقل GoodCRC خود را دریافت میکند، اما هیچ Chunk Request میان Host و Charger ردوبدل نمیشود.
توالی کامل تبادل Unchunked؛ درخواست ۷ بایتی و پاسخ ۳۰ بایتی هرکدام در یک Message مستقل منتقل میشوند.
آرایش بایتی درخواست ۷ بایتی؛ Data Size مرز B0 تا B6 را تعیین میکند و Padding وجود ندارد.
آرایش بایتی پاسخ ۳۰ بایتی؛ همه بایتهای B0 تا B29 در یک Message و بدون Chunk یا Padding منتقل میشوند.
مثال Chunked؛ همان داده با Request/Response مرحلهای
در حالت Chunked، Host همان Security_Request هفتبایتی را با Chunk Number=0، Request Chunk=0 و Data Size=7 میفرستد. Extended Header دو بایت و داده هفت بایت است؛ سه بایت Padding صفر اضافه میشود تا Payload پس از Message Header به ۱۲ بایت، یعنی سه Data Object، برسد. به همین دلیل NDO در Message Header برابر ۳ قرار میگیرد.
Charger پاسخ ۳۰ بایتی را با Chunk 0 آغاز میکند. این Chunk حداکثر ۲۶ بایت نخست Data Block را حمل میکند. Extended Header دو بایت به آن افزوده میشود و مجموع Payload به ۲۸ بایت یا هفت Data Object میرسد؛ پس Padding لازم نیست و NDO برابر ۷ است. Data Size با وجود حضور فقط ۲۶ بایت، مقدار کامل ۳۰ را اعلام میکند.
Host پس از دریافت موفق Chunk 0، یک Security_Response با Request Chunk=1، Chunk Number=1 و Data Size=0 میفرستد. این Message فقط Extended Header دو بایتی دارد و دو بایت Padding آن را به یک Data Object کامل تبدیل میکند؛ بنابراین NDO=1 است. نام Message Type همان Security_Response میماند، زیرا درخواست برای ادامه همان Data Block است.
Charger در پاسخ، Chunk 1 را با چهار بایت باقیمانده B26 تا B29 میفرستد. Extended Header دو بایت و داده چهار بایت در مجموع شش بایت هستند؛ دو بایت Padding مجموع را به هشت بایت یا دو Data Object میرساند. NDO=2، Chunk Number=1، Request Chunk=0 و Data Size همچنان ۳۰ است. پس از GoodCRC این Chunk، Data Block کامل بازسازی میشود.
توالی کامل تبادل Chunked؛ درخواست ۷ بایتی در Chunk 0 ارسال میشود و پاسخ ۳۰ بایتی با Chunk Request میان Chunk 0 و Chunk 1 تکمیل میگردد.
درخواست ۷ بایتی در Chunk 0؛ سه بایت Padding، Payload را به سه Data Object کامل میرساند.
Chunk 0 پاسخ، بایتهای B0 تا B25 را حمل میکند؛ Data Size طول کامل ۳۰ بایتی را نشان میدهد.
درخواست Chunk 1 بدون Data Block؛ دو بایت Padding، Extended Header را به یک Data Object کامل تبدیل میکند.
Chunk 1 بایتهای پایانی B26 تا B29 را حمل میکند و دو بایت Padding، Payload را به دو Data Object میرساند.
حساب بایتها؛ چگونه NDO و Padding را کنترل کنیم؟
برای تحلیل Extended Chunked باید Payload بعد از Message Header را بشماریم. Extended Header همیشه دو بایت است. داده Chunk و Padding به آن اضافه میشوند و حاصل باید مضربی از چهار بایت باشد. NDO حاصل تقسیم این Payload همتراز بر چهار است. Data Size در این محاسبه فقط طول کل Data Block را گزارش میکند و الزاماً برابر داده حاضر نیست.
| Message نمونه | Extended Header | داده حاضر | Padding | Payload | NDO | Data Size |
|---|---|---|---|---|---|---|
| Request، Chunk 0 | 2 B | 7 B | 3 B | 12 B | 3 | 7 |
| Response، Chunk 0 | 2 B | 26 B | 0 B | 28 B | 7 | 30 |
| Chunk Request برای Chunk 1 | 2 B | 0 B | 2 B | 4 B | 1 | 0 |
| Response، Chunk 1 | 2 B | 4 B | 2 B | 8 B | 2 | 30 |
بایتهای Padding جزو Data Block نیستند و نباید به Data Size یا محتوای Security_Response افزوده شوند. آنها فقط برای همترازی Payload با مرز Data Object سیودوبیتی حضور دارند و مقدارشان 0x00 است.
ترتیب عملی Decode یک Message در Capture
قبل از نقشها بدانید Packet برای Port Partner، Cable Plug اول یا Cable Plug دوم است.
Message خراب فیزیکی را با خطای معنایی Header اشتباه نگیرید.
خانواده Control، Data یا Extended را پیش از نام Message تعیین کنید.
SOP و مرحله Role Swap میتوانند معنای بیتها را تغییر دهند.
افزایش ID باید پس از دریافت موفق باشد و Retry ممکن است ID را تکرار کند.
Chunked، Chunk Number، Request Chunk و Data Size را مستقل گزارش کنید.
در Chunked، NDO باید با Extended Header، داده حاضر و Padding سازگار باشد.
Chunkها را از صفر و بهترتیب متصل کنید و Padding را کنار بگذارید.
هشت برداشت اشتباه رایج درباره Message و Chunking
۱. Message و Packet یک چیز هستند
Packet شامل پوشش PHY است؛ Message فقط بخش ساختهشده و تفسیرشده در Protocol Layer است.
۲. NDO همیشه طول Payload را میدهد
در Extended Unchunked، NDO Reserved است و Data Size طول را تعیین میکند.
۳. Message Type بهتنهایی نام Message را تعیین میکند
همان پنج بیت باید در Context خانواده Control، Data یا Extended Decode شود.
۴. ارسال موفق یعنی MessageID باید افزایش یابد
افزایش شمارنده به دریافت GoodCRC وابسته است، نه فقط پایان Drive روی CC.
۵. Chunk 0 هم باید درخواست شود
Chunk صفر خودکار ارسال میشود؛ Chunk 1 و بعدی به Request متناظر نیاز دارند.
۶. Data Size اندازه داده Chunk حاضر است
Data Size در پاسخها اندازه کامل Data Block را نشان میدهد و میان Chunkها ثابت میماند.
۷. Padding بخشی از Data Block است
Padding صفر فقط همترازی ۳۲ بیتی ایجاد میکند و هنگام بازسازی داده حذف میشود.
۸. Revision لینک برای Port و کابل همیشه یکسان است
ممکن است ارتباط Port-to-Port نسخه ۳ و Port-to-Cable نسخه ۲ باشد.
جمعبندی
USB PD سه خانواده Message دارد: Control شانزدهبیتی، Data شامل یک تا هفت Data Object و Extended با Data Block تا ۲۶۰ بایت.
Message Header شانزدهبیتی شامل Extended، NDO، MessageID، نقشها، Revision و Message Type است؛ معنای بیتهای نقش به SOP یا SOP'/SOP'' وابسته است.
Extended=0 و NDO=0 به Control و NDO غیرصفر به Data اشاره میکند. در Extended، شیوه تفسیر NDO به Chunked وابسته است.
MessageID شمارنده سهبیتی چرخشی است که در Power-on و Reset صفر و پس از GoodCRC موفق افزایش مییابد.
Revision مشترک Portها در تبادل Source_Capabilities و Request تعیین میشود؛ Revision ارتباط با Cable Plug میتواند جداگانه پایینتر باشد.
Extended Header شامل Chunked، Chunk Number، Request Chunk و Data Size است. Data Size همیشه اندازه کل Data Block را نشان میدهد.
فقط پشتیبانی Unchunked توسط هر دو Port باعث Chunked=0 میشود؛ در تمام ترکیبهای دیگر انتقال Chunked است.
Chunk 0 بدون درخواست ارسال میشود، اما Chunkهای بعدی باید بهترتیب درخواست شوند. Padding صفر فقط برای مرزبندی Data Object است و جزو داده نیست.
مقاله ۸: پیامهای کنترلی USB Power Delivery
در مقاله بعدی، Section 6.3 و صفحات ۱۲۸ تا ۱۳۷ بررسی میشوند: GoodCRC، Accept، Reject، PS_RDY، Get_Source_Cap، Soft_Reset، Data_Reset و سایر Control Messageها، همراه با دامنه SOP و Revision معتبر هرکدام.