]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_MPU_CEC_MEC_17xx_Keil_GCC/Keil_Specific/RegTest.c
90e1625c5994a95fb7dd8aa6369bce4e5a2c499c
[freertos] / FreeRTOS / Demo / CORTEX_MPU_CEC_MEC_17xx_Keil_GCC / Keil_Specific / RegTest.c
1 /*\r
2     FreeRTOS V9.0.0 - Copyright (C) 2015 Real Time Engineers Ltd.\r
3     All rights reserved\r
4 \r
5     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
6 \r
7     This file is part of the FreeRTOS distribution.\r
8 \r
9     FreeRTOS is free software; you can redistribute it and/or modify it under\r
10     the terms of the GNU General Public License (version 2) as published by the\r
11     Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.\r
12 \r
13     ***************************************************************************\r
14     >>!   NOTE: The modification to the GPL is included to allow you to     !<<\r
15     >>!   distribute a combined work that includes FreeRTOS without being   !<<\r
16     >>!   obliged to provide the source code for proprietary components     !<<\r
17     >>!   outside of the FreeRTOS kernel.                                   !<<\r
18     ***************************************************************************\r
19 \r
20     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
21     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
22     FOR A PARTICULAR PURPOSE.  Full license text is available on the following\r
23     link: http://www.freertos.org/a00114.html\r
24 \r
25     ***************************************************************************\r
26      *                                                                       *\r
27      *    FreeRTOS provides completely free yet professionally developed,    *\r
28      *    robust, strictly quality controlled, supported, and cross          *\r
29      *    platform software that is more than just the market leader, it     *\r
30      *    is the industry's de facto standard.                               *\r
31      *                                                                       *\r
32      *    Help yourself get started quickly while simultaneously helping     *\r
33      *    to support the FreeRTOS project by purchasing a FreeRTOS           *\r
34      *    tutorial book, reference manual, or both:                          *\r
35      *    http://www.FreeRTOS.org/Documentation                              *\r
36      *                                                                       *\r
37     ***************************************************************************\r
38 \r
39     http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading\r
40     the FAQ page "My application does not run, what could be wrong?".  Have you\r
41     defined configASSERT()?\r
42 \r
43     http://www.FreeRTOS.org/support - In return for receiving this top quality\r
44     embedded software for free we request you assist our global community by\r
45     participating in the support forum.\r
46 \r
47     http://www.FreeRTOS.org/training - Investing in training allows your team to\r
48     be as productive as possible as early as possible.  Now you can receive\r
49     FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
50     Ltd, and the world's leading authority on the world's leading RTOS.\r
51 \r
52     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
53     including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
54     compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
55 \r
56     http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
57     Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
58 \r
59     http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
60     Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
61     licenses offer ticketed support, indemnification and commercial middleware.\r
62 \r
63     http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
64     engineered and independently SIL3 certified version for use in safety and\r
65     mission critical applications that require provable dependability.\r
66 \r
67     1 tab == 4 spaces!\r
68 */\r
69 \r
70 /* FreeRTOS includes. */\r
71 #include "FreeRTOS.h"\r
72 #include "queue.h"\r
73 #include "task.h"\r
74 \r
75 /*\r
76  * "Reg test" tasks - These fill the registers with known values, then check\r
77  * that each register maintains its expected value for the lifetime of the\r
78  * task.  Each task uses a different set of values.  The reg test tasks execute\r
79  * with a very low priority, so get preempted very frequently.  A register\r
80  * containing an unexpected value is indicative of an error in the context\r
81  * switching mechanism.\r
82  */\r
83 \r
84 void vRegTest1Implementation( void *pvParameters );\r
85 void vRegTest2Implementation( void *pvParameters );\r
86 void vRegTest3Implementation( void );\r
87 void vRegTest4Implementation( void );\r
88 \r
89 /*\r
90  * Used as an easy way of deleting a task from inline assembly.\r
91  */\r
92 extern void vMainDeleteMe( void ) __attribute__((noinline));\r
93 \r
94 /*\r
95  * Used by the first two reg test tasks and a software timer callback function\r
96  * to send messages to the check task.  The message just lets the check task\r
97  * know that the tasks and timer are still functioning correctly.  If a reg test\r
98  * task detects an error it will delete itself, and in so doing prevent itself\r
99  * from sending any more 'I'm Alive' messages to the check task.\r
100  */\r
101 extern void vMainSendImAlive( QueueHandle_t xHandle, uint32_t ulTaskNumber );\r
102 \r
103 /* The queue used to send a message to the check task. */\r
104 extern QueueHandle_t xGlobalScopeCheckQueue;\r
105 \r
106 /*-----------------------------------------------------------*/\r
107 \r
108 void vRegTest1Implementation( void *pvParameters )\r
109 {\r
110 /* This task is created in privileged mode so can access the file scope\r
111 queue variable.  Take a stack copy of this before the task is set into user\r
112 mode.  Once this task is in user mode the file scope queue variable will no\r
113 longer be accessible but the stack copy will. */\r
114 QueueHandle_t xQueue = xGlobalScopeCheckQueue;\r
115 const TickType_t xDelayTime = pdMS_TO_TICKS( 100UL );\r
116 \r
117         /* Now the queue handle has been obtained the task can switch to user\r
118         mode.  This is just one method of passing a handle into a protected\r
119         task, the other reg test task uses the task parameter instead. */\r
120         portSWITCH_TO_USER_MODE();\r
121 \r
122         /* First check that the parameter value is as expected. */\r
123         if( pvParameters != ( void * ) configREG_TEST_TASK_1_PARAMETER )\r
124         {\r
125                 /* Error detected.  Delete the task so it stops communicating with\r
126                 the check task. */\r
127                 vMainDeleteMe();\r
128         }\r
129 \r
130         for( ;; )\r
131         {\r
132                 #if defined ( __GNUC__ )\r
133                 {\r
134                         /* This task tests the kernel context switch mechanism by reading and\r
135                         writing directly to registers - which requires the test to be written\r
136                         in assembly code. */\r
137                         __asm volatile\r
138                         (\r
139                                 "               MOV     R4, #104                        \n" /* Set registers to a known value.  R0 to R1 are done in the loop below. */\r
140                                 "               MOV     R5, #105                        \n"\r
141                                 "               MOV     R6, #106                        \n"\r
142                                 "               MOV     R8, #108                        \n"\r
143                                 "               MOV     R9, #109                        \n"\r
144                                 "               MOV     R10, #110                       \n"\r
145                                 "               MOV     R11, #111                       \n"\r
146                                 "reg1loop:                                              \n"\r
147                                 "               MOV     R0, #100                        \n" /* Set the scratch registers to known values - done inside the loop as they get clobbered. */\r
148                                 "               MOV     R1, #101                        \n"\r
149                                 "               MOV     R2, #102                        \n"\r
150                                 "               MOV R3, #103                    \n"\r
151                                 "               MOV     R12, #112                       \n"\r
152                                 "               SVC #1                                  \n" /* Yield just to increase test coverage. */\r
153                                 "               CMP     R0, #100                        \n" /* Check all the registers still contain their expected values. */\r
154                                 "               BNE     vMainDeleteMe           \n" /* Value was not as expected, delete the task so it stops communicating with the check task. */\r
155                                 "               CMP     R1, #101                        \n"\r
156                                 "               BNE     vMainDeleteMe           \n"\r
157                                 "               CMP     R2, #102                        \n"\r
158                                 "               BNE     vMainDeleteMe           \n"\r
159                                 "               CMP R3, #103                    \n"\r
160                                 "               BNE     vMainDeleteMe           \n"\r
161                                 "               CMP     R4, #104                        \n"\r
162                                 "               BNE     vMainDeleteMe           \n"\r
163                                 "               CMP     R5, #105                        \n"\r
164                                 "               BNE     vMainDeleteMe           \n"\r
165                                 "               CMP     R6, #106                        \n"\r
166                                 "               BNE     vMainDeleteMe           \n"\r
167                                 "               CMP     R8, #108                        \n"\r
168                                 "               BNE     vMainDeleteMe           \n"\r
169                                 "               CMP     R9, #109                        \n"\r
170                                 "               BNE     vMainDeleteMe           \n"\r
171                                 "               CMP     R10, #110                       \n"\r
172                                 "               BNE     vMainDeleteMe           \n"\r
173                                 "               CMP     R11, #111                       \n"\r
174                                 "               BNE     vMainDeleteMe           \n"\r
175                                 "               CMP     R12, #112                       \n"\r
176                                 "               BNE     vMainDeleteMe           \n"\r
177                                 :::"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12"\r
178                         );\r
179                 }\r
180                 #endif /* __GNUC__ */\r
181 \r
182                 /* Send configREG_TEST_1_STILL_EXECUTING to the check task to indicate that this\r
183                 task is still functioning. */\r
184                 vMainSendImAlive( xQueue, configREG_TEST_1_STILL_EXECUTING );\r
185                 vTaskDelay( xDelayTime );\r
186 \r
187                 #if defined ( __GNUC__ )\r
188                 {\r
189                         /* Go back to check all the register values again. */\r
190                         __asm volatile( "               B reg1loop      " );\r
191                 }\r
192                 #endif /* __GNUC__ */\r
193         }\r
194 }\r
195 /*-----------------------------------------------------------*/\r
196 \r
197 void vRegTest2Implementation( void *pvParameters )\r
198 {\r
199 /* The queue handle is passed in as the task parameter.  This is one method of\r
200 passing data into a protected task, the other reg test task uses a different\r
201 method. */\r
202 QueueHandle_t xQueue = ( QueueHandle_t ) pvParameters;\r
203 const TickType_t xDelayTime = pdMS_TO_TICKS( 100UL );\r
204 \r
205         for( ;; )\r
206         {\r
207                 #if defined ( __GNUC__ )\r
208                 {\r
209                         /* This task tests the kernel context switch mechanism by reading and\r
210                         writing directly to registers - which requires the test to be written\r
211                         in assembly code. */\r
212                         __asm volatile\r
213                         (\r
214                                 "               MOV     R4, #4                          \n" /* Set registers to a known value.  R0 to R1 are done in the loop below. */\r
215                                 "               MOV     R5, #5                          \n"\r
216                                 "               MOV     R6, #6                          \n"\r
217                                 "               MOV     R8, #8                          \n" /* Frame pointer is omitted as it must not be changed. */\r
218                                 "               MOV     R9, #9                          \n"\r
219                                 "               MOV     R10, 10                         \n"\r
220                                 "               MOV     R11, #11                        \n"\r
221                                 "reg2loop:                                              \n"\r
222                                 "               MOV     R0, #13                         \n" /* Set the scratch registers to known values - done inside the loop as they get clobbered. */\r
223                                 "               MOV     R1, #1                          \n"\r
224                                 "               MOV     R2, #2                          \n"\r
225                                 "               MOV R3, #3                              \n"\r
226                                 "               MOV     R12, #12                        \n"\r
227                                 "               CMP     R0, #13                         \n" /* Check all the registers still contain their expected values. */\r
228                                 "               BNE     vMainDeleteMe           \n" /* Value was not as expected, delete the task so it stops communicating with the check task */\r
229                                 "               CMP     R1, #1                          \n"\r
230                                 "               BNE     vMainDeleteMe           \n"\r
231                                 "               CMP     R2, #2                          \n"\r
232                                 "               BNE     vMainDeleteMe           \n"\r
233                                 "               CMP R3, #3                              \n"\r
234                                 "               BNE     vMainDeleteMe           \n"\r
235                                 "               CMP     R4, #4                          \n"\r
236                                 "               BNE     vMainDeleteMe           \n"\r
237                                 "               CMP     R5, #5                          \n"\r
238                                 "               BNE     vMainDeleteMe           \n"\r
239                                 "               CMP     R6, #6                          \n"\r
240                                 "               BNE     vMainDeleteMe           \n"\r
241                                 "               CMP     R8, #8                          \n"\r
242                                 "               BNE     vMainDeleteMe           \n"\r
243                                 "               CMP     R9, #9                          \n"\r
244                                 "               BNE     vMainDeleteMe           \n"\r
245                                 "               CMP     R10, #10                        \n"\r
246                                 "               BNE     vMainDeleteMe           \n"\r
247                                 "               CMP     R11, #11                        \n"\r
248                                 "               BNE     vMainDeleteMe           \n"\r
249                                 "               CMP     R12, #12                        \n"\r
250                                 "               BNE     vMainDeleteMe           \n"\r
251                                 :::"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r8", "r9", "r10", "r11", "r12"\r
252                         );\r
253                 }\r
254                 #endif /* __GNUC__ */\r
255 \r
256                 /* Send configREG_TEST_2_STILL_EXECUTING to the check task to indicate\r
257                 that this task is still functioning. */\r
258                 vMainSendImAlive( xQueue, configREG_TEST_2_STILL_EXECUTING );\r
259                 vTaskDelay( xDelayTime );\r
260 \r
261                 #if defined ( __GNUC__ )\r
262                 {\r
263                         /* Go back to check all the register values again. */\r
264                         __asm volatile( "               B reg2loop      " );\r
265                 }\r
266                 #endif /* __GNUC__ */\r
267         }\r
268 }\r
269 /*-----------------------------------------------------------*/\r
270 \r
271 __asm void vRegTest3Implementation( void )\r
272 {\r
273         extern pulRegTest3LoopCounter\r
274 \r
275         PRESERVE8\r
276 \r
277         /* Fill the core registers with known values. */\r
278         mov     r0, #100\r
279         mov     r1, #101\r
280         mov     r2, #102\r
281         mov     r3, #103\r
282         mov     r4, #104\r
283         mov     r5, #105\r
284         mov     r6, #106\r
285         mov     r7, #107\r
286         mov     r8, #108\r
287         mov     r9, #109\r
288         mov     r10, #110\r
289         mov     r11, #111\r
290         mov     r12, #112\r
291 \r
292         /* Fill the VFP registers with known values. */\r
293         vmov    d0, r0, r1\r
294         vmov    d1, r2, r3\r
295         vmov    d2, r4, r5\r
296         vmov    d3, r6, r7\r
297         vmov    d4, r8, r9\r
298         vmov    d5, r10, r11\r
299         vmov    d6, r0, r1\r
300         vmov    d7, r2, r3\r
301         vmov    d8, r4, r5\r
302         vmov    d9, r6, r7\r
303         vmov    d10, r8, r9\r
304         vmov    d11, r10, r11\r
305         vmov    d12, r0, r1\r
306         vmov    d13, r2, r3\r
307         vmov    d14, r4, r5\r
308         vmov    d15, r6, r7\r
309 \r
310 reg1_loop\r
311 \r
312         /* Check all the VFP registers still contain the values set above.\r
313         First save registers that are clobbered by the test. */\r
314         push { r0-r1 }\r
315 \r
316         vmov    r0, r1, d0\r
317         cmp     r0, #100\r
318         bne     reg1_error_loopf\r
319         cmp     r1, #101\r
320         bne     reg1_error_loopf\r
321         vmov    r0, r1, d1\r
322         cmp     r0, #102\r
323         bne     reg1_error_loopf\r
324         cmp     r1, #103\r
325         bne     reg1_error_loopf\r
326         vmov    r0, r1, d2\r
327         cmp     r0, #104\r
328         bne     reg1_error_loopf\r
329         cmp     r1, #105\r
330         bne     reg1_error_loopf\r
331         vmov    r0, r1, d3\r
332         cmp     r0, #106\r
333         bne     reg1_error_loopf\r
334         cmp     r1, #107\r
335         bne     reg1_error_loopf\r
336         vmov    r0, r1, d4\r
337         cmp     r0, #108\r
338         bne     reg1_error_loopf\r
339         cmp     r1, #109\r
340         bne     reg1_error_loopf\r
341         vmov    r0, r1, d5\r
342         cmp     r0, #110\r
343         bne     reg1_error_loopf\r
344         cmp     r1, #111\r
345         bne     reg1_error_loopf\r
346         vmov    r0, r1, d6\r
347         cmp     r0, #100\r
348         bne     reg1_error_loopf\r
349         cmp     r1, #101\r
350         bne     reg1_error_loopf\r
351         vmov    r0, r1, d7\r
352         cmp     r0, #102\r
353         bne     reg1_error_loopf\r
354         cmp     r1, #103\r
355         bne     reg1_error_loopf\r
356         vmov    r0, r1, d8\r
357         cmp     r0, #104\r
358         bne     reg1_error_loopf\r
359         cmp     r1, #105\r
360         bne     reg1_error_loopf\r
361         vmov    r0, r1, d9\r
362         cmp     r0, #106\r
363         bne     reg1_error_loopf\r
364         cmp     r1, #107\r
365         bne     reg1_error_loopf\r
366         vmov    r0, r1, d10\r
367         cmp     r0, #108\r
368         bne     reg1_error_loopf\r
369         cmp     r1, #109\r
370         bne     reg1_error_loopf\r
371         vmov    r0, r1, d11\r
372         cmp     r0, #110\r
373         bne     reg1_error_loopf\r
374         cmp     r1, #111\r
375         bne     reg1_error_loopf\r
376         vmov    r0, r1, d12\r
377         cmp     r0, #100\r
378         bne     reg1_error_loopf\r
379         cmp     r1, #101\r
380         bne     reg1_error_loopf\r
381         vmov    r0, r1, d13\r
382         cmp     r0, #102\r
383         bne     reg1_error_loopf\r
384         cmp     r1, #103\r
385         bne     reg1_error_loopf\r
386         vmov    r0, r1, d14\r
387         cmp     r0, #104\r
388         bne     reg1_error_loopf\r
389         cmp     r1, #105\r
390         bne     reg1_error_loopf\r
391         vmov    r0, r1, d15\r
392         cmp     r0, #106\r
393         bne     reg1_error_loopf\r
394         cmp     r1, #107\r
395         bne     reg1_error_loopf\r
396 \r
397         /* Restore the registers that were clobbered by the test. */\r
398         pop     {r0-r1}\r
399 \r
400         /* VFP register test passed.  Jump to the core register test. */\r
401         b               reg1_loopf_pass\r
402 \r
403 reg1_error_loopf\r
404         /* If this line is hit then a VFP register value was found to be incorrect. */\r
405         b reg1_error_loopf\r
406 \r
407 reg1_loopf_pass\r
408 \r
409         cmp     r0, #100\r
410         bne     reg1_error_loop\r
411         cmp     r1, #101\r
412         bne     reg1_error_loop\r
413         cmp     r2, #102\r
414         bne     reg1_error_loop\r
415         cmp     r3, #103\r
416         bne     reg1_error_loop\r
417         cmp     r4, #104\r
418         bne     reg1_error_loop\r
419         cmp     r5, #105\r
420         bne     reg1_error_loop\r
421         cmp     r6, #106\r
422         bne     reg1_error_loop\r
423         cmp     r7, #107\r
424         bne     reg1_error_loop\r
425         cmp     r8, #108\r
426         bne     reg1_error_loop\r
427         cmp     r9, #109\r
428         bne     reg1_error_loop\r
429         cmp     r10, #110\r
430         bne     reg1_error_loop\r
431         cmp     r11, #111\r
432         bne     reg1_error_loop\r
433         cmp     r12, #112\r
434         bne     reg1_error_loop\r
435 \r
436         /* Everything passed, increment the loop counter. */\r
437         push    { r0-r1 }\r
438         ldr     r0, =pulRegTest3LoopCounter\r
439         ldr     r0, [r0]\r
440         ldr     r1, [r0]\r
441         adds    r1, r1, #1\r
442         str     r1, [r0]\r
443         pop     { r0-r1 }\r
444 \r
445         /* Start again. */\r
446         b               reg1_loop\r
447 \r
448 reg1_error_loop\r
449         /* If this line is hit then there was an error in a core register value.\r
450         The loop ensures the loop counter stops incrementing. */\r
451         b       reg1_error_loop\r
452         nop\r
453         nop\r
454 }\r
455 /*-----------------------------------------------------------*/\r
456 \r
457 __asm void vRegTest4Implementation( void )\r
458 {\r
459         extern pulRegTest4LoopCounter;\r
460 \r
461         PRESERVE8\r
462 \r
463         /* Set all the core registers to known values. */\r
464         mov     r0, #-1\r
465         mov     r1, #1\r
466         mov     r2, #2\r
467         mov     r3, #3\r
468         mov     r4, #4\r
469         mov     r5, #5\r
470         mov     r6, #6\r
471         mov     r7, #7\r
472         mov     r8, #8\r
473         mov     r9, #9\r
474         mov     r10, #10\r
475         mov     r11, #11\r
476         mov     r12, #12\r
477 \r
478         /* Set all the VFP to known values. */\r
479         vmov    d0, r0, r1\r
480         vmov    d1, r2, r3\r
481         vmov    d2, r4, r5\r
482         vmov    d3, r6, r7\r
483         vmov    d4, r8, r9\r
484         vmov    d5, r10, r11\r
485         vmov    d6, r0, r1\r
486         vmov    d7, r2, r3\r
487         vmov    d8, r4, r5\r
488         vmov    d9, r6, r7\r
489         vmov    d10, r8, r9\r
490         vmov    d11, r10, r11\r
491         vmov    d12, r0, r1\r
492         vmov    d13, r2, r3\r
493         vmov    d14, r4, r5\r
494         vmov    d15, r6, r7\r
495 \r
496 reg2_loop\r
497 \r
498         /* Check all the VFP registers still contain the values set above.\r
499         First save registers that are clobbered by the test. */\r
500         push { r0-r1 }\r
501 \r
502         vmov    r0, r1, d0\r
503         cmp     r0, #-1\r
504         bne     reg2_error_loopf\r
505         cmp     r1, #1\r
506         bne     reg2_error_loopf\r
507         vmov    r0, r1, d1\r
508         cmp     r0, #2\r
509         bne     reg2_error_loopf\r
510         cmp     r1, #3\r
511         bne     reg2_error_loopf\r
512         vmov    r0, r1, d2\r
513         cmp     r0, #4\r
514         bne     reg2_error_loopf\r
515         cmp     r1, #5\r
516         bne     reg2_error_loopf\r
517         vmov    r0, r1, d3\r
518         cmp     r0, #6\r
519         bne     reg2_error_loopf\r
520         cmp     r1, #7\r
521         bne     reg2_error_loopf\r
522         vmov    r0, r1, d4\r
523         cmp     r0, #8\r
524         bne     reg2_error_loopf\r
525         cmp     r1, #9\r
526         bne     reg2_error_loopf\r
527         vmov    r0, r1, d5\r
528         cmp     r0, #10\r
529         bne     reg2_error_loopf\r
530         cmp     r1, #11\r
531         bne     reg2_error_loopf\r
532         vmov    r0, r1, d6\r
533         cmp     r0, #-1\r
534         bne     reg2_error_loopf\r
535         cmp     r1, #1\r
536         bne     reg2_error_loopf\r
537         vmov    r0, r1, d7\r
538         cmp     r0, #2\r
539         bne     reg2_error_loopf\r
540         cmp     r1, #3\r
541         bne     reg2_error_loopf\r
542         vmov    r0, r1, d8\r
543         cmp     r0, #4\r
544         bne     reg2_error_loopf\r
545         cmp     r1, #5\r
546         bne     reg2_error_loopf\r
547         vmov    r0, r1, d9\r
548         cmp     r0, #6\r
549         bne     reg2_error_loopf\r
550         cmp     r1, #7\r
551         bne     reg2_error_loopf\r
552         vmov    r0, r1, d10\r
553         cmp     r0, #8\r
554         bne     reg2_error_loopf\r
555         cmp     r1, #9\r
556         bne     reg2_error_loopf\r
557         vmov    r0, r1, d11\r
558         cmp     r0, #10\r
559         bne     reg2_error_loopf\r
560         cmp     r1, #11\r
561         bne     reg2_error_loopf\r
562         vmov    r0, r1, d12\r
563         cmp     r0, #-1\r
564         bne     reg2_error_loopf\r
565         cmp     r1, #1\r
566         bne     reg2_error_loopf\r
567         vmov    r0, r1, d13\r
568         cmp     r0, #2\r
569         bne     reg2_error_loopf\r
570         cmp     r1, #3\r
571         bne     reg2_error_loopf\r
572         vmov    r0, r1, d14\r
573         cmp     r0, #4\r
574         bne     reg2_error_loopf\r
575         cmp     r1, #5\r
576         bne     reg2_error_loopf\r
577         vmov    r0, r1, d15\r
578         cmp     r0, #6\r
579         bne     reg2_error_loopf\r
580         cmp     r1, #7\r
581         bne     reg2_error_loopf\r
582 \r
583         /* Restore the registers that were clobbered by the test. */\r
584         pop     {r0-r1}\r
585 \r
586         /* VFP register test passed.  Jump to the core register test. */\r
587         b               reg2_loopf_pass\r
588 \r
589 reg2_error_loopf\r
590         /* If this line is hit then a VFP register value was found to be\r
591         incorrect. */\r
592         b reg2_error_loopf\r
593 \r
594 reg2_loopf_pass\r
595 \r
596         cmp     r0, #-1\r
597         bne     reg2_error_loop\r
598         cmp     r1, #1\r
599         bne     reg2_error_loop\r
600         cmp     r2, #2\r
601         bne     reg2_error_loop\r
602         cmp     r3, #3\r
603         bne     reg2_error_loop\r
604         cmp     r4, #4\r
605         bne     reg2_error_loop\r
606         cmp     r5, #5\r
607         bne     reg2_error_loop\r
608         cmp     r6, #6\r
609         bne     reg2_error_loop\r
610         cmp     r7, #7\r
611         bne     reg2_error_loop\r
612         cmp     r8, #8\r
613         bne     reg2_error_loop\r
614         cmp     r9, #9\r
615         bne     reg2_error_loop\r
616         cmp     r10, #10\r
617         bne     reg2_error_loop\r
618         cmp     r11, #11\r
619         bne     reg2_error_loop\r
620         cmp     r12, #12\r
621         bne     reg2_error_loop\r
622 \r
623         /* Increment the loop counter so the check task knows this task is\r
624         still running. */\r
625         push    { r0-r1 }\r
626         ldr     r0, =pulRegTest4LoopCounter\r
627         ldr     r0, [r0]\r
628         ldr     r1, [r0]\r
629         adds    r1, r1, #1\r
630         str     r1, [r0]\r
631         pop { r0-r1 }\r
632 \r
633         /* Yield to increase test coverage. */\r
634         SVC #1\r
635 \r
636         /* Start again. */\r
637         b reg2_loop\r
638 \r
639 reg2_error_loop\r
640         /* If this line is hit then there was an error in a core register value.\r
641         This loop ensures the loop counter variable stops incrementing. */\r
642         b reg2_error_loop\r
643         nop\r
644 }\r
645 /*-----------------------------------------------------------*/\r
646 \r
647 /* Fault handlers are here for convenience as they use compiler specific syntax\r
648 and this file is specific to the Keil compiler. */\r
649 void hard_fault_handler( uint32_t * hardfault_args )\r
650 {\r
651 volatile uint32_t stacked_r0;\r
652 volatile uint32_t stacked_r1;\r
653 volatile uint32_t stacked_r2;\r
654 volatile uint32_t stacked_r3;\r
655 volatile uint32_t stacked_r12;\r
656 volatile uint32_t stacked_lr;\r
657 volatile uint32_t stacked_pc;\r
658 volatile uint32_t stacked_psr;\r
659 \r
660         stacked_r0 = ((uint32_t) hardfault_args[ 0 ]);\r
661         stacked_r1 = ((uint32_t) hardfault_args[ 1 ]);\r
662         stacked_r2 = ((uint32_t) hardfault_args[ 2 ]);\r
663         stacked_r3 = ((uint32_t) hardfault_args[ 3 ]);\r
664 \r
665         stacked_r12 = ((uint32_t) hardfault_args[ 4 ]);\r
666         stacked_lr = ((uint32_t) hardfault_args[ 5 ]);\r
667         stacked_pc = ((uint32_t) hardfault_args[ 6 ]);\r
668         stacked_psr = ((uint32_t) hardfault_args[ 7 ]);\r
669 \r
670         /* Inspect stacked_pc to locate the offending instruction. */\r
671         for( ;; );\r
672 }\r
673 /*-----------------------------------------------------------*/\r
674 \r
675 void HardFault_Handler( void );\r
676 __asm void HardFault_Handler( void )\r
677 {\r
678         extern hard_fault_handler\r
679 \r
680         tst lr, #4\r
681         ite eq\r
682         mrseq r0, msp\r
683         mrsne r0, psp\r
684         ldr r1, [r0, #24]\r
685         ldr r2, hard_fault_handler\r
686         bx r2\r
687 }\r
688 /*-----------------------------------------------------------*/\r
689 \r
690 void MemManage_Handler( void );\r
691 __asm void MemManage_Handler( void )\r
692 {\r
693         extern hard_fault_handler\r
694 \r
695         tst lr, #4\r
696         ite eq\r
697         mrseq r0, msp\r
698         mrsne r0, psp\r
699         ldr r1, [r0, #24]\r
700         ldr r2, hard_fault_handler\r
701         bx r2\r
702 }\r
703 /*-----------------------------------------------------------*/\r