简体   繁体   English

尝试访问结构指针的第一个成员(本身是易失性指针)不会返回存储的成员指针,而是返回结构地址

[英]Trying to access first member(itself a volatile pointer) of struct pointer does not return the stored member pointer but the struct address

I am trying to implement some pointer substitution for some communication interface by passing on a pointer to a struct of pointers to some implementation. 我正在尝试通过将指针传递给某种实现的指针结构来实现某些通信接口的某种指针替换。 This is meant to run on an Atmega328p and is being compiled with avr-gcc.exe (AVR_8_bit_GNU_Toolchain_3.5.4_1709) 4.9.2, installed in/via msys2 64bit on Windows 10 它旨在在Atmega328p上运行,并使用avr-gcc.exe(AVR_8_bit_GNU_Toolchain_3.5.4_1709)4.9.2进行编译,该版本安装在Windows 10上的msys2 64位/中

Now, given the following struct 现在,给出以下结构

typedef struct{
    volatile uint8_t* baudrateRegister;
    volatile uint8_t* statusRegister;
    volatile uint8_t* controlRegister;
    volatile uint8_t* dataRegister;
}CommRegisters;

I create this as a file scope variable in my main file and fill it with the corresponding addresses (in this case 0xB9, 0xB8, 0xBC, 0xBB ) according to my datasheet. 我根据我的数据表在主文件中将其创建为文件范围变量,并用相应的地址(在这种情况下0xB9, 0xB8, 0xBC, 0xBB )进行0xB9, 0xB8, 0xBC, 0xBB

CommRegisters myInterface = {&BAUDRATEREGISTER, &STATUSREGISTER, &CONTROLREGISTER, &DATAREGISTER};

myInterface itself gets stored in 0x100, for reference sake, consistently. 为了参考起见,myInterface本身始终存储在0x100中。 When i try to access any of them from inside the main function it returns the corresponding and expected addresses. 当我尝试从主函数内部访问它们中的任何一个时,它将返回相应的预期地址。

I then pass that to my init function in a different .c file 然后,我将其传递给另一个.c文件中的init函数。

CommRegisters* storedRegisters
void init(CommRegisters* registers, uint32_t clockspeed){
    storedRegisters = registers;
}

and when i try to access any of the members ie by printing it with printf still in that same init function with 当我尝试访问任何成员时,即仍然使用相同的init函数通过printf打印它

printf("storedRegisters %p\n", storedRegisters);
printf("storedRegisters->baudrateRegister %p\n", storedRegisters->baudrateRegister);
printf("storedRegisters->statusRegister %p\n", storedRegisters->statusRegister);
printf("storedRegisters->controlRegister %p\n", storedRegisters->controlRegister);
printf("storedRegisters->dataRegister %p\n", storedRegisters->dataRegister);

I should be getting the following addresses printed 0x100, 0xB9, 0xB8, 0xBC, 0xBB , the first one being the struct itself and then the content of each member, being addresses to my registers. 我应该得到以下打印为0x100, 0xB9, 0xB8, 0xBC, 0xBB ,第一个是结构本身,然后是每个成员的内容,它们是我的寄存器的地址。 Instead accessing storedRegisters->baudrateRegister does return 0x100 , the address to the struct itself, not the content of the member. 而是访问storedRegisters->baudrateRegister确实返回0x100 ,即结构本身的地址,而不是成员的内容。 The output on my console is then 然后在我的控制台上输出

storedRegisters 0x100
storedRegisters->baudrateRegister 0x100
storedRegisters->statusRegister 0xb8
storedRegisters->controlRegister 0xbc
storedRegisters->dataRegister 0xbb

With this I cannot access the first member pointer of my struct pointer, but all others seem fine. 这样,我无法访问我的struct指针的第一个成员指针,但其他所有指针似乎都很好。 If I were to swap the order of eg control and baudrate register in my struct then the controlregister is the one that returns 0x100. 如果我要在结构中交换例如控制和波特率寄存器的顺序,则控制寄存器将返回0x100。 Am I missing something essential? 我缺少必不可少的东西吗?

I am compiling this with the following options: 我使用以下选项进行编译:

avr-gcc -O2 -g2 -gstabs -std=c99 -Wall -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MMD -MP -ffunction-sections -fdata-sections <some files>

and link it with 并链接到

avr-gcc -Wl,-Map,.map -Wl,-u,vfprintf -lprintf_flt -lm -mmcu=atmega328p <some files>

Edit: Typo fixed 编辑:错字固定

Edit2: i call the init function with Edit2:我用调用init函数

init(&myInterface, 100000L);

Edit3: fixed mixed around console output Edit3:固定混合在控制台输出周围

Edit4: Added the 3 relevant source files. Edit4:添加了3个相关的源文件。

The main.c file main.c文件

#include "CommInterface.h"
#include <avr/io.h>
#include <util/delay.h>

//uart
#include "Debug_uart.h"
static FILE uart_str = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
void startUart(void){
    stdout = stdin = &uart_str;
    uart_init();
    printf("\n\n\n\n############################################\n");
}

#define BAUDRATEREGISTER TWBR
#define STATUSREGISTER TWSR
#define CONTROLREGISTER TWCR
#define DATAREGISTER TWDR
CommRegisters myInterface = {&BAUDRATEREGISTER, &STATUSREGISTER, &CONTROLREGISTER, &DATAREGISTER};

void integration_runBMETester(void){
    startUart();
    init(&myInterface, 100000L);
    DDRB = (1 << PB5);
    while(1){
        PORTB |= (1 << PB5);
        _delay_ms(500);
        PORTB &= ~(1 << PB5);
        _delay_ms(500)
    }
}

    int main(int argc, char const *argv[]){
    #ifdef INTEGRATION_BME680
    integration_runBMETester();
    #endif
}

The CommInterface.h file CommInterface.h文件

#ifndef _COMM_INTERFACE_H
#define _COMM_INTERFACE_H

#include <stdint.h>

typedef struct{
    volatile uint8_t* baudrateRegister;
    volatile uint8_t* statusRegister;
    volatile uint8_t* controlRegister;
    volatile uint8_t* dataRegister;
}CommRegisters;

void init(CommRegisters* registers, uint32_t clockspeed);

#endif // _COMM_INTERFACE_H

The CommInterface.c file CommInterface.c文件

#include "CommInterface.h"
#include "registerAbstraction.h"

CommRegisters* storedRegisters;
void init(CommRegisters* registers, uint32_t clockspeed){
    printf("init\n");
    storedRegisters = registers;

    printf("storedRegisters %p\n", storedRegisters);
    printf("storedRegisters->baudrateRegister %p\n", storedRegisters->baudrateRegister);
    printf("storedRegisters->statusRegister %p\n", storedRegisters->statusRegister);
    printf("storedRegisters->controlRegister %p\n", storedRegisters->controlRegister);
    printf("storedRegisters->dataRegister %p\n", storedRegisters->dataRegister);

    abstraction_setRegisterToValue(storedRegisters->statusRegister, 0);
    abstraction_setRegisterToValue(storedRegisters->baudrateRegister, ((F_CPU / clockspeed) - 16) / 2);
}

Please excuse this, reputation too low to comment, so I'll just put my 2 cents here. 请原谅,信誉太低,无法置评,所以我只把2美分放在这里。 If it's useless, feel free to downvote and so on. 如果没有用,请随意投票等等。

I compiled and ran the code (adapted for the PC), and assuming the definitions of TWBR and the other 3 to be something like (*(uint8_t *)(0xB9)) , the correct and expected values were printed when the init() function was called in main. 我编译并运行了代码(适用于PC),并假定TWBR和其他3的定义类似于(*(uint8_t *)(0xB9)) ,在init()时打印了正确的预期值函数在main中被调用。 It's hard to figure out without a debugger what's going on at your side, and as I can not see any obvious C errors, at best I can make wild guesses. 如果没有调试器,很难弄清您身边正在发生什么,并且由于我看不到任何明显的C错误,因此充其量我只能做出疯狂的猜测。

if I were to make an assumption, based on what you said (" If I were to swap the order of eg control and baudrate register in my struct then the controlregister is the one that returns 0x100. Am I missing something essential?") I would attempt try to put the blame somewhere in the printf() statements in init() . 如果我根据您的意见做出假设(“如果要在结构中交换例如控制和波特率寄存器的顺序,则controlregister是返回0x100的那个。我是否缺少必要的内容?”)我会尝试将责任归咎于init()中的printf()语句中的某处。 Would you please try to swap the order of just the printf() calls (eg print the data register member first)? 您是否可以尝试仅交换printf()调用的顺序(例如,首先打印数据寄存器成员)? And see if the first 2 calls print 0x100 again. 并查看前两个调用是否再次打印0x100

 printf("storedRegisters %p\n", storedRegisters);
    printf("storedRegisters->dataRegister %p\n", storedRegisters->dataRegister);
    printf("storedRegisters->baudrateRegister %p\n", storedRegisters->baudrateRegister);
    printf("storedRegisters->statusRegister %p\n", storedRegisters->statusRegister);
    printf("storedRegisters->controlRegister %p\n", storedRegisters->controlRegister);

I know it's rudimentary and a bit of caveman debugging, but: 1. I do not have your system to look closer myself 2. You do not have a debugger 3. I see no obvious C errors in the code you posted 我知道这是基本的调试工作,但是:1.我没有让您自己的系统更近一点2.您没有调试器3.在您发布的代码中没有发现明显的C错误

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM