Qt کو STM32 پر پورٹ کرنا

Qt کو STM32 پر پورٹ کرناصبح بخیر ہم منصوبے میں ہیں۔ ایمبوکس STM32F7-Discovery پر Qt لانچ کیا اور اس کے بارے میں بات کرنا چاہوں گا۔ اس سے پہلے، ہم نے پہلے ہی بتایا تھا کہ ہم کیسے لانچ کرنے میں کامیاب ہوئے۔ OpenCV.

Qt ایک کراس پلیٹ فارم فریم ورک ہے جس میں نہ صرف گرافیکل اجزاء شامل ہیں، بلکہ QtNetwork، ڈیٹا بیس کے ساتھ کام کرنے کے لیے کلاسوں کا ایک سیٹ، آٹومیشن کے لیے Qt (بشمول IoT نفاذ کے لیے) اور بہت کچھ شامل ہے۔ Qt ٹیم ایمبیڈڈ سسٹمز میں Qt استعمال کرنے کے بارے میں متحرک رہی ہے، اس لیے لائبریریاں کافی قابل ترتیب ہیں۔ تاہم، حال ہی میں، بہت کم لوگوں نے Qt کو مائیکرو کنٹرولرز پر پورٹ کرنے کے بارے میں سوچا، شاید اس لیے کہ ایسا کام مشکل لگتا ہے - Qt بڑا ہے، MCUs چھوٹے ہیں۔

دوسری طرف، اس وقت ملٹی میڈیا کے ساتھ کام کرنے کے لیے ڈیزائن کیے گئے مائکروکنٹرولرز ہیں اور پہلے پینٹیم سے بہتر ہیں۔ تقریباً ایک سال پہلے، Qt بلاگ شائع ہوا۔ پوسٹ. ڈویلپرز نے RTEMS OS کے لیے Qt کا ایک پورٹ بنایا، اور stm32f7 چلانے والے کئی بورڈز پر وجیٹس کے ساتھ مثالیں شروع کیں۔ یہ ہماری دلچسپی تھی۔ یہ قابل توجہ تھا، اور ڈویلپر خود اس کے بارے میں لکھتے ہیں، کہ Qt STM32F7-Discovery پر سست ہے۔ ہم سوچ رہے تھے کہ کیا ہم Embox کے تحت Qt چلا سکتے ہیں، اور نہ صرف ویجیٹ بنا سکتے ہیں، بلکہ ایک اینیمیشن چلا سکتے ہیں۔

Qt 4.8 کو ایک طویل عرصے سے Embox میں پورٹ کیا گیا ہے، لہذا ہم نے اسے اس پر آزمانے کا فیصلہ کیا۔ ہم نے موو بلاکس ایپلی کیشن کا انتخاب کیا - بہاری حرکت پذیری کی ایک مثال۔

QEMU پر Qt موو بلاکسQt کو STM32 پر پورٹ کرنا

شروع کرنے کے لیے، ہم Qt کو ترتیب دیتے ہیں، اگر ممکن ہو تو، اینیمیشن کو سپورٹ کرنے کے لیے ضروری اجزاء کے کم از کم سیٹ کے ساتھ۔ اس کے لیے ایک آپشن ہے "-qconfig minimal,small,medium..."۔ یہ Qt سے ایک کنفیگریشن فائل کو بہت سے میکروز کے ساتھ جوڑتا ہے - کیا فعال کرنا ہے / کیا غیر فعال کرنا ہے۔ اس اختیار کے بعد، اگر ہم کسی اور چیز کو غیر فعال کرنا چاہتے ہیں تو ہم کنفیگریشن میں دوسرے جھنڈے شامل کرتے ہیں۔ یہاں ہماری ایک مثال ہے۔ ترتیب.

Qt کے کام کرنے کے لیے، آپ کو OS مطابقت کی پرت شامل کرنے کی ضرورت ہے۔ ایک طریقہ یہ ہے کہ QPA (Qt پلیٹ فارم خلاصہ) کو لاگو کیا جائے۔ ہم نے Qt میں شامل ریڈی میڈ fb_base پلگ ان کو بنیاد بنایا، جس کی بنیاد پر لینکس کے لیے QPA کام کرتا ہے۔ نتیجہ ایک چھوٹا پلگ ان ہے جسے emboxfb کہتے ہیں، جو Qt کو Embox کے فریم بفر کے ساتھ فراہم کرتا ہے، اور پھر یہ بغیر کسی بیرونی مدد کے وہاں کھینچتا ہے۔

پلگ ان بنانا ایسا ہی لگتا ہے۔

QEmboxFbIntegration::QEmboxFbIntegration()
    : fontDb(new QGenericUnixFontDatabase())
{
    struct fb_var_screeninfo vinfo;
    struct fb_fix_screeninfo finfo;
    const char *fbPath = "/dev/fb0";

    fbFd = open(fbPath, O_RDWR);
    if (fbPath < 0) {
        qFatal("QEmboxFbIntegration: Error open framebuffer %s", fbPath);
    }
    if (ioctl(fbFd, FBIOGET_FSCREENINFO, &finfo) == -1) {
        qFatal("QEmboxFbIntegration: Error ioctl framebuffer %s", fbPath);
    }
    if (ioctl(fbFd, FBIOGET_VSCREENINFO, &vinfo) == -1) {
        qFatal("QEmboxFbIntegration: Error ioctl framebuffer %s", fbPath);
    }
    fbWidth        = vinfo.xres;
    fbHeight       = vinfo.yres;
    fbBytesPerLine = finfo.line_length;
    fbSize         = fbBytesPerLine * fbHeight;
    fbFormat       = vinfo.fmt;
    fbData = (uint8_t *)mmap(0, fbSize, PROT_READ | PROT_WRITE,
                             MAP_SHARED, fbFd, 0);
    if (fbData == MAP_FAILED) {
        qFatal("QEmboxFbIntegration: Error mmap framebuffer %s", fbPath);
    }
    if (!fbData || !fbSize) {
        qFatal("QEmboxFbIntegration: Wrong framebuffer: base = %p,"
               "size=%d", fbData, fbSize);
    }

    mPrimaryScreen = new QEmboxFbScreen(fbData, fbWidth,
                                        fbHeight, fbBytesPerLine,
                                        emboxFbFormatToQImageFormat(fbFormat));

    mPrimaryScreen->setPhysicalSize(QSize(fbWidth, fbHeight));
    mScreens.append(mPrimaryScreen);

    this->printFbInfo();
}

اور یہ وہی ہے جو دوبارہ ڈرائنگ کی طرح نظر آئے گا۔

QRegion QEmboxFbScreen::doRedraw()
{
    QVector<QRect> rects;
    QRegion touched = QFbScreen::doRedraw();

    DPRINTF("QEmboxFbScreen::doRedrawn");

    if (!compositePainter) {
        compositePainter = new QPainter(mFbScreenImage);
    }

    rects = touched.rects();
    for (int i = 0; i < rects.size(); i++) {
        compositePainter->drawImage(rects[i], *mScreenImage, rects[i]);
    }
    return touched;
}

نتیجے کے طور پر، میموری سائز -Os کے لیے کمپائلر آپٹیمائزیشن کے ساتھ، لائبریری کی تصویر 3.5 MB نکلی، جو یقیناً STM32F746 کی مین میموری میں فٹ نہیں ہوتی۔ جیسا کہ ہم نے پہلے ہی OpenCV کے بارے میں اپنے دوسرے مضمون میں لکھا ہے، اس بورڈ میں ہے:

  • 1 MB ROM
  • 320 KB ریم
  • 8 MB SDRAM
  • 16 MB QSPI

چونکہ QSPI کی طرف سے کوڈ پر عمل درآمد کے لیے تعاون پہلے ہی OpenCV میں شامل کیا جا چکا ہے، اس لیے ہم نے QSPI میں مکمل Embox c Qt امیج لوڈ کر کے شروع کرنے کا فیصلہ کیا۔ اور جلدی، سب کچھ تقریباً فوراً ہی QSPI سے شروع ہو گیا! لیکن جیسا کہ OpenCV کے معاملے میں، یہ پتہ چلا کہ یہ بہت آہستہ کام کرتا ہے۔

Qt کو STM32 پر پورٹ کرنا

لہذا، ہم نے اسے اس طرح کرنے کا فیصلہ کیا - پہلے ہم تصویر کو QSPI میں کاپی کرتے ہیں، پھر اسے SDRAM میں لوڈ کرتے ہیں اور وہاں سے اس پر عمل درآمد کرتے ہیں۔ SDRAM سے یہ تھوڑا تیز ہو گیا، لیکن پھر بھی QEMU سے بہت دور ہے۔

Qt کو STM32 پر پورٹ کرنا

اس کے بعد، ایک تیرتا ہوا نقطہ شامل کرنے کا خیال آیا - آخر کار، Qt حرکت پذیری میں مربعوں کے نقاط کا کچھ حساب کرتا ہے۔ ہم نے کوشش کی، لیکن یہاں ہمیں کوئی واضح سرعت نہیں ملی، حالانکہ اندر آرٹیکل Qt ڈویلپرز نے دعوی کیا کہ FPU ٹچ اسکرین پر "ڈریگنگ اینیمیشن" کی رفتار میں نمایاں اضافہ کرتا ہے۔ موو بلاکس میں نمایاں طور پر کم فلوٹنگ پوائنٹ حسابات ہوسکتے ہیں، اور یہ مخصوص مثال پر منحصر ہے۔

سب سے مؤثر خیال فریم بفر کو SDRAM سے اندرونی میموری میں منتقل کرنا تھا۔ ایسا کرنے کے لیے، ہم نے اسکرین کے طول و عرض کو 480x272 نہیں بلکہ 272x272 بنایا ہے۔ ہم نے رنگ کی گہرائی کو بھی A8R8G8B8 سے R5G6B5 تک کم کر دیا، اس طرح ایک پکسل کا سائز 4 سے 2 بائٹس تک کم ہو گیا۔ نتیجے میں فریم بفر کا سائز 272 * 272 * 2 = 147968 بائٹس ہے۔ اس نے ایک اہم سرعت دی، شاید سب سے نمایاں طور پر، حرکت پذیری تقریباً ہموار ہو گئی۔

تازہ ترین اصلاح RAM سے Embox کوڈ اور SDRAM سے Qt کوڈ کو چلانا تھا۔ ایسا کرنے کے لیے، ہم سب سے پہلے، ہمیشہ کی طرح، مستقل طور پر Embox کو Qt کے ساتھ جوڑتے ہیں، لیکن ہم لائبریری کے متن، rodata، ڈیٹا اور bss حصوں کو QSPI میں رکھتے ہیں تاکہ اسے SDRAM میں کاپی کر سکیں۔

section (qt_text, SDRAM, QSPI)
phdr	(qt_text, PT_LOAD, FLAGS(5))

section (qt_rodata, SDRAM, QSPI)
phdr	(qt_rodata, PT_LOAD, FLAGS(5))

section (qt_data, SDRAM, QSPI)
phdr	(qt_data, PT_LOAD, FLAGS(6))

section (qt_bss, SDRAM, QSPI)
phdr	(qt_bss, PT_LOAD, FLAGS(6))

ROM سے Embox کوڈ پر عمل کرنے سے، ہمیں ایک قابل توجہ ایکسلریشن بھی ملا۔ نتیجے کے طور پر، حرکت پذیری کافی ہموار نکلی:


بالکل آخر میں، مضمون کی تیاری اور مختلف Embox کنفیگریشنز کو آزمانے کے دوران، یہ پتہ چلا کہ Qt موو بلاکس QSPI سے SDRAM میں ایک فریم بفر کے ساتھ بہت اچھا کام کرتا ہے، اور رکاوٹ بالکل فریم بفر کے سائز کی تھی! بظاہر، ابتدائی "سلائیڈ شو" پر قابو پانے کے لیے، فریم بفر کے سائز میں معمولی کمی کی وجہ سے 2 گنا ایکسلریشن کافی تھا۔ لیکن صرف Embox کوڈ کو مختلف تیز یادوں میں منتقل کرکے ایسا نتیجہ حاصل کرنا ممکن نہیں تھا (سرعت 2 نہیں بلکہ تقریباً 1.5 گنا تھی)۔

اسے خود آزمانے کا طریقہ

اگر آپ کے پاس STM32F7-Discovery ہے، تو آپ خود Embox کے تحت Qt چلا سکتے ہیں۔ آپ پڑھ سکتے ہیں کہ یہ ہمارے پر کیسے کیا جاتا ہے۔ وکی.

حاصل يہ ہوا

نتیجے کے طور پر، ہم Qt شروع کرنے میں کامیاب ہو گئے! کام کی پیچیدگی، ہماری رائے میں، کسی حد تک مبالغہ آمیز ہے۔ قدرتی طور پر، آپ کو مائیکرو کنٹرولرز کی خصوصیات کو مدنظر رکھنا ہوگا اور عام طور پر کمپیوٹر سسٹمز کے فن تعمیر کو سمجھنا ہوگا۔ اصلاح کے نتائج اس معروف حقیقت کی طرف اشارہ کرتے ہیں کہ کمپیوٹنگ سسٹم میں رکاوٹ پروسیسر نہیں بلکہ میموری ہے۔

اس سال ہم میلے میں شرکت کریں گے۔ ٹیک ٹرین. وہاں ہم آپ کو مزید تفصیل سے بتائیں گے اور مائکروکنٹرولرز پر Qt، OpenCV اور اپنی دیگر کامیابیاں دکھائیں گے۔

ماخذ: www.habr.com

نیا تبصرہ شامل کریں