PIO چیست؟
PIO چیست؟ Programmable I/O یا به اختصار PIO مفهوم جدیدی است که شرکت رزبری پای معرفی کرده و از آن در میکروکنترلرهای ساخت خود استفاده کرده است. تا پیش از این دسترسی به I/Oها در میکروکنترلرها از دو طریق امکانپذیر بود:
- دسترسی مستقیم از طریق برنامه
- تخصیص آنها به پریفرالهای از پیش آمادهای مانند SPI, UART, ADC, I2C, DAC و … .
PIO نوع دیگری از دسترسی به I/Oها را مطرح میکند. اتصال I/Oها به یک سختافزار انعطافپذیر که کاربر میتواند با برنامهنویسی برای آن مشخص کند چه کاری را انجام دهد. برای آنکه بدانید PIO چیست و چگونه عمل میکند در ادامه این مقاله با ما همراه باشید.
کاربرد PIO چیست؟
برای آنکه بدانید کاربرد PIO چیست فرض کنید قرار است با یک سنسور که اینترفیس ارتباطی آن SPI است ارتباط برقرار کنید. برای این کار از پریفرال SPI میکروکنترلر خود استفاده میکنید. حال تصور کنید که از تمام پریفرالهای SPI میکروکنترلر در بخشهای دیگر سیستم استفاده کردهاید و دیگر SPI آزاد ندارید. راه حل شما چیست؟ یک راه شاید پیادهسازی نرمافزاری SPI باشد که کتابخانههایی هم برای آن وجود دارد اما به شدت پردازشگر شما را درگیر خواهد کرد و ممکن است پردازنده به وظایف دیگر خود نرسد. علاوه بر این هیچگاه قابلیت اطمینان پریفرال SPI سختافزاری را نخواهد داشت. (این اصل را به خاطر داشته باشید : همواره قابلیت اطمینان سختافزار از نرمافزار بالاتر است)
سناریوی دیگری را مرور کنیم. فرض کنید با سنسوری مواجه هستیم که اینترفیس ارتباطی آن هیچیک از اینترفیسهای استاندارد موجود در میکروکنترلرها (مانند SPI, I2c, UART, LAN, I2S ) نیست و مختص شرکت سازنده سنسور است. اینجا چه باید کرد؟ پیادهسازی نرمافزاری اینگونه ارتباطها علاوه بر مشغول کردن پردازنده و نداشتن قابلیت اطمینان بالا بسیار سخت است. (در اینگونه موارد راهحل ها معمولا به سمت استفاده از FPGA پیش میروند که آن هم هزینههای زمانی و مالی خود را دارد).
PIO یک راه حل جدید برای سناریوهای فوق است. یک سختافزاز قابل برنامهریزی که میتواند به هرچیزی تبدیل شود. میتوان درون آن پروتکل SPI را پیادهسازی کرد یا I2C یا UART و یا حتی چیزهای پیچیدهتری مانند VGA. هرچه که شما بخواهید.
به صورت خلاصه میتوان کاربردهای زیر را برای PIO متصور شد:
- پیادهسازی یک پروتکل خاص که سختافزار آن به صورت استاندارد در میکروکنترلر وجود ندارد
- پیادهسازی یک پروتکل استاندارد که سختافزار آن در میکروکنترلر وجود دارد اما به تعدای بیشتری لازم است
- جایی که نیاز به کنترل I/Oها بدون دخالت نرم افزار باشد (به علت قابلیت اطمینان بالاتر و Timing دقیق)
- جایی که نیاز به تغییر ماهیت سختافزار در حین اجرای برنامه باشد
- جایی که نیاز به اجرای چند برنامه همزمان باشد
ساختار PIO چیست؟
PIO از چهار ماشین حالت، تعدادی FIFO، یک مدار سختافزاری اختصاص I/O و یک حافظه دستور تشکیل شده است. هر یک از ماشینهای حالت دستورات را از حافظه دستور لود کرده و اجرا میکنند. این دستورات همان دستوراتی است که شما درون برنامه خود و به زبان PIO Assembly نوشتهاید. state machine دستورات را یکی یکی از داخل حافظه دستور لود کرده و به ترتیب اجرا میکند. میتوانید تصور کنید که هر state machine پردازنده کوچکی است که برای کار با I/Oها بهینه شده است.
هر State Machine مقسم کلاک و Program Counter خود را دارد. در هر کلاک با توجه به مقدار Program Counter دستوری را از داخل حافظه دستور (Instruction Memory) لود کرده و آن را در یک کلاک اجرا میکند. دقت داشته باشید فضای حافظه دستور بین هر چهار State Machine به اشتراک گذاشته شده است.
Assembly PIO دارای 9 دستور است که با ترکیب آنها میتوان منطق مورد نظر را پیاده کرد:
- JMP
- WAIT
- IN
- OUT
- PUSH
- PULL
- MOV
- IRQ
- SET
اگر نیاز به ساخت اینترفیس سبکی باشد میتوان از هر ماشین حالت به صورت مجزا استفاده کرد و روی هریک مجزا پیادهسازی انجام داد اما اگر اینترفیس پیچیده باشد از هر جهار ماشین حالت استفاده میشود.
مشخصات PIO رزبری پای پیکو
تراشه RP2040 (چیپ اصلی برد رزبری پای پیکو) درون خود دو واحد PIO کاملا مجزا دارد. مشخصات هر یک از این PIOها به صورت زیر است :
- دارای دو 32bit shift register
- دارای دو 32bit scratch register
- دارای چهار 32bit bus FIFO برای ورودی
- دارای چهار 32bit bus FIFO برای خروجی
- دارای مقسم کلاک مجزا
- دارای سختافزار تخصیص I/O
- امکان اتصال به DMA
- امکان اتصال به وقفه
اگر راجع به جزییات بیشتر در مورد PIO کنجکاو هستید میتوانید به دیتاشیت RP2040 مراجعه کنید.
یک مثال ساده از راه اندازی PIO
در این مقاله قصد نداریم به آموزش نحوه کدنویسی PIO بپردازیم اما یک مثال ساده از ایجاد یک چشمکزن روی پین GP0 را قرار دادهایم تا نحوه استفاده از PIO را ببینید. ابتدا کلاس Pin از ماژول machine (برای استفاده از پین میکروکنترلر) و ماژول rp2 (برای استفاده از کلاس State_Machine و همچنین استفاده از دکوراتور asm_pio ) را import میکنیم.
from machine import Pin import rp2
در ادامه تابعی با نام blink تعریف کرده و توسط دکوراتور asm_pio به مفسر میکروپایتون میفهمانیم که این تابع به زبان PIO assembly نوشته شده است. PIO assembly یک زبان سطح پایین برای برنامهنویسی State Machine های PIO است. همچنین حالت اولیه پینها (high/low) به عنوان پارامتر ورودی به این دکوراتور ارسال میشود.
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW,) def blink(): label('again') set(pins, 1)[1] set(x, 10) label('loop1') nop()[10] jmp(x_dec, 'loop1') set(pins, 0) set(x, 10) label('loop2') nop()[10] jmp(x_dec, 'loop2') jmp('again')
در ادامه یک آبجکت با نام sm از کلاس State_Machine میسازیم و پارامترهای زیر را به سازنده آن پاس میدهیم:
- شماره state_machine مورد استفاده (عددی بین 0 تا 7 چون دو PIO داریم که هرکدام چهار state machine دارند)
- نام تابعی که با زبان PIO assembly نوشته شده و به عنوان برنامه باید روی state machine اجرا شود.
- فرکانس کلاک state machine
- شماره اولین pin مورد استفاده در state machine (تعداد پینها را از تعداد حالتهای اولیه که در دکوراتور asm_pio داده شده است میفهمد و به همان تعداد به ترتیب از این شماره پین بالا میرود)
sm = rp2.StateMachine(0, blink, 100_000_000, set_base=Pin(0))
در نهایت آبجکت sm را active میکنیم تا فعالیت خود را شروع کند.
sm.active(1)
کد کامل به صورت زیر است:
from machine import Pin import rp2 @rp2.asm_pio(set_init=rp2.PIO.OUT_LOW,) def blink(): label('again') set(pins, 1)[1] set(x, 10) label('loop1') nop()[10] jmp(x_dec, 'loop1') set(pins, 0) set(x, 10) label('loop2') nop()[10] jmp(x_dec, 'loop2') jmp('again') sm = rp2.StateMachine(0, blink, 100_000_000, set_base=Pin(0)) sm.active(1)
اگر تمایل به مطالعه بیشتر در مورد کلاس Port و نحوه استفاده از آن در میکروپایتون دارید میتوانید به مقاله راه اندازی پایه های رزبری پای پیکو مراجعه کنید.
در پایان
در این مقاله راجع به این که PIO چیست، ساختار PIO چیست، کاربرد PIO چیست و ویژگیهای اصلی واحد PIO رزبریپای پیکو صحبت کردیم. در انتها مثال سادهای از راهاندازی PIO با میکروپایتون را برای آشنایی شما با فضای کدنویسی این واحد آوردیم. بسیار خوشنود خواهیم شد اگر نظرات خود در این زمینه را با در بخش نظرات مقاله با ما و سایر دوستانتان به اشتراک بگذارید.
دیدگاهتان را بنویسید