Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Программирование Новый топик    Ответить
 Соединить несколько списков в один в С.  [new]
jenya7
Member

Откуда:
Сообщений: 1262
Есть объект сенсор.
typedef struct
{
    uint8_t connection;  //0-local, 1-can, 2-rs485, 3-lan
    uint8_t type;        //sensor type
    uint8_t val_type;    //temperature, humidity, etc.
    int8_t state;       //ok, error
    
    GPIO_TypeDef * port; //for local connection
    uint32_t pin;             //for local connection
    uint32_t address       //for local connection

    uint32_t id;  //for remote connection
    
    float value;
}SENSOR;

И для каждой шины я создаю массив объектов (список) CAN, RS485 и локальная. Также я создаю общий список.

SENSOR can_sensors[32];
SENSOR rs485_sensors[32];
SENSOR loc_sensors[32];

SENSOR all_sensors[256];

uint32_t can_sens_count;
uint32_t rs485_sens_count;
uint32_t loc_sens_count;
uint32_t all_sens_count;


Теперь я инициализирую списки.
CAN_DiscoverSensors(can_sensors, &can_sens_count);
RS485_DiscoverSensors(rs485_sensors, &rs485_sens_count);


Я могу их соединить просто копируя?
void SENS_AddToListAll(void)
{
   all_sens_count = 0;
   
   memcpy (all_sensors+all_sens_count, can_sensors, can_sens_count * sizeof(SENSOR)); 
   all_sens_count += can_sens_count;
   
   memcpy (all_sensors+all_sens_count, rs485_sensors, rs485_sens_count * sizeof(SENSOR)); 
   all_sens_count += rs485_sens_count; 
   
   memcpy (all_sensors+all_sens_count, loc_sensors, loc_sens_count * sizeof(SENSOR)); 
   all_sens_count += loc_sens_count; 
}
12 июл 20, 11:55    [22165970]     Ответить | Цитировать Сообщить модератору
 Re: Соединить несколько списков в один в С.  [new]
Dima T
Member

Откуда:
Сообщений: 14886
У тебя POD-структуры, поэтому можно копировать memcpy()

Только непонятно зачем копирование если можно сразу писать в общий массив
SENSOR all_sensors[256];
SENSOR *p = all_sensors;
uint32_t can_sens_count, rs485_sens_count;
CAN_DiscoverSensors(p, &can_sens_count);
p += can_sens_count;
RS485_DiscoverSensors(p, &rs485_sens_count);
p += rs485_sens_count;
...
12 июл 20, 12:07    [22165974]     Ответить | Цитировать Сообщить модератору
 Re: Соединить несколько списков в один в С.  [new]
jenya7
Member

Откуда:
Сообщений: 1262
Dima T
У тебя POD-структуры, поэтому можно копировать memcpy()

Только непонятно зачем копирование если можно сразу писать в общий массив
SENSOR all_sensors[256];
SENSOR *p = all_sensors;
uint32_t can_sens_count, rs485_sens_count;
CAN_DiscoverSensors(p, &can_sens_count);
p += can_sens_count;
RS485_DiscoverSensors(p, &rs485_sens_count);
p += rs485_sens_count;
...

так удобнее. допустим на шину RS485 добавили пару сенсоров. тогда надо сделать заново
RS485_DiscoverSensors(rs485_sensors, &rs485_sens_count);

и сделать рефреш на общий список
SENS_AddToListAll();
12 июл 20, 12:11    [22165975]     Ответить | Цитировать Сообщить модератору
 Re: Соединить несколько списков в один в С.  [new]
Dima T
Member

Откуда:
Сообщений: 14886
Тогда копируй
12 июл 20, 12:13    [22165977]     Ответить | Цитировать Сообщить модератору
 Re: Соединить несколько списков в один в С.  [new]
jenya7
Member

Откуда:
Сообщений: 1262
Dima T
Тогда копируй

спасибо
12 июл 20, 12:22    [22165981]     Ответить | Цитировать Сообщить модератору
 Re: Соединить несколько списков в один в С.  [new]
mini.weblab
Member

Откуда:
Сообщений: 1027
jenya7,

а если использовать структуру данных Multidimensional Array, то ничего копировать не придется
12 июл 20, 12:57    [22165991]     Ответить | Цитировать Сообщить модератору
 Re: Соединить несколько списков в один в С.  [new]
jenya7
Member

Откуда:
Сообщений: 1262
mini.weblab
jenya7,

а если использовать структуру данных Multidimensional Array, то ничего копировать не придется

вопрос как определить второй dimension. списки могут меняться, сегодня добавили пару сенсоров завтра убрали.
12 июл 20, 13:32    [22166000]     Ответить | Цитировать Сообщить модератору
 Re: Соединить несколько списков в один в С.  [new]
mini.weblab
Member

Откуда:
Сообщений: 1027
jenya7,

вы же определили размер массива для разных типов сенсоров

SENSOR can_sensors[32];

а здесь будет
SENSOR all_sensors[3][32]; // 3 строки, 32 столбца
12 июл 20, 18:38    [22166101]     Ответить | Цитировать Сообщить модератору
 Re: Соединить несколько списков в один в С.  [new]
mini.weblab
Member

Откуда:
Сообщений: 1027
sensors.h
+
#ifndef SENSORS_H
#define SENSORS_H
#define NUM_OF_TYPES 4
#define MAXNUM 32

typedef enum {LOCAL, CAN, RS, LAN} SensorType;
typedef enum {OFF, ON, DUMMY} SensorStatus;

typedef struct {
	SensorType stype;
	SensorStatus status;
	float value;
} SENSOR;

SENSOR loc_sensors[MAXNUM];
SENSOR can_sensors[MAXNUM];
SENSOR rs_sensors[MAXNUM];
SENSOR lan_sensors[MAXNUM];

// Initialize group of sensors
SENSOR *SensorGroupInit(SENSOR s[MAXNUM], SensorType type);
// Display all sensors
void display_sensors(SENSOR **s);
// Display group of sensors
void display_group(SENSOR *s);

#endif


sensors.c
+
#include <stdio.h>
#include "sensors.h"

SENSOR *SensorGroupInit(SENSOR s[MAXNUM], SensorType type) {
	for (int i = 0; i < MAXNUM; i++) {
		s[i].stype = type;
		s[i].status = DUMMY;
		s[i].value = 0;
	}
	return s;
}

void display_group(SENSOR *s) {
	for (short i = 0; i < MAXNUM; i++) {
		printf("Sensor id: %-4d type: %-4d status %-4d value %.2f\n",
				i, s[i].stype, s[i].status, s[i].value);
	}
}

void display_sensors(SENSOR **s) {
	for (SensorType type = LOCAL; type <= LAN; type++) {
		printf("\nSensors of type: %d:\n", type);
		for (short j = 0; j < MAXNUM; j++) {
			printf("Sensor id: %-4d status: %-4d value: %.2f\n",
					j, s[type][j].status, s[type][j].value);
		}
	}
}


main.c
+
#include <stdio.h>
#include "sensors.h"

int main(void) {
	SENSOR *loc = SensorGroupInit(loc_sensors, LOCAL);
	SENSOR *can = SensorGroupInit(can_sensors, CAN);
	SENSOR *rs = SensorGroupInit(rs_sensors, RS);
	SENSOR *lan = SensorGroupInit(lan_sensors, LAN);

	SENSOR *sensors[4] = {
			loc_sensors,
			can_sensors,
			rs_sensors,
			lan_sensors
	};

	// Display all sensors on the sensor board
	printf("\nDisplaying all sensors:\n");
	display_sensors(sensors);

	// Display sensors by group
	printf("\nDisplaying sensors by group.\n");
	// LOCAL
	printf("\nDisplaying LOCAL sensors:\n");
	display_group(loc);
	// CAN
	printf("\nDisplaying CAN sensors:\n");
	display_group(can);
	// RS
	printf("\nDisplaying RS sensors:\n");
	display_group(rs);
        // LAN
        printf("\nDisplaying LAN sensors:\n");
        display_group(lan);

	return 0;
}
13 июл 20, 00:48    [22166182]     Ответить | Цитировать Сообщить модератору
 Re: Соединить несколько списков в один в С.  [new]
jenya7
Member

Откуда:
Сообщений: 1262
mini.weblab
jenya7,

вы же определили размер массива для разных типов сенсоров

SENSOR can_sensors[32];

а здесь будет
SENSOR all_sensors[3][32]; // 3 строки, 32 столбца

да но если all_sensors[3][32]; заполнены частично то будут дырки. я же хочу дать пользователю единый список чтоб он обратился по абсолютному индексу. скажем он пишет в терминале "sensor get 7" и получает all_sensors[7].value. ему не нужно ломать голову в какой группе какой индекс выбрать. предварительно он может получить список всех сенсоров "sensor list", так он знает какой сенсор по какому индексу.
13 июл 20, 09:26    [22166242]     Ответить | Цитировать Сообщить модератору
 Re: Соединить несколько списков в один в С.  [new]
mini.weblab
Member

Откуда:
Сообщений: 1027
jenya7,

проблема в том, что приложение использует в 3 раза больше памяти, чем ему на самом деле нужно.
дальше, это уже вам решать, подходит вам такое или нет.
13 июл 20, 13:53    [22166493]     Ответить | Цитировать Сообщить модератору
Все форумы / Программирование Ответить