string - 在FLASH中留下数据数组(字体) - AVR GCC中的PROGMEM

标签 string memory avr avr-gcc winavr

啊哈,PROGMEM,指针,指针的指针,指针的地址……我的头都晕了。

我有相关字体的数据数组

const uint8_t dejaVuSans9ptBitmaps[] = 
{
    /* @0 ' ' (5 pixels wide) */
    0x00, /*          */
    0x00, /*          */
...

我已经添加了 PROGMEM
const uint8_t dejaVuSans9ptBitmaps[] PROGMEM =

这是在另一个结构中引用的;
const FONT_INFO dejaVuSans9ptFontInfo = {
   13,
   ' ',
   '~',
   dejaVuSans9ptDescriptors, 
   dejaVuSans9ptBitmaps,
};

结构定义为;
typedef struct {
   const uint8_t           height;       
   const uint8_t           startChar;    
   const uint8_t           endChar;      
   const FONT_CHAR_INFO*   charInfo;    
   const uint8_t*          data;         
} FONT_INFO;

我假设这需要更改为正确吗?
typedef struct {
   const uint8_t           height;       
   const uint8_t           startChar;    
   const uint8_t           endChar;      
   const FONT_CHAR_INFO*   charInfo;    
   const PGM_P             data;         
} FONT_INFO;

当我这样做时,它提示说
warning: pointer targets in initialization differ in signedness

对于 FONT_INFO 变量中的这一行;
const FONT_INFO dejaVuSans9ptFontInfo = {
    13,
    ' ',
    '~',
    dejaVuSans9ptDescriptors, 
--> dejaVuSans9ptBitmaps, <--
};

然后使用函数绘制;
void drawString(uint16_t x, uint16_t y, uint16_t color, const FONT_INFO *fontInfo, char *str) {
    ...
    drawCharBitmap(currentX, y, color, &fontInfo->data[charOffset], charWidth, fontInfo->height);
    ...

最终绘制出字形;
void drawCharBitmap(const uint16_t xPixel, const uint16_t yPixel, uint16_t color, const uint8_t *glyph, uint8_t cols, uint8_t rows) {
   ...
      if (glyph[indexIntoGlyph] & (0X80)) drawPixel(currentX, currentY, color);
   ...

我不知所措:/谁能给我一些指导?我花了几个小时试图使用 PGM_P 和 pgm_read_byte 等,但无济于事 - 我总是在屏幕上看到垃圾。

救我!

最佳答案

好的,我想我明白这里发生了什么。

一、const uint8_t* data是指向存储在 PROGMEM 中的数据的指针。

function void drawString(uint16_t x, uint16_t y, uint16_t color, const FONT_INFO *fontInfo, char *str)我们传递一个指向 fontInfo 的指针.

要继续,了解以下内容很重要;

fontInfo.data
(*ptr_to_fontInfo).data
ptr_to_fontInfo->data

都是一样的。所以ptr_to_fontInfo->data返回数据(不是地址)

然后使用 &运算符,我们将此数据的“地址”传递给下一个函数
drawCharBitmap(currentX, y, color, 
  &fontInfo->data[charOffset], charWidth, fontInfo->height)

该地址存储在声明的指针变量 unint8_t *glyph 中。这里;
void drawCharBitmap(const uint16_t xPixel, const uint16_t yPixel, 
  uint16_t color, const uint8_t *glyph, uint8_t cols, uint8_t rows)

牢记这一点;
int *ptr;
int a;

ptr = &a;

然后字形现在指向与 fontInfo->data[charOffset] 相同的地址.

接下来要知道的是;

a[b] in C is just a fancy way for writing *(a + b)



所以字形是一个指针,当像这样使用时 glyph[indexIntoGlyph] , 同 *(glyph + indexIntoGlyph) , 和解引用运算符 *意味着我们在该地址获取数据。

从那里,我们可以使用 wex 描述的 pgm 规则;

If the variable is in PROGMEM, you use pgm_read_byte() as a replacement for the dereference operator *. For "normal" variables in RAM you can always write *(&a) instead of just a to return the value of the variable a; so to return a 8-bit wide variable from progmem you write pgm_read_byte(&x).



希望这个解释是正确的,可以帮助人们(像我这样的新手!)更好地理解它。

关于string - 在FLASH中留下数据数组(字体) - AVR GCC中的PROGMEM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8276172/

相关文章:

python - 'str' 对象没有属性 'decode'

Java判断一个字符串是否为回文的方法

PHP-CLI - 如何减少启动 PHP 进程所需的内存使用量

c - 如何从 CodeVision AVR 迁移到 AVR Studio 5

string - Xcode 字符串搜索算法

javascript - 为什么 JavaScript string.split(/[ -_]+/) 的行为就像引号 (' and ") 包含在 [group] 中一样?

c++ - 32B block ,连续和非连续内存访问

java - android中的MemoryFile有什么用

c++ - 通过引用将 int 数组传递给构造函数

c - __C_task 符号,什么意思?