#ifndef _TYPES_H_ #define _TYPES_H_ /* --- 30/08/18 - данный говнокод был закоментирован, т.к. не используется...и слава богу, что не используется... typedef struct _FLAG_PROTECTED // FLAG_PROTECTED - так назваемый защищенный флаг { // Пусть имеется флаг, который могут модифицировать два потока unsigned char bProtected: 1; // Один поток устанавливает флаг, информируя о том, что произошло некое событие unsigned char cFlags : 7; // Другой поток сбрасывает флаг, информируя о том, что он обнаружил, что флаг установлен и, соовтественно, знает о событии int irq; //irq id } FLAG_PROTECTED; // Защищенный флаг создан для этих целей. Первый поток - основной main() // Второй поток - прерывание. Пусть основной поток использует функцию, которая устанавливает флаг события // Так как функция сделает своё действие не атомарно, соответственно, флаг установит не атомарно, // возможно не выполнив до конца все действия. Как только функция установила флаг, уже не гарантируется, что // флаг будет установлен по выходу из функции, так как в любой момент может произойти прервание, и второй поток // (прерывание) сбросит его и выполнит сооветсвующие действия. Чтобы этого избежать, следует защитить флаг от модификации // до тех пор, пока это необходимо. Основной поток должен вызывать макрос SECURITY_FLAG_PROTECTED_MODIFY( *, #, % ), где * - переменная // типа FLAG_PROTECTED. Если переменная свободна ( не защищена ), соответсвующий бит # изменит значение на установленное в % // Как только станет известно, что больше незачем защищаять переменную, поток должен вызвать макрос SECURITY_FLAG_PROTECTED_RELEASE // Любой другой поток, даже этот же самый не сможет изменить флаг в переменной вызовом макроса SECURITY_FLAG_PROTECTED_MODIFY до тех пор, пока // не будет вызван макрос SECURITY_FLAG_PROTECTED_RELEASE(*). Причем вызывать SECURITY_FLAG_PROTECTED_RELEASE должен тот же поток, что и занял переменную */ #define rNVIC_ICSR (*((volatile unsigned int*)0xE000ED04)) #define CURRENT_CONTEXT ((rNVIC_ICSR & 0xFF)?((rNVIC_ICSR & 0xFF)-16):0) #define SECURITY_FLAG_PROTECTED_RELEASE(flag_protected_entry) { \ rICER0 = (1<=0 && (bit)<=6) ((flag_protected_entry).cFlags)|=(1<<(bit));\ } else\ {\ if((bit)>=0 && (bit)<=6) ((flag_protected_entry).cFlags)&=(~(1<<(bit)));\ }\ }\ rISER0 = (1<