[Модули, которые прямо во рту] Боитесь гнаться за новыми? LVGL8 выпускает обновление стабильности (с руководством по развертыванию)
[Модули, которые прямо во рту] Боитесь гнаться за новыми? LVGL8 выпускает обновление стабильности (с руководством по развертыванию)

【Сказано ранее】


LVGLтолько что закончил сопряжениеLVGL8обновления обслуживания,Опубликованоv8.3.5версия。относительноmasterВертикально на веткесуществоватьразвитыйLVGL9,Эта версия является стабильной, рекомендованной Hematemesis:

  • Это техническое обновление для LVGL8.,API остается неизменным,Просто немного повозился
  • Исправления и обновленная поддержка многочисленных графических процессоров.,включать
    • Arm-2D
    • NXP-PXP и NXP-VGLite
    • Частично реконструированный драйвер STM32 DMA2D.

Друзья, которые используют LVGL для производства продуктов, могут смело его есть.

【Как получить пакет LVGL cmsis】


1、Пользователи могут пройтиLVGLсуществоватьGithubПрямая загрузка со склада:

https://github.com/lvgl/lvgl/tree/release/v8.3/env_support/cmsis-pack

2、Пользователи также могут напрямую проходитьMDKизPack-InstallerВыполните прямую установку,Точно так же, как это делает lwIP:

Независимо от того, какой метод используется, после завершения установки вы сможете в будущем получить последнюю версию через Pack-Installer.

[Как развернуть LVGL в MDK]


Шаг 1. Настройте RTE

существоватьMDKчерез меню Project->Manage->Run-Time Enviroment ОткрытьRTEКонфигурацияокно:

существоватьRTEКонфигурация Нашел в интерфейсеLVGL,Разверните его:

Развертывание с другими платформамиLVGLдругой,cmsis-packРазрешите каждому заказывать только то, что ему нужноизмодуль(или функция)Присоединяйтесь к проекту。

Уведомление,этотвнутри Необходимо заказатьизда“Essential”,этоLVGLиз Основные услуги。Вообще говоря,чтобы использоватьLVGLунесенныйиз Богатые элементы управления(Widgets),Нам также необходимо выбрать“Extra Themes”。Если вы делаете это впервые для своей текущей аппаратной платформыLVGLпересадка,Настоятельно рекомендуется добавить немного“Porting”——это добавит тебепересадканеобходимыйизшаблон,Очень удобно.

щелкнуть“OK”закрытиеRTEКонфигурацияокно,посмотримLVGLДобавлен в список проектов:

На этом этапе мы можем успешно скомпилировать.

Шаг 2. Настройте LVGL

Разверните LVGL и найдите файл заголовка конфигурации. lv_conf_cmsis.h

На самом деле этот файлLVGLчиновникпересадкаупоминается в документацииизlv_conf.h,этона основеlv_conf_template.h Модифицировано. Стоит отметить, что некоторые макросы переключения модулей были удалены, например:

Язык кода:javascript
копировать
LV_USE_GPU_ARM2D
LV_USE_GPU_STM32_DMA2D
LV_USE_GPU_NXP_PXP
……

Это потому, что,когда мысуществоватьRTEКонфигурацияокносередина Проверятьверно При выборе,cmsis-pack автоматически добавит соответствующее определение макроса в RTE_Components.h внутри——другими словами,Нам больше не нужно добавлять его вручную!

Для других конфигураций LVGL обратитесь к официальной документации, которая здесь не будет описана.

Шаг 3. Используйте шаблоны для миграции

когда мысуществоватьRTEвыбрано вportingПосле модуля,В список проектов будут добавлены три шаблона миграции.

Они доступны для редактирования,держатьсуществовать Текущий проектизRTE/LVGLв каталоге。

Эти шаблоны значительно упрощают процесс трансплантации драйверов. Ниже мы рассмотрим lv_port_disp_template в качестве примера, чтобы показать, как использовать эти шаблоны:

1. Открыть lv_port_disp_template.h,место в начале #if 0 Изменить на #if 1,Проверьте весь заголовочный файл:

2. Открыть lv_port_disp_template.c,место в начале #if 0 Изменить на #if 1,Проверьте весь удаленный файл.

4. В соответствии с рекомендациями официального документа по портированию и фактической ситуацией с вашим оборудованием выберите один из трех режимов буферизации:

нужен особенныйподчеркиватьизда:Если в вашей системе нет DMA или полный кадр для пользователя BufferобновитьизспециализированныйLCDконтроллер,Тогда двойная буферизация фактически бессмысленна (потому что процессор все равно выполняет работу,Поэтому существенной разницы в производительности по сравнению с режимом с одним буфером не будет)

5. Найти disp_init() функцию и добавьте в нее код инициализации ЖК-дисплея. Эта функция будет lv_port_disp_init() вызов.

6. Найти disp_flush()функция,И в зависимости от фактического положения вашего оборудования,переписать это。напримерэтотда使用 GLCD_DrawBitmapруководитьвыполнитьиз Справочный код:

Язык кода:javascript
копировать
/*Flush the content of the internal buffer the specific area on the display
 *You can use DMA or any hardware acceleration to do this operation in the background but
 *'lv_disp_flush_ready()' has to be called when finished.*/
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    if (disp_flush_enabled) {
        GLCD_DrawBitmap(area->x1,               //!< x
                        area->y1,               //!< y
                        area->x2 - area->x1 + 1,    //!< width
                        area->y2 - area->y1 + 1,    //!< height
                        (const uint8_t *)color_p);
    }
    /*IMPORTANT!!!
     *Inform the graphics library that you are ready with the flushing*/
    lv_disp_flush_ready(disp_drv);
}

GLCD_DrawBitmap Прототип функции, используемый для обновления данного буфера дисплея на ЖК-дисплее, выглядит следующим образом:

Язык кода:javascript
копировать
/**
  \fn          int32_t GLCD_DrawBitmap (uint32_t x, uint32_t y, uint32_t width, uint32_t height, const uint8_t *bitmap)
  \brief       Draw bitmap (bitmap from BMP file without header)
  \param[in]   x      Start x position in pixels (0 = left corner)
  \param[in]   y      Start y position in pixels (0 = upper corner)
  \param[in]   width  Bitmap width in pixels
  \param[in]   height Bitmap height in pixels
  \param[in]   bitmap Bitmap data
  \returns
   - \b  0: function succeeded
   - \b -1: function failed
*/
int32_t GLCD_DrawBitmap (uint32_t x, 
                         uint32_t y, 
                         uint32_t width, 
                         uint32_t height, 
                         const uint8_t *bitmap)

Здесь связь между 5 параметрами показана на рисунке ниже:

Проще говоря, эта функция предназначена для bitmap «Область непрерывного хранения», на которую указывает указатель серединадержатьиз Информация о пикселях копируется вLCDизв пределах заданной прямоугольной области,этот Прямоугольная область содержит информацию о местоположении.(x,y)и Информация об объеме(width,height)совместно определенные。

Многие ЖК-дисплеи поддерживают концепцию, называемую «рабочим окном». Окно на самом деле представляет собой прямоугольную область, показанную на рисунке выше. Как только вы установите окно с помощью команды, пиксели, записанные непрерывно, будут автоматически заполняться в указанной области по очереди. прямоугольная область (без необходимости думать о том, когда нужно переносить изображение).

также,Если вам посчастливилось использовать чип с контроллером ЖК-дисплея, буфер дисплея ЖК-дисплея отображается непосредственно в адресное пространство 4 ГБ чипа Cortex-M.,Затем мы можем использовать простые операции чтения и записи в памяти для реализации вышеуказанной функции.,кSTM32F746G-DiscoveryМакетная плата в качестве примера:

Язык кода:javascript
копировать
//! STM32F746G-Discovery
#define GLCD_WIDTH     480
#define GLCD_HEIGHT    272

#define LCD_DB_ADDR   0xC0000000
#define LCD_DB_PTR    ((volatile uint16_t *)LCD_DB_ADDR)

int32_t GLCD_DrawBitmap (uint32_t x, 
                         uint32_t y, 
                         uint32_t width, 
                         uint32_t height, 
                         const uint8_t *bitmap) 
{
    volatile uint16_t *phwDes = LCD_DB_PTR + y * GLCD_WIDTH + x;
    const uint16_t *phwSrc = (const uint16_t *)bitmap;
    for (int_fast16_t i = 0; i < height; i++) {
        memcpy ((uint16_t *)phwDes, phwSrc, width * 2);
        phwSrc += width;
        phwDes += GLCD_WIDTH;
    }

    return 0;
}

7. в main.c Китай присоединяется к паре lv_port_disp_template.h Цитировать:

Язык кода:javascript
копировать
#include "lv_port_disp_template.h"

8、существоватьmain()функциясерединаверноLVGLруководитьинициализация:

Язык кода:javascript
копировать
int main(void)
{
    ...
    lv_init();
    lv_port_disp_init();
    ...
    while(1) {
        
    }   
}

На данный момент мы завершили развертывание LVGL в проекте MDK. Разве это не очень просто?

[Трансплантация, связанная со временем]


Согласно требованиям официального документа по портированию, нам фактически необходимо решить два вопроса:

  • Сообщите lvgl, сколько миллисекунд прошло с момента сброса
  • Примерно с интервалом в 5 мс вызывайте функцию lv_timer_handler() для обработки событий (включая обновление).

Зависит от платформы,Конечно, у вас, ребята, есть свои собственные решения. Это внутри,Я рекомендую одинMDKсреда Внизна основеperf_counterизплан,это более общее,Это также проще. Статьи о его использовании,Друзья могуткссылка《[Модули, которые на слуху] Супервстроенная система инструментов «производительность/время»》,Я не буду вдаваться в подробности по этому поводу.

Шаг 1: Получите perf_counter cmsis-пакет

После подписки на публичный аккаунт [Bare Metal Thinking] отправьте ключевое слово «perf_counter» на задний план. Получить соответствующееcmsis-пакет Ссылка на сетевой диск。Загрузите и установите。

Шаг 2. Разверните perf_counter в проекте.

Откройте окно конфигурации RTE, найдите «Утилиты», разверните его и выберите «Ядро» perf_counter:

Следует отметить, что,Используете ли вы операционную систему или нет,этотвнутри О различных операционных системахиз Patch Вы можете работать нормально, даже если вы не выбираете,Не волнуйся. Развертывание завершается после нажатия кнопки ОК.

Инициализируется в функции main(). perf_counter(Не забудьте добавить заголовочный файл perf_counter.h включает):

Язык кода:javascript
копировать
#include "perf_counter.h"

int main(void)
{
    /* Конфигурация MCU Тактовая частота системы */
    
    /* ВАЖНО: ОБНОВЛЕНИЕ SystemCoreClock переменная */
    SystemCoreClockUpdate(); 
    
    /* инициализация perf_counter */
    init_cycle_counter(true);
    ...
    while(1) {
    }
    ...
}

Что требует особого пояснения:

  • вызов init_cycle_counter() раньше, лучше пройти SystemCoreClockUpdate() обновить текущую частоту системы до ключевых глобальных переменных SystemCoreClock начальство. Конечно, вы также можете сделать это самостоятельно, используя операторы присваивания, например:
Язык кода:javascript
копировать
extern uint32_t SystemCoreClock;
    SystemCoreClock = 72000000ul;  /* 72MHz */
  • Если у вас уже есть приложение илиRTOSоккупированныйSysTick(一般都даэтот Образец),тогда это должно быть true перешел к init_cycle_counter() как параметр - скажите perf_counter SysTick уже занят; в противном случае его следует передать; false,в это время perf_counter Будет использовано максимальное значение 0x00FFFFFFПриходитьинициализацияSysTick。

Шаг третий: обновите Super Loop

Последняя версия LVGL предоставляет пользователям новый способ периодического обновления. LVGLЗадачафункция:lv_timer_handler_run_in_ period (количество миллисекунд).Будь то голый металл илиRTOSсреда,Можно просто вставить в суперцикл — обновлять функцию задачи LVGL через заданное количество мс интервалов.,Например:

Язык кода:javascript
копировать
int main(void)
{
    ...
    lv_init();
    lv_port_disp_init();
    lv_port_indev_init();
    ...
    while(1) {
        lv_timer_handler_run_in_period(LV_DISP_DEF_REFR_PERIOD);
    }
    
}

[Подсчет очков еще никогда не был таким простым]


После завершения трансплантации,Может быть, вам интересно узнать, какую частоту кадров может поддерживать ваша платформа в текущих условиях? Не волнуйтесь,LVGLизcmsis-packУже готовы к лучшему。ОткрытьRTEКонфигурацияокно,Проверятьbenchmark:

существовать main.c Китай присоединяется к паре lv_demo_benchmark.h «Косвенная» ссылка на:

Язык кода:javascript
копировать
#include "demos/lv_demos.h"

существовать LVGL После инициализации кода добавьтеbenchmark Безмозглая функция входа:

Язык кода:javascript
копировать
int main(void)
{
    lv_init();
    lv_port_disp_init();
    
#if LV_USE_DEMO_BENCHMARK
    lv_demo_benchmark();
#endif
    
    while(1) {
        lv_timer_handler_run_in_period(5);
    }
    
}

Скомпилируйте, запустите и вперед:

Эм…… Медленный, но распространенный случай……

последний benchmark позвольте нам пройтиlv_demo_benchmark_set_finished_cb()Зарегистрируйте обратный звонокфункция——Используется для сообщения нам о том, что все тесты завершены.:

Язык кода:javascript
копировать
static void on_benchmark_finished(void)
{
    
}

int main(void)
{
    lv_init();
    lv_port_disp_init();
    lv_port_indev_init();
    
    lv_demo_benchmark_set_finished_cb(&on_benchmark_finished);
    lv_demo_benchmark();
    //lv_demo_benchmark_set_max_speed(true);
    
    //lv_demo_benchmark_run_scene(43);      // run scene no 31

    while(1) {
        lv_timer_handler();
    }
}

Если нас интересует конкретный сценарий тестирования, мы также можем закомментировать существование. lv_demo_benchmark()После прохожденияфункция lv_demo_benchmark_run_scene() для запуска указанного пронумерованного сценария.

[Притворяться крутым ещё никогда не было так просто]


После завершения трансплантации,может быть, ты“снова”Будет интересно узнать текущую ситуациюсреда Вниз自己из平台能跑出怎Образециз Эффект?(Привет?зачем говоритьснова?)Не волнуйтесь,LVGLизcmsis-packУже готовы к лучшему。ОткрытьRTEКонфигурацияокно,Проверять Demo:Widgets:

существовать main.c Китай присоединяется к паре lv_demo_widgets.h «Косвенная» ссылка на:

Язык кода:javascript
копировать
#include "demos/lv_demos.h"

существовать LVGL После инициализации кода добавьте Demo Widgets Безмозглая функция входа:

Язык кода:javascript
копировать
int main(void)
{

    lv_init();
    lv_port_disp_init();
    
#if LV_USE_DEMO_BENCHMARK
    lv_demo_benchmark();
#endif
    
#if LV_USE_DEMO_WIDGETS
    lv_demo_widgets();
#endif

    while(1) {
        lv_timer_handler_run_in_period(5);
    }
    
}

нужен особенный Уведомлениеизда:Для запуска этой демонстрации стек не может быть меньше 4K.,Помнить,Помнить!

Скомпилируйте, запустите и вперед:

[Произнесите слова, стоящие за существованием]


наконец,верносуществоватьMDKКитайское использованиеcmsis-packПриходитьразвертыватьLVGLизинтересно узнать о процессе,Но снова хочет иметь эталонного партнера,Можетксосредоточиться Следующий проект с открытым исходным кодом (за поддержку которого я также отвечаю):

https://github.com/lvgl/lv_port_an547_cm55_sim

Следуйте инструкциям в readme,Вам даже не нужно оборудование для моделирования платы разработки Arm для бесплатного запуска LVGL в MDK.。Плюс недавноMDKПредоставляет несколько ограничений для случаев некоммерческого использования.из Сообществоверсия,Каждый уже может выпрямить спину и бесплатно заняться блудством в МДК.

также,если тыRaspberry Pi Picoизэнтузиаст,Вы также можете обратиться к этому официальному репозиторию («Снова» поддерживается мной):

https://github.com/lvgl/lv_port_raspberry_pi_pico_mdk

если он поможет тебе,Пожалуйста, дайте мне наградуStarах。


boy illustration
Учебное пособие по Jetpack Compose для начинающих, базовые элементы управления и макет
boy illustration
Код js веб-страницы, фон частицы, код спецэффектов
boy illustration
【новый! Суперподробное】Полное руководство по свойствам компонентов Figma.
boy illustration
🎉Обязательно к прочтению новичкам: полное руководство по написанию мини-программ WeChat с использованием программного обеспечения Cursor.
boy illustration
[Забавный проект Docker] VoceChat — еще одно приложение для мгновенного чата (IM)! Может быть встроен в любую веб-страницу!
boy illustration
Как реализовать переход по странице в HTML (html переходит на указанную страницу)
boy illustration
Как решить проблему зависания и низкой скорости при установке зависимостей с помощью npm. Существуют ли доступные источники npm, которые могут решить эту проблему?
boy illustration
Серия From Zero to Fun: Uni-App WeChat Payment Practice WeChat авторизует вход в систему и украшает страницу заказа, создает интерфейс заказа и инициирует запрос заказа
boy illustration
Серия uni-app: uni.navigateЧтобы передать скачок значения
boy illustration
Апплет WeChat настраивает верхнюю панель навигации и адаптируется к различным моделям.
boy illustration
JS-время конвертации
boy illustration
Обеспечьте бесперебойную работу ChromeDriver 125: советы по решению проблемы chromedriver.exe не найдены
boy illustration
Поле комментария, щелчок мышью, специальные эффекты, js-код
boy illustration
Объект массива перемещения объекта JS
boy illustration
Как открыть разрешение на позиционирование апплета WeChat_Как использовать WeChat для определения местонахождения друзей
boy illustration
Я даю вам два набора из 18 простых в использовании фонов холста Power BI, так что вам больше не придется возиться с цветами!
boy illustration
Получить текущее время в js_Как динамически отображать дату и время в js
boy illustration
Вам необходимо изучить сочетания клавиш vsCode для форматирования и организации кода, чтобы вам больше не приходилось настраивать формат вручную.
boy illustration
У ChatGPT большое обновление. Всего за 45 минут пресс-конференция показывает, что OpenAI сделал еще один шаг вперед.
boy illustration
Copilot облачной разработки — упрощение разработки
boy illustration
Микросборка xChatGPT с низким кодом, создание апплета чат-бота с искусственным интеллектом за пять шагов
boy illustration
CUDA Out of Memory: идеальное решение проблемы нехватки памяти CUDA
boy illustration
Анализ кластеризации отдельных ячеек, который должен освоить каждый&MarkerгенетическийВизуализация
boy illustration
vLLM: мощный инструмент для ускорения вывода ИИ
boy illustration
CodeGeeX: мощный инструмент генерации кода искусственного интеллекта, который можно использовать бесплатно в дополнение к второму пилоту.
boy illustration
Машинное обучение Реальный бой LightGBM + настройка параметров случайного поиска: точность 96,67%
boy illustration
Бесшовная интеграция, мгновенный интеллект [1]: платформа больших моделей Dify-LLM, интеграция без кодирования и встраивание в сторонние системы, более 42 тысяч звезд, чтобы стать свидетелями эксклюзивных интеллектуальных решений.
boy illustration
LM Studio для создания локальных больших моделей
boy illustration
Как определить количество слоев и нейронов скрытых слоев нейронной сети?
boy illustration
[Отслеживание целей] Подробное объяснение ByteTrack и детали кода