feat(assets): embed LCD and audio resources in OTA app
This commit is contained in:
@@ -7,15 +7,13 @@
|
||||
|
||||
#include "lcd_direct.h"
|
||||
#include "lcd_direct_assets.h"
|
||||
#include "platform_asset_bundle.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/ledc.h"
|
||||
@@ -55,7 +53,7 @@
|
||||
#define LCD_DIRECT_PREHEAT_WAIT_TIMEOUT_MS 5000U
|
||||
/*
|
||||
* PNG 缓存固定6项并使用 LRU 淘汰,限制 PSRAM 峰值;边界测试恰好覆盖一次完整
|
||||
* 缓存命中周期。路径上限同时约束缓存键和 LittleFS 资源路径复制。
|
||||
* 缓存命中周期。名称上限同时约束缓存键和嵌入式素材索引。
|
||||
*/
|
||||
#define LCD_DIRECT_FRAME_CACHE_MAX 6U
|
||||
#define LCD_DIRECT_BOUNDARY_TEST_CACHE_HIT_FRAMES LCD_DIRECT_FRAME_CACHE_MAX
|
||||
@@ -316,55 +314,6 @@ static uint16_t lcd_direct_blend_rgb565(uint16_t dst, uint16_t src, uint8_t alph
|
||||
return lcd_direct_rgb888_to_rgb565(out_r, out_g, out_b);
|
||||
}
|
||||
|
||||
static esp_err_t lcd_direct_read_file_psram(const char *path, unsigned char **out_data, size_t *out_size)
|
||||
{
|
||||
/* 整个 PNG 文件优先读入 PSRAM;任何短读都视为失败并关闭句柄。 */
|
||||
ESP_RETURN_ON_FALSE(path != NULL && out_data != NULL && out_size != NULL,
|
||||
ESP_ERR_INVALID_ARG,
|
||||
TAG,
|
||||
"invalid PNG read request");
|
||||
*out_data = NULL;
|
||||
*out_size = 0;
|
||||
|
||||
errno = 0;
|
||||
int fd = open(path, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
ESP_LOGE(TAG, "open PNG asset failed path=%s errno=%d", path, errno);
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
off_t file_size = lseek(fd, 0, SEEK_END);
|
||||
if (file_size <= 0 || lseek(fd, 0, SEEK_SET) < 0) {
|
||||
ESP_LOGE(TAG, "stat PNG asset failed path=%s errno=%d", path, errno);
|
||||
close(fd);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
unsigned char *data = (unsigned char *)lcd_direct_alloc_psram((size_t)file_size);
|
||||
if (data == NULL) {
|
||||
ESP_LOGE(TAG, "allocate PNG file buffer failed path=%s size=%u", path, (unsigned)file_size);
|
||||
close(fd);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
size_t offset = 0;
|
||||
while (offset < (size_t)file_size) {
|
||||
ssize_t bytes_read = read(fd, data + offset, (size_t)file_size - offset);
|
||||
if (bytes_read <= 0) {
|
||||
ESP_LOGE(TAG, "read PNG asset failed path=%s errno=%d", path, errno);
|
||||
free(data);
|
||||
close(fd);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
offset += (size_t)bytes_read;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
*out_data = data;
|
||||
*out_size = (size_t)file_size;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void lcd_direct_release_decoded_image(lcd_direct_decoded_image_t *decoded)
|
||||
{
|
||||
if (decoded == NULL) {
|
||||
@@ -386,18 +335,19 @@ static esp_err_t lcd_direct_decode_png(const char *path,
|
||||
"invalid PNG decode request");
|
||||
memset(out_decoded, 0, sizeof(*out_decoded));
|
||||
|
||||
unsigned char *png_data = NULL;
|
||||
size_t png_size = 0;
|
||||
esp_err_t read_err = lcd_direct_read_file_psram(path, &png_data, &png_size);
|
||||
if (read_err != ESP_OK) {
|
||||
return read_err;
|
||||
/* PNG 字节直接取自应用镜像的只读映射区;解码器只读取输入,不持有或释放该指针。 */
|
||||
platform_asset_view_t asset = {0};
|
||||
esp_err_t find_err = platform_asset_find(path, &asset);
|
||||
if (find_err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "find PNG asset failed path=%s err=%s", path, esp_err_to_name(find_err));
|
||||
return find_err;
|
||||
}
|
||||
|
||||
unsigned char *rgba = NULL;
|
||||
unsigned width = 0;
|
||||
unsigned height = 0;
|
||||
unsigned decode_err = lodepng_esp_decode32(&rgba, &width, &height, png_data, png_size);
|
||||
free(png_data);
|
||||
unsigned decode_err = lodepng_esp_decode32(&rgba, &width, &height,
|
||||
asset.data, asset.size);
|
||||
if (decode_err != 0U) {
|
||||
ESP_LOGE(TAG, "decode PNG failed path=%s error=%u text=%s",
|
||||
path,
|
||||
|
||||
Reference in New Issue
Block a user