LPCOpen Platform
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
m0_ImageLoader.c
Go to the documentation of this file.
1 /*
2  * @brief M0 Image loader module
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2012
6  * All rights reserved.
7  *
8  * @par
9  * Software that is described herein is for illustrative purposes only
10  * which provides customers with programming information regarding the
11  * LPC products. This software is supplied "AS IS" without any warranties of
12  * any kind, and NXP Semiconductors and its licensor disclaim any and
13  * all warranties, express or implied, including all implied warranties of
14  * merchantability, fitness for a particular purpose and non-infringement of
15  * intellectual property rights. NXP Semiconductors assumes no responsibility
16  * or liability for the use of the software, conveys no license or rights under any
17  * patent, copyright, mask work right, or any other intellectual property rights in
18  * or to any products. NXP Semiconductors reserves the right to make changes
19  * in the software without notification. NXP Semiconductors also makes no
20  * representation or warranty that such application will be suitable for the
21  * specified use without further testing or modification.
22  *
23  * @par
24  * Permission to use, copy, modify, and distribute this software and its
25  * documentation is hereby granted, under NXP Semiconductors' and its
26  * licensor's relevant copyrights in the software, without fee, provided that it
27  * is used in conjunction with NXP Semiconductors microcontrollers. This
28  * copyright, permission, and disclaimer notice must appear in all copies of
29  * this code.
30  */
31 
32 #include <string.h>
33 #include "board.h"
34 #include "lpc43xx_dualcore_config.h"
35 
49 /*****************************************************************************
50  * Private types/enumerations/variables
51  ****************************************************************************/
52 
53 /* Magic numbers to identify M0/M4 images */
54 #define SIGNATURE_M4_MAGIC 0xF00D4BAD
55 #define SIGNATURE_M0_MAGIC 0xBEEFF00D
56 
57 #ifndef ERROR_LED
58 /* LED to be blinked when there is an error in loading/starting M0 image */
59 #define ERROR_LED 1
60 #endif
61 
62 #define EX_BLINKY (1 << 0)
63 #define EX_USBHOST (1 << 1)
64 #define EX_USBDEV (1 << 2)
65 #define EX_LWIP (1 << 3)
66 #define EX_EMWIN (1 << 4)
67 
68 #ifdef OS_UCOS_III
69 #define OS_SIGNATURE 3
70 #elif defined(OS_FREE_RTOS)
71 #define OS_SIGNATURE 2
72 #else
73 #define OS_SIGNATURE 1
74 #endif
75 
76 #ifndef EXAMPLE_BLINKY
77 #define EXAMPLE_BLINKY 0
78 #else
79 #undef EXAMPLE_BLINKY
80 #define EXAMPLE_BLINKY EX_BLINKY
81 #endif
82 
83 #ifndef EXAMPLE_USB_HOST
84 #define EXAMPLE_USB_HOST 0
85 #else
86 #undef EXAMPLE_USB_HOST
87 #define EXAMPLE_USB_HOST EX_USBHOST
88 #endif
89 
90 #ifndef EXAMPLE_USB_DEVICE
91 #define EXAMPLE_USB_DEVICE 0
92 #else
93 #undef EXAMPLE_USB_DEVICE
94 #define EXAMPLE_USB_DEVICE EX_USBDEV
95 #endif
96 
97 #ifndef EXAMPLE_LWIP
98 #define EXAMPLE_LWIP 0
99 #else
100 #undef EXAMPLE_LWIP
101 #define EXAMPLE_LWIP EX_LWIP
102 #endif
103 
104 #ifndef EXAMPLE_EMWIN
105 #define EXAMPLE_EMWIN 0
106 #else
107 #undef EXAMPLE_EMWIN
108 #define EXAMPLE_EMWIN EX_EMWIN
109 #endif
110 
111 #define EXAMPLES_INCLUDED (EXAMPLE_BLINKY + EXAMPLE_LWIP + EXAMPLE_USB_HOST + \
112  EXAMPLE_USB_DEVICE + EXAMPLE_EMWIN)
113 
114 /* Image signature structure */
115 /* NOTE: Although the M0 structure created using this type is used in
116  * the startup assembly file, the assembly file just needs the symbol and
117  * not the type, hence keeping it as private structure.
118  */
119 struct image_sig {
120  uint32_t signature; /* Signature M0/M4 image */
121  uint32_t capability; /* Examples included */
122  uint32_t os; /* OS used */
123  char build_date[32]; /* Build Date string */
124  char build_time[32]; /* Build Time string */
125 };
126 
127 #ifdef CORE_M4
128 /* M4 Image Structure */
129 static const struct image_sig __M4Signature = {
130  SIGNATURE_M4_MAGIC, /* M4 Image magic signature */
132  OS_SIGNATURE,
133  __DATE__,
134  __TIME__,
135 };
136 #endif
137 
138 /*****************************************************************************
139  * Public types/enumerations/variables
140  ****************************************************************************/
141 #ifdef CORE_M0
142 /* Structure object that identifies the image as M0 image */
143 /* NOTE: This symbol is used in startup file (only) */
144 const struct image_sig __M0Signature = {
145  SIGNATURE_M0_MAGIC, /* M0 Image magic signature */
147  OS_SIGNATURE,
148  __DATE__,
149  __TIME__,
150 };
151 #endif
152 
153 /*****************************************************************************
154  * Private functions
155  ****************************************************************************/
156 
157 #ifdef CORE_M4
158 /* Function to blink the LED to show the error code
159  * caused by M0 image boot failure
160  */
161 static void booting_m0_failure(uint32_t msec)
162 {
163  int32_t cnt = 60000 / (msec * 2);
164  DEBUGSTR("ERROR: Boot failure!!\r\n");
165  while (cnt--) {
167  MSleep(msec);
169  MSleep(msec);
170  }
171 }
172 
173 /* Prints the information of the M0/M4 image to screen */
174 static void print_image_info(const char *pre, const struct image_sig *img)
175 {
176  DEBUGSTR("***************************************\r\n");
177  DEBUGOUT("%s: Header found at %p\r\n", pre, img);
178  DEBUGOUT("%s: Included Examples: %s%s%s%s%s\r\n", pre,
179  img->capability & EX_BLINKY ? "BLINKY" : "",
180  img->capability & EX_USBHOST ? ", USB_Host" : "",
181  img->capability & EX_USBDEV ? ", USB_Device" : "",
182  img->capability & EX_LWIP ? ", lwIP" : "",
183  img->capability & EX_EMWIN ? ", emWin" : "");
184  DEBUGOUT("%s: OS Used: %s\r\n", pre,
185  img->os == 1 ? "NONE (STANDALONE)" :
186  (img->os == 2 ? "FreeRTOS" : "UCOS-III"));
187  DEBUGOUT("%s: Built on %s %s\r\n", pre,
188  img->build_date,
189  img->build_time);
190  DEBUGSTR("***************************************\r\n");
191 }
192 
193 /* Validates the M0/M4 image at address image_addr */
194 static int CheckImages(uint32_t image_addr, const struct image_sig *m4)
195 {
196  const uint32_t *addr = (uint32_t *) image_addr + 8;
197  const struct image_sig *m0;
198 
199  uint32_t val, usbprob;
200 
201  /* Check for validity of M0 Image */
202  if (*addr != 0xAA55DEAD) {
203  DEBUGOUT("ERROR: Unable to find signature1 of M0 Image at %p\r\n",
204  ((uint32_t *) image_addr + 4));
205  booting_m0_failure(20);
206  return -1;
207  }
208 
209  /* Do sanity check */
210  addr++;
211  if ((image_addr & 0xFFF00000UL) != (*addr & 0xFFF00000UL)) {
212  DEBUGOUT("ERROR: M0 Image at 0x%08X, Infostruct at "
213  "0x%08X not is same region\r\n", image_addr, *addr);
214  booting_m0_failure(20);
215  return -1;
216  }
217 
218  /* Valid structure is found */
219  m0 = (const struct image_sig *) *addr;
220  if (m0->signature != SIGNATURE_M0_MAGIC) {
221  DEBUGSTR("M0_IMAGE: ERROR: M0 image signature 2 not found!\r\n");
222  booting_m0_failure(20);
223  return -1;
224  }
225 
226  /* This should never happen, kept only for completeness */
227  if (m4->signature != SIGNATURE_M4_MAGIC) {
228  DEBUGSTR("M0_IMAGE: ERROR: M4 image signature 2 not found!\r\n");
229  booting_m0_failure(10000);
230  return -1;
231  }
232  print_image_info("M0_IMAGE", m0);
233  print_image_info("M4_IMAGE", m4);
234  val = m0->capability & m4->capability;
235  usbprob = (m0->capability & (EX_USBHOST | EX_USBDEV)) &&
236  (m4->capability & (EX_USBHOST | EX_USBDEV));
237 
238  /* TODO: Check on possibility of running device on one core
239  * and host stack on another
240  **/
241  if (usbprob) {
242  DEBUGSTR("ERROR: Running USB Host/Device stack on both"
243  " cores is not supported yet!\r\n");
244  booting_m0_failure(2000);
245  return -1;
246  }
247 
248  if (val & EX_LWIP) {
249  DEBUGSTR("ERROR: Running lwIP on both core is not supported!\r\n");
250  booting_m0_failure(2000);
251  return -1;
252  }
253 
254  if (val & EX_EMWIN) {
255  DEBUGSTR("ERROR: Running emWIN on both core is not supported!\r\n");
256  booting_m0_failure(2000);
257  return -1;
258  }
259  return 0;
260 }
261 
262 #endif
263 
264 /*****************************************************************************
265  * Public functions
266  ****************************************************************************/
267 
268 #ifdef CORE_M4
269 /* M0 Boot loader */
270 int M0Image_Boot(uint32_t m0_image_addr)
271 {
272  /* Make sure the alignment is OK */
273  if (m0_image_addr & 0xFFF) {
274  return -1;
275  }
276 
277  /* Check the validity of images */
278  if (CheckImages(m0_image_addr, &__M4Signature) != 0) {
279  return -1;
280  }
281 
282  /* Make sure the M0 core is being held in reset via the RGU */
283  Chip_RGU_TriggerReset(RGU_M0APP_RST);
284 
285  Chip_Clock_Enable(CLK_M4_M0APP);
286 
287  /* Keep in mind the M0 image must be aligned on a 4K boundary */
288  Chip_CREG_SetM0AppMemMap(m0_image_addr);
289 
290  Chip_RGU_ClearReset(RGU_M0APP_RST);
291 
292  return 0;
293 }
294 
295 #endif
296