|
отследить изменение переменной. |
|
|
|
Dec 15 2015, 10:14
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
есть пакет с данными 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) вопрос какой способ быстрее?
|
|
|
|
|
Dec 15 2015, 11:09
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(zltigo @ Dec 15 2015, 16:18)  Один другого хреновее. Сравнивать надо сразу 32bit значения. Типы преобразуйте и все. так что ли? if(*((uint32_t*)new_packet) != *((uint32_t*)old_packet)) а что, за кулисами происходит не одно и то же?
|
|
|
|
|
Dec 15 2015, 11:33
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045

|
Цитата(Jenya7 @ Dec 15 2015, 14:09)  так что ли?
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 зависит от вашего компилятора.
|
|
|
|
|
Dec 15 2015, 11:37
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(Dog Pawlowa @ Dec 15 2015, 17:32)  Ну, для начала желательно знать, что за ядро. То, что предложил ув. zltigo, имеет смысл только для 32-битного ядра. это Cortex-M3 Цитата(msalov @ Dec 15 2015, 17:33)  Нет, разное происходит. При таком варианте у вас может быть проблема с невыровненным доступом. Идеальный вариант - объявить упакованную структуру. которая разложит байты пакета согласно логического содержания, ну а дальше оперировать полями этой структуры. Код __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 . к тому же что может быть невыравненно в массиве? ок. допустим. все равно я думаю это будут те же операции на уровне ассемблера.
Сообщение отредактировал Jenya7 - Dec 15 2015, 11:40
|
|
|
|
|
Dec 15 2015, 11:41
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045

|
Цитата(Jenya7 @ Dec 15 2015, 14:37)  функция принимает массив uint8_t . к тому же что может быть невыравненно в массиве? Адрес 0x0F сгодится для указателя на uint8_t, но не сгодится для uint32_t. Цитата(Jenya7 @ Dec 15 2015, 14:37)  ок. допустим. все равно я думаю это будут те же операции на уровне ассемблера. Будущему вам будет проще читать Код 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]) да и ошибку допустить будет сложнее в первом случае, вот и вся премудрость.
|
|
|
|
|
Dec 15 2015, 11:45
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(msalov @ Dec 15 2015, 17:41)  Адрес 0x0F сгодится для указателя на uint8_t, но не сгодится для uint32_t. допустим первая переменная – uint8_t , вторая – uint8_t , третья – uint32_t тогда if(*((uint32_t*)&new_packet[2]) != *((uint32_t*)&old_packet[2])) и так далее.
|
|
|
|
|
Dec 15 2015, 11:54
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (Dog Pawlowa @ Dec 15 2015, 13:32)  Ну, для начала желательно знать, что за ядро. Надо, но не по другой причите о которой тоже сказали. QUOTE То, что предложил ув. zltigo, имеет смысл только для 32-битного ядра. Для любого имеет, ибо сравнение 32bit на любой платформе это встроенная фича компилятора, которая реализована МАКСИМАЛЬНО хорошо. QUOTE (msalov @ Dec 15 2015, 13:41)  Адрес 0x0F сгодится для указателя на uint8_t, но не сгодится для uint32_t. НАЧАЛО массива по любому будет выравнено. Но в общеем случае, то есть ВСЕГДА  , нужно преобразовывать к указателю на структуру и работать с элементеми.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Dec 15 2015, 11:56
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(zltigo @ Dec 15 2015, 17:54)  Надо, но не по другой причите о которой тоже сказали. Для любого имеет, ибо сравнение 32bit на любой платформе это встроенная фича компилятора, которая реализована МАКСИМАЛЬНО хорошо. НАЧАЛО массива по любому будет выравнено. Но в общеем случае, то есть ВСЕГДА  , нужно преобразовывать к указателю на структуру и работать с элементеми. так какой метод МАКСИМАЛЬНО хорош по вашему мнению? меня интересует СКОРОСТЬ исполнения.
Сообщение отредактировал Jenya7 - Dec 15 2015, 11:58
|
|
|
|
|
Dec 15 2015, 12:00
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (Jenya7 @ Dec 15 2015, 13:45)  допустим первая переменная – uint8_t , вторая – uint8_t , третья – uint32_t тогда if(*((uint32_t*)&new_packet[2]) != *((uint32_t*)&old_packet[2])) и так далее. Нет, это фигня. В общем случае НЕЛЬЗЯ. QUOTE (Jenya7 @ Dec 15 2015, 13:56)  так какой метод МАКСИМАЛЬНО хорош по вашему мнению? меня интересует СКОРОСТЬ исполнения.  Тот о котором написано, что так надо делать ВСЕГДА. Что можно было не понять?
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Dec 15 2015, 12:07
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(zltigo @ Dec 15 2015, 18:00)  Нет, это фигня. В общем случае НЕЛЬЗЯ.
Тот о котором написано, что так надо делать ВСЕГДА. Что можно было не понять? а как не фигня? какая структура. у меня функция принимает массив 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 а не как структуру
Сообщение отредактировал Herz - Dec 17 2015, 11:58
|
|
|
|
|
Dec 15 2015, 12:18
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (Jenya7 @ Dec 15 2015, 14:07)  какая структура. у меня функция принимает массив uint8_t. 1) Не массив, а УКАЗАТЕЛЬ на массив 2) Преобразовать этот указатель в указатель на пакованную структкру и работать с ЭЛЕМЕНТАМИ этой сруктуры. 3) Что Вас удивило со структурой, если поняли, что преобразовывать указатель на массив в указатель на long можно?
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|