2 # Copyright (C) 2015 Xilinx, Inc.
\r
4 # This file is part of the FreeRTOS port.
\r
6 # FreeRTOS is free software; you can redistribute it and/or modify it under
\r
7 # the terms of the GNU General Public License (version 2) as published by the
\r
8 # Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
\r
10 # NOTE: The modification to the GPL is included to allow you to distribute a
\r
11 # combined work that includes FreeRTOS without being obliged to provide the
\r
12 # source code for proprietary components outside of the FreeRTOS kernel.
\r
14 # FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
\r
15 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
\r
16 # FOR A PARTICULAR PURPOSE. Full license text is available on the following
\r
17 # link: http://www.freertos.org/a00114.html
\r
21 # standalone bsp version. set this to the latest "ACTIVE" version.
\r
22 set standalone_version standalone_v5_0
\r
24 proc FreeRTOS_drc {os_handle} {
\r
28 set sw_proc_handle [hsi::get_sw_processor]
\r
29 set hw_proc_handle [hsi::get_cells [common::get_property HW_INSTANCE $sw_proc_handle] ]
\r
30 set proctype [common::get_property IPNAME $hw_proc_handle]
\r
32 if { $proctype == "microblaze" } {
\r
37 proc generate {os_handle} {
\r
39 variable standalone_version
\r
40 set have_tick_timer 0
\r
41 set sw_proc_handle [hsi::get_sw_processor]
\r
42 set hw_proc_handle [hsi::get_cells [common::get_property HW_INSTANCE $sw_proc_handle] ]
\r
43 set proctype [common::get_property IP_NAME $hw_proc_handle]
\r
44 set need_config_file "false"
\r
46 set commonsrcdir "../${standalone_version}/src/common"
\r
47 set mbsrcdir "../${standalone_version}/src/microblaze"
\r
48 set arma9srcdir "../${standalone_version}/src/cortexa9"
\r
49 set arma9gccdir "../${standalone_version}/src/cortexa9/gcc"
\r
50 set arma9armccdir "../${standalone_version}/src/cortexa9/armcc"
\r
51 set arma9iarccdir "../${standalone_version}/src/cortexa9/iarcc"
\r
53 foreach entry [glob -nocomplain [file join $commonsrcdir *]] {
\r
54 file copy -force $entry [file join ".." "${standalone_version}" "src"]
\r
60 puts "In start copy ps7_cortexa9"
\r
61 file copy -force "./src/Makefile_ps7_cortexa9" "./src/Makefile"
\r
62 file copy -force "./src/Makefile" "./src/Makefile_dep"
\r
64 foreach entry [glob -nocomplain [file join $arma9srcdir *]] {
\r
65 file copy -force $entry [file join ".." "${standalone_version}" "src"]
\r
68 foreach entry [glob -nocomplain [file join $arma9gccdir *]] {
\r
69 file copy -force $entry [file join ".." "${standalone_version}" "src"]
\r
72 file delete -force "../${standalone_version}/src/gcc"
\r
74 set need_config_file "true"
\r
76 set file_handle [::hsi::utils::open_include_file "xparameters.h"]
\r
77 puts $file_handle "#include \"xparameters_ps.h\""
\r
78 puts $file_handle ""
\r
83 puts "In start copy microblaze"
\r
84 file copy -force "./src/Makefile_microblaze" "./src/Makefile"
\r
85 file copy -force "./src/Makefile" "./src/Makefile_dep"
\r
87 foreach entry [glob -nocomplain [file join $mbsrcdir *]] {
\r
88 if { [string first "microblaze_interrupt_handler" $entry] == -1 } { ;# Do not copy over the Standalone BSP exception handler
\r
89 file copy -force $entry [file join ".." "${standalone_version}" "src"]
\r
93 set need_config_file "true"
\r
97 puts "processor type $proctype not supported\n"
\r
101 # Write the Config.make file
\r
102 set makeconfig [open "../${standalone_version}/src/config.make" w]
\r
103 file rename -force -- "../${standalone_version}/src/Makefile" "../${standalone_version}/src/Makefile_depends"
\r
105 if { $proctype == "ps7_cortexa9" || $proctype == "microblaze" } {
\r
106 puts $makeconfig "LIBSOURCES = *.c *.S"
\r
107 puts $makeconfig "LIBS = standalone_libs"
\r
112 # Remove arm directory...
\r
113 file delete -force $arma9srcdir
\r
114 file delete -force $mbsrcdir
\r
116 # Copy core kernel files to the main src directory
\r
117 file copy -force [file join src Source tasks.c] ./src
\r
118 file copy -force [file join src Source queue.c] ./src
\r
119 file copy -force [file join src Source list.c] ./src
\r
120 file copy -force [file join src Source timers.c] ./src
\r
121 file copy -force [file join src Source event_groups.c] ./src
\r
122 file copy -force [file join src Source portable MemMang heap_4.c] ./src
\r
124 if { $proctype == "ps7_cortexa9" } {
\r
125 file copy -force [file join src Source portable GCC ARM_CA9 port.c] ./src
\r
126 file copy -force [file join src Source portable GCC ARM_CA9 portASM.S] ./src
\r
127 file copy -force [file join src Source portable GCC ARM_CA9 port_asm_vectors.S] ./src
\r
128 file copy -force [file join src Source portable GCC ARM_CA9 portmacro.h] ./src
\r
129 file copy -force [file join src Source portable GCC ARM_CA9 portZynq7000.c] ./src
\r
132 if { $proctype == "microblaze" } {
\r
133 file copy -force [file join src Source portable GCC MicroBlazeV8 port.c] ./src
\r
134 file copy -force [file join src Source portable GCC MicroBlazeV8 port_exceptions.c] ./src
\r
135 file copy -force [file join src Source portable GCC MicroBlazeV8 portasm.S] ./src
\r
136 file copy -force [file join src Source portable GCC MicroBlazeV8 portmacro.h] ./src
\r
137 file copy -force [file join src Source portable GCC MicroBlazeV8 portmicroblaze.c] ./src
\r
139 # Create config file for microblaze interrupt handling
\r
140 if {[string compare -nocase $need_config_file "true"] == 0} {
\r
141 xhandle_mb_interrupts
\r
144 # Create config files for Microblaze exception handling
\r
145 if { [mb_has_exceptions $hw_proc_handle] } {
\r
146 xcreate_mb_exc_config_file
\r
149 # Create bspconfig file
\r
150 set bspcfg_fn [file join ".." "${standalone_version}" "src" "bspconfig.h"]
\r
151 file delete $bspcfg_fn
\r
152 set bspcfg_fh [open $bspcfg_fn w]
\r
153 xprint_generated_header $bspcfg_fh "Configurations for Standalone BSP"
\r
155 if { [mb_has_pvr $hw_proc_handle] } {
\r
157 set pvr [get_property CONFIG.C_PVR $hw_proc_handle]
\r
161 puts $bspcfg_fh "#define MICROBLAZE_PVR_NONE"
\r
164 puts $bspcfg_fh "#define MICROBLAZE_PVR_BASIC"
\r
167 puts $bspcfg_fh "#define MICROBLAZE_PVR_FULL"
\r
170 puts $bspcfg_fh "#define MICROBLAZE_PVR_NONE"
\r
178 set headers [glob -join ./src/Source/include *.\[h\]]
\r
179 foreach header $headers {
\r
180 file copy -force $header src
\r
183 file delete -force [file join src Source]
\r
185 # Remove microblaze, cortexa9 and common directories...
\r
186 file delete -force $mbsrcdir
\r
187 file delete -force $commonsrcdir
\r
188 file delete -force $arma9srcdir
\r
189 file delete -force $arma9gccdir
\r
190 file delete -force $arma9armccdir
\r
191 file delete -force $arma9iarccdir
\r
193 # Handle stdin and stdout
\r
194 ::hsi::utils::handle_stdin $os_handle
\r
195 ::hsi::utils::handle_stdout $os_handle
\r
197 file copy -force "./src/outbyte.c" "../${standalone_version}/src/"
\r
198 file copy -force "./src/inbyte.c" "../${standalone_version}/src/"
\r
200 set file_handle [::hsi::utils::open_include_file "xparameters.h"]
\r
201 puts $file_handle "\n/******************************************************************/\n"
\r
204 ############################################################################
\r
205 ## Add constants common to all architectures to the configuration file.
\r
206 ############################################################################
\r
208 set config_file [xopen_new_include_file "./src/FreeRTOSConfig.h" "FreeRTOS Configuration parameters"]
\r
209 puts $config_file "\#include \"xparameters.h\" \n"
\r
211 set val [common::get_property CONFIG.use_preemption $os_handle]
\r
212 if {$val == "false"} {
\r
213 xput_define $config_file "configUSE_PREEMPTION" "0"
\r
215 xput_define $config_file "configUSE_PREEMPTION" "1"
\r
218 set val [common::get_property CONFIG.use_mutexes $os_handle]
\r
219 if {$val == "false"} {
\r
220 xput_define $config_file "configUSE_MUTEXES" "0"
\r
222 xput_define $config_file "configUSE_MUTEXES" "1"
\r
225 set val [common::get_property CONFIG.use_recursive_mutexes $os_handle]
\r
226 if {$val == "false"} {
\r
227 xput_define $config_file "configUSE_RECURSIVE_MUTEXES" "0"
\r
229 xput_define $config_file "configUSE_RECURSIVE_MUTEXES" "1"
\r
232 set val [common::get_property CONFIG.use_counting_semaphores $os_handle]
\r
233 if {$val == "false"} {
\r
234 xput_define $config_file "configUSE_COUNTING_SEMAPHORES" "0"
\r
236 xput_define $config_file "configUSE_COUNTING_SEMAPHORES" "1"
\r
239 set val [common::get_property CONFIG.use_timers $os_handle]
\r
240 if {$val == "false"} {
\r
241 xput_define $config_file "configUSE_TIMERS" "0"
\r
243 xput_define $config_file "configUSE_TIMERS" "1"
\r
246 set val [common::get_property CONFIG.use_idle_hook $os_handle]
\r
247 if {$val == "false"} {
\r
248 xput_define $config_file "configUSE_IDLE_HOOK" "0"
\r
250 xput_define $config_file "configUSE_IDLE_HOOK" "1"
\r
253 set val [common::get_property CONFIG.use_tick_hook $os_handle]
\r
254 if {$val == "false"} {
\r
255 xput_define $config_file "configUSE_TICK_HOOK" "0"
\r
257 xput_define $config_file "configUSE_TICK_HOOK" "1"
\r
260 set val [common::get_property CONFIG.use_malloc_failed_hook $os_handle]
\r
261 if {$val == "false"} {
\r
262 xput_define $config_file "configUSE_MALLOC_FAILED_HOOK" "0"
\r
264 xput_define $config_file "configUSE_MALLOC_FAILED_HOOK" "1"
\r
267 set val [common::get_property CONFIG.use_trace_facility $os_handle]
\r
268 if {$val == "false"} {
\r
269 xput_define $config_file "configUSE_TRACE_FACILITY" "0"
\r
271 xput_define $config_file "configUSE_TRACE_FACILITY" "1"
\r
274 set val [common::get_property CONFIG.use_task_notifications $os_handle]
\r
275 if {$val == "false"} {
\r
276 xput_define $config_file "configUSE_TASK_NOTIFICATIONS" "0"
\r
278 xput_define $config_file "configUSE_TASK_NOTIFICATIONS" "1"
\r
281 xput_define $config_file "configUSE_16_BIT_TICKS" "0"
\r
282 xput_define $config_file "configUSE_APPLICATION_TASK_TAG" "0"
\r
283 xput_define $config_file "configUSE_CO_ROUTINES" "0"
\r
285 set tick_rate [common::get_property CONFIG.tick_rate $os_handle]
\r
286 xput_define $config_file "configTICK_RATE_HZ" "($tick_rate)"
\r
288 set max_priorities [common::get_property CONFIG.max_priorities $os_handle]
\r
289 xput_define $config_file "configMAX_PRIORITIES" "($max_priorities)"
\r
290 xput_define $config_file "configMAX_CO_ROUTINE_PRIORITIES" "2"
\r
292 set min_stack [common::get_property CONFIG.minimal_stack_size $os_handle]
\r
293 set min_stack [expr [expr $min_stack + 3] & 0xFFFFFFFC]
\r
294 xput_define $config_file "configMINIMAL_STACK_SIZE" "( ( unsigned short ) $min_stack)"
\r
296 set total_heap_size [common::get_property CONFIG.total_heap_size $os_handle]
\r
297 xput_define $config_file "configTOTAL_HEAP_SIZE" "( ( size_t ) ( $total_heap_size ) )"
\r
299 set max_task_name_len [common::get_property CONFIG.max_task_name_len $os_handle]
\r
300 xput_define $config_file "configMAX_TASK_NAME_LEN" $max_task_name_len
\r
302 set val [common::get_property CONFIG.idle_yield $os_handle]
\r
303 if {$val == "false"} {
\r
304 xput_define $config_file "configIDLE_SHOULD_YIELD" "0"
\r
306 xput_define $config_file "configIDLE_SHOULD_YIELD" "1"
\r
309 set val [common::get_property CONFIG.timer_task_priority $os_handle]
\r
310 if {$val == "false"} {
\r
311 xput_define $config_file "configTIMER_TASK_PRIORITY" "0"
\r
313 xput_define $config_file "configTIMER_TASK_PRIORITY" "1"
\r
316 set val [common::get_property CONFIG.timer_command_queue_length $os_handle]
\r
317 if {$val == "false"} {
\r
318 xput_define $config_file "configTIMER_QUEUE_LENGTH" "0"
\r
320 xput_define $config_file "configTIMER_QUEUE_LENGTH" "10"
\r
323 set val [common::get_property CONFIG.timer_task_stack_depth $os_handle]
\r
324 if {$val == "false"} {
\r
325 xput_define $config_file "configTIMER_TASK_STACK_DEPTH" "0"
\r
327 xput_define $config_file "configTIMER_TASK_STACK_DEPTH" $min_stack
\r
330 set val [common::get_property CONFIG.use_newlib_reent $os_handle]
\r
331 if {$val == "false"} {
\r
332 xput_define $config_file "configUSE_NEWLIB_REENTRANT" "0"
\r
334 xput_define $config_file "configUSE_NEWLIB_REENTRANT" "1"
\r
337 set val [common::get_property CONFIG.use_timeslicing $os_handle]
\r
338 if {$val == "false"} {
\r
339 xput_define $config_file "configUSE_TIME_SLICING" "0"
\r
341 xput_define $config_file "configUSE_TIME_SLICING" "1"
\r
344 set val [get_property CONFIG.use_freertos_asserts $os_handle]
\r
345 if {$val == "true"} {
\r
346 puts $config_file "#define configASSERT( x ) if( ( x ) == 0 ) vApplicationAssert( __FILE__, __LINE__ )\n"
\r
349 set val [common::get_property CONFIG.use_queue_sets $os_handle]
\r
350 if {$val == "false"} {
\r
351 xput_define $config_file "configUSE_QUEUE_SETS" "0"
\r
353 xput_define $config_file "configUSE_QUEUE_SETS" "1"
\r
356 set val [common::get_property CONFIG.check_for_stack_overflow $os_handle]
\r
357 if {$val == "false"} {
\r
358 xput_define $config_file "configCHECK_FOR_STACK_OVERFLOW" "0"
\r
361 error "ERROR: check_for_stack_overflow must be between 0 and 2"
\r
363 xput_define $config_file "configCHECK_FOR_STACK_OVERFLOW" $val
\r
368 set val [common::get_property CONFIG.queue_registry_size $os_handle]
\r
369 if {$val == "false"} {
\r
370 xput_define $config_file "configQUEUE_REGISTRY_SIZE" "0"
\r
372 xput_define $config_file "configQUEUE_REGISTRY_SIZE" $val
\r
376 set val [common::get_property CONFIG.use_stats_formatting_functions $os_handle]
\r
377 if {$val == "false"} {
\r
378 xput_define $config_file "configUSE_STATS_FORMATTING_FUNCTIONS" "0"
\r
380 xput_define $config_file "configUSE_STATS_FORMATTING_FUNCTIONS" "1"
\r
383 set val [common::get_property CONFIG.num_thread_local_storage_pointers $os_handle]
\r
384 if {$val == "false"} {
\r
385 xput_define $config_file "configNUM_THREAD_LOCAL_STORAGE_POINTERS" "0"
\r
387 xput_define $config_file "configNUM_THREAD_LOCAL_STORAGE_POINTERS" $val
\r
390 puts $config_file "#define configTASK_RETURN_ADDRESS NULL"
\r
392 puts $config_file "#define INCLUDE_vTaskPrioritySet 1"
\r
393 puts $config_file "#define INCLUDE_uxTaskPriorityGet 1"
\r
394 puts $config_file "#define INCLUDE_vTaskDelete 1"
\r
395 puts $config_file "#define INCLUDE_vTaskCleanUpResources 0"
\r
396 puts $config_file "#define INCLUDE_vTaskSuspend 1"
\r
397 puts $config_file "#define INCLUDE_vTaskDelayUntil 1"
\r
398 puts $config_file "#define INCLUDE_vTaskDelay 1"
\r
399 puts $config_file "#define INCLUDE_uxTaskGetStackHighWaterMark 1"
\r
400 puts $config_file "#define INCLUDE_xTaskGetSchedulerState 1"
\r
401 puts $config_file "#define INCLUDE_xTimerGetTimerTaskHandle 1"
\r
402 puts $config_file "#define INCLUDE_xTaskGetIdleTaskHandle 1"
\r
403 puts $config_file "#define INCLUDE_xQueueGetMutexHolder 1"
\r
404 puts $config_file "#define INCLUDE_eTaskGetState 1"
\r
405 puts $config_file "#define INCLUDE_xEventGroupSetBitsFromISR 1"
\r
406 puts $config_file "#define INCLUDE_xTimerPendFunctionCall 1"
\r
407 puts $config_file "#define INCLUDE_pcTaskGetTaskName 1"
\r
408 puts $config_file "#define INCLUDE_xTaskResumeFromISR 1"
\r
409 puts $config_file "#define INCLUDE_xTaskGetCurrentTaskHandle 1"
\r
410 puts $config_file "#define INCLUDE_xSemaphoreGetMutexHolder 1"
\r
413 ############################################################################
\r
414 ## Add constants specific to the ps7_cortexa9
\r
415 ############################################################################
\r
416 if { $proctype == "ps7_cortexa9" } {
\r
417 set max_api_call_interrupt_priority [common::get_property CONFIG.max_api_call_interrupt_priority $os_handle]
\r
418 xput_define $config_file "configMAX_API_CALL_INTERRUPT_PRIORITY" "($max_api_call_interrupt_priority)"
\r
420 set val [common::get_property CONFIG.use_port_optimized_task_selection $os_handle]
\r
421 if {$val == "false"} {
\r
422 xput_define $config_file "configUSE_PORT_OPTIMISED_TASK_SELECTION" "0"
\r
424 xput_define $config_file "configUSE_PORT_OPTIMISED_TASK_SELECTION" "1"
\r
427 puts $config_file "#define configINTERRUPT_CONTROLLER_BASE_ADDRESS ( XPAR_PS7_SCUGIC_0_DIST_BASEADDR )"
\r
428 puts $config_file "#define configINTERRUPT_CONTROLLER_CPU_INTERFACE_OFFSET ( -0xf00 )"
\r
429 puts $config_file "#define configUNIQUE_INTERRUPT_PRIORITIES 32"
\r
431 # Function prototypes cannot be in the common code as some compilers or
\r
432 # ports require pre-processor guards to ensure they are not visible from
\r
434 puts $config_file "void vApplicationAssert( const char *pcFile, uint32_t ulLine );"
\r
435 puts $config_file "void FreeRTOS_SetupTickInterrupt( void );"
\r
436 puts $config_file "#define configSETUP_TICK_INTERRUPT() FreeRTOS_SetupTickInterrupt()\n"
\r
437 puts $config_file "void FreeRTOS_ClearTickInterrupt( void );"
\r
438 puts $config_file "#define configCLEAR_TICK_INTERRUPT() FreeRTOS_ClearTickInterrupt()\n"
\r
440 # end of if $proctype == "ps7_cortexa9"
\r
444 ############################################################################
\r
445 ## Add constants specific to the microblaze
\r
446 ############################################################################
\r
447 if { $proctype == "microblaze" } {
\r
448 # Interrupt controller setting assumes only one is in use.
\r
449 puts $config_file "#define configINTERRUPT_CONTROLLER_TO_USE XPAR_INTC_SINGLE_DEVICE_ID"
\r
450 puts $config_file "#define configINSTALL_EXCEPTION_HANDLERS 1"
\r
452 # Avoid non #define statements getting included in assembly files.
\r
453 puts $config_file "#ifndef __ASSEMBLER__"
\r
454 puts $config_file "void vApplicationAssert( const char *pcFile, uint32_t ulLine );"
\r
455 puts $config_file "#endif"
\r
457 # end of if $proctype == "microblaze"
\r
460 # complete the header protectors
\r
461 puts $config_file "\#endif"
\r
465 proc xopen_new_include_file { filename description } {
\r
466 set inc_file [open $filename w]
\r
467 xprint_generated_header $inc_file $description
\r
468 set newfname [string map {. _} [lindex [split $filename {\/}] end]]
\r
469 puts $inc_file "\#ifndef _[string toupper $newfname]"
\r
470 puts $inc_file "\#define _[string toupper $newfname]\n\n"
\r
474 proc xput_define { config_file parameter param_value } {
\r
475 puts $config_file "#define $parameter $param_value\n"
\r
478 proc xhandle_mb_interrupts {} {
\r
480 set default_interrupt_handler "XNullHandler"
\r
481 set default_arg "XNULL"
\r
483 set source_interrupt_handler $default_interrupt_handler
\r
484 set source_handler_arg $default_arg
\r
486 # Handle the interrupt pin
\r
487 set sw_proc_handle [get_sw_processor]
\r
488 set periph [get_cells $sw_proc_handle]
\r
489 set source_ports [xget_interrupt_sources $periph]
\r
490 if {[llength $source_ports] > 1} {
\r
491 error "Too many interrupting ports on the MicroBlaze. Should only find 1" "" "error"
\r
495 if {[llength $source_ports] == 1} {
\r
496 set source_port [lindex $source_ports 0]
\r
497 if {[llength $source_port] != 0} {
\r
498 set source_port_name [get_property NAME $source_port]
\r
499 set source_periph [get_cells -of_objects $source_port]
\r
500 set source_name [get_property NAME $source_periph]
\r
501 set source_driver [get_drivers $source_name]
\r
503 if {[string compare -nocase $source_driver ""] != 0} {
\r
504 set int_array [get_arrays -of_objects $source_driver]
\r
505 if {[llength $int_array] != 0} {
\r
506 set size [get_property PROPERTY.size $int_array]
\r
507 for {set i 0 } { $i < $size } { incr $i } {
\r
508 set int_port [lindex [get_property PARAM.int_port $int_array] $i]
\r
509 if {[llength $int_port] != 0} {
\r
510 if {[string compare -nocase $int_port $source_port_name] == 0 } {
\r
511 set source_interrupt_handler [lindex [get_property PARAM.int_handler $int_array] $i ]
\r
512 set source_handler_arg [lindex [get_property PARAM.int_handler_arg $int_array] $i ]
\r
513 if {[string compare -nocase $source_handler_arg DEVICE_ID] == 0 } {
\r
514 set source_handler_arg [xget_name $source_periph "DEVICE_ID"]
\r
516 if {[llength $source_periph] == 0} {
\r
517 set source_handler_arg $default_arg
\r
519 set source_handler_arg [xget_name $source_periph "C_BASEADDR"]
\r
531 # Generate microblaze_interrupts_g.c file...
\r
532 xcreate_mb_intr_config_file $source_interrupt_handler $source_handler_arg
\r
535 proc xcreate_mb_intr_config_file {handler arg} {
\r
537 set mb_table "MB_InterruptVectorTable"
\r
538 variable standalone_version
\r
540 set filename [file join ".." "${standalone_version}" "src" "microblaze_interrupts_g.c"]
\r
541 file delete $filename
\r
542 set config_file [open $filename w]
\r
544 xprint_generated_header $config_file "Interrupt Handler Table for MicroBlaze Processor"
\r
546 puts $config_file "#include \"microblaze_interrupts_i.h\""
\r
547 puts $config_file "#include \"xparameters.h\""
\r
548 puts $config_file "\n"
\r
549 puts $config_file [format "extern void %s (void *);" $handler]
\r
550 puts $config_file "\n/*"
\r
551 puts $config_file "* The interrupt handler table for microblaze processor"
\r
552 puts $config_file "*/\n"
\r
553 puts $config_file [format "%sEntry %s\[\] =" $mb_table $mb_table]
\r
554 puts $config_file "\{"
\r
555 puts -nonewline $config_file [format "\{\t%s" $handler]
\r
556 puts -nonewline $config_file [format ",\n\t(void*) %s\}" $arg]
\r
557 puts -nonewline $config_file "\n\};"
\r
558 puts $config_file "\n"
\r
562 # --------------------------------------
\r
563 # Return true if this MB has
\r
564 # exception handling support
\r
565 # --------------------------------------
\r
566 proc mb_has_exceptions { hw_proc_handle } {
\r
568 # Check if the following parameters exist on this MicroBlaze's MPD
\r
569 set ee [get_property CONFIG.C_UNALIGNED_EXCEPTIONS $hw_proc_handle]
\r
574 set ee [get_property CONFIG.C_ILL_OPCODE_EXCEPTION $hw_proc_handle]
\r
578 set ee [get_property CONFIG.C_IOPB_BUS_EXCEPTION $hw_proc_handle]
\r
582 set ee [get_property CONFIG.C_DOPB_BUS_EXCEPTION $hw_proc_handle]
\r
586 set ee [get_property CONFIG.C_DIV_BY_ZERO_EXCEPTION $hw_proc_handle]
\r
590 set ee [get_property CONFIG.C_DIV_ZERO_EXCEPTION $hw_proc_handle]
\r
594 set ee [get_property CONFIG.C_FPU_EXCEPTION $hw_proc_handle]
\r
598 set ee [get_property CONFIG.C_USE_MMU $hw_proc_handle]
\r
605 # -------------------------------------------
\r
606 # Tcl procedure xcreate_mb_exc_config file
\r
607 # -------------------------------------------
\r
608 proc xcreate_mb_exc_config_file { } {
\r
610 set hfilename [file join "src" "microblaze_exceptions_g.h"]
\r
611 file delete $hfilename
\r
612 set hconfig_file [open $hfilename w]
\r
614 xprint_generated_header $hconfig_file "Exception Handling Header for MicroBlaze Processor"
\r
616 puts $hconfig_file "\n"
\r
618 set sw_proc_handle [get_sw_processor]
\r
619 set hw_proc_handle [get_cells [get_property HW_INSTANCE $sw_proc_handle] ]
\r
620 set proctype [get_property IP_NAME $hw_proc_handle]
\r
621 set procver [get_ip_version $hw_proc_handle]
\r
623 if { ![mb_has_exceptions $hw_proc_handle]} { ;# NO exceptions are enabled
\r
624 close $hconfig_file ;# Do not generate any info in either the header or the C file
\r
628 puts $hconfig_file "\#define MICROBLAZE_EXCEPTIONS_ENABLED 1"
\r
629 if { [mb_can_handle_exceptions_in_delay_slots $procver] } {
\r
630 puts $hconfig_file "#define MICROBLAZE_CAN_HANDLE_EXCEPTIONS_IN_DELAY_SLOTS"
\r
633 close $hconfig_file
\r
636 # --------------------------------------
\r
637 # Return true if MB ver 'procver' has
\r
638 # support for handling exceptions in
\r
640 # --------------------------------------
\r
641 proc mb_can_handle_exceptions_in_delay_slots { procver } {
\r
643 if { [string compare -nocase $procver "5.00.a"] >= 0 } {
\r
650 # --------------------------------------
\r
651 # Return true if this MB has PVR support
\r
652 # --------------------------------------
\r
653 proc mb_has_pvr { hw_proc_handle } {
\r
655 # Check if the following parameters exist on this MicroBlaze's MPD
\r
656 set pvr [get_property CONFIG.C_PVR $hw_proc_handle]
\r
657 if { $pvr != "" } {
\r
664 # --------------------------------------
\r
665 # Microblaze config checks
\r
666 # --------------------------------------
\r
667 proc mb_drc_checks { } {
\r
668 set compiler [common::get_property CONFIG.compiler $sw_proc_handle]
\r
670 # check for valid compiler
\r
671 if { [string first "mb-gcc" $compiler] == 0 && [string first "mb-g++" $compiler] == 0} {
\r
672 error "Wrong compiler requested. FreeRTOS can be compiled only with the GNU compiler for MicroBlaze." "" "mdt_error"
\r
675 # check for valid stdio parameters
\r
676 set stdin [common::get_property CONFIG.stdin $os_handle]
\r
677 set stdout [common::get_property CONFIG.stdout $os_handle]
\r
678 if { $stdin == "none" || $stdout == "none" } {
\r
679 error "The STDIN/STDOUT parameters are not set. FreeRTOS requires stdin/stdout to be set." "" "mdt_error"
\r
682 # check if the design has a intc
\r
683 set intr_port [hsi::get_pins -of_objects $hw_proc_handle Interrupt]
\r
685 if { [llength $intr_port] == 0 } {
\r
688 set intr_net [hsi::get_nets -of_objects $intr_port]
\r
689 if { [llength $intr_port] == 0 } {
\r
694 if {$intr_flag == 0 } {
\r
695 error "CPU has no connection to Interrupt controller." "" "mdt_error"
\r
698 # support only AXI/PLB
\r
700 set interconnect [common::get_property CONFIG.C_INTERCONNECT $hw_proc_handle]
\r
701 puts [format "hw_proc_handle is %s" $hw_proc_handle]
\r
702 if { $interconnect == 2 } {
\r
703 set intf_pin [hsi::get_intf_pins -of_objects $hw_proc_handle "M_AXI_DP"]
\r
704 if { [llength $intf_pin] } {
\r
705 set bus_name [hsi::get_intf_nets -of_objects $intf_pin]
\r
708 error "FreeRTOS supports Microblaze with only a AXI interconnect" "" "mdt_error"
\r
711 if { [llength $bus_name] == 0 } {
\r
712 error "Microblaze M_AXI_DP is not connected to slave peripherals"
\r
715 # obtain handles to all the peripherals in the design
\r
716 set slave_ifs [hsi::get_intf_pins -of_objects $bus_name -filter "TYPE==SLAVE"]
\r
717 puts [format "slave_ifs %s bus_name %s" $slave_ifs $bus_name]
\r
719 set timer_has_intr 0
\r
721 # check for a valid timer
\r
722 foreach if $slave_ifs {
\r
723 set ip_handle [hsi::get_cells -of_objects $if]
\r
725 if {$ip_handle != $hw_proc_handle} {
\r
726 set type [common::get_property IP_NAME $ip_handle]
\r
727 if { $type == "axi_timer" } {
\r
730 # check if the timer interrupts are enabled
\r
731 set intr_port [hsi::get_pins -of_objects $ip_handle interrupt]
\r
732 if { [llength $intr_port] != 0 } {
\r
733 set intr_net [hsi::get_nets -of_objects $intr_port]
\r
734 if { [llength $intr_net] != 0 } {
\r
735 set timer_has_intr 1
\r
742 if { $timer_count == 0 } {
\r
743 error "FreeRTOS for Microblaze requires an axi_timer or xps_timer. The HW platform doesn't have a valid timer." "" "mdt_error"
\r
746 if { $timer_has_intr == 0 } {
\r
747 error "FreeRTOS for Microblaze requires interrupts enabled for a timer." "" "mdt_error"
\r
750 set systmr_interval_ms [common::get_property CONFIG.systmr_interval $os_handle]
\r
751 if { $systmr_interval_ms <= 0 } {
\r
752 error "Invalid value for parameter systmr_interval specified. Please specify a positive value." "" "mdt_error"
\r