📄 boot_osd.c
字号:
/* * * Copyright (c) Sigma Designs, Inc. 2002. All rights reserved. * *//** @file boot_osd.c @brief sample application to generate files to display a bitmap at boot time @author Julien Soulier @ingroup dccsamplecode*/#include "sample_os.h"#define ALLOW_OS_CODE 1#include "common.h"#define USERPREF "userpref"#define BITMAP "bitmap"#define VSYNCPARAM "vsyncparam"#define PALETTE "palette"#define XENV "xenv"#define _BIN ".bin"#define _TXT ".txt"#define TMPFILE_PATTERN "boot_osdXXXXXX"#define RLED 0x44454c52#define RAWD 0x44574152#define CHUNK 4096#define NO_COMPRESSION 0#define COMPRESSION_4BPP 1#define COMPRESSION_7BPP 2static RMstatus read_memory(struct RUA *pRUA, RMuint32 rua_addr, RMuint32 size, RMuint8 *user_addr){ RMuint32 chunk; RMuint8 *BaseAddr; RMstatus err;#if (EM86XX_MODE == EM86XX_MODEID_WITHHOST) || (EM86XX_CHIP>=EM86XX_CHIPID_TANGO2) while (size) { chunk = RMmin(size, 0x100000); // 1 MByte max err = RUALock(pRUA, rua_addr, chunk); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error locking OSD buffer at 0x%08lX (0x%08lX bytes): %d\n", rua_addr, chunk, err)); return err; } BaseAddr = RUAMap(pRUA, rua_addr, chunk); if (BaseAddr == NULL) { RMDBGLOG((ENABLE, "Error mapping OSD buffer at 0x%08lX (0x%08lX bytes)\n", rua_addr, chunk)); return RM_ERROR; } RMMemcpy(user_addr, BaseAddr, chunk); RUAUnMap(pRUA, BaseAddr, chunk); err = RUAUnLock(pRUA, rua_addr, chunk); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error unlocking OSD buffer at 0x%08lX (0x%08lX bytes): %d\n", rua_addr, chunk, err)); return err; } rua_addr += chunk; size -= chunk; user_addr += chunk; }#else BaseAddr = (RMuint8 *)rua_addr; chunk = 0; err = RM_OK; RMMemcpy(user_addr, BaseAddr, size);#endif return RM_OK;}static RMuint32 get_sum(RMuint8 *buf, RMuint32 size){ RMuint32 sum = 0, i; for (i=0 ; i < (size >>2) ; i++ , buf += 4) sum += RMleBufToUint32(buf); if (size & 0x3) { RMuint8 c[4] = {0,}; for (i = 0; i < (size & 0x3); i++) c[i] = *buf++; sum += RMleBufToUint32(c); } return sum;}#if (EM86XX_CHIP<EM86XX_CHIPID_TANGO2)static RMstatus write_section_header(int fd, RMuint32 type, RMuint32 addr, RMuint32 size, RMuint32 *sum){ RMuint8 out_buf[4]; RMint32 len; RMuint32ToLeBuf(type, out_buf); len = write(fd, out_buf, 4); if (len < 4) { fprintf(stderr, "Error while writing type field in header! %ld\n", len); return RM_ERROR; } *sum += type; RMuint32ToLeBuf(addr, out_buf); len = write(fd, out_buf, 4); if (len < 4) { fprintf(stderr, "Error while writing address field in header! %ld\n", len); return RM_ERROR; } *sum += addr; RMuint32ToLeBuf(size, out_buf); len = write(fd, out_buf, 4); if (len < 4) { fprintf(stderr, "Error while writing size field in header! %ld\n", len); return RM_ERROR; } *sum += size; return RM_OK;}#endif // EM86XX_CHIPstatic RMstatus write_data_chunk(struct RUA *pRUA, int fd, RMuint32 data_addr, RMuint32 data_size, RMuint32 *sum){ RMuint8 out_buf[CHUNK]; RMuint32 rd_size, wr_size, total_size; RMint32 len; RMstatus err; total_size = 0; while (total_size < data_size) { rd_size = RMmin(CHUNK, data_size - total_size); err = read_memory(pRUA, data_addr + total_size, rd_size, out_buf); if (RMFAILED(err)) { fprintf(stderr, "Error while reading data section! %d\n", err); return err; } *sum += get_sum(out_buf, rd_size); wr_size = 0; while (wr_size < rd_size) { len = write(fd, out_buf+wr_size, rd_size-wr_size); if (len <= 0) { fprintf(stderr, "Error while writing chunk of data section! %ld\n", len); return RM_ERROR; } wr_size += len; } total_size += rd_size; } /* alignment on 32 bits */ while (total_size & 0x3) { RMuint8 c=0; len = write(fd, &c, 1); if (len <= 0) { fprintf(stderr, "Error while making data alignment of data section! %ld\n", len); return RM_ERROR; } total_size ++; } return RM_OK;}#if (EM86XX_CHIP<EM86XX_CHIPID_TANGO2)static RMstatus write_zero_chunk(int fd, RMuint32 data_size){ RMuint8 out_buf[CHUNK]; RMuint32 rd_size, wr_size, total_size; RMint32 len; memset(out_buf, 0, CHUNK); total_size = 0; while (total_size < data_size) { rd_size = RMmin(CHUNK, data_size - total_size); wr_size = 0; while (wr_size < rd_size) { len = write(fd, out_buf+wr_size, rd_size-wr_size); if (len <= 0) { fprintf(stderr, "Error while writing chunk of 0! %ld\n", len); return RM_ERROR; } wr_size += len; } total_size += rd_size; } return RM_OK;}#endif // EM86XX_CHIPstatic RMstatus create_vsyncparam(struct RUA *pRUA, RMuint32 vsyncapi_addr, RMuint32 vsyncapi_size, RMascii *dir_name){ RMuint32 sum=0; int fd; RMstatus err; RMascii filename[2048]; #if (EM86XX_CHIP<EM86XX_CHIPID_TANGO2) snprintf(filename, 2048, "%s/%s%s", dir_name, VSYNCPARAM, _BIN); #else snprintf(filename, 2048, "%s/%s_0x%08lx%s", dir_name, VSYNCPARAM, vsyncapi_addr, _BIN); #endif // EM86XX_CHIP fd = open(filename, O_CREAT | O_WRONLY, S_IRWXU | S_IRWXG | S_IRWXO); if (fd == -1) { fprintf(stderr, "Could not open %s%s\n" , VSYNCPARAM, _BIN); return RM_ERROR; } /* write vsync api buffer */ err = write_data_chunk(pRUA, fd, vsyncapi_addr, vsyncapi_size - 4, &sum); if (RMFAILED(err)) { fprintf(stderr, "Cannot copy the vsync API inside userpref! %d\n", err); return err; } #if (EM86XX_CHIP<EM86XX_CHIPID_TANGO2) { RMuint8 out_buf[4]; RMint32 len; /* write sum */ sum = ~sum + 1; RMuint32ToLeBuf(sum, out_buf); len = write(fd, out_buf, 4); if (len < 4) { fprintf(stderr, "Error while writing sum of vsync API! %ld\n", len); return RM_ERROR; } }#endif // EM86XX_CHIP close(fd); return RM_OK;}#if (EM86XX_CHIP<EM86XX_CHIPID_TANGO2)static RMstatus create_userpref(struct RUA *pRUA, RMuint32 vsyncapi_addr, RMuint32 vsyncapi_size, RMascii *dir_name){ RMuint8 out_buf[CHUNK]; RMuint32 sum=0; RMint32 len; int fd; RMstatus err; RMascii filename[2048]; snprintf(filename, 2048, "%s/%s%s", dir_name, USERPREF, _BIN); fd = open(filename, O_CREAT | O_WRONLY, S_IRWXU | S_IRWXG | S_IRWXO); if (fd == -1) { fprintf(stderr, "Could not open %s%s\n" , USERPREF, _BIN); return RM_ERROR; } /* first put to zero first 32KB */ err = write_zero_chunk(fd, 32768); if (RMFAILED(err)) { fprintf(stderr, "Cannot create the first 32KB of userpref! %d\n", err); return err; } /* write vsync api buffer */ err = write_data_chunk(pRUA, fd, vsyncapi_addr, vsyncapi_size - 4, &sum); if (RMFAILED(err)) { fprintf(stderr, "Cannot copy the vsync API inside userpref! %d\n", err); return err; } /* write sum */ sum = ~sum + 1; RMuint32ToLeBuf(sum, out_buf); len = write(fd, out_buf, 4); if (len < 4) { fprintf(stderr, "Error while writing sum of vsync API! %ld\n", len); return RM_ERROR; } /* complete with 0 to have another 32KB */ err = write_zero_chunk(fd, 32768-vsyncapi_size); if (RMFAILED(err)) { fprintf(stderr, "Cannot create the last 0 to fill 32KB in userpref! %d\n", err); return err; } close(fd); return RM_OK;}static RMstatus add_raw_section(struct RUA *pRUA, int fd, RMuint32 addr, RMuint32 size, RMuint32 *sum){ RMstatus err; err = write_section_header(fd, RAWD, addr, size, sum); if (RMFAILED(err)) { fprintf(stderr, "Error while writing section header of raw data! %d\n", err); return err; } err = write_data_chunk(pRUA, fd, addr, size, sum); if (RMFAILED(err)) { fprintf(stderr, "Error while writing data of raw data! %d\n", err); return err; } return RM_OK;}static RMuint8 bmp_get_4bits(RMuint8 **pin, RMuint32 *toggle){ RMuint8 val; val = ((**pin) >> (*toggle * 4)) & 0xf; *toggle = 1 - *toggle; if (*toggle == 1) *pin = *pin + 1; return val;}static void bmp_set_4bits(RMuint8 **pout, RMuint8 val, RMuint32 *toggle){ if (*toggle) **pout = (val & 0xf) << 4; else **pout |= (val & 0xf); *toggle = 1 - *toggle; if (*toggle == 1) *pout = *pout + 1;}static RMuint32 compress_line_4bpp(RMuint8 *in_buf, RMuint32 width, RMuint8 *out_buf, RMuint32 out_size){ RMuint8 *pin = in_buf, *pout=out_buf; RMuint32 in_toggle = 1, out_toggle = 1; RMuint8 color, c; RMuint32 count, i; color = bmp_get_4bits(&pin, &in_toggle); count = 1; for (i=1 ; i<width ; i++) { c = bmp_get_4bits(&pin, &in_toggle); if (color != c) { bmp_set_4bits(&pout, color, &out_toggle); while (count > 7) { bmp_set_4bits(&pout, (0x8 | (count & 0x7)), &out_toggle); count = count >> 3; } bmp_set_4bits(&pout, (count & 0x7), &out_toggle); color = c; count = 1; } else count++; } bmp_set_4bits(&pout, color, &out_toggle); bmp_set_4bits(&pout, 0, &out_toggle); if (out_toggle == 0) { out_toggle = 1; pout ++; } return (pout - out_buf);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -