Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

Странен код
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=11004
Страница 1 от 2

Автор:  Nikola Kirov [ Нед Яну 20, 2013 2:28 pm ]
Заглавие:  Странен код

Код:
uint8_t *pack = {0};
pack[0] = (start_address&0xFF00)>>8;
pack[1] = start_address&0xFF;


Това код от Атмел. Би трябвало и да работи. Но нещо не схващам идеята. Някой ще ме насочи ли в правилната посока на мислене?

Автор:  woody [ Нед Яну 20, 2013 2:51 pm ]
Заглавие:  Re: Странен код

Nikola Kirov написа:
Код:
uint8_t *pack = {0};
pack[0] = (start_address&0xFF00)>>8;
pack[1] = start_address&0xFF;


Това код от Атмел. Би трябвало и да работи. Но нещо не схващам идеята. Някой ще ме насочи ли в правилната посока на мислене?

Някаква безсмислена форма на скаларна инициализация.

Код:
uint8_t *pack = 0;

Върши точно същата работа. Другото трябва да ти е ясно.

Автор:  miro_atc [ Нед Яну 20, 2013 3:14 pm ]
Заглавие:  Re: Странен код

woody написа:
Код:
uint8_t *pack = 0;

Върши точно същата работа.

ми не, това е обект от тип указател и той се инициализира с нула.

Докато в декларацията на атмел има 2 обекта:
- масив с един елемент, който се инициализира с нула
- указател, който си инициализира с адреса на масива.


Проблемът в кода е че пишат във втори елемент на масива... Това е бъг Никола, въпреки че много компилатори биха заделили 4 байта, заради подравняване и т.н. Демек може и да не прави бели в кокретния случай, но си е мазане по паметта. Освен това масивът е за инициализация и е друга секция/памет и не е редно да се пише по него дори и по първия и единствен елемент.

Автор:  Nikola Kirov [ Нед Яну 20, 2013 3:47 pm ]
Заглавие:  Re: Странен код

"много компилатори биха заделили 4 байта"

В случая с този код направен да работи за AVR32 ще стане точно така. Това бил трика. Но е безмислено да се пише толкова криво.

Мерси за помоща

Автор:  woody [ Нед Яну 20, 2013 4:19 pm ]
Заглавие:  Re: Странен код

Миро, сигурен ли си? Понеже го проверих преди да пиша.

Автор:  miro_atc [ Нед Яну 20, 2013 5:26 pm ]
Заглавие:  Re: Странен код

да, сигурен съм!

Фигурните скобки в инициализации значат масив или POD структура. В случая масив.

Съответно едно е да инициализираш указател с нула, друго е с адреса на масив, съдържащ елемент с нулева стойност. Съвсем различни бири са.

Автор:  Nikola Kirov [ Нед Яну 20, 2013 6:20 pm ]
Заглавие:  Re: Странен код

Код:
void at24cxx_write_continuous(uint16_t start_address, uint16_t length, uint8_t const *wr_buffer) {
  uint8_t *pack = {0};
  twi_package_t twi_package;

  pack[0] = (start_address&0xFF00)>>8;
  pack[1] = start_address&0xFF;
  uint16_t idx;
  for (idx=0;idx<length;idx++)
    pack[2+idx] = wr_buffer[idx];

  twi_package.chip = AT24CXX_TWI_ADDRESS;
  twi_package.addr_length = 0;
  twi_package.buffer = &pack;
  twi_package.length = sizeof(pack);

  while(twi_master_write(AT24CXX_TWI, &twi_package)!=TWI_SUCCESS);

  return;
}


Тук намерих друг такъв код. Тук вече е по голмо оливане. Така като си разсъждавам pack се инициализира с масив от един елемент който физически се намира в стека. После наблъскват в стека wr_buffer след първите два байта. И би трябвало да става голямо мазало. Но този код е част от ASF на Атмел за AVR32 и би трябвало доста хора да са го ползвали. И това вече ме озадачава. Нещо може да не е както си мисля.

Автор:  bateAz [ Нед Яну 20, 2013 6:30 pm ]
Заглавие:  Re: Странен код

Не може ли да се види на дизасемблито какво се случва ?

Автор:  miro_atc [ Нед Яну 20, 2013 7:22 pm ]
Заглавие:  Re: Странен код

Най-вероятно оригиналният код е бил:
Код:
void at24cxx_write_continuous(uint16_t start_address, uint16_t length, uint8_t const *wr_buffer) {
  uint8_t pack [  length +2];
  twi_package_t twi_package;

  pack[0] = (start_address&0xFF00)>>8;
  pack[1] = start_address&0xFF;
  uint16_t idx;
  for (idx=0;idx<length;idx++)
    pack[2+idx] = wr_buffer[idx];

  twi_package.chip = AT24CXX_TWI_ADDRESS;
  twi_package.addr_length = 0;
  twi_package.buffer = &pack;
  twi_package.length = sizeof(pack);

  while(twi_master_write(AT24CXX_TWI, &twi_package)!=TWI_SUCCESS);

  return;
}


но динамичните масиви са GCC разширение и сигурно са правили порт за друг компилатор. Но са я докарали само до там да се компилира... въпреки че е пълна боза, няма как да работи. Моят съвет е да видиш за по прясна версия. Аз така гледах някакъв код на Чибито дето Цецо каза че работи,
но аз явно съм гледал незавършена версия...

Автор:  ДедоБоре [ Нед Яну 20, 2013 7:40 pm ]
Заглавие:  Re: Странен код

такива програмисти трябва да се бесят по стълбовете...

Автор:  woody [ Нед Яну 20, 2013 8:51 pm ]
Заглавие:  Re: Странен код

miro_atc написа:
да, сигурен съм!

Фигурните скобки в инициализации значат масив или POD структура. В случая масив.

Съответно едно е да инициализираш указател с нула, друго е с адреса на масив, съдържащ елемент с нулева стойност. Съвсем различни бири са.

Хубаво е че си сигурен, защото нали ти казах че го проверих преди да пиша. :)

Код:
char *p1 = {0};
char *p2 = 0;

Код:
        .globl  p1
        .align 4
        .type   p1, @object
        .size   p1, 4
p1:
        .zero   4

        .globl  p2
        .align 4
        .type   p2, @object
        .size   p2, 4
p2:
        .zero   4

Най-обикновени указатели, няма заделяне.
Бира пия вече не толкова много.

Автор:  miro_atc [ Нед Яну 20, 2013 9:16 pm ]
Заглавие:  Re: Странен код

woody написа:
Най-обикновени указатели, няма заделяне.
Бира пия вече не толкова много.

мда, указателите са едни и същи, независимо към какво сочат, а точно там е разликата...
Радвам се, че не пиеш бира щото не съм ти предлагал :-)

Автор:  ДедоБоре [ Нед Яну 20, 2013 9:41 pm ]
Заглавие:  Re: Странен код

добре де, аз ще ви почерпя по една бира...

този код, дори и да се изпълнява правилно, и дори да е (вероятно) синтактично правилен, не ми изглежда семантично ясен.
не виждам причина да се пише триково, когато може да се напише по-разбираемо, дори и резултата да е 20 байта повече код.
това, с недомлъвките в кода, е младеШко увлечение.

Автор:  miro_atc [ Нед Яну 20, 2013 10:32 pm ]
Заглавие:  Re: Странен код

Дедо, виж по-горе как си мисля, че е изглеждал кода преди да го омажат... Съвсем читав изглежда, като изключим че е GCC специфичен.

Целият проблем е, че на високо ниво АПИ-тата трябва да боравят с чисти данни. Клиента казва запиши ей тоз буфер с такава дължина и не се интересува в каква памет ще се пише, с какъв интерфейс и т.н. Така и трябва да бъде.

На ниско ниво обаче различните памети искат различни команди преди данните, в случая И2Ц-то иска адрес. От друга страна пък функциите за писане по хардуера искат всичко да е в един буфер. И не става първо да пратиш служебните данни после истинските с друга транзакция. Ех, не става с тоя тип библиотеки.... аз затова не ползвам такива неща :-)

Та проблемът е че за да се пратят накуп им трябва нов буфер да се сглобят служебните данни с пейлоада. На чисто Ц нямаш голям избор... динамична памет не е желателно да ползваш. Единственият вариант е да заделиш някъде достатъчно памет с максималния размер... Грозно е и затова предлагам някой се е изкушил да ползва ГЦЦ екстри. А после някой е решил да ползва друг компилатор. Вероятно е ползвал друга част от библиотеката и това го е "замазал" само колкото да се компилира останалото... Случват се такива неща, че и по-лоши :-)

Автор:  Реконструктор [ Пон Яну 21, 2013 1:21 pm ]
Заглавие:  Re: Странен код

Nikola Kirov написа:
Код:
uint8_t *pack = {0};
pack[0] = (start_address&0xFF00)>>8;
pack[1] = start_address&0xFF;


Това код от Атмел. Би трябвало и да работи. Но нещо не схващам идеята. Някой ще ме насочи ли в правилната посока на мислене?


pack[0] съдържа старшия байт на start_address, а pack[1] - младшия, кво толкова неясно има. Въпроса е, че &-операцията най-вероятно е излишна, освен това масива е инициализиран само с един елемент.

Страница 1 от 2 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/