gpt4 book ai didi

c - 声明为 static const 的结构如何在 RAM 中结束? (在 C 中)

转载 作者:太空狗 更新时间:2023-10-29 15:22:16 24 4
gpt4 key购买 nike

我正在尝试将一些可怕的混淆代码从 Codewarrior 移植到 Crossworks。这些库是用 C 语言编写的,但我认为是在尝试模仿 C++ 对象。

当声明这些对象时,它们是通过使用宏的宏来完成的,这些宏使用宏,这使得很难遵循!我使用预处理器扩展了它们,使其更容易理解。

现在,在基于 [working] Codwarrior Eclipse 的系统下,有一段文本,在源代码中指定为 static const,最终出现在 RAM 中。据我所知,链接器将其他指定为静态常量的内容放入闪存中。在 Crossworks 中,一切都在闪光中​​结束——这对我来说很有意义。

这是从宏展开后有问题的声明的一个示例:

static const D4D_LABEL scrSplash_lblSID_params
= { { " Unit ID: 42949672955" , sizeof(" Unit ID: 42949672955"), 0, &scrSplash_lblSID_strPrties}, { 6, 76 }, { 118, 16 }, 8 };

D4D标签定义如下:

typedef struct
{
D4D_STRING textBuff; // label text
D4D_POINT scrPos; // position on the screen
D4D_SIZE scrSize; // size on the screen (focus rect only, bitmaps have own size)
D4D_COOR radius; // corner radius
} D4D_LABEL;

D4D_STRING 定义如下:

typedef struct D4D_STRING_S 
{
char *pText;
D4D_INDEX buffSize;
D4D_FONT fontId;
D4D_STR_PROPERTIES *str_properties;
D4D_INDEX printLen;
D4D_INDEX printOff;
}D4D_STRING;

此 D4D_LABEL 按如下方式放入 D4D_OBJECT:

const D4D_OBJECT scrSplash_lblSID = { (void*)&(scrSplash_lblSID_params), (D4D_OBJECT_SYS_FUNCTION*)&d4d_labelSysFunc, 
(void*)0, (void*)0, (0x01 | 0x02 | 0x40), &(scrSplash_lblSID_flags), (void*)0, &(scrSplash_lblSID_pScreen) };

D4D_OBJECT 是这样定义的:

// this is allocated in ROM always
typedef struct D4D_OBJECT_S
{
void* pParam;
D4D_OBJECT_SYS_FUNCTION* pObjFunc;
Byte (*OnUsrMessage)(struct D4D_MESSAGE_S* pMsg);
void *userPointer;
D4D_OBJECT_INITFLAGS initFlags;
D4D_OBJECT_FLAGS* flags;
struct D4D_CLR_SCHEME_S* clrScheme;
struct D4D_SCREEN_S** pScreen;
} D4D_OBJECT;

据我所知,首先放入 D4D_OBJECT scrSplash_lblSID 的是指向 D4D_LABEL scrSplash_lblSID_params 的指针。该 D4D 标签被声明为静态常量,因此放入闪存中。 Crossworks 做到了这一点,而 Codewarrior 在 RAM 中拥有它。

当使用这个函数时:

void D4D_SetText(D4D_OBJECT_PTR pObject, char* pText) 
{
D4D_STRING* p_TextBuff = NULL;

if(pObject->pObjFunc->GetTextBuffer)
p_TextBuff = pObject->pObjFunc->GetTextBuffer((D4D_OBJECT*)pObject);

// ABOVE line equates to: return &(((D4D_LABEL*)((pThis)->pParam))->textBuff);

if(p_TextBuff)
{
D4D_ChangeText(p_TextBuff, pText, 0);
D4D_InvalidateObject(pObject, D4D_FALSE);
}

}

通过以下行:

D4D_SetText(&scrSplash_lblSID, SIdString);

p_TextBuff 在Codewarrior 中是一个RAM 位置,在Crossworks 中是一个flash 位置。 ChangeText 函数试图将 pText 指向的字符串复制到闪存中,当然,处理器(Freescale 的 Cortex M4 - Kinetis 处理器)崩溃了!

以上信息是否足以给我提供建议?我猜 Codewarrior 项目的链接器文件中有一些东西设法使相关字符串最终出现在 RAM 中而不是闪存中。我看不出链接器如何神奇地知道将静态常量放入 RAM 而不是像其他东西一样闪烁!

链接器文件位于下方,以防它可能相关。

非常感谢!

# Default linker command file.
MEMORY {
m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x000001E0 # Interrupts
m_text (RX) : ORIGIN = 0x00004400, LENGTH = 0x0003BC00 # Code and read only data
m_data (RW) : ORIGIN = 0x1FFF0000, LENGTH = 0x00020000 # Read/write data


}

KEEP_SECTION { .vectortable }
KEEP_SECTION { .cfmconfig }

SECTIONS {

.interrupts :
{
__vector_table = .;
* (.vectortable)
. = ALIGN (0x4);
} > m_interrupts

# All the stuff that lives in flash: the application (.text), read only data (.rodata) and .init - whatever the latter is

.app_text:
{
ALIGNALL(4);
* (.init)
* (.text)
.= ALIGN(0x8) ;
* (.rodata)
.= ALIGN(0x4) ;
___ROM_AT = .;
} > m_text

# App data is INITIALISED data. So stuff that was specified in flash, but gets copied to RAM at boot

.app_data: AT(___ROM_AT)
{
* (.sdata)
* (.data)
.= ALIGN(0x4) ;
*(.ARM.extab)
.= ALIGN(0x4) ;
__exception_table_start__ = .;
EXCEPTION
__exception_table_end__ = .;
.= ALIGN(0x4) ;
__sinit__ = .;
STATICINIT
.= ALIGN(0x8) ;
} > m_data

# .bss is UNINITIALISED data that just lives in normal RAM - after the initialised stuff

.bss :
{
.= ALIGN(0x4) ;
__START_BSS = .;
* (.bss)
__END_BSS = .;
.= ALIGN(0x8) ;
} >> m_data

_romp_at = ___ROM_AT + SIZEOF(.app_data);
.romp : AT(_romp_at)
{
__S_romp = _romp_at;
WRITEW(___ROM_AT);
WRITEW(ADDR(.app_data));
WRITEW(SIZEOF(.app_data));
WRITEW(0);
WRITEW(0);
WRITEW(0);
}

__SP_INIT = . + 0x00008000;
__heap_addr = __SP_INIT;
__heap_size = 0x00008000;

}

最佳答案

对象声明为static const是无关紧要的;您要写入的字符串是 D4D_STRING 中的指针:

typedef struct D4D_STRING_S 
{
char *pText;

这是从字符串文字 "Unit ID: 42949672955" 初始化的,写入字符串文字是未定义的行为。

如果您的编译器接受-fwritable-strings 选项(gcc 4.0 之前的版本,clang 的某些版本),那么您可以使用该选项将字符串文字放入RAM。首选的替代方法是使用可变字符缓冲区:

char scrSplash_lblSID_params_text[] = "   Unit ID: 42949672955";

关于c - 声明为 static const 的结构如何在 RAM 中结束? (在 C 中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16648968/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com