amaora 25 30 июля, 2009 Опубликовано 30 июля, 2009 (изменено) · Жалоба Не нашел подходящего раздела, поэтому пишу сюда. Надоело вылавливать баги связанные с тем что компилятор просто выбрасывает важные части кода. Объявлять все с квалификатором volatile это значить получать вот такое, st X, r25 st -X, r24 ld r24, X+ ld r25, X а местах интенсивного использования таких переменных ещё хуже. Можно создавать локальные копии переменных, делать что надо и записывать обратно, но это не подходит если есть много мест где происходит только чтение, а запись асинхронно в другом месте. Во всех этих местах надо будет разводить копии, что неудобно. Я пока делаю наоборот, в прерывании объявляю указатель на volatile и работаю с ним, но это часто приводит к тому что я показал выше. Какие ещё варианты? Проблема похоже ещё и в том, что далее происходит вызов noreturn функции, но разве это повод выбрасывать запись новых значений в глобальные переменные? Изменено 30 июля, 2009 пользователем amaora Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 30 июля, 2009 Опубликовано 30 июля, 2009 · Жалоба Смысл вопроса в чем? Да, с одной стороны, без volatile нельзя, с другой - он, естественно, дает некоторый оверхед. Остается одно - использовать только там, где это действительно надо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amaora 25 30 июля, 2009 Опубликовано 30 июля, 2009 · Жалоба Смысл вопроса в чем? Да, с одной стороны, без volatile нельзя, с другой - он, естественно, дает некоторый оверхед. Остается одно - использовать только там, где это действительно надо. Узнать как другие решают такие проблемы, смысл. Как проще сделать перечитавание и перезапись значения из RAM только в нужных местах. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 30 июля, 2009 Опубликовано 30 июля, 2009 · Жалоба Узнать как другие решают такие проблемы, смысл. Как проще сделать перечитавание и перезапись значения из RAM только в нужных местах. Ну, у меня почему-то такие проблемы и не возникают :laughing: Лучше приведите конкретный пример кода, с которым возникли трудности. Компилятор без веской на то причины ничего не выбрасывает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amaora 25 30 июля, 2009 Опубликовано 30 июля, 2009 · Жалоба Вот тот код, static void thread_restore_helper() __attribute__ ((__noreturn__, __naked__)); struct thread **th_head; struct thread * volatile * th_self_v = &th_self; if (likely(*th_head)) { interrupts_disable(); *th_head = (*th_head)->next; // это было вырезано компилятором *th_self_v = *th_head; // это тоже было, теперь нет thread_restore_helper(); } th_head надо записать, но при этом его не надо три раза читать. Тоесть ещё один указатель на volatile, это все делает код менее понятным, сначала там и th_self_v не было. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
singlskv 0 30 июля, 2009 Опубликовано 30 июля, 2009 · Жалоба Надоело вылавливать баги связанные с тем что компилятор просто выбрасывает важные части кода. Объявлять все с квалификатором volatile это значить получать вот такое,Ваша проблемма в том что Вы не видите что нужно объявлять volatile а что не нужно. Ну и код в студию конечно... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amaora 25 30 июля, 2009 Опубликовано 30 июля, 2009 · Жалоба Насчет одной из строк ошибся, она не выбрасывается, но вот это все таки вот так, th_self = *th_head; 5a6: ed 01 movw r28, r26 5a8: 89 a5 ldd r24, Y+41; 0x29 5aa: 9a a5 ldd r25, Y+42; 0x2a 5ac: 91 83 std Z+1, r25; 0x01 5ae: 80 83 st Z, r24 5b0: e0 91 e9 00 lds r30, 0x00E9 5b4: f0 91 ea 00 lds r31, 0x00EA *th_self_v = *th_head; movw r28, r26 5a8: 89 a5 ldd r24, Y+41; 0x29 5aa: 9a a5 ldd r25, Y+42; 0x2a 5ac: 91 83 std Z+1, r25; 0x01 5ae: 80 83 st Z, r24 5b0: 90 93 ea 00 sts 0x00EA, r25 5b4: 80 93 e9 00 sts 0x00E9, r24 5b8: e0 91 e9 00 lds r30, 0x00E9 5bc: f0 91 ea 00 lds r31, 0x00EA Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
singlskv 0 30 июля, 2009 Опубликовано 30 июля, 2009 · Жалоба Насчет одной из строк ошибся, она не выбрасывается, но вот это все таки вот так, И что Вас здесь удивило ? для volatile просто добавили необходимое сохранение... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amaora 25 30 июля, 2009 Опубликовано 30 июля, 2009 · Жалоба И что Вас здесь удивило ? для volatile просто добавили необходимое сохранение... А не volatile глобальные переменные сохранять не надо? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
singlskv 0 30 июля, 2009 Опубликовано 30 июля, 2009 · Жалоба А не volatile глобальные переменные сохранять не надо?Их нужно сохранять тогда когда действительно НУЖНО(по ходу проги), и не раньше этого... А Вы видимо на это как-то рассчитываете... Их нужно сохранять тогда когда действительно НУЖНО(по ходу проги), и не раньше этого... А Вы видимо на это как-то рассчитываете... O, кажись я телепатировал, видимо Вы думаете что квалификатор volatile обеспечивает атомарный доступ ? это не так... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amaora 25 30 июля, 2009 Опубликовано 30 июля, 2009 · Жалоба Их нужно сохранять тогда когда действительно НУЖНО(по ходу проги), и не раньше этого... А Вы видимо на это как-то рассчитываете... O, кажись я телепатировал, видимо Вы думаете что квалификатор volatile обеспечивает атомарный доступ ? это не так... Причем здесь атомарный доступ? запись в th_self не производится, не понятно почему. А сохранять действительно нужно, далее значение используется, и не только в следующих двух инструкциях. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sigmaN 0 31 июля, 2009 Опубликовано 31 июля, 2009 · Жалоба С такими конструкциями как у вас, volatile обычно не нужен. Тут что-то другое.... Во первых что за компилятор/процессор?(это чтоб народ сориентировался) Во вторых: не глядя в ассемблер, программа исполняется нормально?как и ожидалось? При серьёзных уровнях оптимизации компилятор волен достаточно сильно изменять код(вплоть до неузнаваемости для неопытного глаза) поэтому тот факт, что вы не увидели куска асм кода там и в таком виде, где и как вы его ожидали увидеть - не означает, что этот код вырезан вовсе. Нужно провести более детально отладку, скажем используя тестовый вывод в нужных местах через UART. Тогда будете точно знать что где и как присваивается или не присваивается. Смею предположить, что всё там нормально работает, и либо ошибка в другом совсем, либо её вообще нет :) __attribute__ ((__noreturn__, __naked__)); Это что-то GNUсное? Мне не известна суть этих атрибутов...это не может повлиять на поведение компилятора? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 31 июля, 2009 Опубликовано 31 июля, 2009 · Жалоба если есть много мест где происходит только чтение, а запись асинхронно в другом месте. А здесь без volatile может не получиться. *th_head = (*th_head)->next; // это было вырезано компилятором *th_self_v = *th_head; // это тоже было, теперь нет Что Вас удивляет? Не volatile *th_head выброшен как некрасивое излишество - выражение упрощено. Причем *th_self_v = *th_head = (*th_head)->next; гораздо более понятная конструкция. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xvr 12 31 июля, 2009 Опубликовано 31 июля, 2009 · Жалоба Вот тот код, static void thread_restore_helper() __attribute__ ((__noreturn__, __naked__)); struct thread **th_head; struct thread * volatile * th_self_v = &th_self; if (likely(*th_head)) { interrupts_disable(); *th_head = (*th_head)->next; // это было вырезано компилятором *th_self_v = *th_head; // это тоже было, теперь нет thread_restore_helper(); } Тут volatile не нужен. Строка *th_head = (*th_head)->next; должна быть отработана компилятором (выкидывать он ее не должен). Точнее запись в *th_head он должен сделать, а вот читать *th_head для выделения next он скорее всего не будет th_head надо записать, но при этом его не надо три раза читать.Так и получится Приведите полный код (и ассемблер) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amaora 25 31 июля, 2009 Опубликовано 31 июля, 2009 · Жалоба Копилятор GCC, были проблемы с тем, что компилятор видимо расчитывал на возрат из thread_regs_restore() при -O2 оптмизации, поэтому обернул в функцию с атрибутом noreturn. Вот код полностью, struct thread *th_self; /* running thread */ struct thread *th_run[CONFIG_PRIORITIES_NUMBER]; static struct thread *th_sleep; static uint16_t tov; static void thread_relax() { idle_go(); } static void thread_restore_helper() __attribute__ ((__noreturn__, __naked__)); static void thread_restore_helper() { thread_regs_restore(); for (;;); } void thread_global_shedule() { struct thread * th_temp; struct thread ** th_head; struct thread * volatile * th_self_v = &th_self; uint8_t tqu; uint16_t tdelta; int i; th_self = NULL; tqu = CONFIG_SHEDULE_TQUANT; do { tdelta = (uint16_t) timer_read(); timer_setup(tqu); interrupts_enable(); if (likely(th_sleep)) { tdelta += tov; tov = 0; if (th_sleep->th_tval > tdelta) { th_sleep->th_tval -= tdelta; } else { tov = tdelta - th_sleep->th_tval; th_temp = th_sleep->next; interrupts_disable(); TH_INSERT(th_sleep); interrupts_enable(); th_sleep = th_temp; } } i = (CONFIG_PRIORITIES_NUMBER - 1); do { th_head = th_run + (i--); if (likely(*th_head)) { interrupts_disable(); *th_head = (*th_head)->next; th_self = *th_head; thread_restore_helper(); } } while (i >= 0); dbg_write(0xff); thread_relax(); } while (1); } дизасм, 00000576 <thread_global_shedule>: 576: 10 92 ea 00 sts 0x00EA, r1 57a: 10 92 e9 00 sts 0x00E9, r1 57e: 10 e4 ldi r17, 0x40 ; 64 580: 22 b7 in r18, 0x32 ; 50 582: 12 be out 0x32, r1 ; 50 584: 1c bf out 0x3c, r17 ; 60 586: 78 94 sei 588: c0 91 60 00 lds r28, 0x0060 58c: d0 91 61 00 lds r29, 0x0061 590: 20 97 sbiw r28, 0x00 ; 0 592: a1 f0 breq .+40 ; 0x5bc <thread_global_shedule+0x46> 594: 80 91 62 00 lds r24, 0x0062 598: 90 91 63 00 lds r25, 0x0063 59c: 82 0f add r24, r18 59e: 91 1d adc r25, r1 5a0: 10 92 63 00 sts 0x0063, r1 5a4: 10 92 62 00 sts 0x0062, r1 5a8: 2b a1 ldd r18, Y+35 ; 0x23 5aa: 3c a1 ldd r19, Y+36 ; 0x24 5ac: 82 17 cp r24, r18 5ae: 93 07 cpc r25, r19 5b0: 08 f0 brcs .+2 ; 0x5b4 <thread_global_shedule+0x3e> 5b2: 4f c0 rjmp .+158 ; 0x652 <thread_global_shedule+0xdc> 5b4: 28 1b sub r18, r24 5b6: 39 0b sbc r19, r25 5b8: 3c a3 std Y+36, r19 ; 0x24 5ba: 2b a3 std Y+35, r18 ; 0x23 5bc: 81 e0 ldi r24, 0x01 ; 1 5be: 90 e0 ldi r25, 0x00 ; 0 5c0: fc 01 movw r30, r24 5c2: ee 0f add r30, r30 5c4: ff 1f adc r31, r31 5c6: eb 51 subi r30, 0x1B ; 27 5c8: ff 4f sbci r31, 0xFF ; 255 5ca: a0 81 ld r26, Z 5cc: b1 81 ldd r27, Z+1 ; 0x01 5ce: 10 97 sbiw r26, 0x00 ; 0 5d0: 09 f4 brne .+2 ; 0x5d4 <thread_global_shedule+0x5e> 5d2: 3a c0 rjmp .+116 ; 0x648 <thread_global_shedule+0xd2> 5d4: f8 94 cli 5d6: ed 01 movw r28, r26 5d8: 89 a5 ldd r24, Y+41 ; 0x29 5da: 9a a5 ldd r25, Y+42 ; 0x2a 5dc: 91 83 std Z+1, r25 ; 0x01 5de: 80 83 st Z, r24 5e0: e0 91 e9 00 lds r30, 0x00E9 5e4: f0 91 ea 00 lds r31, 0x00EA 5e8: 00 a1 ldd r16, Z+32 ; 0x20 5ea: 0f bf out 0x3f, r16 ; 63 5ec: 01 a1 ldd r16, Z+33 ; 0x21 5ee: 12 a1 ldd r17, Z+34 ; 0x22 5f0: 0d bf out 0x3d, r16 ; 61 5f2: 1e bf out 0x3e, r17 ; 62 5f4: 06 8d ldd r16, Z+30 ; 0x1e 5f6: 17 8d ldd r17, Z+31 ; 0x1f 5f8: 00 93 5e 04 sts 0x045E, r16 5fc: 10 93 5f 04 sts 0x045F, r17 600: 01 90 ld r0, Z+ 602: 11 90 ld r1, Z+ 604: 21 90 ld r2, Z+ 606: 31 90 ld r3, Z+ 608: 41 90 ld r4, Z+ 60a: 51 90 ld r5, Z+ 60c: 61 90 ld r6, Z+ 60e: 71 90 ld r7, Z+ 610: 81 90 ld r8, Z+ 612: 91 90 ld r9, Z+ 614: a1 90 ld r10, Z+ 616: b1 90 ld r11, Z+ 618: c1 90 ld r12, Z+ 61a: d1 90 ld r13, Z+ 61c: e1 90 ld r14, Z+ 61e: f1 90 ld r15, Z+ 620: 01 91 ld r16, Z+ 622: 11 91 ld r17, Z+ 624: 21 91 ld r18, Z+ 626: 31 91 ld r19, Z+ 628: 41 91 ld r20, Z+ 62a: 51 91 ld r21, Z+ 62c: 61 91 ld r22, Z+ 62e: 71 91 ld r23, Z+ 630: 81 91 ld r24, Z+ 632: 91 91 ld r25, Z+ 634: a1 91 ld r26, Z+ 636: b1 91 ld r27, Z+ 638: c1 91 ld r28, Z+ 63a: d1 91 ld r29, Z+ 63c: e0 91 5e 04 lds r30, 0x045E 640: f0 91 5f 04 lds r31, 0x045F 644: 18 95 reti 646: ff cf rjmp .-2 ; 0x646 <thread_global_shedule+0xd0> 648: 01 97 sbiw r24, 0x01 ; 1 64a: 99 f5 brne .+102 ; 0x6b2 <thread_global_shedule+0x13c> 64c: 80 e0 ldi r24, 0x00 ; 0 64e: 90 e0 ldi r25, 0x00 ; 0 650: b7 cf rjmp .-146 ; 0x5c0 <thread_global_shedule+0x4a> 652: 82 1b sub r24, r18 654: 93 0b sbc r25, r19 656: 90 93 63 00 sts 0x0063, r25 65a: 80 93 62 00 sts 0x0062, r24 65e: 29 a5 ldd r18, Y+41 ; 0x29 660: 3a a5 ldd r19, Y+42 ; 0x2a 662: f8 94 cli 664: 8e a1 ldd r24, Y+38 ; 0x26 666: a8 2f mov r26, r24 668: b0 e0 ldi r27, 0x00 ; 0 66a: aa 0f add r26, r26 66c: bb 1f adc r27, r27 66e: ab 51 subi r26, 0x1B ; 27 670: bf 4f sbci r27, 0xFF ; 255 672: ed 91 ld r30, X+ 674: fc 91 ld r31, X 676: 11 97 sbiw r26, 0x01 ; 1 678: 30 97 sbiw r30, 0x00 ; 0 67a: 09 f1 breq .+66 ; 0x6be <thread_global_shedule+0x148> 67c: 81 a5 ldd r24, Z+41 ; 0x29 67e: 92 a5 ldd r25, Z+42 ; 0x2a 680: 9a a7 std Y+42, r25 ; 0x2a 682: 89 a7 std Y+41, r24 ; 0x29 684: ed 91 ld r30, X+ 686: fc 91 ld r31, X 688: 11 97 sbiw r26, 0x01 ; 1 68a: 01 a4 ldd r0, Z+41 ; 0x29 68c: f2 a5 ldd r31, Z+42 ; 0x2a 68e: e0 2d mov r30, r0 690: d0 a7 std Z+40, r29 ; 0x28 692: c7 a3 std Z+39, r28 ; 0x27 694: 8d 91 ld r24, X+ 696: 9c 91 ld r25, X 698: 11 97 sbiw r26, 0x01 ; 1 69a: 98 a7 std Y+40, r25 ; 0x28 69c: 8f a3 std Y+39, r24 ; 0x27 69e: ed 91 ld r30, X+ 6a0: fc 91 ld r31, X 6a2: d2 a7 std Z+42, r29 ; 0x2a 6a4: c1 a7 std Z+41, r28 ; 0x29 6a6: 78 94 sei 6a8: 30 93 61 00 sts 0x0061, r19 6ac: 20 93 60 00 sts 0x0060, r18 6b0: 85 cf rjmp .-246 ; 0x5bc <thread_global_shedule+0x46> 6b2: 8f ef ldi r24, 0xFF ; 255 6b4: 0e 94 d6 04 call 0x9ac ; 0x9ac <dbg_write> 6b8: 0e 94 ab 03 call 0x756 ; 0x756 <idle_go> 6bc: 61 cf rjmp .-318 ; 0x580 <thread_global_shedule+0xa> 6be: 11 96 adiw r26, 0x01 ; 1 6c0: dc 93 st X, r29 6c2: ce 93 st -X, r28 6c4: d8 a7 std Y+40, r29 ; 0x28 6c6: cf a3 std Y+39, r28 ; 0x27 6c8: ed 91 ld r30, X+ 6ca: fc 91 ld r31, X 6cc: f2 a7 std Z+42, r31 ; 0x2a 6ce: e1 a7 std Z+41, r30 ; 0x29 6d0: ea cf rjmp .-44 ; 0x6a6 <thread_global_shedule+0x130> теперь запись производиться в *th_self_v diff --git a/thread.c.cp b/thread.c index 9e9d22b..6a0f9f5 100644 --- a/thread.c.cp +++ b/thread.c @@ -42,7 +42,7 @@ void thread_global_shedule() uint16_t tdelta; int i; - th_self = NULL; + *th_self_v = NULL; tqu = CONFIG_SHEDULE_TQUANT; do { @@ -77,7 +77,7 @@ void thread_global_shedule() if (likely(*th_head)) { interrupts_disable(); *th_head = (*th_head)->next; - th_self = *th_head; + *th_self_v = *th_head; thread_restore_helper(); } } дизасм, 00000576 <thread_global_shedule>: 576: 10 92 ea 00 sts 0x00EA, r1 57a: 10 92 e9 00 sts 0x00E9, r1 57e: 10 e4 ldi r17, 0x40 ; 64 580: 22 b7 in r18, 0x32 ; 50 582: 12 be out 0x32, r1 ; 50 584: 1c bf out 0x3c, r17 ; 60 586: 78 94 sei 588: c0 91 60 00 lds r28, 0x0060 58c: d0 91 61 00 lds r29, 0x0061 590: 20 97 sbiw r28, 0x00 ; 0 592: a1 f0 breq .+40 ; 0x5bc <thread_global_shedule+0x46> 594: 80 91 62 00 lds r24, 0x0062 598: 90 91 63 00 lds r25, 0x0063 59c: 82 0f add r24, r18 59e: 91 1d adc r25, r1 5a0: 10 92 63 00 sts 0x0063, r1 5a4: 10 92 62 00 sts 0x0062, r1 5a8: 2b a1 ldd r18, Y+35 ; 0x23 5aa: 3c a1 ldd r19, Y+36 ; 0x24 5ac: 82 17 cp r24, r18 5ae: 93 07 cpc r25, r19 5b0: 08 f0 brcs .+2 ; 0x5b4 <thread_global_shedule+0x3e> 5b2: 53 c0 rjmp .+166 ; 0x65a <thread_global_shedule+0xe4> 5b4: 28 1b sub r18, r24 5b6: 39 0b sbc r19, r25 5b8: 3c a3 std Y+36, r19 ; 0x24 5ba: 2b a3 std Y+35, r18 ; 0x23 5bc: 81 e0 ldi r24, 0x01 ; 1 5be: 90 e0 ldi r25, 0x00 ; 0 5c0: fc 01 movw r30, r24 5c2: ee 0f add r30, r30 5c4: ff 1f adc r31, r31 5c6: eb 51 subi r30, 0x1B ; 27 5c8: ff 4f sbci r31, 0xFF ; 255 5ca: a0 81 ld r26, Z 5cc: b1 81 ldd r27, Z+1 ; 0x01 5ce: 10 97 sbiw r26, 0x00 ; 0 5d0: 09 f4 brne .+2 ; 0x5d4 <thread_global_shedule+0x5e> 5d2: 3e c0 rjmp .+124 ; 0x650 <thread_global_shedule+0xda> 5d4: f8 94 cli 5d6: ed 01 movw r28, r26 5d8: 89 a5 ldd r24, Y+41 ; 0x29 5da: 9a a5 ldd r25, Y+42 ; 0x2a 5dc: 91 83 std Z+1, r25 ; 0x01 5de: 80 83 st Z, r24 5e0: 90 93 ea 00 sts 0x00EA, r25 5e4: 80 93 e9 00 sts 0x00E9, r24 5e8: e0 91 e9 00 lds r30, 0x00E9 5ec: f0 91 ea 00 lds r31, 0x00EA 5f0: 00 a1 ldd r16, Z+32 ; 0x20 5f2: 0f bf out 0x3f, r16 ; 63 5f4: 01 a1 ldd r16, Z+33 ; 0x21 5f6: 12 a1 ldd r17, Z+34 ; 0x22 5f8: 0d bf out 0x3d, r16 ; 61 5fa: 1e bf out 0x3e, r17 ; 62 5fc: 06 8d ldd r16, Z+30 ; 0x1e 5fe: 17 8d ldd r17, Z+31 ; 0x1f 600: 00 93 5e 04 sts 0x045E, r16 604: 10 93 5f 04 sts 0x045F, r17 608: 01 90 ld r0, Z+ 60a: 11 90 ld r1, Z+ 60c: 21 90 ld r2, Z+ 60e: 31 90 ld r3, Z+ 610: 41 90 ld r4, Z+ 612: 51 90 ld r5, Z+ 614: 61 90 ld r6, Z+ 616: 71 90 ld r7, Z+ 618: 81 90 ld r8, Z+ 61a: 91 90 ld r9, Z+ 61c: a1 90 ld r10, Z+ 61e: b1 90 ld r11, Z+ 620: c1 90 ld r12, Z+ 622: d1 90 ld r13, Z+ 624: e1 90 ld r14, Z+ 626: f1 90 ld r15, Z+ 628: 01 91 ld r16, Z+ 62a: 11 91 ld r17, Z+ 62c: 21 91 ld r18, Z+ 62e: 31 91 ld r19, Z+ 630: 41 91 ld r20, Z+ 632: 51 91 ld r21, Z+ 634: 61 91 ld r22, Z+ 636: 71 91 ld r23, Z+ 638: 81 91 ld r24, Z+ 63a: 91 91 ld r25, Z+ 63c: a1 91 ld r26, Z+ 63e: b1 91 ld r27, Z+ 640: c1 91 ld r28, Z+ 642: d1 91 ld r29, Z+ 644: e0 91 5e 04 lds r30, 0x045E 648: f0 91 5f 04 lds r31, 0x045F 64c: 18 95 reti 64e: ff cf rjmp .-2 ; 0x64e <thread_global_shedule+0xd8> 650: 01 97 sbiw r24, 0x01 ; 1 652: 99 f5 brne .+102 ; 0x6ba <thread_global_shedule+0x144> 654: 80 e0 ldi r24, 0x00 ; 0 656: 90 e0 ldi r25, 0x00 ; 0 658: b3 cf rjmp .-154 ; 0x5c0 <thread_global_shedule+0x4a> 65a: 82 1b sub r24, r18 65c: 93 0b sbc r25, r19 65e: 90 93 63 00 sts 0x0063, r25 662: 80 93 62 00 sts 0x0062, r24 666: 29 a5 ldd r18, Y+41 ; 0x29 668: 3a a5 ldd r19, Y+42 ; 0x2a 66a: f8 94 cli 66c: 8e a1 ldd r24, Y+38 ; 0x26 66e: a8 2f mov r26, r24 670: b0 e0 ldi r27, 0x00 ; 0 672: aa 0f add r26, r26 674: bb 1f adc r27, r27 676: ab 51 subi r26, 0x1B ; 27 678: bf 4f sbci r27, 0xFF ; 255 67a: ed 91 ld r30, X+ 67c: fc 91 ld r31, X 67e: 11 97 sbiw r26, 0x01 ; 1 680: 30 97 sbiw r30, 0x00 ; 0 682: 09 f1 breq .+66 ; 0x6c6 <thread_global_shedule+0x150> 684: 81 a5 ldd r24, Z+41 ; 0x29 686: 92 a5 ldd r25, Z+42 ; 0x2a 688: 9a a7 std Y+42, r25 ; 0x2a 68a: 89 a7 std Y+41, r24 ; 0x29 68c: ed 91 ld r30, X+ 68e: fc 91 ld r31, X 690: 11 97 sbiw r26, 0x01 ; 1 692: 01 a4 ldd r0, Z+41 ; 0x29 694: f2 a5 ldd r31, Z+42 ; 0x2a 696: e0 2d mov r30, r0 698: d0 a7 std Z+40, r29 ; 0x28 69a: c7 a3 std Z+39, r28 ; 0x27 69c: 8d 91 ld r24, X+ 69e: 9c 91 ld r25, X 6a0: 11 97 sbiw r26, 0x01 ; 1 6a2: 98 a7 std Y+40, r25 ; 0x28 6a4: 8f a3 std Y+39, r24 ; 0x27 6a6: ed 91 ld r30, X+ 6a8: fc 91 ld r31, X 6aa: d2 a7 std Z+42, r29 ; 0x2a 6ac: c1 a7 std Z+41, r28 ; 0x29 6ae: 78 94 sei 6b0: 30 93 61 00 sts 0x0061, r19 6b4: 20 93 60 00 sts 0x0060, r18 6b8: 81 cf rjmp .-254 ; 0x5bc <thread_global_shedule+0x46> 6ba: 8f ef ldi r24, 0xFF ; 255 6bc: 0e 94 da 04 call 0x9b4 ; 0x9b4 <dbg_write> 6c0: 0e 94 af 03 call 0x75e ; 0x75e <idle_go> 6c4: 5d cf rjmp .-326 ; 0x580 <thread_global_shedule+0xa> 6c6: 11 96 adiw r26, 0x01 ; 1 6c8: dc 93 st X, r29 6ca: ce 93 st -X, r28 6cc: d8 a7 std Y+40, r29 ; 0x28 6ce: cf a3 std Y+39, r28 ; 0x27 6d0: ed 91 ld r30, X+ 6d2: fc 91 ld r31, X 6d4: f2 a7 std Z+42, r31 ; 0x2a 6d6: e1 a7 std Z+41, r30 ; 0x29 6d8: ea cf rjmp .-44 ; 0x6ae <thread_global_shedule+0x138> не понимаю почему это происходит. Исходный вопрос был о том как попроще писать следующий код, так чтобы он работал и не было лишних перечитываний, uint8_t buff[16]; volatile uint8_t rd, wr; uint8_t read() { uint8_t val; while (rd == wr); // не плохо было бы только здесь указать, что есть volatile чтение, а с переменных квалификатор снять val = buff[rd]; rd = (rd + 1) & 0x0f; return val; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться