我正在尝试将一些可怕的混淆代码从 Codewarrior 移植到 Crossworks。这些库是用 C 语言编写的,但我认为它正在尝试模仿 C++ 对象。
当这些对象被声明时,它们是通过使用宏的宏来完成的,这些宏使用宏,这使得它很难遵循!我使用预处理器扩展了它们,使其更容易理解。
现在,在基于 [工作] Codwarrior Eclipse 的系统下,有一段文本,在源代码中指定为静态 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 中的闪存位置。ChangeText 函数尝试将 pText 指向的字符串复制到闪存中,当然,处理器(飞思卡尔的 Cortex M4 - Kinetis 处理器)崩溃了!
以上是否有足够的信息可以为我提供建议?我猜想 Codewarrior 项目的链接器文件中有一些东西设法使相关字符串最终出现在 RAM 中而不是闪存中。我看不出链接器是如何神奇地知道将静态 const 放入 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;
}