Модераторы: PILOT, ManiaK, Mazzi
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема с передачей uint64_t в компьютер 
V
    Опции темы
Курсант
Дата 16.6.2016, 13:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 338
Регистрация: 21.2.2009
Где: Балашиха или Воро неж

Репутация: нет
Всего: 4



Всем доброго времени суток!
У меня следующая проблема: я пересылаю пакет данных из микроконтроллера в компьютер через Ethernet по протоколу UDP. В пересылаемой структуре есть поле - число типа uint64_t, метка времени. В компьютер оно принимается как _int64, т.к. программа на ПК отказывается компилироваться с беззнаковой 64-разрядной переменной, некоторые функции ругаются на несоответствие типов. Число в микроконтроллере постепенно увеличивается от 0 до 4294967296, затем снова сбрасывается в ноль и снова увеличивается. На стороне ПК отображается принятое число от 0 до 2147483648, затем от - 2147483647 и до 0, хотя уже здесь есть вопросы, т.к. для 64-разрядного числа рановато наступает заполнение знакового бита. Ну, допустим, библиотечная функция в программе на ПК приводит 64-разрядный аргумент к 32-разрядному, тогда ладно...
После этого я беру 64-разрядное число в контроллере, и перед отправкой делю его на 1000. В этом случае число на ПК должно увеличиваться от 0 до 4294967, и затем снова сбрасываться в ноль и т.п., т.к. знаковый бит будет не заполнен. Однако в реальности На стороне ПК отображается принятое число от 0 до 2147483, затем от - 2147483 и до 0. Тут я в ступоре, т.к. не могу понять, откуда это берётся? Может быть кто-нибудь сталкивался?
Архитектура микроконтроллера Cortex-M0, т.е. для создания и обработки 64-разрядных переменных компилятор что-то химичит с двумя 32-разрядными переменными...
PM ICQ Skype   Вверх
Romikgy
Дата 16.6.2016, 14:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7278
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 3
Всего: 144



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


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
baldman88
Дата 16.6.2016, 14:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 209
Регистрация: 18.1.2009

Репутация: 1
Всего: 7



Попробуйте на ПК, во время использования переменной, принудительно приводить ее к беззнаковому типу (просто поставьте перед ней (uint64_t)). Должно помочь, так как в двоичном виде число приходит правильно, но за счет того, что ПК трактует его как int64_t, получаются такие вещи.

Это сообщение отредактировал(а) baldman88 - 16.6.2016, 15:05
PM MAIL   Вверх
baldman88
Дата 16.6.2016, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 209
Регистрация: 18.1.2009

Репутация: 1
Всего: 7



Кстати, у Вас число в пределах uint32_t (4294967296), так что лучше преобразовывать к нему, а не к uint64_t.
PM MAIL   Вверх
Курсант
Дата 16.6.2016, 19:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 338
Регистрация: 21.2.2009
Где: Балашиха или Воро неж

Репутация: нет
Всего: 4



Спасибо за ответы!
Вы сейчас забросаете меня помидорами, но причина в компиляторе. Функция, возвращающая тип данных uint64_t обрезает старшие 32 разряда возвращаемого значения... Компилятор Keil, версия среды 5.11. Может быть, конечно, и я ошибся, но всё указывает на то, что возвращаемое значение не то, что стоит в операторе return, а обрезанное.
PM ICQ Skype   Вверх
baldman88
Дата 16.6.2016, 21:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 209
Регистрация: 18.1.2009

Репутация: 1
Всего: 7



Давайте по порядку.
1. Для значений от 0 до 4294967296 достаточно иметь поле uint32_t. Так что, если даже компилятор и обрезает старшие биты (в это верится с трудом), то это ни на что, в данном случае, не влияет. Если есть возможность заменить это поле с uint64_t на uint32_t то можно получить некоторые приимущества. Во-первых, компилятор не будет ничего химичить. Во-вторых, пусть и не существенно, но экономится память.
2. Исходя из вот этого:
Цитата
На стороне ПК отображается принятое число от 0 до 2147483648, затем от - 2147483647 и до 0
 само собой вытекает, что полученное значение рассматривается как знаковое (это и не удивительно, ведь Вы указали, что оно принимается как int64_t). Всегда перед использованием приводите значение к тому виду, в котором вы его отправляли (в Вашем случае это uint64_t).
Ради интереса скомпилируйте и запустите вот это:
Код
#include "stdio.h"
#include "stdint.h"

int main(int argc, char **argv)
{
    int64_t x = -2147483647;
    printf("signed = %d\n", x);
    printf("unsigned = %u\n", x);
    uint64_t y = 4294967295;
    printf("signed = %d\n", y);
    printf("unsigned = %u\n", y);
    uint64_t z = 3000000000;
    printf("signed = %d\n", z);
    printf("unsigned = %u\n", z);
    z = 2147483647;
    printf("signed = %d\n", z);
    printf("unsigned = %u\n", z);
    printf("signed = %d\n", z + 1);
    printf("unsigned = %u\n", z + 1);
    return 0;
}
 и посмотрите внимательно на результаты.
Чтобы лучше разобраться -- почитайте про представление знаковых чисел.

Это сообщение отредактировал(а) baldman88 - 17.6.2016, 07:43
PM MAIL   Вверх
Курсант
Дата 17.6.2016, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 338
Регистрация: 21.2.2009
Где: Балашиха или Воро неж

Репутация: нет
Всего: 4



Хммм... Опять не понятно...
Вот такой кусок кода:
Код

uint64_t tmpTime = 96000000 * 60 * 2;

Приводит к тому, что в tmpTime записывается значение 0xFFFFFFFFAEA54000, а должно быть 0x00000002AEA54000... Что это за хрень?

З.Ы. Проблема решена.
Код

uint64_t tmpTime = (uint64_t)96000000 *  (uint64_t)60 *  (uint64_t)2;

PM ICQ Skype   Вверх
Google
  Дата 20.10.2019, 12:49 (ссылка)  





  Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Микроконтроллеры (MCU) и микропроцессоры (MPU)"
PILOT ManiaK
UniBomb Mazzi

На данный раздел помимо Правил форума распространяются текже следующие правила:


  • Прежде чем создать тему воспользуйтесь поиском или посмотрите в faq. Возможно на форуме уже есть ответ на ваш или близкий к вашему вопрос.
  • В заголовке темы в квадратных скобках обозначьте используемое семейство микроконтроллера: [avr],[pic],[arm].
  • При создании темы с вопросом указывайте участок кода с ошибкой, версию компилятора, схемы подключения, fuse биты и прочие данные, которые помогут найти правильный ответ. Для форматирования текста программ используйте кнопку код.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Для флуда, просьб выполнить задание, поиска партнёров или исполнителей существуют свои разделы.
  • Если вы заметили несовместимое с правилами сообщение, то можете уведомить об этом модератора раздела нажав кнопку Репорт у соответствующего сообщения.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, PILOT, ManiaK, UniBomb, Mazzi.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Микроконтроллеры (MCU) и микропроцессоры (MPU) | Следующая тема »


 




[ Время генерации скрипта: 0.1275 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.