| Микроконтролери и електроника http://mcu-bg.com/mcu_site/ |
|
| бъг в оптимизатора на С30 (С за 30та серия на микрочип) http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=5251 |
Страница 1 от 2 |
| Автор: | zaphod [ Сря Дек 26, 2007 11:31 am ] | |||||||||
| Заглавие: | бъг в оптимизатора на С30 (С за 30та серия на микрочип) | |||||||||
при включване на оптимизациите на С30 програмата спря да бачка. проследих проблема и видях че е във една функция която чете два 16 битови инта и ги връща като един 32 битов. разгледах кода на асемблер и видях следното:
резултата от бъга е че прочетените 32 битови числа са със случайно съдържание на старшите 16 бита кво да кажа освен че задълбочих убеждението си че микрочип не могат да пишат софтуер. ако размера на кода и скоростта не са критични, моята препоръка е да не се включва оптимизатора, понеже носи риск, това не само на тая платформа а по принцип. |
||||||||||
| Автор: | TheWizard [ Сря Дек 26, 2007 12:23 pm ] |
| Заглавие: | |
по принцип не ползвам "оптимизации" if then си ги правя сам където е необходимо... а това където си го описал - сигурен ли си че бъга не е от тебе (процедурата "rcall 0x001fae") пасни кода да пробвам на мойто С30... |
|
| Автор: | zaphod [ Сря Дек 26, 2007 1:02 pm ] | ||||||||||||||||||
| Заглавие: | |||||||||||||||||||
това е кода на С, пробвай го, функцията ReadRSWord си сложи някаква която връща инт (16 битов). оптимизатора е на ниво s, на други нива не съм пробвал, без оптимизация се компилира правилно. що се отнася за това къде е бъга - аз не пиша от вчера и знам че компилатор току така не се обвинява. |
|||||||||||||||||||
| Автор: | Nikola Kirov [ Сря Дек 26, 2007 1:52 pm ] | ||||||||||||||||||
| Заглавие: | |||||||||||||||||||
Такава простотия ми е правило visual studio 6. Правилно е да си слижиш явно преобразуване на типа. Също там имаш малко каша с signed/unsigned. Така би трябвало да не се омотва.
A ако искаш да спиш спокойно обясняваш като на малоумен така;
|
|||||||||||||||||||
| Автор: | ДедоБоре [ Сря Дек 26, 2007 1:56 pm ] | |||||||||
| Заглавие: | ||||||||||
майкро[чип|софт] oще по-малко - те са безгрешни. иначе за оптимизациите си прав - трябва да се ползват внимателно и със стратегия за тестване. то самото QA си е наука ако трябва да се прави както трябва. и отнема доста от бюджета на проекта. доколко хардуерна фирма може да прави софтуер... резултата е същия когато софтуерна фирма прави хардуер. преди 20-30 години моторола си правеже сама софтуера. после обаче си купиха metrowerks и престанаха да се занимават със софтуероправене. от това пострада малко потребителя, защото съпорта на моторола си беше на ниво, но такова е решението на корпорацията - оптимизация на разходите. изобщо - силиконовата чалга е повсеместна. при нас се изразява предимно в плиткоумни силиконови певачки, а при тях в бъгав силикон от пикльвци, авери, lpc-та и т.н. всеки гони срокове, а не качество. и за какво му е да гони вътрешни бъгове, били те в силикона или в софтуера? клиента ги вижда след като си купи изделието => прихода е реализиран. а и няма къде да мърда - всички правят недодялани пръчки, щото брата китаец не спи. и става все по-добър, щото вече само той бачка. у нас не знам дали ще се намери жив спец, който да може да направи чип от пластина. май и в щатите занаята замира... аз лично не мога да реша кое е по-зле: да борим бъгави процесори по $2-3 или да ползваме изчистени (или най-много с 2 грешки) чипове по $10. |
||||||||||
| Автор: | zaphod [ Сря Дек 26, 2007 3:09 pm ] | |||||||||
| Заглавие: | ||||||||||
в случая сигнед, унсигнед все тая, това са просто парчета памет които се копират, няма аритметични операции. по принцип знака има значение само за умножение и деление, при събиране и изваждане можеш да си ги месиш спокойно. но в случая това е малко встрани от темата, понеже бъга е на съвсем друга основа. впрочем аз си излязох от ситуацията сравнително лесно - написах volatile пред буферната променлива и работата заспа |
||||||||||
| Автор: | zaphod [ Сря Дек 26, 2007 3:18 pm ] | |||||||||
| Заглавие: | ||||||||||
разни анализатори посочват че една от причините германия да загуби ВВ2 (разбира се след огромното числено превъзходство на врага) е че германците твърде много са наблягали на качеството на техниката. правиш перфектен танк, без чепаци по дръжките, всичко пасва, квадратна планка може да бъде завъртяна на деведесе градуса, и отворите за винтовете пак пасват (нещо невъзможно за бг) и какво - отива на бойното поле и го трошат след седмица. за какво да правят качествени процесори, след като ще се ползват за мигане на коледни лампички? а и правенето на качествени работи не е лесно. хората си мислят че с много тестове и труд може качеството да се докара на 100% почти. е, големите фирми го правят, но това не пречи колите да гаснат насред пътя заради блокирал процесор. в мазните фирми като джонсън например, се бачка точно бавно и солидно, с тестване и бюрокрация, 50 души правят един индикатор за бензин да речем. и какво, нямат бъгове ли? реконструктора да каже, той е бачкал там |
||||||||||
| Автор: | TheWizard [ Сря Дек 26, 2007 4:26 pm ] |
| Заглавие: | |
пробвах - изглежда наред (дори махна call Test) http://tntm.eu/wiz/test.jpg оптимизация S C30 v3.00 PS в часност ползвах TMR2 и 3 ( за ReadRSDWord() и Test() ) щото oптимизацията за прост тест ми маха излишния код |
|
| Автор: | Nikola Kirov [ Сря Дек 26, 2007 4:33 pm ] | ||||||||||||||||||
| Заглавие: | |||||||||||||||||||
Знам че би трябвало да е все тая но примитивните компилатори се дънят някой път и заради такива неща. Както казах за да спиш спокойно трябва да се обяснява като на малоумник. А volatile е грубо решение за случая. |
|||||||||||||||||||
| Автор: | zaphod [ Сря Дек 26, 2007 5:28 pm ] |
| Заглавие: | |
@киров, просто от любопитство пробвах със строго кастване, както ти предложи, резултата е тоя който очаквах - не е от типовете, бъга остава. а volatile е точно правилното решение, понеже това му е смисъла - отказ от оптимизация. в случая дори не премахва оптимизацията (понеже такава в няма), кода със него остава същия, просто се появява изпуснатата инструкция mov.w 0x0000,[0x001e-2]. @TheWizard това което си пробвал няма много общо с това което съм пуснал като код. както виждаш компилатора не прави извикване на ReadRSWord, a замества директно, но май пак е объркал струва ми се |
|
| Автор: | TheWizard [ Сря Дек 26, 2007 5:37 pm ] |
| Заглавие: | |
unsigned long ReadRSDWord() не съм ти я променял - копирах е от тук ReadRSWord() чете таймер Test() записва в таймер а двата таймера са глобални |
|
| Автор: | zaphod [ Сря Дек 26, 2007 5:38 pm ] |
| Заглавие: | |
верно че не си я променял, гледал съм друго парче код, а после си промених поста както и да е, при тебе компилатора е инлайннал ReadRSWord, пробвай да я напишаш да смята нещо, за да го накараш да я вика, и пробвай с изчислим резултат, таймера не го знаеш какво трябва да върне. обърни внимание обаче на кода който се е генерирал при тебе: как мислиш, мене ми изглежда даже още по-бъгав отколкото при мене е станало. аз получавам поне младшите 16 бита правилни, а при тебе струва ми се целия резултат е напълно случаен (забравил е не само съхранението на старшата дума, а на двете думи), но ти нали четеш таймера и няма как да го усетиш. |
|
| Автор: | TheWizard [ Сря Дек 26, 2007 6:01 pm ] |
| Заглавие: | |
ами при мен си бачка rcall ReadRSDWord mov.d w0,w8 (и w9 запазва си резултата) W0W1 -> W8W9 rcall ReadRSDWord mov.d w0,w10 (и w11 запазва си резултата) W0W1 -> W10W11 http://tntm.eu/wiz/test2.jpg http://tntm.eu/wiz/test3.jpg незнам как да направя проекта за да изглежда като твоя |
|
| Автор: | zaphod [ Сря Дек 26, 2007 6:39 pm ] | ||||||||||||||||||
| Заглавие: | |||||||||||||||||||
не бе човек, гледай кода на функцията ReadRSDWord. ти понеже си я викал два пъти и аз в началото си помислих че тоя код при тебе е кода във функцията, после видях че това не е така и си коригирах поста. на картинката от предния ти пост ясно се вижда кода на функцията ReadRSDWord. тая картинка я изрязах от твоята това е кода на твоята функция ReadRSDWord и макар да не е като моя код (заради инлайнването), също е бъгав. ако искаш да постигнеш съвсем същия ефект, предлагам ти следната функция на мястото на ReadRSWord:
пробвах я, компилатора не я инлайнва, бъга се получава точно същия, ползвай глобална променлива DM, на първото викане функцията трябва да върне 10, на второто 20, следователно резултата от ReadRSDWord трябва да е 0x0014000a а вместо това ще получиш хххх000а финално ето ти кода за пробване:
|
|||||||||||||||||||
| Автор: | miro_atc [ Сря Дек 26, 2007 7:20 pm ] | ||||||||||||||||||||||||||||||||||||
| Заглавие: | |||||||||||||||||||||||||||||||||||||
Правилно, компилатор току-така не се обвинява Преди всичко редно би било да се обърнеш към съпорта, но доста верятно ще те отсвирят веднага щото кодът ти е некоректен. Вероятно изхождаш от навика как съответния процесор разполага променливите, обаче не бива да забравяш че все пак пишеш на С и комполатора очаква да спазваш някой от С-стандартите. Така ти може да очакваш че два елемента на един масив ще са разположени един до друг, но според стандартите нямаш право да го очакваш освен ако не задал съответните атрибути за packed и align. Без тях, компилаторът е в правото си да ги разположи както намери за добре и последващ typecast да не работи както очакваш. Що се отнася до самия typecast, по стандарт нямаш право да надхвърляш размера на обекта който преобразуваш. Тук и компилатора е за е@ане че не ти дава warning. Ако някога пробваш GCC ще видиш какво се казва компилатор и как на 100 ред С-код може да получиш 200 warninga при все че на други компилатори може да нямаш нито един Въпреки че има начини да поддтиснеш или заобиколиш warning-те, аз не те съветвам да го правиш, защото проблемът си остава - четейки извън размера на първия елемет, компилаторът няма как да знае а и не му е работа да знае че четеш и втория. И е съвсем нормално да сметне че стойността му не се използва. Идеята на Никола за union също е много неправилна. Аз лично съм си патил от подобни тарикатщини. Проблемите както казах идват при платформи при които packed и allign имат значение и тогава става малка каша. В такива случаи елементите на union (както и структури) не бива да са с размер по-малък от sizeof(int) иначе няма оправия. В случая обаче решението е много просто - значи не бива да имаш typecast от малък към голям, обаче за обратното няма проблем, т.е вместо горния код може:
|
|||||||||||||||||||||||||||||||||||||
| Страница 1 от 2 | Часовете са според зоната UTC + 2 часа [ DST ] |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|