Qt සිට STM32 වෙත ගෙන යාම

Qt සිට STM32 වෙත ගෙන යාමසුභ සන්ධ්යාවක් අපි ව්‍යාපෘතියේ ඉන්නවා එම්බොක්ස් කරන්න STM32F7-Discovery හි Qt දියත් කළ අතර ඒ ගැන කතා කිරීමට කැමතියි. මීට පෙර, අපි දියත් කිරීමට සමත් වූ ආකාරය අපි දැනටමත් පවසා ඇත OpenCV.

Qt යනු ග්‍රැෆික් සංරචක පමණක් නොව, QtNetwork, දත්ත සමුදායන් සමඟ වැඩ කිරීම සඳහා පන්ති සමූහයක්, ස්වයංක්‍රීයකරණය සඳහා Qt (IoT ක්‍රියාත්මක කිරීම ඇතුළුව) සහ තවත් බොහෝ දේ ඇතුළත් හරස් වේදිකා රාමුවකි. Qt කණ්ඩායම කාවැද්දූ පද්ධතිවල Qt භාවිතා කිරීම සම්බන්ධයෙන් ක්‍රියාශීලී වී ඇත, එබැවින් පුස්තකාල ඉතා වින්‍යාසගත වේ. කෙසේ වෙතත්, මෑතක් වන තුරු, ස්වල්ප දෙනෙක් Qt මයික්‍රොකොන්ට්‍රෝලර් වෙත ගෙනයාම ගැන සිතුවේය, සමහර විට එවැනි කාර්යයක් අපහසු බව පෙනෙන නිසා විය හැකිය - Qt විශාලයි, MCU කුඩා වේ.

අනෙක් අතට, මේ මොහොතේ බහුමාධ්‍ය සමඟ වැඩ කිරීමට නිර්මාණය කර ඇති ක්ෂුද්‍ර පාලකයන් සහ පළමු පෙන්ටියම් වලට වඩා උසස් වේ. මීට වසරකට පමණ පෙර, Qt බ්ලොග් අඩවිය දර්ශනය විය තනතුර. සංවර්ධකයින් RTEMS මෙහෙයුම් පද්ධතිය සඳහා Qt වරායක් සාදන ලද අතර, stm32f7 ධාවනය වන පුවරු කිහිපයක විජට් සමඟ උදාහරණ දියත් කරන ලදී. මෙය අප උනන්දු විය. STM32F7-Discovery මත Qt මන්දගාමී බව එය සැලකිය යුතු වූ අතර, සංවර්ධකයින් විසින්ම ඒ ගැන ලියයි. අපි එම්බොක්ස් යටතේ Qt ධාවනය කළ හැකිදැයි කල්පනා කළෙමු, විජට් ඇඳීම පමණක් නොව සජීවිකරණයක් ධාවනය කළ හැකිද යන්නයි.

Qt 4.8 එම්බොක්ස් වෙත දිගු කලක් පෝට් කර ඇත, එබැවින් අපි එය උත්සාහ කිරීමට තීරණය කළෙමු. අපි Moveblocks යෙදුම තෝරා ගත්තෙමු - වසන්ත සජීවිකරණය සඳහා උදාහරණයක්.

QEMU මත Qt moveblocksQt සිට STM32 වෙත ගෙන යාම

ආරම්භ කිරීම සඳහා, අපි හැකි නම්, සජීවිකරණයට සහාය වීමට අවශ්‍ය අවම සංරචක කට්ටලය සමඟ Qt වින්‍යාස කරමු. මේ සඳහා “-qconfig minimal,small,medium...” විකල්පයක් ඇත. එය බොහෝ මැක්‍රෝ සමඟ Qt වෙතින් වින්‍යාස ගොනුවක් සම්බන්ධ කරයි - සක්‍රීය කළ යුතු / අක්‍රිය කළ යුතු දේ. මෙම විකල්පයෙන් පසුව, අපට වෙනත් දෙයක් අක්‍රිය කිරීමට අවශ්‍ය නම් අපි වින්‍යාසයට වෙනත් ධජ එකතු කරමු. මෙන්න අපේ උදාහරණයක් වින්යාසය.

Qt වැඩ කිරීමට නම්, ඔබ OS අනුකූලතා ස්ථරයක් එක් කළ යුතුය. එක් ක්‍රමයක් නම් QPA (Qt Platform Abstraction) ක්‍රියාත්මක කිරීමයි. අපි Linux සඳහා QPA ක්‍රියා කරන Qt හි ඇතුළත් සූදානම් කළ fb_base ප්ලගිනය පදනමක් ලෙස ගත්තෙමු. එහි ප්‍රතිඵලය වන්නේ 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 RAM
  • 8 MB SDRAM
  • 16 MB QSPI

QSPI වෙතින් කේතය ක්‍රියාත්මක කිරීම සඳහා සහය දැනටමත් OpenCV වෙත එක් කර ඇති බැවින්, සම්පූර්ණ Embox c Qt රූපය QSPI වෙත පැටවීමෙන් ආරම්භ කිරීමට අපි තීරණය කළෙමු. හා හුරේ, සෑම දෙයක්ම QSPI වෙතින් වහාම පාහේ ආරම්භ විය! නමුත් OpenCV හි මෙන්, එය ඉතා සෙමින් ක්‍රියා කරන බව පෙනී ගියේය.

Qt සිට STM32 වෙත ගෙන යාම

එමනිසා, අපි එය මේ ආකාරයෙන් කිරීමට තීරණය කළෙමු - පළමුව අපි රූපය QSPI වෙත පිටපත් කර, පසුව එය SDRAM වෙත පටවා එතැන් සිට ක්රියාත්මක කරන්න. SDRAM වෙතින් එය ටිකක් වේගවත් විය, නමුත් තවමත් QEMU වෙතින් බොහෝ දුරයි.

Qt සිට STM32 වෙත ගෙන යාම

ඊළඟට, පාවෙන ලක්ෂ්‍යයක් ඇතුළත් කිරීමට අදහසක් තිබුණි - සියල්ලට පසු, Qt සජීවිකරණයේ වර්ගවල ඛණ්ඩාංක පිළිබඳ සමහර ගණනය කිරීම් කරයි. අපි උත්සාහ කළා, නමුත් මෙහිදී අපට දෘශ්‍ය ත්වරණයක් ලැබුණේ නැත, නමුත් ලිපියයි Qt සංවර්ධකයින් කියා සිටියේ FPU ටච්ස්ක්‍රීන් මත “ඇදගෙන යාමේ සජීවිකරණය” සඳහා වේගයේ සැලකිය යුතු වැඩි වීමක් ලබා දෙන බවයි. Moveblocks හි සැලකිය යුතු ලෙස අඩු පාවෙන ලක්ෂ්‍ය ගණනය කිරීම් තිබිය හැකි අතර මෙය නිශ්චිත උදාහරණය මත රඳා පවතී.

වඩාත් ඵලදායී අදහස වූයේ රාමුබෆරය SDRAM සිට අභ්යන්තර මතකය වෙත ගෙන යාමයි. මෙය සිදු කිරීම සඳහා, අපි තිර මානයන් 480x272 නොව 272x272 බවට පත් කළෙමු. අපි වර්ණ ගැඹුර A8R8G8B8 සිට R5G6B5 දක්වා අඩු කළෙමු, එමඟින් එක් පික්සලයක ප්‍රමාණය බයිට් 4 සිට 2 දක්වා අඩු කළෙමු. එහි ප්රතිඵලයක් වශයෙන් රාමුබෆරයේ ප්රමාණය 272 * 272 * 2 = 147968 බයිට් වේ. මෙය සැලකිය යුතු ත්වරණයක් ලබා දුන්නේය, සමහර විට වඩාත්ම කැපී පෙනෙන ලෙස, සජීවිකරණය පාහේ සුමට විය.

නවතම ප්‍රශස්තිකරණය වූයේ RAM වෙතින් Embox කේතය සහ SDRAM වෙතින් Qt කේතය ධාවනය කිරීමයි. මෙය සිදු කිරීම සඳහා, අපි පළමුව, සුපුරුදු පරිදි, Qt සමඟ ස්ථිතිකව Embox සම්බන්ධ කරමු, නමුත් අපි එය SDRAM වෙත පිටපත් කිරීම සඳහා QSPI තුළ පුස්තකාලයේ පෙළ, rodata, දත්ත සහ bss කොටස් තබමු.

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 වෙතින් එම්බොක්ස් කේතය ක්‍රියාත්මක කිරීමෙන්, අපට සැලකිය යුතු ත්වරණයක් ද ලැබුණි. ප්රතිඵලයක් වශයෙන්, සජීවිකරණය තරමක් සුමට විය:


අවසානයේදී, ලිපිය සකස් කර විවිධ එම්බොක්ස් වින්‍යාසයන් උත්සාහ කරන විට, Qt moveblocks SDRAM හි රාමු බෆරයක් සමඟ QSPI වෙතින් විශිෂ්ට ලෙස ක්‍රියා කරන බව පෙනී ගිය අතර, බාධකය හරියටම රාමු බෆරයේ ප්‍රමාණය විය! පෙනෙන විදිහට, ආරම්භක "විනිවිදක දර්ශනය" ජය ගැනීම සඳහා, රාමු බෆරයේ විශාලත්වය අඩු වීම හේතුවෙන් 2 ගුණයක ත්වරණය ප්රමාණවත් විය. නමුත් එම්බොක්ස් කේතය පමණක් විවිධ වේගවත් මතකයන් වෙත මාරු කිරීමෙන් එවැනි ප්‍රති result ලයක් ලබා ගැනීමට නොහැකි විය (ත්වරණය 2 නොවේ, නමුත් 1.5 වතාවක් පමණ).

එය ඔබම උත්සාහ කරන්නේ කෙසේද

ඔබට STM32F7-Discovery එකක් තිබේ නම්, ඔබට Embox යටතේ Qt ධාවනය කළ හැක. මෙය සිදු කරන්නේ කෙසේදැයි ඔබට අපගේ ලිපියෙන් කියවිය හැකිය විකි.

නිගමනය

එහි ප්‍රතිඵලයක් වශයෙන්, Qt! දියත් කිරීමට අපට හැකි විය. කාර්යයේ සංකීර්ණත්වය, අපගේ මතය අනුව, තරමක් අතිශයෝක්තියට නංවා ඇත. ස්වාභාවිකවම, ඔබ ක්ෂුද්ර පාලකයන්ගේ විශේෂතා සැලකිල්ලට ගත යුතු අතර සාමාන්යයෙන් පරිගණක පද්ධතිවල ගෘහ නිර්මාණ ශිල්පය තේරුම් ගත යුතුය. ප්‍රශස්තිකරණ ප්‍රතිඵල පෙන්වා දෙන්නේ පරිගණක පද්ධතියක ඇති බාධකය ප්‍රොසෙසරය නොව මතකය බව දන්නා කරුණකි.

මේ අවුරුද්දේ අපි උත්සවයට සහභාගි වෙනවා TechTrain. එහිදී අපි ඔබට වඩාත් විස්තරාත්මකව පවසන අතර ක්ෂුද්‍ර පාලක මත Qt, OpenCV සහ අපගේ අනෙකුත් ජයග්‍රහණ පෙන්වමු.

මූලාශ්රය: www.habr.com

අදහස් එක් කරන්න