types.h 4.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. #ifndef _TYPES_H_
  2. #define _TYPES_H_
  3. /* --- 30/08/18 - данный говнокод был закоментирован, т.к. не используется...и слава богу, что не используется...
  4. typedef struct _FLAG_PROTECTED // FLAG_PROTECTED - так назваемый защищенный флаг
  5. { // Пусть имеется флаг, который могут модифицировать два потока
  6. unsigned char bProtected: 1; // Один поток устанавливает флаг, информируя о том, что произошло некое событие
  7. unsigned char cFlags : 7; // Другой поток сбрасывает флаг, информируя о том, что он обнаружил, что флаг установлен и, соовтественно, знает о событии
  8. int irq; //irq id
  9. } FLAG_PROTECTED; // Защищенный флаг создан для этих целей. Первый поток - основной main()
  10. // Второй поток - прерывание. Пусть основной поток использует функцию, которая устанавливает флаг события
  11. // Так как функция сделает своё действие не атомарно, соответственно, флаг установит не атомарно,
  12. // возможно не выполнив до конца все действия. Как только функция установила флаг, уже не гарантируется, что
  13. // флаг будет установлен по выходу из функции, так как в любой момент может произойти прервание, и второй поток
  14. // (прерывание) сбросит его и выполнит сооветсвующие действия. Чтобы этого избежать, следует защитить флаг от модификации
  15. // до тех пор, пока это необходимо. Основной поток должен вызывать макрос SECURITY_FLAG_PROTECTED_MODIFY( *, #, % ), где * - переменная
  16. // типа FLAG_PROTECTED. Если переменная свободна ( не защищена ), соответсвующий бит # изменит значение на установленное в %
  17. // Как только станет известно, что больше незачем защищаять переменную, поток должен вызвать макрос SECURITY_FLAG_PROTECTED_RELEASE
  18. // Любой другой поток, даже этот же самый не сможет изменить флаг в переменной вызовом макроса SECURITY_FLAG_PROTECTED_MODIFY до тех пор, пока
  19. // не будет вызван макрос SECURITY_FLAG_PROTECTED_RELEASE(*). Причем вызывать SECURITY_FLAG_PROTECTED_RELEASE должен тот же поток, что и занял переменную
  20. */
  21. #define rNVIC_ICSR (*((volatile unsigned int*)0xE000ED04))
  22. #define CURRENT_CONTEXT ((rNVIC_ICSR & 0xFF)?((rNVIC_ICSR & 0xFF)-16):0)
  23. #define SECURITY_FLAG_PROTECTED_RELEASE(flag_protected_entry) { \
  24. rICER0 = (1<<ICE_USB); \
  25. int cur_context = CURRENT_CONTEXT; /* volatile==volatile нельзя*/ \
  26. if((flag_protected_entry).bProtected && (cur_context==(flag_protected_entry).irq)) \
  27. (flag_protected_entry).bProtected=0; \
  28. rISER0 = (1<<ICE_USB); }
  29. #define SECURITY_FLAG_PROTECTED_MODIFY(flag_protected_entry, bit, value) {\
  30. rICER0 = (1<<ICE_USB);\
  31. if(!(flag_protected_entry).bProtected)\
  32. { (flag_protected_entry).bProtected = 1;\
  33. (flag_protected_entry).irq = CURRENT_CONTEXT;\
  34. if(value)\
  35. {\
  36. if((bit)>=0 && (bit)<=6) ((flag_protected_entry).cFlags)|=(1<<(bit));\
  37. } else\
  38. {\
  39. if((bit)>=0 && (bit)<=6) ((flag_protected_entry).cFlags)&=(~(1<<(bit)));\
  40. }\
  41. }\
  42. rISER0 = (1<<ICE_USB);}
  43. #endif