Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Помогите разобраться со структурами
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Димон Безпарольный
Компилятор С-Free ошибок не выдает, но виснет при выполнении. Тот же софт в ARM не виснет, но данные через структуру не передает - там мусор. Вот эти структуры:

Код
struct bme280_calibration_param_t {
    u16 dig_T1;/**<calibration T1 data*/
    s16 dig_T2;/**<calibration T2 data*/
    s16 dig_T3;/**<calibration T3 data*/
    u16 dig_P1;/**<calibration P1 data*/
    s16 dig_P2;/**<calibration P2 data*/
    s16 dig_P3;/**<calibration P3 data*/
    s16 dig_P4;/**<calibration P4 data*/
    s16 dig_P5;/**<calibration P5 data*/
    s16 dig_P6;/**<calibration P6 data*/
    s16 dig_P7;/**<calibration P7 data*/
    s16 dig_P8;/**<calibration P8 data*/
    s16 dig_P9;/**<calibration P9 data*/
    u8  dig_H1;/**<calibration H1 data*/
    s16 dig_H2;/**<calibration H2 data*/
    u8  dig_H3;/**<calibration H3 data*/
    s16 dig_H4;/**<calibration H4 data*/
    s16 dig_H5;/**<calibration H5 data*/
    s8  dig_H6;/**<calibration H6 data*/
    s32 t_fine;/**<calibration T_FINE data*/
};
struct bme280_t {
    struct bme280_calibration_param_t cal_param;
    /**< calibration parameters*/
    u8 chip_id;/**< chip id of the sensor*/
    u8 dev_addr;/**< device address of the sensor*/
    u8 oversamp_temperature;/**< temperature over sampling*/
    u8 oversamp_pressure;/**< pressure over sampling*/
    u8 oversamp_humidity;/**< humidity over sampling*/
    u8 ctrl_hum_reg;/**< status of control humidity register*/
    u8 ctrl_meas_reg;/**< status of control measurement register*/
    u8 config_reg;/**< status of configuration register*/
};


Далее определяю ссылку:

Код
static struct bme280_t *p_bme280; /**< pointer to BME280 */


В Main обращаюсь к структуре, заполняя ее поля:

Код
    p_bme280->cal_param.dig_T1 = (u16)1;
    p_bme280->cal_param.dig_T2 = (s16)2;
    p_bme280->cal_param.dig_T3 = (s16)3;
    p_bme280->cal_param.dig_P1 = (u16)4;
    p_bme280->cal_param.dig_P2 = (s16)5;
    p_bme280->cal_param.dig_P3 = (s16)6;
    p_bme280->cal_param.dig_P4 = (s16)7;
    p_bme280->cal_param.dig_P5 = (s16)8;
    p_bme280->cal_param.dig_P6 = (s16)9;
    p_bme280->cal_param.dig_P7 = (s16)10;
    p_bme280->cal_param.dig_P8 = (s16)11;
    p_bme280->cal_param.dig_P9 = (s16)12;
    p_bme280->cal_param.dig_H1 = (s16)13;        
    p_bme280->cal_param.dig_H2 = (s16)14;            
    p_bme280->cal_param.dig_H3 = (s16)15;


В том же Main пытаюсь вывести значения:

Код
    printf("\nT1:%x ",p_bme280->cal_param.dig_T1);    //0x89 = 0x6C, 0x88 = 0x9E
    printf("T2:%x ",  p_bme280->cal_param.dig_T2);    //0x8B = 0x64, 0x8A = 0xFD
    printf("T3:%x ",  p_bme280->cal_param.dig_T3);    //0x8D = 0x00, 0x8C = 0x32
    printf("P1:%x ",  p_bme280->cal_param.dig_P1);    //0x8F = 0x93, 0x8E = 0x43
    printf("P2:%x ",  p_bme280->cal_param.dig_P2);    //0x91 = 0xD4, 0x90 = 0xED
    printf("P3:%x ",  p_bme280->cal_param.dig_P3);    //0x93 = 0x0B, 0x92 = 0xD0
    printf("P4:%x ",  p_bme280->cal_param.dig_P4);    //0x95 = 0x1D, 0x94 = 0x10
    printf("P5:%x ",  p_bme280->cal_param.dig_P5);    //0x97 = 0xFF, 0x96 = 0xFC
    printf("P6:%x ",  p_bme280->cal_param.dig_P6);    //0x99 = 0xFF, 0x98 = 0xF9
    printf("P7:%x ",  p_bme280->cal_param.dig_P7);    //0x9B = 0x26, 0x9A = 0xAC
    printf("P8:%x ",  p_bme280->cal_param.dig_P8);    //0x9D = 0xD8, 0x9C = 0x0A
    printf("P9:%x ",  p_bme280->cal_param.dig_P9);    //0x9F = 0x10, 0x9E = 0xBD
    printf("H1:%x ",  p_bme280->cal_param.dig_H1);    //0xA1 = 0x4B
    printf("H2:%x ",  p_bme280->cal_param.dig_H2);    //0xE2 = 0x01, 0xE1 = 0x69
    printf("H3:%x ",  p_bme280->cal_param.dig_H3);    //0xE3 = 0x00
    printf("H4:%x ",  p_bme280->cal_param.dig_H4);    //0xE4 = 0x14, 0xE5[3..0] = 0x00
    printf("H5:%x ",  p_bme280->cal_param.dig_H5);    //0xE6 = 0x00, 0xE5[7..4] = 0x00
    printf("H6:%x\r", p_bme280->cal_param.dig_H6);    //0xE7 = 0x1E 33 ?????


Что здесь не так?
megajohn
Цитата(Димон Безпарольный @ Dec 5 2016, 20:37) *
Что здесь не так?


указатель должен на что-то реальное указывать

static struct bme280_t bme280_cfg_a;
static struct bme280_t bme280_cfg_b;

static struct bme280_t *p_bme280; /**< pointer to BME280 */

void main void()
{
p_bme280 = &bme280_cfg_a;
p_bme280->cal_param.dig_H3 = 15;
...
}
Димон Безпарольный
И правда. Спасибо. Заработало.
k155la3
Цитата(Димон Безпарольный @ Dec 5 2016, 21:37) *
. . . .
Далее определяю ссылку:

Код
static struct bme280_t *p_bme280; /**< pointer to BME280 */

. . . .


Это указатель объявлен. ссылка в С есть нечто другое со знаком &.
Сергей Борщ
QUOTE (k155la3 @ Dec 6 2016, 09:52) *
ссылка в С есть нечто другое со знаком &.
Ссылок в C нет совсем, они есть в C++.
k155la3
Цитата(Сергей Борщ @ Dec 6 2016, 10:51) *
Ссылок в C нет совсем, они есть в C++.

Нэ знал. Пробелы в консерватории sm.gif
Димон Безпарольный
Пытаюсь доконца разобраться. Для того, чтобы элементы структуры были доступны в каждой функции, мне приходится в каждую функцию прописывать:

Код
p_BME280 = &BME280_cfg;


Это работает. Но в исходнике, который я адаптирую:
https://github.com/BoschSensortec/BME280_dr...master/bme280.c

поступают иначе. Я не могу понять как это работает. В строке 55 объявляется указатель на структуру:
Код
static struct bme280_t *p_bme280; /**< pointer to BME280 */


в единственном месте - функция bme280_init(struct bme280_t *bme280)(строка 90) этому указателю присваивается адрес :

Код
/* assign BME280 ptr */
p_bme280 = bme280;


И все. Далее в каждой функции идет обращение к структуре(строка 230):
Код
p_bme280->cal_param.t_fine - 122880


уже без присваивания адреса в каждой функции. Я понимаю, что указатель p_BME280 глобален. Но все мои попытки один раз назначить ему адрес структуры приводит к ошибке в компиляции. Как это сделать?

Заранее спасибо.
esaulenka
Если эта структура bme280 одна, и размножать их не планируется, предлагаю забыть слово "указатель", раз оно вызывает сложности.
Обращаться непосредственно к полям первоначальной структуры.


А вообще, правильно заданный вопрос - это хороший тон.
Правильно заданный - это минимальный пример, который показывает проблему.
"Я сделал глобальную структуру A, указатель pA, присваиваю в функции init() pA = &A, потом пользуюсь в функции doItNow() pA->var, и у возникает вот такая ошибка компиляции".
Lagman
Цитата(Димон Безпарольный @ Dec 6 2016, 13:10) *
Код
/* assign BME280 ptr */
p_bme280 = bme280;


уже без присваивания адреса в каждой функции. Я понимаю, что указатель p_BME280 глобален. Но все мои попытки один раз назначить ему адрес структуры приводит к ошибке в компиляции. Как это сделать?

p_BME280 не глобален, у него область видимости только файл bme280.c
bme280 передается в функцию bme280_init(&bme280) ну и дальше в файле bme280.c доступен только указатель p_bme280, а в файле bme280_support.c
только структура bme280. И если использовать p_bme280 в другом отличном от файла bme280.c будет ошибка так как у указателя p_bme280 область видимости только этот файл.
Хотите сделать его глобальным уберите static перед объявлением и объявляйте его extern в других файлах.
Димон Безпарольный
Цитата(Lagman @ Dec 6 2016, 14:16) *
bme280 передается в функцию bme280_init(&bme280) ну и дальше в файле bme280.c доступен только указатель p_bme280, а в файле bme280_support.c

Это меня устраивает. Но у меня (в одном файле) получается так:

Код
signed int BME280_Compensate_Temperature(signed int Uncomp_Temperature)
{
    p_BME280 = &BME280_cfg;
    v_x1_u32r  = ((((Uncomp_Temperature >> 3) - ((signed int)p_BME280->cal_param.dig_T1<< 1))) * ((signed int)p_BME280->cal_param.dig_T2)) >> 11;
}


Без строки p_BME280 = &BME280_cfg;, переменная p_BME280->cal_param.dig_T1 содержит мусор. Приходится писать в каждой функции строку p_BME280 = &BME280_cfg;. В этом и вопрос - в приведенном мной исходнике этого не делают, а с параметрами структуры работают.
Lagman
А как и где у вас объявляются p_BME280 и BME280_cfg ?
Димон Безпарольный
Цитата(Lagman @ Dec 6 2016, 16:55) *
А как и где у вас объявляются p_BME280 и BME280_cfg ?

Обявляются в заголовочном файле:

Код
static struct BME280_t BME280_cfg;
static struct BME280_t *p_BME280; /**< pointer to BME280 */
Lagman
А заголовочный файл у вас подключается к двум исходным файлам? и получается в каждом файле своя копия BME280_cfg и p_BME280.
Так не делают, смотрите как сделано на github'e. Либо делайте через typedef и extern.
P.S. что бы не разжевывать тут, почитайте http://digitalchip.ru/osobennosti-ispolzov...-i-static-v-c-c
conan
Цитата(Димон Безпарольный @ Dec 6 2016, 17:51) *
Обявляются в заголовочном файле:

Код
static struct BME280_t BME280_cfg;
static struct BME280_t *p_BME280; /**< pointer to BME280 */


Это не объявление, а определение. И делать определения в заголовочном файле -- плохая практика.

В C/C++ применяется так наз. раздельная компиляция. Если нужна глобальная переменная доступная во всех единицах трансляции (т. е. c-файлах) то, нужно делать так:

1. В одном заголовочном файле должно быть ОБЪЯВЛЕНИЕ:
-------decl.h--------
Код
...
extern struct BME280_t BME280_cfg;
extern struct BME280_t *p_BME280; /**< pointer to BME280 */


2. Только в одном C-файле должно быть ОПРЕДЕЛЕНИЕ:
-------def.c--------
Код
...
struct BME280_t BME280_cfg;
struct BME280_t *p_BME280; /**< pointer to BME280 */


3. Затем в др. C-файлах можно использовать эти глобальные переменные:
-------a.c--------
Код
#include "decl.h"

void f()
{
    BME280_cfg.member1 = 1234;
    p_BME280->member2 = 43444;
}


-------b.c--------
Код
#include "decl.h"

void g()
{
    BME280_cfg.member1 = 5678;
    p_BME280->member2 = 44343;
}


Любой из этих C-файлов: def.c, a.c, b.c может содержать функцию main() (и сам файл может называться main.c)

---------------------------------------------------------------------
Если переменная определена как static в каком-нибудь C-файле, то она будет доступна только в этом c-файле. Если в других C-файлах есть такое же static-определение, то это будет уже др. переменная

-------decl.h-------- Как уже было сказано -- определения в заголовочном файле -- плохо, тем не менее
Код
...
static struct BME280_t BME280_cfg;
static struct BME280_t *p_BME280; /**< pointer to BME280 */


-------a.c--------
Код
#include "decl.h"

void f()
{
    BME280_cfg.member1 = 1234;
    p_BME280->member2 = 43444;
}


-------b.c--------
Код
#include "decl.h"

void g()
{
    BME280_cfg.member1 = 5678;
    p_BME280->member2 = 44343;
}


После препроцессинга (в том числе обработки include-ов) перед компиляцией из a.c получится единица трансляции:
-------a.c*--------
Код
static struct BME280_t BME280_cfg;
static struct BME280_t *p_BME280; /**< pointer to BME280 */

void f()
{
    BME280_cfg.member1 = 1234;
    p_BME280->member2 = 43444;
}


Из b.c получится:
-------b.c*--------
Код
static struct BME280_t BME280_cfg;
static struct BME280_t *p_BME280; /**< pointer to BME280 */

void g()
{
    BME280_cfg.member1 = 5678;
    p_BME280->member2 = 44343;
}


Таким образом, в каждой единице трансляции будет свой комплект переменных BME280_cfg и p_BME280. При изменении переменной BME280_cfg в a.c, это никак не затронет переменную с этим же названием в b.c, ибо там своя отдельная переменная в b.c.

-----------------------------------------------
Если сделать так

-------decl.h-------- Как уже было сказано -- определения в заголовочном файле -- плохо, тем не менее
Код
...
struct BME280_t BME280_cfg;
struct BME280_t *p_BME280; /**< pointer to BME280 */


-------a.c--------
Код
#include "decl.h"

void f()
{
    BME280_cfg.member1 = 1234;
    p_BME280->member2 = 43444;
}


-------b.c--------
Код
#include "decl.h"

void g()
{
    BME280_cfg.member1 = 5678;  // *
    p_BME280->member2 = 44343;
}


то программа пройдет компиляцию, но не пройдет компоновку (linkage), ибо теперь одновременно в двух единицах трансляции получаются одинаковые переменные, но при этом которые должны быть доступны для компоновки с др. единицами трансляции. Т. е. возникает неопределенность, какую например из переменных BME280_cfg использовать при записи в member1 в b.c (*): ту которая определена в a.c или ту которая в b.c...
Димон Безпарольный
Спасибо за развернутый ответ, но речь шла об одном файле. Пост 7 описывает проблему в одном файле. Исходный код (ссылка там же) не использует присваивания p_bme280 = bme280; в каждой функции одного файла. А у меня без этого присваивания (в каждой функции) не работает. Читается мусор. Тестовый вариант (в компиляторе C-Free, функция Main, строка p_bme280 = &bme280_cfg;) просто завершается аварийно без этого присвоения:

Код
typedef    signed char  s8;/**< used for signed 8bit */
typedef    signed short int s16;/**< used for signed 16bit */
typedef    signed int s32;/**< used for signed 32bit */
typedef    signed long long int s64;/**< used for signed 64bit */
typedef    unsigned char u8;/**< used for unsigned 8bit */
typedef    unsigned short int u16;/**< used for unsigned 16bit */
typedef    unsigned int u32;/**< used for unsigned 32bit */
typedef    unsigned long long int u64;/**< used for unsigned 64bit */

struct bme280_calibration_param_t {
    u16 dig_T1;/**<calibration T1 data*/
    s16 dig_T2;/**<calibration T2 data*/
    s16 dig_T3;/**<calibration T3 data*/
    u16 dig_P1;/**<calibration P1 data*/
    s16 dig_P2;/**<calibration P2 data*/
    s16 dig_P3;/**<calibration P3 data*/
    s16 dig_P4;/**<calibration P4 data*/
    s16 dig_P5;/**<calibration P5 data*/
    s16 dig_P6;/**<calibration P6 data*/
    s16 dig_P7;/**<calibration P7 data*/
    s16 dig_P8;/**<calibration P8 data*/
    s16 dig_P9;/**<calibration P9 data*/
    u8  dig_H1;/**<calibration H1 data*/
    s16 dig_H2;/**<calibration H2 data*/
    u8  dig_H3;/**<calibration H3 data*/
    s16 dig_H4;/**<calibration H4 data*/
    s16 dig_H5;/**<calibration H5 data*/
    s8  dig_H6;/**<calibration H6 data*/
    s32 t_fine;/**<calibration T_FINE data*/
};
    
struct bme280_t {
    struct bme280_calibration_param_t cal_param;
    /**< calibration parameters*/
    u8 chip_id;/**< chip id of the sensor*/
    u8 dev_addr;/**< device address of the sensor*/
    u8 oversamp_temperature;/**< temperature over sampling*/
    u8 oversamp_pressure;/**< pressure over sampling*/
    u8 oversamp_humidity;/**< humidity over sampling*/
    u8 ctrl_hum_reg;/**< status of control humidity register*/
    u8 ctrl_meas_reg;/**< status of control measurement register*/
    u8 config_reg;/**< status of configuration register*/
};
static struct bme280_t bme280_cfg;
static struct bme280_t *p_bme280; /**< pointer to BME280 */


int main()
{
    p_bme280 = &bme280_cfg;
    p_bme280->cal_param.dig_T1 = 1;
    p_bme280->cal_param.dig_T2 = 2;
    p_bme280->cal_param.dig_T3 = 3;
    p_bme280->cal_param.dig_P1 = 4;
    p_bme280->cal_param.dig_P2 = 5;
    p_bme280->cal_param.dig_P3 = 6;
    p_bme280->cal_param.dig_P4 = 7;
    p_bme280->cal_param.dig_P5 = 8;
    p_bme280->cal_param.dig_P6 = 9;
    p_bme280->cal_param.dig_P7 = 10;
    p_bme280->cal_param.dig_P8 = 11;
    p_bme280->cal_param.dig_P9 = 12;
    p_bme280->cal_param.dig_H1 = 13;        
    p_bme280->cal_param.dig_H2 = 14;            
    p_bme280->cal_param.dig_H3 = 15;
                
    printf("\nT1:%x ",p_bme280->cal_param.dig_T1);    //0x89 = 0x6C, 0x88 = 0x9E
    printf("T2:%x ",  p_bme280->cal_param.dig_T2);    //0x8B = 0x64, 0x8A = 0xFD
    printf("T3:%x ",  p_bme280->cal_param.dig_T3);    //0x8D = 0x00, 0x8C = 0x32
    printf("P1:%x ",  p_bme280->cal_param.dig_P1);    //0x8F = 0x93, 0x8E = 0x43
    printf("P2:%x ",  p_bme280->cal_param.dig_P2);    //0x91 = 0xD4, 0x90 = 0xED
    printf("P3:%x ",  p_bme280->cal_param.dig_P3);    //0x93 = 0x0B, 0x92 = 0xD0
    printf("P4:%x ",  p_bme280->cal_param.dig_P4);    //0x95 = 0x1D, 0x94 = 0x10
    printf("P5:%x ",  p_bme280->cal_param.dig_P5);    //0x97 = 0xFF, 0x96 = 0xFC
    printf("P6:%x ",  p_bme280->cal_param.dig_P6);    //0x99 = 0xFF, 0x98 = 0xF9
    printf("P7:%x ",  p_bme280->cal_param.dig_P7);    //0x9B = 0x26, 0x9A = 0xAC
    printf("P8:%x ",  p_bme280->cal_param.dig_P8);    //0x9D = 0xD8, 0x9C = 0x0A
    printf("P9:%x ",  p_bme280->cal_param.dig_P9);    //0x9F = 0x10, 0x9E = 0xBD
    printf("H1:%x ",  p_bme280->cal_param.dig_H1);    //0xA1 = 0x4B
    printf("H2:%x ",  p_bme280->cal_param.dig_H2);    //0xE2 = 0x01, 0xE1 = 0x69
    printf("H3:%x \n",  p_bme280->cal_param.dig_H3);//0xE3 = 0x00
    return 0;
}


Вопрос был в том, почему в исходнике нет необходимости писать в каждой функции присвоение p_bme280 = &bme280_cfg;? Повторюсь, все происходит в одном файле.
gerber
Значит, ваш код каким-то образом "сносит" значение указателя на структуру, модифицирует его, т.е. где-то есть memcpy() или что-то подобное, которое выходит за пределы выделенной под приемный буфер памяти, и залезает на указатель. Смотрите map-файл в части размещения указателя и самой структуры.
Возможно, ваши функции вызываются ДО функции, в которой инициализируется указатель. В этом случае он должен быть нулевым.
Нужно поставить отладочный вывод значения указателя перед присвоением в каждой функции и посмотреть глазами его значение, туда ли он указывает, на адрес ли структуры (из map-файла)
Ещё я сталкивался с похожим поведением, когда указатель передавался в функцию с приведением его типа, при этом он "округлялся" из-за выравнивания доступа, и вся структура "съезжала" на 1 байт. Всё это можно увидеть, если поставить отладочный вывод значения указателя.
conan
Цитата(Димон Безпарольный @ Dec 8 2016, 08:40) *
Спасибо за развернутый ответ, но речь шла об одном файле. Пост 7 описывает проблему в одном файле. Исходный код (ссылка там же) не использует присваивания p_bme280 = bme280; в каждой функции одного файла. А у меня без этого присваивания (в каждой функции) не работает. Читается мусор. Тестовый вариант (в компиляторе C-Free, функция Main, строка p_bme280 = &bme280_cfg;) просто завершается аварийно без этого присвоения
...
Вопрос был в том, почему в исходнике нет необходимости писать в каждой функции присвоение p_bme280 = &bme280_cfg;? Повторюсь, все происходит в одном файле.

Что значит присвоение В КАЖДОЙ функции, у вас ведь только одна функция, и эта функция main. Любой указатель перед использованием должен быть инициализирован. Вот вы его в самом начале функции main и инициализируете:
Код
int main()
{
    p_bme280 = &bme280_cfg;
    ...

Всё правильно

А вообще в вашем случае указатель p_bme280 излишен. Вы можете сразу работать с самим объектом:
Код
static struct bme280_t bme280_cfg;

int main()
{
    bme280_cfg.cal_param.dig_T1 = 1;
    bme280_cfg.cal_param.dig_T2 = 2;
    bme280_cfg.cal_param.dig_T3 = 3;
    ...
                
    printf("\nT1:%x ",bme280_cfg.cal_param.dig_T1);    //0x89 = 0x6C, 0x88 = 0x9E
    printf("T2:%x ",  bme280_cfg.cal_param.dig_T2);    //0x8B = 0x64, 0x8A = 0xFD
    printf("T3:%x ",  bme280_cfg.cal_param.dig_T3);    //0x8D = 0x00, 0x8C = 0x32
    ...

    return 0;
}
Димон Безпарольный
Цитата(conan @ Dec 8 2016, 12:29) *
Что значит присвоение В КАЖДОЙ функции, у вас ведь только одна функция, и эта функция main.

Это пример, может быть не очень удачный. В реальном коде подобных функций десяток и в каждой приходится прописывать.

Цитата(conan @ Dec 8 2016, 12:29) *
А вообще в вашем случае указатель p_bme280 излишен.

Лучшее решение. Спасибо. Но оно уводит в сторону от проблемы, которую я пока не могу решить. В дальнейшем эти грабли меня еще достанут...

Я пытался вне функции Main глобально присвоить:

Код
static struct bme280_t bme280_cfg;
static struct bme280_t *p_bme280; /**< pointer to BME280 */
p_bme280 = &bme280_cfg;


Но на последнюю строчку копилятор ругается:

--------------------Configuration: mingw5 - CUI Debug, Builder Type: MinGW--------------------

Цитата
Checking file dependency...
Compiling D:\8051\CFree\Test\Struct_CFREE.c...
[Error] D:\8051\CFree\Test\Struct_CFREE.c:46: error: conflicting types for 'p_bme280'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:45: error: previous declaration of 'p_bme280' was here
[Warning] D:\8051\CFree\Test\Struct_CFREE.c:46: warning: initialization makes integer from pointer without a cast
[Warning] D:\8051\CFree\Test\Struct_CFREE.c:46: warning: data definition has no type or storage class
[Warning] D:\8051\CFree\Test\Struct_CFREE.c:51: warning: assignment makes integer from pointer without a cast
[Error] D:\8051\CFree\Test\Struct_CFREE.c:52: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:53: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:54: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:55: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:56: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:57: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:58: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:59: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:60: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:61: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:62: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:63: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:64: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:65: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:66: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:68: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:69: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:70: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:71: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:72: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:73: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:74: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:75: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:76: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:77: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:78: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:79: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:80: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:81: error: invalid type argument of `->'
[Error] D:\8051\CFree\Test\Struct_CFREE.c:82: error: invalid type argument of `->'
Complete Make Struct_CFREE: 32 error(s), 3 warning(s)




XVR
Цитата(Димон Безпарольный @ Dec 6 2016, 13:10) *
Пытаюсь доконца разобраться. Для того, чтобы элементы структуры были доступны в каждой функции, мне приходится в каждую функцию прописывать:

Код
p_BME280 = &BME280_cfg;
Это бред, (даже несмотря на то, что это работает)

Цитата
Как это сделать?

Вы же сами написали, как это сделать -
Цитата
В строке 55 объявляется указатель на структуру:
Код
static struct bme280_t *p_bme280; /**< pointer to BME280 */


в единственном месте - функция bme280_init(struct bme280_t *bme280)(строка 90) этому указателю присваивается адрес :

Код
/* assign BME280 ptr */
p_bme280 = bme280;


И все. Далее в каждой функции идет обращение к структуре(строка 230):
Код
p_bme280->cal_param.t_fine - 122880

Цитата
Но все мои попытки один раз назначить ему адрес структуры приводит к ошибке в компиляции.

Как эти попытки выглядят?
Если так -
Цитата
Код
static struct bme280_t bme280_cfg;
static struct bme280_t *p_bme280; /**< pointer to BME280 */
p_bme280 = &bme280_cfg;
то это неправильно. На уровне файла (т.е. вне каких либо функций) ничего присваивать нельзя (можно только инициализировать при описании)
Вот так можно:
Код
static struct bme280_t bme280_cfg;
static struct bme280_t *p_bme280 =  &bme280_cfg; /**< pointer to BME280 */
Вот только смысла в этом (если обе переменные static) нет никакого - используйте сразу bme280_cfg без промежуточных указателей
Lagman
Автор топика не может посмотреть соседние файлы в репозитории, где все понятно написано как использовать правильно функции и структуры, а вы ему про высокие материи начинаете. sm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.