RKH
test_rkhfwk_rdygrp.c
Go to the documentation of this file.
1 /*
2  * --------------------------------------------------------------------------
3  *
4  * Framework RKH
5  * -------------
6  *
7  * State-machine framework for reactive embedded systems
8  *
9  * Copyright (C) 2010 Leandro Francucci.
10  * All rights reserved. Protected by international copyright laws.
11  *
12  *
13  * RKH is free software: you can redistribute it and/or modify it under the
14  * terms of the GNU General Public License as published by the Recycle Software
15  * Foundation, either version 3 of the License, or (at your option) any
16  * later version.
17  *
18  * RKH is distributed in the hope that it will be useful, but WITHOUT ANY
19  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
21  * more details.
22  *
23  * You should have received a copy of the GNU General Public License along
24  * with RKH, see copying.txt file.
25  *
26  * Contact information:
27  * RKH site: http://vortexmakes.com/que-es/
28  * RKH GitHub: https://github.com/vortexmakes/RKH
29  * RKH Sourceforge: https://sourceforge.net/projects/rkh-reactivesys/
30  * e-mail: lf@vortexmakes.com
31  * ---------------------------------------------------------------------------
32  */
33 
46 /* -------------------------- Development history -------------------------- */
47 /*
48  * 2018.08.07 LeFr v3.1.00 Initial version
49  */
50 
51 /* -------------------------------- Authors -------------------------------- */
52 /*
53  * LeFr Leandro Francucci lf@vortexmakes.com
54  */
55 
56 /* --------------------------------- Notes --------------------------------- */
57 /* ----------------------------- Include files ----------------------------- */
58 #include "unity.h"
59 #include "rkhfwk_rdygrp.h"
60 #include "Mock_rkhfwk_bittbl.h"
61 #include "Mock_rkhassert.h"
62 
63 /* ----------------------------- Local macros ------------------------------ */
64 /* ------------------------------- Constants ------------------------------- */
65 static const rui8_t bitMaskTbl[] =
66 {
67  0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
68 };
69 
70 static const rui8_t leastBitSetTbl[] =
71 {
72  0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x00 to 0x0F */
73  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x10 to 0x1F */
74  5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x20 to 0x2F */
75  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x30 to 0x3F */
76  6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x40 to 0x4F */
77  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x50 to 0x5F */
78  5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x60 to 0x6F */
79  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x70 to 0x7F */
80  7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x80 to 0x8F */
81  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x90 to 0x9F */
82  5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xA0 to 0xAF */
83  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xB0 to 0xBF */
84  6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xC0 to 0xCF */
85  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xD0 to 0xDF */
86  5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xE0 to 0xEF */
87  4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 /* 0xF0 to 0xFF */
88 };
89 
90 /* ---------------------------- Local data types --------------------------- */
91 typedef struct DerivedRdyCbArg DerivedRdyCbArg;
92 struct DerivedRdyCbArg
93 {
94  RdyCbArg base;
95  int cnt;
96 };
97 
98 /* ---------------------------- Global variables --------------------------- */
99 /* ---------------------------- Local variables ---------------------------- */
100 static RKHRdyGrp rdyTbl;
101 static DerivedRdyCbArg rdyCbArg;
102 static rui8_t prio[] = {0, 3, 9, 17, 27, 33, 41, 55, 63};
103 
104 /* ----------------------- Local function prototypes ----------------------- */
105 /* ---------------------------- Local functions ---------------------------- */
106 static void
107 MockAssertCallback(const char* const file, int line, int cmock_num_calls)
108 {
109  TEST_PASS();
110 }
111 
112 static void
113 rdyCb(RdyCbArg *arg)
114 {
115  TEST_ASSERT_EQUAL(prio[((DerivedRdyCbArg *)arg)->cnt++], arg->aoRdyPrio);
116 }
117 
118 /* ---------------------------- Global functions --------------------------- */
119 void
120 setUp(void)
121 {
122  Mock_rkhfwk_bittbl_Init();
123  Mock_rkhassert_Init();
124  rkh_rdygrp_init(&rdyTbl);
125 }
126 
127 void
128 tearDown(void)
129 {
130  Mock_rkhfwk_bittbl_Verify();
131  Mock_rkhfwk_bittbl_Destroy();
132  Mock_rkhassert_Verify();
133  Mock_rkhassert_Destroy();
134 }
135 
142 void
143 test_ClearAfterInit(void)
144 {
145  rbool_t result;
146 
147  result = rkh_rdygrp_isReady(&rdyTbl);
148  TEST_ASSERT_EQUAL(0, result);
149 }
150 
151 void
152 test_SetOneActiveObjectReady(void)
153 {
154  rbool_t result;
155  rui8_t prio = 1, resultPrio, column, row;
156 
157  column = prio >> 3;
158  row = prio & 7;
159  rkh_bittbl_getBitMask_ExpectAndReturn(column, bitMaskTbl[column]);
160  rkh_bittbl_getBitMask_ExpectAndReturn(row, bitMaskTbl[row]);
161 
162  rkh_rdygrp_setReady(&rdyTbl, prio);
163  result = rkh_rdygrp_isReady(&rdyTbl);
164  TEST_ASSERT_EQUAL(1, result);
165 
166  rkh_bittbl_getLeastBitSetPos_ExpectAndReturn(1, leastBitSetTbl[1]);
167  rkh_bittbl_getLeastBitSetPos_ExpectAndReturn(2, leastBitSetTbl[2]);
168  resultPrio = rkh_rdygrp_findHighest(&rdyTbl);
169  TEST_ASSERT_EQUAL(prio, resultPrio);
170 }
171 
172 void
173 test_SetMultipleActiveObjectsReady(void)
174 {
175  rui8_t prioA = 1, prioC = 0, prioB = 15, resultPrio, column, row;
176 
177  column = prioA >> 3;
178  row = prioA & 7;
179  rkh_bittbl_getBitMask_ExpectAndReturn(column, bitMaskTbl[column]);
180  rkh_bittbl_getBitMask_ExpectAndReturn(row, bitMaskTbl[row]);
181  rkh_rdygrp_setReady(&rdyTbl, prioA);
182 
183  column = prioB >> 3;
184  row = prioB & 7;
185  rkh_bittbl_getBitMask_ExpectAndReturn(column, bitMaskTbl[column]);
186  rkh_bittbl_getBitMask_ExpectAndReturn(row, bitMaskTbl[row]);
187  rkh_rdygrp_setReady(&rdyTbl, prioB);
188 
189  column = prioC >> 3;
190  row = prioC & 7;
191  rkh_bittbl_getBitMask_ExpectAndReturn(column, bitMaskTbl[column]);
192  rkh_bittbl_getBitMask_ExpectAndReturn(row, bitMaskTbl[row]);
193  rkh_rdygrp_setReady(&rdyTbl, prioC);
194 
195  rkh_bittbl_getLeastBitSetPos_ExpectAndReturn(3, leastBitSetTbl[3]);
196  rkh_bittbl_getLeastBitSetPos_ExpectAndReturn(3, leastBitSetTbl[3]);
197  resultPrio = rkh_rdygrp_findHighest(&rdyTbl);
198  TEST_ASSERT_EQUAL(prioC, resultPrio);
199 }
200 
201 void
202 test_SetOneActiveObjectUnready(void)
203 {
204  rbool_t result;
205  rui8_t prio = 1, resultPrio, column, row;
206 
207  column = prio >> 3;
208  row = prio & 7;
209  rkh_bittbl_getBitMask_ExpectAndReturn(column, bitMaskTbl[column]);
210  rkh_bittbl_getBitMask_ExpectAndReturn(row, bitMaskTbl[row]);
211 
212  rkh_rdygrp_setReady(&rdyTbl, prio);
213 
214  rkh_bittbl_getLeastBitSetPos_ExpectAndReturn(1, leastBitSetTbl[1]);
215  rkh_bittbl_getLeastBitSetPos_ExpectAndReturn(2, leastBitSetTbl[2]);
216  resultPrio = rkh_rdygrp_findHighest(&rdyTbl);
217  TEST_ASSERT_EQUAL(prio, resultPrio);
218 
219  rkh_bittbl_getBitMask_ExpectAndReturn(row, bitMaskTbl[row]);
220  rkh_bittbl_getBitMask_ExpectAndReturn(column, bitMaskTbl[column]);
221  rkh_rdygrp_setUnready(&rdyTbl, prio);
222  result = rkh_rdygrp_isReady(&rdyTbl);
223  TEST_ASSERT_EQUAL(0, result);
224 }
225 
226 void
227 test_SetMultipleActiveObjectsUnready(void)
228 {
229  rbool_t result;
230  rui8_t prioA = 1, prioC = 0, prioB = 15, column, row;
231 
232  column = prioA >> 3;
233  row = prioA & 7;
234  rkh_bittbl_getBitMask_ExpectAndReturn(column, bitMaskTbl[column]);
235  rkh_bittbl_getBitMask_ExpectAndReturn(row, bitMaskTbl[row]);
236  rkh_rdygrp_setReady(&rdyTbl, prioA);
237 
238  column = prioB >> 3;
239  row = prioB & 7;
240  rkh_bittbl_getBitMask_ExpectAndReturn(column, bitMaskTbl[column]);
241  rkh_bittbl_getBitMask_ExpectAndReturn(row, bitMaskTbl[row]);
242  rkh_rdygrp_setReady(&rdyTbl, prioB);
243 
244  column = prioC >> 3;
245  row = prioC & 7;
246  rkh_bittbl_getBitMask_ExpectAndReturn(column, bitMaskTbl[column]);
247  rkh_bittbl_getBitMask_ExpectAndReturn(row, bitMaskTbl[row]);
248  rkh_rdygrp_setReady(&rdyTbl, prioC);
249 
250  column = prioA >> 3;
251  row = prioA & 7;
252  rkh_bittbl_getBitMask_ExpectAndReturn(row, bitMaskTbl[row]);
253  rkh_rdygrp_setUnready(&rdyTbl, prioA);
254 
255  column = prioB >> 3;
256  row = prioB & 7;
257  rkh_bittbl_getBitMask_ExpectAndReturn(row, bitMaskTbl[row]);
258  rkh_bittbl_getBitMask_ExpectAndReturn(column, bitMaskTbl[column]);
259  rkh_rdygrp_setUnready(&rdyTbl, prioB);
260 
261  column = prioC >> 3;
262  row = prioC & 7;
263  rkh_bittbl_getBitMask_ExpectAndReturn(row, bitMaskTbl[row]);
264  rkh_bittbl_getBitMask_ExpectAndReturn(column, bitMaskTbl[column]);
265  rkh_rdygrp_setUnready(&rdyTbl, prioC);
266 
267  result = rkh_rdygrp_isReady(&rdyTbl);
268  TEST_ASSERT_EQUAL(0, result);
269 }
270 
271 void
272 test_Fails_InvalidActiveObjectOnSet(void)
273 {
274  rui8_t prio = RKH_CFG_FWK_MAX_SMA;
275 
276  rkh_assert_Expect("rkhfwk_rdygrp", 0);
277  rkh_assert_IgnoreArg_file();
278  rkh_assert_IgnoreArg_line();
279  rkh_assert_StubWithCallback(MockAssertCallback);
280 
281  rkh_rdygrp_setReady(&rdyTbl, prio);
282 }
283 
284 void
285 test_TraverseWithOneReadyActiveObject(void)
286 {
287  rui8_t nRdyAo, resultNRdyAo;
288 
289  rkh_bittbl_getBitMask_IgnoreAndReturn(bitMaskTbl[prio[0] >> 3]);
290  rkh_bittbl_getBitMask_IgnoreAndReturn(bitMaskTbl[prio[0] & 7]);
291 
292  rdyCbArg.cnt = 0;
293  nRdyAo = 1;
294  rkh_rdygrp_setReady(&rdyTbl, prio[0]);
295  resultNRdyAo = rkh_rdygrp_traverse(&rdyTbl, rdyCb, (RdyCbArg *)&rdyCbArg);
296  TEST_ASSERT_EQUAL(nRdyAo, resultNRdyAo);
297  TEST_ASSERT_EQUAL(nRdyAo, rdyCbArg.cnt);
298 }
299 
300 void
301 test_TraverseWithMultipleReadyActiveObject(void)
302 {
303  rui8_t nRdyAo, resultNRdyAo, ix;
304 
305  nRdyAo = 9;
306  for (ix = 0; ix < nRdyAo; ++ix)
307  {
308  rkh_bittbl_getBitMask_IgnoreAndReturn(bitMaskTbl[prio[ix] >> 3]);
309  rkh_bittbl_getBitMask_IgnoreAndReturn(bitMaskTbl[prio[ix] & 7]);
310  rkh_rdygrp_setReady(&rdyTbl, prio[ix]);
311  }
312 
313  rdyCbArg.cnt = 0;
314  resultNRdyAo = rkh_rdygrp_traverse(&rdyTbl, rdyCb, (RdyCbArg *)&rdyCbArg);
315  TEST_ASSERT_EQUAL(nRdyAo, resultNRdyAo);
316  TEST_ASSERT_EQUAL(nRdyAo, rdyCbArg.cnt);
317 }
318 
319 void
320 test_TraverseWithWithoutReadyActiveObject(void)
321 {
322  rui8_t nRdyAo, resultNRdyAo;
323 
324  rdyCbArg.cnt = 0;
325  nRdyAo = 0;
326  resultNRdyAo = rkh_rdygrp_traverse(&rdyTbl, rdyCb, (RdyCbArg *)&rdyCbArg);
327  TEST_ASSERT_EQUAL(nRdyAo, resultNRdyAo);
328  TEST_ASSERT_EQUAL(nRdyAo, rdyCbArg.cnt);
329 }
330 
336 /* ------------------------------ End of file ------------------------------ */
#define RKH_CFG_FWK_MAX_SMA
Specify the maximum number of state machine applications (SMA) to be used by the application (can be ...
Definition: rkhcfg.h:88
void rkh_rdygrp_setReady(RKHRdyGrp *const me, rui8_t prio)
Making an active object ready inserting it into the ready list.
rbool_t rkh_rdygrp_isReady(RKHRdyGrp *const me)
Evaluates to true if any active object is ready.
void rkh_rdygrp_setUnready(RKHRdyGrp *const me, rui8_t prio)
Removing an active object from the ready list.
rui8_t rkh_rdygrp_findHighest(RKHRdyGrp *const me)
Finding the highest priority active object ready.
rui8_t rkh_rdygrp_traverse(RKHRdyGrp *const me, void(*rdyCb)(RdyCbArg *), RdyCbArg *rdyCbArg)
Traverse a ready list to find the ready active objects and thus invoking a callback function.
void rkh_rdygrp_init(RKHRdyGrp *const me)
Initializes the ready mechanism for active objects.
SMA ready table.