combinando dados compactados com acesso alinhado à memória

Estou tentando executar uma otimização de memória que deveria ser teoricamente possível, mas que estou começando a duvidar que esteja dentro da capacidade do arm-elf-gcc. Por favor, mostre-me que estou errado.

Eu tenho um sistema incorporado com uma quantidade muito pequena de memória principal e uma quantidade ainda menor de nvram com bateria. Estou armazenando dados de configuração de soma de verificação no nvram para que na inicialização eu possa validar a soma de verificação e continuar uma execução anterior ou iniciar uma nova, se a soma de verificação for inválida. Durante a execução, atualizo vários campos de vários tamanhos nesses dados de configuração (e não há problema em invalidar a soma de verificação até que seja recalculada posteriormente).

Tudo isso é executado no espaço de endereço físico - o sram normal é mapeado em um local e o nvram é mapeado em outro. Aqui está o problema - todo o acesso ao nvram deve ser feito em palavras de 32 bits; nenhum acesso de byte ou meia palavra é permitido (embora esteja obviamente bom na memória principal).

Assim, eu posso: a) armazenar uma cópia de trabalho de todos os meus dados de configuração na memória principal e copiá-la para o nvram quando recalcular a soma de verificação ou b) trabalhar diretamente com ela no nvram, mas de alguma forma convencer o compilador de que todas as estruturas são embalado e todos os acessos não devem ser apenas de 32 bitsalinhado, mas também de 32 bitsLargo.

A opção a) desperdiça preciosa memória principal, e eu preferiria fazer a troca em tempo de execução para salvá-la (embora não se o tamanho do código acabar desperdiçando mais do que economizo no tamanho dos dados) através da opção b).

Eu estava esperando que__attribute__ ((packed, aligned(4))) ou alguma variação disso poderia ajudar aqui, mas todas as leituras e experiências que fiz até agora me decepcionaram.

Aqui está um exemplo de brinquedo do tipo de dados de configuração com os quais estou lidando:

#define __packed __attribute__ ((packed))
struct __packed Foo
{
    uint64_t foo;
    struct FooFoo foofoo;
}

struct __packed Bar
{
    uint32_t something;
    uint16_t somethingSmaller;
    uint8_t evenSmaller;
}

struct __packed PersistentData
{
    struct Foo;
    struct Bar;
    /* ... */
    struct Baz;
    uint_32 checksum;
}

Você pode imaginar threads diferentes (um para executar as funções Foo, Bar e Baz) atualizando suas próprias estruturas conforme apropriado e sincronizando em algum momento para declarar que é hora de recalcular a soma de verificação e adormecer.

questionAnswers(4)

yourAnswerToTheQuestion