]> git.sur5r.net Git - freertos/blob
ac8347765af9062dd1409f5c425bf44e3d59504a
[freertos] /
1 /******************************************************************************* \r
2  * Tracealyzer v2.4.1 Recorder Library\r
3  * Percepio AB, www.percepio.com\r
4  *\r
5  * trcHardwarePort.h\r
6  *\r
7  * Contains together with trcHardwarePort.c all hardware portability issues of \r
8  * the trace recorder library.\r
9  *\r
10  * Terms of Use\r
11  * This software is copyright Percepio AB. The recorder library is free for\r
12  * use together with Percepio products. You may distribute the recorder library\r
13  * in its original form, including modifications in trcPort.c and trcPort.h\r
14  * given that these modification are clearly marked as your own modifications\r
15  * and documented in the initial comment section of these source files. \r
16  * This software is the intellectual property of Percepio AB and may not be \r
17  * sold or in other ways commercially redistributed without explicit written \r
18  * permission by Percepio AB.\r
19  *\r
20  * Disclaimer \r
21  * The trace tool and recorder library is being delivered to you AS IS and \r
22  * Percepio AB makes no warranty as to its use or performance. Percepio AB does \r
23  * not and cannot warrant the performance or results you may obtain by using the \r
24  * software or documentation. Percepio AB make no warranties, express or \r
25  * implied, as to noninfringement of third party rights, merchantability, or \r
26  * fitness for any particular purpose. In no event will Percepio AB, its \r
27  * technology partners, or distributors be liable to you for any consequential, \r
28  * incidental or special damages, including any lost profits or lost savings, \r
29  * even if a representative of Percepio AB has been advised of the possibility \r
30  * of such damages, or for any claim by any third party. Some jurisdictions do \r
31  * not allow the exclusion or limitation of incidental, consequential or special \r
32  * damages, or the exclusion of implied warranties or limitations on how long an \r
33  * implied warranty may last, so the above limitations may not apply to you.\r
34  *\r
35  * Copyright Percepio AB, 2013.\r
36  * www.percepio.com\r
37  ******************************************************************************/\r
38 \r
39 #ifndef TRCPORT_H\r
40 #define TRCPORT_H\r
41 \r
42 #include "trcKernelPort.h"\r
43 \r
44 /* If Win32 port */\r
45 #ifdef WIN32\r
46 \r
47    #undef _WIN32_WINNT\r
48    #define _WIN32_WINNT 0x0600\r
49 \r
50    /* Standard includes. */\r
51    #include <stdio.h>\r
52    #include <windows.h>\r
53    #include <direct.h>\r
54 \r
55 /*******************************************************************************\r
56  * The Win32 port by default saves the trace to file and then kills the\r
57  * program when the recorder is stopped, to facilitate quick, simple tests\r
58  * of the recorder.\r
59  ******************************************************************************/\r
60    #define WIN32_PORT_SAVE_WHEN_STOPPED 1\r
61    #define WIN32_PORT_EXIT_WHEN_STOPPED 1\r
62 \r
63 #endif\r
64 \r
65 #define DIRECTION_INCREMENTING 1\r
66 #define DIRECTION_DECREMENTING 2\r
67 \r
68 /******************************************************************************\r
69  * Supported ports\r
70  * \r
71  * PORT_HWIndependent\r
72  * A hardware independent fallback option for event timestamping. Provides low \r
73  * resolution timestamps based on the OS tick.\r
74  * This may be used on the Win32 port, but may also be used on embedded hardware \r
75  * platforms. All time durations will be truncated to the OS tick frequency, \r
76  * typically 1 KHz. This means that a task or ISR that executes in less than \r
77  * 1 ms get an execution time of zero.\r
78  *\r
79  * PORT_Win32\r
80  * "Accurate" timestamping based on the Windows performance counter. Note that\r
81  * this gives the host machine time.\r
82  *\r
83  * Officially supported hardware timer ports:\r
84  * - PORT_Atmel_AT91SAM7\r
85  * - PORT_Atmel_UC3A0\r
86  * - PORT_ARM_CortexM \r
87  * - PORT_Renesas_RX600\r
88  * - PORT_Microchip_dsPIC_AND_PIC24\r
89  *\r
90  * We also provide several "unofficial" hardware-specific ports. There have \r
91  * been developed by external contributors, and have not yet been verified \r
92  * by Percepio AB. Let us know if you have problems getting these to work.\r
93  * \r
94  * Unofficial hardware specific ports provided are:\r
95  * - PORT_TEXAS_INSTRUMENTS_TMS570\r
96  * - PORT_TEXAS_INSTRUMENTS_MSP430\r
97  * - PORT_MICROCHIP_PIC32\r
98  * - PORT_XILINX_PPC405\r
99  * - PORT_XILINX_PPC440\r
100  * - PORT_XILINX_MICROBLAZE\r
101  * - PORT_NXP_LPC210X\r
102  *\r
103  *****************************************************************************/\r
104 \r
105 #define PORT_NOT_SET                          -1\r
106 \r
107 /*** Officially supported hardware timer ports *******************************/\r
108 #define PORT_HWIndependent                     0\r
109 #define PORT_Win32                             1\r
110 #define PORT_Atmel_AT91SAM7                    2\r
111 #define PORT_Atmel_UC3A0                       3\r
112 #define PORT_ARM_CortexM                       4\r
113 #define PORT_Renesas_RX600                     5\r
114 #define PORT_Microchip_dsPIC_AND_PIC24         6\r
115 \r
116 /*** Unofficial ports, provided by external developers, not yet verified *****/\r
117 #define PORT_TEXAS_INSTRUMENTS_TMS570          7\r
118 #define PORT_TEXAS_INSTRUMENTS_MSP430          8\r
119 #define PORT_MICROCHIP_PIC32                   9\r
120 #define PORT_XILINX_PPC405                    10\r
121 #define PORT_XILINX_PPC440                    11\r
122 #define PORT_XILINX_MICROBLAZE                12\r
123 #define PORT_NXP_LPC210X                      13\r
124 \r
125 /*** Select your port here! **************************************************/\r
126 #define SELECTED_PORT PORT_Win32\r
127 /*****************************************************************************/\r
128 \r
129 #if (SELECTED_PORT == PORT_NOT_SET) \r
130 #error "You need to define SELECTED_PORT here!"\r
131 #endif\r
132 \r
133 /*******************************************************************************\r
134  * IRQ_PRIORITY_ORDER\r
135  *\r
136  * Macro which should be defined as an integer of 0 or 1.\r
137  *\r
138  * This should be 0 if lower IRQ priority values implies higher priority \r
139  * levels, such as on ARM Cortex M. If the opposite scheme is used, i.e., \r
140  * if higher IRQ priority values means higher priority, this should be 1.\r
141  *\r
142  * This setting is not critical. It is used only to sort and colorize the \r
143  * interrupts in priority order, in case you record interrupts using\r
144  * the vTraceStoreISRBegin and vTraceStoreISREnd routines.\r
145  *\r
146  * We provide this setting for some hardware architectures below:\r
147  * - ARM Cortex M:       0 (lower IRQ priority values are more significant)\r
148  * - Atmel AT91SAM7x:    1 (higher IRQ priority values are more significant)\r
149  * - Atmel AVR32:        1 (higher IRQ priority values are more significant)\r
150  * - Renesas RX600:      1 (higher IRQ priority values are more significant)\r
151  * - Microchip PIC24:    0 (lower IRQ priority values are more significant)\r
152  * - Microchip dsPIC:    0 (lower IRQ priority values are more significant)\r
153  * - TI TMS570:          0 (lower IRQ priority values are more significant)\r
154  * - Freescale HCS08:    0 (lower IRQ priority values are more significant)\r
155  * - Freescale HCS12:    0 (lower IRQ priority values are more significant)\r
156  * - PowerPC 405:        0 (lower IRQ priority values are more significant)\r
157  * - PowerPC 440:        0 (lower IRQ priority values are more significant)\r
158  * - Freescale ColdFire: 1 (higher IRQ priority values are more significant)\r
159  * - NXP LPC210x:        0 (lower IRQ priority values are more significant)\r
160  * - MicroBlaze:        0  (lower IRQ priority values are more significant)\r
161  *\r
162  * If your chip is not on the above list, and you perhaps know this detail by \r
163  * heart, please inform us by e-mail to support@percepio.com.\r
164  *\r
165  ******************************************************************************\r
166  *\r
167  * HWTC Macros \r
168  *\r
169  * These four HWTC macros provides a hardware isolation layer representing a \r
170  * generic hardware timer/counter used for driving the operating system tick, \r
171  * such as the SysTick feature of ARM Cortex M3/M4, or the PIT of the Atmel \r
172  * AT91SAM7X.\r
173  *\r
174  * HWTC_COUNT: The current value of the counter. This is expected to be reset \r
175  * a each tick interrupt. Thus, when the tick handler starts, the counter has \r
176  * already wrapped.\r
177  *\r
178  * HWTC_COUNT_DIRECTION: Should be one of:\r
179  * - DIRECTION_INCREMENTING - for hardware timer/counters of incrementing type\r
180  *   such as the PIT on Atmel AT91SAM7X.\r
181  *   When the counter value reach HWTC_PERIOD, it is reset to zero and the\r
182  *   interrupt is signaled.\r
183  * - DIRECTION_DECREMENTING - for hardware timer/counters of decrementing type\r
184  *   such as the SysTick on ARM Cortex M3/M4 chips.\r
185  *   When the counter value reach 0, it is reset to HWTC_PERIOD and the\r
186  *   interrupt is signaled.\r
187  *\r
188  * HWTC_PERIOD: The number of increments or decrements of HWTC_COUNT between\r
189  * two tick interrupts. This should preferably be mapped to the reload\r
190  * register of the hardware timer, to make it more portable between chips in the \r
191  * same family. The macro should in most cases be (reload register + 1).\r
192  *\r
193  * HWTC_DIVISOR: If the timer frequency is very high, like on the Cortex M chips\r
194  * (where the SysTick runs at the core clock frequency), the "differential \r
195  * timestamping" used in the recorder will more frequently insert extra XTS \r
196  * events to store the timestamps, which increases the event buffer usage. \r
197  * In such cases, to reduce the number of XTS events and thereby get longer \r
198  * traces, you use HWTC_DIVISOR to scale down the timestamps and frequency.\r
199  * Assuming a OS tick rate of 1 KHz, it is suggested to keep the effective timer\r
200  * frequency below 65 MHz to avoid an excessive amount of XTS events. Thus, a\r
201  * Cortex M chip running at 72 MHZ should use a HWTC_DIVISOR of 2, while a \r
202  * faster chip require a higher HWTC_DIVISOR value. \r
203  *\r
204  * The HWTC macros and vTracePortGetTimeStamp is the main porting issue\r
205  * or the trace recorder library. Typically you should not need to change\r
206  * the code of vTracePortGetTimeStamp if using the HWTC macros.\r
207  *\r
208  ******************************************************************************/\r
209 \r
210 #if (SELECTED_PORT == PORT_Win32)\r
211     \r
212     #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING\r
213     #define HWTC_COUNT (ulGetRunTimeCounterValue())\r
214     #define HWTC_PERIOD 0\r
215     #define HWTC_DIVISOR 1\r
216     \r
217     #define IRQ_PRIORITY_ORDER 1  // Please update according to your hardware...\r
218 \r
219 #elif (SELECTED_PORT == PORT_HWIndependent)\r
220     \r
221     #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING\r
222     #define HWTC_COUNT 0\r
223     #define HWTC_PERIOD 1\r
224     #define HWTC_DIVISOR 1\r
225 \r
226     #define IRQ_PRIORITY_ORDER 1  // Please update according to your hardware...\r
227 \r
228 #elif (SELECTED_PORT == PORT_Atmel_AT91SAM7)\r
229 \r
230     /* HWTC_PERIOD is hardcoded for AT91SAM7X256-EK Board (48 MHz)\r
231     A more generic solution is to get the period from pxPIT->PITC_PIMR */\r
232     \r
233     #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING\r
234     #define HWTC_COUNT (AT91C_BASE_PITC->PITC_PIIR & 0xFFFFF)\r
235     #define HWTC_PERIOD 2995 \r
236     #define HWTC_DIVISOR 1\r
237 \r
238     #define IRQ_PRIORITY_ORDER 1  // higher IRQ priority values are more significant\r
239 \r
240 #elif (SELECTED_PORT == PORT_Atmel_UC3A0) \r
241   \r
242     /* For Atmel AVR32 (AT32UC3A) */\r
243   \r
244     #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING\r
245     #define HWTC_COUNT sysreg_read(AVR32_COUNT)\r
246     #define HWTC_PERIOD ( TRACE_CPU_CLOCK_HZ / TRACE_TICK_RATE_HZ )\r
247     #define HWTC_DIVISOR 1    \r
248 \r
249     #define IRQ_PRIORITY_ORDER 1  // higher IRQ priority values are more significant\r
250 \r
251 #elif (SELECTED_PORT == PORT_ARM_CortexM)\r
252 \r
253     /* For all chips using ARM Cortex M cores */\r
254 \r
255     #define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING\r
256     #define HWTC_COUNT (*((uint32_t*)0xE000E018))\r
257     #define HWTC_PERIOD ((*(uint32_t*)0xE000E014) + 1)\r
258     #define HWTC_DIVISOR 2\r
259     \r
260     #define IRQ_PRIORITY_ORDER 0  // lower IRQ priority values are more significant\r
261 \r
262 #elif (SELECTED_PORT == PORT_Renesas_RX600)    \r
263 \r
264     #include "iodefine.h"\r
265 \r
266     #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING\r
267     #define HWTC_COUNT (CMT0.CMCNT)\r
268     #define HWTC_PERIOD ((((TRACE_PERIPHERAL_CLOCK_HZ/TRACE_TICK_RATE_HZ)-1)/8))\r
269     #define HWTC_DIVISOR 1\r
270 \r
271     #define IRQ_PRIORITY_ORDER 1  // higher IRQ priority values are more significant\r
272 \r
273 #elif (SELECTED_PORT == PORT_Microchip_dsPIC_AND_PIC24) \r
274 \r
275     /* For Microchip PIC24 and dsPIC (16 bit) */\r
276 \r
277     /* Note: The trace library was originally designed for 32-bit MCUs, and is slower\r
278        than intended on 16-bit MCUs. Storing an event on a PIC24 takes about 70 µs. \r
279        In comparison, 32-bit MCUs are often 10-20 times faster. If recording overhead \r
280        becomes a problem on PIC24, use the filters to exclude less interesting tasks \r
281        or system calls. */\r
282 \r
283     #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING\r
284     #define HWTC_COUNT (TMR1)\r
285     #define HWTC_PERIOD (PR1+1)\r
286     #define HWTC_DIVISOR 1\r
287 \r
288     #define IRQ_PRIORITY_ORDER 0  // lower IRQ priority values are more significant\r
289 \r
290 #elif (SELECTED_PORT == PORT_NXP_LPC210X)\r
291     /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */\r
292     \r
293     /* Tested with LPC2106, but should work with most LPC21XX chips. */\r
294       \r
295     #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING\r
296     #define HWTC_COUNT  *((uint32_t *)0xE0004008 )\r
297     #define HWTC_PERIOD ( TRACE_CPU_CLOCK_HZ / TRACE_TICK_RATE_HZ ) \r
298     #define HWTC_DIVISOR 1    \r
299 \r
300     #define IRQ_PRIORITY_ORDER 0  // lower IRQ priority values are more significant\r
301 \r
302 #elif (SELECTED_PORT == PORT_TEXAS_INSTRUMENTS_TMS570)\r
303     /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */\r
304 \r
305     #define RTIFRC0 *((uint32_t *)0xFFFFFC10)\r
306     #define RTICOMP0 *((uint32_t *)0xFFFFFC50)\r
307     #define RTIUDCP0 *((uint32_t *)0xFFFFFC54)\r
308     #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING\r
309     #define HWTC_COUNT (RTIFRC0 - (RTICOMP0 - RTIUDCP0))\r
310     #define HWTC_PERIOD (RTIUDCP0)\r
311     #define HWTC_DIVISOR 1\r
312 \r
313     #define IRQ_PRIORITY_ORDER 0  // lower IRQ priority values are more significant\r
314 \r
315 #elif (SELECTED_PORT == PORT_TEXAS_INSTRUMENTS_MSP430)\r
316     /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */\r
317 \r
318     #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING\r
319     #define HWTC_COUNT (TA0R)\r
320     #define HWTC_PERIOD TRACE_CPU_CLOCKS_PER_TICK      \r
321     #define HWTC_DIVISOR 1\r
322 \r
323     #define IRQ_PRIORITY_ORDER 1  // higher IRQ priority values are more significant\r
324 \r
325 #elif (SELECTED_PORT == PORT_MICROCHIP_PIC32)\r
326     /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */\r
327 \r
328     #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING\r
329     #define HWTC_COUNT (ReadTimer1())     /* Should be available in BSP */\r
330     #define HWTC_PERIOD (ReadPeriod1()+1) /* Should be available in BSP */\r
331     #define HWTC_DIVISOR 1\r
332 \r
333     #define IRQ_PRIORITY_ORDER 0  // lower IRQ priority values are more significant\r
334 \r
335 #elif (SELECTED_PORT == PORT_XILINX_PPC405) \r
336     /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */\r
337 \r
338     #define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING\r
339     #define HWTC_COUNT  mfspr( 0x3db)\r
340     #define HWTC_PERIOD ( TRACE_CPU_CLOCK_HZ / TRACE_TICK_RATE_HZ )\r
341     #define HWTC_DIVISOR 1\r
342 \r
343     #define IRQ_PRIORITY_ORDER 0  // lower IRQ priority values are more significant\r
344 \r
345 #elif (SELECTED_PORT == PORT_XILINX_PPC440) \r
346     /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */\r
347 \r
348     /* This should work with most PowerPC chips */\r
349     \r
350     #define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING\r
351     #define HWTC_COUNT  mfspr( 0x016 )\r
352     #define HWTC_PERIOD ( TRACE_CPU_CLOCK_HZ / TRACE_TICK_RATE_HZ )\r
353     #define HWTC_DIVISOR 1    \r
354 \r
355     #define IRQ_PRIORITY_ORDER 0  // lower IRQ priority values are more significant\r
356     \r
357 #elif (SELECTED_PORT == PORT_XILINX_MICROBLAZE)\r
358     /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */\r
359 \r
360     /* This should work with most Microblaze configurations.\r
361      * It uses the AXI Timer 0 - the tick interrupt source.\r
362      * If an AXI Timer 0 peripheral is available on your hardware platform, no modifications are required.\r
363      */\r
364     #include "xtmrctr_l.h"\r
365 \r
366     #define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING\r
367     #define HWTC_COUNT XTmrCtr_GetTimerCounterReg( XPAR_TMRCTR_0_BASEADDR, 0 )\r
368     #define HWTC_PERIOD ( TRACE_CPU_CLOCK_HZ / TRACE_TICK_RATE_HZ )\r
369     #define HWTC_DIVISOR 16\r
370 \r
371     #define IRQ_PRIORITY_ORDER 0  // lower IRQ priority values are more significant\r
372 \r
373 #elif (SELECTED_PORT != PORT_NOT_SET)\r
374 \r
375     #error "SELECTED_PORT had unsupported value!"\r
376     #define SELECTED_PORT PORT_NOT_SET\r
377 \r
378 #endif\r
379 \r
380 #if (SELECTED_PORT != PORT_NOT_SET)\r
381     \r
382     #ifndef HWTC_COUNT_DIRECTION\r
383     #error "HWTC_COUNT_DIRECTION is not set!"\r
384     #endif \r
385     \r
386     #ifndef HWTC_COUNT\r
387     #error "HWTC_COUNT is not set!"    \r
388     #endif \r
389     \r
390     #ifndef HWTC_PERIOD\r
391     #error "HWTC_PERIOD is not set!"\r
392     #endif \r
393     \r
394     #ifndef HWTC_DIVISOR\r
395     #error "HWTC_DIVISOR is not set!"    \r
396     #endif \r
397     \r
398     #ifndef IRQ_PRIORITY_ORDER\r
399     #error "IRQ_PRIORITY_ORDER is not set!"\r
400     #elif (IRQ_PRIORITY_ORDER != 0) && (IRQ_PRIORITY_ORDER != 1)\r
401     #error "IRQ_PRIORITY_ORDER has bad value!"\r
402     #endif \r
403     \r
404     #if (HWTC_DIVISOR < 1)\r
405     #error "HWTC_DIVISOR must be a non-zero positive value!"\r
406     #endif \r
407 \r
408 #endif\r
409 /*******************************************************************************\r
410  * vTraceConsoleMessage\r
411  *\r
412  * A wrapper for your system-specific console "printf" console output function.\r
413  * This needs to be correctly defined to see status reports from the trace \r
414  * status monitor task (this is defined in trcUser.c).\r
415  ******************************************************************************/         \r
416 #if (SELECTED_PORT == PORT_Atmel_AT91SAM7)\r
417 /* Port specific includes */\r
418 #include "console.h"\r
419 #endif\r
420 \r
421 #define vTraceConsoleMessage(x)\r
422 \r
423 /*******************************************************************************\r
424  * vTracePortGetTimeStamp\r
425  *\r
426  * Returns the current time based on the HWTC macros which provide a hardware\r
427  * isolation layer towards the hardware timer/counter.\r
428  *\r
429  * The HWTC macros and vTracePortGetTimeStamp is the main porting issue\r
430  * or the trace recorder library. Typically you should not need to change\r
431  * the code of vTracePortGetTimeStamp if using the HWTC macros.\r
432  *\r
433  ******************************************************************************/\r
434 void vTracePortGetTimeStamp(uint32_t *puiTimestamp);\r
435 \r
436 /*******************************************************************************\r
437  * vTracePortEnd\r
438  * \r
439  * This function is called when the recorder is stopped due to full buffer.\r
440  * Mainly intended to show a message in the console.\r
441  * This is used by the Win32 port to store the trace to a file. The file path is\r
442  * set using vTracePortSetFileName.\r
443  ******************************************************************************/\r
444 void vTracePortEnd(void);\r
445 \r
446 #if (INCLUDE_SAVE_TO_FILE == 1)\r
447 \r
448 /*******************************************************************************\r
449  * vTracePortSetOutFile\r
450  *\r
451  * Sets the filename/path used in vTracePortSave.\r
452  * This is set in a separate function, since the Win32 port calls vTracePortSave\r
453  * in vTracePortEnd if WIN32_PORT_SAVE_WHEN_STOPPED is set.\r
454  ******************************************************************************/\r
455 void vTracePortSetOutFile(char* path);\r
456 \r
457 /******************************************************************************\r
458  * vTracePortSave\r
459  *\r
460  * Saves the trace to a file on a target-side file system. The path is set in a \r
461  * separate function, vTracePortSetOutFile, since the Win32 port may call\r
462  * vTracePortSave in vTracePortEnd, if using WIN32_PORT_SAVE_WHEN_STOPPED.\r
463  ******************************************************************************/\r
464 void vTracePortSave(void);\r
465 \r
466 #else\r
467 \r
468 #define vTraceConsoleMessage(x)\r
469 #define vTracePortSetOutFile(path)\r
470 #define vTracePortSave(void)\r
471 \r
472 #endif\r
473 \r
474 #endif\r