Tout d'abord, désolé pour le titre, il était difficile de trouver une description. J'essaye de créer une structure qui accédera à un périphérique qui a peu de registres internes contrôlés par 3 lignes d'adresse. J'ai donc la définition de la structure suivante:En C, un pointeur vers une structure qui a besoin d'accéder à une liste de pointeurs d'octets
typedef struct {
union {
unsigned char *reg0aPtr;
unsigned char *reg0bPtr;
} RegsAddrOffset0;
union {
unsigned char *reg1aPtr;
unsigned char *reg1bPtr;
} RegsAddrOffset1;
...
union {
unsigned char *reg7aPtr;
unsigned char *reg7bPtr;
} RegsAddrOffset7;
} DeviceRegMap;
Ensuite, si je déclare une variable comme si
DeviceRegMap *uartRegMap = (DeviceRegMap *)(0xD0000000);
Maintenant, si je tente de d'utiliser la variable uartRegMap pour accéder à la mémoire mappée registres Je pensais que je verrait que * (uartRegMap-> RegsAddrOffset0.reg0aPtr) lirait les données de l'adresse 0xD0000000, ce qui est fait. Si j'utilise * (uartRegMap-> RegsAddrOffset1.reg1bPtr), je pensais que j'accéderais à 0xD0000001, mais il accède en fait à l'adresse 0xD0000004. Comme le processeur est en 32 bits, l'alignement naturel est de 4 octets. Je pense que la taille d'un pointeur est un entier qui dans ce cas est de 32 bits, c'est la raison pour laquelle j'accède sur des plages d'adresses de 4 octets (par exemple, 0xD0000000, 0xD0000004, 0xD0000008, etc.).
Si je déclarais une instance du type de données DeviceRegMap j'attendre l'initialisation suivante:
DeviceRegMap uartRegMap = {
(unsigned char *)0xD0000000,
(unsigned char *)0xD0000001,
...
(unsigned char *)0xD0000007,
};
Alors si je voulais accéder à l'adresse 0xD0000007 puis j'utiliser * (uartRegMap.RegsAddrOffset7.reg7bPtr)
La question est pourquoi le pointeur vers le type de données DeviceRegMap accède-t-il à la mémoire sur les alignements 4 octets (par exemple, 0xD0000000, 0xD0000004, etc.) au lieu des alignements d'octets (par exemple, 0xD0000000, 0xD0000001, etc). En ce qui concerne l'ensemble d'outils, j'utilise le compilateur de diabète de Wind River. Merci.
Mark
EDIT: D'après le commentaire de abelenky
Quelle est votre question? "Je veux juste m'assurer de comprendre ce qui se passe." Ce n'est pas une question. – abelenky
Pourquoi utilisez-vous une «union» de deux éléments du même type? –
Juste pour ajouter un aperçu supplémentaire de ce qui se passe. Le code a été développé par un autre ingénieur dont j'ai hérité pour un pilote de périphérique UART. L'UART possède environ 21 registres différents qui sont accessibles via trois lignes d'adresses mappées en mémoire. Comme les gens l'ont souligné, les syndicats ne sont vraiment pas nécessaires, mais ils ajoutent de la clarté à la lecture du code. Par exemple, à un décalage de 0x00, il y a les registres de maintien TX et RX avec quelques autres registres. Donc le code utilise -> RHR ou -> THR qui aide à la lisibilité. – lordhog