Я пытаюсь реализовать некоторую замену указателя для некоторого интерфейса связи, передав указатель на структуру указателей на некоторую реализацию. Он предназначен для работы на Atmega328p и компилируется с помощью avr-gcc.exe (AVR0x100
bit_GNU_Toolchain_3.5.4_1709) 4.9.2, установленного в / через msys2 64bit в Windows 10.
Теперь, учитывая следующую структуру
typedef struct{
volatile uint8_t* baudrateRegister;
volatile uint8_t* statusRegister;
volatile uint8_t* controlRegister;
volatile uint8_t* dataRegister;
}CommRegisters;
Я создаю это как переменную области видимости файла в моем основном файле и заполняю его соответствующими адресами (в данном случае 0xB9, 0xB8, 0xBC, 0xBB
) в соответствии с моей таблицей данных.
CommRegisters myInterface = {&BAUDRATEREGISTER, &STATUSREGISTER, &CONTROLREGISTER, &DATAREGISTER};
Сам myInterface постоянно сохраняется в 0x100 для справки. Когда я пытаюсь получить доступ к любому из них изнутри основной функции, она возвращает соответствующие и ожидаемые адреса.
Затем я передаю это своей функции инициализации в другом файле .c
CommRegisters* storedRegisters
void init(CommRegisters* registers, uint32_t clockspeed){
storedRegisters = registers;
}
и когда я пытаюсь получить доступ к любому из членов, то есть распечатывая его с помощью 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
При этом я не могу получить доступ к указателю первого члена моего указателя на структуру, но все остальные кажутся нормальными. Если бы я поменял порядок, например, регистр управления и скорости передачи в моей структуре, тогда регистр управления - это тот, который возвращает 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(&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);
}
TWBR
(например) - person Anton   schedule 14.08.2018