Added BSP generation files to MicroBlaze directory.
parent
0dc4153997
commit
c056029422
@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
PARAMETER VERSION = 2.2.0
|
||||||
|
|
||||||
|
BEGIN OS
|
||||||
|
PARAMETER OS_NAME = freertos
|
||||||
|
PARAMETER STDIN = *
|
||||||
|
PARAMETER STDOUT = *
|
||||||
|
PARAMETER SYSTMR_SPEC = true
|
||||||
|
PARAMETER SYSTMR_DEV = *
|
||||||
|
PARAMETER SYSINTC_SPEC = *
|
||||||
|
END
|
||||||
|
|
@ -0,0 +1,101 @@
|
|||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# (c) Copyright 2011 Xilinx, Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
# This file contains confidential and proprietary information of Xilinx, Inc.
|
||||||
|
# and is protected under U.S. and international copyright and other
|
||||||
|
# intellectual property laws.
|
||||||
|
#
|
||||||
|
# DISCLAIMER
|
||||||
|
# This disclaimer is not a license and does not grant any rights to the
|
||||||
|
# materials distributed herewith. Except as otherwise provided in a valid
|
||||||
|
# license issued to you by Xilinx, and to the maximum extent permitted by
|
||||||
|
# applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
|
||||||
|
# FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
|
||||||
|
# IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
|
||||||
|
# MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
|
||||||
|
# and (2) Xilinx shall not be liable (whether in contract or tort, including
|
||||||
|
# negligence, or under any other theory of liability) for any loss or damage
|
||||||
|
# of any kind or nature related to, arising under or in connection with these
|
||||||
|
# materials, including for any direct, or any indirect, special, incidental,
|
||||||
|
# or consequential loss or damage (including loss of data, profits, goodwill,
|
||||||
|
# or any type of loss or damage suffered as a result of any action brought by
|
||||||
|
# a third party) even if such damage or loss was reasonably foreseeable or
|
||||||
|
# Xilinx had been advised of the possibility of the same.
|
||||||
|
#
|
||||||
|
# CRITICAL APPLICATIONS
|
||||||
|
# Xilinx products are not designed or intended to be fail-safe, or for use in
|
||||||
|
# any application requiring fail-safe performance, such as life-support or
|
||||||
|
# safety devices or systems, Class III medical devices, nuclear facilities,
|
||||||
|
# applications related to the deployment of airbags, or any other applications
|
||||||
|
# that could lead to death, personal injury, or severe property or
|
||||||
|
# environmental damage (individually and collectively, "Critical
|
||||||
|
# Applications"). Customer assumes the sole risk and liability of any use of
|
||||||
|
# Xilinx products in Critical Applications, subject only to applicable laws
|
||||||
|
# and regulations governing limitations on product liability.
|
||||||
|
#
|
||||||
|
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
|
||||||
|
# AT ALL TIMES.
|
||||||
|
#
|
||||||
|
# This file is part of Xilkernel.
|
||||||
|
#
|
||||||
|
# $Id: xilkernel_v2_1_0.mld,v 1.1.2.4 2010/12/10 07:27:08 svemula Exp $
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
OPTION psf_version = 2.1.0 ;
|
||||||
|
BEGIN OS freertos
|
||||||
|
|
||||||
|
OPTION DRC = kernel_drc ;
|
||||||
|
OPTION SUPPORTED_PERIPHERALS = (microblaze);
|
||||||
|
OPTION COPYFILES = all;
|
||||||
|
OPTION DEPENDS = (standalone_v3_01_a);
|
||||||
|
OPTION APP_LINKER_FLAGS = "-Wl,--start-group,-lxil,-lfreertos,-lgcc,-lc,--end-group";
|
||||||
|
|
||||||
|
OPTION DESC = "FreeRTOS is a popular lightweight kernel."
|
||||||
|
|
||||||
|
# STDIN/STDOUT
|
||||||
|
PARAM name = stdin, type = peripheral_instance, requires_interface = stdin, default=none, desc = "Specify the instance name of the standard input peripheral";
|
||||||
|
PARAM name = stdout, type = peripheral_instance, requires_interface = stdout, default=none, desc = "Specify the instance name of the standard output peripheral";
|
||||||
|
|
||||||
|
# System timer specification
|
||||||
|
PARAM name = systmr_interval, type = int, default = 10, desc = "Specify the time interval for each kernel tick (in milliseconds). This controls the CPU budget for each process. If the timer is fit_timer, then this parameter is automatically determined";
|
||||||
|
|
||||||
|
# System interrupt controller specification
|
||||||
|
# PARAM name = sysintc_spec, type = peripheral_instance, range = (opb_intc, xps_intc, dcr_intc, axi_intc), default = none, desc = "Specify the instance name of the interrupt controller device driving system interrupts";
|
||||||
|
|
||||||
|
BEGIN CATEGORY kernel_behavior
|
||||||
|
PARAM name = kernel_behavior, type = bool, default = true, desc = "Parameters relating to the kernel behavior", permit = user;
|
||||||
|
PARAM name = use_preemption, type = bool, default = true, desc = "Set to true to use the preemptive scheduler, or false to use the cooperative scheduler.";
|
||||||
|
PARAM name = idle_yield, type = bool, default = true, desc = "Set to true if the Idle task should yield if another idle priority task is able to run, or false if the idle task should always use its entire time slice unless it is preempted.";
|
||||||
|
PARAM name = max_priorities, type = int, default = 4, desc = "The number of task priorities that will be available. Priorities can be assigned from zero to (max_priorities - 1)";
|
||||||
|
PARAM name = minimal_stack_size, type = int, default = 120, desc = "The size of the stack allocated to the Idle task. Also used by standard demo and test tasks found in the main FreeRTOS download.";
|
||||||
|
PARAM name = total_heap_size, type = int, default = 65536, desc = "Only used if heap_1.c or heap_2.c is included in the project. Sets the amount of RAM reserved for use by the kernel - used when tasks, queues and semaphores are created.";
|
||||||
|
PARAM name = max_task_name_len, type = int, default = 8, desc = "The maximum number of characters that can be in the name of a task.";
|
||||||
|
END CATEGORY
|
||||||
|
|
||||||
|
BEGIN CATEGORY kernel_features
|
||||||
|
PARAM name = kernel_features, type = bool, default = true, desc = "Include or exclude kernel features", permit = user;
|
||||||
|
PARAM name = use_mutexes, type = bool, default = true, desc = "Set to true to include mutex functionality, or false to exclude mutex functionality.";
|
||||||
|
PARAM name = use_recursive_mutexes, type = bool, default = true, desc = "Set to true to include recursive mutex functionality, or false to exclude recursive mutex functionality.";
|
||||||
|
PARAM name = use_counting_semaphores, type = bool, default = true, desc = "Set to true to include counting semaphore functionality, or false to exclude recursive mutex functionality.";
|
||||||
|
PARAM name = queue_registry_size, type = int, default = 10, desc = "The maximum number of queues that can be registered at any one time. Registered queues can be viewed in the kernel aware debugger plug-in.";
|
||||||
|
PARAM name = use_trace_facility, type = bool, default = true, desc = "Set to true to include the legacy trace functionality, and a few other features. traceMACROS are the preferred method of tracing now.";
|
||||||
|
END CATEGORY
|
||||||
|
|
||||||
|
BEGIN CATEGORY hook_functions
|
||||||
|
PARAM name = hook_functions, type = bool, default = true, desc = "Include or exclude application defined hook (callback) functions. Callback functions must be defined by the application that is using FreeRTOS", permit = user;
|
||||||
|
PARAM name = use_idle_hook, type = bool, default = false, desc = "Set to true for the kernel to call vApplicationIdleHook() on each iteration of the idle task. The application must provide an implementation of vApplicationIdleHook().";
|
||||||
|
PARAM name = use_tick_hook, type = bool, default = false, desc = "Set to true for the kernel to call vApplicationTickHook() during each tick interrupt. The application must provide an implementation of vApplicationTickHook().";
|
||||||
|
PARAM name = use_malloc_failed_hook, type = bool, default = true, desc = "Only used if heap_1.c, heap_2.c or heap_3.c is included in the project. Set to true for the kernel to call vApplicationMallocFailedHookHook() if there is insufficient FreeRTOS heap available for a task, queue or semaphore to be created. The application must provide an implementation of vApplicationMallocFailedHook().";
|
||||||
|
PARAM name = check_for_stack_overflow, type = int, default = 2, desc = "Set to 1 to include basic run time task stack checking. Set to 2 to include more comprehensive run time task stack checking.";
|
||||||
|
END CATEGORY
|
||||||
|
|
||||||
|
BEGIN CATEGORY software_timers
|
||||||
|
PARAM name = software_timers, type = bool, default = true, desc = "Options relating to the software timers functionality", permit = user;
|
||||||
|
PARAM name = use_timers, type = bool, default = true, desc = "Set to true to include software timer functionality, or false to exclude software timer functionality";
|
||||||
|
PARAM name = timer_task_priority, type = string, default = "(configMAX_PRIORITIES - 1)", desc = "The priority at which the software timer service/daemon task will execute.";
|
||||||
|
PARAM name = timer_command_queue_length, type = int, default = 10, desc = "The number of commands the timer command queue can hold at any one time.";
|
||||||
|
PARAM name = timer_task_stack_depth, type = string, default = "(configMINIMAL_STACK_SIZE), desc = "The size of the stack allocated to the timer service/daemon task.";
|
||||||
|
END CATEGORY
|
||||||
|
|
||||||
|
END OS
|
@ -0,0 +1,806 @@
|
|||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# (c) Copyright 2011 Xilinx, Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
# This file contains confidential and proprietary information of Xilinx, Inc.
|
||||||
|
# and is protected under U.S. and international copyright and other
|
||||||
|
# intellectual property laws.
|
||||||
|
#
|
||||||
|
# DISCLAIMER
|
||||||
|
# This disclaimer is not a license and does not grant any rights to the
|
||||||
|
# materials distributed herewith. Except as otherwise provided in a valid
|
||||||
|
# license issued to you by Xilinx, and to the maximum extent permitted by
|
||||||
|
# applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
|
||||||
|
# FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
|
||||||
|
# IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
|
||||||
|
# MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
|
||||||
|
# and (2) Xilinx shall not be liable (whether in contract or tort, including
|
||||||
|
# negligence, or under any other theory of liability) for any loss or damage
|
||||||
|
# of any kind or nature related to, arising under or in connection with these
|
||||||
|
# materials, including for any direct, or any indirect, special, incidental,
|
||||||
|
# or consequential loss or damage (including loss of data, profits, goodwill,
|
||||||
|
# or any type of loss or damage suffered as a result of any action brought by
|
||||||
|
# a third party) even if such damage or loss was reasonably foreseeable or
|
||||||
|
# Xilinx had been advised of the possibility of the same.
|
||||||
|
#
|
||||||
|
# CRITICAL APPLICATIONS
|
||||||
|
# Xilinx products are not designed or intended to be fail-safe, or for use in
|
||||||
|
# any application requiring fail-safe performance, such as life-support or
|
||||||
|
# safety devices or systems, Class III medical devices, nuclear facilities,
|
||||||
|
# applications related to the deployment of airbags, or any other applications
|
||||||
|
# that could lead to death, personal injury, or severe property or
|
||||||
|
# environmental damage (individually and collectively, "Critical
|
||||||
|
# Applications"). Customer assumes the sole risk and liability of any use of
|
||||||
|
# Xilinx products in Critical Applications, subject only to applicable laws
|
||||||
|
# and regulations governing limitations on product liability.
|
||||||
|
#
|
||||||
|
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
|
||||||
|
# AT ALL TIMES.
|
||||||
|
#
|
||||||
|
# This file is part of FreeRTOS.
|
||||||
|
#
|
||||||
|
# $Id: freertos_v2_1_0.tcl,v 1.1.2.8 2010/12/10 07:27:08 svemula Exp $
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
# standalone bsp version. set this to the latest "ACTIVE" version.
|
||||||
|
set standalone_version standalone_v3_01_a
|
||||||
|
|
||||||
|
proc kernel_drc {os_handle} {
|
||||||
|
set sw_proc_handle [xget_libgen_proc_handle]
|
||||||
|
set hw_proc_handle [xget_handle $sw_proc_handle "IPINST"]
|
||||||
|
set proctype [xget_value $hw_proc_handle "OPTION" "IPNAME"]
|
||||||
|
set compiler [xget_value $sw_proc_handle "PARAMETER" "COMPILER"]
|
||||||
|
|
||||||
|
# check for valid compiler
|
||||||
|
if { [string first "mb-gcc" $compiler] == 0 && [string first "mb-g++" $compiler] == 0} {
|
||||||
|
error "Wrong compiler requested. FreeRTOS can be compiled only with the GNU compiler for MicroBlaze." "" "mdt_error"
|
||||||
|
}
|
||||||
|
|
||||||
|
# check for valid stdio parameters
|
||||||
|
set stdin [xget_value $os_handle "PARAMETER" "STDIN"]
|
||||||
|
set stdout [xget_value $os_handle "PARAMETER" "STDOUT"]
|
||||||
|
if { $stdin == "none" || $stdout == "none" } {
|
||||||
|
error "The STDIN/STDOUT parameters are not set. FreeRTOS requires stdin/stdout to be set." "" "mdt_error"
|
||||||
|
}
|
||||||
|
|
||||||
|
# check if the design has a intc
|
||||||
|
set intr_port [xget_value $hw_proc_handle "PORT" "Interrupt"]
|
||||||
|
if { [llength $intr_port] == 0 } {
|
||||||
|
error "CPU has no connection to Interrupt controller." "" "mdt_error"
|
||||||
|
}
|
||||||
|
|
||||||
|
# support only AXI/PLB
|
||||||
|
set interconnect [xget_value $hw_proc_handle "PARAMETER" "C_INTERCONNECT"]
|
||||||
|
if { $interconnect == 1 } {
|
||||||
|
set bus_name [xget_hw_busif_value $hw_proc_handle "DPLB"]
|
||||||
|
} elseif { $interconnect == 2 } {
|
||||||
|
set bus_name [xget_hw_busif_value $hw_proc_handle "M_AXI_DP"]
|
||||||
|
} else {
|
||||||
|
error "FreeRTOS supports Microblaze with only a AXI or PLB interconnect" "" "mdt_error"
|
||||||
|
}
|
||||||
|
|
||||||
|
# obtain handles to all the peripherals in the design
|
||||||
|
set mhs_handle [xget_hw_parent_handle $hw_proc_handle]
|
||||||
|
set slave_ifs [xget_hw_connected_busifs_handle $mhs_handle $bus_name "slave"]
|
||||||
|
set timer_count 0
|
||||||
|
set timer_has_intr 0
|
||||||
|
|
||||||
|
# check for a valid timer
|
||||||
|
foreach if $slave_ifs {
|
||||||
|
set ip_handle [xget_hw_parent_handle $if]
|
||||||
|
|
||||||
|
if {$ip_handle != $hw_proc_handle} {
|
||||||
|
set type [xget_hw_value $ip_handle]
|
||||||
|
if { $type == "xps_timer" || $type == "axi_timer" } {
|
||||||
|
incr timer_count
|
||||||
|
|
||||||
|
# check if the timer interrupts are enabled
|
||||||
|
set intr_port [xget_value $ip_handle "PORT" "Interrupt"]
|
||||||
|
if { [llength $intr_port] != 0 } {
|
||||||
|
set timer_has_intr 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if { $timer_count == 0 } {
|
||||||
|
error "FreeRTOS for Microblaze requires an axi_timer or xps_timer. The HW platform doesn't have a valid timer." "" "mdt_error"
|
||||||
|
}
|
||||||
|
|
||||||
|
if { $timer_has_intr == 0 } {
|
||||||
|
error "FreeRTOS for Microblaze requires interrupts enabled for a timer." "" "mdt_error"
|
||||||
|
}
|
||||||
|
|
||||||
|
set systmr_interval_ms [xget_value $os_handle "PARAMETER" "systmr_interval"]
|
||||||
|
if { $systmr_interval_ms <= 0 } {
|
||||||
|
error "Invalid value for parameter systmr_interval specified. Please specify a positive value." "" "mdt_error"
|
||||||
|
}
|
||||||
|
|
||||||
|
### ToDo: Add DRC specific to FreeRTOS
|
||||||
|
}
|
||||||
|
|
||||||
|
proc generate {os_handle} {
|
||||||
|
|
||||||
|
variable standalone_version
|
||||||
|
|
||||||
|
set sw_proc_handle [xget_libgen_proc_handle]
|
||||||
|
set hw_proc_handle [xget_handle $sw_proc_handle "IPINST"]
|
||||||
|
set proctype [xget_value $hw_proc_handle "OPTION" "IPNAME"]
|
||||||
|
set procver [xget_value $hw_proc_handle "PARAMETER" "HW_VER"]
|
||||||
|
|
||||||
|
set need_config_file "false"
|
||||||
|
|
||||||
|
# proctype should be "microblaze"
|
||||||
|
set mbsrcdir "../${standalone_version}/src/microblaze"
|
||||||
|
set commondir "../${standalone_version}/src/common"
|
||||||
|
set datadir "../${standalone_version}/data"
|
||||||
|
|
||||||
|
foreach entry [glob -nocomplain [file join $commondir *]] {
|
||||||
|
file copy -force $entry [file join ".." "${standalone_version}" "src"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# proctype should be "microblaze"
|
||||||
|
switch -regexp $proctype {
|
||||||
|
"microblaze" {
|
||||||
|
|
||||||
|
foreach entry [glob -nocomplain [file join $mbsrcdir *]] {
|
||||||
|
if { [string first "microblaze_interrupt_handler" $entry] == -1 } { ;# Do not copy over the Standalone BSP exception handler
|
||||||
|
file copy -force $entry [file join ".." "${standalone_version}" "src"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set need_config_file "true"
|
||||||
|
}
|
||||||
|
"default" {puts "unknown processor type $proctype\n"}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Write the config.make file
|
||||||
|
set makeconfig [open "../standalone_v3_01_a/src/config.make" w]
|
||||||
|
xprint_generated_header_tcl $makeconfig "Configuration parameters for Standalone Makefile"
|
||||||
|
|
||||||
|
if { $proctype == "microblaze" } {
|
||||||
|
if { [mb_has_exceptions $hw_proc_handle] } {
|
||||||
|
puts $makeconfig "LIBSOURCES = *.s *.c *.S"
|
||||||
|
} else {
|
||||||
|
puts $makeconfig "LIBSOURCES = *.s *.c"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
puts $makeconfig "LIBS = standalone_libs"
|
||||||
|
close $makeconfig
|
||||||
|
|
||||||
|
# Remove microblaze directories...
|
||||||
|
file delete -force $mbsrcdir
|
||||||
|
|
||||||
|
# copy required files to the main src directory
|
||||||
|
file copy -force [file join src Source tasks.c] src
|
||||||
|
file copy -force [file join src Source queue.c] src
|
||||||
|
file copy -force [file join src Source list.c] src
|
||||||
|
file copy -force [file join src Source timers.c] src
|
||||||
|
file copy -force [file join src Source portable MemMang heap_2.c] src
|
||||||
|
file copy -force [file join src Source portable GCC MicroBlazeV8 port.c] src
|
||||||
|
file copy -force [file join src Source portable GCC MicroBlazeV8 port_exceptions.c] src
|
||||||
|
file copy -force [file join src Source portable GCC MicroBlazeV8 portasm.S] src
|
||||||
|
file copy -force [file join src Source portable GCC MicroBlazeV8 portmacro.h] src
|
||||||
|
set headers [glob -join ./src/Source/include *.\[h\]]
|
||||||
|
foreach header $headers {
|
||||||
|
file copy -force $header src
|
||||||
|
}
|
||||||
|
|
||||||
|
file delete -force [file join src Source]
|
||||||
|
file delete -force [file join src Source]
|
||||||
|
|
||||||
|
# Handle stdin and stdout
|
||||||
|
xhandle_stdin $os_handle
|
||||||
|
xhandle_stdout $os_handle
|
||||||
|
|
||||||
|
# Create config file for microblaze interrupt handling
|
||||||
|
if {[string compare -nocase $need_config_file "true"] == 0} {
|
||||||
|
xhandle_mb_interrupts
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create config files for Microblaze exception handling
|
||||||
|
if { $proctype == "microblaze" && [mb_has_exceptions $hw_proc_handle] } {
|
||||||
|
xcreate_mb_exc_config_file
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create bspconfig file
|
||||||
|
set bspcfg_fn [file join ".." "${standalone_version}" "src" "bspconfig.h"]
|
||||||
|
file delete $bspcfg_fn
|
||||||
|
set bspcfg_fh [open $bspcfg_fn w]
|
||||||
|
xprint_generated_header $bspcfg_fh "Configurations for Standalone BSP"
|
||||||
|
|
||||||
|
if { $proctype == "microblaze" && [mb_has_pvr $hw_proc_handle] } {
|
||||||
|
|
||||||
|
set pvr [xget_value $hw_proc_handle "PARAMETER" "C_PVR"]
|
||||||
|
|
||||||
|
switch $pvr {
|
||||||
|
"0" {
|
||||||
|
puts $bspcfg_fh "#define MICROBLAZE_PVR_NONE"
|
||||||
|
}
|
||||||
|
"1" {
|
||||||
|
puts $bspcfg_fh "#define MICROBLAZE_PVR_BASIC"
|
||||||
|
}
|
||||||
|
"2" {
|
||||||
|
puts $bspcfg_fh "#define MICROBLAZE_PVR_FULL"
|
||||||
|
}
|
||||||
|
"default" {
|
||||||
|
puts $bspcfg_fh "#define MICROBLAZE_PVR_NONE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close $bspcfg_fh
|
||||||
|
|
||||||
|
# ToDO: FreeRTOS does not handle the following, refer xilkernel TCL script
|
||||||
|
# - MPU settings
|
||||||
|
|
||||||
|
set config_file [xopen_new_include_file "./src/FreeRTOSConfig.h" "FreeRTOS Configuration parameters"]
|
||||||
|
puts $config_file "\#include \"xparameters.h\" \n"
|
||||||
|
|
||||||
|
set val [xget_value $os_handle "PARAMETER" "use_preemption"]
|
||||||
|
if {$val == "false"} {
|
||||||
|
xput_define $config_file "configUSE_PREEMPTION" "0"
|
||||||
|
} else {
|
||||||
|
xput_define $config_file "configUSE_PREEMPTION" "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
set val [xget_value $os_handle "PARAMETER" "use_mutexes"]
|
||||||
|
if {$val == "false"} {
|
||||||
|
xput_define $config_file "configUSE_MUTEXES" "0"
|
||||||
|
} else {
|
||||||
|
xput_define $config_file "configUSE_MUTEXES" "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
set val [xget_value $os_handle "PARAMETER" "use_recursive_mutexes"]
|
||||||
|
if {$val == "false"} {
|
||||||
|
xput_define $config_file "configUSE_RECURSIVE_MUTEXES" "0"
|
||||||
|
} else {
|
||||||
|
xput_define $config_file "configUSE_RECURSIVE_MUTEXES" "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
set val [xget_value $os_handle "PARAMETER" "use_counting_semaphores"]
|
||||||
|
if {$val == "false"} {
|
||||||
|
xput_define $config_file "configUSE_COUNTING_SEMAPHORES" "0"
|
||||||
|
} else {
|
||||||
|
xput_define $config_file "configUSE_COUNTING_SEMAPHORES" "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
set val [xget_value $os_handle "PARAMETER" "use_timers"]
|
||||||
|
if {$val == "false"} {
|
||||||
|
xput_define $config_file "configUSE_TIMERS" "0"
|
||||||
|
} else {
|
||||||
|
xput_define $config_file "configUSE_TIMERS" "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
set val [xget_value $os_handle "PARAMETER" "use_idle_hook"]
|
||||||
|
if {$val == "false"} {
|
||||||
|
xput_define $config_file "configUSE_IDLE_HOOK" "0"
|
||||||
|
} else {
|
||||||
|
xput_define $config_file "configUSE_IDLE_HOOK" "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
set val [xget_value $os_handle "PARAMETER" "use_tick_hook"]
|
||||||
|
if {$val == "false"} {
|
||||||
|
xput_define $config_file "configUSE_TICK_HOOK" "0"
|
||||||
|
} else {
|
||||||
|
xput_define $config_file "configUSE_TICK_HOOK" "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
set val [xget_value $os_handle "PARAMETER" "use_malloc_failed_hook"]
|
||||||
|
if {$val == "false"} {
|
||||||
|
xput_define $config_file "configUSE_MALLOC_FAILED_HOOK" "0"
|
||||||
|
} else {
|
||||||
|
xput_define $config_file "configUSE_MALLOC_FAILED_HOOK" "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
set val [xget_value $os_handle "PARAMETER" "use_trace_facility"]
|
||||||
|
if {$val == "false"} {
|
||||||
|
xput_define $config_file "configUSE_TRACE_FACILITY" "0"
|
||||||
|
} else {
|
||||||
|
xput_define $config_file "configUSE_TRACE_FACILITY" "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
xput_define $config_file "configUSE_16_BIT_TICKS" "0"
|
||||||
|
xput_define $config_file "configUSE_APPLICATION_TASK_TAG" "0"
|
||||||
|
xput_define $config_file "configUSE_CO_ROUTINES" "0"
|
||||||
|
|
||||||
|
# System timer tick rate (Microblaze only. kernel DRC ensures this)
|
||||||
|
set systmr_interval [xget_value $os_handle "PARAMETER" "systmr_interval"]
|
||||||
|
xput_define $config_file "configTICK_RATE_HZ" $systmr_interval
|
||||||
|
|
||||||
|
set max_priorities [xget_value $os_handle "PARAMETER" "max_priorities"]
|
||||||
|
xput_define $config_file "configMAX_PRIORITIES" $max_priorities
|
||||||
|
xput_define $config_file "configMAX_CO_ROUTINE_PRIORITIES" "2"
|
||||||
|
|
||||||
|
set min_stack [xget_value $os_handle "PARAMETER" "minimal_stack_size"]
|
||||||
|
set min_stack [expr [expr $min_stack + 3] & 0xFFFFFFFC]
|
||||||
|
xput_define $config_file "configMINIMAL_STACK_SIZE" $min_stack
|
||||||
|
|
||||||
|
set total_heap_size [xget_value $os_handle "PARAMETER" "total_heap_size"]
|
||||||
|
set total_heap_size [expr [expr $total_heap_size + 3] & 0xFFFFFFFC]
|
||||||
|
xput_define $config_file "configTOTAL_HEAP_SIZE" $total_heap_size
|
||||||
|
|
||||||
|
set max_task_name_len [xget_value $os_handle "PARAMETER" "max_task_name_len"]
|
||||||
|
xput_define $config_file "configMAX_TASK_NAME_LEN" $max_task_name_len
|
||||||
|
|
||||||
|
set val [xget_value $os_handle "PARAMETER" "idle_yield"]
|
||||||
|
if {$val == "false"} {
|
||||||
|
xput_define $config_file "configIDLE_SHOULD_YIELD" "0"
|
||||||
|
} else {
|
||||||
|
xput_define $config_file "configIDLE_SHOULD_YIELD" "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
set val [xget_value $os_handle "PARAMETER" "check_for_stack_overflow"]
|
||||||
|
if {$val == "false"} {
|
||||||
|
xput_define $config_file "configCHECK_FOR_STACK_OVERFLOW" "0"
|
||||||
|
} else {
|
||||||
|
xput_define $config_file "configCHECK_FOR_STACK_OVERFLOW" "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
set val [xget_value $os_handle "PARAMETER" "queue_registry_size"]
|
||||||
|
if {$val == "false"} {
|
||||||
|
xput_define $config_file "configQUEUE_REGISTRY_SIZE" "0"
|
||||||
|
} else {
|
||||||
|
xput_define $config_file "configQUEUE_REGISTRY_SIZE" "10"
|
||||||
|
}
|
||||||
|
|
||||||
|
xput_define $config_file "configGENERATE_RUN_TIME_STATS" "0"
|
||||||
|
|
||||||
|
set val [xget_value $os_handle "PARAMETER" "timer_task_priority"]
|
||||||
|
if {$val == "false"} {
|
||||||
|
xput_define $config_file "configTIMER_TASK_PRIORITY" "0"
|
||||||
|
} else {
|
||||||
|
xput_define $config_file "configTIMER_TASK_PRIORITY" "10"
|
||||||
|
}
|
||||||
|
|
||||||
|
set val [xget_value $os_handle "PARAMETER" "timer_command_queue_length"]
|
||||||
|
if {$val == "false"} {
|
||||||
|
xput_define $config_file "configTIMER_QUEUE_LENGTH" "0"
|
||||||
|
} else {
|
||||||
|
xput_define $config_file "configTIMER_QUEUE_LENGTH" "10"
|
||||||
|
}
|
||||||
|
|
||||||
|
set val [xget_value $os_handle "PARAMETER" "timer_task_stack_depth"]
|
||||||
|
if {$val == "false"} {
|
||||||
|
xput_define $config_file "configTIMER_TASK_STACK_DEPTH" "0"
|
||||||
|
} else {
|
||||||
|
xput_define $config_file "configTIMER_TASK_STACK_DEPTH" $min_stack
|
||||||
|
}
|
||||||
|
|
||||||
|
if { [mb_has_exceptions $hw_proc_handle] } {
|
||||||
|
xput_define $config_file "configINSTALL_EXCEPTION_HANDLERS" "1"
|
||||||
|
} else {
|
||||||
|
xput_define $config_file "configINSTALL_EXCEPTION_HANDLERS" "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
xput_define $config_file "configINTERRUPT_CONTROLLER_TO_USE" "XPAR_INTC_SINGLE_DEVICE_ID"
|
||||||
|
|
||||||
|
xput_define $config_file "INCLUDE_vTaskCleanUpResources" "0"
|
||||||
|
xput_define $config_file "INCLUDE_vTaskDelay" "1"
|
||||||
|
xput_define $config_file "INCLUDE_vTaskDelayUntil" "1"
|
||||||
|
xput_define $config_file "INCLUDE_vTaskDelete" "1"
|
||||||
|
xput_define $config_file "INCLUDE_xTaskGetCurrentTaskHandle" "1"
|
||||||
|
xput_define $config_file "INCLUDE_xTaskGetIdleTaskHandle" "1"
|
||||||
|
xput_define $config_file "INCLUDE_xTaskGetSchedulerState" "1"
|
||||||
|
xput_define $config_file "INCLUDE_xTimerGetTimerTaskHandle" "1"
|
||||||
|
xput_define $config_file "INCLUDE_uxTaskGetStackHighWaterMark" "1"
|
||||||
|
xput_define $config_file "INCLUDE_uxTaskPriorityGet" "1"
|
||||||
|
xput_define $config_file "INCLUDE_vTaskPrioritySet" "1"
|
||||||
|
xput_define $config_file "INCLUDE_xTaskResumeFromISR" "1"
|
||||||
|
xput_define $config_file "INCLUDE_vTaskSuspend" "1"
|
||||||
|
xput_define $config_file "INCLUDE_pcTaskNameGet" "1"
|
||||||
|
xput_define $config_file "INCLUDE_xTaskIdleTaskHandleGet" "1"
|
||||||
|
xput_define $config_file "INCLUDE_xTimerDaemonTaskHandleGet" "1"
|
||||||
|
|
||||||
|
# complete the header protectors
|
||||||
|
puts $config_file "\#endif"
|
||||||
|
close $config_file
|
||||||
|
}
|
||||||
|
|
||||||
|
proc xopen_new_include_file { filename description } {
|
||||||
|
set inc_file [open $filename w]
|
||||||
|
xprint_generated_header $inc_file $description
|
||||||
|
set newfname [string map {. _} [lindex [split $filename {\/}] end]]
|
||||||
|
puts $inc_file "\#ifndef _[string toupper $newfname]"
|
||||||
|
puts $inc_file "\#define _[string toupper $newfname]\n\n"
|
||||||
|
return $inc_file
|
||||||
|
}
|
||||||
|
|
||||||
|
proc xadd_define { config_file os_handle parameter } {
|
||||||
|
set param_value [xget_value $os_handle "PARAMETER" $parameter]
|
||||||
|
puts $config_file "#define [string toupper $parameter] $param_value\n"
|
||||||
|
|
||||||
|
# puts "creating #define [string toupper $parameter] $param_value\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
proc xput_define { config_file parameter param_value } {
|
||||||
|
puts $config_file "#define $parameter $param_value\n"
|
||||||
|
|
||||||
|
# puts "creating #define [string toupper $parameter] $param_value\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
# args field of the array
|
||||||
|
proc xadd_extern_fname {initfile oshandle arrayname arg} {
|
||||||
|
|
||||||
|
set arrhandle [xget_handle $oshandle "ARRAY" $arrayname]
|
||||||
|
set elements [xget_handle $arrhandle "ELEMENTS" "*"]
|
||||||
|
set count 0
|
||||||
|
set max_count [llength $elements]
|
||||||
|
|
||||||
|
foreach ele $elements {
|
||||||
|
incr count
|
||||||
|
set arg_value [xget_value $ele "PARAMETER" $arg]
|
||||||
|
puts $initfile "extern void $arg_value\(\)\;"
|
||||||
|
}
|
||||||
|
puts $initfile ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# args is variable no - fields of the array
|
||||||
|
proc xadd_struct {initfile oshandle structtype structname arrayname args} {
|
||||||
|
|
||||||
|
set arrhandle [xget_handle $oshandle "ARRAY" $arrayname]
|
||||||
|
set elements [xget_handle $arrhandle "ELEMENTS" "*"]
|
||||||
|
set count 0
|
||||||
|
set max_count [llength $elements]
|
||||||
|
puts $initfile "struct $structtype $structname\[$max_count\] = \{"
|
||||||
|
|
||||||
|
foreach ele $elements {
|
||||||
|
incr count
|
||||||
|
puts -nonewline $initfile "\t\{"
|
||||||
|
foreach field $args {
|
||||||
|
set field_value [xget_value $ele "PARAMETER" $field]
|
||||||
|
# puts "$arrayname ( $count )->$field is $field_value"
|
||||||
|
puts -nonewline $initfile "$field_value"
|
||||||
|
if { $field != [lindex $args end] } {
|
||||||
|
puts -nonewline $initfile ","
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if {$count < $max_count} {
|
||||||
|
puts $initfile "\},"
|
||||||
|
} else {
|
||||||
|
puts $initfile "\}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
puts $initfile "\}\;"
|
||||||
|
}
|
||||||
|
|
||||||
|
# return the sum of all the arg field values in arrayname
|
||||||
|
proc get_field_sum {oshandle arrayname arg} {
|
||||||
|
|
||||||
|
set arrhandle [xget_handle $oshandle "ARRAY" $arrayname]
|
||||||
|
set elements [xget_handle $arrhandle "ELEMENTS" "*"]
|
||||||
|
set count 0
|
||||||
|
set max_count [llength $elements]
|
||||||
|
|
||||||
|
foreach ele $elements {
|
||||||
|
set field_value [xget_value $ele "PARAMETER" $arg]
|
||||||
|
set count [expr $field_value+$count]
|
||||||
|
}
|
||||||
|
return $count
|
||||||
|
}
|
||||||
|
|
||||||
|
# return the sum of the product of field values in arrayname
|
||||||
|
proc get_field_product_sum {oshandle arrayname field1 field2} {
|
||||||
|
|
||||||
|
set arrhandle [xget_handle $oshandle "ARRAY" $arrayname]
|
||||||
|
set elements [xget_handle $arrhandle "ELEMENTS" "*"]
|
||||||
|
set count 0
|
||||||
|
set max_count [llength $elements]
|
||||||
|
|
||||||
|
foreach ele $elements {
|
||||||
|
set field1_value [xget_value $ele "PARAMETER" $field1]
|
||||||
|
set field2_value [xget_value $ele "PARAMETER" $field2]
|
||||||
|
set incr_value [expr $field1_value*$field2_value]
|
||||||
|
set count [expr $count+$incr_value]
|
||||||
|
}
|
||||||
|
return $count
|
||||||
|
}
|
||||||
|
|
||||||
|
proc xhandle_mb_interrupts {} {
|
||||||
|
|
||||||
|
set default_interrupt_handler "XNullHandler"
|
||||||
|
set default_arg "XNULL"
|
||||||
|
|
||||||
|
set source_interrupt_handler $default_interrupt_handler
|
||||||
|
set source_handler_arg $default_arg
|
||||||
|
|
||||||
|
# Handle the interrupt pin
|
||||||
|
set sw_proc_handle [xget_libgen_proc_handle]
|
||||||
|
set periph [xget_handle $sw_proc_handle "IPINST"]
|
||||||
|
set source_ports [xget_interrupt_sources $periph]
|
||||||
|
if {[llength $source_ports] > 1} {
|
||||||
|
error "Too many interrupting ports on the MicroBlaze. Should only find 1" "" "libgen_error"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if {[llength $source_ports] == 1} {
|
||||||
|
set source_port [lindex $source_ports 0]
|
||||||
|
if {[llength $source_port] != 0} {
|
||||||
|
set source_port_name [xget_value $source_port "VALUE"]
|
||||||
|
set source_periph [xget_handle $source_port "PARENT"]
|
||||||
|
set source_name [xget_value $source_periph "NAME"]
|
||||||
|
set source_driver [xget_sw_driver_handle_for_ipinst $sw_proc_handle $source_name]
|
||||||
|
|
||||||
|
if {[string compare -nocase $source_driver ""] != 0} {
|
||||||
|
set int_array [xget_handle $source_driver "ARRAY" "interrupt_handler"]
|
||||||
|
if {[llength $int_array] != 0} {
|
||||||
|
set int_array_elems [xget_handle $int_array "ELEMENTS" "*"]
|
||||||
|
if {[llength $int_array_elems] != 0} {
|
||||||
|
foreach int_array_elem $int_array_elems {
|
||||||
|
set int_port [xget_value $int_array_elem "PARAMETER" "int_port"]
|
||||||
|
if {[llength $int_port] != 0} {
|
||||||
|
if {[string compare -nocase $int_port $source_port_name] == 0 } {
|
||||||
|
set source_interrupt_handler [xget_value $int_array_elem "PARAMETER" "int_handler"]
|
||||||
|
set source_handler_arg [xget_value $int_array_elem "PARAMETER" "int_handler_arg"]
|
||||||
|
if {[string compare -nocase $source_handler_arg DEVICE_ID] == 0 } {
|
||||||
|
set source_handler_arg [xget_name $source_periph "DEVICE_ID"]
|
||||||
|
} else {
|
||||||
|
if {[string compare -nocase "global" [xget_port_type $source_port]] == 0} {
|
||||||
|
set source_handler_arg $default_arg
|
||||||
|
} else {
|
||||||
|
set source_handler_arg [xget_name $source_periph "C_BASEADDR"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Generate microblaze_interrupts_g.c file...
|
||||||
|
xcreate_mb_intr_config_file $source_interrupt_handler $source_handler_arg
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
proc xcreate_mb_intr_config_file {handler arg} {
|
||||||
|
|
||||||
|
set mb_table "MB_InterruptVectorTable"
|
||||||
|
|
||||||
|
set filename [file join "../standalone_v3_01_a/src" "microblaze_interrupts_g.c"]
|
||||||
|
file delete $filename
|
||||||
|
set config_file [open $filename w]
|
||||||
|
|
||||||
|
xprint_generated_header $config_file "Interrupt Handler Table for MicroBlaze Processor"
|
||||||
|
|
||||||
|
puts $config_file "#include \"microblaze_interrupts_i.h\""
|
||||||
|
puts $config_file "#include \"xparameters.h\""
|
||||||
|
puts $config_file "\n"
|
||||||
|
puts $config_file [format "extern void %s (void *);" $handler]
|
||||||
|
puts $config_file "\n/*"
|
||||||
|
puts $config_file "* The interrupt handler table for microblaze processor"
|
||||||
|
puts $config_file "*/\n"
|
||||||
|
puts $config_file [format "%sEntry %s\[\] =" $mb_table $mb_table]
|
||||||
|
puts $config_file "\{"
|
||||||
|
puts -nonewline $config_file [format "\{\t%s" $handler]
|
||||||
|
puts -nonewline $config_file [format ",\n\t(void*) %s\}" $arg]
|
||||||
|
puts -nonewline $config_file "\n\};"
|
||||||
|
puts $config_file "\n"
|
||||||
|
close $config_file
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# -------------------------------------------
|
||||||
|
# Tcl procedure xcreate_mb_exc_config file
|
||||||
|
# -------------------------------------------
|
||||||
|
proc xcreate_mb_exc_config_file { } {
|
||||||
|
|
||||||
|
set hfilename [file join "src" "microblaze_exceptions_g.h"]
|
||||||
|
file delete $hfilename
|
||||||
|
set hconfig_file [open $hfilename w]
|
||||||
|
|
||||||
|
xprint_generated_header $hconfig_file "Exception Handling Header for MicroBlaze Processor"
|
||||||
|
|
||||||
|
puts $hconfig_file "\n"
|
||||||
|
|
||||||
|
set sw_proc_handle [xget_libgen_proc_handle]
|
||||||
|
set hw_proc_handle [xget_handle $sw_proc_handle "IPINST"]
|
||||||
|
set procver [xget_value $hw_proc_handle "PARAMETER" "HW_VER"]
|
||||||
|
|
||||||
|
if { ![mb_has_exceptions $hw_proc_handle]} { ;# NO exceptions are enabled
|
||||||
|
close $hconfig_file ;# Do not generate any info in either the header or the C file
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
puts $hconfig_file "\#define MICROBLAZE_EXCEPTIONS_ENABLED 1"
|
||||||
|
if { [mb_can_handle_exceptions_in_delay_slots $procver] } {
|
||||||
|
puts $hconfig_file "#define MICROBLAZE_CAN_HANDLE_EXCEPTIONS_IN_DELAY_SLOTS"
|
||||||
|
}
|
||||||
|
|
||||||
|
close $hconfig_file
|
||||||
|
}
|
||||||
|
|
||||||
|
# --------------------------------------
|
||||||
|
# Tcl procedure post_generate
|
||||||
|
# This proc removes from libxil.a the basic
|
||||||
|
# and standalone BSP versions of
|
||||||
|
# _interrupt_handler and _hw_exception_handler
|
||||||
|
# routines
|
||||||
|
# --------------------------------------
|
||||||
|
proc post_generate {os_handle} {
|
||||||
|
set sw_proc_handle [xget_libgen_proc_handle]
|
||||||
|
set hw_proc_handle [xget_handle $sw_proc_handle "IPINST"]
|
||||||
|
set proctype [xget_value $hw_proc_handle "OPTION" "IPNAME"]
|
||||||
|
set procname [xget_value $hw_proc_handle "NAME"]
|
||||||
|
|
||||||
|
set procdrv [xget_sw_driver_handle_for_ipinst $sw_proc_handle $procname]
|
||||||
|
set archiver [xget_value $procdrv "PARAMETER" "archiver"]
|
||||||
|
|
||||||
|
if {[string compare -nocase $proctype "microblaze"] == 0 } {
|
||||||
|
# Remove _interrupt_handler.o from libxil.a for FreeRTOS
|
||||||
|
set libxil_a [file join .. .. lib libxil.a]
|
||||||
|
exec $archiver -d $libxil_a _interrupt_handler.o
|
||||||
|
|
||||||
|
# We have linkage problems due to how these platforms are defined. Can't do this right now.
|
||||||
|
# # Remove _exception_handler.o from libxil.a for FreeRTOS
|
||||||
|
# exec bash -c "$archiver -d ../../lib/libxil.a _exception_handler.o"
|
||||||
|
|
||||||
|
# Remove _hw_exception_handler.o from libxil.a for microblaze cores with exception support
|
||||||
|
if {[mb_has_exceptions $hw_proc_handle]} {
|
||||||
|
exec $archiver -d ../../lib/libxil.a _hw_exception_handler.o
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# --------------------------------------
|
||||||
|
# Tcl procedure execs_generate
|
||||||
|
# This proc removes from libxil.a all
|
||||||
|
# the stuff that we are overriding
|
||||||
|
# with xilkernel
|
||||||
|
# We currently override,
|
||||||
|
# MicroBlaze
|
||||||
|
# - Dummy _interrupt_hander and _hw_exception_handler
|
||||||
|
# (in post_generate)
|
||||||
|
# PPC
|
||||||
|
# - xvectors.o; sleep.o (IF config_time is true)
|
||||||
|
# Common to all processors
|
||||||
|
# - errno.o
|
||||||
|
# --------------------------------------
|
||||||
|
proc execs_generate {os_handle} {
|
||||||
|
set sw_proc_handle [xget_libgen_proc_handle]
|
||||||
|
set hw_proc_handle [xget_handle $sw_proc_handle "IPINST"]
|
||||||
|
set proctype [xget_value $hw_proc_handle "OPTION" "IPNAME"]
|
||||||
|
set procname [xget_value $hw_proc_handle "NAME"]
|
||||||
|
|
||||||
|
set procdrv [xget_sw_driver_handle_for_ipinst $sw_proc_handle $procname]
|
||||||
|
# Remove _interrupt_handler.o from libxil.a for mb-gcc
|
||||||
|
set archiver [xget_value $procdrv "PARAMETER" "archiver"]
|
||||||
|
|
||||||
|
set libxil_a [file join .. .. lib libxil.a]
|
||||||
|
# exec $archiver -d $libxil_a errno.o
|
||||||
|
|
||||||
|
# We have linkage problems due to how these platforms are defined. Can't do this right now.
|
||||||
|
# exec "$archiver -d $libxil_a microblaze_interrupt_handler.o"
|
||||||
|
}
|
||||||
|
|
||||||
|
# --------------------------------------
|
||||||
|
# Return true if this MB has
|
||||||
|
# exception handling support
|
||||||
|
# --------------------------------------
|
||||||
|
proc mb_has_exceptions { hw_proc_handle } {
|
||||||
|
|
||||||
|
# Check if the following parameters exist on this MicroBlaze's MPD
|
||||||
|
set ee [xget_value $hw_proc_handle "PARAMETER" "C_UNALIGNED_EXCEPTIONS"]
|
||||||
|
if { $ee != "" } {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
set ee [xget_value $hw_proc_handle "PARAMETER" "C_ILL_OPCODE_EXCEPTION"]
|
||||||
|
if { $ee != "" } {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
set ee [xget_value $hw_proc_handle "PARAMETER" "C_IOPB_BUS_EXCEPTION"]
|
||||||
|
if { $ee != "" } {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
set ee [xget_value $hw_proc_handle "PARAMETER" "C_DOPB_BUS_EXCEPTION"]
|
||||||
|
if { $ee != "" } {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
set ee [xget_value $hw_proc_handle "PARAMETER" "C_DIV_BY_ZERO_EXCEPTION"]
|
||||||
|
if { $ee != "" } {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
set ee [xget_value $hw_proc_handle "PARAMETER" "C_DIV_ZERO_EXCEPTION"]
|
||||||
|
if { $ee != "" } {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
set ee [xget_value $hw_proc_handle "PARAMETER" "C_FPU_EXCEPTION"]
|
||||||
|
if { $ee != "" } {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
set ee [xget_value $hw_proc_handle "PARAMETER" "C_USE_MMU"]
|
||||||
|
if { $ee != "" && $ee != 0 } {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
# --------------------------------------
|
||||||
|
# Return true if this MB has
|
||||||
|
# FPU exception handling support
|
||||||
|
# --------------------------------------
|
||||||
|
proc mb_has_fpu_exceptions { hw_proc_handle } {
|
||||||
|
|
||||||
|
# Check if the following parameters exist on this MicroBlaze's MPD
|
||||||
|
set ee [xget_value $hw_proc_handle "PARAMETER" "C_FPU_EXCEPTION"]
|
||||||
|
if { $ee != "" } {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
# --------------------------------------
|
||||||
|
# Return true if this MB has PVR support
|
||||||
|
# --------------------------------------
|
||||||
|
proc mb_has_pvr { hw_proc_handle } {
|
||||||
|
|
||||||
|
# Check if the following parameters exist on this MicroBlaze's MPD
|
||||||
|
set pvr [xget_value $hw_proc_handle "PARAMETER" "C_PVR"]
|
||||||
|
if { $pvr != "" } {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
# --------------------------------------
|
||||||
|
# Return true if MB ver 'procver' has
|
||||||
|
# support for handling exceptions in
|
||||||
|
# delay slots
|
||||||
|
# --------------------------------------
|
||||||
|
proc mb_can_handle_exceptions_in_delay_slots { procver } {
|
||||||
|
|
||||||
|
if { [string compare -nocase $procver "5.00.a"] >= 0 } {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# Gets all the handles that are memory controller cores.
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
proc xget_memory_controller_handles { mhs } {
|
||||||
|
set ret_list ""
|
||||||
|
|
||||||
|
# Gets all MhsInsts in the system
|
||||||
|
set mhsinsts [xget_hw_ipinst_handle $mhs "*"]
|
||||||
|
|
||||||
|
# Loop thru each MhsInst and determine if have "ADDR_TYPE = MEMORY" in
|
||||||
|
# the parameters.
|
||||||
|
foreach mhsinst $mhsinsts {
|
||||||
|
# Gets all parameters of the component
|
||||||
|
set params [xget_hw_parameter_handle $mhsinst "*"]
|
||||||
|
|
||||||
|
# Loop thru each param and find tag "ADDR_TYPE = MEMORY"
|
||||||
|
foreach param $params {
|
||||||
|
if {$param == 0} {
|
||||||
|
continue
|
||||||
|
} elseif {$param == ""} {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
set addrTypeValue [ xget_hw_subproperty_value $param "ADDR_TYPE" ]
|
||||||
|
|
||||||
|
# Found tag! Add MhsInst to list and break to go to next MhsInst
|
||||||
|
if {[string compare -nocase $addrTypeValue "MEMORY"] == 0} {
|
||||||
|
lappend ret_list $mhsinst
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret_list
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
The necessary files are copied to this BSP directory structure by executing
|
||||||
|
the CreateProjectDirectoryStructure.bat batch file located in the
|
||||||
|
FreeRTOS\\Demo\MicroBlaze_Spartan-6_EthernetLite\SDKProjects\RTOSDemoSource
|
||||||
|
folder.
|
@ -0,0 +1,77 @@
|
|||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# Copyright (c) 2010 Xilinx, Inc. All rights reserved.
|
||||||
|
#
|
||||||
|
# Xilinx, Inc.
|
||||||
|
# XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
|
||||||
|
# COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
|
||||||
|
# ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
|
||||||
|
# STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
|
||||||
|
# IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
|
||||||
|
# FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
|
||||||
|
# XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
|
||||||
|
# THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
|
||||||
|
# ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
|
||||||
|
# FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
# AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
#
|
||||||
|
# Top level Makefile
|
||||||
|
#
|
||||||
|
# $Id: $
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
#
|
||||||
|
# Processor architecture
|
||||||
|
# microblaze
|
||||||
|
#
|
||||||
|
ARCH = microblaze
|
||||||
|
|
||||||
|
SYSTEMDIR = ../../..
|
||||||
|
|
||||||
|
TOPDIR = .
|
||||||
|
|
||||||
|
ARCH_PREFIX = mb
|
||||||
|
|
||||||
|
#
|
||||||
|
# gnu tools for Makefile
|
||||||
|
#
|
||||||
|
CC = $(ARCH_PREFIX)-gcc
|
||||||
|
AR = $(ARCH_PREFIX)-ar
|
||||||
|
CP = cp
|
||||||
|
|
||||||
|
#
|
||||||
|
# Compiler, linker and other options.
|
||||||
|
#
|
||||||
|
CFLAGS = ${COMPILER_FLAGS} ${EXTRA_COMPILER_FLAGS}
|
||||||
|
|
||||||
|
#
|
||||||
|
# System project directories.
|
||||||
|
#
|
||||||
|
LIBDIR = $(SYSTEMDIR)/lib
|
||||||
|
INCLUDEDIR = $(SYSTEMDIR)/include
|
||||||
|
|
||||||
|
# Kernel library.
|
||||||
|
LIBFREERTOS = ${LIBDIR}/libfreertos.a
|
||||||
|
|
||||||
|
INCLUDEFILES = ${TOPDIR}/*.h
|
||||||
|
|
||||||
|
INCLUDES = -I$(INCLUDEDIR) \
|
||||||
|
-I${TOPDIR}
|
||||||
|
|
||||||
|
KERNEL_AR_OBJS = *.c *.S
|
||||||
|
|
||||||
|
OUTS = *.o
|
||||||
|
|
||||||
|
libs: $(KERNEL_AR_OBJS)
|
||||||
|
@echo "Compiling FreeRTOS"
|
||||||
|
@$(COMPILER) $(COMPILER_FLAGS) $(EXTRA_COMPILER_FLAGS) $(INCLUDES) $^
|
||||||
|
@$(ARCHIVER) -r ${LIBFREERTOS} ${OUTS}
|
||||||
|
make clean
|
||||||
|
|
||||||
|
.PHONY: include
|
||||||
|
include:
|
||||||
|
${CP} ${INCLUDEFILES} ${INCLUDEDIR}
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf ${OUTS}
|
@ -0,0 +1,19 @@
|
|||||||
|
Each real time kernel port consists of three files that contain the core kernel
|
||||||
|
components and are common to every port, and one or more files that are
|
||||||
|
specific to a particular microcontroller and/or compiler.
|
||||||
|
|
||||||
|
|
||||||
|
+ The FreeRTOS/Source/Portable/MemMang directory contains the three sample
|
||||||
|
memory allocators as described on the http://www.FreeRTOS.org WEB site.
|
||||||
|
|
||||||
|
+ The other directories each contain files specific to a particular
|
||||||
|
microcontroller or compiler.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
For example, if you are interested in the GCC port for the ATMega323
|
||||||
|
microcontroller then the port specific files are contained in
|
||||||
|
FreeRTOS/Source/Portable/GCC/ATMega323 directory. If this is the only
|
||||||
|
port you are interested in then all the other directories can be
|
||||||
|
ignored.
|
||||||
|
|
@ -0,0 +1,17 @@
|
|||||||
|
Each real time kernel port consists of three files that contain the core kernel
|
||||||
|
components and are common to every port, and one or more files that are
|
||||||
|
specific to a particular microcontroller and or compiler.
|
||||||
|
|
||||||
|
+ The FreeRTOS/Source directory contains the three files that are common to
|
||||||
|
every port - list.c, queue.c and tasks.c. The kernel is contained within these
|
||||||
|
three files. croutine.c implements the optional co-routine functionality - which
|
||||||
|
is normally only used on very memory limited systems.
|
||||||
|
|
||||||
|
+ The FreeRTOS/Source/Portable directory contains the files that are specific to
|
||||||
|
a particular microcontroller and or compiler.
|
||||||
|
|
||||||
|
+ The FreeRTOS/Source/include directory contains the real time kernel header
|
||||||
|
files.
|
||||||
|
|
||||||
|
See the readme file in the FreeRTOS/Source/Portable directory for more
|
||||||
|
information.
|
@ -0,0 +1,19 @@
|
|||||||
|
The download includes the kernel source code, and a demo application for EVERY
|
||||||
|
RTOS port. See http://www.freertos.org/a00017.html for full details of the
|
||||||
|
directory structure and information on locating the files you require.
|
||||||
|
|
||||||
|
The easiest way to use FreeRTOS is start start with one of the demo application
|
||||||
|
projects. Once this is running the project can be modified to include your own
|
||||||
|
source files. This way the correct files and compiler options will be
|
||||||
|
automatically included in your application.
|
||||||
|
|
||||||
|
+ The Source directory contains the real time kernel source files for every
|
||||||
|
port. The kernel itself is only 3 files.
|
||||||
|
|
||||||
|
+ The Demo directory contains the demo application source files for every
|
||||||
|
port.
|
||||||
|
|
||||||
|
+ The TraceCon directory contains the trace visualisation exe file.
|
||||||
|
|
||||||
|
See the readme files in the respective directories for further information.
|
||||||
|
|
@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
PARAMETER VERSION = 2.2.0
|
||||||
|
|
||||||
|
|
||||||
|
BEGIN OS
|
||||||
|
PARAMETER OS_NAME = freertos
|
||||||
|
PARAMETER STDIN = *
|
||||||
|
PARAMETER STDOUT = *
|
||||||
|
END
|
@ -0,0 +1,126 @@
|
|||||||
|
proc swapp_get_name {} {
|
||||||
|
return "FreeRTOS Hello World";
|
||||||
|
}
|
||||||
|
|
||||||
|
proc swapp_get_description {} {
|
||||||
|
return "Let's say 'Hello World' in FreeRTOS.";
|
||||||
|
}
|
||||||
|
|
||||||
|
proc get_os {} {
|
||||||
|
set oslist [xget_sw_modules "type" "os"];
|
||||||
|
set os [lindex $oslist 0];
|
||||||
|
|
||||||
|
if { $os == "" } {
|
||||||
|
error "No Operating System specified in the Board Support Package.";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $os;
|
||||||
|
}
|
||||||
|
|
||||||
|
proc get_stdout {} {
|
||||||
|
set os [get_os];
|
||||||
|
set stdout [xget_sw_module_parameter $os "STDOUT"];
|
||||||
|
return $stdout;
|
||||||
|
}
|
||||||
|
|
||||||
|
proc check_stdout_hw {} {
|
||||||
|
set p7_uarts [xget_ips "type" "ps7_uart"];
|
||||||
|
set uartlites [xget_ips "type" "uartlite"];
|
||||||
|
set uart16550s [xget_ips "type" "uart16550"];
|
||||||
|
if { ([llength $p7_uarts] == 0) && ([llength $uartlites] == 0) &&
|
||||||
|
([llength $uart16550s] == 0) } {
|
||||||
|
# Check for MDM-Uart peripheral. The MDM would be listed as a peripheral
|
||||||
|
# only if it has a UART interface. So no further check is required
|
||||||
|
set mdmlist [xget_ips "type" "mdm"]
|
||||||
|
if { [llength $mdmlist] == 0 } {
|
||||||
|
error "This application requires a Uart IP in the hardware."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
proc check_stdout_sw {} {
|
||||||
|
set stdout [get_stdout];
|
||||||
|
if { $stdout == "none" } {
|
||||||
|
error "The STDOUT parameter is not set on the OS. Hello World requires stdout to be set."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
proc swapp_is_supported_hw {} {
|
||||||
|
# check for uart peripheral
|
||||||
|
check_stdout_hw;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
proc swapp_is_supported_sw {} {
|
||||||
|
# check for stdout being set
|
||||||
|
check_stdout_sw;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
proc generate_stdout_config { fid } {
|
||||||
|
set stdout [get_stdout];
|
||||||
|
|
||||||
|
# if stdout is uartlite, we don't have to generate anything
|
||||||
|
set stdout_type [xget_ip_attribute "type" $stdout];
|
||||||
|
|
||||||
|
if { [regexp -nocase "uartlite" $stdout_type] || [string match -nocase "mdm" $stdout_type] ||
|
||||||
|
[regexp -nocase "ps7_uart" $stdout_type]} {
|
||||||
|
return;
|
||||||
|
} elseif { [regexp -nocase "uart16550" $stdout_type] } {
|
||||||
|
# mention that we have a 16550
|
||||||
|
puts $fid "#define STDOUT_IS_16550";
|
||||||
|
|
||||||
|
# and note down its base address
|
||||||
|
set prefix "XPAR_";
|
||||||
|
set postfix "_BASEADDR";
|
||||||
|
set stdout_baseaddr_macro $prefix$stdout$postfix;
|
||||||
|
set stdout_baseaddr_macro [string toupper $stdout_baseaddr_macro];
|
||||||
|
puts $fid "#define STDOUT_BASEADDR $stdout_baseaddr_macro";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
proc generate_cache_mask { fid } {
|
||||||
|
set mask [format "0x%x" [xget_ppc_cache_mask]]
|
||||||
|
puts $fid "#ifdef __PPC__"
|
||||||
|
puts $fid "#define CACHEABLE_REGION_MASK $mask"
|
||||||
|
puts $fid "#endif\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
# depending on the type of os (standalone|xilkernel), choose
|
||||||
|
# the correct source files
|
||||||
|
proc swapp_generate {} {
|
||||||
|
set os [get_os];
|
||||||
|
|
||||||
|
if { $os == "xilkernel" } {
|
||||||
|
file rename -force "helloworld_xmk.c" "helloworld.c"
|
||||||
|
} else {
|
||||||
|
file delete -force "helloworld_xmk.c"
|
||||||
|
}
|
||||||
|
|
||||||
|
# cleanup this file for writing
|
||||||
|
set fid [open "platform_config.h" "w+"];
|
||||||
|
puts $fid "#ifndef __PLATFORM_CONFIG_H_";
|
||||||
|
puts $fid "#define __PLATFORM_CONFIG_H_\n";
|
||||||
|
|
||||||
|
# if we have a uart16550 as stdout, then generate some config for that
|
||||||
|
generate_stdout_config $fid;
|
||||||
|
|
||||||
|
# for ppc, generate cache mask string
|
||||||
|
generate_cache_mask $fid;
|
||||||
|
|
||||||
|
puts $fid "#endif";
|
||||||
|
close $fid;
|
||||||
|
}
|
||||||
|
|
||||||
|
proc swapp_get_linker_constraints {} {
|
||||||
|
# this app does not require a .vectors section if it is being run w/ the standalone OS on PPC
|
||||||
|
set os [get_os];
|
||||||
|
|
||||||
|
if { $os == "standalone" } {
|
||||||
|
return "vector_section no";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
@ -0,0 +1,398 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
See http://www.FreeRTOS.org for full information on FreeRTOS, including
|
||||||
|
an API reference, pdf API reference manuals, and FreeRTOS tutorial books.
|
||||||
|
|
||||||
|
See http://www.freertos.org/Free-RTOS-for-Xilinx-MicroBlaze-on-Spartan-6-FPGA.html
|
||||||
|
for comprehensive standalone FreeRTOS for MicroBlaze demos.
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||||
|
contact details.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||||
|
critical systems.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||||
|
licensing and training services.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* main-blinky.c (this file) defines a very simple demo that creates two tasks,
|
||||||
|
* one queue, and one timer.
|
||||||
|
*
|
||||||
|
* The main() Function:
|
||||||
|
* main() creates one software timer, one queue, and two tasks. It then starts
|
||||||
|
* the scheduler.
|
||||||
|
*
|
||||||
|
* The Queue Send Task:
|
||||||
|
* The queue send task is implemented by the prvQueueSendTask() function in
|
||||||
|
* this file. prvQueueSendTask() sits in a loop that causes it to repeatedly
|
||||||
|
* block for 200 milliseconds, before sending the value 100 to the queue that
|
||||||
|
* was created within main(). Once the value is sent, the task loops back
|
||||||
|
* around to block for another 200 milliseconds.
|
||||||
|
*
|
||||||
|
* The Queue Receive Task:
|
||||||
|
* The queue receive task is implemented by the prvQueueReceiveTask() function
|
||||||
|
* in this file. prvQueueReceiveTask() sits in a loop that causes it to
|
||||||
|
* repeatedly attempt to read data from the queue that was created within
|
||||||
|
* main(). When data is received, the task checks the value of the data, and
|
||||||
|
* if the value equals the expected 100, increments the ulRecieved variable.
|
||||||
|
* The 'block time' parameter passed to the queue receive function specifies
|
||||||
|
* that the task should be held in the Blocked state indefinitely to wait for
|
||||||
|
* data to be available on the queue. The queue receive task will only leave
|
||||||
|
* the Blocked state when the queue send task writes to the queue. As the queue
|
||||||
|
* send task writes to the queue every 200 milliseconds, the queue receive task
|
||||||
|
* leaves the Blocked state every 200 milliseconds, and therefore toggles the LED
|
||||||
|
* every 200 milliseconds.
|
||||||
|
*
|
||||||
|
* The Software Timer
|
||||||
|
* The software timer is configured to be an "auto reset" timer. Its callback
|
||||||
|
* function simply increments the ulCallback variable each time it executes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Kernel includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "queue.h"
|
||||||
|
#include "timers.h"
|
||||||
|
|
||||||
|
/* BSP includes. */
|
||||||
|
#include "xtmrctr.h"
|
||||||
|
|
||||||
|
/* Priorities at which the tasks are created. */
|
||||||
|
#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
|
||||||
|
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
||||||
|
|
||||||
|
/* The rate at which data is sent to the queue, specified in milliseconds, and
|
||||||
|
converted to ticks using the portTICK_RATE_MS constant. */
|
||||||
|
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_RATE_MS )
|
||||||
|
|
||||||
|
/* The number of items the queue can hold. This is 1 as the receive task
|
||||||
|
will remove items as they are added because it has the higher priority, meaning
|
||||||
|
the send task should always find the queue empty. */
|
||||||
|
#define mainQUEUE_LENGTH ( 1 )
|
||||||
|
|
||||||
|
/* A block time of 0 simply means, "don't block". */
|
||||||
|
#define mainDONT_BLOCK ( portTickType ) 0
|
||||||
|
|
||||||
|
/* The following constants describe the timer instance used in this application.
|
||||||
|
They are defined here such that a user can easily change all the needed parameters
|
||||||
|
in one place. */
|
||||||
|
#define TIMER_DEVICE_ID XPAR_TMRCTR_0_DEVICE_ID
|
||||||
|
#define TIMER_FREQ_HZ XPAR_TMRCTR_0_CLOCK_FREQ_HZ
|
||||||
|
#define TIMER_INTR_ID XPAR_INTC_0_TMRCTR_0_VEC_ID
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The tasks as described in the comments at the top of this file.
|
||||||
|
*/
|
||||||
|
static void prvQueueReceiveTask( void *pvParameters );
|
||||||
|
static void prvQueueSendTask( void *pvParameters );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The LED timer callback function. This does nothing but increment the
|
||||||
|
* ulCallback variable each time it executes.
|
||||||
|
*/
|
||||||
|
static void vSoftwareTimerCallback( xTimerHandle xTimer );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* The queue used by the queue send and queue receive tasks. */
|
||||||
|
static xQueueHandle xQueue = NULL;
|
||||||
|
|
||||||
|
/* The LED software timer. This uses vSoftwareTimerCallback() as its callback
|
||||||
|
function. */
|
||||||
|
static xTimerHandle xExampleSoftwareTimer = NULL;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Structures that hold the state of the various peripherals used by this demo.
|
||||||
|
These are used by the Xilinx peripheral driver API functions. */
|
||||||
|
static XTmrCtr xTimer0Instance;
|
||||||
|
|
||||||
|
/* The variable that is incremented each time the receive task receives the
|
||||||
|
value 100. */
|
||||||
|
static unsigned long ulReceived = 0UL;
|
||||||
|
|
||||||
|
/* The variable that is incremented each time the software time callback function
|
||||||
|
executes. */
|
||||||
|
static unsigned long ulCallback = 0UL;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
int main( void )
|
||||||
|
{
|
||||||
|
/***************************************************************************
|
||||||
|
See http://www.FreeRTOS.org for full information on FreeRTOS, including
|
||||||
|
an API reference, pdf API reference manuals, and FreeRTOS tutorial books.
|
||||||
|
|
||||||
|
See http://www.freertos.org/Free-RTOS-for-Xilinx-MicroBlaze-on-Spartan-6-FPGA.html
|
||||||
|
for comprehensive standalone FreeRTOS for MicroBlaze demos.
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/* Create the queue used by the queue send and queue receive tasks as
|
||||||
|
described in the comments at the top of this file. */
|
||||||
|
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );
|
||||||
|
|
||||||
|
/* Sanity check that the queue was created. */
|
||||||
|
configASSERT( xQueue );
|
||||||
|
|
||||||
|
/* Start the two tasks as described in the comments at the top of this
|
||||||
|
file. */
|
||||||
|
xTaskCreate( prvQueueReceiveTask, ( signed char * ) "Rx", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_RECEIVE_TASK_PRIORITY, NULL );
|
||||||
|
xTaskCreate( prvQueueSendTask, ( signed char * ) "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
|
||||||
|
|
||||||
|
/* Create the software timer */
|
||||||
|
xExampleSoftwareTimer = xTimerCreate( ( const signed char * ) "SoftwareTimer", /* A text name, purely to help debugging. */
|
||||||
|
( 5000 / portTICK_RATE_MS ), /* The timer period, in this case 5000ms (5s). */
|
||||||
|
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
|
||||||
|
( void * ) 0, /* The ID is not used, so can be set to anything. */
|
||||||
|
vSoftwareTimerCallback /* The callback function that switches the LED off. */
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Start the software timer. */
|
||||||
|
xTimerStart( xExampleSoftwareTimer, mainDONT_BLOCK );
|
||||||
|
|
||||||
|
/* Start the tasks and timer running. */
|
||||||
|
vTaskStartScheduler();
|
||||||
|
|
||||||
|
/* If all is well, the scheduler will now be running, and the following line
|
||||||
|
will never be reached. If the following line does execute, then there was
|
||||||
|
insufficient FreeRTOS heap memory available for the idle and/or timer tasks
|
||||||
|
to be created. See the memory management section on the FreeRTOS web site
|
||||||
|
for more details. */
|
||||||
|
for( ;; );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* The callback is executed when the software timer expires. */
|
||||||
|
static void vSoftwareTimerCallback( xTimerHandle xTimer )
|
||||||
|
{
|
||||||
|
/* Just increment the ulCallbac variable. */
|
||||||
|
ulCallback++;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvQueueSendTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
portTickType xNextWakeTime;
|
||||||
|
const unsigned long ulValueToSend = 100UL;
|
||||||
|
|
||||||
|
/* Initialise xNextWakeTime - this only needs to be done once. */
|
||||||
|
xNextWakeTime = xTaskGetTickCount();
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Place this task in the blocked state until it is time to run again.
|
||||||
|
The block time is specified in ticks, the constant used converts ticks
|
||||||
|
to ms. While in the Blocked state this task will not consume any CPU
|
||||||
|
time. */
|
||||||
|
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
|
||||||
|
|
||||||
|
/* Send to the queue - causing the queue receive task to unblock and
|
||||||
|
toggle an LED. 0 is used as the block time so the sending operation
|
||||||
|
will not block - it shouldn't need to block as the queue should always
|
||||||
|
be empty at this point in the code. */
|
||||||
|
xQueueSend( xQueue, &ulValueToSend, mainDONT_BLOCK );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvQueueReceiveTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
unsigned long ulReceivedValue;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Wait until something arrives in the queue - this task will block
|
||||||
|
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
|
||||||
|
FreeRTOSConfig.h. */
|
||||||
|
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
|
||||||
|
|
||||||
|
/* To get here something must have been received from the queue, but
|
||||||
|
is it the expected value? If it is, increment the ulReceived variable. */
|
||||||
|
if( ulReceivedValue == 100UL )
|
||||||
|
{
|
||||||
|
ulReceived++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vApplicationMallocFailedHook( void )
|
||||||
|
{
|
||||||
|
/* vApplicationMallocFailedHook() will only be called if
|
||||||
|
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
|
||||||
|
function that will get called if a call to pvPortMalloc() fails.
|
||||||
|
pvPortMalloc() is called internally by the kernel whenever a task, queue or
|
||||||
|
semaphore is created. It is also called by various parts of the demo
|
||||||
|
application. If heap_1.c or heap_2.c are used, then the size of the heap
|
||||||
|
available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
|
||||||
|
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
|
||||||
|
to query the size of free heap space that remains (although it does not
|
||||||
|
provide information on how the remaining heap might be fragmented). */
|
||||||
|
taskDISABLE_INTERRUPTS();
|
||||||
|
for( ;; );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName )
|
||||||
|
{
|
||||||
|
( void ) pcTaskName;
|
||||||
|
( void ) pxTask;
|
||||||
|
|
||||||
|
/* vApplicationStackOverflowHook() will only be called if
|
||||||
|
configCHECK_FOR_STACK_OVERFLOW is set to either 1 or 2. The handle and name
|
||||||
|
of the offending task will be passed into the hook function via its
|
||||||
|
parameters. However, when a stack has overflowed, it is possible that the
|
||||||
|
parameters will have been corrupted, in which case the pxCurrentTCB variable
|
||||||
|
can be inspected directly. */
|
||||||
|
taskDISABLE_INTERRUPTS();
|
||||||
|
for( ;; );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vApplicationIdleHook( void )
|
||||||
|
{
|
||||||
|
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
|
||||||
|
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
|
||||||
|
task. It is essential that code added to this hook function never attempts
|
||||||
|
to block in any way (for example, call xQueueReceive() with a block time
|
||||||
|
specified, or call vTaskDelay()). If the application makes use of the
|
||||||
|
vTaskDelete() API function (as this demo application does) then it is also
|
||||||
|
important that vApplicationIdleHook() is permitted to return to its calling
|
||||||
|
function, because it is the responsibility of the idle task to clean up
|
||||||
|
memory allocated by the kernel to any task that has since been deleted. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vApplicationTickHook( void )
|
||||||
|
{
|
||||||
|
/* vApplicationTickHook() will only be called if configUSE_TICK_HOOK is set
|
||||||
|
to 1 in FreeRTOSConfig.h. It executes from an interrupt context so must
|
||||||
|
not use any FreeRTOS API functions that do not end in ...FromISR().
|
||||||
|
|
||||||
|
This simple blinky demo does not use the tick hook, but a tick hook is
|
||||||
|
required to be defined as the blinky and full demos share a
|
||||||
|
FreeRTOSConfig.h header file. */
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This is an application defined callback function used to install the tick
|
||||||
|
interrupt handler. It is provided as an application callback because the kernel
|
||||||
|
will run on lots of different MicroBlaze and FPGA configurations - there could
|
||||||
|
be multiple timer instances in the hardware platform and the users can chose to
|
||||||
|
use any one of them. This example uses Timer 0. If that is available in your
|
||||||
|
hardware platform then this example callback implementation should not require
|
||||||
|
modification. The definitions for the timer instance used are at the top of this
|
||||||
|
file so that users can change them at one place based on the timer instance they
|
||||||
|
use. The name of the interrupt handler that should be installed is vPortTickISR(),
|
||||||
|
which the function below declares as an extern. */
|
||||||
|
void vApplicationSetupTimerInterrupt( void )
|
||||||
|
{
|
||||||
|
portBASE_TYPE xStatus;
|
||||||
|
const unsigned char ucTimerCounterNumber = ( unsigned char ) 0U;
|
||||||
|
const unsigned long ulCounterValue = ( ( TIMER_FREQ_HZ / configTICK_RATE_HZ ) - 1UL );
|
||||||
|
extern void vPortTickISR( void *pvUnused );
|
||||||
|
|
||||||
|
/* Initialise the timer/counter. */
|
||||||
|
xStatus = XTmrCtr_Initialize( &xTimer0Instance, TIMER_DEVICE_ID );
|
||||||
|
|
||||||
|
if( xStatus == XST_SUCCESS )
|
||||||
|
{
|
||||||
|
/* Install the tick interrupt handler as the timer ISR.
|
||||||
|
*NOTE* The xPortInstallInterruptHandler() API function must be used for
|
||||||
|
this purpose. */
|
||||||
|
xStatus = xPortInstallInterruptHandler( TIMER_INTR_ID, vPortTickISR, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xStatus == pdPASS )
|
||||||
|
{
|
||||||
|
/* Enable the timer interrupt in the interrupt controller.
|
||||||
|
*NOTE* The vPortEnableInterrupt() API function must be used for this
|
||||||
|
purpose. */
|
||||||
|
vPortEnableInterrupt( TIMER_INTR_ID );
|
||||||
|
|
||||||
|
/* Configure the timer interrupt handler. */
|
||||||
|
XTmrCtr_SetHandler( &xTimer0Instance, ( void * ) vPortTickISR, NULL );
|
||||||
|
|
||||||
|
/* Set the correct period for the timer. */
|
||||||
|
XTmrCtr_SetResetValue( &xTimer0Instance, ucTimerCounterNumber, ulCounterValue );
|
||||||
|
|
||||||
|
/* Enable the interrupts. Auto-reload mode is used to generate a
|
||||||
|
periodic tick. Note that interrupts are disabled when this function is
|
||||||
|
called, so interrupts will not start to be processed until the first
|
||||||
|
task has started to run. */
|
||||||
|
XTmrCtr_SetOptions( &xTimer0Instance, ucTimerCounterNumber, ( XTC_INT_MODE_OPTION | XTC_AUTO_RELOAD_OPTION | XTC_DOWN_COUNT_OPTION ) );
|
||||||
|
|
||||||
|
/* Start the timer. */
|
||||||
|
XTmrCtr_Start( &xTimer0Instance, ucTimerCounterNumber );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sanity check that the function executed as expected. */
|
||||||
|
configASSERT( ( xStatus == pdPASS ) );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This is an application defined callback function used to clear whichever
|
||||||
|
interrupt was installed by the the vApplicationSetupTimerInterrupt() callback
|
||||||
|
function - in this case the interrupt generated by the AXI timer. It is
|
||||||
|
provided as an application callback because the kernel will run on lots of
|
||||||
|
different MicroBlaze and FPGA configurations - not all of which will have the
|
||||||
|
same timer peripherals defined or available. This example uses the AXI Timer 0.
|
||||||
|
If that is available on your hardware platform then this example callback
|
||||||
|
implementation should not require modification provided the example definition
|
||||||
|
of vApplicationSetupTimerInterrupt() is also not modified. */
|
||||||
|
void vApplicationClearTimerInterrupt( void )
|
||||||
|
{
|
||||||
|
unsigned long ulCSR;
|
||||||
|
|
||||||
|
/* Clear the timer interrupt */
|
||||||
|
ulCSR = XTmrCtr_GetControlStatusReg( XPAR_TMRCTR_0_BASEADDR, 0 );
|
||||||
|
XTmrCtr_SetControlStatusReg( XPAR_TMRCTR_0_BASEADDR, 0, ulCSR );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
Loading…
Reference in New Issue