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