реклама на сайте
подробности

 
 
> UART+xmodem1k. передача файла
Klaxons
сообщение Dec 8 2015, 19:50
Сообщение #1





Группа: Участник
Сообщений: 9
Регистрация: 8-12-15
Пользователь №: 89 623



Здравствуйте

Столкнулся со следующей проблемой, пытаюсь организовать передачу файла с компьютера на микроконтроллер STM32F4 при помощи uart и протокола xmodem1k.

Отправитель написан на java, сразу оговорюсь, написал на java также receiver, и передавал по xmodem1k файл на java, проблем никаких не было, стал писать приемщик на C под stm32 и заметил что, в какой-то момент данные в буфере смещаются.

Вот пример пакета, который шлет компьютер

Код
[b]2 1 -2[/b] -1 -40 -1 -32 0 16 74 70 73 70 0 1 1 1 0 1 0 1 0 0 -1 -37 0 67 0 . . . 233 [b]128 197[/b]


То есть первый байт я говорю, длину пакета (STX или SOH), второй байт - это номер пакета, 3 - инверсия номера пакета, далее данные по 128 или 1024 байта, последние два байта CRC16

И в какой-то момент я вижу что данные смещаются, например так

Код
[b]197 2 1[/b] -2 -1 -40 -1 -32 0 16 74 70 73 70 0 1 1 1 0 1 0 1 0 0 -1 -37 0 67 0 . . . [b]233 128[/b]


или даже так бывает

Код
[b]233 128 197[/b] 2 1 -2 -1 -40 -1 -32 0 16 74 70 73 70 0 1 1 1 0 1 0 1 0 0 -1 -37 0 67 0 . . .


То есть начало буфера получается в конце данных, при этом вроде как порядок байтов не меняется, то есть когда порядок начинается с 2 1 -2 ...
Я вижу, что CRC возвращает истину и пакет цел

Сначала думал, что проблема в отправители, но попробовал ставить паузу после отправки каждого байта все отправляет корректно, то есть я вижу последовательность байтов.

Еще такой момент, когда запускаю отладчик, и ставлю breakpoint на прием последнего байта, то получается чаще принимать данные в правильной последовательности.
То есть если запустить на плате прием данных, без прерывания отладчиком, то начинает зависать на втором пакете, всегда CRC не совпадает и программа отправляет NAK, а если поставить точку в отладчике, то с n раза пакет приходит в правильной последовательности и я сообщаю отправителю слать следующий пакет, иногда, конечно, приходит не в той последовательности, но в другой попытке - все приходит ровно. Но в отладчике также есть момент, когда в какой-то момент программа подвисает, то есть не дойдя до контрольной точки никак не реагирует, хотя отправитель послал пакет, либо после resume контрольной точки, не доходит до места отправки NAK или ACK, приходится хардверно отправлять NAK (на пользовательскую кнопку повешена такая задача)

Также пробовал перебирать последовательность принятых байт, смещая их на одну позицию назад, но это не очень удобно, если неизвестно на какой позиции находится настоящий первый элемент пакета.

Вот пример инициализации и приема данных в stm

Если, например, опустить дополнительные байты, а отправлять только данные, то все пакеты проходят, однако, там байты тоже сдвигаются, и, отправляя, например, картинку, в stm я вижу эту картинку, но видно, что в некоторых местах байты не на месте

CODE
void usart3_init(void)
{
huart3.Instance = USART3;
huart3.Init.BaudRate = 9600;
huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart3.Init.Mode = UART_MODE_TX_RX;
huart3.Init.OverSampling = UART_OVERSAMPLING_16;
huart3.Init.Parity = UART_PARITY_NONE;
huart3.Init.StopBits = UART_STOPBITS_1;
huart3.Init.WordLength = UART_WORDLENGTH_8B;
HAL_UART_Init(&huart3);
}

...

void interrupts_usart3_init(void)
{
HAL_NVIC_SetPriority(USART3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART3_IRQn);

HAL_NVIC_SetPriority(DMA1_Stream3_IRQn, 6, 1);
HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn);

HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 6, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);

__HAL_UART_FLUSH_DRREGISTER(&huart3);
HAL_UART_Receive_DMA(&huart3, &rxBuffer, 1);
}

...

void dma_usart3_rx_init(void)
{
hdma_usart3_rx.Instance = DMA1_Stream1;
hdma_usart3_rx.Init.Channel = DMA_CHANNEL_4;
hdma_usart3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart3_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart3_rx.Init.MemInc = DMA_MINC_DISABLE;
hdma_usart3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart3_rx.Init.Mode = DMA_CIRCULAR;
hdma_usart3_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
hdma_usart3_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_usart3_rx);

__HAL_LINKDMA(&huart3, hdmarx, hdma_usart3_rx);

}

...

void DMA1_Stream1_IRQHandler(void)
{
HAL_NVIC_ClearPendingIRQ(DMA1_Stream1_IRQn);
HAL_DMA_IRQHandler(&hdma_usart3_rx);
}

void USART3_IRQHandler(void)
{
HAL_UART_IRQHandler(&huart3);
}

...

#define MAXCLISTRING 1029

uint8_t rxString[MAXCLISTRING];
uint8_t rxBuffer = 0;
uint8_t rxindex = 0;

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
__HAL_UART_FLUSH_DRREGISTER(&huart3); // Clear the buffer to prevent overrun

if (rxindex == MAXCLISTRING) // если конец пакета
{
rxindex = 0;
if (checkCRC16(&rxString[3], SIZE) == 1) // сравниваю контрольную сумму
{
led_toggle(BLUE);
xbuf[0] = ACK;

UINT* bw;
f_write(&fil, &rxString[3], SIZE, (UINT*)&bw);
if (bw > 0) led_toggle(ORANGE);
HAL_UART_Transmit(&huart3, xbuf, 1, 5); // сообщаю, что готов принять следующий пакет
}
else
{
xbuf[0] = NAK;
HAL_UART_Transmit(&huart3, xbuf, 1, 5); // прошу повторить пакет
}
}
else
{
rxString[rxindex] = rxBuffer; // записываю новый байт в буфер
rxindex++; // увеличиваю индекс
}
}


Сообщение отредактировал IgorKossak - Dec 9 2015, 19:10
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 17:21
Рейтинг@Mail.ru


Страница сгенерированна за 0.02274 секунд с 7
ELECTRONIX ©2004-2016