]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_MPU_Static_Simulator_Keil_GCC/Keil_Specific/RegTest.c
Update version number in readiness for V10.3.0 release. Sync SVN with reviewed releas...
[freertos] / FreeRTOS / Demo / CORTEX_MPU_Static_Simulator_Keil_GCC / Keil_Specific / RegTest.c
1 /*\r
2  * FreeRTOS Kernel V10.3.0\r
3  * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6  * this software and associated documentation files (the "Software"), to deal in\r
7  * the Software without restriction, including without limitation the rights to\r
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9  * the Software, and to permit persons to whom the Software is furnished to do so,\r
10  * subject to the following conditions:\r
11  *\r
12  * The above copyright notice and this permission notice shall be included in all\r
13  * copies or substantial portions of the Software.\r
14  *\r
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
21  *\r
22  * http://www.FreeRTOS.org\r
23  * http://aws.amazon.com/freertos\r
24  *\r
25  * 1 tab == 4 spaces!\r
26  */\r
27 \r
28 /* FreeRTOS includes. */\r
29 #include "FreeRTOS.h"\r
30 #include "queue.h"\r
31 #include "task.h"\r
32 \r
33 /*\r
34  * "Reg test" tasks - These fill the registers with known values, then check\r
35  * that each register maintains its expected value for the lifetime of the\r
36  * task.  Each task uses a different set of values.  The reg test tasks execute\r
37  * with a very low priority, so get preempted very frequently.  A register\r
38  * containing an unexpected value is indicative of an error in the context\r
39  * switching mechanism.\r
40  */\r
41 \r
42 void vRegTest1Implementation( void *pvParameters );\r
43 void vRegTest2Implementation( void *pvParameters );\r
44 void vRegTest3Implementation( void );\r
45 void vRegTest4Implementation( void );\r
46 \r
47 /*\r
48  * Used as an easy way of deleting a task from inline assembly.\r
49  */\r
50 extern void vMainDeleteMe( void ) __attribute__((noinline));\r
51 \r
52 /*\r
53  * Used by the first two reg test tasks and a software timer callback function\r
54  * to send messages to the check task.  The message just lets the check task\r
55  * know that the tasks and timer are still functioning correctly.  If a reg test\r
56  * task detects an error it will delete itself, and in so doing prevent itself\r
57  * from sending any more 'I'm Alive' messages to the check task.\r
58  */\r
59 extern void vMainSendImAlive( QueueHandle_t xHandle, uint32_t ulTaskNumber );\r
60 \r
61 /* The queue used to send a message to the check task. */\r
62 extern QueueHandle_t xGlobalScopeCheckQueue;\r
63 \r
64 /*-----------------------------------------------------------*/\r
65 \r
66 void vRegTest1Implementation( void *pvParameters )\r
67 {\r
68 /* This task is created in privileged mode so can access the file scope\r
69 queue variable.  Take a stack copy of this before the task is set into user\r
70 mode.  Once this task is in user mode the file scope queue variable will no\r
71 longer be accessible but the stack copy will. */\r
72 QueueHandle_t xQueue = xGlobalScopeCheckQueue;\r
73 const TickType_t xDelayTime = pdMS_TO_TICKS( 100UL );\r
74 \r
75         /* Now the queue handle has been obtained the task can switch to user\r
76         mode.  This is just one method of passing a handle into a protected\r
77         task, the other reg test task uses the task parameter instead. */\r
78         portSWITCH_TO_USER_MODE();\r
79 \r
80         /* First check that the parameter value is as expected. */\r
81         if( pvParameters != ( void * ) configREG_TEST_TASK_1_PARAMETER )\r
82         {\r
83                 /* Error detected.  Delete the task so it stops communicating with\r
84                 the check task. */\r
85                 vMainDeleteMe();\r
86         }\r
87 \r
88         for( ;; )\r
89         {\r
90                 #if defined ( __GNUC__ )\r
91                 {\r
92                         /* This task tests the kernel context switch mechanism by reading and\r
93                         writing directly to registers - which requires the test to be written\r
94                         in assembly code. */\r
95                         __asm volatile\r
96                         (\r
97                                 "               MOV     R4, #104                        \n" /* Set registers to a known value.  R0 to R1 are done in the loop below. */\r
98                                 "               MOV     R5, #105                        \n"\r
99                                 "               MOV     R6, #106                        \n"\r
100                                 "               MOV     R8, #108                        \n"\r
101                                 "               MOV     R9, #109                        \n"\r
102                                 "               MOV     R10, #110                       \n"\r
103                                 "               MOV     R11, #111                       \n"\r
104                                 "reg1loop:                                              \n"\r
105                                 "               MOV     R0, #100                        \n" /* Set the scratch registers to known values - done inside the loop as they get clobbered. */\r
106                                 "               MOV     R1, #101                        \n"\r
107                                 "               MOV     R2, #102                        \n"\r
108                                 "               MOV R3, #103                    \n"\r
109                                 "               MOV     R12, #112                       \n"\r
110                                 "               SVC #1                                  \n" /* Yield just to increase test coverage. */\r
111                                 "               CMP     R0, #100                        \n" /* Check all the registers still contain their expected values. */\r
112                                 "               BNE     vMainDeleteMe           \n" /* Value was not as expected, delete the task so it stops communicating with the check task. */\r
113                                 "               CMP     R1, #101                        \n"\r
114                                 "               BNE     vMainDeleteMe           \n"\r
115                                 "               CMP     R2, #102                        \n"\r
116                                 "               BNE     vMainDeleteMe           \n"\r
117                                 "               CMP R3, #103                    \n"\r
118                                 "               BNE     vMainDeleteMe           \n"\r
119                                 "               CMP     R4, #104                        \n"\r
120                                 "               BNE     vMainDeleteMe           \n"\r
121                                 "               CMP     R5, #105                        \n"\r
122                                 "               BNE     vMainDeleteMe           \n"\r
123                                 "               CMP     R6, #106                        \n"\r
124                                 "               BNE     vMainDeleteMe           \n"\r
125                                 "               CMP     R8, #108                        \n"\r
126                                 "               BNE     vMainDeleteMe           \n"\r
127                                 "               CMP     R9, #109                        \n"\r
128                                 "               BNE     vMainDeleteMe           \n"\r
129                                 "               CMP     R10, #110                       \n"\r
130                                 "               BNE     vMainDeleteMe           \n"\r
131                                 "               CMP     R11, #111                       \n"\r
132                                 "               BNE     vMainDeleteMe           \n"\r
133                                 "               CMP     R12, #112                       \n"\r
134                                 "               BNE     vMainDeleteMe           \n"\r
135                                 :::"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12"\r
136                         );\r
137                 }\r
138                 #endif /* __GNUC__ */\r
139 \r
140                 /* Send configREG_TEST_1_STILL_EXECUTING to the check task to indicate that this\r
141                 task is still functioning. */\r
142                 vMainSendImAlive( xQueue, configREG_TEST_1_STILL_EXECUTING );\r
143                 vTaskDelay( xDelayTime );\r
144 \r
145                 #if defined ( __GNUC__ )\r
146                 {\r
147                         /* Go back to check all the register values again. */\r
148                         __asm volatile( "               B reg1loop      " );\r
149                 }\r
150                 #endif /* __GNUC__ */\r
151         }\r
152 }\r
153 /*-----------------------------------------------------------*/\r
154 \r
155 void vRegTest2Implementation( void *pvParameters )\r
156 {\r
157 /* The queue handle is passed in as the task parameter.  This is one method of\r
158 passing data into a protected task, the other reg test task uses a different\r
159 method. */\r
160 QueueHandle_t xQueue = ( QueueHandle_t ) pvParameters;\r
161 const TickType_t xDelayTime = pdMS_TO_TICKS( 100UL );\r
162 \r
163         for( ;; )\r
164         {\r
165                 #if defined ( __GNUC__ )\r
166                 {\r
167                         /* This task tests the kernel context switch mechanism by reading and\r
168                         writing directly to registers - which requires the test to be written\r
169                         in assembly code. */\r
170                         __asm volatile\r
171                         (\r
172                                 "               MOV     R4, #4                          \n" /* Set registers to a known value.  R0 to R1 are done in the loop below. */\r
173                                 "               MOV     R5, #5                          \n"\r
174                                 "               MOV     R6, #6                          \n"\r
175                                 "               MOV     R8, #8                          \n" /* Frame pointer is omitted as it must not be changed. */\r
176                                 "               MOV     R9, #9                          \n"\r
177                                 "               MOV     R10, 10                         \n"\r
178                                 "               MOV     R11, #11                        \n"\r
179                                 "reg2loop:                                              \n"\r
180                                 "               MOV     R0, #13                         \n" /* Set the scratch registers to known values - done inside the loop as they get clobbered. */\r
181                                 "               MOV     R1, #1                          \n"\r
182                                 "               MOV     R2, #2                          \n"\r
183                                 "               MOV R3, #3                              \n"\r
184                                 "               MOV     R12, #12                        \n"\r
185                                 "               CMP     R0, #13                         \n" /* Check all the registers still contain their expected values. */\r
186                                 "               BNE     vMainDeleteMe           \n" /* Value was not as expected, delete the task so it stops communicating with the check task */\r
187                                 "               CMP     R1, #1                          \n"\r
188                                 "               BNE     vMainDeleteMe           \n"\r
189                                 "               CMP     R2, #2                          \n"\r
190                                 "               BNE     vMainDeleteMe           \n"\r
191                                 "               CMP R3, #3                              \n"\r
192                                 "               BNE     vMainDeleteMe           \n"\r
193                                 "               CMP     R4, #4                          \n"\r
194                                 "               BNE     vMainDeleteMe           \n"\r
195                                 "               CMP     R5, #5                          \n"\r
196                                 "               BNE     vMainDeleteMe           \n"\r
197                                 "               CMP     R6, #6                          \n"\r
198                                 "               BNE     vMainDeleteMe           \n"\r
199                                 "               CMP     R8, #8                          \n"\r
200                                 "               BNE     vMainDeleteMe           \n"\r
201                                 "               CMP     R9, #9                          \n"\r
202                                 "               BNE     vMainDeleteMe           \n"\r
203                                 "               CMP     R10, #10                        \n"\r
204                                 "               BNE     vMainDeleteMe           \n"\r
205                                 "               CMP     R11, #11                        \n"\r
206                                 "               BNE     vMainDeleteMe           \n"\r
207                                 "               CMP     R12, #12                        \n"\r
208                                 "               BNE     vMainDeleteMe           \n"\r
209                                 :::"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12"\r
210                         );\r
211                 }\r
212                 #endif /* __GNUC__ */\r
213 \r
214                 /* Send configREG_TEST_2_STILL_EXECUTING to the check task to indicate\r
215                 that this task is still functioning. */\r
216                 vMainSendImAlive( xQueue, configREG_TEST_2_STILL_EXECUTING );\r
217                 vTaskDelay( xDelayTime );\r
218 \r
219                 #if defined ( __GNUC__ )\r
220                 {\r
221                         /* Go back to check all the register values again. */\r
222                         __asm volatile( "               B reg2loop      " );\r
223                 }\r
224                 #endif /* __GNUC__ */\r
225         }\r
226 }\r
227 /*-----------------------------------------------------------*/\r
228 \r
229 __asm void vRegTest3Implementation( void )\r
230 {\r
231         extern pulRegTest3LoopCounter\r
232 \r
233         PRESERVE8\r
234 \r
235         /* Fill the core registers with known values. */\r
236         mov     r0, #100\r
237         mov     r1, #101\r
238         mov     r2, #102\r
239         mov     r3, #103\r
240         mov     r4, #104\r
241         mov     r5, #105\r
242         mov     r6, #106\r
243         mov     r7, #107\r
244         mov     r8, #108\r
245         mov     r9, #109\r
246         mov     r10, #110\r
247         mov     r11, #111\r
248         mov     r12, #112\r
249 \r
250         /* Fill the VFP registers with known values. */\r
251         vmov    d0, r0, r1\r
252         vmov    d1, r2, r3\r
253         vmov    d2, r4, r5\r
254         vmov    d3, r6, r7\r
255         vmov    d4, r8, r9\r
256         vmov    d5, r10, r11\r
257         vmov    d6, r0, r1\r
258         vmov    d7, r2, r3\r
259         vmov    d8, r4, r5\r
260         vmov    d9, r6, r7\r
261         vmov    d10, r8, r9\r
262         vmov    d11, r10, r11\r
263         vmov    d12, r0, r1\r
264         vmov    d13, r2, r3\r
265         vmov    d14, r4, r5\r
266         vmov    d15, r6, r7\r
267 \r
268 reg1_loop\r
269 \r
270         /* Check all the VFP registers still contain the values set above.\r
271         First save registers that are clobbered by the test. */\r
272         push { r0-r1 }\r
273 \r
274         vmov    r0, r1, d0\r
275         cmp     r0, #100\r
276         bne     reg1_error_loopf\r
277         cmp     r1, #101\r
278         bne     reg1_error_loopf\r
279         vmov    r0, r1, d1\r
280         cmp     r0, #102\r
281         bne     reg1_error_loopf\r
282         cmp     r1, #103\r
283         bne     reg1_error_loopf\r
284         vmov    r0, r1, d2\r
285         cmp     r0, #104\r
286         bne     reg1_error_loopf\r
287         cmp     r1, #105\r
288         bne     reg1_error_loopf\r
289         vmov    r0, r1, d3\r
290         cmp     r0, #106\r
291         bne     reg1_error_loopf\r
292         cmp     r1, #107\r
293         bne     reg1_error_loopf\r
294         vmov    r0, r1, d4\r
295         cmp     r0, #108\r
296         bne     reg1_error_loopf\r
297         cmp     r1, #109\r
298         bne     reg1_error_loopf\r
299         vmov    r0, r1, d5\r
300         cmp     r0, #110\r
301         bne     reg1_error_loopf\r
302         cmp     r1, #111\r
303         bne     reg1_error_loopf\r
304         vmov    r0, r1, d6\r
305         cmp     r0, #100\r
306         bne     reg1_error_loopf\r
307         cmp     r1, #101\r
308         bne     reg1_error_loopf\r
309         vmov    r0, r1, d7\r
310         cmp     r0, #102\r
311         bne     reg1_error_loopf\r
312         cmp     r1, #103\r
313         bne     reg1_error_loopf\r
314         vmov    r0, r1, d8\r
315         cmp     r0, #104\r
316         bne     reg1_error_loopf\r
317         cmp     r1, #105\r
318         bne     reg1_error_loopf\r
319         vmov    r0, r1, d9\r
320         cmp     r0, #106\r
321         bne     reg1_error_loopf\r
322         cmp     r1, #107\r
323         bne     reg1_error_loopf\r
324         vmov    r0, r1, d10\r
325         cmp     r0, #108\r
326         bne     reg1_error_loopf\r
327         cmp     r1, #109\r
328         bne     reg1_error_loopf\r
329         vmov    r0, r1, d11\r
330         cmp     r0, #110\r
331         bne     reg1_error_loopf\r
332         cmp     r1, #111\r
333         bne     reg1_error_loopf\r
334         vmov    r0, r1, d12\r
335         cmp     r0, #100\r
336         bne     reg1_error_loopf\r
337         cmp     r1, #101\r
338         bne     reg1_error_loopf\r
339         vmov    r0, r1, d13\r
340         cmp     r0, #102\r
341         bne     reg1_error_loopf\r
342         cmp     r1, #103\r
343         bne     reg1_error_loopf\r
344         vmov    r0, r1, d14\r
345         cmp     r0, #104\r
346         bne     reg1_error_loopf\r
347         cmp     r1, #105\r
348         bne     reg1_error_loopf\r
349         vmov    r0, r1, d15\r
350         cmp     r0, #106\r
351         bne     reg1_error_loopf\r
352         cmp     r1, #107\r
353         bne     reg1_error_loopf\r
354 \r
355         /* Restore the registers that were clobbered by the test. */\r
356         pop     {r0-r1}\r
357 \r
358         /* VFP register test passed.  Jump to the core register test. */\r
359         b               reg1_loopf_pass\r
360 \r
361 reg1_error_loopf\r
362         /* If this line is hit then a VFP register value was found to be incorrect. */\r
363         b reg1_error_loopf\r
364 \r
365 reg1_loopf_pass\r
366 \r
367         cmp     r0, #100\r
368         bne     reg1_error_loop\r
369         cmp     r1, #101\r
370         bne     reg1_error_loop\r
371         cmp     r2, #102\r
372         bne     reg1_error_loop\r
373         cmp     r3, #103\r
374         bne     reg1_error_loop\r
375         cmp     r4, #104\r
376         bne     reg1_error_loop\r
377         cmp     r5, #105\r
378         bne     reg1_error_loop\r
379         cmp     r6, #106\r
380         bne     reg1_error_loop\r
381         cmp     r7, #107\r
382         bne     reg1_error_loop\r
383         cmp     r8, #108\r
384         bne     reg1_error_loop\r
385         cmp     r9, #109\r
386         bne     reg1_error_loop\r
387         cmp     r10, #110\r
388         bne     reg1_error_loop\r
389         cmp     r11, #111\r
390         bne     reg1_error_loop\r
391         cmp     r12, #112\r
392         bne     reg1_error_loop\r
393 \r
394         /* Everything passed, increment the loop counter. */\r
395         push    { r0-r1 }\r
396         ldr     r0, =pulRegTest3LoopCounter\r
397         ldr     r0, [r0]\r
398         ldr     r1, [r0]\r
399         adds    r1, r1, #1\r
400         str     r1, [r0]\r
401         pop     { r0-r1 }\r
402 \r
403         /* Start again. */\r
404         b               reg1_loop\r
405 \r
406 reg1_error_loop\r
407         /* If this line is hit then there was an error in a core register value.\r
408         The loop ensures the loop counter stops incrementing. */\r
409         b       reg1_error_loop\r
410         nop\r
411         nop\r
412 }\r
413 /*-----------------------------------------------------------*/\r
414 \r
415 __asm void vRegTest4Implementation( void )\r
416 {\r
417         extern pulRegTest4LoopCounter;\r
418 \r
419         PRESERVE8\r
420 \r
421         /* Set all the core registers to known values. */\r
422         mov     r0, #-1\r
423         mov     r1, #1\r
424         mov     r2, #2\r
425         mov     r3, #3\r
426         mov     r4, #4\r
427         mov     r5, #5\r
428         mov     r6, #6\r
429         mov     r7, #7\r
430         mov     r8, #8\r
431         mov     r9, #9\r
432         mov     r10, #10\r
433         mov     r11, #11\r
434         mov     r12, #12\r
435 \r
436         /* Set all the VFP to known values. */\r
437         vmov    d0, r0, r1\r
438         vmov    d1, r2, r3\r
439         vmov    d2, r4, r5\r
440         vmov    d3, r6, r7\r
441         vmov    d4, r8, r9\r
442         vmov    d5, r10, r11\r
443         vmov    d6, r0, r1\r
444         vmov    d7, r2, r3\r
445         vmov    d8, r4, r5\r
446         vmov    d9, r6, r7\r
447         vmov    d10, r8, r9\r
448         vmov    d11, r10, r11\r
449         vmov    d12, r0, r1\r
450         vmov    d13, r2, r3\r
451         vmov    d14, r4, r5\r
452         vmov    d15, r6, r7\r
453 \r
454 reg2_loop\r
455 \r
456         /* Check all the VFP registers still contain the values set above.\r
457         First save registers that are clobbered by the test. */\r
458         push { r0-r1 }\r
459 \r
460         vmov    r0, r1, d0\r
461         cmp     r0, #-1\r
462         bne     reg2_error_loopf\r
463         cmp     r1, #1\r
464         bne     reg2_error_loopf\r
465         vmov    r0, r1, d1\r
466         cmp     r0, #2\r
467         bne     reg2_error_loopf\r
468         cmp     r1, #3\r
469         bne     reg2_error_loopf\r
470         vmov    r0, r1, d2\r
471         cmp     r0, #4\r
472         bne     reg2_error_loopf\r
473         cmp     r1, #5\r
474         bne     reg2_error_loopf\r
475         vmov    r0, r1, d3\r
476         cmp     r0, #6\r
477         bne     reg2_error_loopf\r
478         cmp     r1, #7\r
479         bne     reg2_error_loopf\r
480         vmov    r0, r1, d4\r
481         cmp     r0, #8\r
482         bne     reg2_error_loopf\r
483         cmp     r1, #9\r
484         bne     reg2_error_loopf\r
485         vmov    r0, r1, d5\r
486         cmp     r0, #10\r
487         bne     reg2_error_loopf\r
488         cmp     r1, #11\r
489         bne     reg2_error_loopf\r
490         vmov    r0, r1, d6\r
491         cmp     r0, #-1\r
492         bne     reg2_error_loopf\r
493         cmp     r1, #1\r
494         bne     reg2_error_loopf\r
495         vmov    r0, r1, d7\r
496         cmp     r0, #2\r
497         bne     reg2_error_loopf\r
498         cmp     r1, #3\r
499         bne     reg2_error_loopf\r
500         vmov    r0, r1, d8\r
501         cmp     r0, #4\r
502         bne     reg2_error_loopf\r
503         cmp     r1, #5\r
504         bne     reg2_error_loopf\r
505         vmov    r0, r1, d9\r
506         cmp     r0, #6\r
507         bne     reg2_error_loopf\r
508         cmp     r1, #7\r
509         bne     reg2_error_loopf\r
510         vmov    r0, r1, d10\r
511         cmp     r0, #8\r
512         bne     reg2_error_loopf\r
513         cmp     r1, #9\r
514         bne     reg2_error_loopf\r
515         vmov    r0, r1, d11\r
516         cmp     r0, #10\r
517         bne     reg2_error_loopf\r
518         cmp     r1, #11\r
519         bne     reg2_error_loopf\r
520         vmov    r0, r1, d12\r
521         cmp     r0, #-1\r
522         bne     reg2_error_loopf\r
523         cmp     r1, #1\r
524         bne     reg2_error_loopf\r
525         vmov    r0, r1, d13\r
526         cmp     r0, #2\r
527         bne     reg2_error_loopf\r
528         cmp     r1, #3\r
529         bne     reg2_error_loopf\r
530         vmov    r0, r1, d14\r
531         cmp     r0, #4\r
532         bne     reg2_error_loopf\r
533         cmp     r1, #5\r
534         bne     reg2_error_loopf\r
535         vmov    r0, r1, d15\r
536         cmp     r0, #6\r
537         bne     reg2_error_loopf\r
538         cmp     r1, #7\r
539         bne     reg2_error_loopf\r
540 \r
541         /* Restore the registers that were clobbered by the test. */\r
542         pop     {r0-r1}\r
543 \r
544         /* VFP register test passed.  Jump to the core register test. */\r
545         b               reg2_loopf_pass\r
546 \r
547 reg2_error_loopf\r
548         /* If this line is hit then a VFP register value was found to be\r
549         incorrect. */\r
550         b reg2_error_loopf\r
551 \r
552 reg2_loopf_pass\r
553 \r
554         cmp     r0, #-1\r
555         bne     reg2_error_loop\r
556         cmp     r1, #1\r
557         bne     reg2_error_loop\r
558         cmp     r2, #2\r
559         bne     reg2_error_loop\r
560         cmp     r3, #3\r
561         bne     reg2_error_loop\r
562         cmp     r4, #4\r
563         bne     reg2_error_loop\r
564         cmp     r5, #5\r
565         bne     reg2_error_loop\r
566         cmp     r6, #6\r
567         bne     reg2_error_loop\r
568         cmp     r7, #7\r
569         bne     reg2_error_loop\r
570         cmp     r8, #8\r
571         bne     reg2_error_loop\r
572         cmp     r9, #9\r
573         bne     reg2_error_loop\r
574         cmp     r10, #10\r
575         bne     reg2_error_loop\r
576         cmp     r11, #11\r
577         bne     reg2_error_loop\r
578         cmp     r12, #12\r
579         bne     reg2_error_loop\r
580 \r
581         /* Increment the loop counter so the check task knows this task is\r
582         still running. */\r
583         push    { r0-r1 }\r
584         ldr     r0, =pulRegTest4LoopCounter\r
585         ldr     r0, [r0]\r
586         ldr     r1, [r0]\r
587         adds    r1, r1, #1\r
588         str     r1, [r0]\r
589         pop { r0-r1 }\r
590 \r
591         /* Yield to increase test coverage. */\r
592         SVC #1\r
593 \r
594         /* Start again. */\r
595         b reg2_loop\r
596 \r
597 reg2_error_loop\r
598         /* If this line is hit then there was an error in a core register value.\r
599         This loop ensures the loop counter variable stops incrementing. */\r
600         b reg2_error_loop\r
601         nop\r
602 }\r
603 /*-----------------------------------------------------------*/\r
604 \r
605 /* Fault handlers are here for convenience as they use compiler specific syntax\r
606 and this file is specific to the Keil compiler. */\r
607 void hard_fault_handler( uint32_t * hardfault_args )\r
608 {\r
609 volatile uint32_t stacked_r0;\r
610 volatile uint32_t stacked_r1;\r
611 volatile uint32_t stacked_r2;\r
612 volatile uint32_t stacked_r3;\r
613 volatile uint32_t stacked_r12;\r
614 volatile uint32_t stacked_lr;\r
615 volatile uint32_t stacked_pc;\r
616 volatile uint32_t stacked_psr;\r
617 \r
618         stacked_r0 = ((uint32_t) hardfault_args[ 0 ]);\r
619         stacked_r1 = ((uint32_t) hardfault_args[ 1 ]);\r
620         stacked_r2 = ((uint32_t) hardfault_args[ 2 ]);\r
621         stacked_r3 = ((uint32_t) hardfault_args[ 3 ]);\r
622 \r
623         stacked_r12 = ((uint32_t) hardfault_args[ 4 ]);\r
624         stacked_lr = ((uint32_t) hardfault_args[ 5 ]);\r
625         stacked_pc = ((uint32_t) hardfault_args[ 6 ]);\r
626         stacked_psr = ((uint32_t) hardfault_args[ 7 ]);\r
627 \r
628         /* Inspect stacked_pc to locate the offending instruction. */\r
629         for( ;; );\r
630 }\r
631 /*-----------------------------------------------------------*/\r
632 \r
633 void HardFault_Handler( void );\r
634 __asm void HardFault_Handler( void )\r
635 {\r
636         extern hard_fault_handler\r
637 \r
638         tst lr, #4\r
639         ite eq\r
640         mrseq r0, msp\r
641         mrsne r0, psp\r
642         ldr r1, [r0, #24]\r
643         ldr r2, hard_fault_handler\r
644         bx r2\r
645 }\r
646 /*-----------------------------------------------------------*/\r
647 \r
648 void MemManage_Handler( void );\r
649 __asm void MemManage_Handler( void )\r
650 {\r
651         extern hard_fault_handler\r
652 \r
653         tst lr, #4\r
654         ite eq\r
655         mrseq r0, msp\r
656         mrsne r0, psp\r
657         ldr r1, [r0, #24]\r
658         ldr r2, hard_fault_handler\r
659         bx r2\r
660 }\r
661 /*-----------------------------------------------------------*/\r