Наиболее эффективный способ записи байтового массива для потоковой передачи - PullRequest
1 голос
/ 19 мая 2011

Мне нужно создать байтовый массив, который необходим для потоковой передачи на другое устройство через UART.Есть некоторые фиксированные параметры, которые я могу заполнить заранее, но такие переменные, как строка, имеют динамический размер.До сих пор я делал:

unsigned char buffer[255];
unsigned char wr_head = 0;
buffer[wr_head++] = 0x01; // and so on
memcpy(&buffer[wr_head], &some_chararray, sizeof(some_chararray));
wr_head += some_chararray;

Я экспериментировал с другими методами, такими как std::string и std::vector, но я чувствовал, что есть много управляемых способов записи байтового массива для потоков,Предложения?

edit : Пожалуйста, советуйте по производительности, потому что это резьбовое соединение.

edit2 : Извините за отсутствие подробностей в первый раз.Устройство действительно является встроенным устройством.Хотя некоторые предложили какое-то решение, это не совсем то, что я хочу.Может быть, фрагмент моей текущей реализации прояснит некоторую путаницу:

unsigned char buffer[255];
unsigned char wr_head = 0;

buffer[wr_head++] = 0x01; // Set message type
buffer[wr_head++] = 0x30; // message length
memcpy(&buffer[wr_head], &some_chararray, sizeof(some_chararray));
wr_head += some_chararray;
buffer[wr_head++] = CalChecksum;
UartSend(&buffer, wr_head); // Send array to stream out from UART

Значение конфигурации и настройки заранее известно, что указано в документации устройства.Этот вопрос связан с тем, что я задал в здесь

Спасибо за усилия.

Ответы [ 2 ]

3 голосов
/ 19 мая 2011

Кольцевой буфер является типичным решением для подобных проблем.

Понятия не имею, на каком устройстве вы находитесь, но я просто предположу , что вы пишете для какого-то встроенного устройства. Давайте предположим, что есть какие-то прерывания, перемещающие данные из кольцевого буфера в UART. Это прерывание вызовет getc, другой код вызовет putc и puts.

class RingBuffer {
private:
    static unsigned BUFSZ = 256;
    volatile unsigned char buf[BUFSZ];
    volatile unsigned char read, write;

public:
    RingBuffer() : read(0), write(0) { }

    // Blocks until space is available
    void putc(unsigned int c) {
        while (((write - read) & (BUFSZ - 1)) == 1)
            sleep();
        buf[write++ & (BUFSZ - 1)] = c;
    }

    // Returns -1 if empty
    int getc() {
        if (read == write)
            return -1;
        return buf[read++ & (BUFSZ - 1)];
    }

    // There are faster ways to write this.
    void puts(char *str) {
        for (; *str; ++str)
            putc(*str);
    }
};

Как правило, вы не хотите, чтобы буфер динамически увеличивался для чего-то подобного. В вышеприведенном коде есть много возможностей для улучшения, и есть также библиотеки, доступные для такого рода вещей.

Эта конкретная реализация также никогда не позволяет полностью заполнить буфер, но в результате код становится проще. Вероятно, я бы не стал запускать этот код в производство, но, надеюсь, это шаг в правильном направлении.

0 голосов
/ 19 мая 2011

Если UartSend является функцией блокировки, вы можете сделать это:

void UartSend(byte b) { UartSend(&b, 1); } // sends one byte

UartSend(0x01); // Set message type
UartSend(0x30); // message length
UartSend(some_chararray,sizeof(some_chararray));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...