| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 |
- #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<<ICE_USB); \
- int cur_context = CURRENT_CONTEXT; /* volatile==volatile нельзя*/ \
- if((flag_protected_entry).bProtected && (cur_context==(flag_protected_entry).irq)) \
- (flag_protected_entry).bProtected=0; \
- rISER0 = (1<<ICE_USB); }
-
-
- #define SECURITY_FLAG_PROTECTED_MODIFY(flag_protected_entry, bit, value) {\
- rICER0 = (1<<ICE_USB);\
- if(!(flag_protected_entry).bProtected)\
- { (flag_protected_entry).bProtected = 1;\
- (flag_protected_entry).irq = CURRENT_CONTEXT;\
- if(value)\
- {\
- if((bit)>=0 && (bit)<=6) ((flag_protected_entry).cFlags)|=(1<<(bit));\
- } else\
- {\
- if((bit)>=0 && (bit)<=6) ((flag_protected_entry).cFlags)&=(~(1<<(bit)));\
- }\
- }\
- rISER0 = (1<<ICE_USB);}
-
- #endif
|