Этот пакет программного обеспечения предназначен для сбора данных и обработки информации в соответствии с протоколом DL/T 645. После завершения портирования аппаратной части (в основном для передачи данных через последовательный порт) пользователи могут использовать всего один API для чтения, обработки и хранения данных, отмеченных специфическим протоколом (DL/T 1997 или DL/T 2007). Это позволяет пользователям не беспокоиться о формировании запросов и распаковке полученных данных, что делает процесс сбора данных действительно "одним кликом".
Конечно, из-за ограниченных возможностей, мне было сложно сразу предусмотреть все возможные ситуации и функции. Поэтому основные возможности этого пакета программного обеспечения были созданы исходя из моих потребностей, и они пока не охватывают все требования. Также возможно наличие некоторых мелких проблем. Однако в будущем эта инструкция будет содержать подробное руководство по разработке функциональности, чтобы разработчики могли легко добавлять и модифицировать функции в соответствии со своими потребностями. Со временем этот пакет программного обеспечения будет становиться всё более совершенным, и мы надеемся, что разработчики, использующие этот пакет, будут активно участвовать в его улучшении.### Поддерживаемые функции:
Перед использованием пакета программного обеспечения необходимо добавить все исходные файлы из директории src в проект, а также добавить директорию inc в список заголовочных файлов. Кроме того, следует реализовать портирование нижнего уровня аппаратной части, ориентированное на используемую платформу, следуя примеру файла dlt645_port.c, находящегося в директории port. В данный момент SCons по умолчанию не добавляет файлы из директории port в проект, поэтому эти файлы должны быть добавлены вручную в других директориях проекта (подробное описание методики портирования приведено ниже).
После завершения портирования аппаратной части можно использовать пакет программного обеспечения следуя указанным ниже шагам:1. Вызовите пользовательскую реализацию функции инициализации аппаратной части для подготовки оборудования к сбору данных по протоколу DLT645 и зарегистрируйте структуру окружения DLT645.
2. Вызовите функцию dlt645_set_addr()
для установки адреса устройства-слейва, которое требуется сканировать. (Подробное описание функции см. в разделе Детальное описание API)
3. Вызовите функцию dlt645_read_data()
для чтения конкретных данных идентификаторов и сохранения их в указанном пользователем месте. (Подробное описание функции см. в разделе Детальное описание API)
dlt645
как контейнера для среды работы с протоколом DLT645.Контейнер среды является основным объектом при работе программы, а его содержимое и интерфейсы будут использоваться ядром программы. Поэтому предоставленные пользователем интерфейсы также должны быть зарегистрированы в этой структуре. Его структура представлена ниже:
``````c
typedef struct dlt645
{
uint8_t addr[6]; // адрес устройства-слейва
uint8_t debug; // флаг отладки
int (*write)(struct dlt645 *ctx, uint8_t *buf, uint16_t len); // низкоуровневый интерфейс записи
int (*read) (struct dlt645 *ctx, uint8_t *msg, uint16_t len); // низкоуровневый интерфейс чтения
void *port_data; // расширенный пользовательский интерфейс
} dlt645_t;
Член | Описание |
---|---|
addr | Шестизначный массив адресов устройства-слейва |
debug | Флаг отладки ядра |
write | Низкоуровневый интерфейс записи (предоставляемый пользователем) |
read | Низкоуровневый интерфейс чтения (предоставляемый пользователем) |
port_data | Расширенный пользовательский интерфейс |
Формат интерфейса:
int (*write)(struct dlt645 *ctx, uint8_t *buf, uint16_t len);
Подробное описание:
При необходимости пользователя прочитать/записать устройство-слейв, ядро программы будет использовать этот интерфейс для отправки командных фреймов. Пользователь должен реализовать эту функцию для своего оборудования. Эта функция принимает три параметра:
Формат интерфейса:
int (*read)(struct dlt645 *ctx, uint8_t *msg, uint16_t len);
Подробное описание:
После успешной отправки команды, ядро программы немедленно использует этот интерфейс для получения ответа от устройства-слейва. При вызове этого интерфейса передаются три параметра:
### Расширенные интерфейсы
Структура dlt645 содержит поле **port_data**, тип которого — `void *`. Пользователи могут использовать это поле для создания собственной структуры данных, расширяющей возможности интерфейсов и позволяющей выполнять более сложные операции с оборудованием.
### Пример миграции
```C
/*************************************************
Copyright (c) 2019
Все права защищены.
Название файла: dlt645_port.c
Описание: Файл примера миграции и использования DLT645
История:
1. Версия:
Дата: 2019-09-19
Автор: wangjunjie
Изменение:
*************************************************/
#include "dlt645.h"
#include "rtthread.h"
#include "drv_gpio.h"
// Имя используемого для сбора данных последовательного порта
#define DLT645_SERIAL_NAME "uart4"
// Структура расширения оборудования DLT645
typedef struct
{
rt_sem_t dlt645_sem; // Сигнальная семафорная переменная для приема данных через последовательный порт
uint32_t byte_timeout; // Время ожидания между байтами
} dlt645_port_t;
static dlt645_port_t dlt645_port = {
.dlt645_sem = RT_NULL,
.byte_timeout = 10, // Время ожидания между байтами
};
```// Объект устройства DLT645
static rt_device_t dlt645_device = RT_NULL;
// Сигнальная семафорная переменная для приема данных DLT645
static struct rt_semaphore dlt645_receive_sem;
// Параметры конфигурации последовательного порта
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
// Структура окружения DLT645
dlt645_t dlt645;```markdown
---
#### 3. API Подробное описание
##### Функция `uart_handler`
**Описание:** Функция обратного вызова для приема данных через последовательный порт.
**Параметры:**
- `dev`: устройство
- `size`: размер данных
**Возвращаемое значение:** `rt_err_t` — результат выполнения функции.
```c
rt_err_t uart_handler(rt_device_t dev, rt_size_t size)
{
// Освобождение сигнальной семафорной переменной при получении данных
rt_sem_release(&dlt645_receive_sem);
return RT_EOK;
}
dlt645_hw_read
Название: dlt645_hw_read
Краткое описание: Чтение данных на уровне аппаратной реализации.
Входные параметры:
ctx
: контекст работы протокола 645msg
: адрес хранения полученных данныхlen
: максимальная длина принимаемых данныхstatic int dlt645_hw_read(dlt645_t *ctx, uint8_t *msg, uint16_t len)
{
// фактическая длина принятых данных
int read_len = 0;
// очистка буфера
uint8_t buf = 0;
// очистка буфера
while(rt_device_read(dlt645_device, 0, &buf, 1));
// ожидание получения данных через последовательный порт
if(rt_sem_take(&dlt645_receive_sem, 1000) == -RT_ETIMEOUT)
{
return 0;
}
// чтение данных по одному байту за раз
while (rt_device_read(dlt645_device, 0, msg + read_len, 1) == 1)
{
if(read_len > len)
{
return 0;
}
else
{
read_len++;
}
// проверка на истечение времени ожидания приёма данных
if (rt_sem_take(&dlt645_receive_sem, ((dlt645_port_t *)(ctx->port_data))->byte_timeout) == -RT_ETIMEOUT)
{
break;
}
}
return read_len;
}
**Описание:** При чтении данных с устройства по протоколу 645 пользователю сначала следует использовать этот интерфейс для установки адреса желаемого Slave.
**Формат API:**
```c
void dlt645_set_addr(dlt645_t *ctx, uint8_t *addr);
Параметры:
Параметр | Описание |
---|---|
ctx | Обработчик структуры 645 |
addr | Массив из 6 байт, представляющий адрес |
Пример использования
// dlt645 среда
extern dlt645_t dlt645;
// Адрес Slave равен 111
uint8_t slave_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x01, 0x11};
dlt645_set_addr(&dlt645, slave_addr);
Краткое описание: Пользователи могут использовать этот интерфейс для чтения данных с указанного идентификатора с рабочего устройства.
Формат API:
int dlt645_read_data(dlt645_t *ctx, uint32_t code, uint8_t *read_data, dlt645_protocol protocol);
Параметры:
Название параметра | Описание |
---|---|
ctx | Обработчик структуры 645 |
code | Идентификатор |
read_data | Адрес хранения считываемых данных (обратите внимание, что размер адреса составляет 4 байта) |
protocol | Указание типа протокола (опционально DLT645_2007 или DLT645_1997) |
Возвращаемое значение | Описание |
---|---|
целое число | Длина считываемых данных |
-1 | Чтение не удалось |
Пример использования
// структура окружения dlt645
extern dlt645_t dlt645;
// тестовый идентификатор сбора данных dlt645 (напряжение A фазы)
#define DLT645_2007_READ_TEST_CODE 0x02010100
// массив для хранения считываемых данных
uint8_t read_buf[4];
// чтение данных
if (dlt645_read_data(&dlt645, DLT645_2007_READ_TEST_CODE, read_buf, DLT645_2007) > 0) {
printf("Чтение успешно выполнено, напряжение A фазы равно: %.2f \r\n", *(float *)read_buf);
} else {
rt_kprintf("Чтение не удалось\r\n");
}
/*************************************************
Copyright (c) 2019
Все права защищены.
Имя файла: sample.c
Описание: Пример использования пакета программ DLT645
История:
1. Версия:
Дата: 2019-09-23
Автор: wangjunjie
Изменение:
*************************************************/
#include "dlt645.h"
#include "dlt645_port.h"
``````markdown
/**
* Название: dlt645_read_test
* Краткое описание: тестовый программный модуль для проверки сбора данных по протоколу DLT645
* Входные данные: отсутствуют
* Выходные данные: отсутствуют
*/
static void dlt645_read_test(void)
{
uint8_t read_buf[4];
rt_memset(read_buf, 0, 4);
// Установка адреса slave устройства
dlt645_set_addr(&dlt645, test_addr);
//if(dlt645_read_data(&dlt645, DLT645_1997_READ_TEST_CODE, read_buf, DLT645_1997) > 0) // Тест сбора данных по версии 1997 года
if(dlt645_read_data(&dlt645, DLT645_2007_READ_TEST_CODE, read_buf, DLT645_2007) > 0) // Тест сбора данных по версии 2007 года
{
printf("Чтение выполнено успешно, значение напряжения А фазы составляет: %.2f \r\n", *(float *)read_buf);
}
else
{
rt_kprintf("Чтение не удалось\r\n");
}
}
/**
* Название: main
* Краткое описание: основная функция
* Входные данные: отсутствуют
* Выходные данные: отсутствуют
*/
int main(void)
{
// Инициализация аппаратного слоя dlt645
dlt645_port_init();
while(1)
{
// Чтение данных для тестирования
dlt645_read_test();
rt_thread_mdelay(1000);
}
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )