rseq.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. #include "core/config.h"
  2. #if CONFIG_AUTOMAT_MODE || CONFIG_LEDS
  3. #define ROUTINE_SEQUENCE_AUTOMAT_C
  4. #include "rseq.h"
  5. //------------------------------------------------------------------------------
  6. #define NULL ((void*)0)
  7. #define NULL_Routine ((fRoutine_t*)NULL)
  8. //------------------------------------------------------------------------------
  9. bool rsa_sequence_init( sRoutineSequence_t * pSeq, void * arg, fRoutine_t ** papfRoutineList, uint32_t size );
  10. bool rsa_sequence_insert_routine( sRoutineSequence_t * pSeq, fRoutine_t * routine );
  11. bool rsa_sequence_remove_routine( sRoutineSequence_t * pSeq );
  12. bool rsa_sequence_call( sRoutineSequence_t * pSeq );
  13. bool rsa_sequence_reset( sRoutineSequence_t * pSeq );
  14. bool rsa_sequence_clear( sRoutineSequence_t * pSeq );
  15. #if RSA_USE_LOCKERS > 0
  16. bool rsa_sequence_iinsert_routine( sRoutineSequence_t * pSeq, fRoutine_t * routine );
  17. bool rsa_sequence_iremove_routine( sRoutineSequence_t * pSeq );
  18. bool rsa_sequence_icall( sRoutineSequence_t * pSeq );
  19. bool rsa_sequence_ireset( sRoutineSequence_t * pSeq );
  20. bool rsa_sequence_iclear( sRoutineSequence_t * pSeq );
  21. #endif
  22. //------------------------------------------------------------------------------
  23. static bool rsa_stub_locker( void * arg )
  24. {
  25. return true;
  26. }
  27. //------------------------------------------------------------------------------
  28. // rsa_sequence_init()
  29. // Initialize sRoutineSequence_t before any operations
  30. // Params:
  31. // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be initialized
  32. // * IN [ void * ] @arg - an user argument to be passed into each routine
  33. // * IN [ fRoutine_t **] @papfRoutineList - the routine list to hold the values
  34. // * IN [ uint32_t ] @size - the size of routine list array @papfRoutineList
  35. // Returns:
  36. // [ bool ], result of operation, true = success, false = error
  37. bool rsa_sequence_init( sRoutineSequence_t * pSeq, void * arg, fRoutine_t ** papfRoutineList, uint32_t size )
  38. {
  39. #if RSA_STRICT_CHECKS > 0
  40. if( NULL == pSeq || NULL == papfRoutineList || 0 == size )
  41. return false;
  42. #endif
  43. pSeq->count = 0;
  44. pSeq->idx = 0;
  45. pSeq->arg = arg;
  46. pSeq->papfRoutineList = papfRoutineList;
  47. pSeq->size = size;
  48. #if RSA_USE_LOCKERS > 0
  49. pSeq->fLocker = rsa_stub_locker;
  50. pSeq->fUnlocker = rsa_stub_locker;
  51. #endif
  52. return true;
  53. }
  54. //------------------------------------------------------------------------------
  55. #if RSA_USE_LOCKERS > 0
  56. // rsa_sequence_setlockers()
  57. // Specifies a special Lock/Unlock function to be used during all procedures
  58. // Params:
  59. // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be initialized
  60. // * IN [ fRoutine_t * ] @fLocker - a function to be used to lock the object @pSeq
  61. // * IN [ fRoutine_t * ] @fUnlocker - a function to be used to unlock the object @pSeq
  62. // Returns:
  63. // [ bool ], result of operation, true = success, false = error
  64. bool rsa_sequence_setlockers( sRoutineSequence_t * pSeq, fRoutine_t * fLocker, fRoutine_t * fUnlocker )
  65. {
  66. #if RSA_STRICT_CHECKS > 0
  67. if( NULL == pSeq || NULL == fLocker || NULL == fUnlocker )
  68. return false;
  69. #endif
  70. pSeq->fLocker = fLocker;
  71. pSeq->fUnlocker = fUnlocker;
  72. return true;
  73. }
  74. #endif
  75. // -----------------------------------------------------------------------------
  76. // rsa_sequence_iinsert_routine()
  77. // Inserts a routine into the routine sequence without locking
  78. // Params:
  79. // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified
  80. // * IN [ fRoutine_t * ] @routine - a routine to be inserted
  81. // Returns:
  82. // [ bool ], result of operation, true = success, false = error
  83. #if RSA_USE_LOCKERS > 0
  84. bool rsa_sequence_iinsert_routine( sRoutineSequence_t * pSeq, fRoutine_t * routine )
  85. #else
  86. bool rsa_sequence_insert_routine( sRoutineSequence_t * pSeq, fRoutine_t * routine )
  87. #endif
  88. {
  89. #if RSA_STRICT_CHECKS > 0
  90. if( NULL == pSeq || NULL == routine )
  91. return false;
  92. #endif
  93. if( pSeq->count < pSeq->size )
  94. {
  95. pSeq->papfRoutineList[ pSeq->count++ ] = routine;
  96. return true;
  97. }
  98. return false;
  99. }
  100. // -----------------------------------------------------------------------------
  101. #if RSA_USE_LOCKERS > 0
  102. // rsa_sequence_insert_routine()
  103. // Inserts a routine into the routine sequence with locking
  104. // Params:
  105. // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified
  106. // * IN [ fRoutine_t * ] @routine - a routine to be inserted
  107. // Returns:
  108. // [ bool ], result of operation, true = success, false = error
  109. bool rsa_sequence_insert_routine( sRoutineSequence_t * pSeq, fRoutine_t * routine )
  110. {
  111. #if RSA_STRICT_CHECKS > 0
  112. if( NULL == pSeq || NULL == routine )
  113. return false;
  114. if( NULL == pSeq->fLocker || NULL == pSeq->fUnlocker )
  115. {
  116. return false;
  117. }
  118. #endif
  119. bool result = false;
  120. if( pSeq->fLocker( pSeq ) )
  121. {
  122. result = rsa_sequence_iinsert_routine( pSeq, routine );
  123. pSeq->fUnlocker( pSeq );
  124. }
  125. return result;
  126. }
  127. #endif
  128. // -----------------------------------------------------------------------------
  129. // rsa_sequence_iskip_routine()
  130. // Skips the current routine into the routine sequence without locking
  131. // Params:
  132. // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified
  133. // Returns:
  134. // [ bool ], result of operation, true = success, false = error
  135. #if RSA_USE_LOCKERS > 0
  136. bool rsa_sequence_iskip_routine( sRoutineSequence_t * pSeq )
  137. #else
  138. bool rsa_sequence_skip_routine( sRoutineSequence_t * pSeq )
  139. #endif
  140. {
  141. #if RSA_STRICT_CHECKS > 0
  142. if( NULL == pSeq )
  143. return false;
  144. #endif
  145. if( pSeq->idx + 1 < pSeq->count )
  146. {
  147. pSeq->idx++;
  148. return true;
  149. }
  150. return false;
  151. }
  152. // -----------------------------------------------------------------------------
  153. #if RSA_USE_LOCKERS > 0
  154. // rsa_sequence_skip_routine()
  155. // Skips the current routine into the routine sequence with locking
  156. // Params:
  157. // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified
  158. // Returns:
  159. // [ bool ], result of operation, true = success, false = error
  160. bool rsa_sequence_skip_routine( sRoutineSequence_t * pSeq )
  161. {
  162. #if RSA_STRICT_CHECKS > 0
  163. if( NULL == pSeq )
  164. return false;
  165. if( NULL == pSeq->fLocker || NULL == pSeq->fUnlocker )
  166. {
  167. return false;
  168. }
  169. #endif
  170. bool result = false;
  171. if( pSeq->fLocker( pSeq ) )
  172. {
  173. result = rsa_sequence_iskip_routine( pSeq );
  174. pSeq->fUnlocker( pSeq );
  175. }
  176. return result;
  177. }
  178. #endif
  179. // -----------------------------------------------------------------------------
  180. // rsa_sequence_iback_routine()
  181. // Rolls the routine sequence back and make the previous routine to be called without locking
  182. // Params:
  183. // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified
  184. // Returns:
  185. // [ bool ], result of operation, true = success, false = error
  186. #if RSA_USE_LOCKERS > 0
  187. bool rsa_sequence_iback_routine( sRoutineSequence_t * pSeq )
  188. #else
  189. bool rsa_sequence_back_routine( sRoutineSequence_t * pSeq )
  190. #endif
  191. {
  192. #if RSA_STRICT_CHECKS > 0
  193. if( NULL == pSeq )
  194. return false;
  195. #endif
  196. if( pSeq->idx - 1 > 0 )
  197. {
  198. pSeq->idx--;
  199. return true;
  200. }
  201. return false;
  202. }
  203. // -----------------------------------------------------------------------------
  204. #if RSA_USE_LOCKERS > 0
  205. // rsa_sequence_back_routine()
  206. // Rolls the routine sequence back and make the previous routine to be called with locking
  207. // Params:
  208. // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified
  209. // Returns:
  210. // [ bool ], result of operation, true = success, false = error
  211. bool rsa_sequence_back_routine( sRoutineSequence_t * pSeq )
  212. {
  213. #if RSA_STRICT_CHECKS > 0
  214. if( NULL == pSeq )
  215. return false;
  216. if( NULL == pSeq->fLocker || NULL == pSeq->fUnlocker )
  217. {
  218. return false;
  219. }
  220. #endif
  221. bool result = false;
  222. if( pSeq->fLocker( pSeq ) )
  223. {
  224. result = rsa_sequence_iback_routine( pSeq );
  225. pSeq->fUnlocker( pSeq );
  226. }
  227. return result;
  228. }
  229. #endif
  230. // -----------------------------------------------------------------------------
  231. // rsa_sequence_iremove_routine()
  232. // Removes the lastest routine from the routine sequence without locking
  233. // Params:
  234. // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified
  235. // Returns:
  236. // [ bool ], result of operation, true = success, false = error
  237. #if RSA_USE_LOCKERS > 0
  238. bool rsa_sequence_iremove_routine( sRoutineSequence_t * pSeq )
  239. #else
  240. bool rsa_sequence_remove_routine( sRoutineSequence_t * pSeq )
  241. #endif
  242. {
  243. #if RSA_STRICT_CHECKS > 0
  244. if( NULL == pSeq )
  245. return false;
  246. #endif
  247. if( pSeq->count > 0 )
  248. {
  249. pSeq->papfRoutineList[ --pSeq->count ] = NULL_Routine;
  250. return true;
  251. }
  252. return false;
  253. }
  254. // -----------------------------------------------------------------------------
  255. #if RSA_USE_LOCKERS > 0
  256. // rsa_sequence_remove_routine()
  257. // Removes the lastest routine from the routine sequence
  258. // Params:
  259. // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified
  260. // Returns:
  261. // [ bool ], result of operation, true = success, false = error
  262. bool rsa_sequence_remove_routine( sRoutineSequence_t * pSeq )
  263. {
  264. #if RSA_STRICT_CHECKS > 0
  265. if( NULL == pSeq )
  266. return false;
  267. if( NULL == pSeq->fLocker || NULL == pSeq->fUnlocker )
  268. {
  269. return false;
  270. }
  271. #endif
  272. bool result = false;
  273. if( pSeq->fLocker( pSeq ) )
  274. {
  275. result = rsa_sequence_iremove_routine( pSeq );
  276. pSeq->fUnlocker( pSeq );
  277. }
  278. return result;
  279. }
  280. #endif
  281. // -----------------------------------------------------------------------------
  282. // rsa_sequence_icall()
  283. // Implements an ordinar call of the routines sequence without locking
  284. // Params:
  285. // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified
  286. // Returns:
  287. // [ bool ], end of sequence sign, true = sequence completed, false = sequence is in progress
  288. #if RSA_USE_LOCKERS > 0
  289. bool rsa_sequence_icall( sRoutineSequence_t * pSeq )
  290. #else
  291. bool rsa_sequence_call( sRoutineSequence_t * pSeq )
  292. #endif
  293. {
  294. #if RSA_STRICT_CHECKS > 0
  295. if( NULL == pSeq )
  296. return false;
  297. #endif
  298. if( (pSeq->count > 0) && (pSeq->idx < pSeq->count) )
  299. {
  300. if( pSeq->papfRoutineList[ pSeq->idx ]( pSeq->arg ) )
  301. {
  302. pSeq->idx++;
  303. }
  304. return ( pSeq->idx >= pSeq->count );
  305. }
  306. return true;
  307. }
  308. // -----------------------------------------------------------------------------
  309. #if RSA_USE_LOCKERS > 0
  310. // rsa_sequence_call()
  311. // Implements an ordinar call of the routines sequence with locking
  312. // Params:
  313. // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified
  314. // Returns:
  315. // [ bool ], end of sequence sign, true = sequence completed, false = sequence is in progress
  316. bool rsa_sequence_call( sRoutineSequence_t * pSeq )
  317. {
  318. #if RSA_STRICT_CHECKS > 0
  319. if( NULL == pSeq )
  320. return false;
  321. if( NULL == pSeq->fLocker || NULL == pSeq->fUnlocker )
  322. {
  323. return false;
  324. }
  325. #endif
  326. bool result = false;
  327. if( pSeq->fLocker( pSeq ) )
  328. {
  329. result = rsa_sequence_icall( pSeq );
  330. pSeq->fUnlocker( pSeq );
  331. }
  332. return result;
  333. }
  334. #endif
  335. // -----------------------------------------------------------------------------
  336. // rsa_sequence_ireset()
  337. // Resets the routines sequence and makes it to be restarted without locking
  338. // Params:
  339. // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified
  340. // Returns:
  341. // [ bool ], result of operation, true = success, false = error
  342. #if RSA_USE_LOCKERS > 0
  343. bool rsa_sequence_ireset( sRoutineSequence_t * pSeq )
  344. #else
  345. bool rsa_sequence_reset( sRoutineSequence_t * pSeq )
  346. #endif
  347. {
  348. #if RSA_STRICT_CHECKS > 0
  349. if( NULL == pSeq )
  350. return false;
  351. #endif
  352. pSeq->idx = 0;
  353. return true;
  354. }
  355. // -----------------------------------------------------------------------------
  356. #if RSA_USE_LOCKERS > 0
  357. // rsa_sequence_reset()
  358. // Resets the routines sequence and makes it to be restarted with locking
  359. // Params:
  360. // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified
  361. // Returns:
  362. // [ bool ], result of operation, true = success, false = error
  363. bool rsa_sequence_reset( sRoutineSequence_t * pSeq )
  364. {
  365. #if RSA_STRICT_CHECKS > 0
  366. if( NULL == pSeq )
  367. return false;
  368. if( NULL == pSeq->fLocker || NULL == pSeq->fUnlocker )
  369. {
  370. return false;
  371. }
  372. #endif
  373. bool result = false;
  374. if( pSeq->fLocker( pSeq ) )
  375. {
  376. result = rsa_sequence_ireset( pSeq );
  377. pSeq->fUnlocker( pSeq );
  378. }
  379. return result;
  380. }
  381. #endif
  382. // -----------------------------------------------------------------------------
  383. // rsa_sequence_iclear()
  384. // Clears all the routines in the sequence without locking
  385. // Params:
  386. // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified
  387. // Returns:
  388. // [ bool ], result of operation, true = success, false = error
  389. #if RSA_USE_LOCKERS > 0
  390. bool rsa_sequence_iclear( sRoutineSequence_t * pSeq )
  391. #else
  392. bool rsa_sequence_clear( sRoutineSequence_t * pSeq )
  393. #endif
  394. {
  395. #if RSA_STRICT_CHECKS > 0
  396. if( NULL == pSeq )
  397. return false;
  398. #endif
  399. pSeq->count = 0;
  400. pSeq->idx = 0;
  401. return true;
  402. }
  403. // -----------------------------------------------------------------------------
  404. #if RSA_USE_LOCKERS > 0
  405. // rsa_sequence_reset()
  406. // Clears all the routines in the sequence without locking
  407. // Params:
  408. // * IN/OUT [ sRoutineSequence_t ] @pSeq - the sequence to be modified
  409. // Returns:
  410. // [ bool ], result of operation, true = success, false = error
  411. bool rsa_sequence_clear( sRoutineSequence_t * pSeq )
  412. {
  413. #if RSA_STRICT_CHECKS > 0
  414. if( NULL == pSeq )
  415. return false;
  416. if( NULL == pSeq->fLocker || NULL == pSeq->fUnlocker )
  417. {
  418. return false;
  419. }
  420. #endif
  421. bool result = false;
  422. if( pSeq->fLocker( pSeq ) )
  423. {
  424. result = rsa_sequence_iclear( pSeq );
  425. pSeq->fUnlocker( pSeq );
  426. }
  427. return result;
  428. }
  429. #endif
  430. #endif