summaryrefslogtreecommitdiff
path: root/FreeRTOS-Labs/Demo/FreeRTOS_Plus_TCP_and_FAT_Windows_Simulator/trcHardwarePort.h
blob: c324445ff45b5c7faab023948c63c160de2f7338 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
/*******************************************************************************
 * Tracealyzer v2.4.1 Recorder Library
 * Percepio AB, www.percepio.com
 *
 * trcHardwarePort.h
 *
 * Contains together with trcHardwarePort.c all hardware portability issues of
 * the trace recorder library.
 *
 * Terms of Use
 * This software is copyright Percepio AB. The recorder library is free for
 * use together with Percepio products. You may distribute the recorder library
 * in its original form, including modifications in trcPort.c and trcPort.h
 * given that these modification are clearly marked as your own modifications
 * and documented in the initial comment section of these source files.
 * This software is the intellectual property of Percepio AB and may not be
 * sold or in other ways commercially redistributed without explicit written
 * permission by Percepio AB.
 *
 * Disclaimer
 * The trace tool and recorder library is being delivered to you AS IS and
 * Percepio AB makes no warranty as to its use or performance. Percepio AB does
 * not and cannot warrant the performance or results you may obtain by using the
 * software or documentation. Percepio AB make no warranties, express or
 * implied, as to noninfringement of third party rights, merchantability, or
 * fitness for any particular purpose. In no event will Percepio AB, its
 * technology partners, or distributors be liable to you for any consequential,
 * incidental or special damages, including any lost profits or lost savings,
 * even if a representative of Percepio AB has been advised of the possibility
 * of such damages, or for any claim by any third party. Some jurisdictions do
 * not allow the exclusion or limitation of incidental, consequential or special
 * damages, or the exclusion of implied warranties or limitations on how long an
 * implied warranty may last, so the above limitations may not apply to you.
 *
 * Copyright Percepio AB, 2013.
 * www.percepio.com
 ******************************************************************************/

#ifndef TRCPORT_H
#define TRCPORT_H

#include "trcKernelPort.h"

/* If Win32 port */
#ifdef WIN32

   #undef _WIN32_WINNT
   #define _WIN32_WINNT 0x0600

   /* Standard includes. */
   #include <stdio.h>
   #include <windows.h>
   #include <direct.h>

/*******************************************************************************
 * The Win32 port by default saves the trace to file and then kills the
 * program when the recorder is stopped, to facilitate quick, simple tests
 * of the recorder.
 ******************************************************************************/
   #define WIN32_PORT_SAVE_WHEN_STOPPED 1
   #define WIN32_PORT_EXIT_WHEN_STOPPED 1

#endif

#define DIRECTION_INCREMENTING 1
#define DIRECTION_DECREMENTING 2

/******************************************************************************
 * Supported ports
 *
 * PORT_HWIndependent
 * A hardware independent fallback option for event timestamping. Provides low
 * resolution timestamps based on the OS tick.
 * This may be used on the Win32 port, but may also be used on embedded hardware
 * platforms. All time durations will be truncated to the OS tick frequency,
 * typically 1 KHz. This means that a task or ISR that executes in less than
 * 1 ms get an execution time of zero.
 *
 * PORT_Win32
 * "Accurate" timestamping based on the Windows performance counter. Note that
 * this gives the host machine time.
 *
 * Officially supported hardware timer ports:
 * - PORT_Atmel_AT91SAM7
 * - PORT_Atmel_UC3A0
 * - PORT_ARM_CortexM
 * - PORT_Renesas_RX600
 * - PORT_Microchip_dsPIC_AND_PIC24
 *
 * We also provide several "unofficial" hardware-specific ports. There have
 * been developed by external contributors, and have not yet been verified
 * by Percepio AB. Let us know if you have problems getting these to work.
 *
 * Unofficial hardware specific ports provided are:
 * - PORT_TEXAS_INSTRUMENTS_TMS570
 * - PORT_TEXAS_INSTRUMENTS_MSP430
 * - PORT_MICROCHIP_PIC32
 * - PORT_XILINX_PPC405
 * - PORT_XILINX_PPC440
 * - PORT_XILINX_MICROBLAZE
 * - PORT_NXP_LPC210X
 *
 *****************************************************************************/

#define PORT_NOT_SET                          -1

/*** Officially supported hardware timer ports *******************************/
#define PORT_HWIndependent                     0
#define PORT_Win32                             1
#define PORT_Atmel_AT91SAM7                    2
#define PORT_Atmel_UC3A0                       3
#define PORT_ARM_CortexM                       4
#define PORT_Renesas_RX600                     5
#define PORT_Microchip_dsPIC_AND_PIC24         6

/*** Unofficial ports, provided by external developers, not yet verified *****/
#define PORT_TEXAS_INSTRUMENTS_TMS570          7
#define PORT_TEXAS_INSTRUMENTS_MSP430          8
#define PORT_MICROCHIP_PIC32                   9
#define PORT_XILINX_PPC405                    10
#define PORT_XILINX_PPC440                    11
#define PORT_XILINX_MICROBLAZE                12
#define PORT_NXP_LPC210X                      13

/*** Select your port here! **************************************************/
#define SELECTED_PORT PORT_Win32
/*****************************************************************************/

#if (SELECTED_PORT == PORT_NOT_SET)
#error "You need to define SELECTED_PORT here!"
#endif

/*******************************************************************************
 * IRQ_PRIORITY_ORDER
 *
 * Macro which should be defined as an integer of 0 or 1.
 *
 * This should be 0 if lower IRQ priority values implies higher priority
 * levels, such as on ARM Cortex M. If the opposite scheme is used, i.e.,
 * if higher IRQ priority values means higher priority, this should be 1.
 *
 * This setting is not critical. It is used only to sort and colorize the
 * interrupts in priority order, in case you record interrupts using
 * the vTraceStoreISRBegin and vTraceStoreISREnd routines.
 *
 * We provide this setting for some hardware architectures below:
 * - ARM Cortex M:       0 (lower IRQ priority values are more significant)
 * - Atmel AT91SAM7x:    1 (higher IRQ priority values are more significant)
 * - Atmel AVR32:        1 (higher IRQ priority values are more significant)
 * - Renesas RX600:      1 (higher IRQ priority values are more significant)
 * - Microchip PIC24:    0 (lower IRQ priority values are more significant)
 * - Microchip dsPIC:    0 (lower IRQ priority values are more significant)
 * - TI TMS570:          0 (lower IRQ priority values are more significant)
 * - Freescale HCS08:    0 (lower IRQ priority values are more significant)
 * - Freescale HCS12:    0 (lower IRQ priority values are more significant)
 * - PowerPC 405:        0 (lower IRQ priority values are more significant)
 * - PowerPC 440:        0 (lower IRQ priority values are more significant)
 * - Freescale ColdFire: 1 (higher IRQ priority values are more significant)
 * - NXP LPC210x:        0 (lower IRQ priority values are more significant)
 * - MicroBlaze:        0  (lower IRQ priority values are more significant)
 *
 * If your chip is not on the above list, and you perhaps know this detail by
 * heart, please inform us by e-mail to support@percepio.com.
 *
 ******************************************************************************
 *
 * HWTC Macros
 *
 * These four HWTC macros provides a hardware isolation layer representing a
 * generic hardware timer/counter used for driving the operating system tick,
 * such as the SysTick feature of ARM Cortex M3/M4, or the PIT of the Atmel
 * AT91SAM7X.
 *
 * HWTC_COUNT: The current value of the counter. This is expected to be reset
 * a each tick interrupt. Thus, when the tick handler starts, the counter has
 * already wrapped.
 *
 * HWTC_COUNT_DIRECTION: Should be one of:
 * - DIRECTION_INCREMENTING - for hardware timer/counters of incrementing type
 *   such as the PIT on Atmel AT91SAM7X.
 *   When the counter value reach HWTC_PERIOD, it is reset to zero and the
 *   interrupt is signaled.
 * - DIRECTION_DECREMENTING - for hardware timer/counters of decrementing type
 *   such as the SysTick on ARM Cortex M3/M4 chips.
 *   When the counter value reach 0, it is reset to HWTC_PERIOD and the
 *   interrupt is signaled.
 *
 * HWTC_PERIOD: The number of increments or decrements of HWTC_COUNT between
 * two tick interrupts. This should preferably be mapped to the reload
 * register of the hardware timer, to make it more portable between chips in the
 * same family. The macro should in most cases be (reload register + 1).
 *
 * HWTC_DIVISOR: If the timer frequency is very high, like on the Cortex M chips
 * (where the SysTick runs at the core clock frequency), the "differential
 * timestamping" used in the recorder will more frequently insert extra XTS
 * events to store the timestamps, which increases the event buffer usage.
 * In such cases, to reduce the number of XTS events and thereby get longer
 * traces, you use HWTC_DIVISOR to scale down the timestamps and frequency.
 * Assuming a OS tick rate of 1 KHz, it is suggested to keep the effective timer
 * frequency below 65 MHz to avoid an excessive amount of XTS events. Thus, a
 * Cortex M chip running at 72 MHZ should use a HWTC_DIVISOR of 2, while a
 * faster chip require a higher HWTC_DIVISOR value.
 *
 * The HWTC macros and vTracePortGetTimeStamp is the main porting issue
 * or the trace recorder library. Typically you should not need to change
 * the code of vTracePortGetTimeStamp if using the HWTC macros.
 *
 ******************************************************************************/

#if (SELECTED_PORT == PORT_Win32)

    #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
    #define HWTC_COUNT (ulGetRunTimeCounterValue())
    #define HWTC_PERIOD 0
    #define HWTC_DIVISOR 1

    #define IRQ_PRIORITY_ORDER 1  // Please update according to your hardware...

#elif (SELECTED_PORT == PORT_HWIndependent)

    #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
    #define HWTC_COUNT 0
    #define HWTC_PERIOD 1
    #define HWTC_DIVISOR 1

    #define IRQ_PRIORITY_ORDER 1  // Please update according to your hardware...

#elif (SELECTED_PORT == PORT_Atmel_AT91SAM7)

    /* HWTC_PERIOD is hardcoded for AT91SAM7X256-EK Board (48 MHz)
    A more generic solution is to get the period from pxPIT->PITC_PIMR */

    #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
    #define HWTC_COUNT (AT91C_BASE_PITC->PITC_PIIR & 0xFFFFF)
    #define HWTC_PERIOD 2995
    #define HWTC_DIVISOR 1

    #define IRQ_PRIORITY_ORDER 1  // higher IRQ priority values are more significant

#elif (SELECTED_PORT == PORT_Atmel_UC3A0)

    /* For Atmel AVR32 (AT32UC3A) */

    #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
    #define HWTC_COUNT sysreg_read(AVR32_COUNT)
    #define HWTC_PERIOD ( TRACE_CPU_CLOCK_HZ / TRACE_TICK_RATE_HZ )
    #define HWTC_DIVISOR 1

    #define IRQ_PRIORITY_ORDER 1  // higher IRQ priority values are more significant

#elif (SELECTED_PORT == PORT_ARM_CortexM)

    /* For all chips using ARM Cortex M cores */

    #define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING
    #define HWTC_COUNT (*((uint32_t*)0xE000E018))
    #define HWTC_PERIOD ((*(uint32_t*)0xE000E014) + 1)
    #define HWTC_DIVISOR 2

    #define IRQ_PRIORITY_ORDER 0  // lower IRQ priority values are more significant

#elif (SELECTED_PORT == PORT_Renesas_RX600)

    #include "iodefine.h"

    #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
    #define HWTC_COUNT (CMT0.CMCNT)
    #define HWTC_PERIOD ((((TRACE_PERIPHERAL_CLOCK_HZ/TRACE_TICK_RATE_HZ)-1)/8))
    #define HWTC_DIVISOR 1

    #define IRQ_PRIORITY_ORDER 1  // higher IRQ priority values are more significant

#elif (SELECTED_PORT == PORT_Microchip_dsPIC_AND_PIC24)

    /* For Microchip PIC24 and dsPIC (16 bit) */

    /* Note: The trace library was originally designed for 32-bit MCUs, and is slower
       than intended on 16-bit MCUs. Storing an event on a PIC24 takes about 70 µs.
       In comparison, 32-bit MCUs are often 10-20 times faster. If recording overhead
       becomes a problem on PIC24, use the filters to exclude less interesting tasks
       or system calls. */

    #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
    #define HWTC_COUNT (TMR1)
    #define HWTC_PERIOD (PR1+1)
    #define HWTC_DIVISOR 1

    #define IRQ_PRIORITY_ORDER 0  // lower IRQ priority values are more significant

#elif (SELECTED_PORT == PORT_NXP_LPC210X)
    /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */

    /* Tested with LPC2106, but should work with most LPC21XX chips. */

    #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
    #define HWTC_COUNT  *((uint32_t *)0xE0004008 )
    #define HWTC_PERIOD ( TRACE_CPU_CLOCK_HZ / TRACE_TICK_RATE_HZ )
    #define HWTC_DIVISOR 1

    #define IRQ_PRIORITY_ORDER 0  // lower IRQ priority values are more significant

#elif (SELECTED_PORT == PORT_TEXAS_INSTRUMENTS_TMS570)
    /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */

    #define RTIFRC0 *((uint32_t *)0xFFFFFC10)
    #define RTICOMP0 *((uint32_t *)0xFFFFFC50)
    #define RTIUDCP0 *((uint32_t *)0xFFFFFC54)
    #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
    #define HWTC_COUNT (RTIFRC0 - (RTICOMP0 - RTIUDCP0))
    #define HWTC_PERIOD (RTIUDCP0)
    #define HWTC_DIVISOR 1

    #define IRQ_PRIORITY_ORDER 0  // lower IRQ priority values are more significant

#elif (SELECTED_PORT == PORT_TEXAS_INSTRUMENTS_MSP430)
    /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */

    #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
    #define HWTC_COUNT (TA0R)
    #define HWTC_PERIOD TRACE_CPU_CLOCKS_PER_TICK
    #define HWTC_DIVISOR 1

    #define IRQ_PRIORITY_ORDER 1  // higher IRQ priority values are more significant

#elif (SELECTED_PORT == PORT_MICROCHIP_PIC32)
    /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */

    #define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
    #define HWTC_COUNT (ReadTimer1())     /* Should be available in BSP */
    #define HWTC_PERIOD (ReadPeriod1()+1) /* Should be available in BSP */
    #define HWTC_DIVISOR 1

    #define IRQ_PRIORITY_ORDER 0  // lower IRQ priority values are more significant

#elif (SELECTED_PORT == PORT_XILINX_PPC405)
    /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */

    #define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING
    #define HWTC_COUNT  mfspr( 0x3db)
    #define HWTC_PERIOD ( TRACE_CPU_CLOCK_HZ / TRACE_TICK_RATE_HZ )
    #define HWTC_DIVISOR 1

    #define IRQ_PRIORITY_ORDER 0  // lower IRQ priority values are more significant

#elif (SELECTED_PORT == PORT_XILINX_PPC440)
    /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */

    /* This should work with most PowerPC chips */

    #define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING
    #define HWTC_COUNT  mfspr( 0x016 )
    #define HWTC_PERIOD ( TRACE_CPU_CLOCK_HZ / TRACE_TICK_RATE_HZ )
    #define HWTC_DIVISOR 1

    #define IRQ_PRIORITY_ORDER 0  // lower IRQ priority values are more significant

#elif (SELECTED_PORT == PORT_XILINX_MICROBLAZE)
    /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */

    /* This should work with most Microblaze configurations.
     * It uses the AXI Timer 0 - the tick interrupt source.
     * If an AXI Timer 0 peripheral is available on your hardware platform, no modifications are required.
     */
    #include "xtmrctr_l.h"

    #define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING
    #define HWTC_COUNT XTmrCtr_GetTimerCounterReg( XPAR_TMRCTR_0_BASEADDR, 0 )
    #define HWTC_PERIOD ( TRACE_CPU_CLOCK_HZ / TRACE_TICK_RATE_HZ )
    #define HWTC_DIVISOR 16

    #define IRQ_PRIORITY_ORDER 0  // lower IRQ priority values are more significant

#elif (SELECTED_PORT != PORT_NOT_SET)

    #error "SELECTED_PORT had unsupported value!"
    #define SELECTED_PORT PORT_NOT_SET

#endif

#if (SELECTED_PORT != PORT_NOT_SET)

    #ifndef HWTC_COUNT_DIRECTION
    #error "HWTC_COUNT_DIRECTION is not set!"
    #endif

    #ifndef HWTC_COUNT
    #error "HWTC_COUNT is not set!"
    #endif

    #ifndef HWTC_PERIOD
    #error "HWTC_PERIOD is not set!"
    #endif

    #ifndef HWTC_DIVISOR
    #error "HWTC_DIVISOR is not set!"
    #endif

    #ifndef IRQ_PRIORITY_ORDER
    #error "IRQ_PRIORITY_ORDER is not set!"
    #elif (IRQ_PRIORITY_ORDER != 0) && (IRQ_PRIORITY_ORDER != 1)
    #error "IRQ_PRIORITY_ORDER has bad value!"
    #endif

    #if (HWTC_DIVISOR < 1)
    #error "HWTC_DIVISOR must be a non-zero positive value!"
    #endif

#endif
/*******************************************************************************
 * vTraceConsoleMessage
 *
 * A wrapper for your system-specific console "printf" console output function.
 * This needs to be correctly defined to see status reports from the trace
 * status monitor task (this is defined in trcUser.c).
 ******************************************************************************/
#if (SELECTED_PORT == PORT_Atmel_AT91SAM7)
/* Port specific includes */
#include "console.h"
#endif

#define vTraceConsoleMessage(x)

/*******************************************************************************
 * vTracePortGetTimeStamp
 *
 * Returns the current time based on the HWTC macros which provide a hardware
 * isolation layer towards the hardware timer/counter.
 *
 * The HWTC macros and vTracePortGetTimeStamp is the main porting issue
 * or the trace recorder library. Typically you should not need to change
 * the code of vTracePortGetTimeStamp if using the HWTC macros.
 *
 ******************************************************************************/
void vTracePortGetTimeStamp(uint32_t *puiTimestamp);

/*******************************************************************************
 * vTracePortEnd
 *
 * This function is called when the recorder is stopped due to full buffer.
 * Mainly intended to show a message in the console.
 * This is used by the Win32 port to store the trace to a file. The file path is
 * set using vTracePortSetFileName.
 ******************************************************************************/
void vTracePortEnd(void);

#if (INCLUDE_SAVE_TO_FILE == 1)

/*******************************************************************************
 * vTracePortSetOutFile
 *
 * Sets the filename/path used in vTracePortSave.
 * This is set in a separate function, since the Win32 port calls vTracePortSave
 * in vTracePortEnd if WIN32_PORT_SAVE_WHEN_STOPPED is set.
 ******************************************************************************/
void vTracePortSetOutFile(char* path);

/******************************************************************************
 * vTracePortSave
 *
 * Saves the trace to a file on a target-side file system. The path is set in a
 * separate function, vTracePortSetOutFile, since the Win32 port may call
 * vTracePortSave in vTracePortEnd, if using WIN32_PORT_SAVE_WHEN_STOPPED.
 ******************************************************************************/
void vTracePortSave(void);

#else

#define vTraceConsoleMessage(x)
#define vTracePortSetOutFile(path)
#define vTracePortSave(void)

#endif

#endif