使用X-macro扩展时强制字符串和指针进入闪存

时间:2016-04-20 20:49:23

标签: c embedded x-macros

我以为我对X-macros很了解,但这真的让我感到难过。我定义了以下代码:

#define FOR_DESCR_STRINGS(apply) \
    apply(LANGUAGE_ID_STRING, "\0x04\0x03\0x09\0x04")  \
    apply(MANUFACTURER_STRING, "Quest Engineering & Development, Inc.") \
    apply(PRODUCT_STRING, "PowerExpander Eq10E") \
    apply(SERIAL_NUMBER_STRING, "\0x00")              \
    apply(MS_OS_COMPAT_STRING "MSFT100\0xFF")

#define SELECT_DESCR_STRING_ID(a, b) a,
#define SELECT_DESCR_STRING(a, b) b
#define SELECT_DESCR_STRING_PTR(a, b) b,

enum
{
     FOR_DESCR_STRINGS(SELECT_DESCR_STRING_ID)
     DESCR_STRING_CNT
};

const uint8_t  DESCR_STRINGS[][] = /* Array of Descriptor Strings */
    {FOR_DESCR_STRINGS(SELECT_DESCR_STRING)};  

const uint8_t* DESCR_STRING_PTRS[] = /* Array of Descriptor String Ptrs */
    {FOR_DESCR_STRINGS(SELECT_DESCR_STRING_PTR)}; 

我希望字符串和指针进入闪存,但我最终得到的是.rodata,其中指针和字符串在C启动代码期间被复制到RAM。反正有没有做我想做的事情(定义多个字符串并将指针数组定义为字符串)所以它们保留在flash中并且在使用X-macros时不会复制到RAM中? 谢谢,

1 个答案:

答案 0 :(得分:-1)

你的问题不在于宏扩展或C,就像链接器和分散收集/链接描述符文件一样,也可能与你的底层硬件有关。

private EntityManager em; public User findByName(String firstName, String lastName) { TypedQuery<User> query = em.createQuery( "SELECT u FROM User u WHERE u.firstName = :firstName " + "AND u.lastName = :lastName", User.class) .setParameter("firstName", firstName).setParameter("lastName", lastName); List<User> users = query.getResultList(); if (!users.isEmpty()) { return users.iterator().next(); } else { return null; } } public void save(User user) { if (user.getId() == null) { em.persist(user); } else { em.merge(user); } } 数据几乎总是指向const,它由链接描述符文件放置在内存映射中,该文件也是(有点......并且可能非常间接地)指定的内容需要由启动库初始化或不启动。

您或许可以使用.rodata#pragma将部分名称从__attribute__()更改为.rodata,但这些事情是出了名的变化,脆弱,并且特定于供应商。 GNU的做法与Keil,IAR或GHS有所不同,有时机制和未记录的功能(比如你捅它直到它适用于你)从版本变为版本。

即使你可以,你可能会发现你的USB控制器根本无法访问闪存,因此无论如何都需要将它扩展到SRAM中。