Jump to content

    
Sign in to follow this  
jenya7

отследить изменение переменной.

Recommended Posts

есть пакет с данными uint8_t packet[20] . переменная uint32_t занимает 4 байта. соответственно если я хочу посмотреть изменилась ли переменная в следующей посылке я могу сделать так

if (new_packet[0] != old_packet[0] || new_packet[1] != old_packet[1] || new_packet[2] != old_packet[2] || new_packet[3] != old_packet[3])

или так

if(memcmp(new_packet, old_packet, 4) != 0)

вопрос какой способ быстрее?

Share this post


Link to post
Share on other sites
вопрос какой способ быстрее?

Один другого хреновее. Сравнивать надо сразу 32bit значения. Типы преобразуйте и все.

 

 

 

 

Share this post


Link to post
Share on other sites
Один другого хреновее. Сравнивать надо сразу 32bit значения. Типы преобразуйте и все.

так что ли?

 

if(*((uint32_t*)new_packet) != *((uint32_t*)old_packet))

 

а что, за кулисами происходит не одно и то же?

Share this post


Link to post
Share on other sites
так что ли?

 

if(*((uint32_t*)new_packet) != *((uint32_t*)old_packet))

 

а что, за кулисами происходит не одно и то же?

 

Нет, разное происходит. При таком варианте у вас может быть проблема с невыровненным доступом.

Идеальный вариант - объявить упакованную структуру. которая разложит байты пакета согласно логического содержания, ну а дальше оперировать полями этой структуры.

 

   __packed struct packet {
       ...
       uint32_t ref;
       ...
   };
   
   struct packet *old_packet;
   struct packet *new_packet;
   
   if (old_packet->ref != new_packet->ref)
   {
       do_stuff();
   }

__packed зависит от вашего компилятора.

Share this post


Link to post
Share on other sites
Ну, для начала желательно знать, что за ядро.

То, что предложил ув. zltigo, имеет смысл только для 32-битного ядра.

это Cortex-M3

 

Нет, разное происходит. При таком варианте у вас может быть проблема с невыровненным доступом.

Идеальный вариант - объявить упакованную структуру. которая разложит байты пакета согласно логического содержания, ну а дальше оперировать полями этой структуры.

 

 __packed struct packet {
       ...
       uint32_t ref;
       ...
   };
   
   struct packet *old_packet;
   struct packet *new_packet;
   
   if (old_packet->ref != new_packet-<ref)
   {
       do_stuff();
   }

__packed зависит от вашего компилятора.

 

функция принимает массив uint8_t . к тому же что может быть невыравненно в массиве?

ок. допустим. все равно я думаю это будут те же операции на уровне ассемблера.

Edited by Jenya7

Share this post


Link to post
Share on other sites
функция принимает массив uint8_t . к тому же что может быть невыравненно в массиве?

Адрес 0x0F сгодится для указателя на uint8_t, но не сгодится для uint32_t.

 

ок. допустим. все равно я думаю это будут те же операции на уровне ассемблера.

Будущему вам будет проще читать

if (old_packet->ref != new_packet-<ref)

нежели

if (new_packet[0] != old_packet[0] || new_packet[1] != old_packet[1] || new_packet[2] != old_packet[2] || new_packet[3] != old_packet[3])

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

Share this post


Link to post
Share on other sites
Адрес 0x0F сгодится для указателя на uint8_t, но не сгодится для uint32_t.

допустим первая переменная – uint8_t , вторая – uint8_t , третья – uint32_t тогда

if(*((uint32_t*)&new_packet[2]) != *((uint32_t*)&old_packet[2]))

и так далее.

Share this post


Link to post
Share on other sites
Ну, для начала желательно знать, что за ядро.

Надо, но не по другой причите о которой тоже сказали.

То, что предложил ув. zltigo, имеет смысл только для 32-битного ядра.

Для любого имеет, ибо сравнение 32bit на любой платформе это встроенная фича компилятора, которая реализована МАКСИМАЛЬНО хорошо.

 

 

Адрес 0x0F сгодится для указателя на uint8_t, но не сгодится для uint32_t.

НАЧАЛО массива по любому будет выравнено.

Но в общеем случае, то есть ВСЕГДА :), нужно преобразовывать к указателю на структуру и работать с элементеми.

 

Share this post


Link to post
Share on other sites
Надо, но не по другой причите о которой тоже сказали.

 

Для любого имеет, ибо сравнение 32bit на любой платформе это встроенная фича компилятора, которая реализована МАКСИМАЛЬНО хорошо.

 

 

 

НАЧАЛО массива по любому будет выравнено.

Но в общеем случае, то есть ВСЕГДА :), нужно преобразовывать к указателю на структуру и работать с элементеми.

так какой метод МАКСИМАЛЬНО хорош по вашему мнению?

меня интересует СКОРОСТЬ исполнения. :)

Edited by Jenya7

Share this post


Link to post
Share on other sites
допустим первая переменная – uint8_t , вторая – uint8_t , третья – uint32_t тогда

if(*((uint32_t*)&new_packet[2]) != *((uint32_t*)&old_packet[2]))

и так далее.

Нет, это фигня. В общем случае НЕЛЬЗЯ.

 

 

 

так какой метод МАКСИМАЛЬНО хорош по вашему мнению?

меня интересует СКОРОСТЬ исполнения. :)

Тот о котором написано, что так надо делать ВСЕГДА. Что можно было не понять?

 

Share this post


Link to post
Share on other sites
Нет, это фигня. В общем случае НЕЛЬЗЯ.

 

Тот о котором написано, что так надо делать ВСЕГДА. Что можно было не понять?

а как не фигня?

какая структура. у меня функция принимает массив uint8_t.

 

tBleStatus aci_gatt_update_char_value(uint16_t servHandle, 
                      uint16_t charHandle,
                      uint8_t charValOffset,
                      uint8_t charValueLen,   
                      const uint8_t *charValue)

вот сюда - uint8_t *charValue - я должен передать свой пакет.

и для сравнения я получаю его как uint8_t *charValue а не как структуру

Edited by Herz

Share this post


Link to post
Share on other sites
какая структура. у меня функция принимает массив uint8_t.

1) Не массив, а УКАЗАТЕЛЬ на массив

2) Преобразовать этот указатель в указатель на пакованную структкру и работать с ЭЛЕМЕНТАМИ этой сруктуры.

3) Что Вас удивило со структурой, если поняли, что преобразовывать указатель на массив в указатель на long можно?

 

 

 

Share this post


Link to post
Share on other sites
1) Не массив, а УКАЗАТЕЛЬ на массив

2) Преобразовать этот указатель в указатель на пакованную структкру и работать с ЭЛЕМЕНТАМИ этой сруктуры.

3) Что Вас удивило со структурой, если поняли, что преобразовывать указатель на массив в указатель на long можно?

и все это для того чтобы сравнить неколько переменных? мне кажется быстрее уж сделать тем же memcmp

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this