2013-12-05 4 views
1

Мне нужно отправить несколько чисел с плавающей точкой между некоторыми узлами Texas Instrument CC2530. Эта архитектура может посылать только массив uint8.
То, что я уже пытался сделать, это присвоить указателю uint8 указатель float с литой. Затем я отправляю эти байты, и когда они получены, они копируются в массив uint8. В конце я создаю другой указатель float, который устанавливает листинг ранее созданного массива.
На самом деле, этот трюк работает на моем компьютере (используя символ без знака вместо uint8), но не в узлах, где полученное число всегда равно 0.TI CC2530 - конвертировать поплавок в uint8 [] для отправки, а затем конвертировать обратно в поплавок на прием

Это часть кода используется в случае передачи (там он создает msa_Data1, что пакет передается, где номер для отправки является valMed (глобальная переменная)):

void Data_create(){ 
    uint8 *sends; 
    sends = (uint8 *) &valMed; 
    uint8 rec_index; 
    for(rec_index=0; rec_index < sizeof(float); ++rec_index){ 
     msa_Data1[rec_index]= sends[rec_index]; 
    } 
} 

в разделе приема у меня есть:

uint8 receiveds[sizeof(float)]; 
uint8 rec_index; 
    for(rec_index=0; rec_index < sizeof(float); ++rec_index){ 
     receiveds[rec_index]= pData->dataInd.msdu.p[rec_index]; 
    } 
float *received= (float *)receiveds; 

Данные от передачи принимается pData->dataInd.msdu.p[rec_index]

моделирования передачи я пытался на компьютере является:

main(){ 
    float send= -3.14; 
    unsigned char *sends; 
    sends = (unsigned char *)&send; 
    printf("1:%d, 2:%d, 3:%d, 4:%d \nfloat sent:%f \n", sends[0], sends[1], sends[2], sends[3], send); 
    unsigned char receiveds[sizeof(float)]; 
    int rec_index; 
    for(rec_index=0; rec_index < sizeof(float); ++rec_index){ 
     receiveds[rec_index]= sends[rec_index]; 
    } 
    float *received= (float *)receiveds; 
    printf("float received:%f\n", *received); 
} 

Выход:

[email protected] ~/test $ ./test 
1:195, 2:245, 3:72, 4:192 
float sent:-3.140000 
float received:-3.140000 

В этом случае я могу увидеть тест хорошо работает на ПК, но это не на узлах. Что случилось?

Заранее благодарю за помощь!

Alex

+0

Может ли принимающая сторона получить «вне фазы», ​​так что она принимает пакет 1 конца байтов и первый байт следующего пакета? Если это возможно, ваши пакеты должны увеличиваться в размере, чтобы включить что-то, чтобы обеспечить правильное согласование во время общения. – chux

+0

Размер пакета должен быть достаточным для этой области, у меня есть 20-байтовый пакет, в то время как поплавок всего 4 байта. Кроме того, создается пакет, устанавливающий данные в правильном расположении массива для отправки, что устраняет даже проблему обратного переупорядочения (классическая проблема с последовательной связью). Благодаря! – Alex

ответ

2

Код в секции приема проблематичен. Вы копируете байты в receiveds, а затем используете преобразования указателей, чтобы обрабатывать их как float. Однако во многих реализациях C используется однобайтное выравнивание для типов символов/байтов (как, вероятно, receiveds) и четырехбайтовое выравнивание для типов float. Преобразование указателя uint8 в указатель float может привести к указанию с неправильным выравниванием.

Вместо этого, вы можете сделать это:

float received; 
… // Code that prepares receiveds goes here. 
memcpy(&received, receiveds, sizeof received); 

Кроме того, если pData->dataInd.msdu.p представляет собой массив или указатель на байты (char, unsigned char, или, скорее всего, uint8 и uint8 типа символов в вашем C осуществление), то вы можете опустить с помощью receiveds в качестве промежуточного буфера и просто скопировать непосредственно:

float received; 
// Omit the code that copied into receiveds. 
memcpy(&received, pData->dataInd.msdu.p, sizeof received); 

Если это не решит проблему, то экзамен в котором фактические байты копируются в буфер отправки, а байты копируются из буфера приема и гарантируют, что они одинаковы.

+0

Спасибо за ваш ответ: тест на ПК (составленный gcc) также работал (очевидно). Завтра я проведу его на CC2530, и я увижу, что произойдет. То, что я не видел, это возможное разное выравнивание. Это имеет смысл для системы с ограниченной памятью, а также CC2530. – Alex

+0

Он отлично работает! Просто используется 'osal_memcpy', который предоставляется TI. Еще раз спасибо. – Alex

1

Почему бы не представлять ваши номера с помощью фиксированной точки? Всякий раз, когда я работал с TI CC2530, я старался избегать накладных расходов с плавающей запятой и прибегал к отображению чисел в фиксированной точке.Эти значения гораздо более прямолинейны при отправке, но вы должны быть осторожны с вашим представлением.

+0

Вы совершенно правы в смысле накладных расходов, но для приложения, которое я создаю, мне нужно использовать float, чтобы сохранить определенную точность. Поскольку для этого приложения накладные расходы не важны, я не хотел иметь дело с предварительными умножениями и делением, чтобы сохранить эту точность постоянной. Более того, я думаю, что это может иметь ту же проблему при копировании как поплавок, потому что выравнивание (8 бит не достаточно, хотя). Спасибо! – Alex