В Примерах к китам, повсеместно для установка пинов вызывается что типа:
Код
IO1SET |= 0x00000001;
Как то раньше не задумывалься, пока глюку не словил, ножка "сама" прыгала в "1",
хорошо это было направления 485 и контроллер просто переставал отвечать оставаясь в передаче, тяжело было не заметить.
Проблема в том что операция не атомарная, и при наличии нескольких потоков, одновременно работающих с портом, в порт может быть выведена ерунда:
если после загрузки значения IOSET в регистр произойдет переключение потоков, в другом потоке будут сброшены битики, потом управление будет возвращено первому потоку, он установить сброшеные биты обратно в "1" (аналогично для IOCLR).
Решается проблема просто использованием
Код
IO1SET = 0x00000001
IO1CLR = 0x00000001
IO1CLR = 0x00000001
или помещением в критическую секцию. Тем более что
Код
IO1SET |= ..
бесмысленно, т.к. запись нуля ничего не меняет.вот как выглядет на асме:
Код
//IO1SET |= 0x1;
LDR R0, [PC, #+156]
LDR R1, [PC, #+152]
LDR R1, [R1, #+0]
ORRS R1, R1, #0x1
STR R1, [R0, #+0]
//IO1SET_bit.P0_1 = 1;
LDR R0, [PC, #+136]
LDR R1, [PC, #+132]
LDR R1, [R1, #+0]
ORRS R1, R1, #0x2
STR R1, [R0, #+0]
//IO1SET = 0x1;
LDR R0, [PC, #+116]
MOV R1, #+1
STR R1, [R0, #+0]
LDR R0, [PC, #+156]
LDR R1, [PC, #+152]
LDR R1, [R1, #+0]
ORRS R1, R1, #0x1
STR R1, [R0, #+0]
//IO1SET_bit.P0_1 = 1;
LDR R0, [PC, #+136]
LDR R1, [PC, #+132]
LDR R1, [R1, #+0]
ORRS R1, R1, #0x2
STR R1, [R0, #+0]
//IO1SET = 0x1;
LDR R0, [PC, #+116]
MOV R1, #+1
STR R1, [R0, #+0]