Speicherzuweisung von Konstanten und Statik in der Struktur?

Ich arbeite an der IIR-Filterimplementierung, bei der ich Filterkoeffizienten und Speicher (Form-2 w) wie folgt initialisiere.

typedef struct
{
const _iq b_coeff[NUM_OF_COEFF];
const _iq a_coeff[NUM_OF_COEFF];
_iq w[NUM_OF_COEFF];
}IIR_FILTER;

Da gibt es Konstanten und statische Variablen in der Struktur. Normalerweise ordnet der Compiler Konstanten im FLASH (.cinit) und statische im RAM (.ebss) zu. [Ich verwende CCS Compiler mit TMS320F28033, falls das hilft]

Meine Frage ist also, wie der Compiler dies zuweisen wird, da es sich um eine Struktur handelt.

Dies können Sie leicht selbst überprüfen, indem Sie die Kartendatei kompilieren und nachsehen. Und Sie können sogar Ihre Ergebnisse teilen.

Antworten (2)

Der Compiler kann die Speicherzuweisung für Ihre Struktur nicht zwischen RAM und FLASH aufteilen.
Alle Strukturvariablen, die Sie mit diesem Typ erstellen, befinden sich dort, wo Sie den Compiler anweisen, die gesamte Struktur abzulegen, also:
IIR_FILTER f1;befinden sich im RAM und
const IIR_FILTER f2;im FLASH.

Wenn sich die Struktur jedoch im RAM befindet (wie f1oben), sollte Ihr Compiler Ihnen einen Fehler ausgeben, wenn Sie versuchen, einem als deklarierten Member einen Wert zuzuweisen const, also:
f1.b_coeff[0] = 5;sollte einen Compilerfehler erzeugen, obwohl sich f1 im RAM befindet.

Ich gehe davon aus, dass der Grund, warum Sie so etwas tun möchten, darin besteht, RAM-Nutzung zu sparen.
Eine Technik, die Sie verwenden könnten und die für Sie funktionieren könnte, wäre etwa:

typedef struct
{
    const _iq * const b_coeff;
    const _iq * const a_coeff;
    _iq w[NUM_OF_COEFF];
} IIR_FILTER;

const _iq b_coeff_const[NUM_OF_COEFF];
const _iq a_coeff_const[NUM_OF_COEFF];

und dann, wenn Sie die Strukturvariable deklarieren:
IIR_FILTER f1 = {.b_coeff = b_coeff_const, .a_coeff = a_coeff_const};

Auf diese Weise behalten Sie nur die Zeiger auf die Arrays im RAM, während sich die Arrays selbst im FLASH befinden.
Da C Arrays und Zeiger ziemlich gleich behandelt, können Sie die Zeiger so verwenden, als wären sie Arrays, aber Sie würden alle Begrenzungsprüfungen verlieren, die Ihr Compiler möglicherweise bereitstellt - stellen Sie also sicher, dass Sie nicht über das Ende von hinauslesen Arrays.

Nur aus Interesse, was glauben Sie, was die Strafe dafür in Bezug auf die beim Adressieren verlorenen Zyklen wäre? Ich frage, weil Sie, obwohl Sie mit Zeigern arbeiten, die Adressen sowohl im RAM als auch im Flash weitergeben müssen.

Ich bin mit Ihrer Architektur oder Ihrem Compiler nicht vertraut, aber wenn Sie GCC auf ARM verwenden, wenn Sie die konstanten Felder auf etwas Nicht-Null initialisieren, wird die gesamte Struktur sowohl im Flash (Nicht-Null-Initialisierung) als auch im RAM (Nicht-Konstante, at zumindest teilweise).

Nicht-Null-Initialisierungswerte müssen im Flash gespeichert werden, während Nicht-Konstanten im RAM sein müssen. Aaaand der C-Standard erfordert, dass die Struktur in einen kontinuierlichen Speicher gestellt wird. Versuchen Sie, diese Struktur in zwei Teile aufzuteilen, und prüfen Sie, ob sich Ihre Programmgröße ändert. Oder setzen Sie einfach die gesamte Struktur als const.