Данное программное обеспечение предназначено для сбора и обработки данных в соответствии с протоколом DL/T 645. После переноса на аппаратный уровень (в основном, для передачи и приёма данных через последовательный порт) пользователю достаточно вызвать один API для чтения, обработки и хранения данных идентификаторов, соответствующих определённому протоколу (DL/T 1997 или DL/T 2007). Пользователю не нужно разбираться в сложных внутренних операциях протокола, таких как упаковка и распаковка запросов данных, — всё это делается автоматически.
Конечно, из-за ограниченности моих возможностей я не могу сразу учесть и написать все возможные ситуации и функции, поэтому на начальном этапе функциональность программного пакета ограничивается только теми функциями, которые я использую сам, и не охватывает всех требований. Также могут быть некоторые небольшие проблемы. Однако со временем этот пакет будет постепенно улучшаться, и я надеюсь, что разработчики, использующие этот пакет, смогут присоединиться к его улучшению и внести свой вклад в его развитие!
Перед использованием программного пакета необходимо добавить все исходные файлы в каталоге src в проект, добавить каталог inc в каталог заголовочных файлов и использовать файл dlt645_port.c в каталоге port для реализации переноса на основе используемой аппаратной платформы. В настоящее время scons по умолчанию не добавляет файл порта в проект, и его необходимо добавлять вручную в другой каталог проекта при использовании. (Подробное описание процесса переноса будет представлено ниже.)
После завершения переноса на аппаратный уровень можно выполнить следующие шаги для использования программного пакета:
dlt645_set_addr()
, чтобы установить адрес устройства-получателя, данные которого необходимо собрать. (Подробные инструкции по функциям см. в разделе «API-подробное описание».)dlt645_read_data()
, чтобы прочитать данные идентификатора и сохранить их в указанном пользователем месте. (Подробные инструкции по функциям см. в разделе «API-подробное описание».)Программное обеспечение предоставляет полный набор функций для упаковки и распаковки данных в соответствии с протоколом DL/T 645, а пользователь должен предоставить интерфейс для отправки и получения данных на нижнем уровне в соответствии со своей платформой, чтобы программное обеспечение могло получать и успешно отправлять данные. Ниже подробно описывается процесс переноса программного обеспечения. Если текстовое описание непонятно или вы не понимаете его, вы можете обратиться к примеру переноса в этом разделе.
Структура среды является внутренним объектом ядра программного обеспечения во время выполнения, ядро вызывает данные и интерфейсы внутри него во время работы, поэтому интерфейсы, предоставляемые пользователем, также должны быть зарегистрированы в этой структуре. Его структура выглядит следующим образом:
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);
Подробное описание:
После успешной отправки команды программным ядром оно немедленно вызовет этот интерфейс для считывания ответа от устройства-получателя. При вызове передаются три параметра:
Среди них параметр len указывает максимальную длину разрешённых данных текущего приёма. Пользователь должен обратить внимание на длину полученных данных и вернуть 0, если фактическая длина полученных данных превышает максимально допустимую длину.
В структуре DLT645 предоставляется элемент port_data, тип которого — void *
. Пользователь может использовать этот элемент для создания структуры, соответствующей его приложению, тем самым расширяя больше интерфейсов и полей данных и реализуя более сложные операции с оборудованием.
/*************************************************
Copyright (c) 2019
All rights reserved.
File name: dlt645_port.c
Description: DLT645 Перенос и использование примера файла
History:
1. Version:
Date: 2019-09-19
Author: wangjunjie
Modify:
*************************************************/
#include "dlt645.h"
#include "rtthread.h"
#include "drv_gpio.h"
//DLT645 Последовательный порт для использования
#define DLT645_SERIAL_NAME "uart4"
//RS485 Контакт управления приёмом и отправкой, если слой привода уже имеет привод 485, не используйте заполнение -1
#define DLT645_RS485_DE_PIN -1 //Если используется PA15, измените на 15
//Структура расширения оборудования 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;
//Функция обратного вызова последовательного порта для приёма данных
rt_err_t uart_handler(rt_device_t dev, rt_size_t size)
{
//Освободить сигнал приёма семафора
rt_sem_release(&dlt645_receive_sem);
return RT_EOK;
}
/**
* Name: dlt645_hw_read
* Brief: Нижний уровень DLT645 для получения данных
* Input:
* @ctx: 645 Среда выполнения
* @msg: Данные хранилища для приёма
* @len: Максимальная длина данных приёма
* Output: Длина полученных данных
*/
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;
Это фрагмент кода на языке C. В нём используется функция rt_sem_take
для ожидания освобождения семафора dlt645_receive_sem
. Если семафор не освобождается в течение 1 секунды (1000 миллисекунд), то функция возвращает значение 0.
Далее идёт цикл while
, который считывает данные из устройства dlt645_device
по одному байту за раз. Считываемые данные добавляются к переменной msg
. Переменная read_len
используется для отслеживания количества считанных байт. Если read_len
становится больше, чем len
, то цикл завершается и функция возвращает 0. Иначе read_len
увеличивается на 1.
Затем проверяется, не произошло ли чтение данных с превышением времени ожидания. Для этого снова используется функция rt_sem_take
, но на этот раз с параметром byte_timeout
, который, вероятно, указывает на время ожидания одного байта данных. Если время ожидания истекло, то цикл прерывается.
В конце функции возвращается значение read_len
, которое указывает на количество успешно считанных байт данных.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )