繁体   English   中英

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

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

我正在尝试通过将指针传递给某种实现的指针结构来实现某些通信接口的某种指针替换。 它旨在在Atmega328p上运行,并使用avr-gcc.exe(AVR_8_bit_GNU_Toolchain_3.5.4_1709)4.9.2进行编译,该版本安装在Windows 10上的msys2 64位/中

现在,给出以下结构

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

我根据我的数据表在主文件中将其创建为文件范围变量,并用相应的地址(在这种情况下0xB9, 0xB8, 0xBC, 0xBB )进行0xB9, 0xB8, 0xBC, 0xBB

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

为了参考起见,myInterface本身始终存储在0x100中。 当我尝试从主函数内部访问它们中的任何一个时,它将返回相应的预期地址。

然后,我将其传递给另一个.c文件中的init函数。

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

当我尝试访问任何成员时,即仍然使用相同的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);

我应该得到以下打印为0x100, 0xB9, 0xB8, 0xBC, 0xBB ,第一个是结构本身,然后是每个成员的内容,它们是我的寄存器的地址。 而是访问storedRegisters->baudrateRegister确实返回0x100 ,即结构本身的地址,而不是成员的内容。 然后在我的控制台上输出

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

这样,我无法访问我的struct指针的第一个成员指针,但其他所有指针似乎都很好。 如果我要在结构中交换例如控制和波特率寄存器的顺序,则控制寄存器将返回0x100。 我缺少必不可少的东西吗?

我使用以下选项进行编译:

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

并链接到

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

编辑:错字固定

Edit2:我用调用init函数

init(&myInterface, 100000L);

Edit3:固定混合在控制台输出周围

Edit4:添加了3个相关的源文件。

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
}

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

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);
}

请原谅,信誉太低,无法置评,所以我只把2美分放在这里。 如果没有用,请随意投票等等。

我编译并运行了代码(适用于PC),并假定TWBR和其他3的定义类似于(*(uint8_t *)(0xB9)) ,在init()时打印了正确的预期值函数在main中被调用。 如果没有调试器,很难弄清您身边正在发生什么,并且由于我看不到任何明显的C错误,因此充其量我只能做出疯狂的猜测。

如果我根据您的意见做出假设(“如果要在结构中交换例如控制和波特率寄存器的顺序,则controlregister是返回0x100的那个。我是否缺少必要的内容?”)我会尝试将责任归咎于init()中的printf()语句中的某处。 您是否可以尝试仅交换printf()调用的顺序(例如,首先打印数据寄存器成员)? 并查看前两个调用是否再次打印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);

我知道这是基本的调试工作,但是:1.我没有让您自己的系统更近一点2.您没有调试器3.在您发布的代码中没有发现明显的C错误

暂无
暂无

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

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