--- /dev/null
+# Doxyfile 1.7.1
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = "BlackTank LPC1769"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = 0.0.1
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = ./doc
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak,
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given extension.
+# Doxygen has a built-in mapping, but you can override or extend it using this
+# tag. The format is ext=language, where ext is a file extension, and language
+# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,
+# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make
+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
+# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
+# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen to replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penality.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will rougly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = YES
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
+# will list include files with double quotes in the documentation
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
+# will sort the (brief and detailed) documentation of class members so that
+# constructors and destructors are listed first. If set to NO (the default)
+# the constructors will appear in the respective orders defined by
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page. This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. The create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option.
+# You can optionally specify a file name after the option, if omitted
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = .
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS = *.c \
+ *.cc \
+ *.cxx \
+ *.cpp \
+ *.c++ \
+ *.d \
+ *.java \
+ *.ii \
+ *.ixx \
+ *.ipp \
+ *.i++ \
+ *.inl \
+ *.h \
+ *.hh \
+ *.hxx \
+ *.hpp \
+ *.h++ \
+ *.idl \
+ *.odl \
+ *.cs \
+ *.php \
+ *.php3 \
+ *.inc \
+ *.m \
+ *.mm \
+ *.dox \
+ *.py \
+ *.f90 \
+ *.f \
+ *.vhd \
+ *.vhdl
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH = ./images
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code. Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
+# Doxygen will adjust the colors in the stylesheet and background images
+# according to this color. Hue is specified as an angle on a colorwheel,
+# see http://en.wikipedia.org/wiki/Hue for more information.
+# For instance the value 0 represents red, 60 is yellow, 120 is green,
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
+# The allowed range is 0 to 359.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
+# the colors in the HTML output. For a value of 0 the output will use
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
+# the luminance component of the colors in the HTML output. Values below
+# 100 gradually make the output lighter, whereas values above 100 make
+# the output darker. The value divided by 100 is the actual gamma applied,
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP = YES
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
+# that can be used as input for Qt's qhelpgenerator to generate a
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
+# add. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
+# will be generated, which together with the HTML files, form an Eclipse help
+# plugin. To install this plugin and make it available under the help contents
+# menu in Eclipse, the contents of the directory containing the HTML and XML
+# files needs to be copied into the plugins directory of eclipse. The name of
+# the directory within the plugins directory should be the same as
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
+# the help appears.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have
+# this name.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = YES
+
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
+# and Class Hierarchy pages using a tree view instead of an ordered list.
+
+USE_INLINE_TREES = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are
+# not supported properly for IE 6.0, but are supported on all modern browsers.
+# Note that when changing this option you need to delete any form_*.png files
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT = YES
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box
+# for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
+# (GENERATE_DOCSET) there is already a search function so this one should
+# typically be disabled. For large projects the javascript based search engine
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE = NO
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a PHP enabled web server instead of at the web client
+# using Javascript. Doxygen will generate the search PHP script and index
+# file to put on the web server. The advantage of the server
+# based approach is that it scales better to large projects and allows
+# full text search. The disadvances is that it is more difficult to setup
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+# Note that when enabling USE_PDFLATEX this option is only used for
+# generating bitmaps for formulas in the HTML output, but not in the
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include
+# source code with syntax highlighting in the LaTeX output.
+# Note that which sources are shown also depends on other settings
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = NO
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = YES
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
+# allowed to run in parallel. When set to 0 (the default) doxygen will
+# base this on the number of processors available in the system. You can set it
+# explicitly to a value larger than 0 to get control over the balance
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS = 0
+
+# By default doxygen will write a font called FreeSans.ttf to the output
+# directory and reference it in all dot files that doxygen generates. This
+# font does not include all possible unicode characters however, so when you need
+# these (or just want a differently looking font) you can specify the font name
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
+# which can be done by putting it in a standard location or by setting the
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
+# containing the font.
+
+DOT_FONTNAME = FreeSans.ttf
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the output directory to look for the
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a
+# different font using DOT_FONTNAME you can set the path where dot
+# can find it using this tag.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = YES
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = YES
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
--- /dev/null
+#
+# TOPPERS/ASP Kernel
+# Toyohashi Open Platform for Embedded Real-Time Systems/
+# Advanced Standard Profile Kernel
+#
+# Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+# Toyohashi Univ. of Technology, JAPAN
+# Copyright (C) 2006-2010 by Embedded and Real-Time Systems Laboratory
+# Graduate School of Information Science, Nagoya Univ., JAPAN
+#
+# 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+# スコード中に含まれていること.
+# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+# の無保証規定を掲載すること.
+# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+# と.
+# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+# 作権表示,この利用条件および下記の無保証規定を掲載すること.
+# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+# 報告すること.
+# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+# 免責すること.
+#
+# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+# の責任を負わない.
+#
+# @(#) $Id: Makefile 1786 2010-05-16 20:27:00Z ertl-hiro $
+#
+
+#
+# ターゲットの指定(Makefile.targetで上書きされるのを防ぐため)
+#
+all:
+
+#
+# ターゲット略称の定義
+#
+TARGET = lpc1768_generic_gcc
+
+#
+# プログラミング言語の定義
+#
+SRCLANG = c
+ifeq ($(SRCLANG),c++)
+ USE_CXX = true
+ CXXLIBS = -lstdc++ -lm -lc
+ CXXRTS = cxxrt.o newlibrt.o
+endif
+
+#
+# ソースファイルのディレクトリの定義
+#
+SRCDIR = kernel
+
+#
+# オブジェクトファイル名の拡張子の設定
+#
+OBJEXT =axf
+
+#
+# 実行環境の定義(ターゲット依存に上書きされる場合がある)
+#
+DBGENV :=
+
+#
+# カーネルライブラリ(libkernel.a)のディレクトリ名
+# (カーネルライブラリもmake対象にする時は,空に定義する)
+#
+KERNEL_LIB =
+
+#
+# カーネルを関数単位でコンパイルするかどうかの定義
+#
+KERNEL_FUNCOBJS =
+
+#
+# トレースログを取得するかどうかの定義
+#
+ENABLE_TRACE =
+
+#
+# ユーティリティプログラムの名称
+#
+PERL = /usr/bin/perl
+CFG = $(SRCDIR)/cfg/cfg/cfg
+
+#
+# オブジェクトファイル名の定義
+#
+OBJNAME = TOPPERS-ASP_BlackTank-LPC1769
+ifdef OBJEXT
+ OBJFILE = $(OBJNAME).$(OBJEXT)
+ CFG1_OUT = cfg1_out.$(OBJEXT)
+else
+ OBJFILE = $(OBJNAME)
+ CFG1_OUT = cfg1_out
+endif
+
+#
+# ターゲット依存部のディレクトリの定義
+#
+TARGETDIR = $(SRCDIR)/target/$(TARGET)
+
+#
+# ターゲット依存の定義のインクルード
+#
+include $(TARGETDIR)/Makefile.target
+
+#
+# コンフィギュレータ関係の変数の定義
+#
+CFG_TABS := --api-table $(SRCDIR)/kernel/kernel_api.csv \
+ --cfg1-def-table $(SRCDIR)/kernel/kernel_def.csv $(CFG_TABS)
+CFG_OBJS := kernel_cfg.o $(CFG_OBJS)
+CFG2_OUT := kernel_cfg.c kernel_cfg.h $(CFG2_OUT)
+
+#
+# 共通コンパイルオプションの定義
+#
+COPTS := $(COPTS) -gstabs
+ifndef OMIT_WARNING_ALL
+ COPTS := $(COPTS) -Wall
+endif
+ifndef OMIT_OPTIMIZATION
+ COPTS := $(COPTS) -O0
+endif
+CDEFS := $(CDEFS)
+INCLUDES := -I. -I$(SRCDIR)/include -I$(SRCDIR)/arch -I$(SRCDIR) -I./drivers/ff -I./drivers/oled -I./drivers/led -I./drivers/hid -I./drivers/tlv320aic23b $(INCLUDES)
+LDFLAGS := $(LDFLAGS)
+LIBS := $(LIBS) $(CXXLIBS)
+CFLAGS = $(COPTS) $(CDEFS) $(INCLUDES)
+
+#
+# アプリケーションプログラムに関する定義
+#
+APPLNAME = application
+APPLDIR =
+APPL_CFG = $(APPLNAME).cfg
+
+DIR_TASK = task
+MYOBJS = sys_init.o \
+ \
+ vtparse.o \
+ vtparse_table.o \
+ text_history.o \
+ text_editor.o \
+ ntopt.o \
+ ntshell.o \
+ ntlibc.o \
+ \
+ ff.o \
+ ffrtc.o \
+ ffspi.o \
+ diskio_ff_mmc.o \
+ \
+ oled.o \
+ led.o \
+ hid.o \
+ \
+ task_led.o \
+ task_ntshell.o \
+ task_userinput.o \
+ task_display.o \
+ task_menu.o \
+ task_audio.o \
+ task_init.o \
+ \
+ audio_effect.o \
+ i2c_subsystem.o \
+ i2s_subsystem.o \
+ codec_subsystem.o \
+ tlv320aic23b.o \
+ \
+ testpin.o \
+ bmplowio.o \
+ cmd.o
+
+APPL_DIR = $(APPLDIR) $(SRCDIR)/library ./drivers/ff ./drivers/oled ./drivers/led ./drivers/hid ./drivers/tlv320aic23b
+APPL_ASMOBJS =
+ifdef USE_CXX
+ APPL_CXXOBJS = $(MYOBJS)
+ APPL_COBJS =
+else
+ APPL_COBJS = $(MYOBJS)
+endif
+APPL_CFLAGS =
+APPL_LIBS =
+ifdef APPLDIR
+ INCLUDES := $(INCLUDES) $(foreach dir,$(APPLDIR),-I$(dir))
+endif
+
+#
+# システムサービスに関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR) $(SRCDIR)/syssvc $(SRCDIR)/library
+SYSSVC_ASMOBJS := $(SYSSVC_ASMOBJS)
+SYSSVC_COBJS := $(SYSSVC_COBJS) banner.o syslog.o serial.o logtask.o \
+ log_output.o vasyslog.o t_perror.o strerror.o \
+ $(CXXRTS)
+SYSSVC_CFLAGS := $(SYSSVC_CFLAGS)
+SYSSVC_LIBS := $(SYSSVC_LIBS)
+INCLUDES := $(INCLUDES)
+
+#
+# カーネルに関する定義
+#
+# KERNEL_ASMOBJS:
+# カーネルライブラリに含めるソースがアセンブリ言語のオブジェクトファイル.
+#
+# KERNEL_COBJS:
+# カーネルのライブラリに含めるソースがC言語で,ソースファイルと1対1に
+# 対応するオブジェクトファイル.
+#
+# KERNEL_LCSRCS:
+# カーネルのライブラリに含めるC言語のソースファイルで,1つのソース
+# ファイルから複数のオブジェクトファイルを生成するもの.
+#
+# KERNEL_LCOBJS:
+# 上のソースファイルから生成されるオブジェクトファイル.
+#
+# KERNEL_AUX_COBJS:
+# ロードモジュールに含めないが,カーネルのソースファイルと同じオプションを
+# 適用してコンパイルすべき,ソースがC言語のオブジェクトファイル.
+#
+KERNEL_DIR := $(KERNEL_DIR) $(SRCDIR)/kernel
+KERNEL_ASMOBJS := $(KERNEL_ASMOBJS)
+KERNEL_COBJS := $(KERNEL_COBJS)
+KERNEL_CFLAGS := $(KERNEL_CFLAGS) -I$(SRCDIR)/kernel
+ifdef OMIT_MAKEOFFSET
+ OFFSET_H =
+ KERNEL_AUX_COBJS =
+else
+ OFFSET_H = offset.h
+ KERNEL_AUX_COBJS = makeoffset.o
+endif
+
+#
+# ターゲットファイル(複数を同時に選択してはならない)
+#
+all: $(OBJFILE)
+#all: $(OBJNAME).bin
+#all: $(OBJNAME).srec
+
+##### 以下は編集しないこと #####
+
+#
+# 環境に依存するコンパイルオプションの定義
+#
+ifdef DBGENV
+ CDEFS := $(CDEFS) -D$(DBGENV)
+endif
+
+#
+# カーネルライブラリに関連する定義
+#
+ifdef KERNEL_LIB
+ LIBKERNEL = $(KERNEL_LIB)/libkernel.a
+else
+ LIBKERNEL = libkernel.a
+endif
+
+#
+# カーネルのファイル構成の定義
+#
+include $(SRCDIR)/kernel/Makefile.kernel
+ifdef KERNEL_FUNCOBJS
+ KERNEL_LCSRCS := $(KERNEL_FCSRCS)
+ KERNEL_LCOBJS := $(foreach file,$(KERNEL_FCSRCS),$($(file:.c=)))
+else
+ KERNEL_CFLAGS := -DALLFUNC $(KERNEL_CFLAGS)
+ KERNEL_COBJS := $(KERNEL_COBJS) \
+ $(foreach file,$(KERNEL_FCSRCS),$(file:.c=.o))
+endif
+
+#
+# ソースファイルのあるディレクトリに関する定義
+#
+vpath %.c $(KERNEL_DIR) $(SYSSVC_DIR) $(APPL_DIR)
+vpath %.S $(KERNEL_DIR) $(SYSSVC_DIR) $(APPL_DIR)
+
+#
+# コンパイルのための変数の定義
+#
+KERNEL_LIB_OBJS = $(KERNEL_ASMOBJS) $(KERNEL_COBJS) $(KERNEL_LCOBJS)
+SYSSVC_OBJS = $(SYSSVC_ASMOBJS) $(SYSSVC_COBJS)
+APPL_OBJS = $(APPL_ASMOBJS) $(APPL_COBJS) $(APPL_CXXOBJS)
+ALL_OBJS = $(START_OBJS) $(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) \
+ $(END_OBJS) $(HIDDEN_OBJS)
+ALL_LIBS = $(APPL_LIBS) $(SYSSVC_LIBS) $(LIBKERNEL) $(LIBS)
+
+ifdef TEXT_START_ADDRESS
+ LDFLAGS := $(LDFLAGS) -Wl,-Ttext,$(TEXT_START_ADDRESS)
+endif
+ifdef DATA_START_ADDRESS
+ LDFLAGS := $(LDFLAGS) -Wl,-Tdata,$(DATA_START_ADDRESS)
+endif
+ifdef LDSCRIPT
+ LDFLAGS := $(LDFLAGS) -T $(LDSCRIPT)
+endif
+
+#
+# offset.h の生成規則(構造体内のオフセット値の算出)
+#
+offset.h: makeoffset.s $(SRCDIR)/utils/genoffset
+ $(PERL) $(SRCDIR)/utils/genoffset makeoffset.s > offset.h
+
+#
+# カーネルのコンフィギュレーションファイルの生成
+#
+cfg1_out.c:
+ $(CFG) --pass 1 --kernel asp $(INCLUDES) $(CFG_TABS) $(APPL_CFG)
+
+kernel_cfg.timestamp: $(START_OBJS) cfg1_out.o $(END_OBJS) $(HIDDEN_OBJS)
+kernel_cfg.timestamp $(CFG2_OUT):
+ $(LINK) $(CFLAGS) $(LDFLAGS) $(CFG1_OUT_LDFLAGS) -o $(CFG1_OUT) \
+ $(START_OBJS) cfg1_out.o $(END_OBJS)
+ $(NM) -C $(CFG1_OUT) > cfg1_out.syms
+ $(OBJCOPY) -O srec -S $(CFG1_OUT) cfg1_out.srec
+ $(CFG) --pass 2 --kernel asp $(INCLUDES) \
+ -T $(TARGETDIR)/target.tf $(CFG_TABS) $(APPL_CFG)
+ touch kernel_cfg.timestamp
+
+#
+# カーネルライブラリファイルの生成
+#
+libkernel.a: $(OFFSET_H) $(KERNEL_LIB_OBJS)
+ rm -f libkernel.a
+ $(AR) -rcs libkernel.a $(KERNEL_LIB_OBJS)
+ $(RANLIB) libkernel.a
+
+#
+# 特別な依存関係の定義
+#
+banner.o: kernel_cfg.timestamp $(filter-out banner.o,$(ALL_OBJS)) \
+ $(filter %.a,$(ALL_LIBS))
+
+#
+# 全体のリンク
+#
+$(OBJFILE): permission kernel_cfg.timestamp $(ALL_OBJS) $(filter %.a,$(ALL_LIBS))
+ $(LINK) $(CFLAGS) $(LDFLAGS) -o $(OBJFILE) $(START_OBJS) \
+ $(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) $(ALL_LIBS) $(END_OBJS)
+ $(NM) -C $(OBJFILE) > $(OBJNAME).syms
+ $(OBJCOPY) -O srec -S $(OBJFILE) $(OBJNAME).srec
+ $(CFG) --pass 3 --kernel asp $(INCLUDES) \
+ --rom-image $(OBJNAME).srec --symbol-table $(OBJNAME).syms \
+ -T $(TARGETDIR)/target_check.tf $(CFG_TABS) $(APPL_CFG)
+
+permission:
+ $(shell chmod u+x ./configure) \
+ $(shell chmod u+x ./kernel/cfg/cfg/cfg)
+
+#
+# バイナリファイルの生成
+#
+$(OBJNAME).bin: $(OBJFILE)
+ $(OBJCOPY) -O binary -S $(OBJFILE) $(OBJNAME).bin
+ checksum -v -d $(OBJNAME).bin
+
+#
+# Sレコードファイルの生成
+#
+$(OBJNAME).srec: $(OBJFILE)
+ $(OBJCOPY) -O srec -S $(OBJFILE) $(OBJNAME).srec
+
+#
+# コンパイル結果の消去
+#
+.PHONY: clean
+clean:
+ rm -f \#* *~ *.o $(CLEAN_FILES)
+ rm -f $(OBJFILE) $(OBJNAME).syms $(OBJNAME).srec $(OBJNAME).bin
+ rm -f kernel_cfg.timestamp $(CFG2_OUT)
+ rm -f cfg1_out.c $(CFG1_OUT) cfg1_out.syms cfg1_out.srec
+ifndef KERNEL_LIB
+ rm -f $(LIBKERNEL)
+endif
+ rm -f makeoffset.s offset.h
+
+.PHONY: cleankernel
+cleankernel:
+ rm -rf $(KERNEL_LIB_OBJS)
+ rm -f makeoffset.s offset.h
+
+.PHONY: cleandep
+cleandep:
+ if ! [ -f Makefile.depend ]; then \
+ rm -f kernel_cfg.timestamp $(CFG2_OUT); \
+ rm -f cfg1_out.c cfg1_out.o $(CFG1_OUT) cfg1_out.syms cfg1_out.srec; \
+ rm -f makeoffset.s offset.h; \
+ fi
+ rm -f Makefile.depend
+
+.PHONY: realclean
+realclean: cleandep clean
+ rm -f $(REALCLEAN_FILES)
+
+#
+# kernel_cfg.cとcfg1_out.cのコンパイルルールと依存関係作成ルールの定義
+#
+# kernel_cfg.cとcfg1_out.cは,アプリケーションプログラム用,システムサー
+# ビス用,カーネル用のすべてのオプションを付けてコンパイルする.
+#
+KERNEL_CFG_CFLAGS = $(APPL_CFLAGS) $(SYSSVC_CFLAGS) $(KERNEL_CFLAGS)
+
+kernel_cfg.o cfg1_out.o: %.o: %.c
+ $(CC) -c $(CFLAGS) $(KERNEL_CFG_CFLAGS) $<
+
+kernel_cfg.s cfg1_out.s: %.s: %.c
+ $(CC) -S $(CFLAGS) $(KERNEL_CFG_CFLAGS) $<
+
+kernel_cfg.d cfg1_out.d: %.d: %.c
+ @$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+ -O "$(CFLAGS) $(KERNEL_CFG_CFLAGS)" $< >> Makefile.depend
+
+#
+# 特殊な依存関係作成ルールの定義
+#
+cfg1_out.depend:
+ @$(CFG) -M cfg1_out.c $(INCLUDES) $(APPL_CFG) >> Makefile.depend
+
+makeoffset.d: makeoffset.c
+ @$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+ -T "makeoffset.s" -O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+#
+# 依存関係ファイルの生成
+#
+.PHONY: gendepend
+gendepend:
+ @echo "Generating Makefile.depend."
+
+.PHONY: depend
+ifdef KERNEL_LIB
+depend: cleandep kernel_cfg.timestamp gendepend \
+ cfg1_out.depend cfg1_out.d \
+ $(ALL_OBJS:.o=.d)
+else
+depend: cleandep $(OFFSET_H) kernel_cfg.timestamp gendepend \
+ cfg1_out.depend cfg1_out.d \
+ $(KERNEL_AUX_COBJS:.o=.d) $(KERNEL_ASMOBJS:.o=.d) \
+ $(KERNEL_COBJS:.o=.d) $(KERNEL_LCSRCS:.c=.d) $(ALL_OBJS:.o=.d)
+endif
+
+#
+# 依存関係ファイルをインクルード
+#
+-include Makefile.depend
+
+#
+# 開発ツールのコマンド名の定義
+#
+ifeq ($(TOOL),gcc)
+ #
+ # GNU開発環境用
+ #
+ ifdef GCC_TARGET
+ GCC_TARGET_PREFIX = $(GCC_TARGET)-
+ else
+ GCC_TARGET_PREFIX =
+ endif
+ CC = $(GCC_TARGET_PREFIX)gcc
+ CXX = $(GCC_TARGET_PREFIX)g++
+ AS = $(GCC_TARGET_PREFIX)as
+ LD = $(GCC_TARGET_PREFIX)ld
+ AR = $(GCC_TARGET_PREFIX)ar
+ NM = $(GCC_TARGET_PREFIX)nm
+ RANLIB = $(GCC_TARGET_PREFIX)ranlib
+ OBJCOPY = $(GCC_TARGET_PREFIX)objcopy
+ OBJDUMP = $(GCC_TARGET_PREFIX)objdump
+endif
+
+ifdef USE_CXX
+ LINK = $(CXX)
+else
+ LINK = $(CC)
+endif
+
+#
+# コンパイルルールの定義
+#
+KERNEL_ALL_COBJS = $(KERNEL_COBJS) $(KERNEL_AUX_COBJS)
+
+$(KERNEL_ALL_COBJS): %.o: %.c
+ $(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_ALL_COBJS:.o=.s): %.s: %.c
+ $(CC) -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS): %.o:
+ $(CC) -DTOPPERS_$(*F) -o $@ -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS:.o=.s): %.s:
+ $(CC) -DTOPPERS_$(*F) -o $@ -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_ASMOBJS): %.o: %.S
+ $(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(SYSSVC_COBJS): %.o: %.c
+ $(CC) -c $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_COBJS:.o=.s): %.s: %.c
+ $(CC) -S $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_ASMOBJS): %.o: %.S
+ $(CC) -c $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(APPL_COBJS): %.o: %.c
+ $(CC) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_COBJS:.o=.s): %.s: %.c
+ $(CC) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS): %.o: %.cpp
+ $(CXX) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS:.o=.s): %.s: %.cpp
+ $(CXX) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_ASMOBJS): %.o: %.S
+ $(CC) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+#
+# 依存関係作成ルールの定義
+#
+$(KERNEL_COBJS:.o=.d): %.d: %.c
+ @$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+ -O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(KERNEL_LCSRCS:.c=.d): %.d: %.c
+ @$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) -T "$($*)" \
+ -O "-DALLFUNC $(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(KERNEL_ASMOBJS:.o=.d): %.d: %.S
+ @$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+ -O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(SYSSVC_COBJS:.o=.d): %.d: %.c
+ @$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+ -O "$(CFLAGS) $(SYSSVC_CFLAGS)" $< >> Makefile.depend
+
+$(SYSSVC_ASMOBJS:.o=.d): %.d: %.S
+ @$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+ -O "$(CFLAGS) $(SYSSVC_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_COBJS:.o=.d): %.d: %.c
+ @$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+ -O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_CXXOBJS:.o=.d): %.d: %.cpp
+ @$(PERL) $(SRCDIR)/utils/makedep -C $(CXX) $(MAKEDEP_OPTS) \
+ -O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_ASMOBJS:.o=.d): %.d: %.S
+ @$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+ -O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+#
+# デフォルトコンパイルルールを上書き
+#
+%.o: %.c
+ @echo "*** Default compile rules should not be used."
+ $(CC) -c $(CFLAGS) $<
+
+%.s: %.c
+ @echo "*** Default compile rules should not be used."
+ $(CC) -S $(CFLAGS) $<
+
+%.o: %.cpp
+ @echo "*** Default compile rules should not be used."
+ $(CXX) -c $(CFLAGS) $<
+
+%.s: %.cpp
+ @echo "*** Default compile rules should not be used."
+ $(CXX) -S $(CFLAGS) $<
+
+%.o: %.S
+ @echo "*** Default compile rules should not be used."
+ $(CC) -c $(CFLAGS) $<
--- /dev/null
+TOPPERS/ASP for BlackTank LPC1769はNXP LPC1769を搭載したオーディオ評価ボードで動作するTOPPERS/ASPを使ったパッケージです。
--- /dev/null
+===============================================================
+ 3千円で楽しめるARMマイコンとRTOSの世界
+ TOPPERS/ASP on LPCXpresso LPC1768
+===============================================================
+
+
+0. 謝辞
+ TOPPERS/ASP for LPCは@suikan_blackfinさんによってポーティング
+ されました。
+ 氏は様々な鋭い洞察力で過去にも沢山の偉業を成し遂げている方です。
+ ここに過去の沢山の偉業を挙げることは出来ませんが、素晴らしい
+ ポーティングに感謝すると共に、厚くお礼を申し上げます。
+ ありがとうございます。
+
+ 氏のウェブサイトはhttp://d.hatena.ne.jp/suikan+embedded/にあります。
+
+ また、LPCXpressoはNXPセミコンダクターズジャパンさんが積極的に
+ 国内市場への展開を行って下さっています。
+ このような安価で優れたツールを手に入れることのできるのは、
+ 嬉しい限りです。
+ NXPセミコンダクターズジャパンさんが運営されている日本語サイト
+ (LPCZone)はhttp://www.nxp-lpc.com/cgi-bin/linkv.htmlにあります。
+
+ いずれのサイトも沢山の面白い情報が盛り沢山ですので是非ご覧下さい。
+
+
+1. はじめに
+ TOPPERS/ASP for LPCはTOPPERS/ASPをNXPセミコンダクターズのLPCシリーズ上で
+ 動作するようにしたもので@suikan_blackfinさんがメインテナンスされています。
+ http://sourceforge.jp/projects/toppersasp4lpc/
+
+ 公開当初から完成度が高く、私にも簡単に動作させて楽しむことができました。
+ そこで、今回は更に沢山の方にTOPPERS/ASP for LPCを楽しんで頂くために
+ LPCXpressoさえあれば楽しめるようにしようと考えました。
+ 従来は評価用ボードに加えて、JTAGデバッガ、環境構築など様々な準備が必要
+ でしたが、TOPPERS/ASP on LPCXpressoを使えばLPCXpresso上で簡単に動作させる
+ ことができるようになります。
+
+
+2. 対応環境について
+ 2-1. ホストのOS
+ 環境はLPCXpressoが対応しているLinux環境に今回は限定しました。
+ TOPPERS/ASPのビルドシステムにはシェルとperlに依存する箇所があります。
+ Windowsでも様々な外部ツールを使って、依存する環境に近い状況を作り出す事が
+ 可能ですが、今回は作業負担を軽減させるために割愛しました。
+
+ 最近ですとVMware Player上で簡単にLinux環境が構築できますし、Windowsと
+ Linuxの両環境で対応できるように沢山の時間をかけるよりも、早く提供したいと
+ いう思いが先行した結果でもあります。
+
+ 2-2. 動作を確認した環境
+ 参考までに動作を確認した環境を記します。
+
+ * Ubuntu 10.10
+ * LPCXpresso 3.8.2 [Build 129][31/01/2011]
+ * LPCXpresso LPC1768 REV A
+
+
+3. オリジナルからの変更点
+ @suikan_blackfinさんがお作りになったオリジナルから行った変更に
+ ついて記します。
+
+ 変更は
+ * デバッグをIDE上でできるようにすること。
+ * 極力TOPPERS/ASPのオリジナルとの差分を小さくすること。
+ * LPCXpressoのみで実現可能なこと。
+ を念頭に作業しました。
+
+ ソースコードとビルド用ファイルについては以下の変更を行っています。
+ * 元々あったlpc1768_sram.ldとlpc1768_rom.ldを削除しました。
+ * LPCXpressoが生成したDebugとReleaseのリンカスクリプトを使用しました。
+ -> ENTRY(ResetISR)をENTRY(_start)に変更しました。
+ -> STARTUP(start.o)を追加しました。
+ -> __bss_start, __bss_endを追加しました。
+ -> __idata_start, __idata_end, __data_startを追加しました。
+ -> init_hook関数をPROVIDEで追加しました。
+ -> .isr_vectorを.vectorに名称を変更しました。
+ * kernel/target/lpc1768_generic_gcc/Makefile.targetに以下を追加しました。
+ -> CDEFS=-DDEBUG -D__CODE_RED -D__REDLIB__
+ * Makefileで生成されるオブジェクトの名称を変更しました。
+ * Makefileで生成されるオブジェクトの拡張子を変更しました。
+ * LPCXpresso IDE上でアーカイブプロジェクトzipファイルをインポートすると
+ 全てのファイルの実行権限が落ちてしまいます。
+ そこでMakefileにpermissionというターゲットを追加し、ビルド時に実行権限
+ を立てるようにしてあります。(暫定対策)
+
+ LPCXpressoのプロジェクトに対しては以下の変更を行っています。
+ * Debug ConfigurationsのDebuggerタブでStop on startup at: sta_kerに変更
+ しました。これはLPCXpresso IDE上でデバッグを開始した時に実行を停止
+ させる関数を指定するものです。
+ * Debug ConfigurationsのDebuggerタブでVector catch: Trueに変更しました。
+ * PropertiesのC/C++ BuildでGenerate Makefiles automaticallyのチェックを
+ 外しました。これによりLPCXpressoは外部Makefileを参照するようになります。
+ * PropertiesのC/C++ BuildでBuild directoryからDebugとReleaseを削除しました。
+ これによりプロジェクトのルートディレクトリを参照する形になりMakefileと
+ の整合性が確保されます。
+
+ バグ修正
+ * SIO_PORTIDで1以外の値を選択した時にビルドできない問題を修正しました。
+ kernel/pdic/uart/uart.h
+ 63: SIO_PORID -> SIO_PORTID
+ 66: SIO_PORID -> SIO_PORTID
+ 69: SIO_PORID -> SIO_PORTID
+
+ その他変更点
+ * ledblink.cfgに以下を追加しました。
+ INCLUDE("syssvc/syslog.cfg");
+ INCLUDE("syssvc/banner.cfg");
+ INCLUDE("syssvc/logtask.cfg");
+ * ファイル名の命名規則を変更しました。
+ app_init: アプリケーションに関する初期化。
+ task_xxx: タスクに関するファイル。1ソース1タスクを基本としました。
+ TOPPERS/ASPが提供しているサービス名と同じ名称は避けて
+ 名称を決めて下さい。
+
+ システムログがUART0(LPCXpressoの21, 22ピンに相当)に出力されます。
+ LPCXpressoの21番ピンはLPC1768のP0[1]/TXD0/AD0[7]ピンに接続されています。
+ 同様に22番ピンはLPC1768のP0[3]/RXD0/AD0[6]ピンに接続されています。
+
+ シリアルポートの設定はボーレート57600、8ビット、ノンパリティ、
+ ストップビット1です。
+
+
+4. 使い方
+ 展開するとzipファイルとREADME(このファイル)が現れます。
+ zipファイルは展開せずにLPCXpressoの「Import Example project(s)」で
+ 使用します。
+
+ Import Example project(s)でzipファイルを選択するとワークスペースに
+ プロジェクトがインポートされます。
+ インポートができたらLPCXpresso上でビルドして下さい。
+
+ 場合によって、コンフィギュレータのビルドが必要かもしれません。
+ 展開したディレクトリのトップにconfigureがありますので、必要に応じて
+ 実行して下さい。
+
+ ビルドが完了したらDebug 'TOPPERS-ASP_LPCXpresso-LPC1768'でデバッグできます。
+ Resume, Suspendがソースコード表示と共に楽しめます。
+
+
+5. 最後に
+ 今回の対応は既存のTOPPERS/ASPのビルドの枠組みを超えない形で行ないました。
+ 本来であれば、LPCXpresso上のプリビルドやポストビルドを駆使してカーネルに
+ 対するコンフィギュレーションなどを行うのが筋ですが、先に述べたとおり早めの
+ 公開を目指して割愛したものです。
+
+ もし、何かシンプルな方法でコンフィギュレータまでを包括的に処理させることが
+ できる方法を思いついた場合、是非ご一報頂ければと思います。
+
+
+6. 連絡先
+ このプロジェクトに関するお問い合せは下記までお願いします。
+
+ Shinichiro Nakamura
+
+ shinta.main.jp@gmail.com
+ http://shinta-main-jp.blogspot.com/
+
--- /dev/null
+===============================================================
+ Natural Tiny Shell(NT-Shell)のポーティング事例。
+ LPCXpressoとTOPPERS/ASPで小規模組み込みシステムの開発を
+ もっと便利に!
+===============================================================
+
+[はじめに]
+
+前回VT100仮想端末を小規模組み込みシステムで実現するための
+ライブラリを公開しました。
+
+中には「これが何の役に立つのだろう?」と疑問に思われた方も
+少なくないでしょう。
+この手のツールは実際の開発作業が進むにつれて利便性を再認識
+することが少なくありません。
+(逆に言うと実際に開発作業で相当に困らないと不便な事に
+気付かない事が多いのです。)
+
+今回はLPCXpresso上でTOPPERS/ASPを動作させるシステムを実際に
+開発するシステムと見立てて、Natural Tiny Shell(NT-Shell)を
+ポーティングして活用した時のメリットについて御紹介します。
+
+
+[TOPPERS/ASPでNatural Tiny Shell(NT-Shell)を使う]
+
+今回はRTOS上にシェルを実装することでシステム開発をもっと
+便利にしてみましょう。
+
+題して「LPCXpressoとTOPPERS/ASPで小規模組み込みシステムの
+開発をもっと便利に!」です。
+
+小規模組み込みシステムでありがちな「この程度の規模だからいいや。」
+と諦めている方におすすめです。
+きちんと動作するデバッグ用シェルがあるだけでシステムが
+見違えるように良くなったように感じます。
+デバッグも楽しくなって作業効率が向上すること間違いなし!
+是非皆さんも挑戦してみませんか?
+
+
+[エコーバックを行わないようにする]
+
+受信した文字列をエコーバックする設定を取り除きます。
+TOPPERS/ASPでは受信した文字列をエコーバックすることが
+できるようになっています。
+Natural Tiny Shell(NT-Shell)を使用する時、エコーバックは
+都合が悪いので設定を外します。
+これはシリアルインターフェースドライバで行うことができます。
+
+syssvc/serial.c の serial_opn_por 関数でIOCTL_ECHOの指定を取り除きます。
+serial.cの240行目付近です。
+
+
+/*
+ * 変数の初期化
+ * エコーバックさせたい時にはIOCTL_ECHOを追加すると良い。
+ */
+p_spcb->ioctl = (IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV);
+
+
+なぜ受信した文字列をそのまま返してはいけないかという話です。
+
+システムに接続されたシリアル端末が送信してくるコードの中には
+制御コードが含まれる事があります。
+今回のシェルを設計実装した目的の1つは「制御コードをうまく
+処理してシリアル端末ユーザに便利な機能を提供しよう」です。
+
+受信したコードをそのまま送信した結果、シリアル端末上で制御コードが
+解釈されてしまっては従来と何も変わらない事になってしまいます。
+これを避ける為にエコーバックをしないようにします。
+
+例えば、「おっ。上方向キーだな。じゃあ、過去のコマンドを表示して
+あげよう。」といった具合です。
+
+[システム]
+
+今回のシステムは以下のようになっています。
+実際に開発するシステムに見立てていると考えてみて下さい。
+
++----+ +--------------------+
+| | <----USB----> | LPCXpresso LPC1768 |
+| | +--------------------+
+| | |
+|HOST| |UART
+| PC | |
+| | +--------------------+
+| | <----USB----> | USB-UART Converter |
++----+ +--------------------+
+
+システムと開発用ホストは2つのUSBで接続されています。
+
+1つはLPCXpresso用でこれはLPCXpresso上のデバッガに接続されています。
+実際に開発するシステムによってはここは他のデバッガに置き換わる事も
+あるでしょう。
+
+もう1つは開発対象システムのUARTをUSBで入出力するための変換器との接続です。
+今回は秋月電子通商で販売されているFT2232Dを使った変換器を使用しました。
+
+実際の接続した状態は以下のようになっています。
+
+
+[内部タスクの構成]
+
+今回の内部タスク構成を以下のようにしました。
+
+* task_ledblink: LEDを一定間隔でトグルするLED点滅タスク
+* task_ntshll: Natural Tiny Shellをフロントエンドとするシェルタスク
+
+
+[LED点滅タスクを作る]
+
+LED点滅タスクは一定時間間隔で動作しLEDの状態をトグルさせるタスクです。
+点滅の間隔は100[ms]ですが、データキューから値を受け取って変化させる
+ことができるようにしてあります。
+外部からデータキュー経由で点滅の速度(正確にいうとタスクの動作間隔)
+を変化させることができるようにしてあります。
+
+void task_ledblink(intptr_t exinf)
+{
+ syslog(LOG_NOTICE, "task_ledblink: Started.");
+
+ int ledspd = 100;
+ while(1)
+ {
+ uint_t value;
+ while (prcv_dtq(DTQ_LEDSPD, (intptr_t *)&value) == E_OK) {
+ if (value > 0) {
+ ledspd = value;
+ // syslog(LOG_NOTICE, "new value is %d.", value);
+ }
+ }
+ LPC_GPIO0->FIOPIN ^= ACTLED;
+ tslp_tsk(ledspd);
+ }
+}
+
+
+[シェルタスクを作る]
+
+次にNatural Tiny Shell(NT-Shell)を組み込んだシェルタスクを立てます。
+シェルタスクはUARTに対する入出力を管理しながら、ユーザの要求を
+システムに伝達する役目を果たします。
+
+
+void task_ntshell(intptr_t exinf)
+{
+ syslog(LOG_NOTICE, "task_ntshell: Started.");
+ serial_opn_por(SIO_PORTID);
+
+ ntshell_execute(&parser,
+ &editor, &history,
+ func_read, func_write, func_cb);
+}
+
+
+ntshell_executeは処理を戻さない関数です。
+UARTからの入出力関数を受け取って処理を行ないます。
+
+今回の例ではfunc_readは以下のようになっています。
+
+
+int func_read(void *buf, int cnt)
+{
+ return serial_rea_dat(SIO_PORTID, buf, cnt);
+}
+
+
+同様にfunc_writeは以下のようになっています。
+
+
+int func_write(const void *buf, int cnt)
+{
+ return serial_wri_dat(SIO_PORTID, buf, cnt);
+}
+
+
+ユーザが操作を決定するとコールバック関数(上記ではfunc_cb)が
+呼ばれるようになっています。
+ユーザが入力を完了後、エンターキーを押した時の入力文字列が
+渡されるようになっています。
+
+ここでユーザの要求に応じて処理を行えば良い事になります。
+
+
+int func_cb(const unsigned char *text)
+{
+ // TODO 入力されたコマンドに応じて処理を行う。
+}
+
+
+ちなみに、この関数内部の実行スレッドはシェルタスクのスレッドです。
+今回のアプリケーションでは以下のように実装してみました。
+ntopt_compareはNatural Tiny Shellに含まれるユティリティ関数で、
+文字列の比較を行うものです。
+
+
+int func_cb(const unsigned char *text)
+{
+ static int ledspd = 100;
+ if (ntopt_compare(text, "INTERVAL UP") == 0) {
+ if (ledspd < 500) {
+ ledspd++;
+ snd_dtq(DTQ_LEDSPD, (intptr_t)ledspd);
+ }
+ } else if (ntopt_compare(text, "INTERVAL DOWN") == 0) {
+ if (ledspd > 1) {
+ ledspd--;
+ snd_dtq(DTQ_LEDSPD, (intptr_t)ledspd);
+ }
+ } else if ((ntopt_compare(text, "HELP") == 0)
+ || (ntopt_compare(text, "?") == 0)) {
+ text_puts("\r\nINTERVAL UP : Task interval time increase.");
+ text_puts("\r\nINTERVAL DOWN : Task interval time decrease.");
+ } else {
+ if (ntopt_get_count(text) > 0) {
+ text_puts("\r\nUnknown command found. (HELP: display help.)");
+ }
+ }
+
+ return 0;
+}
+
+
+[実際に使ってみる]
+
+実際に使用している様子を動画で御紹介します。
+http://www.youtube.com/watch?v=4v47XPAijbE
+
+
+[リソース]
+
+今回は3千円で楽しめるARMマイコンとRTOSの世界(TOPPERS/ASP on LPCXpresso
+LPC1768)のプロジェクトに小規模組み込みシステムデバッグ用シェル
+Natural Tiny Shell (NT-Shell)を追加する形で作業しました。
+
+
+[まとめ]
+
+ターゲットに対して対話型で操作要求ができるとちょっとした確認をする
+時に非常に便利です。
+今回はLPCXpresso(Cortex-M3搭載)でRTOS(TOPPERS/ASP)を動作させるという
+比較的小さな組み込みシステムでの応用例を示しました。
+
+システム内部の値を外部から変更することは当然デバッガなどでも可能です。
+しかし、ちょっとしたパラメータを変更したい場合や複数のパラメータを
+同時に変更したい時には不便です。
+
+対話型のシェルインターフェースがあれば、開発ホスト並の利便性を確保する
+ことも可能になります。
+
+
+[補足]
+念の為補足しておくと、LEDの点灯間隔を変化させるという行為が主眼では
+ありません。
+おそらく点灯間隔を変えるための実装にはもっと相応しいものがあるでしょう。
+
+今回はあくまでシステム内部の挙動をシェルを介して変化させるという
+ところに視点をおいてあります。
+今回の実装では点灯間隔が狭くなるにつれてプロセッサの使用率も
+相当上がります。
+システムがどの程度の負荷を許容するのかを外部でパラメータを変更させながら
+見ることもできるでしょう。
+
+
+[連絡先]
+ このプロジェクトに関するお問い合せは下記までお願いします。
+
+ Shinichiro Nakamura
+
+ shinta.main.jp@gmail.com
+ http://shinta-main-jp.blogspot.com/
+
--- /dev/null
+===============================================================
+ TOPPERS/ASPを使ってもっと便利に小規模組み込み開発
+ TraceLogVisualizer(TLV)を使ってカーネル動作を確認しよう
+===============================================================
+
+[はじめに]
+README.1stとREADME.2ndで示したように、Cortex-M3を使った小規模
+組み込みシステムの実現に関する幾つかのトピックを扱いました。
+
+ここでは先に取り上げたLPCXpresso IDE上での開発、Natural Tiny
+Shellを使ったデバッグ環境に加えて、TOPPERSプロジェクトが公開
+しているTraceLog Visualizer(TLV)を使った動作確認方法について
+ご紹介します。
+
+
+[謝辞]
+TraceLogVisualizerの企画、開発、公開を行なってくださった方々に
+感謝致します。このような興味深いツールを無償で公開して頂いた事
+に大変感謝しております。
+
+
+[カーネルに対する設定]
+ベースとなっているのは@suikan_blackfinさんがポーティングされた
+TOPPERS/ASP for LPCです。
+これに加えて公開されている最新のTLVを組み込む形をとっています。
+
+* http://www.toppers.jp/tlv.htmlからTLV_1.2.zipをダウンロード。
+ (http://www.toppers.jp/download.cgi/TLV_1.2.zip)
+* ダウンロードしたファイルを展開してlogtrace/aspの内容をコピー。
+* コピーしたファイルのtrace_config.hの中で定義されているトレース
+ ログバッファのサイズをCortex-M3のRAMサイズを考慮して小さくする。
+* kernel.tfの最後に以下を追加。
+ $INCLUDE"arch/logtrace/tlv.tf"$
+* Makefileのトレースを有効にする。
+ ENABLE_TRACE = true
+* コンフィギュレーションファイルに以下を追加。
+ #include "logtrace/trace_config.h"
+ ATT_INI({ TA_NULL, TRACE_STOP, trace_initialize });
+ ATT_TER({ TA_NULL, target_fput_log, trace_dump });
+* trace_config.hで指定されているLOG_TEX_LEAVEの引数を1つに修正。
+ LOG_TEX_LEAVE(p_tcb)
+* trace_config.hで定義されている以下の定義をコメントアウト。
+ これはGUIで「指定されたリソース(CPUExceptionHandler(id==21))が
+ 見つかりません。」といった内容の例外が発生する事に対する暫定的
+ な対策です。
+ 本来正しくはルールファイルの修正が必要と思う。
+ #define LOG_EXC_ENTER(excno) trace_1(LOG_TYPE_EXC|LOG_ENTER, excno)
+ #define LOG_EXC_LEAVE(excno) trace_1(LOG_TYPE_EXC|LOG_LEAVE, excno)
+* syssvc/syslog.hのTCNT_SYSLOG_BUFFERを64に変更。
+* syssvc/logtask.hのLOGTASK_STACK_SIZEを512に変更。
+
+
+[どうやって使うの?]
+トレースをするのは簡単です。
+
+trace_sta_log(TRACE_AUTOSTOP);を呼ぶとトレースが開始されます。
+バッファサイズが一杯になった時点で自動的に停止します。
+ext_ker();を呼ぶとカーネルを終了させることができます。
+この時、コンフィギュレーションファイルでATT_TERしたtrace_dumpが
+呼ばれ、システムコンソールにトレース結果が出力されます。
+
+(トレース結果の例 - 一部抜粋)
+ [37182007] task 1 becomes RUNNABLE.
+ [37182019] dispatch to task 1.
+ [37182026] leave from dly_tsk ercd=0.
+ [37182034] enter to dly_tsk dlytim=10.
+ [37182047] task 1 becomes WAITING.
+ [37182053] dispatch from task 1.
+ [37193007] task 1 becomes RUNNABLE.
+ [37193019] dispatch to task 1.
+ [37193026] leave from dly_tsk ercd=0.
+ [37193034] enter to dly_tsk dlytim=10.
+ [37193047] task 1 becomes WAITING.
+ [37193053] dispatch from task 1.
+ [37204007] task 1 becomes RUNNABLE.
+
+システムコンソールに出力されたトレース結果をテキストファイルと
+して保存して下さい。例えば、kernel.logのような感じです。
+
+トレース機能を組み込んだカーネルをビルドするとリソースファイル
+というものが生成されています。これはkernel.resのような名前で
+存在します。
+
+(リソースファイルの例 - 一部抜粋)
+ "TASK_LEDBLINK":{
+ "Type":"Task",
+ "Attributes":
+ {
+ "id" :2,
+ "atr" :"TA_ACT",
+ "pri" :5,
+ "exinf" :"0",
+ "task" :"task_ledblink",
+ "stksz" :1024,
+ "stk" :"NULL",
+ "state" :"RUNNABLE"
+ }
+ },
+
+上記の「トレース結果のファイル」と「リソースが記述されたファイル」
+をTOPPERSプロジェクトが公開しているファイルに読み込ませることで
+カーネル動作を可視化させることができるようになっています。
+
+
+[お勧めの開発方法]
+* LinuxホストとWindowsホストを用意します。
+ (あるいはWindows上でVMware Playerを使ってLinuxを動作させます。)
+* LPCXpresso IDEはLinux上で動作させます。
+* ビルド時に生成されたリソースファイルをWindowsホストにコピーします。
+* UART出力をUSB-シリアル変換ケーブルを利用してWindowsホストに接続
+ します。
+* 出力されたトレースログをファイル化してGUIで観察します。
+
+
+[連絡先]
+ このプロジェクトに関するお問い合せは下記までお願いします。
+
+ Shinichiro Nakamura
+
+ shinta.main.jp@gmail.com
+ http://shinta-main-jp.blogspot.com/
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="com.crt.ctrlcenter.idleNative2">
+<stringAttribute key=".gdbinit" value=""/>
+<stringAttribute key="com.crt.ctrlcenter.targetbase" value="NXP LPC17xx (*)"/>
+<stringAttribute key="com.crt.ctrlcenter.targetconfig" value="<?xml version="1.0" encoding="UTF-8"?> <config chipvendor="NXP" genname="NXP LPC17xx" id="config.gdb.stub"><parameters><params><param description="Enter as XTAL[,PLL]. PLL is optional. Values are in kHz" name="Crystal (XTAL) frequency and PLL value" required="false" type="nullString" var="xtal.hz"/> </params> <initValue value="false" var="vector.catch"/> <params><param default="true" description="Vector catch" name="Vector catch" value="True" var="vector.catch"><enum value="True"/> <enum value="False"/> </param> </params> <params><param default="true" description="Enable Red Trace" name="Enable Red Trace " value="true" var="swv.enable"><enum value="true"/> <enum value="false"/> </param> </params> <params><param default="Auto" description="Enablement of semihosting support" name="Semihosting support" value="Auto" var="internal.semihost"><enum value="On"/> <enum value="Off"/> <enum value="Auto"/> </param> </params> <params><param default="" description="Switch debug interface between SWD and JTAG (leave blank for default [SWD])" name="Debug interface" option="" value="" var="internal.debug.interface"><enum value=""/> <enum value="JTAG"/> <enum value="SWD"/> </param> </params> <params><param default="" description="Maximum wire speed in KHz (leave blank to Auto-detect). Not all values are supported by all targets" name="Maximum wire speed" type="nullString" value="" var="emu.speed"><enum value=""/> <enum value="30000"/> <enum value="15000"/> <enum value="10000"/> <enum value="7500"/> <enum value="6000"/> <enum value="5000"/> <enum value="3750"/> <enum value="3000"/> <enum value="2500"/> <enum value="2000"/> <enum value="1500"/> <enum value="1250"/> <enum value="1200"/> <enum value="1000"/> <enum value="750"/> <enum value="600"/> <enum value="500"/> <enum value="400"/> <enum value="300"/> <enum value="250"/> <enum value="200"/> <enum value="150"/> </param> </params> <params><param default="" description="Additional options" name="Additional options" value="" var="misc.options"/> <param default="2" description="Set stub debug level (1-4)" name="Debug Level " value="2" var="debug.level"/> <param default="True" description="when True, executable image will be loaded into the target" name="Load image" type="boolean" value="True" var="load"><enum value="True"/> <enum value="False"/> </param> <param default="cont" description="Run, continue or (do nothing)" name="Run/Continue image" value="cont" var="run"><enum value="run"/> <enum value="cont"/> <enum value=""/> </param> <param default="off" description="If on is specified, make the debugger treat unknown memory as non-existent and refuse \naccesses to such memory. If off is specified, treat the memory as RAM" name="Memory Access Checking" value="off" var="mem.access"><enum value="on"/> <enum value="off"/> </param> <param default="cont" description="choose the disconnect behavior for the target" name="Disconnect behavior" value="cont" var="ondisconnect"><enum value="nochange"/> <enum value="stop"/> <enum value="cont"/> <enum value="run_cont"/> </param> </params> </parameters> <script emulators="${gdb.stub} -mi -info-emu" silent="false" swv="true" type="init">set remotetimeout 60000&#x0A;target extended-remote | ${gdb.stub} -g -mi -${debug.level:2} ${-c+speed:$null} ${-s+emu.speed:$null} ${-p+package:$null} ${-e+emulator:$null} ${vector.catch?-vc:} ${misc.options}&#x0A;set mem inaccessible-by-default ${mem.access}&#x0A;mon ondisconnect ${ondisconnect}&#x0A;set arm force-mode thumb&#x0A;${load}</script> <script silent="false" type="run">${run}</script> </config> "/>
+<stringAttribute key="org.eclipse.cdt.debug.mi.core.DEBUG_NAME" value="arm-none-eabi-gdb"/>
+<stringAttribute key="org.eclipse.cdt.debug.mi.core.GDB_INIT" value=""/>
+<booleanAttribute key="org.eclipse.cdt.debug.mi.core.breakpointsFullPath" value="false"/>
+<stringAttribute key="org.eclipse.cdt.debug.mi.core.commandFactory" value="com.crt.ctrlcenter.cmdfactory"/>
+<stringAttribute key="org.eclipse.cdt.debug.mi.core.protocol" value="mi"/>
+<booleanAttribute key="org.eclipse.cdt.debug.mi.core.verboseMode" value="false"/>
+<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_ID" value="com.crt.ctrlcenter.CRTEmbeddedCDebugger"/>
+<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
+<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_START_MODE" value="run"/>
+<booleanAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN" value="true"/>
+<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN_SYMBOL" value="sta_ker"/>
+<booleanAttribute key="org.eclipse.cdt.launch.ENABLE_REGISTER_BOOKKEEPING" value="false"/>
+<booleanAttribute key="org.eclipse.cdt.launch.ENABLE_VARIABLE_BOOKKEEPING" value="false"/>
+<stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?><contentList/>"/>
+<stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <globalVariableList/> "/>
+<stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList/> "/>
+<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="TOPPERS-ASP_BlackTank-LPC1769.axf"/>
+<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="TOPPERS-ASP_BlackTank-LPC1769"/>
+<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="com.crt.advproject.config.exe.debug.1288027607"/>
+<booleanAttribute key="org.eclipse.cdt.launch.use_terminal" value="false"/>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+<listEntry value="/TOPPERS-ASP_BlackTank-LPC1769"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="4"/>
+</listAttribute>
+</launchConfiguration>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="com.crt.ctrlcenter.idleNative2">
+<stringAttribute key=".gdbinit" value=""/>
+<stringAttribute key="com.crt.ctrlcenter.targetbase" value="NXP LPC17xx (*)"/>
+<stringAttribute key="com.crt.ctrlcenter.targetconfig" value="<?xml version="1.0" encoding="UTF-8"?> <config chipvendor="NXP" genname="NXP LPC17xx" id="config.gdb.stub"><parameters><params><param description="Enter as XTAL[,PLL]. PLL is optional. Values are in kHz" name="Crystal (XTAL) frequency and PLL value" required="false" type="nullString" var="xtal.hz"/> </params> <initValue value="false" var="vector.catch"/> <params><param default="true" description="Vector catch" name="Vector catch" value="True" var="vector.catch"><enum value="True"/> <enum value="False"/> </param> </params> <params><param default="true" description="Enable Red Trace" name="Enable Red Trace " value="true" var="swv.enable"><enum value="true"/> <enum value="false"/> </param> </params> <params><param default="Auto" description="Enablement of semihosting support" name="Semihosting support" value="Auto" var="internal.semihost"><enum value="On"/> <enum value="Off"/> <enum value="Auto"/> </param> </params> <params><param default="" description="Switch debug interface between SWD and JTAG (leave blank for default [SWD])" name="Debug interface" option="" value="" var="internal.debug.interface"><enum value=""/> <enum value="JTAG"/> <enum value="SWD"/> </param> </params> <params><param default="" description="Maximum wire speed in KHz (leave blank to Auto-detect). Not all values are supported by all targets" name="Maximum wire speed" type="nullString" value="" var="emu.speed"><enum value=""/> <enum value="30000"/> <enum value="15000"/> <enum value="10000"/> <enum value="7500"/> <enum value="6000"/> <enum value="5000"/> <enum value="3750"/> <enum value="3000"/> <enum value="2500"/> <enum value="2000"/> <enum value="1500"/> <enum value="1250"/> <enum value="1200"/> <enum value="1000"/> <enum value="750"/> <enum value="600"/> <enum value="500"/> <enum value="400"/> <enum value="300"/> <enum value="250"/> <enum value="200"/> <enum value="150"/> </param> </params> <params><param default="" description="Additional options" name="Additional options" value="" var="misc.options"/> <param default="2" description="Set stub debug level (1-4)" name="Debug Level " value="2" var="debug.level"/> <param default="True" description="when True, executable image will be loaded into the target" name="Load image" type="boolean" value="True" var="load"><enum value="True"/> <enum value="False"/> </param> <param default="cont" description="Run, continue or (do nothing)" name="Run/Continue image" value="cont" var="run"><enum value="run"/> <enum value="cont"/> <enum value=""/> </param> <param default="off" description="If on is specified, make the debugger treat unknown memory as non-existent and refuse \naccesses to such memory. If off is specified, treat the memory as RAM" name="Memory Access Checking" value="off" var="mem.access"><enum value="on"/> <enum value="off"/> </param> <param default="cont" description="choose the disconnect behavior for the target" name="Disconnect behavior" value="cont" var="ondisconnect"><enum value="nochange"/> <enum value="stop"/> <enum value="cont"/> <enum value="run_cont"/> </param> </params> </parameters> <script emulators="${gdb.stub} -mi -info-emu" silent="false" swv="true" type="init">set remotetimeout 60000&#x0A;target extended-remote | ${gdb.stub} -g -mi -${debug.level:2} ${-c+speed:$null} ${-s+emu.speed:$null} ${-p+package:$null} ${-e+emulator:$null} ${vector.catch?-vc:} ${misc.options}&#x0A;set mem inaccessible-by-default ${mem.access}&#x0A;mon ondisconnect ${ondisconnect}&#x0A;set arm force-mode thumb&#x0A;${load}</script> <script silent="false" type="run">${run}</script> </config> "/>
+<stringAttribute key="org.eclipse.cdt.debug.mi.core.DEBUG_NAME" value="arm-none-eabi-gdb"/>
+<stringAttribute key="org.eclipse.cdt.debug.mi.core.GDB_INIT" value=""/>
+<booleanAttribute key="org.eclipse.cdt.debug.mi.core.breakpointsFullPath" value="false"/>
+<stringAttribute key="org.eclipse.cdt.debug.mi.core.commandFactory" value="com.crt.ctrlcenter.cmdfactory"/>
+<stringAttribute key="org.eclipse.cdt.debug.mi.core.protocol" value="mi"/>
+<booleanAttribute key="org.eclipse.cdt.debug.mi.core.verboseMode" value="false"/>
+<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_ID" value="com.crt.ctrlcenter.CRTEmbeddedCDebugger"/>
+<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_START_MODE" value="run"/>
+<booleanAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN" value="true"/>
+<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN_SYMBOL" value="sta_ker"/>
+<booleanAttribute key="org.eclipse.cdt.launch.ENABLE_REGISTER_BOOKKEEPING" value="false"/>
+<booleanAttribute key="org.eclipse.cdt.launch.ENABLE_VARIABLE_BOOKKEEPING" value="false"/>
+<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="TOPPERS-ASP_BlackTank-LPC1769.axf"/>
+<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="TOPPERS-ASP_BlackTank-LPC1769"/>
+<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="com.crt.advproject.config.exe.release.700661640"/>
+<booleanAttribute key="org.eclipse.cdt.launch.use_terminal" value="false"/>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+<listEntry value="/TOPPERS-ASP_BlackTank-LPC1769"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="4"/>
+</listAttribute>
+</launchConfiguration>
--- /dev/null
+/*
+ * アプリケーションのコンフィギュレーションファイル
+ */
+
+/*
+ * システムタイマーとシリアル機能を取り込む。
+ * この二つは事実上必須機能である。
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+INCLUDE("syssvc/logtask.cfg");
+
+/*
+ * アプリケーション・インクルード・ファイルからタスク優先順位等を取り込む。
+ */
+#include "sys_init.h"
+#include "task_init.h"
+#include "task_led.h"
+#include "task_ntshell.h"
+#include "task_userinput.h"
+#include "task_display.h"
+#include "task_menu.h"
+#include "task_audio.h"
+/* #include "logtrace/trace_config.h" */
+
+CFG_INT(INTNO_DMA, { TA_ENAINT, -3 });
+
+ATT_ISR({ TA_NULL, 0, INTNO_DMA, dma_intr_handler, 1 });
+ATT_INI({ TA_NULL, 0, sys_init });
+
+/* ATT_INI({ TA_NULL, TRACE_STOP, trace_initialize }); */
+/* ATT_TER({ TA_NULL, target_fput_log, trace_dump }); */
+
+CRE_DTQ(DTQ_LED, {TA_TPRI, 8, NULL});
+CRE_DTQ(DTQ_USERINPUT, {TA_TPRI, 8, NULL});
+CRE_DTQ(DTQ_AUDIOPARAM, {TA_TPRI, 8, NULL});
+CRE_MPF(MPF_DISPLAY, {TA_TPRI, 1, 128, NULL, NULL});
+CRE_MBX(MBX_DISPLAY, {TA_NULL, TMAX_MPRI, NULL});
+CRE_SEM(SEM_I2SDMA, { TA_TPRI, 0, 1 });
+
+/*
+ * 全てのタスクは初期化タスクから起動する。
+ */
+CRE_TSK(TASK_INIT,
+ { TA_ACT, 0, task_init, TSKPRI_INIT, TSKSTK_INIT, NULL });
+
+/*
+ * 以下のタスクは初期化タスクから起動する。
+ */
+CRE_TSK(TASK_DISPLAY,
+ { 0, 0, task_display, TSKPRI_DISPLAY, TSKSTK_DISPLAY, NULL });
+CRE_TSK(TASK_LED,
+ { 0, 0, task_led, TSKPRI_LED, TSKSTK_LED, NULL });
+CRE_TSK(TASK_NTSHELL,
+ { 0, 0, task_ntshell, TSKPRI_NTSHELL, TSKSTK_NTSHELL, NULL });
+CRE_TSK(TASK_AUDIO,
+ { 0, 0, task_audio, TSKPRI_AUDIO, TSKSTK_AUDIO, NULL });
+CRE_TSK(TASK_MENU,
+ { 0, 0, task_menu, TSKPRI_MENU, TSKSTK_MENU, NULL });
+CRE_TSK(TASK_USERINPUT,
+ { 0, 0, task_userinput, TSKPRI_USERINPUT, TSKSTK_USERINPUT, NULL });
+
--- /dev/null
+# Doxyfile 1.6.3
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = Sample LED Blink Program
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY =
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak,
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it parses.
+# With this tag you can assign which parser to use for a given extension.
+# Doxygen has a built-in mapping, but you can override or extend it using this tag.
+# The format is ext=language, where ext is a file extension, and language is one of
+# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP,
+# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat
+# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran),
+# use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen to replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penality.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will rougly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = YES
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = YES
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
+# will list include files with double quotes in the documentation
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST = YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by
+# doxygen. The layout file controls the global structure of the generated output files
+# in an output format independent way. The create the layout file that represents
+# doxygen's defaults, run doxygen with the -l option. You can optionally specify a
+# file name after the option, if omitted DoxygenLayout.xml will be used as the name
+# of the layout file.
+
+LAYOUT_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT =
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS =
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.
+# Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP = YES
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER
+# are set, an additional index file will be generated that can be used as input for
+# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated
+# HTML documentation.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add.
+# For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
+# will be generated, which together with the HTML files, form an Eclipse help
+# plugin. To install this plugin and make it available under the help contents
+# menu in Eclipse, the contents of the directory containing the HTML and XML
+# files needs to be copied into the plugins directory of eclipse. The name of
+# the directory within the plugins directory should be the same as
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before the help appears.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have
+# this name.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
+# and Class Hierarchy pages using a tree view instead of an ordered list.
+
+USE_INLINE_TREES = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) there is already a search function so this one should
+# typically be disabled. For large projects the javascript based search engine
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE = NO
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be implemented using a PHP enabled web server instead of at the web client using Javascript. Doxygen will generate the search PHP script and index
+# file to put on the web server. The advantage of the server based approach is that it scales better to large projects and allows full text search. The disadvances is that it is more difficult to setup
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+# Note that when enabling USE_PDFLATEX this option is only used for
+# generating bitmaps for formulas in the HTML output, but not in the
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# By default doxygen will write a font called FreeSans.ttf to the output
+# directory and reference it in all dot files that doxygen generates. This
+# font does not include all possible unicode characters however, so when you need
+# these (or just want a differently looking font) you can specify the font name
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
+# which can be done by putting it in a standard location or by setting the
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
+# containing the font.
+
+DOT_FONTNAME = FreeSans
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the output directory to look for the
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a
+# different font using DOT_FONTNAME you can set the path where dot
+# can find it using this tag.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = YES
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
--- /dev/null
+/**
+ * @file audio_common.h
+ * @brief オーディオに関する共通の定義。
+ */
+
+#ifndef AUDIO_COMMON_H
+#define AUDIO_COMMON_H
+
+/**
+ * @brief オーディオデータ型
+ * @details
+ * プログラム内部で使うオーディオの基本型。
+ * 左詰めの符号付き固定小数点型である。小数点はMSBのすぐ右にある。
+ */
+typedef int AUDIOSAMPLE;
+
+/**
+ * @brief I2S DMAバッファの長さ
+ * @details
+ * 一回のDMA転送に使うデータバッファの長さ。
+ * AUDIOBUFSIZEがNならば、ステレオなので、N/2サンプルのデータを
+ * 一回のDMAで転送することになる。
+ */
+#define AUDIOBUFSIZE 64
+
+/**
+ * @brief 左チャンネルインデックス
+ */
+#define LCH 0
+
+/**
+ * @brief 右チャンネルインデックス
+ */
+#define RCH 1
+
+#endif
+
--- /dev/null
+/**
+ * @file audio_effect.c
+ * @brief コーデックから受け取ったデータに対して、実際の信号処理を施す。
+ * @date 2011/02/19
+ * @author: Takemasa Nakamura (Modified: Shinichiro Nakamura)
+ */
+
+#include "i2s_subsystem.h"
+#include "audio_effect.h"
+
+void audio_effect_through(
+ const effect_param_t *param,
+ const AUDIOSAMPLE *in_left,
+ const AUDIOSAMPLE *in_right,
+ AUDIOSAMPLE *out_left,
+ AUDIOSAMPLE *out_right)
+{
+ const int var0 = param->var0;
+ const int var1 = param->var1;
+ *out_left = ((*in_left) >> 10) * var0;
+ *out_right = ((*in_right) >> 10) * var1;
+}
+
+/**
+ * オーディオエフェクト(ボーカルキャンセル)を実行する。
+ *
+ * @param param エフェクトパラメータ。
+ * @param in_left 入力データ。(L)
+ * @param in_right 入力データ。(R)
+ * @param out_left 出力データ。(L)
+ * @param out_right 出力データ。(R)
+ */
+void audio_effect_vocal_cancel(
+ const effect_param_t *param,
+ const AUDIOSAMPLE *in_left,
+ const AUDIOSAMPLE *in_right,
+ AUDIOSAMPLE *out_left,
+ AUDIOSAMPLE *out_right)
+{
+ const int var0 = param->var0;
+ const int var1 = param->var1;
+ const AUDIOSAMPLE mix = ((*in_left) - (*in_right)) >> 1;
+ *out_left = (mix >> 10) * var0;
+ *out_right = (mix >> 10) * var1;
+}
+
+/**
+ * オーディオエフェクト(FIR: Finite Impulse Response)を実行する。
+ *
+ * @param param エフェクトパラメータ。
+ * @param in_left 入力データ。(L)
+ * @param in_right 入力データ。(R)
+ * @param out_left 出力データ。(L)
+ * @param out_right 出力データ。(R)
+ */
+void audio_effect_fir(
+ const effect_param_t *param,
+ const AUDIOSAMPLE *in_left,
+ const AUDIOSAMPLE *in_right,
+ AUDIOSAMPLE *out_left,
+ AUDIOSAMPLE *out_right)
+{
+ /** @todo FIRフィルタを挿入する。 */
+}
+
+/**
+ * オーディオエフェクト(IIR: Infinite Impulse Response)を実行する。
+ *
+ * @param param エフェクトパラメータ。
+ * @param in_left 入力データ。(L)
+ * @param in_right 入力データ。(R)
+ * @param out_left 出力データ。(L)
+ * @param out_right 出力データ。(R)
+ */
+void audio_effect_iir(
+ const effect_param_t *param,
+ const AUDIOSAMPLE *in_left,
+ const AUDIOSAMPLE *in_right,
+ AUDIOSAMPLE *out_left,
+ AUDIOSAMPLE *out_right)
+{
+ /** @todo IIRフィルタを挿入する。 */
+}
+
--- /dev/null
+/**
+ * @file audio_effect.h
+ * @brief コーデックから受け取ったデータに対して、実際の信号処理を施す。
+ * @date 2011/02/19
+ * @author: Takemasa Nakamura (Modified: Shinichiro Nakamura)
+ */
+
+#ifndef AUDIO_EFFECT_H
+#define AUDIO_EFFECT_H
+
+/**
+ * @brief エフェクトに対するパラメータ。
+ * @details
+ * エフェクトに対するパラメータの解釈は、各エフェクト処理が行う。
+ */
+typedef struct {
+ int var0; /**< エフェクトパラメータ値0。(意味は各エフェクタに依存) */
+ int var1; /**< エフェクトパラメータ値1。(意味は各エフェクタに依存) */
+ int var2; /**< エフェクトパラメータ値2。(意味は各エフェクタに依存) */
+ int var3; /**< エフェクトパラメータ値3。(意味は各エフェクタに依存) */
+} effect_param_t;
+
+/**
+ * オーディオエフェクト(スルー)を実行する。
+ *
+ * @param param エフェクトパラメータ。
+ * @param in_left 入力データ。(L)
+ * @param in_right 入力データ。(R)
+ * @param out_left 出力データ。(L)
+ * @param out_right 出力データ。(R)
+ */
+void audio_effect_through(
+ const effect_param_t *param,
+ const AUDIOSAMPLE *in_left,
+ const AUDIOSAMPLE *in_right,
+ AUDIOSAMPLE *out_left,
+ AUDIOSAMPLE *out_right);
+
+/**
+ * オーディオエフェクト(ボーカルキャンセル)を実行する。
+ *
+ * @param param エフェクトパラメータ。
+ * @param in_left 入力データ。(L)
+ * @param in_right 入力データ。(R)
+ * @param out_left 出力データ。(L)
+ * @param out_right 出力データ。(R)
+ */
+void audio_effect_vocal_cancel(
+ const effect_param_t *param,
+ const AUDIOSAMPLE *in_left,
+ const AUDIOSAMPLE *in_right,
+ AUDIOSAMPLE *out_left,
+ AUDIOSAMPLE *out_right);
+
+/**
+ * オーディオエフェクト(FIR: Finite Impulse Response)を実行する。
+ *
+ * @param param エフェクトパラメータ。
+ * @param in_left 入力データ。(L)
+ * @param in_right 入力データ。(R)
+ * @param out_left 出力データ。(L)
+ * @param out_right 出力データ。(R)
+ */
+void audio_effect_fir(
+ const effect_param_t *param,
+ const AUDIOSAMPLE *in_left,
+ const AUDIOSAMPLE *in_right,
+ AUDIOSAMPLE *out_left,
+ AUDIOSAMPLE *out_right);
+
+/**
+ * オーディオエフェクト(IIR: Infinite Impulse Response)を実行する。
+ *
+ * @param param エフェクトパラメータ。
+ * @param in_left 入力データ。(L)
+ * @param in_right 入力データ。(R)
+ * @param out_left 出力データ。(L)
+ * @param out_right 出力データ。(R)
+ */
+void audio_effect_iir(
+ const effect_param_t *param,
+ const AUDIOSAMPLE *in_left,
+ const AUDIOSAMPLE *in_right,
+ AUDIOSAMPLE *out_left,
+ AUDIOSAMPLE *out_right);
+
+#endif
+
--- /dev/null
+/**\r
+ * @file bmplowio.c\r
+ * @author Shinichiro Nakamura\r
+ * @brief BMPファイルを少ないメモリでI/Oできるモジュールの実装。\r
+ */\r
+\r
+/*\r
+ * ===============================================================\r
+ * BMP Low I/O Module\r
+ * Version 0.0.1\r
+ * ===============================================================\r
+ * Copyright (c) 2010-2011 Shinichiro Nakamura\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person\r
+ * obtaining a copy of this software and associated documentation\r
+ * files (the "Software"), to deal in the Software without\r
+ * restriction, including without limitation the rights to use,\r
+ * copy, modify, merge, publish, distribute, sublicense, and/or\r
+ * sell copies of the Software, and to permit persons to whom the\r
+ * Software is furnished to do so, subject to the following\r
+ * conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be\r
+ * included in all copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\r
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\r
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\r
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\r
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\r
+ * OTHER DEALINGS IN THE SOFTWARE.\r
+ * ===============================================================\r
+ */\r
+\r
+#include "bmplowio.h"\r
+\r
+static int fread_uint32_t(\r
+ uint32_t *data,\r
+ int (*func_getc)(void)) {\r
+ uint8_t temp[4];\r
+ uint8_t i;\r
+ for (i = 0; i < 4; i++) {\r
+ int c = func_getc();\r
+ if (c < 0) {\r
+ return -1;\r
+ }\r
+ temp[i] = c;\r
+ }\r
+ *data = ((((uint32_t)temp[0]) << 0) & 0x000000ff)\r
+ | ((((uint32_t)temp[1]) << 8) & 0x0000ff00)\r
+ | ((((uint32_t)temp[2]) << 16) & 0x00ff0000)\r
+ | ((((uint32_t)temp[3]) << 24) & 0xff000000) ;\r
+ return 0;\r
+}\r
+\r
+static int fread_uint16_t(\r
+ uint16_t *data,\r
+ int (*func_getc)(void)) {\r
+ uint8_t temp[2];\r
+ uint8_t i;\r
+ for (i = 0; i < 2; i++) {\r
+ int c = func_getc();\r
+ if (c < 0) {\r
+ return -1;\r
+ }\r
+ temp[i] = c;\r
+ }\r
+ *data = ((((uint16_t)temp[0]) << 0) & 0x00ff)\r
+ | ((((uint16_t)temp[1]) << 8) & 0xff00) ;\r
+ return 0;\r
+}\r
+\r
+static int fwrite_uint32_t(\r
+ uint32_t data,\r
+ int (*func_putc)(uint8_t c)) {\r
+ uint8_t temp[4];\r
+ uint8_t i;\r
+ temp[0] = ((data) >> 0) & 0x000000ff;\r
+ temp[1] = ((data) >> 8) & 0x000000ff;\r
+ temp[2] = ((data) >> 16) & 0x000000ff;\r
+ temp[3] = ((data) >> 24) & 0x000000ff;\r
+ for (i = 0; i < 4; i++) {\r
+ if (func_putc(temp[i]) < 0) {\r
+ return -1;\r
+ }\r
+ }\r
+ return 0;\r
+}\r
+\r
+static int fwrite_uint16_t(\r
+ uint16_t data,\r
+ int (*func_putc)(uint8_t c)) {\r
+ uint8_t temp[2];\r
+ uint8_t i;\r
+ temp[0] = ((data) >> 0) & 0x00ff;\r
+ temp[1] = ((data) >> 8) & 0x00ff;\r
+ for (i = 0; i < 2; i++) {\r
+ if (func_putc(temp[i]) < 0) {\r
+ return -1;\r
+ }\r
+ }\r
+ return 0;\r
+}\r
+\r
+int bmplowio_header_init(\r
+ bmp_file_t* filehead,\r
+ bmp_info_t *infohead) {\r
+ filehead->bfType = 0;\r
+ filehead->bfType = 0;\r
+ filehead->bfSize = 0;\r
+ filehead->bfReserved1 = 0;\r
+ filehead->bfReserved2 = 0;\r
+ filehead->bfOffBits = 0;\r
+\r
+ infohead->biSize = 0;\r
+ infohead->biWidth = 0;\r
+ infohead->biHeight = 0;\r
+ infohead->biPlanes = 0;\r
+ infohead->biBitCount = 0;\r
+ infohead->biCompression = 0;\r
+ infohead->biSizeImage = 0;\r
+ infohead->biXPelsPerMeter = 0;\r
+ infohead->biYPelsPerMeter = 0;\r
+ infohead->biClrUsed = 0;\r
+ infohead->biClrImportant = 0;\r
+\r
+ return 0;\r
+}\r
+\r
+int bmplowio_header_write(\r
+ int (*func_putc)(uint8_t c),\r
+ const bmp_file_t *filehead,\r
+ const bmp_info_t *infohead) {\r
+ fwrite_uint16_t(filehead->bfType, func_putc);\r
+ fwrite_uint32_t(filehead->bfSize, func_putc);\r
+ fwrite_uint16_t(filehead->bfReserved1, func_putc);\r
+ fwrite_uint16_t(filehead->bfReserved2, func_putc);\r
+ fwrite_uint32_t(filehead->bfOffBits, func_putc);\r
+\r
+ fwrite_uint32_t(infohead->biSize, func_putc);\r
+ fwrite_uint32_t(infohead->biWidth, func_putc);\r
+ fwrite_uint32_t(infohead->biHeight, func_putc);\r
+ fwrite_uint16_t(infohead->biPlanes, func_putc);\r
+ fwrite_uint16_t(infohead->biBitCount, func_putc);\r
+ fwrite_uint32_t(infohead->biCompression, func_putc);\r
+ fwrite_uint32_t(infohead->biSizeImage, func_putc);\r
+ fwrite_uint32_t(infohead->biXPelsPerMeter, func_putc);\r
+ fwrite_uint32_t(infohead->biYPelsPerMeter, func_putc);\r
+ fwrite_uint32_t(infohead->biClrUsed, func_putc);\r
+ fwrite_uint32_t(infohead->biClrImportant, func_putc);\r
+\r
+ return 0;\r
+}\r
+\r
+int bmplowio_palette_write(\r
+ int (*func_putc)(uint8_t c),\r
+ const bmp_rgbquad_t *rgbquad,\r
+ size_t n) {\r
+ int i;\r
+ const bmp_rgbquad_t *p = rgbquad;\r
+ for (i = 0; i < n; i++) {\r
+ func_putc(p->red);\r
+ func_putc(p->green);\r
+ func_putc(p->blue);\r
+ func_putc(p->reserved);\r
+ p++;\r
+ }\r
+ return 0;\r
+}\r
+\r
+int bmplowio_image_write(\r
+ int (*func_putc)(uint8_t c),\r
+ const bmp_file_t *filehead,\r
+ const bmp_info_t *infohead,\r
+ void(*func)(int x, int y, int *r, int *g, int *b)) {\r
+ /**\r
+ * @todo 書き込みが必要になったら対応する。\r
+ */\r
+ return 0;\r
+}\r
+\r
+int bmplowio_header_read(\r
+ int (*func_getc)(void),\r
+ bmp_file_t *filehead,\r
+ bmp_info_t *infohead) {\r
+ fread_uint16_t(&filehead->bfType, func_getc);\r
+ fread_uint32_t(&filehead->bfSize, func_getc);\r
+ fread_uint16_t(&filehead->bfReserved1, func_getc);\r
+ fread_uint16_t(&filehead->bfReserved2, func_getc);\r
+ fread_uint32_t(&filehead->bfOffBits, func_getc);\r
+\r
+ fread_uint32_t(&infohead->biSize, func_getc);\r
+ fread_uint32_t(&infohead->biWidth, func_getc);\r
+ fread_uint32_t(&infohead->biHeight, func_getc);\r
+ fread_uint16_t(&infohead->biPlanes, func_getc);\r
+ fread_uint16_t(&infohead->biBitCount, func_getc);\r
+ fread_uint32_t(&infohead->biCompression, func_getc);\r
+ fread_uint32_t(&infohead->biSizeImage, func_getc);\r
+ fread_uint32_t(&infohead->biXPelsPerMeter, func_getc);\r
+ fread_uint32_t(&infohead->biYPelsPerMeter, func_getc);\r
+ fread_uint32_t(&infohead->biClrUsed, func_getc);\r
+ fread_uint32_t(&infohead->biClrImportant, func_getc);\r
+\r
+ return 0;\r
+}\r
+\r
+int bmplowio_palette_read(\r
+ int (*func_getc)(void),\r
+ bmp_rgbquad_t *rgbquad,\r
+ size_t n) {\r
+ int i;\r
+ bmp_rgbquad_t *p = rgbquad;\r
+ for (i = 0; i < n; i++) {\r
+ p->red = func_getc();\r
+ p->green = func_getc();\r
+ p->blue = func_getc();\r
+ p->reserved = func_getc();\r
+ p++;\r
+ }\r
+ return 0;\r
+}\r
+\r
+int bmplowio_image_read(\r
+ int (*func_getc)(void),\r
+ const bmp_file_t *filehead,\r
+ const bmp_info_t *infohead,\r
+ void(*func)(int x, int y, int r, int g, int b)) {\r
+ const int w = infohead->biWidth;\r
+ const int h = infohead->biHeight;\r
+ const int p = (w * infohead->biBitCount + 31) / 32 * 4\r
+ - (w * infohead->biBitCount + 7 ) / 8;\r
+ int x, y;\r
+ int i;\r
+ for (y = 0; y < infohead->biHeight; y++) {\r
+ for (x = 0; x < infohead->biWidth; x++) {\r
+ if (infohead->biBitCount == 24) {\r
+ int a, b, c;\r
+ a = (uint8_t)func_getc();\r
+ b = (uint8_t)func_getc();\r
+ c = (uint8_t)func_getc();\r
+ if (func != NULL) {\r
+ func(x, h - y - 1, c, b, a);\r
+ }\r
+ }\r
+ // TODO\r
+ }\r
+ for (i = 0; i < p; i++) {\r
+ func_getc();\r
+ }\r
+ }\r
+ return 0;\r
+}\r
+\r
+int have_palette(const bmp_info_t *infohead) {\r
+ if ((infohead->biBitCount == 8)\r
+ || (infohead->biBitCount == 4)\r
+ || (infohead->biBitCount == 2)\r
+ || (infohead->biBitCount == 1)) {\r
+ return 1;\r
+ }\r
+ return 0;\r
+}\r
+\r
+int calc_framebytesize(const bmp_info_t *infohead) {\r
+ const int biBitCount = infohead->biBitCount;\r
+ const int biWidth = infohead->biWidth;\r
+ const int biHeight = infohead->biHeight;\r
+ int bmp_frame_bytesize = -1;\r
+\r
+ if (biBitCount == 32) {\r
+ bmp_frame_bytesize = biWidth * 4 * biHeight;\r
+ }\r
+\r
+ if (biBitCount == 24) {\r
+ bmp_frame_bytesize =\r
+ ((biWidth * 3 + 3) / 4) * 4 * biHeight;\r
+ }\r
+\r
+ if (biBitCount == 8) {\r
+ bmp_frame_bytesize =\r
+ ((biWidth + 3) / 4) * 4 * biHeight;\r
+ }\r
+\r
+ if (biBitCount == 4) {\r
+ bmp_frame_bytesize =\r
+ ((biWidth / 2 + 3) / 4) * 4 * biHeight;\r
+ }\r
+\r
+ if (biBitCount == 2) {\r
+ bmp_frame_bytesize =\r
+ ((biWidth / 4 + 3) / 4) * 4 * biHeight;\r
+ }\r
+\r
+ if (biBitCount == 1) {\r
+ bmp_frame_bytesize =\r
+ ((biWidth / 8 + 3) / 4) * 4 * biHeight;\r
+ }\r
+\r
+ return bmp_frame_bytesize;\r
+}\r
--- /dev/null
+/**\r
+ * @file bmplowio.h\r
+ * @author Shinichiro Nakamura\r
+ * @brief BMPファイルを少ないメモリでI/Oできるモジュールの定義。\r
+ */\r
+\r
+/*\r
+ * ===============================================================\r
+ * BMP Low I/O Module\r
+ * Version 0.0.1\r
+ * ===============================================================\r
+ * Copyright (c) 2010-2011 Shinichiro Nakamura\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person\r
+ * obtaining a copy of this software and associated documentation\r
+ * files (the "Software"), to deal in the Software without\r
+ * restriction, including without limitation the rights to use,\r
+ * copy, modify, merge, publish, distribute, sublicense, and/or\r
+ * sell copies of the Software, and to permit persons to whom the\r
+ * Software is furnished to do so, subject to the following\r
+ * conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be\r
+ * included in all copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\r
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\r
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\r
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\r
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\r
+ * OTHER DEALINGS IN THE SOFTWARE.\r
+ * ===============================================================\r
+ */\r
+\r
+#ifndef BMPLOWIO_H\r
+#define BMPLOWIO_H\r
+\r
+#include <kernel.h>\r
+#include <t_stdlib.h>\r
+\r
+#define BMP_FILE_MAGIC_TEXT (('B' << 0) | ('M' << 8))\r
+\r
+typedef struct bmp_file {\r
+ uint16_t bfType;\r
+ uint32_t bfSize;\r
+ uint16_t bfReserved1;\r
+ uint16_t bfReserved2;\r
+ uint32_t bfOffBits;\r
+} bmp_file_t;\r
+\r
+typedef struct bmp_info {\r
+ uint32_t biSize;\r
+ uint32_t biWidth;\r
+ uint32_t biHeight;\r
+ uint16_t biPlanes;\r
+ uint16_t biBitCount;\r
+ uint32_t biCompression;\r
+ uint32_t biSizeImage;\r
+ uint32_t biXPelsPerMeter;\r
+ uint32_t biYPelsPerMeter;\r
+ uint32_t biClrUsed;\r
+ uint32_t biClrImportant;\r
+} bmp_info_t;\r
+\r
+typedef struct bmp_rgbquad {\r
+ uint8_t blue;\r
+ uint8_t green;\r
+ uint8_t red;\r
+ uint8_t reserved;\r
+} bmp_rgbquad_t;\r
+\r
+int bmplowio_header_init(\r
+ bmp_file_t* filehead,\r
+ bmp_info_t *infohead);\r
+\r
+int bmplowio_header_write(\r
+ int (*func_putc)(uint8_t c),\r
+ const bmp_file_t* filehead,\r
+ const bmp_info_t *infohead);\r
+\r
+int bmplowio_palette_write(\r
+ int (*func_putc)(uint8_t c),\r
+ const bmp_rgbquad_t *rgbquad,\r
+ size_t n);\r
+\r
+int bmplowio_image_write(\r
+ int (*func_putc)(uint8_t c),\r
+ const bmp_file_t *filehead,\r
+ const bmp_info_t *infohead,\r
+ void(*func)(int x, int y, int *r, int *g, int *b));\r
+\r
+int bmplowio_header_read(\r
+ int (*func_getc)(void),\r
+ bmp_file_t *filehead,\r
+ bmp_info_t *infohead);\r
+\r
+int bmplowio_palette_read(\r
+ int (*func_getc)(void),\r
+ bmp_rgbquad_t *rgbquad,\r
+ size_t n);\r
+\r
+int bmplowio_image_read(\r
+ int (*func_getc)(void),\r
+ const bmp_file_t *filehead,\r
+ const bmp_info_t *infohead,\r
+ void(*func)(int x, int y, int r, int g, int b));\r
+\r
+int have_palette(const bmp_info_t *infoh);\r
+\r
+int calc_framebytesize(const bmp_info_t *infoh);\r
+\r
+#endif\r
+\r
--- /dev/null
+/**
+ * @file cmd.c
+ * @author Shinichiro Nakamura
+ * @brief ナチュラルタイニーシェルタスクコマンドの実装
+ * @details
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <target_syssvc.h>
+#include <syssvc/serial.h>
+#include <logtrace/trace_config.h>
+
+#include "kernel_cfg.h"
+#include "ntopt.h"
+#include "ntlibc.h"
+#include "ff.h"
+
+#include "task_audio.h"
+#include "task_led.h"
+#include "task_display.h"
+
+char curdir[32];
+FATFS fatfs[_VOLUMES];
+DIR dir;
+FIL fil;
+FILINFO filinfo;
+
+void cmd_taskinfo(int argc, char **argv) {
+ int i;
+ T_ITSK itsk;
+ syslog(LOG_NOTICE, "TSKID\tSTACK ADDR (HEAD:TAIL)\tSTACK USED (USED/TOTAL)");
+ syslog(LOG_NOTICE, "=========================================================");
+ for (i = 0; i < TNUM_TSKID; i++) {
+ const int tskid = 1 + i;
+ inf_tsk(tskid, &itsk);
+ syslog(LOG_NOTICE, " %2d\t0x%x:0x%x\t%5d/%5d",
+ tskid,
+ itsk.stk_head, itsk.stk_tail,
+ itsk.stk_used, itsk.stk_total);
+#if 0
+ syslog(LOG_NOTICE, " (%02d:%02d)",
+ itsk.tsk_pri_curr, itsk.tsk_pri_base);
+#endif
+ }
+ syslog(LOG_NOTICE, "=========================================================");
+}
+
+void cmd_audio(int argc, char **argv) {
+ if (argc == 2) {
+ if (ntlibc_strcmp(argv[1], "through") == 0) {
+ TSKAPI_AUDIO_PARAM(AUDIO_PARAM_MODE, AUDIO_VALUE_MODE_THROUGH);
+ return;
+ }
+ if (ntlibc_strcmp(argv[1], "vocal_cancel") == 0) {
+ TSKAPI_AUDIO_PARAM(AUDIO_PARAM_MODE, AUDIO_VALUE_MODE_VOCAL_CANCEL);
+ return;
+ }
+ if (ntlibc_strcmp(argv[1], "fir") == 0) {
+ TSKAPI_AUDIO_PARAM(AUDIO_PARAM_MODE, AUDIO_VALUE_MODE_FIR);
+ return;
+ }
+ if (ntlibc_strcmp(argv[1], "iir") == 0) {
+ TSKAPI_AUDIO_PARAM(AUDIO_PARAM_MODE, AUDIO_VALUE_MODE_IIR);
+ return;
+ }
+ }
+ syslog(LOG_NOTICE, "audio [through | vocal_cancel | fir | iir]");
+}
+
+void cmd_lcd(int argc, char **argv) {
+ if (argc == 2) {
+ if (ntlibc_strcmp(argv[1], "cls") == 0) {
+ TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
+ return;
+ }
+ }
+ syslog(LOG_NOTICE, "lcd cls : Clear the LCD.");
+}
+
+void cmd_led(int argc, char **argv) {
+ if (argc != 3) {
+ syslog(LOG_NOTICE, "led [DBLEDn|SWLEDn] [ON|OFF]");
+ return;
+ }
+ if (ntlibc_strcmp(argv[1], "DBLED0") == 0) {
+ if (ntlibc_strcmp(argv[2], "ON") == 0) {
+ TSKAPI_LED_LEDMSG(DBLED0, LEDON);
+ return;
+ }
+ if (ntlibc_strcmp(argv[2], "OFF") == 0) {
+ TSKAPI_LED_LEDMSG(DBLED0, LEDOFF);
+ return;
+ }
+ }
+ if (ntlibc_strcmp(argv[1], "DBLED1") == 0) {
+ if (ntlibc_strcmp(argv[2], "ON") == 0) {
+ TSKAPI_LED_LEDMSG(DBLED1, LEDON);
+ return;
+ }
+ if (ntlibc_strcmp(argv[2], "OFF") == 0) {
+ TSKAPI_LED_LEDMSG(DBLED1, LEDOFF);
+ return;
+ }
+ }
+ if (ntlibc_strcmp(argv[1], "DBLED2") == 0) {
+ if (ntlibc_strcmp(argv[2], "ON") == 0) {
+ TSKAPI_LED_LEDMSG(DBLED2, LEDON);
+ return;
+ }
+ if (ntlibc_strcmp(argv[2], "OFF") == 0) {
+ TSKAPI_LED_LEDMSG(DBLED2, LEDOFF);
+ return;
+ }
+ }
+ if (ntlibc_strcmp(argv[1], "DBLED3") == 0) {
+ if (ntlibc_strcmp(argv[2], "ON") == 0) {
+ TSKAPI_LED_LEDMSG(DBLED3, LEDON);
+ return;
+ }
+ if (ntlibc_strcmp(argv[2], "OFF") == 0) {
+ TSKAPI_LED_LEDMSG(DBLED3, LEDOFF);
+ return;
+ }
+ }
+ if (ntlibc_strcmp(argv[1], "SWLED0") == 0) {
+ if (ntlibc_strcmp(argv[2], "ON") == 0) {
+ TSKAPI_LED_LEDMSG(SWLED0, LEDON);
+ return;
+ }
+ if (ntlibc_strcmp(argv[2], "OFF") == 0) {
+ TSKAPI_LED_LEDMSG(SWLED0, LEDOFF);
+ return;
+ }
+ }
+ if (ntlibc_strcmp(argv[1], "SWLED1") == 0) {
+ if (ntlibc_strcmp(argv[2], "ON") == 0) {
+ TSKAPI_LED_LEDMSG(SWLED1, LEDON);
+ return;
+ }
+ if (ntlibc_strcmp(argv[2], "OFF") == 0) {
+ TSKAPI_LED_LEDMSG(SWLED1, LEDOFF);
+ return;
+ }
+ }
+ if (ntlibc_strcmp(argv[1], "SWLED2") == 0) {
+ if (ntlibc_strcmp(argv[2], "ON") == 0) {
+ TSKAPI_LED_LEDMSG(SWLED2, LEDON);
+ return;
+ }
+ if (ntlibc_strcmp(argv[2], "OFF") == 0) {
+ TSKAPI_LED_LEDMSG(SWLED2, LEDOFF);
+ return;
+ }
+ }
+ if (ntlibc_strcmp(argv[1], "SWLED3") == 0) {
+ if (ntlibc_strcmp(argv[2], "ON") == 0) {
+ TSKAPI_LED_LEDMSG(SWLED3, LEDON);
+ return;
+ }
+ if (ntlibc_strcmp(argv[2], "OFF") == 0) {
+ TSKAPI_LED_LEDMSG(SWLED3, LEDOFF);
+ return;
+ }
+ }
+ syslog(LOG_NOTICE, "Invalid command.");
+}
+
+void cmd_mount(int argc, char **argv) {
+ int a = f_mount(0, &fatfs[0]);
+ int b = f_opendir(&dir, "");
+ ntlibc_strcpy(curdir, "");
+ if ((a == 0) && (b == 0)) {
+ syslog(LOG_NOTICE, "Mounted the SD card.");
+ } else {
+ syslog(LOG_NOTICE, "Failure to mount the SD card.");
+ }
+}
+
+void cmd_ls(int argc, char **argv) {
+ int r;
+ r = f_opendir(&dir, curdir);
+ if (r) {
+ syslog(LOG_NOTICE, "Failure to open the directory. (code=%d)", r);
+ return;
+ }
+ while (1) {
+ r = f_readdir(&dir, &filinfo);
+ if (r != FR_OK) {
+ syslog(LOG_NOTICE, "Failure to read the directory. (code=%d)", r);
+ return;
+ }
+ if (!filinfo.fname[0]) {
+ break;
+ }
+ if (filinfo.fattrib & AM_DIR) {
+ syslog(LOG_NOTICE, "<DIR>\t%s", filinfo.fname);
+ } else {
+ syslog(LOG_NOTICE, "%d\t%s", filinfo.fsize, filinfo.fname);
+ }
+ tslp_tsk(10);
+ }
+}
+
+void cmd_cd(int argc, char **argv) {
+ int r;
+ switch (argc) {
+ case 1:
+ r = f_opendir(&dir, "");
+ if (!r) {
+ ntlibc_strcpy(curdir, "");
+ }
+ break;
+ case 2:
+ r = f_opendir(&dir, argv[1]);
+ if (!r) {
+ ntlibc_strcpy(curdir, argv[1]);
+ }
+ break;
+ default:
+ syslog(LOG_NOTICE, "cd [dir]");
+ return;
+ }
+ if (r) {
+ syslog(LOG_NOTICE, "Failure to open the director. (code=%d)", r);
+ return;
+ }
+}
+
+void cmd_trace(int argc, char **argv) {
+#ifdef TOPPERS_ENABLE_TRACE
+ syslog(LOG_NOTICE, "trace started.");
+ tslp_tsk(250);
+ trace_sta_log(TRACE_STOP);
+ trace_sta_log(TRACE_CLEAR);
+ trace_sta_log(TRACE_AUTOSTOP);
+#else
+ syslog(LOG_NOTICE, "trace disabled in this build.");
+#endif
+}
+
+void cmd_exit(int argc, char **argv) {
+ ext_ker();
+}
+
--- /dev/null
+/**
+ * @file cmd.h
+ * @author Shinichiro Nakamura
+ * @brief ナチュラルタイニーシェルタスクコマンドの実装
+ * @details
+ */
+
+#ifndef _CMD_H_
+#define _CMD_H_
+
+void cmd_taskinfo(int argc, char **argv);
+void cmd_audio(int argc, char **argv);
+void cmd_lcd(int argc, char **argv);
+void cmd_led(int argc, char **argv);
+void cmd_mount(int argc, char **argv);
+void cmd_ls(int argc, char **argv);
+void cmd_cd(int argc, char **argv);
+void cmd_trace(int argc, char **argv);
+void cmd_exit(int argc, char **argv);
+
+#endif
--- /dev/null
+/**
+ * \file codec_subsystem.c
+ * \brief TLV320AIC23B操作関数
+ * \date 2011/02/19
+ * \author takemasa
+ */
+
+#include "codec_subsystem.h"
+#include "i2c_subsystem.h"
+
+#include <LPC17xx.h>
+#include <kernel.h>
+#include <t_syslog.h>
+
+/**
+ * \brief コーデック初期化データ列の長さ
+ * \details
+ * TLV320AIC23に与える初期化データの長さである。長さはレジスタアドレスとデータの組が
+ * 何組であるかを示す。
+ */
+#define CODECINITDATALEN 10 /* TLV320AIC23B初期化データ長 */
+
+
+/**
+ * \brief CODEC初期化データ列
+ * \details
+ * TLV320AIC23Bを初期化するためのデータ列である。
+ */
+static unsigned char tlv320aic23init[CODECINITDATALEN][2] = {
+ {0 | 0x01, 0x17}, /* L_in vol : LR simul-update, unmute, 0dB */
+ {2 | 0x01, 0x17}, /* R_in vol : LR simul-update, unmute, 0dB */
+ {4 | 0x01, 0xF9}, /* L_HP vol : LR simul-update, zero-cross, 0dB */
+ {6 | 0x01, 0xF9}, /* R_HP vol : LR simul-update, zero-cross, 0dB */
+ {8 | 0x00, 0x12}, /* Analog Audio Path : No Sidetone, No bypass, DAC for Out, Line out for ADC, Mic Mute */
+ {10 | 0x00, 0x06}, /* Digital Paht: DAC unmute, De-emphasis 48k, ADC LPF enable */
+ {12 | 0x00, 0x02}, /* Power Down : Only Mic is down */
+ {14 | 0x00, 0x4E}, /* Digital Audio Format : Master, 24bit, I2S */
+// { 16 | 0x00, 0x01 }, /* Sanmpling Rate, 48kHz, USB mode*/
+ {16 | 0x00, 0x00}, /* Sanmpling Rate, 48kHz, NORMAL mode */
+ {18 | 0x00, 0x01} /* Activateion : Active. */
+
+};
+
+void codec_init()
+{
+ int i;
+
+ /* TLV320AIC23Bに初期化データを送信する */
+ for (i = 0; i < CODECINITDATALEN; i++) {
+ i2c_send_2bytes(0x1A, tlv320aic23init[i][0], tlv320aic23init[i][1]); /* Activate all functionality of TLV320AIC23B */
+ tslp_tsk(10);
+ }
+}
--- /dev/null
+/**
+ * @file codec_subsystem.h
+ * @brief TLV320AIC23B操作関数
+ * @date 2011/02/19
+ * @author takemasa
+ * @details
+ * @ref codec_init 関数を呼ぶとTLV320AIC23Bの初期化を行う。
+ * その前に \ref i2c_init 関数を呼んでおくこと。
+ */
+
+#ifndef CODEC_SUBSYSTEM_H_
+#define CODEC_SUBSYSTEM_H_
+
+/**
+ * @brief TLV320AIC23Bの初期化関数
+ * @details
+ * 初期化文字列を与えてCODECを初期化し、動作を開始させる。
+ * この関数を呼ぶ前に \ref i2c_init 関数を呼んでI2Cペリフェラルを
+ * 初期化しておく。
+ */
+void codec_init();
+
+#endif /* CODEC_SUBSYSTEM_H_ */
+
--- /dev/null
+/**
+ * @file config.h
+ * @author Shinichiro Nakamura
+ * @brief
+ * アプリケーションに関連する定義ファイル。
+ * 動作をカスタマイズするのに用いられる。
+ */
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#define TASK_AUDIO_ENABLED() 0
+
+#endif
+
--- /dev/null
+cd kernel/cfg
+./configure
+make
+cd ../..
+kernel/configure -T lpc1768_generic_gcc -A application
+make depend
+make
--- /dev/null
+
+#include "debug_helper.h"
+
+void svc_perror(const char *file, int_t line, const char *expr, ER ercd)
+{
+ if (ercd < 0) {
+ t_perror(LOG_ERROR, file, line, expr, ercd);
+ }
+}
+
--- /dev/null
+#ifndef DEBUG_HELPER_H
+#define DEBUG_HELPER_H
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <syssvc/syslog.h>
+
+void svc_perror(const char *file, int_t line, const char *expr, ER ercd);
+
+#define SVC_PERROR(expr) svc_perror(__FILE__, __LINE__, #expr, (expr))
+
+#endif
+
--- /dev/null
+#!/bin/sh
+screen /dev/ttyUSB0 57600,cs8
+
--- /dev/null
+#!/bin/sh
+arm-none-eabi-gdb TOPPERS-ASP_BlackTank-LPC1769.axf -x gdbcmd-load.txt
+
--- /dev/null
+#!/bin/sh
+
+lpc21isp TOPPERS-ASP_BlackTank-LPC1769.hex /dev/ttyUSB0 57600 4000
+
--- /dev/null
+
+DIR_A=./kernel
+DIR_B=../talkthrough1768/kernel
+
+FILELIST_A=`cd $DIR_A;find . -name "*.[c|h]"`
+FILELIST_B=`cd $DIR_B;find . -name "*.[c|h]"`
+
+for FILE in $FILELIST_A
+do
+ if [ -f "$DIR_A/$FILE" ]
+ then
+ OUT=`diff "$DIR_A/$FILE" "$DIR_B/$FILE"`
+ if [ "$OUT" != "" ]
+ then
+ echo "===[ $FILE ]========================================"
+ diff "$DIR_A/$FILE" "$DIR_B/$FILE"
+ echo " "
+ echo " "
+ echo " "
+ fi
+ fi
+done
--- /dev/null
+/**
+ * @file doxygen.h
+ * @author Shinichiro Nakamura
+ * @brief Doxygen用のファイル。モジュールの定義を記述してある。
+ * @details
+ */
+
+/**
+ * @defgroup BLACKTANK_LPC1769
+ */
+
+/**
+ * @defgroup BLACKTANK_LPC1769_TASK
+ * @ingroup BLACKTANK_LPC1769
+ */
+
+/**
+ * @defgroup BLACKTANK_LPC1769_DRIVER
+ * @ingroup BLACKTANK_LPC1769
+ */
--- /dev/null
+/**
+ * @file doxygen_development.c
+ * @author Shinichiro Nakamura
+ * @brief Doxygen用のファイル。開発に関するトピックを記述してある。
+ * @details
+ *
+ * @page development 開発に関するトピック
+ *
+ * @section debugging デバッグ方法
+ *
+ * @subsection debugging_with_telnet telnetを使ったデバッグ
+ *
+ * @code
+ * > telnet localhost 4444
+ * >> halt
+ * >> flash probe 0
+ * >> flash write_image erase TOPPERS-ASP_BlackTank-LPC1769.bin
+ * >> reset
+ * @endcode
+ *
+ * @subsection debugging_with_gdb gdbを使ったデバッグ
+ *
+ * @code
+ * > arm-none-eabi-gdb TOPPERS-ASP_BlackTank-LPC1769.axf
+ * (gdb) target remote localhost:3333
+ * (gdb) monitor halt
+ * (gdb) load TOPPERS-ASP_BlackTank-LPC1769.axf
+ * (gdb) continue
+ * @endcode
+ *
+ * リセットがうまく動作しない場合、monitor haltの代わりにmonitor soft_reset_haltを試して下さい。
+ *
+ * @subsection debugging_with_lpc21isp lpc21ispを使った書き込み
+ *
+ * @code
+ * > lpc21isp TOPPERS-ASP_BlackTank-LPC1769.hex /dev/ttyUSB0 57600 4000
+ * @endcode
+ */
+
--- /dev/null
+/**
+ * @file doxygen_firmware.c
+ * @author Shinichiro Nakamura
+ * @brief Doxygen用のファイル。ファームウェアに関するトピックを記述してある。
+ * @details
+ *
+ * @page firmware ファームウェアに関するトピック
+ *
+ * ファームウェアに関する既知の問題点については @ref problems_firmware をご覧下さい。
+ *
+ * @section task_structure_design タスク設計
+ *
+ * @subsection task_userinput ユーザインプットタスク(task_userinput)
+ *
+ * ユーザインプットタスクは4系統のユーザ入力の変化を観察する
+ * タスクです。
+ * 変化があればデータキューを介してシステムコントロールタスクに
+ * 通知されます。
+ *
+ * @subsection task_menu メニュータスク(task_menu)
+ *
+ * メニュータスクはユーザにシステムのサービスを提示し、
+ * ユーザからの要求をシステムに伝達する役目を果たします。
+ *
+ * ユーザは各タスクから次のマクロのみで指示することができます。
+ *
+ * @code
+ * USERMSG(device, value);
+ * @endcode
+ *
+ * - deviceは以下から選択できます。
+ * - スイッチ: SW0, SW1, SW2, SW3
+ * - ボリューム: VOL0, VOL1, VOL2, VOL3
+ * .
+ * .
+ *
+ * - Typeはビットマッピングです。
+ * - 長押し状態フラグ:SW_LONG_PUSH
+ * .
+ * .
+ *
+ * このタスクへの指示はデータキューを介して行われます。
+ * データキュー内部データ構造は以下のようになっています。
+ *
+ * <pre>
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+------------------+
+ * |15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| Description |
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+------------------+
+ * | |<- [9:0] ->| Value |
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+------------------+
+ * | |11:10| | Type |
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+------------------+
+ * |<-[15:12]->| | Device |
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+------------------+
+ * </pre>
+ *
+ * @subsection task_led LEDタスク(task_led)
+ *
+ * LEDタスクはLEDの点灯を制御するタスクです。
+ *
+ * 点灯は各タスクから次のマクロのみで指示することができます。
+ *
+ * @code
+ * LEDMSG(target, control);
+ * @endcode
+ *
+ * - targetは以下から選択できます。
+ * - デバッグ用LED: DBLED0, DBLED1, DBLED2, DBLED3
+ * - スイッチ用LED: SWLED0, SWLED1, SWLED2, SWLED3
+ * .
+ * .
+ *
+ * - controlは以下から選択できます。
+ * - LED点灯:LEDON
+ * - LED消灯:LEDOFF
+ * .
+ * .
+ *
+ * このタスクへの指示はデータキューを介して行われます。
+ * データキュー内部データ構造は以下のようになっています。
+ *
+ * <pre>
+ * +---+---+---+---+---+---+---+---+-------------+
+ * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Description |
+ * +---+---+---+---+---+---+---+---+-------------+
+ * | |<- [3:0] ->| Target |
+ * +---+---+---+---+---+---+---+---+-------------+
+ * | | x x x | | Reserved |
+ * +---+---+---+---+---+---+---+---+-------------+
+ * |[7]| | Control |
+ * +---+---+---+---+---+---+---+---+-------------+
+ * </pre>
+ *
+ * @subsection task_display ディスプレイタスク(task_display)
+ * ディスプレイタスクは有機ELディスプレイを制御するタスクです。
+ *
+ * ディスプレイの制御は以下のマクロを使って行うことができます。
+ *
+ * @code
+ * DISP_CLEAR(R, G, B);
+ * DISP_LINE(X1, Y1, X2, Y2, R, G, B);
+ * DISP_BOX(X1, Y1, X2, Y2, R, G, B);
+ * DISP_FILLBOX(X1, Y1, X2, Y2, R1, G1, B1, R2, G2, B2);
+ * DISP_TEXT(X, Y, R, G, B, "TEXT");
+ * DISP_BMPFILE("0:FILENAME");
+ * DISP_AUDIO_LEVELMETER(L, R);
+ * @endcode
+ *
+ * タスク間はメールボックスでやりとりされます。
+ * マクロはこれを隠蔽した実装としました。
+ * メールボックスで陥りがちな同期問題を未然に防ぐ対策として
+ * メモリプール管理機能を使ってデータ領域に対するアクセスを
+ * 管理しています。
+ *
+ * 今回の実装では受信側が処理を完了するまで送信側が次の処理に
+ * 遷移しない実装にしてあります。
+ * 今回のタスク設計ではメニュータスクがブロックの対象となります。
+ *
+ * @subsection task_init 初期化タスク(task_init)
+ * 初期化するタスクです。
+ *
+ * @subsection task_ntshell ナチュラルタイニーシェルタスク(task_ntshell)
+ * システムをコンソールから制御することのできるインターフェース
+ * タスクです。
+ *
+ * @subsection task_audio オーディオタスク(task_audio)
+ * オーディオを処理するためのタスクです。
+ *
+ * このタスクにはパラメータを指定するためのマクロがあります。
+ *
+ * @code
+ * AUDIO_PARAM(TARGET,VALUE);
+ * @endcode
+ *
+ * - TARGETとVALUEは以下から選択します。
+ * - TARGET: VAR0, VAR1, VAR2, VAR3
+ * - VALUE : The value of the target.
+ * .
+ * .
+ *
+ * <pre>
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+------------------+
+ * |15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| Description |
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+------------------+
+ * | |<- [11:0] ->| Value |
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+------------------+
+ * |<-[15:12]->| | Target |
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+------------------+
+ * </pre>
+ *
+ * VAR0, VAR1, VAR2, VAR3の各値をどのように使うのかは実装される
+ * オーディオエフェクトに依存します。
+ * 詳しくはaudio_effect.cを御参照下さい。
+ *
+ * @section application_examples アプリケーション例
+ *
+ * - オーディオエフェクタ
+ * - メトロノーム
+ * - 多機能時計
+ * - ピンボールゲーム
+ *
+ * @section task_priority プライオリティ
+ *
+ * タスクプライオリティに関しては以下のように定めた。
+ * 一般にRTOSのプライオリティはサーバ>クライアントとなる。
+ * これに層別の視点を加えてプライオリティを決定した。
+ *
+ * <table>
+ * <tr>
+ * <th>カテゴリ</th>
+ * <th>タスク</th>
+ * <th>プライオリティ</th>
+ * </tr>
+ * <tr>
+ * <td>リアルタイム・タスク</td>
+ * <td>@ref task_audio</td>
+ * <td>10</td>
+ * </tr>
+ * <tr>
+ * <td rowspan="2">サーバ・タスク</td>
+ * <td>@ref task_display</td>
+ * <td>11</td>
+ * </tr>
+ * <tr>
+ * <td>@ref task_led</td>
+ * <td>11</td>
+ * </tr>
+ * <tr>
+ * <td rowspan="2">クライアント・タスク</td>
+ * <td>@ref task_menu</td>
+ * <td>12</td>
+ * </tr>
+ * <tr>
+ * <td>@ref task_userinput</td>
+ * <td>12</td>
+ * </tr>
+ * <tr>
+ * <td>イニシャライザ</td>
+ * <td>@ref task_init</td>
+ * <td>13</td>
+ * </tr>
+ * <tr>
+ * <td>デバッガ</td>
+ * <td>@ref task_ntshell</td>
+ * <td>14</td>
+ * </tr>
+ * </table>
+ *
+ * @section sec_audio_effect_refactoring オーディオ処理の効率改善。
+ *
+ * ここではオーディオ処理の効率改善について記す。
+ *
+ * @subsection sec_audio_effect_refactoring1 オリジナルの設計
+ *
+ * オリジナルの実装では以下のような処理となっていた。
+ *
+ * - DMA転送されたオーディオバッファサイズ分のデータがrxbufに入っている。
+ * - 並び替えながらrxbufからaudio_data.inputBufferにコピーする。
+ * - オーディオ処理を実行する。
+ * - ここでは処理に応じてaudio_data.inputBufferからaudio_data.outputBufferへのコピーが発生する。
+ * .
+ * - 並び替えながらaudio_data.outputBufferからtxbufにコピーする。
+ * .
+ *
+ * 図を用いて整理すると以下のようになる。
+ *
+ * <pre>
+ * +-----+ +-----------+ +------------+ +-----+
+ * |rxbuf| -> |inputBuffer| -> |outputBuffer| -> |txbuf|
+ * +-----+ +-----------+ +------------+ +-----+
+ * </pre>
+ *
+ * 要するに主記憶上におけるメモリコピーが少なくとも3回発生している。
+ *
+ * また、このメモリコピーはforループで実装されており、3回のforループによる性能への影響も気になる。
+ *
+ * 通常、性能という観点で見た場合、メモリコピーや重複したforループは性能劣化の主要な要因のひとつとなる。
+ *
+ * そこで、今回は上記処理の効率改善を行う。
+ *
+ * まず初めに、最小限の処理について考えてみる。
+ *
+ * <pre>
+ * +-----+ +-----+
+ * |rxbuf| -> |txbuf|
+ * +-----+ +-----+
+ * </pre>
+ *
+ * 入力をそのまま出力に伝達する場合、単なるメモリコピーで良い。
+ *
+ * 入力に何らかの処理を加え、出力に伝える場合でもこの入出力間のメモリコピーの間に何らかの処理を追加するだけで済むので、本質的に上記と変わらない。
+ *
+ * オリジナルの実装ではコーデックのデータ形式を鑑みて工夫がしてある。
+ *
+ * この処理を順次見ていくことにする。
+ *
+ * まず初めに入力されたデータを内部で扱いやすい形式にメモリコピーする。
+ *
+ * これはrxbufからinputBufferへのコピーである。
+ *
+ * <pre>
+ * +--------------------------+
+ * |+-----+ +-----------+| +------------+ +-----+
+ * ||rxbuf| -> |inputBuffer|| -> |outputBuffer| -> |txbuf|
+ * |+-----+ +-----------+| +------------+ +-----+
+ * +--------------------------+
+ * </pre>
+ *
+ * 次にオーディオの処理を実行する。
+ *
+ * これはinputBufferからoutputBufferへのコピーである。
+ *
+ * オーディオの処理を実装する過程で、ここに様々な演算が入ることになる。
+ *
+ * <pre>
+ * +---------------------------------+
+ * +-----+ |+-----------+ +------------+| +-----+
+ * |rxbuf| -> ||inputBuffer| -> |outputBuffer|| -> |txbuf|
+ * +-----+ |+-----------+ +------------+| +-----+
+ * +---------------------------------+
+ * </pre>
+ *
+ * 最後に結果を出力バッファに書き込む。
+ *
+ * outputBufferからtxbufへのコピーである。
+ *
+ * これはオーディオバッファの内容を、都合の良い形式に前段で並び替えた結果発生する作業である。
+ *
+ * <pre>
+ * +---------------------------+
+ * +-----+ +-----------+ |+------------+ +-----+|
+ * |rxbuf| -> |inputBuffer| -> ||outputBuffer| -> |txbuf||
+ * +-----+ +-----------+ |+------------+ +-----+|
+ * +---------------------------+
+ * </pre>
+ *
+ * まとめると以下のようになる。
+ * - コーデックから得られたデータ形式は扱いにくいので並び替える。
+ * - 並び替えは主記憶上でMCUが実行する。
+ * - 並び替えたデータは、コーデックがそのまま扱えないので再変換する。
+ * .
+ *
+ * コードブロックは以下のようになっていた。(一部はオリジナルと少し異なる。)
+ *
+ * @code
+ * index = 0;
+ * for (sample = 0; sample < AUDIOBUFSIZE / 2; sample++) {
+ * for (ch = 0; ch < 2; ch++) {
+ * audio_data.inputBuffer[ch][sample] = rxbuf[index++];
+ * }
+ * }
+ * audio_effect_through(
+ * &effect_param,
+ * audio_data.inputBuffer,
+ * audio_data.outputBuffer,
+ * AUDIOBUFSIZE / 2);
+ * index = 0;
+ * for (sample = 0; sample < AUDIOBUFSIZE / 2; sample++) {
+ * for (ch = 0; ch < 2; ch++) {
+ * txbuf[index++] = audio_data.outputBuffer[ch][sample];
+ * }
+ * }
+ * @endcode
+ *
+ * オーディオエフェクト処理の前後でデータ形式変換を行なっていることがわかる。
+ *
+ * 前段と後段で各((AUDIOBUFSIZE / 2) x 2)回分のメモリコピーを行なっている。
+ *
+ * 実際にオーディオ処理関数内部の実装も見る。(一部はオリジナルと少し異なる。)
+ *
+ * @code
+ * void audio_effect_through(
+ * effect_param_t *param,
+ * AUDIOSAMPLE input[2][AUDIOBUFSIZE / 2],
+ * AUDIOSAMPLE output[2][AUDIOBUFSIZE / 2],
+ * int count)
+ * {
+ * int i;
+ *
+ * const int var0 = param->var0;
+ * const int var1 = param->var1;
+ * for (i = 0; i < count; i++)
+ * {
+ * output[LCH][i] = (input[LCH][i] >> 10) * var0;
+ * output[RCH][i] = (input[RCH][i] >> 10) * var1;
+ * }
+ * }
+ * @endcode
+ *
+ * ここで上位から渡されるcountは(AUDIOBUFSIZE / 2)である。
+ *
+ * よって、ここでも((AUDIOBUFSIZE / 2) x 2)回分のメモリコピーを行なっていることになる。
+ *
+ * @subsection sec_audio_effect_refactoring2 改善の提案
+ *
+ * ここまではオリジナルの設計について述べた。
+ *
+ * それでは実際にオーディオ処理の効率改善について述べる。
+ *
+ * 基本的な思想は以下の通りである。
+ * - 主記憶上におけるメモリコピーは性能に対して著しい劣化を伴う。
+ * - より多くの処理を実現するためにはメモリコピーを排除すれば良い。
+ * - メモリコピーを行なっている主な理由はデータ形式変換である。
+ * - データ形式変換が不要となるような枠組みを用意すれば、データ形式変換が不要となるはずである。
+ * - データ形式変換が不要となれば、必要となるバッファも削減することができ、RAM容量という観点から見ても有利である。
+ * .
+ *
+ * 要するに「データ形式変換」を実現しながらも、「メモリコピー」を発生させないという矛盾を解決すれば良い事になる。
+ * この中でforループについても削減可能と判断した。
+ *
+ * オリジナルの実装ではオーディオ処理関数に渡るデータ形式が重要であった。
+ *
+ * この点は改善案でも特に変わるものではない。
+ *
+ * オリジナルと異なるのはその実現手法である。
+ *
+ * ここで実際に改善したコードを示す。
+ *
+ * @code
+ * for (index = 0; index < AUDIOBUFSIZE; index+=2) {
+ * audio_effect_through(
+ * &effect_param,
+ * rxbuf + (index + 0), rxbuf + (index + 1),
+ * txbuf + (index + 0), txbuf + (index + 1));
+ * }
+ * @endcode
+ *
+ * オーディオ処理関数へL-Rのステレオデータを揃えて渡す部分はコールバック関数とし、オーディオ処理関数内部で直接出力データを格納させる形式とした。
+ *
+ * これによりオリジナルに存在した前段と後段でのメモリコピーを排除できる。
+ *
+ * オリジナルの実装では、前段と後段で(AUDIOBUFSIZE / 2) x 2回分のメモリコピーを必要としていたが、これを置きかえる形となる。
+ *
+ * これによりinputBufferとoutputBufferも不要となった。
+ *
+ * audio_effect_throught関数はオーディオデータをスルーコピーする関数である。
+ *
+ * @code
+ * void audio_effect_through(
+ * const effect_param_t *param,
+ * const AUDIOSAMPLE *in_left,
+ * const AUDIOSAMPLE *in_right,
+ * AUDIOSAMPLE *out_left,
+ * AUDIOSAMPLE *out_right)
+ * {
+ * const int var0 = param->var0;
+ * const int var1 = param->var1;
+ * *out_left = ((*in_left) >> 10) * var0;
+ * *out_right = ((*in_right) >> 10) * var1;
+ * }
+ * @endcode
+ *
+ * オーディオエフェクト関数には1サンプル毎に処理を依頼する。
+ *
+ * 処理結果は関数に渡されたバッファへのポインタを用いて直接格納する。
+ *
+ * 上記により中間バッファを排除しながらも、渡されるデータ形式はL-Rのステレオで揃っているという状況を作ることができる。
+ *
+ * また、バッファサイズ分のforループも1回で済むようになり、効率改善が期待できる。
+ *
+ * @subsection sec_audio_effect_refactoring3 改善の効果
+ *
+ * ここで実際の処理時間に与える影響を調査した。
+ *
+ * 処理時間はオーディオ処理ブロックに差し掛かったところでGPIOをハイレベルにし、オシロスコープにより観測した。
+ *
+ * ここでの処理対象は1オーディオサンプルブロックでAUDIOBUFSIZE分のデータである。
+ *
+ * 初めにオリジナル実装でオーディオスルーにかかっている処理時間を示す。
+ *
+ * 約70[us]の時間を要している。
+ *
+ * @image html task_audio_before.bmp
+ *
+ * 次に示すのは改良した実装でオーディオスルーを行なった場合の処理時間である。
+ *
+ * 約25[us]の時間で処理できている。
+ *
+ * @image html task_audio_after.bmp
+ *
+ * 上記のようにオリジナルの実装に対して35.7%の時間で同等の処理が実現できる事が確認できた。
+ *
+ * 削減できた約45[us]は別の演算に割り当てることができる。
+ *
+ * 従来より高度な演算も可能となる。
+ *
+ * @subsection sec_audio_effect_refactoring4 改善のまとめ
+ *
+ * 本改善提案によれば、処理を非常に簡単に記述することが出来る上、主記憶上のメモリコピーが必要ない。
+ *
+ * このため大幅な処理時間の短縮が可能となった。
+ *
+ * これによりMCUの演算能力を効率的にオーディオ処理に割り当てる事が可能となる。
+ *
+ * オーディオエフェクト関数を同じパラメータで作成すれば、関数ポインタの切り替えのみでオーディオエフェクト処理を切り替えることが可能となる。
+ *
+ * 通常、オーディオ処理では特定サンプルに対して、時間軸方向前後のデータも用いてフィルタリングを行なう。
+ *
+ * 提案手法ではオーディオ処理関数に渡ってくるデータは1サンプル分のみであるが、オーディオエフェクト関数内部で静的メモリを保持し、バッファリングしながら処理をすれば、時間軸の前後方向のデータも用いて処理することが可能である。
+ *
+ * なお、実験結果はコンパイラの最適化オプションを外した状態で行なった。最適化を施すことで、場合によってはより多くのパフォーマンス改善が得られる可能性もある。
+ */
+
--- /dev/null
+/**
+ * @file doxygen_hardware.c
+ * @author Shinichiro Nakamura
+ * @brief Doxygen用のファイル。ハードウェアに関するトピックが記述してある。
+ * @details
+ *
+ * @page hardware ハードウェアに関するトピック
+ *
+ * ハードウェアに関する既知の問題点については @ref problems_hardware をご覧下さい。
+ *
+ * @section hardware_warning 使用上の注意
+ *
+ * OLEDは同じ内容を表示し続けると焼き付きが発生します。
+ * 表示内容を時折変更するようにして下さい。
+ *
+ * @section hardware_validation ハードウェアテスト項目
+ *
+ * <pre>
+ * +======+================+===================================+
+ * | | 緑ランプ波形 | |
+ * | +----------------+-----------------------------------+
+ * | OLED | 青ランプ波形 | |
+ * | +----------------+-----------------------------------+
+ * | | 赤ランプ波形 | |
+ * +------+----------------+-----------------------------------+
+ * | | スイッチ入力 | |
+ * | SW. +----------------+-----------------------------------+
+ * | | スイッチLED | |
+ * +------+----------------+-----------------------------------+
+ * |Volume| スイッチ入力 | |
+ * +------+----------------+-----------------------------------+
+ * |DEBLED| スイッチ入力 | |
+ * +------+----------------+-----------------------------------+
+ * | | コーデック | |
+ * | +----------------+-----------------------------------+
+ * | | MIC-IN | |
+ * | +----------------+-----------------------------------+
+ * |AUDIO | LINE-IN | |
+ * | +----------------+-----------------------------------+
+ * | | LINE-OUT | |
+ * | +----------------+-----------------------------------+
+ * | | PHONE-OUT | |
+ * +------+----------------+-----------------------------------+
+ * | JTAG | JTAG | |
+ * +------+----------------+-----------------------------------+
+ * | | RESET | |
+ * |DEBSW.+----------------+-----------------------------------+
+ * | | ISP | |
+ * +------+----------------+-----------------------------------+
+ * | USB | USB-UART | |
+ * +------+----------------+-----------------------------------+
+ * | SD | SDCARD | |
+ * +------+----------------+-----------------------------------+
+ * | | UART1 | |
+ * | +----------------+-----------------------------------+
+ * | UART | UART2 | |
+ * | +----------------+-----------------------------------+
+ * | | UART3 | |
+ * +------+----------------+-----------------------------------+
+ * | | Main Power | |
+ * | RTC +----------------+-----------------------------------+
+ * | | Battery | |
+ * +------+----------------+-----------------------------------+
+ * | | 5.0V | |
+ * |POWER +----------------+-----------------------------------+
+ * | | 3.3V | |
+ * +------+----------------+-----------------------------------+
+ * </pre>
+ */
+
--- /dev/null
+/**
+ * @file doxygen_mainpage.c
+ * @author Shinichiro Nakamura
+ * @brief Doxygen用のファイル。ドキュメントのメインページに関する記述がしてある。
+ * @details
+ *
+ * @mainpage
+ *
+ * このドキュメントは以下の要素で構成されている。
+ * - @subpage overview
+ * - @subpage hardware
+ * - @subpage firmware
+ * - @subpage development
+ * - @subpage problems
+ * - @subpage requests
+ */
+
--- /dev/null
+/**
+ * @file doxygen_overview.c
+ * @author Shinichiro Nakamura
+ * @brief Doxygen用のファイル。概要が記述してある。
+ * @details
+ *
+ * @page overview 概要
+ *
+ * @image html logo.bmp
+ *
+ * @section product_overview BlackTank LPC1769
+ *
+ * BlackTank LPC1769はARM Cortex-M3とRTOSを楽しむ事を目的に設計
+ * した基板です。
+ * 有機ELディスプレイ、4系統ユーザ入力、オーディオコーデック、
+ * マイクロSDカードなどが1枚の基板に搭載されています。
+ * ARM Cortex-M3にはNXP SemiconductorsのLPC1769を採用しています。
+ *
+ * @image html board-photo-1.jpg
+ *
+ * 基板サイズはユニバーサル基板(Sunhayato ICB-293)と同じです。
+ * 実験回路をユニバーサル基板に実装して、ドッキングして使用することもできます。
+ *
+ * 有機ELディスプレイも搭載。
+ * 実用的なアプリケーションで欠かせないユーザインターフェースの実現も簡単です。
+ *
+ * @image html board-photo-2.jpg
+ *
+ * 文字列を指定しての描画など、用意されたサンプルを用いて直ぐに実現することができます。
+ *
+ * @image html board-photo-3.jpg
+ */
+
--- /dev/null
+/**
+ * @file doxygen_problems.c
+ * @author Shinichiro Nakamura
+ * @brief Doxygen用のファイル。既知の問題点が記述してある。
+ * @details
+ *
+ * @page problems 既知の問題点
+ *
+ * @section problems_hardware ハードウェアに関する既知の問題点
+ *
+ * - OLEDの電源配線ミス。
+ * - 電源の配線を追加する。
+ *
+ * - レギュレータのGNDの配線が細い。
+ * - 配線を太く、短くする。
+ *
+ * - 基板名やリビジョン、スペシャルサンクスのシルクが入っていない。
+ * - ガーバーデータ作成時にレイヤー指定を間違えたかも。
+ * - さらにチェックが甘かった。
+ *
+ * - OLEDのノイズ音が気になる。
+ * - 初期化パラメータの動作周波数変更で回避可能か?
+ *
+ * - OLEDに書き込みを行うとオーディオにノイズが発生する。
+ * - 配線がよくない。
+ * - 配置がよくない。
+ * - 完全分離が必須。
+ *
+ * - 発振器がオーディオを愛する人の周波数になっていない。
+ * - すいません!
+ *
+ * - ポリスイッチのパッケージが違う。
+ *
+ * - C31, C32への変なGND配線がある。
+ *
+ * - R37のビアがポリスイッチに近すぎる。
+ *
+ * - オーディオコネクタのパッケージがおかしい。
+ *
+ * - SDカードがレガシーSPIコアを使うようなペリフェラル割り当てになっている。
+ * - GPDMAによる転送が使えない。
+ * - OLEDよりもSDカードの方が優先度高いんじゃない?
+ *
+ * - SDカードを差し込むと電源がドロップする。
+ * - Cの容量を増やす。
+ * - Lを挿入して突入電流を阻止するか。
+ *
+ * - 何だかわからない電池BOXをやめて、入手可能なパッケージにしたい。
+ *
+ * - MIDI用UARTのコネクタのパッケージに位置決め穴がない。
+ *
+ * - MIC INの回路ってこれで良いの?
+ * - TI Stellaris LM3S9B96 Development Kitを参考にしている。
+ *
+ * - リセットスイッチを押さないとファームウェアが起動しない。
+ * - リセットの入り方が条件を満たしていないのではないか?
+ * - リセット解除が早すぎるのが原因。
+ * - 電源が安定する前に解除されている。
+ * - リセットICにしたい。
+ *
+ * @section problems_firmware ファームウェアに関する既知の問題点
+ *
+ * - codecの初期化に失敗することがある。
+ * - CMSISのドライバを使った実装に修正したい。
+ *
+ * - I2S DMAの開始で割り込み無限ループに突入する。
+ * - デバッガを外したコールドスタートで必ず発生する。
+ *
+ * - TLVを組み込んでブートできない。
+ */
+
--- /dev/null
+/**
+ * @file doxygen_requests.c
+ * @author Shinichiro Nakamura
+ * @brief Doxygen用のファイル。改善要求が記述してある。
+ * @details
+ *
+ * @page requests 改善要求
+ *
+ * @section requests_hardware ハードウェアに関する改善要求
+ *
+ * - NIKKAI HB2-15の感触やクリック音が個体によって異なるので他のスイッチにしたい。
+ * - FUJISOKU CFPB-1CC-4W9W が結構良いのでそちらにしたい。
+ *
+ * - 隣り合うパッドで接続するパターンが一部良くない。(ショートチェックがやりにくい。)
+ * - パッドの横から直接横に伸びている。
+ * - OLEDコネクタ
+ * - TLV320AIC23Bの一部の端子
+ *
+ * - ボリュームのセンス値がフラフラしすぎのような気がするけど?
+ *
+ * - 通信確認LEDが暗い。
+ * - デバッグ用LEDに採用したLEDと同じ物を使う。(3号機、4号機は改善済み。)
+ *
+ * - RESET, ISPのシルクが入っていない。
+ * - ガーバーデータ作成時にレイヤー指定を間違えたかも。
+ * - さらにチェックが甘かった。
+ *
+ * - オーディオコネクタのどれが何かわからない。シルクを入れたい。
+ * - 場所がない。
+ *
+ * - デバッグ用LEDが眩しすぎる。意図して高輝度LEDだが、眩しすぎ!
+ * - 抵抗値を変更する。
+ *
+ * - スイッチが微妙な基板端に配置されていてカバーアクリルを作りづらい。
+ * - 基板端にするならする。しないなら離す。
+ *
+ * - UART2がネジ穴に近すぎる。
+ * - もう少し離して配置したい。
+ *
+ * - JTAGコネクタがネジ穴に近い。
+ * - もう少し離して配置したい。
+ *
+ * - 発振器のパッケージを見直したい。
+ * - 小さいパッケージの中ではどれが一般的?
+ *
+ * - ボリュームではなく、ロータリーエンコーダにしたい。
+ * - ボリュームの初期状態に設定値が縛られるのを避けたい。
+ * - クルクル回したい。
+ *
+ * - TP1, TP2の位置が使いづらい。
+ * - 配線の都合上?
+ *
+ * @section requests_firmware ファームウェアに関する改善要求
+ *
+ * - サンプルデザインをもっと魅力的にしたい。
+ */
--- /dev/null
+/**\r
+ * @file diskio_ff.h\r
+ * @brief 低レベルディスクI/Oインターフェースモジュールの定義。\r
+ */\r
+\r
+/*-----------------------------------------------------------------------\r
+/ Low level disk interface modlue include file (C)ChaN, 2009\r
+/-----------------------------------------------------------------------*/\r
+\r
+#ifndef DISKIO_FF_H\r
+#define DISKIO_FF_H\r
+\r
+#include "integer_ff.h"\r
+\r
+\r
+/* Status of Disk Functions */\r
+typedef BYTE DSTATUS;\r
+\r
+/* Results of Disk Functions */\r
+typedef enum {\r
+ RES_OK = 0, /* 0: Successful */\r
+ RES_ERROR, /* 1: R/W Error */\r
+ RES_WRPRT, /* 2: Write Protected */\r
+ RES_NOTRDY, /* 3: Not Ready */\r
+ RES_PARERR /* 4: Invalid Parameter */\r
+} DRESULT;\r
+\r
+\r
+/*---------------------------------------*/\r
+/* Prototypes for disk control functions */\r
+\r
+int assign_drives (int, int);\r
+DSTATUS disk_initialize (BYTE);\r
+DSTATUS disk_status (BYTE);\r
+DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);\r
+DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);\r
+DRESULT disk_ioctl (BYTE, BYTE, void*);\r
+\r
+\r
+\r
+/* Disk Status Bits (DSTATUS) */\r
+\r
+#define STA_NOINIT 0x01 /* Drive not initialized */\r
+#define STA_NODISK 0x02 /* No medium in the drive */\r
+#define STA_PROTECT 0x04 /* Write protected */\r
+\r
+\r
+/* Command code for disk_ioctrl fucntion */\r
+\r
+/* Generic command (mandatory for FatFs) */\r
+#define CTRL_SYNC 0 /* Flush disk cache (for write functions) */\r
+#define GET_SECTOR_COUNT 1 /* Get media size (for only f_mkfs()) */\r
+#define GET_SECTOR_SIZE 2 /* Get sector size (for multiple sector size (_MAX_SS >= 1024)) */\r
+#define GET_BLOCK_SIZE 3 /* Get erase block size (for only f_mkfs()) */\r
+\r
+#endif\r
--- /dev/null
+/**\r
+ * @file diskio_ff_mmc.c\r
+ * @brief 低レベルディスクI/Oインターフェースモジュールの実装。(SPI版)\r
+ */\r
+\r
+/*------------------------------------------------------------------------/\r
+/ SPI MMCv3/SDv1/SDv2 (in SPI mode) control module\r
+/-------------------------------------------------------------------------/\r
+/\r
+/ Copyright (C) 2010, ChaN, all right reserved.\r
+/\r
+/ * This software is a free software and there is NO WARRANTY.\r
+/ * No restriction on use. You can use, modify and redistribute it for\r
+/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.\r
+/ * Redistributions of source code must retain the above copyright notice.\r
+/\r
+/--------------------------------------------------------------------------/\r
+ Features and Limitations:\r
+\r
+ * Very Easy to Port\r
+ It uses only 4-6 bit of GPIO port. No interrupt, no SPI port is used.\r
+\r
+ * Platform Independent\r
+ You need to modify only a few macros to control GPIO ports.\r
+\r
+ * Low Speed\r
+ The data transfer rate will be several times slower than hardware SPI.\r
+\r
+ * No Media Change Detection\r
+ Application program must re-mount the volume after media change or it\r
+ results a hard error.\r
+\r
+/-------------------------------------------------------------------------*/\r
+\r
+\r
+#include "diskio_ff.h" /* Common include file for FatFs and disk I/O layer */\r
+\r
+\r
+/*-------------------------------------------------------------------------*/\r
+/* Platform dependent macros and functions needed to be modified */\r
+/*-------------------------------------------------------------------------*/\r
+\r
+#include "ffspi.h" /* Include device specific declareation file here */\r
+\r
+#define INIT_PORT() ffspi_init() /* Initialize MMC control port (CS/CLK/DI:output, DO/WP/INS:input) */\r
+#define DLY_MS(n) ffspi_dly_ms(n) /* Delay n microseconds */\r
+\r
+#define CS_H() ffspi_cs_dis() /* Set MMC CS "high" */\r
+#define CS_L() ffspi_cs_ena() /* Set MMC CS "low" */\r
+\r
+#define INS (1) /* Card is inserted (yes:true, no:false, default:true) */\r
+#define WP (0) /* Card is write protected (yes:true, no:false, default:false) */\r
+\r
+\r
+\r
+/*--------------------------------------------------------------------------\r
+\r
+ Module Private Functions\r
+\r
+---------------------------------------------------------------------------*/\r
+\r
+/* MMC/SD command (SPI mode) */\r
+#define CMD0 (0) /* GO_IDLE_STATE */\r
+#define CMD1 (1) /* SEND_OP_COND */\r
+#define ACMD41 (0x80+41) /* SEND_OP_COND (SDC) */\r
+#define CMD8 (8) /* SEND_IF_COND */\r
+#define CMD9 (9) /* SEND_CSD */\r
+#define CMD10 (10) /* SEND_CID */\r
+#define CMD12 (12) /* STOP_TRANSMISSION */\r
+#define ACMD13 (0x80+13) /* SD_STATUS (SDC) */\r
+#define CMD16 (16) /* SET_BLOCKLEN */\r
+#define CMD17 (17) /* READ_SINGLE_BLOCK */\r
+#define CMD18 (18) /* READ_MULTIPLE_BLOCK */\r
+#define CMD23 (23) /* SET_BLOCK_COUNT */\r
+#define ACMD23 (0x80+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */\r
+#define CMD24 (24) /* WRITE_BLOCK */\r
+#define CMD25 (25) /* WRITE_MULTIPLE_BLOCK */\r
+#define CMD41 (41) /* SEND_OP_COND (ACMD) */\r
+#define CMD55 (55) /* APP_CMD */\r
+#define CMD58 (58) /* READ_OCR */\r
+\r
+/* Card type flags (CardType) */\r
+#define CT_MMC 0x01 /* MMC ver 3 */\r
+#define CT_SD1 0x02 /* SD ver 1 */\r
+#define CT_SD2 0x04 /* SD ver 2 */\r
+#define CT_SDC (CT_SD1|CT_SD2) /* SD */\r
+#define CT_BLOCK 0x08 /* Block addressing */\r
+\r
+\r
+static\r
+DSTATUS Stat = STA_NOINIT; /* Disk status */\r
+\r
+static\r
+BYTE CardType; /* b0:MMC, b1:SDv1, b2:SDv2, b3:Block addressing */\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Transmit bytes to the MMC (bitbanging) */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+void xmit_mmc (\r
+ const BYTE* buff, /* Data to be sent */\r
+ UINT bc /* Number of bytes to send */\r
+)\r
+{\r
+ do {\r
+ ffspi_tx(*buff++);\r
+ } while (--bc);\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Receive bytes from the MMC (bitbanging) */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+void rcvr_mmc (\r
+ BYTE *buff, /* Pointer to read buffer */\r
+ UINT bc /* Number of bytes to receive */\r
+)\r
+{\r
+ do {\r
+ *buff++ = ffspi_rx();\r
+ } while (--bc);\r
+}\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Wait for card ready */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+int wait_ready (void) /* 1:OK, 0:Timeout */\r
+{\r
+ BYTE d;\r
+ UINT tmr;\r
+\r
+\r
+ for (tmr = 5000; tmr; tmr--) { /* Wait for ready in timeout of 500ms */\r
+ rcvr_mmc(&d, 1);\r
+ if (d == 0xFF) return 1;\r
+ DLY_MS(1);\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Deselect the card and release SPI bus */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+void deselect (void)\r
+{\r
+ BYTE d;\r
+\r
+ CS_H();\r
+ rcvr_mmc(&d, 1);\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Select the card and wait for ready */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+int select (void) /* 1:OK, 0:Timeout */\r
+{\r
+ CS_L();\r
+ if (!wait_ready()) {\r
+ deselect();\r
+ return 0;\r
+ }\r
+ return 1;\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Receive a data packet from MMC */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+int rcvr_datablock ( /* 1:OK, 0:Failed */\r
+ BYTE *buff, /* Data buffer to store received data */\r
+ UINT btr /* Byte count */\r
+)\r
+{\r
+ BYTE d[2];\r
+ UINT tmr;\r
+\r
+\r
+ for (tmr = 1000; tmr; tmr--) { /* Wait for data packet in timeout of 100ms */\r
+ rcvr_mmc(d, 1);\r
+ if (d[0] != 0xFF) break;\r
+ DLY_MS(1);\r
+ }\r
+ if (d[0] != 0xFE) return 0; /* If not valid data token, retutn with error */\r
+\r
+ rcvr_mmc(buff, btr); /* Receive the data block into buffer */\r
+ rcvr_mmc(d, 2); /* Discard CRC */\r
+\r
+ return 1; /* Return with success */\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Send a data packet to MMC */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+int xmit_datablock ( /* 1:OK, 0:Failed */\r
+ const BYTE *buff, /* 512 byte data block to be transmitted */\r
+ BYTE token /* Data/Stop token */\r
+)\r
+{\r
+ BYTE d[2];\r
+\r
+\r
+ if (!wait_ready()) return 0;\r
+\r
+ d[0] = token;\r
+ xmit_mmc(d, 1); /* Xmit a token */\r
+ if (token != 0xFD) { /* Is it data token? */\r
+ xmit_mmc(buff, 512); /* Xmit the 512 byte data block to MMC */\r
+ rcvr_mmc(d, 2); /* Dummy CRC (FF,FF) */\r
+ rcvr_mmc(d, 1); /* Receive data response */\r
+ if ((d[0] & 0x1F) != 0x05) /* If not accepted, return with error */\r
+ return 0;\r
+ }\r
+\r
+ return 1;\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Send a command packet to MMC */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+BYTE send_cmd ( /* Returns command response (bit7==1:Send failed)*/\r
+ BYTE cmd, /* Command byte */\r
+ DWORD arg /* Argument */\r
+)\r
+{\r
+ BYTE n, d, buf[6];\r
+\r
+\r
+ if (cmd & 0x80) { /* ACMD<n> is the command sequense of CMD55-CMD<n> */\r
+ cmd &= 0x7F;\r
+ n = send_cmd(CMD55, 0);\r
+ if (n > 1) return n;\r
+ }\r
+\r
+ /* Select the card and wait for ready */\r
+ deselect();\r
+ if (!select()) return 0xFF;\r
+\r
+ /* Send a command packet */\r
+ buf[0] = 0x40 | cmd; /* Start + Command index */\r
+ buf[1] = (BYTE)(arg >> 24); /* Argument[31..24] */\r
+ buf[2] = (BYTE)(arg >> 16); /* Argument[23..16] */\r
+ buf[3] = (BYTE)(arg >> 8); /* Argument[15..8] */\r
+ buf[4] = (BYTE)arg; /* Argument[7..0] */\r
+ n = 0x01; /* Dummy CRC + Stop */\r
+ if (cmd == CMD0) n = 0x95; /* (valid CRC for CMD0(0)) */\r
+ if (cmd == CMD8) n = 0x87; /* (valid CRC for CMD8(0x1AA)) */\r
+ buf[5] = n;\r
+ xmit_mmc(buf, 6);\r
+\r
+ /* Receive command response */\r
+ if (cmd == CMD12) rcvr_mmc(&d, 1); /* Skip a stuff byte when stop reading */\r
+ n = 10; /* Wait for a valid response in timeout of 10 attempts */\r
+ do\r
+ rcvr_mmc(&d, 1);\r
+ while ((d & 0x80) && --n);\r
+\r
+ return d; /* Return with the response value */\r
+}\r
+\r
+\r
+\r
+/*--------------------------------------------------------------------------\r
+\r
+ Public Functions\r
+\r
+---------------------------------------------------------------------------*/\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Get Disk Status */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+DSTATUS disk_status (\r
+ BYTE drv /* Drive number (0) */\r
+)\r
+{\r
+ DSTATUS s = Stat;\r
+\r
+\r
+ if (drv || !INS) {\r
+ s = STA_NODISK | STA_NOINIT;\r
+ } else {\r
+ s &= ~STA_NODISK;\r
+ if (WP)\r
+ s |= STA_PROTECT;\r
+ else\r
+ s &= ~STA_PROTECT;\r
+ }\r
+ Stat = s;\r
+\r
+ return s;\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Initialize Disk Drive */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+DSTATUS disk_initialize (\r
+ BYTE drv /* Physical drive nmuber (0) */\r
+)\r
+{\r
+ BYTE n, ty, cmd, buf[4];\r
+ UINT tmr;\r
+ DSTATUS s;\r
+\r
+\r
+ INIT_PORT(); /* Initialize control port */\r
+\r
+ s = disk_status(drv); /* Check if card is in the socket */\r
+ if (s & STA_NODISK) return s;\r
+\r
+ CS_H();\r
+ for (n = 10; n; n--) rcvr_mmc(buf, 1); /* 80 dummy clocks */\r
+\r
+ ty = 0;\r
+ if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */\r
+ if (send_cmd(CMD8, 0x1AA) == 1) { /* SDv2? */\r
+ rcvr_mmc(buf, 4); /* Get trailing return value of R7 resp */\r
+ if (buf[2] == 0x01 && buf[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */\r
+ for (tmr = 1000; tmr; tmr--) { /* Wait for leaving idle state (ACMD41 with HCS bit) */\r
+ if (send_cmd(ACMD41, 1UL << 30) == 0) break;\r
+ DLY_MS(1);\r
+ }\r
+ if (tmr && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */\r
+ rcvr_mmc(buf, 4);\r
+ ty = (buf[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* SDv2 */\r
+ }\r
+ }\r
+ } else { /* SDv1 or MMCv3 */\r
+ if (send_cmd(ACMD41, 0) <= 1) {\r
+ ty = CT_SD1; cmd = ACMD41; /* SDv1 */\r
+ } else {\r
+ ty = CT_MMC; cmd = CMD1; /* MMCv3 */\r
+ }\r
+ for (tmr = 1000; tmr; tmr--) { /* Wait for leaving idle state */\r
+ if (send_cmd(ACMD41, 0) == 0) break;\r
+ DLY_MS(1);\r
+ }\r
+ if (!tmr || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */\r
+ ty = 0;\r
+ }\r
+ }\r
+ CardType = ty;\r
+ if (ty) /* Initialization succeded */\r
+ s &= ~STA_NOINIT;\r
+ else /* Initialization failed */\r
+ s |= STA_NOINIT;\r
+ Stat = s;\r
+\r
+ deselect();\r
+\r
+ return s;\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Read Sector(s) */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+DRESULT disk_read (\r
+ BYTE drv, /* Physical drive nmuber (0) */\r
+ BYTE *buff, /* Pointer to the data buffer to store read data */\r
+ DWORD sector, /* Start sector number (LBA) */\r
+ BYTE count /* Sector count (1..128) */\r
+)\r
+{\r
+ DSTATUS s;\r
+\r
+\r
+ s = disk_status(drv);\r
+ if (s & STA_NOINIT) return RES_NOTRDY;\r
+ if (!count) return RES_PARERR;\r
+ if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert LBA to byte address if needed */\r
+\r
+ if (count == 1) { /* Single block read */\r
+ if ((send_cmd(CMD17, sector) == 0) /* READ_SINGLE_BLOCK */\r
+ && rcvr_datablock(buff, 512))\r
+ count = 0;\r
+ }\r
+ else { /* Multiple block read */\r
+ if (send_cmd(CMD18, sector) == 0) { /* READ_MULTIPLE_BLOCK */\r
+ do {\r
+ if (!rcvr_datablock(buff, 512)) break;\r
+ buff += 512;\r
+ } while (--count);\r
+ send_cmd(CMD12, 0); /* STOP_TRANSMISSION */\r
+ }\r
+ }\r
+ deselect();\r
+\r
+ return count ? RES_ERROR : RES_OK;\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Write Sector(s) */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+DRESULT disk_write (\r
+ BYTE drv, /* Physical drive nmuber (0) */\r
+ const BYTE *buff, /* Pointer to the data to be written */\r
+ DWORD sector, /* Start sector number (LBA) */\r
+ BYTE count /* Sector count (1..128) */\r
+)\r
+{\r
+ DSTATUS s;\r
+\r
+\r
+ s = disk_status(drv);\r
+ if (s & STA_NOINIT) return RES_NOTRDY;\r
+ if (s & STA_PROTECT) return RES_WRPRT;\r
+ if (!count) return RES_PARERR;\r
+ if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert LBA to byte address if needed */\r
+\r
+ if (count == 1) { /* Single block write */\r
+ if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */\r
+ && xmit_datablock(buff, 0xFE))\r
+ count = 0;\r
+ }\r
+ else { /* Multiple block write */\r
+ if (CardType & CT_SDC) send_cmd(ACMD23, count);\r
+ if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */\r
+ do {\r
+ if (!xmit_datablock(buff, 0xFC)) break;\r
+ buff += 512;\r
+ } while (--count);\r
+ if (!xmit_datablock(0, 0xFD)) /* STOP_TRAN token */\r
+ count = 1;\r
+ }\r
+ }\r
+ deselect();\r
+\r
+ return count ? RES_ERROR : RES_OK;\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Miscellaneous Functions */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+DRESULT disk_ioctl (\r
+ BYTE drv, /* Physical drive nmuber (0) */\r
+ BYTE ctrl, /* Control code */\r
+ void *buff /* Buffer to send/receive control data */\r
+)\r
+{\r
+ DRESULT res;\r
+ BYTE n, csd[16];\r
+ WORD cs;\r
+\r
+\r
+ if (disk_status(drv) & STA_NOINIT) /* Check if card is in the socket */\r
+ return RES_NOTRDY;\r
+\r
+ res = RES_ERROR;\r
+ switch (ctrl) {\r
+ case CTRL_SYNC : /* Make sure that no pending write process */\r
+ if (select()) {\r
+ deselect();\r
+ res = RES_OK;\r
+ }\r
+ break;\r
+\r
+ case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */\r
+ if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {\r
+ if ((csd[0] >> 6) == 1) { /* SDC ver 2.00 */\r
+ cs= csd[9] + ((WORD)csd[8] << 8) + 1;\r
+ *(DWORD*)buff = (DWORD)cs << 10;\r
+ } else { /* SDC ver 1.XX or MMC */\r
+ n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;\r
+ cs = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;\r
+ *(DWORD*)buff = (DWORD)cs << (n - 9);\r
+ }\r
+ res = RES_OK;\r
+ }\r
+ break;\r
+\r
+ case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */\r
+ *(DWORD*)buff = 128;\r
+ res = RES_OK;\r
+ break;\r
+\r
+ default:\r
+ res = RES_PARERR;\r
+ }\r
+\r
+ deselect();\r
+\r
+ return res;\r
+}\r
+\r
--- /dev/null
+/**\r
+ * @file ff.c\r
+ * @brief FATファイルシステムドライバの実装。\r
+ */\r
+\r
+/*----------------------------------------------------------------------------/\r
+/ FatFs - FAT file system module R0.08b (C)ChaN, 2011\r
+/-----------------------------------------------------------------------------/\r
+/ FatFs module is a generic FAT file system module for small embedded systems.\r
+/ This is a free software that opened for education, research and commercial\r
+/ developments under license policy of following terms.\r
+/\r
+/ Copyright (C) 2011, ChaN, all right reserved.\r
+/\r
+/ * The FatFs module is a free software and there is NO WARRANTY.\r
+/ * No restriction on use. You can use, modify and redistribute it for\r
+/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.\r
+/ * Redistributions of source code must retain the above copyright notice.\r
+/\r
+/-----------------------------------------------------------------------------/\r
+/ Feb 26,'06 R0.00 Prototype.\r
+/\r
+/ Apr 29,'06 R0.01 First stable version.\r
+/\r
+/ Jun 01,'06 R0.02 Added FAT12 support.\r
+/ Removed unbuffered mode.\r
+/ Fixed a problem on small (<32M) partition.\r
+/ Jun 10,'06 R0.02a Added a configuration option (_FS_MINIMUM).\r
+/\r
+/ Sep 22,'06 R0.03 Added f_rename().\r
+/ Changed option _FS_MINIMUM to _FS_MINIMIZE.\r
+/ Dec 11,'06 R0.03a Improved cluster scan algorithm to write files fast.\r
+/ Fixed f_mkdir() creates incorrect directory on FAT32.\r
+/\r
+/ Feb 04,'07 R0.04 Supported multiple drive system.\r
+/ Changed some interfaces for multiple drive system.\r
+/ Changed f_mountdrv() to f_mount().\r
+/ Added f_mkfs().\r
+/ Apr 01,'07 R0.04a Supported multiple partitions on a physical drive.\r
+/ Added a capability of extending file size to f_lseek().\r
+/ Added minimization level 3.\r
+/ Fixed an endian sensitive code in f_mkfs().\r
+/ May 05,'07 R0.04b Added a configuration option _USE_NTFLAG.\r
+/ Added FSInfo support.\r
+/ Fixed DBCS name can result FR_INVALID_NAME.\r
+/ Fixed short seek (<= csize) collapses the file object.\r
+/\r
+/ Aug 25,'07 R0.05 Changed arguments of f_read(), f_write() and f_mkfs().\r
+/ Fixed f_mkfs() on FAT32 creates incorrect FSInfo.\r
+/ Fixed f_mkdir() on FAT32 creates incorrect directory.\r
+/ Feb 03,'08 R0.05a Added f_truncate() and f_utime().\r
+/ Fixed off by one error at FAT sub-type determination.\r
+/ Fixed btr in f_read() can be mistruncated.\r
+/ Fixed cached sector is not flushed when create and close without write.\r
+/\r
+/ Apr 01,'08 R0.06 Added fputc(), fputs(), fprintf() and fgets().\r
+/ Improved performance of f_lseek() on moving to the same or following cluster.\r
+/\r
+/ Apr 01,'09 R0.07 Merged Tiny-FatFs as a configuration option. (_FS_TINY)\r
+/ Added long file name feature.\r
+/ Added multiple code page feature.\r
+/ Added re-entrancy for multitask operation.\r
+/ Added auto cluster size selection to f_mkfs().\r
+/ Added rewind option to f_readdir().\r
+/ Changed result code of critical errors.\r
+/ Renamed string functions to avoid name collision.\r
+/ Apr 14,'09 R0.07a Separated out OS dependent code on reentrant cfg.\r
+/ Added multiple sector size feature.\r
+/ Jun 21,'09 R0.07c Fixed f_unlink() can return FR_OK on error.\r
+/ Fixed wrong cache control in f_lseek().\r
+/ Added relative path feature.\r
+/ Added f_chdir() and f_chdrive().\r
+/ Added proper case conversion to extended char.\r
+/ Nov 03,'09 R0.07e Separated out configuration options from ff.h to ffconf.h.\r
+/ Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH.\r
+/ Fixed name matching error on the 13 char boundary.\r
+/ Added a configuration option, _LFN_UNICODE.\r
+/ Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.\r
+/\r
+/ May 15,'10 R0.08 Added a memory configuration option. (_USE_LFN = 3)\r
+/ Added file lock feature. (_FS_SHARE)\r
+/ Added fast seek feature. (_USE_FASTSEEK)\r
+/ Changed some types on the API, XCHAR->TCHAR.\r
+/ Changed fname member in the FILINFO structure on Unicode cfg.\r
+/ String functions support UTF-8 encoding files on Unicode cfg.\r
+/ Aug 16,'10 R0.08a Added f_getcwd(). (_FS_RPATH = 2)\r
+/ Added sector erase feature. (_USE_ERASE)\r
+/ Moved file lock semaphore table from fs object to the bss.\r
+/ Fixed a wrong directory entry is created on non-LFN cfg when the given name contains ';'.\r
+/ Fixed f_mkfs() creates wrong FAT32 volume.\r
+/ Jan 15,'11 R0.08b Fast seek feature is also applied to f_read() and f_write().\r
+/ f_lseek() reports required table size on creating CLMP.\r
+/ Extended format syntax of f_printf function.\r
+/ Ignores duplicated directory separators in given path names.\r
+/---------------------------------------------------------------------------*/\r
+\r
+#include "ff.h" /* FatFs configurations and declarations */\r
+#include "diskio_ff.h" /* Declarations of low level disk I/O functions */\r
+\r
+\r
+/*--------------------------------------------------------------------------\r
+\r
+ Module Private Definitions\r
+\r
+---------------------------------------------------------------------------*/\r
+\r
+#if _FATFS != 8237\r
+#error Wrong include file (ff.h).\r
+#endif\r
+\r
+\r
+/* Definitions on sector size */\r
+#if _MAX_SS != 512 && _MAX_SS != 1024 && _MAX_SS != 2048 && _MAX_SS != 4096\r
+#error Wrong sector size.\r
+#endif\r
+#if _MAX_SS != 512\r
+#define SS(fs) ((fs)->ssize) /* Multiple sector size */\r
+#else\r
+#define SS(fs) 512U /* Fixed sector size */\r
+#endif\r
+\r
+\r
+/* Reentrancy related */\r
+#if _FS_REENTRANT\r
+#if _USE_LFN == 1\r
+#error Static LFN work area must not be used in re-entrant configuration.\r
+#endif\r
+#define ENTER_FF(fs) { if (!lock_fs(fs)) return FR_TIMEOUT; }\r
+#define LEAVE_FF(fs, res) { unlock_fs(fs, res); return res; }\r
+#else\r
+#define ENTER_FF(fs)\r
+#define LEAVE_FF(fs, res) return res\r
+#endif\r
+\r
+#define ABORT(fs, res) { fp->flag |= FA__ERROR; LEAVE_FF(fs, res); }\r
+\r
+\r
+/* File shareing feature */\r
+#if _FS_SHARE\r
+#if _FS_READONLY\r
+#error _FS_SHARE must be 0 on read-only cfg.\r
+#endif\r
+typedef struct {\r
+ FATFS *fs; /* File ID 1, volume (NULL:blank entry) */\r
+ DWORD clu; /* File ID 2, directory */\r
+ WORD idx; /* File ID 3, directory index */\r
+ WORD ctr; /* File open counter, 0:none, 0x01..0xFF:read open count, 0x100:write mode */\r
+} FILESEM;\r
+#endif\r
+\r
+\r
+/* Misc definitions */\r
+#define LD_CLUST(dir) (((DWORD)LD_WORD(dir+DIR_FstClusHI)<<16) | LD_WORD(dir+DIR_FstClusLO))\r
+#define ST_CLUST(dir,cl) {ST_WORD(dir+DIR_FstClusLO, cl); ST_WORD(dir+DIR_FstClusHI, (DWORD)cl>>16);}\r
+\r
+\r
+/* DBCS code ranges and SBCS extend char conversion table */\r
+\r
+#if _CODE_PAGE == 932 /* Japanese Shift-JIS */\r
+#define _DF1S 0x81 /* DBC 1st byte range 1 start */\r
+#define _DF1E 0x9F /* DBC 1st byte range 1 end */\r
+#define _DF2S 0xE0 /* DBC 1st byte range 2 start */\r
+#define _DF2E 0xFC /* DBC 1st byte range 2 end */\r
+#define _DS1S 0x40 /* DBC 2nd byte range 1 start */\r
+#define _DS1E 0x7E /* DBC 2nd byte range 1 end */\r
+#define _DS2S 0x80 /* DBC 2nd byte range 2 start */\r
+#define _DS2E 0xFC /* DBC 2nd byte range 2 end */\r
+\r
+#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */\r
+#define _DF1S 0x81\r
+#define _DF1E 0xFE\r
+#define _DS1S 0x40\r
+#define _DS1E 0x7E\r
+#define _DS2S 0x80\r
+#define _DS2E 0xFE\r
+\r
+#elif _CODE_PAGE == 949 /* Korean */\r
+#define _DF1S 0x81\r
+#define _DF1E 0xFE\r
+#define _DS1S 0x41\r
+#define _DS1E 0x5A\r
+#define _DS2S 0x61\r
+#define _DS2E 0x7A\r
+#define _DS3S 0x81\r
+#define _DS3E 0xFE\r
+\r
+#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */\r
+#define _DF1S 0x81\r
+#define _DF1E 0xFE\r
+#define _DS1S 0x40\r
+#define _DS1E 0x7E\r
+#define _DS2S 0xA1\r
+#define _DS2E 0xFE\r
+\r
+#elif _CODE_PAGE == 437 /* U.S. (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 720 /* Arabic (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 737 /* Greek (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \\r
+ 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 775 /* Baltic (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \\r
+ 0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \\r
+ 0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \\r
+ 0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 857 /* Turkish (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \\r
+ 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 862 /* Hebrew (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 866 /* Russian (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 1250 /* Central Europe (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \\r
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}\r
+\r
+#elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \\r
+ 0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF}\r
+\r
+#elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \\r
+ 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}\r
+\r
+#elif _CODE_PAGE == 1253 /* Greek (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \\r
+ 0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF}\r
+\r
+#elif _CODE_PAGE == 1254 /* Turkish (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}\r
+\r
+#elif _CODE_PAGE == 1255 /* Hebrew (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 1256 /* Arabic (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 1257 /* Baltic (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}\r
+\r
+#elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \\r
+ 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F}\r
+\r
+#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */\r
+#if _USE_LFN\r
+#error Cannot use LFN feature without valid code page.\r
+#endif\r
+#define _DF1S 0\r
+\r
+#else\r
+#error Unknown code page\r
+\r
+#endif\r
+\r
+\r
+/* Character code support macros */\r
+#define IsUpper(c) (((c)>='A')&&((c)<='Z'))\r
+#define IsLower(c) (((c)>='a')&&((c)<='z'))\r
+#define IsDigit(c) (((c)>='0')&&((c)<='9'))\r
+\r
+#if _DF1S /* Code page is DBCS */\r
+\r
+#ifdef _DF2S /* Two 1st byte areas */\r
+#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E))\r
+#else /* One 1st byte area */\r
+#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E)\r
+#endif\r
+\r
+#ifdef _DS3S /* Three 2nd byte areas */\r
+#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E))\r
+#else /* Two 2nd byte areas */\r
+#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E))\r
+#endif\r
+\r
+#else /* Code page is SBCS */\r
+\r
+#define IsDBCS1(c) 0\r
+#define IsDBCS2(c) 0\r
+\r
+#endif /* _DF1S */\r
+\r
+\r
+/* Name status flags */\r
+#define NS 11 /* Index of name status byte in fn[] */\r
+#define NS_LOSS 0x01 /* Out of 8.3 format */\r
+#define NS_LFN 0x02 /* Force to create LFN entry */\r
+#define NS_LAST 0x04 /* Last segment */\r
+#define NS_BODY 0x08 /* Lower case flag (body) */\r
+#define NS_EXT 0x10 /* Lower case flag (ext) */\r
+#define NS_DOT 0x20 /* Dot entry */\r
+\r
+\r
+/* FAT sub-type boundaries */\r
+/* Note that the FAT spec by Microsoft says 4085 but Windows works with 4087! */\r
+#define MIN_FAT16 4086 /* Minimum number of clusters for FAT16 */\r
+#define MIN_FAT32 65526 /* Minimum number of clusters for FAT32 */\r
+\r
+\r
+/* FatFs refers the members in the FAT structures as byte array instead of\r
+/ structure member because the structure is not binary compatible between\r
+/ different platforms */\r
+\r
+#define BS_jmpBoot 0 /* Jump instruction (3) */\r
+#define BS_OEMName 3 /* OEM name (8) */\r
+#define BPB_BytsPerSec 11 /* Sector size [byte] (2) */\r
+#define BPB_SecPerClus 13 /* Cluster size [sector] (1) */\r
+#define BPB_RsvdSecCnt 14 /* Size of reserved area [sector] (2) */\r
+#define BPB_NumFATs 16 /* Number of FAT copies (1) */\r
+#define BPB_RootEntCnt 17 /* Number of root dir entries for FAT12/16 (2) */\r
+#define BPB_TotSec16 19 /* Volume size [sector] (2) */\r
+#define BPB_Media 21 /* Media descriptor (1) */\r
+#define BPB_FATSz16 22 /* FAT size [sector] (2) */\r
+#define BPB_SecPerTrk 24 /* Track size [sector] (2) */\r
+#define BPB_NumHeads 26 /* Number of heads (2) */\r
+#define BPB_HiddSec 28 /* Number of special hidden sectors (4) */\r
+#define BPB_TotSec32 32 /* Volume size [sector] (4) */\r
+#define BS_DrvNum 36 /* Physical drive number (2) */\r
+#define BS_BootSig 38 /* Extended boot signature (1) */\r
+#define BS_VolID 39 /* Volume serial number (4) */\r
+#define BS_VolLab 43 /* Volume label (8) */\r
+#define BS_FilSysType 54 /* File system type (1) */\r
+#define BPB_FATSz32 36 /* FAT size [sector] (4) */\r
+#define BPB_ExtFlags 40 /* Extended flags (2) */\r
+#define BPB_FSVer 42 /* File system version (2) */\r
+#define BPB_RootClus 44 /* Root dir first cluster (4) */\r
+#define BPB_FSInfo 48 /* Offset of FSInfo sector (2) */\r
+#define BPB_BkBootSec 50 /* Offset of backup boot sectot (2) */\r
+#define BS_DrvNum32 64 /* Physical drive number (2) */\r
+#define BS_BootSig32 66 /* Extended boot signature (1) */\r
+#define BS_VolID32 67 /* Volume serial number (4) */\r
+#define BS_VolLab32 71 /* Volume label (8) */\r
+#define BS_FilSysType32 82 /* File system type (1) */\r
+#define FSI_LeadSig 0 /* FSI: Leading signature (4) */\r
+#define FSI_StrucSig 484 /* FSI: Structure signature (4) */\r
+#define FSI_Free_Count 488 /* FSI: Number of free clusters (4) */\r
+#define FSI_Nxt_Free 492 /* FSI: Last allocated cluster (4) */\r
+#define MBR_Table 446 /* MBR: Partition table offset (2) */\r
+#define SZ_PTE 16 /* MBR: Size of a partition table entry */\r
+#define BS_55AA 510 /* Boot sector signature (2) */\r
+\r
+#define DIR_Name 0 /* Short file name (11) */\r
+#define DIR_Attr 11 /* Attribute (1) */\r
+#define DIR_NTres 12 /* NT flag (1) */\r
+#define DIR_CrtTime 14 /* Created time (2) */\r
+#define DIR_CrtDate 16 /* Created date (2) */\r
+#define DIR_FstClusHI 20 /* Higher 16-bit of first cluster (2) */\r
+#define DIR_WrtTime 22 /* Modified time (2) */\r
+#define DIR_WrtDate 24 /* Modified date (2) */\r
+#define DIR_FstClusLO 26 /* Lower 16-bit of first cluster (2) */\r
+#define DIR_FileSize 28 /* File size (4) */\r
+#define LDIR_Ord 0 /* LFN entry order and LLE flag (1) */\r
+#define LDIR_Attr 11 /* LFN attribute (1) */\r
+#define LDIR_Type 12 /* LFN type (1) */\r
+#define LDIR_Chksum 13 /* Sum of corresponding SFN entry */\r
+#define LDIR_FstClusLO 26 /* Filled by zero (0) */\r
+#define SZ_DIR 32 /* Size of a directory entry */\r
+#define LLE 0x40 /* Last long entry flag in LDIR_Ord */\r
+#define DDE 0xE5 /* Deleted directory enrty mark in DIR_Name[0] */\r
+#define NDDE 0x05 /* Replacement of a character collides with DDE */\r
+\r
+\r
+/*------------------------------------------------------------*/\r
+/* Work area */\r
+\r
+#if _VOLUMES\r
+static\r
+FATFS *FatFs[_VOLUMES]; /* Pointer to the file system objects (logical drives) */\r
+#else\r
+#error Number of drives must not be 0.\r
+#endif\r
+\r
+static\r
+WORD Fsid; /* File system mount ID */\r
+\r
+#if _FS_RPATH\r
+static\r
+BYTE CurrVol; /* Current drive */\r
+#endif\r
+\r
+#if _FS_SHARE\r
+static\r
+FILESEM Files[_FS_SHARE]; /* File lock semaphores */\r
+#endif\r
+\r
+#if _USE_LFN == 0 /* No LFN */\r
+#define DEF_NAMEBUF BYTE sfn[12]\r
+#define INIT_BUF(dobj) (dobj).fn = sfn\r
+#define FREE_BUF()\r
+\r
+#elif _USE_LFN == 1 /* LFN with static LFN working buffer */\r
+static WCHAR LfnBuf[_MAX_LFN+1];\r
+#define DEF_NAMEBUF BYTE sfn[12]\r
+#define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = LfnBuf; }\r
+#define FREE_BUF()\r
+\r
+#elif _USE_LFN == 2 /* LFN with dynamic LFN working buffer on the stack */\r
+#define DEF_NAMEBUF BYTE sfn[12]; WCHAR lbuf[_MAX_LFN+1]\r
+#define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = lbuf; }\r
+#define FREE_BUF()\r
+\r
+#elif _USE_LFN == 3 /* LFN with dynamic LFN working buffer on the heap */\r
+#define DEF_NAMEBUF BYTE sfn[12]; WCHAR *lfn\r
+#define INIT_BUF(dobj) { lfn = ff_memalloc((_MAX_LFN + 1) * 2); \\r
+ if (!lfn) LEAVE_FF((dobj).fs, FR_NOT_ENOUGH_CORE); \\r
+ (dobj).lfn = lfn; (dobj).fn = sfn; }\r
+#define FREE_BUF() ff_memfree(lfn)\r
+\r
+#else\r
+#error Wrong LFN configuration.\r
+#endif\r
+\r
+\r
+\r
+\r
+/*--------------------------------------------------------------------------\r
+\r
+ Module Private Functions\r
+\r
+---------------------------------------------------------------------------*/\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* String functions */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+/* Copy memory to memory */\r
+static\r
+void mem_cpy (void* dst, const void* src, UINT cnt) {\r
+ BYTE *d = (BYTE*)dst;\r
+ const BYTE *s = (const BYTE*)src;\r
+\r
+#if _WORD_ACCESS == 1\r
+ while (cnt >= sizeof(int)) {\r
+ *(int*)d = *(int*)s;\r
+ d += sizeof(int); s += sizeof(int);\r
+ cnt -= sizeof(int);\r
+ }\r
+#endif\r
+ while (cnt--)\r
+ *d++ = *s++;\r
+}\r
+\r
+/* Fill memory */\r
+static\r
+void mem_set (void* dst, int val, UINT cnt) {\r
+ BYTE *d = (BYTE*)dst;\r
+\r
+ while (cnt--)\r
+ *d++ = (BYTE)val;\r
+}\r
+\r
+/* Compare memory to memory */\r
+static\r
+int mem_cmp (const void* dst, const void* src, UINT cnt) {\r
+ const BYTE *d = (const BYTE *)dst, *s = (const BYTE *)src;\r
+ int r = 0;\r
+\r
+ while (cnt-- && (r = *d++ - *s++) == 0) ;\r
+ return r;\r
+}\r
+\r
+/* Check if chr is contained in the string */\r
+static\r
+int chk_chr (const char* str, int chr) {\r
+ while (*str && *str != chr) str++;\r
+ return *str;\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Request/Release grant to access the volume */\r
+/*-----------------------------------------------------------------------*/\r
+#if _FS_REENTRANT\r
+\r
+static\r
+int lock_fs (\r
+ FATFS *fs /* File system object */\r
+)\r
+{\r
+ return ff_req_grant(fs->sobj);\r
+}\r
+\r
+\r
+static\r
+void unlock_fs (\r
+ FATFS *fs, /* File system object */\r
+ FRESULT res /* Result code to be returned */\r
+)\r
+{\r
+ if (res != FR_NOT_ENABLED &&\r
+ res != FR_INVALID_DRIVE &&\r
+ res != FR_INVALID_OBJECT &&\r
+ res != FR_TIMEOUT) {\r
+ ff_rel_grant(fs->sobj);\r
+ }\r
+}\r
+#endif\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* File shareing control functions */\r
+/*-----------------------------------------------------------------------*/\r
+#if _FS_SHARE\r
+\r
+static\r
+FRESULT chk_lock ( /* Check if the file can be accessed */\r
+ DIR* dj, /* Directory object pointing the file to be checked */\r
+ int acc /* Desired access (0:Read, 1:Write, 2:Delete/Rename) */\r
+)\r
+{\r
+ UINT i, be;\r
+\r
+ /* Search file semaphore table */\r
+ for (i = be = 0; i < _FS_SHARE; i++) {\r
+ if (Files[i].fs) { /* Existing entry */\r
+ if (Files[i].fs == dj->fs && /* Check if the file matched with an open file */\r
+ Files[i].clu == dj->sclust &&\r
+ Files[i].idx == dj->index) break;\r
+ } else { /* Blank entry */\r
+ be++;\r
+ }\r
+ }\r
+ if (i == _FS_SHARE) /* The file is not opened */\r
+ return (be || acc == 2) ? FR_OK : FR_TOO_MANY_OPEN_FILES; /* Is there a blank entry for new file? */\r
+\r
+ /* The file has been opened. Reject any open against writing file and all write mode open */\r
+ return (acc || Files[i].ctr == 0x100) ? FR_LOCKED : FR_OK;\r
+}\r
+\r
+\r
+static\r
+int enq_lock ( /* Check if an entry is available for a new file */\r
+ FATFS* fs /* File system object */\r
+)\r
+{\r
+ UINT i;\r
+\r
+ for (i = 0; i < _FS_SHARE && Files[i].fs; i++) ;\r
+ return (i == _FS_SHARE) ? 0 : 1;\r
+}\r
+\r
+\r
+static\r
+UINT inc_lock ( /* Increment file open counter and returns its index (0:int error) */\r
+ DIR* dj, /* Directory object pointing the file to register or increment */\r
+ int acc /* Desired access mode (0:Read, !0:Write) */\r
+)\r
+{\r
+ UINT i;\r
+\r
+\r
+ for (i = 0; i < _FS_SHARE; i++) { /* Find the file */\r
+ if (Files[i].fs == dj->fs &&\r
+ Files[i].clu == dj->sclust &&\r
+ Files[i].idx == dj->index) break;\r
+ }\r
+\r
+ if (i == _FS_SHARE) { /* Not opened. Register it as new. */\r
+ for (i = 0; i < _FS_SHARE && Files[i].fs; i++) ;\r
+ if (i == _FS_SHARE) return 0; /* No space to register (int err) */\r
+ Files[i].fs = dj->fs;\r
+ Files[i].clu = dj->sclust;\r
+ Files[i].idx = dj->index;\r
+ Files[i].ctr = 0;\r
+ }\r
+\r
+ if (acc && Files[i].ctr) return 0; /* Access violation (int err) */\r
+\r
+ Files[i].ctr = acc ? 0x100 : Files[i].ctr + 1; /* Set semaphore value */\r
+\r
+ return i + 1;\r
+}\r
+\r
+\r
+static\r
+FRESULT dec_lock ( /* Decrement file open counter */\r
+ UINT i /* Semaphore index */\r
+)\r
+{\r
+ WORD n;\r
+ FRESULT res;\r
+\r
+\r
+ if (--i < _FS_SHARE) {\r
+ n = Files[i].ctr;\r
+ if (n == 0x100) n = 0;\r
+ if (n) n--;\r
+ Files[i].ctr = n;\r
+ if (!n) Files[i].fs = 0;\r
+ res = FR_OK;\r
+ } else {\r
+ res = FR_INT_ERR;\r
+ }\r
+ return res;\r
+}\r
+\r
+\r
+static\r
+void clear_lock ( /* Clear lock entries of the volume */\r
+ FATFS *fs\r
+)\r
+{\r
+ UINT i;\r
+\r
+ for (i = 0; i < _FS_SHARE; i++) {\r
+ if (Files[i].fs == fs) Files[i].fs = 0;\r
+ }\r
+}\r
+#endif\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Change window offset */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+FRESULT move_window (\r
+ FATFS *fs, /* File system object */\r
+ DWORD sector /* Sector number to make appearance in the fs->win[] */\r
+) /* Move to zero only writes back dirty window */\r
+{\r
+ DWORD wsect;\r
+\r
+\r
+ wsect = fs->winsect;\r
+ if (wsect != sector) { /* Changed current window */\r
+#if !_FS_READONLY\r
+ if (fs->wflag) { /* Write back dirty window if needed */\r
+ if (disk_write(fs->drv, fs->win, wsect, 1) != RES_OK)\r
+ return FR_DISK_ERR;\r
+ fs->wflag = 0;\r
+ if (wsect < (fs->fatbase + fs->fsize)) { /* In FAT area */\r
+ BYTE nf;\r
+ for (nf = fs->n_fats; nf > 1; nf--) { /* Reflect the change to all FAT copies */\r
+ wsect += fs->fsize;\r
+ disk_write(fs->drv, fs->win, wsect, 1);\r
+ }\r
+ }\r
+ }\r
+#endif\r
+ if (sector) {\r
+ if (disk_read(fs->drv, fs->win, sector, 1) != RES_OK)\r
+ return FR_DISK_ERR;\r
+ fs->winsect = sector;\r
+ }\r
+ }\r
+\r
+ return FR_OK;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Clean-up cached data */\r
+/*-----------------------------------------------------------------------*/\r
+#if !_FS_READONLY\r
+static\r
+FRESULT sync ( /* FR_OK: successful, FR_DISK_ERR: failed */\r
+ FATFS *fs /* File system object */\r
+)\r
+{\r
+ FRESULT res;\r
+\r
+\r
+ res = move_window(fs, 0);\r
+ if (res == FR_OK) {\r
+ /* Update FSInfo sector if needed */\r
+ if (fs->fs_type == FS_FAT32 && fs->fsi_flag) {\r
+ fs->winsect = 0;\r
+ /* Create FSInfo structure */\r
+ mem_set(fs->win, 0, 512);\r
+ ST_WORD(fs->win+BS_55AA, 0xAA55);\r
+ ST_DWORD(fs->win+FSI_LeadSig, 0x41615252);\r
+ ST_DWORD(fs->win+FSI_StrucSig, 0x61417272);\r
+ ST_DWORD(fs->win+FSI_Free_Count, fs->free_clust);\r
+ ST_DWORD(fs->win+FSI_Nxt_Free, fs->last_clust);\r
+ /* Write it into the FSInfo sector */\r
+ disk_write(fs->drv, fs->win, fs->fsi_sector, 1);\r
+ fs->fsi_flag = 0;\r
+ }\r
+ /* Make sure that no pending write process in the physical drive */\r
+ if (disk_ioctl(fs->drv, CTRL_SYNC, (void*)0) != RES_OK)\r
+ res = FR_DISK_ERR;\r
+ }\r
+\r
+ return res;\r
+}\r
+#endif\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Get sector# from cluster# */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+\r
+DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */\r
+ FATFS *fs, /* File system object */\r
+ DWORD clst /* Cluster# to be converted */\r
+)\r
+{\r
+ clst -= 2;\r
+ if (clst >= (fs->n_fatent - 2)) return 0; /* Invalid cluster# */\r
+ return clst * fs->csize + fs->database;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* FAT access - Read value of a FAT entry */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+\r
+DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, Else:Cluster status */\r
+ FATFS *fs, /* File system object */\r
+ DWORD clst /* Cluster# to get the link information */\r
+)\r
+{\r
+ UINT wc, bc;\r
+ BYTE *p;\r
+\r
+\r
+ if (clst < 2 || clst >= fs->n_fatent) /* Chack range */\r
+ return 1;\r
+\r
+ switch (fs->fs_type) {\r
+ case FS_FAT12 :\r
+ bc = (UINT)clst; bc += bc / 2;\r
+ if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break;\r
+ wc = fs->win[bc % SS(fs)]; bc++;\r
+ if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break;\r
+ wc |= fs->win[bc % SS(fs)] << 8;\r
+ return (clst & 1) ? (wc >> 4) : (wc & 0xFFF);\r
+\r
+ case FS_FAT16 :\r
+ if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)))) break;\r
+ p = &fs->win[clst * 2 % SS(fs)];\r
+ return LD_WORD(p);\r
+\r
+ case FS_FAT32 :\r
+ if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)))) break;\r
+ p = &fs->win[clst * 4 % SS(fs)];\r
+ return LD_DWORD(p) & 0x0FFFFFFF;\r
+ }\r
+\r
+ return 0xFFFFFFFF; /* An error occurred at the disk I/O layer */\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* FAT access - Change value of a FAT entry */\r
+/*-----------------------------------------------------------------------*/\r
+#if !_FS_READONLY\r
+\r
+FRESULT put_fat (\r
+ FATFS *fs, /* File system object */\r
+ DWORD clst, /* Cluster# to be changed in range of 2 to fs->n_fatent - 1 */\r
+ DWORD val /* New value to mark the cluster */\r
+)\r
+{\r
+ UINT bc;\r
+ BYTE *p;\r
+ FRESULT res;\r
+\r
+\r
+ if (clst < 2 || clst >= fs->n_fatent) { /* Check range */\r
+ res = FR_INT_ERR;\r
+\r
+ } else {\r
+ switch (fs->fs_type) {\r
+ case FS_FAT12 :\r
+ bc = clst; bc += bc / 2;\r
+ res = move_window(fs, fs->fatbase + (bc / SS(fs)));\r
+ if (res != FR_OK) break;\r
+ p = &fs->win[bc % SS(fs)];\r
+ *p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val;\r
+ bc++;\r
+ fs->wflag = 1;\r
+ res = move_window(fs, fs->fatbase + (bc / SS(fs)));\r
+ if (res != FR_OK) break;\r
+ p = &fs->win[bc % SS(fs)];\r
+ *p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F));\r
+ break;\r
+\r
+ case FS_FAT16 :\r
+ res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)));\r
+ if (res != FR_OK) break;\r
+ p = &fs->win[clst * 2 % SS(fs)];\r
+ ST_WORD(p, (WORD)val);\r
+ break;\r
+\r
+ case FS_FAT32 :\r
+ res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)));\r
+ if (res != FR_OK) break;\r
+ p = &fs->win[clst * 4 % SS(fs)];\r
+ val |= LD_DWORD(p) & 0xF0000000;\r
+ ST_DWORD(p, val);\r
+ break;\r
+\r
+ default :\r
+ res = FR_INT_ERR;\r
+ }\r
+ fs->wflag = 1;\r
+ }\r
+\r
+ return res;\r
+}\r
+#endif /* !_FS_READONLY */\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* FAT handling - Remove a cluster chain */\r
+/*-----------------------------------------------------------------------*/\r
+#if !_FS_READONLY\r
+static\r
+FRESULT remove_chain (\r
+ FATFS *fs, /* File system object */\r
+ DWORD clst /* Cluster# to remove a chain from */\r
+)\r
+{\r
+ FRESULT res;\r
+ DWORD nxt;\r
+#if _USE_ERASE\r
+ DWORD scl = clst, ecl = clst, resion[2];\r
+#endif\r
+\r
+ if (clst < 2 || clst >= fs->n_fatent) { /* Check range */\r
+ res = FR_INT_ERR;\r
+\r
+ } else {\r
+ res = FR_OK;\r
+ while (clst < fs->n_fatent) { /* Not a last link? */\r
+ nxt = get_fat(fs, clst); /* Get cluster status */\r
+ if (nxt == 0) break; /* Empty cluster? */\r
+ if (nxt == 1) { res = FR_INT_ERR; break; } /* Internal error? */\r
+ if (nxt == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } /* Disk error? */\r
+ res = put_fat(fs, clst, 0); /* Mark the cluster "empty" */\r
+ if (res != FR_OK) break;\r
+ if (fs->free_clust != 0xFFFFFFFF) { /* Update FSInfo */\r
+ fs->free_clust++;\r
+ fs->fsi_flag = 1;\r
+ }\r
+#if _USE_ERASE\r
+ if (ecl + 1 == nxt) { /* Next cluster is contiguous */\r
+ ecl = nxt;\r
+ } else { /* End of contiguous clusters */ \r
+ resion[0] = clust2sect(fs, scl); /* Start sector */\r
+ resion[1] = clust2sect(fs, ecl) + fs->csize - 1; /* End sector */\r
+ disk_ioctl(fs->drv, CTRL_ERASE_SECTOR, resion); /* Erase the block */\r
+ scl = ecl = nxt;\r
+ }\r
+#endif\r
+ clst = nxt; /* Next cluster */\r
+ }\r
+ }\r
+\r
+ return res;\r
+}\r
+#endif\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* FAT handling - Stretch or Create a cluster chain */\r
+/*-----------------------------------------------------------------------*/\r
+#if !_FS_READONLY\r
+static\r
+DWORD create_chain ( /* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk error, >=2:New cluster# */\r
+ FATFS *fs, /* File system object */\r
+ DWORD clst /* Cluster# to stretch. 0 means create a new chain. */\r
+)\r
+{\r
+ DWORD cs, ncl, scl;\r
+ FRESULT res;\r
+\r
+\r
+ if (clst == 0) { /* Create a new chain */\r
+ scl = fs->last_clust; /* Get suggested start point */\r
+ if (!scl || scl >= fs->n_fatent) scl = 1;\r
+ }\r
+ else { /* Stretch the current chain */\r
+ cs = get_fat(fs, clst); /* Check the cluster status */\r
+ if (cs < 2) return 1; /* It is an invalid cluster */\r
+ if (cs < fs->n_fatent) return cs; /* It is already followed by next cluster */\r
+ scl = clst;\r
+ }\r
+\r
+ ncl = scl; /* Start cluster */\r
+ for (;;) {\r
+ ncl++; /* Next cluster */\r
+ if (ncl >= fs->n_fatent) { /* Wrap around */\r
+ ncl = 2;\r
+ if (ncl > scl) return 0; /* No free cluster */\r
+ }\r
+ cs = get_fat(fs, ncl); /* Get the cluster status */\r
+ if (cs == 0) break; /* Found a free cluster */\r
+ if (cs == 0xFFFFFFFF || cs == 1)/* An error occurred */\r
+ return cs;\r
+ if (ncl == scl) return 0; /* No free cluster */\r
+ }\r
+\r
+ res = put_fat(fs, ncl, 0x0FFFFFFF); /* Mark the new cluster "last link" */\r
+ if (res == FR_OK && clst != 0) {\r
+ res = put_fat(fs, clst, ncl); /* Link it to the previous one if needed */\r
+ }\r
+ if (res == FR_OK) {\r
+ fs->last_clust = ncl; /* Update FSINFO */\r
+ if (fs->free_clust != 0xFFFFFFFF) {\r
+ fs->free_clust--;\r
+ fs->fsi_flag = 1;\r
+ }\r
+ } else {\r
+ ncl = (res == FR_DISK_ERR) ? 0xFFFFFFFF : 1;\r
+ }\r
+\r
+ return ncl; /* Return new cluster number or error code */\r
+}\r
+#endif /* !_FS_READONLY */\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* FAT handling - Convert offset into cluster with link map table */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+#if _USE_FASTSEEK\r
+static\r
+DWORD clmt_clust ( /* <2:Error, >=2:Cluster number */\r
+ FIL* fp, /* Pointer to the file object */\r
+ DWORD ofs /* File offset to be converted to cluster# */\r
+)\r
+{\r
+ DWORD cl, ncl, *tbl;\r
+\r
+\r
+ tbl = fp->cltbl + 1; /* Top of CLMT */\r
+ cl = ofs / SS(fp->fs) / fp->fs->csize; /* Cluster order from top of the file */\r
+ for (;;) {\r
+ ncl = *tbl++; /* Number of cluters in the fragment */\r
+ if (!ncl) return 0; /* End of table? (error) */\r
+ if (cl < ncl) break; /* In this fragment? */\r
+ cl -= ncl; tbl++; /* Next fragment */\r
+ }\r
+ return cl + *tbl; /* Return the cluster number */\r
+}\r
+#endif /* _USE_FASTSEEK */\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Directory handling - Set directory index */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+FRESULT dir_sdi (\r
+ DIR *dj, /* Pointer to directory object */\r
+ WORD idx /* Directory index number */\r
+)\r
+{\r
+ DWORD clst;\r
+ WORD ic;\r
+\r
+\r
+ dj->index = idx;\r
+ clst = dj->sclust;\r
+ if (clst == 1 || clst >= dj->fs->n_fatent) /* Check start cluster range */\r
+ return FR_INT_ERR;\r
+ if (!clst && dj->fs->fs_type == FS_FAT32) /* Replace cluster# 0 with root cluster# if in FAT32 */\r
+ clst = dj->fs->dirbase;\r
+\r
+ if (clst == 0) { /* Static table (root-dir in FAT12/16) */\r
+ dj->clust = clst;\r
+ if (idx >= dj->fs->n_rootdir) /* Index is out of range */\r
+ return FR_INT_ERR;\r
+ dj->sect = dj->fs->dirbase + idx / (SS(dj->fs) / SZ_DIR); /* Sector# */\r
+ }\r
+ else { /* Dynamic table (sub-dirs or root-dir in FAT32) */\r
+ ic = SS(dj->fs) / SZ_DIR * dj->fs->csize; /* Entries per cluster */\r
+ while (idx >= ic) { /* Follow cluster chain */\r
+ clst = get_fat(dj->fs, clst); /* Get next cluster */\r
+ if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */\r
+ if (clst < 2 || clst >= dj->fs->n_fatent) /* Reached to end of table or int error */\r
+ return FR_INT_ERR;\r
+ idx -= ic;\r
+ }\r
+ dj->clust = clst;\r
+ dj->sect = clust2sect(dj->fs, clst) + idx / (SS(dj->fs) / SZ_DIR); /* Sector# */\r
+ }\r
+\r
+ dj->dir = dj->fs->win + (idx % (SS(dj->fs) / SZ_DIR)) * SZ_DIR; /* Ptr to the entry in the sector */\r
+\r
+ return FR_OK; /* Seek succeeded */\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Directory handling - Move directory index next */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:EOT and could not stretch */\r
+ DIR *dj, /* Pointer to directory object */\r
+ int stretch /* 0: Do not stretch table, 1: Stretch table if needed */\r
+)\r
+{\r
+ DWORD clst;\r
+ WORD i;\r
+\r
+\r
+ i = dj->index + 1;\r
+ if (!i || !dj->sect) /* Report EOT when index has reached 65535 */\r
+ return FR_NO_FILE;\r
+\r
+ if (!(i % (SS(dj->fs) / SZ_DIR))) { /* Sector changed? */\r
+ dj->sect++; /* Next sector */\r
+\r
+ if (dj->clust == 0) { /* Static table */\r
+ if (i >= dj->fs->n_rootdir) /* Report EOT when end of table */\r
+ return FR_NO_FILE;\r
+ }\r
+ else { /* Dynamic table */\r
+ if (((i / (SS(dj->fs) / SZ_DIR)) & (dj->fs->csize - 1)) == 0) { /* Cluster changed? */\r
+ clst = get_fat(dj->fs, dj->clust); /* Get next cluster */\r
+ if (clst <= 1) return FR_INT_ERR;\r
+ if (clst == 0xFFFFFFFF) return FR_DISK_ERR;\r
+ if (clst >= dj->fs->n_fatent) { /* When it reached end of dynamic table */\r
+#if !_FS_READONLY\r
+ BYTE c;\r
+ if (!stretch) return FR_NO_FILE; /* When do not stretch, report EOT */\r
+ clst = create_chain(dj->fs, dj->clust); /* Stretch cluster chain */\r
+ if (clst == 0) return FR_DENIED; /* No free cluster */\r
+ if (clst == 1) return FR_INT_ERR;\r
+ if (clst == 0xFFFFFFFF) return FR_DISK_ERR;\r
+ /* Clean-up stretched table */\r
+ if (move_window(dj->fs, 0)) return FR_DISK_ERR; /* Flush active window */\r
+ mem_set(dj->fs->win, 0, SS(dj->fs)); /* Clear window buffer */\r
+ dj->fs->winsect = clust2sect(dj->fs, clst); /* Cluster start sector */\r
+ for (c = 0; c < dj->fs->csize; c++) { /* Fill the new cluster with 0 */\r
+ dj->fs->wflag = 1;\r
+ if (move_window(dj->fs, 0)) return FR_DISK_ERR;\r
+ dj->fs->winsect++;\r
+ }\r
+ dj->fs->winsect -= c; /* Rewind window address */\r
+#else\r
+ return FR_NO_FILE; /* Report EOT */\r
+#endif\r
+ }\r
+ dj->clust = clst; /* Initialize data for new cluster */\r
+ dj->sect = clust2sect(dj->fs, clst);\r
+ }\r
+ }\r
+ }\r
+\r
+ dj->index = i;\r
+ dj->dir = dj->fs->win + (i % (SS(dj->fs) / SZ_DIR)) * SZ_DIR;\r
+\r
+ return FR_OK;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* LFN handling - Test/Pick/Fit an LFN segment from/to directory entry */\r
+/*-----------------------------------------------------------------------*/\r
+#if _USE_LFN\r
+static\r
+const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30}; /* Offset of LFN chars in the directory entry */\r
+\r
+\r
+static\r
+int cmp_lfn ( /* 1:Matched, 0:Not matched */\r
+ WCHAR *lfnbuf, /* Pointer to the LFN to be compared */\r
+ BYTE *dir /* Pointer to the directory entry containing a part of LFN */\r
+)\r
+{\r
+ UINT i, s;\r
+ WCHAR wc, uc;\r
+\r
+\r
+ i = ((dir[LDIR_Ord] & ~LLE) - 1) * 13; /* Get offset in the LFN buffer */\r
+ s = 0; wc = 1;\r
+ do {\r
+ uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */\r
+ if (wc) { /* Last char has not been processed */\r
+ wc = ff_wtoupper(uc); /* Convert it to upper case */\r
+ if (i >= _MAX_LFN || wc != ff_wtoupper(lfnbuf[i++])) /* Compare it */\r
+ return 0; /* Not matched */\r
+ } else {\r
+ if (uc != 0xFFFF) return 0; /* Check filler */\r
+ }\r
+ } while (++s < 13); /* Repeat until all chars in the entry are checked */\r
+\r
+ if ((dir[LDIR_Ord] & LLE) && wc && lfnbuf[i]) /* Last segment matched but different length */\r
+ return 0;\r
+\r
+ return 1; /* The part of LFN matched */\r
+}\r
+\r
+\r
+\r
+static\r
+int pick_lfn ( /* 1:Succeeded, 0:Buffer overflow */\r
+ WCHAR *lfnbuf, /* Pointer to the Unicode-LFN buffer */\r
+ BYTE *dir /* Pointer to the directory entry */\r
+)\r
+{\r
+ UINT i, s;\r
+ WCHAR wc, uc;\r
+\r
+\r
+ i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13; /* Offset in the LFN buffer */\r
+\r
+ s = 0; wc = 1;\r
+ do {\r
+ uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */\r
+ if (wc) { /* Last char has not been processed */\r
+ if (i >= _MAX_LFN) return 0; /* Buffer overflow? */\r
+ lfnbuf[i++] = wc = uc; /* Store it */\r
+ } else {\r
+ if (uc != 0xFFFF) return 0; /* Check filler */\r
+ }\r
+ } while (++s < 13); /* Read all character in the entry */\r
+\r
+ if (dir[LDIR_Ord] & LLE) { /* Put terminator if it is the last LFN part */\r
+ if (i >= _MAX_LFN) return 0; /* Buffer overflow? */\r
+ lfnbuf[i] = 0;\r
+ }\r
+\r
+ return 1;\r
+}\r
+\r
+\r
+#if !_FS_READONLY\r
+static\r
+void fit_lfn (\r
+ const WCHAR *lfnbuf, /* Pointer to the LFN buffer */\r
+ BYTE *dir, /* Pointer to the directory entry */\r
+ BYTE ord, /* LFN order (1-20) */\r
+ BYTE sum /* SFN sum */\r
+)\r
+{\r
+ UINT i, s;\r
+ WCHAR wc;\r
+\r
+\r
+ dir[LDIR_Chksum] = sum; /* Set check sum */\r
+ dir[LDIR_Attr] = AM_LFN; /* Set attribute. LFN entry */\r
+ dir[LDIR_Type] = 0;\r
+ ST_WORD(dir+LDIR_FstClusLO, 0);\r
+\r
+ i = (ord - 1) * 13; /* Get offset in the LFN buffer */\r
+ s = wc = 0;\r
+ do {\r
+ if (wc != 0xFFFF) wc = lfnbuf[i++]; /* Get an effective char */\r
+ ST_WORD(dir+LfnOfs[s], wc); /* Put it */\r
+ if (!wc) wc = 0xFFFF; /* Padding chars following last char */\r
+ } while (++s < 13);\r
+ if (wc == 0xFFFF || !lfnbuf[i]) ord |= LLE; /* Bottom LFN part is the start of LFN sequence */\r
+ dir[LDIR_Ord] = ord; /* Set the LFN order */\r
+}\r
+\r
+#endif\r
+#endif\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Create numbered name */\r
+/*-----------------------------------------------------------------------*/\r
+#if _USE_LFN\r
+void gen_numname (\r
+ BYTE *dst, /* Pointer to generated SFN */\r
+ const BYTE *src, /* Pointer to source SFN to be modified */\r
+ const WCHAR *lfn, /* Pointer to LFN */\r
+ WORD seq /* Sequence number */\r
+)\r
+{\r
+ BYTE ns[8], c;\r
+ UINT i, j;\r
+\r
+\r
+ mem_cpy(dst, src, 11);\r
+\r
+ if (seq > 5) { /* On many collisions, generate a hash number instead of sequential number */\r
+ do seq = (seq >> 1) + (seq << 15) + (WORD)*lfn++; while (*lfn);\r
+ }\r
+\r
+ /* itoa (hexdecimal) */\r
+ i = 7;\r
+ do {\r
+ c = (seq % 16) + '0';\r
+ if (c > '9') c += 7;\r
+ ns[i--] = c;\r
+ seq /= 16;\r
+ } while (seq);\r
+ ns[i] = '~';\r
+\r
+ /* Append the number */\r
+ for (j = 0; j < i && dst[j] != ' '; j++) {\r
+ if (IsDBCS1(dst[j])) {\r
+ if (j == i - 1) break;\r
+ j++;\r
+ }\r
+ }\r
+ do {\r
+ dst[j++] = (i < 8) ? ns[i++] : ' ';\r
+ } while (j < 8);\r
+}\r
+#endif\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Calculate sum of an SFN */\r
+/*-----------------------------------------------------------------------*/\r
+#if _USE_LFN\r
+static\r
+BYTE sum_sfn (\r
+ const BYTE *dir /* Ptr to directory entry */\r
+)\r
+{\r
+ BYTE sum = 0;\r
+ UINT n = 11;\r
+\r
+ do sum = (sum >> 1) + (sum << 7) + *dir++; while (--n);\r
+ return sum;\r
+}\r
+#endif\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Directory handling - Find an object in the directory */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+FRESULT dir_find (\r
+ DIR *dj /* Pointer to the directory object linked to the file name */\r
+)\r
+{\r
+ FRESULT res;\r
+ BYTE c, *dir;\r
+#if _USE_LFN\r
+ BYTE a, ord, sum;\r
+#endif\r
+\r
+ res = dir_sdi(dj, 0); /* Rewind directory object */\r
+ if (res != FR_OK) return res;\r
+\r
+#if _USE_LFN\r
+ ord = sum = 0xFF;\r
+#endif\r
+ do {\r
+ res = move_window(dj->fs, dj->sect);\r
+ if (res != FR_OK) break;\r
+ dir = dj->dir; /* Ptr to the directory entry of current index */\r
+ c = dir[DIR_Name];\r
+ if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */\r
+#if _USE_LFN /* LFN configuration */\r
+ a = dir[DIR_Attr] & AM_MASK;\r
+ if (c == DDE || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */\r
+ ord = 0xFF;\r
+ } else {\r
+ if (a == AM_LFN) { /* An LFN entry is found */\r
+ if (dj->lfn) {\r
+ if (c & LLE) { /* Is it start of LFN sequence? */\r
+ sum = dir[LDIR_Chksum];\r
+ c &= ~LLE; ord = c; /* LFN start order */\r
+ dj->lfn_idx = dj->index;\r
+ }\r
+ /* Check validity of the LFN entry and compare it with given name */\r
+ ord = (c == ord && sum == dir[LDIR_Chksum] && cmp_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF;\r
+ }\r
+ } else { /* An SFN entry is found */\r
+ if (!ord && sum == sum_sfn(dir)) break; /* LFN matched? */\r
+ ord = 0xFF; dj->lfn_idx = 0xFFFF; /* Reset LFN sequence */\r
+ if (!(dj->fn[NS] & NS_LOSS) && !mem_cmp(dir, dj->fn, 11)) break; /* SFN matched? */\r
+ }\r
+ }\r
+#else /* Non LFN configuration */\r
+ if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) /* Is it a valid entry? */\r
+ break;\r
+#endif\r
+ res = dir_next(dj, 0); /* Next entry */\r
+ } while (res == FR_OK);\r
+\r
+ return res;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Read an object from the directory */\r
+/*-----------------------------------------------------------------------*/\r
+#if _FS_MINIMIZE <= 1\r
+static\r
+FRESULT dir_read (\r
+ DIR *dj /* Pointer to the directory object that pointing the entry to be read */\r
+)\r
+{\r
+ FRESULT res;\r
+ BYTE c, *dir;\r
+#if _USE_LFN\r
+ BYTE a, ord = 0xFF, sum = 0xFF;\r
+#endif\r
+\r
+ res = FR_NO_FILE;\r
+ while (dj->sect) {\r
+ res = move_window(dj->fs, dj->sect);\r
+ if (res != FR_OK) break;\r
+ dir = dj->dir; /* Ptr to the directory entry of current index */\r
+ c = dir[DIR_Name];\r
+ if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */\r
+#if _USE_LFN /* LFN configuration */\r
+ a = dir[DIR_Attr] & AM_MASK;\r
+ if (c == DDE || (!_FS_RPATH && c == '.') || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */\r
+ ord = 0xFF;\r
+ } else {\r
+ if (a == AM_LFN) { /* An LFN entry is found */\r
+ if (c & LLE) { /* Is it start of LFN sequence? */\r
+ sum = dir[LDIR_Chksum];\r
+ c &= ~LLE; ord = c;\r
+ dj->lfn_idx = dj->index;\r
+ }\r
+ /* Check LFN validity and capture it */\r
+ ord = (c == ord && sum == dir[LDIR_Chksum] && pick_lfn(dj->lfn, dir)) ? ord - 1 : 0xFF;\r
+ } else { /* An SFN entry is found */\r
+ if (ord || sum != sum_sfn(dir)) /* Is there a valid LFN? */\r
+ dj->lfn_idx = 0xFFFF; /* It has no LFN. */\r
+ break;\r
+ }\r
+ }\r
+#else /* Non LFN configuration */\r
+ if (c != DDE && (_FS_RPATH || c != '.') && !(dir[DIR_Attr] & AM_VOL)) /* Is it a valid entry? */\r
+ break;\r
+#endif\r
+ res = dir_next(dj, 0); /* Next entry */\r
+ if (res != FR_OK) break;\r
+ }\r
+\r
+ if (res != FR_OK) dj->sect = 0;\r
+\r
+ return res;\r
+}\r
+#endif\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Register an object to the directory */\r
+/*-----------------------------------------------------------------------*/\r
+#if !_FS_READONLY\r
+static\r
+FRESULT dir_register ( /* FR_OK:Successful, FR_DENIED:No free entry or too many SFN collision, FR_DISK_ERR:Disk error */\r
+ DIR *dj /* Target directory with object name to be created */\r
+)\r
+{\r
+ FRESULT res;\r
+ BYTE c, *dir;\r
+#if _USE_LFN /* LFN configuration */\r
+ WORD n, ne, is;\r
+ BYTE sn[12], *fn, sum;\r
+ WCHAR *lfn;\r
+\r
+\r
+ fn = dj->fn; lfn = dj->lfn;\r
+ mem_cpy(sn, fn, 12);\r
+\r
+ if (_FS_RPATH && (sn[NS] & NS_DOT)) /* Cannot create dot entry */\r
+ return FR_INVALID_NAME;\r
+\r
+ if (sn[NS] & NS_LOSS) { /* When LFN is out of 8.3 format, generate a numbered name */\r
+ fn[NS] = 0; dj->lfn = 0; /* Find only SFN */\r
+ for (n = 1; n < 100; n++) {\r
+ gen_numname(fn, sn, lfn, n); /* Generate a numbered name */\r
+ res = dir_find(dj); /* Check if the name collides with existing SFN */\r
+ if (res != FR_OK) break;\r
+ }\r
+ if (n == 100) return FR_DENIED; /* Abort if too many collisions */\r
+ if (res != FR_NO_FILE) return res; /* Abort if the result is other than 'not collided' */\r
+ fn[NS] = sn[NS]; dj->lfn = lfn;\r
+ }\r
+\r
+ if (sn[NS] & NS_LFN) { /* When LFN is to be created, reserve an SFN + LFN entries. */\r
+ for (ne = 0; lfn[ne]; ne++) ;\r
+ ne = (ne + 25) / 13;\r
+ } else { /* Otherwise reserve only an SFN entry. */\r
+ ne = 1;\r
+ }\r
+\r
+ /* Reserve contiguous entries */\r
+ res = dir_sdi(dj, 0);\r
+ if (res != FR_OK) return res;\r
+ n = is = 0;\r
+ do {\r
+ res = move_window(dj->fs, dj->sect);\r
+ if (res != FR_OK) break;\r
+ c = *dj->dir; /* Check the entry status */\r
+ if (c == DDE || c == 0) { /* Is it a blank entry? */\r
+ if (n == 0) is = dj->index; /* First index of the contiguous entry */\r
+ if (++n == ne) break; /* A contiguous entry that required count is found */\r
+ } else {\r
+ n = 0; /* Not a blank entry. Restart to search */\r
+ }\r
+ res = dir_next(dj, 1); /* Next entry with table stretch */\r
+ } while (res == FR_OK);\r
+\r
+ if (res == FR_OK && ne > 1) { /* Initialize LFN entry if needed */\r
+ res = dir_sdi(dj, is);\r
+ if (res == FR_OK) {\r
+ sum = sum_sfn(dj->fn); /* Sum of the SFN tied to the LFN */\r
+ ne--;\r
+ do { /* Store LFN entries in bottom first */\r
+ res = move_window(dj->fs, dj->sect);\r
+ if (res != FR_OK) break;\r
+ fit_lfn(dj->lfn, dj->dir, (BYTE)ne, sum);\r
+ dj->fs->wflag = 1;\r
+ res = dir_next(dj, 0); /* Next entry */\r
+ } while (res == FR_OK && --ne);\r
+ }\r
+ }\r
+\r
+#else /* Non LFN configuration */\r
+ res = dir_sdi(dj, 0);\r
+ if (res == FR_OK) {\r
+ do { /* Find a blank entry for the SFN */\r
+ res = move_window(dj->fs, dj->sect);\r
+ if (res != FR_OK) break;\r
+ c = *dj->dir;\r
+ if (c == DDE || c == 0) break; /* Is it a blank entry? */\r
+ res = dir_next(dj, 1); /* Next entry with table stretch */\r
+ } while (res == FR_OK);\r
+ }\r
+#endif\r
+\r
+ if (res == FR_OK) { /* Initialize the SFN entry */\r
+ res = move_window(dj->fs, dj->sect);\r
+ if (res == FR_OK) {\r
+ dir = dj->dir;\r
+ mem_set(dir, 0, SZ_DIR); /* Clean the entry */\r
+ mem_cpy(dir, dj->fn, 11); /* Put SFN */\r
+#if _USE_LFN\r
+ dir[DIR_NTres] = *(dj->fn+NS) & (NS_BODY | NS_EXT); /* Put NT flag */\r
+#endif\r
+ dj->fs->wflag = 1;\r
+ }\r
+ }\r
+\r
+ return res;\r
+}\r
+#endif /* !_FS_READONLY */\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Remove an object from the directory */\r
+/*-----------------------------------------------------------------------*/\r
+#if !_FS_READONLY && !_FS_MINIMIZE\r
+static\r
+FRESULT dir_remove ( /* FR_OK: Successful, FR_DISK_ERR: A disk error */\r
+ DIR *dj /* Directory object pointing the entry to be removed */\r
+)\r
+{\r
+ FRESULT res;\r
+#if _USE_LFN /* LFN configuration */\r
+ WORD i;\r
+\r
+ i = dj->index; /* SFN index */\r
+ res = dir_sdi(dj, (WORD)((dj->lfn_idx == 0xFFFF) ? i : dj->lfn_idx)); /* Goto the SFN or top of the LFN entries */\r
+ if (res == FR_OK) {\r
+ do {\r
+ res = move_window(dj->fs, dj->sect);\r
+ if (res != FR_OK) break;\r
+ *dj->dir = DDE; /* Mark the entry "deleted" */\r
+ dj->fs->wflag = 1;\r
+ if (dj->index >= i) break; /* When reached SFN, all entries of the object has been deleted. */\r
+ res = dir_next(dj, 0); /* Next entry */\r
+ } while (res == FR_OK);\r
+ if (res == FR_NO_FILE) res = FR_INT_ERR;\r
+ }\r
+\r
+#else /* Non LFN configuration */\r
+ res = dir_sdi(dj, dj->index);\r
+ if (res == FR_OK) {\r
+ res = move_window(dj->fs, dj->sect);\r
+ if (res == FR_OK) {\r
+ *dj->dir = DDE; /* Mark the entry "deleted" */\r
+ dj->fs->wflag = 1;\r
+ }\r
+ }\r
+#endif\r
+\r
+ return res;\r
+}\r
+#endif /* !_FS_READONLY */\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Pick a segment and create the object name in directory form */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+FRESULT create_name (\r
+ DIR *dj, /* Pointer to the directory object */\r
+ const TCHAR **path /* Pointer to pointer to the segment in the path string */\r
+)\r
+{\r
+#ifdef _EXCVT\r
+ static const BYTE excvt[] = _EXCVT; /* Upper conversion table for extended chars */\r
+#endif\r
+\r
+#if _USE_LFN /* LFN configuration */\r
+ BYTE b, cf;\r
+ WCHAR w, *lfn;\r
+ UINT i, ni, si, di;\r
+ const TCHAR *p;\r
+\r
+ /* Create LFN in Unicode */\r
+ for (p = *path; *p == '/' || *p == '\\'; p++) ; /* Strip duplicated separator */\r
+ lfn = dj->lfn;\r
+ si = di = 0;\r
+ for (;;) {\r
+ w = p[si++]; /* Get a character */\r
+ if (w < ' ' || w == '/' || w == '\\') break; /* Break on end of segment */\r
+ if (di >= _MAX_LFN) /* Reject too long name */\r
+ return FR_INVALID_NAME;\r
+#if !_LFN_UNICODE\r
+ w &= 0xFF;\r
+ if (IsDBCS1(w)) { /* Check if it is a DBC 1st byte (always false on SBCS cfg) */\r
+ b = (BYTE)p[si++]; /* Get 2nd byte */\r
+ if (!IsDBCS2(b))\r
+ return FR_INVALID_NAME; /* Reject invalid sequence */\r
+ w = (w << 8) + b; /* Create a DBC */\r
+ }\r
+ w = ff_convert(w, 1); /* Convert ANSI/OEM to Unicode */\r
+ if (!w) return FR_INVALID_NAME; /* Reject invalid code */\r
+#endif\r
+ if (w < 0x80 && chk_chr("\"*:<>\?|\x7F", w)) /* Reject illegal chars for LFN */\r
+ return FR_INVALID_NAME;\r
+ lfn[di++] = w; /* Store the Unicode char */\r
+ }\r
+ *path = &p[si]; /* Return pointer to the next segment */\r
+ cf = (w < ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */\r
+#if _FS_RPATH\r
+ if ((di == 1 && lfn[di-1] == '.') || /* Is this a dot entry? */\r
+ (di == 2 && lfn[di-1] == '.' && lfn[di-2] == '.')) {\r
+ lfn[di] = 0;\r
+ for (i = 0; i < 11; i++)\r
+ dj->fn[i] = (i < di) ? '.' : ' ';\r
+ dj->fn[i] = cf | NS_DOT; /* This is a dot entry */\r
+ return FR_OK;\r
+ }\r
+#endif\r
+ while (di) { /* Strip trailing spaces and dots */\r
+ w = lfn[di-1];\r
+ if (w != ' ' && w != '.') break;\r
+ di--;\r
+ }\r
+ if (!di) return FR_INVALID_NAME; /* Reject nul string */\r
+\r
+ lfn[di] = 0; /* LFN is created */\r
+\r
+ /* Create SFN in directory form */\r
+ mem_set(dj->fn, ' ', 11);\r
+ for (si = 0; lfn[si] == ' ' || lfn[si] == '.'; si++) ; /* Strip leading spaces and dots */\r
+ if (si) cf |= NS_LOSS | NS_LFN;\r
+ while (di && lfn[di - 1] != '.') di--; /* Find extension (di<=si: no extension) */\r
+\r
+ b = i = 0; ni = 8;\r
+ for (;;) {\r
+ w = lfn[si++]; /* Get an LFN char */\r
+ if (!w) break; /* Break on end of the LFN */\r
+ if (w == ' ' || (w == '.' && si != di)) { /* Remove spaces and dots */\r
+ cf |= NS_LOSS | NS_LFN; continue;\r
+ }\r
+\r
+ if (i >= ni || si == di) { /* Extension or end of SFN */\r
+ if (ni == 11) { /* Long extension */\r
+ cf |= NS_LOSS | NS_LFN; break;\r
+ }\r
+ if (si != di) cf |= NS_LOSS | NS_LFN; /* Out of 8.3 format */\r
+ if (si > di) break; /* No extension */\r
+ si = di; i = 8; ni = 11; /* Enter extension section */\r
+ b <<= 2; continue;\r
+ }\r
+\r
+ if (w >= 0x80) { /* Non ASCII char */\r
+#ifdef _EXCVT\r
+ w = ff_convert(w, 0); /* Unicode -> OEM code */\r
+ if (w) w = excvt[w - 0x80]; /* Convert extended char to upper (SBCS) */\r
+#else\r
+ w = ff_convert(ff_wtoupper(w), 0); /* Upper converted Unicode -> OEM code */\r
+#endif\r
+ cf |= NS_LFN; /* Force create LFN entry */\r
+ }\r
+\r
+ if (_DF1S && w >= 0x100) { /* Double byte char (always false on SBCS cfg) */\r
+ if (i >= ni - 1) {\r
+ cf |= NS_LOSS | NS_LFN; i = ni; continue;\r
+ }\r
+ dj->fn[i++] = (BYTE)(w >> 8);\r
+ } else { /* Single byte char */\r
+ if (!w || chk_chr("+,;=[]", w)) { /* Replace illegal chars for SFN */\r
+ w = '_'; cf |= NS_LOSS | NS_LFN;/* Lossy conversion */\r
+ } else {\r
+ if (IsUpper(w)) { /* ASCII large capital */\r
+ b |= 2;\r
+ } else {\r
+ if (IsLower(w)) { /* ASCII small capital */\r
+ b |= 1; w -= 0x20;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ dj->fn[i++] = (BYTE)w;\r
+ }\r
+\r
+ if (dj->fn[0] == DDE) dj->fn[0] = NDDE; /* If the first char collides with deleted mark, replace it with 0x05 */\r
+\r
+ if (ni == 8) b <<= 2;\r
+ if ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03) /* Create LFN entry when there are composite capitals */\r
+ cf |= NS_LFN;\r
+ if (!(cf & NS_LFN)) { /* When LFN is in 8.3 format without extended char, NT flags are created */\r
+ if ((b & 0x03) == 0x01) cf |= NS_EXT; /* NT flag (Extension has only small capital) */\r
+ if ((b & 0x0C) == 0x04) cf |= NS_BODY; /* NT flag (Filename has only small capital) */\r
+ }\r
+\r
+ dj->fn[NS] = cf; /* SFN is created */\r
+\r
+ return FR_OK;\r
+\r
+\r
+#else /* Non-LFN configuration */\r
+ BYTE b, c, d, *sfn;\r
+ UINT ni, si, i;\r
+ const char *p;\r
+\r
+ /* Create file name in directory form */\r
+ for (p = *path; *p == '/' || *p == '\\'; p++) ; /* Strip duplicated separator */\r
+ sfn = dj->fn;\r
+ mem_set(sfn, ' ', 11);\r
+ si = i = b = 0; ni = 8;\r
+#if _FS_RPATH\r
+ if (p[si] == '.') { /* Is this a dot entry? */\r
+ for (;;) {\r
+ c = (BYTE)p[si++];\r
+ if (c != '.' || si >= 3) break;\r
+ sfn[i++] = c;\r
+ }\r
+ if (c != '/' && c != '\\' && c > ' ') return FR_INVALID_NAME;\r
+ *path = &p[si]; /* Return pointer to the next segment */\r
+ sfn[NS] = (c <= ' ') ? NS_LAST | NS_DOT : NS_DOT; /* Set last segment flag if end of path */\r
+ return FR_OK;\r
+ }\r
+#endif\r
+ for (;;) {\r
+ c = (BYTE)p[si++];\r
+ if (c <= ' ' || c == '/' || c == '\\') break; /* Break on end of segment */\r
+ if (c == '.' || i >= ni) {\r
+ if (ni != 8 || c != '.') return FR_INVALID_NAME;\r
+ i = 8; ni = 11;\r
+ b <<= 2; continue;\r
+ }\r
+ if (c >= 0x80) { /* Extended char? */\r
+ b |= 3; /* Eliminate NT flag */\r
+#ifdef _EXCVT\r
+ c = excvt[c-0x80]; /* Upper conversion (SBCS) */\r
+#else\r
+#if !_DF1S /* ASCII only cfg */\r
+ return FR_INVALID_NAME;\r
+#endif\r
+#endif\r
+ }\r
+ if (IsDBCS1(c)) { /* Check if it is a DBC 1st byte (always false on SBCS cfg) */\r
+ d = (BYTE)p[si++]; /* Get 2nd byte */\r
+ if (!IsDBCS2(d) || i >= ni - 1) /* Reject invalid DBC */\r
+ return FR_INVALID_NAME;\r
+ sfn[i++] = c;\r
+ sfn[i++] = d;\r
+ } else { /* Single byte code */\r
+ if (chk_chr("\"*+,:;<=>\?[]|\x7F", c)) /* Reject illegal chrs for SFN */\r
+ return FR_INVALID_NAME;\r
+ if (IsUpper(c)) { /* ASCII large capital? */\r
+ b |= 2;\r
+ } else {\r
+ if (IsLower(c)) { /* ASCII small capital? */\r
+ b |= 1; c -= 0x20;\r
+ }\r
+ }\r
+ sfn[i++] = c;\r
+ }\r
+ }\r
+ *path = &p[si]; /* Return pointer to the next segment */\r
+ c = (c <= ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */\r
+\r
+ if (!i) return FR_INVALID_NAME; /* Reject nul string */\r
+ if (sfn[0] == DDE) sfn[0] = NDDE; /* When first char collides with DDE, replace it with 0x05 */\r
+\r
+ if (ni == 8) b <<= 2;\r
+ if ((b & 0x03) == 0x01) c |= NS_EXT; /* NT flag (Name extension has only small capital) */\r
+ if ((b & 0x0C) == 0x04) c |= NS_BODY; /* NT flag (Name body has only small capital) */\r
+\r
+ sfn[NS] = c; /* Store NT flag, File name is created */\r
+\r
+ return FR_OK;\r
+#endif\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Get file information from directory entry */\r
+/*-----------------------------------------------------------------------*/\r
+#if _FS_MINIMIZE <= 1\r
+static\r
+void get_fileinfo ( /* No return code */\r
+ DIR *dj, /* Pointer to the directory object */\r
+ FILINFO *fno /* Pointer to the file information to be filled */\r
+)\r
+{\r
+ UINT i;\r
+ BYTE nt, *dir;\r
+ TCHAR *p, c;\r
+\r
+\r
+ p = fno->fname;\r
+ if (dj->sect) {\r
+ dir = dj->dir;\r
+ nt = dir[DIR_NTres]; /* NT flag */\r
+ for (i = 0; i < 8; i++) { /* Copy name body */\r
+ c = dir[i];\r
+ if (c == ' ') break;\r
+ if (c == NDDE) c = (TCHAR)DDE;\r
+ if (_USE_LFN && (nt & NS_BODY) && IsUpper(c)) c += 0x20;\r
+#if _LFN_UNICODE\r
+ if (IsDBCS1(c) && i < 7 && IsDBCS2(dir[i+1]))\r
+ c = (c << 8) | dir[++i];\r
+ c = ff_convert(c, 1);\r
+ if (!c) c = '?';\r
+#endif\r
+ *p++ = c;\r
+ }\r
+ if (dir[8] != ' ') { /* Copy name extension */\r
+ *p++ = '.';\r
+ for (i = 8; i < 11; i++) {\r
+ c = dir[i];\r
+ if (c == ' ') break;\r
+ if (_USE_LFN && (nt & NS_EXT) && IsUpper(c)) c += 0x20;\r
+#if _LFN_UNICODE\r
+ if (IsDBCS1(c) && i < 10 && IsDBCS2(dir[i+1]))\r
+ c = (c << 8) | dir[++i];\r
+ c = ff_convert(c, 1);\r
+ if (!c) c = '?';\r
+#endif\r
+ *p++ = c;\r
+ }\r
+ }\r
+ fno->fattrib = dir[DIR_Attr]; /* Attribute */\r
+ fno->fsize = LD_DWORD(dir+DIR_FileSize); /* Size */\r
+ fno->fdate = LD_WORD(dir+DIR_WrtDate); /* Date */\r
+ fno->ftime = LD_WORD(dir+DIR_WrtTime); /* Time */\r
+ }\r
+ *p = 0; /* Terminate SFN str by a \0 */\r
+\r
+#if _USE_LFN\r
+ if (fno->lfname && fno->lfsize) {\r
+ TCHAR *tp = fno->lfname;\r
+ WCHAR w, *lfn;\r
+\r
+ i = 0;\r
+ if (dj->sect && dj->lfn_idx != 0xFFFF) {/* Get LFN if available */\r
+ lfn = dj->lfn;\r
+ while ((w = *lfn++) != 0) { /* Get an LFN char */\r
+#if !_LFN_UNICODE\r
+ w = ff_convert(w, 0); /* Unicode -> OEM conversion */\r
+ if (!w) { i = 0; break; } /* Could not convert, no LFN */\r
+ if (_DF1S && w >= 0x100) /* Put 1st byte if it is a DBC (always false on SBCS cfg) */\r
+ tp[i++] = (TCHAR)(w >> 8);\r
+#endif\r
+ if (i >= fno->lfsize - 1) { i = 0; break; } /* Buffer overflow, no LFN */\r
+ tp[i++] = (TCHAR)w;\r
+ }\r
+ }\r
+ tp[i] = 0; /* Terminate the LFN str by a \0 */\r
+ }\r
+#endif\r
+}\r
+#endif /* _FS_MINIMIZE <= 1 */\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Follow a file path */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */\r
+ DIR *dj, /* Directory object to return last directory and found object */\r
+ const TCHAR *path /* Full-path string to find a file or directory */\r
+)\r
+{\r
+ FRESULT res;\r
+ BYTE *dir, ns;\r
+\r
+\r
+#if _FS_RPATH\r
+ if (*path == '/' || *path == '\\') { /* There is a heading separator */\r
+ path++; dj->sclust = 0; /* Strip it and start from the root dir */\r
+ } else { /* No heading separator */\r
+ dj->sclust = dj->fs->cdir; /* Start from the current dir */\r
+ }\r
+#else\r
+ if (*path == '/' || *path == '\\') /* Strip heading separator if exist */\r
+ path++;\r
+ dj->sclust = 0; /* Start from the root dir */\r
+#endif\r
+\r
+ if ((UINT)*path < ' ') { /* Nul path means the start directory itself */\r
+ res = dir_sdi(dj, 0);\r
+ dj->dir = 0;\r
+\r
+ } else { /* Follow path */\r
+ for (;;) {\r
+ res = create_name(dj, &path); /* Get a segment */\r
+ if (res != FR_OK) break;\r
+ res = dir_find(dj); /* Find it */\r
+ ns = *(dj->fn+NS);\r
+ if (res != FR_OK) { /* Failed to find the object */\r
+ if (res != FR_NO_FILE) break; /* Abort if any hard error occured */\r
+ /* Object not found */\r
+ if (_FS_RPATH && (ns & NS_DOT)) { /* If dot entry is not exit */\r
+ dj->sclust = 0; dj->dir = 0; /* It is the root dir */\r
+ res = FR_OK;\r
+ if (!(ns & NS_LAST)) continue;\r
+ } else { /* Could not find the object */\r
+ if (!(ns & NS_LAST)) res = FR_NO_PATH;\r
+ }\r
+ break;\r
+ }\r
+ if (ns & NS_LAST) break; /* Last segment match. Function completed. */\r
+ dir = dj->dir; /* There is next segment. Follow the sub directory */\r
+ if (!(dir[DIR_Attr] & AM_DIR)) { /* Cannot follow because it is a file */\r
+ res = FR_NO_PATH; break;\r
+ }\r
+ dj->sclust = LD_CLUST(dir);\r
+ }\r
+ }\r
+\r
+ return res;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Load boot record and check if it is an FAT boot record */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+BYTE check_fs ( /* 0:The FAT BR, 1:Valid BR but not an FAT, 2:Not a BR, 3:Disk error */\r
+ FATFS *fs, /* File system object */\r
+ DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */\r
+)\r
+{\r
+ if (disk_read(fs->drv, fs->win, sect, 1) != RES_OK) /* Load boot record */\r
+ return 3;\r
+ if (LD_WORD(&fs->win[BS_55AA]) != 0xAA55) /* Check record signature (always placed at offset 510 even if the sector size is >512) */\r
+ return 2;\r
+\r
+ if ((LD_DWORD(&fs->win[BS_FilSysType]) & 0xFFFFFF) == 0x544146) /* Check "FAT" string */\r
+ return 0;\r
+ if ((LD_DWORD(&fs->win[BS_FilSysType32]) & 0xFFFFFF) == 0x544146)\r
+ return 0;\r
+\r
+ return 1;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Check if the file system object is valid or not */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+FRESULT chk_mounted ( /* FR_OK(0): successful, !=0: any error occurred */\r
+ const TCHAR **path, /* Pointer to pointer to the path name (drive number) */\r
+ FATFS **rfs, /* Pointer to pointer to the found file system object */\r
+ BYTE chk_wp /* !=0: Check media write protection for write access */\r
+)\r
+{\r
+ BYTE fmt, b, *tbl;\r
+ UINT vol;\r
+ DSTATUS stat;\r
+ DWORD bsect, fasize, tsect, sysect, nclst, szbfat;\r
+ WORD nrsv;\r
+ const TCHAR *p = *path;\r
+ FATFS *fs;\r
+\r
+ /* Get logical drive number from the path name */\r
+ vol = p[0] - '0'; /* Is there a drive number? */\r
+ if (vol <= 9 && p[1] == ':') { /* Found a drive number, get and strip it */\r
+ p += 2; *path = p; /* Return pointer to the path name */\r
+ } else { /* No drive number is given */\r
+#if _FS_RPATH\r
+ vol = CurrVol; /* Use current drive */\r
+#else\r
+ vol = 0; /* Use drive 0 */\r
+#endif\r
+ }\r
+\r
+ /* Check if the logical drive is valid or not */\r
+ if (vol >= _VOLUMES) /* Is the drive number valid? */\r
+ return FR_INVALID_DRIVE;\r
+ *rfs = fs = FatFs[vol]; /* Return pointer to the corresponding file system object */\r
+ if (!fs) return FR_NOT_ENABLED; /* Is the file system object available? */\r
+\r
+ ENTER_FF(fs); /* Lock file system */\r
+\r
+ if (fs->fs_type) { /* If the logical drive has been mounted */\r
+ stat = disk_status(fs->drv);\r
+ if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized (has not been changed), */\r
+#if !_FS_READONLY\r
+ if (chk_wp && (stat & STA_PROTECT)) /* Check write protection if needed */\r
+ return FR_WRITE_PROTECTED;\r
+#endif\r
+ return FR_OK; /* The file system object is valid */\r
+ }\r
+ }\r
+\r
+ /* The logical drive must be mounted. */\r
+ /* Following code attempts to mount a volume. (analyze BPB and initialize the fs object) */\r
+\r
+ fs->fs_type = 0; /* Clear the file system object */\r
+ fs->drv = (BYTE)LD2PD(vol); /* Bind the logical drive and a physical drive */\r
+ stat = disk_initialize(fs->drv); /* Initialize low level disk I/O layer */\r
+ if (stat & STA_NOINIT) /* Check if the initialization succeeded */\r
+ return FR_NOT_READY; /* Failed to initialize due to no media or hard error */\r
+#if _MAX_SS != 512 /* Get disk sector size (variable sector size cfg only) */\r
+ if (disk_ioctl(fs->drv, GET_SECTOR_SIZE, &fs->ssize) != RES_OK)\r
+ return FR_DISK_ERR;\r
+#endif\r
+#if !_FS_READONLY\r
+ if (chk_wp && (stat & STA_PROTECT)) /* Check disk write protection if needed */\r
+ return FR_WRITE_PROTECTED;\r
+#endif\r
+ /* Search FAT partition on the drive. Supports only generic partitionings, FDISK and SFD. */\r
+ fmt = check_fs(fs, bsect = 0); /* Check sector 0 if it is a VBR */\r
+ if (fmt == 1) { /* Not an FAT-VBR, the disk may be partitioned */\r
+ /* Check the partition listed in top of the partition table */\r
+ tbl = &fs->win[MBR_Table + LD2PT(vol) * SZ_PTE];/* Partition table */\r
+ if (tbl[4]) { /* Is the partition existing? */\r
+ bsect = LD_DWORD(&tbl[8]); /* Partition offset in LBA */\r
+ fmt = check_fs(fs, bsect); /* Check the partition */\r
+ }\r
+ }\r
+ if (fmt == 3) return FR_DISK_ERR;\r
+ if (fmt) return FR_NO_FILESYSTEM; /* No FAT volume is found */\r
+\r
+ /* Following code initializes the file system object */\r
+\r
+ if (LD_WORD(fs->win+BPB_BytsPerSec) != SS(fs)) /* (BPB_BytsPerSec must be equal to the physical sector size) */\r
+ return FR_NO_FILESYSTEM;\r
+\r
+ fasize = LD_WORD(fs->win+BPB_FATSz16); /* Number of sectors per FAT */\r
+ if (!fasize) fasize = LD_DWORD(fs->win+BPB_FATSz32);\r
+ fs->fsize = fasize;\r
+\r
+ fs->n_fats = b = fs->win[BPB_NumFATs]; /* Number of FAT copies */\r
+ if (b != 1 && b != 2) return FR_NO_FILESYSTEM; /* (Must be 1 or 2) */\r
+ fasize *= b; /* Number of sectors for FAT area */\r
+\r
+ fs->csize = b = fs->win[BPB_SecPerClus]; /* Number of sectors per cluster */\r
+ if (!b || (b & (b - 1))) return FR_NO_FILESYSTEM; /* (Must be power of 2) */\r
+\r
+ fs->n_rootdir = LD_WORD(fs->win+BPB_RootEntCnt); /* Number of root directory entries */\r
+ if (fs->n_rootdir % (SS(fs) / SZ_DIR)) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be sector aligned) */\r
+\r
+ tsect = LD_WORD(fs->win+BPB_TotSec16); /* Number of sectors on the volume */\r
+ if (!tsect) tsect = LD_DWORD(fs->win+BPB_TotSec32);\r
+\r
+ nrsv = LD_WORD(fs->win+BPB_RsvdSecCnt); /* Number of reserved sectors */\r
+ if (!nrsv) return FR_NO_FILESYSTEM; /* (BPB_RsvdSecCnt must not be 0) */\r
+\r
+ /* Determine the FAT sub type */\r
+ sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZ_DIR); /* RSV+FAT+DIR */\r
+ if (tsect < sysect) return FR_NO_FILESYSTEM; /* (Invalid volume size) */\r
+ nclst = (tsect - sysect) / fs->csize; /* Number of clusters */\r
+ if (!nclst) return FR_NO_FILESYSTEM; /* (Invalid volume size) */\r
+ fmt = FS_FAT12;\r
+ if (nclst >= MIN_FAT16) fmt = FS_FAT16;\r
+ if (nclst >= MIN_FAT32) fmt = FS_FAT32;\r
+\r
+ /* Boundaries and Limits */\r
+ fs->n_fatent = nclst + 2; /* Number of FAT entries */\r
+ fs->database = bsect + sysect; /* Data start sector */\r
+ fs->fatbase = bsect + nrsv; /* FAT start sector */\r
+ if (fmt == FS_FAT32) {\r
+ if (fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */\r
+ fs->dirbase = LD_DWORD(fs->win+BPB_RootClus); /* Root directory start cluster */\r
+ szbfat = fs->n_fatent * 4; /* (Required FAT size) */\r
+ } else {\r
+ if (!fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */\r
+ fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */\r
+ szbfat = (fmt == FS_FAT16) ? /* (Required FAT size) */\r
+ fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1);\r
+ }\r
+ if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) /* (BPB_FATSz must not be less than required) */\r
+ return FR_NO_FILESYSTEM;\r
+\r
+#if !_FS_READONLY\r
+ /* Initialize cluster allocation information */\r
+ fs->free_clust = 0xFFFFFFFF;\r
+ fs->last_clust = 0;\r
+\r
+ /* Get fsinfo if available */\r
+ if (fmt == FS_FAT32) {\r
+ fs->fsi_flag = 0;\r
+ fs->fsi_sector = bsect + LD_WORD(fs->win+BPB_FSInfo);\r
+ if (disk_read(fs->drv, fs->win, fs->fsi_sector, 1) == RES_OK &&\r
+ LD_WORD(fs->win+BS_55AA) == 0xAA55 &&\r
+ LD_DWORD(fs->win+FSI_LeadSig) == 0x41615252 &&\r
+ LD_DWORD(fs->win+FSI_StrucSig) == 0x61417272) {\r
+ fs->last_clust = LD_DWORD(fs->win+FSI_Nxt_Free);\r
+ fs->free_clust = LD_DWORD(fs->win+FSI_Free_Count);\r
+ }\r
+ }\r
+#endif\r
+ fs->fs_type = fmt; /* FAT sub-type */\r
+ fs->id = ++Fsid; /* File system mount ID */\r
+ fs->winsect = 0; /* Invalidate sector cache */\r
+ fs->wflag = 0;\r
+#if _FS_RPATH\r
+ fs->cdir = 0; /* Current directory (root dir) */\r
+#endif\r
+#if _FS_SHARE /* Clear file lock semaphores */\r
+ clear_lock(fs);\r
+#endif\r
+\r
+ return FR_OK;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Check if the file/dir object is valid or not */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+FRESULT validate ( /* FR_OK(0): The object is valid, !=0: Invalid */\r
+ FATFS *fs, /* Pointer to the file system object */\r
+ WORD id /* Member id of the target object to be checked */\r
+)\r
+{\r
+ if (!fs || !fs->fs_type || fs->id != id)\r
+ return FR_INVALID_OBJECT;\r
+\r
+ ENTER_FF(fs); /* Lock file system */\r
+\r
+ if (disk_status(fs->drv) & STA_NOINIT)\r
+ return FR_NOT_READY;\r
+\r
+ return FR_OK;\r
+}\r
+\r
+\r
+\r
+\r
+/*--------------------------------------------------------------------------\r
+\r
+ Public Functions\r
+\r
+--------------------------------------------------------------------------*/\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Mount/Unmount a Logical Drive */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT f_mount (\r
+ BYTE vol, /* Logical drive number to be mounted/unmounted */\r
+ FATFS *fs /* Pointer to new file system object (NULL for unmount)*/\r
+)\r
+{\r
+ FATFS *rfs;\r
+\r
+\r
+ if (vol >= _VOLUMES) /* Check if the drive number is valid */\r
+ return FR_INVALID_DRIVE;\r
+ rfs = FatFs[vol]; /* Get current fs object */\r
+\r
+ if (rfs) {\r
+#if _FS_SHARE\r
+ clear_lock(rfs);\r
+#endif\r
+#if _FS_REENTRANT /* Discard sync object of the current volume */\r
+ if (!ff_del_syncobj(rfs->sobj)) return FR_INT_ERR;\r
+#endif\r
+ rfs->fs_type = 0; /* Clear old fs object */\r
+ }\r
+\r
+ if (fs) {\r
+ fs->fs_type = 0; /* Clear new fs object */\r
+#if _FS_REENTRANT /* Create sync object for the new volume */\r
+ if (!ff_cre_syncobj(vol, &fs->sobj)) return FR_INT_ERR;\r
+#endif\r
+ }\r
+ FatFs[vol] = fs; /* Register new fs object */\r
+\r
+ return FR_OK;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Open or Create a File */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT f_open (\r
+ FIL *fp, /* Pointer to the blank file object */\r
+ const TCHAR *path, /* Pointer to the file name */\r
+ BYTE mode /* Access mode and file open mode flags */\r
+)\r
+{\r
+ FRESULT res;\r
+ DIR dj;\r
+ BYTE *dir;\r
+ DEF_NAMEBUF;\r
+\r
+\r
+ fp->fs = 0; /* Clear file object */\r
+\r
+#if !_FS_READONLY\r
+ mode &= FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW;\r
+ res = chk_mounted(&path, &dj.fs, (BYTE)(mode & ~FA_READ));\r
+#else\r
+ mode &= FA_READ;\r
+ res = chk_mounted(&path, &dj.fs, 0);\r
+#endif\r
+ INIT_BUF(dj);\r
+ if (res == FR_OK)\r
+ res = follow_path(&dj, path); /* Follow the file path */\r
+ dir = dj.dir;\r
+\r
+#if !_FS_READONLY /* R/W configuration */\r
+ if (res == FR_OK) {\r
+ if (!dir) /* Current dir itself */\r
+ res = FR_INVALID_NAME;\r
+#if _FS_SHARE\r
+ else\r
+ res = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0);\r
+#endif\r
+ }\r
+ /* Create or Open a file */\r
+ if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) {\r
+ DWORD dw, cl;\r
+\r
+ if (res != FR_OK) { /* No file, create new */\r
+ if (res == FR_NO_FILE) /* There is no file to open, create a new entry */\r
+#if _FS_SHARE\r
+ res = enq_lock(dj.fs) ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES;\r
+#else\r
+ res = dir_register(&dj);\r
+#endif\r
+ mode |= FA_CREATE_ALWAYS; /* File is created */\r
+ dir = dj.dir; /* New entry */\r
+ }\r
+ else { /* Any object is already existing */\r
+ if (dir[DIR_Attr] & (AM_RDO | AM_DIR)) { /* Cannot overwrite it (R/O or DIR) */\r
+ res = FR_DENIED;\r
+ } else {\r
+ if (mode & FA_CREATE_NEW) /* Cannot create as new file */\r
+ res = FR_EXIST;\r
+ }\r
+ }\r
+ if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) { /* Truncate it if overwrite mode */\r
+ dw = get_fattime(); /* Created time */\r
+ ST_DWORD(dir+DIR_CrtTime, dw);\r
+ dir[DIR_Attr] = 0; /* Reset attribute */\r
+ ST_DWORD(dir+DIR_FileSize, 0); /* size = 0 */\r
+ cl = LD_CLUST(dir); /* Get start cluster */\r
+ ST_CLUST(dir, 0); /* cluster = 0 */\r
+ dj.fs->wflag = 1;\r
+ if (cl) { /* Remove the cluster chain if exist */\r
+ dw = dj.fs->winsect;\r
+ res = remove_chain(dj.fs, cl);\r
+ if (res == FR_OK) {\r
+ dj.fs->last_clust = cl - 1; /* Reuse the cluster hole */\r
+ res = move_window(dj.fs, dw);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ else { /* Open an existing file */\r
+ if (res == FR_OK) { /* Follow succeeded */\r
+ if (dir[DIR_Attr] & AM_DIR) { /* It is a directory */\r
+ res = FR_NO_FILE;\r
+ } else {\r
+ if ((mode & FA_WRITE) && (dir[DIR_Attr] & AM_RDO)) /* R/O violation */\r
+ res = FR_DENIED;\r
+ }\r
+ }\r
+ }\r
+ if (res == FR_OK) {\r
+ if (mode & FA_CREATE_ALWAYS) /* Set file change flag if created or overwritten */\r
+ mode |= FA__WRITTEN;\r
+ fp->dir_sect = dj.fs->winsect; /* Pointer to the directory entry */\r
+ fp->dir_ptr = dir;\r
+#if _FS_SHARE\r
+ fp->lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0);\r
+ if (!fp->lockid) res = FR_INT_ERR;\r
+#endif\r
+ }\r
+\r
+#else /* R/O configuration */\r
+ if (res == FR_OK) { /* Follow succeeded */\r
+ if (!dir) { /* Current dir itself */\r
+ res = FR_INVALID_NAME;\r
+ } else {\r
+ if (dir[DIR_Attr] & AM_DIR) /* It is a directory */\r
+ res = FR_NO_FILE;\r
+ }\r
+ }\r
+#endif\r
+ FREE_BUF();\r
+\r
+ if (res == FR_OK) {\r
+ fp->flag = mode; /* File access mode */\r
+ fp->sclust = LD_CLUST(dir); /* File start cluster */\r
+ fp->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */\r
+ fp->fptr = 0; /* File pointer */\r
+ fp->dsect = 0;\r
+#if _USE_FASTSEEK\r
+ fp->cltbl = 0; /* Normal seek mode */\r
+#endif\r
+ fp->fs = dj.fs; fp->id = dj.fs->id; /* Validate file object */\r
+ }\r
+\r
+ LEAVE_FF(dj.fs, res);\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Read File */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT f_read (\r
+ FIL *fp, /* Pointer to the file object */\r
+ void *buff, /* Pointer to data buffer */\r
+ UINT btr, /* Number of bytes to read */\r
+ UINT *br /* Pointer to number of bytes read */\r
+)\r
+{\r
+ FRESULT res;\r
+ DWORD clst, sect, remain;\r
+ UINT rcnt, cc;\r
+ BYTE csect, *rbuff = buff;\r
+\r
+\r
+ *br = 0; /* Initialize byte counter */\r
+\r
+ res = validate(fp->fs, fp->id); /* Check validity */\r
+ if (res != FR_OK) LEAVE_FF(fp->fs, res);\r
+ if (fp->flag & FA__ERROR) /* Aborted file? */\r
+ LEAVE_FF(fp->fs, FR_INT_ERR);\r
+ if (!(fp->flag & FA_READ)) /* Check access mode */\r
+ LEAVE_FF(fp->fs, FR_DENIED);\r
+ remain = fp->fsize - fp->fptr;\r
+ if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */\r
+\r
+ for ( ; btr; /* Repeat until all data read */\r
+ rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) {\r
+ if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */\r
+ csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */\r
+ if (!csect) { /* On the cluster boundary? */\r
+ if (fp->fptr == 0) { /* On the top of the file? */\r
+ clst = fp->sclust; /* Follow from the origin */\r
+ } else { /* Middle or end of the file */\r
+#if _USE_FASTSEEK\r
+ if (fp->cltbl)\r
+ clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */\r
+ else\r
+#endif\r
+ clst = get_fat(fp->fs, fp->clust); /* Follow cluster chain on the FAT */\r
+ }\r
+ if (clst < 2) ABORT(fp->fs, FR_INT_ERR);\r
+ if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);\r
+ fp->clust = clst; /* Update current cluster */\r
+ }\r
+ sect = clust2sect(fp->fs, fp->clust); /* Get current sector */\r
+ if (!sect) ABORT(fp->fs, FR_INT_ERR);\r
+ sect += csect;\r
+ cc = btr / SS(fp->fs); /* When remaining bytes >= sector size, */\r
+ if (cc) { /* Read maximum contiguous sectors directly */\r
+ if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */\r
+ cc = fp->fs->csize - csect;\r
+ if (disk_read(fp->fs->drv, rbuff, sect, (BYTE)cc) != RES_OK)\r
+ ABORT(fp->fs, FR_DISK_ERR);\r
+#if !_FS_READONLY && _FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */\r
+#if _FS_TINY\r
+ if (fp->fs->wflag && fp->fs->winsect - sect < cc)\r
+ mem_cpy(rbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), fp->fs->win, SS(fp->fs));\r
+#else\r
+ if ((fp->flag & FA__DIRTY) && fp->dsect - sect < cc)\r
+ mem_cpy(rbuff + ((fp->dsect - sect) * SS(fp->fs)), fp->buf, SS(fp->fs));\r
+#endif\r
+#endif\r
+ rcnt = SS(fp->fs) * cc; /* Number of bytes transferred */\r
+ continue;\r
+ }\r
+#if !_FS_TINY\r
+ if (fp->dsect != sect) { /* Load data sector if not in cache */\r
+#if !_FS_READONLY\r
+ if (fp->flag & FA__DIRTY) { /* Write-back dirty sector cache */\r
+ if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)\r
+ ABORT(fp->fs, FR_DISK_ERR);\r
+ fp->flag &= ~FA__DIRTY;\r
+ }\r
+#endif\r
+ if (disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK) /* Fill sector cache */\r
+ ABORT(fp->fs, FR_DISK_ERR);\r
+ }\r
+#endif\r
+ fp->dsect = sect;\r
+ }\r
+ rcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs)); /* Get partial sector data from sector buffer */\r
+ if (rcnt > btr) rcnt = btr;\r
+#if _FS_TINY\r
+ if (move_window(fp->fs, fp->dsect)) /* Move sector window */\r
+ ABORT(fp->fs, FR_DISK_ERR);\r
+ mem_cpy(rbuff, &fp->fs->win[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */\r
+#else\r
+ mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */\r
+#endif\r
+ }\r
+\r
+ LEAVE_FF(fp->fs, FR_OK);\r
+}\r
+\r
+\r
+\r
+\r
+#if !_FS_READONLY\r
+/*-----------------------------------------------------------------------*/\r
+/* Write File */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT f_write (\r
+ FIL *fp, /* Pointer to the file object */\r
+ const void *buff, /* Pointer to the data to be written */\r
+ UINT btw, /* Number of bytes to write */\r
+ UINT *bw /* Pointer to number of bytes written */\r
+)\r
+{\r
+ FRESULT res;\r
+ DWORD clst, sect;\r
+ UINT wcnt, cc;\r
+ const BYTE *wbuff = buff;\r
+ BYTE csect;\r
+\r
+\r
+ *bw = 0; /* Initialize byte counter */\r
+\r
+ res = validate(fp->fs, fp->id); /* Check validity */\r
+ if (res != FR_OK) LEAVE_FF(fp->fs, res);\r
+ if (fp->flag & FA__ERROR) /* Aborted file? */\r
+ LEAVE_FF(fp->fs, FR_INT_ERR);\r
+ if (!(fp->flag & FA_WRITE)) /* Check access mode */\r
+ LEAVE_FF(fp->fs, FR_DENIED);\r
+ if ((DWORD)(fp->fsize + btw) < fp->fsize) btw = 0; /* File size cannot reach 4GB */\r
+\r
+ for ( ; btw; /* Repeat until all data written */\r
+ wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) {\r
+ if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */\r
+ csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */\r
+ if (!csect) { /* On the cluster boundary? */\r
+ if (fp->fptr == 0) { /* On the top of the file? */\r
+ clst = fp->sclust; /* Follow from the origin */\r
+ if (clst == 0) /* When no cluster is allocated, */\r
+ fp->sclust = clst = create_chain(fp->fs, 0); /* Create a new cluster chain */\r
+ } else { /* Middle or end of the file */\r
+#if _USE_FASTSEEK\r
+ if (fp->cltbl)\r
+ clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */\r
+ else\r
+#endif\r
+ clst = create_chain(fp->fs, fp->clust); /* Follow or stretch cluster chain on the FAT */\r
+ }\r
+ if (clst == 0) break; /* Could not allocate a new cluster (disk full) */\r
+ if (clst == 1) ABORT(fp->fs, FR_INT_ERR);\r
+ if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);\r
+ fp->clust = clst; /* Update current cluster */\r
+ }\r
+#if _FS_TINY\r
+ if (fp->fs->winsect == fp->dsect && move_window(fp->fs, 0)) /* Write-back sector cache */\r
+ ABORT(fp->fs, FR_DISK_ERR);\r
+#else\r
+ if (fp->flag & FA__DIRTY) { /* Write-back sector cache */\r
+ if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)\r
+ ABORT(fp->fs, FR_DISK_ERR);\r
+ fp->flag &= ~FA__DIRTY;\r
+ }\r
+#endif\r
+ sect = clust2sect(fp->fs, fp->clust); /* Get current sector */\r
+ if (!sect) ABORT(fp->fs, FR_INT_ERR);\r
+ sect += csect;\r
+ cc = btw / SS(fp->fs); /* When remaining bytes >= sector size, */\r
+ if (cc) { /* Write maximum contiguous sectors directly */\r
+ if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */\r
+ cc = fp->fs->csize - csect;\r
+ if (disk_write(fp->fs->drv, wbuff, sect, (BYTE)cc) != RES_OK)\r
+ ABORT(fp->fs, FR_DISK_ERR);\r
+#if _FS_TINY\r
+ if (fp->fs->winsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */\r
+ mem_cpy(fp->fs->win, wbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), SS(fp->fs));\r
+ fp->fs->wflag = 0;\r
+ }\r
+#else\r
+ if (fp->dsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */\r
+ mem_cpy(fp->buf, wbuff + ((fp->dsect - sect) * SS(fp->fs)), SS(fp->fs));\r
+ fp->flag &= ~FA__DIRTY;\r
+ }\r
+#endif\r
+ wcnt = SS(fp->fs) * cc; /* Number of bytes transferred */\r
+ continue;\r
+ }\r
+#if _FS_TINY\r
+ if (fp->fptr >= fp->fsize) { /* Avoid silly cache filling at growing edge */\r
+ if (move_window(fp->fs, 0)) ABORT(fp->fs, FR_DISK_ERR);\r
+ fp->fs->winsect = sect;\r
+ }\r
+#else\r
+ if (fp->dsect != sect) { /* Fill sector cache with file data */\r
+ if (fp->fptr < fp->fsize &&\r
+ disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK)\r
+ ABORT(fp->fs, FR_DISK_ERR);\r
+ }\r
+#endif\r
+ fp->dsect = sect;\r
+ }\r
+ wcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs));/* Put partial sector into file I/O buffer */\r
+ if (wcnt > btw) wcnt = btw;\r
+#if _FS_TINY\r
+ if (move_window(fp->fs, fp->dsect)) /* Move sector window */\r
+ ABORT(fp->fs, FR_DISK_ERR);\r
+ mem_cpy(&fp->fs->win[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */\r
+ fp->fs->wflag = 1;\r
+#else\r
+ mem_cpy(&fp->buf[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */\r
+ fp->flag |= FA__DIRTY;\r
+#endif\r
+ }\r
+\r
+ if (fp->fptr > fp->fsize) fp->fsize = fp->fptr; /* Update file size if needed */\r
+ fp->flag |= FA__WRITTEN; /* Set file change flag */\r
+\r
+ LEAVE_FF(fp->fs, FR_OK);\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Synchronize the File Object */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT f_sync (\r
+ FIL *fp /* Pointer to the file object */\r
+)\r
+{\r
+ FRESULT res;\r
+ DWORD tim;\r
+ BYTE *dir;\r
+\r
+\r
+ res = validate(fp->fs, fp->id); /* Check validity of the object */\r
+ if (res == FR_OK) {\r
+ if (fp->flag & FA__WRITTEN) { /* Has the file been written? */\r
+#if !_FS_TINY /* Write-back dirty buffer */\r
+ if (fp->flag & FA__DIRTY) {\r
+ if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)\r
+ LEAVE_FF(fp->fs, FR_DISK_ERR);\r
+ fp->flag &= ~FA__DIRTY;\r
+ }\r
+#endif\r
+ /* Update the directory entry */\r
+ res = move_window(fp->fs, fp->dir_sect);\r
+ if (res == FR_OK) {\r
+ dir = fp->dir_ptr;\r
+ dir[DIR_Attr] |= AM_ARC; /* Set archive bit */\r
+ ST_DWORD(dir+DIR_FileSize, fp->fsize); /* Update file size */\r
+ ST_CLUST(dir, fp->sclust); /* Update start cluster */\r
+ tim = get_fattime(); /* Update updated time */\r
+ ST_DWORD(dir+DIR_WrtTime, tim);\r
+ fp->flag &= ~FA__WRITTEN;\r
+ fp->fs->wflag = 1;\r
+ res = sync(fp->fs);\r
+ }\r
+ }\r
+ }\r
+\r
+ LEAVE_FF(fp->fs, res);\r
+}\r
+\r
+#endif /* !_FS_READONLY */\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Close File */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT f_close (\r
+ FIL *fp /* Pointer to the file object to be closed */\r
+)\r
+{\r
+ FRESULT res;\r
+\r
+#if _FS_READONLY\r
+ FATFS *fs = fp->fs;\r
+ res = validate(fs, fp->id);\r
+ if (res == FR_OK) fp->fs = 0; /* Discard file object */\r
+ LEAVE_FF(fs, res);\r
+\r
+#else\r
+ res = f_sync(fp); /* Flush cached data */\r
+#if _FS_SHARE\r
+ if (res == FR_OK) { /* Decrement open counter */\r
+#if _FS_REENTRANT\r
+ res = validate(fp->fs, fp->id);\r
+ if (res == FR_OK) {\r
+ res = dec_lock(fp->lockid); \r
+ unlock_fs(fp->fs, FR_OK);\r
+ }\r
+#else\r
+ res = dec_lock(fp->lockid);\r
+#endif\r
+ }\r
+#endif\r
+ if (res == FR_OK) fp->fs = 0; /* Discard file object */\r
+ return res;\r
+#endif\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Current Drive/Directory Handlings */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+#if _FS_RPATH >= 1\r
+\r
+FRESULT f_chdrive (\r
+ BYTE drv /* Drive number */\r
+)\r
+{\r
+ if (drv >= _VOLUMES) return FR_INVALID_DRIVE;\r
+\r
+ CurrVol = drv;\r
+\r
+ return FR_OK;\r
+}\r
+\r
+\r
+\r
+FRESULT f_chdir (\r
+ const TCHAR *path /* Pointer to the directory path */\r
+)\r
+{\r
+ FRESULT res;\r
+ DIR dj;\r
+ DEF_NAMEBUF;\r
+\r
+\r
+ res = chk_mounted(&path, &dj.fs, 0);\r
+ if (res == FR_OK) {\r
+ INIT_BUF(dj);\r
+ res = follow_path(&dj, path); /* Follow the path */\r
+ FREE_BUF();\r
+ if (res == FR_OK) { /* Follow completed */\r
+ if (!dj.dir) {\r
+ dj.fs->cdir = dj.sclust; /* Start directory itself */\r
+ } else {\r
+ if (dj.dir[DIR_Attr] & AM_DIR) /* Reached to the directory */\r
+ dj.fs->cdir = LD_CLUST(dj.dir);\r
+ else\r
+ res = FR_NO_PATH; /* Reached but a file */\r
+ }\r
+ }\r
+ if (res == FR_NO_FILE) res = FR_NO_PATH;\r
+ }\r
+\r
+ LEAVE_FF(dj.fs, res);\r
+}\r
+\r
+\r
+#if _FS_RPATH >= 2\r
+FRESULT f_getcwd (\r
+ TCHAR *path, /* Pointer to the directory path */\r
+ UINT sz_path /* Size of path */\r
+)\r
+{\r
+ FRESULT res;\r
+ DIR dj;\r
+ UINT i, n;\r
+ DWORD ccl;\r
+ TCHAR *tp;\r
+ FILINFO fno;\r
+ DEF_NAMEBUF;\r
+\r
+\r
+ *path = 0;\r
+ res = chk_mounted((const TCHAR**)&path, &dj.fs, 0); /* Get current volume */\r
+ if (res == FR_OK) {\r
+ INIT_BUF(dj);\r
+ i = sz_path; /* Bottom of buffer (dir stack base) */\r
+ dj.sclust = dj.fs->cdir; /* Start to follow upper dir from current dir */\r
+ while ((ccl = dj.sclust) != 0) { /* Repeat while current dir is a sub-dir */\r
+ res = dir_sdi(&dj, 1); /* Get parent dir */\r
+ if (res != FR_OK) break;\r
+ res = dir_read(&dj);\r
+ if (res != FR_OK) break;\r
+ dj.sclust = LD_CLUST(dj.dir); /* Goto parent dir */\r
+ res = dir_sdi(&dj, 0);\r
+ if (res != FR_OK) break;\r
+ do { /* Find the entry links to the child dir */\r
+ res = dir_read(&dj);\r
+ if (res != FR_OK) break;\r
+ if (ccl == LD_CLUST(dj.dir)) break; /* Found the entry */\r
+ res = dir_next(&dj, 0); \r
+ } while (res == FR_OK);\r
+ if (res == FR_NO_FILE) res = FR_INT_ERR;/* It cannot be 'not found'. */\r
+ if (res != FR_OK) break;\r
+#if _USE_LFN\r
+ fno.lfname = path;\r
+ fno.lfsize = i;\r
+#endif\r
+ get_fileinfo(&dj, &fno); /* Get the dir name and push it to the buffer */\r
+ tp = fno.fname;\r
+ if (_USE_LFN && *path) tp = path;\r
+ for (n = 0; tp[n]; n++) ;\r
+ if (i < n + 3) {\r
+ res = FR_NOT_ENOUGH_CORE; break;\r
+ }\r
+ while (n) path[--i] = tp[--n];\r
+ path[--i] = '/';\r
+ }\r
+ tp = path;\r
+ if (res == FR_OK) {\r
+ *tp++ = '0' + CurrVol; /* Put drive number */\r
+ *tp++ = ':';\r
+ if (i == sz_path) { /* Root-dir */\r
+ *tp++ = '/';\r
+ } else { /* Sub-dir */\r
+ do /* Add stacked path str */\r
+ *tp++ = path[i++];\r
+ while (i < sz_path);\r
+ }\r
+ }\r
+ *tp = 0;\r
+ FREE_BUF();\r
+ }\r
+\r
+ LEAVE_FF(dj.fs, res);\r
+}\r
+#endif /* _FS_RPATH >= 2 */\r
+#endif /* _FS_RPATH >= 1 */\r
+\r
+\r
+\r
+#if _FS_MINIMIZE <= 2\r
+/*-----------------------------------------------------------------------*/\r
+/* Seek File R/W Pointer */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT f_lseek (\r
+ FIL *fp, /* Pointer to the file object */\r
+ DWORD ofs /* File pointer from top of file */\r
+)\r
+{\r
+ FRESULT res;\r
+\r
+\r
+ res = validate(fp->fs, fp->id); /* Check validity of the object */\r
+ if (res != FR_OK) LEAVE_FF(fp->fs, res);\r
+ if (fp->flag & FA__ERROR) /* Check abort flag */\r
+ LEAVE_FF(fp->fs, FR_INT_ERR);\r
+\r
+#if _USE_FASTSEEK\r
+ if (fp->cltbl) { /* Fast seek */\r
+ DWORD cl, pcl, ncl, tcl, dsc, tlen, ulen, *tbl;\r
+\r
+ if (ofs == CREATE_LINKMAP) { /* Create CLMT */\r
+ tbl = fp->cltbl;\r
+ tlen = *tbl++; ulen = 2; /* Given table size and required table size */\r
+ cl = fp->sclust; /* Top of the chain */\r
+ if (cl) {\r
+ do {\r
+ /* Get a fragment */\r
+ tcl = cl; ncl = 0; ulen += 2; /* Top, length and used items */\r
+ do {\r
+ pcl = cl; ncl++;\r
+ cl = get_fat(fp->fs, cl);\r
+ if (cl <= 1) ABORT(fp->fs, FR_INT_ERR);\r
+ if (cl == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);\r
+ } while (cl == pcl + 1);\r
+ if (ulen <= tlen) { /* Store the length and top of the fragment */\r
+ *tbl++ = ncl; *tbl++ = tcl;\r
+ }\r
+ } while (cl < fp->fs->n_fatent); /* Repeat until end of chain */\r
+ }\r
+ *fp->cltbl = ulen; /* Number of items used */\r
+ if (ulen <= tlen)\r
+ *tbl = 0; /* Terminate table */\r
+ else\r
+ res = FR_NOT_ENOUGH_CORE; /* Given table size is smaller than required */\r
+\r
+ } else { /* Fast seek */\r
+ if (ofs > fp->fsize) /* Clip offset at the file size */\r
+ ofs = fp->fsize;\r
+ fp->fptr = ofs; /* Set file pointer */\r
+ if (ofs) {\r
+ fp->clust = clmt_clust(fp, ofs - 1);\r
+ dsc = clust2sect(fp->fs, fp->clust);\r
+ if (!dsc) ABORT(fp->fs, FR_INT_ERR);\r
+ dsc += (ofs - 1) / SS(fp->fs) & (fp->fs->csize - 1);\r
+ if (fp->fptr % SS(fp->fs) && dsc != fp->dsect) { /* Refill sector cache if needed */\r
+#if !_FS_TINY\r
+#if !_FS_READONLY\r
+ if (fp->flag & FA__DIRTY) { /* Write-back dirty sector cache */\r
+ if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)\r
+ ABORT(fp->fs, FR_DISK_ERR);\r
+ fp->flag &= ~FA__DIRTY;\r
+ }\r
+#endif\r
+ if (disk_read(fp->fs->drv, fp->buf, dsc, 1) != RES_OK) /* Load current sector */\r
+ ABORT(fp->fs, FR_DISK_ERR);\r
+#endif\r
+ fp->dsect = dsc;\r
+ }\r
+ }\r
+ }\r
+ } else\r
+#endif\r
+\r
+ /* Normal Seek */\r
+ {\r
+ DWORD clst, bcs, nsect, ifptr;\r
+\r
+ if (ofs > fp->fsize /* In read-only mode, clip offset with the file size */\r
+#if !_FS_READONLY\r
+ && !(fp->flag & FA_WRITE)\r
+#endif\r
+ ) ofs = fp->fsize;\r
+\r
+ ifptr = fp->fptr;\r
+ fp->fptr = nsect = 0;\r
+ if (ofs) {\r
+ bcs = (DWORD)fp->fs->csize * SS(fp->fs); /* Cluster size (byte) */\r
+ if (ifptr > 0 &&\r
+ (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */\r
+ fp->fptr = (ifptr - 1) & ~(bcs - 1); /* start from the current cluster */\r
+ ofs -= fp->fptr;\r
+ clst = fp->clust;\r
+ } else { /* When seek to back cluster, */\r
+ clst = fp->sclust; /* start from the first cluster */\r
+#if !_FS_READONLY\r
+ if (clst == 0) { /* If no cluster chain, create a new chain */\r
+ clst = create_chain(fp->fs, 0);\r
+ if (clst == 1) ABORT(fp->fs, FR_INT_ERR);\r
+ if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);\r
+ fp->sclust = clst;\r
+ }\r
+#endif\r
+ fp->clust = clst;\r
+ }\r
+ if (clst != 0) {\r
+ while (ofs > bcs) { /* Cluster following loop */\r
+#if !_FS_READONLY\r
+ if (fp->flag & FA_WRITE) { /* Check if in write mode or not */\r
+ clst = create_chain(fp->fs, clst); /* Force stretch if in write mode */\r
+ if (clst == 0) { /* When disk gets full, clip file size */\r
+ ofs = bcs; break;\r
+ }\r
+ } else\r
+#endif\r
+ clst = get_fat(fp->fs, clst); /* Follow cluster chain if not in write mode */\r
+ if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);\r
+ if (clst <= 1 || clst >= fp->fs->n_fatent) ABORT(fp->fs, FR_INT_ERR);\r
+ fp->clust = clst;\r
+ fp->fptr += bcs;\r
+ ofs -= bcs;\r
+ }\r
+ fp->fptr += ofs;\r
+ if (ofs % SS(fp->fs)) {\r
+ nsect = clust2sect(fp->fs, clst); /* Current sector */\r
+ if (!nsect) ABORT(fp->fs, FR_INT_ERR);\r
+ nsect += ofs / SS(fp->fs);\r
+ }\r
+ }\r
+ }\r
+ if (fp->fptr % SS(fp->fs) && nsect != fp->dsect) { /* Fill sector cache if needed */\r
+#if !_FS_TINY\r
+#if !_FS_READONLY\r
+ if (fp->flag & FA__DIRTY) { /* Write-back dirty sector cache */\r
+ if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)\r
+ ABORT(fp->fs, FR_DISK_ERR);\r
+ fp->flag &= ~FA__DIRTY;\r
+ }\r
+#endif\r
+ if (disk_read(fp->fs->drv, fp->buf, nsect, 1) != RES_OK) /* Fill sector cache */\r
+ ABORT(fp->fs, FR_DISK_ERR);\r
+#endif\r
+ fp->dsect = nsect;\r
+ }\r
+#if !_FS_READONLY\r
+ if (fp->fptr > fp->fsize) { /* Set file change flag if the file size is extended */\r
+ fp->fsize = fp->fptr;\r
+ fp->flag |= FA__WRITTEN;\r
+ }\r
+#endif\r
+ }\r
+\r
+ LEAVE_FF(fp->fs, res);\r
+}\r
+\r
+\r
+\r
+#if _FS_MINIMIZE <= 1\r
+/*-----------------------------------------------------------------------*/\r
+/* Create a Directroy Object */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT f_opendir (\r
+ DIR *dj, /* Pointer to directory object to create */\r
+ const TCHAR *path /* Pointer to the directory path */\r
+)\r
+{\r
+ FRESULT res;\r
+ DEF_NAMEBUF;\r
+\r
+\r
+ res = chk_mounted(&path, &dj->fs, 0);\r
+ if (res == FR_OK) {\r
+ INIT_BUF(*dj);\r
+ res = follow_path(dj, path); /* Follow the path to the directory */\r
+ FREE_BUF();\r
+ if (res == FR_OK) { /* Follow completed */\r
+ if (dj->dir) { /* It is not the root dir */\r
+ if (dj->dir[DIR_Attr] & AM_DIR) { /* The object is a directory */\r
+ dj->sclust = LD_CLUST(dj->dir);\r
+ } else { /* The object is not a directory */\r
+ res = FR_NO_PATH;\r
+ }\r
+ }\r
+ if (res == FR_OK) {\r
+ dj->id = dj->fs->id;\r
+ res = dir_sdi(dj, 0); /* Rewind dir */\r
+ }\r
+ }\r
+ if (res == FR_NO_FILE) res = FR_NO_PATH;\r
+ }\r
+\r
+ LEAVE_FF(dj->fs, res);\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Read Directory Entry in Sequense */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT f_readdir (\r
+ DIR *dj, /* Pointer to the open directory object */\r
+ FILINFO *fno /* Pointer to file information to return */\r
+)\r
+{\r
+ FRESULT res;\r
+ DEF_NAMEBUF;\r
+\r
+\r
+ res = validate(dj->fs, dj->id); /* Check validity of the object */\r
+ if (res == FR_OK) {\r
+ if (!fno) {\r
+ res = dir_sdi(dj, 0); /* Rewind the directory object */\r
+ } else {\r
+ INIT_BUF(*dj);\r
+ res = dir_read(dj); /* Read an directory item */\r
+ if (res == FR_NO_FILE) { /* Reached end of dir */\r
+ dj->sect = 0;\r
+ res = FR_OK;\r
+ }\r
+ if (res == FR_OK) { /* A valid entry is found */\r
+ get_fileinfo(dj, fno); /* Get the object information */\r
+ res = dir_next(dj, 0); /* Increment index for next */\r
+ if (res == FR_NO_FILE) {\r
+ dj->sect = 0;\r
+ res = FR_OK;\r
+ }\r
+ }\r
+ FREE_BUF();\r
+ }\r
+ }\r
+\r
+ LEAVE_FF(dj->fs, res);\r
+}\r
+\r
+\r
+\r
+#if _FS_MINIMIZE == 0\r
+/*-----------------------------------------------------------------------*/\r
+/* Get File Status */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT f_stat (\r
+ const TCHAR *path, /* Pointer to the file path */\r
+ FILINFO *fno /* Pointer to file information to return */\r
+)\r
+{\r
+ FRESULT res;\r
+ DIR dj;\r
+ DEF_NAMEBUF;\r
+\r
+\r
+ res = chk_mounted(&path, &dj.fs, 0);\r
+ if (res == FR_OK) {\r
+ INIT_BUF(dj);\r
+ res = follow_path(&dj, path); /* Follow the file path */\r
+ if (res == FR_OK) { /* Follow completed */\r
+ if (dj.dir) /* Found an object */\r
+ get_fileinfo(&dj, fno);\r
+ else /* It is root dir */\r
+ res = FR_INVALID_NAME;\r
+ }\r
+ FREE_BUF();\r
+ }\r
+\r
+ LEAVE_FF(dj.fs, res);\r
+}\r
+\r
+\r
+\r
+#if !_FS_READONLY\r
+/*-----------------------------------------------------------------------*/\r
+/* Get Number of Free Clusters */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT f_getfree (\r
+ const TCHAR *path, /* Pointer to the logical drive number (root dir) */\r
+ DWORD *nclst, /* Pointer to the variable to return number of free clusters */\r
+ FATFS **fatfs /* Pointer to pointer to corresponding file system object to return */\r
+)\r
+{\r
+ FRESULT res;\r
+ DWORD n, clst, sect, stat;\r
+ UINT i;\r
+ BYTE fat, *p;\r
+\r
+\r
+ /* Get drive number */\r
+ res = chk_mounted(&path, fatfs, 0);\r
+ if (res == FR_OK) {\r
+ /* If free_clust is valid, return it without full cluster scan */\r
+ if ((*fatfs)->free_clust <= (*fatfs)->n_fatent - 2) {\r
+ *nclst = (*fatfs)->free_clust;\r
+ } else {\r
+ /* Get number of free clusters */\r
+ fat = (*fatfs)->fs_type;\r
+ n = 0;\r
+ if (fat == FS_FAT12) {\r
+ clst = 2;\r
+ do {\r
+ stat = get_fat(*fatfs, clst);\r
+ if (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; }\r
+ if (stat == 1) { res = FR_INT_ERR; break; }\r
+ if (stat == 0) n++;\r
+ } while (++clst < (*fatfs)->n_fatent);\r
+ } else {\r
+ clst = (*fatfs)->n_fatent;\r
+ sect = (*fatfs)->fatbase;\r
+ i = 0; p = 0;\r
+ do {\r
+ if (!i) {\r
+ res = move_window(*fatfs, sect++);\r
+ if (res != FR_OK) break;\r
+ p = (*fatfs)->win;\r
+ i = SS(*fatfs);\r
+ }\r
+ if (fat == FS_FAT16) {\r
+ if (LD_WORD(p) == 0) n++;\r
+ p += 2; i -= 2;\r
+ } else {\r
+ if ((LD_DWORD(p) & 0x0FFFFFFF) == 0) n++;\r
+ p += 4; i -= 4;\r
+ }\r
+ } while (--clst);\r
+ }\r
+ (*fatfs)->free_clust = n;\r
+ if (fat == FS_FAT32) (*fatfs)->fsi_flag = 1;\r
+ *nclst = n;\r
+ }\r
+ }\r
+ LEAVE_FF(*fatfs, res);\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Truncate File */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT f_truncate (\r
+ FIL *fp /* Pointer to the file object */\r
+)\r
+{\r
+ FRESULT res;\r
+ DWORD ncl;\r
+\r
+\r
+ res = validate(fp->fs, fp->id); /* Check validity of the object */\r
+ if (res == FR_OK) {\r
+ if (fp->flag & FA__ERROR) { /* Check abort flag */\r
+ res = FR_INT_ERR;\r
+ } else {\r
+ if (!(fp->flag & FA_WRITE)) /* Check access mode */\r
+ res = FR_DENIED;\r
+ }\r
+ }\r
+ if (res == FR_OK) {\r
+ if (fp->fsize > fp->fptr) {\r
+ fp->fsize = fp->fptr; /* Set file size to current R/W point */\r
+ fp->flag |= FA__WRITTEN;\r
+ if (fp->fptr == 0) { /* When set file size to zero, remove entire cluster chain */\r
+ res = remove_chain(fp->fs, fp->sclust);\r
+ fp->sclust = 0;\r
+ } else { /* When truncate a part of the file, remove remaining clusters */\r
+ ncl = get_fat(fp->fs, fp->clust);\r
+ res = FR_OK;\r
+ if (ncl == 0xFFFFFFFF) res = FR_DISK_ERR;\r
+ if (ncl == 1) res = FR_INT_ERR;\r
+ if (res == FR_OK && ncl < fp->fs->n_fatent) {\r
+ res = put_fat(fp->fs, fp->clust, 0x0FFFFFFF);\r
+ if (res == FR_OK) res = remove_chain(fp->fs, ncl);\r
+ }\r
+ }\r
+ }\r
+ if (res != FR_OK) fp->flag |= FA__ERROR;\r
+ }\r
+\r
+ LEAVE_FF(fp->fs, res);\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Delete a File or Directory */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT f_unlink (\r
+ const TCHAR *path /* Pointer to the file or directory path */\r
+)\r
+{\r
+ FRESULT res;\r
+ DIR dj, sdj;\r
+ BYTE *dir;\r
+ DWORD dclst;\r
+ DEF_NAMEBUF;\r
+\r
+\r
+ res = chk_mounted(&path, &dj.fs, 1);\r
+ if (res == FR_OK) {\r
+ INIT_BUF(dj);\r
+ res = follow_path(&dj, path); /* Follow the file path */\r
+ if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT))\r
+ res = FR_INVALID_NAME; /* Cannot remove dot entry */\r
+#if _FS_SHARE\r
+ if (res == FR_OK) res = chk_lock(&dj, 2); /* Cannot remove open file */\r
+#endif\r
+ if (res == FR_OK) { /* The object is accessible */\r
+ dir = dj.dir;\r
+ if (!dir) {\r
+ res = FR_INVALID_NAME; /* Cannot remove the start directory */\r
+ } else {\r
+ if (dir[DIR_Attr] & AM_RDO)\r
+ res = FR_DENIED; /* Cannot remove R/O object */\r
+ }\r
+ dclst = LD_CLUST(dir);\r
+ if (res == FR_OK && (dir[DIR_Attr] & AM_DIR)) { /* Is it a sub-dir? */\r
+ if (dclst < 2) {\r
+ res = FR_INT_ERR;\r
+ } else {\r
+ mem_cpy(&sdj, &dj, sizeof(DIR)); /* Check if the sub-dir is empty or not */\r
+ sdj.sclust = dclst;\r
+ res = dir_sdi(&sdj, 2); /* Exclude dot entries */\r
+ if (res == FR_OK) {\r
+ res = dir_read(&sdj);\r
+ if (res == FR_OK /* Not empty dir */\r
+#if _FS_RPATH\r
+ || dclst == sdj.fs->cdir /* Current dir */\r
+#endif\r
+ ) res = FR_DENIED;\r
+ if (res == FR_NO_FILE) res = FR_OK; /* Empty */\r
+ }\r
+ }\r
+ }\r
+ if (res == FR_OK) {\r
+ res = dir_remove(&dj); /* Remove the directory entry */\r
+ if (res == FR_OK) {\r
+ if (dclst) /* Remove the cluster chain if exist */\r
+ res = remove_chain(dj.fs, dclst);\r
+ if (res == FR_OK) res = sync(dj.fs);\r
+ }\r
+ }\r
+ }\r
+ FREE_BUF();\r
+ }\r
+ LEAVE_FF(dj.fs, res);\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Create a Directory */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT f_mkdir (\r
+ const TCHAR *path /* Pointer to the directory path */\r
+)\r
+{\r
+ FRESULT res;\r
+ DIR dj;\r
+ BYTE *dir, n;\r
+ DWORD dsc, dcl, pcl, tim = get_fattime();\r
+ DEF_NAMEBUF;\r
+\r
+\r
+ res = chk_mounted(&path, &dj.fs, 1);\r
+ if (res == FR_OK) {\r
+ INIT_BUF(dj);\r
+ res = follow_path(&dj, path); /* Follow the file path */\r
+ if (res == FR_OK) res = FR_EXIST; /* Any object with same name is already existing */\r
+ if (_FS_RPATH && res == FR_NO_FILE && (dj.fn[NS] & NS_DOT))\r
+ res = FR_INVALID_NAME;\r
+ if (res == FR_NO_FILE) { /* Can create a new directory */\r
+ dcl = create_chain(dj.fs, 0); /* Allocate a cluster for the new directory table */\r
+ res = FR_OK;\r
+ if (dcl == 0) res = FR_DENIED; /* No space to allocate a new cluster */\r
+ if (dcl == 1) res = FR_INT_ERR;\r
+ if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR;\r
+ if (res == FR_OK) /* Flush FAT */\r
+ res = move_window(dj.fs, 0);\r
+ if (res == FR_OK) { /* Initialize the new directory table */\r
+ dsc = clust2sect(dj.fs, dcl);\r
+ dir = dj.fs->win;\r
+ mem_set(dir, 0, SS(dj.fs));\r
+ mem_set(dir+DIR_Name, ' ', 8+3); /* Create "." entry */\r
+ dir[DIR_Name] = '.';\r
+ dir[DIR_Attr] = AM_DIR;\r
+ ST_DWORD(dir+DIR_WrtTime, tim);\r
+ ST_CLUST(dir, dcl);\r
+ mem_cpy(dir+SZ_DIR, dir, SZ_DIR); /* Create ".." entry */\r
+ dir[33] = '.'; pcl = dj.sclust;\r
+ if (dj.fs->fs_type == FS_FAT32 && pcl == dj.fs->dirbase)\r
+ pcl = 0;\r
+ ST_CLUST(dir+SZ_DIR, pcl);\r
+ for (n = dj.fs->csize; n; n--) { /* Write dot entries and clear following sectors */\r
+ dj.fs->winsect = dsc++;\r
+ dj.fs->wflag = 1;\r
+ res = move_window(dj.fs, 0);\r
+ if (res != FR_OK) break;\r
+ mem_set(dir, 0, SS(dj.fs));\r
+ }\r
+ }\r
+ if (res == FR_OK) res = dir_register(&dj); /* Register the object to the directoy */\r
+ if (res != FR_OK) {\r
+ remove_chain(dj.fs, dcl); /* Could not register, remove cluster chain */\r
+ } else {\r
+ dir = dj.dir;\r
+ dir[DIR_Attr] = AM_DIR; /* Attribute */\r
+ ST_DWORD(dir+DIR_WrtTime, tim); /* Created time */\r
+ ST_CLUST(dir, dcl); /* Table start cluster */\r
+ dj.fs->wflag = 1;\r
+ res = sync(dj.fs);\r
+ }\r
+ }\r
+ FREE_BUF();\r
+ }\r
+\r
+ LEAVE_FF(dj.fs, res);\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Change Attribute */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT f_chmod (\r
+ const TCHAR *path, /* Pointer to the file path */\r
+ BYTE value, /* Attribute bits */\r
+ BYTE mask /* Attribute mask to change */\r
+)\r
+{\r
+ FRESULT res;\r
+ DIR dj;\r
+ BYTE *dir;\r
+ DEF_NAMEBUF;\r
+\r
+\r
+ res = chk_mounted(&path, &dj.fs, 1);\r
+ if (res == FR_OK) {\r
+ INIT_BUF(dj);\r
+ res = follow_path(&dj, path); /* Follow the file path */\r
+ FREE_BUF();\r
+ if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT))\r
+ res = FR_INVALID_NAME;\r
+ if (res == FR_OK) {\r
+ dir = dj.dir;\r
+ if (!dir) { /* Is it a root directory? */\r
+ res = FR_INVALID_NAME;\r
+ } else { /* File or sub directory */\r
+ mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC; /* Valid attribute mask */\r
+ dir[DIR_Attr] = (value & mask) | (dir[DIR_Attr] & (BYTE)~mask); /* Apply attribute change */\r
+ dj.fs->wflag = 1;\r
+ res = sync(dj.fs);\r
+ }\r
+ }\r
+ }\r
+\r
+ LEAVE_FF(dj.fs, res);\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Change Timestamp */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT f_utime (\r
+ const TCHAR *path, /* Pointer to the file/directory name */\r
+ const FILINFO *fno /* Pointer to the time stamp to be set */\r
+)\r
+{\r
+ FRESULT res;\r
+ DIR dj;\r
+ BYTE *dir;\r
+ DEF_NAMEBUF;\r
+\r
+\r
+ res = chk_mounted(&path, &dj.fs, 1);\r
+ if (res == FR_OK) {\r
+ INIT_BUF(dj);\r
+ res = follow_path(&dj, path); /* Follow the file path */\r
+ FREE_BUF();\r
+ if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT))\r
+ res = FR_INVALID_NAME;\r
+ if (res == FR_OK) {\r
+ dir = dj.dir;\r
+ if (!dir) { /* Root directory */\r
+ res = FR_INVALID_NAME;\r
+ } else { /* File or sub-directory */\r
+ ST_WORD(dir+DIR_WrtTime, fno->ftime);\r
+ ST_WORD(dir+DIR_WrtDate, fno->fdate);\r
+ dj.fs->wflag = 1;\r
+ res = sync(dj.fs);\r
+ }\r
+ }\r
+ }\r
+\r
+ LEAVE_FF(dj.fs, res);\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Rename File/Directory */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT f_rename (\r
+ const TCHAR *path_old, /* Pointer to the old name */\r
+ const TCHAR *path_new /* Pointer to the new name */\r
+)\r
+{\r
+ FRESULT res;\r
+ DIR djo, djn;\r
+ BYTE buf[21], *dir;\r
+ DWORD dw;\r
+ DEF_NAMEBUF;\r
+\r
+\r
+ res = chk_mounted(&path_old, &djo.fs, 1);\r
+ if (res == FR_OK) {\r
+ djn.fs = djo.fs;\r
+ INIT_BUF(djo);\r
+ res = follow_path(&djo, path_old); /* Check old object */\r
+ if (_FS_RPATH && res == FR_OK && (djo.fn[NS] & NS_DOT))\r
+ res = FR_INVALID_NAME;\r
+#if _FS_SHARE\r
+ if (res == FR_OK) res = chk_lock(&djo, 2);\r
+#endif\r
+ if (res == FR_OK) { /* Old object is found */\r
+ if (!djo.dir) { /* Is root dir? */\r
+ res = FR_NO_FILE;\r
+ } else {\r
+ mem_cpy(buf, djo.dir+DIR_Attr, 21); /* Save the object information except for name */\r
+ mem_cpy(&djn, &djo, sizeof(DIR)); /* Check new object */\r
+ res = follow_path(&djn, path_new);\r
+ if (res == FR_OK) res = FR_EXIST; /* The new object name is already existing */\r
+ if (res == FR_NO_FILE) { /* Is it a valid path and no name collision? */\r
+/* Start critical section that any interruption or error can cause cross-link */\r
+ res = dir_register(&djn); /* Register the new entry */\r
+ if (res == FR_OK) {\r
+ dir = djn.dir; /* Copy object information except for name */\r
+ mem_cpy(dir+13, buf+2, 19);\r
+ dir[DIR_Attr] = buf[0] | AM_ARC;\r
+ djo.fs->wflag = 1;\r
+ if (djo.sclust != djn.sclust && (dir[DIR_Attr] & AM_DIR)) { /* Update .. entry in the directory if needed */\r
+ dw = clust2sect(djn.fs, LD_CLUST(dir));\r
+ if (!dw) {\r
+ res = FR_INT_ERR;\r
+ } else {\r
+ res = move_window(djn.fs, dw);\r
+ dir = djn.fs->win+SZ_DIR; /* .. entry */\r
+ if (res == FR_OK && dir[1] == '.') {\r
+ dw = (djn.fs->fs_type == FS_FAT32 && djn.sclust == djn.fs->dirbase) ? 0 : djn.sclust;\r
+ ST_CLUST(dir, dw);\r
+ djn.fs->wflag = 1;\r
+ }\r
+ }\r
+ }\r
+ if (res == FR_OK) {\r
+ res = dir_remove(&djo); /* Remove old entry */\r
+ if (res == FR_OK)\r
+ res = sync(djo.fs);\r
+ }\r
+ }\r
+/* End critical section */\r
+ }\r
+ }\r
+ }\r
+ FREE_BUF();\r
+ }\r
+ LEAVE_FF(djo.fs, res);\r
+}\r
+\r
+#endif /* !_FS_READONLY */\r
+#endif /* _FS_MINIMIZE == 0 */\r
+#endif /* _FS_MINIMIZE <= 1 */\r
+#endif /* _FS_MINIMIZE <= 2 */\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Forward data to the stream directly (available on only tiny cfg) */\r
+/*-----------------------------------------------------------------------*/\r
+#if _USE_FORWARD && _FS_TINY\r
+\r
+FRESULT f_forward (\r
+ FIL *fp, /* Pointer to the file object */\r
+ UINT (*func)(const BYTE*,UINT), /* Pointer to the streaming function */\r
+ UINT btr, /* Number of bytes to forward */\r
+ UINT *bf /* Pointer to number of bytes forwarded */\r
+)\r
+{\r
+ FRESULT res;\r
+ DWORD remain, clst, sect;\r
+ UINT rcnt;\r
+ BYTE csect;\r
+\r
+\r
+ *bf = 0; /* Initialize byte counter */\r
+\r
+ res = validate(fp->fs, fp->id); /* Check validity of the object */\r
+ if (res != FR_OK) LEAVE_FF(fp->fs, res);\r
+ if (fp->flag & FA__ERROR) /* Check error flag */\r
+ LEAVE_FF(fp->fs, FR_INT_ERR);\r
+ if (!(fp->flag & FA_READ)) /* Check access mode */\r
+ LEAVE_FF(fp->fs, FR_DENIED);\r
+\r
+ remain = fp->fsize - fp->fptr;\r
+ if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */\r
+\r
+ for ( ; btr && (*func)(0, 0); /* Repeat until all data transferred or stream becomes busy */\r
+ fp->fptr += rcnt, *bf += rcnt, btr -= rcnt) {\r
+ csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */\r
+ if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */\r
+ if (!csect) { /* On the cluster boundary? */\r
+ clst = (fp->fptr == 0) ? /* On the top of the file? */\r
+ fp->sclust : get_fat(fp->fs, fp->clust);\r
+ if (clst <= 1) ABORT(fp->fs, FR_INT_ERR);\r
+ if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);\r
+ fp->clust = clst; /* Update current cluster */\r
+ }\r
+ }\r
+ sect = clust2sect(fp->fs, fp->clust); /* Get current data sector */\r
+ if (!sect) ABORT(fp->fs, FR_INT_ERR);\r
+ sect += csect;\r
+ if (move_window(fp->fs, sect)) /* Move sector window */\r
+ ABORT(fp->fs, FR_DISK_ERR);\r
+ fp->dsect = sect;\r
+ rcnt = SS(fp->fs) - (WORD)(fp->fptr % SS(fp->fs)); /* Forward data from sector window */\r
+ if (rcnt > btr) rcnt = btr;\r
+ rcnt = (*func)(&fp->fs->win[(WORD)fp->fptr % SS(fp->fs)], rcnt);\r
+ if (!rcnt) ABORT(fp->fs, FR_INT_ERR);\r
+ }\r
+\r
+ LEAVE_FF(fp->fs, FR_OK);\r
+}\r
+#endif /* _USE_FORWARD */\r
+\r
+\r
+\r
+#if _USE_MKFS && !_FS_READONLY\r
+/*-----------------------------------------------------------------------*/\r
+/* Create File System on the Drive */\r
+/*-----------------------------------------------------------------------*/\r
+#define N_ROOTDIR 512 /* Number of root dir entries for FAT12/16 */\r
+#define N_FATS 1 /* Number of FAT copies (1 or 2) */\r
+\r
+\r
+FRESULT f_mkfs (\r
+ BYTE drv, /* Logical drive number */\r
+ BYTE sfd, /* Partitioning rule 0:FDISK, 1:SFD */\r
+ UINT au /* Allocation unit size [bytes] */\r
+)\r
+{\r
+ static const WORD vst[] = { 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 0};\r
+ static const WORD cst[] = {32768, 16384, 8192, 4096, 2048, 16384, 8192, 4096, 2048, 1024, 512};\r
+ BYTE fmt, md, *tbl;\r
+ DWORD n_clst, vs, n, wsect;\r
+ UINT i;\r
+ DWORD b_vol, b_fat, b_dir, b_data; /* Offset (LBA) */\r
+ DWORD n_vol, n_rsv, n_fat, n_dir; /* Size */\r
+ FATFS *fs;\r
+ DSTATUS stat;\r
+\r
+\r
+ /* Check mounted drive and clear work area */\r
+ if (drv >= _VOLUMES) return FR_INVALID_DRIVE;\r
+ fs = FatFs[drv];\r
+ if (!fs) return FR_NOT_ENABLED;\r
+ fs->fs_type = 0;\r
+ drv = LD2PD(drv);\r
+\r
+ /* Get disk statics */\r
+ stat = disk_initialize(drv);\r
+ if (stat & STA_NOINIT) return FR_NOT_READY;\r
+ if (stat & STA_PROTECT) return FR_WRITE_PROTECTED;\r
+#if _MAX_SS != 512 /* Get disk sector size */\r
+ if (disk_ioctl(drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK)\r
+ return FR_DISK_ERR;\r
+#endif\r
+ if (disk_ioctl(drv, GET_SECTOR_COUNT, &n_vol) != RES_OK || n_vol < 128)\r
+ return FR_DISK_ERR;\r
+ b_vol = (sfd) ? 0 : 63; /* Volume start sector */\r
+ n_vol -= b_vol;\r
+ if (au & (au - 1)) au = 0; /* Check validity of the AU size */\r
+ if (!au) { /* AU auto selection */\r
+ vs = n_vol / (2000 / (SS(fs) / 512));\r
+ for (i = 0; vs < vst[i]; i++) ;\r
+ au = cst[i];\r
+ }\r
+ au /= SS(fs); /* Number of sectors per cluster */\r
+ if (au == 0) au = 1;\r
+ if (au > 128) au = 128;\r
+\r
+ /* Pre-compute number of clusters and FAT syb-type */\r
+ n_clst = n_vol / au;\r
+ fmt = FS_FAT12;\r
+ if (n_clst >= MIN_FAT16) fmt = FS_FAT16;\r
+ if (n_clst >= MIN_FAT32) fmt = FS_FAT32;\r
+\r
+ /* Determine offset and size of FAT structure */\r
+ if (fmt == FS_FAT32) {\r
+ n_fat = ((n_clst * 4) + 8 + SS(fs) - 1) / SS(fs);\r
+ n_rsv = 32;\r
+ n_dir = 0;\r
+ } else {\r
+ n_fat = (fmt == FS_FAT12) ? (n_clst * 3 + 1) / 2 + 3 : (n_clst * 2) + 4;\r
+ n_fat = (n_fat + SS(fs) - 1) / SS(fs);\r
+ n_rsv = 1;\r
+ n_dir = (DWORD)N_ROOTDIR * SZ_DIR / SS(fs);\r
+ }\r
+ b_fat = b_vol + n_rsv; /* FAT area start sector */\r
+ b_dir = b_fat + n_fat * N_FATS; /* Directory area start sector */\r
+ b_data = b_dir + n_dir; /* Data area start sector */\r
+ if (n_vol < b_data + au) return FR_MKFS_ABORTED; /* Too small volume */\r
+\r
+ /* Align data start sector to erase block boundary (for flash memory media) */\r
+ if (disk_ioctl(drv, GET_BLOCK_SIZE, &n) != RES_OK || !n || n > 32768) n = 1;\r
+ n = (b_data + n - 1) & ~(n - 1); /* Next nearest erase block from current data start */\r
+ n = (n - b_data) / N_FATS;\r
+ if (fmt == FS_FAT32) { /* FAT32: Move FAT offset */\r
+ n_rsv += n;\r
+ b_fat += n;\r
+ } else { /* FAT12/16: Expand FAT size */\r
+ n_fat += n;\r
+ }\r
+\r
+ /* Determine number of clusters and final check of validity of the FAT sub-type */\r
+ n_clst = (n_vol - n_rsv - n_fat * N_FATS - n_dir) / au;\r
+ if ( (fmt == FS_FAT16 && n_clst < MIN_FAT16)\r
+ || (fmt == FS_FAT32 && n_clst < MIN_FAT32))\r
+ return FR_MKFS_ABORTED;\r
+\r
+ /* Create partition table if required */\r
+ if (sfd) { /* No patition table (SFD) */\r
+ md = 0xF0;\r
+ } else { /* With patition table (FDISK) */\r
+ DWORD n_disk = b_vol + n_vol;\r
+\r
+ mem_set(fs->win, 0, SS(fs));\r
+ tbl = fs->win+MBR_Table;\r
+ ST_DWORD(tbl, 0x00010180); /* Partition start in CHS */\r
+ if (n_disk < 63UL * 255 * 1024) { /* Partition end in CHS */\r
+ n_disk = n_disk / 63 / 255;\r
+ tbl[7] = (BYTE)n_disk;\r
+ tbl[6] = (BYTE)((n_disk >> 2) | 63);\r
+ } else {\r
+ ST_WORD(&tbl[6], 0xFFFF); /* CHS saturated */\r
+ }\r
+ tbl[5] = 254;\r
+ if (fmt != FS_FAT32) /* System ID */\r
+ tbl[4] = (n_vol < 0x10000) ? 0x04 : 0x06;\r
+ else\r
+ tbl[4] = 0x0c;\r
+ ST_DWORD(tbl+8, 63); /* Partition start in LBA */\r
+ ST_DWORD(tbl+12, n_vol); /* Partition size in LBA */\r
+ ST_WORD(fs->win+BS_55AA, 0xAA55); /* MBR signature */\r
+ if (disk_write(drv, fs->win, 0, 1) != RES_OK) /* Put the MBR into first physical sector */\r
+ return FR_DISK_ERR;\r
+ md = 0xF8;\r
+ }\r
+\r
+ /* Create volume boot record */\r
+ tbl = fs->win; /* Clear sector */\r
+ mem_set(tbl, 0, SS(fs));\r
+ mem_cpy(tbl, "\xEB\xFE\x90" "MSDOS5.0", 11);/* Boot jump code, OEM name */\r
+ i = SS(fs); /* Sector size */\r
+ ST_WORD(tbl+BPB_BytsPerSec, i);\r
+ tbl[BPB_SecPerClus] = (BYTE)au; /* Sectors per cluster */\r
+ ST_WORD(tbl+BPB_RsvdSecCnt, n_rsv); /* Reserved sectors */\r
+ tbl[BPB_NumFATs] = N_FATS; /* Number of FATs */\r
+ i = (fmt == FS_FAT32) ? 0 : N_ROOTDIR; /* Number of rootdir entries */\r
+ ST_WORD(tbl+BPB_RootEntCnt, i);\r
+ if (n_vol < 0x10000) { /* Number of total sectors */\r
+ ST_WORD(tbl+BPB_TotSec16, n_vol);\r
+ } else {\r
+ ST_DWORD(tbl+BPB_TotSec32, n_vol);\r
+ }\r
+ tbl[BPB_Media] = md; /* Media descriptor */\r
+ ST_WORD(tbl+BPB_SecPerTrk, 63); /* Number of sectors per track */\r
+ ST_WORD(tbl+BPB_NumHeads, 255); /* Number of heads */\r
+ ST_DWORD(tbl+BPB_HiddSec, b_vol); /* Hidden sectors */\r
+ n = get_fattime(); /* Use current time as VSN */\r
+ if (fmt == FS_FAT32) {\r
+ ST_DWORD(tbl+BS_VolID32, n); /* VSN */\r
+ ST_DWORD(tbl+BPB_FATSz32, n_fat); /* Number of sectors per FAT */\r
+ ST_DWORD(tbl+BPB_RootClus, 2); /* Root directory start cluster (2) */\r
+ ST_WORD(tbl+BPB_FSInfo, 1); /* FSInfo record offset (VBR+1) */\r
+ ST_WORD(tbl+BPB_BkBootSec, 6); /* Backup boot record offset (VBR+6) */\r
+ tbl[BS_DrvNum32] = 0x80; /* Drive number */\r
+ tbl[BS_BootSig32] = 0x29; /* Extended boot signature */\r
+ mem_cpy(tbl+BS_VolLab32, "NO NAME " "FAT32 ", 19); /* Volume label, FAT signature */\r
+ } else {\r
+ ST_DWORD(tbl+BS_VolID, n); /* VSN */\r
+ ST_WORD(tbl+BPB_FATSz16, n_fat); /* Number of sectors per FAT */\r
+ tbl[BS_DrvNum] = 0x80; /* Drive number */\r
+ tbl[BS_BootSig] = 0x29; /* Extended boot signature */\r
+ mem_cpy(tbl+BS_VolLab, "NO NAME " "FAT ", 19); /* Volume label, FAT signature */\r
+ }\r
+ ST_WORD(tbl+BS_55AA, 0xAA55); /* Signature (Offset is fixed here regardless of sector size) */\r
+ if (disk_write(drv, tbl, b_vol, 1) != RES_OK) /* Write VBR */\r
+ return FR_DISK_ERR;\r
+ if (fmt == FS_FAT32) /* Write backup VBR if needed (VBR+6) */\r
+ disk_write(drv, tbl, b_vol + 6, 1);\r
+\r
+ /* Initialize FAT area */\r
+ wsect = b_fat;\r
+ for (i = 0; i < N_FATS; i++) { /* Initialize each FAT copy */\r
+ mem_set(tbl, 0, SS(fs)); /* 1st sector of the FAT */\r
+ n = md; /* Media descriptor byte */\r
+ if (fmt != FS_FAT32) {\r
+ n |= (fmt == FS_FAT12) ? 0x00FFFF00 : 0xFFFFFF00;\r
+ ST_DWORD(tbl+0, n); /* Reserve cluster #0-1 (FAT12/16) */\r
+ } else {\r
+ n |= 0xFFFFFF00;\r
+ ST_DWORD(tbl+0, n); /* Reserve cluster #0-1 (FAT32) */\r
+ ST_DWORD(tbl+4, 0xFFFFFFFF);\r
+ ST_DWORD(tbl+8, 0x0FFFFFFF); /* Reserve cluster #2 for root dir */\r
+ }\r
+ if (disk_write(drv, tbl, wsect++, 1) != RES_OK)\r
+ return FR_DISK_ERR;\r
+ mem_set(tbl, 0, SS(fs)); /* Fill following FAT entries with zero */\r
+ for (n = 1; n < n_fat; n++) { /* This loop may take a time on FAT32 volume due to many single sector writes */\r
+ if (disk_write(drv, tbl, wsect++, 1) != RES_OK)\r
+ return FR_DISK_ERR;\r
+ }\r
+ }\r
+\r
+ /* Initialize root directory */\r
+ i = (fmt == FS_FAT32) ? au : n_dir;\r
+ do {\r
+ if (disk_write(drv, tbl, wsect++, 1) != RES_OK)\r
+ return FR_DISK_ERR;\r
+ } while (--i);\r
+\r
+#if _USE_ERASE /* Erase data area if needed */\r
+ {\r
+ DWORD eb[2];\r
+\r
+ eb[0] = wsect; eb[1] = wsect + (n_clst - ((fmt == FS_FAT32) ? 1 : 0)) * au - 1;\r
+ disk_ioctl(drv, CTRL_ERASE_SECTOR, eb);\r
+ }\r
+#endif\r
+\r
+ /* Create FSInfo if needed */\r
+ if (fmt == FS_FAT32) {\r
+ ST_DWORD(tbl+FSI_LeadSig, 0x41615252);\r
+ ST_DWORD(tbl+FSI_StrucSig, 0x61417272);\r
+ ST_DWORD(tbl+FSI_Free_Count, n_clst - 1); /* Number of free clusters */\r
+ ST_DWORD(tbl+FSI_Nxt_Free, 2); /* Last allocated cluster# */\r
+ ST_WORD(tbl+BS_55AA, 0xAA55);\r
+ disk_write(drv, tbl, b_vol + 1, 1); /* Write original (VBR+1) */\r
+ disk_write(drv, tbl, b_vol + 7, 1); /* Write backup (VBR+7) */\r
+ }\r
+\r
+ return (disk_ioctl(drv, CTRL_SYNC, (void*)0) == RES_OK) ? FR_OK : FR_DISK_ERR;\r
+}\r
+\r
+#endif /* _USE_MKFS && !_FS_READONLY */\r
+\r
+\r
+\r
+\r
+#if _USE_STRFUNC\r
+/*-----------------------------------------------------------------------*/\r
+/* Get a string from the file */\r
+/*-----------------------------------------------------------------------*/\r
+TCHAR* f_gets (\r
+ TCHAR* buff, /* Pointer to the string buffer to read */\r
+ int len, /* Size of string buffer (characters) */\r
+ FIL* fil /* Pointer to the file object */\r
+)\r
+{\r
+ int n = 0;\r
+ TCHAR c, *p = buff;\r
+ BYTE s[2];\r
+ UINT rc;\r
+\r
+\r
+ while (n < len - 1) { /* Read bytes until buffer gets filled */\r
+ f_read(fil, s, 1, &rc);\r
+ if (rc != 1) break; /* Break on EOF or error */\r
+ c = s[0];\r
+#if _LFN_UNICODE /* Read a character in UTF-8 encoding */\r
+ if (c >= 0x80) {\r
+ if (c < 0xC0) continue; /* Skip stray trailer */\r
+ if (c < 0xE0) { /* Two-byte sequense */\r
+ f_read(fil, s, 1, &rc);\r
+ if (rc != 1) break;\r
+ c = ((c & 0x1F) << 6) | (s[0] & 0x3F);\r
+ if (c < 0x80) c = '?';\r
+ } else {\r
+ if (c < 0xF0) { /* Three-byte sequense */\r
+ f_read(fil, s, 2, &rc);\r
+ if (rc != 2) break;\r
+ c = (c << 12) | ((s[0] & 0x3F) << 6) | (s[1] & 0x3F);\r
+ if (c < 0x800) c = '?';\r
+ } else { /* Reject four-byte sequense */\r
+ c = '?';\r
+ }\r
+ }\r
+ }\r
+#endif\r
+#if _USE_STRFUNC >= 2\r
+ if (c == '\r') continue; /* Strip '\r' */\r
+#endif\r
+ *p++ = c;\r
+ n++;\r
+ if (c == '\n') break; /* Break on EOL */\r
+ }\r
+ *p = 0;\r
+ return n ? buff : 0; /* When no data read (eof or error), return with error. */\r
+}\r
+\r
+\r
+\r
+#if !_FS_READONLY\r
+#include <stdarg.h>\r
+/*-----------------------------------------------------------------------*/\r
+/* Put a character to the file */\r
+/*-----------------------------------------------------------------------*/\r
+int f_putc (\r
+ TCHAR c, /* A character to be output */\r
+ FIL* fil /* Pointer to the file object */\r
+)\r
+{\r
+ UINT bw, btw;\r
+ BYTE s[3];\r
+\r
+\r
+#if _USE_STRFUNC >= 2\r
+ if (c == '\n') f_putc ('\r', fil); /* LF -> CRLF conversion */\r
+#endif\r
+\r
+#if _LFN_UNICODE /* Write the character in UTF-8 encoding */\r
+ if (c < 0x80) { /* 7-bit */\r
+ s[0] = (BYTE)c;\r
+ btw = 1;\r
+ } else {\r
+ if (c < 0x800) { /* 11-bit */\r
+ s[0] = (BYTE)(0xC0 | (c >> 6));\r
+ s[1] = (BYTE)(0x80 | (c & 0x3F));\r
+ btw = 2;\r
+ } else { /* 16-bit */\r
+ s[0] = (BYTE)(0xE0 | (c >> 12));\r
+ s[1] = (BYTE)(0x80 | ((c >> 6) & 0x3F));\r
+ s[2] = (BYTE)(0x80 | (c & 0x3F));\r
+ btw = 3;\r
+ }\r
+ }\r
+#else /* Write the character without conversion */\r
+ s[0] = (BYTE)c;\r
+ btw = 1;\r
+#endif\r
+ f_write(fil, s, btw, &bw); /* Write the char to the file */\r
+ return (bw == btw) ? 1 : EOF; /* Return the result */\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Put a string to the file */\r
+/*-----------------------------------------------------------------------*/\r
+int f_puts (\r
+ const TCHAR* str, /* Pointer to the string to be output */\r
+ FIL* fil /* Pointer to the file object */\r
+)\r
+{\r
+ int n;\r
+\r
+\r
+ for (n = 0; *str; str++, n++) {\r
+ if (f_putc(*str, fil) == EOF) return EOF;\r
+ }\r
+ return n;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Put a formatted string to the file */\r
+/*-----------------------------------------------------------------------*/\r
+int f_printf (\r
+ FIL* fil, /* Pointer to the file object */\r
+ const TCHAR* str, /* Pointer to the format string */\r
+ ... /* Optional arguments... */\r
+)\r
+{\r
+ va_list arp;\r
+ BYTE f, r;\r
+ UINT i, j, w;\r
+ ULONG v;\r
+ TCHAR c, d, s[16], *p;\r
+ int res, cc;\r
+\r
+\r
+ va_start(arp, str);\r
+\r
+ for (cc = res = 0; cc != EOF; res += cc) {\r
+ c = *str++;\r
+ if (c == 0) break; /* End of string */\r
+ if (c != '%') { /* Non escape character */\r
+ cc = f_putc(c, fil);\r
+ if (cc != EOF) cc = 1;\r
+ continue;\r
+ }\r
+ w = f = 0;\r
+ c = *str++;\r
+ if (c == '0') { /* Flag: '0' padding */\r
+ f = 1; c = *str++;\r
+ } else {\r
+ if (c == '-') { /* Flag: left justified */\r
+ f = 2; c = *str++;\r
+ }\r
+ }\r
+ while (IsDigit(c)) { /* Precision */\r
+ w = w * 10 + c - '0';\r
+ c = *str++;\r
+ }\r
+ if (c == 'l' || c == 'L') { /* Prefix: Size is long int */\r
+ f |= 4; c = *str++;\r
+ }\r
+ if (!c) break;\r
+ d = c;\r
+ if (IsLower(d)) d -= 0x20;\r
+ switch (d) { /* Type is... */\r
+ case 'S' : /* String */\r
+ p = va_arg(arp, TCHAR*);\r
+ for (j = 0; p[j]; j++) ;\r
+ res = 0;\r
+ while (!(f & 2) && j++ < w) res += (cc = f_putc(' ', fil));\r
+ res += (cc = f_puts(p, fil));\r
+ while (j++ < w) res += (cc = f_putc(' ', fil));\r
+ if (cc != EOF) cc = res;\r
+ continue;\r
+ case 'C' : /* Character */\r
+ cc = f_putc((TCHAR)va_arg(arp, int), fil); continue;\r
+ case 'B' : /* Binary */\r
+ r = 2; break;\r
+ case 'O' : /* Octal */\r
+ r = 8; break;\r
+ case 'D' : /* Signed decimal */\r
+ case 'U' : /* Unsigned decimal */\r
+ r = 10; break;\r
+ case 'X' : /* Hexdecimal */\r
+ r = 16; break;\r
+ default: /* Unknown type (passthrough) */\r
+ cc = f_putc(c, fil); continue;\r
+ }\r
+\r
+ /* Get an argument and put it in numeral */\r
+ v = (f & 4) ? va_arg(arp, long) : ((d == 'D') ? (long)va_arg(arp, int) : va_arg(arp, unsigned int));\r
+ if (d == 'D' && (v & 0x80000000)) {\r
+ v = 0 - v;\r
+ f |= 8;\r
+ }\r
+ i = 0;\r
+ do {\r
+ d = (TCHAR)(v % r); v /= r;\r
+ if (d > 9) d += (c == 'x') ? 0x27 : 0x07;\r
+ s[i++] = d + '0';\r
+ } while (v && i < sizeof(s) / sizeof(s[0]));\r
+ if (f & 8) s[i++] = '-';\r
+ j = i; d = (f & 1) ? '0' : ' ';\r
+ res = 0;\r
+ while (!(f & 2) && j++ < w) res += (cc = f_putc(d, fil));\r
+ do res += (cc = f_putc(s[--i], fil)); while(i);\r
+ while (j++ < w) res += (cc = f_putc(' ', fil));\r
+ if (cc != EOF) cc = res;\r
+ }\r
+\r
+ va_end(arp);\r
+ return (cc == EOF) ? cc : res;\r
+}\r
+\r
+#endif /* !_FS_READONLY */\r
+#endif /* _USE_STRFUNC */\r
--- /dev/null
+/**\r
+ * @file ff.h\r
+ * @brief FATファイルシステムドライバの定義。\r
+ */\r
+\r
+/*---------------------------------------------------------------------------/\r
+/ FatFs - FAT file system module include file R0.08b (C)ChaN, 2011\r
+/----------------------------------------------------------------------------/\r
+/ FatFs module is a generic FAT file system module for small embedded systems.\r
+/ This is a free software that opened for education, research and commercial\r
+/ developments under license policy of following trems.\r
+/\r
+/ Copyright (C) 2011, ChaN, all right reserved.\r
+/\r
+/ * The FatFs module is a free software and there is NO WARRANTY.\r
+/ * No restriction on use. You can use, modify and redistribute it for\r
+/ personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY.\r
+/ * Redistributions of source code must retain the above copyright notice.\r
+/\r
+/----------------------------------------------------------------------------*/\r
+\r
+#ifndef _FATFS\r
+#define _FATFS 8237 /* Revision ID */\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#include "integer_ff.h" /* Basic integer types */\r
+#include "ffconf.h" /* FatFs configuration options */\r
+\r
+#if _FATFS != _FFCONF\r
+#error Wrong configuration file (ffconf.h).\r
+#endif\r
+\r
+\r
+\r
+/* Definitions of volume management */\r
+\r
+#if _MULTI_PARTITION /* Multiple partition configuration */\r
+#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive# */\r
+#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition# */\r
+typedef struct {\r
+ BYTE pd; /* Physical drive# */\r
+ BYTE pt; /* Partition # (0-3) */\r
+} PARTITION;\r
+extern const PARTITION VolToPart[]; /* Volume - Physical location resolution table */\r
+\r
+#else /* Single partition configuration */\r
+#define LD2PD(vol) (vol) /* Logical drive# is bound to the same physical drive# */\r
+#define LD2PT(vol) 0 /* Always mounts the 1st partition */\r
+\r
+#endif\r
+\r
+\r
+\r
+/* Type of path name strings on FatFs API */\r
+\r
+#if _LFN_UNICODE /* Unicode string */\r
+#if !_USE_LFN\r
+#error _LFN_UNICODE must be 0 in non-LFN cfg.\r
+#endif\r
+#ifndef _INC_TCHAR\r
+typedef WCHAR TCHAR;\r
+#define _T(x) L ## x\r
+#define _TEXT(x) L ## x\r
+#endif\r
+\r
+#else /* ANSI/OEM string */\r
+#ifndef _INC_TCHAR\r
+typedef char TCHAR;\r
+#define _T(x) x\r
+#define _TEXT(x) x\r
+#endif\r
+\r
+#endif\r
+\r
+\r
+\r
+/* File system object structure (FATFS) */\r
+\r
+typedef struct {\r
+ BYTE fs_type; /* FAT sub-type (0:Not mounted) */\r
+ BYTE drv; /* Physical drive number */\r
+ BYTE csize; /* Sectors per cluster (1,2,4...128) */\r
+ BYTE n_fats; /* Number of FAT copies (1,2) */\r
+ BYTE wflag; /* win[] dirty flag (1:must be written back) */\r
+ BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */\r
+ WORD id; /* File system mount ID */\r
+ WORD n_rootdir; /* Number of root directory entries (FAT12/16) */\r
+#if _MAX_SS != 512\r
+ WORD ssize; /* Bytes per sector (512,1024,2048,4096) */\r
+#endif\r
+#if _FS_REENTRANT\r
+ _SYNC_t sobj; /* Identifier of sync object */\r
+#endif\r
+#if !_FS_READONLY\r
+ DWORD last_clust; /* Last allocated cluster */\r
+ DWORD free_clust; /* Number of free clusters */\r
+ DWORD fsi_sector; /* fsinfo sector (FAT32) */\r
+#endif\r
+#if _FS_RPATH\r
+ DWORD cdir; /* Current directory start cluster (0:root) */\r
+#endif\r
+ DWORD n_fatent; /* Number of FAT entries (= number of clusters + 2) */\r
+ DWORD fsize; /* Sectors per FAT */\r
+ DWORD fatbase; /* FAT start sector */\r
+ DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */\r
+ DWORD database; /* Data start sector */\r
+ DWORD winsect; /* Current sector appearing in the win[] */\r
+ BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and Data on tiny cfg) */\r
+} FATFS;\r
+\r
+\r
+\r
+/* File object structure (FIL) */\r
+\r
+typedef struct {\r
+ FATFS* fs; /* Pointer to the owner file system object */\r
+ WORD id; /* Owner file system mount ID */\r
+ BYTE flag; /* File status flags */\r
+ BYTE pad1;\r
+ DWORD fptr; /* File read/write pointer (0 on file open) */\r
+ DWORD fsize; /* File size */\r
+ DWORD sclust; /* File start cluster (0 when fsize==0) */\r
+ DWORD clust; /* Current cluster */\r
+ DWORD dsect; /* Current data sector */\r
+#if !_FS_READONLY\r
+ DWORD dir_sect; /* Sector containing the directory entry */\r
+ BYTE* dir_ptr; /* Ponter to the directory entry in the window */\r
+#endif\r
+#if _USE_FASTSEEK\r
+ DWORD* cltbl; /* Pointer to the cluster link map table (null on file open) */\r
+#endif\r
+#if _FS_SHARE\r
+ UINT lockid; /* File lock ID (index of file semaphore table) */\r
+#endif\r
+#if !_FS_TINY\r
+ BYTE buf[_MAX_SS]; /* File data read/write buffer */\r
+#endif\r
+} FIL;\r
+\r
+\r
+\r
+/* Directory object structure (DIR) */\r
+\r
+typedef struct {\r
+ FATFS* fs; /* Pointer to the owner file system object */\r
+ WORD id; /* Owner file system mount ID */\r
+ WORD index; /* Current read/write index number */\r
+ DWORD sclust; /* Table start cluster (0:Root dir) */\r
+ DWORD clust; /* Current cluster */\r
+ DWORD sect; /* Current sector */\r
+ BYTE* dir; /* Pointer to the current SFN entry in the win[] */\r
+ BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */\r
+#if _USE_LFN\r
+ WCHAR* lfn; /* Pointer to the LFN working buffer */\r
+ WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */\r
+#endif\r
+} DIR;\r
+\r
+\r
+\r
+/* File status structure (FILINFO) */\r
+\r
+typedef struct {\r
+ DWORD fsize; /* File size */\r
+ WORD fdate; /* Last modified date */\r
+ WORD ftime; /* Last modified time */\r
+ BYTE fattrib; /* Attribute */\r
+ TCHAR fname[13]; /* Short file name (8.3 format) */\r
+#if _USE_LFN\r
+ TCHAR* lfname; /* Pointer to the LFN buffer */\r
+ UINT lfsize; /* Size of LFN buffer in TCHAR */\r
+#endif\r
+} FILINFO;\r
+\r
+\r
+\r
+/* File function return code (FRESULT) */\r
+\r
+typedef enum {\r
+ FR_OK = 0, /* (0) Succeeded */\r
+ FR_DISK_ERR, /* (1) A hard error occured in the low level disk I/O layer */\r
+ FR_INT_ERR, /* (2) Assertion failed */\r
+ FR_NOT_READY, /* (3) The physical drive cannot work */\r
+ FR_NO_FILE, /* (4) Could not find the file */\r
+ FR_NO_PATH, /* (5) Could not find the path */\r
+ FR_INVALID_NAME, /* (6) The path name format is invalid */\r
+ FR_DENIED, /* (7) Acces denied due to prohibited access or directory full */\r
+ FR_EXIST, /* (8) Acces denied due to prohibited access */\r
+ FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */\r
+ FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */\r
+ FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */\r
+ FR_NOT_ENABLED, /* (12) The volume has no work area */\r
+ FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume on the physical drive */\r
+ FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */\r
+ FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */\r
+ FR_LOCKED, /* (16) The operation is rejected according to the file shareing policy */\r
+ FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */\r
+ FR_TOO_MANY_OPEN_FILES /* (18) Number of open files > _FS_SHARE */\r
+} FRESULT;\r
+\r
+\r
+\r
+/*--------------------------------------------------------------*/\r
+/* FatFs module application interface */\r
+\r
+FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */\r
+FRESULT f_open (FIL*, const TCHAR*, BYTE); /* Open or create a file */\r
+FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */\r
+FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */\r
+FRESULT f_close (FIL*); /* Close an open file object */\r
+FRESULT f_opendir (DIR*, const TCHAR*); /* Open an existing directory */\r
+FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */\r
+FRESULT f_stat (const TCHAR*, FILINFO*); /* Get file status */\r
+FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */\r
+FRESULT f_getfree (const TCHAR*, DWORD*, FATFS**); /* Get number of free clusters on the drive */\r
+FRESULT f_truncate (FIL*); /* Truncate file */\r
+FRESULT f_sync (FIL*); /* Flush cached data of a writing file */\r
+FRESULT f_unlink (const TCHAR*); /* Delete an existing file or directory */\r
+FRESULT f_mkdir (const TCHAR*); /* Create a new directory */\r
+FRESULT f_chmod (const TCHAR*, BYTE, BYTE); /* Change attriburte of the file/dir */\r
+FRESULT f_utime (const TCHAR*, const FILINFO*); /* Change timestamp of the file/dir */\r
+FRESULT f_rename (const TCHAR*, const TCHAR*); /* Rename/Move a file or directory */\r
+FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */\r
+FRESULT f_mkfs (BYTE, BYTE, UINT); /* Create a file system on the drive */\r
+FRESULT f_chdrive (BYTE); /* Change current drive */\r
+FRESULT f_chdir (const TCHAR*); /* Change current directory */\r
+FRESULT f_getcwd (TCHAR*, UINT); /* Get current directory */\r
+int f_putc (TCHAR, FIL*); /* Put a character to the file */\r
+int f_puts (const TCHAR*, FIL*); /* Put a string to the file */\r
+int f_printf (FIL*, const TCHAR*, ...); /* Put a formatted string to the file */\r
+TCHAR* f_gets (TCHAR*, int, FIL*); /* Get a string from the file */\r
+\r
+#ifndef EOF\r
+#define EOF (-1)\r
+#endif\r
+\r
+#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0)\r
+#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0)\r
+#define f_tell(fp) ((fp)->fptr)\r
+#define f_size(fp) ((fp)->fsize)\r
+\r
+\r
+\r
+\r
+/*--------------------------------------------------------------*/\r
+/* Additional user defined functions */\r
+\r
+/* RTC function */\r
+#if !_FS_READONLY\r
+DWORD get_fattime (void);\r
+#endif\r
+\r
+/* Unicode support functions */\r
+#if _USE_LFN /* Unicode - OEM code conversion */\r
+WCHAR ff_convert (WCHAR, UINT); /* OEM-Unicode bidirectional conversion */\r
+WCHAR ff_wtoupper (WCHAR); /* Unicode upper-case conversion */\r
+#if _USE_LFN == 3 /* Memory functions */\r
+void* ff_memalloc (UINT); /* Allocate memory block */\r
+void ff_memfree (void*); /* Free memory block */\r
+#endif\r
+#endif\r
+\r
+/* Sync functions */\r
+#if _FS_REENTRANT\r
+int ff_cre_syncobj (BYTE, _SYNC_t*);/* Create a sync object */\r
+int ff_req_grant (_SYNC_t); /* Lock sync object */\r
+void ff_rel_grant (_SYNC_t); /* Unlock sync object */\r
+int ff_del_syncobj (_SYNC_t); /* Delete a sync object */\r
+#endif\r
+\r
+\r
+\r
+\r
+/*--------------------------------------------------------------*/\r
+/* Flags and offset address */\r
+\r
+\r
+/* File access control and file status flags (FIL.flag) */\r
+\r
+#define FA_READ 0x01\r
+#define FA_OPEN_EXISTING 0x00\r
+#define FA__ERROR 0x80\r
+\r
+#if !_FS_READONLY\r
+#define FA_WRITE 0x02\r
+#define FA_CREATE_NEW 0x04\r
+#define FA_CREATE_ALWAYS 0x08\r
+#define FA_OPEN_ALWAYS 0x10\r
+#define FA__WRITTEN 0x20\r
+#define FA__DIRTY 0x40\r
+#endif\r
+\r
+\r
+/* FAT sub type (FATFS.fs_type) */\r
+\r
+#define FS_FAT12 1\r
+#define FS_FAT16 2\r
+#define FS_FAT32 3\r
+\r
+\r
+/* File attribute bits for directory entry */\r
+\r
+#define AM_RDO 0x01 /* Read only */\r
+#define AM_HID 0x02 /* Hidden */\r
+#define AM_SYS 0x04 /* System */\r
+#define AM_VOL 0x08 /* Volume label */\r
+#define AM_LFN 0x0F /* LFN entry */\r
+#define AM_DIR 0x10 /* Directory */\r
+#define AM_ARC 0x20 /* Archive */\r
+#define AM_MASK 0x3F /* Mask of defined bits */\r
+\r
+\r
+/* Fast seek function */\r
+#define CREATE_LINKMAP 0xFFFFFFFF\r
+\r
+\r
+\r
+/*--------------------------------*/\r
+/* Multi-byte word access macros */\r
+\r
+#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */\r
+#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))\r
+#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))\r
+#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)\r
+#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)\r
+#else /* Use byte-by-byte access to the FAT structure */\r
+#define LD_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))\r
+#define LD_DWORD(ptr) (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr))\r
+#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8)\r
+#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24)\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* _FATFS */\r
--- /dev/null
+/**\r
+ * @file ffconf.h\r
+ * @brief FATファイルシステムドライバの設定。\r
+ */\r
+\r
+/*---------------------------------------------------------------------------/\r
+/ FatFs - FAT file system module configuration file R0.08b (C)ChaN, 2011\r
+/----------------------------------------------------------------------------/\r
+/\r
+/ CAUTION! Do not forget to make clean the project after any changes to\r
+/ the configuration options.\r
+/\r
+/----------------------------------------------------------------------------*/\r
+#ifndef _FFCONF\r
+#define _FFCONF 8237 /* Revision ID */\r
+\r
+\r
+/*---------------------------------------------------------------------------/\r
+/ Function and Buffer Configurations\r
+/----------------------------------------------------------------------------*/\r
+\r
+#define _FS_TINY 1 /* 0:Normal or 1:Tiny */\r
+/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system\r
+/ object instead of the sector buffer in the individual file object for file\r
+/ data transfer. This reduces memory consumption 512 bytes each file object. */\r
+\r
+\r
+#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */\r
+/* Setting _FS_READONLY to 1 defines read only configuration. This removes\r
+/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,\r
+/ f_truncate and useless f_getfree. */\r
+\r
+\r
+#define _FS_MINIMIZE 0 /* 0 to 3 */\r
+/* The _FS_MINIMIZE option defines minimization level to remove some functions.\r
+/\r
+/ 0: Full function.\r
+/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename\r
+/ are removed.\r
+/ 2: f_opendir and f_readdir are removed in addition to 1.\r
+/ 3: f_lseek is removed in addition to 2. */\r
+\r
+\r
+#define _USE_STRFUNC 0 /* 0:Disable or 1/2:Enable */\r
+/* To enable string functions, set _USE_STRFUNC to 1 or 2. */\r
+\r
+\r
+#define _USE_MKFS 0 /* 0:Disable or 1:Enable */\r
+/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */\r
+\r
+\r
+#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */\r
+/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */\r
+\r
+\r
+#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */\r
+/* To enable fast seek feature, set _USE_FASTSEEK to 1. */\r
+\r
+\r
+\r
+/*---------------------------------------------------------------------------/\r
+/ Locale and Namespace Configurations\r
+/----------------------------------------------------------------------------*/\r
+\r
+#define _CODE_PAGE 932\r
+/* The _CODE_PAGE specifies the OEM code page to be used on the target system.\r
+/ Incorrect setting of the code page can cause a file open failure.\r
+/\r
+/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows)\r
+/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)\r
+/ 949 - Korean (DBCS, OEM, Windows)\r
+/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)\r
+/ 1250 - Central Europe (Windows)\r
+/ 1251 - Cyrillic (Windows)\r
+/ 1252 - Latin 1 (Windows)\r
+/ 1253 - Greek (Windows)\r
+/ 1254 - Turkish (Windows)\r
+/ 1255 - Hebrew (Windows)\r
+/ 1256 - Arabic (Windows)\r
+/ 1257 - Baltic (Windows)\r
+/ 1258 - Vietnam (OEM, Windows)\r
+/ 437 - U.S. (OEM)\r
+/ 720 - Arabic (OEM)\r
+/ 737 - Greek (OEM)\r
+/ 775 - Baltic (OEM)\r
+/ 850 - Multilingual Latin 1 (OEM)\r
+/ 858 - Multilingual Latin 1 + Euro (OEM)\r
+/ 852 - Latin 2 (OEM)\r
+/ 855 - Cyrillic (OEM)\r
+/ 866 - Russian (OEM)\r
+/ 857 - Turkish (OEM)\r
+/ 862 - Hebrew (OEM)\r
+/ 874 - Thai (OEM, Windows)\r
+/ 1 - ASCII only (Valid for non LFN cfg.)\r
+*/\r
+\r
+\r
+#define _USE_LFN 0 /* 0 to 3 */\r
+#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */\r
+/* The _USE_LFN option switches the LFN support.\r
+/\r
+/ 0: Disable LFN feature. _MAX_LFN and _LFN_UNICODE have no effect.\r
+/ 1: Enable LFN with static working buffer on the BSS. Always NOT reentrant.\r
+/ 2: Enable LFN with dynamic working buffer on the STACK.\r
+/ 3: Enable LFN with dynamic working buffer on the HEAP.\r
+/\r
+/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. To enable LFN,\r
+/ Unicode handling functions ff_convert() and ff_wtoupper() must be added\r
+/ to the project. When enable to use heap, memory control functions\r
+/ ff_memalloc() and ff_memfree() must be added to the project. */\r
+\r
+\r
+#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */\r
+/* To switch the character code set on FatFs API to Unicode,\r
+/ enable LFN feature and set _LFN_UNICODE to 1. */\r
+\r
+\r
+#define _FS_RPATH 0 /* 0 to 2 */\r
+/* The _FS_RPATH option configures relative path feature.\r
+/\r
+/ 0: Disable relative path feature and remove related functions.\r
+/ 1: Enable relative path. f_chdrive() and f_chdir() are available.\r
+/ 2: f_getcwd() is available in addition to 1.\r
+/\r
+/ Note that output of the f_readdir fnction is affected by this option. */\r
+\r
+\r
+\r
+/*---------------------------------------------------------------------------/\r
+/ Physical Drive Configurations\r
+/----------------------------------------------------------------------------*/\r
+\r
+#define _VOLUMES 1\r
+/* Number of volumes (logical drives) to be used. */\r
+\r
+\r
+#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */\r
+/* Maximum sector size to be handled.\r
+/ Always set 512 for memory card and hard disk but a larger value may be\r
+/ required for on-board flash memory, floppy disk and optical disk.\r
+/ When _MAX_SS is larger than 512, it configures FatFs to variable sector size\r
+/ and GET_SECTOR_SIZE command must be implememted to the disk_ioctl function. */\r
+\r
+\r
+#define _MULTI_PARTITION 0 /* 0:Single partition or 1:Multiple partition */\r
+/* When set to 0, each volume is bound to the same physical drive number and\r
+/ it can mount only first primaly partition. When it is set to 1, each volume\r
+/ is tied to the partitions listed in VolToPart[]. */\r
+\r
+\r
+#define _USE_ERASE 0 /* 0:Disable or 1:Enable */\r
+/* To enable sector erase feature, set _USE_ERASE to 1. CTRL_ERASE_SECTOR command\r
+/ should be added to the disk_ioctl functio. */\r
+\r
+\r
+\r
+/*---------------------------------------------------------------------------/\r
+/ System Configurations\r
+/----------------------------------------------------------------------------*/\r
+\r
+#define _WORD_ACCESS 0 /* 0 or 1 */\r
+/* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS\r
+/ option defines which access method is used to the word data on the FAT volume.\r
+/\r
+/ 0: Byte-by-byte access.\r
+/ 1: Word access. Do not choose this unless following condition is met.\r
+/\r
+/ When the byte order on the memory is big-endian or address miss-aligned word\r
+/ access results incorrect behavior, the _WORD_ACCESS must be set to 0.\r
+/ If it is not the case, the value can also be set to 1 to improve the\r
+/ performance and code size. */\r
+\r
+\r
+/* A header file that defines sync object types on the O/S, such as\r
+/ windows.h, ucos_ii.h and semphr.h, must be included prior to ff.h. */\r
+\r
+#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */\r
+#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */\r
+#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */\r
+\r
+/* The _FS_REENTRANT option switches the reentrancy (thread safe) of the FatFs module.\r
+/\r
+/ 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect.\r
+/ 1: Enable reentrancy. Also user provided synchronization handlers,\r
+/ ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj\r
+/ function must be added to the project. */\r
+\r
+\r
+#define _FS_SHARE 0 /* 0:Disable or >=1:Enable */\r
+/* To enable file shareing feature, set _FS_SHARE to 1 or greater. The value\r
+ defines how many files can be opened simultaneously. */\r
+\r
+\r
+#endif /* _FFCONFIG */\r
--- /dev/null
+/**
+ * @file ffrtc.c
+ * @brief FATファイルシステムドライバ用RTCモジュールの実装。
+ */
+
+#include "ffrtc.h"
+#include "lpc17xx_rtc.h"
+
+void ffrtc_init(void)
+{
+ RTC_Init(LPC_RTC);
+}
+
+unsigned long get_fattime(void)
+{
+#if 1
+ RTC_TIME_Type RTCFullTime;
+ RTC_GetFullTime(LPC_RTC, &RTCFullTime);
+ return ((unsigned long)(RTCFullTime.YEAR - 1980) << 25)
+ | ((unsigned long)RTCFullTime.MONTH << 21)
+ | ((unsigned long)RTCFullTime.DOM << 16)
+ | ((unsigned long)RTCFullTime.HOUR << 11)
+ | ((unsigned long)RTCFullTime.MIN << 5)
+ | ((unsigned long)RTCFullTime.SEC >> 1);
+#else
+ /* Fixed to Jan. 1, 2010 */
+ return ((unsigned long)(2010 - 1980) << 25)
+ | ((unsigned long)1 << 21)
+ | ((unsigned long)1 << 16)
+ | ((unsigned long)0 << 11)
+ | ((unsigned long)0 << 5)
+ | ((unsigned long)0 >> 1);
+#endif
+}
+
--- /dev/null
+/**
+ * @file ffrtc.h
+ * @brief FATファイルシステムドライバ用RTCモジュールの定義。
+ */
+
+#ifndef FFRTC_H
+#define FFRTC_H
+
+void ffrtc_init(void);
+unsigned long get_fattime(void);
+
+#endif
+
--- /dev/null
+/**
+ * @file ffspi.c
+ * @brief FATファイルシステム用下層SPIドライバの実装。
+ */
+
+#include "ffspi.h"
+
+#include <lpc17xx_spi.h>
+#include <lpc17xx_gpio.h>
+#include <lpc17xx_pinsel.h>
+#include <lpc17xx_libcfg.h>
+#include <kernel.h>
+
+SPI_CFG_Type SPI_ConfigStruct;
+PINSEL_CFG_Type PinCfg;
+SPI_DATA_SETUP_Type xferConfig;
+
+// PORT number that /CS pin assigned on
+#define CS_PORT_NUM 1
+// PIN number that /CS pin assigned on
+#define CS_PIN_NUM 29
+
+void ffspi_cs_init(void)
+{
+ GPIO_SetDir(CS_PORT_NUM, (1 << CS_PIN_NUM), 1);
+ GPIO_SetValue(CS_PORT_NUM, (1 << CS_PIN_NUM));
+}
+
+void ffspi_cs_ena(void)
+{
+ GPIO_ClearValue(CS_PORT_NUM, (1 << CS_PIN_NUM));
+}
+
+void ffspi_cs_dis(void)
+{
+ GPIO_SetValue(CS_PORT_NUM, (1 << CS_PIN_NUM));
+}
+
+/* CS status (true:CS == L) */
+unsigned char ffspi_cs_stat(void)
+{
+ unsigned char val = GPIO_ReadValue(CS_PORT_NUM);
+ return ((val & (1 << CS_PIN_NUM)) == 0) ? 1 : 0;
+}
+
+void ffspi_init(void)
+{
+ /*
+ * Initialize SPI pin connect
+ * P0.15 - SCK;
+ * P0.17 - MISO
+ * P0.18 - MOSI
+ */
+ PinCfg.Funcnum = 3;
+ PinCfg.OpenDrain = 0;
+ PinCfg.Pinmode = 0;
+ PinCfg.Portnum = 0;
+ PinCfg.Pinnum = 15;
+ PINSEL_ConfigPin(&PinCfg);
+ PinCfg.Pinnum = 17;
+ PINSEL_ConfigPin(&PinCfg);
+ PinCfg.Pinnum = 18;
+ PINSEL_ConfigPin(&PinCfg);
+
+ // initialize SPI configuration structure to default
+#if 0
+ SPI_ConfigStructInit(&SPI_ConfigStruct);
+#else
+ SPI_ConfigStruct.CPHA = SPI_CPHA_FIRST;
+ SPI_ConfigStruct.CPOL = SPI_CPOL_HI;
+ SPI_ConfigStruct.ClockRate = 5000000;
+ SPI_ConfigStruct.DataOrder = SPI_DATA_MSB_FIRST;
+ SPI_ConfigStruct.Databit = SPI_DATABIT_8;
+ SPI_ConfigStruct.Mode = SPI_MASTER_MODE;
+#endif
+ // Initialize SPI peripheral with parameter given in structure above
+ SPI_Init(LPC_SPI, &SPI_ConfigStruct);
+
+ ffspi_cs_init();
+}
+
+void ffspi_tx(unsigned char c)
+{
+ SPI_SendData(LPC_SPI, c);
+ while (!(SPI_GetStatus(LPC_SPI) & SPI_SPSR_SPIF))
+ {
+ }
+ SPI_ReceiveData(LPC_SPI);
+}
+
+unsigned char ffspi_rx(void)
+{
+ SPI_SendData(LPC_SPI, 0xff);
+ while (!(SPI_GetStatus(LPC_SPI) & SPI_SPSR_SPIF))
+ {
+ }
+ return SPI_ReceiveData(LPC_SPI);
+}
+
+void ffspi_dly_ms(int ms)
+{
+ tslp_tsk(ms);
+}
+
--- /dev/null
+/**
+ * @file ffspi.h
+ * @brief FATファイルシステム用下層SPIドライバの定義。
+ */
+
+#ifndef FFSPI_H
+#define FFSPI_H
+
+void ffspi_init(void);
+void ffspi_tx(unsigned char c);
+unsigned char ffspi_rx(void);
+void ffspi_cs_init(void);
+void ffspi_cs_ena(void);
+void ffspi_cs_dis(void);
+unsigned char ffspi_cs_stat(void);
+void ffspi_dly_ms(int ms);
+
+#endif
+
--- /dev/null
+/**\r
+ * @file integer_ff.h\r
+ * @brief FatFsモジュール用の整数型定義。\r
+ */\r
+\r
+/*-------------------------------------------*/\r
+/* Integer type definitions for FatFs module */\r
+/*-------------------------------------------*/\r
+\r
+#ifndef _INTEGER\r
+#define _INTEGER\r
+\r
+/* These types must be 16-bit, 32-bit or larger integer */\r
+#ifndef TOPPERS_ITRON_H\r
+typedef int INT;\r
+typedef unsigned int UINT;\r
+#endif\r
+\r
+/* These types must be 8-bit integer */\r
+typedef char CHAR;\r
+typedef unsigned char UCHAR;\r
+typedef unsigned char BYTE;\r
+\r
+/* These types must be 16-bit integer */\r
+typedef short SHORT;\r
+typedef unsigned short USHORT;\r
+typedef unsigned short WORD;\r
+typedef unsigned short WCHAR;\r
+\r
+/* These types must be 32-bit integer */\r
+typedef long LONG;\r
+typedef unsigned long ULONG;\r
+typedef unsigned long DWORD;\r
+\r
+#endif\r
+\r
--- /dev/null
+/*----------------------------------------------------------------------*/\r
+/* FatFs sample project for generic microcontrollers (C)ChaN, 2010 */\r
+/*----------------------------------------------------------------------*/\r
+\r
+#include <stdio.h>\r
+#include "ff.h"\r
+\r
+\r
+\r
+void die ( /* Stop with dying message */\r
+ FRESULT rc /* FatFs return value */\r
+)\r
+{\r
+ printf("Failed with rc=%u.\n", rc);\r
+ for (;;) ;\r
+}\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Program Main */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+int main (void)\r
+{\r
+ FRESULT rc; /* Result code */\r
+ FATFS fatfs; /* File system object */\r
+ FIL fil; /* File object */\r
+ DIR dir; /* Directory object */\r
+ FILINFO fno; /* File information object */\r
+ UINT bw, br, i;\r
+ BYTE buff[128];\r
+\r
+\r
+ f_mount(0, &fatfs); /* Register volume work area (never fails) */\r
+\r
+ printf("\nOpen a test file (message.txt).\n");\r
+ rc = f_open(&fil, "MESSAGE.TXT", FA_READ);\r
+ if (rc) die(rc);\r
+\r
+ printf("\nType the file content.\n");\r
+ for (;;) {\r
+ rc = f_read(&fil, buff, sizeof(buff), &br); /* Read a chunk of file */\r
+ if (rc || !br) break; /* Error or end of file */\r
+ for (i = 0; i < br; i++) /* Type the data */\r
+ putchar(buff[i]);\r
+ }\r
+ if (rc) die(rc);\r
+\r
+ printf("\nClose the file.\n");\r
+ rc = f_close(&fil);\r
+ if (rc) die(rc);\r
+\r
+ printf("\nCreate a new file (hello.txt).\n");\r
+ rc = f_open(&fil, "HELLO.TXT", FA_WRITE | FA_CREATE_ALWAYS);\r
+ if (rc) die(rc);\r
+\r
+ printf("\nWrite a text data. (Hello world!)\n");\r
+ rc = f_write(&fil, "Hello world!\r\n", 14, &bw);\r
+ if (rc) die(rc);\r
+ printf("%u bytes written.\n", bw);\r
+\r
+ printf("\nClose the file.\n");\r
+ rc = f_close(&fil);\r
+ if (rc) die(rc);\r
+\r
+ printf("\nOpen root directory.\n");\r
+ rc = f_opendir(&dir, "");\r
+ if (rc) die(rc);\r
+\r
+ printf("\nDirectory listing...\n");\r
+ for (;;) {\r
+ rc = f_readdir(&dir, &fno); /* Read a directory item */\r
+ if (rc || !fno.fname[0]) break; /* Error or end of dir */\r
+ if (fno.fattrib & AM_DIR)\r
+ printf(" <dir> %s\n", fno.fname);\r
+ else\r
+ printf("%8lu %s\n", fno.fsize, fno.fname);\r
+ }\r
+ if (rc) die(rc);\r
+\r
+ printf("\nTest completed.\n");\r
+ for (;;) ;\r
+}\r
+\r
+\r
+\r
+/*---------------------------------------------------------*/\r
+/* User Provided Timer Function for FatFs module */\r
+/*---------------------------------------------------------*/\r
+\r
+DWORD get_fattime (void)\r
+{\r
+ return ((DWORD)(2010 - 1980) << 25) /* Fixed to Jan. 1, 2010 */\r
+ | ((DWORD)1 << 21)\r
+ | ((DWORD)1 << 16)\r
+ | ((DWORD)0 << 11)\r
+ | ((DWORD)0 << 5)\r
+ | ((DWORD)0 >> 1);\r
+}\r
+\r
--- /dev/null
+/**
+ * @file hid.c
+ * @author Shinichiro Nakamura
+ * @brief ヒューマンインターフェースデバイスドライバの実装。
+ * @details
+ * ここで言う「ヒューマンインターフェースデバイス」とは
+ * ボリュームとスイッチを指す。
+ */
+
+#include "hid.h"
+
+#include <lpc17xx_gpio.h>
+#include <lpc17xx_adc.h>
+#include <lpc17xx_pinsel.h>
+#include <lpc17xx_libcfg.h>
+#include <kernel.h>
+
+#define SW1_PORT_NUM 1
+#define SW2_PORT_NUM 1
+#define SW3_PORT_NUM 1
+#define SW4_PORT_NUM 1
+
+#define SW1_PIN_NUM 0
+#define SW2_PIN_NUM 1
+#define SW3_PIN_NUM 4
+#define SW4_PIN_NUM 8
+
+void hid_init(void)
+{
+ PINSEL_CFG_Type PinCfg;
+
+ GPIO_SetDir(SW1_PORT_NUM, (1 << SW1_PIN_NUM), 0);
+ GPIO_SetDir(SW2_PORT_NUM, (1 << SW2_PIN_NUM), 0);
+ GPIO_SetDir(SW3_PORT_NUM, (1 << SW3_PIN_NUM), 0);
+ GPIO_SetDir(SW4_PORT_NUM, (1 << SW4_PIN_NUM), 0);
+
+ /*
+ * Init ADC pin connect
+ * AD0.2 on P0.25
+ */
+ PinCfg.Funcnum = 1;
+ PinCfg.OpenDrain = 0;
+ PinCfg.Pinmode = 0;
+ PinCfg.Portnum = 0;
+
+ PinCfg.Pinnum = 23;
+ PINSEL_ConfigPin(&PinCfg);
+ PinCfg.Pinnum = 24;
+ PINSEL_ConfigPin(&PinCfg);
+ PinCfg.Pinnum = 25;
+ PINSEL_ConfigPin(&PinCfg);
+ PinCfg.Pinnum = 26;
+ PINSEL_ConfigPin(&PinCfg);
+
+ ADC_Init(LPC_ADC, 1000000);
+
+ ADC_IntConfig(LPC_ADC, ADC_ADINTEN0, DISABLE);
+ ADC_IntConfig(LPC_ADC, ADC_ADINTEN1, DISABLE);
+ ADC_IntConfig(LPC_ADC, ADC_ADINTEN2, DISABLE);
+ ADC_IntConfig(LPC_ADC, ADC_ADINTEN3, DISABLE);
+
+ ADC_ChannelCmd(LPC_ADC, ADC_CHANNEL_0, ENABLE);
+ ADC_ChannelCmd(LPC_ADC, ADC_CHANNEL_1, ENABLE);
+ ADC_ChannelCmd(LPC_ADC, ADC_CHANNEL_2, ENABLE);
+ ADC_ChannelCmd(LPC_ADC, ADC_CHANNEL_3, ENABLE);
+
+ ADC_BurstCmd(LPC_ADC, 1);
+}
+
+uint8_t hid_swread(unsigned char ch)
+{
+ int port;
+ int pin;
+ switch (ch) {
+ case 0:
+ port = SW1_PORT_NUM;
+ pin = SW1_PIN_NUM;
+ break;
+ case 1:
+ port = SW2_PORT_NUM;
+ pin = SW2_PIN_NUM;
+ break;
+ case 2:
+ port = SW3_PORT_NUM;
+ pin = SW3_PIN_NUM;
+ break;
+ case 3:
+ port = SW4_PORT_NUM;
+ pin = SW4_PIN_NUM;
+ break;
+ default:
+ return 0;
+ }
+ if ((GPIO_ReadValue(port) & (1 << pin)) != 0) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+uint32_t hid_volread(unsigned char ch)
+{
+ uint32_t val = 0;
+ switch (ch) {
+ case 0:
+ val = ADC_ChannelGetData(LPC_ADC,ADC_CHANNEL_0);
+ break;
+ case 1:
+ val = ADC_ChannelGetData(LPC_ADC,ADC_CHANNEL_1);
+ break;
+ case 2:
+ val = ADC_ChannelGetData(LPC_ADC,ADC_CHANNEL_2);
+ break;
+ case 3:
+ val = ADC_ChannelGetData(LPC_ADC,ADC_CHANNEL_3);
+ break;
+ }
+ return val;
+}
+
--- /dev/null
+/**
+ * @file hid.h
+ * @author Shinichiro Nakamura
+ * @brief ヒューマンインターフェースデバイスドライバの定義。
+ * @details
+ * ここで言う「ヒューマンインターフェースデバイス」とは
+ * ボリュームとスイッチを指す。
+ */
+
+#ifndef HID_H
+#define HID_H
+
+#include <stdint.h>
+
+/**
+ * @defgroup BLACKTANK_LPC1769_DRIVER_HID
+ * @ingroup BLACKTANK_LPC1769_DRIVER
+ * @{
+ */
+
+void hid_init(void);
+uint8_t hid_swread(unsigned char ch);
+uint32_t hid_volread(unsigned char ch);
+
+/**
+ * @}
+ */
+
+#endif
+
--- /dev/null
+/**
+ * @file led.c
+ * @author Shinichiro Nakamura
+ * @brief LEDドライバの実装。
+ */
+
+#include "led.h"
+#include <LPC17xx.h>
+#include <lpc17xx_gpio.h>
+#include <lpc17xx_pinsel.h>
+#include <lpc17xx_libcfg.h>
+
+#define DEBLED1_PIN_NUM 4
+#define DEBLED2_PIN_NUM 5
+#define DEBLED3_PIN_NUM 6
+#define DEBLED4_PIN_NUM 7
+
+#define SWLED1_PORT_NUM 1
+#define SWLED2_PORT_NUM 1
+#define SWLED3_PORT_NUM 1
+#define SWLED4_PORT_NUM 1
+
+#define SWLED1_PIN_NUM 9
+#define SWLED2_PIN_NUM 10
+#define SWLED3_PIN_NUM 14
+#define SWLED4_PIN_NUM 15
+
+void led_init(void)
+{
+ LPC_GPIO2->FIOCLR = (1 << DEBLED1_PIN_NUM);
+ LPC_GPIO2->FIOCLR = (1 << DEBLED2_PIN_NUM);
+ LPC_GPIO2->FIOCLR = (1 << DEBLED3_PIN_NUM);
+ LPC_GPIO2->FIOCLR = (1 << DEBLED4_PIN_NUM);
+
+ LPC_GPIO2->FIODIR |= (1 << DEBLED1_PIN_NUM);
+ LPC_GPIO2->FIODIR |= (1 << DEBLED2_PIN_NUM);
+ LPC_GPIO2->FIODIR |= (1 << DEBLED3_PIN_NUM);
+ LPC_GPIO2->FIODIR |= (1 << DEBLED4_PIN_NUM);
+
+ GPIO_SetValue(SWLED1_PORT_NUM, (1 << SWLED1_PIN_NUM));
+ GPIO_SetValue(SWLED2_PORT_NUM, (1 << SWLED2_PIN_NUM));
+ GPIO_SetValue(SWLED3_PORT_NUM, (1 << SWLED3_PIN_NUM));
+ GPIO_SetValue(SWLED4_PORT_NUM, (1 << SWLED4_PIN_NUM));
+
+ GPIO_SetDir(SWLED1_PORT_NUM, (1 << SWLED1_PIN_NUM), 1);
+ GPIO_SetDir(SWLED2_PORT_NUM, (1 << SWLED2_PIN_NUM), 1);
+ GPIO_SetDir(SWLED3_PORT_NUM, (1 << SWLED3_PIN_NUM), 1);
+ GPIO_SetDir(SWLED4_PORT_NUM, (1 << SWLED4_PIN_NUM), 1);
+}
+
+void led_debug_write(const uint8_t target, const uint8_t on)
+{
+ int pin;
+ switch (target) {
+ case 0:
+ pin = (1 << DEBLED1_PIN_NUM);
+ break;
+ case 1:
+ pin = (1 << DEBLED2_PIN_NUM);
+ break;
+ case 2:
+ pin = (1 << DEBLED3_PIN_NUM);
+ break;
+ case 3:
+ pin = (1 << DEBLED4_PIN_NUM);
+ break;
+ default:
+ return;
+ }
+ if (on) {
+ LPC_GPIO2->FIOPIN |= pin;
+ } else {
+ LPC_GPIO2->FIOPIN &= ~pin;
+ }
+}
+
+void led_switch_write(const uint8_t target, const uint8_t on)
+{
+ int port;
+ int pin;
+ switch (target) {
+ case 0:
+ port = SWLED1_PORT_NUM;
+ pin = SWLED1_PIN_NUM;
+ break;
+ case 1:
+ port = SWLED2_PORT_NUM;
+ pin = SWLED2_PIN_NUM;
+ break;
+ case 2:
+ port = SWLED3_PORT_NUM;
+ pin = SWLED3_PIN_NUM;
+ break;
+ case 3:
+ port = SWLED4_PORT_NUM;
+ pin = SWLED4_PIN_NUM;
+ break;
+ default:
+ return;
+ }
+ if (on) {
+ GPIO_ClearValue(port, (1 << pin));
+ } else {
+ GPIO_SetValue(port, (1 << pin));
+ }
+}
+
--- /dev/null
+/**
+ * @file led.h
+ * @author Shinichiro Nakamura
+ * @brief LEDドライバの定義。
+ */
+
+#ifndef LED_H
+#define LED_H
+
+#include <stdint.h>
+
+/**
+ * @defgroup BLACKTANK_LPC1769_DRIVER_LED
+ * @ingroup BLACKTANK_LPC1769_DRIVER
+ * @{
+ */
+
+void led_init(void);
+void led_debug_write(const uint8_t target, const uint8_t on);
+void led_switch_write(const uint8_t target, const uint8_t on);
+
+/**
+ * @}
+ */
+
+#endif
+
--- /dev/null
+/**\r
+ * @file oled.c\r
+ * @author Shinichiro Nakamura\r
+ * @brief OLEDドライバの実装。\r
+ * @details\r
+ * OLED(96x64dots)の下層ドライバ。\r
+ * リソースに対するロックは上層で行うこと。\r
+ * 焼付防止のような処理はアプリケーション層に委ねる。\r
+ */\r
+\r
+/*\r
+ * ===============================================================\r
+ * Aitendo OLED device driver library. (Version 0.0.2)\r
+ *\r
+ * [The product]\r
+ * OLED-2P-095BWNN-SPI : http://www.aitendo.co.jp/product/2099\r
+ * ALO-095BWNN-J9 : http://www.aitendo.co.jp/product/1449\r
+ *\r
+ * [References]\r
+ * http://serdisplib.sourceforge.net/ser/doc/Treiber_IC-SSD1332_OLED_96x64_COLOR.pdf\r
+ * ===============================================================\r
+ * Copyright (c) 2010-2011 Shinichiro Nakamura\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person\r
+ * obtaining a copy of this software and associated documentation\r
+ * files (the "Software"), to deal in the Software without\r
+ * restriction, including without limitation the rights to use,\r
+ * copy, modify, merge, publish, distribute, sublicense, and/or\r
+ * sell copies of the Software, and to permit persons to whom the\r
+ * Software is furnished to do so, subject to the following\r
+ * conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be\r
+ * included in all copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\r
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\r
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\r
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\r
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\r
+ * OTHER DEALINGS IN THE SOFTWARE.\r
+ * ===============================================================\r
+ */\r
+\r
+#include "oled.h"\r
+\r
+#include <lpc17xx_ssp.h>\r
+#include <lpc17xx_gpio.h>\r
+#include <lpc17xx_pinsel.h>\r
+#include <lpc17xx_libcfg.h>\r
+#include <kernel.h>\r
+\r
+#define CS_PORT_NUM 1\r
+#define CS_PIN_NUM 28\r
+\r
+#define DC_PORT_NUM 0\r
+#define DC_PIN_NUM 21\r
+\r
+#define RES_PORT_NUM 0\r
+#define RES_PIN_NUM 22\r
+\r
+SSP_CFG_Type SSP_ConfigStruct;\r
+PINSEL_CFG_Type PinCfg;\r
+SSP_DATA_SETUP_Type xferConfig;\r
+\r
+static void oled_spi_tx(unsigned char c);\r
+static unsigned char oled_spi_rx(void);\r
+\r
+#define SPI_WRITE(c) oled_spi_tx(c)\r
+#define SPI_READ() oled_spi_rx()\r
+\r
+#define WAIT_MS(n) tslp_tsk(n)\r
+\r
+#define RES_ENA() GPIO_ClearValue(RES_PORT_NUM, (1 << RES_PIN_NUM))\r
+#define RES_DIS() GPIO_SetValue(RES_PORT_NUM, (1 << RES_PIN_NUM))\r
+\r
+#define CS_ENA() GPIO_ClearValue(CS_PORT_NUM, (1 << CS_PIN_NUM))\r
+#define CS_DIS() GPIO_SetValue(CS_PORT_NUM, (1 << CS_PIN_NUM))\r
+\r
+#define DC_CMD() GPIO_ClearValue(DC_PORT_NUM, (1 << DC_PIN_NUM))\r
+#define DC_DAT() GPIO_SetValue(DC_PORT_NUM, (1 << DC_PIN_NUM))\r
+\r
+#define swap(a,b) do{int c=a;a=b;b=c;}while(0)\r
+#define abs(n) (((n) > 0) ? (n) : -(n))\r
+#define flip(x,y) do{x=OLED_X-(x)-1;y=OLED_Y-(y)-1;}while(0)\r
+#define align(x1,y1,x2,y2) \\r
+ do{\\r
+ int tx1=x1;\\r
+ int ty1=y1;\\r
+ int tx2=x2;\\r
+ int ty2=y2;\\r
+ if (ty1 > ty2) {\\r
+ x1=tx2;\\r
+ y1=ty2;\\r
+ x2=tx1;\\r
+ y2=ty1;\\r
+ } else {\\r
+ x1=tx1;\\r
+ y1=ty1;\\r
+ x2=tx2;\\r
+ y2=ty2;\\r
+ }\\r
+ }while(0)\r
+\r
+static void oled_spi_tx(unsigned char c)\r
+{\r
+ SSP_SendData(LPC_SSP0, c);\r
+ while (SSP_GetStatus(LPC_SSP0, SSP_SR_BSY))\r
+ {\r
+ }\r
+ SSP_ReceiveData(LPC_SSP0);\r
+}\r
+\r
+static unsigned char oled_spi_rx(void)\r
+{\r
+ SSP_SendData(LPC_SSP0, 0xff);\r
+ while (SSP_GetStatus(LPC_SSP0, SSP_SR_BSY))\r
+ {\r
+ }\r
+ return SSP_ReceiveData(LPC_SSP0);\r
+}\r
+\r
+/**\r
+ * Reset.\r
+ */\r
+static void oled_reset();\r
+\r
+/**\r
+ * Write data.\r
+ *\r
+ * @param data Data.\r
+ */\r
+static void oled_write_data(unsigned char data);\r
+\r
+/**\r
+ * Set mode.\r
+ *\r
+ * @param fillrect Fill the rectangle.\r
+ * @param revcopy Reverse copy.\r
+ */\r
+static void oled_set_mode(unsigned char fillrect, unsigned char revcopy);\r
+\r
+/**\r
+ * Set column address.\r
+ *\r
+ * @param start Start address. (0-95)\r
+ * @param end End address. (0-95)\r
+ */\r
+static void oled_set_column_address(int start, int end);\r
+\r
+/**\r
+ * Set row address.\r
+ *\r
+ * @param start Start address. (0-63)\r
+ * @param end End address. (0-63)\r
+ */\r
+static void oled_set_row_address(int start, int end);\r
+\r
+/**\r
+ * Set contrast for Color A.\r
+ *\r
+ * @param contrast Contrast. (Default:0x80)\r
+ */\r
+static void oled_set_contrast_for_color_a(int contrast);\r
+\r
+/**\r
+ * Set contrast for Color B.\r
+ *\r
+ * @param contrast Contrast. (Default:0x80)\r
+ */\r
+static void oled_set_contrast_for_color_b(int contrast);\r
+\r
+/**\r
+ * Set contrast for Color C.\r
+ *\r
+ * @param contrast Contrast. (Default:0x80)\r
+ */\r
+static void oled_set_contrast_for_color_c(int contrast);\r
+\r
+/**\r
+ * Set master current control value.\r
+ *\r
+ * @param current Current value. (0x00-0x0F)\r
+ */\r
+static void oled_set_master_current_control(int current);\r
+\r
+/**\r
+ * Set remapping mode and the data format.\r
+ *\r
+ * @param mode See the document.\r
+ */\r
+static void oled_set_remap_and_data_format(int mode);\r
+\r
+/**\r
+ * Set display start line.\r
+ *\r
+ * @param line Start line number. (0-63)\r
+ */\r
+static void oled_set_display_start_line(int line);\r
+\r
+/**\r
+ * Set display offset line.\r
+ *\r
+ * @param offset Offset line number. (0-63)\r
+ */\r
+static void oled_set_display_offset(int offset);\r
+\r
+typedef enum {\r
+ NormalDisplay,\r
+ EntireDisplayOn,\r
+ EntireDisplayOff,\r
+ InverseDisplay\r
+} DisplayMode;\r
+\r
+/**\r
+ * Set display mode.\r
+ *\r
+ * @param mode Display mode.\r
+ */\r
+static void oled_set_display_mode(DisplayMode mode);\r
+\r
+/**\r
+ * Set multiplex ratio.\r
+ *\r
+ * @param ratio Ratio.\r
+ */\r
+static void oled_set_multiplex_ratio(int ratio);\r
+\r
+/**\r
+ * Set display on/off.\r
+ *\r
+ * @param on On.\r
+ */\r
+static void oled_set_display_on_off(unsigned char on);\r
+\r
+typedef struct gray_scale_table {\r
+ char data[32];\r
+} gray_scale_table_t;\r
+\r
+/**\r
+ * Set gray scale table.\r
+ *\r
+ * @param p A pointer to the look up table.\r
+ */\r
+static void oled_set_gray_scale_table(gray_scale_table_t *p);\r
+\r
+/**\r
+ * NOP.\r
+ */\r
+static void oled_nop();\r
+\r
+/**\r
+ * Set power saving mode.\r
+ *\r
+ * @param value Value. (0x00:None, 0x12:power saving)\r
+ */\r
+static void oled_set_power_saving_mode(int value);\r
+\r
+/**\r
+ * Set phase period.\r
+ *\r
+ * @param value Value. (Default:0x74)\r
+ */\r
+static void oled_set_phase_period(int value);\r
+\r
+/**\r
+ * Set display clock divide ratio.\r
+ *\r
+ * @param value Value. (Default:0x00)\r
+ */\r
+static void oled_set_display_clock_divide_ratio(int value);\r
+\r
+/**\r
+ * Set second pre-charge speed for color A.\r
+ *\r
+ * @param value Value.\r
+ */\r
+static void oled_set_second_pre_charge_speed_for_color_a(int value);\r
+\r
+/**\r
+ * Set second pre-charge speed for color B.\r
+ *\r
+ * @param value Value.\r
+ */\r
+static void oled_set_second_pre_charge_speed_for_color_b(int value);\r
+\r
+/**\r
+ * Set second pre-charge speed for color C.\r
+ *\r
+ * @param value Value.\r
+ */\r
+static void oled_set_second_pre_charge_speed_for_color_c(int value);\r
+\r
+/**\r
+ * Set pre charge level for color A.\r
+ *\r
+ * @param value The value.\r
+ */\r
+static void oled_set_pre_charge_level_for_color_a(int value);\r
+\r
+/**\r
+ * Set pre charge level for color B.\r
+ *\r
+ * @param value The value.\r
+ */\r
+static void oled_set_pre_charge_level_for_color_b(int value);\r
+\r
+/**\r
+ * Set pre charge level for color C.\r
+ *\r
+ * @param value The value.\r
+ */\r
+static void oled_set_pre_charge_level_for_color_c(int value);\r
+\r
+/**\r
+ * Set VCOMH.\r
+ *\r
+ * @param value VCOMH value. (0x00:0.43 * Vref, 0x3F:0x83 * Vref)\r
+ */\r
+static void oled_set_vcomh(int value);\r
+\r
+/**\r
+ * Read the status register.\r
+ *\r
+ * @return the value.\r
+ */\r
+static unsigned char oled_read_status_register();\r
+\r
+void oled_init(void)\r
+{\r
+ /*\r
+ * Initialize SPI pin connect\r
+ * P1.20 - SCLK;\r
+ * P1.23 - MISO\r
+ * P1.24 - MOSI\r
+ */\r
+ PinCfg.Funcnum = 3;\r
+ PinCfg.OpenDrain = 0;\r
+ PinCfg.Pinmode = 0;\r
+ PinCfg.Portnum = 1;\r
+ PinCfg.Pinnum = 20;\r
+ PINSEL_ConfigPin(&PinCfg);\r
+ PinCfg.Pinnum = 23;\r
+ PINSEL_ConfigPin(&PinCfg);\r
+ PinCfg.Pinnum = 24;\r
+ PINSEL_ConfigPin(&PinCfg);\r
+\r
+ // initialize SSP configuration structure to default\r
+ SSP_ConfigStructInit(&SSP_ConfigStruct);\r
+ SSP_ConfigStruct.ClockRate = 4000000;\r
+ // Initialize SSP peripheral with parameter given in structure above\r
+ SSP_Init(LPC_SSP0, &SSP_ConfigStruct);\r
+ // Enable SSP peripheral\r
+ SSP_Cmd(LPC_SSP0, ENABLE);\r
+\r
+ // CS(Chip Select)\r
+ GPIO_SetDir(CS_PORT_NUM, (1 << CS_PIN_NUM), 1);\r
+ GPIO_SetValue(CS_PORT_NUM, (1 << CS_PIN_NUM));\r
+\r
+ // DC(Data/Command)\r
+ GPIO_SetDir(DC_PORT_NUM, (1 << DC_PIN_NUM), 1);\r
+ GPIO_SetValue(DC_PORT_NUM, (1 << DC_PIN_NUM));\r
+\r
+ // RES(Reset)\r
+ GPIO_SetDir(RES_PORT_NUM, (1 << RES_PIN_NUM), 1);\r
+ GPIO_SetValue(RES_PORT_NUM, (1 << RES_PIN_NUM));\r
+\r
+ oled_reset();\r
+}\r
+\r
+/**\r
+ * Draw pixel.\r
+ *\r
+ * @param x X.\r
+ * @param y Y.\r
+ * @param c Color.\r
+ */\r
+void oled_draw_pixel(int x, int y, Color c) {\r
+ flip(x,y);\r
+ oled_set_column_address(x, x);\r
+ oled_set_row_address(y, y);\r
+ c.b = c.b >> 3;\r
+ c.g = c.g >> 3;\r
+ c.r = c.r >> 3;\r
+ oled_write_data((((c.b << 3) & 0xF8) | ((c.g >> 3) & 0x07)));\r
+ oled_write_data((((c.g << 5) & 0xE0) | ((c.r >> 0) & 0x1F)));\r
+}\r
+\r
+/**\r
+ * Draw line.\r
+ *\r
+ * @param x1 X1.\r
+ * @param y1 Y1.\r
+ * @param x2 X2.\r
+ * @param y2 Y2.\r
+ * @param c Color.\r
+ */\r
+void oled_draw_line(int x1, int y1, int x2, int y2, Color c) {\r
+ align(x1,y1,x2,y2);\r
+ /*\r
+ * Bresenham's line algorithm\r
+ */\r
+ unsigned char steep = abs(y2 - y1) > abs(x2 - x1);\r
+ if (steep) {\r
+ swap(x1, y1);\r
+ swap(x2, y2);\r
+ }\r
+ if (x1 > x2) {\r
+ swap(x1, x2);\r
+ swap(y1, y2);\r
+ }\r
+ int deltax = x2 - x1;\r
+ int deltay = abs(y2 - y1);\r
+ int error = deltax / 2;\r
+ int ystep;\r
+ int y = y1;\r
+ if (y1 < y2) {\r
+ ystep = 1;\r
+ } else {\r
+ ystep = -1;\r
+ }\r
+ int x;\r
+ for (x = x1; x <= x2; x++) {\r
+ if (steep) {\r
+ oled_draw_pixel(y, x, c);\r
+ } else {\r
+ oled_draw_pixel(x, y, c);\r
+ }\r
+ error = error - deltay;\r
+ if (error < 0) {\r
+ y = y + ystep;\r
+ error = error + deltax;\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ * Fill box.\r
+ *\r
+ * @param x1 X1.\r
+ * @param y1 Y1.\r
+ * @param x2 X2.\r
+ * @param y2 Y2.\r
+ * @param c1 Color1.\r
+ * @param c2 Color2.\r
+ */\r
+void oled_fill_box(int x1, int y1, int x2, int y2, Color c1, Color c2) {\r
+ if (x1 == x2) {\r
+ return;\r
+ }\r
+ if (y1 == y2) {\r
+ return;\r
+ }\r
+ flip(x1,y1);\r
+ flip(x2,y2);\r
+ align(x1,y1,x2,y2);\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0x22);\r
+ SPI_WRITE(x1);\r
+ SPI_WRITE(y1);\r
+ SPI_WRITE(x2);\r
+ SPI_WRITE(y2);\r
+ SPI_WRITE(c1.b >> 3);\r
+ SPI_WRITE(c1.g >> 3);\r
+ SPI_WRITE(c1.r >> 3);\r
+ SPI_WRITE(c2.b >> 3);\r
+ SPI_WRITE(c2.g >> 3);\r
+ SPI_WRITE(c2.r >> 3);\r
+ CS_DIS();\r
+ WAIT_MS(1);\r
+}\r
+\r
+/**\r
+ * Copy.\r
+ *\r
+ * @param x1 X1.\r
+ * @param y1 Y1.\r
+ * @param x2 X2.\r
+ * @param y2 Y2.\r
+ * @param nx X of the destination.\r
+ * @param ny Y of the destination.\r
+ */\r
+void oled_copy(int x1, int y1, int x2, int y2, int nx, int ny) {\r
+ flip(x1,y1);\r
+ flip(x2,y2);\r
+ align(x1,y1,x2,y2);\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0x23);\r
+ SPI_WRITE(x1);\r
+ SPI_WRITE(y1);\r
+ SPI_WRITE(x2);\r
+ SPI_WRITE(y2);\r
+ SPI_WRITE(nx);\r
+ SPI_WRITE(ny);\r
+ CS_DIS();\r
+ WAIT_MS(1);\r
+}\r
+\r
+/**\r
+ * Darker.\r
+ *\r
+ * @param x1 X1.\r
+ * @param y1 Y1.\r
+ * @param x2 X2.\r
+ * @param y2 Y2.\r
+ */\r
+void oled_darker(int x1, int y1, int x2, int y2) {\r
+ flip(x1,y1);\r
+ flip(x2,y2);\r
+ align(x1,y1,x2,y2);\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0x24);\r
+ SPI_WRITE(x1);\r
+ SPI_WRITE(y1);\r
+ SPI_WRITE(x2);\r
+ SPI_WRITE(y2);\r
+ CS_DIS();\r
+ WAIT_MS(1);\r
+}\r
+\r
+/**\r
+ * Clear.\r
+ *\r
+ * @param x1 X1.\r
+ * @param y1 Y1.\r
+ * @param x2 X2.\r
+ * @param y2 Y2.\r
+ */\r
+void oled_clear(int x1, int y1, int x2, int y2) {\r
+ flip(x1,y1);\r
+ flip(x2,y2);\r
+ align(x1,y1,x2,y2);\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0x25);\r
+ SPI_WRITE(x1);\r
+ SPI_WRITE(y1);\r
+ SPI_WRITE(x2);\r
+ SPI_WRITE(y2);\r
+ CS_DIS();\r
+ WAIT_MS(1);\r
+}\r
+\r
+/**\r
+ * Reset.\r
+ */\r
+void oled_reset() {\r
+\r
+ RES_ENA();\r
+ WAIT_MS(200);\r
+ RES_DIS();\r
+ WAIT_MS(200);\r
+\r
+ oled_set_display_on_off(0);\r
+ oled_set_row_address(0, 63);\r
+ oled_set_column_address(0, 95);\r
+ oled_set_remap_and_data_format(0x70);\r
+ oled_set_display_start_line(0);\r
+ oled_set_display_offset(0);\r
+ oled_set_display_mode(NormalDisplay);\r
+ oled_set_multiplex_ratio(0x3f);\r
+ oled_set_master_current_control(0x8f);\r
+ oled_set_power_saving_mode(0x00);\r
+ oled_set_phase_period(0x74);\r
+ oled_set_display_clock_divide_ratio(0xD0);\r
+ oled_set_second_pre_charge_speed_for_color_a(0x80);\r
+ oled_set_second_pre_charge_speed_for_color_b(0x80);\r
+ oled_set_second_pre_charge_speed_for_color_c(0x80);\r
+ oled_set_pre_charge_level_for_color_a(0x3F);\r
+ oled_set_pre_charge_level_for_color_b(0x3F);\r
+ oled_set_pre_charge_level_for_color_c(0x3F);\r
+ oled_set_vcomh(0x3E);\r
+ oled_set_master_current_control(0x0F);\r
+ // A:Blue, B:Green, C:Red\r
+ oled_set_contrast_for_color_a(0x80);\r
+ oled_set_contrast_for_color_b(0x80);\r
+ oled_set_contrast_for_color_c(0x80);\r
+ oled_set_mode(1, 0);\r
+ oled_set_display_on_off(1);\r
+}\r
+\r
+/**\r
+ * Write data.\r
+ *\r
+ * @param data Data.\r
+ */\r
+void oled_write_data(unsigned char data) {\r
+ DC_DAT();\r
+ CS_ENA();\r
+ SPI_WRITE(data);\r
+ CS_DIS();\r
+}\r
+\r
+/**\r
+ * Set mode.\r
+ *\r
+ * @param fillrect Fill the rectangle.\r
+ * @param revcopy Reverse copy.\r
+ */\r
+void oled_set_mode(unsigned char fillrect, unsigned char revcopy) {\r
+ unsigned char val = 0x00;\r
+ if (fillrect) {\r
+ val |= 1 << 0;\r
+ }\r
+ if (revcopy) {\r
+ val |= 1 << 4;\r
+ }\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0x26);\r
+ SPI_WRITE(val);\r
+ CS_DIS();\r
+}\r
+\r
+/**\r
+ * Set column address.\r
+ *\r
+ * @param start Start address. (0-95)\r
+ * @param end End address. (0-95)\r
+ */\r
+void oled_set_column_address(int start, int end) {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0x15);\r
+ SPI_WRITE(start);\r
+ SPI_WRITE(end);\r
+ CS_DIS();\r
+}\r
+\r
+/**\r
+ * Set row address.\r
+ *\r
+ * @param start Start address. (0-63)\r
+ * @param end End address. (0-63)\r
+ */\r
+void oled_set_row_address(int start, int end) {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0x75);\r
+ SPI_WRITE(start);\r
+ SPI_WRITE(end);\r
+ CS_DIS();\r
+}\r
+\r
+/**\r
+ * Set contrast for Color A.\r
+ *\r
+ * @param contrast Contrast. (Default:0x80)\r
+ */\r
+void oled_set_contrast_for_color_a(int contrast) {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0x81);\r
+ SPI_WRITE(contrast);\r
+ CS_DIS();\r
+}\r
+\r
+/**\r
+ * Set contrast for Color B.\r
+ *\r
+ * @param contrast Contrast. (Default:0x80)\r
+ */\r
+void oled_set_contrast_for_color_b(int contrast) {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0x82);\r
+ SPI_WRITE(contrast);\r
+ CS_DIS();\r
+}\r
+\r
+/**\r
+ * Set contrast for Color C.\r
+ *\r
+ * @param contrast Contrast. (Default:0x80)\r
+ */\r
+void oled_set_contrast_for_color_c(int contrast) {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0x83);\r
+ SPI_WRITE(contrast);\r
+ CS_DIS();\r
+}\r
+\r
+/**\r
+ * Set master current control value.\r
+ *\r
+ * @param current Current value. (0x00-0x0F)\r
+ */\r
+void oled_set_master_current_control(int current) {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0x87);\r
+ SPI_WRITE(current);\r
+ CS_DIS();\r
+}\r
+\r
+/**\r
+ * Set remapping mode and the data format.\r
+ *\r
+ * @param mode See the document.\r
+ */\r
+void oled_set_remap_and_data_format(int mode) {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0xA0);\r
+ SPI_WRITE(mode);\r
+ CS_DIS();\r
+}\r
+\r
+/**\r
+ * Set display start line.\r
+ *\r
+ * @param line Start line number. (0-63)\r
+ */\r
+void oled_set_display_start_line(int line) {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0xA1);\r
+ SPI_WRITE(line);\r
+ CS_DIS();\r
+}\r
+\r
+/**\r
+ * Set display offset line.\r
+ *\r
+ * @param offset Offset line number. (0-63)\r
+ */\r
+void oled_set_display_offset(int offset) {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0xA2);\r
+ SPI_WRITE(offset);\r
+ CS_DIS();\r
+}\r
+\r
+/**\r
+ * Set display mode.\r
+ *\r
+ * @param mode Display mode.\r
+ */\r
+void oled_set_display_mode(DisplayMode mode) {\r
+ int val = 0;\r
+ switch (mode) {\r
+ case NormalDisplay:\r
+ val = 0xA4;\r
+ break;\r
+ case EntireDisplayOn:\r
+ val = 0xA5;\r
+ break;\r
+ case EntireDisplayOff:\r
+ val = 0xA6;\r
+ break;\r
+ case InverseDisplay:\r
+ val = 0xA7;\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ if (val != 0) {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(val);\r
+ CS_DIS();\r
+ }\r
+}\r
+\r
+/**\r
+ * Set multiplex ratio.\r
+ *\r
+ * @param ratio Ratio.\r
+ */\r
+void oled_set_multiplex_ratio(int ratio) {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0xA8);\r
+ SPI_WRITE(ratio);\r
+ CS_DIS();\r
+}\r
+\r
+/**\r
+ * Set display on/off.\r
+ *\r
+ * @param on On.\r
+ */\r
+void oled_set_display_on_off(unsigned char on) {\r
+ if (on) {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0xAF);\r
+ CS_DIS();\r
+ } else {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0xAE);\r
+ CS_DIS();\r
+ }\r
+}\r
+\r
+/**\r
+ * Set gray scale table.\r
+ *\r
+ * @param p A pointer to the look up table.\r
+ */\r
+void oled_set_gray_scale_table(gray_scale_table_t *p) {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0xB8);\r
+ int i;\r
+ for (i = 0; i < 32; i++) {\r
+ SPI_WRITE(p->data[i]);\r
+ }\r
+ CS_DIS();\r
+}\r
+\r
+/**\r
+ * NOP.\r
+ */\r
+void oled_nop() {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0xE3);\r
+ CS_DIS();\r
+}\r
+\r
+/**\r
+ * Set power saving mode.\r
+ *\r
+ * @param value Value. (0x00:None, 0x12:power saving)\r
+ */\r
+void oled_set_power_saving_mode(int value) {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0xB0);\r
+ SPI_WRITE(value);\r
+ CS_DIS();\r
+}\r
+\r
+/**\r
+ * Set phase period.\r
+ *\r
+ * @param value Value. (Default:0x74)\r
+ */\r
+void oled_set_phase_period(int value) {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0xB1);\r
+ SPI_WRITE(value);\r
+ CS_DIS();\r
+}\r
+\r
+/**\r
+ * Set display clock divide ratio.\r
+ *\r
+ * @param value Value. (Default:0x00)\r
+ */\r
+void oled_set_display_clock_divide_ratio(int value) {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0xB3);\r
+ SPI_WRITE(value);\r
+ CS_DIS();\r
+}\r
+\r
+/**\r
+ * Set second pre-charge speed for color A.\r
+ *\r
+ * @param value Value.\r
+ */\r
+void oled_set_second_pre_charge_speed_for_color_a(int value) {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0x8A);\r
+ SPI_WRITE(value);\r
+ CS_DIS();\r
+}\r
+\r
+/**\r
+ * Set second pre-charge speed for color B.\r
+ *\r
+ * @param value Value.\r
+ */\r
+void oled_set_second_pre_charge_speed_for_color_b(int value) {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0x8B);\r
+ SPI_WRITE(value);\r
+ CS_DIS();\r
+}\r
+\r
+/**\r
+ * Set second pre-charge speed for color C.\r
+ *\r
+ * @param value Value.\r
+ */\r
+void oled_set_second_pre_charge_speed_for_color_c(int value) {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0x8C);\r
+ SPI_WRITE(value);\r
+ CS_DIS();\r
+}\r
+\r
+/**\r
+ * Set pre charge level for color A.\r
+ *\r
+ * @param value The value.\r
+ */\r
+void oled_set_pre_charge_level_for_color_a(int value) {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0xBB);\r
+ SPI_WRITE(value);\r
+ CS_DIS();\r
+}\r
+\r
+/**\r
+ * Set pre charge level for color B.\r
+ *\r
+ * @param value The value.\r
+ */\r
+void oled_set_pre_charge_level_for_color_b(int value) {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0xBC);\r
+ SPI_WRITE(value);\r
+ CS_DIS();\r
+}\r
+\r
+/**\r
+ * Set pre charge level for color C.\r
+ *\r
+ * @param value The value.\r
+ */\r
+void oled_set_pre_charge_level_for_color_c(int value) {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0xBD);\r
+ SPI_WRITE(value);\r
+ CS_DIS();\r
+}\r
+\r
+/**\r
+ * Set VCOMH.\r
+ *\r
+ * @param value VCOMH value. (0x00:0.43 * Vref, 0x3F:0x83 * Vref)\r
+ */\r
+void oled_set_vcomh(int value) {\r
+ DC_CMD();\r
+ CS_ENA();\r
+ SPI_WRITE(0xBE);\r
+ SPI_WRITE(value);\r
+ CS_DIS();\r
+}\r
+\r
+/**\r
+ * Read the status register.\r
+ *\r
+ * @return the value. (0x80:CommandLock)\r
+ */\r
+unsigned char oled_readStatusRegister() {\r
+ unsigned char s;\r
+ DC_CMD();\r
+ CS_ENA();\r
+ s = SPI_READ();\r
+ CS_DIS();\r
+ return s;\r
+}\r
--- /dev/null
+/**\r
+ * @file oled.h\r
+ * @author Shinichiro Nakamura\r
+ * @brief OLEDドライバの定義。\r
+ * @details\r
+ * OLED(96x64dots)の下層ドライバ。\r
+ * リソースに対するロックは上層で行うこと。\r
+ * 焼付防止のような処理はアプリケーション層に委ねる。\r
+ */\r
+\r
+/*\r
+ * ===============================================================\r
+ * Aitendo OLED device driver library. (Version 0.0.2)\r
+ *\r
+ * [The product]\r
+ * OLED-2P-095BWNN-SPI : http://www.aitendo.co.jp/product/2099\r
+ * ALO-095BWNN-J9 : http://www.aitendo.co.jp/product/1449\r
+ *\r
+ * [References]\r
+ * http://serdisplib.sourceforge.net/ser/doc/Treiber_IC-SSD1332_OLED_96x64_COLOR.pdf\r
+ * ===============================================================\r
+ * Copyright (c) 2010-2011 Shinichiro Nakamura\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person\r
+ * obtaining a copy of this software and associated documentation\r
+ * files (the "Software"), to deal in the Software without\r
+ * restriction, including without limitation the rights to use,\r
+ * copy, modify, merge, publish, distribute, sublicense, and/or\r
+ * sell copies of the Software, and to permit persons to whom the\r
+ * Software is furnished to do so, subject to the following\r
+ * conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be\r
+ * included in all copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\r
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\r
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\r
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\r
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\r
+ * OTHER DEALINGS IN THE SOFTWARE.\r
+ * ===============================================================\r
+ */\r
+\r
+#ifndef AITENDO_OLED_H\r
+#define AITENDO_OLED_H\r
+\r
+typedef struct color {\r
+ unsigned char r;\r
+ unsigned char g;\r
+ unsigned char b;\r
+} Color;\r
+\r
+#define OLED_X 96\r
+#define OLED_Y 64\r
+\r
+/**\r
+ * @defgroup BLACKTANK_LPC1769_DRIVER_OLED\r
+ * @ingroup BLACKTANK_LPC1769_DRIVER\r
+ * @{\r
+ */\r
+\r
+void oled_init(void);\r
+\r
+/**\r
+ * Draw pixel.\r
+ *\r
+ * @param x X.\r
+ * @param y Y.\r
+ * @param c Color.\r
+ */\r
+void oled_draw_pixel(int x, int y, Color c);\r
+\r
+/**\r
+ * Draw line.\r
+ *\r
+ * @param x1 X1.\r
+ * @param y1 Y1.\r
+ * @param x2 X2.\r
+ * @param y2 Y2.\r
+ * @param c Color.\r
+ */\r
+void oled_draw_line(int x1, int y1, int x2, int y2, Color c);\r
+\r
+/**\r
+ * Fill box.\r
+ *\r
+ * @param x1 X1.\r
+ * @param y1 Y1.\r
+ * @param x2 X2.\r
+ * @param y2 Y2.\r
+ * @param c1 Color1.\r
+ * @param c2 Color2.\r
+ */\r
+void oled_fill_box(int x1, int y1, int x2, int y2, Color c1, Color c2);\r
+\r
+/**\r
+ * Copy.\r
+ *\r
+ * @param x1 X1.\r
+ * @param y1 Y1.\r
+ * @param x2 X2.\r
+ * @param y2 Y2.\r
+ * @param nx X of the destination.\r
+ * @param ny Y of the destination.\r
+ */\r
+void oled_copy(int x1, int y1, int x2, int y2, int nx, int ny);\r
+\r
+/**\r
+ * Darker.\r
+ *\r
+ * @param x1 X1.\r
+ * @param y1 Y1.\r
+ * @param x2 X2.\r
+ * @param y2 Y2.\r
+ */\r
+void oled_darker(int x1, int y1, int x2, int y2);\r
+\r
+/**\r
+ * Clear.\r
+ *\r
+ * @param x1 X1.\r
+ * @param y1 Y1.\r
+ * @param x2 X2.\r
+ * @param y2 Y2.\r
+ */\r
+void oled_clear(int x1, int y1, int x2, int y2);\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#endif\r
--- /dev/null
+/**\r
+ * @file diskio_pff.h\r
+ * @brief 低レベルディスクI/Oインターフェースモジュールの定義。\r
+ */\r
+\r
+/*-----------------------------------------------------------------------\r
+/ PFF - Low level disk interface modlue include file (C)ChaN, 2009\r
+/-----------------------------------------------------------------------*/\r
+\r
+#ifndef DISKIO_PFF_H\r
+\r
+#include "integer_pff.h"\r
+\r
+\r
+/* Status of Disk Functions */\r
+typedef BYTE DSTATUS;\r
+\r
+\r
+/* Results of Disk Functions */\r
+typedef enum {\r
+ RES_OK = 0, /* 0: Function succeeded */\r
+ RES_ERROR, /* 1: Disk error */\r
+ RES_NOTRDY, /* 2: Not ready */\r
+ RES_PARERR /* 3: Invalid parameter */\r
+} DRESULT;\r
+\r
+\r
+/*---------------------------------------*/\r
+/* Prototypes for disk control functions */\r
+\r
+DSTATUS disk_initialize (void);\r
+DRESULT disk_readp (BYTE*, DWORD, WORD, WORD);\r
+DRESULT disk_writep (const BYTE*, DWORD);\r
+\r
+#define STA_NOINIT 0x01 /* Drive not initialized */\r
+#define STA_NODISK 0x02 /* No medium in the drive */\r
+\r
+/* Card type flags (CardType) */\r
+#define CT_MMC 0x01 /* MMC ver 3 */\r
+#define CT_SD1 0x02 /* SD ver 1 */\r
+#define CT_SD2 0x04 /* SD ver 2 */\r
+#define CT_SDC (CT_SD1|CT_SD2) /* SD */\r
+#define CT_BLOCK 0x08 /* Block addressing */\r
+\r
+#define _DISKIO\r
+#endif\r
--- /dev/null
+/**\r
+ * @file diskio_pff_mmc.c\r
+ * @brief 低レベルディスクI/Oインターフェースモジュールの実装。(SPI版)\r
+ */\r
+\r
+/*-------------------------------------------------------------------------*/\r
+/* PFF - Low level disk control module for AVR (C)ChaN, 2010 */\r
+/*-------------------------------------------------------------------------*/\r
+\r
+#include "pff.h"\r
+#include "diskio_pff.h"\r
+#include "pffspi.h"\r
+\r
+#define SPI_INIT() pffspi_init()\r
+#define SPI_TX(c) pffspi_tx(c)\r
+#define SPI_RX() pffspi_rx()\r
+#define SPI_CS_ENA() pffspi_cs_ena()\r
+#define SPI_CS_DIS() pffspi_cs_dis()\r
+#define SPI_CS_STAT() pffspi_cs_stat()\r
+\r
+#define SPI_FORWARD(c)\r
+#define SPI_DLY_1MS() pffspi_dly_1ms()\r
+\r
+/*--------------------------------------------------------------------------\r
+\r
+ Module Private Functions\r
+\r
+---------------------------------------------------------------------------*/\r
+\r
+/* Definitions for MMC/SDC command */\r
+#define CMD0 (0x40+0) /* GO_IDLE_STATE */\r
+#define CMD1 (0x40+1) /* SEND_OP_COND (MMC) */\r
+#define ACMD41 (0xC0+41) /* SEND_OP_COND (SDC) */\r
+#define CMD8 (0x40+8) /* SEND_IF_COND */\r
+#define CMD16 (0x40+16) /* SET_BLOCKLEN */\r
+#define CMD17 (0x40+17) /* READ_SINGLE_BLOCK */\r
+#define CMD24 (0x40+24) /* WRITE_BLOCK */\r
+#define CMD55 (0x40+55) /* APP_CMD */\r
+#define CMD58 (0x40+58) /* READ_OCR */\r
+\r
+\r
+/* Card type flags (CardType) */\r
+#define CT_MMC 0x01 /* MMC ver 3 */\r
+#define CT_SD1 0x02 /* SD ver 1 */\r
+#define CT_SD2 0x04 /* SD ver 2 */\r
+#define CT_BLOCK 0x08 /* Block addressing */\r
+\r
+\r
+static\r
+BYTE CardType;\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Send a command packet to MMC */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+BYTE send_cmd (\r
+ BYTE cmd, /* 1st byte (Start + Index) */\r
+ DWORD arg /* Argument (32 bits) */\r
+)\r
+{\r
+ BYTE n, res;\r
+\r
+\r
+ if (cmd & 0x80) { /* ACMD<n> is the command sequense of CMD55-CMD<n> */\r
+ cmd &= 0x7F;\r
+ res = send_cmd(CMD55, 0);\r
+ if (res > 1) return res;\r
+ }\r
+\r
+ /* Select the card */\r
+ SPI_CS_DIS();\r
+ SPI_RX();\r
+ SPI_CS_ENA();\r
+ SPI_RX();\r
+\r
+ /* Send a command packet */\r
+ SPI_TX(cmd); /* Start + Command index */\r
+ SPI_TX((BYTE)(arg >> 24)); /* Argument[31..24] */\r
+ SPI_TX((BYTE)(arg >> 16)); /* Argument[23..16] */\r
+ SPI_TX((BYTE)(arg >> 8)); /* Argument[15..8] */\r
+ SPI_TX((BYTE)arg); /* Argument[7..0] */\r
+ n = 0x01; /* Dummy CRC + Stop */\r
+ if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */\r
+ if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */\r
+ SPI_TX(n);\r
+\r
+ /* Receive a command response */\r
+ n = 10; /* Wait for a valid response in timeout of 10 attempts */\r
+ do {\r
+ res = SPI_RX();\r
+ } while ((res & 0x80) && --n);\r
+\r
+ return res; /* Return with the response value */\r
+}\r
+\r
+\r
+\r
+\r
+/*--------------------------------------------------------------------------\r
+\r
+ Public Functions\r
+\r
+---------------------------------------------------------------------------*/\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Initialize Disk Drive */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+DSTATUS disk_initialize (void)\r
+{\r
+ BYTE n, cmd, ty, ocr[4];\r
+ UINT tmr;\r
+\r
+#if _USE_WRITE\r
+ if (CardType && SPI_CS_STAT()) disk_writep(0, 0); /* Finalize write process if it is in progress */\r
+#endif\r
+ SPI_INIT(); /* Initialize ports to control MMC */\r
+ SPI_CS_DIS();\r
+ for (n = 10; n; n--) SPI_RX(); /* 80 dummy clocks with CS=H */\r
+\r
+ ty = 0;\r
+ if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */\r
+ if (send_cmd(CMD8, 0x1AA) == 1) { /* SDv2 */\r
+ for (n = 0; n < 4; n++) ocr[n] = SPI_RX(); /* Get trailing return value of R7 resp */\r
+ if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */\r
+ for (tmr = 10000; tmr && send_cmd(ACMD41, 1UL << 30); tmr--) SPI_DLY_1MS(); /* Wait for leaving idle state (ACMD41 with HCS bit) */\r
+ if (tmr && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */\r
+ for (n = 0; n < 4; n++) ocr[n] = SPI_RX();\r
+ ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* SDv2 (HC or SC) */\r
+ }\r
+ }\r
+ } else { /* SDv1 or MMCv3 */\r
+ if (send_cmd(ACMD41, 0) <= 1) {\r
+ ty = CT_SD1; cmd = ACMD41; /* SDv1 */\r
+ } else {\r
+ ty = CT_MMC; cmd = CMD1; /* MMCv3 */\r
+ }\r
+ for (tmr = 10000; tmr && send_cmd(cmd, 0); tmr--) SPI_DLY_1MS(); /* Wait for leaving idle state */\r
+ if (!tmr || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */\r
+ ty = 0;\r
+ }\r
+ }\r
+ CardType = ty;\r
+ SPI_CS_DIS();\r
+ SPI_RX();\r
+\r
+ return ty ? 0 : STA_NOINIT;\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Read partial sector */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+DRESULT disk_readp (\r
+ BYTE *buff, /* Pointer to the read buffer (NULL:Read bytes are forwarded to the stream) */\r
+ DWORD lba, /* Sector number (LBA) */\r
+ WORD ofs, /* Byte offset to read from (0..511) */\r
+ WORD cnt /* Number of bytes to read (ofs + cnt mus be <= 512) */\r
+)\r
+{\r
+ DRESULT res;\r
+ BYTE rc;\r
+ WORD bc;\r
+\r
+\r
+ if (!(CardType & CT_BLOCK)) lba *= 512; /* Convert to byte address if needed */\r
+\r
+ res = RES_ERROR;\r
+ if (send_cmd(CMD17, lba) == 0) { /* READ_SINGLE_BLOCK */\r
+\r
+ bc = 40000;\r
+ do { /* Wait for data packet */\r
+ rc = SPI_RX();\r
+ } while (rc == 0xFF && --bc);\r
+\r
+ if (rc == 0xFE) { /* A data packet arrived */\r
+ bc = 514 - ofs - cnt;\r
+\r
+ /* Skip leading bytes */\r
+ if (ofs) {\r
+ do SPI_RX(); while (--ofs);\r
+ }\r
+\r
+ /* Receive a part of the sector */\r
+ if (buff) { /* Store data to the memory */\r
+ do {\r
+ *buff++ = SPI_RX();\r
+ } while (--cnt);\r
+ } else { /* Forward data to the outgoing stream (depends on the project) */\r
+ do {\r
+ SPI_FORWARD(SPI_RX());\r
+ } while (--cnt);\r
+ }\r
+\r
+ /* Skip trailing bytes and CRC */\r
+ do SPI_RX(); while (--bc);\r
+\r
+ res = RES_OK;\r
+ }\r
+ }\r
+\r
+ SPI_CS_DIS();\r
+ SPI_RX();\r
+\r
+ return res;\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Write partial sector */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+#if _USE_WRITE\r
+DRESULT disk_writep (\r
+ const BYTE *buff, /* Pointer to the bytes to be written (NULL:Initiate/Finalize sector write) */\r
+ DWORD sa /* Number of bytes to send, Sector number (LBA) or zero */\r
+)\r
+{\r
+ DRESULT res;\r
+ WORD bc;\r
+ static WORD wc;\r
+\r
+ res = RES_ERROR;\r
+\r
+ if (buff) { /* Send data bytes */\r
+ bc = (WORD)sa;\r
+ while (bc && wc) { /* Send data bytes to the card */\r
+ SPI_TX(*buff++);\r
+ wc--; bc--;\r
+ }\r
+ res = RES_OK;\r
+ } else {\r
+ if (sa) { /* Initiate sector write process */\r
+ if (!(CardType & CT_BLOCK)) sa *= 512; /* Convert to byte address if needed */\r
+ if (send_cmd(CMD24, sa) == 0) { /* WRITE_SINGLE_BLOCK */\r
+ SPI_TX(0xFF); SPI_TX(0xFE); /* Data block header */\r
+ wc = 512; /* Set byte counter */\r
+ res = RES_OK;\r
+ }\r
+ } else { /* Finalize sector write process */\r
+ bc = wc + 2;\r
+ while (bc--) SPI_TX(0); /* Fill left bytes and CRC with zeros */\r
+ if ((SPI_RX() & 0x1F) == 0x05) { /* Receive data resp and wait for end of write process in timeout of 500ms */\r
+ for (bc = 5000; SPI_RX() != 0xFF && bc; bc--) SPI_DLY_1MS(); /* Wait ready */\r
+ if (bc) res = RES_OK;\r
+ }\r
+ SPI_CS_DIS();\r
+ SPI_RX();\r
+ }\r
+ }\r
+\r
+ return res;\r
+}\r
+#endif\r
--- /dev/null
+/**\r
+ * @file integer_pff.h\r
+ * @brief FatFsモジュール用の整数型定義。\r
+ */\r
+\r
+/*-------------------------------------------*/\r
+/* Integer type definitions for FatFs module */\r
+/*-------------------------------------------*/\r
+\r
+#ifndef INTEGER_PFF_H\r
+#define INTEGER_PFF_H\r
+\r
+/* These types must be 16-bit, 32-bit or larger integer */\r
+#ifndef TOPPERS_ITRON_H\r
+typedef int INT;\r
+typedef unsigned int UINT;\r
+#endif\r
+\r
+/* These types must be 8-bit integer */\r
+typedef char CHAR;\r
+typedef unsigned char UCHAR;\r
+typedef unsigned char BYTE;\r
+\r
+/* These types must be 16-bit integer */\r
+typedef short SHORT;\r
+typedef unsigned short USHORT;\r
+typedef unsigned short WORD;\r
+typedef unsigned short WCHAR;\r
+\r
+/* These types must be 32-bit integer */\r
+typedef long LONG;\r
+typedef unsigned long ULONG;\r
+typedef unsigned long DWORD;\r
+\r
+#endif\r
--- /dev/null
+/**\r
+ * @file pff.c\r
+ * @brief FATファイルシステムドライバの実装。\r
+ */\r
+\r
+/*----------------------------------------------------------------------------/\r
+/ Petit FatFs - FAT file system module R0.02a (C)ChaN, 2010\r
+/-----------------------------------------------------------------------------/\r
+/ Petit FatFs module is an open source software to implement FAT file system to\r
+/ small embedded systems. This is a free software and is opened for education,\r
+/ research and commercial developments under license policy of following trems.\r
+/\r
+/ Copyright (C) 2010, ChaN, all right reserved.\r
+/\r
+/ * The Petit FatFs module is a free software and there is NO WARRANTY.\r
+/ * No restriction on use. You can use, modify and redistribute it for\r
+/ personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.\r
+/ * Redistributions of source code must retain the above copyright notice.\r
+/\r
+/-----------------------------------------------------------------------------/\r
+/ Jun 15,'09 R0.01a First release. (Branched from FatFs R0.07b.)\r
+/\r
+/ Dec 14,'09 R0.02 Added multiple code page support.\r
+/ Added write funciton.\r
+/ Changed stream read mode interface.\r
+/ Dec 07,'10 R0.02a Added some configuration options.\r
+/ Fixed fails to open objects with DBCS character.\r
+/----------------------------------------------------------------------------*/\r
+\r
+#include "pff.h" /* Petit FatFs configurations and declarations */\r
+#include "diskio_pff.h" /* Declarations of low level disk I/O functions */\r
+\r
+\r
+\r
+/*--------------------------------------------------------------------------\r
+\r
+ Module Private Definitions\r
+\r
+---------------------------------------------------------------------------*/\r
+\r
+\r
+#if _FS_FAT32\r
+#define LD_CLUST(dir) (((DWORD)LD_WORD(dir+DIR_FstClusHI)<<16) | LD_WORD(dir+DIR_FstClusLO))\r
+#else\r
+#define LD_CLUST(dir) LD_WORD(dir+DIR_FstClusLO)\r
+#endif\r
+\r
+\r
+/*--------------------------------------------------------*/\r
+/* DBCS code ranges and SBCS extend char conversion table */\r
+\r
+#if _CODE_PAGE == 932 /* Japanese Shift-JIS */\r
+#define _DF1S 0x81 /* DBC 1st byte range 1 start */\r
+#define _DF1E 0x9F /* DBC 1st byte range 1 end */\r
+#define _DF2S 0xE0 /* DBC 1st byte range 2 start */\r
+#define _DF2E 0xFC /* DBC 1st byte range 2 end */\r
+#define _DS1S 0x40 /* DBC 2nd byte range 1 start */\r
+#define _DS1E 0x7E /* DBC 2nd byte range 1 end */\r
+#define _DS2S 0x80 /* DBC 2nd byte range 2 start */\r
+#define _DS2E 0xFC /* DBC 2nd byte range 2 end */\r
+\r
+#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */\r
+#define _DF1S 0x81\r
+#define _DF1E 0xFE\r
+#define _DS1S 0x40\r
+#define _DS1E 0x7E\r
+#define _DS2S 0x80\r
+#define _DS2E 0xFE\r
+\r
+#elif _CODE_PAGE == 949 /* Korean */\r
+#define _DF1S 0x81\r
+#define _DF1E 0xFE\r
+#define _DS1S 0x41\r
+#define _DS1E 0x5A\r
+#define _DS2S 0x61\r
+#define _DS2E 0x7A\r
+#define _DS3S 0x81\r
+#define _DS3E 0xFE\r
+\r
+#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */\r
+#define _DF1S 0x81\r
+#define _DF1E 0xFE\r
+#define _DS1S 0x40\r
+#define _DS1E 0x7E\r
+#define _DS2S 0xA1\r
+#define _DS2E 0xFE\r
+\r
+#elif _CODE_PAGE == 437 /* U.S. (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 720 /* Arabic (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 737 /* Greek (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \\r
+ 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 775 /* Baltic (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \\r
+ 0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \\r
+ 0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \\r
+ 0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 857 /* Turkish (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \\r
+ 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 862 /* Hebrew (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 866 /* Russian (OEM) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 1250 /* Central Europe (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \\r
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}\r
+\r
+#elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \\r
+ 0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF}\r
+\r
+#elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \\r
+ 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}\r
+\r
+#elif _CODE_PAGE == 1253 /* Greek (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \\r
+ 0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF}\r
+\r
+#elif _CODE_PAGE == 1254 /* Turkish (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}\r
+\r
+#elif _CODE_PAGE == 1255 /* Hebrew (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 1256 /* Arabic (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF}\r
+\r
+#elif _CODE_PAGE == 1257 /* Baltic (Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \\r
+ 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}\r
+\r
+#elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */\r
+#define _DF1S 0\r
+#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \\r
+ 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \\r
+ 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F}\r
+\r
+#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */\r
+#define _DF1S 0\r
+\r
+#else\r
+#error Unknown code page\r
+\r
+#endif\r
+\r
+\r
+\r
+/* Character code support macros */\r
+\r
+#define IsUpper(c) (((c)>='A')&&((c)<='Z'))\r
+#define IsLower(c) (((c)>='a')&&((c)<='z'))\r
+\r
+#if _DF1S /* DBCS configuration */\r
+\r
+#ifdef _DF2S /* Two 1st byte areas */\r
+#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E))\r
+#else /* One 1st byte area */\r
+#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E)\r
+#endif\r
+\r
+#ifdef _DS3S /* Three 2nd byte areas */\r
+#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E))\r
+#else /* Two 2nd byte areas */\r
+#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E))\r
+#endif\r
+\r
+#else /* SBCS configuration */\r
+\r
+#define IsDBCS1(c) 0\r
+#define IsDBCS2(c) 0\r
+\r
+#endif /* _DF1S */\r
+\r
+\r
+/* FatFs refers the members in the FAT structures with byte offset instead\r
+/ of structure member because there are incompatibility of the packing option\r
+/ between various compilers. */\r
+\r
+#define BS_jmpBoot 0\r
+#define BS_OEMName 3\r
+#define BPB_BytsPerSec 11\r
+#define BPB_SecPerClus 13\r
+#define BPB_RsvdSecCnt 14\r
+#define BPB_NumFATs 16\r
+#define BPB_RootEntCnt 17\r
+#define BPB_TotSec16 19\r
+#define BPB_Media 21\r
+#define BPB_FATSz16 22\r
+#define BPB_SecPerTrk 24\r
+#define BPB_NumHeads 26\r
+#define BPB_HiddSec 28\r
+#define BPB_TotSec32 32\r
+#define BS_55AA 510\r
+\r
+#define BS_DrvNum 36\r
+#define BS_BootSig 38\r
+#define BS_VolID 39\r
+#define BS_VolLab 43\r
+#define BS_FilSysType 54\r
+\r
+#define BPB_FATSz32 36\r
+#define BPB_ExtFlags 40\r
+#define BPB_FSVer 42\r
+#define BPB_RootClus 44\r
+#define BPB_FSInfo 48\r
+#define BPB_BkBootSec 50\r
+#define BS_DrvNum32 64\r
+#define BS_BootSig32 66\r
+#define BS_VolID32 67\r
+#define BS_VolLab32 71\r
+#define BS_FilSysType32 82\r
+\r
+#define MBR_Table 446\r
+\r
+#define DIR_Name 0\r
+#define DIR_Attr 11\r
+#define DIR_NTres 12\r
+#define DIR_CrtTime 14\r
+#define DIR_CrtDate 16\r
+#define DIR_FstClusHI 20\r
+#define DIR_WrtTime 22\r
+#define DIR_WrtDate 24\r
+#define DIR_FstClusLO 26\r
+#define DIR_FileSize 28\r
+\r
+\r
+\r
+/*--------------------------------------------------------------------------\r
+\r
+ Private Functions\r
+\r
+---------------------------------------------------------------------------*/\r
+\r
+\r
+static\r
+FATFS *FatFs; /* Pointer to the file system object (logical drive) */\r
+\r
+\r
+/* Fill memory */\r
+static\r
+void mem_set (void* dst, int val, int cnt) {\r
+ char *d = (char*)dst;\r
+ while (cnt--) *d++ = (char)val;\r
+}\r
+\r
+/* Compare memory to memory */\r
+static\r
+int mem_cmp (const void* dst, const void* src, int cnt) {\r
+ const char *d = (const char *)dst, *s = (const char *)src;\r
+ int r = 0;\r
+ while (cnt-- && (r = *d++ - *s++) == 0) ;\r
+ return r;\r
+}\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* FAT access - Read value of a FAT entry */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+CLUST get_fat ( /* 1:IO error, Else:Cluster status */\r
+ CLUST clst /* Cluster# to get the link information */\r
+)\r
+{\r
+ WORD wc, bc, ofs;\r
+ BYTE buf[4];\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ if (clst < 2 || clst >= fs->n_fatent) /* Range check */\r
+ return 1;\r
+\r
+ switch (fs->fs_type) {\r
+#if _FS_FAT12\r
+ case FS_FAT12 :\r
+ bc = (WORD)clst; bc += bc / 2;\r
+ ofs = bc % 512; bc /= 512;\r
+ if (ofs != 511) {\r
+ if (disk_readp(buf, fs->fatbase + bc, ofs, 2)) break;\r
+ } else {\r
+ if (disk_readp(buf, fs->fatbase + bc, 511, 1)) break;\r
+ if (disk_readp(buf+1, fs->fatbase + bc + 1, 0, 1)) break;\r
+ }\r
+ wc = LD_WORD(buf);\r
+ return (clst & 1) ? (wc >> 4) : (wc & 0xFFF);\r
+#endif\r
+ case FS_FAT16 :\r
+ if (disk_readp(buf, fs->fatbase + clst / 256, (WORD)(((WORD)clst % 256) * 2), 2)) break;\r
+ return LD_WORD(buf);\r
+#if _FS_FAT32\r
+ case FS_FAT32 :\r
+ if (disk_readp(buf, fs->fatbase + clst / 128, (WORD)(((WORD)clst % 128) * 4), 4)) break;\r
+ return LD_DWORD(buf) & 0x0FFFFFFF;\r
+#endif\r
+ }\r
+\r
+ return 1; /* An error occured at the disk I/O layer */\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Get sector# from cluster# */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */\r
+ CLUST clst /* Cluster# to be converted */\r
+)\r
+{\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ clst -= 2;\r
+ if (clst >= (fs->n_fatent - 2)) return 0; /* Invalid cluster# */\r
+ return (DWORD)clst * fs->csize + fs->database;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Directory handling - Rewind directory index */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+FRESULT dir_rewind (\r
+ DIR *dj /* Pointer to directory object */\r
+)\r
+{\r
+ CLUST clst;\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ dj->index = 0;\r
+ clst = dj->sclust;\r
+ if (clst == 1 || clst >= fs->n_fatent) /* Check start cluster range */\r
+ return FR_DISK_ERR;\r
+ if (_FS_FAT32 && !clst && fs->fs_type == FS_FAT32) /* Replace cluster# 0 with root cluster# if in FAT32 */\r
+ clst = (CLUST)fs->dirbase;\r
+ dj->clust = clst; /* Current cluster */\r
+ dj->sect = clst ? clust2sect(clst) : fs->dirbase; /* Current sector */\r
+\r
+ return FR_OK; /* Seek succeeded */\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Directory handling - Move directory index next */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table */\r
+ DIR *dj /* Pointer to directory object */\r
+)\r
+{\r
+ CLUST clst;\r
+ WORD i;\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ i = dj->index + 1;\r
+ if (!i || !dj->sect) /* Report EOT when index has reached 65535 */\r
+ return FR_NO_FILE;\r
+\r
+ if (!(i % 16)) { /* Sector changed? */\r
+ dj->sect++; /* Next sector */\r
+\r
+ if (dj->clust == 0) { /* Static table */\r
+ if (i >= fs->n_rootdir) /* Report EOT when end of table */\r
+ return FR_NO_FILE;\r
+ }\r
+ else { /* Dynamic table */\r
+ if (((i / 16) & (fs->csize-1)) == 0) { /* Cluster changed? */\r
+ clst = get_fat(dj->clust); /* Get next cluster */\r
+ if (clst <= 1) return FR_DISK_ERR;\r
+ if (clst >= fs->n_fatent) /* When it reached end of dynamic table */\r
+ return FR_NO_FILE; /* Report EOT */\r
+ dj->clust = clst; /* Initialize data for new cluster */\r
+ dj->sect = clust2sect(clst);\r
+ }\r
+ }\r
+ }\r
+\r
+ dj->index = i;\r
+\r
+ return FR_OK;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Directory handling - Find an object in the directory */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+FRESULT dir_find (\r
+ DIR *dj, /* Pointer to the directory object linked to the file name */\r
+ BYTE *dir /* 32-byte working buffer */\r
+)\r
+{\r
+ FRESULT res;\r
+ BYTE c;\r
+\r
+\r
+ res = dir_rewind(dj); /* Rewind directory object */\r
+ if (res != FR_OK) return res;\r
+\r
+ do {\r
+ res = disk_readp(dir, dj->sect, (WORD)((dj->index % 16) * 32), 32) /* Read an entry */\r
+ ? FR_DISK_ERR : FR_OK;\r
+ if (res != FR_OK) break;\r
+ c = dir[DIR_Name]; /* First character */\r
+ if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */\r
+ if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) /* Is it a valid entry? */\r
+ break;\r
+ res = dir_next(dj); /* Next entry */\r
+ } while (res == FR_OK);\r
+\r
+ return res;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Read an object from the directory */\r
+/*-----------------------------------------------------------------------*/\r
+#if _USE_DIR\r
+static\r
+FRESULT dir_read (\r
+ DIR *dj, /* Pointer to the directory object to store read object name */\r
+ BYTE *dir /* 32-byte working buffer */\r
+)\r
+{\r
+ FRESULT res;\r
+ BYTE a, c;\r
+\r
+\r
+ res = FR_NO_FILE;\r
+ while (dj->sect) {\r
+ res = disk_readp(dir, dj->sect, (WORD)((dj->index % 16) * 32), 32) /* Read an entry */\r
+ ? FR_DISK_ERR : FR_OK;\r
+ if (res != FR_OK) break;\r
+ c = dir[DIR_Name];\r
+ if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */\r
+ a = dir[DIR_Attr] & AM_MASK;\r
+ if (c != 0xE5 && c != '.' && !(a & AM_VOL)) /* Is it a valid entry? */\r
+ break;\r
+ res = dir_next(dj); /* Next entry */\r
+ if (res != FR_OK) break;\r
+ }\r
+\r
+ if (res != FR_OK) dj->sect = 0;\r
+\r
+ return res;\r
+}\r
+#endif\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Pick a segment and create the object name in directory form */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+#ifdef _EXCVT\r
+ static const BYTE cvt[] = _EXCVT;\r
+#endif\r
+\r
+static\r
+FRESULT create_name (\r
+ DIR *dj, /* Pointer to the directory object */\r
+ const char **path /* Pointer to pointer to the segment in the path string */\r
+)\r
+{\r
+ BYTE c, d, ni, si, i, *sfn;\r
+ const char *p;\r
+\r
+ /* Create file name in directory form */\r
+ sfn = dj->fn;\r
+ mem_set(sfn, ' ', 11);\r
+ si = i = 0; ni = 8;\r
+ p = *path;\r
+ for (;;) {\r
+ c = p[si++];\r
+ if (c <= ' ' || c == '/') break; /* Break on end of segment */\r
+ if (c == '.' || i >= ni) {\r
+ if (ni != 8 || c != '.') break;\r
+ i = 8; ni = 11;\r
+ continue;\r
+ }\r
+#ifdef _EXCVT\r
+ if (c >= 0x80) /* To upper extended char (SBCS) */\r
+ c = cvt[c - 0x80];\r
+#endif\r
+ if (IsDBCS1(c) && i < ni - 1) { /* DBC 1st byte? */\r
+ d = p[si++]; /* Get 2nd byte */\r
+ sfn[i++] = c;\r
+ sfn[i++] = d;\r
+ } else { /* Single byte code */\r
+ if (IsLower(c)) c -= 0x20; /* toupper */\r
+ sfn[i++] = c;\r
+ }\r
+ }\r
+ *path = &p[si]; /* Rerurn pointer to the next segment */\r
+\r
+ sfn[11] = (c <= ' ') ? 1 : 0; /* Set last segment flag if end of path */\r
+\r
+ return FR_OK;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Get file information from directory entry */\r
+/*-----------------------------------------------------------------------*/\r
+#if _USE_DIR\r
+static\r
+void get_fileinfo ( /* No return code */\r
+ DIR *dj, /* Pointer to the directory object */\r
+ BYTE *dir, /* 32-byte working buffer */\r
+ FILINFO *fno /* Pointer to store the file information */\r
+)\r
+{\r
+ BYTE i, c;\r
+ char *p;\r
+\r
+\r
+ p = fno->fname;\r
+ if (dj->sect) {\r
+ for (i = 0; i < 8; i++) { /* Copy file name body */\r
+ c = dir[i];\r
+ if (c == ' ') break;\r
+ if (c == 0x05) c = 0xE5;\r
+ *p++ = c;\r
+ }\r
+ if (dir[8] != ' ') { /* Copy file name extension */\r
+ *p++ = '.';\r
+ for (i = 8; i < 11; i++) {\r
+ c = dir[i];\r
+ if (c == ' ') break;\r
+ *p++ = c;\r
+ }\r
+ }\r
+ fno->fattrib = dir[DIR_Attr]; /* Attribute */\r
+ fno->fsize = LD_DWORD(dir+DIR_FileSize); /* Size */\r
+ fno->fdate = LD_WORD(dir+DIR_WrtDate); /* Date */\r
+ fno->ftime = LD_WORD(dir+DIR_WrtTime); /* Time */\r
+ }\r
+ *p = 0;\r
+}\r
+#endif /* _USE_DIR */\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Follow a file path */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */\r
+ DIR *dj, /* Directory object to return last directory and found object */\r
+ BYTE *dir, /* 32-byte working buffer */\r
+ const char *path /* Full-path string to find a file or directory */\r
+)\r
+{\r
+ FRESULT res;\r
+\r
+\r
+ while (*path == ' ') path++; /* Skip leading spaces */\r
+ if (*path == '/') path++; /* Strip heading separator */\r
+ dj->sclust = 0; /* Set start directory (always root dir) */\r
+\r
+ if ((BYTE)*path <= ' ') { /* Null path means the root directory */\r
+ res = dir_rewind(dj);\r
+ dir[0] = 0;\r
+\r
+ } else { /* Follow path */\r
+ for (;;) {\r
+ res = create_name(dj, &path); /* Get a segment */\r
+ if (res != FR_OK) break;\r
+ res = dir_find(dj, dir); /* Find it */\r
+ if (res != FR_OK) { /* Could not find the object */\r
+ if (res == FR_NO_FILE && !*(dj->fn+11))\r
+ res = FR_NO_PATH;\r
+ break;\r
+ }\r
+ if (*(dj->fn+11)) break; /* Last segment match. Function completed. */\r
+ if (!(dir[DIR_Attr] & AM_DIR)) { /* Cannot follow because it is a file */\r
+ res = FR_NO_PATH; break;\r
+ }\r
+ dj->sclust = LD_CLUST(dir);\r
+ }\r
+ }\r
+\r
+ return res;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Check a sector if it is an FAT boot record */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+static\r
+BYTE check_fs ( /* 0:The FAT boot record, 1:Valid boot record but not an FAT, 2:Not a boot record, 3:Error */\r
+ BYTE *buf, /* Working buffer */\r
+ DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */\r
+)\r
+{\r
+ if (disk_readp(buf, sect, 510, 2)) /* Read the boot sector */\r
+ return 3;\r
+ if (LD_WORD(buf) != 0xAA55) /* Check record signature */\r
+ return 2;\r
+\r
+ if (!disk_readp(buf, sect, BS_FilSysType, 2) && LD_WORD(buf) == 0x4146) /* Check FAT12/16 */\r
+ return 0;\r
+ if (_FS_FAT32 && !disk_readp(buf, sect, BS_FilSysType32, 2) && LD_WORD(buf) == 0x4146) /* Check FAT32 */\r
+ return 0;\r
+ return 1;\r
+}\r
+\r
+\r
+\r
+\r
+/*--------------------------------------------------------------------------\r
+\r
+ Public Functions\r
+\r
+--------------------------------------------------------------------------*/\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Mount/Unmount a Locical Drive */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT pf_mount (\r
+ FATFS *fs /* Pointer to new file system object (NULL: Unmount) */\r
+)\r
+{\r
+ BYTE fmt, buf[36];\r
+ DWORD bsect, fsize, tsect, mclst;\r
+\r
+\r
+ FatFs = 0;\r
+ if (!fs) return FR_OK; /* Unregister fs object */\r
+\r
+ if (disk_initialize() & STA_NOINIT) /* Check if the drive is ready or not */\r
+ return FR_NOT_READY;\r
+\r
+ /* Search FAT partition on the drive */\r
+ bsect = 0;\r
+ fmt = check_fs(buf, bsect); /* Check sector 0 as an SFD format */\r
+ if (fmt == 1) { /* Not an FAT boot record, it may be FDISK format */\r
+ /* Check a partition listed in top of the partition table */\r
+ if (disk_readp(buf, bsect, MBR_Table, 16)) { /* 1st partition entry */\r
+ fmt = 3;\r
+ } else {\r
+ if (buf[4]) { /* Is the partition existing? */\r
+ bsect = LD_DWORD(&buf[8]); /* Partition offset in LBA */\r
+ fmt = check_fs(buf, bsect); /* Check the partition */\r
+ }\r
+ }\r
+ }\r
+ if (fmt == 3) return FR_DISK_ERR;\r
+ if (fmt) return FR_NO_FILESYSTEM; /* No valid FAT patition is found */\r
+\r
+ /* Initialize the file system object */\r
+ if (disk_readp(buf, bsect, 13, sizeof(buf))) return FR_DISK_ERR;\r
+\r
+ fsize = LD_WORD(buf+BPB_FATSz16-13); /* Number of sectors per FAT */\r
+ if (!fsize) fsize = LD_DWORD(buf+BPB_FATSz32-13);\r
+\r
+ fsize *= buf[BPB_NumFATs-13]; /* Number of sectors in FAT area */\r
+ fs->fatbase = bsect + LD_WORD(buf+BPB_RsvdSecCnt-13); /* FAT start sector (lba) */\r
+ fs->csize = buf[BPB_SecPerClus-13]; /* Number of sectors per cluster */\r
+ fs->n_rootdir = LD_WORD(buf+BPB_RootEntCnt-13); /* Nmuber of root directory entries */\r
+ tsect = LD_WORD(buf+BPB_TotSec16-13); /* Number of sectors on the file system */\r
+ if (!tsect) tsect = LD_DWORD(buf+BPB_TotSec32-13);\r
+ mclst = (tsect /* Last cluster# + 1 */\r
+ - LD_WORD(buf+BPB_RsvdSecCnt-13) - fsize - fs->n_rootdir / 16\r
+ ) / fs->csize + 2;\r
+ fs->n_fatent = (CLUST)mclst;\r
+\r
+ fmt = FS_FAT16; /* Determine the FAT sub type */\r
+ if (mclst < 0xFF7) /* Number of clusters < 0xFF5 */\r
+#if _FS_FAT12\r
+ fmt = FS_FAT12;\r
+#else\r
+ return FR_NO_FILESYSTEM;\r
+#endif\r
+ if (mclst >= 0xFFF7) /* Number of clusters >= 0xFFF5 */\r
+#if _FS_FAT32\r
+ fmt = FS_FAT32;\r
+#else\r
+ return FR_NO_FILESYSTEM;\r
+#endif\r
+\r
+ fs->fs_type = fmt; /* FAT sub-type */\r
+ if (_FS_FAT32 && fmt == FS_FAT32)\r
+ fs->dirbase = LD_DWORD(buf+(BPB_RootClus-13)); /* Root directory start cluster */\r
+ else\r
+ fs->dirbase = fs->fatbase + fsize; /* Root directory start sector (lba) */\r
+ fs->database = fs->fatbase + fsize + fs->n_rootdir / 16; /* Data start sector (lba) */\r
+\r
+ fs->flag = 0;\r
+ FatFs = fs;\r
+\r
+ return FR_OK;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Open or Create a File */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT pf_open (\r
+ const char *path /* Pointer to the file name */\r
+)\r
+{\r
+ FRESULT res;\r
+ DIR dj;\r
+ BYTE sp[12], dir[32];\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ if (!fs) /* Check file system */\r
+ return FR_NOT_ENABLED;\r
+\r
+ fs->flag = 0;\r
+ dj.fn = sp;\r
+ res = follow_path(&dj, dir, path); /* Follow the file path */\r
+ if (res != FR_OK) return res; /* Follow failed */\r
+ if (!dir[0] || (dir[DIR_Attr] & AM_DIR)) /* It is a directory */\r
+ return FR_NO_FILE;\r
+\r
+ fs->org_clust = LD_CLUST(dir); /* File start cluster */\r
+ fs->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */\r
+ fs->fptr = 0; /* File pointer */\r
+ fs->flag = FA_OPENED;\r
+\r
+ return FR_OK;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Read File */\r
+/*-----------------------------------------------------------------------*/\r
+#if _USE_READ\r
+\r
+FRESULT pf_read (\r
+ void* buff, /* Pointer to the read buffer (NULL:Forward data to the stream)*/\r
+ WORD btr, /* Number of bytes to read */\r
+ WORD* br /* Pointer to number of bytes read */\r
+)\r
+{\r
+ DRESULT dr;\r
+ CLUST clst;\r
+ DWORD sect, remain;\r
+ WORD rcnt;\r
+ BYTE cs, *rbuff = buff;\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ *br = 0;\r
+ if (!fs) return FR_NOT_ENABLED; /* Check file system */\r
+ if (!(fs->flag & FA_OPENED)) /* Check if opened */\r
+ return FR_NOT_OPENED;\r
+\r
+ remain = fs->fsize - fs->fptr;\r
+ if (btr > remain) btr = (WORD)remain; /* Truncate btr by remaining bytes */\r
+\r
+ while (btr) { /* Repeat until all data transferred */\r
+ if ((fs->fptr % 512) == 0) { /* On the sector boundary? */\r
+ cs = (BYTE)(fs->fptr / 512 & (fs->csize - 1)); /* Sector offset in the cluster */\r
+ if (!cs) { /* On the cluster boundary? */\r
+ clst = (fs->fptr == 0) ? /* On the top of the file? */\r
+ fs->org_clust : get_fat(fs->curr_clust);\r
+ if (clst <= 1) goto fr_abort;\r
+ fs->curr_clust = clst; /* Update current cluster */\r
+ }\r
+ sect = clust2sect(fs->curr_clust); /* Get current sector */\r
+ if (!sect) goto fr_abort;\r
+ fs->dsect = sect + cs;\r
+ }\r
+ rcnt = (WORD)(512 - (fs->fptr % 512)); /* Get partial sector data from sector buffer */\r
+ if (rcnt > btr) rcnt = btr;\r
+ dr = disk_readp(!buff ? 0 : rbuff, fs->dsect, (WORD)(fs->fptr % 512), rcnt);\r
+ if (dr) goto fr_abort;\r
+ fs->fptr += rcnt; rbuff += rcnt; /* Update pointers and counters */\r
+ btr -= rcnt; *br += rcnt;\r
+ }\r
+\r
+ return FR_OK;\r
+\r
+fr_abort:\r
+ fs->flag = 0;\r
+ return FR_DISK_ERR;\r
+}\r
+#endif\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Write File */\r
+/*-----------------------------------------------------------------------*/\r
+#if _USE_WRITE\r
+\r
+FRESULT pf_write (\r
+ const void* buff, /* Pointer to the data to be written */\r
+ WORD btw, /* Number of bytes to write (0:Finalize the current write operation) */\r
+ WORD* bw /* Pointer to number of bytes written */\r
+)\r
+{\r
+ CLUST clst;\r
+ DWORD sect, remain;\r
+ const BYTE *p = buff;\r
+ BYTE cs;\r
+ WORD wcnt;\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ *bw = 0;\r
+ if (!fs) return FR_NOT_ENABLED; /* Check file system */\r
+ if (!(fs->flag & FA_OPENED)) /* Check if opened */\r
+ return FR_NOT_OPENED;\r
+\r
+ if (!btw) { /* Finalize request */\r
+ if ((fs->flag & FA__WIP) && disk_writep(0, 0)) goto fw_abort;\r
+ fs->flag &= ~FA__WIP;\r
+ return FR_OK;\r
+ } else { /* Write data request */\r
+ if (!(fs->flag & FA__WIP)) /* Round-down fptr to the sector boundary */\r
+ fs->fptr &= 0xFFFFFE00;\r
+ }\r
+ remain = fs->fsize - fs->fptr;\r
+ if (btw > remain) btw = (WORD)remain; /* Truncate btw by remaining bytes */\r
+\r
+ while (btw) { /* Repeat until all data transferred */\r
+ if (((WORD)fs->fptr % 512) == 0) { /* On the sector boundary? */\r
+ cs = (BYTE)(fs->fptr / 512 & (fs->csize - 1)); /* Sector offset in the cluster */\r
+ if (!cs) { /* On the cluster boundary? */\r
+ clst = (fs->fptr == 0) ? /* On the top of the file? */\r
+ fs->org_clust : get_fat(fs->curr_clust);\r
+ if (clst <= 1) goto fw_abort;\r
+ fs->curr_clust = clst; /* Update current cluster */\r
+ }\r
+ sect = clust2sect(fs->curr_clust); /* Get current sector */\r
+ if (!sect) goto fw_abort;\r
+ fs->dsect = sect + cs;\r
+ if (disk_writep(0, fs->dsect)) goto fw_abort; /* Initiate a sector write operation */\r
+ fs->flag |= FA__WIP;\r
+ }\r
+ wcnt = 512 - ((WORD)fs->fptr % 512); /* Number of bytes to write to the sector */\r
+ if (wcnt > btw) wcnt = btw;\r
+ if (disk_writep(p, wcnt)) goto fw_abort; /* Send data to the sector */\r
+ fs->fptr += wcnt; p += wcnt; /* Update pointers and counters */\r
+ btw -= wcnt; *bw += wcnt;\r
+ if (((WORD)fs->fptr % 512) == 0) {\r
+ if (disk_writep(0, 0)) goto fw_abort; /* Finalize the currtent secter write operation */\r
+ fs->flag &= ~FA__WIP;\r
+ }\r
+ }\r
+\r
+ return FR_OK;\r
+\r
+fw_abort:\r
+ fs->flag = 0;\r
+ return FR_DISK_ERR;\r
+}\r
+#endif\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Seek File R/W Pointer */\r
+/*-----------------------------------------------------------------------*/\r
+#if _USE_LSEEK\r
+\r
+FRESULT pf_lseek (\r
+ DWORD ofs /* File pointer from top of file */\r
+)\r
+{\r
+ CLUST clst;\r
+ DWORD bcs, sect, ifptr;\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ if (!fs) return FR_NOT_ENABLED; /* Check file system */\r
+ if (!(fs->flag & FA_OPENED)) /* Check if opened */\r
+ return FR_NOT_OPENED;\r
+\r
+ if (ofs > fs->fsize) ofs = fs->fsize; /* Clip offset with the file size */\r
+ ifptr = fs->fptr;\r
+ fs->fptr = 0;\r
+ if (ofs > 0) {\r
+ bcs = (DWORD)fs->csize * 512; /* Cluster size (byte) */\r
+ if (ifptr > 0 &&\r
+ (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */\r
+ fs->fptr = (ifptr - 1) & ~(bcs - 1); /* start from the current cluster */\r
+ ofs -= fs->fptr;\r
+ clst = fs->curr_clust;\r
+ } else { /* When seek to back cluster, */\r
+ clst = fs->org_clust; /* start from the first cluster */\r
+ fs->curr_clust = clst;\r
+ }\r
+ while (ofs > bcs) { /* Cluster following loop */\r
+ clst = get_fat(clst); /* Follow cluster chain */\r
+ if (clst <= 1 || clst >= fs->n_fatent) goto fe_abort;\r
+ fs->curr_clust = clst;\r
+ fs->fptr += bcs;\r
+ ofs -= bcs;\r
+ }\r
+ fs->fptr += ofs;\r
+ sect = clust2sect(clst); /* Current sector */\r
+ if (!sect) goto fe_abort;\r
+ fs->dsect = sect + (fs->fptr / 512 & (fs->csize - 1));\r
+ }\r
+\r
+ return FR_OK;\r
+\r
+fe_abort:\r
+ fs->flag = 0;\r
+ return FR_DISK_ERR;\r
+}\r
+#endif\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Create a Directroy Object */\r
+/*-----------------------------------------------------------------------*/\r
+#if _USE_DIR\r
+\r
+FRESULT pf_opendir (\r
+ DIR *dj, /* Pointer to directory object to create */\r
+ const char *path /* Pointer to the directory path */\r
+)\r
+{\r
+ FRESULT res;\r
+ BYTE sp[12], dir[32];\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ if (!fs) { /* Check file system */\r
+ res = FR_NOT_ENABLED;\r
+ } else {\r
+ dj->fn = sp;\r
+ res = follow_path(dj, dir, path); /* Follow the path to the directory */\r
+ if (res == FR_OK) { /* Follow completed */\r
+ if (dir[0]) { /* It is not the root dir */\r
+ if (dir[DIR_Attr] & AM_DIR) /* The object is a directory */\r
+ dj->sclust = LD_CLUST(dir);\r
+ else /* The object is not a directory */\r
+ res = FR_NO_PATH;\r
+ }\r
+ if (res == FR_OK)\r
+ res = dir_rewind(dj); /* Rewind dir */\r
+ }\r
+ if (res == FR_NO_FILE) res = FR_NO_PATH;\r
+ }\r
+\r
+ return res;\r
+}\r
+\r
+\r
+\r
+\r
+/*-----------------------------------------------------------------------*/\r
+/* Read Directory Entry in Sequense */\r
+/*-----------------------------------------------------------------------*/\r
+\r
+FRESULT pf_readdir (\r
+ DIR *dj, /* Pointer to the open directory object */\r
+ FILINFO *fno /* Pointer to file information to return */\r
+)\r
+{\r
+ FRESULT res;\r
+ BYTE sp[12], dir[32];\r
+ FATFS *fs = FatFs;\r
+\r
+\r
+ if (!fs) { /* Check file system */\r
+ res = FR_NOT_ENABLED;\r
+ } else {\r
+ dj->fn = sp;\r
+ if (!fno) {\r
+ res = dir_rewind(dj);\r
+ } else {\r
+ res = dir_read(dj, dir);\r
+ if (res == FR_NO_FILE) {\r
+ dj->sect = 0;\r
+ res = FR_OK;\r
+ }\r
+ if (res == FR_OK) { /* A valid entry is found */\r
+ get_fileinfo(dj, dir, fno); /* Get the object information */\r
+ res = dir_next(dj); /* Increment index for next */\r
+ if (res == FR_NO_FILE) {\r
+ dj->sect = 0;\r
+ res = FR_OK;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return res;\r
+}\r
+\r
+#endif /* _USE_DIR */\r
+\r
--- /dev/null
+/**\r
+ * @file pff.h\r
+ * @brief FATファイルシステムドライバの定義。\r
+ */\r
+\r
+/*---------------------------------------------------------------------------/\r
+/ Petit FatFs - FAT file system module include file R0.02a (C)ChaN, 2010\r
+/----------------------------------------------------------------------------/\r
+/ Petit FatFs module is an open source software to implement FAT file system to\r
+/ small embedded systems. This is a free software and is opened for education,\r
+/ research and commercial developments under license policy of following trems.\r
+/\r
+/ Copyright (C) 2010, ChaN, all right reserved.\r
+/\r
+/ * The Petit FatFs module is a free software and there is NO WARRANTY.\r
+/ * No restriction on use. You can use, modify and redistribute it for\r
+/ personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.\r
+/ * Redistributions of source code must retain the above copyright notice.\r
+/\r
+/----------------------------------------------------------------------------*/\r
+\r
+#include "integer_pff.h"\r
+\r
+/*---------------------------------------------------------------------------/\r
+/ Petit FatFs Configuration Options\r
+/\r
+/ CAUTION! Do not forget to make clean the project after any changes to\r
+/ the configuration options.\r
+/\r
+/----------------------------------------------------------------------------*/\r
+#ifndef _FATFS\r
+#define _FATFS\r
+\r
+#define _USE_READ 1 /* 1:Enable pf_read() */\r
+\r
+#define _USE_DIR 1 /* 1:Enable pf_opendir() and pf_readdir() */\r
+\r
+#define _USE_LSEEK 1 /* 1:Enable pf_lseek() */\r
+\r
+#define _USE_WRITE 1 /* 1:Enable pf_write() */\r
+\r
+#define _FS_FAT12 1 /* 1:Enable FAT12 support */\r
+#define _FS_FAT32 1 /* 1:Enable FAT32 support */\r
+\r
+\r
+#define _CODE_PAGE 1\r
+/* Defines which code page is used for path name. Supported code pages are:\r
+/ 932, 936, 949, 950, 437, 720, 737, 775, 850, 852, 855, 857, 858, 862, 866,\r
+/ 874, 1250, 1251, 1252, 1253, 1254, 1255, 1257, 1258 and 1 (ASCII only).\r
+/ SBCS code pages except for 1 requiers a case conversion table. This\r
+/ might occupy 128 bytes on the RAM on some platforms, e.g. avr-gcc. */\r
+\r
+\r
+#define _WORD_ACCESS 1\r
+/* The _WORD_ACCESS option defines which access method is used to the word\r
+/ data in the FAT structure.\r
+/\r
+/ 0: Byte-by-byte access. Always compatible with all platforms.\r
+/ 1: Word access. Do not choose this unless following condition is met.\r
+/\r
+/ When the byte order on the memory is big-endian or address miss-aligned\r
+/ word access results incorrect behavior, the _WORD_ACCESS must be set to 0.\r
+/ If it is not the case, the value can also be set to 1 to improve the\r
+/ performance and code efficiency. */\r
+\r
+\r
+/* End of configuration options. Do not change followings without care. */\r
+/*--------------------------------------------------------------------------*/\r
+\r
+\r
+\r
+#if _FS_FAT32\r
+#define CLUST DWORD\r
+#else\r
+#define CLUST WORD\r
+#endif\r
+\r
+\r
+/* File system object structure */\r
+\r
+typedef struct {\r
+ BYTE fs_type; /* FAT sub type */\r
+ BYTE flag; /* File status flags */\r
+ BYTE csize; /* Number of sectors per cluster */\r
+ BYTE pad1;\r
+ WORD n_rootdir; /* Number of root directory entries (0 on FAT32) */\r
+ CLUST n_fatent; /* Number of FAT entries (= number of clusters + 2) */\r
+ DWORD fatbase; /* FAT start sector */\r
+ DWORD dirbase; /* Root directory start sector (Cluster# on FAT32) */\r
+ DWORD database; /* Data start sector */\r
+ DWORD fptr; /* File R/W pointer */\r
+ DWORD fsize; /* File size */\r
+ CLUST org_clust; /* File start cluster */\r
+ CLUST curr_clust; /* File current cluster */\r
+ DWORD dsect; /* File current data sector */\r
+} FATFS;\r
+\r
+\r
+\r
+/* Directory object structure */\r
+\r
+typedef struct {\r
+ WORD index; /* Current read/write index number */\r
+ BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */\r
+ CLUST sclust; /* Table start cluster (0:Static table) */\r
+ CLUST clust; /* Current cluster */\r
+ DWORD sect; /* Current sector */\r
+} DIR;\r
+\r
+\r
+\r
+/* File status structure */\r
+\r
+typedef struct {\r
+ DWORD fsize; /* File size */\r
+ WORD fdate; /* Last modified date */\r
+ WORD ftime; /* Last modified time */\r
+ BYTE fattrib; /* Attribute */\r
+ char fname[13]; /* File name */\r
+} FILINFO;\r
+\r
+\r
+\r
+/* File function return code (FRESULT) */\r
+\r
+typedef enum {\r
+ FR_OK = 0, /* 0 */\r
+ FR_DISK_ERR, /* 1 */\r
+ FR_NOT_READY, /* 2 */\r
+ FR_NO_FILE, /* 3 */\r
+ FR_NO_PATH, /* 4 */\r
+ FR_NOT_OPENED, /* 5 */\r
+ FR_NOT_ENABLED, /* 6 */\r
+ FR_NO_FILESYSTEM /* 7 */\r
+} FRESULT;\r
+\r
+\r
+\r
+/*--------------------------------------------------------------*/\r
+/* Petit FatFs module application interface */\r
+\r
+FRESULT pf_mount (FATFS*); /* Mount/Unmount a logical drive */\r
+FRESULT pf_open (const char*); /* Open a file */\r
+FRESULT pf_read (void*, WORD, WORD*); /* Read data from the open file */\r
+FRESULT pf_write (const void*, WORD, WORD*); /* Write data to the open file */\r
+FRESULT pf_lseek (DWORD); /* Move file pointer of the open file */\r
+FRESULT pf_opendir (DIR*, const char*); /* Open a directory */\r
+FRESULT pf_readdir (DIR*, FILINFO*); /* Read a directory item from the open directory */\r
+\r
+\r
+\r
+/*--------------------------------------------------------------*/\r
+/* Flags and offset address */\r
+\r
+/* File status flag (FATFS.flag) */\r
+\r
+#define FA_OPENED 0x01\r
+#define FA_WPRT 0x02\r
+#define FA__WIP 0x40\r
+\r
+\r
+/* FAT sub type (FATFS.fs_type) */\r
+\r
+#define FS_FAT12 1\r
+#define FS_FAT16 2\r
+#define FS_FAT32 3\r
+\r
+\r
+/* File attribute bits for directory entry */\r
+\r
+#define AM_RDO 0x01 /* Read only */\r
+#define AM_HID 0x02 /* Hidden */\r
+#define AM_SYS 0x04 /* System */\r
+#define AM_VOL 0x08 /* Volume label */\r
+#define AM_LFN 0x0F /* LFN entry */\r
+#define AM_DIR 0x10 /* Directory */\r
+#define AM_ARC 0x20 /* Archive */\r
+#define AM_MASK 0x3F /* Mask of defined bits */\r
+\r
+\r
+/*--------------------------------*/\r
+/* Multi-byte word access macros */\r
+\r
+#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */\r
+#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))\r
+#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))\r
+#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)\r
+#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)\r
+#else /* Use byte-by-byte access to the FAT structure */\r
+#define LD_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))\r
+#define LD_DWORD(ptr) (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr))\r
+#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8)\r
+#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24)\r
+#endif\r
+\r
+\r
+#endif /* _FATFS */\r
--- /dev/null
+/**
+ * @file pffspi.c
+ * @brief FATファイルシステム用下層SPIドライバの実装。
+ */
+
+#include "pffspi.h"
+
+#include <lpc17xx_spi.h>
+#include <lpc17xx_gpio.h>
+#include <lpc17xx_pinsel.h>
+#include <lpc17xx_libcfg.h>
+#include <kernel.h>
+
+SPI_CFG_Type SPI_ConfigStruct;
+PINSEL_CFG_Type PinCfg;
+SPI_DATA_SETUP_Type xferConfig;
+
+// PORT number that /CS pin assigned on
+#define CS_PORT_NUM 1
+// PIN number that /CS pin assigned on
+#define CS_PIN_NUM 29
+
+void pffspi_cs_init(void)
+{
+ GPIO_SetDir(CS_PORT_NUM, (1 << CS_PIN_NUM), 1);
+ GPIO_SetValue(CS_PORT_NUM, (1 << CS_PIN_NUM));
+}
+
+void pffspi_cs_ena(void)
+{
+ GPIO_ClearValue(CS_PORT_NUM, (1 << CS_PIN_NUM));
+}
+
+void pffspi_cs_dis(void)
+{
+ GPIO_SetValue(CS_PORT_NUM, (1 << CS_PIN_NUM));
+}
+
+/* CS status (true:CS == L) */
+unsigned char pffspi_cs_stat(void)
+{
+ unsigned char val = GPIO_ReadValue(CS_PORT_NUM);
+ return ((val & (1 << CS_PIN_NUM)) == 0) ? 1 : 0;
+}
+
+void pffspi_init(void)
+{
+ /*
+ * Initialize SPI pin connect
+ * P0.15 - SCK;
+ * P0.17 - MISO
+ * P0.18 - MOSI
+ */
+ PinCfg.Funcnum = 3;
+ PinCfg.OpenDrain = 0;
+ PinCfg.Pinmode = 0;
+ PinCfg.Portnum = 0;
+ PinCfg.Pinnum = 15;
+ PINSEL_ConfigPin(&PinCfg);
+ PinCfg.Pinnum = 17;
+ PINSEL_ConfigPin(&PinCfg);
+ PinCfg.Pinnum = 18;
+ PINSEL_ConfigPin(&PinCfg);
+
+ // initialize SPI configuration structure to default
+#if 0
+ SPI_ConfigStructInit(&SPI_ConfigStruct);
+#else
+ SPI_ConfigStruct.CPHA = SPI_CPHA_FIRST;
+ SPI_ConfigStruct.CPOL = SPI_CPOL_HI;
+ SPI_ConfigStruct.ClockRate = 5000000;
+ SPI_ConfigStruct.DataOrder = SPI_DATA_MSB_FIRST;
+ SPI_ConfigStruct.Databit = SPI_DATABIT_8;
+ SPI_ConfigStruct.Mode = SPI_MASTER_MODE;
+#endif
+ // Initialize SPI peripheral with parameter given in structure above
+ SPI_Init(LPC_SPI, &SPI_ConfigStruct);
+
+ pffspi_cs_init();
+}
+
+void pffspi_tx(unsigned char c)
+{
+ SPI_SendData(LPC_SPI, c);
+ while (!(SPI_GetStatus(LPC_SPI) & SPI_SPSR_SPIF))
+ {
+ }
+ SPI_ReceiveData(LPC_SPI);
+}
+
+unsigned char pffspi_rx(void)
+{
+ SPI_SendData(LPC_SPI, 0xff);
+ while (!(SPI_GetStatus(LPC_SPI) & SPI_SPSR_SPIF))
+ {
+ }
+ return SPI_ReceiveData(LPC_SPI);
+}
+
+void pffspi_dly_1ms(void)
+{
+ tslp_tsk(1);
+}
+
--- /dev/null
+/**
+ * @file pffspi.h
+ * @brief FATファイルシステム用下層SPIドライバの定義。
+ */
+
+#ifndef PFFSPI_H
+#define PFFSPI_H
+
+void pffspi_init(void);
+void pffspi_tx(unsigned char c);
+unsigned char pffspi_rx(void);
+void pffspi_cs_init(void);
+void pffspi_cs_ena(void);
+void pffspi_cs_dis(void);
+unsigned char pffspi_cs_stat(void);
+void pffspi_dly_1ms(void);
+
+#endif
+
--- /dev/null
+#include "tlv320aic23b.h"
+
+void tlv320aic23b_init()
+{
+}
+
--- /dev/null
+#ifndef TLV320AIC23B_H
+#define TLV320AIC23B_H
+
+void tlv320aic23b_init();
+
+#endif
+
--- /dev/null
+#!/bin/sh
+
+if [ $# -ne 1 ]
+then
+ echo "findkeyword.sh [keyword]"
+ exit
+fi
+
+FILELIST=`find . -name "*.[c|h]"`
+KEYWORD=$1
+
+for FILE in $FILELIST
+do
+ OUT=`grep "$KEYWORD" $FILE`
+ if [ ! "$OUT" = "" ]
+ then
+ echo " "
+ echo "[Found in $FILE]"
+ grep -i -n "$KEYWORD" $FILE
+ echo " "
+ fi
+done
+
--- /dev/null
+target remote localhost:3333
+monitor soft_reset_halt
+#monitor halt
+shell sleep 2
+load TOPPERS-ASP_BlackTank-LPC1769.axf
+shell sleep 2
+continue
--- /dev/null
+#
+# プログラムをロードして開始するスクリプト。
+#
+
+target remote localhost:3333
+shell sleep 2
+
+monitor halt
+# monitor soft_reset_halt
+shell sleep 2
+
+load TOPPERS-ASP_BlackTank-LPC1769.axf
+shell sleep 2
+
+continue
+
--- /dev/null
+/**
+ * \file i2c_subsystem.c
+ * \brief I2C制御関数群
+ * \date 2011/02/19
+ * \author Takemasa Nakamura
+ */
+#include "i2c_subsystem.h"
+
+#include <LPC17xx.h>
+#include <kernel.h>
+#include <t_syslog.h>
+
+#define I2C_DEBUG 0
+
+void i2c_init()
+{
+ /* I2C0の電源をオン */
+ LPC_SC->PCONP |= 1 << 7;
+ /* I2C0のPCLKを 1/4 にセット (25MHz) */
+ LPC_SC->PCLKSEL0 &= ~(0x3 << 14);
+
+ /* P0.27, P0.28を SCL0, SDA0に */
+ LPC_PINCON->PINSEL1 &= ~(0xF << 22);
+ LPC_PINCON->PINSEL1 |= 0x5 << 22;
+
+ /* I2C動作クロック 100KHz (コアクロック100MHzのとき) */
+ LPC_I2C0->I2SCLH = 1250;
+ LPC_I2C0->I2SCLL = 1250;
+
+ /* I2C ディセーブル */
+ LPC_I2C0->I2CONCLR = 0xFF;
+}
+
+void i2c_send_2bytes(int addr, int data0, int data1)
+{
+ /* I2C マスターモード */
+ LPC_I2C0->I2CONSET = 0x40;
+ /* I2C START */
+ LPC_I2C0->I2CONSET = 0x20;
+ tslp_tsk(10);
+ if (LPC_I2C0->I2STAT != 0x08) {
+#if I2C_DEBUG
+ syslog(LOG_NOTICE, "I2C0 Start. Expects 0x08 ");
+ syslog(LOG_NOTICE, "I2CONSET0 %02x", LPC_I2C0->I2CONSET);
+ syslog(LOG_NOTICE, "I2STAT0 %02x", LPC_I2C0->I2STAT);
+#endif
+ }
+
+ /* I2C アドレス TLV320AIC23B CS=0, Write */
+ LPC_I2C0->I2DAT = addr << 1;
+
+ /* reset SIC & STA */
+ LPC_I2C0->I2CONCLR = 0x28;
+ tslp_tsk(10);
+ if (LPC_I2C0->I2STAT != 0x18) {
+#if I2C_DEBUG
+ syslog(LOG_NOTICE, "SI&STA Clear, SLA + W sent. Expects 0x18 ");
+ syslog(LOG_NOTICE, "I2CONSET0 %02x", LPC_I2C0->I2CONSET);
+ syslog(LOG_NOTICE, "I2STAT0 %02x", LPC_I2C0->I2STAT);
+#endif
+ }
+
+ /* 最初のデータの転送 */
+ LPC_I2C0->I2DAT = data0;
+ /* reset SIC */
+ LPC_I2C0->I2CONCLR = 0x08;
+ tslp_tsk(10);
+ if (LPC_I2C0->I2STAT != 0x28) {
+#if I2C_DEBUG
+ syslog(LOG_NOTICE, "SI Clear, dataH sent. Expects 0x28 ");
+ syslog(LOG_NOTICE, "I2CONSET0 %02x", LPC_I2C0->I2CONSET);
+ syslog(LOG_NOTICE, "I2STAT0 %02x", LPC_I2C0->I2STAT);
+#endif
+ }
+ /* 次のデータの転送 */
+ LPC_I2C0->I2DAT = data1;
+ /* reset SIC */
+ LPC_I2C0->I2CONCLR = 0x08;
+ tslp_tsk(10);
+ if (LPC_I2C0->I2STAT != 0x28) {
+#if I2C_DEBUG
+ syslog(LOG_NOTICE, "SI Clear, dataL sent. Expects 0x28 ");
+ syslog(LOG_NOTICE, "I2CONSET0 %02x", LPC_I2C0->I2CONSET);
+ syslog(LOG_NOTICE, "I2STAT0 %02x", LPC_I2C0->I2STAT);
+#endif
+ }
+ /* set STOP */
+ LPC_I2C0->I2CONSET = 0x10;
+
+ /* reset SIC */
+ LPC_I2C0->I2CONCLR = 0x08;
+ tslp_tsk(10);
+ if (LPC_I2C0->I2STAT != 0xF8) {
+#if I2C_DEBUG
+ syslog(LOG_NOTICE, "SI Clear. Expects 0xF8, NO SI ");
+ syslog(LOG_NOTICE, "I2CONSET0 %02x", LPC_I2C0->I2CONSET);
+ syslog(LOG_NOTICE, "I2STAT0 %02x", LPC_I2C0->I2STAT);
+#endif
+ }
+}
--- /dev/null
+/**
+ * @file i2c_subsystem.h
+ * @brief I2C制御関数群
+ * @date 2011/02/19
+ * @author Takemasa Nakamura
+ * @details
+ * 最初に @ref i2c_init 関数を使って、I2Cペリフェラルを初期化する。
+ * @ref i2c_send_2bytes 関数は2バイトデータをI2Cデバイスに送る関数である。
+ * この関数はアドホックな版であり、割り込みは使っていない。
+ */
+
+#ifndef I2C_SUBSYSTEM_H_
+#define I2C_SUBSYSTEM_H_
+
+/**
+ * @brief ISC0の初期化を行う。
+ * @details
+ * I2C0にポートを割り当て、初期化する。
+ * I2C動作クロックは100kHzにしているが、
+ * これはI2Cの標準モードの最大クロックである。
+ * LPC1768のコアクロックは100MHzと計算しているが、
+ * もしコアクロックがことなるなら、再設定が必要である。
+ */
+void i2c_init();
+
+/**
+ * @brief I2C0からTLV320AIC23Bへデータを送信する
+ * @param addr 7bitのI2Cアドレス。右揃え。
+ * @param data0 バイト0のデータ
+ * @param data1 バイト1のデータ
+ * @details
+ * 与えられたI2Cアドレスのデバイスに、2バイトデータを送る。
+ * 基本的にはLPC1768のユーザーズマニュアルUM10360で解説されている
+ * 状態遷移のうち、成功する場合だけをなぞっている。
+ * 失敗した場合にはメッセージを表示するだけで、とくに回復はしていない。
+ */
+void i2c_send_2bytes( int addr, int data0, int data1 );
+
+#endif /* I2C_SUBSYSTEM_H_ */
--- /dev/null
+/**
+ * \file i2s_subsystem.c
+ * \brief I2S制御関数群
+ * \date 2011/02/19
+ * \author takemasa
+ */
+
+#include "i2s_subsystem.h"
+#include "kernel_cfg.h"
+
+#include <LPC17xx.h>
+#include <kernel.h>
+#include <t_syslog.h>
+
+void i2s_init()
+{
+ /* I2Sの電源をオン */
+ LPC_SC->PCONP |= 1 << 27;
+ /* I2SのPCLKを 1/4 にセット (25MHz) */
+ LPC_SC->PCLKSEL0 &= ~(0x3 << 22);
+
+ /** P0.4 - P0.9を I2Sに */
+ LPC_PINCON->PINSEL0 &= ~(0xFFF << 8);
+// LPC_PINCON->PINSEL0 |= 0x555 << 8;
+ LPC_PINCON->PINSEL0 |= 0x550 << 8; // RX ws/clk disconnect
+
+ /*
+ * I2Sのモード設定。
+ * I2S, 32bit, 4-wire transmitter slave mode sharing the
+ * receiver bit clock and WS Typical receiver slave mode
+ * stereo, stop & reset.
+ *
+ * TXのビット/ワードクロックはRXから供給を受け、RXの
+ * ビット/ワードクロックは外部から供給を受ける。
+ * この場合、TXはデバイダ関係の設定が不要のはずである。
+ * また、UM10360 rev 2 Fig111によるとI2SRXBITRATEは
+ * div by 1になるよう設定しなければならない。
+ */
+
+ /*
+ * Digital Audio Output & Input
+ */
+
+ /*
+ * UM10360には詳細がしるされていないが、NXPによるCMSISの例題を
+ * 読む限り、設定前にDAO/DAIをreset, stop状態に置き、
+ * 処理開始時にresetから解除し、stopから解除する動作になっている。
+ * reset状態でレジスタを操作する事には不安を感じるが、例題しか
+ * 情報源がないのでそれにしたがう。
+ */
+ LPC_I2S->I2SDAO = 0x0; /* Disable */
+ LPC_I2S->I2SDAI = 0x0; /* Disable */
+
+ LPC_I2S->I2SDAO = 3 << 0 // 32bit data
+ | 0 << 2 // mono : 1 is mono, 0 is stereo
+ | 1 << 3 // stop : 1 is stop
+ | 1 << 4 // reset : 1 is reset;
+ | 1 << 5 // ws_sel : 1 is slave, 0 is master
+ | 31 << 6 // ws_halfpeiod : half period value -1;
+ | 0 << 15; // mute : 1 is mute, 0 is unmute
+
+ LPC_I2S->I2SDAI = 3 << 0 // 32bit data
+ | 0 << 2 // mono : 1 is mono, 0 is stereo
+ | 1 << 3 // stop : 1 is stop
+ | 1 << 4 // reset : 1 is reset;
+ | 1 << 5 // ws_sel : 1 is slave, 0 is master
+ | 31 << 6; // ws_halfpeiod : half period value -1;
+
+ /* DMA Configuration. RX DMA is Enabled */
+ LPC_I2S->I2SDMA1 = 1 << 0 // RX enable
+ | 2 << 8; // FIFO depth = 2
+ /* DMA Configuration. TX DMA is enabled */
+ LPC_I2S->I2SDMA2 = 1 << 1 // TX DMA Enable
+ | 2 << 16; // FIFO depth = 2;
+
+ /*
+ * I2SRXBITRATE
+ */
+
+ /*
+ * 外部ビットクロックから内部ビットクロックを生成する分周器。1で割る。
+ */
+ LPC_I2S->I2SRXBITRATE = 0; /* RX bit clock div by 1 */
+ LPC_I2S->I2STXBITRATE = 0; /* RX bit clock div by 1 */
+
+ /* 送信モード */
+ LPC_I2S->I2STXMODE = 0; /* Transmit slave typical mode */
+ /* 受信モード */
+ LPC_I2S->I2SRXMODE = 4; /* Receive slave typical mode */
+// LPC_I2S->I2SRXMODE = 0; /* Receive slave 4-wire mode */
+
+}
+
+void i2s_start()
+{
+ /* TX I2S をストップから開放 */
+ LPC_I2S->I2SDAO &= ~(1 << 3);
+ /* RX I2S をストップから開放 */
+ LPC_I2S->I2SDAI &= ~(1 << 3);
+ /* TX I2S をリセットから開放 */
+ LPC_I2S->I2SDAO &= ~(1 << 4);
+ /* RX I2S をリセットから開放 */
+ LPC_I2S->I2SDAI &= ~(1 << 4);
+}
+
+void i2s_dma_init(struct I2S_AUDIO_DATA *audio_data)
+{
+ int i;
+
+ /* DMA の電源をオン */
+ LPC_SC->PCONP |= 1 << 29;
+ /* DMA Controler Enable */
+ LPC_GPDMA->DMACConfig = 0x01; /* Little Endian, Enable */
+
+ /* 送信LLIの初期化 */
+ audio_data->txI2SLLI[0].SrcAddr = audio_data->txBuffer[0]; /* 送信データのバッファ */
+ audio_data->txI2SLLI[0].DstAddr = (int *) &LPC_I2S->I2STXFIFO; /* I2SのFIFOに送信する */
+ audio_data->txI2SLLI[0].nextLLI = &(audio_data->txI2SLLI[1]); /* 次のLLIへのリンク */
+ /* No interrupt, Source Incr, Src/Dest 32bit, Src/Dest Bust=1, Bufsize = AUDIOBUFSIZE */
+ audio_data->txI2SLLI[0].Control = 0 << 31 // I : Interrupt : Do not trigger interrupt
+ | 0 << 27 // DI : Destination Increment : Do not increment after transfer
+ | 1 << 26 // SI : Source increment : Increment after transfer
+ | 2 << 21 // Dwidth : Destination width : 32bit
+ | 2 << 18 // SWidth : Source width : 32bit
+ | 0 << 15 // DBSize : Destination Burst
+ | 0 << 12 // SBSize : Source burst
+ | AUDIOBUFSIZE; // Transfer size [count]
+
+ /* 送信LLIの初期化 */
+ audio_data->txI2SLLI[1].SrcAddr = audio_data->txBuffer[1]; /* 送信データのバッファ */
+ audio_data->txI2SLLI[1].DstAddr = (int *) &LPC_I2S->I2STXFIFO; /* I2SのFIFOに送信する */
+ audio_data->txI2SLLI[1].nextLLI = &(audio_data->txI2SLLI[0]); /* 次のLLIへのリンク */
+ /* No interrupt, Source Incr, Src/Dest 32bit, Src/Dest Bust=1, Bufsize = AUDIOBUFSIZE */
+ audio_data->txI2SLLI[1].Control = 0 << 31 // I : Interrupt : Do not trigger interrupt
+ | 0 << 27 // DI : Destination Increment : Do not increment after transfer
+ | 1 << 26 // SI : Source increment : Increment after transfer
+ | 2 << 21 // Dwidth : Destination width : 32bit
+ | 2 << 18 // SWidth : Source width : 32bit
+ | 0 << 15 // DBSize : Destination Burst
+ | 0 << 12 // SBSize : Source burst
+ | AUDIOBUFSIZE; // Transfer size [count]
+
+ /* 受信LLIの初期化 */
+ audio_data->rxI2SLLI[0].DstAddr = audio_data->rxBuffer[0]; /* 受信データのバッファ */
+ audio_data->rxI2SLLI[0].SrcAddr = (int *) &LPC_I2S->I2SRXFIFO; /* I2SのFIFOから受信する */
+ audio_data->rxI2SLLI[0].nextLLI = &(audio_data->rxI2SLLI[1]); /* 次のLLIへのリンク */
+ /* No interrupt, Source Incr, Src/Dest 32bit, Src/Dest Bust=1, Bufsize = AUDIOBUFSIZE */
+ audio_data->rxI2SLLI[0].Control = 1 << 31 // I : Interrupt : trigger interrupt
+ | 1 << 27 // DI : Destination Increment : Increment after transfer
+ | 0 << 26 // SI : Source increment : Do not increment after transfer
+ | 2 << 21 // Dwidth : Destination width : 32bit
+ | 2 << 18 // SWidth : Source width : 32bit
+ | 0 << 15 // DBSize : Destination Burst
+ | 0 << 12 // SBSize : Source burst
+ | AUDIOBUFSIZE; // Transfer size [count]
+
+ /* 受信LLIの初期化 */
+ audio_data->rxI2SLLI[1].DstAddr = audio_data->rxBuffer[1]; /* 受信データのバッファ */
+ audio_data->rxI2SLLI[1].SrcAddr = (int *) &LPC_I2S->I2SRXFIFO; /* I2SのFIFOから受信する */
+ audio_data->rxI2SLLI[1].nextLLI = &(audio_data->rxI2SLLI[0]); /* 次のLLIへのリンク */
+ /* No interrupt, Source Incr, Src/Dest 32bit, Src/Dest Bust=1, Bufsize = AUDIOBUFSIZE */
+ audio_data->rxI2SLLI[1].Control = 1 << 31 // I : Interrupt : trigger interrupt
+ | 1 << 27 // DI : Destination Increment : Increment after transfer
+ | 0 << 26 // SI : Source increment : Do not increment after transfer
+ | 2 << 21 // Dwidth : Destination width : 32bit
+ | 2 << 18 // SWidth : Source width : 32bit
+ | 0 << 15 // DBSize : Destination Burst
+ | 0 << 12 // SBSize : Source burst
+ | AUDIOBUFSIZE; // Transfer size [count]
+
+ /* 送信バッファのクリア */
+ for (i = 0; i < AUDIOBUFSIZE; i++) {
+ audio_data->txBuffer[0][i] = 0x00; /* ゼロフィル */
+ audio_data->txBuffer[1][i] = 0x00;
+ }
+
+ /* 受信バッファのクリア */
+ for (i = 0; i < AUDIOBUFSIZE; i++) {
+ audio_data->rxBuffer[0][i] = 0x00; /* ゼロフィル */
+ audio_data->rxBuffer[1][i] = 0x00;
+ }
+
+ /*
+ * DMAの最初の1回の動作はレジスタを直接初期化して起動する。
+ * LPC1768のDMA起動方法は洗練されているとは言い難い。
+ */
+
+ /* 送信DMAの起動準備 */
+ LPC_GPDMACH0->DMACCSrcAddr = (int) audio_data->txI2SLLI[0].SrcAddr;
+ LPC_GPDMACH0->DMACCDestAddr = (int) audio_data->txI2SLLI[0].DstAddr;
+ LPC_GPDMACH0->DMACCLLI = (int) &audio_data->txI2SLLI[1];
+ LPC_GPDMACH0->DMACCControl = audio_data->txI2SLLI[0].Control;
+
+ /* 受信DMAの起動準備 */
+ LPC_GPDMACH1->DMACCSrcAddr = (int) audio_data->rxI2SLLI[0].SrcAddr;
+ LPC_GPDMACH1->DMACCDestAddr = (int) audio_data->rxI2SLLI[0].DstAddr;
+ LPC_GPDMACH1->DMACCLLI = (int) &(audio_data->rxI2SLLI[1]);
+ LPC_GPDMACH1->DMACCControl = audio_data->rxI2SLLI[0].Control;
+
+ /*
+ * DMAチャンネルの設定を行う。
+ * この時点ではDMAはディセーブルである。
+ */
+
+ /* TX */
+ LPC_GPDMACH0->DMACCConfig = 0 // Enable : 0 is Disable
+ | 0 << 1 // Src Peripheral ( Ignored when M->P )
+ | 6 << 6 // Dst Peripheral, Dest is I2Sch1
+ | 1 << 11 // Transfer type : 1 is M->P
+ | 0 << 14 // IE : Interrupt Enable : 0 is Disable
+ | 0 << 15 // ITC : Terminal Count Intr Mask : 0 is masking out
+ | 0 << 18; // H : Halt : 0 is active, 1 is Halt
+ /* RX */
+ LPC_GPDMACH1->DMACCConfig = 0 // Enable : 0 is Disable
+ | 5 << 1 // Src Peripheral, Src is I2Sch0
+ | 0 << 6 // Dst Peripheral, ( Ignored when P->M )
+ | 2 << 11 // Transfer type : 2 is P->M
+ | 1 << 14 // IE : Interrupt Enable : 0 is Disable
+ | 1 << 15 // ITC : Terminal Count Intr Mask : 0 is masking out
+ | 0 << 18; // H : Halt : 0 is active, 1 is Halt
+
+ /* 最後の処理としてDMAチャンネルを有功にする */
+ LPC_GPDMACH0->DMACCConfig |= 1;
+ LPC_GPDMACH1->DMACCConfig |= 1;
+}
+
+/**
+ * \brief 現在ソフトウェアが使えるI2S TXバッファをかえす。
+ * \return プログラムが書き込んでいい送信バッファの先頭アドレス
+ * \details
+ * DMAが使用していないバッファをかえす。
+ * DMAと同期したプログラムを書く場合には必ずこのルーチンを使用して
+ * プログラムが使ってもよいバッファを決定する。
+ * \todo
+ * DMAチャンネルの番号は決め打ちである。
+ * 適切なDMA管理機構を使った方式への変更が必要である。
+ */
+AUDIOSAMPLE *i2s_getTxBuf()
+{
+ struct LLI *nextLLI;
+
+ // このプログラムではDMACH0をI2S TXに使っている。
+ // 使用していないバッファとは、現在使用中のLLIの、
+ // 次のLLIが指し示すバッファである。
+ nextLLI = (struct LLI *) LPC_GPDMACH0->DMACCLLI;
+ return nextLLI->SrcAddr;
+}
+
+/**
+ * \brief 現在ソフトウェアが使えるI2S RXバッファをかえす。
+ * \return プログラムが読み込んでいい受信バッファの先頭アドレス
+ * \details
+ * DMAが使用していないバッファをかえす。
+ * DMAと同期したプログラムを書く場合には必ずこのルーチンを使用して
+ * プログラムが使ってもよいバッファを決定する。
+ * \todo
+ * DMAチャンネルの番号は決め打ちである。
+ * 適切なDMA管理機構を使った方式への変更が必要である。
+ */
+AUDIOSAMPLE *i2s_getRxBuf()
+{
+ struct LLI *nextLLI;
+
+ // このプログラムではDMACH1をI2S RXに使っている。
+ // 使用していないバッファとは、現在使用中のLLIの、
+ // 次のLLIが指し示すバッファである。
+ nextLLI = (struct LLI *) LPC_GPDMACH1->DMACCLLI;
+ return nextLLI->DstAddr;
+}
+
+void i2s_dma_intr_handler()
+{
+ if (LPC_GPDMA->DMACIntTCStat & (1 << 1))
+ {
+ /*
+ * I2S DMAバッファ終了割り込み
+ */
+ // CH1 (I2S DMA)のTC割り込みをクリア
+ LPC_GPDMA->DMACIntTCClear = (1 << 1);
+ // IS2 バッファ転送割り込みが起きたことをタスクに通知する。
+ isig_sem(SEM_I2SDMA);
+ }
+}
+
--- /dev/null
+/**
+ * @file i2s_subsystem.h
+ * @brief I2S操作関数群
+ * @date 2011/02/19
+ * @author Takemasa Nakamura
+ * @details
+ * @ref i2s_init 関数を使ってI2Sペリフェラルを初期化し、
+ * 次に @ref i2s_dma_init 関数を使ってDMA機能を初期化する。
+ * 最後に @ref i2s_start 関数を呼ぶことで実際のI2S動作が始まる。
+ *
+ * I2Sはダブルバッファを使う。
+ * バッファのデータ転送が終わるたびにDMA割り込みが入る。
+ * この割り込みを処理するにはDMA割り込みが起きるたびに、
+ * @ref i2s_dma_intr_handler 関数を割り込みハンドラ内部から呼べばよい。
+ *
+ * @ref audio_task 関数は、オーディオ処理タスクの実態であり、
+ * TOPPERS/ASPのタスクにすること。
+ * この関数はSEM_I2SDMAセマフォを使って @ref i2s_dma_intr_handler と
+ * 同期するため、SEM_I2SDMAセマフォを用意しておかなければならない。
+ *
+ * @ref process_audio 関数は、audio_processing.c でユーザーが実装すべき
+ * オーディオ信号処理関数である。この関数は audio_task から呼び出される。
+ */
+
+#ifndef I2S_SUBSYSTEM_H_
+#define I2S_SUBSYSTEM_H_
+
+#include <LPC17xx.h>
+#include <kernel.h>
+#include <t_syslog.h>
+#include "audio_common.h"
+
+/**
+ * @brief DMA用のリンクリストの構成要素型
+ * @details
+ * LP17xxの GPDMAはスキャッタ、ギャザーにも使用できるリンクリストを
+ * 構成できる。LLI型はそのリストの構成単位となるデータ型である。
+ * 基本的にLLIはLPC1768のユーザーズマニュアル、UM10360で記述されている
+ * DMA LLIそのままである。
+ * 詳しくはユーザーズマニュアル参照の事。
+ */
+struct LLI {
+ int * SrcAddr; /**< DMAのソース・バッファ・アドレス */
+ int * DstAddr; /**< DMAのデスティネーション・バッファ・アドレス・ */
+ struct LLI * nextLLI; /**< 次のLLI要素へのポインタ */
+ unsigned int Control; /**< DMAコントロール・レジスタへのロード値 */
+};
+
+/**
+ * @brief I2S用データ
+ * @details DMA転送などに使うデータを一ヶ所にあつめたもの。
+ */
+struct I2S_AUDIO_DATA {
+ /**
+ * @brief 送信DMA用のLLIリスト
+ * @details
+ * LLIチェーンは2要素をもち、全体でサーキュラーバッファを構成する。
+ * 初期化は @ref i2s_dma_init で行う。
+ */
+ struct LLI txI2SLLI[2];
+
+ /**
+ * @brief 受信DMA用のLLIリスト
+ * @details
+ * LLIチェーンは2要素をもち、全体でサーキュラーバッファを構成する。
+ * 初期化は @ref i2s_dma_init で行う。
+ */
+ struct LLI rxI2SLLI[2];
+
+ /**
+ * @brief I2S送信DMAのバッファ
+ * @details
+ * DMAを使ってI2Sポートから送信するためのデータバッファ。
+ * 二つのバッファを持つのは、ピンポン(ダブルバッファ)
+ * 制御を行うためである。
+ * DMA転送中にプログラムが次の送信データを書き込むためのバッファを
+ * 取得するには、
+ * @ref i2s_getTxBuf 関数を使う。
+ */
+ AUDIOSAMPLE txBuffer[2][AUDIOBUFSIZE];
+
+ /**
+ * @brief I2S受信DMAのバッファ
+ * @details
+ * DMAを使ってI2Sポートから受信するためのデータバッファ。
+ * 二つのバッファを持つのは、ピンポン(ダブルバッファ)
+ * 制御を行うためである。
+ * DMA転送中にプログラムが直前の受信データを読み込むための
+ * バッファを取得するには、 @ref i2s_getRxBuf 関数を使う。
+ */
+ AUDIOSAMPLE rxBuffer[2][AUDIOBUFSIZE];
+};
+
+/**
+ * @brief I2S 初期化ルーチン
+ * @details
+ * LPC1768のI2Sペリフェラルを初期化する。送受信とも
+ * @li スレーブ
+ * @li 32bit
+ * @li 4ワイアー
+ * である。DMA1をRXに、DMA2をTXに割り当てている。
+ *
+ * なお、このルーチンは初期化はするが、I2Sを起動しない。
+ * 起動はDMAの設定が終わった後に @ref i2s_start ルーチンを呼んで行う。
+ *
+ * @todo
+ * 現在の設定でも過不足なく動くが、TXのクロックをRXから分けるようにすれば、
+ * もっと少ないピン数で動作させることもできるはずである。
+ */
+void i2s_init();
+
+/**
+ * @brief DMA初期化
+ * @details
+ * I2Sに関連づけされたDMAを初期化する。
+ * 同時に、LLIを初期化して、ピンポンバッファをすぐに使えるような
+ * 状態にする。
+ * 受信DMAは各バッファの受信完了ごとにDMA割り込みをおこす。
+ * 送信では起こさない。
+ * プログラムはこれに同期してタスクと協調動作をする。
+ *
+ * DMA受信割り込みは @ref dma_intr_handler で処理を行う。
+ *
+ * @todo
+ * DMAの割り当ては決め打ちである。
+ * 適切なDMA管理機構を使用して衝突を避ける。
+ */
+void i2s_dma_init();
+
+/**
+ * @brief I2S 開始。DMA初期化後に行う
+ * @details
+ * @ref i2s_init ルーチンと @ref i2s_dma_init ルーチンによって準備を
+ * 終えた後、このルーチンを呼び出してi2sによる転送を始める。
+ */
+void i2s_start();
+
+/**
+ * @brief I2S DMA 割り込みハンドラの初期化を行う
+ * @details
+ * LPC1768のDMA割り込みステータスをチェックし、I2S DMA 受信TC割り込みが
+ * 発生していたら、その割り込みに対処する。
+ */
+void i2s_dma_intr_handler();
+
+AUDIOSAMPLE * i2s_getTxBuf();
+AUDIOSAMPLE * i2s_getRxBuf();
+
+#endif
+
--- /dev/null
+#
+# Amontec JTAGkey2P
+#
+# http://www.amontec.com/jtagkey2p.shtml
+#
+
+interface ft2232
+ft2232_device_desc "Amontec JTAGkey-2P"
+ft2232_layout jtagkey
+ft2232_vid_pid 0x0403 0xCFF8
+
--- /dev/null
+{
+ "TimeScale" :"us",
+ "TimeRadix" :10,
+ "ConvertRules" :["asp"],
+ "VisualizeRules" :["toppers","asp"],
+ "ResourceHeaders":["asp"],
+ "Resources":
+ {
+ "CurrentContext":{
+ "Type":"Context",
+ "Attributes":
+ {
+ "name" : "None"
+ }
+ },
+ "LOGTASK":{
+ "Type":"Task",
+ "Attributes":
+ {
+ "id" :1,
+ "atr" :"TA_ACT",
+ "pri" :3,
+ "exinf" :"LOGTASK_PORTID",
+ "task" :"logtask_main",
+ "stksz" :1024,
+ "stk" :"NULL",
+ "state" :"RUNNABLE"
+ }
+ },
+ "TASK_INIT":{
+ "Type":"Task",
+ "Attributes":
+ {
+ "id" :2,
+ "atr" :"TA_ACT",
+ "pri" :13,
+ "exinf" :"0",
+ "task" :"task_init",
+ "stksz" :2048,
+ "stk" :"NULL",
+ "state" :"RUNNABLE"
+ }
+ },
+ "TASK_DISPLAY":{
+ "Type":"Task",
+ "Attributes":
+ {
+ "id" :3,
+ "atr" :"0",
+ "pri" :11,
+ "exinf" :"0",
+ "task" :"task_display",
+ "stksz" :2048,
+ "stk" :"NULL",
+ "state" :"DORMANT"
+ }
+ },
+ "TASK_LED":{
+ "Type":"Task",
+ "Attributes":
+ {
+ "id" :4,
+ "atr" :"0",
+ "pri" :11,
+ "exinf" :"0",
+ "task" :"task_led",
+ "stksz" :2048,
+ "stk" :"NULL",
+ "state" :"DORMANT"
+ }
+ },
+ "TASK_NTSHELL":{
+ "Type":"Task",
+ "Attributes":
+ {
+ "id" :5,
+ "atr" :"0",
+ "pri" :14,
+ "exinf" :"0",
+ "task" :"task_ntshell",
+ "stksz" :2048,
+ "stk" :"NULL",
+ "state" :"DORMANT"
+ }
+ },
+ "TASK_AUDIO":{
+ "Type":"Task",
+ "Attributes":
+ {
+ "id" :6,
+ "atr" :"0",
+ "pri" :10,
+ "exinf" :"0",
+ "task" :"task_audio",
+ "stksz" :2048,
+ "stk" :"NULL",
+ "state" :"DORMANT"
+ }
+ },
+ "TASK_MENU":{
+ "Type":"Task",
+ "Attributes":
+ {
+ "id" :7,
+ "atr" :"0",
+ "pri" :12,
+ "exinf" :"0",
+ "task" :"task_menu",
+ "stksz" :2048,
+ "stk" :"NULL",
+ "state" :"DORMANT"
+ }
+ },
+ "TASK_USERINPUT":{
+ "Type":"Task",
+ "Attributes":
+ {
+ "id" :8,
+ "atr" :"0",
+ "pri" :12,
+ "exinf" :"0",
+ "task" :"task_userinput",
+ "stksz" :2048,
+ "stk" :"NULL",
+ "state" :"DORMANT"
+ }
+ },
+ "INH_INHNO_TIMER_target_timer_handler":{
+ "Type":"InterruptHandler",
+ "Attributes":
+ {
+ "id" :15,
+ "state" : "DORMANT"
+ }
+ },
+ "INH_21__kernel_inthdr_21":{
+ "Type":"InterruptHandler",
+ "Attributes":
+ {
+ "id" :21,
+ "state" : "DORMANT"
+ }
+ },
+ "INH_42__kernel_inthdr_42":{
+ "Type":"InterruptHandler",
+ "Attributes":
+ {
+ "id" :42,
+ "state" : "DORMANT"
+ }
+ },
+ "ISR_INTNO_SIO_sio_isr_SIO_PORTID":{
+ "Type":"InterruptServiceRoutine",
+ "Attributes":
+ {
+ "id" :21,
+ "state" : "DORMANT"
+ }
+ },
+ "ISR_INTNO_DMA_dma_intr_handler_0":{
+ "Type":"InterruptServiceRoutine",
+ "Attributes":
+ {
+ "id" :42,
+ "state" : "DORMANT"
+ }
+ },
+,
+,
+,
+ "TASK_TEX":{
+ "Type":"TaskExceptionRoutine",
+ "Attributes":
+ {
+ "state" : "DORMANT"
+ }
+ }
+ }
+}
+
--- /dev/null
+PACKAGE asp
+VERSION 1.6.0
+
+configure
+MANIFEST
+README.txt
+
+doc/asp_spec.txt
+doc/configurator.txt
+doc/design.txt
+doc/extension.txt
+doc/porting.txt
+doc/user.txt
+doc/version.txt
+
+include/histogram.h
+include/itron.h
+include/kernel.h
+include/log_output.h
+include/queue.h
+include/sil.h
+include/t_stddef.h
+include/t_stdlib.h
+include/t_syslog.h
+include/test_lib.h
+
+kernel/Makefile.kernel
+kernel/alarm.c
+kernel/alarm.h
+kernel/allfunc.h
+kernel/check.h
+kernel/cyclic.c
+kernel/cyclic.h
+kernel/dataqueue.c
+kernel/dataqueue.h
+kernel/eventflag.c
+kernel/eventflag.h
+kernel/exception.c
+kernel/exception.h
+kernel/interrupt.c
+kernel/interrupt.h
+kernel/kernel.tf
+kernel/kernel_api.csv
+kernel/kernel_check.tf
+kernel/kernel_def.csv
+kernel/kernel_impl.h
+kernel/kernel_int.h
+kernel/kernel_rename.def
+kernel/kernel_rename.h
+kernel/kernel_unrename.h
+kernel/mailbox.c
+kernel/mailbox.h
+kernel/mempfix.c
+kernel/mempfix.h
+kernel/pridataq.c
+kernel/pridataq.h
+kernel/semaphore.c
+kernel/semaphore.h
+kernel/startup.c
+kernel/sys_manage.c
+kernel/task.c
+kernel/task.h
+kernel/task_except.c
+kernel/task_manage.c
+kernel/task_refer.c
+kernel/task_sync.c
+kernel/time_event.c
+kernel/time_event.h
+kernel/time_manage.c
+kernel/wait.c
+kernel/wait.h
+
+library/histogram.c
+library/log_output.c
+library/strerror.c
+library/t_perror.c
+library/test_lib.c
+
+sample/Makefile
+sample/sample1.c
+sample/sample1.cfg
+sample/sample1.h
+
+syssvc/banner.c
+syssvc/banner.cfg
+syssvc/banner.h
+syssvc/logtask.c
+syssvc/logtask.cfg
+syssvc/logtask.h
+syssvc/serial.c
+syssvc/serial.cfg
+syssvc/serial.h
+syssvc/syslog.c
+syssvc/syslog.cfg
+syssvc/syslog.h
+syssvc/vasyslog.c
+
+utils/applyrename
+utils/genoffset
+utils/genrename
+utils/gentest
+utils/makedep
+utils/makerelease
+
+INCLUDE target/dve68k_gcc/MANIFEST
+INCLUDE arch/m68k_gcc/MANIFEST
+INCLUDE arch/gcc/MANIFEST
+INCLUDE arch/logtrace/MANIFEST
+INCLUDE pdic/upd72001/MANIFEST
+INCLUDE test/MANIFEST
+INCLUDE extension/MANIFEST
--- /dev/null
+
+ TOPPERS/ASP Kernel(Release 1.6.0)
+ Toyohashi Open Platform for Embedded Real-Time Systems/
+ Advanced Standard Profile Kernel
+
+TOPPERS/ASPカーネル(以下,ASPカーネル)は,TOPPERS新世代カーネルの基盤
+となるものとして,TOPPERSプロジェクトにおいて開発したリアルタイムカーネ
+ルです.μITRON4.0仕様のスタンダードプロファイル準拠のリアルタイムカー
+ネルであるTOPPERS/JSPカーネルを拡張・改良する形で開発しました.
+
+【最初に読むべきドキュメント】
+
+ASPカーネルのユーザーズマニュアルが,doc/user.txtにあります.ASPカーネ
+ルを使用する場合には,まずはこのドキュメントからお読み下さい.
+
+【ファイルの閲覧にあたって】
+
+ASPカーネルのドキュメント(プレーンテキストファイル)およびソースファイ
+ルを読む際には,TABを4に設定してください.
+
+【利用条件】
+
+ASPカーネルの利用条件は,各ファイルの先頭に表示されているTOPPERSライセ
+ンスです.TOPPERSライセンスに関するFAQが,以下のページにあります.
+
+ http://www.toppers.jp/faq/faq_ct12.html
+
+【質問・バグレポート・意見等の送付先】
+
+ASPカーネルをより良いものにするためのご意見等を歓迎します.ASPカーネル
+に関する質問やバグレポート,ご意見等は,TOPPERSプロジェクトの会員は
+TOPPERS開発者メーリングリスト(dev@toppers.jp)宛またはASPカーネルのバ
+グトラッキングシステム(Trac)に,その他の方はTOPPERSユーザーズメーリン
+グリスト(users@toppers.jp)宛にお願いします.
+
+TOPPERSユーザーズメーリングリストへの登録方法については,以下のページに
+説明があります.
+
+ http://www.toppers.jp/community.html
+
+【ポーティングにあたって】
+
+ASPカーネルを,TOPPERSプロジェクトからオープンソースにすることを前提に,
+未サポートのターゲットにポーティングされる場合には,あらかじめご相談く
+ださると幸いです.
+
+【今後の改造計画】
+
+今後(Release 1.7以降),ASPカーネルに対して大きな変更の可能性がある項
+目は次の通りです.
+
+・TOPPERS組込みコンポーネントシステム(TECS)の導入.現時点では,TECSの
+ 配布パッケージにTECS対応のASPカーネルが含まれていますが,ASPのパッケー
+ ジをTECS対応にする可能性があります.
+
+以上
--- /dev/null
+PACKAGE asp_arch_arm_m_gcc
+VERSION 1.6.0
+
+MANIFEST
+Makefile.prc
+arm_m.h
+makeoffset.c
+prc.tf
+prc_cfg1_out.h
+prc_check.tf
+prc_config.c
+prc_config.h
+prc_def.csv
+prc_design.txt
+prc_insn.h
+prc_kernel.h
+prc_rename.def
+prc_rename.h
+prc_sil.h
+prc_stddef.h
+prc_support.S
+prc_test.h
+prc_timer.c
+prc_timer.cfg
+prc_timer.h
+prc_unrename.h
+prc_user_annex.txt
+prc_user.txt
+start.S
+
+INCLUDE ../../target/lm3s8962_gcc/MANIFEST
+INCLUDE ../../target/cq_starm_gcc/MANIFEST
+INCLUDE ../../chip/lpc17xx_gcc/MANIFEST
+INCLUDE ../../target/lpc1768_generic_gcc/MANIFEST
--- /dev/null
+#
+# @(#) $Id: Makefile.prc 1304 2008-08-27 07:28:36Z ertl-honda $
+#
+
+#
+# Makefile のプロセッサ依存部(ARM-M用)
+#
+
+#
+# コンパイルオプション
+#
+COPTS := $(COPTS) -mthumb
+INCLUDES := $(INCLUDES) -I$(SRCDIR)/arch/$(PRC)_$(TOOL)/
+LDFLAGS := -nostdlib $(LDFLAGS)
+CDEFS := $(CDEFS) -DTOPPERS_LABEL_ASM
+LIBS := $(LIBS) -lgcc
+
+#
+# カーネルに関する定義
+#
+KERNEL_DIR := $(KERNEL_DIR) $(SRCDIR)/arch/$(PRC)_$(TOOL)
+KERNEL_ASMOBJS := $(KERNEL_ASMOBJS) prc_support.o
+KERNEL_COBJS := $(KERNEL_COBJS) prc_config.o
+
+#
+# コンフィギュレータ関係の変数の定義
+#
+CFG_TABS := $(CFG_TABS) --cfg1-def-table $(SRCDIR)/arch/$(PRC)_$(TOOL)/prc_def.csv
+
+#
+# 依存関係の定義
+#
+cfg1_out.c: $(SRCDIR)/arch/$(PRC)_$(TOOL)/prc_def.csv
+kernel_cfg.timestamp: $(SRCDIR)/arch/$(PRC)_$(TOOL)/prc.tf
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: arm_m.h 1304 2008-08-27 07:28:36Z ertl-honda $
+ */
+
+/*
+ * ARMVx-Mのハードウェア資源の定義
+ */
+
+#ifndef ARM_M_H
+#define ARM_M_H
+
+
+/*
+ * EPSRのTビット
+ */
+#define EPSR_T 0x01000000
+
+/*
+ * IPSRの ISR NUMBER
+ */
+#define IPSR_ISR_NUMBER 0x1ff
+
+/*
+ * 例外・割込み発生時にスタック上に積まれる保存領域のサイズ
+ * 本カーネルでは例外フレームと呼ぶ
+ */
+#define EXC_FRAME_SIZE (8*4)
+
+/*
+ * 例外・割込み発生時にLRに設定されるEXC_RETURNの値
+ */
+#define EXC_RETURN_HANDLER 0x0
+#define EXC_RETURN_THREAD 0x8
+#define EXC_RETURN_MSP 0x0
+#define EXC_RETURN_PSP 0x4
+
+/*
+ * CONTROLレジスタ
+ */
+#define CONTROL_PSP 0x02
+#define CONTROL_MSP 0x00
+
+/*
+ * 例外番号
+ */
+#define EXCNO_NMI 2
+#define EXCNO_HARD 3
+#define EXCNO_MPU 4
+#define EXCNO_BUS 5
+#define EXCNO_USAGE 6
+#define EXCNO_SVCALL 11
+#define EXCNO_DEBUG 12
+#define EXCNO_PENDSV 14
+
+/*
+ * 例外番号の最小値と最大値
+ */
+#define TMIN_EXCNO 2
+#define TMAX_EXCNO 14
+
+/*
+ * 割込み番号
+ */
+#define IRQNO_SYSTICK 15
+
+/*
+ * 割込み番号の最小値
+ */
+#define TMIN_INTNO 15
+
+/*
+ * 例外フレームのオフセット
+ */
+#define P_EXCINF_OFFSET_EXC_RETURN 0x00
+#define P_EXCINF_OFFSET_BASEPRI 0x01
+#define P_EXCINF_OFFSET_XPSR 0x09
+#define P_EXCINF_OFFSET_PC 0x08
+
+/*
+ * NVIC関連
+ */
+
+/*
+ * コントロールレジスタ
+ */
+#define NVIC_INT_CTRL 0xe000ed04
+
+#define NVIC_PENDSVSET 0x10000000
+
+/*
+ * システムハンドラーコントロールレジスタ
+ */
+#define NVIC_SYS_HND_CTRL 0xE000ED24
+
+/*
+ * 各例外の許可ビット
+ */
+#define NVIC_SYS_HND_CTRL_USAGE 0x00040000
+#define NVIC_SYS_HND_CTRL_BUS 0x00020000
+#define NVIC_SYS_HND_CTRL_MEM 0x00010000
+
+/*
+ * 優先度設定レジスタ
+ */
+#define NVIC_SYS_PRI1 0xE000ED18 // Sys. Handlers 4 to 7 Priority
+#define NVIC_SYS_PRI2 0xE000ED1C // Sys. Handlers 8 to 11 Priority
+#define NVIC_SYS_PRI3 0xE000ED20 // Sys. Handlers 12 to 15 Priority
+#define NVIC_PRI0 0xE000E400 // IRQ 0 to 3 Priority Register
+
+/*
+ * 割込み許可レジスタ
+ */
+#define NVIC_SETENA0 0xE000E100 // IRQ 0 to 31 Set Enable Register
+
+/*
+ * 割込み禁止レジスタ
+ */
+#define NVIC_CLRENA0 0xE000E180 // IRQ 0 to 31 Set Disable Register
+
+/*
+ * ベクタテーブルオフセットレジスタ
+ */
+#define NVIC_VECTTBL 0xE000ED08
+
+
+/*
+ * SYSTIC関連レジスタ
+ */
+#define SYSTIC_CONTROL_STATUS 0xE000E010
+#define SYSTIC_RELOAD_VALUE 0xE000E014
+#define SYSTIC_CURRENT_VALUE 0xE000E018
+#define SYSTIC_CALIBRATION 0xE000E01C
+
+#define SYSTIC_ENABLE 0x01
+#define SYSTIC_TICINT 0x02
+#define SYSTIC_CLKSOURCE 0x04
+#define SYSTIC_COUNTFLAG 0x10000
+
+#define SYSTIC_SKEW 0x40000000
+#define SYSTIC_NOREF 0x80000000
+#define SYSTIC_TENMS 0x00ffffff
+
+#endif /* ARM_M_H */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: makeoffset.c 1304 2008-08-27 07:28:36Z ertl-honda $
+ */
+
+#include "kernel_impl.h"
+#include "task.h"
+
+#define OFFSET_DEF(TYPE, FIELD) \
+ Asm("OFFSET_DEF " #TYPE "_" #FIELD " = %0" \
+ : /* no output */ \
+ : "g"(offsetof(TYPE, FIELD)))
+
+#define OFFSET_DEF2(TYPE, FIELD, FIELDNAME) \
+ Asm("OFFSET_DEF " #TYPE "_" #FIELDNAME " = %0" \
+ : /* no output */ \
+ : "g"(offsetof(TYPE, FIELD)))
+
+void
+makeoffset(void)
+{
+ OFFSET_DEF(TCB, p_tinib);
+ OFFSET_DEF(TCB, texptn);
+ OFFSET_DEF2(TCB, tskctxb.sp, sp);
+ OFFSET_DEF2(TCB, tskctxb.pc, pc);
+
+ OFFSET_DEF(TINIB, exinf);
+ OFFSET_DEF(TINIB, task);
+}
+
+uint32_t BIT_REF_4 = 0x12345678;
+uint16_t BIT_REF_2 = 0x1234;
+uint8_t BIT_REF_1 = 0x12;
+
+TCB BIT_BB_TCB_enatex = {
+ { NULL, NULL }, /* task_queue */
+ NULL, /* p_tinib */
+ 0U, /* tstat */
+#ifdef TOPPERS_SUPPORT_MUTEX
+ 0U, /* bpriority */
+#endif /* TOPPERS_SUPPORT_MUTEX */
+ 0U, /* priority */
+ false, /* acqeue */
+ false, /* wupque */
+ true, /* enatex */
+ 0U, /* texprn */
+ NULL, /* p_winifo */
+#ifdef TOPPERS_SUPPORT_MUTEX
+ { NULL, NULL }, /* mutex_queue */
+#endif /* TOPPERS_SUPPORT_MUTEX */
+ { NULL, NULL } /* tskctxb */
+};
--- /dev/null
+$
+$ パス2のアーキテクチャ依存テンプレート(ARM-M用)
+$
+
+$
+$ 有効な割込み番号,割込みハンドラ番号
+$
+$INTNO_VALID = RANGE(15, TMAX_INTNO)$
+$INHNO_VALID = INTNO_VALID$
+
+$
+$ 有効なCPU例外番号
+$
+$EXCNO_VALID = { 2,3,4,5,6,11,12,14 }$
+
+$
+$ ATT_ISRで使用できる割込み番号とそれに対応する割込みハンドラ番号
+$
+$INTNO_ATTISR_VALID = INTNO_VALID$
+$INHNO_ATTISR_VALID = INHNO_VALID$
+
+$
+$ DEF_INT/DEF_EXCで使用できる割込みハンドラ番号/CPU例外ハンドラ番号
+$
+$INHNO_DEFINH_VALID = INHNO_VALID$
+$EXCNO_DEFEXC_VALID = EXCNO_VALID$
+
+$
+$ チェック方法の指定
+$
+$CHECK_STKSZ_ALIGN = 8$
+
+$
+$ CFG_INTで使用できる割込み番号と割込み優先度
+$
+$INTNO_CFGINT_VALID = INTNO_VALID$
+$INTPRI_CFGINT_VALID = RANGE(-(1 << TBITW_IPRI),-1)$
+
+$
+$ 割込み属性中のターゲット依存に用いるビット
+$
+$ TARGET_INTATR = $
+
+$
+$ 標準テンプレートファイルのインクルード
+$
+$INCLUDE "kernel/kernel.tf"$
+
+/*$NL$
+$SPC$* Target-dependent Definitions (ARM-M)$NL$
+$SPC$*/$NL$
+$NL$
+
+$
+$ ベクターテーブル
+$
+$FILE "kernel_cfg.c"$
+$NL$
+__attribute__ ((section(".vector"))) $NL$
+const FP _kernel_vector_table[] = $NL$
+{ $NL$
+ $TAB$(FP)(TOPPERS_ISTKPT(TOPPERS_ISTK, TOPPERS_ISTKSZ)), // 0 The initial stack pointer $NL$
+ $TAB$(FP)_start, // 1 The reset handler $NL$
+
+$FOREACH excno {2,3,...,14}$
+ $IF excno == 11$
+ $TAB$(FP)(_kernel_svc_handler), // 11 SVCall handler
+ $ELSE$
+ $TAB$(FP)(_kernel_exc_entry),
+ $END$
+ $SPC$$FORMAT("/* %d */", +excno)$$NL$
+$END$
+
+$FOREACH inhno INTNO_VALID$
+ $IF LENGTH(INH.INHNO[inhno]) && (INT.INTPRI[inhno] < TIPM_LOCK)$
+ $TAB$(FP)($INH.INTHDR[inhno]$),
+ $ELSE$
+ $TAB$(FP)(_kernel_int_entry),
+ $END$
+ $SPC$$FORMAT("/* %d */", +inhno)$$NL$
+$END$
+
+
+$NL$};$NL$
+$NL$
+
+$NL$
+const FP _kernel_exc_tbl[] = $NL$
+{$NL$
+$FOREACH excno {0,1,...,14}$
+ $IF LENGTH(EXC.EXCNO[excno])$
+ $TAB$(FP)($EXC.EXCHDR[excno]$),
+ $ELSE$
+ $TAB$(FP)(_kernel_default_exc_handler),
+ $END$
+ $SPC$$FORMAT("/* %d */", +excno)$$NL$
+$END$
+
+
+$FOREACH inhno INTNO_VALID$
+ $IF LENGTH(INH.INHNO[inhno])$
+ $TAB$(FP)($INH.INTHDR[inhno]$),
+ $ELSE$
+ $TAB$(FP)(_kernel_default_int_handler),
+ $END$
+ $SPC$$FORMAT("/* %d */", +inhno)$$NL$
+$END$
+
+
+$NL$};$NL$
+$NL$
+
+$
+$ _kernel_bitpat_cfgintの生成
+$
+
+$bitpat_cfgint_num = 0$
+$bitpat_cfgint = 0$
+
+
+const uint32_t _kernel_bitpat_cfgint[
+$IF (TMAX_INTNO & 0x0f) == 0x00 $
+ $bitpat_cfgint_num = (TMAX_INTNO >> 4)$
+$ELSE$
+ $bitpat_cfgint_num = (TMAX_INTNO >> 4) + 1$
+$END$
+ $bitpat_cfgint_num$
+] = {$NL$
+$FOREACH num RANGE(0,(bitpat_cfgint_num-1))$
+ $bitpat_cfgint = 1-1$
+ $FOREACH inhno RANGE(num*32, (num*32)+31)$
+ $IF LENGTH(INH.INHNO[inhno])$
+ $bitpat_cfgint = bitpat_cfgint | (1 << (inhno & 0x01f))$
+ $END$
+ $END$
+ $TAB$UINT32_C($FORMAT("0x%08x", bitpat_cfgint)$), $NL$
+$END$
+
+$NL$};$NL$
+$NL$
--- /dev/null
+/*
+ * @(#) $Id: prc_cfg1_out.h 1304 2008-08-27 07:28:36Z ertl-honda $
+ */
+
+/*
+ * cfg1_out.cをリンクするために必要なスタブの定義
+ */
+
+void sta_ker(void){}
+#ifdef TOPPERS_CHIP_LPC17XX
+/* TOPPERS_CHIP_LPC17XXが宣言されているときには、何もここでは宣言しない */
+#else
+STK_T *const _kernel_istkpt = 0x00;
+#endif
--- /dev/null
+$
+$ パス3のプロセッサ依存テンプレート(ARM-M用)
+$
+
+$
+$ チェック方法の指定
+$
+$CHECK_FUNC_ALIGN = 1$
+$CHECK_FUNC_NONNULL = 1$
+$CHECK_STACK_ALIGN = 8$
+$CHECK_STACK_NONNULL = 1$
+$CHECK_MPF_ALIGN = 4$
+$CHECK_MPF_NONNULL = 1$
+
+$
+$ 標準テンプレートファイルのインクルード
+$
+$INCLUDE "kernel/kernel_check.tf"$
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: prc_config.c 1304 2008-08-27 07:28:36Z ertl-honda $
+ */
+
+/*
+ * プロセッサ依存モジュール(ARM-M用)
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+
+/*
+ * CPUロックフラグ実現のための変数
+ */
+volatile bool_t lock_flag; /* CPUロックフラグの値を保持する変数 */
+volatile uint32_t saved_iipm; /* 割込み優先度マスクを保存する変数 */
+
+/*
+ * ベクタテーブル(kernel_cfg.c)
+ */
+extern const FP vector_table[];
+
+/*
+ * システム例外・割込みの(例外番号 4〜15)
+ * 割込み優先度設定レジスタへのアクセスのための配列
+ */
+static const unsigned int nvic_sys_pri_reg[] = {
+ 0,
+ NVIC_SYS_PRI1,
+ NVIC_SYS_PRI2,
+ NVIC_SYS_PRI3
+};
+
+/*
+ * 例外と割込みの割込み優先度をセット
+ *
+ * excnoはARM-Mで定められている Exception Number を指定.
+ */
+void
+set_exc_int_priority(uint32_t excno, uint8_t pri){
+ uint32_t tmp, reg;
+
+ /*
+ * 割込み優先度設定レジスタの決定
+ */
+ if ((EXCNO_MPU <= excno) && (excno <= IRQNO_SYSTICK)) {
+ /*
+ * Exception Number 4(Memory Management)から
+ * Exception Number 15(SysTick)までの割込み優先度はシステム優先度
+ * レジスタにより設定.
+ */
+ reg = nvic_sys_pri_reg[excno >> 2];
+ }
+ else if ((TMIN_INTNO < excno) && (excno <= TMAX_INTNO)){
+ /*
+ * IRQ割込みなら
+ */
+ reg = NVIC_PRI0 + (((excno - (TMIN_INTNO + 1)) >> 2) * 4);
+ }
+ else {
+ return ;
+ }
+
+ tmp = sil_rew_mem((void *)reg);
+ tmp &= ~(0xFF << (8 * (excno & 0x03)));
+ tmp |= (pri << (8 - TBITW_IPRI)) << (8 * (excno & 0x03));
+ sil_wrw_mem((void *)reg, tmp);
+}
+
+/*
+ * 例外の許可
+ *
+ * Memory Management, Bus Fault, Usage Fault は禁止・許可が買おう
+ */
+void
+enable_exc(EXCNO excno)
+{
+ uint32_t tmp;
+
+ switch (excno) {
+ case EXCNO_MPU:
+ tmp = sil_rew_mem((void *)NVIC_SYS_HND_CTRL);
+ tmp |= NVIC_SYS_HND_CTRL_MEM;
+ sil_wrw_mem((void *)NVIC_SYS_HND_CTRL, tmp);
+ break;
+ case EXCNO_BUS:
+ tmp = sil_rew_mem((void *)NVIC_SYS_HND_CTRL);
+ tmp |= NVIC_SYS_HND_CTRL_BUS;
+ sil_wrw_mem((void *)NVIC_SYS_HND_CTRL, tmp);
+ break;
+ case EXCNO_USAGE:
+ tmp = sil_rew_mem((void *)NVIC_SYS_HND_CTRL);
+ tmp |= NVIC_SYS_HND_CTRL_USAGE;
+ sil_wrw_mem((void *)NVIC_SYS_HND_CTRL, tmp);
+ break;
+ }
+}
+
+/*
+ * 例外の禁止
+ */
+void
+disable_exc(EXCNO excno)
+{
+ uint32_t tmp;
+
+ switch (excno) {
+ case EXCNO_MPU:
+ tmp = sil_rew_mem((void *)NVIC_SYS_HND_CTRL);
+ tmp &= ~NVIC_SYS_HND_CTRL_MEM;
+ sil_wrw_mem((void *)NVIC_SYS_HND_CTRL, tmp);
+ break;
+ case EXCNO_BUS:
+ tmp = sil_rew_mem((void *)NVIC_SYS_HND_CTRL);
+ tmp &= ~NVIC_SYS_HND_CTRL_BUS;
+ sil_wrw_mem((void *)NVIC_SYS_HND_CTRL, tmp);
+ break;
+ case EXCNO_USAGE:
+ tmp = sil_rew_mem((void *)NVIC_SYS_HND_CTRL);
+ tmp &= ~NVIC_SYS_HND_CTRL_USAGE;
+ sil_wrw_mem((void *)NVIC_SYS_HND_CTRL, tmp);
+ break;
+ }
+}
+
+
+/*
+ * プロセッサ依存の初期化
+ */
+void
+prc_initialize(void)
+{
+ /*
+ * CPUロックフラグ実現のための変数の初期化
+ */
+ lock_flag = true;
+ saved_iipm = IIPM_ENAALL;
+
+ /*
+ * ベクタテーブルを設定
+ */
+ sil_wrw_mem((void*)NVIC_VECTTBL, (uint32_t)vector_table);
+
+ /*
+ * SVCハンドラの優先度を設定
+ */
+ set_exc_int_priority(EXCNO_SVCALL, 0);
+
+ /*
+ * SVCハンドラを有効に
+ */
+ x_enable_int(EXCNO_SVCALL);
+}
+
+/*
+ * プロセッサ依存の終了処理
+ */
+void
+prc_terminate(void)
+{
+
+}
+
+/*
+ * 割込み要求ライン属性の設定
+ */
+void
+x_config_int(INTNO intno, ATR intatr, PRI intpri)
+{
+ assert(VALID_INTNO_CFGINT(intno));
+ assert(TMIN_INTPRI <= intpri && intpri <= TMAX_INTPRI);
+
+ /*
+ * 一旦割込みを禁止する
+ */
+ (void)x_disable_int(intno);
+
+ /*
+ * 割込み優先度をセット
+ */
+ set_exc_int_priority(intno, intpri);
+
+ /*
+ * 割込み要求マスク解除(必要な場合)
+ * 同時に割込み優先度もセットされる
+ */
+ if ((intatr & TA_ENAINT) != 0U) {
+ (void) x_enable_int(intno);
+ }
+}
+
+
+#ifndef OMIT_DEFAULT_EXC_HANDLER
+/*
+ * Trapa以外の例外で登録されていない例外が発生すると呼び出される
+ */
+void
+default_exc_handler(void *p_excinf)
+{
+ uint32_t basepri = *(((uint32_t*)p_excinf) + P_EXCINF_OFFSET_BASEPRI);
+ uint32_t pc = *(((uint32_t*)p_excinf) + P_EXCINF_OFFSET_PC);
+ uint32_t xpsr = *(((uint32_t*)p_excinf) + P_EXCINF_OFFSET_XPSR);
+ uint32_t excno = get_ipsr() & IPSR_ISR_NUMBER;
+
+ syslog(LOG_EMERG, "\nUnregistered Exception occurs.");
+ syslog(LOG_EMERG, "Excno = %08x PC = %08x XPSR = %08x basepri = %08X, p_excinf = %08X",
+ excno, pc, xpsr, basepri, p_excinf);
+
+ target_exit();
+}
+#endif /* OMIT_DEFAULT_EXC_HANDLER */
+
+#ifndef OMIT_DEFAULT_INT_HANDLER
+/*
+ * 未登録の割込みが発生した場合に呼び出される
+ */
+void
+default_int_handler(void *p_excinf)
+{
+ uint32_t basepri = *(((uint32_t*)p_excinf) + P_EXCINF_OFFSET_BASEPRI);
+ uint32_t pc = *(((uint32_t*)p_excinf) + P_EXCINF_OFFSET_PC);
+ uint32_t xpsr = *(((uint32_t*)p_excinf) + P_EXCINF_OFFSET_XPSR);
+ uint32_t excno = get_ipsr() & IPSR_ISR_NUMBER;
+
+ syslog(LOG_EMERG, "\nUnregistered Interrupt occurs.");
+ syslog(LOG_EMERG, "Excno = %08x PC = %08x XPSR = %08x basepri = %08X, p_excinf = %08X",
+ excno, pc, xpsr, basepri, p_excinf);
+
+ target_exit();
+}
+#endif /* OMIT_DEFAULT_INT_HANDLER */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: prc_config.h 1304 2008-08-27 07:28:36Z ertl-honda $
+ */
+
+/*
+ * プロセッサ依存モジュール(ARM-M用)
+ *
+ * このインクルードファイルは,target_config.h(または,そこからインク
+ * ルードされるファイル)のみからインクルードされる.他のファイルから
+ * 直接インクルードしてはならない.
+ */
+
+#ifndef TOPPERS_PRC_CONFIG_H
+#define TOPPERS_PRC_CONFIG_H
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ * プロセッサの特殊命令のインライン関数定義
+ */
+#include "prc_insn.h"
+
+/*
+ * 非タスクコンテキスト用のスタック初期値
+ */
+#define TOPPERS_ISTKPT(istk, istksz) ((STK_T *)((istk) + (istksz)/(sizeof(STK_T))))
+
+/*
+ * タスクコンテキストブロックの定義
+ */
+typedef struct task_context_block {
+ void *sp; /* スタックポインタ */
+ FP pc; /* プログラムカウンタ */
+} TSKCTXB;
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#ifndef TOPPERS_MACRO_ONLY
+/*
+ * コンテキストの参照
+ *
+ */
+Inline bool_t
+sense_context(void)
+{
+ /*
+ * PSPが有効ならタスクコンテキスト,MSPが有効なら非タスクコンテキスト
+ * とする.
+ */
+ if ((get_control() & CONTROL_PSP) == CONTROL_PSP){
+ return false;
+ }
+ else {
+ return true;
+ }
+}
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ * TOPPERS標準割込み処理モデルの実現
+ *
+ * 割込み優先度マスクとしては,BASEPRIを用いる.全割込みを禁止する
+ * 機能として,FAULTMASKやPRIMASKがあるが,カーネル管理外の割込みを
+ * サポートするため,これらはCPUロックのために用いない.
+ * そのため,BASEPRIを用いて擬似的にCPUロックフラグを実現する.
+ *
+ * まず,CPUロック状態を管理すための変数(lock_flag)を用意する.
+ *
+ * CPUロックフラグがクリアされている間は,BASEPRIをモデル上の割込み
+ * 優先度マスクの値に設定する.この間は,モデル上の割込み優先度マス
+ * クは,BASEPRIを用いる.
+ *
+ * それに対してCPUロックフラグがセットされいる間は,BASEPRIを,カーネ
+ * ル管理外のものを除くすべての割込み要求をマスクする値(TIPM_LOCK)と,
+ * モデル上の割込み優先度マスクとの高い方に設定する.この間のモデル上
+ * の割込み優先度マスクは,そのための変数(saved_iipm, 内部表現で保持)
+ * を用意して保持する.
+ */
+
+/*
+ * 割込み優先度マスクの外部表現と内部表現の変換
+ *
+ * アセンブリ言語のソースファイルからインクルードする場合のために,
+ * CASTを使用
+ * 割込み優先度のビット幅(TBITW_IPRI)が 8 の場合は,内部優先度 255
+ * は,外部優先度 -1 に対応する.
+ */
+#define EXT_IPM(iipm) (CAST(PRI,((iipm >> (8 - TBITW_IPRI)) - (1 << TBITW_IPRI)))) /* 内部表現を外部表現に */
+#define INT_IPM(ipm) (((1 << TBITW_IPRI) - CAST(uint8_t, -(ipm))) << (8 - TBITW_IPRI)) /* 外部表現を内部表現に */
+
+/*
+ * CPUロック状態での割込み優先度マスク
+ */
+#define TIPM_LOCK TMIN_INTPRI
+
+/*
+ * CPUロック状態での割込み優先度マスクの内部表現
+ *
+ * TIPM_LOCKは,CPUロック状態でのBASEPRIの値.カーネル管理外のものを
+ * 除くすべての割込みをマスクする値に定義する.
+ */
+#define IIPM_LOCK INT_IPM(TIPM_LOCK)
+
+/*
+ * TIPM_ENAALL(割込み優先度マスク全解除)の内部表現
+ *
+ * BASEPRIに '0' を設定することで,全割込みを許可する.
+ */
+#define IIPM_ENAALL (0)
+
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ * CPUロックフラグ実現のための変数
+ *
+ * これらの変数は,CPUロック状態の時のみ書き換えてもよいとする.
+ * インライン関数中で,アクセスの順序が変化しないよう,volatile を指定.
+ */
+extern volatile bool_t lock_flag; /* CPUロックフラグの値を保持する変数 */
+extern volatile uint32_t saved_iipm; /* 割込み優先度をマスクする変数 */
+
+/*
+ * CPUロック状態への移行
+ *
+ * BASEPRI(ハードウェアの割込み優先度マスク)を,saved_iipmに保存し,
+ * カーネル管理外のものを除くすべての割込みをマスクする値(TIPM_LOCK)
+ * に設定する.また,lock_flagをtrueにする.
+ *
+ * BASEPRIが,最初からTIPM_LOCKと同じかそれより高い場合には,それを
+ * saved_iipmに保存するのみで,TIPM_LOCKには設定しない.これは,モデル
+ * 上の割込み優先度マスクが,TIPM_LOCKと同じかそれより高いレベルに設定
+ * されている状態にあたる.
+ *
+ * この関数は,CPUロック状態(lock_flagがtrueの状態)で呼ばれることは
+ * ないものと想定している.
+ */
+Inline void
+x_lock_cpu(void)
+{
+ uint32_t iipm;
+
+ /*
+ * current_iipm()の返り値を直接saved_iipmに保存せず,一時変数iipm
+ * を用いているのは,current_iipm()を呼んだ直後に割込みが発生し,
+ * 起動された割込み処理でsaved_iipmが変更される可能性があるためで
+ * ある.
+ */
+ iipm = get_basepri();
+ if ((IIPM_LOCK < iipm) || (IIPM_ENAALL == iipm)) {
+ set_basepri(IIPM_LOCK);
+ }
+ saved_iipm = iipm;
+ lock_flag = true;
+ /* クリティカルセクションの前後でメモリが書き換わる可能性がある */
+ Asm("":::"memory");
+}
+
+#define t_lock_cpu() x_lock_cpu()
+#define i_lock_cpu() x_lock_cpu()
+
+/*
+ * CPUロック状態の解除
+ *
+ * lock_flagをfalseにし,IPM(ハードウェアの割込み優先度マスク)を,
+ * saved_iipmに保存した値に戻す.
+ *
+ * この関数は,CPUロック状態(lock_flagがtrueの状態)でのみ呼ばれるも
+ * のと想定している.
+ */
+Inline void
+x_unlock_cpu(void)
+{
+ /* クリティカルセクションの前後でメモリが書き換わる可能性がある */
+ Asm("":::"memory");
+ lock_flag = false;
+ set_basepri(saved_iipm);
+}
+
+#define t_unlock_cpu() x_unlock_cpu()
+#define i_unlock_cpu() x_unlock_cpu()
+
+/*
+ * CPUロック状態の参照
+ */
+Inline bool_t
+x_sense_lock(void)
+{
+ return(lock_flag);
+}
+
+#define t_sense_lock() x_sense_lock()
+#define i_sense_lock() x_sense_lock()
+
+/*
+ * chg_ipmで有効な割込み優先度の範囲の判定
+ *
+ * TMIN_INTPRIの値によらず,chg_ipmでは,-(1 << TBITW_IPRI)〜TIPM_ENAALL(=0)
+ * の範囲に設定できることとする(ターゲット定義の拡張).
+ * 割込み優先度のビット幅(TBITW_IPRI)が 8 の場合は,-256 〜 0 が指定可能である.
+ *
+ */
+#define VALID_INTPRI_CHGIPM(intpri) \
+ ((-((1 << TBITW_IPRI) - 1) <= (intpri) && (intpri) <= TIPM_ENAALL))
+
+/*
+ * (モデル上の)割込み優先度マスクの設定
+ *
+ * CPUロックフラグがクリアされている時は,ハードウェアの割込み優先度マ
+ * スクを設定する.CPUロックフラグがセットされている時は,saved_iipm
+ * を設定し,さらに,ハードウェアの割込み優先度マスクを,設定しようと
+ * した(モデル上の)割込み優先度マスクとTIPM_LOCKの高い方に設定する.
+ */
+Inline void
+x_set_ipm(PRI intpri)
+{
+ uint8_t iipm = INT_IPM(intpri);
+
+ if (intpri == TIPM_ENAALL){
+ iipm = IIPM_ENAALL;
+ }
+
+ if (!lock_flag) {
+ set_basepri(iipm);
+ }
+ else {
+ saved_iipm = iipm;
+ set_basepri(iipm < IIPM_LOCK ? iipm : IIPM_LOCK);
+ }
+}
+
+#define t_set_ipm(intpri) x_set_ipm(intpri)
+#define i_set_ipm(intpri) x_set_ipm(intpri)
+
+/*
+ * (モデル上の)割込み優先度マスクの参照
+ *
+ * CPUロックフラグがクリアされている時はハードウェアの割込み優先度マ
+ * スクを,セットされている時はsaved_iipmを参照する.
+ */
+Inline PRI
+x_get_ipm(void)
+{
+ uint8_t iipm;
+
+ if (!lock_flag) {
+ iipm = get_basepri();
+ }
+ else {
+ iipm = saved_iipm;
+ }
+
+ if (iipm == IIPM_ENAALL) {
+ return(TIPM_ENAALL);
+ }
+ else {
+ return(EXT_IPM(iipm));
+ }
+}
+
+#define t_get_ipm() x_get_ipm()
+#define i_get_ipm() x_get_ipm()
+
+/*
+ * SVCハンドラ(prc_support.S)
+ */
+extern void svc_handler(void);
+
+/*
+ * スタートアップルーチン(start.S)
+ */
+extern void _start(void);
+
+/*
+ * 最高優先順位タスクへのディスパッチ(prc_support.S)
+ *
+ * dispatchは,タスクコンテキストから呼び出されたサービスコール処理か
+ * ら呼び出すべきもので,タスクコンテキスト・CPUロック状態・ディスパッ
+ * チ許可状態・(モデル上の)割込み優先度マスク全解除状態で呼び出さな
+ * ければならない.
+ */
+extern void dispatch(void);
+
+/*
+ * ディスパッチャの動作開始(prc_support.S)
+ *
+ * start_dispatchは,カーネル起動時に呼び出すべきもので,すべての割込
+ * みを禁止した状態(割込みロック状態と同等の状態)で呼び出さなければ
+ * ならない.
+ */
+extern void start_dispatch(void) NoReturn;
+
+/*
+ * 現在のコンテキストを捨ててディスパッチ(prc_support.S)
+ *
+ * exit_and_dispatchは,ext_tskから呼び出すべきもので,タスクコンテキ
+ * スト・CPUロック状態・ディスパッチ許可状態・(モデル上の)割込み優先
+ * 度マスク全解除状態で呼び出さなければならない.
+ */
+extern void exit_and_dispatch(void) NoReturn;
+
+/*
+ * カーネルの終了処理の呼出し(prc_support.S)
+ *
+ * call_exit_kernelは,カーネルの終了時に呼び出すべきもので,非タスク
+ * コンテキストに切り換えて,カーネルの終了処理(exit_kernel)を呼び出
+ * す.
+ */
+extern void call_exit_kernel(void) NoReturn;
+
+/*
+ * タスクコンテキストの初期化
+ *
+ * タスクが休止状態から実行できる状態に移行する時に呼ばれる.この時点
+ * でスタック領域を使ってはならない.
+ *
+ * activate_contextを,インライン関数ではなくマクロ定義としているのは,
+ * この時点ではTCBが定義されていないためである.
+ */
+extern void start_r(void);
+
+#define activate_context(p_tcb) \
+{ \
+ (p_tcb)->tskctxb.sp = (void *)((char_t *)((p_tcb)->p_tinib->stk) \
+ + (p_tcb)->p_tinib->stksz); \
+ (p_tcb)->tskctxb.pc = (void *) start_r; \
+}
+
+/*
+ * calltexは使用しない
+ */
+#define OMIT_CALLTEX
+
+/*
+ * 割込み番号・割込みハンドラ番号
+ *
+ * 割込みハンドラ番号(inhno)と割込み番号(intno)は,割り込み発生時に
+ * EPSRに設定される例外番号とする.
+ */
+
+/*
+ * 割込み番号の範囲の判定
+ */
+#define VALID_INTNO(intno) ((TMIN_INTNO <= (intno)) && ((intno) <= TMAX_INTNO))
+#define VALID_INTNO_DISINT(intno) VALID_INTNO(intno)
+#define VALID_INTNO_CFGINT(intno) VALID_INTNO(intno)
+
+/*
+ * 割込みハンドラの設定
+ *
+ * ベクトル番号inhnoの割込みハンドラの起動番地int_entryに設定する.割込み
+ * ハンドラテーブル
+ */
+Inline void
+x_define_inh(INHNO inhno, FP int_entry)
+{
+
+}
+
+/*
+ * 割込みハンドラの出入口処理の生成マクロ
+ *
+ */
+#define INT_ENTRY(inhno, inthdr) inthdr
+#define INTHDR_ENTRY(inhno, inhno_num, inthdr) extern void inthdr(void);
+
+/*
+ * 割込み要求禁止フラグ
+ */
+
+/*
+ * 割込み属性が設定されているかを判別するための変数(kernel_cfg.c)
+ */
+extern const uint32_t bitpat_cfgint[];
+
+/*
+ * 割込み要求禁止フラグのセット
+ *
+ * 割込み属性が設定されていない割込み要求ラインに対して割込み要求禁止
+ * フラグをクリアしようとした場合には,falseを返す.
+ */
+Inline bool_t
+x_disable_int(INTNO intno)
+{
+ uint32_t tmp;
+
+ /*
+ * 割込み属性が設定されていない場合
+ */
+ if ((bitpat_cfgint[intno >> 5] & (1 << (intno & 0x1f))) == 0x00) {
+ return(false);
+ }
+
+ if (intno == IRQNO_SYSTICK) {
+ tmp = sil_rew_mem((void *)SYSTIC_CONTROL_STATUS);
+ tmp &= ~SYSTIC_TICINT;
+ sil_wrw_mem((void *)SYSTIC_CONTROL_STATUS, tmp);
+ }else {
+ tmp = intno - 16;
+ sil_wrw_mem((void *)NVIC_CLRENA0 + (tmp >> 5), (1 << (tmp & 0x1f)));
+ }
+
+ return(true);
+}
+
+#define t_disable_int(intno) x_disable_int(intno)
+#define i_disable_int(intno) x_disable_int(intno)
+
+/*
+ * 割込み要求禁止フラグの解除
+ *
+ * 割込み属性が設定されていない割込み要求ラインに対して割込み要求禁止
+ * フラグをクリアしようとした場合には,falseを返す.
+ */
+Inline bool_t
+x_enable_int(INTNO intno)
+{
+ uint32_t tmp;
+
+ /*
+ * 割込み属性が設定されていない場合
+ */
+ if ((bitpat_cfgint[intno >> 5] & (1 << (intno & 0x1f))) == 0x00) {
+ return(false);
+ }
+
+ if (intno == IRQNO_SYSTICK) {
+ tmp = sil_rew_mem((void *)SYSTIC_CONTROL_STATUS);
+ tmp |= SYSTIC_TICINT;
+ sil_wrw_mem((void *)SYSTIC_CONTROL_STATUS, tmp);
+ }else {
+ tmp = intno - 16;
+ sil_wrw_mem((void *)((uint32_t *)NVIC_SETENA0 + (tmp >> 5)),
+ (1 << (tmp & 0x1f)));
+ }
+
+ return(true);
+}
+
+#define t_enable_int(intno) x_enable_int(intno)
+#define i_enable_int(intno) x_enable_int(intno)
+
+/*
+ * 割込み要求ラインの属性の設定
+ */
+extern void x_config_int(INTNO intno, ATR intatr, PRI intpri);
+
+/*
+ * 割込みハンドラ入口で必要なIRC操作
+ */
+Inline void
+i_begin_int(INTNO intno)
+{
+}
+
+/*
+ * 割込みハンドラの出口で必要なIRC操作
+ */
+Inline void
+i_end_int(INTNO intno)
+{
+}
+
+/*
+ * CPU例外ハンドラ関係
+ */
+
+/*
+ * CPU例外ハンドラ番号
+ */
+#define VALID_EXCNO_DEFEXC(excno) (TMIN_EXCNO <= (excno) && (excno) <= TMAX_EXCNO)
+
+/*
+ * CPU例外ハンドラの許可
+ */
+extern void enable_exc(EXCNO excno);
+
+/*
+ * CPU例外ハンドラの禁止
+ */
+extern void disable_exc(EXCNO excno);
+
+/*
+ * CPU例外ハンドラの設定
+ */
+Inline void
+x_define_exc(EXCNO excno, FP exc_entry)
+{
+ /*
+ * 一部の例外は許可を行う必要がある
+ */
+ enable_exc(excno);
+}
+
+/*
+ * CPU例外ハンドラの入口処理の生成マクロ
+ */
+#define EXC_ENTRY(excno, exchdr) exchdr
+#define EXCHDR_ENTRY(excno, excno_num, exchdr) extern void exchdr(void *p_excinf);
+
+/*
+ * CPU例外の発生した時のコンテキストの参照
+ *
+ * CPU例外の発生した時のコンテキストが,タスクコンテキストの時にfalse,
+ * そうでない時にtrueを返す.
+ */
+Inline bool_t
+exc_sense_context(void *p_excinf)
+{
+ uint32_t exc_return;
+
+ exc_return = *((uint32_t *)p_excinf + P_EXCINF_OFFSET_EXC_RETURN);
+ if ((exc_return & EXC_RETURN_PSP) == EXC_RETURN_PSP){
+ return false;
+ }
+ else {
+ return true;
+ }
+}
+
+/*
+ * CPU例外の発生した時のIPM(ハードウェアの割込み優先度マスク,内部表
+ * 現)の参照
+ */
+Inline uint32_t
+exc_get_iipm(void *p_excinf)
+{
+ return(*((uint32_t *)p_excinf + P_EXCINF_OFFSET_BASEPRI));
+}
+
+/*
+ * CPU例外の発生した時のコンテキストと割込みのマスク状態の参照
+ *
+ * CPU例外の発生した時のシステム状態が,カーネル実行中でなく,タスクコ
+ * ンテキストであり,割込みロック状態でなく,CPUロック状態でなく,(モ
+ * デル上の)割込み優先度マスク全解除状態である時にtrue,そうでない時
+ * にfalseを返す(CPU例外がカーネル管理外の割込み処理中で発生した場合
+ * にもfalseを返す).
+ *
+ * PU例外の発生した時のBASEPRI(ハードウェアの割込み優先度マスク)
+ * がすべての割込みを許可する状態であることをチェックすることで,カー
+ * ネル実行中でないこと,割込みロック状態でないこと,CPUロック状態でな
+ * いこと,(モデル上の)割込み優先度マスク全解除状態であることの4つの
+ * 条件をチェックすることができる(CPU例外が発生した時のlock_flagを参
+ * 照する必要はない).
+ */
+Inline bool_t
+exc_sense_intmask(void *p_excinf)
+{
+ return(!exc_sense_context(p_excinf)
+ && (exc_get_iipm(p_excinf) == IIPM_ENAALL));
+}
+
+/*
+ * CPU例外の発生した時のコンテキストと割込み/CPUロック状態の参照
+ *
+ * CPU例外の発生した時のシステム状態が,カーネル実行中でなく,タスクコ
+ * ンテキストであり,割込みロック状態でなく,CPUロック状態でない時に
+ * true,そうでない時にfalseを返す(CPU例外がカーネル管理外の割込み処
+ * 理中で発生した場合にもfalseを返す).
+ *
+ * CPU例外の発生した時のBASEPRI(ハードウェアの割込み優先度マ
+ * スク)がTIPM_LOCKより低いことをチェックすることで,カーネル実行中で
+ * ないこと,割込みロック状態でないこと,CPUロック状態でないことの3つ
+ * の条件をチェックしている(CPU例外が発生した時のlock_flagは参照して
+ * いない).これにより,(モデル上の)割込み優先度マスクをTIPM_LOCK以
+ * 上に設定してタスクを実行している時にもfalseが返ってしまうが,判断を
+ * 正確にするためのオーバヘッドが大きいことから,許容することにする.
+ */
+Inline bool_t
+exc_sense_unlock(void *p_excinf)
+{
+ return(!exc_sense_context(p_excinf)
+ && ((exc_get_iipm(p_excinf) > IIPM_LOCK)
+ || exc_get_iipm(p_excinf) == IIPM_ENAALL));
+}
+
+/*
+ * CPU例外エントリ(prc_support.S)
+ */
+extern void exc_entry(void);
+
+/*
+ * 割込みエントリ(prc_support.S)
+ */
+extern void int_entry(void);
+
+/*
+ * プロセッサ依存の初期化
+ */
+extern void prc_initialize(void);
+
+/*
+ * プロセッサ依存の終了時処理
+ */
+extern void prc_terminate(void);
+
+/*
+ * atexitの処理とデストラクタの実行
+ */
+Inline void
+call_atexit(void)
+{
+ extern void software_term_hook(void);
+ void (*volatile fp)(void) = software_term_hook;
+
+ /*
+ * software_term_hookへのポインタを,一旦volatile指定のあるfpに代
+ * 入してから使うのは,0との比較が最適化で削除されないようにするた
+ * めである.
+ */
+ if (fp != 0) {
+ (*fp)();
+ }
+}
+
+/*
+ * 登録されていない例外が発生すると呼び出される
+ */
+extern void default_exc_handler(void *p_excinf);
+
+/*
+ * 未登録の割込みが発生した場合に呼び出される
+ */
+extern void default_int_handler(void *p_excinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
+#endif /* TOPPERS_PRC_CONFIG_H */
--- /dev/null
+TMAX_INTNO,TMAX_INTNO
+TIPM_LOCK,TIPM_LOCK
+TBITW_IPRI,TBITW_IPRI
--- /dev/null
+=====================================================================
+ ARM-Mプロセッサ依存部設計メモ
+ Last Modified: 23 Aug 2008 21:54:54
+=====================================================================
+
+○このドキュメントの位置づけ
+
+このドキュメントは,TOPPERS/ASPカーネルをARMvX-Mプロセッサに移植するため
+の設計メモである.
+
+
+○ARMVx-Mの仕様まとめ
+
+ARMvX-Mの仕様のうち,カーネルの設計に関係する事項についてまとめる.
+
+●レジスタ
+
+汎用レジスタはR0〜R15の16種類あり,R13のみが2バンク構成(PSP,MSP)とな
+っている.R15はPC, R14はリンクレジスタ(LR)となっている.R0〜R3,R12は
+スクラッチレジスタである.
+
+●コーリングコンベンション
+
+R0〜R4が引数,それ以上はスタック.戻り値は,R0〜R1に格納される.(ARMに
+より規定されているため,コンパイラに依存せずこのルールとなる.)
+
+●CONTROLレジスタ
+
+PSP,MSPの切り替え,PrivilageとUserモードのレジスタ.変更後は,インスト
+ラクションバッファフラッシュ命令を実行する必要がある(isb).CONTROLレ
+ジスタの詳細は,ARMv7-M Architecture Application Level Reference
+Manual の B1-9 を参照のこと.
+
+●割込みベクタ
+
+ベクタテーブル型で,ベクタテーブルのアドレスは,リセット時は0x00で,
+Vector Table Offset Register(メモリマップドレジスタ) を操作すること
+で,任意のアドレスに配置可能である.
+
+●優先度
+
+値が小さい方が高優先度となる.
+
+優先度は最大8bitであり,SoC毎に実装されているビット幅が異なる.実装さ
+れるビットが8bit以下の場合は,LSBから無効になる.例えば,実装されてい
+るビット幅が7bitの場合は,ビット0が無効となる.
+
+優先度のビットフィールドのLSBから数ビットをサブ優先度と呼ぶフィールド
+に設定することが可能である.残りの上位ビットをプリエンプション優先度と
+呼ぶ.プリエンプション優先度が同じで,サブ優先度が異なる優先度のグルー
+プは,お互いをプリエンプトすることができない.
+
+Reset,NMI,Hard Fault 以外の例外は割込みと同様に優先度が設定可能であり,
+割込みマスク機能により,発生を禁止することが可能である.
+
+●CPUモード
+
+プロセッサは,ThreadモードもしくはHandlerモードのいずれかのモードとな
+る.
+
+●リセット時の状態
+
+リセット時はThreadモード,MSPが有効となっている.
+
+●Handlerモード
+
+例外/割込みを受け付けると遷移するモード.受け付けた例外/割込みの例外番
+号が,IPSRにセットされる.例外番号は,TRMで定められている番号である.
+
+ 例外 例外番号
+ Reset 1
+ Non-makable Interrupt 2
+ Hard Fault 3
+ Memory Management 4
+ Bus Fault 5
+ Usage Fault 6
+ SVCall 11
+ Debug Monitor 12
+ PendSV 14
+ SysTick 15
+ IRQ0 16
+ IRQ1 17
+ ..
+
+例外/割込みを受け付けると,受け付けた例外/割込みの優先度以下の例外/割
+込みを禁止する.この優先度マスクを"NVIC優先度マスク"と呼ぶ.この優先度
+は,ソフトウェアから変更することができず,例外/割込みのリターンにより
+割込み前の値に自動的に戻る.
+
+●スタックポインタ(PSPとMSP)
+
+スタックポインタは,PSPとMSPがあり,排他的に使用可能である.Handlerモ
+ードではMSPのみ使用可能であり,ThreadモードではCONTROLレジスタで選択可
+能である.CONTROLレジスタの1ビット目をセットするとPSPが有効に,クリア
+すると,MSPが有効になる.
+
+●ThreadモードとHandlerモードの遷移
+
+ThreadモードからHandlerモードへの遷移は,例外/割込みを受け付けることで
+発生する.一方,HandlerモードからThreadモードへの遷移は,PCに
+EXC_RETURN(0xfffffffx)の値を設定することにより行う(例外リターン処理と
+呼ぶ).EXC_RETURNの下位4bitにより,遷移先のモードや使用するスタックポ
+インタを変更可能である.例外リターンにより,PRIMASKやBASEPRIの値は変化
+しない.一方,FAULTMASKの値は'0'にクリアさせる.
+
+●EXC_RETURN
+
+例外/割込み受付け時にlrに設定される値.ビット31〜4ビットは全て'1'で,
+下位4bitは,受付け時のCPUモードやスタックを反映した値となっている.
+
+ 0b0001 : Handlerモード
+ 0b1001 : Threadモード with MSP
+ 0b1101 : Threadモード with PSP
+
+●ThreadモードとHandlerモードの判定
+
+現状のモードを判定するには,IPSRを見て,'0'ならThreadモード,それ以外
+なら,Handlerモードとなる.
+
+●BASEPRIレジスタ
+
+設定した優先度以下の優先度の割込みの受付を禁止する.この優先度マスクを
+"BASEPRI優先度マスク"と呼ぶ.'0'を設定すると,全ての割込みを許可する.
+例外/割込みの受付とリターンにより変化しない.例外/割込みに対する割込み
+優先度マスクは,NVIC優先度マスクとBASEPRIの設定値の高い方(値が小さい
+方)となる.
+
+●FAULTMASK
+
+FAULTMASKは'1'をセットすることにより,NMI以外の全ての割込みを禁止する.
+FAULTMASKは,例外のリターン処理により'0'にクリアさせる.
+
+●PRIMASKとWFI
+
+PRIMASKを'1'に設定すると,NMI と Hardware Fault 以外の例外/割込みを禁
+止する.PRIMASKは割込みの許可と割込み待ちをアトミックに行うために用い
+る.具体的には,PRIMASKがセットされている状態でwfiを実行すると,割り込
+み待ちとなり,割込み受付けるとハンドラを実行せずに,wfiからリターンし
+てくる.
+
+●例外/割込みの受付
+
+・例外/割込みを受付けると,受付け時にアクティブなスタック上に以下のコ
+ ンテキストを保存する(例外フレームと呼ぶ).
+
+ -----------
+ | R0 | <- new SP
+ -----------
+ | R1 |
+ -----------
+ | R2 |
+ -----------
+ | R3 |
+ -----------
+ | R12 |
+ -----------
+ | LR |
+ -----------
+ | PC |
+ -----------
+ | xPSR |
+ -----------
+ | | <- old SP
+
+・プロセッサをHandlerモードとする.MSPが有効となる.
+・受付けた例外/割込みの例外番号をIPSRに設定する.
+・NVIC割込み優先度マスクを受付けた例外/割込みの優先度に設定する.
+・lrにEXC_RETURNの値が設定される.
+・ベクタテーブルを読み込みハンドラを実行する.
+
+●例外/割込みからのリターン
+
+pcにEXC_RETURNの値を設定することにより,例外/割込みからリターンする.
+pcへの設定に使用可能な命令には制限があり,以下命令が使用可能である.
+
+ ・POP/LDM, LDR, BX
+
+●未解決課題
+
+・ベクターテーブルに登録する関数のアドレスのLSBは'1'にするべきか?
+・NVICは例外・割込みのネスト回数を内部的に管理しているらしい.
+ (!リファレンスを明らかに).
+ ソフトウェアでは,ネストの帳尻を合わせれば,リターンスタックを偽造し
+ ても問題ないか.
+
+
+○OSの実装
+
+1.ターゲット名
+
+ 1-1 cm3(Cortex-M3)
+ 1-2 armv7m(ARMV7M)
+ 1-3 arm_m
+
+cm3では,Coretex-M1(armv6-m)をサポートする場合に問題となる.armv7mでは,
+armv8mがリリースされた場合に問題となる.ARM依存部はJSPでは,armv4とな
+っていたが,armv5やarmv7も動作するためASPでは単にarmとした.そのため,
+arm_mが無難と考えられる.
+
+
+2.ThreadモードとHandlerモードの使い分け
+
+ 2-1
+ タスクコンテキストはThreadモード,非タスクコンテキストはHandlerモー
+ ドで動作させる.
+
+ 2-2
+ タスクコンテキストと非タスクコンテキスト共にHandlerモードで動作させ
+ る.
+
+プロセッサの設計方針を考慮すると2-1が有力.2-1での問題点としては,割込
+みハンドラからタスクへのリターン時にモードの変更が以下の様に多発するこ
+とが挙げられる.
+
+1.割込みハンドラ : Handlerモード
+2.タスク例外ハンドラの呼び出し : Threadモード
+3.タスクへのリターン処理 : Handlerモード
+4.タスクの再開 : Threadモード
+
+3でHandlerモードに移行する必要があるのは,例外フレームを用いて復帰する
+には,Handlerモードで例外リターン処理を行う必要があるためである.ARMで
+は,複数レジスタのロードとCPSRの復帰を同時に行えるが,M3は行えないため,
+この方法で割込み先のタスクにリターンする必要がある.
+
+2-2の場合の割込みハンドラからタスクへのリターン時にモードの変更を以下
+に示す.また,2-2では割込み優先度の最低値をタスクの実行時の優先度とし
+てリザーブする必要がある.
+
+1.割込みハンドラ : Handlerモード
+2.NVIC優先度マスク'0'を0へ : Threadモード
+3.最低優先度のHandlerモードへ : Handlerモード
+4.タスク例外ハンドラの呼び出し : Handlerモード
+5.タスクへのリターンの前処理 : Threadモード
+3.タスクへのリターン : Handlerモード
+4.タスクの再開 : Handlerモード
+
+割込みハンドラからタスクのリターンに関しては,2-2であっても,2を実行す
+る場合に,NVIC優先度マスクを'0'にするため,例外リターン処理を行う必要
+がある.また,NVIC自体が,割込みのネスト回数を管理しているため,3から4
+への遷移のために,いったん例外/割込みを受付けた状態にする必要があるた
+め,結果的に2-1以上の遷移が必要となる.
+
+2-2の場合は,MSPしか使えないため,割込みの入り口でネスト回数を判断して,
+スタックを入れ替える必要がある.
+
+HRP等でメモリ保護を用いる場合は2-1となる.
+
+以上の理由により,2-1を採用する.ただし2-1は,カーネル起動時とIDLEルー
+プの扱いを検討する必要がある.これらについては別途議論する.
+
+
+3.ディスパッチャの実行モード
+
+ 3-1
+ Threadモードで実行する
+
+ 3-2
+ Handlerモードで実行する
+
+ディスパッチャをThreadモードで実行すると,割込みによりプリエンプトされ
+たタスクに戻る場合は次のようなパスになる.
+
+ 1. ディスパッチャ呼び出し : Threadモード
+ 2. ディスパッチャ実行 : Threadモード
+ 3. タスク例外実行 : Threadモード
+ 4.タスクへのリターン処理 : Handlerモード
+ 5. タスクの再開 : Threadモード
+
+割込みハンドラから自らディスパッチしたタスクへリターンする場合は次のパ
+スになる.
+
+ 1.割込みハンドラ : Handlerモード
+ 2.ディスパッチャ実行 : Threadモード
+ 3.タスク例外ハンドラの呼び出し : Threadモード
+ 4.タスクへのリターン : Handlerモード
+ 5.タスクの再開 : Threadモード
+
+一方,ディスパッチャをHandlerモードで実行すると,割込みによりプリエン
+プトされたタスクに戻る場合は次のようなパスになる.
+
+ 1. ディスパッチャ呼び出し : Threadモード
+ 2. ディスパッチャ実行 : Handlerモード
+ 3. タスク例外実行 : Threadモード
+ 4.タスクへのリターン : Handlerモード
+ 5. タスクの再開 : Threadモード
+
+割込みハンドラの出口から自らディスパッチしたタスクへリターンする場合は
+次のパスになる.
+
+ 1.割込みハンドラ : Handlerモード
+ 2.ディスパッチャ実行 : Handlerモード
+ 3.タスク例外ハンドラの呼び出し : Threadモード
+ 4.タスクへのリターン : Handlerモード
+ 5.タスクの再開 : Threadモード
+
+タスク例外ハンドラがないOSの場合は,Handlerモードで実行した方がモード
+の遷移の回数が減るが,タスク例外ハンドラがあると,Threadモードの方が遷
+移回数が減るため,Threadモードとする.
+
+メモリ保護を考慮すると,ディスパッチャはHandlerモードで動作させた方が
+効率がよいと考えられる(SVCでハンドラを呼び出すとHandlerモードとなるた
+め).
+
+
+4.スタックの使い分け
+
+ 4-1
+ タスクコンテキストをPSP, 非タスクコンテキストをMSP
+ 4-2
+ タスクコンテキスト,非タスクコンテキスト共にMSP
+
+4-2の場合,割込みの入り口でネスト回数を判断して,スタックを入れ替える
+必要がある.2でタスクコンテキストはThreadモード,非タスクコンテキスト
+はHandlerモードで動作させるとしたため,4-1を採用すると,割込みの入り口
+で自動的にスタックが切り替わる.ThreadモードでのPSPのアクセスも,
+mrs/msr命令で行えるため,4-1を採用する.
+
+
+5.コンテキストの判定
+
+ 5-1
+ IPSRが'0'(Threadモード)ならタスクタスクコンテキスト,'1'(Handlerモー
+ ド)なら非タスクコンテキストとする.
+
+ 5-2
+ 割込みのネスト回数を保持する変数を用意.1以上で非タスクコンテキスト.
+
+ 5-3
+ アクティブなスタックにより判断(MSPなら非タスクコンテキスト,PSPなら
+ タスクコンテキストとする)
+
+5-1は,ソフトウェア側でコンテキスト管理のための処理を行う必要がないと
+いうメリットがある.しかしながら,カーネルの起動時Threadモードであるた
+め,Handlerモードへ移行する必要がある.ASPカーネルでは,IDLEループ実行
+は非タスクコンテキストとして動作させる必要があるため,IDLEループは
+Handlerモードで動作させる必要がある.IDLEループはディスパッチャから呼
+び出される.3で定めたように,ディスパッチャをThreadモードで動作させる
+ため,IDLEループを呼び出す際には,Handlerモードへ遷移する必要がある.
+Handlerモードへの遷移は,SVC/PendSVCを用いると実現可能であるが,6の割
+込みにプリエンプトされたタスクへのリターン時のHandlerモードへの移行で
+もSVC/PendSVCの使用が必要となるため,SVCハンドラでは,どの目的で呼び出
+されたか判定する必要が出てくるため,オーバヘッドが増大する.
+
+5-2では,カーネル起動時やIDLEループ時に変数を'1'に設定すればよいことに
+なる.この場合,カーネル起動時やIDLEループ時にThreadモードで実行しても
+動作に問題がないよう,特に割込みの出入り口の設計を注意する必要がある.
+
+カーネル起動時に関しては,全割込みを禁止しており,割込みが入らないので
+特に問題はない.IDLEループ時は,ThreadモードでMSPとPSPの選択が可能であ
+ることを利用して,非タスクコンテキストのスタックであるMSPに変更する.
+例外/割込みの入り口では,多重割込みであるかをEXC_RETURNのモード判定の
+ビットではなく,スタックの判定ビットで行えば問題ない.例外/割込みから
+のリターンに関しては,多重割込みの判定は,入り口と同様にEXC_RETURNのス
+タック判定ビットで行えばよい.例外リターン処理時にpcに代入する
+EXC_RETURNの値を一律0xfffffffd (Threadモード with MSP)とするのではなく,
+例外/割込み受付け時にLRに設定されるEXC_RETURNを用いることにより,IDLE
+ループに割り込んだ場合でも問題なくリターンする.
+
+カーネル起動時は,MSPがアクティブであり,割込みハンドラ実行時はHandler
+モードであることからMSPがアクティブでり,IDLEループ時にMSPをアクティブ
+に設定すると,非タスクコンテキストは全て,MSPをアクティブにして動作す
+ることになる.また,割込み時は割込み前にアクティブなスタックの情報が,
+EXC_RETURNに設定される.そのため,コンテキストの判定は,割込みネスト回
+数を保持する変数がなくとも,アクティブなスタックを見ればよいことになる.
+また,exc_sense_context()に関しては,例外フレーム中にEXC_RETURNを追加
+し,その内容により判断すればよい.以上の理由により,5-3を採用する.
+
+
+6.割込みにプリエンプトされたタスクへのリターン時のHandlerモードへの移
+ 行方法
+
+ 6-1
+ SVCを用いる
+ 6-2
+ PendSVCを用いる
+
+PendSVCとSVCの違いは,PendSVCが要求がキューイングされ,SVCは要求がキュ
+ーイングされないことである.割込みにプリエンプトされたタスクへのリター
+ン時のHandlerモードへの移行は,キューイングされずに即座に処理される必
+要があるため,どちらで実現しても問題ない.どちらをカーネルのリソースし
+て使用するかの選択だけである.
+
+どちらを使うとしても,優先度の設定が問題となる.ディスパッチャから割込
+みにプリエンプトされたタスクへのリターンまでの処理は,少なくともCPUロ
+ック状態で実行されなければならない.SVCやPendSVCはどちらも割込み優先度
+を持つため,NVIC優先度マスクよりBASEPRI優先度マスクの方が高い場合,処
+理されない.
+
+CPUロック状態をBASEPRIの設定で実現した場合,その設定値をSVCやPendSVCに
+設定した値より低くする必要がある.言い換えると,SVCやPendSVCの優先度を
+CPUロック時の優先度マスクの値より高い値(他の割込みより高い優先度)と
+する必要がある.
+
+CPUロック状態をFAULTMASKやPRIMASKで実現した場合は,これらが設定される
+と,SVCやPendSVCが受付けられないため,いったんBASEPRIにより割込みをマ
+スクするように設定する必要がある.この場合も,SVCやPendSVCは他の割込み
+より高い優先度を設定する必要がある.
+
+以上により,Handlerモードへの移行のためには,CPUロック状態をBASEPRIで
+実現し,SVCやPendSVCに設定する優先度をカーネル管理内の最高優先度より一
+つ高い優先度に設定する必要がある.
+
+
+7. 例外/割込み出入り口での多重割込みの判断
+
+7-1
+ EXC_RETURNのモード判定ビット
+7-2
+ EXC_RETURNのスタック判定ビット
+7-3
+ 割込みネスト回数の管理変数
+
+例外/割込み受付け時は,受付けた例外/割込み以下の割込みは禁止するが,全
+割込み禁止状態にはならない.そのため,割込みネスト回数の管理変数をイン
+クリメントする前に割込みが入る可能性があるため,7-3は使用することがで
+きない.
+
+5で議論した通り,IDLEループをThreadモードで実行するため,7-1ではなく,
+7-2で判断する必要がある.
+
+
+8. IDLEループ
+
+8-1
+ Threadモードで実行
+8-2
+ Handlerモードで実行
+
+5で議論した通り,Threadモードで実行できた方がオーバヘッドが小さい.ま
+た,Threadモードで実行しても,割り込みの出入り口で正しく非タスクコンテ
+キストと判定できれば,Threadモードで問題ない.
+
+
+9.カーネル管理外の割込みのサポート
+
+9-1
+ カーネル管理外の割込みをサポートしない
+9-2
+ カーネル管理外の割込みをサポートする
+
+ベクタテーブルをサポートしており,割込みハンドラもC言語で記述可能であ
+るため,サポートが容易であるため,サポートする.
+
+
+10. CPUロック
+
+10-1
+ BASEPRIを使用
+10-2
+ FAULTMASK/PRIMASKを使用
+
+カーネルの管理外の割込みをサポートするなら,BASEPRIを使用する必要があ
+る.
+
+
+11. 割込みロックとCPU例外の関係
+
+11-1
+ BASEPRIを使用
+11-2
+ FAULTMASK/PRIMASKを使用
+
+FAULTMASK/PRIMASKを使用すると,NMI と Hardware Fault 以外のCPU例外も禁
+止されてしまう.
+
+BASEPRIを用いると,割込みロック中にもCPU例外を受付けたい場合は,
+BASEPRIを用いて,最高優先度をCPU例外のためにリザーブする必要がある.
+
+割込みロック時も,CPU例外を受付けるようにしたければBASEPRIを使用する必
+要がある.
+
+μIRON4.0仕様の3.5.3では,CPU例外の優先度は次のように定められている.
+
+"CPU例外ハンドラの優先順位は,CPU例外が発生した処理の優先度と,ディス
+パッチャの優先順位のいずれかよりも高い."
+
+CPU例外が発生した処理の優先度よりも高いとあるので,CPUロックや割込みロ
+ック状態のタスクで発生した場合でも,優先して実行されるべきだとも考えら
+れる.
+
+一方,TOPPERS標準割込み処理モデルの仕様書では,CPU例外は,プロセッサ毎
+に異なるため,CPU例外の処理モデルの標準化検討の対象外としている.その
+ため,ARM-Mでの扱いを決めて,マニュアルに明記すればよいと考えられる.
+
+
+12. 外部優先度と内部優先度の変換
+
+外部優先度とはAPIで指定する割込み優先度(PRI型)のことであり,値が小さい
+ほど優先度が高い.割込みハンドラには,-1から連続した負の値を設定可能で
+ある.内部優先度は,BASEPRIやNVICの優先度レジスタに設定する値である.
+
+実装される割込み優先度のビット幅を TBITW_IPRI とすると,設定可能な外部
+優先度は次のようになる.
+
+ TIPM_ENAALL(=0)〜 -(1 << TBITW_IPRI)
+
+
+13. カーネル管理内の最高優先度(CPUロック状態での優先度マスク)
+
+6.で述べたように,割込みの出口でSVCハンドラを呼び出す必要があるため,
+SVCハンドラはCPUロック状態のBASEPRIに設定する優先度マスクより高い優先度
+を設定する必要がある.
+
+実装される割込み優先度のビット幅を TBITW_IPRI,優先度中のサブ優先度の
+ビット幅をTBIT_IPRIとすると,CPUロック状態(カーネル管理内割込みに設定
+可能な最高優先度)として指定可能な優先度マスクの設定範囲は以下の値の範
+囲となる.
+
+ -(2^(TBIW_IPRI)) + (2^TBITW_SUBIPRI)) 〜 -1
+
+
+14. 未解決課題
+
+・割込みロックとCPU例外の関係
+ BASEPRIを使ったとしても,あるCPU例外処理中に他の例外が発生すると,そ
+ の例外は受け付けられないため,ITRON仕様は満たせない.
+ ->あきらめてマニュアル記載に逃げるか.
+ メモリプロテクションの例外もマスク可能であるため要件等.
+
+
+以上.
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: prc_insn.h 1304 2008-08-27 07:28:36Z ertl-honda $
+ */
+
+
+/*
+ * コア依存の特殊命令のインライン関数定義(ARM-M用)
+ */
+
+#ifndef CORE_INSN_H
+#define CORE_INSN_H
+
+#include <arm_m.h>
+
+/*
+ * FAULTMASKのセット
+ */
+Inline void
+set_faultmask(void){
+ Asm("cpsid f":::"memory");
+}
+
+/*
+ * FAULTMASKのクリア
+ */
+Inline void
+clear_faultmask(void){
+ Asm("cpsie f":::"memory");
+}
+
+/*
+ * PRIMASKのセット
+ */
+Inline void
+set_primask(void){
+ Asm("cpsid i":::"memory");
+}
+
+/*
+ * PRIMASKのクリア
+ */
+Inline void
+clear_primask(void){
+ Asm("cpsie i":::"memory");
+}
+
+/*
+ * BASEPRIのセット
+ */
+Inline void
+set_basepri(uint32_t val){
+ Asm("msr BASEPRI, %0" : : "r"(val) : "memory");
+}
+
+/*
+ * BASEPRIの取得
+ */
+Inline uint32_t
+get_basepri(void){
+ uint32_t val;
+ Asm("mrs %0, BASEPRI" : "=r"(val));
+ return(val);
+}
+
+/*
+ * CONTROLのセット
+ */
+Inline void
+set_control(uint32_t val){
+ Asm("msr control, %0 \n"
+ " isb"
+ : : "r"(val) : "memory");
+}
+
+/*
+ * CONTROLの取得
+ */
+Inline uint32_t
+get_control(void){
+ uint32_t val;
+ Asm("mrs %0, CONTROL" : "=r"(val));
+ return(val);
+}
+
+/*
+ * ステータスレジスタ(CPSR)の現在値の読出し
+ */
+Inline uint32_t
+get_ipsr(void)
+{
+ uint32_t sr;
+ Asm("mrs %0, ipsr" : "=r"(sr));
+ return(sr);
+}
+
+#endif /* CORE_INSN_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: prc_kernel.h 1304 2008-08-27 07:28:36Z ertl-honda $
+ */
+
+/*
+ * kernel.hのプロセッサ依存部(ARM-M用)
+ *
+ * このインクルードファイルは,target_kernel.h(または,そこからインク
+ * ルードされるファイル)のみからインクルードされる.他のファイルから
+ * 直接インクルードしてはならない.
+ */
+
+#ifndef TOPPERS_PRC_KERNEL_H
+#define TOPPERS_PRC_KERNEL_H
+
+/*
+ * サポートする機能の定義
+ */
+#define TOPPERS_SUPPORT_DIS_INT /* dis_intをサポートする */
+#define TOPPERS_SUPPORT_ENA_INT /* ena_intをサポートする */
+
+#define TMAX_INTPRI (-1) /* 割込み優先度の最大値(最低値)*/
+
+#ifndef TOPPERS_MACRO_ONLY
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#endif /* TOPPERS_PRC_KERNEL_H */
--- /dev/null
+# prc_config.c
+exc_tbl
+vector_table
+lock_flag
+saved_iipm
+default_exc_handler
+default_int_handler
+x_config_int
+prc_initialize
+prc_terminate
+bitpat_cfgint
+
+# prc_support.S
+int_entry
+exc_entry
+ret_int
+ret_exc
+svc_handler
+start_r
--- /dev/null
+/* This file is generated from prc_rename.def by genrename. */
+
+#ifndef TOPPERS_PRC_RENAME_H
+#define TOPPERS_PRC_RENAME_H
+
+/*
+ * prc_config.c
+ */
+#define exc_tbl _kernel_exc_tbl
+#define vector_table _kernel_vector_table
+#define lock_flag _kernel_lock_flag
+#define saved_iipm _kernel_saved_iipm
+#define default_exc_handler _kernel_default_exc_handler
+#define default_int_handler _kernel_default_int_handler
+#define x_config_int _kernel_x_config_int
+#define prc_initialize _kernel_prc_initialize
+#define prc_terminate _kernel_prc_terminate
+#define bitpat_cfgint _kernel_bitpat_cfgint
+
+/*
+ * prc_support.S
+ */
+#define int_entry _kernel_int_entry
+#define exc_entry _kernel_exc_entry
+#define ret_int _kernel_ret_int
+#define ret_exc _kernel_ret_exc
+#define svc_handler _kernel_svc_handler
+#define start_r _kernel_start_r
+
+#ifdef TOPPERS_LABEL_ASM
+
+/*
+ * prc_config.c
+ */
+#define _exc_tbl __kernel_exc_tbl
+#define _vector_table __kernel_vector_table
+#define _lock_flag __kernel_lock_flag
+#define _saved_iipm __kernel_saved_iipm
+#define _default_exc_handler __kernel_default_exc_handler
+#define _default_int_handler __kernel_default_int_handler
+#define _x_config_int __kernel_x_config_int
+#define _prc_initialize __kernel_prc_initialize
+#define _prc_terminate __kernel_prc_terminate
+#define _bitpat_cfgint __kernel_bitpat_cfgint
+
+/*
+ * prc_support.S
+ */
+#define _int_entry __kernel_int_entry
+#define _exc_entry __kernel_exc_entry
+#define _ret_int __kernel_ret_int
+#define _ret_exc __kernel_ret_exc
+#define _svc_handler __kernel_svc_handler
+#define _start_r __kernel_start_r
+
+#endif /* TOPPERS_LABEL_ASM */
+
+
+#endif /* TOPPERS_PRC_RENAME_H */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: prc_sil.h 1304 2008-08-27 07:28:36Z ertl-honda $
+ */
+
+/*
+ * sil.hのプロセッサ依存部(ARM-M用)
+ */
+
+#ifndef TOPPERS_PRC_SIL_H
+#define TOPPERS_PRC_SIL_H
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ * NMIを除くすべての割込みの禁止
+ */
+Inline bool_t
+TOPPERS_disint(void)
+{
+ uint32_t val;
+
+ Asm("mrs %0, FAULTMASK" : "=r"(val));
+ Asm("cpsid f":::"memory");
+
+ if (val == 1) {
+ return (true);
+ }
+ else {
+ return (false);
+ }
+}
+
+Inline void
+TOPPERS_enaint(bool_t locked)
+{
+ if (!locked) {
+ Asm("cpsie f":::"memory");
+ }
+}
+
+/*
+ * 全割込みロック状態の制御
+ */
+#define SIL_PRE_LOC bool_t TOPPERS_locked
+#define SIL_LOC_INT() ((void)(TOPPERS_locked = TOPPERS_disint()))
+#define SIL_UNL_INT() (TOPPERS_enaint(TOPPERS_locked))
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#endif /* TOPPERS_PRC_SIL_H */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: prc_stddef.h 1304 2008-08-27 07:28:36Z ertl-honda $
+ */
+
+/*
+ * t_stddef.hのプロセッサ依存部(ARM-M用)
+ *
+ * このインクルードファイルは,target_stddef.h(または,そこからインク
+ * ルードされるファイル)のみからインクルードされる.他のファイルから
+ * 直接インクルードしてはならない.
+ */
+
+#ifndef TOPPERS_PRC_STDDEF_H
+#define TOPPERS_PRC_STDDEF_H
+
+/*
+ * ターゲットを識別するためのマクロの定義
+ */
+#define TOPPERS_ARM_M /* プロセッサ略称 */
+
+/*
+ * スタックの型
+ * ARMでは,スタックを8byte境界に配置する必要がある
+ */
+#define TOPPERS_STK_T long long
+
+#endif /* TOPPERS_PRC_STDDEF_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: prc_support.S 1365 2008-09-28 07:23:15Z futl-takaki $
+ */
+
+/*
+ * プロセッサ依存モジュール アセンブリ言語部(ARM-M用)
+ */
+
+#define TOPPERS_MACRO_ONLY
+#define UINT_C(val) (val) /* uint_t型の定数を作るマクロ */
+#define ULONG_C(val) (val) /* ulong_t型の定数を作るマクロ */
+#define CAST(type, val) (val) /* 型キャストを行うマクロ */
+
+#include "kernel_impl.h"
+#include "arm_m.h"
+#include "offset.h"
+
+
+/*
+ * タスクディスパッチャ
+ */
+ .text
+ .syntax unified
+ .code 16
+ .global dispatch
+ .type dispatch, function
+dispatch:
+ /*
+ *
+ * このルーチンは,タスクコンテキスト・CPUロック状態・ディパッチ許可状態
+ * ・(モデル上の)割込み優先度マスク全開状態で呼び出される.
+ */
+ stmfd sp!,{r4-r11,lr} /* レジスタの保存 */
+ ldr r0, =p_runtsk /* p_runtskを読み込む */
+ ldr r1, [r0]
+ str sp, [r1,#TCB_sp] /* タスクスタックを保存 */
+ ldr lr, =dispatch_r /* 実行再開番地を保存 */
+ str lr, [r1,#TCB_pc]
+ b dispatcher
+
+ .text
+ .syntax unified
+ .code 16
+ .type dispatch_r, function
+dispatch_r:
+ ldmfd sp!,{r4 - r11,lr} /* レジスタの復帰 */
+ /*
+ * タスク例外処理ルーチンの起動
+ * dispatcherから呼び出されるため,TCBのアドレスはr1に入っている
+ */
+ ldrb r0,[r1,#TCB_enatex]
+ tst r0,#TCB_enatex_mask
+ beq dispatch_r_1 /* enatex が false ならリターン */
+ ldr r0,[r1,#TCB_texptn] /* texptn が0でなければ */
+ tst r0,r0
+ bne call_texrtn /* タスク例外ルーチンの呼び出し */
+dispatch_r_1: /* タスクへのcall_textnから戻る */
+ mov pc,lr
+
+
+/*
+ * CPU例外エントリ
+ *
+ * 割込みエントリと処理の内容は同等だが,ログの種類が異なるため,
+ * 分けている.
+ */
+ .align 2
+ .syntax unified
+ .code 16
+ .global exc_entry
+ .type exc_entry, function
+exc_entry:
+ /*
+ * 例外/割込みが発生すると,発生時にアクティブなスタックにスクラ
+ * ッチレジスタ等が保存される.
+ * この内容に加えて,CPU例外ハンドラへの情報として,basepri の値と,
+ * EXC_RETURNの情報を加えて保存する.basepriの値は,CPU例外からの
+ * リターン時に割込み優先度マスクの値を元に戻すためにも用いられる.
+ *
+ * -----------
+ * | EXC_RETURN|
+ * -----------
+ * | basepri |
+ * -----------
+ * | R0 |
+ * -----------
+ * | R1 |
+ * -----------
+ * | R2 |
+ * -----------
+ * | R3 |
+ * -----------
+ * | R12 |
+ * -----------
+ * | LR |
+ * -----------
+ * | PC |
+ * -----------
+ * | xPSR |
+ * -----------
+ *
+ */
+
+ /*
+ * 割込み発生時の割込み優先度マスクをスタックに保存するため取得
+ */
+ mrs r2, basepri /* baepriの値を取得 */
+
+ /*
+ * 多重割込みかチェック
+ * EXC_RETURN(割込み時にLRに設定される値)をチェックして,例外発生時に
+ * アクティブなスタックを特定することで多重割込みか判定する.
+ */
+ tst lr, #EXC_RETURN_PSP /* 割込み元がMSPなら多重割込み */
+ beq exc_entry_1 /* 多重割込みならexc_entry_1へ */
+ mrs r0, psp /* 一段目の割込みの場合はPSP上に */
+ stmfd r0!,{r2} /* 割込み発生時の割込み優先度マスクを積む */
+ stmfd r0!,{lr} /* EXC_RETURN を積む */
+ msr psp, r0 /* CPU例外ハンドラへの引数となる */
+ push {lr} /* MSP上にもEXC_RETURN を積む */
+ b exc_entry_2
+exc_entry_1: /* 多重割込みの場合 */
+ push {r2} /* 割込み発生時の割込み優先度マスクを積む */
+ push {lr} /* EXC_RETURN を積む */
+ mov r0, sp /* CPU例外ハンドラへの引数となる */
+
+ /*
+ * 共通処理
+ */
+exc_entry_2:
+ mrs r3, ipsr /* ハンドラアドレスを取得 */
+ ldr r1, =_kernel_exc_tbl
+ ldr r2, [r1, r3, lsl #2]
+
+#ifdef LOG_EXC_ENTER
+ push {r0,r2,r3}
+ mov r0, r3 /* 例外番号をパラメータに */
+ bl log_exc_enter /* log_exc_enterを呼び出す */
+ pop {r0,r2,r3}
+ push {r3} /* 例外番号をスタックへ */
+#endif /* LOG_EXC_ENTER */
+
+ /*
+ * CPU例外ハンドラの呼び出し
+ */
+ blx r2
+
+#ifdef LOG_EXC_ENTER
+ pop {r0} /* 例外番号を引数に */
+ bl log_exc_leave /* log_exc_leaveを呼び出す */
+#endif /* LOG_EXC_ENTER */
+
+ b ret_exc
+
+
+/*
+ * 割込みエントリ
+ */
+ .align 2
+ .syntax unified
+ .code 16
+ .global int_entry
+ .type int_entry, function
+int_entry:
+ /*
+ * 割込み発生時の割込み優先度マスクをスタックに保存するため取得
+ */
+ mrs r2, basepri /* baepriの値を取得 */
+
+ /*
+ * 多重割込みかチェック
+ * EXC_RETURN(割込み時にLRに設定される値)をチェックして,例外発生時に
+ * アクティブなスタックを特定することで多重割込みか判定する.
+ */
+ tst lr, #EXC_RETURN_PSP /* 割込み元がMSPなら多重割込み */
+ beq int_entry_1 /* 多重割込みならint_entry_1へ */
+ mrs r0, psp /* 一段目の割込みの場合はPSP上に */
+ stmfd r0!,{r2} /* 割込み発生時の割込み優先度マスクを積む */
+ stmfd r0!,{lr} /* EXC_RETURN を積む */
+ msr psp, r0 /* CPU例外ハンドラへの引数となる */
+ push {lr} /* MSP上にもEXC_RETURN を積む */
+ b int_entry_2
+int_entry_1: /* 多重割込みの場合 */
+ push {r2} /* 割込み発生時の割込み優先度マスクを積む */
+ push {lr} /* EXC_RETURN を積む */
+ mov r0, sp /* 未定義の割込みが発生した場合の情報とする */
+
+ /*
+ * 共通処理
+ */
+int_entry_2:
+ mrs r3, ipsr /* ハンドラアドレスを取得 */
+ ldr r1, =_kernel_exc_tbl
+ ldr r2, [r1, r3, lsl #2]
+
+#ifdef LOG_EXC_ENTER
+ push {r0,r2,r3}
+ mov r0, r3 /* 例外番号をパラメータに */
+ bl log_inh_enter /* log_exc_enterを呼び出す */
+ pop {r0,r2,r3}
+ push {r3} /* 例外番号をスタックへ */
+#endif /* LOG_EXC_ENTER */
+
+ /*
+ * 割込みハンドラの呼び出し
+ */
+ blx r2
+
+#ifdef LOG_EXC_ENTER
+ pop {r0} /* 例外番号を引数に */
+ bl log_exc_leave /* log_exc_leaveを呼び出す */
+#endif /* LOG_EXC_ENTER */
+
+
+
+/*
+ * 割込み/例外出口
+ *
+ * ret_exc/ret_intは,CPU例外/割込みハンドラから戻った直後に実行する
+ * ルーチンである.
+ */
+ret_exc:
+ret_int:
+ /*
+ * 割込みロック状態とする.この時点では,CPUロック状態にはならない
+ * (basepriとlock_flagとsaved_iipmは更新しない).
+ *
+ * 割込みロック状態とするのは,戻り先のコンテキストのチェックと,
+ * 戻り先が非タスクコンテキストであった場合のリターンをアトミック
+ * に行うためである.bsepriをCPUロックの値にすることでもアトミッ
+ * クなチェックと復帰は可能であるが,割込みからリターンしても,
+ * basepri の設定内容は元に戻らないため,使用することができない.
+ * 一方,FAULTMASKは,割込みからのリターン処理によって,'0'にクリ
+ * アされる.
+ */
+ cpsid f
+
+ /*
+ * 戻り先のコンテキストの判定
+ *
+ * 割込みハンドラ実行にLRにセットされるEXC_RETURNをチェックして,戻り
+ * 先でMSPが使われていれば,割込み先が非タスクコンテキストと判定する.
+ */
+ pop {r3} /* lrをスタックから取得 */
+ tst r3, #EXC_RETURN_PSP /* 戻り先がPSPなら ret_int_1 へ */
+ bne ret_int_1
+ pop {r1} /* 元の割込み優先度マスク(basepri)をr1へ */
+ b ret_int_2 /* の値をMSPから取得 */
+
+ /*
+ * 一段目の割込みの出口処理
+ */
+ret_int_1:
+ /*
+ * PSP上からEXC_RETURNを削除
+ */
+ mrs r2, psp
+ add r2, r2, #4
+ msr psp, r2
+
+ /*
+ * reqflgをチェックする
+ *
+ * カーネル管理内の割込みは禁止した状態で実行する必要があるため,
+ * FAULTMASKを'1'にした状態で実行する.
+ * reqflgをチェックする前に割込みを禁止するのは,reqflgをチェック
+ * した直後に割込みハンドラが起動され,その中でディスパッチが要求
+ * された場合に,すぐにディスパッチされないという問題が生じるため
+ * である.
+ */
+ ldr r0, =reqflg /* reqflgがfalseならそのまま戻る */
+ ldr r1, [r0]
+ cbnz r1, ret_int_3 /* trueならret_int_3へ */
+ mrs r2, psp /* 元の割込み優先度マスク(basepri) */
+ ldmfd r2!, {r1} /* の値をPSPから取得 */
+ msr psp, r2
+
+ret_int_2:
+ /*
+ * ここには割込みロック状態(FAULTMASKがセット)された状態で来る.
+ * Threadモードからのリターンにより自動的に割込みロック解除状態になる.
+ * 割込み優先度マスクは割込み前に状態に戻す.
+ */
+ msr basepri, r1 /* 割込み優先度マスクを割込み前に状態へ */
+ bx r3 /* リターン */
+
+
+ret_int_3:
+ /*
+ * ここでは,戻り先がタスクであり,PSP上にスクラッチレジスタと割
+ * 込み優先度マスク(basepri)が保存された状態になっている.また,
+ * プロセッサは,Handlerモード・割込みロック状態となっている.
+ * また,r0には,reqflgのアドレス,r3には割込み受付時のlrの値が保
+ * 持されている.
+ */
+ mov r1, #0 /* reqflgをfalseに */
+ str r1, [r0]
+
+ /*
+ * CPUロック状態に移行する.
+ *
+ * カーネルの管理内の割込みを禁止するようにbasepriを設定し,
+ * lock_flag と saved_iipm を更新する.saved_iipmは,戻り先の割込み
+ * 優先度マスク(の内部表現)に設定する.
+ * この時点でCPUロック状態とするのは,dispatcherへ分岐する時と,
+ * call_texrtnを呼び出す時に,CPUロック状態になっている必要がある
+ * ためである.
+ * なお,この処理の後,Threadモードへの移行処理を行なうため,割込み
+ * ロック状態(FAULTMASKを"1")は保持する.
+ */
+ ldr r1, =IIPM_LOCK /* CPUロック状態 */
+ msr basepri, r1
+ mov r1, #0x01 /* lock_flag を trueに */
+ ldr r0, =lock_flag
+ str r1, [r0]
+ mrs r2, psp /* 割込み前の割込み優先度マスクを */
+ ldr r1, [r2] /* タスクスタックから取得 */
+ ldr r0, =saved_iipm /* saved_iipmに保存 */
+ str r1, [r0]
+
+ /*
+ * Threadモードへ移行する.
+ *
+ * dispatcherやcall_texrnを呼び出す場合は,Threadモードである必
+ * 要があるため,PSPスタック上にダミーの例外フレームを置いて,
+ * 擬似的に割込みハンドラからリターンする.
+ * リターンと同時にFAULTMASKが自動的にクリアされ,カーネル管理外の
+ * 割込みが許可される.
+ */
+ ldr r0, =ret_int_4 /* PC */
+ ldr r1, =EPSR_T /* xPSR(Tビットが'1'である必要がある) */
+ stmfd r2!, {r0-r1} /* ダミーフレームをスタック上に積む */
+ sub r2, #(EXC_FRAME_SIZE - (4*2)) /* r0-r3,r12,lrの内容は設定する必要がない */
+ msr psp,r2
+ bx r3 /* Threadモードへ移行 */
+
+ret_int_4:
+ /*
+ * 上記の処理により,Threadモードで実行される.
+ * dspflgがfalseである場合と,p_runtskとp_schedtskが同じ場合には,
+ * ディスパッチを行わない.このチェックが必要なのは,タスク例外処
+ * 理ルーチンの呼出しが必要な場合に,ディスパッチが必要なくても,
+ * reqflgをtrueにするためである.
+ */
+ ldr r0, =p_runtsk /* ディスパッチを行わない場合でも,r1にp_runtsk の値(TCB) */
+ ldr r1, [r0] /* が入っている必要があるので,先に読み込む */
+ ldr r0, =dspflg
+ ldr r2, [r0]
+ cbz r2, ret_int_r_1 /* dspflgがfalseならret_int_r_1へ */
+ ldr r0, =p_schedtsk
+ ldr r2, [r0]
+ cmp r1, r2 /* p_runtskとp_schedtskが同じなら */
+ beq ret_int_r_1 /* ret_int_r_1へ */
+ stmfd sp!, {r4-r11} /* 残りのレジスタを保存 */
+ str sp, [r1,#TCB_sp] /* タスクスタックを保存 */
+ ldr lr, =ret_int_r /* 実行再開番地を保存 */
+ str lr, [r1,#TCB_pc]
+ b dispatcher /* ディスパッチャへ */
+
+/*
+ * 割込みによりプリエンプトされたタスクへのリターン処理
+ *
+ * Threadモードで,ディスパッチャや割込みの出口処理から呼び出される.
+ * 割込みによりプリエンプトされたタスクへリターンするには,いったん
+ * Handlerモードに移行し,PCに0xfffffffdを代入してリターンする必要
+ * がある.そのため,SVCにより,SVCハンドラを呼び出し,Handlerモー
+ * ドへ移行する.
+ */
+ .text
+ .syntax unified
+ .code 16
+ .type ret_int_r, function
+ret_int_r:
+ pop {r4-r11} /* レジスタの復帰 */
+ret_int_r_1:
+ /*
+ * enatexがtrueで,texptnが0でなければ,タスク例外処理ルーチンを
+ * 呼び出す.
+ * dispatcherから呼び出されるため,TCBのアドレスはr1に入っている
+ */
+ ldrb r0, [r1,#TCB_enatex]
+ tst r0, #TCB_enatex_mask
+ beq ret_int_r_2 /* enatex が false なら ret_int_r_2へ */
+ ldr r0, [r1,#TCB_texptn] /* texptnをロード */
+ cbz r0, ret_int_r_2 /* '0'ならリターン */
+ bl call_texrtn /* タスク例外ルーチンの呼び出し */
+ret_int_r_2:
+ svc 0 /* SVCの呼び出し */
+
+/*
+ * SVCハンドラ
+ */
+ .text
+ .syntax unified
+ .thumb
+ .thumb_func
+ .global svc_handler
+ .type svc_handler, function
+svc_handler:
+ /*
+ * 割込み処理からのリターンにより,CPUロック解除状態に移行するよ
+ * う準備する.
+ */
+ cpsid f /* 割込みロック状態へ */
+ mrs r0, psp
+ add r0, #EXC_FRAME_SIZE /* スタックを捨てる */
+ msr psp, r0
+ mov r0, #0
+ ldr r1, =lock_flag /* CPUロック解除状態へ */
+ str r0, [r1]
+ mrs r0, psp /* 割込み優先度マスクをタスクスタック */
+ ldmfd r0!, {r1} /* から取得 */
+ msr psp, r0
+ msr basepri, r1 /* 割込み優先度マスクを設定 */
+ bx lr /* リターン */
+
+/*
+ * ディスパッチャの動作開始
+ */
+ .align 2
+ .thumb
+ .thumb_func
+ .globl start_dispatch
+start_dispatch:
+ /*
+ * このルーチンは,カーネル起動時に,すべての割込みを禁止した状態
+ * (割込みロック状態と同等)で呼び出される.また,割込みモード(非
+ * タスクコンテキストと同等)で呼び出されることを想定している.
+ *
+ * prc_initializeで,lock_flagをtrueに,saved_iipmをIIPM_ENAALLに
+ * 初期化しているため,カーネル管理外の割込みを許可することで,
+ * CPUロック状態・(モデル上の)割込み優先度マスク全解除状態になる.
+ * また,task_initializeでdisdspをfalseに初期化しているため,ディ
+ * スパッチ許可状態になっている.
+ */
+ ldr r0,=istkpt /* MSPを初期化 */
+ ldr r1,[r0] /* start_dispatch呼び出し時に呼び出し用に */
+ msr msp, r1 /* 使用しているため初期化する */
+ ldr r1, =IIPM_LOCK /* カーネル管理内の割込みを禁止 */
+ msr basepri, r1
+ cpsie f /* カーネル管理外の割込みを許可 */
+ mov r0, #CONTROL_PSP /* PSPを有効に */
+ msr control, r0
+ isb /* control の操作後に必要 */
+
+/*
+ * 現在のコンテキストを捨ててディスパッチ
+ */
+ .align 2
+ .thumb
+ .thumb_func
+ .globl exit_and_dispatch
+exit_and_dispatch:
+ /* ディスパッチャ本体(dispatcher)へ */
+
+
+/*
+ * ディスパッチャ本体
+ */
+dispatcher:
+ /*
+ * このルーチンは,タスクコンテキスト・CPUロック状態・ディスパッチ
+ * 許可状態・(モデル上の)割込み優先度マスク全解除状態で呼び出さ
+ * れる.
+ *
+ * すなわち,Threadモード・lock_flagがtrue・disdspがfalse・dspflg
+ * がtrue・saved_iipmがIIPM_ENAALLとなっている.実行再開番地へもこ
+ * の状態のまま分岐する.
+ */
+#ifdef LOG_DSP_ENTER
+ ldr r1, =p_runtsk /* p_runtskをパラメータに */
+ ldr r0, [r1]
+ bl log_dsp_enter
+#endif /* LOG_DSP_ENTER */
+dispatcher_0:
+ ldr r0, =p_schedtsk /* p_schedtskをp_runtskに */
+ ldr r1, [r0]
+ ldr r2, =p_runtsk
+ str r1, [r2]
+ cmp r1, #0 /* p_runtskがNULLならdispatcher_1へ */
+ beq dispatcher_1
+ ldr sp, [r1,#TCB_sp] /* タスクスタックを復帰 */
+#ifdef LOG_DSP_LEAVE
+ mov r0, r1 /* p_runtskをパラメータに */
+ mov r4, r1 /* r1はスクラッチレジスタなので保存 */
+ bl log_dsp_leave
+ mov r1, r4
+#endif /* LOG_DSP_LEAVE */
+ ldr pc, [r1,#TCB_pc] /* 実行再開番地を復帰 */
+dispatcher_1:
+ /*
+ * CPUロック状態の解除と,非タスクコンテキスト実行状態への
+ * 準備をする
+ */
+ mov r0, #CONTROL_MSP /* MSPを有効に */
+ msr control, r0
+ isb /* control の操作後に必要 */
+ ldr r2, =reqflg /* r2 <- reqflg */
+ ldr r1, =IIPM_LOCK /* 割込みロック状態の割込み優先度マスクの値 */
+ mov r0, #0
+ ldr r4, =lock_flag /* CPUロック解除状態へ */
+ str r0, [r4]
+dispatcher_2:
+ /*
+ * 割込みを許可し,非タスクコンテキスト実行状態とし割込みを待つ.
+ *
+ * ここで非タスクコンテキスト実行状態に切り換えるのは,ここで発生
+ * する割込み処理にどのスタックを使うかという問題の解決と,割込み
+ * ハンドラ内でのタスクディスパッチの防止という2つの意味がある.
+ *
+ * プロセッサを割込み待ちに移行させる処理と,割込み許可とは,不可
+ * 分に行なう必要がある.
+ * これを不可分に行なわない場合,割込みを許可した直後に割込
+ * みが入り,その中でタスクが実行可能状態になると,実行すべきタス
+ * クがあるにもかかわらずプロセッサが割込み待ちになってしまう.
+ * ARM-Mでは,PRIMASKをセットした状態でWFIを呼び出すことで実現できる.
+ * この状態で割込みが入ると,割込みは実行されず,WFIからリターンす
+ * ることになるので,一旦割込みを許可して割込みハンドラを実行する.
+ *
+ * 割込み待ちの間は,p_runtskをNULL(=0)に設定しなければならな
+ * い.このように設定しないと,割込みハンドラからiget_tidを呼び出
+ * した際の動作が仕様に合致しなくなる.
+ *
+ */
+#ifdef TOPPERS_CUSTOM_IDEL
+ toppers_asm_custom_idle
+#else
+ cpsid i /* PRIMASK をセット */
+ msr basepri, r0 /* 全割込み許可 */
+ wfi
+ cpsie i /* PRIMASK をクリア(割込みを受け付ける) */
+ msr basepri, r1 /* CPUロック状態へ */
+#endif /* TOPPERS_CUSTOM_IDLE */
+
+ ldr r6, [r2] /* reqflgがfalseならdispatcher_2へ */
+ cmp r6, #0
+ beq dispatcher_2
+ str r0, [r2] /* reqflgをfalseに */
+
+ /*
+ * CPUロック状態に戻す.割込み待ちの間に実行した割込みハンドラによ
+ * り,saved_iipmが書き換えられる可能性があるため,元の値に戻す必
+ * 要がある.dispatcherが実行される時は,saved_iipmがIIPM_ENAALL
+ * となっているため,ここではsaved_iipmをIIPM_ENAALL(=0)に戻せ
+ * ばよい.
+ */
+ mov r0, #CONTROL_PSP /* PSPを有効に */
+ msr control, r0
+ isb /* control の操作後に必要 */
+ mov r2, #1 /* lock_flagをtrueへ */
+ ldr r4, =lock_flag
+ str r2, [r4]
+ ldr r4, =saved_iipm /* saved_iipm を0に */
+ mov r0, #0
+ str r0, [r4]
+ b dispatcher_0
+
+
+/*
+ * カーネルの終了処理の呼出し
+ *
+ * スタックを非タスクコンテキスト用に切り替え.
+ *
+ */
+ .text
+ .syntax unified
+ .code 16
+ .globl call_exit_kernel
+ .type call_exit_kernel, function
+call_exit_kernel:
+ mov r0, #CONTROL_MSP
+ msr control, r0 /* MSPを有効に */
+ isb /* control の操作後に必要 */
+ b exit_kernel /* カーネルの終了処理を呼ぶ */
+
+
+/*
+ * タスク起動処理
+ *
+ * dispatcherから呼び出されるため,TCBのアドレスはr1に入っている
+ *
+ */
+ .text
+ .syntax unified
+ .code 16
+ .global start_r
+ .type start_r, function
+start_r:
+ mov r0, #0
+ ldr r4, =lock_flag /* CPUロック解除状態へ */
+ str r0, [r4]
+ msr basepri, r0 /* 割込み許可 */
+ ldr lr, =ext_tsk /* 戻り番地設定 */
+ ldr r2, [r1, #TCB_p_tinib] /* p_runtsk->p_tinibをr2に */
+ ldr r0, [r2, #TINIB_exinf] /* exinfを引数レジスタr0に */
+ ldr r1, [r2, #TINIB_task] /* タスク起動番地にジャンプ */
+ mov pc, r1
+
+/*
+ * 微少時間待ち
+ */
+ .text
+ .syntax unified
+ .code 16
+ .globl sil_dly_nse
+ .type sil_dly_nse, function
+sil_dly_nse:
+ sub r0, r0, #SIL_DLY_TIM1
+ cmp r0, #0
+ bgt sil_dly_nse1
+ mov pc, lr
+sil_dly_nse1:
+ sub r0, r0, #SIL_DLY_TIM2
+ cmp r0, #0
+ bgt sil_dly_nse1
+ mov pc, lr
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: prc_test.h 1304 2008-08-27 07:28:36Z ertl-honda $
+ */
+
+/*
+ * テストプログラムのチップ依存定義(ARM-M用)
+ */
+
+#ifndef TOPPERS_CHIP_TEST_H
+#define TOPPERS_CHIP_TEST_H
+
+/*
+ * チップで共通な定義
+ */
+#define CPUEXC1 6 /* Usage Fault */
+#define RAISE_CPU_EXCEPTION Asm("mcr p15, 0, r1, c2, c0, 0");
+#define CANNOT_RETURN_CPUEXC
+
+#endif /* TOPPERS_CHIP_TEST_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: prc_timer.c 1304 2008-08-27 07:28:36Z ertl-honda $
+ */
+
+/*
+ * タイマドライバ(SYSTIC用)
+ */
+#include <sil.h>
+#include "kernel_impl.h"
+#include "time_event.h"
+#include "target_timer.h"
+
+/*
+ * タイマの起動処理
+ */
+void
+target_timer_initialize(intptr_t exinf)
+{
+ CLOCK cyc;
+ uint32_t tmp;
+
+#ifdef SYSTIC_USE_CALIBRATION
+ /* CALIBRATIONレジスタの値を使用 */
+ cyc = (sil_rew_mem((void *)SYSTIC_CALIBRATION) & SYSTIC_TENMS) / 10;
+#else
+ cyc = TO_CLOCK(TIC_NUME, TIC_DENO) - 1;
+#endif /* SYSTIC_USE_CALIBRATION */
+
+ /* 停止 */
+ tmp = sil_rew_mem((void *)SYSTIC_CONTROL_STATUS);
+ tmp &= ~SYSTIC_ENABLE;
+ sil_wrw_mem((void *)SYSTIC_CONTROL_STATUS, tmp);
+
+ sil_wrw_mem((void *)SYSTIC_RELOAD_VALUE, cyc);
+ sil_wrw_mem((void *)SYSTIC_CURRENT_VALUE, cyc);
+
+ tmp = sil_rew_mem((void *)SYSTIC_CONTROL_STATUS);
+
+#ifdef SYSTIC_USE_STCLK
+ /* 外部クロックの使用 */
+ tmp |= SYSTIC_ENABLE;
+#else
+ /* プロセッサクロックの使用 */
+ tmp |= SYSTIC_ENABLE|SYSTIC_CLKSOURCE;
+#endif /* SYSTIC_USE_STCLK */
+
+ sil_wrw_mem((void *)SYSTIC_CONTROL_STATUS, tmp);
+}
+
+/*
+ * タイマの停止処理
+ */
+void
+target_timer_terminate(intptr_t exinf)
+{
+ /* タイマを停止 */
+ sil_wrw_mem((void*)SYSTIC_CONTROL_STATUS, 0x00);
+}
+
+/*
+ * タイマ割込みハンドラ
+ */
+void
+target_timer_handler(void)
+{
+ unsigned int tmp;
+
+ /* probe_int のため,COUNTFLAGをクリア */
+ tmp = sil_rew_mem((void *)SYSTIC_CONTROL_STATUS);
+
+ i_begin_int(INTNO_TIMER);
+ signal_time(); /* タイムティックの供給 */
+ i_end_int(INTNO_TIMER);
+}
--- /dev/null
+/*
+ * @(#) $Id: prc_timer.cfg 1304 2008-08-27 07:28:36Z ertl-honda $
+ */
+
+/*
+ * タイマドライバのコンフィギュレーションファイル
+ */
+ATT_INI({ TA_NULL, 0, target_timer_initialize });
+ATT_TER({ TA_NULL, 0, target_timer_terminate });
+DEF_INH(INHNO_TIMER, { TA_NULL, target_timer_handler });
+CFG_INT(INTNO_TIMER, { TA_ENAINT|INTATR_TIMER, INTPRI_TIMER });
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: prc_timer.h 1304 2008-08-27 07:28:36Z ertl-honda $
+ */
+
+/*
+ * タイマドライバ(SYSTIC用)
+ */
+
+#ifndef TOPPERS_PRC_TIMER_H
+#define TOPPERS_PRC_TIMER_H
+
+#include <sil.h>
+
+/*
+ * タイマ割込みハンドラ登録のための定数
+ */
+#define INHNO_TIMER IRQNO_SYSTICK /* 割込みハンドラ番号 */
+#define INTNO_TIMER IRQNO_SYSTICK /* 割込み番号 */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ * タイマ値の内部表現の型
+ */
+typedef uint32_t CLOCK;
+
+/*
+ * タイマ値の内部表現とミリ秒・μ秒単位との変換
+ *
+ */
+#define TO_CLOCK(nume, deno) ((CLOCK)(TIMER_CLOCK * (nume) / (deno)))
+#define TO_USEC(clock) (((SYSUTM) clock) * 1000U / TIMER_CLOCK)
+
+/*
+ * 設定できる最大のタイマ周期(単位は内部表現)
+ */
+#define MAX_CLOCK ((CLOCK) 0x00ffffffU)
+
+/*
+ * タイマの起動処理
+ *
+ * タイマを初期化し,周期的なタイマ割込み要求を発生させる.
+ */
+extern void target_timer_initialize(intptr_t exinf);
+
+/*
+ * タイマの停止処理
+ *
+ * タイマの動作を停止させる.
+ */
+extern void target_timer_terminate(intptr_t exinf);
+
+/*
+ * タイマの現在値の読出し
+ */
+Inline CLOCK
+target_timer_get_current(void)
+{
+ return(TO_CLOCK(TIC_NUME, TIC_DENO) - sil_rew_mem((void*)SYSTIC_CURRENT_VALUE));
+}
+
+/*
+ * タイマ割込み要求のチェック
+ */
+Inline bool_t
+target_timer_probe_int(void)
+{
+ return((sil_rew_mem((void*)SYSTIC_CONTROL_STATUS) & SYSTIC_COUNTFLAG) == SYSTIC_COUNTFLAG);
+}
+
+/*
+ * タイマ割込みハンドラ
+ */
+extern void target_timer_handler(void);
+
+#endif /* TOPPERS_MACRO_ONLY */
+#endif /* TOPPERS_PRC_TIMER_H */
--- /dev/null
+/* This file is generated from prc_rename.def by genrename. */
+
+/* This file is included only when prc_rename.h has been included. */
+#ifdef TOPPERS_PRC_RENAME_H
+#undef TOPPERS_PRC_RENAME_H
+
+/*
+ * prc_config.c
+ */
+#undef exc_tbl
+#undef vector_table
+#undef lock_flag
+#undef saved_iipm
+#undef default_exc_handler
+#undef default_int_handler
+#undef x_config_int
+#undef prc_initialize
+#undef prc_terminate
+#undef bitpat_cfgint
+
+/*
+ * prc_support.S
+ */
+#undef int_entry
+#undef exc_entry
+#undef ret_int
+#undef ret_exc
+#undef svc_handler
+#undef start_r
+
+#ifdef TOPPERS_LABEL_ASM
+
+/*
+ * prc_config.c
+ */
+#undef _exc_tbl
+#undef _vector_table
+#undef _lock_flag
+#undef _saved_iipm
+#undef _default_exc_handler
+#undef _default_int_handler
+#undef _x_config_int
+#undef _prc_initialize
+#undef _prc_terminate
+#undef _bitpat_cfgint
+
+/*
+ * prc_support.S
+ */
+#undef _int_entry
+#undef _exc_entry
+#undef _ret_int
+#undef _ret_exc
+#undef _svc_handler
+#undef _start_r
+
+#endif /* TOPPERS_LABEL_ASM */
+
+
+#endif /* TOPPERS_PRC_RENAME_H */
--- /dev/null
+=====================================================================
+ ARM-Mプロセッサ依存部
+ Last Modified: 23 Aug 2008 22:04:49
+=====================================================================
+
+Ver 1.6.0以降の変更に関しては、prc_user_annex.txtを参照。
+
+(1) 対応しているターゲットシステムの種類・構成
+
+ARM-M依存部は,ARMVx-Mアーキテクチャをターゲットとしている.ARMVx-Mは,
+ARMとは異なり,ARM命令を実行できないため,ARM依存部と分けている.
+
+
+(2) 使用する開発環境と動作検証した条件(バージョン,オプション等)
+
+カーネルはGCCを用いてコンパイルする.動作確認したバージョンは各ターゲ
+ット依存部のドキュメントに記載する.
+
+
+(3) ターゲット定義事項の規定
+
+(3-1) データ型に関する規定
+
+データ型は arch/gcc/tool_stddef.h で定義されている内容で,float型と
+double型は,それぞれIEEE754準拠の単精度浮動小数点数と倍精度浮動小数点
+数である.
+
+(3-2) 割込み処理に関する規定
+
+○割込みハンドラ番号と割込み番号の割当て,両者の対応
+
+割込みハンドラ番号と割込み番号は,例外発生時にIPSRにセットされる例外番
+号を用いる.SYSTICKは15番で,外部割込みは16番からの番号が割り付けられ
+ている.
+
+○割込み優先度の段階数(TMIN_INTPRIの値),その設定方法
+
+割込み優先度の段階数は,SoC毎にハードウェア的にサポートする割込み優先
+度ビット幅が異なるので,ターゲット依存部毎に異なる.ターゲット依存部で
+は,割込み優先度のビット幅(TBITW_IPRI)とその割込み優先度中のサブ優先
+度のビット幅(TBITW_SUBPRI)を定義する.各ビット幅の値と設定可能な優先
+度の範囲は次の通りである.
+
+ -(2^(TBIW_IPRI)) + (2^TBITW_SUBIPRI)) 〜 -1
+
+例えば優先度のビット幅(TBITW_IPRI)が8bit,サブ優先度のビット幅
+(TBITW_SUBIPRI) が1bitの場合は,-254 〜 -1 の範囲である.
+
+この範囲で,カーネル管理内の割込みの最高優先度(TMIN_INTPRI)をターゲ
+ット依存部で設定する.
+
+各割込みの割込み優先度は,CFG_INTでTMIN_INTPRI以上の値を指定する.
+
+○dis_intとena_intのサポートの有無,その制限事項
+
+dis_intとena_intをサポートする.制限事項は特にない.
+
+○CFG_INTの制限事項と拡張(ターゲット定義で使用できる割込み属性)
+
+CFG_INTの制限事項はなく,ターゲット定義で使用可能な割込み属性は特にな
+い.
+
+○カーネル管理外の割込み
+
+カーネル管理外の割込みをサポートする.指定方法は,割込み優先度の段階数
+で指定した,サポートする割込み優先度の最高値(最小値)より,
+TMIN_INTPRIを大きく設定すると,TMIN_INTPRIより値が小い(高優先度)な割
+込み優先度を設定した割込みを割込み優先度として扱う.
+
+カーネル管理外の割込みはOS実行中も禁止になることはなく(厳密には割込み
+の出口でごく短い区間禁止される),割込み発生時は,カーネルのコードを経
+由せずに呼び出される.
+
+カーネル管理外の割込みに対する,DEF_INH,CFG_INTはサポートする.
+
+(3-3) CPU例外処理に関する規定
+
+○CPU例外ハンドラ番号
+
+CPU例外ハンドラ番号としては,例外発生時にIPSRにセットされる,例外番号
+を用いる.各例外の例外番号は以下の通りである.
+
+ 例外 例外番号
+ Reset 1
+ Non-makable Interrupt 2
+ Hard Fault 3
+ Memory Management 4
+ Bus Fault 5
+ Usage Fault 6
+ SVCall 11
+ Debug Monitor 12
+ PendSV 14
+
+なお,Resetと,SVCallについては,カーネルが使用するため,ユーザーは使
+用することができない.
+
+(3-4) CPUロック・割込みロック
+
+CPUロックは,basepriをTMIN_INTPRIの優先度の割込みを禁止する値に設定す
+る.割込みロックは,FAULTMASKを'1'に設定することで実現している.
+
+(3-5) 性能評価用システム時刻の参照に関する規定
+
+get_utmをサポートする.精度に関しては,ターゲット毎に異なる.
+
+(3-6) スタートアップルーチンでの初期化内容
+
+スタートアップルーチンは,Threadモードで呼び出されることを前提としてい
+る.実行後,割込みロック状態(FAULTMASKをセット)とする.割込みロック
+状態は,カーネルの初期化終了時に許可する.スタートアップルーチンで,
+MSPをアクティブなスタックとし,MSPの内容を初期化するためには,INIT_MSP
+をターゲット依存部で定義する.
+
+(3-7) ベクタテーブルオフセットの初期化
+
+プロセッサ依存の初期化処理で,Vector Table Offset Register をターゲッ
+ト依存部の初期化ルーチンで設定する.なお,ベクターテーブルは,.vector
+のセクション属性が付加されているため,リンカスクリプトでこのセクション
+を指定して配置する.
+
+
+(4) タイマドライバ関連の情報
+
+カーネルのタイムティックとして,SYSTICを使用する場合は,prc_config.c
+をコンパイル対象とし,コンフィギュレーションファイルに prc_config.cfg
+を指定すること.
+
+周期の基本は1msecとする.周期をCALIBRATIONレジスタの設定内容を元に計算
+する場合は,SYSTIC_USE_CALIBRATION を定義する.CALIBRATIONレジスタを用
+いない場合は,1msec周期分のカウント値を TIMER_CLOCK に設定する.クロッ
+クソースとして,外部クロックを用いる場合は,SYSTIC_USE_STCLK を用いる.
+
+
+(5) ターゲット依存部での設定項目
+
+ターゲット依存部では以下のマクロを定義する必要がある.
+
+ ・TMAX_INTNO : 割込み番号の最大値(通常の割込み番号 + 15)
+ ・TBITW_IPRI : 割込み優先度のビット幅
+ ・TBITW_SUBIPRI : 割込み優先度のビット幅中のサブ優先度のビット幅
+ ・TMIN_INTPRI : 割込み優先度の最小値(最高値)
+ ・TIC_NUME : タイムティックの周期の分子
+ ・TIC_DENO : タイムティックの周期の分母
+ ・TIMER_CLOCK : タイマ値の内部表現とミリ秒単位との変換
+ ・INTPRI_TIMER : タイマ割込み割込み優先度
+ ・INTATR_TIMER : タイマ割込みの割込み属性
+ ・INIT_MSP : スタートアップルーチンでMSPを初期化する場合は定義
+ ・DEFAULT_ISTKSZ : スタックサイズ(8byte単位で指定)
+ ・SIL_DLY_TIM1 : 微少時間待ちのための定義
+ ・SIL_DLY_TIM2 : 微少時間待ちのための定義
+
+
+(6) ディレクトリ構成・ファイル構成
+ ./arch/arm_m_gcc/
+ ./Makefile.prc
+ ./arm_m.h
+ ./makeoffset.c
+ ./prc.tf
+ ./prc_cfg1_out.h
+ ./prc_check.tf
+ ./prc_config.c
+ ./prc_config.h
+ ./prc_def.csv
+ ./prc_insn.h
+ ./prc_kernel.h
+ ./prc_rename.def
+ ./prc_rename.h
+ ./prc_sil.h
+ ./prc_stddef.h
+ ./prc_support.S
+ ./prc_test.h
+ ./prc_timer.c
+ ./prc_timer.cfg
+ ./prc_timer.h
+ ./prc_unrename.h
+ ./prc_user_annex.txt
+ ./prc_user.txt
+ ./start.S
+
+(12) バージョン履歴
+
+2010/10/23
+ ・1.6.0対応にしたがい、数点の変更を行った。詳しくは prc_user_annex.txtを参照。
+
+2008/08/22
+ ・prc_user.txt/prc_design.txt
+ ・2008/8/21の技術検討会での議論結果を反映.
+ ・prc_support.S/prc_config.c/prc_config.h/arm_m.h
+ ・コンテキスト判定をexc_ncntからアクティブなスタックに変更
+ ・prc_config.c
+ ・set_exc_int_priority() でサポート可能なIRQの上限を239に拡張.
+ ・start.S
+ ・起動時はThreadモードを前提としていることを明記.
+ ・ブートローダー等から起動される場合を想定し,MSPを有効にするように
+ 変更.
+ ・prc_timer.c
+ ・コメントを修正
+ ・デバッグ用コードを削除
+
+2008/07/11
+ ・最初のリリース
--- /dev/null
+=====================================================================
+ ARM-Mプロセッサ依存部 ASP 1.6.0対応版
+ Last Modified: 2010/Oct/11
+=====================================================================
+
+
+(1) CPU依存部の概要
+
+このARM-M依存部は、TOPPERSプロジェクトが配布しているTOPPERS/ASP
+1.3.2対応版CORTEX-M3依存部を元に修正したものである。
+
+(2) 変更点
+以下の点を元にしたASP 1.3.2.対応版から変更した
+
+(2-1) prc_cfg1_out.h
+_kernel_istkptの定義を、LPC17xx向けコンパイル時に外すようにした。
+これによって、メモリリマップのないLPC17xxでもGDBでSRAMにロードした
+プログラムが正しいMSP値を取得できるようになる。
+
+(2-2) prc_config.h
+ターゲット非依存部の要請に従い、CTXBをTSKCTXBに改名した。
+
+TOPPERS_ISTKPTにある、割り込みスタックのサイズの計算のバグを修正した。
+
+(2-3) prc.tf
+以下の議論に従い、$bitpat_cfgintへの代入方法を修正した。
+http://www.toppers.jp/TOPPERS-USERS/201004/msg00034.html
+> prc.tfの130行目に
+> $bitpat_cfgint = 0$
+> という行がありますが、これを
+> $bitpat_cfgint = 1-1$
+> に書き換えるとうまくいくようです。
+
+(2-4) prc_user_annex.h
+当ドキュメントを追加した。
+
+(2-5) MANIFEST
+バージョン番号を1.6.0に変更し、新設したチップ依存部、ターゲット依存部の
+マニフェストのINCLUDEを追加した。
+
+当ドキュメントの名前を追加した。
+
+(3) 変更履歴
+2010/Oct/23
+ - 初版
+
+以上
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: start.S 1304 2008-08-27 07:28:36Z ertl-honda $
+ */
+
+/*
+ * カーネル用のスタートアップモジュール(ARM-M用)
+ */
+#define TOPPERS_MACRO_ONLY
+#define UINT_C(val) (val) /* uint_t型の定数を作るマクロ */
+#define ULONG_C(val) (val) /* ulong_t型の定数を作るマクロ */
+#define CAST(type, val) (val) /* 型キャストを行うマクロ */
+
+#include "kernel_impl.h"
+#include "arm_m.h"
+
+/*
+ * スタートアップルーチン
+ *
+ * Threadモードで呼び出されることを前提としてる.
+ */
+ .text
+ .align 2
+ .code 16
+ .syntax unified
+ .globl _start
+ .type _start, function
+_start:
+ cpsid f /* 割込みロック状態へ */
+
+#ifdef INIT_MSP
+ /*
+ * MSPの設定
+ */
+ mov r0, #CONTROL_MSP /* MSPを有効に */
+ msr control, r0
+ isb /* control の操作後に必要 */
+ ldr r0,=_kernel_istkpt
+ ldr r1,[r0]
+ msr msp, r1
+#endif /* INIT_MSP */
+
+ /*
+ * hardware_init_hookの呼び出し (0でない場合)
+ *
+ * ターゲットハードウェアに依存して必要な初期化処理がある場合
+ * は,hardware_init_hook という関数を用意する
+ */
+ ldr r0, =hardware_init_hook
+ cbz r0, start_1
+ blx r0
+
+start_1:
+#ifndef OMIT_BSS_INIT
+ /*
+ * BSSセクション初期化
+ */
+ mov r0, #0
+ ldr r1, =__bss_start
+ ldr r2, =__bss_end
+ cmp r1, r2
+ bhs start_3
+start_2:
+ str r0, [r1]
+ add r1,r1, #4
+ cmp r1, r2
+ blo start_2
+#endif /* OMIT_BSS_INIT */
+
+
+start_3:
+
+#ifndef OMIT_DATA_INIT
+ /*
+ * DATAセクション初期化
+ * __idata_start から __idata_end までを,__data_start 以降に
+ * コピーする
+ */
+ ldr r1, =__idata_start
+ ldr r2, =__idata_end
+ cmp r1, r2
+ bhs start_5
+ ldr r3, =__data_start
+start_4:
+ ldr r0, [r1]
+ str r0, [r3]
+ add r1, #4
+ add r3, #4
+ cmp r1, r2
+ blo start_4
+#endif /* OMIT_DATA_INIT */
+
+ /*
+ * software_init_hook を呼出し(0 でない場合)
+ *
+ * ソフトウェア環境(特にライブラリ)に依存して必要な初期化処
+ * 理がある場合は,software_init_hook という関数を用意すれば
+ * よい.
+ */
+start_5:
+ ldr r0, =software_init_hook
+ cbz r0, start_6
+ blx r0
+
+start_6:
+ bl sta_ker
+
+l_end:
+ b l_end
--- /dev/null
+PACKAGE asp
+
+MANIFEST
+tool_stddef.h
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: tool_stddef.h 819 2008-03-18 12:58:50Z hiro $
+ */
+
+/*
+ * t_stddef.hの開発環境依存部(GCC用)
+ */
+
+#ifndef TOPPERS_TOOL_STDDEF_H
+#define TOPPERS_TOOL_STDDEF_H
+
+/*
+ * コンパイラの拡張機能のためのマクロ定義
+ */
+#ifndef __cplusplus /* C++にはinline がある */
+#if __STDC_VERSION__ < 199901L /* C99にはinline がある */
+#define inline __inline__ /* インライン関数 */
+#endif /* __STDC_VERSION__ < 199901L */
+#endif /* __cplusplus */
+
+#define Inline static __inline__ /* インライン関数 */
+
+#ifndef __cplusplus /* C++にはasmがある */
+#define asm __asm__ /* インラインアセンブラ */
+#endif /* __cplusplus */
+
+#define Asm __asm__ volatile /* インラインアセンブラ(最適化抑止)*/
+
+#define NoReturn __attribute__((__noreturn__))
+ /* リターンしない関数 */
+
+/*
+ * 開発環境の標準インクルードファイルの利用
+ *
+ * NULLの定義をstddef.hから,INT_MAX,INT_MIN,UINT_MAX,LONG_MAX,
+ * LONG_MIN,ULONG_MAX,CHAR_BITの定義をlimits.hから取り込む.
+ *
+ * C++/EC++では,標準仕様上はこれらのインクルードファイルが用意されて
+ * いるとは限らないので注意が必要である(ほとんどの開発環境で用意され
+ * ている).
+ */
+#ifndef TOPPERS_MACRO_ONLY
+#include <stddef.h>
+#include <limits.h>
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ * stdint.hの代用となる定義
+ *
+ * 開発環境にstdint.hが用意されておらず,各整数型のサイズがあるパター
+ * ンに当てはまる場合に,stdint.hの代用となる定義を与える.
+ *
+ * TOPPERS_STDINT_TYPE1: char/short/int/long longのビット長がそれぞれ
+ * 8/16/32/64ビットで,ポインタのビット長がlong
+ * のビット長と一致する場合
+ */
+#ifdef TOPPERS_STDINT_TYPE1
+
+/*
+ * コンパイラ依存のデータ型の定義
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+typedef signed char int8_t; /* 符号付き8ビット整数 */
+typedef unsigned char uint8_t; /* 符号無し8ビット整数 */
+
+typedef signed short int16_t; /* 符号付き16ビット整数 */
+typedef unsigned short uint16_t; /* 符号無し16ビット整数 */
+
+typedef signed int int32_t; /* 符号付き32ビット整数 */
+typedef unsigned int uint32_t; /* 符号無し32ビット整数 */
+
+typedef signed long long int64_t; /* 符号付き64ビット整数 */
+typedef unsigned long long uint64_t; /* 符号無し64ビット整数 */
+
+typedef int8_t int_least8_t; /* 8ビット以上の符号付き整数 */
+typedef uint8_t uint_least8_t; /* 8ビット以上の符号無し整数 */
+
+typedef long intptr_t; /* ポインタを格納できる符号付き整数 */
+typedef unsigned long uintptr_t; /* ポインタを格納できる符号無し整数 */
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ * コンパイラ依存のデータ型の整数定数を作るマクロ
+ */
+#ifndef INT8_C
+#define INT8_C(val) (val)
+#endif /* INT8_C */
+
+#ifndef UINT8_C
+#define UINT8_C(val) (val ## U)
+#endif /* UINT8_C */
+
+#ifndef INT16_C
+#define INT16_C(val) (val)
+#endif /* INT16_C */
+
+#ifndef UINT16_C
+#define UINT16_C(val) (val ## U)
+#endif /* UINT16_C */
+
+#ifndef INT32_C
+#define INT32_C(val) (val)
+#endif /* INT32_C */
+
+#ifndef UINT32_C
+#define UINT32_C(val) (val ## U)
+#endif /* UINT32_C */
+
+#ifndef INT64_C
+#define INT64_C(val) (val ## LL)
+#endif /* INT64_C */
+
+#ifndef UINT64_C
+#define UINT64_C(val) (val ## ULL)
+#endif /* UINT64_C */
+
+/*
+ * コンパイラ依存のデータ型に格納できる最大値と最小値の定義
+ */
+#define INT8_MAX SCHAR_MAX
+#define INT8_MIN SCHAR_MIN
+#define UINT8_MAX UCHAR_MAX
+
+#define INT16_MAX SHRT_MAX
+#define INT16_MIN SHRT_MIN
+#define UINT16_MAX USHRT_MAX
+
+#define INT32_MAX INT_MAX
+#define INT32_MIN INT_MIN
+#define UINT32_MAX UINT_MAX
+
+#define INT64_MAX LLONG_MAX
+#define INT64_MIN LLONG_MIN
+#define UINT64_MAX ULLONG_MAX
+
+#define INT_LEAST8_MAX INT8_MAX
+#define INT_LEAST8_MIN INT8_MIN
+#define UINT_LEAST8_MAX INT8_MAX
+
+#endif /* TOPPERS_STDINT_TYPE1 */
+
+/*
+ * 浮動小数点型に関する定義
+ *
+ * TOPPERS_STDFLOAT_TYPE1: floatがIEEE754準拠の単精度浮動小数点数,
+ * doubleが倍精度浮動小数点数の場合
+ */
+#ifdef TOPPERS_STDFLOAT_TYPE1
+#ifndef TOPPERS_MACRO_ONLY
+
+typedef float float32_t; /* IEEE754準拠の単精度浮動小数点数 */
+typedef double double64_t; /* IEEE754準拠の倍精度浮動小数点数 */
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#define FLOAT32_MIN 1.17549435e-38F
+#define FLOAT32_MAX 3.40282347e+38F
+#define DOUBLE64_MIN 2.2250738585072014e-308
+#define DOUBLE64_MAX 1.7976931348623157e+308
+
+#endif /* TOPPERS_STDFLOAT_TYPE1 */
+#endif /* TOPPERS_TOOL_STDDEF_H */
--- /dev/null
+PACKAGE asp
+
+MANIFEST
+tlv.tf
+trace_config.c
+trace_config.h
+trace_dump.c
+kernel_fncode.h
+
--- /dev/null
+/* This file is generated from svc.def by gensvc. ¡¡*/
+
+#ifndef TOPPERS_KERNEL_FNCODE_H
+#define TOPPERS_KERNEL_FNCODE_H
+
+#define TFN_ACT_TSK (-5)
+#define TFN_IACT_TSK (-6)
+#define TFN_CAN_ACT (-7)
+#define TFN_EXT_TSK (-8)
+#define TFN_TER_TSK (-9)
+#define TFN_CHG_PRI (-10)
+#define TFN_GET_PRI (-11)
+#define TFN_GET_INF (-12)
+#define TFN_SLP_TSK (-13)
+#define TFN_TSLP_TSK (-14)
+#define TFN_WUP_TSK (-15)
+#define TFN_IWUP_TSK (-16)
+#define TFN_CAN_WUP (-17)
+#define TFN_REL_WAI (-18)
+#define TFN_IREL_WAI (-19)
+#define TFN_DIS_WAI (-21)
+#define TFN_IDIS_WAI (-22)
+#define TFN_ENA_WAI (-23)
+#define TFN_IENA_WAI (-24)
+#define TFN_SUS_TSK (-25)
+#define TFN_RSM_TSK (-26)
+#define TFN_DLY_TSK (-27)
+#define TFN_RAS_TEX (-29)
+#define TFN_IRAS_TEX (-30)
+#define TFN_DIS_TEX (-31)
+#define TFN_ENA_TEX (-32)
+#define TFN_SNS_TEX (-33)
+#define TFN_REF_TEX (-34)
+#define TFN_SIG_SEM (-37)
+#define TFN_ISIG_SEM (-38)
+#define TFN_WAI_SEM (-39)
+#define TFN_POL_SEM (-40)
+#define TFN_TWAI_SEM (-41)
+#define TFN_SET_FLG (-45)
+#define TFN_ISET_FLG (-46)
+#define TFN_CLR_FLG (-47)
+#define TFN_WAI_FLG (-48)
+#define TFN_POL_FLG (-49)
+#define TFN_TWAI_FLG (-50)
+#define TFN_SND_DTQ (-53)
+#define TFN_PSND_DTQ (-54)
+#define TFN_IPSND_DTQ (-55)
+#define TFN_TSND_DTQ (-56)
+#define TFN_FSND_DTQ (-57)
+#define TFN_IFSND_DTQ (-58)
+#define TFN_RCV_DTQ (-59)
+#define TFN_PRCV_DTQ (-60)
+#define TFN_TRCV_DTQ (-61)
+#define TFN_SND_PDQ (-65)
+#define TFN_PSND_PDQ (-66)
+#define TFN_IPSND_PDQ (-67)
+#define TFN_TSND_PDQ (-68)
+#define TFN_RCV_PDQ (-69)
+#define TFN_PRCV_PDQ (-70)
+#define TFN_TRCV_PDQ (-71)
+#define TFN_SND_MBX (-73)
+#define TFN_RCV_MBX (-74)
+#define TFN_PRCV_MBX (-75)
+#define TFN_TRCV_MBX (-76)
+#define TFN_LOC_MTX (-77)
+#define TFN_PLOC_MTX (-78)
+#define TFN_TLOC_MTX (-79)
+#define TFN_UNL_MTX (-80)
+#define TFN_SND_MBF (-81)
+#define TFN_PSND_MBF (-82)
+#define TFN_TSND_MBF (-83)
+#define TFN_RCV_MBF (-84)
+#define TFN_PRCV_MBF (-85)
+#define TFN_TRCV_MBF (-86)
+#define TFN_GET_MPF (-89)
+#define TFN_PGET_MPF (-90)
+#define TFN_TGET_MPF (-91)
+#define TFN_REL_MPF (-92)
+#define TFN_GET_TIM (-93)
+#define TFN_GET_UTM (-94)
+#define TFN_STA_CYC (-97)
+#define TFN_STP_CYC (-98)
+#define TFN_STA_ALM (-101)
+#define TFN_ISTA_ALM (-102)
+#define TFN_STP_ALM (-103)
+#define TFN_ISTP_ALM (-104)
+#define TFN_STA_OVR (-105)
+#define TFN_STP_OVR (-106)
+#define TFN_REF_OVR (-107)
+#define TFN_SAC_SYS (-109)
+#define TFN_REF_SYS (-110)
+#define TFN_ROT_RDQ (-111)
+#define TFN_IROT_RDQ (-112)
+#define TFN_GET_DID (-113)
+#define TFN_GET_CDM (-114)
+#define TFN_GET_TID (-115)
+#define TFN_IGET_TID (-116)
+#define TFN_LOC_CPU (-117)
+#define TFN_ILOC_CPU (-118)
+#define TFN_UNL_CPU (-119)
+#define TFN_IUNL_CPU (-120)
+#define TFN_DIS_DSP (-121)
+#define TFN_ENA_DSP (-122)
+#define TFN_SNS_CTX (-123)
+#define TFN_SNS_LOC (-124)
+#define TFN_SNS_DSP (-125)
+#define TFN_SNS_DPN (-126)
+#define TFN_SNS_KER (-127)
+#define TFN_EXT_KER (-128)
+#define TFN_ATT_MEM (-129)
+#define TFN_DET_MEM (-130)
+#define TFN_SAC_MEM (-131)
+#define TFN_PRB_MEM (-132)
+#define TFN_REF_MEM (-133)
+#define TFN_CFG_INT (-137)
+#define TFN_DIS_INT (-138)
+#define TFN_ENA_INT (-139)
+#define TFN_REF_INT (-140)
+#define TFN_CHG_IPM (-141)
+#define TFN_GET_IPM (-142)
+#define TFN_XSNS_DPN (-145)
+#define TFN_XSNS_XPN (-146)
+#define TFN_REF_CFG (-149)
+#define TFN_REF_VER (-150)
+#define TFN_INI_SEM (-162)
+#define TFN_INI_FLG (-163)
+#define TFN_INI_DTQ (-164)
+#define TFN_INI_PDQ (-165)
+#define TFN_INI_MBX (-166)
+#define TFN_INI_MTX (-167)
+#define TFN_INI_MBF (-168)
+#define TFN_INI_MPF (-169)
+#define TFN_REF_TSK (-177)
+#define TFN_REF_SEM (-178)
+#define TFN_REF_FLG (-179)
+#define TFN_REF_DTQ (-180)
+#define TFN_REF_PDQ (-181)
+#define TFN_REF_MBX (-182)
+#define TFN_REF_MTX (-183)
+#define TFN_REF_MBF (-184)
+#define TFN_REF_MPF (-185)
+#define TFN_REF_CYC (-186)
+#define TFN_REF_ALM (-187)
+#define TFN_REF_ISR (-188)
+#define TFN_ACRE_TSK (-193)
+#define TFN_ACRE_SEM (-194)
+#define TFN_ACRE_FLG (-195)
+#define TFN_ACRE_DTQ (-196)
+#define TFN_ACRE_PDQ (-197)
+#define TFN_ACRE_MBX (-198)
+#define TFN_ACRE_MTX (-199)
+#define TFN_ACRE_MBF (-200)
+#define TFN_ACRE_MPF (-201)
+#define TFN_ACRE_CYC (-202)
+#define TFN_ACRE_ALM (-203)
+#define TFN_ACRE_ISR (-204)
+#define TFN_DEL_TSK (-209)
+#define TFN_DEL_SEM (-210)
+#define TFN_DEL_FLG (-211)
+#define TFN_DEL_DTQ (-212)
+#define TFN_DEL_PDQ (-213)
+#define TFN_DEL_MBX (-214)
+#define TFN_DEL_MTX (-215)
+#define TFN_DEL_MBF (-216)
+#define TFN_DEL_MPF (-217)
+#define TFN_DEL_CYC (-218)
+#define TFN_DEL_ALM (-219)
+#define TFN_DEL_ISR (-220)
+#define TFN_SAC_TSK (-225)
+#define TFN_SAC_SEM (-226)
+#define TFN_SAC_FLG (-227)
+#define TFN_SAC_DTQ (-228)
+#define TFN_SAC_PDQ (-229)
+#define TFN_SAC_MTX (-231)
+#define TFN_SAC_MBF (-232)
+#define TFN_SAC_MPF (-233)
+#define TFN_SAC_CYC (-234)
+#define TFN_SAC_ALM (-235)
+#define TFN_SAC_ISR (-236)
+#define TFN_DEF_TEX (-241)
+#define TFN_DEF_OVR (-242)
+#define TFN_DEF_INH (-243)
+#define TFN_DEF_EXC (-244)
+#define TFN_DEF_SVC (-245)
+
+#endif /* TOPPERS_KERNEL_FNCODE_H */
--- /dev/null
+$FILE "kernel.res"$
+{$NL$
+$TAB$"TimeScale" :"us",$NL$
+$TAB$"TimeRadix" :10,$NL$
+$TAB$"ConvertRules" :["asp"],$NL$
+$TAB$"VisualizeRules" :["toppers","asp"],$NL$
+$TAB$"ResourceHeaders":["asp"],$NL$
+$TAB$"Resources":$NL$
+$TAB${$NL$
+$TAB$$TAB$"CurrentContext":{$NL$
+$TAB$$TAB$$TAB$"Type":"Context",$NL$
+$TAB$$TAB$$TAB$"Attributes":$NL$
+$TAB$$TAB$$TAB${$NL$
+$TAB$$TAB$$TAB$$TAB$"name" : "None"$NL$
+$TAB$$TAB$$TAB$}$NL$
+$TAB$$TAB$},$NL$
+$JOINEACH tskid TSK.ID_LIST ",\n"$
+ $TAB$$TAB$"$tskid$":{$NL$
+ $TAB$$TAB$$TAB$"Type":"Task",$NL$
+ $TAB$$TAB$$TAB$"Attributes":$NL$
+ $TAB$$TAB$$TAB${$NL$
+ $TAB$$TAB$$TAB$$TAB$"id" :$+tskid$,$NL$
+ $TAB$$TAB$$TAB$$TAB$"atr" :"$TSK.TSKATR[tskid]$",$NL$
+ $TAB$$TAB$$TAB$$TAB$"pri" :$+TSK.ITSKPRI[tskid]$,$NL$
+ $TAB$$TAB$$TAB$$TAB$"exinf" :"$TSK.EXINF[tskid]$",$NL$
+ $TAB$$TAB$$TAB$$TAB$"task" :"$TSK.TASK[tskid]$",$NL$
+ $TAB$$TAB$$TAB$$TAB$"stksz" :$+TSK.STKSZ[tskid]$,$NL$
+ $TAB$$TAB$$TAB$$TAB$"stk" :"NULL",$NL$
+ $TAB$$TAB$$TAB$$TAB$"state" :
+ $IF TSK.TSKATR[tskid] == TA_ACT$
+ "RUNNABLE"$NL$
+ $ELSE$
+ "DORMANT"$NL$
+ $END$
+ $TAB$$TAB$$TAB$}$NL$
+ $TAB$$TAB$}
+$END$,
+$NL$
+$JOINEACH inhno INH.ORDER_LIST ",\n"$
+ $TAB$$TAB$"INH_$INH.INHNO[inhno]$_$INH.INTHDR[inhno]$":{$NL$
+ $TAB$$TAB$$TAB$"Type":"InterruptHandler",$NL$
+ $TAB$$TAB$$TAB$"Attributes":$NL$
+ $TAB$$TAB$$TAB${$NL$
+ $TAB$$TAB$$TAB$$TAB$"id" :$+INH.INHNO[inhno]$,$NL$
+ $TAB$$TAB$$TAB$$TAB$"state" : "DORMANT"$NL$
+ $TAB$$TAB$$TAB$}$NL$
+ $TAB$$TAB$}
+$END$,
+$NL$
+$JOINEACH order ISR.ORDER_LIST ",\n"$
+ $TAB$$TAB$"ISR_$ISR.INTNO[order]$_$ISR.ISR[order]$_$ISR.EXINF[order]$":{$NL$
+ $TAB$$TAB$$TAB$"Type":"InterruptServiceRoutine",$NL$
+ $TAB$$TAB$$TAB$"Attributes":$NL$
+ $TAB$$TAB$$TAB${$NL$
+ $TAB$$TAB$$TAB$$TAB$"id" :$+ISR.INTNO[order]$,$NL$
+ $TAB$$TAB$$TAB$$TAB$"state" : "DORMANT"$NL$
+ $TAB$$TAB$$TAB$}$NL$
+ $TAB$$TAB$}
+$END$,
+$NL$
+$JOINEACH cycid CYC.ID_LIST ",\n"$
+ $TAB$$TAB$"$cycid$":{$NL$
+ $TAB$$TAB$$TAB$"Type":"CyclicHandler",$NL$
+ $TAB$$TAB$$TAB$"Attributes":$NL$
+ $TAB$$TAB$$TAB${$NL$
+ $TAB$$TAB$$TAB$$TAB$"id" :$+cycid$,$NL$
+ $TAB$$TAB$$TAB$$TAB$"state" : "DORMANT"$NL$
+ $TAB$$TAB$$TAB$}$NL$
+ $TAB$$TAB$}
+$END$,
+$NL$
+$JOINEACH almid ALM.ID_LIST ",\n"$
+ $TAB$$TAB$"$almid$":{$NL$
+ $TAB$$TAB$$TAB$"Type":"AlarmHandler",$NL$
+ $TAB$$TAB$$TAB$"Attributes":$NL$
+ $TAB$$TAB$$TAB${$NL$
+ $TAB$$TAB$$TAB$$TAB$"id" :$+almid$,$NL$
+ $TAB$$TAB$$TAB$$TAB$"state" : "DORMANT"$NL$
+ $TAB$$TAB$$TAB$}$NL$
+ $TAB$$TAB$}
+$END$,
+$NL$
+$JOINEACH excno EXC.ORDER_LIST ",\n"$
+ $TAB$$TAB$"$EXC.EXCNO[excno]$":{$NL$
+ $TAB$$TAB$$TAB$"Type":"CPUExceptionHandler",$NL$
+ $TAB$$TAB$$TAB$"Attributes":$NL$
+ $TAB$$TAB$$TAB${$NL$
+ $TAB$$TAB$$TAB$$TAB$"id" :$+EXC.EXCNO[excno]$,$NL$
+ $TAB$$TAB$$TAB$$TAB$"state" : "DORMANT"$NL$
+ $TAB$$TAB$$TAB$}$NL$
+ $TAB$$TAB$}
+$END$,
+$NL$
+ $TAB$$TAB$"TASK_TEX":{$NL$
+ $TAB$$TAB$$TAB$"Type":"TaskExceptionRoutine",$NL$
+ $TAB$$TAB$$TAB$"Attributes":$NL$
+ $TAB$$TAB$$TAB${$NL$
+ $TAB$$TAB$$TAB$$TAB$"state" : "DORMANT"$NL$
+ $TAB$$TAB$$TAB$}$NL$
+ $TAB$$TAB$}
+$NL$
+$TAB$}$NL$
+}$NL$
+$FILE "kernel_cfg.c"$
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * ¾åµÃøºî¸¢¼Ô¤Ï¡¤°Ê²¼¤Î(1)¡Á(4)¤Î¾ò·ï¤òËþ¤¿¤¹¾ì¹ç¤Ë¸Â¤ê¡¤ËÜ¥½¥Õ¥È¥¦¥§
+ * ¥¢¡ÊËÜ¥½¥Õ¥È¥¦¥§¥¢¤ò²þÊѤ·¤¿¤â¤Î¤ò´Þ¤à¡¥°Ê²¼Æ±¤¸¡Ë¤ò»ÈÍÑ¡¦Ê£À½¡¦²þ
+ * ÊÑ¡¦ºÆÇÛÉۡʰʲ¼¡¤ÍøÍѤȸƤ֡ˤ¹¤ë¤³¤È¤ò̵½þ¤ÇµöÂú¤¹¤ë¡¥
+ * (1) ËÜ¥½¥Õ¥È¥¦¥§¥¢¤ò¥½¡¼¥¹¥³¡¼¥É¤Î·Á¤ÇÍøÍѤ¹¤ë¾ì¹ç¤Ë¤Ï¡¤¾åµ¤ÎÃøºî
+ * ¸¢É½¼¨¡¤¤³¤ÎÍøÍѾò·ï¤ª¤è¤Ó²¼µ¤Î̵Êݾڵ¬Ä꤬¡¤¤½¤Î¤Þ¤Þ¤Î·Á¤Ç¥½¡¼
+ * ¥¹¥³¡¼¥ÉÃæ¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ë¤³¤È¡¥
+ * (2) ËÜ¥½¥Õ¥È¥¦¥§¥¢¤ò¡¤¥é¥¤¥Ö¥é¥ê·Á¼°¤Ê¤É¡¤Â¾¤Î¥½¥Õ¥È¥¦¥§¥¢³«È¯¤Ë»È
+ * ÍѤǤ¤ë·Á¤ÇºÆÇÛÉÛ¤¹¤ë¾ì¹ç¤Ë¤Ï¡¤ºÆÇÛÉÛ¤Ëȼ¤¦¥É¥¥å¥á¥ó¥È¡ÊÍøÍÑ
+ * ¼Ô¥Þ¥Ë¥å¥¢¥ë¤Ê¤É¡Ë¤Ë¡¤¾åµ¤ÎÃøºî¸¢É½¼¨¡¤¤³¤ÎÍøÍѾò·ï¤ª¤è¤Ó²¼µ
+ * ¤Î̵Êݾڵ¬Äê¤ò·ÇºÜ¤¹¤ë¤³¤È¡¥
+ * (3) ËÜ¥½¥Õ¥È¥¦¥§¥¢¤ò¡¤µ¡´ï¤ËÁȤ߹þ¤à¤Ê¤É¡¤Â¾¤Î¥½¥Õ¥È¥¦¥§¥¢³«È¯¤Ë»È
+ * ÍѤǤ¤Ê¤¤·Á¤ÇºÆÇÛÉÛ¤¹¤ë¾ì¹ç¤Ë¤Ï¡¤¼¡¤Î¤¤¤º¤ì¤«¤Î¾ò·ï¤òËþ¤¿¤¹¤³
+ * ¤È¡¥
+ * (a) ºÆÇÛÉÛ¤Ëȼ¤¦¥É¥¥å¥á¥ó¥È¡ÊÍøÍѼԥޥ˥奢¥ë¤Ê¤É¡Ë¤Ë¡¤¾åµ¤ÎÃø
+ * ºî¸¢É½¼¨¡¤¤³¤ÎÍøÍѾò·ï¤ª¤è¤Ó²¼µ¤Î̵Êݾڵ¬Äê¤ò·ÇºÜ¤¹¤ë¤³¤È¡¥
+ * (b) ºÆÇÛÉۤηÁÂÖ¤ò¡¤Ê̤ËÄê¤á¤ëÊýË¡¤Ë¤è¤Ã¤Æ¡¤TOPPERS¥×¥í¥¸¥§¥¯¥È¤Ë
+ * Êó¹ð¤¹¤ë¤³¤È¡¥
+ * (4) ËÜ¥½¥Õ¥È¥¦¥§¥¢¤ÎÍøÍѤˤè¤êľÀÜŪ¤Þ¤¿¤Ï´ÖÀÜŪ¤ËÀ¸¤¸¤ë¤¤¤«¤Ê¤ë»
+ * ³²¤«¤é¤â¡¤¾åµÃøºî¸¢¼Ô¤ª¤è¤ÓTOPPERS¥×¥í¥¸¥§¥¯¥È¤òÌÈÀÕ¤¹¤ë¤³¤È¡¥
+ * ¤Þ¤¿¡¤ËÜ¥½¥Õ¥È¥¦¥§¥¢¤Î¥æ¡¼¥¶¤Þ¤¿¤Ï¥¨¥ó¥É¥æ¡¼¥¶¤«¤é¤Î¤¤¤«¤Ê¤ëÍý
+ * ͳ¤Ë´ð¤Å¤¯ÀÁµá¤«¤é¤â¡¤¾åµÃøºî¸¢¼Ô¤ª¤è¤ÓTOPPERS¥×¥í¥¸¥§¥¯¥È¤ò
+ * ÌÈÀÕ¤¹¤ë¤³¤È¡¥
+ *
+ * ËÜ¥½¥Õ¥È¥¦¥§¥¢¤Ï¡¤ÌµÊݾڤÇÄ󶡤µ¤ì¤Æ¤¤¤ë¤â¤Î¤Ç¤¢¤ë¡¥¾åµÃøºî¸¢¼Ô¤ª
+ * ¤è¤ÓTOPPERS¥×¥í¥¸¥§¥¯¥È¤Ï¡¤ËÜ¥½¥Õ¥È¥¦¥§¥¢¤Ë´Ø¤·¤Æ¡¤ÆÃÄê¤Î»ÈÍÑÌÜŪ
+ * ¤ËÂФ¹¤ëŬ¹çÀ¤â´Þ¤á¤Æ¡¤¤¤¤«¤Ê¤ëÊݾڤâ¹Ô¤ï¤Ê¤¤¡¥¤Þ¤¿¡¤ËÜ¥½¥Õ¥È¥¦¥§
+ * ¥¢¤ÎÍøÍѤˤè¤êľÀÜŪ¤Þ¤¿¤Ï´ÖÀÜŪ¤ËÀ¸¤¸¤¿¤¤¤«¤Ê¤ë»³²¤Ë´Ø¤·¤Æ¤â¡¤¤½
+ * ¤ÎÀÕǤ¤òÉé¤ï¤Ê¤¤¡¥
+ *
+ * @(#) $Id$
+ */
+
+/*
+ * ¥È¥ì¡¼¥¹¥í¥°µ¡Ç½
+ */
+
+#include "kernel_impl.h"
+#include "task.h"
+#include "time_event.h"
+#include <sil.h>
+
+#ifdef TOPPERS_SUPPORT_GET_UTM
+/*
+ * get_utm¤òÍѤ¤¤Æ¥Þ¥¯¥íÉÃñ°Ì¤Ç¤Î¥í¥°»þ¹ï¤ò¼èÆÀ
+ */
+Inline SYSUTM
+trace_get_tim_utime(void){
+ SYSUTM utime1;
+ get_utm(&utime1);
+ return utime1;
+}
+#endif /* TOPPERS_SUPPORT_GET_UTM */
+
+/*
+ * ¥È¥ì¡¼¥¹¥í¥°¥Ð¥Ã¥Õ¥¡¤È¤½¤ì¤Ë¥¢¥¯¥»¥¹¤¹¤ë¤¿¤á¤Î¥Ý¥¤¥ó¥¿
+ */
+SYSLOG trace_buffer[TCNT_TRACE_BUFFER]; /* ¥È¥ì¡¼¥¹¥í¥°¥Ð¥Ã¥Õ¥¡ */
+
+uint_t trace_count; /* ¥È¥ì¡¼¥¹¥í¥°¥Ð¥Ã¥Õ¥¡Ãæ¤Î¥í¥°¤Î¿ô */
+uint_t trace_head; /* ÀèƬ¤Î¥È¥ì¡¼¥¹¥í¥°¤Î³ÊǼ°ÌÃÖ */
+uint_t trace_tail; /* ¼¡¤Î¥È¥ì¡¼¥¹¥í¥°¤Î³ÊǼ°ÌÃÖ */
+MODE trace_mode; /* ¥È¥ì¡¼¥¹¥â¡¼¥É */
+
+/*
+ * ¥È¥ì¡¼¥¹¥í¥°µ¡Ç½¤Î½é´ü²½
+ */
+void
+trace_initialize(intptr_t exinf)
+{
+ MODE mode = ((MODE) exinf);
+
+ trace_count = 0U;
+ trace_head = trace_tail = 0U;
+ trace_mode = mode;
+
+ TRACE_HW_INIT();
+}
+
+/*
+ * ¥È¥ì¡¼¥¹¥í¥°¤Î³«»Ï
+ */
+ER
+trace_sta_log(MODE mode)
+{
+ if ((mode & TRACE_CLEAR) != 0U) {
+ trace_count = 0U;
+ trace_head = trace_tail = 0U;
+ }
+ trace_mode = mode;
+ return(E_OK);
+}
+
+/*
+ * ¥È¥ì¡¼¥¹¥í¥°¤Î½ñ¹þ¤ß
+ */
+ER
+trace_wri_log(TRACE *p_trace)
+{
+ SIL_PRE_LOC;
+
+ if (trace_mode != TRACE_STOP) {
+ SIL_LOC_INT();
+
+ /*
+ * ¥È¥ì¡¼¥¹»þ¹ï¤ÎÀßÄê
+ *
+ * LOG_WRI_LOG_ENTER¤«¤é¸Æ¤Ð¤ì¤¿¾ì¹ç¤Ëp_trace->logtim¤ò½ñ¤´¹
+ * ¤¨¤Æ¤·¤Þ¤¦¤Î¤Ïµ¤»ý¤Á¤¬°¤¤¤¬¡¤wri_log¤ÎÊý¤Ç¾å½ñ¤¤¹¤ë¤¿¤áÌä
+ * Âê¤Ï¤Ê¤¤¡¥
+ */
+ p_trace->logtim = TRACE_GET_TIM();
+
+ /*
+ * ¥È¥ì¡¼¥¹¥Ð¥Ã¥Õ¥¡¤ËµÏ¿
+ */
+ trace_buffer[trace_tail] = *p_trace;
+ trace_tail++;
+ if (trace_tail >= TCNT_TRACE_BUFFER) {
+ trace_tail = 0U;
+ }
+ if (trace_count < TCNT_TRACE_BUFFER) {
+ trace_count++;
+ if (trace_count >= TCNT_TRACE_BUFFER
+ && (trace_mode & TRACE_AUTOSTOP) != 0U) {
+ trace_mode = TRACE_STOP;
+ }
+ }
+ else {
+ trace_head = trace_tail;
+ }
+
+ SIL_UNL_INT();
+ }
+ return(E_OK);
+}
+
+/*
+ * ¥È¥ì¡¼¥¹¥í¥°¤ÎÆɽФ·
+ */
+ER
+trace_rea_log(TRACE *p_trace)
+{
+ ER_UINT ercd;
+ SIL_PRE_LOC;
+
+ SIL_LOC_INT();
+
+ /*
+ * ¥È¥ì¡¼¥¹¥í¥°¥Ð¥Ã¥Õ¥¡¤«¤é¤Î¼è½Ð¤·
+ */
+ if (trace_count > 0U) {
+ *p_trace = trace_buffer[trace_head];
+ trace_count--;
+ trace_head++;
+ if (trace_head >= TCNT_TRACE_BUFFER) {
+ trace_head = 0U;
+ }
+ ercd = E_OK;
+ }
+ else {
+ ercd = E_OBJ;
+ }
+
+ SIL_UNL_INT();
+ return(ercd);
+}
+
+/*
+ * ¥È¥ì¡¼¥¹¥í¥°¤ò½ÐÎϤ¹¤ë¤¿¤á¤Î¥é¥¤¥Ö¥é¥ê´Ø¿ô
+ */
+
+void
+trace_write_0(uint_t type)
+{
+ TRACE trace;
+
+ trace.logtype = type;
+ (void) trace_wri_log(&trace);
+}
+
+void
+trace_write_1(uint_t type, intptr_t arg1)
+{
+ TRACE trace;
+
+ trace.logtype = type;
+ trace.loginfo[0] = arg1;
+ (void) trace_wri_log(&trace);
+}
+
+void
+trace_write_2(uint_t type, intptr_t arg1, intptr_t arg2)
+{
+ TRACE trace;
+
+ trace.logtype = type;
+ trace.loginfo[0] = arg1;
+ trace.loginfo[1] = arg2;
+ (void) trace_wri_log(&trace);
+}
+
+void
+trace_write_3(uint_t type, intptr_t arg1, intptr_t arg2, intptr_t arg3)
+{
+ TRACE trace;
+
+ trace.logtype = type;
+ trace.loginfo[0] = arg1;
+ trace.loginfo[1] = arg2;
+ trace.loginfo[2] = arg3;
+ (void) trace_wri_log(&trace);
+}
+
+void
+trace_write_4(uint_t type, intptr_t arg1, intptr_t arg2, intptr_t arg3,
+ intptr_t arg4)
+{
+ TRACE trace;
+
+ trace.logtype = type;
+ trace.loginfo[0] = arg1;
+ trace.loginfo[1] = arg2;
+ trace.loginfo[2] = arg3;
+ trace.loginfo[3] = arg4;
+ (void) trace_wri_log(&trace);
+}
+
+void
+trace_write_5(uint_t type, intptr_t arg1, intptr_t arg2, intptr_t arg3,
+ intptr_t arg4, intptr_t arg5)
+{
+ TRACE trace;
+
+ trace.logtype = type;
+ trace.loginfo[0] = arg1;
+ trace.loginfo[1] = arg2;
+ trace.loginfo[2] = arg3;
+ trace.loginfo[3] = arg4;
+ trace.loginfo[4] = arg5;
+ (void) trace_wri_log(&trace);
+}
+
+void
+trace_write_6(uint_t type, intptr_t arg1, intptr_t arg2, intptr_t arg3,
+ intptr_t arg4, intptr_t arg5, intptr_t arg6)
+{
+ TRACE trace;
+
+ trace.logtype = type;
+ trace.loginfo[0] = arg1;
+ trace.loginfo[1] = arg2;
+ trace.loginfo[2] = arg3;
+ trace.loginfo[3] = arg4;
+ trace.loginfo[4] = arg5;
+ trace.loginfo[5] = arg6;
+ (void) trace_wri_log(&trace);
+}
+
+/*
+ * ¥¢¥»¥ó¥Ö¥ê¸À¸ì¤Çµ½Ò¤µ¤ì¤ë¥³¡¼¥É¤«¤é¥È¥ì¡¼¥¹¥í¥°¤ò½ÐÎϤ¹¤ë¤¿¤á¤Î´Ø
+ * ¿ô
+ */
+
+void
+log_dsp_enter(TCB *p_tcb)
+{
+ trace_1(LOG_TYPE_DSP|LOG_ENTER, p_tcb);
+}
+
+void
+log_dsp_leave(TCB *p_tcb)
+{
+ trace_1(LOG_TYPE_DSP|LOG_LEAVE, p_tcb);
+}
+
+void
+log_inh_enter(INHNO inhno)
+{
+ trace_1(LOG_TYPE_INH|LOG_ENTER, inhno);
+}
+
+void
+log_inh_leave(INHNO inhno)
+{
+ trace_1(LOG_TYPE_INH|LOG_LEAVE, inhno);
+}
+
+void
+log_exc_enter(EXCNO excno)
+{
+ trace_1(LOG_TYPE_EXC|LOG_ENTER, excno);
+}
+
+void
+log_exc_leave(EXCNO excno)
+{
+ trace_1(LOG_TYPE_EXC|LOG_LEAVE, excno);
+}
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * ¾åµÃøºî¸¢¼Ô¤Ï¡¤°Ê²¼¤Î(1)¡Á(4)¤Î¾ò·ï¤òËþ¤¿¤¹¾ì¹ç¤Ë¸Â¤ê¡¤ËÜ¥½¥Õ¥È¥¦¥§
+ * ¥¢¡ÊËÜ¥½¥Õ¥È¥¦¥§¥¢¤ò²þÊѤ·¤¿¤â¤Î¤ò´Þ¤à¡¥°Ê²¼Æ±¤¸¡Ë¤ò»ÈÍÑ¡¦Ê£À½¡¦²þ
+ * ÊÑ¡¦ºÆÇÛÉۡʰʲ¼¡¤ÍøÍѤȸƤ֡ˤ¹¤ë¤³¤È¤ò̵½þ¤ÇµöÂú¤¹¤ë¡¥
+ * (1) ËÜ¥½¥Õ¥È¥¦¥§¥¢¤ò¥½¡¼¥¹¥³¡¼¥É¤Î·Á¤ÇÍøÍѤ¹¤ë¾ì¹ç¤Ë¤Ï¡¤¾åµ¤ÎÃøºî
+ * ¸¢É½¼¨¡¤¤³¤ÎÍøÍѾò·ï¤ª¤è¤Ó²¼µ¤Î̵Êݾڵ¬Ä꤬¡¤¤½¤Î¤Þ¤Þ¤Î·Á¤Ç¥½¡¼
+ * ¥¹¥³¡¼¥ÉÃæ¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ë¤³¤È¡¥
+ * (2) ËÜ¥½¥Õ¥È¥¦¥§¥¢¤ò¡¤¥é¥¤¥Ö¥é¥ê·Á¼°¤Ê¤É¡¤Â¾¤Î¥½¥Õ¥È¥¦¥§¥¢³«È¯¤Ë»È
+ * ÍѤǤ¤ë·Á¤ÇºÆÇÛÉÛ¤¹¤ë¾ì¹ç¤Ë¤Ï¡¤ºÆÇÛÉÛ¤Ëȼ¤¦¥É¥¥å¥á¥ó¥È¡ÊÍøÍÑ
+ * ¼Ô¥Þ¥Ë¥å¥¢¥ë¤Ê¤É¡Ë¤Ë¡¤¾åµ¤ÎÃøºî¸¢É½¼¨¡¤¤³¤ÎÍøÍѾò·ï¤ª¤è¤Ó²¼µ
+ * ¤Î̵Êݾڵ¬Äê¤ò·ÇºÜ¤¹¤ë¤³¤È¡¥
+ * (3) ËÜ¥½¥Õ¥È¥¦¥§¥¢¤ò¡¤µ¡´ï¤ËÁȤ߹þ¤à¤Ê¤É¡¤Â¾¤Î¥½¥Õ¥È¥¦¥§¥¢³«È¯¤Ë»È
+ * ÍѤǤ¤Ê¤¤·Á¤ÇºÆÇÛÉÛ¤¹¤ë¾ì¹ç¤Ë¤Ï¡¤¼¡¤Î¤¤¤º¤ì¤«¤Î¾ò·ï¤òËþ¤¿¤¹¤³
+ * ¤È¡¥
+ * (a) ºÆÇÛÉÛ¤Ëȼ¤¦¥É¥¥å¥á¥ó¥È¡ÊÍøÍѼԥޥ˥奢¥ë¤Ê¤É¡Ë¤Ë¡¤¾åµ¤ÎÃø
+ * ºî¸¢É½¼¨¡¤¤³¤ÎÍøÍѾò·ï¤ª¤è¤Ó²¼µ¤Î̵Êݾڵ¬Äê¤ò·ÇºÜ¤¹¤ë¤³¤È¡¥
+ * (b) ºÆÇÛÉۤηÁÂÖ¤ò¡¤Ê̤ËÄê¤á¤ëÊýË¡¤Ë¤è¤Ã¤Æ¡¤TOPPERS¥×¥í¥¸¥§¥¯¥È¤Ë
+ * Êó¹ð¤¹¤ë¤³¤È¡¥
+ * (4) ËÜ¥½¥Õ¥È¥¦¥§¥¢¤ÎÍøÍѤˤè¤êľÀÜŪ¤Þ¤¿¤Ï´ÖÀÜŪ¤ËÀ¸¤¸¤ë¤¤¤«¤Ê¤ë»
+ * ³²¤«¤é¤â¡¤¾åµÃøºî¸¢¼Ô¤ª¤è¤ÓTOPPERS¥×¥í¥¸¥§¥¯¥È¤òÌÈÀÕ¤¹¤ë¤³¤È¡¥
+ * ¤Þ¤¿¡¤ËÜ¥½¥Õ¥È¥¦¥§¥¢¤Î¥æ¡¼¥¶¤Þ¤¿¤Ï¥¨¥ó¥É¥æ¡¼¥¶¤«¤é¤Î¤¤¤«¤Ê¤ëÍý
+ * ͳ¤Ë´ð¤Å¤¯ÀÁµá¤«¤é¤â¡¤¾åµÃøºî¸¢¼Ô¤ª¤è¤ÓTOPPERS¥×¥í¥¸¥§¥¯¥È¤ò
+ * ÌÈÀÕ¤¹¤ë¤³¤È¡¥
+ *
+ * ËÜ¥½¥Õ¥È¥¦¥§¥¢¤Ï¡¤ÌµÊݾڤÇÄ󶡤µ¤ì¤Æ¤¤¤ë¤â¤Î¤Ç¤¢¤ë¡¥¾åµÃøºî¸¢¼Ô¤ª
+ * ¤è¤ÓTOPPERS¥×¥í¥¸¥§¥¯¥È¤Ï¡¤ËÜ¥½¥Õ¥È¥¦¥§¥¢¤Ë´Ø¤·¤Æ¡¤ÆÃÄê¤Î»ÈÍÑÌÜŪ
+ * ¤ËÂФ¹¤ëŬ¹çÀ¤â´Þ¤á¤Æ¡¤¤¤¤«¤Ê¤ëÊݾڤâ¹Ô¤ï¤Ê¤¤¡¥¤Þ¤¿¡¤ËÜ¥½¥Õ¥È¥¦¥§
+ * ¥¢¤ÎÍøÍѤˤè¤êľÀÜŪ¤Þ¤¿¤Ï´ÖÀÜŪ¤ËÀ¸¤¸¤¿¤¤¤«¤Ê¤ë»³²¤Ë´Ø¤·¤Æ¤â¡¤¤½
+ * ¤ÎÀÕǤ¤òÉé¤ï¤Ê¤¤¡¥
+ *
+ * @(#) $Id: trace_config.h 264 2007-07-12 08:23:10Z hiro $
+ */
+
+/*
+ * ¥È¥ì¡¼¥¹¥í¥°¤Ë´Ø¤¹¤ëÀßÄê
+ *
+ * ¤³¤Î¥¤¥ó¥¯¥ë¡¼¥É¥Õ¥¡¥¤¥ë¤Ï¡¤target_config.h¤ª¤è¤Ótarget_syssvc.h¤Î
+ * ¤ß¤«¤é¥¤¥ó¥¯¥ë¡¼¥É¤µ¤ì¤ë¡¥Â¾¤Î¥Õ¥¡¥¤¥ë¤«¤éľÀÜ¥¤¥ó¥¯¥ë¡¼¥É¤·¤Æ¤Ï¤Ê
+ * ¤é¤Ê¤¤¡¥
+ */
+
+#ifndef TOPPERS_TRACE_CONFIG_H
+#define TOPPERS_TRACE_CONFIG_H
+
+/*
+ * µ¡Ç½¥³¡¼¥É¤ÎÆɤ߹þ¤ß
+ */
+#include "kernel_fncode.h"
+
+/*
+ * ¥È¥ì¡¼¥¹¥í¥°¥Ð¥Ã¥Õ¥¡¤Î¥µ¥¤¥º
+ */
+#ifndef TCNT_TRACE_BUFFER
+#define TCNT_TRACE_BUFFER 256
+#endif /* TCNT_TRACE_BUFFER */
+
+/*
+ * ¥È¥ì¡¼¥¹»þ¹ï¼èÆÀÍѥϡ¼¥É¥¦¥§¥¢¤Î½é´ü²½
+ */
+#ifndef TRACE_HW_INIT
+#define TRACE_HW_INIT()
+#endif /* TRACE_HW_INIT */
+
+/*
+ * ¥È¥ì¡¼¥¹»þ¹ï¤Î¼èÆÀÊýË¡
+ */
+#ifndef TRACE_GET_TIM
+#ifdef TOPPERS_SUPPORT_GET_UTM
+#define TRACE_GET_TIM() (trace_get_tim_utime())
+#else
+#define TRACE_GET_TIM() (current_time)
+#endif /* TOPPERS_SUPPORT_GET_UTM */
+#endif /* TRACE_GET_TIM */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ * ¥È¥ì¡¼¥¹¥í¥°¤Î¥Ç¡¼¥¿¹½Â¤
+ *
+ * ¥·¥¹¥Æ¥à¥í¥°µ¡Ç½¤Î¥í¥°¾ðÊó¤Î¥Ç¡¼¥¿¹½Â¤¤ÈƱ¤¸¤â¤Î¤òÍѤ¤¤ë¡¥
+ */
+#include <t_syslog.h>
+typedef SYSLOG TRACE;
+
+/*
+ * ¥È¥ì¡¼¥¹¥í¥°¥Ð¥Ã¥Õ¥¡¤È¤½¤ì¤Ë¥¢¥¯¥»¥¹¤¹¤ë¤¿¤á¤Î¥Ý¥¤¥ó¥¿
+ */
+extern TRACE trace_buffer[]; /* ¥È¥ì¡¼¥¹¥í¥°¥Ð¥Ã¥Õ¥¡ */
+extern uint_t trace_count; /* ¥È¥ì¡¼¥¹¥í¥°¥Ð¥Ã¥Õ¥¡Ãæ¤Î¥í¥°¤Î¿ô */
+extern uint_t trace_head; /* ÀèƬ¤Î¥È¥ì¡¼¥¹¥í¥°¤Î³ÊǼ°ÌÃÖ */
+extern uint_t trace_tail; /* ¼¡¤Î¥È¥ì¡¼¥¹¥í¥°¤Î³ÊǼ°ÌÃÖ */
+extern uint_t trace_lost; /* ¼º¤ï¤ì¤¿¥È¥ì¡¼¥¹¤Î¿ô */
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ * ¥È¥ì¡¼¥¹¥â¡¼¥É¤ÎÄêµÁ
+ */
+#define TRACE_STOP UINT_C(0x00) /* ¥È¥ì¡¼¥¹Ää»ß */
+#define TRACE_RINGBUF UINT_C(0x01) /* ¥ê¥ó¥°¥Ð¥Ã¥Õ¥¡¥â¡¼¥É */
+#define TRACE_AUTOSTOP UINT_C(0x02) /* ¼«Æ°Ää»ß¥â¡¼¥É */
+#define TRACE_CLEAR UINT_C(0x04) /* ¥È¥ì¡¼¥¹¥í¥°¤Î¥¯¥ê¥¢ */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ * ¥È¥ì¡¼¥¹¥í¥°µ¡Ç½¤Î½é´ü²½
+ *
+ * ¥È¥ì¡¼¥¹¥í¥°µ¡Ç½¤ò½é´ü²½¤¹¤ë¡¥½é´ü²½¥ë¡¼¥Á¥ó¤È¤·¤ÆÅÐÏ¿¤¹¤ë¤³¤È¤òÁÛ
+ * Äꤷ¤Æ¤¤¤ë¡¥°ú¿ô¤Ë¤è¤ê¼¡¤ÎÆ°ºî¤ò¹Ô¤¦¡¥
+ *
+ * TRACE_STOP¡§½é´ü²½¤Î¤ß¤Ç¥È¥ì¡¼¥¹¤Ï³«»Ï¤·¤Ê¤¤¡¥
+ * TRACE_RINGBUF¡§¥ê¥ó¥°¥Ð¥Ã¥Õ¥¡¥â¡¼¥É¤Ç¥È¥ì¡¼¥¹¤ò³«»Ï¡¥
+ * TRACE_AUTOSTOP¡§¼«Æ°Ää»ß¥â¡¼¥É¤Ç¥È¥ì¡¼¥¹¤ò³«»Ï¡¥
+ */
+extern void trace_initialize(intptr_t exinf);
+
+/*
+ * ¥È¥ì¡¼¥¹¥í¥°¤Î³«»Ï
+ *
+ * ¥È¥ì¡¼¥¹¥í¥°¤ÎµÏ¿¤ò³«»Ï¡¿Ää»ß¤¹¤ë¡¥°ú¿ô¤Ë¤è¤ê¼¡¤ÎÆ°ºî¤ò¹Ô¤¦¡¥
+ *
+ * TRACE_STOP¡§¥È¥ì¡¼¥¹¤òÄä»ß¡¥
+ * TRACE_RINGBUF¡§¥ê¥ó¥°¥Ð¥Ã¥Õ¥¡¥â¡¼¥É¤Ç¥È¥ì¡¼¥¹¤ò³«»Ï¡¥
+ * TRACE_AUTOSTOP¡§¼«Æ°Ää»ß¥â¡¼¥É¤Ç¥È¥ì¡¼¥¹¤ò³«»Ï¡¥
+ * TRACE_CLEAR¡§¥È¥ì¡¼¥¹¥í¥°¤ò¥¯¥ê¥¢¡¥
+ */
+extern ER trace_sta_log(MODE mode);
+
+/*
+ * ¥È¥ì¡¼¥¹¥í¥°¤Î½ñ¹þ¤ß
+ */
+extern ER trace_wri_log(TRACE *p_trace);
+
+/*
+ * ¥È¥ì¡¼¥¹¥í¥°¤ÎÆɽФ·
+ */
+extern ER trace_rea_log(TRACE *p_trace);
+
+/*
+ * ¥È¥ì¡¼¥¹¥í¥°¤Î¥À¥ó¥×¡Êtrace_dump.c¡Ë
+ *
+ * ¥È¥ì¡¼¥¹¥í¥°¤ò¥À¥ó¥×¤¹¤ë¡¥½ªÎ»½èÍý¥ë¡¼¥Á¥ó¤È¤·¤ÆÅÐÏ¿¤¹¤ë¤³¤È¤âÁÛÄê
+ * ¤·¤Æ¤¤¤ë¡¥°ú¿ô¤È¤·¤Æ¡¤¥À¥ó¥×Àè¤È¤Ê¤ëʸ»ú½ÐÎÏ´Ø¿ô¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÅϤ¹¡¥
+ * ¥¿¡¼¥²¥Ã¥È°Í¸¤ÎÄã¥ì¥Ù¥ëʸ»ú½ÐÎϤòÍøÍѤ¹¤ë¾ì¹ç¤Ë¤Ï¡¤target_putc¤òÅÏ
+ * ¤¹¡¥
+ */
+extern void trace_dump(intptr_t exinf);
+
+/*
+ * ¥È¥ì¡¼¥¹¥í¥°¤ò½ÐÎϤ¹¤ë¤¿¤á¤Î¥é¥¤¥Ö¥é¥ê´Ø¿ô
+ */
+extern void trace_write_0(uint_t type);
+extern void trace_write_1(uint_t type, intptr_t arg1);
+extern void trace_write_2(uint_t type, intptr_t arg1, intptr_t arg2);
+extern void trace_write_3(uint_t type, intptr_t arg1, intptr_t arg2, intptr_t arg3);
+extern void trace_write_4(uint_t type, intptr_t arg1, intptr_t arg2, intptr_t arg3, \
+ intptr_t arg4);
+extern void trace_write_5(uint_t type, intptr_t arg1, intptr_t arg2, intptr_t arg3, \
+ intptr_t arg4, intptr_t arg5);
+extern void trace_write_6(uint_t type, intptr_t arg1, intptr_t arg2, intptr_t arg3, \
+ intptr_t arg4, intptr_t arg5, intptr_t arg6);
+
+/*
+ * ¥È¥ì¡¼¥¹¥í¥°¤ò½ÐÎϤ¹¤ë¤¿¤á¤Î¥Þ¥¯¥í
+ */
+
+#define trace_0(type) \
+ trace_write_0(type)
+
+#define trace_1(type, arg1) \
+ trace_write_1(type, (intptr_t)(arg1))
+
+#define trace_2(type, arg1, arg2) \
+ trace_write_2(type, (intptr_t)(arg1), (intptr_t)(arg2))
+
+#define trace_3(type, arg1, arg2, arg3) \
+ trace_write_3(type, (intptr_t)(arg1), (intptr_t)(arg2), \
+ (intptr_t)(arg3))
+
+#define trace_4(type, arg1, arg2, arg3, arg4) \
+ trace_write_4(type, (intptr_t)(arg1), (intptr_t)(arg2), \
+ (intptr_t)(arg3), (intptr_t)(arg4))
+
+#define trace_5(type, arg1, arg2, arg3, arg4, arg5) \
+ trace_write_5(type, (intptr_t)(arg1), (intptr_t)(arg2), \
+ (intptr_t)(arg3), (intptr_t)(arg4), \
+ (intptr_t)(arg5))
+
+#define trace_6(type, arg1, arg2, arg3, arg4, arg5, arg6) \
+ trace_write_6(type, (intptr_t)(arg1), (intptr_t)(arg2), \
+ (intptr_t)(arg3), (intptr_t)(arg4), \
+ (intptr_t)(arg5), (intptr_t)(arg6))
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ * ¥È¥ì¡¼¥¹¥í¥°ÊýË¡¤ÎÀßÄê
+ */
+
+/*
+ * ³ä¹þ¤ß¥Ï¥ó¥É¥é¤ÎÁ°¸å
+ */
+#define LOG_INH_ENTER(inhno) trace_1(LOG_TYPE_INH|LOG_ENTER, inhno)
+#define LOG_INH_LEAVE(inhno) trace_1(LOG_TYPE_INH|LOG_LEAVE, inhno)
+
+/*
+ * ³ä¹þ¤ß¥µ¡¼¥Ó¥¹¥ë¡¼¥Á¥ó¤ÎÁ°¸å
+ */
+#define LOG_ISR_ENTER(intno) trace_1(LOG_TYPE_ISR|LOG_ENTER, intno)
+#define LOG_ISR_LEAVE(intno) trace_1(LOG_TYPE_ISR|LOG_LEAVE, intno)
+
+/*
+ * ¼þ´ü¥Ï¥ó¥É¥é¤ÎÁ°¸å
+ */
+#define LOG_CYC_ENTER(p_cyccb) trace_1(LOG_TYPE_CYC|LOG_ENTER, p_cyccb)
+#define LOG_CYC_LEAVE(p_cyccb) trace_1(LOG_TYPE_CYC|LOG_LEAVE, p_cyccb)
+
+/*
+ * ¥¢¥é¡¼¥à¥Ï¥ó¥É¥é¤ÎÁ°¸å
+ */
+#define LOG_ALM_ENTER(p_almcb) trace_1(LOG_TYPE_ALM|LOG_ENTER, p_almcb)
+#define LOG_ALM_LEAVE(p_almcb) trace_1(LOG_TYPE_ALM|LOG_LEAVE, p_almcb)
+
+/*
+ * CPUÎã³°¥Ï¥ó¥É¥é¤ÎÁ°¸å
+ */
+// #define LOG_EXC_ENTER(excno) trace_1(LOG_TYPE_EXC|LOG_ENTER, excno)
+// #define LOG_EXC_LEAVE(excno) trace_1(LOG_TYPE_EXC|LOG_LEAVE, excno)
+
+/*
+ * ¥¿¥¹¥¯Îã³°½èÍý¥ë¡¼¥Á¥ó
+ */
+#define LOG_TEX_ENTER(p_tcb, texptn) trace_2(LOG_TYPE_TEX|LOG_ENTER, p_tcb, texptn)
+#define LOG_TEX_LEAVE(p_tcb) trace_2(LOG_TYPE_TEX|LOG_LEAVE, p_tcb, texptn)
+
+/*
+ * ¥¿¥¹¥¯¤Î¾õÂÖÊѹ¹
+ */
+#define LOG_TSKSTAT(p_tcb) trace_2(LOG_TYPE_TSKSTAT, p_tcb, p_tcb->tstat)
+
+/*
+ * ¥Ç¥£¥¹¥Ñ¥Ã¥Á¥ã¤ÎÁ°¸å
+ */
+#define LOG_DSP_ENTER(p_tcb) trace_1(LOG_TYPE_DSP|LOG_ENTER, p_tcb)
+#define LOG_DSP_LEAVE(p_tcb) trace_1(LOG_TYPE_DSP|LOG_LEAVE, p_tcb)
+
+/*
+ * ¥·¥¹¥Æ¥à¥í¥°¤Ø¤Î½ñ¤½Ð¤·
+ */
+#define LOG_SYSLOG_WRI_LOG_ENTER(prio, p_syslog) trace_wri_log((TRACE *) p_syslog)
+
+/*
+ * ¥·¥¹¥Æ¥à¥³¡¼¥ë
+ */
+
+/*
+ * ¥¿¥¹¥¯´ÉÍýµ¡Ç½
+ */
+#define LOG_ACT_TSK_ENTER(tskid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_ACT_TSK, tskid)
+#define LOG_ACT_TSK_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_ACT_TSK, ercd)
+
+#define LOG_IACT_TSK_ENTER(tskid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_IACT_TSK, tskid)
+#define LOG_IACT_TSK_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_IACT_TSK, ercd)
+
+#define LOG_CAN_ACT_ENTER(tskid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_CAN_ACT, tskid)
+#define LOG_CAN_ACT_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_CAN_ACT, ercd)
+
+#define LOG_EXT_TSK_ENTER() trace_1(LOG_TYPE_SVC|LOG_ENTER, TFN_EXT_TSK)
+#define LOG_EXT_TSK_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_EXT_TSK, ercd)
+
+#define LOG_TER_TSK_ENTER(tskid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_TER_TSK, tskid)
+#define LOG_TER_TSK_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_TER_TSK, ercd)
+
+#define LOG_CHG_PRI_ENTER(tskid, tskpri) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_CHG_PRI, tskid, tskpri)
+#define LOG_CHG_PRI_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_CHG_PRI, ercd)
+
+#define LOG_GET_PRI_ENTER(tskid, p_tskpri) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_GET_PRI, tskid, p_tskpri)
+#define LOG_GET_PRI_LEAVE(ercd, tskpri) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_GET_PRI, ercd, tskpri)
+
+#define LOG_GET_INF_ENTER(p_exinf) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_GET_INF, p_exinf)
+#define LOG_GET_INF_LEAVE(ercd, exinf) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_GET_INF, ercd, exinf)
+
+
+/*
+ * ¥¿¥¹¥¯¾õÂÖ»²¾Èµ¡Ç½
+ */
+#define LOG_REF_TSK_ENTER(tskid, pk_rtsk) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_REF_TSK, tskid, pk_rtsk)
+#define LOG_REF_TSK_LEAVE(ercd, pk_rtsk) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_REF_TSK, ercd, pk_rtsk)
+
+
+/*
+ * ¥¿¥¹¥¯ÉÕ°Ʊ´üµ¡Ç½
+ */
+#define LOG_SLP_TSK_ENTER() trace_1(LOG_TYPE_SVC|LOG_ENTER, TFN_SLP_TSK)
+#define LOG_SLP_TSK_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_SLP_TSK, ercd)
+
+#define LOG_TSLP_TSK_ENTER(tmout) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_TSLP_TSK, tmout)
+#define LOG_TSLP_TSK_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_TSLP_TSK, ercd)
+
+#define LOG_WUP_TSK_ENTER(tskid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_WUP_TSK, tskid)
+#define LOG_WUP_TSK_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_WUP_TSK, ercd)
+
+#define LOG_IWUP_TSK_ENTER(tskid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_IWUP_TSK, tskid)
+#define LOG_IWUP_TSK_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_IWUP_TSK, ercd)
+
+#define LOG_CAN_WUP_ENTER(tskid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_CAN_WUP, tskid)
+#define LOG_CAN_WUP_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_CAN_WUP, ercd)
+
+#define LOG_REL_WAI_ENTER(tskid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_REL_WAI, tskid)
+#define LOG_REL_WAI_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_REL_WAI, ercd)
+
+#define LOG_IREL_WAI_ENTER(tskid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_IREL_WAI, tskid)
+#define LOG_IREL_WAI_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_IREL_WAI, ercd)
+
+#define LOG_SUS_TSK_ENTER(tskid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_SUS_TSK, tskid)
+#define LOG_SUS_TSK_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_SUS_TSK, ercd)
+
+#define LOG_RSM_TSK_ENTER(tskid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_RSM_TSK, tskid)
+#define LOG_RSM_TSK_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_RSM_TSK, ercd)
+
+#define LOG_DLY_TSK_ENTER(dlytim) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_DLY_TSK, dlytim)
+#define LOG_DLY_TSK_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_DLY_TSK, ercd)
+
+
+/*
+ * ¥¿¥¹¥¯Îã³°½èÍýµ¡Ç½
+ */
+#define LOG_RAS_TEX_ENTER(tskid, rasptn) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_RAS_TEX, tskid, rasptn)
+#define LOG_RAS_TEX_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_RAS_TEX, ercd)
+
+#define LOG_IRAS_TEX_ENTER(tskid, rasptn) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_IRAS_TEX, tskid, rasptn)
+#define LOG_IRAS_TEX_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_IRAS_TEX, ercd)
+
+#define LOG_DIS_TEX_ENTER() trace_1(LOG_TYPE_SVC|LOG_ENTER, TFN_DIS_TEX)
+#define LOG_DIS_TEX_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_DIS_TEX, ercd)
+
+#define LOG_ENA_TEX_ENTER() trace_1(LOG_TYPE_SVC|LOG_ENTER, TFN_ENA_TEX)
+#define LOG_ENA_TEX_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_ENA_TEX, ercd)
+
+#define LOG_SNS_TEX_ENTER() trace_1(LOG_TYPE_SVC|LOG_ENTER, TFN_SNS_TEX)
+#define LOG_SNS_TEX_LEAVE(state) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_SNS_TEX, state)
+
+#define LOG_REF_TEX_ENTER(tskid, pk_rtex) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_REF_TEX, tskid, pk_rtex)
+#define LOG_REF_TEX_LEAVE(ercd, pk_rtex) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_REF_TEX, ercd, pk_rtex)
+
+
+/*
+ * ¥»¥Þ¥Õ¥©µ¡Ç½
+ */
+#define LOG_SIG_SEM_ENTER(semid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_SIG_SEM, semid)
+#define LOG_SIG_SEM_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_SIG_SEM, ercd)
+
+#define LOG_ISIG_SEM_ENTER(semid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_ISIG_SEM, semid)
+#define LOG_ISIG_SEM_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_ISIG_SEM, ercd)
+
+#define LOG_WAI_SEM_ENTER(semid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_WAI_SEM, semid)
+#define LOG_WAI_SEM_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_WAI_SEM, ercd)
+
+#define LOG_POL_SEM_ENTER(semid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_POL_SEM, semid)
+#define LOG_POL_SEM_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_POL_SEM, ercd)
+
+#define LOG_TWAI_SEM_ENTER(semid, tmout) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_TWAI_SEM, semid, tmout)
+#define LOG_TWAI_SEM_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_TWAI_SEM, ercd)
+
+#define LOG_INI_SEM_ENTER(semid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_INI_SEM, semid)
+#define LOG_INI_SEM_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_INI_SEM, ercd)
+
+#define LOG_REF_SEM_ENTER(semid, pk_rsem) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_REF_SEM, semid, pk_rsem)
+#define LOG_REF_SEM_LEAVE(ercd, pk_rsem) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_REF_SEM, ercd, pk_rsem)
+
+
+/*
+ * ¥¤¥Ù¥ó¥È¥Õ¥é¥°
+ */
+#define LOG_SET_FLG_ENTER(flgid, setptn) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_SET_FLG, flgid, setptn)
+#define LOG_SET_FLG_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_SET_FLG, ercd)
+
+#define LOG_ISET_FLG_ENTER(flgid, setptn) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_ISET_FLG, flgid, setptn)
+#define LOG_ISET_FLG_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_ISET_FLG, ercd)
+
+#define LOG_CLR_FLG_ENTER(flgid, clrptn) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_CLR_FLG, flgid, clrptn)
+#define LOG_CLR_FLG_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_CLR_FLG, ercd)
+
+#define LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn) trace_5(LOG_TYPE_SVC|LOG_ENTER, TFN_WAI_FLG, flgid, waiptn, wfmode, p_flgptn)
+#define LOG_WAI_FLG_LEAVE(ercd, flgptn) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_WAI_FLG, ercd, flgptn)
+
+#define LOG_POL_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn) trace_5(LOG_TYPE_SVC|LOG_ENTER, TFN_POL_FLG, flgid, waiptn, wfmode, p_flgptn)
+#define LOG_POL_FLG_LEAVE(ercd, flgptn) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_POL_FLG, ercd, flgptn)
+
+#define LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout) trace_6(LOG_TYPE_SVC|LOG_ENTER, TFN_TWAI_FLG, flgid, waiptn, wfmode, p_flgptn, tmout)
+#define LOG_TWAI_FLG_LEAVE(ercd, flgptn) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_TWAI_FLG, ercd, flgptn)
+
+#define LOG_INI_FLG_ENTER(flgid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_INI_FLG, flgid)
+#define LOG_INI_FLG_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_INI_FLG, ercd)
+
+#define LOG_REF_FLG_ENTER(flgid, pk_rflg) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_REF_FLG, flgid, pk_rflg)
+#define LOG_REF_FLG_LEAVE(ercd, pk_rflg) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_REF_FLG, ercd, pk_rflg)
+
+
+/*
+ * ¥Ç¡¼¥¿¥¥å¡¼µ¯ÍÑ
+ */
+#define LOG_SND_DTQ_ENTER(dtqid, data) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_SND_DTQ, dtqid, data)
+#define LOG_SND_DTQ_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_SND_DTQ, ercd)
+
+#define LOG_PSND_DTQ_ENTER(dtqid, data) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_PSND_DTQ, dtqid, data)
+#define LOG_PSND_DTQ_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_PSND_DTQ, ercd)
+
+#define LOG_IPSND_DTQ_ENTER(dtqid, data) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_IPSND_DTQ, dtqid, data)
+#define LOG_IPSND_DTQ_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_IPSND_DTQ, ercd)
+
+#define LOG_TSND_DTQ_ENTER(dtqid, data, tmout) trace_4(LOG_TYPE_SVC|LOG_ENTER, TFN_TSND_DTQ, dtqid, data, tmout)
+#define LOG_TSND_DTQ_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_TSND_DTQ, ercd)
+
+#define LOG_FSND_DTQ_ENTER(dtqid, data) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_FSND_DTQ, dtqid, data)
+#define LOG_FSND_DTQ_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_FSND_DTQ, ercd)
+
+#define LOG_IFSND_DTQ_ENTER(dtqid, data) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_IFSND_DTQ, dtqid, data)
+#define LOG_IFSND_DTQ_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_IFSND_DTQ, ercd)
+
+#define LOG_RCV_DTQ_ENTER(dtqid, p_data) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_RCV_DTQ, dtqid, p_data)
+#define LOG_RCV_DTQ_LEAVE(ercd, data) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_RCV_DTQ, ercd, data)
+
+#define LOG_PRCV_DTQ_ENTER(dtqid, p_data) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_PRCV_DTQ, dtqid, p_data)
+#define LOG_PRCV_DTQ_LEAVE(ercd, data) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_PRCV_DTQ, ercd, data)
+
+#define LOG_TRCV_DTQ_ENTER(dtqid, p_data, tmout) trace_4(LOG_TYPE_SVC|LOG_ENTER, TFN_TRCV_DTQ, dtqid, p_data, tmout)
+#define LOG_TRCV_DTQ_LEAVE(ercd, data) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_TRCV_DTQ, ercd, data)
+
+#define LOG_INI_DTQ_ENTER(dtqid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_INI_DTQ, dtqid)
+#define LOG_INI_DTQ_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_INI_DTQ, ercd)
+
+#define LOG_REF_DTQ_ENTER(dtqid, pk_rdtq) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_REF_DTQ, dtqid, pk_rdtq)
+#define LOG_REF_DTQ_LEAVE(ercd, pk_rdtq) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_REF_DTQ, ercd, pk_rdtq)
+
+
+/*
+ * Í¥ÀèÅ٥ǡ¼¥¿¥¥å¡¼µ¡Ç½
+ */
+#define LOG_SND_PDQ_ENTER(pdqid, data, datapri) trace_4(LOG_TYPE_SVC|LOG_ENTER, TFN_SND_PDQ, pdqid, data, datapri)
+#define LOG_SND_PDQ_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_SND_PDQ, ercd)
+
+#define LOG_PSND_PDQ_ENTER(pdqid, data, datapri) trace_4(LOG_TYPE_SVC|LOG_ENTER, TFN_PSND_PDQ, pdqid, data, datapri)
+#define LOG_PSND_PDQ_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_PSND_PDQ, ercd)
+
+#define LOG_IPSND_PDQ_ENTER(pdqid, data, datapri) trace_4(LOG_TYPE_SVC|LOG_ENTER, TFN_IPSND_PDQ, pdqid, data, datapri)
+#define LOG_IPSND_PDQ_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_IPSND_PDQ, ercd)
+
+#define LOG_TSND_PDQ_ENTER(pdqid, data, datapri, tmout) trace_5(LOG_TYPE_SVC|LOG_ENTER, TFN_TSND_PDQ, pdqid, data, datapri, tmout)
+#define LOG_TSND_PDQ_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_TSND_PDQ, ercd)
+
+#define LOG_RCV_PDQ_ENTER(pdqid, p_data, p_datapri) trace_4(LOG_TYPE_SVC|LOG_ENTER, TFN_RCV_PDQ, pdqid, p_data, p_datapri)
+#define LOG_RCV_PDQ_LEAVE(ercd, data, datapri) trace_4(LOG_TYPE_SVC|LOG_LEAVE, TFN_RCV_PDQ, ercd, data, datapri)
+
+#define LOG_PRCV_PDQ_ENTER(pdqid, p_data, p_datapri) trace_4(LOG_TYPE_SVC|LOG_ENTER, TFN_PRCV_PDQ, pdqid, p_data, p_datapri)
+#define LOG_PRCV_PDQ_LEAVE(ercd, data, datapri) trace_4(LOG_TYPE_SVC|LOG_LEAVE, TFN_PRCV_PDQ, ercd, data, datapri)
+
+#define LOG_TRCV_PDQ_ENTER(pdqid, p_data, p_datapri, tmout) trace_5(LOG_TYPE_SVC|LOG_ENTER, TFN_TRCV_PDQ, pdqid, p_data, p_datapri, tmout)
+#define LOG_TRCV_PDQ_LEAVE(ercd, data, datapri) trace_4(LOG_TYPE_SVC|LOG_LEAVE, TFN_TRCV_PDQ, ercd, data, datapri)
+
+#define LOG_INI_PDQ_ENTER(pdqid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_INI_PDQ, pdqid)
+#define LOG_INI_PDQ_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_INI_PDQ, ercd)
+
+#define LOG_REF_PDQ_ENTER(pdqid, pk_rpdq) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_REF_PDQ, pdqid, pk_rpdq)
+#define LOG_REF_PDQ_LEAVE(ercd, pk_rpdq) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_REF_PDQ, ercd, pk_rpdq)
+
+
+/*
+ * ¥á¡¼¥ë¥Ü¥Ã¥¯¥¹µ¡Ç½
+ */
+#define LOG_SND_MBX_ENTER(mbxid, pk_msg) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_SND_MBX, mbxid, pk_msg)
+#define LOG_SND_MBX_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_SND_MBX, ercd)
+
+#define LOG_RCV_MBX_ENTER(mbxid, ppk_msg) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_RCV_MBX, mbxid, ppk_msg)
+#define LOG_RCV_MBX_LEAVE(ercd, pk_msg) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_RCV_MBX, ercd, pk_msg)
+
+#define LOG_PRCV_MBX_ENTER(mbxid, ppk_msg) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_PRCV_MBX, mbxid, ppk_msg)
+#define LOG_PRCV_MBX_LEAVE(ercd, pk_msg) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_PRCV_MBX, ercd, pk_msg)
+
+#define LOG_TRCV_MBX_ENTER(mbxid, ppk_msg, tmout) trace_4(LOG_TYPE_SVC|LOG_ENTER, TFN_TRCV_MBX, mbxid, ppk_msg, tmout)
+#define LOG_TRCV_MBX_LEAVE(ercd, pk_msg) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_TRCV_MBX, ercd, pk_msg)
+
+#define LOG_INI_MBX_ENTER(mbxid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_INI_MBX, mbxid)
+#define LOG_INI_MBX_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_INI_MBX, ercd)
+
+#define LOG_REF_MBX_ENTER(mbxid, pk_rmbx) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_REF_MBX, mbxid, pk_rmbx)
+#define LOG_REF_MBX_LEAVE(ercd, pk_rmbx) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_REF_MBX, ercd, pk_rmbx)
+
+
+/*
+ * ¸ÇÄêĹ¥á¥â¥ê¥×¡¼¥ëµ¡Ç½
+ */
+#define LOG_GET_MPF_ENTER(mpfid, p_blk) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_GET_MPF, mpfid, p_blk)
+#define LOG_GET_MPF_LEAVE(ercd, blk) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_GET_MPF, ercd, blk)
+
+#define LOG_PGET_MPF_ENTER(mpfid, p_blk) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_PGET_MPF, mpfid, p_blk)
+#define LOG_PGET_MPF_LEAVE(ercd, blk) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_PGET_MPF, ercd, blk)
+
+#define LOG_TGET_MPF_ENTER(mpfid, p_blk, tmout) trace_4(LOG_TYPE_SVC|LOG_ENTER, TFN_TGET_MPF, mpfid, p_blk, tmout)
+#define LOG_TGET_MPF_LEAVE(ercd, blk) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_TGET_MPF, ercd, blk)
+
+#define LOG_REL_MPF_ENTER(mpfid, blk) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_REL_MPF, mpfid, blk)
+#define LOG_REL_MPF_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_REL_MPF, ercd)
+
+#define LOG_INI_MPF_ENTER(mpfid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_INI_MPF, mpfid)
+#define LOG_INI_MPF_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_INI_MPF, ercd)
+
+#define LOG_REF_MPF_ENTER(mpfid, pk_rmpf) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_REF_MPF, mpfid, pk_rmpf)
+#define LOG_REF_MPF_LEAVE(ercd, pk_rmpf) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_REF_MPF, ercd, pk_rmpf)
+
+
+/*
+ * ¥·¥¹¥Æ¥à»þ¹ï´ÉÍýµ¡Ç½
+ */
+#define LOG_GET_TIM_ENTER(p_systim) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_GET_TIM, p_systim)
+#define LOG_GET_TIM_LEAVE(ercd, systim) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_GET_TIM, ercd, systim)
+
+//¥í¥°Êݸ»þ¤Ëget_utm¤ò»ÈÍѤ¹¤ë¤¿¤á¡¤¥í¥°¤ò͸ú¤Ë¤¹¤ë¤È½Û´Ä¤·¤Æ¤·¤Þ¤¦¤¿¤á̵¸ú¤Ë¤¹¤ë
+//#define LOG_GET_UTM_ENTER(p_sysutm) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_GET_UTM, p_sysutm)
+//#define LOG_GET_UTM_LEAVE(ercd, sysutm) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_GET_UTM, ercd, sysutm)
+
+
+/*
+ * ¼þ´ü¥Ï¥ó¥É¥éµ¡Ç½
+ */
+#define LOG_STA_CYC_ENTER(cycid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_STA_CYC, cycid)
+#define LOG_STA_CYC_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_STA_CYC, ercd)
+
+#define LOG_STP_CYC_ENTER(cycid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_STP_CYC, cycid)
+#define LOG_STP_CYC_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_STP_CYC, ercd)
+
+#define LOG_REF_CYC_ENTER(cycid, pk_rcyc) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_REF_CYC, cycid, pk_rcyc)
+#define LOG_REF_CYC_LEAVE(ercd, pk_rcyc) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_REF_CYC, ercd, pk_rcyc)
+
+
+/*
+ * ¥¢¥é¡¼¥à¥Ï¥ó¥É¥éµ¡Ç½
+ */
+#define LOG_STA_ALM_ENTER(almid, almtim) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_STA_ALM, almid, almtim)
+#define LOG_STA_ALM_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_STA_ALM, ercd)
+
+#define LOG_ISTA_ALM_ENTER(almid, almtim) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_ISTA_ALM, almid, almtim)
+#define LOG_ISTA_ALM_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_ISTA_ALM, ercd)
+
+#define LOG_STP_ALM_ENTER(almid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_STP_ALM, almid)
+#define LOG_STP_ALM_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_STP_ALM, ercd)
+
+#define LOG_ISTP_ALM_ENTER(almid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_ISTP_ALM, almid)
+#define LOG_ISTP_ALM_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_ISTP_ALM, ercd)
+
+#define LOG_REF_ALM_ENTER(almid, pk_ralm) trace_3(LOG_TYPE_SVC|LOG_ENTER, TFN_REF_ALM, almid, pk_ralm)
+#define LOG_REF_ALM_LEAVE(ercd, pk_ralm) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_REF_ALM, ercd, pk_ralm)
+
+
+/*
+ * ³ä¹þ¤ß´ÉÍýµ¡Ç½
+ */
+#define LOG_DIS_INT_ENTER(intno) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_DIS_INT, intno)
+#define LOG_DIS_INT_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_DIS_INT, ercd)
+
+#define LOG_ENA_INT_ENTER(intno) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_ENA_INT, intno)
+#define LOG_ENA_INT_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_ENA_INT, ercd)
+
+#define LOG_CHG_IPM_ENTER(intpri) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_CHG_IPM, intpri)
+#define LOG_CHG_IPM_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_CHG_IPM, ercd)
+
+#define LOG_GET_IPM_ENTER(p_intpri) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_GET_IPM, p_intpri)
+#define LOG_GET_IPM_LEAVE(ercd, intpri) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_GET_IPM, ercd, intpri)
+
+
+/*
+ * CPUÎã³°´ÉÍýµ¡Ç½
+ */
+#define LOG_XSNS_DPN_ENTER(p_excinf) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_XSNS_DPN, p_excinf)
+#define LOG_XSNS_DPN_LEAVE(state) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_XSNS_DPN, state)
+
+#define LOG_XSNS_XPN_ENTER(p_excinf) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_XSNS_XPN, p_excinf)
+#define LOG_XSNS_XPN_LEAVE(state) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_XSNS_XPN, state)
+
+
+/*
+ * ¥·¥¹¥Æ¥à¾õÂÖ´ÉÍýµ¡Ç½
+ */
+#define LOG_ROT_RDQ_ENTER(tskpri) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_ROT_RDQ, tskpri)
+#define LOG_ROT_RDQ_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_ROT_RDQ, ercd)
+
+#define LOG_IROT_RDQ_ENTER(tskpri) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_IROT_RDQ, tskpri)
+#define LOG_IROT_RDQ_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_IROT_RDQ, ercd)
+
+//#define LOG_GET_TID_ENTER(p_tskid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_GET_TID, p_tskid)
+//#define LOG_GET_TID_LEAVE(ercd, tskid) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_GET_TID, ercd, tskid)
+
+//#define LOG_IGET_TID_ENTER(p_tskid) trace_2(LOG_TYPE_SVC|LOG_ENTER, TFN_IGET_TID, p_tskid)
+//#define LOG_IGET_TID_LEAVE(ercd, tskid) trace_3(LOG_TYPE_SVC|LOG_LEAVE, TFN_IGET_TID, ercd, tskid)
+
+//#define LOG_LOC_CPU_ENTER() trace_1(LOG_TYPE_SVC|LOG_ENTER, TFN_LOC_CPU)
+//#define LOG_LOC_CPU_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_LOC_CPU, ercd)
+
+//#define LOG_ILOC_CPU_ENTER() trace_1(LOG_TYPE_SVC|LOG_ENTER, TFN_ILOC_CPU)
+//#define LOG_ILOC_CPU_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_ILOC_CPU, ercd)
+
+//#define LOG_UNL_CPU_ENTER() trace_1(LOG_TYPE_SVC|LOG_ENTER, TFN_UNL_CPU)
+//#define LOG_UNL_CPU_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_UNL_CPU, ercd)
+
+//#define LOG_IUNL_CPU_ENTER() trace_1(LOG_TYPE_SVC|LOG_ENTER, TFN_IUNL_CPU)
+//#define LOG_IUNL_CPU_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_IUNL_CPU, ercd)
+
+//#define LOG_DIS_DSP_ENTER() trace_1(LOG_TYPE_SVC|LOG_ENTER, TFN_DIS_DSP)
+//#define LOG_DIS_DSP_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_DIS_DSP, ercd)
+
+//#define LOG_ENA_DSP_ENTER() trace_1(LOG_TYPE_SVC|LOG_ENTER, TFN_ENA_DSP)
+//#define LOG_ENA_DSP_LEAVE(ercd) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_ENA_DSP, ercd)
+
+//#define LOG_SNS_CTX_ENTER() trace_1(LOG_TYPE_SVC|LOG_ENTER, TFN_SNS_CTX)
+//#define LOG_SNS_CTX_LEAVE(state) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_SNS_CTX, state)
+
+//#define LOG_SNS_LOC_ENTER() trace_1(LOG_TYPE_SVC|LOG_ENTER, TFN_SNS_LOC)
+//#define LOG_SNS_LOC_LEAVE(state) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_SNS_LOC, state)
+
+//#define LOG_SNS_DSP_ENTER() trace_1(LOG_TYPE_SVC|LOG_ENTER, TFN_SNS_DSP)
+//#define LOG_SNS_DSP_LEAVE(state) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_SNS_DSP, state)
+
+//#define LOG_SNS_DPN_ENTER() trace_1(LOG_TYPE_SVC|LOG_ENTER, TFN_SNS_DPN)
+//#define LOG_SNS_DPN_LEAVE(state) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_SNS_DPN, state)
+
+//#define LOG_SNS_KER_ENTER() trace_1(LOG_TYPE_SVC|LOG_ENTER, TFN_SNS_KER)
+//#define LOG_SNS_KER_LEAVE(state) trace_2(LOG_TYPE_SVC|LOG_LEAVE, TFN_SNS_KER, state)
+
+
+/*
+ * ¥«¡¼¥Í¥ë¤Î½é´ü²½¤È½ªÎ»½èÍý
+ */
+#define LOG_KER_ENTER()
+#define LOG_KER_LEAVE()
+#define LOG_EXT_KER_ENTER() trace_1(LOG_TYPE_SVC|LOG_ENTER, TFN_EXT_KER)
+#define LOG_EXT_KER_LEAVE()
+
+
+/*
+ * ¥·¥¹¥Æ¥à¥í¥°µ¡Ç½
+ */
+#define LOG_SYSLOG_WRI_LOG_LEAVE(ercd)
+#define LOG_SYSLOG_REA_LOG_ENTER(p_syslog)
+#define LOG_SYSLOG_REA_LOG_LEAVE(ercd, p_syslog)
+#define LOG_SYSLOG_MSK_LOG_ENTER(logmask, lowmask)
+#define LOG_SYSLOG_MSK_LOG_LEAVE(ercd)
+#define LOG_SYSLOG_REF_LOG_ENTER(pk_rlog)
+#define LOG_SYSLOG_REF_LOG_LEAVE(pk_rlog)
+
+#endif /* TOPPERS_TRACE_CONFIG_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2007,2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * ¾åµÃøºî¸¢¼Ô¤Ï¡¤°Ê²¼¤Î(1)¡Á(4)¤Î¾ò·ï¤òËþ¤¿¤¹¾ì¹ç¤Ë¸Â¤ê¡¤ËÜ¥½¥Õ¥È¥¦¥§
+ * ¥¢¡ÊËÜ¥½¥Õ¥È¥¦¥§¥¢¤ò²þÊѤ·¤¿¤â¤Î¤ò´Þ¤à¡¥°Ê²¼Æ±¤¸¡Ë¤ò»ÈÍÑ¡¦Ê£À½¡¦²þ
+ * ÊÑ¡¦ºÆÇÛÉۡʰʲ¼¡¤ÍøÍѤȸƤ֡ˤ¹¤ë¤³¤È¤ò̵½þ¤ÇµöÂú¤¹¤ë¡¥
+ * (1) ËÜ¥½¥Õ¥È¥¦¥§¥¢¤ò¥½¡¼¥¹¥³¡¼¥É¤Î·Á¤ÇÍøÍѤ¹¤ë¾ì¹ç¤Ë¤Ï¡¤¾åµ¤ÎÃøºî
+ * ¸¢É½¼¨¡¤¤³¤ÎÍøÍѾò·ï¤ª¤è¤Ó²¼µ¤Î̵Êݾڵ¬Ä꤬¡¤¤½¤Î¤Þ¤Þ¤Î·Á¤Ç¥½¡¼
+ * ¥¹¥³¡¼¥ÉÃæ¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ë¤³¤È¡¥
+ * (2) ËÜ¥½¥Õ¥È¥¦¥§¥¢¤ò¡¤¥é¥¤¥Ö¥é¥ê·Á¼°¤Ê¤É¡¤Â¾¤Î¥½¥Õ¥È¥¦¥§¥¢³«È¯¤Ë»È
+ * ÍѤǤ¤ë·Á¤ÇºÆÇÛÉÛ¤¹¤ë¾ì¹ç¤Ë¤Ï¡¤ºÆÇÛÉÛ¤Ëȼ¤¦¥É¥¥å¥á¥ó¥È¡ÊÍøÍÑ
+ * ¼Ô¥Þ¥Ë¥å¥¢¥ë¤Ê¤É¡Ë¤Ë¡¤¾åµ¤ÎÃøºî¸¢É½¼¨¡¤¤³¤ÎÍøÍѾò·ï¤ª¤è¤Ó²¼µ
+ * ¤Î̵Êݾڵ¬Äê¤ò·ÇºÜ¤¹¤ë¤³¤È¡¥
+ * (3) ËÜ¥½¥Õ¥È¥¦¥§¥¢¤ò¡¤µ¡´ï¤ËÁȤ߹þ¤à¤Ê¤É¡¤Â¾¤Î¥½¥Õ¥È¥¦¥§¥¢³«È¯¤Ë»È
+ * ÍѤǤ¤Ê¤¤·Á¤ÇºÆÇÛÉÛ¤¹¤ë¾ì¹ç¤Ë¤Ï¡¤¼¡¤Î¤¤¤º¤ì¤«¤Î¾ò·ï¤òËþ¤¿¤¹¤³
+ * ¤È¡¥
+ * (a) ºÆÇÛÉÛ¤Ëȼ¤¦¥É¥¥å¥á¥ó¥È¡ÊÍøÍѼԥޥ˥奢¥ë¤Ê¤É¡Ë¤Ë¡¤¾åµ¤ÎÃø
+ * ºî¸¢É½¼¨¡¤¤³¤ÎÍøÍѾò·ï¤ª¤è¤Ó²¼µ¤Î̵Êݾڵ¬Äê¤ò·ÇºÜ¤¹¤ë¤³¤È¡¥
+ * (b) ºÆÇÛÉۤηÁÂÖ¤ò¡¤Ê̤ËÄê¤á¤ëÊýË¡¤Ë¤è¤Ã¤Æ¡¤TOPPERS¥×¥í¥¸¥§¥¯¥È¤Ë
+ * Êó¹ð¤¹¤ë¤³¤È¡¥
+ * (4) ËÜ¥½¥Õ¥È¥¦¥§¥¢¤ÎÍøÍѤˤè¤êľÀÜŪ¤Þ¤¿¤Ï´ÖÀÜŪ¤ËÀ¸¤¸¤ë¤¤¤«¤Ê¤ë»
+ * ³²¤«¤é¤â¡¤¾åµÃøºî¸¢¼Ô¤ª¤è¤ÓTOPPERS¥×¥í¥¸¥§¥¯¥È¤òÌÈÀÕ¤¹¤ë¤³¤È¡¥
+ * ¤Þ¤¿¡¤ËÜ¥½¥Õ¥È¥¦¥§¥¢¤Î¥æ¡¼¥¶¤Þ¤¿¤Ï¥¨¥ó¥É¥æ¡¼¥¶¤«¤é¤Î¤¤¤«¤Ê¤ëÍý
+ * ͳ¤Ë´ð¤Å¤¯ÀÁµá¤«¤é¤â¡¤¾åµÃøºî¸¢¼Ô¤ª¤è¤ÓTOPPERS¥×¥í¥¸¥§¥¯¥È¤ò
+ * ÌÈÀÕ¤¹¤ë¤³¤È¡¥
+ *
+ * ËÜ¥½¥Õ¥È¥¦¥§¥¢¤Ï¡¤ÌµÊݾڤÇÄ󶡤µ¤ì¤Æ¤¤¤ë¤â¤Î¤Ç¤¢¤ë¡¥¾åµÃøºî¸¢¼Ô¤ª
+ * ¤è¤ÓTOPPERS¥×¥í¥¸¥§¥¯¥È¤Ï¡¤ËÜ¥½¥Õ¥È¥¦¥§¥¢¤Ë´Ø¤·¤Æ¡¤ÆÃÄê¤Î»ÈÍÑÌÜŪ
+ * ¤ËÂФ¹¤ëŬ¹çÀ¤â´Þ¤á¤Æ¡¤¤¤¤«¤Ê¤ëÊݾڤâ¹Ô¤ï¤Ê¤¤¡¥¤Þ¤¿¡¤ËÜ¥½¥Õ¥È¥¦¥§
+ * ¥¢¤ÎÍøÍѤˤè¤êľÀÜŪ¤Þ¤¿¤Ï´ÖÀÜŪ¤ËÀ¸¤¸¤¿¤¤¤«¤Ê¤ë»³²¤Ë´Ø¤·¤Æ¤â¡¤¤½
+ * ¤ÎÀÕǤ¤òÉé¤ï¤Ê¤¤¡¥
+ *
+ * @(#) $Id$
+ */
+
+/*
+ * ¥È¥ì¡¼¥¹¥í¥°¤Î¥À¥ó¥×
+ */
+
+#include "kernel_impl.h"
+#include "task.h"
+#include "cyclic.h"
+#include "alarm.h"
+#include <log_output.h>
+
+/*
+ * ¥«¡¼¥Í¥ë¾ðÊó¤Î¼è½Ð¤·
+ */
+static intptr_t
+get_tskid(intptr_t info)
+{
+ TCB *p_tcb;
+ ID tskid;
+
+ p_tcb = (TCB *) info;
+ if (p_tcb == NULL) {
+ tskid = 0;
+ }
+ else {
+ tskid = TSKID(p_tcb);
+ }
+ return((intptr_t) tskid);
+}
+
+static intptr_t
+get_tskstat(intptr_t info)
+{
+ uint_t tstat;
+ const char *tstatstr;
+
+ tstat = (uint_t) info;
+
+ switch (tstat & (TS_RUNNABLE|TS_WAITING|TS_SUSPENDED)) {
+ case TS_DORMANT:
+ tstatstr = "DORMANT";
+ break;
+ case TS_RUNNABLE:
+ tstatstr = "RUNNABLE";
+ break;
+ case TS_WAITING:
+ tstatstr = "WAITING";
+ break;
+ case TS_SUSPENDED:
+ tstatstr = "SUSPENDED";
+ break;
+ case TS_WAITING|TS_SUSPENDED:
+ tstatstr = "WAITING-SUSPENDED";
+ break;
+ default:
+ tstatstr = "unknown state";
+ break;
+ }
+
+ return((intptr_t) tstatstr);
+}
+
+
+/*
+ * ¥¿¥¹¥¯´ÉÍý¡¦¥¿¥¹¥¯ÉÕ°Ʊ´üµ¡Ç½ - Æþ¸ý¥í¥°
+ */
+static intptr_t
+trace_print_tskenter(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+
+ /* ¥¿¥¹¥¯´ÉÍýµ¡Ç½ */
+ case TFN_ACT_TSK:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to act_tsk tskid=%d.";
+ break;
+ case TFN_IACT_TSK:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to iact_tsk tskid=%d.";
+ break;
+ case TFN_CAN_ACT:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to can_act tskid=%d.";
+ break;
+ case TFN_EXT_TSK:
+ tracemsg = "enter to ext_tsk.";
+ break;
+ case TFN_TER_TSK:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to ter_tsk tskid=%d.";
+ break;
+ case TFN_CHG_PRI:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "enter to chg_pri tskid=%d. tskpri=%d.";
+ break;
+ case TFN_GET_PRI:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "enter to get_pri tskid=%d. p_tskpri=%d.";
+ break;
+ case TFN_GET_INF:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to get_inf p_exinf=%d.";
+ break;
+ case TFN_REF_TSK:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to ref_tsk tskid=%d.";
+ break;
+
+ /* ¥¿¥¹¥¯ÉÕ°Ʊ´üµ¡Ç½ */
+ case TFN_SLP_TSK:
+ tracemsg = "enter to slp_tsk.";
+ break;
+ case TFN_TSLP_TSK:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to tslp_tsk tmout=%d.";
+ break;
+ case TFN_WUP_TSK:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to wup_tsk tskid=%d.";
+ break;
+ case TFN_IWUP_TSK:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to iwup_tsk tskid=%d.";
+ break;
+ case TFN_CAN_WUP:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to can_wup tskid=%d.";
+ break;
+ case TFN_REL_WAI:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to rel_wai tskid=%d.";
+ break;
+ case TFN_IREL_WAI:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to irel_wai tskid=%d.";
+ break;
+ case TFN_SUS_TSK:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to sus_tsk tskid=%d.";
+ break;
+ case TFN_RSM_TSK:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to rsm_tsk tskid=%d.";
+ break;
+ case TFN_DLY_TSK:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to dly_tsk dlytim=%d.";
+ break;
+ default:
+ tracemsg = "unknown service call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¥¿¥¹¥¯´ÉÍý¡¦¥¿¥¹¥¯ÉÕ°Ʊ´üµ¡Ç½ - ½Ð¸ý¥í¥°
+ */
+static intptr_t
+trace_print_tskleave(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+
+ /* ¥¿¥¹¥¯´ÉÍýµ¡Ç½ */
+ case TFN_ACT_TSK:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from act_tsk ercd=%d.";
+ break;
+ case TFN_IACT_TSK:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from iact_tsk ercd=%d.";
+ break;
+ case TFN_CAN_ACT:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from can_act ercd=%d.";
+ break;
+ case TFN_EXT_TSK:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ext_tsk ercd=%d.";
+ break;
+ case TFN_TER_TSK:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ter_tsk ercd=%d.";
+ break;
+ case TFN_CHG_PRI:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from chg_pri ercd=%d.";
+ break;
+ case TFN_GET_PRI:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "leave from get_pri ercd=%d. tskpri=%d.";
+ break;
+ case TFN_GET_INF:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "leave from get_inf ercd=%d. exinf=%d.";
+ break;
+ case TFN_REF_TSK:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ref_tsk ercd=%d.";
+ break;
+
+ /* ¥¿¥¹¥¯ÉÕ°Ʊ´üµ¡Ç½ */
+ case TFN_SLP_TSK:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from slp_tsk ercd=%d.";
+ break;
+ case TFN_TSLP_TSK:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from tslp_tsk ercd=%d.";
+ break;
+ case TFN_WUP_TSK:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from wup_tsk ercd=%d.";
+ break;
+ case TFN_IWUP_TSK:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from iwup_tsk ercd=%d.";
+ break;
+ case TFN_CAN_WUP:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from can_wup ercd=%d.";
+ break;
+ case TFN_REL_WAI:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from rel_wai ercd=%d.";
+ break;
+ case TFN_IREL_WAI:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from irel_wai ercd=%d.";
+ break;
+ case TFN_SUS_TSK:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from sus_tsk ercd=%d.";
+ break;
+ case TFN_RSM_TSK:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from rsm_tsk ercd=%d.";
+ break;
+ case TFN_DLY_TSK:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from dly_tsk ercd=%d.";
+ break;
+ default:
+ tracemsg = "unknown tsk service call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¥¿¥¹¥¯Îã³°½èÍýµ¡Ç½ - Æþ¸ý¥í¥°
+ */
+static intptr_t
+trace_print_texenter(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_RAS_TEX:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to ras_tex tskid=%d. rasptn=%d.";
+ break;
+ case TFN_IRAS_TEX:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to iras_tex tskid=%d. rasptn=%d.";
+ break;
+ case TFN_DIS_TEX:
+ tracemsg = "enter to dis_tex.";
+ break;
+ case TFN_ENA_TEX:
+ tracemsg = "enter to ena_tex.";
+ break;
+ case TFN_SNS_TEX:
+ tracemsg = "enter to sns_tex.";
+ break;
+ case TFN_REF_TEX:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to ref_tex tskid=%d.";
+ break;
+ default:
+ tracemsg = "unknown service call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¥¿¥¹¥¯Îã³°½èÍýµ¡Ç½ - ½Ð¸ý¥í¥°
+ */
+static intptr_t
+trace_print_texleave(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_RAS_TEX:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ras_tex ercd=%d.";
+ break;
+ case TFN_IRAS_TEX:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from iras_tex ercd=%d.";
+ break;
+ case TFN_DIS_TEX:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from dis_tex ercd=%d.";
+ break;
+ case TFN_ENA_TEX:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ena_tex ercd=%d";
+ break;
+ case TFN_SNS_TEX:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from sns_tex state=%d.";
+ break;
+ case TFN_REF_TEX:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ref_tex ercd=%d.";
+ break;
+ default:
+ tracemsg = "unknown service call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¥»¥Þ¥Õ¥©µ¡Ç½ - Æþ¸ý¥í¥°
+ */
+static intptr_t
+trace_print_sementer(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_SIG_SEM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to sig_sem semid=%d.";
+ break;
+ case TFN_ISIG_SEM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to isig_sem semid=%d.";
+ break;
+ case TFN_WAI_SEM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to wai_sem semid=%d.";
+ break;
+ case TFN_POL_SEM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to pol_sem semid=%d.";
+ break;
+ case TFN_TWAI_SEM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to twai_sem semid=%d.";
+ break;
+ case TFN_INI_SEM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to ini_sem semid=%d.";
+ break;
+ case TFN_REF_SEM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to ref_sem semid=%d.";
+ break;
+ default:
+ tracemsg = "unknown service call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¥»¥Þ¥Õ¥©µ¡Ç½ - ½Ð¸ý¥í¥°
+ */
+static intptr_t
+trace_print_semleave(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_SIG_SEM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from sig_sem ercd=%d.";
+ break;
+ case TFN_ISIG_SEM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from isig_sem ercd=%d.";
+ break;
+ case TFN_WAI_SEM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from wai_sem ercd=%d.";
+ break;
+ case TFN_POL_SEM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from pol_sem ercd=%d.";
+ break;
+ case TFN_TWAI_SEM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from twai_sem ercd=%d.";
+ break;
+ case TFN_INI_SEM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ini_sem ercd=%d.";
+ break;
+ case TFN_REF_SEM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ref_sem ercd=%d.";
+ break;
+ default:
+ tracemsg = "unknown servic call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¥¤¥Ù¥ó¥È¥Õ¥é¥°µ¡Ç½ - Æþ¸ý¥í¥°
+ */
+static intptr_t
+trace_print_flgenter(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_SET_FLG:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "enter to set_flg flgid=%d. setptn=%d.";
+ break;
+ case TFN_ISET_FLG:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "enter to iset_flg flgid=%d. setptn=%d.";
+ break;
+ case TFN_CLR_FLG:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "enter to clr_flg flgid=%d. clrptn=%d.";
+ break;
+ case TFN_WAI_FLG:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ info[2] = (intptr_t)trace->loginfo[3];
+ info[3] = (intptr_t)trace->loginfo[4];
+ tracemsg = "enter to wai_flg flgid=%d. waiptn=%d. wfmode=%d. p_flgptn=%d.";
+ break;
+ case TFN_POL_FLG:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ info[2] = (intptr_t)trace->loginfo[3];
+ info[3] = (intptr_t)trace->loginfo[4];
+ tracemsg = "enter to pol_flg flgid=%d. waiptn=%d. wfmode=%d. p_flgptn=%d.";
+ break;
+ case TFN_TWAI_FLG:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ info[2] = (intptr_t)trace->loginfo[3];
+ info[3] = (intptr_t)trace->loginfo[4];
+ info[4] = (intptr_t)trace->loginfo[5];
+ tracemsg = "enter to twai_flg flgid=%d. waiptn=%d. wfmode=%d. p_flgptn=%d. tmout=%d.";
+ break;
+ case TFN_INI_FLG:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to ini_flg flgid=%d.";
+ break;
+ case TFN_REF_FLG:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to ref_flg flgid=%d.";
+ break;
+ default:
+ tracemsg = "unknown service call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¥¤¥Ù¥ó¥È¥Õ¥é¥°µ¡Ç½ - ½Ð¸ý¥í¥°
+ */
+static intptr_t
+trace_print_flgleave(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_SET_FLG:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from set_flg ercd=%d.";
+ break;
+ case TFN_ISET_FLG:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from iset_flg ercd=%d.";
+ break;
+ case TFN_CLR_FLG:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from clr_flg ercd=%d.";
+ break;
+ case TFN_WAI_FLG:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "leave from wai_flg ercd=%d. flgptn=%d.";
+ break;
+ case TFN_POL_FLG:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "leave from pol_flg ercd=%d. flgptn=%d.";
+ break;
+ case TFN_TWAI_FLG:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "leave from twai_flg ercd=%d. flgptn=%d.";
+ break;
+ case TFN_INI_FLG:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ini_flg ercd=%d.";
+ break;
+ case TFN_REF_FLG:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ref_flg ercd=%d.";
+ break;
+ default:
+ tracemsg = "unknown servic call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¥Ç¡¼¥¿¥¥å¡¼µ¡Ç½ - Æþ¸ý¥í¥°
+ */
+static intptr_t
+trace_print_dtqenter(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_SND_DTQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "enter to snd_dtq dtqid=%d. data=%d.";
+ break;
+ case TFN_PSND_DTQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "enter to psnd_dtq dtqid=%d. data=%d.";
+ break;
+ case TFN_IPSND_DTQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "enter to ipsnd_dtq dtqid=%d. data=%d.";
+ break;
+ case TFN_TSND_DTQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ info[2] = (intptr_t)trace->loginfo[3];
+ tracemsg = "enter to tsnd_dtq dtqid=%d. data=%d. tmout=%d.";
+ break;
+ case TFN_FSND_DTQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "enter to fsnd_dtq dtqid=%d. data=%d.";
+ break;
+ case TFN_IFSND_DTQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "enter to ifsnd_dtq dtqid=%d. data=%d.";
+ break;
+ case TFN_RCV_DTQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "enter to rcv_dtq dtqid=%d. p_data=%d.";
+ break;
+ case TFN_PRCV_DTQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "enter to prcv_dtq dtqid=%d. p_data=%d.";
+ break;
+ case TFN_TRCV_DTQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ info[2] = (intptr_t)trace->loginfo[3];
+ tracemsg = "enter to trcv_dtq dtqid=%d. p_data=%d. tmout=%d.";
+ break;
+ case TFN_INI_DTQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to ini_dtq dtqid=%d.";
+ break;
+ case TFN_REF_DTQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to ref_dtq dtqid=%d.";
+ break;
+ default:
+ tracemsg = "unknown service call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¥Ç¡¼¥¿¥¥å¡¼µ¡Ç½ - ½Ð¸ý¥í¥°
+ */
+static intptr_t
+trace_print_dtqleave(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_SND_DTQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from snd_dtq ercd=%d.";
+ break;
+ case TFN_PSND_DTQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from psnd_dtq ercd=%d.";
+ break;
+ case TFN_IPSND_DTQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ipsnd_dtq ercd=%d.";
+ break;
+ case TFN_TSND_DTQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from tsnd_dtq ercd=%d.";
+ break;
+ case TFN_FSND_DTQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from fsnd_dtq ercd=%d.";
+ break;
+ case TFN_IFSND_DTQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ifsnd_dtq ercd=%d.";
+ break;
+ case TFN_RCV_DTQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "leave from rcv_dtq ercd=%d. data=%d.";
+ break;
+ case TFN_PRCV_DTQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "leave from prcv_dtq ercd=%d. data=%d.";
+ break;
+ case TFN_TRCV_DTQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "leave from trcv_dtq ercd=%d. data=%d.";
+ break;
+ case TFN_INI_DTQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ini_dtq ercd=%d.";
+ break;
+ case TFN_REF_DTQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ref_dtq ercd=%d.";
+ break;
+ default:
+ tracemsg = "unknown service call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+/*
+ * Í¥ÀèÅ٥ǡ¼¥¿¥¥å¡¼µ¡Ç½ -Æþ¸ý¥í¥°
+ */
+static intptr_t
+trace_print_pdqenter(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_SND_PDQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ info[2] = (intptr_t)trace->loginfo[3];
+ tracemsg = "enter to snd_pdq pdqid=%d. data=%d. datapri=%d.";
+ break;
+ case TFN_PSND_PDQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ info[2] = (intptr_t)trace->loginfo[3];
+ tracemsg = "enter to psnd_pdq pdqid=%d. data=%d. datapri=%d.";
+ break;
+ case TFN_IPSND_PDQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ info[2] = (intptr_t)trace->loginfo[3];
+ tracemsg = "enter to ipsnd_pdq pdqid=%d. data=%d. datapri=%d.";
+ break;
+ case TFN_TSND_PDQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ info[2] = (intptr_t)trace->loginfo[3];
+ info[3] = (intptr_t)trace->loginfo[4];
+ tracemsg = "enter to tsnd_pdq pdqid=%d. data=%d. datapri=%d. tmout=%d.";
+ break;
+ case TFN_RCV_PDQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ info[2] = (intptr_t)trace->loginfo[3];
+ tracemsg = "enter to rcv_pdq pdqid=%d. p_data=%d. p_datapri=%d.";
+ break;
+ case TFN_PRCV_PDQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ info[2] = (intptr_t)trace->loginfo[3];
+ tracemsg = "enter to prcv_pdq pdqid=%d. p_data=%d. p_datapri=%d.";
+ break;
+ case TFN_TRCV_PDQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ info[2] = (intptr_t)trace->loginfo[3];
+ info[3] = (intptr_t)trace->loginfo[4];
+ tracemsg = "enter to trcv_pdq pdqid=%d. p_data=%d. p_datapri=%d. tmout=%d.";
+ break;
+ case TFN_INI_PDQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to ini_pdq pdqid=%d.";
+ break;
+ case TFN_REF_PDQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to ref_pdq pdqid=%d.";
+ break;
+ default:
+ tracemsg = "unknown service call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * Í¥ÀèÅ٥ǡ¼¥¿¥¥å¡¼µ¡Ç½ - ½Ð¸ý¥í¥°
+ */
+static intptr_t
+trace_print_pdqleave(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_SND_PDQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from snd_pdq ercd=%d.";
+ break;
+ case TFN_PSND_PDQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from psnd_pdq ercd=%d.";
+ break;
+ case TFN_IPSND_PDQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ipsnd_pdq ercd=%d.";
+ break;
+ case TFN_TSND_PDQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from tsnd_pdq ercd=%d.";
+ break;
+ case TFN_RCV_PDQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ info[2] = (intptr_t)trace->loginfo[3];
+ tracemsg = "leave from rcv_pdq ercd=%d. data=%d. datapri=%d.";
+ break;
+ case TFN_PRCV_PDQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ info[2] = (intptr_t)trace->loginfo[3];
+ tracemsg = "leave from prcv_pdq ercd=%d. data=%d. datapri=%d.";
+ break;
+ case TFN_TRCV_PDQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ info[2] = (intptr_t)trace->loginfo[3];
+ tracemsg = "leave from trcv_pdq ercd=%d. data=%d. datapri=%d.";
+ break;
+ case TFN_INI_PDQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ini_pdq ercd=%d.";
+ break;
+ case TFN_REF_PDQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ref_pdq ercd=%d.";
+ break;
+ default:
+ tracemsg = "unknown service call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¥á¡¼¥ë¥Ü¥Ã¥¯¥¹µ¡Ç½ - Æþ¸ý¥í¥°
+ */
+static intptr_t
+trace_print_mbxenter(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_SND_MBX:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "enter to snd_mbx mbxid=%d. pk_msg=%s.";
+ break;
+ case TFN_RCV_MBX:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "enter to rcv_mbx mbxid=%d. ppk_msg=%s.";
+ break;
+ case TFN_PRCV_MBX:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "enter to prcv_mbx mbxid=%d. ppk_msg=%s.";
+ break;
+ case TFN_TRCV_MBX:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ info[2] = (intptr_t)trace->loginfo[3];
+ tracemsg = "enter to trcv_mbx mbxid=%d. ppk_msg=%s. tmout=%d.";
+ break;
+ case TFN_INI_MBX:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to ini_mbx mbxid=%d.";
+ break;
+ case TFN_REF_MBX:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to ref_mbx mbxid=%d.";
+ break;
+ default:
+ tracemsg = "unknown service call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¥á¡¼¥ë¥Ü¥Ã¥¯¥¹µ¡Ç½ - ½Ð¸ý¥í¥°
+ */
+static intptr_t
+trace_print_mbxleave(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_SND_MBX:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from snd_mbx ercd=%d.";
+ break;
+ case TFN_RCV_MBX:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "leave from rcv_mbx ercd=%d. pk_msg=%s.";
+ break;
+ case TFN_PRCV_MBX:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "leave from prcv_mbx ercd=%d. pk_msg=%s.";
+ break;
+ case TFN_TRCV_MBX:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "leave from trcv_mbx ercd=%d. pk_msg=%s.";
+ break;
+ case TFN_INI_MBX:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ini_mbx ercd=%d.";
+ break;
+ case TFN_REF_MBX:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ref_mbx ercd=%d.";
+ break;
+ default:
+ tracemsg = "unknown service call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¸ÇÄêĹ¥á¥â¥ê¥×¡¼¥ëµ¡Ç½ - Æþ¸ý¥í¥°
+ */
+static intptr_t
+trace_print_mpfenter(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_GET_MPF:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "enter to get_mpf mpfid=%d. p_blk=%d.";
+ break;
+ case TFN_PGET_MPF:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "enter to pget_mpf mpfid=%d. p_blk=%d.";
+ break;
+ case TFN_TGET_MPF:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ info[2] = (intptr_t)trace->loginfo[3];
+ tracemsg = "enter to tget_mpf mpfid=%d. p_blk=%d. tmout=%d.";
+ break;
+ case TFN_REL_MPF:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "enter to rel_mpf mpfid=%d. blk=%d.";
+ break;
+ case TFN_INI_MPF:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to ini_mpf mpfid=%d.";
+ break;
+ case TFN_REF_MPF:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to ref_mpf mpfid=%d.";
+ break;
+ default:
+ tracemsg = "unknown service call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¸ÇÄêĹ¥á¥â¥ê¥×¡¼¥ëµ¡Ç½ - ½Ð¸ý¥í¥°
+ */
+static intptr_t
+trace_print_mpfleave(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_GET_MPF:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "leave from get_mpf ercd=%d. blk=%d.";
+ break;
+ case TFN_PGET_MPF:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "leave from pget_mpf ercd=%d. blk=%d.";
+ break;
+ case TFN_TGET_MPF:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "leave from tget_mpf ercd=%d. blk=%d.";
+ break;
+ case TFN_REL_MPF:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from rel_mpf ercd=%d";
+ break;
+ case TFN_INI_MPF:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ini_mpf ercd=%d.";
+ break;
+ case TFN_REF_MPF:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ref_mpf ercd=%d.";
+ break;
+ default:
+ tracemsg = "unknown service call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¥·¥¹¥Æ¥à»þ¹ï´ÉÍýµ¡Ç½ - Æþ¸ý¥í¥°
+ */
+static intptr_t
+trace_print_timenter(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_GET_TIM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to get_tim p_systim=%d.";
+ break;
+ case TFN_GET_UTM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to get_utm p_systum=%d.";
+ break;
+ default:
+ tracemsg = "unknown service call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¥·¥¹¥Æ¥à»þ¹ï´ÉÍýµ¡Ç½ - ½Ð¸ý¥í¥°
+ */
+static intptr_t
+trace_print_timleave(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_GET_TIM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "leave from get_tim ercd=%d. systim=%d.";
+ break;
+ case TFN_GET_UTM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "leave from get_utm ercd=%d. systum=%d.";
+ break;
+ default:
+ tracemsg = "unknown servic call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¼þ´ü¥Ï¥ó¥É¥éµ¡Ç½ - Æþ¸ý¥í¥°
+ */
+static intptr_t
+trace_print_cycenter(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_STA_CYC:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to sta_cyc cycid=%d.";
+ break;
+ case TFN_STP_CYC:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to stp_cyc cycid=%d.";
+ break;
+ case TFN_REF_CYC:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to ref_cyc cycid=%d.";
+ break;
+ default:
+ tracemsg = "unknown service call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¼þ´ü¥Ï¥ó¥É¥éµ¡Ç½ - ½Ð¸ý¥í¥°
+ */
+static intptr_t
+trace_print_cycleave(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_STA_CYC:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from sta_cyc ercd=%d.";
+ break;
+ case TFN_STP_CYC:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from stp_cyc ercd=%d.";
+ break;
+ case TFN_REF_CYC:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ref_cyc ercd=%d.";
+ break;
+ default:
+ tracemsg = "unknown servic call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¥¢¥é¡¼¥à¥Ï¥ó¥É¥éµ¡Ç½ - Æþ¸ý¥í¥°
+ */
+static intptr_t
+trace_print_almenter(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_STA_ALM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "enter to sta_alm almid=%d. almtim=%d.";
+ break;
+ case TFN_ISTA_ALM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "enter to ista_alm almid=%d. almtim=%d.";
+ break;
+ case TFN_STP_ALM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to stp_alm almid=%d.";
+ break;
+ case TFN_ISTP_ALM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to istp_alm almid=%d.";
+ break;
+ case TFN_REF_ALM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to ref_alm almid=%d.";
+ break;
+ default:
+ tracemsg = "unknown service call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¥¢¥é¡¼¥à¥Ï¥ó¥É¥éµ¡Ç½ - ½Ð¸ý¥í¥°
+ */
+static intptr_t
+trace_print_almleave(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_STA_ALM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from sta_alm ercd=%d.";
+ break;
+ case TFN_ISTA_ALM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ista_alm ercd=%d.";
+ break;
+ case TFN_STP_ALM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from stp_alm ercd=%d.";
+ break;
+ case TFN_ISTP_ALM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from istp_alm ercd=%d.";
+ break;
+ case TFN_REF_ALM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ref_alm ercd=%d.";
+ break;
+ default:
+ tracemsg = "unknown servic call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ³ä¹þ¤ß´ÉÍýµ¡Ç½ - Æþ¸ý¥í¥°
+ */
+static intptr_t
+trace_print_intenter(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_DIS_INT:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to dis_int intno=%d.";
+ break;
+ case TFN_ENA_INT:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to ena_int intno=%d.";
+ break;
+ case TFN_CHG_IPM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to chg_ipm intpri=%d.";
+ break;
+ case TFN_GET_IPM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to get_ipm p_intpri=%d.";
+ break;
+ default:
+ tracemsg = "unknown service call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ³ä¹þ¤ß´ÉÍýµ¡Ç½ - ½Ð¸ý¥í¥°
+ */
+static intptr_t
+trace_print_intleave(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_DIS_INT:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from dis_int ercd=%d.";
+ break;
+ case TFN_ENA_INT:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ena_int ercd=%d.";
+ break;
+ case TFN_CHG_IPM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from chg_ipm ercd=%d.";
+ break;
+ case TFN_GET_IPM:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "leave from get_ipm ercd=%d. intpri=%d.";
+ break;
+ default:
+ tracemsg = "unknown servic call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * CPUÎã³°½èÍýµ¡Ç½ - Æþ¸ý¥í¥°
+ */
+static intptr_t
+trace_print_dpnenter(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_XSNS_DPN:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to xsns_dpn p_excinf=%d.";
+ break;
+ case TFN_XSNS_XPN:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to xsns_xpn p_excinf=%d.";
+ break;
+ default:
+ tracemsg = "unknown service call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * CPUÎã³°½èÍýµ¡Ç½ - ½Ð¸ý¥í¥°
+ */
+static intptr_t
+trace_print_dpnleave(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_XSNS_DPN:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from xsns_dpn state=%d.";
+ break;
+ case TFN_XSNS_XPN:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from xsns_xpn state=%d.";
+ break;
+ default:
+ tracemsg = "unknown servic call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¥·¥¹¥Æ¥à¾õÂÖ´ÉÍýµ¡Ç½ - Æþ¸ý¥í¥°
+ */
+static intptr_t
+trace_print_sysenter(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_ROT_RDQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to rot_rdq tskpri=%d.";
+ break;
+ case TFN_IROT_RDQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to irot_rdq tskpri=%d.";
+ break;
+ case TFN_GET_TID:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to get_tid p_tskid=%d.";
+ break;
+ case TFN_IGET_TID:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "enter to iget_tid p_tskid=%d.";
+ break;
+ case TFN_LOC_CPU:
+ tracemsg = "enter to loc_cpu.";
+ break;
+ case TFN_ILOC_CPU:
+ tracemsg = "enter to iloc_cpu.";
+ break;
+ case TFN_UNL_CPU:
+ tracemsg = "enter to unl_cpu.";
+ break;
+ case TFN_IUNL_CPU:
+ tracemsg = "enter to iunl_cpu.";
+ break;
+ case TFN_DIS_DSP:
+ tracemsg = "enter to dis_dsp.";
+ break;
+ case TFN_ENA_DSP:
+ tracemsg = "enter to ena_dsp.";
+ break;
+ case TFN_SNS_CTX:
+ tracemsg = "enter to sns_ctx.";
+ break;
+ case TFN_SNS_LOC:
+ tracemsg = "enter to sns_loc.";
+ break;
+ case TFN_SNS_DSP:
+ tracemsg = "enter to sns_dsp.";
+ break;
+ case TFN_SNS_DPN:
+ tracemsg = "enter to sns_dpn.";
+ break;
+ case TFN_SNS_KER:
+ tracemsg = "enter to sns_ker.";
+ break;
+ default:
+ tracemsg = "unknown servic call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¥·¥¹¥Æ¥à¾õÂÖ´ÉÍýµ¡Ç½ - ½Ð¸ý¥í¥°
+ */
+static intptr_t
+trace_print_sysleave(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_ROT_RDQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from rot_rdq ercd=%d.";
+ break;
+ case TFN_IROT_RDQ:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from irot_rdq ercd=%d.";
+ break;
+ case TFN_GET_TID:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "leave from get_tid ercd=%d. tskid=%d";
+ break;
+ case TFN_IGET_TID:
+ info[0] = (intptr_t)trace->loginfo[1];
+ info[1] = (intptr_t)trace->loginfo[2];
+ tracemsg = "leave from iget_tid ercd=%d. tskid=%d";
+ break;
+ case TFN_LOC_CPU:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from loc_cpu ercd=%d.";
+ break;
+ case TFN_ILOC_CPU:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from iloc_cpu ercd=%d.";
+ break;
+ case TFN_UNL_CPU:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from unl_cpu ercd=%d.";
+ break;
+ case TFN_IUNL_CPU:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from iunl_cpu ercd=%d.";
+ break;
+ case TFN_DIS_DSP:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from dis_dsp ercd=%d.";
+ break;
+ case TFN_ENA_DSP:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from ena_dsp ercd=%d.";
+ break;
+ case TFN_SNS_CTX:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from sns_ctx state=%d.";
+ break;
+ case TFN_SNS_LOC:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from sns_loc state=%d.";
+ break;
+ case TFN_SNS_DSP:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from sns_dsp state=%d.";
+ break;
+ case TFN_SNS_DPN:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from sns_dpn state=%d.";
+ break;
+ case TFN_SNS_KER:
+ info[0] = (intptr_t)trace->loginfo[1];
+ tracemsg = "leave from sns_ker state=%d.";
+ break;
+ default:
+ tracemsg = "unknown servic call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¥«¡¼¥Í¥ë¤Î½é´ü²½¤È½ªÎ»½èÍý
+ */
+static intptr_t
+trace_print_kerenter(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+ case TFN_EXT_KER:
+ tracemsg = "enter to ext_ker.";
+ break;
+ default:
+ tracemsg = "unknown service call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¥·¥¹¥Æ¥à¥³¡¼¥ë¤ÎÆþ¸ý¥í¥°(LOG_TYPE_SVC|ENTER)
+ */
+static intptr_t
+trace_print_svcenter(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+
+ /*¥¿¥¹¥¯´ÉÍý¡¦¥¿¥¹¥¯ÉÕ°Ʊ´üµ¡Ç½ */
+ case TFN_ACT_TSK:
+ case TFN_IACT_TSK:
+ case TFN_CAN_ACT:
+ case TFN_EXT_TSK:
+ case TFN_TER_TSK:
+ case TFN_CHG_PRI:
+ case TFN_GET_PRI:
+ case TFN_GET_INF:
+ case TFN_REF_TSK:
+ case TFN_SLP_TSK:
+ case TFN_TSLP_TSK:
+ case TFN_WUP_TSK:
+ case TFN_IWUP_TSK:
+ case TFN_CAN_WUP:
+ case TFN_REL_WAI:
+ case TFN_IREL_WAI:
+ case TFN_SUS_TSK:
+ case TFN_RSM_TSK:
+ case TFN_DLY_TSK:
+ tracemsg = (const char*)trace_print_tskenter(trace, info);
+ break;
+
+ /* ¥¿¥¹¥¯Îã³°½èÍýµ¡Ç½ */
+ case TFN_RAS_TEX:
+ case TFN_IRAS_TEX:
+ case TFN_DIS_TEX:
+ case TFN_ENA_TEX:
+ case TFN_SNS_TEX:
+ case TFN_REF_TEX:
+ tracemsg = (const char*)trace_print_texenter(trace, info);
+ break;
+
+ /* ¥»¥Þ¥Õ¥©µ¡Ç½ */
+ case TFN_SIG_SEM:
+ case TFN_ISIG_SEM:
+ case TFN_WAI_SEM:
+ case TFN_POL_SEM:
+ case TFN_TWAI_SEM:
+ case TFN_INI_SEM:
+ case TFN_REF_SEM:
+ tracemsg = (const char*)trace_print_sementer(trace, info);
+ break;
+
+ /* ¥¤¥Ù¥ó¥È¥Õ¥é¥°µ¡Ç½ */
+ case TFN_SET_FLG:
+ case TFN_ISET_FLG:
+ case TFN_CLR_FLG:
+ case TFN_WAI_FLG:
+ case TFN_POL_FLG:
+ case TFN_TWAI_FLG:
+ case TFN_INI_FLG:
+ case TFN_REF_FLG:
+ tracemsg = (const char*)trace_print_flgenter(trace, info);
+ break;
+
+ /* ¥Ç¡¼¥¿¥¥å¡¼µ¡Ç½ */
+ case TFN_SND_DTQ:
+ case TFN_PSND_DTQ:
+ case TFN_IPSND_DTQ:
+ case TFN_TSND_DTQ:
+ case TFN_FSND_DTQ:
+ case TFN_IFSND_DTQ:
+ case TFN_RCV_DTQ:
+ case TFN_PRCV_DTQ:
+ case TFN_TRCV_DTQ:
+ case TFN_INI_DTQ:
+ case TFN_REF_DTQ:
+ tracemsg = (const char*)trace_print_dtqenter(trace, info);
+ break;
+
+ /* Í¥ÀèÅ٥ǡ¼¥¿¥¥å¡¼µ¡Ç½ */
+ case TFN_SND_PDQ:
+ case TFN_PSND_PDQ:
+ case TFN_IPSND_PDQ:
+ case TFN_TSND_PDQ:
+ case TFN_RCV_PDQ:
+ case TFN_PRCV_PDQ:
+ case TFN_TRCV_PDQ:
+ case TFN_INI_PDQ:
+ case TFN_REF_PDQ:
+ tracemsg = (const char*)trace_print_pdqenter(trace, info);
+ break;
+
+ /* ¸ÇÄêĹ¥á¥â¥ê¥×¡¼¥ëµ¡Ç½ */
+ case TFN_GET_MPF:
+ case TFN_PGET_MPF:
+ case TFN_TGET_MPF:
+ case TFN_REL_MPF:
+ case TFN_INI_MPF:
+ case TFN_REF_MPF:
+ tracemsg = (const char*)trace_print_mpfenter(trace, info);
+ break;
+
+ /* ¥·¥¹¥Æ¥à»þ¹ï´ÉÍýµ¡Ç½ */
+ case TFN_GET_TIM:
+ case TFN_GET_UTM:
+ tracemsg = (const char*)trace_print_timenter(trace, info);
+ break;
+
+ /* ¼þ´ü¥Ï¥ó¥É¥éµ¡Ç½ */
+ case TFN_STA_CYC:
+ case TFN_STP_CYC:
+ case TFN_REF_CYC:
+ tracemsg = (const char*)trace_print_cycenter(trace, info);
+ break;
+
+ /* ¥¢¥é¡¼¥à¥Ï¥ó¥É¥éµ¡Ç½ */
+ case TFN_STA_ALM:
+ case TFN_ISTA_ALM:
+ case TFN_STP_ALM:
+ case TFN_ISTP_ALM:
+ case TFN_REF_ALM:
+ tracemsg = (const char*)trace_print_almenter(trace, info);
+ break;
+
+ /* ¥á¡¼¥ë¥Ü¥Ã¥¯¥¹µ¡Ç½ */
+ case TFN_SND_MBX:
+ case TFN_RCV_MBX:
+ case TFN_PRCV_MBX:
+ case TFN_TRCV_MBX:
+ case TFN_INI_MBX:
+ case TFN_REF_MBX:
+ tracemsg = (const char*)trace_print_mbxenter(trace, info);
+ break;
+
+ /* ³ä¹þ¤ß´ÉÍýµ¡Ç½ */
+ case TFN_DIS_INT:
+ case TFN_ENA_INT:
+ case TFN_CHG_IPM:
+ case TFN_GET_IPM:
+ tracemsg = (const char*)trace_print_intenter(trace, info);
+ break;
+
+ /* CPUÎã³°½èÍý */
+ case TFN_XSNS_DPN:
+ case TFN_XSNS_XPN:
+ tracemsg = (const char*)trace_print_dpnenter(trace, info);
+ break;
+
+ /* ¥·¥¹¥Æ¥à¾õÂÖ´ÉÍýµ¡Ç½ */
+ case TFN_ROT_RDQ:
+ case TFN_IROT_RDQ:
+ case TFN_GET_TID:
+ case TFN_IGET_TID:
+ case TFN_LOC_CPU:
+ case TFN_ILOC_CPU:
+ case TFN_UNL_CPU:
+ case TFN_IUNL_CPU:
+ case TFN_DIS_DSP:
+ case TFN_ENA_DSP:
+ case TFN_SNS_CTX:
+ case TFN_SNS_LOC:
+ case TFN_SNS_DSP:
+ case TFN_SNS_DPN:
+ case TFN_SNS_KER:
+ tracemsg = (const char*)trace_print_sysenter(trace, info);
+ break;
+
+ /* ¥«¡¼¥Í¥ë¤Î½é´ü²½¤È½ªÎ»½èÍý */
+ case TFN_EXT_KER:
+ tracemsg = (const char*)trace_print_kerenter(trace, info);
+ break;
+
+
+ default:
+ tracemsg = "unknown LOG_TYPE_SVC|ENTER service call";
+ break;
+ }
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¥·¥¹¥Æ¥à¥³¡¼¥ë¤Î½Ð¸ý¥í¥°(LOG_TYPE_SVC|LEAVE)
+ */
+static intptr_t
+trace_print_svcleave(TRACE *trace, intptr_t *info)
+{
+ uint_t type;
+ const char *tracemsg;
+
+ type = (uint_t)trace->loginfo[0];
+
+ switch (type) {
+
+ /* ¥¿¥¹¥¯´ÉÍý¡¦¥¿¥¹¥¯ÉÕ°Ʊ´üµ¡Ç½ */
+ case TFN_ACT_TSK:
+ case TFN_IACT_TSK:
+ case TFN_CAN_ACT:
+ case TFN_EXT_TSK:
+ case TFN_TER_TSK:
+ case TFN_CHG_PRI:
+ case TFN_GET_PRI:
+ case TFN_GET_INF:
+ case TFN_REF_TSK:
+ case TFN_SLP_TSK:
+ case TFN_TSLP_TSK:
+ case TFN_WUP_TSK:
+ case TFN_IWUP_TSK:
+ case TFN_CAN_WUP:
+ case TFN_REL_WAI:
+ case TFN_IREL_WAI:
+ case TFN_SUS_TSK:
+ case TFN_RSM_TSK:
+ case TFN_DLY_TSK:
+ tracemsg = (const char*)trace_print_tskleave(trace, info);
+ break;
+
+ /* ¥¿¥¹¥¯Îã³°½èÍýµ¡Ç½ */
+ case TFN_RAS_TEX:
+ case TFN_IRAS_TEX:
+ case TFN_DIS_TEX:
+ case TFN_ENA_TEX:
+ case TFN_SNS_TEX:
+ case TFN_REF_TEX:
+ tracemsg = (const char*)trace_print_texleave(trace, info);
+ break;
+
+ /* ¥»¥Þ¥Õ¥©µ¡Ç½ */
+ case TFN_SIG_SEM:
+ case TFN_ISIG_SEM:
+ case TFN_WAI_SEM:
+ case TFN_POL_SEM:
+ case TFN_TWAI_SEM:
+ case TFN_INI_SEM:
+ case TFN_REF_SEM:
+ tracemsg = (const char*)trace_print_semleave(trace, info);
+ break;
+
+ /* ¥¤¥Ù¥ó¥È¥Õ¥é¥°µ¡Ç½ */
+ case TFN_SET_FLG:
+ case TFN_ISET_FLG:
+ case TFN_CLR_FLG:
+ case TFN_WAI_FLG:
+ case TFN_POL_FLG:
+ case TFN_TWAI_FLG:
+ case TFN_INI_FLG:
+ case TFN_REF_FLG:
+ tracemsg = (const char*)trace_print_flgleave(trace, info);
+ break;
+
+ /* ¥Ç¡¼¥¿¥¥å¡¼µ¡Ç½ */
+ case TFN_SND_DTQ:
+ case TFN_PSND_DTQ:
+ case TFN_IPSND_DTQ:
+ case TFN_TSND_DTQ:
+ case TFN_FSND_DTQ:
+ case TFN_IFSND_DTQ:
+ case TFN_RCV_DTQ:
+ case TFN_PRCV_DTQ:
+ case TFN_TRCV_DTQ:
+ case TFN_INI_DTQ:
+ case TFN_REF_DTQ:
+ tracemsg = (const char*)trace_print_dtqleave(trace, info);
+ break;
+
+ /* Í¥ÀèÅ٥ǡ¼¥¿¥¥å¡¼µ¡Ç½ */
+ case TFN_SND_PDQ:
+ case TFN_PSND_PDQ:
+ case TFN_IPSND_PDQ:
+ case TFN_TSND_PDQ:
+ case TFN_RCV_PDQ:
+ case TFN_PRCV_PDQ:
+ case TFN_TRCV_PDQ:
+ case TFN_INI_PDQ:
+ case TFN_REF_PDQ:
+ tracemsg = (const char*)trace_print_pdqleave(trace, info);
+ break;
+
+ /* ¸ÇÄêĹ¥á¥â¥ê¥×¡¼¥ëµ¡Ç½ */
+ case TFN_GET_MPF:
+ case TFN_PGET_MPF:
+ case TFN_TGET_MPF:
+ case TFN_REL_MPF:
+ case TFN_INI_MPF:
+ case TFN_REF_MPF:
+ tracemsg = (const char*)trace_print_mpfleave(trace, info);
+ break;
+
+ /* ¥·¥¹¥Æ¥à»þ¹ï´ÉÍýµ¡Ç½ */
+ case TFN_GET_TIM:
+ case TFN_GET_UTM:
+ tracemsg = (const char*)trace_print_timleave(trace, info);
+ break;
+
+ /* ¼þ´ü¥Ï¥ó¥É¥éµ¡Ç½ */
+ case TFN_STA_CYC:
+ case TFN_STP_CYC:
+ case TFN_REF_CYC:
+ tracemsg = (const char*)trace_print_cycleave(trace, info);
+ break;
+
+ /* ¥¢¥é¡¼¥à¥Ï¥ó¥É¥éµ¡Ç½ */
+ case TFN_STA_ALM:
+ case TFN_ISTA_ALM:
+ case TFN_STP_ALM:
+ case TFN_ISTP_ALM:
+ case TFN_REF_ALM:
+ tracemsg = (const char*)trace_print_almleave(trace, info);
+ break;
+
+ /* ¥á¡¼¥ë¥Ü¥Ã¥¯¥¹µ¡Ç½ */
+ case TFN_SND_MBX:
+ case TFN_RCV_MBX:
+ case TFN_PRCV_MBX:
+ case TFN_TRCV_MBX:
+ case TFN_INI_MBX:
+ case TFN_REF_MBX:
+ tracemsg = (const char*)trace_print_mbxleave(trace, info);
+ break;
+
+ /* ³ä¹þ¤ß´ÉÍýµ¡Ç½ */
+ case TFN_DIS_INT:
+ case TFN_ENA_INT:
+ case TFN_CHG_IPM:
+ case TFN_GET_IPM:
+ tracemsg = (const char*)trace_print_intleave(trace, info);
+ break;
+
+ /* CPUÎã³°½èÍýµ¡Ç½ */
+ case TFN_XSNS_DPN:
+ case TFN_XSNS_XPN:
+ tracemsg = (const char*)trace_print_dpnleave(trace, info);
+ break;
+
+ /* ¥·¥¹¥Æ¥à¾õÂÖ´ÉÍýµ¡Ç½ */
+ case TFN_ROT_RDQ:
+ case TFN_IROT_RDQ:
+ case TFN_GET_TID:
+ case TFN_IGET_TID:
+ case TFN_LOC_CPU:
+ case TFN_ILOC_CPU:
+ case TFN_UNL_CPU:
+ case TFN_IUNL_CPU:
+ case TFN_DIS_DSP:
+ case TFN_ENA_DSP:
+ case TFN_SNS_CTX:
+ case TFN_SNS_LOC:
+ case TFN_SNS_DSP:
+ case TFN_SNS_DPN:
+ case TFN_SNS_KER:
+ tracemsg = (const char*)trace_print_sysleave(trace, info);
+ break;
+
+ default:
+ tracemsg = "unknown LOG_TYPE_SVC|LEAVE servic call";
+ break;
+ }
+
+ return((intptr_t) tracemsg);
+}
+
+
+/*
+ * ¥È¥ì¡¼¥¹¥í¥°¤Îɽ¼¨
+ */
+static void
+trace_print(TRACE *p_trace, void (*putc)(char_t))
+{
+ intptr_t traceinfo[TMAX_LOGINFO + 1];
+ const char *tracemsg;
+ int_t i;
+
+ traceinfo[0] = (intptr_t)(p_trace->logtim);
+ syslog_printf("[%d] ", traceinfo, putc);
+
+ switch (p_trace->logtype) {
+ case LOG_TYPE_INH|LOG_ENTER:
+ traceinfo[0] = p_trace->loginfo[0];
+ tracemsg = "enter to int handler %d.";
+ break;
+ case LOG_TYPE_INH|LOG_LEAVE:
+ traceinfo[0] = p_trace->loginfo[0];
+ tracemsg = "leave from int handler %d.";
+ break;
+ case LOG_TYPE_ISR|LOG_ENTER:
+ traceinfo[0] = p_trace->loginfo[0];
+ tracemsg = "enter to isr %d.";
+ break;
+ case LOG_TYPE_ISR|LOG_LEAVE:
+ traceinfo[0] = p_trace->loginfo[0];
+ tracemsg = "leave from isr %d.";
+ break;
+ case LOG_TYPE_CYC|LOG_ENTER:
+ traceinfo[0] = (intptr_t)((ID)((((CYCCB*)(p_trace->loginfo[0])) - cyccb_table) + TMIN_CYCID));
+ tracemsg = "enter to cyclic handler %d.";
+ break;
+ case LOG_TYPE_CYC|LOG_LEAVE:
+ traceinfo[0] = (intptr_t)((ID)((((CYCCB*)(p_trace->loginfo[0])) - cyccb_table) + TMIN_CYCID));
+ tracemsg = "leave from cyclic handler %d.";
+ break;
+ case LOG_TYPE_ALM|LOG_ENTER:
+ traceinfo[0] = (intptr_t)((ID)((((ALMCB*)(p_trace->loginfo[0])) - almcb_table) + TMIN_ALMID));
+ tracemsg = "enter to alarm handler %d.";
+ break;
+ case LOG_TYPE_ALM|LOG_LEAVE:
+ traceinfo[0] = (intptr_t)((ID)((((ALMCB*)(p_trace->loginfo[0])) - almcb_table) + TMIN_ALMID));
+ tracemsg = "leave from alarm handler %d.";
+ break;
+ case LOG_TYPE_EXC|LOG_ENTER:
+ traceinfo[0] = p_trace->loginfo[0];
+ tracemsg = "enter to exc handler %d.";
+ break;
+ case LOG_TYPE_EXC|LOG_LEAVE:
+ traceinfo[0] = p_trace->loginfo[0];
+ tracemsg = "leave from exc handler %d.";
+ break;
+ case LOG_TYPE_TEX|LOG_ENTER:
+ traceinfo[0] = p_trace->loginfo[1];
+ tracemsg = "enter to tex %d.";
+ break;
+ case LOG_TYPE_TEX|LOG_LEAVE:
+ traceinfo[0] = p_trace->loginfo[1];
+ tracemsg = "leave from tex %d.";
+ break;
+ case LOG_TYPE_TSKSTAT:
+ traceinfo[0] = get_tskid(p_trace->loginfo[0]);
+ traceinfo[1] = get_tskstat(p_trace->loginfo[1]);
+ tracemsg = "task %d becomes %s.";
+ break;
+ case LOG_TYPE_DSP|LOG_ENTER:
+ traceinfo[0] = get_tskid(p_trace->loginfo[0]);
+ tracemsg = "dispatch from task %d.";
+ break;
+ case LOG_TYPE_DSP|LOG_LEAVE:
+ traceinfo[0] = get_tskid(p_trace->loginfo[0]);
+ tracemsg = "dispatch to task %d.";
+ break;
+ case LOG_TYPE_SVC|LOG_ENTER:
+ tracemsg = (const char *)trace_print_svcenter(p_trace, traceinfo);
+ break;
+ case LOG_TYPE_SVC|LOG_LEAVE:
+ tracemsg = (const char *)trace_print_svcleave(p_trace, traceinfo);
+ break;
+ case LOG_TYPE_COMMENT:
+ for (i = 1; i < TMAX_LOGINFO; i++) {
+ traceinfo[i-1] = p_trace->loginfo[i];
+ }
+ tracemsg = (const char *)(p_trace->loginfo[0]);
+ break;
+ case LOG_TYPE_ASSERT:
+ traceinfo[0] = p_trace->loginfo[0];
+ traceinfo[1] = p_trace->loginfo[1];
+ traceinfo[2] = p_trace->loginfo[2];
+ tracemsg = "%s:%u: Assertion `%s' failed.";
+ break;
+ default:
+ traceinfo[0] = p_trace->logtype;
+ tracemsg = "unknown trace log type: %d.";
+ break;
+ }
+ syslog_printf(tracemsg, traceinfo, putc);
+ (*putc)('\n');
+}
+
+/*
+ * ¥È¥ì¡¼¥¹¥í¥°¤Î¥À¥ó¥×
+ */
+void
+trace_dump(intptr_t exinf)
+{
+ TRACE trace;
+ void (*putc)(char_t);
+
+ putc = (void (*)(char_t)) exinf;
+ while (trace_rea_log(&trace) >= 0) {
+ trace_print(&trace, putc);
+ }
+}
--- /dev/null
+PACKAGE cfg
+VERSION 1.6.0
+
+cfg.sln
+configure
+Makefile
+MANIFEST
+README.txt
+
+cfg/cfg.cpp
+cfg/cfg.hpp
+cfg/cfg.vcproj
+cfg/cfg0.cpp
+cfg/cfg1.cpp
+cfg/cfg2.cpp
+cfg/cfg3.cpp
+cfg/cfg4.cpp
+cfg/cfg_init.cpp
+cfg/cfg_version.cpp
+cfg/ja.po
+cfg/Makefile
+cfg/require_modules.hpp
+
+toppers/builtin_function.cpp
+toppers/codeset.hpp
+toppers/config.hpp
+toppers/cpp.cpp
+toppers/cpp.hpp
+toppers/csv.hpp
+toppers/c_chlit_parser.cpp
+toppers/c_expr.hpp
+toppers/c_ident_parser.cpp
+toppers/c_int_parser.cpp
+toppers/c_keywords.cpp
+toppers/c_parser.hpp
+toppers/c_plus_plus_keywords.cpp
+toppers/c_pp_line.hpp
+toppers/c_strlit_parser.cpp
+toppers/debug.hpp
+toppers/diagnostics.cpp
+toppers/diagnostics.hpp
+toppers/gettext.cpp
+toppers/gettext.hpp
+toppers/global.cpp
+toppers/global.hpp
+toppers/io.cpp
+toppers/io.hpp
+toppers/macro_processor.cpp
+toppers/macro_processor.hpp
+toppers/Makefile
+toppers/mbchar_parser.cpp
+toppers/misc.hpp
+toppers/nm_symbol.cpp
+toppers/nm_symbol.hpp
+toppers/output_file.cpp
+toppers/output_file.hpp
+toppers/s_record.cpp
+toppers/s_record.hpp
+toppers/text.hpp
+toppers/text_line.hpp
+toppers/toppers.vcproj
+toppers/ucn_parser.cpp
+toppers/workaround.hpp
+
+toppers/itronx/cfg1_out.cpp
+toppers/itronx/cfg1_out.hpp
+toppers/itronx/checker.cpp
+toppers/itronx/checker.hpp
+toppers/itronx/component.cpp
+toppers/itronx/component.hpp
+toppers/itronx/factory.cpp
+toppers/itronx/factory.hpp
+toppers/itronx/init_helper.hpp
+toppers/itronx/itronx.vcproj
+toppers/itronx/kernel_chk.hpp
+toppers/itronx/Makefile
+toppers/itronx/preprocess.cpp
+toppers/itronx/preprocess.hpp
+toppers/itronx/static_api.cpp
+toppers/itronx/static_api.hpp
+toppers/itronx/static_api_parser.hpp
--- /dev/null
+-include Makefile.config
+
+ifndef BOOST_DIR
+ ifndef BOOST_VERSION
+ BOOST_VERSION = 1_42_0
+ endif
+ ifeq ($(OSTYPE), msys)
+ BOOST_DIR = /mingw/include/boost-$(BOOST_VERSION)
+ else
+ ifeq ($(shell echo $$OSTYPE), cygwin)
+ BOOST_DIR = /usr/include/boost-$(BOOST_VERSION)
+ else
+ BOOST_DIR = /usr/local/include/boost-$(BOOST_VERSION)
+ endif
+ endif
+endif
+
+# 非力なマシンなどでコンパイルに非常に長い時間がかかる、もしくはコンパイル時に
+# ハングアップする場合には、-O0に変更してみてください。
+OPTIMIZE = -O2
+
+SUBDIRS = toppers \
+ toppers/itronx \
+ cfg
+
+all: $(SUBDIRS)
+
+$(SUBDIRS)::
+ make BOOST_DIR="$(BOOST_DIR)" LIBBOOST_SUFFIX="$(LIBBOOST_SUFFIX)" CXXFLAGS="$(OPTIMIZE) $(OPTIONS)" -C $@
+
+depend:
+ for subdir in $(SUBDIRS) ; do \
+ if test -d $$subdir ; then \
+ make BOOST_DIR="$(BOOST_DIR)" LIBBOOST_SUFFIX="$(LIBBOOST_SUFFIX)" depend -C $$subdir; \
+ fi ; \
+ done \
+
+clean:
+ for subdir in $(SUBDIRS) ; do \
+ if test -d $$subdir ; then \
+ make clean -C $$subdir ; \
+ fi ; \
+ done \
+
+realclean: clean
+ for subdir in $(SUBDIRS) ; do \
+ if test -d $$subdir ; then \
+ rm -f $$subdir/Makefile.depend ; \
+ fi ; \
+ done
+ rm -f Makefile.config
+
--- /dev/null
+LIBBOOST_SUFFIX=-mt
+BOOST_VERSION=1_42
+BOOST_DIR=/usr/include
+LIBBOOST_DIR=/usr/lib
+OPTIONS=
--- /dev/null
+
+ TOPPERS新世代カーネル用コンフィギュレータ(Release 1.6.0)
+
+
+TOPPERS新世代カーネル用コンフィギュレータは、カーネルやソフトウェア部品
+の構成や初期状態を定義したシステムコンフィギュレーションファイルを解釈し、
+システムを構築する上で必要なファイル類を生成するTOPPERS新世代カーネル用
+のツールです。
+
+コンフィギュレータは、コンパイラやアセンブラを初めとする開発ツールと同様、
+PC等の開発用コンピュータ上で動作するコマンドラインプログラムです。したが
+って、コンフィギュレータそのものが最終的な製品に組み込まれることは、原則
+としてありません。コンフィギュレータはコマンドラインツールなので、コンパ
+イラを初めとした他のコマンドラインツールと組み合わせて使用することを前提
+としています。しかし、ユーザーが適切に設定を行うことで、多くの統合開発環
+境から呼び出せます。
+
+
+【コンフィギュレータの構築方法】
+
+カーネルを構築する前に、まず、コンフィギュレータをコンパイルする必要が
+あります(コンフィギュレータをバイナリで入手した場合には、このステップ
+は必要はありません)。
+コンフィギュレータの構築にはBoost C++ Libraries 1.42.0以上が必要です。
+Boost C++ Librariesは、下記URLから入手することができます。
+
+http://www.boost.org/
+
+Windowsの場合、Visual C++用のバイナリが下記URLのサイトから入手可能です。
+
+http://www.boostpro.com/
+
+Boost C++ Librariesをバイナリで入手できない場合には、ソースからビルドし
+てください。
+
+=== GNU開発環境を用いる場合 ===
+
+コンフィギュレータ(cfgプログラム)を構築するには、cfgディレクトリに移動
+し、configureおよびmakeコマンドを実行します。
+
+ % cd cfg
+ % ./configure
+ % make
+
+ただし、Boostをインストールしたディレクトリおよび名称が、標準で想定して
+いるものと違う場合には、configureに--with-headersおよび--with-libraries
+オプションによりインクルードおよびライブラリのディレクトリを指定してくだ
+さい。
+また、ホストシステムによっては、最適化レベルを上げると正しくコンパイルで
+きないことが知られています。そのような場合には、最適化レベルを下げるか、
+最適化を抑止するように、Makefileを修正する必要があります。
+
+=== Microsoft Visual Studioを用いる場合 ===
+
+コンフィギュレータ(cfgプログラム)を構築するには、cfgディレクトリ中の
+cfg.slnをVisual Studio(またはVisual C++ Express Edition)で開いてくだ
+さい。cfg.slnはVisual Studio.NET 2003用のものですが、上位のバージョンを
+使用する場合にはソリューションを変換して使用してください。
+ソリューションを開いた後、Release版としてビルドを実行してださい。
+cfg/cfg/Releaseディレクトリにcfg.exeが生成されますので、必要なフォルダ
+にコピーまたは移動してください。
+
+・注意事項
+
+Boost C++ Librariesをインストールした後、インクルードおよびライブラリの
+ディレクトリをVisual Studioに登録してからビルドを実行してください。
+Visual C++ 2005 Express Editionを使用する場合、別途Platform SDKをインス
+トールする必要があります。
+
+
+【コンフィギュレータの使い方】
+
+コンフィギュレータ(cfg)は、TOPPERS新世代カーネル統合仕様書の2.12.5節
+の記述の通り、3つ(または4つ)のパスで構成されます。
+
+コンフィギュレータは、システムコンフィギュレーションファイル名をパラメー
+タに取り、以下のオプションを持ちます(重要なもののみ)。
+
+ --help
+ オプションのリストと説明を表示する。
+
+ -v[--version]
+ コンフィギュレータのバージョンを表示する。
+
+ -k[--kernel]<カーネル名>
+ カーネルの名称を指定する。デフォルトはasp。
+
+ -p[--pass]<パス番号>
+ パス番号を指定する。1〜3のいずれか。
+
+ -I[--include-path]<インクルードパス名>
+ INCLUDEディレクティブにおいて、インクルードするコンフィギュレー
+ ションファイルを探すパス名を指定する。
+
+ -T[--template-file]<テンプレートファイル名>
+ テンプレートファイルの名称を指定する。パス2とパス3で有効。
+
+ --api-table <静的APIテーブルファイル名>
+ 静的APIテーブルのファイル名を指定する。
+
+ --cfg1-def-table <値取得シンボルテーブルファイル名>
+ 値取得シンボルテーブルのファイル名を指定する。
+
+ -r[--rom-image]<ロードモジュール名>
+ ロードモジュールをSレコードフォーマットの形に変換したファイルの
+ 名称を指定する。パス3でのみ有効。
+
+ -s [--symbol-table] <シンボルファイル名>
+ ロードモジュール中の各シンボルとアドレスの対応表を含むシンボル
+ ファイルの名称を指定する。パス3でのみ有効。
+
+ --id-output-file <ID番号出力ファイル名>
+ オブジェクトのID番号の割付け結果を、指定した名前のファイルに書
+ き出す。パス2でのみ有効。
+
+ --id-input-file <ID番号入力ファイル名>
+ オブジェクトのID番号の割付けを、指定した名前のファイルから取り
+ 込む。パス2でのみ有効。
+
+ --external-id
+ オブジェクトのID番号を保持する変数の定義を生成する。パス2でのみ
+ 有効。
+
+ -M[--print-dependencies]<ターゲットシンボル>
+ システムコンフィギュレーションファイルの依存関係を出力する。
+ Makefile中の依存関係を生成する際に用いる。
+
+コンフィギュレータの詳細仕様については、別途PDFファイルの形で配布してい
+る「TOPPERS新世代カーネル用コンフィギュレータ仕様」を参照してください。
+テンプレートファイルの作成にあたっては、「TOPPERS新世代カーネル用コンフ
+ィギュレータ内蔵マクロプロセッサ仕様書」を参照してください。
+
--- /dev/null
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cfg", "cfg\cfg.vcproj", "{E2E91785-C5CB-4E57-98F0-7953A42FFEC0}"
+ ProjectSection(ProjectDependencies) = postProject
+ {101BA469-E065-401C-86F9-789B5F2C85AB} = {101BA469-E065-401C-86F9-789B5F2C85AB}
+ {994810C2-F530-4679-9DF8-AF39A3AC61C9} = {994810C2-F530-4679-9DF8-AF39A3AC61C9}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "toppers", "toppers\toppers.vcproj", "{101BA469-E065-401C-86F9-789B5F2C85AB}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "itronx", "toppers\itronx\itronx.vcproj", "{994810C2-F530-4679-9DF8-AF39A3AC61C9}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Release = Release
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {E2E91785-C5CB-4E57-98F0-7953A42FFEC0}.Debug.ActiveCfg = Debug|Win32
+ {E2E91785-C5CB-4E57-98F0-7953A42FFEC0}.Debug.Build.0 = Debug|Win32
+ {E2E91785-C5CB-4E57-98F0-7953A42FFEC0}.Release.ActiveCfg = Release|Win32
+ {E2E91785-C5CB-4E57-98F0-7953A42FFEC0}.Release.Build.0 = Release|Win32
+ {101BA469-E065-401C-86F9-789B5F2C85AB}.Debug.ActiveCfg = Debug|Win32
+ {101BA469-E065-401C-86F9-789B5F2C85AB}.Debug.Build.0 = Debug|Win32
+ {101BA469-E065-401C-86F9-789B5F2C85AB}.Release.ActiveCfg = Release|Win32
+ {101BA469-E065-401C-86F9-789B5F2C85AB}.Release.Build.0 = Release|Win32
+ {994810C2-F530-4679-9DF8-AF39A3AC61C9}.Debug.ActiveCfg = Debug|Win32
+ {994810C2-F530-4679-9DF8-AF39A3AC61C9}.Debug.Build.0 = Debug|Win32
+ {994810C2-F530-4679-9DF8-AF39A3AC61C9}.Release.ActiveCfg = Release|Win32
+ {994810C2-F530-4679-9DF8-AF39A3AC61C9}.Release.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
--- /dev/null
+-include ../Makefile.config
+
+PROJDIR = ..
+WORKDIR = $(PROJDIR)/cfg
+
+CPPFLAGS := $(CPPFLAGS) -I$(BOOST_DIR) -I$(PROJDIR)
+CXXFLAGS := $(CXXFLAGS) -O2 -g
+
+CXXFILES = \
+ cfg.cpp \
+ cfg0.cpp \
+ cfg1.cpp \
+ cfg2.cpp \
+ cfg3.cpp \
+ cfg4.cpp \
+ cfg_version.cpp
+
+OBJFILES := $(CXXFILES:%.cpp=%.o)
+
+ifeq ($(OSTYPE),msys)
+BOOST_LIBFILES = /mingw/lib/libboost_system-mgw-mt-s.lib /mingw/lib/libboost_filesystem-mgw-mt-s.lib /mingw/lib/libboost_program_options-mgw-mt-s.lib
+else
+BOOST_LIBFILES := $(BOOST_LIBFILES) -lboost_system$(LIBBOOST_SUFFIX) -lboost_filesystem$(LIBBOOST_SUFFIX) -lboost_program_options$(LIBBOOST_SUFFIX)
+endif
+
+LIBFILES = $(PROJDIR)/toppers/itronx/libitronx.a \
+ $(PROJDIR)/toppers/libtoppers.a \
+
+all: cfg
+
+cfg: $(OBJFILES) $(LIBFILES)
+ $(CXX) $(CXXFLAGS) -o cfg $(OBJFILES) -L$(LIBBOOST_DIR) $(LIBFILES) $(BOOST_LIBFILES)
+
+depend:
+ $(CXX) $(CPPFLAGS) -M $(CXXFILES) > Makefile.depend
+
+clean:
+ -rm -f *.o cfg *.exe
+
+-include Makefile.depend
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+#include "cfg.hpp"
+#include <boost/program_options.hpp>
+#include <boost/spirit/include/classic.hpp>
+
+namespace
+{
+
+ //! 連続したスラッシュ / を単一のスラッシュに置換する
+ std::string slashes_to_single_slash( std::string const& str )
+ {
+ std::string result( str );
+ std::string::size_type pos = 0;
+ while ( ( pos = result.find( "//", pos ) ) != std::string::npos )
+ {
+ result.erase( pos, 1 );
+ }
+ return result;
+ }
+
+ //! 起動オプションの解析
+ int parse_program_options( int argc, char* argv[] )
+ {
+ namespace po = boost::program_options;
+ int pass = 0;
+
+ // 一般オプション
+ po::options_description generic( _( "Generic options" ) );
+ generic.add_options()
+ ( "help", _( "display this information" ) )
+ ( "version,v", _( "display cfg version number" ) )
+ ;
+
+ // 設定オプション
+ po::options_description config( _( "Configuration" ) );
+ config.add_options()
+ ( "kernel,k", po::value< std::string >()->default_value( std::string( "asp" ) ), _( "kernel type (default: asp)" ) )
+ ( "pass,p", po::value< int >( &pass )->default_value( 0 ), _( "run for pass #`arg\'" ) )
+ ( "include-path,I", po::value< std::vector< std::string > >(), _( "include path" ) )
+ ( "template-file,T", po::value< std::string >(), _( "template file" ) )
+ ( "input-charset", po::value< std::string >()->default_value( std::string( "ascii" ) ), _( "character set of input file (default: ascii)" ) )
+ ( "api-table", po::value< std::vector< std::string > >(), _( "specify static API table" ) )
+ ( "cfg1-def-table", po::value< std::vector< std::string > >(), _( "specify cfg1 definition table" ) )
+ ( "cfg1_out", po::value< std::string >()->default_value( std::string( "cfg1_out" ) ), _( "specify file name instead of `cfg1_out.srec\' (default: cfg1_out)" ) )
+ ( "rom-image,r", po::value< std::string >(), _( "ROM image (S-record)" ) )
+ ( "symbol-table,s", po::value< std::string >(), _( "Symbol table (`nm' style)" ) )
+ ( "cfg-directory,d", po::value< std::string >(), _( "cfg directory" ) )
+ ( "msgcat-directory,m", po::value< std::vector< std::string > >(), _( "msgcat(*.po) directory" ) )
+ ( "destination-directory,n", po::value< std::string >()->default_value( "." ), _( "destination directory" ) )
+ ( "id-output-file", po::value< std::string >()->default_value( std::string() ), _( "output file for id assignment" ) )
+ ( "id-input-file", po::value< std::string >()->default_value( std::string() ), _( "input file for id assignment" ) )
+ ( "alignof-fp", po::value< std::size_t >()->default_value( 1 ), _( "alignment of pointer to function" ) )
+ ( "external-id", _( "output ID numbers as external `const\' object" ) )
+ ( "print-dependencies,M", po::value< std::string >(), _( "output dependencies of source file (for `make\')" ) )
+ ( "with-software-components", _( "with software components" ) )
+ ;
+
+ // 非表示オプション
+ po::options_description hidden( _( "Hidden options" ) );
+ hidden.add_options()
+ ( "input-file,s", po::value< std::string >(), _( "input file" ) )
+ ;
+
+ po::options_description cmdline_options;
+ cmdline_options.add( generic ).add( config ).add( hidden );
+
+ po::options_description visible( _( "Allowed options" ) );
+ visible.add( generic ).add( config );
+
+ po::positional_options_description p;
+ p.add( "input-file", -1 );
+
+ po::variables_map vm;
+ try
+ {
+ store( po::command_line_parser( argc, argv ).
+ options( cmdline_options ).positional( p ).run(), vm );
+ notify( vm );
+ }
+ catch ( boost::program_options::error& )
+ {
+ toppers::fatal( _( "illegal options" ) );
+ }
+
+ // グローバル変数の設定
+ if ( vm.count( "print-dependencies" ) )
+ {
+ toppers::global( "print-dependencies" ) = vm[ "print-dependencies" ].as< std::string >();
+ pass = 1; // 依存関係の出力が必要な場合、強制的にパス1に変更
+ }
+
+ toppers::global( "pass" ) = pass;
+ if ( vm.count( "kernel" ) )
+ {
+ std::string kernel = toppers::tolower( vm[ "kernel" ].as< std::string >() );
+ toppers::global( "kernel" ) = kernel;
+ bool has_class = false;
+ bool has_domain = false;
+
+ if ( kernel == "fmp" || kernel == "fmp+hrp2" || kernel == "hrp2+fmp" )
+ {
+ has_class = true;
+ }
+ if ( kernel == "hrp2" || kernel == "fmp+hrp2" || kernel == "hrp2+fmp" )
+ {
+ has_domain = true;
+ }
+
+ toppers::global( "max-pass" ) = ( has_domain ? 4 : 3 );
+ toppers::global( "has-class" ) = has_class;
+ toppers::global( "has-domain" ) = has_domain;
+ }
+ if ( vm.count( "include-path" ) )
+ {
+ std::vector< std::string > v( vm[ "include-path" ].as< std::vector< std::string > >() );
+ std::transform( v.begin(), v.end(), v.begin(), &slashes_to_single_slash );
+ toppers::global( "include-path" ) = v;
+ }
+ if ( vm.count( "template-file" ) )
+ {
+ toppers::global( "template-file" )
+ = slashes_to_single_slash( vm[ "template-file" ].as< std::string >() );
+ }
+ if ( vm.count( "input-file" ) )
+ {
+ toppers::global( "input-file" )
+ = slashes_to_single_slash( vm[ "input-file" ].as< std::string >() );
+ }
+ if ( vm.count( "input-charset" ) )
+ {
+ std::string input_charset( toppers::tolower( vm[ "input-charset" ].as< std::string >() ) );
+ toppers::global( "input-charset" ) = input_charset;
+
+ toppers::codeset_t codeset = toppers::ascii;
+ if ( ( input_charset == "cp932" )
+ || ( input_charset == "shift_jis" )
+ || ( input_charset == "sjis" ) )
+ {
+ codeset = toppers::shift_jis;
+ }
+ else if ( ( input_charset == "eucjp" )
+ || ( input_charset == "euc-jp" )
+ || ( input_charset == "euc" ) )
+ {
+ codeset = toppers::euc_jp;
+ }
+ else if ( ( input_charset == "utf-8" )
+ || ( input_charset == "utf8" ) )
+ {
+ codeset = toppers::utf8;
+ }
+ toppers::global( "codeset" ) = codeset;
+ }
+ if ( vm.count( "api-table" ) )
+ {
+ std::vector< std::string > v( vm[ "api-table" ].as< std::vector< std::string > >() );
+ std::transform( v.begin(), v.end(), v.begin(), &slashes_to_single_slash );
+ toppers::global( "api-table" ) = v;
+ }
+ if ( vm.count( "cfg1-def-table" ) )
+ {
+ std::vector< std::string > v( vm[ "cfg1-def-table" ].as< std::vector< std::string > >() );
+ std::transform( v.begin(), v.end(), v.begin(), &slashes_to_single_slash );
+ toppers::global( "cfg1-def-table" ) = v;
+ }
+ if ( vm.count( "cfg1_out" ) )
+ {
+ toppers::global( "cfg1_out" ) = vm[ "cfg1_out" ].as< std::string >();
+ }
+ else
+ {
+ toppers::global( "cfg1_out" ) = std::string( "cfg1_out" );
+ }
+ if ( vm.count( "cfg-directory" ) )
+ {
+ std::string cfg_directory( vm[ "cfg-directory" ].as< std::string >() );
+ toppers::global( "cfg-directory" ) = slashes_to_single_slash( cfg_directory );
+ toppers::load_msgcat( cfg_directory );
+ }
+ if ( vm.count( "msgcat-directory" ) )
+ {
+ std::vector< std::string > msgcat_dirs( vm[ "msgcat-directory" ].as< std::vector< std::string > >() );
+ std::transform( msgcat_dirs.begin(), msgcat_dirs.end(), msgcat_dirs.begin(), &slashes_to_single_slash );
+ std::for_each( msgcat_dirs.begin(), msgcat_dirs.end(), &toppers::load_msgcat );
+ }
+ if ( true ) // include-path を空にしてはならない
+ {
+ std::vector< std::string > include_path;
+ boost::any t( toppers::global( "include-path" ) );
+ if ( !t.empty() )
+ {
+ include_path = boost::any_cast< std::vector< std::string > >( t );
+ }
+ include_path.push_back( toppers::get_global< std::string >( "cfg-directory" ) );
+ toppers::global( "include-path" ) = include_path;
+ }
+ if ( vm.count( "output-directory" ) )
+ {
+ toppers::global( "output-directory" ) = slashes_to_single_slash( vm[ "output-directory" ].as< std::string >() );
+ }
+ if ( vm.count( "rom-image" ) )
+ {
+ toppers::global( "rom-image" ) = slashes_to_single_slash( vm[ "rom-image" ].as< std::string >() );
+ }
+ if ( vm.count( "symbol-table" ) )
+ {
+ toppers::global( "symbol-table" ) = slashes_to_single_slash( vm[ "symbol-table" ].as< std::string >() );
+ }
+ else
+ {
+ toppers::global( "symbol-table" ) = toppers::get_global< std::string >( "kernel" ) + ".syms";
+ }
+ if ( vm.count( "id-output-file" ) )
+ {
+ toppers::global( "id-output-file" ) = slashes_to_single_slash( vm[ "id-output-file" ].as< std::string >() );
+ }
+ if ( vm.count( "id-input-file" ) )
+ {
+ toppers::global( "id-input-file" ) = slashes_to_single_slash( vm[ "id-input-file" ].as< std::string >() );
+ }
+ if ( vm.count( "alignof-fp" ) )
+ {
+ toppers::global( "alignof-fp" ) = vm[ "alignof-fp" ].as< std::size_t >();
+ }
+ toppers::global( "external-id" ) = vm.count( "external-id" ) ? true : false;
+ toppers::global( "with-software-components" ) = vm.count( "with-software-components" ) ? true : false;
+
+ toppers::global( "version" ) = std::string( CFG_VERSION );
+
+ if ( vm.count( "version" ) )
+ {
+ std::cout << "TOPPERS Kernel Configurator version " << CFG_VERSION << std::endl;
+ toppers::global( "pass0" ) = true;
+ }
+ if ( vm.count( "help" ) )
+ {
+ toppers::global( "help" ) = boost::lexical_cast< std::string >( visible );
+ std::cout << visible << std::endl;
+ toppers::global( "pass0" ) = true;
+ }
+ return pass;
+ }
+
+}
+
+//! コンフィギュレータのメイン処理
+int cfg_main( int argc, char* argv[] )
+{
+ using namespace toppers;
+
+ std::string const cfg_path( argv[0] );
+ std::string const cfg_name( "cfg" );
+ std::string::const_iterator iter = std::find_end( cfg_path.begin(), cfg_path.end(), cfg_name.begin(), cfg_name.end() );
+ // 環境変数のサーチまでは行わない
+ std::string cfg_dir( cfg_path.begin(), iter );
+ if ( *cfg_dir.rbegin() == '/' || *cfg_dir.rbegin() == '\\' )
+ {
+ cfg_dir.resize( cfg_dir.size() - 1 );
+ }
+ toppers::global( "cfg-directory" ) = cfg_dir;
+ toppers::global( "argv0" ) = std::string( argv[ 0 ] ); // プログラム名
+ toppers::global( "timestamp" ) = cfg_timestamp(); // タイムスタンプ
+
+ int pass = parse_program_options( argc, argv );
+ bool ( * pfn_cfg[] )() = { &cfg0_main, &cfg1_main, &cfg2_main, &cfg3_main, &cfg4_main };
+ int max_pass = toppers::get_global< int >( "max-pass" );
+
+ if ( pass < 0 || max_pass < pass )
+ {
+ fatal( _( "illegal cfg pass #%d" ), pass );
+ }
+
+ if ( !( *pfn_cfg[ pass ] )() )
+ {
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
+}
+
+int main( int arg, char* argv[] )
+{
+ int status;
+ try
+ {
+ toppers::set_program_name( "cfg" );
+ status = cfg_main( arg, argv );
+ if ( status != EXIT_SUCCESS && toppers::get_error_count() == 0 )
+ {
+ std::fprintf( stderr, "cfg: %s\n", _( "unknown error" ) );
+ }
+ if ( toppers::get_error_count() > 0 )
+ {
+ status = EXIT_FAILURE;
+ }
+ }
+ catch ( toppers::normal_exit& )
+ {
+ status = EXIT_SUCCESS;
+ }
+ catch ( std::exception& e )
+ {
+ std::fprintf( stderr, "cfg: %s\n", e.what() );
+ status = EXIT_FAILURE;
+ }
+ catch ( ... )
+ {
+ std::fprintf( stderr, "cfg: %s\n", _( "internal error" ) );
+ status = EXIT_FAILURE;
+ }
+ return status;
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+#ifndef CFG_HPP_
+#define CFG_HPP_
+
+#include <cctype>
+#include <cstdio>
+#include <cstdlib>
+#include <string>
+#include <vector>
+#include <sstream>
+#include <iostream>
+#include <algorithm>
+#include "toppers/workaround.hpp"
+#include "toppers/codeset.hpp"
+#include "toppers/global.hpp"
+#include "toppers/diagnostics.hpp"
+#include "toppers/text.hpp"
+#include "toppers/misc.hpp"
+#include "toppers/itronx/preprocess.hpp"
+#include "toppers/itronx/static_api.hpp"
+#include "toppers/itronx/factory.hpp"
+#include "toppers/itronx/cfg1_out.hpp"
+#include <boost/utility.hpp>
+#include <boost/format.hpp>
+
+#define CFG_VERSION cfg_version
+
+bool cfg0_main();
+bool cfg1_main();
+bool cfg2_main();
+bool cfg3_main();
+bool cfg4_main();
+void cfg_init();
+
+extern char const cfg_version[];
+
+std::tr1::int64_t cfg_timestamp();
+
+bool read_cfg_file( std::map< std::string, toppers::itronx::static_api::info > const info_map,
+ std::string& cfg1_list, std::string& includes,
+ std::vector< toppers::itronx::static_api >& static_api_array );
+
+void assign_id( toppers::itronx::cfg1_out::static_api_map& api_map );
+
+#endif // ! CFG_HPP_
--- /dev/null
+<?xml version="1.0" encoding="shift_jis"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="cfg"
+ ProjectGUID="{E2E91785-C5CB-4E57-98F0-7953A42FFEC0}"
+ RootNamespace="cfg"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=".."
+ PreprocessorDefinitions="_SCL_SECURE_NO_WARNINGS=1"
+ StringPooling="TRUE"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ SmallerTypeCheck="TRUE"
+ RuntimeLibrary="1"
+ BufferSecurityCheck="TRUE"
+ EnableFunctionLevelLinking="TRUE"
+ TreatWChar_tAsBuiltInType="TRUE"
+ ForceConformanceInForLoopScope="TRUE"
+ RuntimeTypeInfo="TRUE"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="oldnames.lib"
+ OutputFile="$(OutDir)/cfg.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/cfg.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="0"
+ EnableIntrinsicFunctions="TRUE"
+ ImproveFloatingPointConsistency="FALSE"
+ FavorSizeOrSpeed="2"
+ AdditionalIncludeDirectories=".."
+ PreprocessorDefinitions="_SCL_SECURE_NO_WARNINGS=1"
+ StringPooling="TRUE"
+ RuntimeLibrary="0"
+ TreatWChar_tAsBuiltInType="TRUE"
+ ForceConformanceInForLoopScope="TRUE"
+ RuntimeTypeInfo="TRUE"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="oldnames.lib"
+ OutputFile="$(OutDir)/cfg.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="ソース ファイル"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath=".\cfg.cpp">
+ </File>
+ <File
+ RelativePath=".\cfg0.cpp">
+ </File>
+ <File
+ RelativePath=".\cfg1.cpp">
+ </File>
+ <File
+ RelativePath=".\cfg2.cpp">
+ </File>
+ <File
+ RelativePath=".\cfg3.cpp">
+ </File>
+ <File
+ RelativePath=".\cfg4.cpp">
+ </File>
+ <File
+ RelativePath=".\cfg_version.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="ヘッダー ファイル"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath=".\cfg.hpp">
+ </File>
+ </Filter>
+ <File
+ RelativePath=".\ja.po">
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+#include "toppers/global.hpp"
+#include "toppers/diagnostics.hpp"
+
+bool cfg0_main()
+{
+ using namespace toppers;
+
+ try
+ {
+ if ( global( "pass0" ).empty() && !get_global< bool >( "pass0" ) )
+ {
+ goto failure;
+ }
+ }
+ catch ( boost::bad_any_cast& )
+ {
+ goto failure;
+ }
+ return true;
+
+failure:
+ fatal( _( "pass # is not specified" ) );
+ return false;
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+#include <fstream>
+#include "toppers/output_file.hpp"
+#include "cfg.hpp"
+
+/*!
+ * \brief パス1処理
+ * \retval true 成功
+ * \retval false 失敗
+ */
+bool cfg1_main()
+{
+ using namespace toppers;
+ using namespace toppers::itronx;
+
+ std::string kernel( get_global< std::string >( "kernel" ) );
+ itronx::factory factory( kernel );
+
+ std::string input_file;
+ try
+ {
+ input_file = get_global< std::string >( "input-file" );
+ }
+ catch ( boost::bad_any_cast& )
+ {
+ fatal( _( "no input files" ) );
+ }
+ codeset_t codeset = get_global< codeset_t >( "codeset" );
+
+ std::string cfg1_out_name( get_global< std::string >( "cfg1_out" ) );
+ std::auto_ptr< cfg1_out > cfg1_out( factory.create_cfg1_out( cfg1_out_name + ".c" ) );
+ cfg1_out->load_cfg( input_file, codeset, *factory.get_static_api_info_map() );
+ cfg1_out->generate();
+
+ if ( get_error_count() > 0 )
+ {
+ return false;
+ }
+ output_file::save();
+ return true;
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+#include <fstream>
+#include <sstream>
+#include "toppers/diagnostics.hpp"
+#include "toppers/s_record.hpp"
+#include "toppers/macro_processor.hpp"
+#include "toppers/itronx/component.hpp"
+#include "cfg.hpp"
+#include <boost/spirit/include/classic.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/operations.hpp>
+
+/*!
+ * \brief オブジェクトID番号の割付け
+ * \param[in] api_map ソースに記述された静的APIを登録したコンテナ
+ */
+void assign_id( toppers::itronx::cfg1_out::static_api_map& api_map )
+{
+ using namespace toppers;
+ using namespace toppers::itronx;
+
+ std::string id_input_file( get_global< std::string >( "id-input-file" ) );
+ if ( id_input_file.empty() ) // --id-input-file オプションが指定されていない場合...
+ {
+ for ( cfg1_out::static_api_map::iterator iter( api_map.begin() ), last( api_map.end() );
+ iter != last;
+ ++iter )
+ {
+ static_api::assign_id( iter->second.begin(), iter->second.end() );
+ }
+ }
+ else // --id-input-file オプションが指定されている場合...
+ {
+ typedef std::map< std::string, std::pair< long, bool > > id_map_t;
+ id_map_t id_map;
+ std::ifstream ifs( id_input_file.c_str() );
+ while ( ifs )
+ {
+ std::string linebuf;
+ std::getline( ifs, linebuf );
+ if ( ifs.bad() )
+ {
+ fatal( _( "I/O error" ) );
+ }
+ if ( linebuf.empty() || linebuf == "\r" )
+ {
+ break;
+ }
+
+ std::istringstream iss( linebuf );
+ std::string name;
+ iss >> name;
+ if ( iss.fail() )
+ {
+ fatal( _( "id file `%1%\' is invalid" ), id_input_file );
+ }
+
+ long value;
+ iss >> value;
+ if ( iss.fail() )
+ {
+ fatal( _( "id file `%1%\' is invalid" ), id_input_file );
+ }
+
+ if ( id_map.find( name ) != id_map.end() )
+ {
+ fatal( _( "E_OBJ: `%1%\' is duplicated" ), name );
+ }
+ else
+ {
+ id_map[ name ] = std::make_pair( value, false );
+ }
+ }
+
+ for ( cfg1_out::static_api_map::iterator iter( api_map.begin() ), last( api_map.end() );
+ iter != last;
+ ++iter )
+ {
+ for ( std::vector< static_api >::iterator iter2( iter->second.begin() ), last2( iter->second.end() );
+ iter2 != last2;
+ ++iter2 )
+ {
+ static_api::info const* info = iter2->get_info();
+ if ( info->id_pos >= 0 )
+ {
+ std::string name( iter2->at( info->id_pos ).text );
+ std::string symbol( iter2->at( info->id_pos ).symbol );
+ if ( !info->slave && symbol[0] == '#' )
+ {
+ id_map_t::iterator hit( id_map.find( name ) );
+ if ( hit != id_map.end() )
+ {
+ long id_value = hit->second.first;
+ if ( id_value > 0 )
+ {
+ iter2->at( info->id_pos ).value = id_value;
+ hit->second.second = true;
+ }
+ }
+ }
+ }
+ }
+ static_api::assign_id( iter->second.begin(), iter->second.end() );
+ }
+
+ for ( id_map_t::const_iterator iter( id_map.begin() ), last( id_map.end() ); iter != last; ++iter ) // 残り物があれば...
+ {
+ if ( !iter->second.second )
+ {
+ warning( _( "object identifier `%1%\' is not used" ), iter->first );
+ }
+ }
+ }
+
+ // --id-output-file オプションが指定されている場合
+ std::string id_output_file( get_global< std::string >( "id-output-file" ) );
+ if ( !id_output_file.empty() )
+ {
+ std::ofstream ofs( id_output_file.c_str() );
+ for ( cfg1_out::static_api_map::iterator iter( api_map.begin() ), last( api_map.end() );
+ iter != last;
+ ++iter )
+ {
+ for ( std::vector< static_api >::const_iterator iter2( iter->second.begin() ), last2( iter->second.end() );
+ iter2 != last2;
+ ++iter2 )
+ {
+ static_api::info const* info = iter2->get_info();
+ if ( info->id_pos >= 0 )
+ {
+ std::string name( iter2->at( info->id_pos ).text );
+ std::string symbol( iter2->at( info->id_pos ).symbol );
+ if ( !info->slave && symbol[0] == '#' )
+ {
+ ofs << name << '\t' << iter2->at( info->id_pos ).value.get() << std::endl;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+/*!
+ * \brief マクロプロセッサに登録するID割付け関数
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ */
+toppers::macro_processor::var_t bf_assignid( toppers::text_line const& line,
+ std::vector< toppers::macro_processor::var_t > const& arg_list,
+ toppers::macro_processor::context* p_ctx )
+{
+ using namespace toppers;
+ using namespace toppers::itronx;
+ using toppers::text_line;
+ typedef toppers::macro_processor::element element;
+ typedef toppers::macro_processor::var_t var_t;
+ typedef toppers::macro_processor::context context;
+
+ return var_t();
+}
+
+//! 組み込み関数ASSIGNIDを登録する
+void register_bf_assignid( toppers::macro_processor* mproc )
+{
+ // ↓ 追加組み込み関数の登録
+ toppers::macro_processor::func_t func_info = {};
+ func_info.name = "ASSIGNID";
+ func_info.f = &bf_assignid;
+ mproc->add_builtin_function( func_info );
+}
+
+/*!
+ * \brief パス2処理
+ * \retval true 成功
+ * \retval false 失敗
+ */
+bool cfg2_main()
+{
+ using namespace toppers;
+ using namespace toppers::itronx;
+
+ std::string kernel( get_global< std::string >( "kernel" ) );
+ itronx::factory factory( kernel );
+ global( "factory" ) = &factory;
+
+ // *.cfgとcfg1_out.srecの読み込み
+ std::string input_file;
+ try
+ {
+ input_file = get_global< std::string >( "input-file" );
+ }
+ catch ( boost::bad_any_cast& )
+ {
+ fatal( _( "no input files" ) );
+ }
+ std::string cfg1_out_name( get_global< std::string >( "cfg1_out" ) );
+ std::auto_ptr< cfg1_out > cfg1_out( factory.create_cfg1_out( cfg1_out_name ) );
+
+ codeset_t codeset = get_global< codeset_t >( "codeset" );
+ cfg1_out->load_cfg( input_file, codeset, *factory.get_static_api_info_map() );
+ cfg1_out->load_srec();
+
+ std::auto_ptr< macro_processor > mproc;
+ std::auto_ptr< component > component_ptr;
+
+ if ( get_global< bool >( "with-software-components" ) )
+ {
+ mproc = factory.create_macro_processor( *cfg1_out, cfg1_out->get_static_api_array() );
+ component_ptr.reset( new component( mproc.get() ) );
+ }
+ else // 従来仕様(ソフトウェア部品非対応)
+ {
+ cfg1_out::static_api_map api_map( cfg1_out->merge() );
+ assign_id( api_map ); // ID番号の割付け
+ mproc = factory.create_macro_processor( *cfg1_out, api_map );
+ }
+
+ // テンプレート処理
+ boost::any template_file( global( "template-file" ) );
+ namespace fs = boost::filesystem;
+ fs::path cfg_dir( get_global< std::string >( "cfg-directory" ), fs::native );
+ std::vector< std::string > include_paths = get_global< std::vector< std::string > >( "include-path" );
+ include_paths.push_back( cfg_dir.empty() ? "." : cfg_dir.native_file_string() );
+ if ( !template_file.empty() )
+ {
+ toppers::text in_text;
+ toppers::text pp_text;
+ std::string file_name( boost::any_cast< std::string& >( template_file ) );
+
+ in_text.set_line( file_name, 1 );
+ std::ifstream ifs( file_name.c_str() );
+ in_text.append( ifs );
+ macro_processor::preprocess( in_text, pp_text );
+ mproc->evaluate( pp_text );
+ }
+ else // テンプレートファイルが指定されていないので、共通部分(kernel.tf)のみを処理
+ {
+ fs::path kernel_cfg_template_file( cfg_dir/fs::path( "../../kernel/kernel.tf" ) );
+ if ( !fs::exists( kernel_cfg_template_file ) )
+ {
+ error( _( "cannot open file `%1%\'" ), kernel_cfg_template_file.native_file_string() );
+ }
+ else
+ {
+ toppers::text in_text;
+ toppers::text pp_text;
+
+ in_text.set_line( kernel_cfg_template_file.native_file_string(), 1 );
+ std::ifstream ifs( kernel_cfg_template_file.native_file_string().c_str() );
+ in_text.append( ifs );
+ macro_processor::preprocess( in_text, pp_text );
+ mproc->evaluate( pp_text );
+ }
+ }
+
+ if ( get_error_count() > 0 )
+ {
+ return false;
+ }
+ output_file::save();
+ return true;
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+#include <fstream>
+#include <sstream>
+#include "toppers/diagnostics.hpp"
+#include "toppers/s_record.hpp"
+#include "toppers/macro_processor.hpp"
+#include "toppers/itronx/component.hpp"
+#include "toppers/itronx/component.hpp"
+#include "cfg.hpp"
+#include <boost/spirit/include/classic.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/operations.hpp>
+
+namespace
+{
+ using toppers::text_line;
+ typedef toppers::macro_processor::element element;
+ typedef toppers::macro_processor::var_t var_t;
+ typedef toppers::macro_processor::context context;
+
+ /*!
+ * \brief シンボルに対応するアドレスの取得
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ */
+ var_t bf_symbol( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ using namespace toppers;
+ using namespace toppers::itronx;
+
+ if ( macro_processor::check_arity( line, arg_list.size(), 1, "SYMBOL" ) )
+ {
+ std::string symbol( macro_processor::to_string( arg_list[0], p_ctx ) );
+ std::tr1::shared_ptr< checker > chk = get_global< std::tr1::shared_ptr< checker > >( "checker" );
+ nm_symbol::entry entry = chk->find( symbol );
+ if ( entry.type >= 0 )
+ {
+ element e;
+ e.i = entry.address;
+ return var_t( 1, e );
+ }
+ }
+ return var_t();
+ }
+
+ // VMA アドレス解決用テーブル
+ std::vector< std::pair< std::tr1::int64_t, std::vector< unsigned char > > > vma_table;
+
+ /*!
+ * \brief 指定したアドレスに格納されている値の取得
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ *
+ * 第1引数にアドレスを、第2引数に読み込むバイト数を指定します。
+ */
+ var_t bf_peek( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ using namespace toppers;
+ using namespace toppers::itronx;
+
+ if ( macro_processor::check_arity( line, arg_list.size(), 2, "PEEK" ) )
+ {
+ std::size_t address = static_cast< std::size_t >( macro_processor::to_integer( arg_list[0], p_ctx ) );
+ std::size_t size = static_cast< std::size_t >( macro_processor::to_integer( arg_list[1], p_ctx ) );
+ std::tr1::shared_ptr< checker > chk = get_global< std::tr1::shared_ptr< checker > >( "checker" );
+
+ std::map< std::string, var_t >::const_iterator le_iter( p_ctx->var_map.find( "LITTLE_ENDIAN" ) );
+ if ( le_iter != p_ctx->var_map.end() )
+ {
+ bool little_endian = !!( *le_iter->second.front().i );
+ long pos = -1;
+ long base = 0;
+ element e;
+
+ for ( std::size_t i = 0, n = vma_table.size(); i < n; i++ )
+ {
+ if ( vma_table[i].first <= address && address < vma_table[i].first + vma_table[i].second.size() )
+ {
+ pos = i;
+ base = static_cast< long >( address - vma_table[i].first );
+ }
+ }
+ if ( pos >= 0 ) // VMA から読み取る
+ {
+ std::tr1::uint64_t value = 0;
+ if ( little_endian )
+ {
+ for ( long j = static_cast< long >( size-1 ); j >= 0; j-- )
+ {
+ int t = vma_table[ pos ].second[ base + j ];
+ if ( t < 0 )
+ {
+ return var_t();
+ }
+ value = ( value << 8 ) | ( t & 0xff );
+ }
+ }
+ else
+ {
+ for ( std::size_t j = 0; j < size; j++ )
+ {
+ int t = vma_table[ pos ].second[ base + j ];
+ if ( t < 0 )
+ {
+ return var_t();
+ }
+ value = ( value << 8 ) | ( t & 0xff );
+ }
+ }
+ e.i = value;
+ }
+ else // VMA ではないので、Sレコードから読み取る
+ {
+ e.i = chk->get( address, size, !!little_endian );
+ }
+ return var_t( 1, e );
+ }
+ }
+ return var_t();
+ }
+
+ /*!
+ * \brief メモリブロックの転送
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ *
+ * 第1引数に転送元アドレス、第2引数に転送先アドレス、第3引数に転送するバイト数を指定します。
+ * 指定したコピー元アドレスからコピー先アドレスへ、指定バイト数のメモリブロックを転送します。
+ * この関数は、LMAからVMAへのアドレス変換を目的として使用することを想定しています。
+ *
+ * \attention この組み込み関数は、LMAからVMAへのアドレス変換を想定しているため、頻繁に転送を
+ * 繰り返すような状況には対応していません(メモリ不足が発生します)。
+ */
+ var_t bf_bcopy( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ using namespace toppers;
+ using namespace toppers::itronx;
+
+ if ( macro_processor::check_arity( line, arg_list.size(), 3, "BCOPY" ) )
+ {
+ std::size_t src = static_cast< std::size_t >( macro_processor::to_integer( arg_list[0], p_ctx ) );
+ std::size_t dst = static_cast< std::size_t >( macro_processor::to_integer( arg_list[1], p_ctx ) );
+ std::size_t size = static_cast< std::size_t >( macro_processor::to_integer( arg_list[2], p_ctx ) );
+ std::tr1::shared_ptr< checker > chk = get_global< std::tr1::shared_ptr< checker > >( "checker" );
+
+ std::pair< std::tr1::int64_t, std::vector< unsigned char > > block;
+ block.first = dst;
+ block.second.reserve( size );
+ for ( std::tr1::int64_t i = 0; i < size; i++ )
+ {
+ block.second.push_back( static_cast< unsigned char >( chk->get( static_cast< std::size_t >( src + i ), 1, true ) ) );
+ }
+ vma_table.push_back( block );
+ }
+ return var_t();
+ }
+
+}
+
+bool cfg3_main()
+{
+ using namespace toppers;
+ using namespace toppers::itronx;
+
+ std::string kernel( get_global< std::string >( "kernel" ) );
+ itronx::factory factory( kernel );
+ global( "factory" ) = &factory;
+
+ // *.cfgとcfg1_out.srecの読み込み
+ std::string input_file;
+ try
+ {
+ input_file = get_global< std::string >( "input-file" );
+ }
+ catch ( boost::bad_any_cast& )
+ {
+ fatal( _( "no input files" ) );
+ }
+ std::string cfg1_out_name( get_global< std::string >( "cfg1_out" ) );
+ std::auto_ptr< cfg1_out > cfg1_out( factory.create_cfg1_out( cfg1_out_name ) );
+
+ codeset_t codeset = get_global< codeset_t >( "codeset" );
+ cfg1_out->load_cfg( input_file, codeset, *factory.get_static_api_info_map() );
+ cfg1_out->load_srec();
+
+ std::auto_ptr< checker > p_checker( factory.create_checker() );
+ std::tr1::shared_ptr< checker > chk( p_checker );
+ global( "checker" ) = chk;
+ std::string rom_image( get_global< std::string >( "rom-image" ) );
+ std::string symbol_table( get_global< std::string >( "symbol-table" ) );
+ chk->load_rom_image( rom_image, symbol_table );
+
+ // テンプレートファイル
+ boost::any template_file( global( "template-file" ) );
+ if ( template_file.empty() )
+ {
+ // テンプレートファイルが指定されていなければ最低限のチェックのみ(後方互換性のため)
+ // パラメータチェック
+ if ( !chk->check( *cfg1_out ) )
+ {
+ return false;
+ }
+ }
+ else
+ {
+ namespace fs = boost::filesystem;
+
+ // テンプレート処理
+ std::auto_ptr< macro_processor > mproc;
+ std::auto_ptr< component > component_ptr;
+
+ if ( get_global< bool >( "with-software-components" ) )
+ {
+ mproc = factory.create_macro_processor( *cfg1_out, cfg1_out->get_static_api_array() );
+ component_ptr.reset( new component( mproc.get() ) );
+ }
+ else
+ {
+ cfg1_out::static_api_map api_map( cfg1_out->merge() );
+ assign_id( api_map ); // ID番号の割付け
+ mproc = factory.create_macro_processor( *cfg1_out, api_map );
+ }
+
+ // ↓ 追加組み込み関数の登録
+ toppers::macro_processor::func_t func_info = {};
+ func_info.name = "SYMBOL";
+ func_info.f = &bf_symbol;
+ mproc->add_builtin_function( func_info );
+
+ func_info.name = "PEEK";
+ func_info.f = &bf_peek;
+ mproc->add_builtin_function( func_info );
+
+ func_info.name = "BCOPY";
+ func_info.f = &bf_bcopy;
+ mproc->add_builtin_function( func_info );
+ // ↑ 追加組み込み関数の登録
+
+ fs::path cfg_dir( get_global< std::string >( "cfg-directory" ), fs::native );
+ std::vector< std::string > include_paths = get_global< std::vector< std::string > >( "include-path" );
+ include_paths.push_back( cfg_dir.empty() ? "." : cfg_dir.native_file_string() );
+
+ toppers::text in_text;
+ toppers::text pp_text;
+ std::string file_name( boost::any_cast< std::string& >( template_file ) );
+
+ in_text.set_line( file_name, 1 );
+ std::ifstream ifs( file_name.c_str() );
+ if ( ifs.is_open() )
+ {
+ in_text.append( ifs );
+ macro_processor::preprocess( in_text, pp_text );
+ mproc->evaluate( pp_text );
+ }
+
+ if ( get_error_count() > 0 )
+ {
+ return false;
+ }
+ // 出力ファイルがあるかどうか分からないが、一応セーブする。
+ output_file::save();
+ }
+
+ // パス4以降からも流用されるため、現在処理中のパスを調べる。
+ int pass = get_global< int >( "pass" );
+ int max_pass = get_global< int >( "max-pass" );
+ if ( max_pass == pass ) // 最終段階のパスが成功したときに"check complete"メッセージを出す。
+ {
+ std::cerr << _( "check complete" ) << std::endl;
+ }
+
+ return true;
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2009 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+#include "cfg.hpp"
+
+bool cfg4_main()
+{
+ return cfg3_main();
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+void cfg_init()
+{
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+#define __STDC_CONSTANT_MACROS 1
+#include "cfg.hpp"
+#include <ctime>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+//! cfgのバージョン情報
+extern char const cfg_version[] = "1.6.0";
+
+/*!
+ * \brief プログラムファイル(cfg or cfg.exe)のタイムスタンプを取得する。
+ * \return タイムスタンプを64ビット整数値として返す。
+ *
+ * 返却値の形式は
+ *
+ * YYYYMMDDhhmmss
+ *
+ * となる。YYYYは年、MMは月、DDは日、hhは時、mmは分、ssは秒
+ *
+ * \note ファイル名は main の引数 argv[0] を使っている。PATH は検索しないので注意!
+ * \note この関数は stat 関数に依存しているため移植性に問題がある。
+ */
+std::tr1::int64_t cfg_timestamp()
+{
+ std::tr1::int64_t result;
+
+ try
+ {
+ std::string program_name = toppers::get_global< std::string >( "argv0" );
+
+ struct stat sb;
+ stat( program_name.c_str(), &sb );
+ struct tm t = *localtime( &sb.st_mtime );
+ result = ( t.tm_year + 1900 ) * INT64_C( 10000000000 ) + ( t.tm_mon + 1 ) * INT64_C( 100000000 ) + t.tm_mday * 1000000
+ + t.tm_hour * 10000 + t.tm_min * 100 + t.tm_sec;
+ }
+ catch ( ... )
+ {
+ result = -1;
+ }
+ return result;
+}
--- /dev/null
+#
+# TOPPERS Software
+# Toyohashi Open Platform for Embedded Real-Time Systems
+#
+# Copyright (C) 2007-2008 by TAKAGI Nobuhisa
+#
+# 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+# スコード中に含まれていること.
+# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+# の無保証規定を掲載すること.
+# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+# と.
+# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+# 作権表示,この利用条件および下記の無保証規定を掲載すること.
+# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+# 報告すること.
+# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+# 免責すること.
+#
+# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+# の責任を負わない.
+
+# このファイルは必ずUTF-8Nで保存すること。
+
+msgid "Generic options"
+msgstr "一般オプション"
+
+msgid "display this information"
+msgstr "この情報を表示する"
+
+msgid "display cfg version number"
+msgstr "cfgのバージョン番号を表示する"
+
+msgid "Configuration"
+msgstr "設定"
+
+msgid "kernel type (default: asp)"
+msgstr "カーネル種別 (既定ではasp)"
+
+msgid "run for pass #`arg\'"
+msgstr "パス #`arg\'を実行する"
+
+msgid "include path"
+msgstr "インクルードパス"
+
+msgid "template file"
+msgstr "一時ファイル"
+
+msgid "character set of input file (default: ascii)"
+msgstr "入力ファイルの文字コード (既定ではascii)"
+
+msgid "specify static API table"
+msgstr "静的APIテーブルを指定する"
+
+msgid "specify cfg1 definition table"
+msgstr "cfg1定義テーブルを指定する"
+
+msgid "specify file name instead of `cfg1_out.srec\' (default: cfg1_out)"
+msgstr "`cfg1_out.srec\'に代わるファイル名を指定する (既定ではcfg1_out)"
+
+msgid "ROM image (S-record)"
+msgstr "ROMイメージ (Sレコード)"
+
+msgid "cfg directory"
+msgstr "cfgディレクトリ"
+
+msgid "msgcat(*.po) directory"
+msgstr "msgcat(*.po)ディレクトリ"
+
+msgid "destination directory"
+msgstr "出力先ディレクトリ"
+
+msgid "output file for id assignment"
+msgstr "ID割り付けのための出力ファイル"
+
+msgid "input file for id assignment"
+msgstr "ID割り付けのための入力ファイル"
+
+msgid "alignment of pointer to function"
+msgstr "関数へのポインタの境界調整"
+
+msgid "output ID numbers as external `const\' object"
+msgstr "ID番号を外部`const\'オブジェクトとして出力する"
+
+msgid "output dependencies of source file (for `make\')"
+msgstr "ソースファイルの依存関係を出力 (`make\'用)"
+
+msgid "Hidden options"
+msgstr "隠しオプション"
+
+msgid "input file"
+msgstr "入力ファイル"
+
+msgid "Allowed options"
+msgstr "指定可能なオプション"
+
+msgid "illegal options"
+msgstr "不正なオプション"
+
+msgid "illegal cfg pass #%d"
+msgstr "不正なcfgパス#%d"
+
+msgid "unknown error"
+msgstr "不明なエラー"
+
+msgid "internal error"
+msgstr "内部エラー"
+
+msgid "pass # is not specified"
+msgstr "パス番号が指定されていない"
+
+msgid "no input files"
+msgstr "入力ファイルが無い"
+
+msgid "id file `%1%\' is invalid"
+msgstr "IDファイル`%1%\'が不正"
+
+msgid "`%1%\' is undefined"
+msgstr "`%1%\'が定義されていない"
+
+msgid "static API `%1%\' is unknown"
+msgstr "未知の静的API `%1%\'"
+
+msgid "cannot open file `%1%\'"
+msgstr "ファイル`%1%\'がオープンできない"
+
+msgid "check complete"
+msgstr "チェック完了"
+
+msgid "too few arguments for `%1%\'"
+msgstr "`%1%\'に対する実引数が少なすぎる"
+
+msgid "too many arguments for `%1%\'"
+msgstr "`%1%\'に対する実引数が多すぎる"
+
+msgid "warning"
+msgstr "警告"
+
+msgid "error"
+msgstr "エラー"
+
+msgid "too many errors"
+msgstr "エラーが多すぎる"
+
+msgid "fatal error"
+msgstr "致命的エラー"
+
+msgid "I/O error"
+msgstr "I/Oエラー"
+
+msgid "end of line"
+msgstr "行末"
+
+msgid "missing `%1%\' before %2%"
+msgstr "%2%の前に`%1%\'がない"
+
+msgid "non-value is referred"
+msgstr "値ではないのに参照しようとした"
+
+msgid "`%1%\' does not have a value"
+msgstr "`%1%\'は値を持たない"
+
+msgid "shift with nagative value `%1%\'"
+msgstr "負の値`%1%\'によるシフト"
+
+msgid "shift with too large value `%1%\'"
+msgstr "大きすぎる値`%1%\'によるシフト"
+
+msgid "negative value `%1%\' is shift"
+msgstr "負の値`%1%\'がシフトされた"
+
+msgid "overflow at `%1%\'"
+msgstr "`%1%\'でオーバーーフロー"
+
+msgid "devide by zero"
+msgstr "0による除算"
+
+msgid "function `%1%\' is undefined"
+msgstr "関数`%1%\'は定義されていない"
+
+msgid "illegal arithmetic sequence"
+msgstr "不正な等差数列"
+
+msgid "syntax error"
+msgstr "構文エラー"
+
+msgid "illegal character `%1%\' is found"
+msgstr "不正な文字`%1%\'が現れた"
+
+msgid "`#%1%\' is not supported"
+msgstr "`#%1%\'はサポートしていない"
+
+msgid "`%1%\'' is illegal object identifier"
+msgstr "`%1%\'は不正なオブジェクト識別子"
+
+msgid "magic number is not found in `%1%\'"
+msgstr "`%1%\'の中にマジックナンバーが見つからない"
+
+msgid "`%1%\' is corrupted"
+msgstr "`%1%\'が壊れている"
+
+msgid "E_NOEXS: `%1%\' is undefined"
+msgstr "E_NOEXS: `%1%\'は定義されていない"
+
+msgid "probably, %1% argument of `%2%\' is illegal"
+msgstr "おそらく、%2%の%1%実引数は不正"
+
+msgid "1st"
+msgstr "第1"
+
+msgid "2nd"
+msgstr "第2"
+
+msgid "3rd"
+msgstr "第3"
+
+msgid "missing token `%1%\'"
+msgstr "字句`%1%\'がない"
+
+msgid "illegal token `%1%\'"
+msgstr "不正な字句`%1%\'"
+
+msgid "`%1%\' is duplicated"
+msgstr "`%1%\'が重複している"
+
+msgid "`%1%\' of #%2% is null pointer"
+msgstr "#%2%の`%1%\'が空ポインタ"
+
+msgid "`%1%\' of #%2% is not aligned on `%3%\' bytes boundary"
+msgstr "#%2%の`%1%\'が%3%バイト境界に整列していない"
+
+msgid "illegal %1% `%2%\' in %3%"
+msgstr "%3%における%1% `%2%\'が不正"
+
+msgid "illegal %1% `%2%\' of `%3%\' in %4%"
+msgstr "%4%における`%3%\'の%1% `%2%\'が不正"
+
+msgid "too large %1% `%2%\' of `%3%\' in %4%"
+msgstr "%4%における`%3%\'の%1% `%2%\'が大きすぎる"
+
+msgid "illegal %1% `%2%\' of %3% `%4%\' in %5%"
+msgstr "%5%における%3% `%4%\'の%1% `%2%\'が不正"
+
+msgid "%1% `%2%\' in %3% is duplicated"
+msgstr "%3%における%1% `%2%\'が重複している"
+
+msgid "%1% `%2%\' in %3% is duplicated with %4% `%5%\'"
+msgstr "%3%における%1% `%2%\'が%4 `%5%\'と重複している"
+
+msgid "%1% `%2%\' is not configured with %3%"
+msgstr "%1% `%2%\'が%3によって設定されていない"
+
+msgid "%1% `%2%\' corresponding to %3% `%4%\' is not configured with %5%"
+msgstr "%3% `%4%\'に対応する%1% `%2%\'が%5によって設定されていない"
+
+msgid "%1% `%2%\' configured for %3% `%4%\' is higher than %5%"
+msgstr "%3% `%4%\'に設定されている%1% `%2%\'が%5よりも高い"
+
+msgid "%1% `%2%\' configured for %3% `%4%\' is lower than or equal to %5%"
+msgstr "%3% `%4%\'に設定されている%1% `%2%\'が%5よりも同じか低い"
+
+msgid "too many %1%"
+msgstr "%1%が多すぎる"
+
+msgid "%1% is not recommended when %2% is set to %3% in %4%"
+msgstr "%3%に%2%が設定されている場合には%1%とすることは推奨されない"
+
+msgid "`%1%\' id numbers do not continue"
+msgstr "`%1%\' ID番号が連続していない"
+
+msgid "object identifier `%1%\' is not used"
+msgstr "オブジェクト識別子 `%1%\'は使われていない"
+
+msgid "%1% `%2%\' of `%3%\' in %4% is not aligned"
+msgstr "%4%における`%3%\'の%1% `%2%\'がアラインしていない"
+
+msgid "%1% `%2%\' of `%3%\' in %4% is null"
+msgstr "%4%における`%3%\'の%1% `%2%\'がNULLである"
+
+msgid "%1% `%2%\' in %3% is not aligned"
+msgstr "%3%における%1% `%2%\'がアラインしていない"
+
+msgid "%1% `%2%\' in %3% is null"
+msgstr "%3%における%1% `%2%\'がNULLである"
+
+msgid "no body of %1%"
+msgstr "%1%の本体がない"
+
+msgid "E_OBJ: `%1%\' is duplicated"
+msgstr "E_OBJ: `%1%\'が重複している"
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/*!
+ * \file require_module.hpp
+ * \brief サポート対象カーネルのためのモジュール要求
+ *
+ * \todo ASP以外のカーネルをサポートするときは、このヘッダファイルを存在するディレクトリを元に
+ * 自動生成させること。(OSEK SGと類似の方法?)
+ */
+#define REQUIRE_MODULE( name ) \
+ namespace name { bool init(); bool call_init = init(); }
+
+namespace toppers { namespace itronx {
+
+ REQUIRE_MODULE( asp )
+
+} }
--- /dev/null
+#!/bin/sh
+
+makefile_config="Makefile.config"
+
+# コマンドライン引数の処理
+for arg in "$@"
+do
+ name=`echo $arg | cut -d "=" -f 1`
+ value=`echo $arg | cut -d "=" -f 2`
+
+ case $name in
+ --with-headers) include_path=$value ;;
+ --with-libraries) library_path=$value ;;
+ --help) echo "configure options:"
+ echo "--help"
+ echo " display this information"
+ echo "--with-headers=<dir>"
+ echo " specify the directory of Boost headers"
+ echo "--with-libraries=<dir>"
+ echo " specify the directory of Boost libraries"
+ ;;
+ esac
+done
+
+# Boost C++ Librariesのヘッダファイルがあるディレクトリをサーチ
+for dir in $include_path "/usr/local/include" "/opt/local/include" "/opt/include" "/usr/include" "/mingw/include"
+do
+ ls $dir/boost* 2> /dev/null > /dev/null
+ if test $? -eq 0
+ then
+ boost_dir=`ls -d $dir/boost* | sort -r | head -1`
+ if test $boost_dir = $dir/boost
+ then
+ include_path=$dir
+ else
+ include_path=$boost_dir
+ fi
+ break
+ fi
+done
+
+# Boost C++ Librariesのライブラリファイルがあるディレクトリをサーチ
+for dir in $library_path "/usr/local/lib" "/opt/local/lib" "/opt/lib" "/usr/lib" "/lib" "/mingw/lib"
+do
+ ls $dir/libboost* 2> /dev/null > /dev/null
+ if test $? -eq 0
+ then
+ library_path=$dir
+ break
+ fi
+done
+
+##### 以下、Makefile.configを生成する #####
+
+rm Makefile.config 2> /dev/null
+
+# Boost C++ Librariesのバージョンを調べる
+boost_version=`echo "#include <boost/version.hpp>
+echo BOOST_VERSION" | g++ -E -I$include_path -L$library_path - | sh`
+
+boost_lib_version=`echo "#include <boost/version.hpp>
+echo BOOST_LIB_VERSION" | g++ -E -I$include_path -L$library_path - | sh`
+
+# ライブラリファイルの添字を調べる
+# 環境によって、-gcc-mt-s, -mt-s, -gcc42-mt-sなど、添字が異なるため
+libboost_regex_filename=`ls $library_path/libboost_regex*-s.* 2> /dev/null | head -1`
+if test -z $libboost_regex_filename
+then
+ libboost_regex_filename=`ls $library_path/libboost_regex*.* | head -1`
+fi
+libboost_suffix=`echo $libboost_regex_filename | sed -e s/.*libboost_regex//g -e s/\.[a-z]*$//g`
+echo "LIBBOOST_SUFFIX=$libboost_suffix" >> $makefile_config
+
+options=`echo "#if defined(__x86_64) && defined(__APPLE__)
+-m32
+#endif" | g++ -E -x c++ - | grep m32`
+
+# 各種変数を出力
+echo BOOST_VERSION=$boost_lib_version >> $makefile_config
+echo BOOST_DIR=$include_path >> $makefile_config
+echo LIBBOOST_DIR=$library_path >> $makefile_config
+echo OPTIONS=$options >> $makefile_config
+
+# 生成結果を表示
+cat Makefile.config
+
+# 終わり
--- /dev/null
+-include ../Makefile.config
+
+PROJDIR = ..
+WORKDIR = $(PROJDIR)/toppers
+
+CPPFLAGS := $(CPPFLAGS) -I$(BOOST_DIR) -I$(PROJDIR)
+CXXFLAGS := $(CXXFLAGS) -O2 -g
+
+CXXFILES = \
+ builtin_function.cpp \
+ c_chlit_parser.cpp \
+ c_ident_parser.cpp \
+ c_int_parser.cpp \
+ c_keywords.cpp \
+ c_plus_plus_keywords.cpp \
+ c_strlit_parser.cpp \
+ cpp.cpp \
+ diagnostics.cpp \
+ gettext.cpp \
+ global.cpp \
+ io.cpp \
+ macro_processor.cpp \
+ mbchar_parser.cpp \
+ nm_symbol.cpp \
+ output_file.cpp \
+ s_record.cpp \
+ ucn_parser.cpp \
+
+OBJFILES := $(CXXFILES:%.cpp=%.o)
+
+all: libtoppers.a
+
+libtoppers.a: $(OBJFILES)
+ $(AR) rcs libtoppers.a $(OBJFILES)
+
+depend:
+ $(CXX) $(CPPFLAGS) -M $(CXXFILES) > Makefile.depend
+
+clean:
+ -rm -f *.o *.a
+
+-include Makefile.depend
+
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+#include <cstdlib>
+#include <cerrno>
+#include <string>
+#include <vector>
+#include <utility>
+#include <algorithm>
+#include <ostream>
+#include "toppers/macro_processor.hpp"
+#include "toppers/diagnostics.hpp"
+#include "toppers/gettext.hpp"
+#include "toppers/cpp.hpp"
+#include <boost/format.hpp>
+#include <boost/utility.hpp>
+#include <boost/lexical_cast.hpp>
+#include <cstdio>
+
+namespace toppers
+{
+ namespace
+ {
+ typedef macro_processor::element element;
+ typedef macro_processor::var_t var_t;
+ typedef macro_processor::context context;
+
+ inline std::tr1::int64_t get_i( var_t const& var, context const* p_ctx )
+ {
+ return macro_processor::to_integer( var, p_ctx );
+ }
+ inline std::string get_s( var_t const& var, context const* p_ctx )
+ {
+ return macro_processor::to_string( var, p_ctx );
+ }
+
+ }
+
+ /*!
+ * \brief 引数の個数チェック
+ * \param[in] line 行番号情報
+ * \param[in] arity 引数の個数
+ * \param[in] valid 期待している引数の個数
+ * \param[in] function_name 組み込み関数名
+ */
+ bool macro_processor::check_arity( text_line const& line, std::size_t arity, std::size_t valid, char const* function_name )
+ {
+ bool result = false;
+ if ( arity < valid )
+ {
+ error( line, _( "too few arguments for `%1%\'" ), function_name );
+ }
+ else if ( arity > valid )
+ {
+ error( line, _( "too many arguments for `%1%\'" ), function_name );
+ }
+ else
+ {
+ result = true;
+ }
+ return result;
+ }
+
+ /*!
+ * \brief 変数ダンプのための<<演算子
+ * \param[in,out] ostr 出力ストリーム
+ * \param[in] arg 変数を参照するためのペア
+ * \return ostrを返す
+ * \note 現在の実装では、arg.second は使用していない。
+ */
+ std::ostream& operator<<( std::ostream& ostr, std::pair< var_t const*, context const* > const& arg )
+ {
+ for ( var_t::const_iterator iter( arg.first->begin() ), last( arg.first->end() ); iter != last; ++iter )
+ {
+ if ( !iter->s.empty() )
+ {
+ ostr << iter->s;
+ }
+ else if ( iter->i )
+ {
+ ostr << iter->i.get();
+ }
+ if ( boost::next( iter ) != last )
+ {
+ ostr << ",";
+ }
+ }
+ return ostr;
+ }
+
+ /*!
+ * \brief 順序リストの長さ
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ * 第1マクロ実引数として指定した順序付きリストの要素数を返す。
+ * 第1マクロ実引数が順序付きリストでない場合は1を返す。また、第1マクロ実引数が無効な変数の場合は0を返す。
+ */
+ var_t bf_length( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ element e;
+ if ( macro_processor::check_arity( line, arg_list.size(), 1, "LENGTH" ) )
+ {
+ std::tr1::int64_t size = arg_list.front().size();
+ e.i = size;
+ }
+ return var_t( 1, e );
+ }
+
+ /*!
+ * \brief 文字列の一致判定
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ * 第1マクロ実引数と第2マクロ実引数を文字列として比較し、一致する場合は真を、そうでなければ偽を返す。
+ */
+ var_t bf_eq( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ element e;
+ if ( macro_processor::check_arity( line, arg_list.size(), 2, "EQ" ) )
+ {
+ e.i = get_s( arg_list[ 0 ], p_ctx ) == get_s( arg_list[ 1 ], p_ctx );
+ }
+ return var_t( 1, e );
+ }
+
+ /*!
+ * \brief 代替値
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ * 第1マクロ実引数が無効な変数の場合は第2実引数を返す。その他は第1実引数を返す。
+ */
+ var_t bf_alt( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ element e;
+ if ( macro_processor::check_arity( line, arg_list.size(), 2, "ALT" ) )
+ {
+ if ( !arg_list[0].empty() )
+ {
+ return arg_list[ 0 ];
+ }
+ else
+ {
+ return arg_list[ 1 ];
+ }
+ }
+ return var_t( 1, e );
+ }
+
+ /*!
+ * \brief 順序リストの整列
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ * 第1マクロ実引数として与えた順序付きリストの各要素を、第2マクロ実引数の添え字とした場合の変数を評価し、
+ * その評価結果に基づき昇順に整列する。
+ *
+ * \code
+ * $FOO[1] = 20$
+ * $FOO[2] = 10$
+ * $FOO[3] = 30$
+ * $SORT({ 1,2,3 }, "FOO")$
+ * → { 2,1,3 }
+ * \endcode
+ */
+ var_t bf_sort( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ var_t result;
+ if ( macro_processor::check_arity( line, arg_list.size(), 2, "SORT" ) )
+ {
+ var_t list( arg_list[ 0 ] );
+ std::string field( get_s( arg_list[ 1 ], p_ctx ) );
+ std::vector< std::pair< element, std::tr1::int64_t > > temp;
+
+ for ( var_t::const_iterator iter( list.begin() ), last( list.end() ); iter != last; ++iter )
+ {
+ std::tr1::int64_t order = iter->i.get();
+ std::string name( ( boost::format( "%s[%d]" ) % field % order ).str() );
+ std::map< std::string, var_t >::const_iterator m_iter( p_ctx->var_map.find( name ) );
+ if ( m_iter == p_ctx->var_map.end() )
+ {
+ return var_t();
+ }
+ if ( !m_iter->second.empty() )
+ {
+ temp.push_back( std::make_pair( m_iter->second.front(), order ) );
+ }
+ }
+
+ std::stable_sort( temp.begin(), temp.end() );
+
+ for ( std::vector< std::pair< element, std::tr1::int64_t > >::const_iterator iter( temp.begin() ), last( temp.end() );
+ iter != last;
+ ++iter )
+ {
+ element e;
+ e.i = iter->second;
+ result.push_back( e );
+ }
+ }
+ return result;
+ }
+
+ /*!
+ * \brief 環境変数の取得
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ * 第1マクロ実引数で指定した環境変数の値を返す。
+ */
+ var_t bf_environ( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ element e;
+ if ( macro_processor::check_arity( line, arg_list.size(), 1, "ENVIRON" ) )
+ {
+ std::string name = get_s( arg_list[ 0 ], p_ctx );
+ char const* env = std::getenv( name.c_str() );
+ if ( env == 0 )
+ {
+ return var_t();
+ }
+ e.s = env;
+ errno = 0;
+ char* endptr;
+ if ( std::tr1::int64_t value = std::strtol( env, &endptr, 0 ) )
+ {
+ if ( *endptr == '\0' && errno == 0 )
+ {
+ e.i = value;
+ }
+ }
+ }
+ return var_t( 1, e );
+ }
+
+ /*!
+ * \brief 値の生成
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ * 第1マクロ実引数をテキスト、第2マクロ実引数を数値として、値を生成する。
+ */
+ var_t bf_value( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ element e;
+ if ( macro_processor::check_arity( line, arg_list.size(), 2, "VALUE" ) )
+ {
+ if ( !arg_list[0].empty() )
+ {
+ e.s = get_s( arg_list[ 0 ], p_ctx );
+ }
+ if ( !arg_list[1].empty() )
+ {
+ e.i = get_i( arg_list[ 1 ], p_ctx );
+ }
+ }
+ return var_t( 1, e );
+ }
+
+ /*!
+ * \brief 文字列の連結
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ * 第1マクロ実引数と第2マクロ実引数を連結して新しい文字列を生成する。
+ */
+ var_t bf_concat( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ element e;
+ if ( macro_processor::check_arity( line, arg_list.size(), 2, "CAT" ) )
+ {
+ e.s = get_s( arg_list[ 0 ], p_ctx ) + get_s( arg_list[ 1 ], p_ctx );
+ }
+ return var_t( 1, e );
+ }
+
+ /*!
+ * \brief 順序リストの終端に要素を追加
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ * 第1マクロ実引数と第2マクロ実引数を連結して新しい順序付きリストを生成する。
+ */
+ var_t bf_append( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ var_t result;
+ if ( macro_processor::check_arity( line, arg_list.size(), 2, "APPEND" ) )
+ {
+ result = arg_list[ 0 ];
+ result.insert( result.end(), arg_list[ 1 ].begin(), arg_list[1].end() );
+ }
+ return result;
+ }
+
+ /*!
+ * \brief 順序リストの指定要素の参照
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ * 第1マクロ実引数で指定した順序リストの、第2マクロ実引数で指定した要素を返す。
+ */
+ var_t bf_at( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ element e;
+ if ( macro_processor::check_arity( line, arg_list.size(), 2, "CAT" ) )
+ {
+ try
+ {
+ e = arg_list[ 0 ].at( static_cast< std::vector< var_t >::size_type >( get_i( arg_list[1], p_ctx ) ) );
+ }
+ catch ( std::out_of_range& )
+ {
+ // 添え字が不正
+ // 特に何もしない → この時点で e が空値であることを期待
+ }
+ }
+ return var_t( 1, e );
+ }
+
+ /*!
+ * \brief テキストの翻訳
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ * 第1マクロ実引数で指定した文字列を翻訳する。
+ */
+ var_t bf_gettext( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ element e;
+ if ( macro_processor::check_arity( line, arg_list.size(), 1, "GETTEXT" ) )
+ {
+ std::string message = get_s( arg_list[ 0 ], p_ctx );
+ e.s = gettext( message );
+ }
+ return var_t( 1, e );
+ }
+
+ /*!
+ * \brief マクロ実引数の書式化
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ * 第1マクロ実引数で指定した初期化文字列によって、第2マクロ実引数以降を書式化する。
+ * 書式化文字列は、%nが使えないことを除き、printf関数のスーパーセットである。
+ * 正確な仕様は、boost::formatを参照のこと。
+ */
+ var_t bf_format( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ element e;
+ std::size_t arity = arg_list.size();
+ if ( arity < 1 )
+ {
+ error( line, _( "too few arguments for `%1%\'" ), "FORMAT" );
+ }
+ std::string format_str = get_s( arg_list[ 0 ], p_ctx );
+#if 0
+ std::string debug_str = format_str;
+ if ( debug_str == "0x%08x" )
+ toppers::trace("%s", debug_str.c_str() );
+#endif
+ boost::format fmt( format_str );
+ for ( std::size_t i = 1; i < arity; i++ )
+ {
+ std::pair< var_t const*, context const* > arg( &arg_list[i], p_ctx );
+ fmt % arg;
+ }
+ e.s = fmt.str();
+ return var_t( 1, e );
+ }
+
+ /*!
+ * \brief 順序付きリスト内の探索
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ * 第1マクロ実引数で指定した順序付きリストに含まれる第2マクロ実引数で指定した値に等しい要素を、
+ * 先頭から順に探索する。
+ * 等しい要素が見つかればその要素へのインデックスを、そうでなければ空値を返す。
+ */
+ var_t bf_find( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ element e;
+ if ( macro_processor::check_arity( line, arg_list.size(), 2, "FIND" ) )
+ {
+ var_t list( arg_list[ 0 ] );
+ std::tr1::int64_t value( get_i( arg_list[ 1 ], p_ctx ) );
+
+ for ( var_t::const_iterator iter( list.begin() ), last( list.end() ); iter != last; ++iter )
+ {
+ if ( iter->i.get() == value ) // 発見!
+ {
+ e.i = iter - list.begin(); // iter は RandomAccessIterator
+ return var_t( 1, e );
+ }
+ }
+ }
+ return var_t();
+ }
+
+ /*!
+ * \brief 範囲指定による順序付きリスト
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ * 第1マクロ実引数で最初の値を、第2マクロ実引数で最後の値を指定する。
+ * { 最初の値, 最初の値 + 1, ... 最後の値 }
+ * となる順序付きリストを生成する。
+ * 引数が正しくない場合は空値を返す。
+ */
+ var_t bf_range( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ var_t result;
+ if ( macro_processor::check_arity( line, arg_list.size(), 2, "RANGE" ) )
+ {
+ std::tr1::int64_t arg1( get_i( arg_list[ 0 ], p_ctx ) );
+ std::tr1::int64_t arg2( get_i( arg_list[ 1 ], p_ctx ) );
+
+ for ( ; arg1 <= arg2; ++arg1 )
+ {
+ element e;
+ e.i = arg1;
+ result.push_back( e );
+ }
+ }
+ return result;
+ }
+
+ /*!
+ * \brief 全変数のダンプ
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ * マクロ実引数を指定した場合、その文字列属性で指定したファイルにダンプした文字列を追記する。
+ * ファイル名として、"stdout"を指定した場合は標準出力、"stderr"を指定した場合は標準エラーに出力する。
+ * ファイル名を省略した場合は"stderr"を指定したものとして振舞う。
+ */
+ var_t bf_dump( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ std::size_t arity = arg_list.size();
+
+ if ( arity > 1 )
+ {
+ error( line, _( "too many arguments for `%1%\'" ), "DUMP" );
+ }
+
+ std::string dump_str;
+
+ // 全変数をなめる
+ for ( std::map< std::string, var_t >::const_iterator iter( p_ctx->var_map.begin() ), last( p_ctx->var_map.end() );
+ iter != last;
+ ++iter )
+ {
+ dump_str += "$" + iter->first + "$ = { ";
+ if ( !iter->second.empty() )
+ {
+ // 各変数の全要素
+ for ( var_t::const_iterator iter2( iter->second.begin() ), last2( iter->second.end() );
+ iter2 != last2;
+ ++iter2 )
+ {
+ dump_str += "\"" + iter2->s + "\"(";
+ if ( iter2->i ) // 値属性があれば...
+ {
+ dump_str += boost::lexical_cast< std::string >( *iter2->i );
+ }
+ dump_str += "), ";
+ }
+ }
+ dump_str += " }\n";
+ }
+
+ std::string filename( "stderr" );
+ if ( arity == 1 )
+ {
+ filename = get_s( arg_list[ 0 ], p_ctx );
+ }
+ if ( filename == "stdout" )
+ {
+ fputs( dump_str.c_str(), stdout );
+ }
+ else if ( filename == "stderr" )
+ {
+ fputs( dump_str.c_str(), stderr );
+ }
+ else
+ {
+ std::FILE* stream = std::fopen( filename.c_str(), "a" );
+ if ( stream != 0 )
+ {
+ fputs( dump_str.c_str(), stream );
+ std::fclose( stream );
+ }
+ }
+ element e;
+ return var_t( 1, e );
+ }
+
+ /*!
+ * \brief 変数のトレース
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ * 第1マクロ実引数で指定した変数の内容をトレースする。
+ * 第2マクロ実引数を指定した場合、その文字列属性で指定したファイルにトレース内容を追記する。
+ * ファイル名として、"stdout"を指定した場合は標準出力、"stderr"を指定した場合は標準エラーに出力する。
+ * ファイル名を省略した場合は"stderr"を指定したものとして振舞う。
+ */
+ var_t bf_trace( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ std::size_t arity = arg_list.size();
+
+ if ( arity < 1 )
+ {
+ error( line, _( "too few arguments for `%1%\'" ), "TRACE" );
+ }
+ else if ( arity > 2 )
+ {
+ error( line, _( "too many arguments for `%1%\'" ), "TRACE" );
+ }
+
+ var_t value( arg_list[ 0 ] );
+
+ std::string trace_str = "{ ";
+ for ( var_t::const_iterator iter( value.begin() ), last( value.end() );
+ iter != last;
+ ++iter )
+ {
+ trace_str += "\"" + iter->s + "\"(";
+ if ( iter->i ) // 値属性があれば...
+ {
+ trace_str += boost::lexical_cast< std::string >( *iter->i ) + " as integer";
+ }
+ else if ( !iter->v.empty() )
+ {
+ trace_str += "\"" + boost::lexical_cast< std::string >( iter->v ) + "\" as string";
+ }
+ trace_str += "), ";
+ }
+ trace_str += " }\n";
+
+ std::string filename( "stderr" );
+ if ( arity == 2 )
+ {
+ filename = get_s( arg_list[ 1 ], p_ctx );
+ }
+ if ( filename == "stdout" )
+ {
+ fputs( trace_str.c_str(), stdout );
+ }
+ else if ( filename == "stderr" )
+ {
+ fputs( trace_str.c_str(), stderr );
+ }
+ else
+ {
+ std::FILE* stream = std::fopen( filename.c_str(), "a" );
+ if ( stream != 0 )
+ {
+ fputs( trace_str.c_str(), stream );
+ std::fclose( stream );
+ }
+ }
+
+ element e;
+ return var_t( 1, e );
+ }
+
+ /*!
+ * \brief 文字列のエスケープ
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ */
+ var_t bf_escstr( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ element e;
+ if ( macro_processor::check_arity( line, arg_list.size(), 1, "ESCSTR" ) )
+ {
+ std::string str( get_s( arg_list[ 0 ], p_ctx ) );
+ e.s = quote_string( str );
+ }
+ return var_t( 1, e );
+ }
+
+ /*!
+ * \brief 文字列のエスケープ解除
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ */
+ var_t bf_unescstr( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ element e;
+ if ( macro_processor::check_arity( line, arg_list.size(), 1, "UNESCSTR" ) )
+ {
+ std::string str( get_s( arg_list[ 0 ], p_ctx ) );
+ e.s = expand_quote( str );
+ }
+ return var_t( 1, e );
+ }
+
+ /*!
+ * \brief 関数の呼び出し
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ */
+ var_t bf_call( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ return macro_processor::call_user_function( line, arg_list, p_ctx );
+ }
+
+ namespace
+ {
+ struct bf_functor : std::binary_function< element const&, element const&, bool >
+ {
+ public:
+ bf_functor( text_line const& line, std::string const& func_name, context* p_ctx )
+ : line_( line ), func_name_( func_name ), p_ctx_( p_ctx )
+ {
+ }
+ bool operator()( element const& lhs, element const& rhs )
+ {
+ std::vector< var_t > arg_list;
+ arg_list.reserve( 3 );
+
+ element e;
+ e.s = func_name_;
+ arg_list.push_back( var_t( 1, e ) );
+ arg_list.push_back( var_t( 1, lhs ) );
+ arg_list.push_back( var_t( 1, rhs ) );
+ int arg1 = static_cast< int >( *lhs.i );
+ int arg2 = static_cast< int >( *rhs.i );
+
+ var_t r = bf_call( line_, arg_list, p_ctx_ );
+ bool result = 0;
+ if ( !r.empty() )
+ {
+ int retval = static_cast< int >( *r.front().i );
+ result = ( *r.front().i < 0 );
+ }
+ return result;
+ }
+ private:
+ std::string func_name_;
+ context* p_ctx_;
+ text_line line_;
+ };
+ }
+
+ /*!
+ * \brief ソート
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ */
+ var_t bf_lsort( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ if ( macro_processor::check_arity( line, arg_list.size(), 2, "LSORT" ) )
+ {
+ var_t temp( arg_list[ 0 ] );
+ std::string compare( arg_list[ 1 ].front().s );
+ std::stable_sort( temp.begin(), temp.end(), bf_functor( line, compare, p_ctx ) );
+ return temp;
+ }
+ element e;
+ return var_t( 1, e );
+ }
+
+ /*!
+ * \brief 関数かどうかの判別
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ */
+ var_t bf_isfunction( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ element e;
+ if ( macro_processor::check_arity( line, arg_list.size(), 1, "ISFUNCTION" ) )
+ {
+ std::string func_name( get_s( arg_list[ 0 ], p_ctx ) );
+ if ( p_ctx->func_map.find( func_name ) != p_ctx->func_map.end() )
+ {
+ e.i = 1;
+ }
+ else
+ {
+ e.i = 0;
+ }
+ }
+ return var_t( 1, e );
+ }
+
+ /*!
+ * \brief 順序付きリストの並びを逆にする
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ */
+ var_t bf_reverse( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ var_t result;
+ if ( macro_processor::check_arity( line, arg_list.size(), 1, "REVERSE" ) )
+ {
+ result = arg_list[ 0 ];
+ std::reverse(result.begin(), result.end());
+ }
+ return result;
+ }
+
+ /*!
+ * \brief 何もしない組み込み関数
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ * この組み込み関数は何も行わない。また、マクロ実引数のチェックも行わない。
+ * NOOP関数は常に "" を返す。
+ * \note 空値を返さないのは、$NOOP()$のような使い方をしたときでも不正な参照が起こらないようにするため。
+ */
+ var_t bf_noop( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ element e;
+ return var_t( 1, e );
+ }
+
+ macro_processor::func_t const macro_processor::builtin_function_table[] =
+ {
+ { "LENGTH", bf_length },
+ { "EQ", bf_eq },
+ { "ALT", bf_alt },
+ { "SORT", bf_sort },
+ { "ENVIRON", bf_environ },
+ { "VALUE", bf_value },
+ { "CONCAT", bf_concat },
+ { "APPEND", bf_append },
+ { "AT", bf_at },
+ { "GETTEXT", bf_gettext },
+ { "_", bf_gettext }, // GETTEXTのシノニム
+ { "FORMAT", bf_format },
+ { "FIND", bf_find },
+ { "RANGE", bf_range },
+ { "DUMP", bf_dump },
+ { "TRACE", bf_trace },
+ { "ESCSTR", bf_escstr },
+ { "UNESCSTR", bf_unescstr },
+ { "CALL", bf_call },
+ { "LSORT", bf_lsort },
+ { "ISFUNCTION", bf_isfunction },
+ { "REVERSE", bf_reverse },
+ { "NOOP", bf_noop },
+ { "", 0 },
+ };
+
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2005-2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/*
+ * toppers/c_chlit_parser.cpp
+ */
+#include "toppers/c_parser.hpp"
+
+namespace toppers
+{
+
+ //! C言語形式の文字定数パーサー(ASCII)
+ boost::spirit::classic::functor_parser< detail::c_chlit_parse_functor< ascii > > const ascii_ch_p;
+
+ //! C言語形式の文字定数パーサー(Shift JIS)
+ boost::spirit::classic::functor_parser< detail::c_chlit_parse_functor< shift_jis > > const shift_jis_ch_p;
+
+ //! C言語形式の文字定数パーサー(EUC-JP)
+ boost::spirit::classic::functor_parser< detail::c_chlit_parse_functor< euc_jp > > const euc_jp_ch_p;
+
+ //! C言語形式の文字定数パーサー(UTF-8)
+ boost::spirit::classic::functor_parser< detail::c_chlit_parse_functor< utf8 > > const utf8_ch_p;
+
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2005-2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/*!
+ * \file toppers/c_expr.hpp
+ * \brief C言語の式の構文解析に関する宣言定義
+ *
+ * このファイルで定義されるクラス
+ * \code
+ * struct c_expr_parser_base< Derived >;
+ * struct c_expr_parser;
+ * struct c_const_expr_parser;
+ * \endcode
+ */
+#ifndef TOPPERS_C_EXPR_HPP_
+#define TOPPERS_C_EXPR_HPP_
+
+#include "toppers/c_parser.hpp"
+#include <boost/cstdint.hpp>
+
+namespace toppers
+{
+
+ /*!
+ * \struct c_expr_parser_base c_expr.hpp "toppers/c_expr.hpp"
+ * \brief C言語の式を構文解析するための基底クラス
+ *
+ * 実際に使用する際は、 c_expr_parser_base および c_expr_parser_base::definition
+ * クラスを派生する必要があります。 c_expr_parser_base::definition の派生クラスでは、
+ * start メンバ関数を定義して、構文中の必要なルールを取り出すようにしてください。
+ * こうすることで、定数式の文法、一次式の文法といったように、C言語の文法のサブ
+ * セットを容易に作り出すことができます。
+ *
+ * \code
+ * // 一次式を取り出す例
+ * struct c_primary_expression : c_expr_parser_base< c_primary_expression >
+ * {
+ * template < class Scanner >
+ * struct definition : c_expr_parser_base< c_primary_expression >::definition
+ * {
+ * rule_t const& start() const { return primary_expression; }
+ * };
+ * };
+ * \endcode
+ */
+ template < class Derived >
+ struct c_expr_parser_base : boost::spirit::classic::grammar< Derived >
+ {
+ public:
+ /*!
+ * \struct definition c_expr.hpp "toppers/c_expr.hpp"
+ * \brief 文法定義
+ */
+ template < class Scanner >
+ struct definition
+ {
+ typedef boost::spirit::classic::rule< Scanner > rule_t;
+ rule_t primary_expression,
+ expression,
+ constant_expression,
+ conditional_expression,
+ assignment_expression,
+ assignment_operator,
+ postfix_expression,
+ unary_expression,
+ unary_operator,
+ cast_expression,
+ multiplicative_expression,
+ additive_expression,
+ shift_expression,
+ relational_expression,
+ equality_expression,
+ AND_expression,
+ exclusive_OR_expression,
+ inclusive_OR_expression,
+ logical_AND_expression,
+ logical_OR_expression,
+ string_literal,
+ constant,
+ floating_constant,
+ decimal_floating_constant,
+ hexadecimal_floating_constant,
+ integer_constant,
+ character_constant,
+ declaration_specifiers,
+ type_name,
+ specifier_qualifier_list,
+ storage_class_specifier,
+ type_specifier,
+ type_qualifier,
+ declarator,
+ direct_declarator,
+ struct_or_union_specifier,
+ struct_declaration,
+ struct_declarator,
+ enum_specifier,
+ enumerator,
+ abstract_declarator,
+ pointer,
+ parameter_type_list,
+ parameter_list,
+ parameter_declaration,
+ direct_abstract_declarator;
+
+ c_ident_parser_t identifier;
+ c_strlit_parser_t c_strlit_p;
+ c_chlit_parser_t c_chlit_p;
+
+ /*!
+ * \brief コンストラクタ
+ * \param self 文法クラス( c_expr_parser_base< Derived > クラスからの継承)への参照
+ */
+ definition( Derived const& self )
+ : identifier( c_ident_parser( self.ucn_, self.c_plus_plus_ ) ),
+ c_strlit_p( c_strlit_parser( self.codeset_ ) ),
+ c_chlit_p( c_chlit_parser( self.codeset_ ) )
+ {
+ using namespace boost::spirit::classic;
+ static functor_parser< detail::c_integer_constant_parse_functor< boost::uintmax_t > > const c_int_const_p;
+ static functor_parser< detail::c_integer_suffix_parse_functor > const c_int_suffix_p;
+
+ primary_expression = // 複合リテラル未対応
+ identifier
+ | constant
+ | string_literal
+ | ( '(' >> expression >> ')' );
+ expression =
+ assignment_expression % ',';
+ constant_expression =
+ conditional_expression;
+ conditional_expression =
+ logical_OR_expression >> *( '\?' >> expression >> ':' >> logical_OR_expression );
+ assignment_expression =
+ *( unary_expression >> assignment_operator ) >> conditional_expression;
+ assignment_operator =
+ ch_p( '=' ) | "*=" | "/=" | "%=" | "+=" | "?=" | "<<=" | ">>=" | "&=" | "^=" | "|=";
+ postfix_expression =
+ primary_expression >>
+ *(
+ ( '[' >> expression >> ']' )
+ | ( '(' >> list_p( assignment_expression, ',' ) >> ')' )
+ | ( '.' >> identifier )
+ | ( "->" >> identifier )
+ | "++"
+ | "--"
+ );
+ unary_expression =
+ *( str_p( "++" ) || "--" ) >>
+ (
+ ( "sizeof" >> unary_expression )
+ | ( str_p( "sizeof" ) >> '(' >> type_name >> ')' )
+ | postfix_expression
+ | ( unary_operator >> cast_expression )
+ );
+ unary_operator =
+ chset<>( "&*~!+-" );
+ cast_expression =
+ *( '(' >> type_name >> ')' ) >> unary_expression
+ | +( '(' >> ( type_name | identifier ) >> ')' ); // 構文解析に失敗する不具合対策
+ multiplicative_expression =
+ cast_expression >>
+ *(
+ ( '*' >> cast_expression )
+ | ( '/' >> cast_expression )
+ | ( '%' >> cast_expression )
+ );
+ additive_expression =
+ multiplicative_expression >>
+ *(
+ ( '+' >> multiplicative_expression )
+ | ( '-' >> multiplicative_expression )
+ );
+ shift_expression =
+ additive_expression >>
+ *(
+ ( "<<" >> additive_expression )
+ | ( ">>" >> additive_expression )
+ );
+ relational_expression =
+ shift_expression >>
+ *(
+ ( '<' >> shift_expression )
+ | ( '>' >> shift_expression )
+ | ( "<=" >> shift_expression )
+ | ( ">=" >> shift_expression )
+ );
+ equality_expression =
+ relational_expression >>
+ *(
+ ( "==" >> relational_expression )
+ | ( "!=" >> relational_expression )
+ );
+ AND_expression =
+ equality_expression >> *( '&' >> equality_expression );
+ exclusive_OR_expression =
+ AND_expression >> *( '^' >> AND_expression );
+ inclusive_OR_expression =
+ exclusive_OR_expression >> *( '|' >> exclusive_OR_expression );
+ logical_AND_expression =
+ inclusive_OR_expression >> *( "&&" >> inclusive_OR_expression );
+ logical_OR_expression =
+ logical_AND_expression >> *( "||" >> logical_AND_expression );
+ string_literal =
+ c_strlit_p
+ | lexeme_d[ 'L' >> c_strlit_p ];
+ constant =
+ floating_constant
+ | integer_constant
+ | identifier // 列挙定数
+ | character_constant;
+ floating_constant =
+ decimal_floating_constant
+ | hexadecimal_floating_constant;
+ decimal_floating_constant =
+ lexeme_d
+ [
+ as_lower_d
+ [
+ ( ( *digit_p >> '.' >> +digit_p ) | ( +digit_p >> '.' ) ) >>
+ 'e' >> !chset<>( "+-" ) >> +digit_p >>
+ !chset<>( "fl" )
+ ]
+ ];
+ hexadecimal_floating_constant =
+ lexeme_d
+ [
+ as_lower_d
+ [
+ "0x" >>
+ ( ( *xdigit_p >> '.' >> +xdigit_p ) | ( +xdigit_p >> '.' ) ) >>
+ 'p' >> !chset<>( "+-" ) >> +digit_p >>
+ !chset<>( "fl" )
+ ]
+ ];
+ integer_constant =
+ lexeme_d[ c_int_const_p >> !c_int_suffix_p ];
+ character_constant =
+ c_chlit_p
+ | lexeme_d[ 'L' >> c_chlit_p ];
+ declaration_specifiers =
+ +( storage_class_specifier | type_specifier | type_qualifier );
+ type_name =
+ specifier_qualifier_list >> !abstract_declarator;
+ specifier_qualifier_list =
+ +( type_specifier | type_qualifier );
+ storage_class_specifier =
+ str_p( "auto" )
+ | "register"
+ | "static"
+ | "extern"
+ | "typedef";
+ type_specifier =
+ str_p( "void" ) | "char" | "short" | "int" | "long" | "float" | "double"
+ | "signed" | "unsigned"
+ | identifier
+ | struct_or_union_specifier
+ | enum_specifier;
+ type_qualifier =
+ str_p( "const" ) | "volatile" | "restrict";
+ declarator =
+ !pointer >> direct_declarator;
+ direct_declarator =
+ ( identifier | ( '(' >> declarator >> ')' ) )
+ >>
+ *(
+ ( '[' >> !constant_expression >> ']' )
+ | ( '(' >> parameter_type_list >> ')' )
+ | ( '(' >> !( identifier % ',' ) >> ')' )
+ );
+ struct_or_union_specifier =
+ lexeme_d[ ( str_p( "struct" ) | "union" ) >> +space_p >> identifier ]
+ | ( lexeme_d[ ( str_p( "struct" ) | "union" ) >> +space_p >> !identifier ] >> '{' >> +struct_declaration >> '}' );
+ struct_declaration =
+ specifier_qualifier_list >> !list_p( struct_declarator, ',' ) >> ';';
+ // lisp_p( struct_declarator, ',' )を省略可能としているのは、
+ // struct_declarator の identifier を specifier_qualifier_list が
+ // typedef 名と間違うことを回避するため
+ struct_declarator =
+ ( !declarator >> ':' >> constant_expression ) // ビットフィールド
+ | declarator;
+ enum_specifier =
+ ( lexeme_d[ "enum" >> +space_p >> !identifier ] >> '{' >> list_p( enumerator, ',', ',' ) >> '}' ) // C99では末尾のカンマがあってもよい
+ | lexeme_d[ "enum" >> +space_p >> identifier ];
+ enumerator =
+ identifier >> !( '=' >> constant_expression );
+ abstract_declarator =
+ ( !pointer >> direct_abstract_declarator )
+ | pointer;
+ pointer =
+ +( '*' >> *type_qualifier );
+ parameter_type_list =
+ parameter_list >> !( ch_p( ',' ) >> "..." ); // 可変個引数
+ parameter_list =
+ parameter_declaration % ',';
+ parameter_declaration =
+ ( declaration_specifiers >> declarator )
+ | ( declaration_specifiers >> !abstract_declarator );
+ direct_abstract_declarator =
+ (
+ !( '(' >> abstract_declarator >> ')' ) >>
+ +(
+ ( '[' >> !constant_expression >> ']' )
+ | ( '(' >> !parameter_type_list >> ')' )
+ )
+ )
+ | ( '(' >> abstract_declarator >> ')' );
+ }
+ };
+ bool ucn_;
+ codeset_t codeset_;
+ bool c_plus_plus_;
+
+ /*!
+ * \brief コンストラクタ
+ * \param ucn 国際文字名に対応する場合は true を指定する
+ * \param codeset 文字コード
+ * \param c_plus_plus C++ に対応する場合は true を指定する
+ */
+ explicit c_expr_parser_base( bool ucn = false, codeset_t codeset = ascii, bool c_plus_plus = false )
+ : ucn_( ucn ), codeset_( codeset ), c_plus_plus_( c_plus_plus )
+ {
+ }
+ };
+
+ /*!
+ * \class c_expr_parser c_expr.hpp "toppers/c_expr.hpp"
+ * \brief C言語の式の構文解析クラス
+ */
+ struct c_expr_parser : c_expr_parser_base< c_expr_parser >
+ {
+ typedef c_expr_parser_base< c_expr_parser > base_t;
+
+ /*!
+ * \struct definition c_expr.hpp "toppers/c_expr.hpp"
+ * \brief 文法定義
+ */
+ template < class Scanner >
+ struct definition : base_t::definition< Scanner >
+ {
+ typedef typename base_t::definition< Scanner >::rule_t rule_t;
+
+ definition( c_expr_parser const& self ) : base_t::definition< Scanner >( self ) {}
+ rule_t const& start() const { return base_t::definition< Scanner >::expression; };
+ };
+
+ /*!
+ * \brief コンストラクタ
+ * \param ucn 国際文字名に対応する場合は true を指定する
+ * \param codeset 文字コード
+ */
+ explicit c_expr_parser( bool ucn = false, codeset_t codeset = ascii )
+ : c_expr_parser_base< c_expr_parser >( ucn, codeset )
+ {
+ }
+ };
+
+ /*!
+ * \class c_const_expr_parser c_expr.hpp "toppers/c_expr.hpp"
+ * \brief C言語の定数式の構文解析クラス
+ */
+ struct c_const_expr_parser : c_expr_parser_base< c_const_expr_parser >
+ {
+ typedef c_expr_parser_base< c_const_expr_parser > base_t;
+
+ /*!
+ * \struct definition c_expr.hpp "toppers/c_expr.hpp"
+ * \brief 文法定義
+ */
+ template < class Scanner >
+ struct definition : base_t::definition< Scanner >
+ {
+ typedef typename base_t::definition< Scanner >::rule_t rule_t;
+
+ definition( c_const_expr_parser const& self ) : base_t::definition< Scanner >( self ) {}
+ rule_t const& start() const { return base_t::definition< Scanner >::constant_expression; };
+ };
+
+ /*!
+ * \brief コンストラクタ
+ * \param ucn 国際文字名に対応する場合は true を指定する
+ * \param codeset 文字コード
+ */
+ explicit c_const_expr_parser( bool ucn = false, codeset_t codeset = ascii )
+ : c_expr_parser_base< c_const_expr_parser >( ucn, codeset )
+ {
+ }
+ };
+
+}
+
+#endif // ! TOPPERS_C_EXPR_HPP_
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2005-2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/*
+ * toppers/c_ident_parser.cpp
+ */
+#include "toppers/c_parser.hpp"
+
+namespace toppers
+{
+
+ //! C90形式の識別子パーサー
+ boost::spirit::classic::functor_parser< detail::c_identifier_parse_functor > const c_ident_p;
+
+ //! C99形式の識別子パーサー
+ boost::spirit::classic::functor_parser< detail::c_identifier_parse_functor > const c99_ident_p( detail::c_identifier_parse_functor( true ) );
+
+ //! C++形式の識別子パーサー
+ boost::spirit::classic::functor_parser< detail::c_identifier_parse_functor > const c_plus_plus_ident_p( detail::c_identifier_parse_functor( true, true ) );
+
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2005-2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/*
+ * toppers/c_int_parser.cpp
+ */
+#include "toppers/c_parser.hpp"
+
+namespace toppers
+{
+
+ //! C言語形式のint型定数パーサ
+ boost::spirit::classic::functor_parser< detail::c_integer_parse_functor< int > > const c_int_p;
+
+ //! C言語形式のunsigned int型定数パーサ
+ boost::spirit::classic::functor_parser< detail::c_integer_parse_functor< unsigned int > > const c_uint_p;
+
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2005-2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/*
+ * toppers/c_keyword.cpp
+ */
+
+namespace toppers
+{
+
+ namespace detail
+ {
+
+ extern char const* const c_keywords[];
+
+ char const* const c_keywords[] =
+ {
+ "_Bool", "_Complex", "_Imaginary", "auto", "break", "case", "char", "const",
+ "continue", "default", "do", "double", "else", "enum", "extern", "float",
+ "for", "goto", "if", "inline", "int", "long" "register", "restrict", "return",
+ "short", "sizeof", "static", "struct", "switch", "typedef", "union", "unsigned",
+ "void", "volatile", "while",
+ "_Decimal", "_Fract", "_Accum", "_Sat",
+ 0,
+ };
+
+ }
+
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2005-2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/*!
+ * \file toppers/c_parser.hpp
+ * \brief 一般的なパーサーの宣言定義
+ */
+#ifndef TOPPERS_PARSER_HPP_
+#define TOPPERS_PARSER_HPP_
+
+#include "toppers/codeset.hpp"
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_actor.hpp>
+#include <boost/spirit/include/classic_utility.hpp>
+#include <boost/spirit/include/classic_dynamic.hpp>
+
+namespace toppers
+{
+
+ namespace detail
+ {
+
+ struct c_integer_suffix_parse_functor
+ {
+ typedef boost::spirit::classic::nil_t result_t;
+ template < class Scanner >
+ int operator()( Scanner scan, result_t& ) const
+ {
+ using namespace boost::spirit::classic;
+ int length =
+ as_lower_d
+ [
+ ch_p( 'u' ) >> !( str_p( "ll" ) | 'l' | "i8" | "i16" | "i32" | "i64" )
+ | ( str_p( "ll" ) | 'l' | "i8" | "i16" | "i32" | "i64" ) >> !ch_p( 'u' )
+ ].parse( scan ).length();
+ return length;
+ }
+ };
+
+ template < typename T >
+ struct c_integer_constant_parse_functor
+ {
+ typedef T result_t;
+ template < class Scanner >
+ int operator()( Scanner scan, result_t& result ) const
+ {
+ using namespace boost::spirit::classic;
+ result_t x = T( 0 );
+ int length =
+ (
+ if_p( '0' ) // 16進または8進
+ [
+ !(
+ ( ch_p( 'x' ) | 'X' ) >> uint_parser< T, 16 >()[ assign_a( x ) ]
+ | uint_parser< T, 8 >()[ assign_a( x ) ]
+ )
+ ]
+ .else_p // 10進
+ [
+ uint_parser< T, 10 >()[ assign_a( x ) ]
+ ]
+ ).parse( scan ).length();
+ result = x;
+ return length;
+ }
+ };
+
+ template < typename T >
+ struct c_integer_parse_functor
+ {
+ typedef T result_t;
+ template < class Scanner >
+ int operator()( Scanner scan, result_t& result ) const
+ {
+ using namespace boost::spirit::classic;
+ static functor_parser< c_integer_constant_parse_functor< T > > const c_int_const_p;
+ static functor_parser< c_integer_suffix_parse_functor > const c_int_suffix_p;
+ bool negative = false;
+ result_t x;
+ int length =
+ (
+ !sign_p[ assign_a( negative ) ] >> lexeme_d[ c_int_const_p[ assign_a( x ) ] >> !c_int_suffix_p ]
+ ).parse( scan ).length();
+ result = ( negative ? -x : x );
+ return length;
+ }
+ };
+
+ template < int CodeSet = -1 > struct mbchar_parse_functor;
+
+ template <>
+ struct mbchar_parse_functor< ascii >
+ {
+ typedef boost::spirit::classic::nil_t result_t;
+ template < class Scanner >
+ int operator()( Scanner scan, result_t& ) const
+ {
+ return boost::spirit::classic::range_p( '\x01', '\x7f' ).parse( scan ).length();
+ }
+ };
+
+ template <>
+ struct mbchar_parse_functor< shift_jis >
+ {
+ typedef boost::spirit::classic::nil_t result_t;
+ template < class Scanner >
+ int operator()( Scanner scan, result_t& ) const
+ {
+ using namespace boost::spirit::classic;
+ int length =
+ (
+ range_p( '\x01', '\x7f' ) // 半角英数字記号
+ | range_p( '\xa1', '\xdf' ) // 半角カタカナ
+ | ( chset<>( "\x81-\x9f\xe0-\xef" ) >> chset<>( "\x40-\x7e\x80-\xfc" ) ) // 全角
+ ).parse( scan ).length();
+ return length;
+ }
+ };
+
+ template <>
+ struct mbchar_parse_functor< euc_jp >
+ {
+ typedef boost::spirit::classic::nil_t result_t;
+ template < class Scanner >
+ int operator()( Scanner scan, result_t& ) const
+ {
+ using namespace boost::spirit::classic;
+ int length =
+ (
+ range_p( '\x01', '\x7f' ) // 半角英数字記号
+ | ( ch_p( '\x8e' ) >> range_p( '\xa1', '\xdf' ) ) // 半角カタカナ
+ | ( !ch_p( '\x8f' ) >> range_p( '\xa1', '\xf0' ) >> range_p( '\xa1', '\xf0' ) ) // 全角
+ ).parse( scan ).length();
+ return length;
+ }
+ };
+
+ template <>
+ struct mbchar_parse_functor< utf8 >
+ {
+ typedef boost::spirit::classic::nil_t result_t;
+ template < class Scanner >
+ int operator()( Scanner scan, result_t& ) const
+ {
+ using namespace boost::spirit::classic;
+ int length =
+ (
+ range_p( '\x01', '\x7f' ) // 1バイト
+ | ( range_p( '\xc0', '\xdf' ) >> range_p( '\x80', '\xbf' ) ) // 2バイト
+ | ( range_p( '\xe0', '\xef' ) >> repeat_p( 2 )[ range_p( '\x80', '\xbf' ) ] ) // 3バイト
+ | ( range_p( '\xf0', '\xf7' ) >> repeat_p( 3 )[ range_p( '\x80', '\xbf' ) ] ) // 4バイト
+ | ( range_p( '\xf8', '\xfb' ) >> repeat_p( 4 )[ range_p( '\x80', '\xbf' ) ] ) // 5バイト
+ | ( range_p( '\xfc', '\xfd' ) >> repeat_p( 5 )[ range_p( '\x80', '\xbf' ) ] ) // 6バイト
+ ).parse( scan ).length();
+ return length;
+ }
+ };
+
+ template <>
+ struct mbchar_parse_functor< -1 >
+ {
+ typedef boost::spirit::classic::nil_t result_t;
+ explicit mbchar_parse_functor( codeset_t codeset = ascii ) : codeset_( codeset ) {}
+ template < class Scanner >
+ int operator()( Scanner scan, result_t& result ) const
+ {
+ int length;
+ switch ( codeset_ )
+ {
+ case ascii:
+ {
+ static mbchar_parse_functor< ascii > f;
+ length = f( scan, result );
+ }
+ break;
+ case shift_jis:
+ {
+ static mbchar_parse_functor< shift_jis > f;
+ length = f( scan, result );
+ }
+ break;
+ case euc_jp:
+ {
+ static mbchar_parse_functor< euc_jp > f;
+ length = f( scan, result );
+ }
+ break;
+ case utf8:
+ {
+ static mbchar_parse_functor< utf8 > f;
+ length = f( scan, result );
+ }
+ break;
+ default:
+ length = -1;
+ break;
+ }
+ return length;
+ }
+ codeset_t codeset_;
+ };
+
+ struct ucn_parse_functor
+ {
+ typedef long result_t;
+ template < class Scanner >
+ int operator()( Scanner scan, result_t& result ) const
+ {
+ using namespace boost::spirit::classic;
+ result_t x;
+ int length =
+ (
+ lexeme_d
+ [
+ ch_p( '\\' ) >>
+ (
+ ( 'U' >> int_parser< long, 16, 8, 8 >()[ assign_a( x ) ] ) // \Uhhhhhhhh形式
+ | ( 'u' >> int_parser< long, 16, 4, 4 >()[ assign_a( x ) ] ) // \uhhhh形式
+ )
+ ]
+ ).parse( scan ).length();
+ if ( ( x < 0xa0 && !( x == 0x24 || x == 0x40 || x == 0x60 ) )
+ || ( 0xd800 <= x && x <= 0xdfff )
+ || 0x10ffff < x ) // 国際文字名に使えない値(JIS X3010:2003 6.4.3)
+ {
+ x = -1;
+ }
+ result = x;
+ return length;
+ }
+ };
+
+ template < int CodeSet = -1 > struct c_strlit_parse_functor;
+
+ template < int CodeSet >
+ struct c_strlit_parse_functor
+ {
+ typedef boost::spirit::classic::nil_t result_t;
+ template < class Scanner >
+ int operator()( Scanner scan, result_t& result ) const
+ {
+ using namespace boost::spirit::classic;
+ static functor_parser< detail::mbchar_parse_functor< CodeSet > > const mbchar_p;
+ static functor_parser< detail::ucn_parse_functor > const ucn_p;
+ int length =
+ (
+ confix_p( '\"', *( "\\\"" | mbchar_p - '\\' | ucn_p | c_escape_ch_p ), '\"' )
+ ).parse( scan ).length();
+ return length;
+ }
+ };
+
+ template <>
+ struct c_strlit_parse_functor< -1 >
+ {
+ typedef boost::spirit::classic::nil_t result_t;
+ explicit c_strlit_parse_functor( codeset_t codeset = ascii ) : codeset_( codeset ) {}
+ template < class Scanner >
+ int operator()( Scanner scan, result_t& result ) const
+ {
+ using namespace boost::spirit::classic;
+ mbchar_parse_functor<> const functor( codeset_ );
+ functor_parser< detail::mbchar_parse_functor<> > const mbchar_p( functor );
+ static functor_parser< detail::ucn_parse_functor > const ucn_p;
+ int length =
+ (
+ confix_p( '\"', *( "\\\"" | ( mbchar_p - ch_p( '\\' ) ) | ucn_p | c_escape_ch_p ), '\"' )
+ ).parse( scan ).length();
+ return length;
+ }
+ codeset_t codeset_;
+ };
+
+ template < int CodeSet = -1 > struct c_chlit_parse_functor;
+
+ template < int CodeSet >
+ struct c_chlit_parse_functor
+ {
+ typedef boost::spirit::classic::nil_t result_t;
+ template < class Scanner >
+ int operator()( Scanner scan, result_t& result ) const
+ {
+ using namespace boost::spirit::classic;
+ static functor_parser< detail::mbchar_parse_functor< CodeSet > > const mbchar_p;
+ static functor_parser< detail::ucn_parse_functor > const ucn_p;
+ int length =
+ (
+ confix_p( '\'', +( "\\\'" | mbchar_p - '\\' | ucn_p | c_escape_ch_p ), '\'' )
+ ).parse( scan ).length();
+ return length;
+ }
+ };
+
+ template <>
+ struct c_chlit_parse_functor< -1 >
+ {
+ typedef boost::spirit::classic::nil_t result_t;
+ explicit c_chlit_parse_functor( codeset_t codeset = ascii ) : codeset_( codeset ) {}
+ template < class Scanner >
+ int operator()( Scanner scan, result_t& result ) const
+ {
+ using namespace boost::spirit::classic;
+ mbchar_parse_functor<> const functor( codeset_ );
+ functor_parser< detail::mbchar_parse_functor<> > const mbchar_p( functor );
+ static functor_parser< detail::ucn_parse_functor > const ucn_p;
+ int length =
+ (
+ confix_p( '\'', +( "\\\'" | mbchar_p - '\\' | ucn_p | c_escape_ch_p ), '\'' )
+ ).parse( scan ).length();
+ return length;
+ }
+ codeset_t codeset_;
+ };
+
+ extern char const* const c_keywords[];
+ extern char const* const c_plus_plus_keywords[];
+
+ struct c_identifier_parse_functor
+ {
+ typedef boost::spirit::classic::nil_t result_t;
+ template < class Scanner >
+ int operator()( Scanner scan, result_t& result ) const
+ {
+ using namespace boost::spirit::classic;
+ static functor_parser< detail::ucn_parse_functor > const ucn_p;
+ int length;
+ typename Scanner::iterator_t const first( scan.first );
+
+ if ( ucn_ )
+ {
+ length =
+ (
+ lexeme_d
+ [
+ ( alpha_p | '_' | ucn_p ) >>
+ *( alnum_p | '_' | ucn_p )
+ ]
+ ).parse( scan ).length();
+ }
+ else
+ {
+ length =
+ (
+ lexeme_d
+ [
+ ( alpha_p | '_' ) >>
+ *( alnum_p | '_' )
+ ]
+ ).parse( scan ).length();
+ }
+ std::string token( first, scan.first );
+
+ for ( int i = 0; c_keywords[i] != 0; i++ )
+ {
+ if ( token == c_keywords[i] )
+ {
+ length = -1;
+ break;
+ }
+ }
+ if ( c_plus_plus_ )
+ {
+ for ( int i = 0; c_plus_plus_keywords[i] != 0; i++ )
+ {
+ if ( token == c_plus_plus_keywords[i] )
+ {
+ length = -1;
+ break;
+ }
+ }
+ }
+ return length;
+ }
+ explicit c_identifier_parse_functor( bool ucn = false, bool c_plus_plus = false )
+ : ucn_( ucn ), c_plus_plus_( c_plus_plus )
+ {
+ }
+
+ bool ucn_;
+ bool c_plus_plus_;
+ };
+
+ }
+
+ /*!
+ * \brief C言語形式の整数定数パーサー
+ *
+ * boost::spirit::int_parserとの違いは、接頭辞に応じて8進数や16進数として解釈
+ * する点です。また型を特定するための接尾辞も受け入れます。
+ */
+ template < typename T >
+ inline boost::spirit::classic::functor_parser< detail::c_integer_parse_functor< T > > const c_int_parser()
+ {
+ return boost::spirit::classic::functor_parser< detail::c_integer_parse_functor< T > >();
+ }
+
+ extern boost::spirit::classic::functor_parser< detail::c_integer_parse_functor< int > > const c_int_p;
+ extern boost::spirit::classic::functor_parser< detail::c_integer_parse_functor< unsigned int > > const c_uint_p;
+
+ /*!
+ * \brief マルチバイト文字パーサー
+ *
+ * テンプレート引数 CodeSet で指定した文字コードを解析します。
+ * ascii 以外を指定した場合でも、ASCIIの範囲(0x7f以下)にも合致します。
+ * 0x00 は文字列の終端と区別できないため、合致対象にはなりません。
+ */
+ template < int CodeSet >
+ inline boost::spirit::classic::functor_parser< detail::mbchar_parse_functor< CodeSet > > const mbchar_parser()
+ {
+ return boost::spirit::classic::functor_parser< detail::mbchar_parse_functor< CodeSet > >();
+ }
+ inline boost::spirit::classic::functor_parser< detail::mbchar_parse_functor<> > const mbchar_parser( codeset_t codeset )
+ {
+ return boost::spirit::classic::functor_parser< detail::mbchar_parse_functor<> >( detail::mbchar_parse_functor<>( codeset ) );
+ }
+
+ extern boost::spirit::classic::functor_parser< detail::mbchar_parse_functor< ascii > > const ascii_p;
+ extern boost::spirit::classic::functor_parser< detail::mbchar_parse_functor< shift_jis > > const shift_jis_p;
+ extern boost::spirit::classic::functor_parser< detail::mbchar_parse_functor< euc_jp > > const euc_jp_p;
+ extern boost::spirit::classic::functor_parser< detail::mbchar_parse_functor< utf8 > > const utf8_p;
+
+ /*!
+ * \brief 国際文字名パーサー
+ *
+ * \\uまたは\\Uで始まる国際文字名(Universal Character Name)を解析します。
+ * \\uhhhhまたは\\Uhhhhhhhh(hは16進数字)に合致します。なお、これらの形式に
+ * 合致している場合でも、一部の値は国際文字名として使用できません。
+ */
+ inline boost::spirit::classic::functor_parser< detail::ucn_parse_functor > const ucn_parser()
+ {
+ return boost::spirit::classic::functor_parser< detail::ucn_parse_functor >();
+ }
+
+ extern boost::spirit::classic::functor_parser< detail::ucn_parse_functor > const ucn_p;
+
+ /*!
+ * \brief C言語形式の文字列定数パーサー
+ *
+ * 二重引用符で囲まれたC言語形式の文字列を解析します。
+ * 文字列の文字コードは CodeSet で指定したものになります。
+ */
+ template < int CodeSet >
+ inline boost::spirit::classic::functor_parser< detail::c_strlit_parse_functor< CodeSet > > const c_strlit_parser()
+ {
+ return boost::spirit::classic::functor_parser< detail::c_strlit_parse_functor< CodeSet > >();
+ }
+
+ typedef boost::spirit::classic::functor_parser< detail::c_strlit_parse_functor<> > c_strlit_parser_t;
+
+ /*!
+ * \brief C言語形式の文字列定数パーサー
+ * \param codeset 文字列に使用されている文字コード
+ *
+ * 二重引用符で囲まれたC言語形式の文字列を解析します。
+ */
+ inline boost::spirit::classic::functor_parser< detail::c_strlit_parse_functor<> > const c_strlit_parser( codeset_t codeset )
+ {
+ return boost::spirit::classic::functor_parser< detail::c_strlit_parse_functor<> >( detail::c_strlit_parse_functor<>( codeset ) );
+ }
+
+ extern boost::spirit::classic::functor_parser< detail::c_strlit_parse_functor< ascii > > const ascii_str_p;
+ extern boost::spirit::classic::functor_parser< detail::c_strlit_parse_functor< shift_jis > > const shift_jis_str_p;
+ extern boost::spirit::classic::functor_parser< detail::c_strlit_parse_functor< euc_jp > > const euc_jp_str_p;
+ extern boost::spirit::classic::functor_parser< detail::c_strlit_parse_functor< utf8 > > const utf8_str_p;
+
+ /*!
+ * \brief C言語形式の文字定数パーサー
+ *
+ * 単引用符で囲まれたC言語形式の文字定数を解析します。
+ * 文字コードは CodeSet で指定したものになります。
+ */
+ template < int CodeSet >
+ inline boost::spirit::classic::functor_parser< detail::c_chlit_parse_functor< CodeSet > > const c_chlit_parser()
+ {
+ return boost::spirit::classic::functor_parser< detail::c_chlit_parse_functor< CodeSet > >();
+ }
+
+ typedef boost::spirit::classic::functor_parser< detail::c_chlit_parse_functor<> > c_chlit_parser_t;
+
+ /*!
+ * \brief C言語形式の文字定数パーサー
+ * \param codeset 文字コード
+ *
+ * 単引用符で囲まれたC言語形式の文字定数を解析します。
+ */
+ inline boost::spirit::classic::functor_parser< detail::c_chlit_parse_functor<> > const c_chlit_parser( codeset_t codeset )
+ {
+ return boost::spirit::classic::functor_parser< detail::c_chlit_parse_functor<> >( detail::c_chlit_parse_functor<>( codeset ) );
+ }
+
+ extern boost::spirit::classic::functor_parser< detail::c_chlit_parse_functor< ascii > > const ascii_ch_p;
+ extern boost::spirit::classic::functor_parser< detail::c_chlit_parse_functor< shift_jis > > const shift_jis_ch_p;
+ extern boost::spirit::classic::functor_parser< detail::c_chlit_parse_functor< euc_jp > > const euc_jp_ch_p;
+ extern boost::spirit::classic::functor_parser< detail::c_chlit_parse_functor< utf8 > > const utf8_ch_p;
+
+ typedef boost::spirit::classic::functor_parser< detail::c_identifier_parse_functor > c_ident_parser_t;
+
+ /*!
+ * \brief C言語形式の識別子パーサー
+ * \param ucn 国際文字を許容する場合は true を指定
+ * \param c_plus_plus C++の予約語を禁止する場合は true を指定
+ *
+ * C言語の識別子として使用できる文字列の解析を行います。
+ * 識別子は下線または英文字で始まり、下線または英数字が続くのが原則ですが、
+ * C99以降では国際文字名も使用できるため、引数 ucn に true を指定することで、
+ * 国際文字名対応が可能になります。
+ *
+ * \note 翻訳限界および予約識別子の判別は行っていません。
+ */
+ inline boost::spirit::classic::functor_parser< detail::c_identifier_parse_functor > const c_ident_parser( bool ucn = false, bool c_plus_plus = false )
+ {
+ return boost::spirit::classic::functor_parser< detail::c_identifier_parse_functor >( detail::c_identifier_parse_functor( ucn, c_plus_plus ) );
+ }
+
+ extern boost::spirit::classic::functor_parser< detail::c_identifier_parse_functor > const c_ident_p;
+ extern boost::spirit::classic::functor_parser< detail::c_identifier_parse_functor > const c99_ident_p;
+ extern boost::spirit::classic::functor_parser< detail::c_identifier_parse_functor > const c_plus_plus_ident_p;
+
+}
+
+#endif // ! TOPPERS_PARSER_HPP_
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2005-2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/*
+ * toppers/c_plus_plus_keywords.cpp
+ */
+
+namespace toppers
+{
+ namespace detail
+ {
+
+ extern char const* const c_plus_plus_keywords[];
+
+ char const* const c_plus_plus_keywords[] =
+ {
+ "and", "and_eq", "asm", "bitand", "bitor", "bool", "catch", "class", "compl",
+ "const_cast", "delete", "dynamic_cast", "explicit", "false", "friend", "namespace",
+ "new", "not", "not_eq", "operator", "or", "or_eq", "private", "protected",
+ "public", "reinterpret_cast", "static_cast", "this", "throw", "true", "try",
+ "typeid", "using", "virtual", "wchar_t", "xor", "xor_eq",
+ "alignof", "axiom", "char16_t", "char32_t", "constexpr", "decltype", "late_check",
+ "nullptr", "requires", "static_assert", "thread_local",
+ 0
+ };
+
+ }
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2005-2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/*!
+ * \file toppers/c_pp_line.hpp
+ * \brief \#line指令に関する宣言定義
+ */
+#ifndef TOPPERS_C_PP_LINE_HPP_
+#define TOPPERS_C_PP_LINE_HPP_
+
+#include "toppers/text_line.hpp"
+#include "toppers/c_parser.hpp"
+#include "toppers/workaround.hpp"
+#include <vector>
+#include <functional>
+
+namespace toppers
+{
+
+ namespace detail
+ {
+
+ //! \#line 指令の構文解析
+ struct c_pp_line_parser : boost::spirit::grammar< c_pp_line_parser >
+ {
+ template < class Scanner >
+ struct definition
+ {
+ typedef boost::spirit::rule< Scanner > rule_t;
+ rule_t r;
+ definition( c_pp_line_parser const& self )
+ {
+ using namespace boost::spirit;
+ r = (
+ '#' >> lexeme_d[ str_p( "line" ) >> space_p >> uint_p[ assign_a( self.line_ ) ] ] >>
+ c_strlit_parser( self.codeset_ )[ assign_a( self.file_ ) ]
+ )
+ | (
+ '#' >>
+ uint_p[ assign_a( self.line_ ) ] >>
+ c_strlit_parser( self.codeset_ )[ assign_a( self.file_ ) ] >>
+ *anychar_p
+ );
+ }
+ rule_t const& start() const { return r; }
+ };
+
+ c_pp_line_parser( long& line, std::string& file, codeset_t codeset = ascii )
+ : line_( line ), file_( file ), codeset_( codeset )
+ {
+ }
+
+ long& line_;
+ std::string& file_;
+ codeset_t codeset_;
+ };
+
+ //! \#pragma 指令の構文解析
+ struct c_pp_pragma_parser : boost::spirit::grammar< c_pp_pragma_parser >
+ {
+ template < class Scanner >
+ struct definition
+ {
+ typedef boost::spirit::rule< Scanner > rule_t;
+ rule_t r;
+ definition( c_pp_pragma_parser const& self )
+ {
+ using namespace boost::spirit;
+ r = '#' >> lexeme_d[ str_p( "pragma" ) >> space_p >> ( +anychar_p )[ assign_a( self.parameter_ ) ] ];
+ }
+ rule_t const& start() const { return r; }
+ };
+
+ c_pp_pragma_parser( std::string& parameter ) : parameter_( parameter )
+ {
+ }
+ std::string& parameter_;
+ };
+
+ }
+
+ /*!
+ * \class c_pp_line c_pp_line.hpp "toppers/c_pp_line.hpp"
+ * \brief \#line指令を処理させるためのファンクタクラス
+ *
+ * このクラスは basic_text クラスと組み合わせて使用します。
+ */
+ template < class Container >
+ class c_pp_line : public std::binary_function< Container, line_buf, void >
+ {
+ public:
+ typedef Container conatiner;
+
+ /*!
+ * \brief コンストラクタ
+ * \param codeset 文字コード指定
+ */
+ explicit c_pp_line( codeset_t codeset = ascii )
+ : codeset_( codeset ), pragmas_( new std::vector< line_buf > )
+ {
+ }
+ /*!
+ * \brief 括弧演算子
+ * \param cont line_buf を要素とするコンテナ
+ * \param buf 1行バッファ
+ */
+ void operator()( conatiner& cont, line_buf& buf )
+ {
+ using namespace boost::spirit;
+ long line;
+ std::string file;
+ detail::c_pp_line_parser c_pp_line_p( line, file, codeset_ );
+
+ if ( parse( buf.buf.begin(), buf.buf.end(), c_pp_line_p, space_p ).full ) // #line指令の処理
+ {
+ buf.line.line = line;
+ assert( file.size() >= 2 );
+ buf.line.file = file.substr( 1, file.size()-2 );
+ }
+ else
+ {
+ std::string param;
+ detail::c_pp_pragma_parser c_pp_pragma_p( param );
+
+ if ( parse( buf.buf.begin(), buf.buf.end(), c_pp_pragma_p, space_p ).full ) // #pragma指令の処理
+ {
+ line_buf t( buf );
+ t.buf = param;
+ pragmas_->push_back( t );
+ }
+ else
+ {
+ std::string::size_type pos = buf.buf.find_first_not_of( " \t" );
+ if ( pos == std::string::npos || buf.buf[pos] != '#' )
+ {
+ cont.push_back( buf );
+ }
+ ++buf.line.line;
+ }
+ }
+ buf.buf.clear();
+ }
+ /*!
+ * \brief \#pragma指令リストの取得
+ * \return \#pragma指令リストを返す
+ */
+ std::vector< line_buf > const& pragmas() const { return *pragmas_; }
+ private:
+ codeset_t codeset_;
+ std::tr1::shared_ptr< std::vector< line_buf > > pragmas_;
+ };
+
+}
+
+#endif // ! TOPPERS_C_PP_LINE_HPP_
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2005-2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/*
+ * toppers/c_strlit_parser.cpp
+ */
+#include "toppers/c_parser.hpp"
+
+namespace toppers
+{
+
+ //! C言語形式の文字列定数パーサー(ASCII)
+ boost::spirit::classic::functor_parser< detail::c_strlit_parse_functor< ascii > > const ascii_str_p;
+
+ //! C言語形式の文字列定数パーサー(ShiftJIS)
+ boost::spirit::classic::functor_parser< detail::c_strlit_parse_functor< shift_jis > > const shift_jis_str_p;
+
+ //! C言語形式の文字列定数パーサー(EUC-JP)
+ boost::spirit::classic::functor_parser< detail::c_strlit_parse_functor< euc_jp > > const euc_jp_str_p;
+
+ //! C言語形式の文字列定数パーサー(UTF-8)
+ boost::spirit::classic::functor_parser< detail::c_strlit_parse_functor< utf8 > > const utf8_str_p;
+
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2005-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/*!
+ * \file toppers/codeset.hpp
+ * \brief 文字コード種別に関する宣言定義
+ */
+#ifndef TOPPERS_CODESET_HPP_
+#define TOPPERS_CODESET_HPP_
+
+#include "toppers/config.hpp"
+
+namespace toppers
+{
+
+ /*!
+ * \enum codeset_t
+ * \brief 文字コード種別
+ *
+ * 現状では日本語のみを考慮しています。
+ */
+ enum codeset_t
+ {
+ ascii,
+ shift_jis,
+ euc_jp,
+ utf8
+ };
+
+ template < codeset_t Codeset >
+ inline bool is_lead( char c )
+ {
+ return static_cast< unsigned char >( c ) & 0x80;
+ }
+
+ template <>
+ inline bool is_lead< shift_jis >( char c )
+ {
+ int ch = static_cast< unsigned char >( c );
+ return ( 0x81 <= ch && ch <= 0x9f ) || ( 0xe0 <= ch && ch <= 0xef );
+ }
+
+ template <>
+ inline bool is_lead< utf8 >( char c )
+ {
+ return ( static_cast< unsigned char >( c ) & 0xc0 ) != 0;
+ }
+
+}
+
+#endif // ! TOPPERS_CODESET_HPP_
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2004 by Witz Corporation, JAPAN
+ * Copyright (C) 2005-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/*!
+ * \file toppers/config.hpp
+ * \brief 処理系に依存する設定
+ */
+#ifndef TOPPERS_CONFIG_HPP_
+#define TOPPERS_CONFIG_HPP_
+
+#ifdef _MSC_VER
+
+# define for if(0);else for
+
+# pragma warning( disable: 4127 )
+# pragma warning( disable: 4239 )
+# pragma warning( disable: 4505 )
+# pragma warning( disable: 4511 )
+# pragma warning( disable: 4512 )
+# pragma warning( disable: 4630 )
+# pragma warning( disable: 4701 )
+# pragma warning( disable: 4786 )
+# pragma warning( disable: 4819 )
+# pragma warning( disable: 4996 )
+
+#define _SCL_SECURE_NO_WARNINGS 1
+
+#endif // _MSC_VER
+
+#ifdef __BORLANDC__
+
+#pragma warn -8026
+#pragma warn -8027
+
+#endif // __BORLANDC__
+
+#ifdef __GNUC__
+
+# define TOPPERS_HAS_ICONV 1
+
+#endif // __GNUC__
+
+#if defined(unix) || defined(__unix) || defined(__unix__)
+
+# define TOPPERS_HAS_ICONV 1
+
+#endif // UNIX
+
+#endif // ! TOPPERS_CONFIG_HPP_
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+#include <cctype>
+#include <cstring>
+#include <cstdio>
+#include <stdexcept>
+#include "toppers/cpp.hpp"
+
+namespace toppers
+{
+
+ /*!
+ * \brief 二重引用符で囲まれた文字列を展開する。
+ */
+ std::string expand_quote( std::string const& str )
+ {
+ // boost-1.35.x以上対策
+ std::string::size_type n = str.find_first_not_of( " \t\r\n" );
+ std::string quoted( str, n );
+
+ if ( quoted.empty() || quoted[0] != '"' || quoted[quoted.size() - 1] != '"' )
+ {
+ throw std::invalid_argument( "argument is not quoted" );
+ }
+ std::string result;
+ for ( std::string::const_iterator iter( quoted.begin() + 1 ), last( quoted.end() - 1 );
+ iter != last;
+ ++iter )
+ {
+ if ( *iter == '\\' )
+ {
+ if ( ++iter == last )
+ {
+ throw std::invalid_argument( "argument is not quoted" );
+ }
+ char c = *iter;
+ switch ( c )
+ {
+ case 'a':
+ c = '\a';
+ break;
+ case 'b':
+ c = '\b';
+ break;
+ case 'f':
+ c = '\f';
+ break;
+ case 'n':
+ c = '\n';
+ break;
+ case 'r':
+ c = '\r';
+ break;
+ case 't':
+ c = '\t';
+ break;
+ case 'v':
+ c = '\v';
+ break;
+ case 'x':
+ if ( std::isxdigit( static_cast< unsigned char >( *iter ) ) )
+ {
+ c = 0;
+ for ( std::string::const_iterator bound( iter + 2 );
+ iter != bound && std::isxdigit( static_cast< unsigned char >( *iter ) );
+ ++iter )
+ {
+ c <<= 4;
+ int t = std::tolower( static_cast< unsigned char >( *iter ) );
+ static char const xdigits[] = "0123456789abcdef";
+ c += std::strchr( xdigits, t ) - xdigits;
+ }
+ }
+ break;
+ default:
+ if ( '0' <= c && c <= '7' ) // '\ooo'
+ {
+ c = 0;
+ for ( std::string::const_iterator bound( iter + 3 );
+ iter != bound && ( '0' <= *iter && *iter <= '7' );
+ ++iter )
+ {
+ c = ( c << 3 ) + *iter - '0';
+ }
+ }
+ // 国際文字名(\uhhhh, \Uhhhhhhhh)未対応
+ // 二文字表記(<:等)未対応
+ // 三文字表記(??/等)未対応
+ break;
+ }
+ result.push_back( c );
+ }
+ else
+ {
+ result.push_back( *iter );
+ }
+ }
+ return result;
+ }
+
+ /*!
+ * \brief 文字列で二重引用符で囲む
+ */
+ std::string quote_string( std::string const& str )
+ {
+ std::string result;
+ result.reserve( str.size() + 2 );
+
+ result.push_back( '"' ); // open
+
+ for ( std::string::const_iterator iter( str.begin() ), last( str.end() );
+ iter != last;
+ ++iter )
+ {
+ switch ( char c = *iter )
+ {
+ case '\'':
+ result += "\\\'";
+ break;
+ case '\"':
+ result += "\\\"";
+ break;
+ case '\0':
+ result += "\\0";
+ break;
+ case '\a':
+ result += "\\a";
+ break;
+ case '\b':
+ result += "\\b";
+ break;
+ case '\f':
+ result += "\\f";
+ break;
+ case '\n':
+ result += "\\n";
+ break;
+ case '\r':
+ result += "\\r";
+ break;
+ case '\t':
+ result += "\\t";
+ break;
+ case '\v':
+ result += "\\v";
+ break;
+ case '\\':
+ // SJIS未対応
+ result.push_back( c );
+ result.push_back( c );
+ break;
+ default:
+ result.push_back( c );
+ break;
+ }
+ }
+
+ result.push_back( '"' ); // close
+
+ return result;
+ }
+
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/*!
+ * \file toppers/cpp.hpp
+ * \brief Cプリプロセッサ代替機能に関する宣言定義
+ */
+#ifndef TOPPERS_CPP_HPP_
+#define TOPPERS_CPP_HPP_
+
+#include "toppers/codeset.hpp"
+#include <boost/utility.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/exception.hpp>
+
+namespace toppers
+{
+
+ /*!
+ * \brief コメントの除去
+ * \param[in] first 入力元の先頭位置
+ * \param[in] last 入力元の終端位置の次
+ * \param[out] result 結果の出力先
+ * \param[in] codeset 文字コード
+ * \return 処理完了後の result の値
+ *
+ * CスタイルのブロックコメントとC++スタイルの行コメントを取り除きます。
+ * 行コメントは、行末の \\ があっても次の行には続きません。
+ */
+ template < class ForwardIterator, class OutputIterator >
+ OutputIterator remove_comment( ForwardIterator first, ForwardIterator last, OutputIterator result, codeset_t codeset = ascii )
+ {
+ enum { none, line_comment, block_comment, single_quote, double_quote } state = none;
+ char prev = '\0';
+
+ for ( ; first != last; ++first, ++result )
+ {
+ char c = *first;
+ ForwardIterator next_iter = boost::next( first );
+ char next = ( next_iter != last ? *next_iter : '\0' );
+
+ switch ( state )
+ {
+ case line_comment:
+ if ( c == '\n' )
+ {
+ state = none;
+ *result = c;
+ }
+ break;
+ case block_comment:
+ if ( c == '*' && next == '/' )
+ {
+ state = none;
+ ++first;
+ }
+ else if ( c == '\n' )
+ {
+ *result = c;
+ }
+ break;
+ case single_quote:
+ if ( c == '\\'
+ && !( codeset == shift_jis && is_lead< shift_jis >( prev ) )
+ && next == '\'' ) // '〜\'〜 の場合
+ {
+ *result++ = *first++;
+ }
+ else if ( c == '\'' )
+ {
+ state = none;
+ }
+ *result = *first;
+ break;
+ case double_quote:
+ if ( c == '\\'
+ && !( codeset == shift_jis && is_lead< shift_jis >( prev ) )
+ && next == '\"' ) // "〜\"〜 の場合
+ {
+ *result++ = *first++;
+ }
+ else if ( c == '\"' )
+ {
+ state = none;
+ }
+ *result = *first;
+ break;
+ default:
+ switch ( c )
+ {
+ case '/': // コメント開始の検出
+ if ( next == '*' )
+ {
+ state = block_comment;
+ ++first;
+ }
+ else if ( next == '/' )
+ {
+ state = line_comment;
+ ++first;
+ }
+ else
+ {
+ *result = *first;
+ }
+ break;
+ case '\'':
+ state = single_quote;
+ *result = c;
+ break;
+ case '\"':
+ state = double_quote;
+ *result = c;
+ break;
+ default:
+ *result = c;
+ break;
+ }
+ }
+ prev = *first;
+ }
+ return result;
+ }
+
+ /*!
+ * \brief インクルードパスの探索
+ * \param[in] first 探索対象ディレクトリ列の先頭位置
+ * \param[in] last 探索対象ディレクトリ列の終端位置の次
+ * \param[in] headername 探索対象のヘッダ名
+ * \return 探索に成功すればヘッダへの相対またはフルパスを返す。失敗した場合は空文字列を返す。
+ */
+ template < class InputIterator >
+ std::string search_include_file( InputIterator first, InputIterator last, std::string const& headername )
+ {
+ namespace fs = boost::filesystem;
+ fs::path filename( headername, fs::native );
+
+ if ( fs::exists( filename ) && !fs::is_directory( filename ) )
+ {
+ return headername;
+ }
+ while ( first != last )
+ {
+ fs::path pathname = fs::path( *first, fs::native )/filename;
+ if ( fs::exists( pathname ) && !fs::is_directory( pathname ) )
+ {
+ return pathname.native_file_string();
+ }
+ ++first;
+ }
+ return std::string();
+ }
+
+ std::string expand_quote( std::string const& str );
+ std::string quote_string( std::string const& str );
+
+}
+
+#endif // ! TOPPERS_CPP_HPP_
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/*!
+ * \file toppers/csv.hpp
+ * \brief CSVファイル入出力に関する宣言定義
+ */
+#ifndef TOPPERS_CSV_HPP_
+#define TOPPERS_CSV_HPP_
+
+#include <stdexcept>
+#include <ostream>
+#include <iterator>
+#include <string>
+#include <vector>
+#include <algorithm>
+#include <boost/utility.hpp>
+#include "toppers/misc.hpp"
+
+namespace toppers
+{
+
+ class csv_error : public std::runtime_error
+ {
+ public:
+ explicit csv_error( long line )
+ : std::runtime_error( "CSV parse error" ), line_( line )
+ {
+ }
+ long line() const
+ {
+ return line_;
+ }
+ private:
+ long line_;
+ };
+
+ /*!
+ * \class basic_csv csv.hpp "toppers/csv.hpp"
+ * \brief CSV ファイルの解析クラス
+ */
+ template < typename CharT, class Traits = std::char_traits< CharT > >
+ class basic_csv
+ {
+ public:
+ typedef std::basic_string< CharT, Traits > string_type;
+ typedef typename std::vector< std::vector< string_type > >::const_iterator const_iterator;
+ typedef typename std::vector< std::vector< string_type > >::const_reference const_reference;
+ typedef typename std::vector< std::vector< string_type > >::value_type value_type;
+ typedef typename std::vector< std::vector< string_type > >::size_type size_type;
+
+ basic_csv();
+ template < class InputIterator >
+ basic_csv( InputIterator first, InputIterator last )
+ {
+ read( first, last );
+ }
+
+ template < class InputIterator >
+ void read( InputIterator first, InputIterator last )
+ {
+ const CharT dquo = widen< CharT >( '\"' );
+ const CharT comma = widen< CharT >( ',' );
+ const CharT lf = widen< CharT >( '\n' );
+ enum
+ {
+ none,
+ non_escaped,
+ escape_opened,
+ escape_closed
+ } state = none;
+ std::vector< std::vector< string_type > > records;
+ std::vector< string_type > record;
+ string_type field;
+ long line = 1;
+
+ record.reserve( 16 );
+ field.reserve( 255 );
+
+ while ( first != last )
+ {
+ CharT ch = *first;
+ if ( ch == dquo )
+ {
+ switch ( state )
+ {
+ case none:
+ state = escape_opened;
+ break;
+ case escape_opened:
+ ++first;
+ ch = *first;
+ if ( ch == dquo ) // "" だったので、" を追加
+ {
+ field.push_back( dquo );
+ }
+ else // 閉じ "
+ {
+ state = escape_closed;
+ }
+ continue; // ++first をこれ以上実行させない
+ default:
+ throw csv_error( line );
+ break;
+ }
+ }
+ else // ch != dquo
+ {
+ if ( state == escape_opened )
+ {
+ field.push_back( ch );
+ }
+ else
+ {
+ if ( ch == comma || ch == lf )
+ {
+ record.push_back( field );
+ field.clear();
+ state = none;
+ if ( ch == lf ) // 改行(RFC4180 では厳密には CR-LF なければならないが、とりあえず '\n' とする)
+ {
+ records.push_back( record );
+ record.clear();
+ ++line;
+ }
+ }
+ else
+ {
+ field.push_back( ch );
+// CharT const* debug_string = field.c_str();
+ }
+ }
+ }
+ ++first;
+ }
+ records_.swap( records );
+ }
+ template < class OutputIterator >
+ void write( OutputIterator result ) const
+ {
+ const CharT dquo = widen< CharT >( '\"' );
+ const CharT comma = widen< CharT >( ',' );
+ const CharT lf = widen< CharT >( '\n' );
+
+ for ( typename std::vector< std::vector< string_type > >::const_iterator r_iter( records_.begin() ), r_last( records_.end() );
+ r_iter != r_last;
+ ++r_iter )
+ {
+ for ( typename std::vector< string_type >::const_iterator f_iter( r_iter->begin() ), f_last( r_iter->end() );
+ f_iter != f_last;
+ ++f_iter )
+ {
+ std::string field;
+ bool need_escape = false;
+
+ for ( typename string_type::const_iterator s_iter( f_iter->begin() ), s_last( f_iter->end() );
+ s_iter != s_last;
+ ++s_iter )
+ {
+ CharT ch = *s_iter;
+ if ( ch == dquo )
+ {
+ field.push_back( dquo );
+ need_escape = true;
+ }
+ else if ( ch == comma || ch == lf )
+ {
+ need_escape = true;
+ }
+ field.push_back( ch );
+ }
+
+ if ( need_escape )
+ {
+ field = dquo + field + dquo;
+ }
+ result = std::copy( field.begin(), field.end(), result );
+ if ( boost::next( f_iter ) != f_last )
+ {
+ *result++ = comma;
+ }
+ }
+ *result++ = lf;
+ }
+ }
+
+ const_iterator begin() const
+ {
+ return records_.begin();
+ }
+ const_iterator end() const
+ {
+ return records_.end();
+ }
+ const_reference at( size_type pos ) const
+ {
+ return records_.at( pos );
+ }
+ const_reference operator[]( size_type pos ) const
+ {
+ return records_[ pos ];
+ }
+ bool empty() const
+ {
+ return records_.empty();
+ }
+ size_type size() const
+ {
+ return records_.size();
+ }
+ void swap( basic_csv& other )
+ {
+ records_.swap( other.records_ );
+ }
+ private:
+ std::vector< std::vector< string_type > > records_;
+ };
+
+ typedef basic_csv< char > csv;
+ typedef basic_csv< wchar_t > wcsv;
+
+}
+
+#endif // TOPPERS_CSV_HPP_
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2005-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/*!
+ * \file toppers/debug.hpp
+ * \brief デバッグ用ライブラリに関する宣言定義
+ */
+#ifndef TOPPERS_DEBUG_HPP_
+#define TOPPERS_DEBUG_HPP_
+
+#include "toppers/config.hpp"
+#include <iostream>
+#if defined( _WIN32 ) || defined( __WIN32__ ) || defined( WIN32 )
+#include <windows.h>
+#include <sstream>
+#endif
+
+namespace toppers
+{
+
+ template < typename T >
+ void trace( char const* str, const T& value )
+ {
+#if defined( _WIN32 ) || defined( __WIN32__ ) || defined( WIN32 )
+ std::ostringstream ostr;
+ ostr << str << value << '\n';
+ ::OutputDebugString( ostr.str().c_str() );
+#else
+ std::cerr << str << value << std::endl;
+#endif
+ }
+
+}
+
+#if defined( _DEBUG ) || defined( __DEBUG ) || defined( DEBUG )
+#define TOPPERS_TRACE( str, value ) ::toppers::trace( ( str ), ( value ) )
+#else
+#define TOPPERS_TRACE( str, value ) ( ( void )0 )
+#endif
+
+#endif // ! TOPPERS_DEBUG_HPP_
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+#include <cstdio>
+#include <string>
+#include "toppers/diagnostics.hpp"
+#include "toppers/text_line.hpp"
+
+namespace toppers
+{
+ namespace
+ {
+ int error_abort_threshold = 100;
+ int error_count = 0;
+ std::string program_name( "(unknown)" );
+ }
+
+ int get_error_count()
+ {
+ return error_count;
+ }
+
+ int increment_error_count()
+ {
+ return ++error_count;
+ }
+
+ void set_program_name( char const* name )
+ {
+ program_name = name;
+ }
+
+ std::string const& get_program_name()
+ {
+ return program_name;
+ }
+
+ int set_error_abort_threshold( int thresh )
+ {
+ if ( thresh < 1 )
+ {
+ return -1;
+ }
+ int previous = error_abort_threshold;
+ error_abort_threshold = thresh;
+ return previous;
+ }
+
+ void warning( const char* msg )
+ {
+ fprintf( stderr, "%s: %s: %s\n", program_name.c_str(), _( "warning" ), msg );
+ }
+ void warning( text_line const& line, const char* msg )
+ {
+ fprintf( stderr, "%s:%s:%ld: %s: %s\n", program_name.c_str(), line.file.c_str(), line.line, _( "warning" ), msg );
+ }
+ void error( const char* msg )
+ {
+ fprintf( stderr, "%s: %s: %s\n", program_name.c_str(), _( "error" ), msg );
+ ++error_count;
+ if ( error_abort_threshold <= error_count )
+ {
+ throw diagnostics_error( _( "too many errors" ) );
+ }
+ }
+ void error( text_line const& line, const char* msg )
+ {
+ fprintf( stderr, "%s:%s:%ld: %s: %s\n", program_name.c_str(), line.file.c_str(), line.line, _( "error" ), msg );
+ ++error_count;
+ if ( error_abort_threshold <= error_count )
+ {
+ throw diagnostics_error( _( "too many errors" ) );
+ }
+ }
+ void fatal( const char* msg )
+ {
+ fprintf( stderr, "%s: %s: %s\n", program_name.c_str(), _( "error" ), msg );
+ throw diagnostics_error( _( "fatal error" ) );
+ }
+ void fatal( text_line const& line, const char* msg )
+ {
+ fprintf( stderr, "%s:%s:%ld: %s: %s\n", program_name.c_str(), line.file.c_str(), line.line, _( "error" ), msg );
+ throw diagnostics_error( _( "fatal error" ) );
+ }
+
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/*!
+ * \file toppers/diagnostics.hpp
+ * \brief 診断処理に関する宣言定義
+ */
+#ifndef TOPPERS_DIAGNOSTICS_HPP_
+#define TOPPERS_DIAGNOSTICS_HPP_
+
+#include <stdexcept>
+#include "toppers/debug.hpp"
+#include "toppers/gettext.hpp"
+#include <boost/format.hpp>
+
+namespace toppers
+{
+
+ struct text_line;
+
+ class diagnostics_error : public std::runtime_error
+ {
+ public:
+ diagnostics_error( std::string const& msg ) : std::runtime_error( msg ) {}
+ };
+
+ class normal_exit {};
+
+ int get_error_count();
+ int increment_error_count();
+ void set_program_name( char const* name );
+ std::string const& get_program_name();
+ int set_error_abort_threshold( int thresh );
+ void warning( const char* msg );
+ void warning( text_line const& line, const char* msg );
+ void error( const char* msg );
+ void error( text_line const& line, const char* msg );
+ void fatal( const char* msg );
+ void fatal( text_line const& line, const char* msg );
+
+ template < typename T1 >
+ inline void warning( const char* str, T1 const& arg1 )
+ {
+ warning( ( boost::format( str ) % arg1 ).str().c_str() );
+ }
+
+ template < typename T1, typename T2 >
+ inline void warning( const char* str, T1 const& arg1, T2 const& arg2 )
+ {
+ warning( ( boost::format( str ) % arg1 % arg2 ).str().c_str() );
+ }
+
+ template < typename T1, typename T2, typename T3 >
+ inline void warning( const char* str, T1 const& arg1, T2 const& arg2, T3 const& arg3 )
+ {
+ warning( ( boost::format( str ) % arg1 % arg2 % arg3 ).str().c_str() );
+ }
+
+ template < typename T1, typename T2, typename T3, typename T4 >
+ inline void warning( const char* str, T1 const& arg1, T2 const& arg2, T3 const& arg3, T4 const& arg4 )
+ {
+ warning( ( boost::format( str ) % arg1 % arg2 % arg3 % arg4 ).str().c_str() );
+ }
+
+ template < typename T1 >
+ inline void warning( text_line const& line, const char* str, T1 const& arg1 )
+ {
+ warning( line, ( boost::format( str ) % arg1 ).str().c_str() );
+ }
+
+ template < typename T1, typename T2 >
+ inline void warning( text_line const& line, const char* str, T1 const& arg1, T2 const& arg2 )
+ {
+ warning( line, ( boost::format( str ) % arg1 % arg2 ).str().c_str() );
+ }
+
+ template < typename T1, typename T2, typename T3 >
+ inline void warning( text_line const& line, const char* str, T1 const& arg1, T2 const& arg2, T3 const& arg3 )
+ {
+ warning( line, ( boost::format( str ) % arg1 % arg2 % arg3 ).str().c_str() );
+ }
+
+ template < typename T1, typename T2, typename T3, typename T4 >
+ inline void warning( text_line const& line, const char* str, T1 const& arg1, T2 const& arg2, T3 const& arg3, T4 const& arg4 )
+ {
+ warning( line, ( boost::format( str ) % arg1 % arg2 % arg3 % arg4 ).str().c_str() );
+ }
+
+ template < typename T1 >
+ inline void error( const char* str, T1 const& arg1 )
+ {
+ error( ( boost::format( str ) % arg1 ).str().c_str() );
+ }
+
+ template < typename T1, typename T2 >
+ inline void error( const char* str, T1 const& arg1, T2 const& arg2 )
+ {
+ error( ( boost::format( str ) % arg1 % arg2 ).str().c_str() );
+ }
+
+ template < typename T1, typename T2, typename T3 >
+ inline void error( const char* str, T1 const& arg1, T2 const& arg2, T3 const& arg3 )
+ {
+ error( ( boost::format( str ) % arg1 % arg2 % arg3 ).str().c_str() );
+ }
+
+ template < typename T1, typename T2, typename T3, typename T4 >
+ inline void error( const char* str, T1 const& arg1, T2 const& arg2, T3 const& arg3, T4 const& arg4 )
+ {
+ error( ( boost::format( str ) % arg1 % arg2 % arg3 % arg4 ).str().c_str() );
+ }
+
+ template < typename T1 >
+ inline void error( text_line const& line, const char* str, T1 const& arg1 )
+ {
+ error( line, ( boost::format( str ) % arg1 ).str().c_str() );
+ }
+
+ template < typename T1, typename T2 >
+ inline void error( text_line const& line, const char* str, T1 const& arg1, T2 const& arg2 )
+ {
+ error( line, ( boost::format( str ) % arg1 % arg2 ).str().c_str() );
+ }
+
+ template < typename T1, typename T2, typename T3 >
+ inline void error( text_line const& line, const char* str, T1 const& arg1, T2 const& arg2, T3 const& arg3 )
+ {
+ error( line, ( boost::format( str ) % arg1 % arg2 % arg3 ).str().c_str() );
+ }
+
+ template < typename T1, typename T2, typename T3, typename T4 >
+ inline void error( text_line const& line, const char* str, T1 const& arg1, T2 const& arg2, T3 const& arg3, T4 const& arg4 )
+ {
+ error( line, ( boost::format( str ) % arg1 % arg2 % arg3 % arg4 ).str().c_str() );
+ }
+
+ template < typename T1 >
+ inline void fatal( const char* str, T1 const& arg1 )
+ {
+ fatal( ( boost::format( str ) % arg1 ).str().c_str() );
+ }
+
+ template < typename T1, typename T2 >
+ inline void fatal( const char* str, T1 const& arg1, T2 const& arg2 )
+ {
+ fatal( ( boost::format( str ) % arg1 % arg2 ).str().c_str() );
+ }
+
+ template < typename T1, typename T2, typename T3 >
+ inline void fatal( const char* str, T1 const& arg1, T2 const& arg2, T3 const& arg3 )
+ {
+ fatal( ( boost::format( str ) % arg1 % arg2 % arg3 ).str().c_str() );
+ }
+
+ template < typename T1, typename T2, typename T3, typename T4 >
+ inline void fatal( const char* str, T1 const& arg1, T2 const& arg2, T3 const& arg3, T4 const& arg4 )
+ {
+ fatal( ( boost::format( str ) % arg1 % arg2 % arg3 % arg4 ).str().c_str() );
+ }
+
+ template < typename T1 >
+ inline void fatal( text_line const& line, const char* str, T1 const& arg1 )
+ {
+ fatal( line, ( boost::format( str ) % arg1 ).str().c_str() );
+ }
+
+ template < typename T1, typename T2 >
+ inline void fatal( text_line const& line, const char* str, T1 const& arg1, T2 const& arg2 )
+ {
+ fatal( line, ( boost::format( str ) % arg1 % arg2 ).str().c_str() );
+ }
+
+ template < typename T1, typename T2, typename T3 >
+ inline void fatal( text_line const& line, const char* str, T1 const& arg1, T2 const& arg2, T3 const& arg3 )
+ {
+ fatal( line, ( boost::format( str ) % arg1 % arg2 % arg3 ).str().c_str() );
+ }
+
+ template < typename T1, typename T2, typename T3, typename T4 >
+ inline void fatal( text_line const& line, const char* str, T1 const& arg1, T2 const& arg2, T3 const& arg3, T4 const& arg4 )
+ {
+ fatal( line, ( boost::format( str ) % arg1 % arg2 % arg3 % arg4 ).str().c_str() );
+ }
+
+ inline void exit()
+ {
+ throw normal_exit();
+ }
+
+#undef _
+#define _( str ) ::toppers::gettext( str ).c_str()
+
+}
+
+#endif // ! TOPPERS_DIAGNOSTICS_HPP_
+
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+#include <cstdlib>
+#include <stdlib.h> // Cygwin対策
+#include <cstring>
+#include <clocale>
+#include <string>
+#include <map>
+#include <fstream>
+#include <stdexcept>
+#include "toppers/gettext.hpp"
+#include "toppers/cpp.hpp"
+#include "toppers/global.hpp"
+#include <boost/scoped_array.hpp>
+#include <boost/any.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/operations.hpp>
+
+namespace toppers
+{
+ namespace
+ {
+
+ std::map< std::string, std::string > msgcat;
+
+ void register_msgcat( std::string const& msgid, std::string const& msgstr )
+ {
+ std::string::size_type size = msgstr.size();
+ boost::scoped_array< wchar_t > wbuf( new wchar_t[ size + 1 ] );
+ boost::scoped_array< char > buf( new char[ size + 1 ] );
+ wchar_t* wcs = wbuf.get();
+ wchar_t wc = 0;
+ for ( std::string::const_iterator iter( msgstr.begin() ), last( msgstr.end() ); iter != last; ++iter )
+ {
+ int c = static_cast< unsigned char >( *iter );
+ if ( ( ( c & 0xc0 ) == 0xc0 ) || ( c < 0x80 ) ) // 先行バイト
+ {
+ if ( wc != 0 )
+ {
+ *wcs++ = wc;
+ wc = 0;
+ }
+ if ( ( c & 0x80 ) == 0 )
+ {
+ wc = static_cast< wchar_t >( c );
+ }
+ else if ( ( c & 0xe0 ) == 0xc0 )
+ {
+ wc = static_cast< wchar_t >( c & 0x1f );
+ }
+ else if ( ( c & 0xf0 ) == 0xe0 )
+ {
+ wc = static_cast< wchar_t >( c & 0xf );
+ }
+ else
+ {
+ // サロゲートは未対応(ここで対応したとしても、文字コード変換時にしくじる可能性大)
+ }
+ }
+ else // 後続バイト
+ {
+ wc = static_cast< wchar_t >( ( wc << 6 ) | ( c & 0x3f ) );
+ }
+ }
+ if ( wc != 0 )
+ {
+ *wcs++ = wc;
+ }
+ *wcs = L'\0';
+
+ // ↓ この間は決して例外が発生しない
+ char const* locale = std::setlocale( LC_CTYPE, "" );
+ /* std:: */wcstombs( buf.get(), wbuf.get(), size + 1 ); // Unicode から環境依存の文字コードへ変換
+ std::setlocale( LC_CTYPE, locale );
+ // ↑ この間は決して例外が発生しない
+
+ msgcat[ msgid ] = std::string( buf.get() );
+ }
+
+ bool msgcat_loaded = false;
+
+ }
+
+ /*!
+ * \brief メッセージカタログのロード
+ * \param[in] dir *.po ファイルが存在するディレクトリ
+ * \retval true 成功
+ * \retval false 失敗
+ *
+ * 実装を簡便化するため、.poファイルの記述方法には以下の制約がある。
+ * - msgid, msgstr は必ず行の先頭に記述する。
+ * - msgid, msgstr の直後には、必ず空白類文字一文字とし、その直後に文字列を記述する。
+ * - 文字列のみを記述する行は必ず " で始める。
+ * - .poファイルはの文字コードは必ず UTF-8N とする。
+ */
+ bool load_msgcat( std::string const& dir )
+ {
+ namespace fs = boost::filesystem;
+ char const* env = std::getenv( "TOPPERS_CFG_LANG" );
+// env = "ja";
+ if ( env == 0 )
+ {
+ return false;
+ }
+ std::string lang( env );
+
+ fs::path cfg_dir( dir, fs::native );
+ fs::path po_file( cfg_dir/fs::path( lang + ".po", fs::native ) );
+ std::ifstream ifs( po_file.native_file_string().c_str() );
+ std::string msgid;
+ std::string msgstr;
+
+ while ( ifs )
+ {
+ std::string str;
+ std::getline( ifs, str );
+
+ // 改行文字の違いを吸収
+ std::string::size_type pos = str.find_last_not_of( " \t\r\n" ); // ついでに行末の空白類も除去
+ if ( pos != std::string::npos && pos < str.size() - 1 )
+ {
+ char c = str[pos];
+ str.erase( pos + 1, std::string::npos );
+ }
+
+ if ( str.empty() || str[ 0 ] == '#' || str == "" )
+ {
+ ; // 空行またはコメント行
+ }
+ else
+ {
+ try
+ {
+ if ( std::strncmp( str.c_str(), "msgid", sizeof( "msgid" )-1 ) == 0 )
+ {
+ str.erase( 0, sizeof( "msgid" )-1+1 );
+ msgid = expand_quote( str );
+ }
+ else if ( std::strncmp( str.c_str(), "msgstr", sizeof( "msgstr" )-1 ) == 0 )
+ {
+ str.erase( 0, sizeof( "msgstr" )-1+1 );
+ msgstr = expand_quote( str );
+ }
+ else
+ {
+ msgstr += expand_quote( str );
+ }
+ if ( !msgid.empty() && !msgstr.empty() ) // 直前の msgid / msgstr を登録
+ {
+ register_msgcat( msgid, msgstr );
+ msgid.clear();
+ msgstr.clear();
+ }
+ }
+ catch ( std::invalid_argument& )
+ {
+ return false;
+ }
+ }
+ }
+ msgcat_loaded = true;
+ return true;
+ }
+
+ /*!
+ * \brief メッセージの翻訳
+ * \param[in] message メッセージID
+ * \return 翻訳後のメッセージ
+ */
+ std::string const& gettext( std::string const& message )
+ {
+ static bool f = load_msgcat( get_global< std::string >( "cfg-directory" ) );
+ if ( !msgcat_loaded )
+ {
+ return message;
+ }
+
+ std::map< std::string, std::string >::const_iterator iter( msgcat.find( message ) ), last( msgcat.end() );
+ if ( iter != last )
+ {
+ std::string const& result( iter->second );
+ return result;
+ }
+ return message;
+ }
+
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/*!
+ * \file toppers/gettext.hpp
+ * \brief GNU gettext の代替コード
+ *
+ * 本来であればGNU gettextを使用すべきかも知れないが、Visual C++でGNU gettextを使用するには、
+ * インストールが面倒なこともあり、代替コードを自前で用意することにした。
+ */
+#ifndef TOPPERS_GETTEXT_HPP_
+#define TOPPERS_GETTEXT_HPP_
+
+#include <string>
+#include "toppers/config.hpp"
+
+namespace toppers
+{
+ bool load_msgcat( std::string const& dir );
+ std::string const& gettext( std::string const& message );
+}
+
+#endif // ! TOPPERS_GETTEXT_HPP_
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+#include <new>
+#include <map>
+#include "toppers/global.hpp"
+
+namespace toppers
+{
+
+ /*!
+ * \brief グローバルオブジェクトへのアクセッサ
+ * \param[in] key オブジェクト名
+ * \return key で指定したオブジェクトへの参照
+ *
+ * グローバルオブジェクトへのアクセスを一元管理する。
+ * この関数を介してグローバルアクセスを行うことにより、通常の静的オブジェクトが持つ動的初期化の
+ * 順序に関する問題が解消される。
+ * また、内部的に管理しているオブジェクトは、プログラム終了時にデストラクタが呼ばれることはない。
+ * (厳密にいえばメモリリークにあたるが、弊害はとくにない)
+ */
+ boost::any& global( std::string const& key )
+ {
+ static std::map< std::string, boost::any >* gvm = 0;
+ if ( gvm == 0 )
+ {
+ union max_aligner
+ {
+ long long ll;
+ double d;
+ long double ld;
+ void* pv;
+ void (*pfn)();
+ };
+ const std::size_t size = ( sizeof( std::map< std::string, boost::any > ) + sizeof( max_aligner ) - 1 ) / sizeof( max_aligner );
+ static max_aligner gvm_storage[ size ];
+ gvm = new ( gvm_storage ) std::map< std::string, boost::any >; // デストラクタは呼ばれない
+ }
+ return ( *gvm )[key];
+ }
+
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/*!
+ * \file toppers/global.hpp
+ * \brief 疑似グローバルオブジェクトに関する宣言定義
+ */
+#ifndef TOPPERS_GLOBAL_HPP_
+#define TOPPERS_GLOBAL_HPP_
+
+#include <cstddef>
+#include <stdexcept>
+#include <string>
+#include "toppers/config.hpp"
+#include <boost/any.hpp>
+
+namespace toppers
+{
+
+ class global_error : public std::logic_error
+ {
+ public:
+ explicit global_error( std::string const& s )
+ : std::logic_error( "there is not global object `" + s + "`" )
+ {
+ }
+ };
+
+ boost::any& global( std::string const& key );
+
+ template < typename T >
+ T const& get_global( std::string const& key )
+ {
+ try
+ {
+ return boost::any_cast< T const& >( global( key ) );
+ }
+ catch ( boost::bad_any_cast& )
+ {
+ throw global_error( key );
+ }
+ static T t;
+ return t;
+ }
+
+ template < typename T >
+ inline T const& get_global( std::string const& key, T& storage )
+ {
+ storage = get_global< T >( key );
+ return storage;
+ }
+
+}
+
+#endif // ! TOPPERS_GLOBAL_HPP_
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+#include <fstream>
+#include <algorithm>
+#include <iterator>
+#include "toppers/io.hpp"
+#include "toppers/diagnostics.hpp"
+#include <boost/format.hpp>
+
+namespace toppers
+{
+
+ void read( std::string const& filename, std::string& buf, std::ios_base::openmode omode )
+ {
+ std::ifstream ifs( filename.c_str(), std::ios_base::in | omode );
+ if ( !ifs.is_open() )
+ {
+ throw io_error( str( boost::format( _( "cannot open file `%1%\'" ) ) % filename ) );
+ }
+ std::string t;
+ char c;
+ while ( ifs.get( c ) )
+ {
+ t.push_back( c );
+ }
+ if ( ifs.bad() )
+ {
+ throw io_error( _( "I/O error" ) );
+ }
+ buf.swap( t );
+ }
+
+ void write( std::string const& filename, std::string const& buf, std::ios_base::openmode omode )
+ {
+ std::ofstream ofs( filename.c_str(), std::ios_base::out | omode );
+ if ( !ofs.is_open() )
+ {
+ throw io_error( str( boost::format( _( "cannot open file `%1%\'" ) ) % filename ) );
+ }
+ std::copy( buf.begin(), buf.end(), std::ostream_iterator< char >( ofs ) );
+ if ( ofs.bad() )
+ {
+ throw io_error( _( "I/O error" ) );
+ }
+ }
+
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/*!
+ * \file toppers/io.hpp
+ * \brief ファイル入出力に関する宣言定義
+ */
+#ifndef TOPPERS_IO_HPP_
+#define TOPPERS_IO_HPP_
+
+#include <ios>
+#include <string>
+#include <stdexcept>
+#include "toppers/config.hpp"
+
+namespace toppers
+{
+
+ class io_error : public std::runtime_error
+ {
+ public:
+ explicit io_error( std::string const& msg ) : std::runtime_error( msg ) {}
+ };
+
+ void read( std::string const& filename, std::string& buf, std::ios_base::openmode omode = std::ios_base::openmode( 0 ) );
+ void write( std::string const& filename, std::string const& buf, std::ios_base::openmode omode = std::ios_base::openmode( 0 ) );
+
+ inline void append( std::string const& filename, std::string const buf, std::ios_base::openmode omode = std::ios_base::openmode( 0 ) )
+ {
+ write( filename, buf, omode | std::ios_base::app );
+ }
+
+}
+
+#endif // ! TOPPERS_IO_HPP_
--- /dev/null
+-include ../Makefile.config
+
+PROJDIR = ../..
+WORKDIR = $(PROJDIR)/toppers/itronx
+
+CPPFLAGS := $(CPPFLAGS) -I$(BOOST_DIR) -I$(PROJDIR)
+CXXFLAGS := $(CXXFLAGS) -O2 -g
+
+CXXFILES = \
+ cfg1_out.cpp \
+ checker.cpp \
+ component.cpp \
+ factory.cpp \
+ preprocess.cpp \
+ static_api.cpp
+
+OBJFILES := $(CXXFILES:%.cpp=%.o)
+
+all: libitronx.a
+
+libitronx.a: $(OBJFILES)
+ $(AR) rcs libitronx.a $(OBJFILES)
+
+depend:
+ $(CXX) $(CPPFLAGS) -M $(CXXFILES) > Makefile.depend
+
+clean:
+ -rm -f *.o *.a
+
+-include Makefile.depend
+
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+#include <cstdlib>
+#include <cerrno>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <iterator>
+#include <algorithm>
+#include <stack>
+#include "toppers/text.hpp"
+#include "toppers/diagnostics.hpp"
+#include "toppers/c_expr.hpp"
+#include "toppers/global.hpp"
+#include "toppers/macro_processor.hpp"
+#include "toppers/s_record.hpp"
+#include "toppers/nm_symbol.hpp"
+#include "toppers/itronx/cfg1_out.hpp"
+#include "toppers/itronx/preprocess.hpp"
+#include <boost/spirit/include/classic.hpp>
+#include <boost/filesystem/path.hpp>
+
+namespace toppers
+{
+ namespace itronx
+ {
+ namespace
+ {
+ struct block_t
+ {
+ std::string type;
+ std::string id;
+ text_line line;
+ };
+ }
+
+ //! cfg_out クラスの実装詳細
+ struct cfg1_out::implementation
+ {
+ protected:
+ output_file ofile_;
+ std::vector< static_api > static_api_array_;
+ std::string cfg1_out_list_;
+ std::string includes_;
+ std::string domid_defs_;
+ std::vector< block_t > block_table_;
+ std::vector< std::pair< std::string, long > > clsid_table_;
+ std::vector< std::pair< std::string, long > > domid_table_;
+
+ std::tr1::shared_ptr< s_record > srec_;
+ std::tr1::shared_ptr< nm_symbol > syms_;
+ bool little_endian_;
+ std::size_t base_;
+ cfg1_def_table const* def_table_;
+
+ implementation( std::string const& filename, std::ios_base::openmode omode, cfg1_def_table const* def_table = 0 )
+ : ofile_( filename, omode ), little_endian_( true ), base_( 1 ), def_table_( def_table )
+ {
+ }
+ virtual ~implementation()
+ {
+ }
+ virtual void do_load_cfg( std::string const& input_file, codeset_t codeset, std::map< std::string, static_api::info > const& info_map );
+ virtual void do_generate_includes() const
+ {
+ }
+ virtual void do_generate_cfg1_def() const
+ {
+ ofile_ << "const uint32_t TOPPERS_cfg_magic_number = 0x12345678;\n"
+ "const uint32_t TOPPERS_cfg_sizeof_signed_t = sizeof(signed_t);\n"
+ "const unsigned_t TOPPERS_cfg_CHAR_BIT = CHAR_BIT;\n"
+ "const unsigned_t TOPPERS_cfg_CHAR_MAX = CHAR_MAX;\n"
+ "const unsigned_t TOPPERS_cfg_CHAR_MIN = CHAR_MIN;\n"
+ "const unsigned_t TOPPERS_cfg_SCHAR_MAX = SCHAR_MAX;\n"
+ "const unsigned_t TOPPERS_cfg_SHRT_MAX = SHRT_MAX;\n"
+ "const unsigned_t TOPPERS_cfg_INT_MAX = INT_MAX;\n"
+ "const unsigned_t TOPPERS_cfg_LONG_MAX = LONG_MAX;\n"
+ "\n";
+
+ if ( def_table_ != 0 )
+ {
+ for ( cfg1_def_table::const_iterator iter( def_table_->begin() ), last( def_table_->end() );
+ iter != last;
+ ++iter )
+ {
+ // 式の最初に # があれば、それはマクロ定義の判定
+ // ★注意★ #@ で始まる書式は廃止 2010/07/23
+ bool is_pp = ( iter->expression[ 0 ] == '#' );
+ if ( !iter->value1.empty() || !iter->value2.empty() ) // (CSVの)4番目または5番目の値があれば...
+ {
+ is_pp = true;
+ }
+
+ std::string definition = ( iter->is_signed ? "const signed_t " : "const unsigned_t " );
+ definition += "TOPPERS_cfg_" + iter->name;
+ if ( is_pp )
+ {
+ std::string expression = iter->expression.substr( iter->expression[ 0 ] == '#' ? 1 : 0 );
+ std::string value1 = ( !iter->value1.empty() ? iter->value1 : "1" );
+ std::string value2 = ( !iter->value2.empty() ? iter->value2 : "0" );
+ definition +=
+ " = \n"
+ "#if " + expression + "\n"
+ "(" + value1 + ");\n"
+ "#else\n"
+ "(" + value2 + ");\n"
+ "#endif\n";
+ }
+ else
+ {
+ definition +=
+ " = " + iter->expression + ";\n";
+ }
+ ofile_ << definition;
+ }
+ }
+ }
+ virtual void do_assign_params();
+ virtual implementation* do_clone() const
+ {
+ return new implementation( *this );
+ }
+
+ void preprocess( std::string const& input_file, codeset_t codeset, text& txt );
+
+ friend class cfg1_out;
+ };
+
+
+ /*!
+ * \brief コンストラクタ
+ * \param[in] filename cfg1_out.c または cfg1_out.srec 若しくはそれらの代替名
+ * \param[in] def_table cfg1_out.c 生成用の定義テーブル
+ */
+ cfg1_out::cfg1_out( std::string const& filename, cfg1_def_table const* def_table )
+ : pimpl_( new implementation( filename, std::ios_base::out, def_table ) )
+ {
+ }
+
+ /*!
+ * \brief コピーコンストラクタ
+ * \param[in] other コピー元
+ */
+ cfg1_out::cfg1_out( cfg1_out const& other )
+ : pimpl_( other.pimpl_->do_clone() )
+ {
+ }
+
+ //! デストラクタ
+ cfg1_out::~cfg1_out()
+ {
+ delete pimpl_;
+ pimpl_ = 0;
+ }
+
+ /*!
+ * \brief システムコンフィギュレーションファイルのロード
+ * \param[in] input_file 入力ファイル名
+ * \param[in] codeset 文字コード
+ * \param[in] info_map 静的API情報の連想配列
+ */
+ void cfg1_out::load_cfg( std::string const& input_file, codeset_t codeset, std::map< std::string, static_api::info > const& info_map )
+ {
+ return pimpl_->do_load_cfg( input_file, codeset, info_map );
+ }
+
+ //! 前処理
+ void cfg1_out::implementation::preprocess( std::string const& input_file, codeset_t codeset, text& txt )
+ {
+ boost::any print_depend = global( "print-dependencies" );
+ if ( !print_depend.empty() )
+ {
+ std::set< std::string > depend, onces;
+ itronx::preprocess( input_file, txt, codeset, &depend, &onces );
+
+ // 依存関係の出力(GNU makeに適した形式)
+ std::string target_file = boost::any_cast< std::string& >( print_depend );
+ std::cout << target_file << ": " << input_file << ' ';
+ std::copy( depend.begin(), depend.end(), std::ostream_iterator< std::string >( std::cout, " " ) );
+ std::cout << std::endl;
+ exit();
+ }
+ else
+ {
+ std::set< std::string > onces;
+ itronx::preprocess( input_file, txt, codeset, 0, &onces );
+ }
+ }
+
+ /*!
+ * \brief システムコンフィギュレーションファイルのロード処理の実体
+ * \param[in] input_file 入力ファイル名
+ * \param[in] codeset 文字コード
+ * \param[in] info_map 静的API情報の連想配列
+ */
+ void cfg1_out::implementation::do_load_cfg( std::string const& input_file, codeset_t codeset, std::map< std::string, static_api::info > const& info_map )
+ {
+ text txt;
+ preprocess( input_file, codeset, txt );
+
+ // システムコンフィギュレーションファイルの解析
+ std::ostringstream oss, includes_oss;
+ std::vector< static_api > api_array;
+ long serial = 0;
+ std::stack< block_t > block_stack;
+ std::vector< block_t > block_table;
+ std::string current_class, current_domain;
+ long domain_serial = 1;
+ std::map< std::string, std::pair< long, bool > > id_map;
+ std::vector< std::pair< std::string, long > > clsid_table;
+ std::vector< std::pair< std::string, long > > domid_table;
+
+ for ( text::const_iterator iter( txt.begin() ), last( txt.end() ); iter != last; ++iter )
+ {
+ using namespace boost::spirit::classic;
+ parse_info< text::const_iterator > info;
+
+ info = parse( iter, last, ( ch_p( '#' ) >> *( anychar_p - eol_p ) >> eol_p ) ); // 前処理指令の検出
+ if ( info.hit ) // 前処理指令ならば...
+ {
+ if ( std::size_t col = info.stop.get_col() )
+ {
+ if ( info.stop.get_row()->buf.find_first_not_of( " \t" ) < col )
+ {
+ error( _( "illegal character `%1%\' is found" ), '#' );
+ }
+ }
+ text::const_iterator stop = info.stop;
+ std::string directive;
+ info = parse( iter, last, ( ch_p( '#' ) >> ( +alnum_p )[ assign_a( directive ) ] >> *( anychar_p - eol_p ) >> eol_p ) );
+ if ( info.hit )
+ {
+ if ( directive == "include" )
+ {
+ std::string directive_line_str( iter, info.stop );
+ if ( *directive_line_str.rbegin() == '\n' )
+ {
+ directive_line_str.erase( directive_line_str.size() - 1 );
+ }
+ includes_oss << directive_line_str << '\n';
+ oss << "/* " << directive_line_str << " */\n";
+ }
+ else if ( directive == "if" || directive == "ifdef" || directive == "ifndef"
+ || directive == "else" || directive == "elif" || directive == "endif" )
+ {
+ oss << '\n' << std::string( iter, stop );
+ }
+ else if ( directive != "pragma" ) // コンフィギュレータが処理すべき#pragma指令はこの時点では除去されている
+ {
+ error( iter.line(), _( "`#%1%\' is not supported" ), directive );
+ }
+ }
+ else
+ {
+ oss << std::string( iter, stop );
+ }
+ iter = boost::prior( stop );
+ }
+ else // 前処理指令ではなく...
+ if ( !std::isspace( static_cast< unsigned char >( *iter ) ) )
+ {
+ while ( iter != last )
+ {
+ int ch = static_cast< unsigned char >( *iter );
+ if ( !std::isspace( ch ) )
+ {
+ break;
+ }
+ }
+
+ std::string block_type;
+ std::string id;
+ std::string idexp;
+ c_const_expr_parser const c_const_expr_p;
+ info = parse( iter, last,
+ (
+ str_p( "DOMAIN" )[ assign_a( block_type ) ]
+ >> '(' >> c_ident_p[ assign_a( id ) ] >> ')' >> '{'
+ )
+ | (
+ str_p( "CLASS" )[ assign_a( block_type ) ]
+ >> '(' >> c_const_expr_p[ assign_a( id ) ] >> ')' >> '{'
+ )
+ | (
+ str_p( "KERNEL_DOMAIN" )[ assign_a( block_type ) ] >> '{'
+ ),
+ space_p );
+ if ( info.hit ) // CLASS or DOMAINブロック開始ならば...
+ {
+ block_t b;
+ b.type = block_type;
+ b.id = id;
+ b.line = iter.line();
+ idexp = id; // 字面としてのIDを保存
+
+ if ( block_type == "CLASS" )
+ {
+ if ( !get_global< bool >( "has-class" ) )
+ {
+ error( "cannot use `%1%'", "CLASS" );
+ }
+ }
+ if ( block_type == "DOMAIN" || block_type == "KERNEL_DOMAIN" )
+ {
+ if ( !get_global< bool >( "has-domain" ) )
+ {
+ error( "cannot use `%1%'", block_type );
+ }
+ }
+ // カーネルドメインを通常のドメインと同じように扱えるように変形
+ if ( block_type == "KERNEL_DOMAIN" )
+ {
+ block_type = "DOMAIN";
+ id = "TDOM_KERNEL";
+ b.type = block_type;
+ b.id = id;
+ }
+ else if ( block_type == "DOMAIN" ) // ドメインIDの仮登録
+ {
+ bool hit = false;
+ for ( std::vector< std::pair< std::string, long > >::const_iterator iter( domid_table.begin() ), last( domid_table.end() );
+ iter != last;
+ ++iter )
+ {
+ if ( iter->first == id )
+ {
+ hit = true;
+ break;
+ }
+ }
+ if ( !hit )
+ {
+ domid_table.push_back( std::make_pair( id, 0L ) );
+ }
+ }
+ else if ( block_type == "CLASS" ) // クラスIDの登録
+ {
+ // クラスIDに式を使えるようにしたため、識別子に使える形式に変換する必要がある
+ std::tr1::uint64_t hash = 0;
+ for ( const char* s = id.c_str(); *s != '\0'; ++s )
+ {
+ hash = ( ( hash << 1 ) | ( hash >> 63 ) ) ^ static_cast< unsigned char >( *s );
+ }
+ id = boost::str( boost::format( "%02x_%016x_%u" ) % *id.c_str() % hash % id.size() );
+ b.id = id;
+
+ bool hit = false;
+ for ( std::vector< std::pair< std::string, long > >::const_iterator iter( clsid_table.begin() ), last( clsid_table.end() );
+ iter != last;
+ ++iter )
+ {
+ if ( iter->first == id )
+ {
+ hit = true;
+ break;
+ }
+ }
+ if ( !hit )
+ {
+ clsid_table.push_back( std::make_pair( id, 0L ) );
+ }
+ }
+
+ // 入れ子判定
+ if ( block_type == "CLASS" && !current_class.empty()
+ || block_type == "DOMAIN" && !current_domain.empty() )
+ {
+ fatal( iter.line(), _( "`%1%\' is nested" ), block_type );
+ }
+
+ block_stack.push( b );
+ block_table.push_back( b );
+
+ if ( block_type == "CLASS" )
+ {
+ oss << "\n#ifndef TOPPERS_cfg_valueof_" << id << "_DEFINED\n"
+ "#define TOPPERS_cfg_valueof_" << id << "_DEFINED 1\n";
+ oss << boost::format( "\n#line %1% \"%2%\"\n" ) % ( iter.line().line ) % iter.line().file;
+
+ current_class = idexp;
+ oss << "const unsigned_t TOPPERS_cfg_valueof_" << id << " = " << idexp << ";\n";
+ }
+ if ( block_type == "DOMAIN" )
+ {
+ oss << "\n#ifndef TOPPERS_cfg_valueof_" << id << "_DEFINED\n"
+ "#define TOPPERS_cfg_valueof_" << id << "_DEFINED 1\n";
+ oss << boost::format( "\n#line %1% \"%2%\"\n" ) % ( iter.line().line ) % iter.line().file;
+
+ current_domain = id;
+ oss << "const unsigned_t TOPPERS_cfg_valueof_" << id << " = ";
+ if ( id == "TDOM_KERNEL" )
+ {
+ oss << "-1" << ";\n";
+ }
+ else
+ {
+ oss << id << ";\n";
+ }
+ }
+ oss << "\n#endif\n";
+
+ oss << "#define TOPPERS_cfg_inside_of_" << id << "\n";
+
+ iter = boost::prior( info.stop );
+ }
+ else if ( *info.stop == '}' ) // ブロック末尾ならば...
+ {
+ if ( block_stack.empty() )
+ {
+ fatal( iter.line(), _( "syntax error" ) );
+ }
+ block_t b = block_stack.top();
+ block_stack.pop();
+
+ oss << "\n#ifndef TOPPERS_cfg_inside_of_" << b.id << "\n";
+ oss << boost::format( "\n#line %1% \"%2%\"\n" ) % ( iter.line().line ) % iter.line().file;
+ oss << "#error syntax error\n"
+ "#endif\n";
+ oss << "#undef TOPPERS_cfg_inside_of_" << b.id << "\n"
+ "\n";
+
+ if ( b.type == "CLASS" )
+ {
+ current_class.clear();
+ }
+ if ( b.type == "DOMAIN" )
+ {
+ current_domain.clear();
+ }
+ iter = info.stop;
+ }
+ else
+ {
+ static_api api;
+ if ( api.parse( iter, last, info_map, false, codeset ) ) // 静的APIならば...
+ {
+ if ( !current_class.empty() )
+ {
+ api.set_class( current_class );
+ oss << "const unsigned_t TOPPERS_cfg_valueof_CLASS_" << serial << " = " << current_class << ";";
+ }
+ if ( !current_domain.empty() )
+ {
+ api.set_domain( current_domain );
+ oss << "const unsigned_t TOPPERS_cfg_valueof_DOMAIN_" << serial << " = " << current_domain << ";";
+ }
+
+ api_array.push_back( api );
+
+ std::string file( boost::filesystem::path( api.line().file, boost::filesystem::native ).string() ); // ディレクトリ区切子を / に変更
+ oss << boost::format( "\n#line %1% \"%2%\"\n" ) % api.line().line % file;
+ oss << "const unsigned_t TOPPERS_cfg_static_api_" << serial << " = " << serial << ";\n";
+
+ if ( !api.params().empty() && api.begin()->symbol[0] == '#' ) // オブジェクト識別名
+ {
+ std::string object_id( api.begin()->text );
+ bool valid_object_id = true;
+ if ( !object_id.empty() && ( std::isalpha( static_cast< unsigned char >( object_id[ 0 ] ) ) || object_id[ 0 ] == '_' ) )
+ {
+ for ( std::string::const_iterator id_iter( object_id.begin() + 1 ), id_last( object_id.end() );
+ id_iter != id_last;
+ ++id_iter )
+ {
+ if ( !( std::isalnum( static_cast< unsigned char >( *id_iter ) ) || *id_iter == '_' ) )
+ {
+ valid_object_id = false;
+ }
+ }
+ }
+ else
+ {
+ valid_object_id = false;
+ }
+ if ( !valid_object_id )
+ {
+ error( _( "`%1%\' is illegal object identifier" ), object_id );
+ }
+ else
+ {
+ oss << "#define " << object_id << "\t(<>)\n"; // でたらめな字句(基本ソース文字集合のみで構成)に定義することで、誤使用を検出する
+ oss << boost::format( "\n#line %1% \"%2%\"\n" ) % ( api.line().line ) % file;
+ }
+ }
+ for ( static_api::iterator api_iter( api.begin() ), api_last( api.end() );
+ api_iter != api_last;
+ ++api_iter )
+ {
+ if ( ( api_iter->symbol[0] == '.' ) || ( api_iter->symbol[0] == '+' ) )
+ // 整数定数式パラメータのみ出力
+ {
+ if ( api_iter->symbol[0] == '.' )
+ {
+ oss << "const unsigned_t ";
+ }
+ else
+ {
+ oss << "const signed_t ";
+ }
+
+ // 省略可能パラメータ情報の末尾にある ? を除去
+ std::string parameter_name( api_iter->symbol.c_str() + 1 );
+ if ( *parameter_name.rbegin() == '\?' )
+ {
+ parameter_name.resize( parameter_name.size() - 1 );
+ }
+
+ oss << "TOPPERS_cfg_valueof_" << parameter_name << "_" << serial << " = ( " << api_iter->text << " ); ";
+
+ // 暫定値を設定
+ char* endptr;
+ errno = 0;
+ unsigned long value = std::strtoul( api_iter->text.c_str(), &endptr, 0 );
+ if ( errno == 0 && *endptr == '\0' )
+ {
+ api_iter->value = value;
+ }
+ }
+ else if ( api_iter->symbol[0] == '$' ) // 文字列定数式パラメータ
+ {
+ // 省略可能パラメータ情報の末尾にある ? を除去
+ std::string parameter_name( api_iter->symbol.c_str() + 1 );
+ if ( *parameter_name.rbegin() == '\?' )
+ {
+ parameter_name.resize( parameter_name.size() - 1 );
+ }
+
+ oss << "const char TOPPERS_cfg_valueof_" << parameter_name << "_" << serial << "[] = " << api_iter->text << "; ";
+ }
+ }
+ }
+ else
+ {
+ fatal( iter.line(), _( "syntax error" ) );
+ }
+
+ ++serial;
+ iter = boost::prior( iter );
+ }
+ }
+ }
+
+ for ( std::vector< block_t >::const_iterator iter( block_table.begin() ), last( block_table.end() );
+ iter != last;
+ ++iter )
+ {
+ oss << "\n#ifdef TOPPERS_cfg_inside_of_" << iter->id << "\n";
+ oss << "#error missing \'}\'\n"
+ "#endif\n";
+ }
+
+ // 統合仕様書1.1.0における2.14.2 TOPPERS共通データ型の規定により、ACPTNは32ビット符号無し整数型である。
+ // これにより、ドメインの最大数は32個でなければならない。
+ const std::size_t domain_max = 32;
+ if ( domid_table.size() > domain_max )
+ {
+ fatal( _( "there are too many %1% ids" ), "domain" );
+ }
+
+ std::string domid_defs_temp;
+
+ if ( get_global< bool >( "has-domain" ) )
+ {
+ load_id_input_file( id_map ); // --id-input-fileによるドメインIDの読み込み
+
+ std::string domids[ domain_max ];
+
+ // 一周目は、--id-input-fileオプションを反映
+ for ( std::vector< std::pair< std::string, long > >::iterator iter( domid_table.begin() ), last( domid_table.end() );
+ iter != last;
+ ++iter )
+ {
+ std::map< std::string, std::pair< long, bool > >::iterator hit = id_map.find( iter->first );
+ if ( hit != id_map.end() )
+ {
+ long domid = hit->second.first; // --id-input-fileオプションで指定された値
+ if ( domid > 32 )
+ {
+ fatal( _( "%1% id `%2%' is too large" ), "domain", hit->first );
+ }
+ domids[ domid - 1 ] = hit->first;
+ }
+ }
+ // 二周目は、残りのドメインIDを割り付ける
+ for ( std::vector< std::pair< std::string, long > >::iterator iter( domid_table.begin() ), last( domid_table.end() );
+ iter != last;
+ ++iter )
+ {
+ if ( id_map.find( iter->first ) == id_map.end() )
+ {
+ for ( int i = 0; i < sizeof( domids ) / sizeof( domids[ 0 ] ); i++ )
+ {
+ if ( domids[ i ].empty() )
+ {
+ domids[ i ] = iter->first;
+ break;
+ }
+ }
+ }
+ }
+ domid_table.clear();
+ for ( std::size_t i = 0; i < sizeof( domids ) / sizeof( domids[ 0 ] ); i++ )
+ {
+ domid_table.push_back( std::make_pair( domids[ i ], long( i + 1 ) ) );
+ }
+
+ // cfg1_out.c出力用のコードを生成
+ for ( std::vector< std::pair< std::string, long > >::iterator iter( domid_table.begin() ), last( domid_table.end() );
+ iter != last;
+ ++iter )
+ {
+ if ( !iter->first.empty() )
+ {
+ domid_defs_temp += ( boost::format( "#define %1%\t%2%\n" ) % iter->first % iter->second ).str();
+ }
+ }
+ }
+
+ // データメンバへの反映
+ std::string cfg1_list_temp( oss.str() );
+ std::string includes_temp( includes_oss.str() );
+
+ clsid_table_.swap( clsid_table );
+ domid_table_.swap( domid_table );
+ domid_defs_.swap( domid_defs_temp );
+ cfg1_out_list_.swap( cfg1_list_temp );
+ includes_.swap( includes_temp );
+ static_api_array_.swap( api_array );
+ block_table_.swap( block_table );
+ }
+
+ /*!
+ * \brief cfg1_out.c の内容生成
+ * \param[in] type 配列 cfg1_out[] の要素型。空ポインタの場合は uint32_t として扱われる。
+ */
+ void cfg1_out::generate( char const* type ) const
+ {
+ if ( type == 0 )
+ {
+ type = "uint32_t";
+ }
+ pimpl_->ofile_ << "/* cfg1_out.c */\n"
+ "#define TOPPERS_CFG1_OUT 1\n"
+ "#include \"kernel/kernel_int.h\"\n";
+ pimpl_->do_generate_includes();
+ pimpl_->ofile_ << pimpl_->includes_ << '\n';
+
+ // int128_tは故意に無視
+ // int128_tに揃えると処理が重くなりすぎるため
+ pimpl_->ofile_ << "\n#ifdef INT64_MAX\n"
+ " typedef int64_t signed_t;\n"
+ " typedef uint64_t unsigned_t;\n"
+ "#else\n"
+ " typedef int32_t signed_t;\n"
+ " typedef uint32_t unsigned_t;\n"
+ "#endif\n";
+
+ pimpl_->ofile_ << "\n#include <target_cfg1_out.h>\n\n";
+
+ pimpl_->do_generate_cfg1_def();
+ pimpl_->ofile_ << '\n' << pimpl_->domid_defs_ << '\n';
+ pimpl_->ofile_ << pimpl_->cfg1_out_list_ << '\n';
+ }
+
+ /*!
+ * \brief 静的API配列の参照
+ * \return 内部で保持している静的API配列への参照
+ */
+ std::vector< static_api > const& cfg1_out::get_static_api_array() const
+ {
+ return pimpl_->static_api_array_;
+ }
+
+ /*!
+ * \brief ドメインIDテーブルの参照
+ * \return 内部で保持しているドメインIDテーブルへの参照
+ */
+ std::vector< std::pair< std::string, long > > const& cfg1_out::get_domid_table() const
+ {
+ return pimpl_->domid_table_;
+ }
+
+ /*!
+ * \brief クラスIDテーブルの参照
+ * \return 内部で保持しているクラスIDテーブルへの参照
+ */
+ std::vector< std::pair< std::string, long > > const& cfg1_out::get_clsid_table() const
+ {
+ return pimpl_->clsid_table_;
+ }
+
+ /*!
+ * \brief #include指令の並びを取得する
+ * \return #include指令の並び
+ *
+ * このメンバ関数は、
+ * \code
+ * #include <...>
+ * #include "..."
+ * \endcode
+ * といった#include指令の並びを文字列として返す。
+ */
+ std::string const& cfg1_out::get_includes() const
+ {
+ return pimpl_->includes_;
+ }
+
+ /*!
+ * \brief Sレコードのロード
+ */
+ void cfg1_out::load_srec()
+ {
+ std::ifstream srec_ifs( ( pimpl_->ofile_.file_name() + ".srec" ).c_str() );
+ if ( !srec_ifs.is_open() )
+ {
+ fatal( _( "cannot open file `%1%\'" ), pimpl_->ofile_.file_name() + ".srec" );
+ }
+ pimpl_->srec_ = std::tr1::shared_ptr< s_record >( new s_record( srec_ifs ) );
+
+ std::ifstream syms_ifs( ( pimpl_->ofile_.file_name() + ".syms" ).c_str() );
+ if ( !syms_ifs.is_open() )
+ {
+ fatal( _( "cannot open file `%1%\'" ), pimpl_->ofile_.file_name() + ".syms" );
+ }
+ pimpl_->syms_ = std::tr1::shared_ptr< nm_symbol >( new nm_symbol( syms_ifs ) );
+
+ nm_symbol::entry nm_entry = pimpl_->syms_->find( "TOPPERS_cfg_magic_number" );
+ if ( nm_entry.type < 0 )
+ {
+ fatal( _( "magic number is not found in `%1%\'" ), ( pimpl_->ofile_.file_name() + ".srec/.syms" ) );
+ }
+ unsigned long magic[ 4 ];
+ magic[ 0 ] = ( *pimpl_->srec_ )[ nm_entry.address + 0 ];
+ magic[ 1 ] = ( *pimpl_->srec_ )[ nm_entry.address + 1 ];
+ magic[ 2 ] = ( *pimpl_->srec_ )[ nm_entry.address + 2 ];
+ magic[ 3 ] = ( *pimpl_->srec_ )[ nm_entry.address + 3 ];
+ unsigned long magic_number = ( magic[ 0 ] << 24 ) | ( magic[ 1 ] << 16 ) | ( magic[ 2 ] << 8 ) | magic[ 3 ];
+ if ( magic_number == 0x12345678 )
+ {
+ pimpl_->little_endian_ = false;
+ }
+ else if ( magic_number == 0x78563412 )
+ {
+ pimpl_->little_endian_ = true;
+ }
+ else
+ {
+ fatal( _( "magic number is not found in `%1%\'" ), ( pimpl_->ofile_.file_name() + ".srec/.syms" ) );
+ }
+ pimpl_->do_assign_params();
+ }
+
+ /*!
+ * \brief "cfg1_out.srec" から読み取った情報の参照
+ */
+ std::tr1::shared_ptr< s_record > cfg1_out::get_srec() const
+ {
+ return pimpl_->srec_;
+ }
+
+ /*!
+ * \brief "cfg1_out.syms" から読み取った情報の参照
+ */
+ std::tr1::shared_ptr< nm_symbol > cfg1_out::get_syms() const
+ {
+ return pimpl_->syms_;
+ }
+
+ cfg1_out::cfg1_def_table const* cfg1_out::get_def_table() const
+ {
+ return pimpl_->def_table_;
+ }
+
+ /*!
+ * \brief カーネルオブジェクトごとに静的API情報をまとめる
+ * \return 静的API情報
+ *
+ * この関数は、"tsk"や"sem"といった種別をキーとして、その種別に分類される静的API情報の連想配列を生成する。
+ */
+ cfg1_out::static_api_map cfg1_out::merge() const
+ {
+ static_api_map result;
+ for ( std::vector< static_api >::const_iterator iter( pimpl_->static_api_array_.begin() ), last( pimpl_->static_api_array_.end() );
+ iter != last;
+ ++iter )
+ {
+ static_api::info const* info = iter->get_info();
+ if ( info != 0 )
+ {
+ result[ info->type ].push_back( *iter );
+ }
+ }
+ return result;
+ }
+
+ /*!
+ * \brief リトルエンディアンかどうかの判定
+ * \retval true リトルエンディアン
+ * \retval false ビッグエンディアン
+ * \attention load_srec 呼び出し前は正しい結果を得られない。
+ */
+ bool cfg1_out::is_little_endian() const
+ {
+ return pimpl_->little_endian_;
+ }
+
+ /*!
+ * \brief 静的APIのパラメータにSレコードから取得した値を代入する
+ */
+ void cfg1_out::implementation::do_assign_params()
+ {
+ std::vector< toppers::itronx::static_api > temp_array;
+
+ for ( std::vector< static_api >::size_type serial = 0, n = static_api_array_.size(); serial < n; ++serial )
+ {
+ toppers::itronx::static_api api( static_api_array_.at( serial ) );
+
+ nm_symbol::entry nm_entry = syms_->find( boost::str( boost::format( "TOPPERS_cfg_static_api_%d" ) % serial ) );
+ if ( nm_entry.type == -1 )
+ {
+ continue;
+ }
+
+ // sizeof( signed_t )
+ std::size_t const sizeof_signed_t = static_cast< std::size_t >( srec_->get_value( syms_->find( "TOPPERS_cfg_sizeof_signed_t" ).address, 4, little_endian_ ) );
+
+ for ( toppers::itronx::static_api::iterator api_iter( api.begin() ),
+ api_last( api.end() );
+ api_iter != api_last;
+ ++api_iter )
+ {
+ if ( ( api_iter->symbol[0] == '.' ) || ( api_iter->symbol[0] == '+' ) || ( api_iter->symbol[0] == '*' ) )
+ // 整数定数式パラメータのみ値を取得
+ {
+ std::string parameter_name( api_iter->symbol.c_str() + 1 );
+
+ // 省略可能パラメータ情報の末尾にある ? を除去
+ if ( *parameter_name.rbegin() == '\?' )
+ {
+ parameter_name.resize( parameter_name.size() - 1 );
+ }
+
+ std::string symbol = boost::str( boost::format( "TOPPERS_cfg_valueof_%s_%d" ) % parameter_name % serial );
+ nm_symbol::entry nm_entry = syms_->find( symbol );
+ if ( nm_entry.type == -1 )
+ {
+ continue;
+ }
+ const std::size_t size = sizeof_signed_t;
+ std::tr1::intmax_t value = srec_->get_value( nm_entry.address, size, little_endian_ );
+
+ if ( api_iter->symbol[0] == '+' )
+ {
+ value = make_signed( static_cast< std::tr1::uint32_t >( value ) );
+ }
+ api_iter->value = value;
+ }
+ else if ( api_iter->symbol[0] == '$' ) // 文字列定数式パラメータ
+ {
+ std::string parameter_name( api_iter->symbol.c_str() + 1 );
+
+ // 省略可能パラメータ情報の末尾にある ? を除去
+ if ( *parameter_name.rbegin() == '\?' )
+ {
+ parameter_name.resize( parameter_name.size() - 1 );
+ }
+
+ std::string symbol = boost::str( boost::format( "TOPPERS_cfg_valueof_%s_%d" ) % parameter_name % serial );
+ nm_symbol::entry nm_entry = syms_->find( symbol );
+ if ( nm_entry.type == -1 )
+ {
+ continue;
+ }
+ std::string string;
+ string.reserve( 256 );
+ char c;
+ for ( long i = 0; ( c = static_cast< char >( srec_->get_value( nm_entry.address + i, 1, little_endian_ ) ) ) != '\0'; i++ )
+ {
+ string.push_back( c );
+ }
+
+ api_iter->string = string;
+ }
+ }
+ temp_array.push_back( api );
+ }
+ static_api_array_.swap( temp_array );
+ }
+
+ /*!
+ * \brief --id-input-fileオプションで指定したファイルの読み込み
+ * \id_map 読み込んだデータの格納先
+ */
+ void cfg1_out::load_id_input_file( std::map< std::string, std::pair< long, bool > >& id_map )
+ {
+ std::string id_input_file( get_global< std::string >( "id-input-file" ) );
+ if ( id_input_file.empty() )
+ {
+ return;
+ }
+
+ std::ifstream ifs( id_input_file.c_str() );
+ while ( ifs )
+ {
+ std::string linebuf;
+ std::getline( ifs, linebuf );
+ if ( ifs.bad() )
+ {
+ fatal( _( "I/O error" ) );
+ }
+ if ( linebuf.empty() || linebuf == "\r" )
+ {
+ break;
+ }
+
+ std::istringstream iss( linebuf );
+ std::string name;
+ iss >> name;
+ if ( iss.fail() )
+ {
+ fatal( _( "id file `%1%\' is invalid" ), id_input_file );
+ }
+
+ long value;
+ iss >> value;
+ if ( iss.fail() )
+ {
+ fatal( _( "id file `%1%\' is invalid" ), id_input_file );
+ }
+
+ if ( id_map.find( name ) != id_map.end() )
+ {
+ fatal( _( "`%1%\' is duplicated" ), name );
+ }
+ else
+ {
+ id_map[ name ] = std::make_pair( value, false );
+ }
+ }
+ }
+
+ }
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/*!
+ * \file toppers/itronx/cfg1_out.hpp
+ * \brief cfg1_out.c/.srec ファイルを扱うための宣言定義
+ *
+ * このファイルで定義されるクラス
+ * \code
+ * class cfg1_out;
+ * \endcode
+ */
+#ifndef TOPPERS_ITRONX_CFG1_OUT_HPP_
+#define TOPPERS_ITRONX_CFG1_OUT_HPP_
+
+#include <string>
+#include <vector>
+#include <map>
+#include "toppers/workaround.hpp"
+#include "toppers/codeset.hpp"
+#include "toppers/itronx/static_api.hpp"
+
+namespace toppers
+{
+
+ class macro_processor;
+ class s_record;
+ class nm_symbol;
+
+ namespace itronx
+ {
+
+ /*!
+ * \class cfg1_out cfg1_out.hpp "toppers/itronx/cfg1_out.hpp"
+ * \brief cfg1_out.c/.srec ファイル管理クラス
+ */
+ class cfg1_out
+ {
+ public:
+ struct cfg1_def_t
+ {
+ bool is_signed;
+ std::string name;
+ std::string expression;
+ std::string value1;
+ std::string value2;
+ };
+ typedef std::map< std::string, std::vector< static_api > > static_api_map;
+ typedef std::vector< cfg1_def_t > cfg1_def_table;
+
+ explicit cfg1_out( std::string const& filename, cfg1_def_table const* def_table = 0 );
+ cfg1_out( cfg1_out const& other );
+ virtual ~cfg1_out();
+ cfg1_out& operator = ( cfg1_out const& other )
+ {
+ cfg1_out t( other );
+ swap( t );
+ return *this;
+ }
+
+ void load_cfg( std::string const& input_file, codeset_t codeset, std::map< std::string, static_api::info > const& info_map );
+ void generate( char const* type = 0 ) const;
+ std::vector< static_api > const& get_static_api_array() const;
+ std::vector< std::pair< std::string, long > > const& get_domid_table() const;
+ std::vector< std::pair< std::string, long > > const& get_clsid_table() const;
+ std::string const& get_includes() const;
+
+ void load_srec();
+ std::tr1::shared_ptr< s_record > get_srec() const;
+ std::tr1::shared_ptr< nm_symbol > get_syms() const;
+ cfg1_def_table const* get_def_table() const;
+ static_api_map merge() const;
+ bool is_little_endian() const;
+
+ void swap( cfg1_out& other )
+ {
+ implementation* t = pimpl_;
+ pimpl_ = other.pimpl_;
+ other.pimpl_ = t;
+ }
+
+ static std::tr1::int32_t make_signed( std::tr1::uint32_t value )
+ {
+ std::tr1::int32_t result;
+ if ( ( value >> 31 ) != 0 )
+ {
+ result = -static_cast< std::tr1::int32_t >( ( value ^ 0xffffffff ) + 1 ); // 2の補数表現にしか対応しない
+ }
+ else
+ {
+ result = static_cast< std::tr1::int32_t >( value );
+ }
+ return result;
+ }
+
+ static void load_id_input_file( std::map< std::string, std::pair< long, bool > >& id_map );
+
+ protected:
+ struct implementation;
+ explicit cfg1_out( implementation* pimpl ) : pimpl_( pimpl ) {}
+ private:
+ implementation* pimpl_;
+ };
+
+ }
+}
+
+#endif // ! TOPPERS_ITRONX_CFG1_OUT_HPP_
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2007-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+#include <fstream>
+#include <map>
+#include "toppers/workaround.hpp"
+#include "toppers/s_record.hpp"
+#include "toppers/nm_symbol.hpp"
+#include "toppers/misc.hpp"
+#include "toppers/diagnostics.hpp"
+#include "toppers/itronx/checker.hpp"
+#include "toppers/itronx/cfg1_out.hpp"
+
+namespace toppers
+{
+ namespace itronx
+ {
+
+ struct checker::implementation
+ {
+ protected:
+ std::tr1::shared_ptr< s_record > srec_;
+ std::tr1::shared_ptr< nm_symbol > syms_;
+
+ virtual ~implementation() {}
+ virtual bool do_check( cfg1_out& cfg1out, std::map< std::string, std::size_t > const& count_map )
+ {
+ return true;
+ }
+ virtual implementation* do_clone() const
+ {
+ return new implementation( *this );
+ }
+
+ friend class checker;
+ };
+
+ checker::checker()
+ : pimpl_( new implementation )
+ {
+ }
+
+ /*!
+ * \brief コピーコンストラクタ
+ * \param[in] コピー元
+ */
+ checker::checker( checker const& other )
+ : pimpl_( other.pimpl_->do_clone() )
+ {
+ }
+
+ //! デストラクタ
+ checker::~checker()
+ {
+ delete pimpl_;
+ pimpl_ = 0;
+ }
+
+ /*!
+ * \brief ROMイメージのロード
+ * \param[in] srec_file Sレコード形式のファイル名
+ * \param[in] nm_file nmコマンドが出力したシンボルテーブルのファイル名
+ */
+ void checker::load_rom_image( std::string const& srec_file, std::string const& nm_file )
+ {
+ std::ifstream ifs_srec( srec_file.c_str() );
+ if ( !ifs_srec.is_open() )
+ {
+ fatal( _( "cannot open file `%1%\'" ), srec_file );
+ }
+ std::tr1::shared_ptr< s_record > srec( new s_record( ifs_srec ) );
+
+ std::ifstream ifs_nm( nm_file.c_str() );
+ if ( !ifs_nm.is_open() )
+ {
+ fatal( _( "cannot open file `%1%\'" ), nm_file );
+ }
+ std::tr1::shared_ptr< nm_symbol > syms( new nm_symbol( ifs_nm ) );
+
+ pimpl_->srec_.swap( srec );
+ pimpl_->syms_.swap( syms );
+ }
+
+ /*!
+ * \brief チェックの実施
+ * \param[in] cfg1_out情報
+ */
+ bool checker::check( cfg1_out& cfg1out ) const
+ {
+ cfg1_out::static_api_map api_map( cfg1out.merge() );
+
+ std::map< std::string, std::size_t > count_map;
+ for ( cfg1_out::static_api_map::const_iterator iter( api_map.begin() ), last( api_map.end() );
+ iter != last;
+ ++iter )
+ {
+ std::size_t count = 0;
+ for ( std::vector< static_api >::const_iterator iter2( iter->second.begin() ), last2( iter->second.end() );
+ iter2 != last2;
+ ++iter2 )
+ {
+ if ( !iter2->get_info()->slave )
+ {
+ ++count;
+ }
+ }
+ count_map[ iter->first ] = count;
+ }
+
+ return pimpl_->do_check( cfg1out, count_map );
+ }
+
+ /*!
+ * \brief シンボル情報の検索
+ * \param[in] symbol 検索するシンボル名
+ * \return 検索結果
+ *
+ * 検索に失敗した場合には、返却値の.typeフィールドに-1が設定される。
+ */
+ nm_symbol::entry checker::find( std::string const& symbol ) const
+ {
+ return pimpl_->syms_->find( symbol );
+ }
+
+ /*!
+ * \brief 指定アドレスの整数値を取得
+ * \param[in] address アドレス
+ * \param[in] size 整数値を構成するバイト数
+ * \param[in] little_endian バイトオーダーがリトルエンディアンならtrueを指定する
+ * \return 取得した整数値を符号無しで返す。
+ */
+ std::tr1::uintmax_t checker::get( std::size_t address, std::size_t size, bool little_endian ) const
+ {
+ return pimpl_->srec_->get_value( address, size, little_endian );
+ }
+
+ }
+}
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2007-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+#ifndef TOPPERS_ITRONX_CHECKER_HPP_
+#define TOPPERS_ITRONX_CHECKER_HPP_
+
+#include <cstddef>
+#include <string>
+#include "toppers/workaround.hpp"
+#include "toppers/nm_symbol.hpp"
+
+namespace toppers
+{
+ namespace itronx
+ {
+
+ class cfg1_out;
+
+ /*!
+ * \class checker checker.hpp "toppers/itronx/checker.hpp"
+ * \brief 全体リンク後のパラメータチェック処理クラス
+ */
+ class checker
+ {
+ public:
+ checker();
+ checker( checker const& other );
+ virtual ~checker();
+ checker& operator=( checker const& other )
+ {
+ checker t( other );
+ swap( t );
+ return *this;
+ }
+
+ void load_rom_image( std::string const& srec_file, std::string const& nm_file );
+ bool check( cfg1_out& cfg1out ) const;
+ nm_symbol::entry find( std::string const& symbol ) const;
+ std::tr1::uintmax_t get( std::size_t address, std::size_t size, bool little_endian ) const;
+
+ void swap( checker& other )
+ {
+ implementation* t = pimpl_;
+ pimpl_ = other.pimpl_;
+ other.pimpl_ = t;
+ }
+ protected:
+ struct implementation;
+ explicit checker( implementation* pimpl ) : pimpl_( pimpl ) {}
+ private:
+ implementation* pimpl_;
+ };
+
+ }
+}
+
+#endif // ! TOPPERS_ITRONX_CHECKER_HPP_
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+#include <cstdlib>
+#include <cstring>
+#include <cerrno>
+#include <string>
+#include <vector>
+#include <utility>
+#include <algorithm>
+#include <fstream>
+#include "toppers/macro_processor.hpp"
+#include "toppers/diagnostics.hpp"
+#include "toppers/gettext.hpp"
+#include "toppers/cpp.hpp"
+#include "toppers/global.hpp"
+#include "toppers/misc.hpp"
+#include "toppers/itronx/static_api.hpp"
+#include "toppers/itronx/factory.hpp"
+#include "toppers/itronx/component.hpp"
+#include <boost/format.hpp>
+#include <boost/utility.hpp>
+#include <boost/lexical_cast.hpp>
+
+namespace toppers
+{
+ namespace
+ {
+ typedef macro_processor::element element;
+ typedef macro_processor::var_t var_t;
+ typedef macro_processor::context context;
+
+ inline std::tr1::int64_t get_i( var_t const& var, context const* p_ctx )
+ {
+ return macro_processor::to_integer( var, p_ctx );
+ }
+ inline std::string get_s( var_t const& var, context const* p_ctx )
+ {
+ return macro_processor::to_string( var, p_ctx );
+ }
+
+ inline bool less_element( const element& lhs, const element& rhs )
+ {
+ return *lhs.i < *rhs.i;
+ }
+
+ /*!
+ * \brief ID番号を割付ける
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ * 第一引数で指定した種別のオブジェクトに対してID番号を割付け、個々のパラメータを表す変数、
+ * TEXT_LINE、ID_LIST、ORDER_LIST、およびRORDER_LISTを設定する。ただし、ID番号を持たない
+ * オブジェクトの場合、ID_LISTは設定しない。
+ */
+ var_t bf_assignid( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ if ( macro_processor::check_arity( line, arg_list.size(), 1, "ASSIGNID" ) )
+ {
+ itronx::factory* factory = get_global< itronx::factory* >( "factory" );
+ std::map< std::string, itronx::static_api::info > const* info_map = factory->get_static_api_info_map();
+
+ std::string type = get_s( arg_list[ 0 ], p_ctx ); // 出力先リストの識別名
+ std::string TYPE = toppers::toupper( type );
+ typedef std::map< std::string, long > id_map_t;
+ typedef std::map< long, std::string > id_rmap_t;
+ id_map_t id_map;
+ id_rmap_t id_rmap;
+ var_t id_list, order_list, rorder_list;
+ bool has_id = false;
+
+ std::string id_input_file( get_global< std::string >( "id-input-file" ) );
+ if ( !id_input_file.empty() ) // --id-input-file オプションが指定されている場合...
+ {
+ std::ifstream ifs( id_input_file.c_str() );
+ while ( ifs )
+ {
+ std::string linebuf;
+ std::getline( ifs, linebuf );
+ if ( ifs.bad() )
+ {
+ fatal( _( "I/O error" ) );
+ }
+ if ( linebuf.empty() || linebuf == "\r" )
+ {
+ break;
+ }
+
+ std::istringstream iss( linebuf );
+ std::string name;
+ iss >> name;
+ if ( iss.fail() )
+ {
+ fatal( _( "id file `%1%\' is invalid" ), id_input_file );
+ }
+
+ long value;
+ iss >> value;
+ if ( iss.fail() )
+ {
+ fatal( _( "id file `%1%\' is invalid" ), id_input_file );
+ }
+
+ if ( id_map.find( name ) != id_map.end() )
+ {
+ fatal( _( "E_OBJ: `%1%\' is duplicated" ), name );
+ }
+ else
+ {
+ id_map[ name ] = value;
+ id_rmap[ value ] = name;
+ }
+ }
+ }
+ long order = 1;
+ for ( int i = 1; ; i++ )
+ {
+ std::string str_i = boost::lexical_cast< std::string >( i );
+ if ( p_ctx->var_map.find( "API.TYPE[" + str_i + "]" ) == p_ctx->var_map.end() )
+ {
+ break;
+ }
+ std::string api_name = p_ctx->var_map[ "API.NAME[" + str_i + "]" ].at( 0 ).s;
+ std::map< std::string, itronx::static_api::info >::const_iterator it = info_map->find( api_name );
+ if ( it == info_map->end() )
+ {
+ break;
+ }
+ itronx::static_api::info info = it->second;
+ if ( info.type != type )
+ {
+ continue;
+ }
+
+ var_t params = p_ctx->var_map[ "API.PARAMS[" + str_i + "]" ];
+ var_t args = p_ctx->var_map[ "API.ARGS[" + str_i + "]" ];
+ long id = -1;
+
+ if ( info.id_pos >= 0 ) // ID番号のあるもの...
+ {
+ if ( !info.slave )
+ {
+ if ( std::strchr( info.params, '#' ) != 0 ) // オブジェクト識別名を持つ場合...
+ {
+ for ( id = 1; id_rmap.find( id ) != id_rmap.end(); id++ ) // 未使用のID番号を検索
+ ;
+ args.at( info.id_pos ).i = id; // ID番号を設定
+ }
+ else
+ {
+ id = static_cast< long >( *args.at( info.id_pos ).i );
+ }
+ std::string idname = args[ info.id_pos ].s; // IDの字面
+ id_map[ idname ] = id;
+ id_rmap[ id ] = idname;
+ order_list.push_back( args[ info.id_pos ] );
+ }
+ else
+ {
+ id_map_t::iterator it = id_map.find( args.at( info.id_pos ).s );
+ if ( it == id_map.end() )
+ {
+ fatal( line, _( "`%1%\' is undefined" ), args[ info.id_pos ].s );
+ }
+ args.at( info.id_pos ).i = it->second;
+ }
+ has_id = true;
+ }
+ else // ID番号の無いもの...
+ {
+ element e;
+ e.i = order;
+ order_list.push_back( e );
+ }
+ std::string str_id = boost::lexical_cast< std::string >( id > 0 ? id : order );
+
+ // 各パラメータの変数を設定
+ for ( var_t::size_type i = 0, n = params.size(); i < n; i++ )
+ {
+ std::string var_name = params[ i ].s + "[" + str_id + "]";
+ p_ctx->var_map[ var_name ] = var_t( 1, args.at( i ) );
+ }
+ p_ctx->var_map[ TYPE + ".TEXT_LINE[" + str_id + "]" ] = p_ctx->var_map[ "API.TEXT_LINE[" + str_i + "]" ];
+ ++order;
+ }
+
+ id_list = order_list;
+ std::sort( id_list.begin(), id_list.end(), less_element );
+ rorder_list = order_list;
+ std::reverse( rorder_list.begin(), rorder_list.end() );
+ p_ctx->var_map[ TYPE + ".ID_LIST" ] = id_list;
+ p_ctx->var_map[ TYPE + ".ORDER_LIST" ] = order_list;
+ p_ctx->var_map[ TYPE + ".RORDER_LIST" ] = rorder_list;
+ }
+ return var_t();
+ }
+
+ /*!
+ * \brief 指定した連想配列群に静的APIを追加する
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ * API.で始まる連想配列群を、必要に応じて適切に変換を行った上で、別のプレフィックスで始まる
+ * 連想配列群に追加する。想定する使用方法としては、特定のソフトウェア部品で理解可能な静的API
+ * に関しては、追加を行わないか、他の静的APIに置き換えて追加を行う。理解できない静的APIに関して
+ * はそのまま追加を行う。
+ * この関数の第一引数にはAPI.で始まる連想配列の連番を、第二引数には追加先に連想配列群の
+ * プレフィックスを、第三引数には対象とする静的API名を、第四引数には追加するパラメータシンボルの
+ * 並びを、第五引数にはパラメータの並びを指定する。
+ */
+ var_t bf_addapi( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ element e;
+ if ( macro_processor::check_arity( line, arg_list.size(), 5, "ADDAPI" ) )
+ {
+ itronx::factory* factory = get_global< itronx::factory* >( "factory" );
+ std::map< std::string, itronx::static_api::info > const* info_map = factory->get_static_api_info_map();
+
+ std::tr1::int64_t order = get_i( arg_list[ 0 ], p_ctx ); // 元の静的APIの連番
+ std::string list_name = get_s( arg_list[ 1 ], p_ctx ); // 出力先リストの識別名
+ std::string api_name = get_s( arg_list[ 2 ], p_ctx ); // 静的API名
+ var_t params = arg_list[ 3 ]; // パラメータシンボルの並び
+ var_t args = arg_list[ 4 ]; // パラメータの並び
+
+ std::map< std::string, itronx::static_api::info >::const_iterator it = info_map->find( api_name );
+ if ( it != info_map->end() )
+ {
+ itronx::static_api::info info = it->second;
+ std::string str_order = boost::lexical_cast< std::string >( order );
+ p_ctx->var_map[ list_name + ".TEXT_LINE[" + str_order + "]" ] = p_ctx->var_map[ "API.TEXT_LINE[" + str_order + "]" ];
+ e.s = api_name;
+ p_ctx->var_map[ list_name + ".NAME[" + str_order + "]" ] = var_t( 1, e );
+ e.s = info.type;
+ p_ctx->var_map[ list_name + ".TYPE[" + str_order + "]" ] = var_t( 1, e );
+ p_ctx->var_map[ list_name + ".PARAMS[" + str_order + "]" ] = params;
+ p_ctx->var_map[ list_name + ".ARGS[" + str_order + "]" ] = args;
+
+ e.s.clear();
+ if ( !p_ctx->var_map[ list_name + ".ORDER_LIST" ].empty() )
+ {
+ e.i = *p_ctx->var_map[ list_name + ".ORDER_LIST" ].back().i + 1;
+ }
+ else
+ {
+ e.i = 1;
+ }
+ p_ctx->var_map[ list_name + ".ORDER_LIST" ].push_back( e );
+
+ e.s.clear();
+ e.i = 1;
+ }
+ }
+ return var_t( 1, e );
+ }
+
+ /*!
+ * \brief 変数群の交換
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ * 第一引数および第二引数で指定したプレフィックスを持つ変数群を入れ替える。
+ * ‘ADDAPI’関数で、別のプレフィックスを持つ連想配列を組み立てたあとは、この関数を用いることで、
+ * API.をプレフィックスに持つ連想配列と交換することができる。
+ */
+ var_t bf_swapprefix( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ if ( macro_processor::check_arity( line, arg_list.size(), 2, "SWAPPREFIX" ) )
+ {
+ std::string list1_name = get_s( arg_list[ 0 ], p_ctx ) + "."; // 一方のAPIリストの識別名.
+ std::string list2_name = get_s( arg_list[ 1 ], p_ctx ) + "."; // 他方のAPIリストの識別名.
+ std::string::size_type list1_size = list1_name.size();
+ std::string::size_type list2_size = list2_name.size();
+
+ std::map< std::string, var_t > temp;
+ for ( std::map< std::string, var_t >::const_iterator iter = p_ctx->var_map.begin(), last = p_ctx->var_map.end();
+ iter != last;
+ ++iter )
+ {
+ std::pair< std::string, var_t > element = *iter;
+ if ( std::strncmp( iter->first.c_str(), list1_name.c_str(), list1_size ) == 0 )
+ {
+ element.first = list2_name + ( iter->first.c_str() + list1_size );
+ }
+ else if ( std::strncmp( iter->first.c_str(), list2_name.c_str(), list2_size ) == 0 )
+ {
+ element.first = list1_name + ( iter->first.c_str() + list2_size );
+ }
+ temp.insert( element );
+ }
+ p_ctx->var_map.swap( temp );
+ }
+ return var_t();
+ }
+
+ /*!
+ * \brief 変数群の交換
+ * \param[in] line 行番号
+ * \param[in] arg_list マクロ実引数リスト
+ * \param[in] p_ctx マクロコンテキスト
+ * \retval マクロ返却値
+ * 第一引数で指定したプレフィックスで始まる変数群を削除する。’SWAPPREFIX’関数で交換したあと、
+ * 不要になった変数群はこの関数で削除しておくことが望ましい。
+ */
+ var_t bf_cleanvars( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ if ( macro_processor::check_arity( line, arg_list.size(), 1, "CLEANVARS" ) )
+ {
+ std::string prefix = get_s( arg_list[ 0 ], p_ctx ) + "."; // 変数の接頭辞
+ std::size_t n = prefix.size();
+ std::map< std::string, var_t > temp_map;
+
+ for ( std::map< std::string, var_t >::const_iterator iter = p_ctx->var_map.begin(), last =p_ctx->var_map.end();
+ iter != last;
+ ++iter )
+ {
+ if ( std::strncmp( iter->first.c_str(), prefix.c_str(), n ) != 0 )
+ {
+ temp_map.insert( *iter );
+ }
+ }
+ p_ctx->var_map.swap( temp_map );
+ }
+ return var_t();
+ }
+
+ macro_processor::func_t const function_table[] =
+ {
+ { "ASSIGNID", &bf_assignid },
+ { "ADDAPI", &bf_addapi },
+ { "SWAPPREFIX", &bf_swapprefix },
+ { "CLEANVARS", &bf_cleanvars },
+ };
+
+ }
+
+ namespace itronx
+ {
+
+ component::component( macro_processor* mproc )
+ : mproc_( mproc )
+ {
+ for ( std::size_t i = 0; i < sizeof( function_table ) / sizeof( function_table[ 0 ] ); i++ )
+ {
+ mproc_->add_builtin_function( function_table[ i ] );
+ }
+ }
+
+ }
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/*!
+ * \file toppers/itronx/component.hpp
+ * \brief ソフトウェア部品用のコンフィギュレーションを扱うための宣言定義
+ *
+ * このファイルで定義されるクラス
+ * \code
+ * class component;
+ * \endcode
+ */
+#ifndef TOPPERS_ITRONX_COMPONENT_HPP_
+#define TOPPERS_ITRONX_COMPONENT_HPP_
+
+namespace toppers
+{
+
+ class macro_processor;
+
+ namespace itronx
+ {
+
+ /*!
+ * \class component component.hpp "toppers/itronx/component.hpp"
+ * \brief ソフトウェア部品用のコンフィギュレーションを扱うためのクラス
+ * \note 現状ではコンストラクタ以外のメンバ関数を持たない。将来の拡張用にクラスにする。
+ */
+ class component
+ {
+ public:
+ explicit component( macro_processor* mproc );
+ // 現状ではメンバ無し
+ private:
+ macro_processor* mproc_;
+ };
+
+ }
+}
+
+#endif // !TOPPERS_ITRONX_COMPONENT_HPP_
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+#include <cstring>
+#include <cstdlib>
+#include <fstream>
+#include <boost/lexical_cast.hpp>
+#include "toppers/misc.hpp"
+#include "toppers/global.hpp"
+#include "toppers/csv.hpp"
+#include "toppers/nm_symbol.hpp"
+#include "toppers/s_record.hpp"
+#include "toppers/diagnostics.hpp"
+#include "toppers/macro_processor.hpp"
+#include "toppers/io.hpp"
+#include "toppers/cpp.hpp"
+#include "toppers/itronx/factory.hpp"
+#include "toppers/itronx/cfg1_out.hpp"
+
+namespace toppers
+{
+ namespace itronx
+ {
+ namespace
+ {
+
+ // カーネルオブジェクト生成・定義用静的APIの各パラメータをマクロプロセッサの変数として設定する。
+ void set_object_vars( cfg1_out::static_api_map const& api_map, macro_processor& mproc )
+ {
+ typedef macro_processor::element element;
+ typedef macro_processor::var_t var_t;
+ std::map< std::string, var_t > order_list_map;
+ std::map< std::string, long > id_map;
+
+ for ( cfg1_out::static_api_map::const_iterator m_iter( api_map.begin() ), m_last( api_map.end() );
+ m_iter != m_last;
+ ++m_iter )
+ {
+ int order = 1;
+
+ for ( std::vector< static_api >::const_iterator v_iter( m_iter->second.begin() ), v_last( m_iter->second.end() );
+ v_iter != v_last;
+ ++v_iter )
+ {
+ static_api::info const* info = v_iter->get_info();
+
+ long id = -1;
+ if ( !info->slave )
+ {
+ // 出現順 $OBJ.ORDER$
+ if ( v_iter->id().value )
+ {
+ id = static_cast< long >( v_iter->id().value.get() );
+ }
+ else
+ {
+ id = order;
+ }
+ id_map[ v_iter->id().text ] = id;
+ element e;
+ e.i = order;
+ mproc.set_var( toppers::toupper( ( boost::format( "%s.order" ) % info->type ).str() ), id, var_t( 1, e ) );
+
+ e.i = id;
+ e.s = v_iter->id().text;
+ order_list_map[ info->type ].push_back( e );
+ ++order;
+ }
+ else
+ {
+ std::map< std::string, long >::iterator iter( id_map.find( v_iter->id().text ) );
+ if ( iter == id_map.end() )
+ {
+ error( v_iter->line(), _( "E_NOEXS: `%1%\' is undefined" ), v_iter->id().text );
+ }
+ else
+ {
+ id = iter->second;
+ }
+ }
+
+ // 各パラメータ
+ for ( static_api::const_iterator api_iter( v_iter->begin() ), api_last( v_iter->end() );
+ api_iter != api_last;
+ ++api_iter )
+ {
+ std::string name( toppers::toupper( ( boost::format( "%s.%s" ) % info->type % ( api_iter->symbol.c_str() + 1 ) ).str() ) );
+ // 末尾の ? を除去
+ if ( *name.rbegin() == '\?' )
+ {
+ name.resize( name.size() - 1 );
+ }
+
+ element e;
+ e.s = api_iter->text; // ソースの字面
+ if ( api_iter->symbol[0] != '&' ) // 一般定数式パラメータは値が特定できない
+ {
+ if ( api_iter->symbol[0] == '$' ) // 文字列定数式パラメータ
+ {
+ e.v = api_iter->string; // 展開後の文字列
+ }
+ else
+ {
+ e.i = api_iter->value;
+ }
+ if ( api_iter->symbol[0] == '%' )
+ {
+ continue;
+ }
+ }
+ mproc.set_var( name, id, var_t( 1, e ) );
+ }
+
+ // 静的APIが出現した行番号
+ {
+ element e;
+ e.s = v_iter->line().file;
+ e.i = v_iter->line().line;
+ std::string type( toppers::toupper( info->type ) );
+
+ if ( info->slave )
+ {
+ type = info->api_name;
+ }
+ mproc.set_var( type + ".TEXT_LINE", id, var_t( 1, e ) );
+ }
+ }
+ }
+
+ std::map< std::string, var_t > id_list_map;
+
+ for ( std::map< std::string, var_t >::const_iterator iter( order_list_map.begin() ), last( order_list_map.end() );
+ iter != last;
+ ++iter )
+ {
+ // 出現順リスト $OBJ.ORDER_LIST$ -- ID番号の並び
+ mproc.set_var( toppers::toupper( iter->first + ".order_list" ), iter->second );
+ var_t rorder_list( iter->second );
+
+ // 逆順リスト $OBJ.RORDER_LIST$ -- ID番号の並び
+ std::reverse( rorder_list.begin(), rorder_list.end() );
+ mproc.set_var( toppers::toupper( iter->first + ".rorder_list" ), rorder_list );
+
+ // ID番号リスト $OBJ.ID_LIST$ -- ID番号の並び
+ var_t id_list( iter->second );
+ std::sort( id_list.begin(), id_list.end() );
+ mproc.set_var( toppers::toupper( iter->first + ".id_list" ), id_list );
+ }
+
+ element external_id;
+ external_id.i = get_global< bool >( "external-id" );
+ mproc.set_var( "USE_EXTERNAL_ID", var_t( 1, external_id ) );
+ }
+
+ // カーネルオブジェクト生成・定義用静的APIの各パラメータをマクロプロセッサの変数として設定する。
+ void set_object_vars( std::vector< static_api > const& api_array, macro_processor& mproc )
+ {
+ typedef macro_processor::element element;
+ typedef macro_processor::var_t var_t;
+ long order = 1;
+ var_t order_list;
+
+ for ( std::vector< static_api >::const_iterator v_iter( api_array.begin() ), v_last( api_array.end() );
+ v_iter != v_last;
+ ++v_iter )
+ {
+ static_api::info const* info = v_iter->get_info();
+ var_t params;
+ var_t args;
+
+ // 静的APIが出現した行番号
+ element e;
+ e.s = v_iter->line().file;
+ e.i = v_iter->line().line;
+ mproc.set_var( "API.TEXT_LINE", order, var_t( 1, e ) );
+
+ // 静的API名
+ e.s = info->api_name;
+ e.i = boost::none;
+ mproc.set_var( "API.NAME", order, var_t( 1, e ) );
+
+ // オブジェクトタイプ("TSK", "SEM", ...)
+ e.s = toppers::toupper( info->type );
+ mproc.set_var( "API.TYPE", order, var_t( 1 , e ) );
+
+ // 各パラメータ
+ for ( static_api::const_iterator api_iter( v_iter->begin() ), api_last( v_iter->end() );
+ api_iter != api_last;
+ ++api_iter )
+ {
+ std::string name( toppers::toupper( ( boost::format( "%s.%s" ) % info->type % ( api_iter->symbol.c_str() + 1 ) ).str() ) );
+ // 末尾の ? を除去
+ if ( *name.rbegin() == '\?' )
+ {
+ name.resize( name.size() - 1 );
+ }
+
+ element e;
+ e.s = api_iter->text; // ソースの字面
+ if ( api_iter->symbol[0] != '&' ) // 一般定数式パラメータは値が特定できない
+ {
+ if ( api_iter->symbol[0] == '$' ) // 文字列定数式パラメータ
+ {
+ e.v = api_iter->string; // 展開後の文字列
+ }
+ else
+ {
+ e.i = api_iter->value;
+ }
+ }
+ args.push_back( e );
+
+ e.s = name;
+ e.i = boost::none;
+ params.push_back( e );
+
+ if ( api_iter->symbol[0] == '%' )
+ {
+ continue;
+ }
+ }
+ mproc.set_var( "API.ARGS", order, args );
+ mproc.set_var( "API.PARAMS", order, params );
+ e.s.clear();
+ e.i = order;
+ order_list.push_back( e );
+ ++order;
+ }
+ mproc.set_var( "API.ORDER_LIST", order_list );
+
+ element external_id;
+ external_id.i = get_global< bool >( "external-id" );
+ mproc.set_var( "USE_EXTERNAL_ID", var_t( 1, external_id ) );
+ }
+
+ // クラスIDリストをマクロプロセッサの変数として設定する。
+ void set_clsid_vars( std::vector< std::pair< std::string, long > > const& table, cfg1_out const& cfg1out, macro_processor& mproc )
+ {
+ typedef macro_processor::element element;
+ macro_processor::var_t var;
+
+ bool little_endian = cfg1out.is_little_endian();
+ nm_symbol::entry nm_entry = cfg1out.get_syms()->find( "TOPPERS_cfg_sizeof_signed_t" );
+ std::size_t sizeof_signed_t = static_cast< std::size_t >( cfg1out.get_srec()->get_value( nm_entry.address, 4, little_endian ) );
+
+ for ( std::vector< std::pair< std::string, long > >::const_iterator iter( table.begin() ), last( table.end() );
+ iter != last;
+ ++iter )
+ {
+ if ( !iter->first.empty() )
+ {
+ element e;
+ e.s = iter->first;
+
+ std::string symbol = "TOPPERS_cfg_valueof_" + iter->first;
+ nm_symbol::entry nm_entry = cfg1out.get_syms()->find( symbol );
+ if ( nm_entry.type == -1 )
+ {
+ continue;
+ }
+ const std::size_t size = sizeof_signed_t;
+ std::tr1::intmax_t value = cfg1out.get_srec()->get_value( nm_entry.address, size, little_endian );
+
+ e.i = value;
+
+ var.push_back( e );
+ }
+ }
+ // クラスIDの値でソートしていない
+ mproc.set_var( "CLS.ID_LIST", var );
+ }
+
+ // ドメインIDリストをマクロプロセッサの変数として設定する。
+ void set_domid_vars( std::vector< std::pair< std::string, long > > const& table, macro_processor& mproc )
+ {
+ typedef macro_processor::element element;
+ macro_processor::var_t var;
+
+ for ( std::vector< std::pair< std::string, long > >::const_iterator iter( table.begin() ), last( table.end() );
+ iter != last;
+ ++iter )
+ {
+ if ( !iter->first.empty() )
+ {
+ element e;
+ e.s = iter->first;
+ e.i = iter->second;
+ var.push_back( e );
+ }
+ }
+ mproc.set_var( "DOM.ID_LIST", var );
+ }
+
+ // プラットフォーム・コンパイラ依存の値をマクロプロセッサの変数として設定する。
+ void set_platform_vars( cfg1_out const& cfg1out, macro_processor& mproc )
+ {
+ typedef macro_processor::element element;
+ typedef macro_processor::var_t var_t;
+
+ cfg1_out::cfg1_def_table const* def_table = cfg1out.get_def_table();
+ std::size_t sizeof_signed_t;
+
+ static cfg1_out::cfg1_def_t const limit_defs[] =
+ {
+ { false, "TOPPERS_cfg_CHAR_BIT", "CHAR_BIT" },
+ { false, "TOPPERS_cfg_CHAR_MAX", "CHAR_MAX" },
+ { true, "TOPPERS_cfg_CHAR_MIN", "CHAR_MIN" },
+ { false, "TOPPERS_cfg_SCHAR_MAX", "SCHAR_MAX" }, // 本来は符号付きだが、負になることはない
+ { false, "TOPPERS_cfg_SHRT_MAX", "SHRT_MAX" }, // 本来は符号付きだが、負になることはない
+ { false, "TOPPERS_cfg_INT_MAX", "INT_MAX" }, // 本来は符号付きだが、負になることはない
+ { false, "TOPPERS_cfg_LONG_MAX", "LONG_MAX" }, // 本来は符号付きだが、負になることはない
+ };
+
+ nm_symbol::entry nm_entry = cfg1out.get_syms()->find( "TOPPERS_cfg_sizeof_signed_t" );
+ sizeof_signed_t = static_cast< std::size_t >( cfg1out.get_srec()->get_value( nm_entry.address, 4, cfg1out.is_little_endian() ) );
+
+ for ( std::size_t i = 0; i < sizeof limit_defs / sizeof limit_defs[ 0 ]; ++i )
+ {
+ element e;
+ e.s = limit_defs[ i ].expression;
+ nm_entry = cfg1out.get_syms()->find( limit_defs[ i ].name );
+ std::tr1::int64_t value = cfg1out.get_srec()->get_value( nm_entry.address, sizeof_signed_t, cfg1out.is_little_endian() );
+ if ( sizeof_signed_t < 8 && limit_defs[ i ].is_signed )
+ {
+ value = cfg1_out::make_signed( static_cast< std::tr1::uint32_t >( value ) );
+ }
+ mproc.set_var( e.s, var_t( 1, e ) );
+ }
+
+ for ( cfg1_out::cfg1_def_table::const_iterator iter( def_table->begin() ), last( def_table->end() );
+ iter != last;
+ ++iter )
+ {
+ element e;
+ e.s = iter->expression;
+ nm_entry = cfg1out.get_syms()->find( "TOPPERS_cfg_" + iter->name );
+ if ( nm_entry.type >= 0 )
+ {
+ std::tr1::int64_t value = cfg1out.get_srec()->get_value( nm_entry.address, sizeof_signed_t, cfg1out.is_little_endian() );
+ if ( sizeof_signed_t < 8 && iter->is_signed )
+ {
+ value = cfg1_out::make_signed( static_cast< std::tr1::uint32_t >( value ) );
+ }
+ e.i = value;
+ mproc.set_var( iter->name, var_t( 1, e ) );
+ }
+ }
+
+ // バイトオーダー
+ {
+ bool little_endian = cfg1out.is_little_endian();
+ element e;
+ e.i = little_endian;
+ mproc.set_var( "LITTLE_ENDIAN", var_t( 1, e ) );
+
+ e.i = !little_endian;
+ mproc.set_var( "BIG_ENDIAN", var_t( 1, e ) );
+ }
+ }
+
+ }
+
+ //! コンストラクタ
+ factory::factory( std::string const& kernel )
+ : kernel_( tolower( kernel ) )
+ {
+ }
+
+ //! デストラクタ
+ factory::~factory()
+ {
+ }
+
+ //! サポートしている静的API情報の取得
+ std::map< std::string, static_api::info > const* factory::get_static_api_info_map() const
+ {
+ // CSVから静的API情報を読み取り、登録するためのローカルクラス
+ struct init_t
+ {
+ init_t()
+ {
+ boost::any t = global( "api-table" );
+ if ( !t.empty() )
+ {
+ std::vector< std::string > api_tables( boost::any_cast< std::vector< std::string >& >( t ) );
+ for ( std::vector< std::string >::const_iterator iter( api_tables.begin() ), last( api_tables.end() );
+ iter != last;
+ ++iter )
+ {
+ std::string buf;
+ std::string api_table_filename = *iter;
+ read( api_table_filename.c_str(), buf );
+ csv data( buf.begin(), buf.end() );
+ for ( csv::const_iterator d_iter( data.begin() ), d_last( data.end() );
+ d_iter != d_last;
+ ++d_iter )
+ {
+ csv::size_type len = d_iter->size();
+ if ( len < 3 ) // type, api_name, params は必須要素
+ {
+ toppers::fatal( _( "too little fields in `%1%\'" ), *iter );
+ }
+ static_api::info api_info = { 0 };
+ try
+ {
+ char* s;
+ s = new char[ ( *d_iter )[ 0 ].size() + 1 ];
+ std::strcpy( s, ( *d_iter )[ 0 ].c_str() );
+ api_info.type = s;
+
+ s = new char[ ( *d_iter )[ 1 ].size() + 1 ];
+ std::strcpy( s, ( *d_iter )[ 1 ].c_str() );
+ api_info.api_name = s;
+
+ s = new char[ ( *d_iter )[ 2 ].size() + 1 ];
+ std::strcpy( s, ( *d_iter )[ 2 ].c_str() );
+ api_info.params = s;
+ if ( len >= 4 && !( *d_iter )[ 3 ].empty() )
+ {
+ api_info.id_pos = std::strtol( ( *d_iter )[ 3 ].c_str(), 0, 0 );
+ }
+ if ( len >= 5 && !( *d_iter )[ 4 ].empty() )
+ {
+ api_info.slave = !!std::strtol( ( *d_iter )[ 4 ].c_str(), 0, 0 );
+ }
+ static_api_table_[ api_info.api_name ] = api_info;
+ }
+ catch ( ... )
+ {
+ delete[] api_info.type;
+ delete[] api_info.api_name;
+ delete[] api_info.params;
+ throw;
+ }
+ }
+ }
+ }
+ }
+
+ ~init_t()
+ {
+ for ( std::map< std::string, static_api::info >::const_iterator iter( static_api_table_.begin() ), last( static_api_table_.end() );
+ iter != last;
+ ++iter )
+ {
+ delete[] iter->second.type;
+ delete[] iter->second.api_name;
+ delete[] iter->second.params;
+ }
+ }
+
+ std::map< std::string, static_api::info > static_api_table_;
+ };
+ static init_t init;
+ std::map< std::string, static_api::info > const* result = &init.static_api_table_;
+ return result;
+ }
+
+ /*!
+ * \brief cfg1_out.c への出力情報テーブルの生成
+ * \return 生成した cfg1_out::cfg1_def_table オブジェクトへのポインタ
+ * \note この関数が返すポインタは delete してはならない
+ *
+ * --cfg1-def-table オプションで指定したファイルから、cfg1_out.c へ出力する情報を読み取り、
+ * cfg1_out::cfg1_def_table オブジェクトを生成する。
+ *
+ * CSV の形式は以下の通り
+ *
+ * シンボル名,式[,s|signed]
+ *
+ * 末尾の s または signed は省略可能。省略時は符号無し整数とみなす。s または signed 指定時は
+ * 符号付き整数とみなす。\n
+ * 「式」の最初に # があれば前処理式とみなす。
+ */
+ cfg1_out::cfg1_def_table const* factory::get_cfg1_def_table() const
+ {
+ struct init_t
+ {
+ init_t()
+ {
+ boost::any t = global( "cfg1-def-table" );
+ if ( !t.empty() )
+ {
+ std::vector< std::string > cfg1_def_table = boost::any_cast< std::vector< std::string >& >( t );
+ for ( std::vector< std::string >::const_iterator iter( cfg1_def_table.begin() ), last( cfg1_def_table.end() );
+ iter != last;
+ ++iter )
+ {
+ std::string buf;
+ read( iter->c_str(), buf );
+ csv data( buf.begin(), buf.end() );
+ for ( csv::const_iterator d_iter( data.begin() ), d_last( data.end() );
+ d_iter != d_last;
+ ++d_iter )
+ {
+ csv::size_type len = d_iter->size();
+ if ( len < 2 )
+ {
+ toppers::fatal( _( "too little fields in `%1%\'" ), *iter );
+ }
+ cfg1_out::cfg1_def_t def = { 0 };
+ def.name = ( *d_iter )[ 0 ];
+ def.expression = ( *d_iter )[ 1 ];
+ if ( len >= 3 )
+ {
+ std::string is_signed( ( *d_iter )[ 2 ] );
+ def.is_signed = ( is_signed == "s" || is_signed == "signed" );
+ }
+ if ( len >= 4)
+ {
+ def.value1 = ( *d_iter )[ 3 ];
+ }
+ if ( len >= 5)
+ {
+ def.value2 = ( *d_iter )[ 4 ];
+ }
+ cfg1_def_table_.push_back( def );
+ }
+ }
+ }
+ }
+ cfg1_out::cfg1_def_table cfg1_def_table_;
+ };
+ static init_t init;
+ cfg1_out::cfg1_def_table const* result = &init.cfg1_def_table_;
+ return result;
+ }
+
+ //! オブジェクトの交換
+ void factory::do_swap( factory& other )
+ {
+ kernel_.swap( other.kernel_ );
+ }
+
+ /*!
+ * \brief マクロプロセッサの生成
+ * \param[in] cfg1out cfg1_out オブジェクト
+ * \param[in] api_map .cfg ファイルに記述された静的API情報
+ * \return マクロプロセッサへのポインタ
+ * \note このメンバ関数は従来仕様(ソフトウェア部品非対応版)の温存のためにそのまま残す。
+ */
+ std::auto_ptr< macro_processor > factory::do_create_macro_processor( cfg1_out const& cfg1out, cfg1_out::static_api_map const& api_map ) const
+ {
+ typedef macro_processor::element element;
+ typedef macro_processor::var_t var_t;
+ std::auto_ptr< macro_processor > mproc( new macro_processor );
+ element e;
+
+ e.s = " "; mproc->set_var( "SPC", var_t( 1, e ) ); // $SPC$
+ e.s = "\t"; mproc->set_var( "TAB", var_t( 1, e ) ); // $TAB$
+ e.s = "\n"; mproc->set_var( "NL", var_t( 1, e ) ); // $NL$
+
+ // バージョン情報
+ e.s = toppers::get_global< std::string >( "version" );
+ e.i = toppers::get_global< std::tr1::int64_t >( "timestamp" );
+ mproc->set_var( "CFG_VERSION", var_t( 1, e ) ); // $CFG_VERSION$
+
+ // その他の組み込み変数の設定
+ set_object_vars( api_map, *mproc );
+ set_clsid_vars( cfg1out.get_clsid_table(), cfg1out, *mproc );
+ set_domid_vars( cfg1out.get_domid_table(), *mproc );
+ set_platform_vars( cfg1out, *mproc );
+ e.s = cfg1out.get_includes();
+ mproc->set_var( "INCLUDES", var_t( 1, e ) );
+ return mproc;
+ }
+
+ /*!
+ * \brief マクロプロセッサの生成
+ * \param[in] cfg1out cfg1_out オブジェクト
+ * \param[in] api_array .cfg ファイルに記述された静的API情報
+ * \return マクロプロセッサへのポインタ
+ */
+ std::auto_ptr< macro_processor > factory::do_create_macro_processor( cfg1_out const& cfg1out, std::vector< static_api > const& api_array ) const
+ {
+ typedef macro_processor::element element;
+ typedef macro_processor::var_t var_t;
+ std::auto_ptr< macro_processor > mproc( new macro_processor );
+ element e;
+
+ e.s = " "; mproc->set_var( "SPC", var_t( 1, e ) ); // $SPC$
+ e.s = "\t"; mproc->set_var( "TAB", var_t( 1, e ) ); // $TAB$
+ e.s = "\n"; mproc->set_var( "NL", var_t( 1, e ) ); // $NL$
+
+ // バージョン情報
+ e.s = toppers::get_global< std::string >( "version" );
+ e.i = toppers::get_global< std::tr1::int64_t >( "timestamp" );
+ mproc->set_var( "CFG_VERSION", var_t( 1, e ) ); // $CFG_VERSION$
+
+ // その他の組み込み変数の設定
+ set_object_vars( api_array, *mproc );
+ set_clsid_vars( cfg1out.get_clsid_table(), cfg1out, *mproc );
+ set_domid_vars( cfg1out.get_domid_table(), *mproc );
+ set_platform_vars( cfg1out, *mproc );
+ e.s = cfg1out.get_includes();
+ mproc->set_var( "INCLUDES", var_t( 1, e ) );
+ return mproc;
+ }
+
+ std::auto_ptr< cfg1_out > factory::do_create_cfg1_out( std::string const& filename ) const
+ {
+ return std::auto_ptr< itronx::cfg1_out >( new cfg1_out( filename, get_cfg1_def_table() ) );
+ }
+
+ std::auto_ptr< checker > factory::do_create_checker() const
+ {
+ return std::auto_ptr< itronx::checker >( new checker );
+ }
+
+ }
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/*!
+ * \file toppers/itronx/factory.hpp
+ * \brief カーネルまたはモジュールに応じた処理オブジェクト生成に関する宣言定義
+ *
+ * このファイルで定義されるクラス
+ * \code
+ * class factory;
+ * \endcode
+ */
+#ifndef TOPPERS_ITRONX_FACTORY_HPP_
+#define TOPPERS_ITRONX_FACTORY_HPP_
+
+#include <memory>
+#include <string>
+#include <vector>
+#include "toppers/macro_processor.hpp"
+#include "toppers/itronx/static_api.hpp"
+#include "toppers/itronx/cfg1_out.hpp"
+#include "toppers/itronx/checker.hpp"
+
+namespace toppers
+{
+
+ namespace itronx
+ {
+
+ /*!
+ * \class factory factory.hpp "toppers/itronx/factory.hpp"
+ * \brief カーネルまたはモジュールに応じた処理オブジェクト生成クラス
+ */
+ class factory
+ {
+ public:
+ explicit factory( std::string const& kernel );
+ virtual ~factory();
+ std::map< std::string, static_api::info > const* get_static_api_info_map() const;
+ cfg1_out::cfg1_def_table const* get_cfg1_def_table() const;
+ std::auto_ptr< cfg1_out > create_cfg1_out( std::string const& filename ) const
+ {
+ return do_create_cfg1_out( filename );
+ }
+ std::auto_ptr< checker > create_checker() const
+ {
+ return do_create_checker();
+ }
+ std::auto_ptr< macro_processor > create_macro_processor( cfg1_out const& cfg1out, cfg1_out::static_api_map const& api_map ) const
+ {
+ return do_create_macro_processor( cfg1out, api_map );
+ }
+ std::auto_ptr< macro_processor > create_macro_processor( cfg1_out const& cfg1out, std::vector< static_api > const& api_array ) const
+ {
+ return do_create_macro_processor( cfg1out, api_array );
+ }
+ void swap( factory& other ) { do_swap( other ); }
+ protected:
+ virtual void do_swap( factory& other );
+ virtual std::auto_ptr< macro_processor > do_create_macro_processor( cfg1_out const& cfg1out, cfg1_out::static_api_map const& api_map ) const;
+ virtual std::auto_ptr< macro_processor > do_create_macro_processor( cfg1_out const& cfg1out, std::vector< static_api > const& api_array ) const;
+ private:
+ virtual std::auto_ptr< cfg1_out > do_create_cfg1_out( std::string const& filename ) const;
+ virtual std::auto_ptr< checker > do_create_checker() const;
+
+ std::string kernel_;
+ };
+
+ }
+}
+
+#endif // ! TOPPERS_ITRONX_FACTORY_HPP_
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/*!
+ * \file toppers/itronx/init_helper.hpp
+ * \brief カーネルまたはモジュールの初期化処理ヘルパー関数の宣言・定義
+ */
+#ifndef TOPPERS_ITRONX_INIT_HELPER_HPP_
+#define TOPPERS_ITRONX_INIT_HELPER_HPP_
+
+#include <string>
+#include <map>
+#include <iostream>
+#include "toppers/global.hpp"
+#include "toppers/itronx/static_api.hpp"
+#include "toppers/itronx/asp/factory.hpp"
+
+namespace toppers
+{
+ namespace itronx
+ {
+
+ /*!
+ * \brief カーネルまたはモジュールの初期化処理ヘルパー関数
+ * \param[in] module_name モジュール名
+ * \param[in] info_table 静的APIに関する情報テーブル
+ * \param[in] table_count info_table の要素数
+ * retval true 初期化成功
+ * retval false 初期化失敗
+ */
+ template < class Factory >
+ bool init_helper( std::string const& module_name, static_api::info const* info_table, std::size_t table_count )
+ {
+ try
+ {
+ std::map< std::string, static_api::info > temp_map;
+ for ( std::size_t i = 0; ( i < table_count ) && ( info_table[ i ].type != 0 ); ++i )
+ {
+ temp_map[ info_table[ i ].api_name ] = info_table[ i ];
+ }
+ static std::map< std::string, static_api::info > const info_map( temp_map );
+ global( module_name + "_static_api_info_map" ) = static_cast< void const* >( &info_map ); // GCCバグ対策
+
+ static Factory factory;
+ global( module_name + "_factory" ) = static_cast< itronx::factory* >( &factory );
+ }
+ catch ( ... )
+ {
+ std::cerr << "module `" << module_name << "\' is failed to initialize" << std::endl;
+ return false;
+ }
+ return true;
+ }
+
+ }
+}
+
+#endif // ! TOPPERS_ITRONX_INIT_HELPER_HPP_
--- /dev/null
+<?xml version="1.0" encoding="shift_jis"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="itronx"
+ ProjectGUID="{994810C2-F530-4679-9DF8-AF39A3AC61C9}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="4"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../.."
+ PreprocessorDefinitions="_SCL_SECURE_NO_WARNINGS=1"
+ StringPooling="TRUE"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ SmallerTypeCheck="TRUE"
+ RuntimeLibrary="1"
+ BufferSecurityCheck="TRUE"
+ EnableFunctionLevelLinking="TRUE"
+ TreatWChar_tAsBuiltInType="TRUE"
+ ForceConformanceInForLoopScope="TRUE"
+ RuntimeTypeInfo="TRUE"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/itronx.lib"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="4"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="0"
+ EnableIntrinsicFunctions="TRUE"
+ ImproveFloatingPointConsistency="FALSE"
+ FavorSizeOrSpeed="2"
+ AdditionalIncludeDirectories="../.."
+ PreprocessorDefinitions="_SCL_SECURE_NO_WARNINGS=1"
+ StringPooling="TRUE"
+ RuntimeLibrary="0"
+ TreatWChar_tAsBuiltInType="TRUE"
+ ForceConformanceInForLoopScope="TRUE"
+ RuntimeTypeInfo="TRUE"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/itronx.lib"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="ソース ファイル"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath=".\cfg1_out.cpp">
+ </File>
+ <File
+ RelativePath=".\checker.cpp">
+ </File>
+ <File
+ RelativePath=".\component.cpp">
+ </File>
+ <File
+ RelativePath=".\factory.cpp">
+ </File>
+ <File
+ RelativePath=".\preprocess.cpp">
+ </File>
+ <File
+ RelativePath=".\static_api.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="ヘッダー ファイル"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath=".\cfg1_out.hpp">
+ </File>
+ <File
+ RelativePath=".\checker.hpp">
+ </File>
+ <File
+ RelativePath=".\component.hpp">
+ </File>
+ <File
+ RelativePath=".\factory.hpp">
+ </File>
+ <File
+ RelativePath=".\init_helper.hpp">
+ </File>
+ <File
+ RelativePath=".\preprocess.hpp">
+ </File>
+ <File
+ RelativePath=".\static_api.hpp">
+ </File>
+ <File
+ RelativePath=".\static_api_parser.hpp">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+#undef BEGIN_KERNEL_CHK
+#undef END_KERNEL_CHK
+#undef KERNEL_CHK_SIZEOF
+#undef KERNEL_CHK_OFFSETOF
+#undef KERNEL_CHK_VALUEOF
+
+#ifdef IMPLEMENT_KERNEL_CHK
+
+#define BEGIN_KERNEL_CHK ofile_ << "\t0x12345678,\n\tTKERNEL_PRID,\n" \
+ "\tCHAR_BIT,\n" \
+ "\tCHAR_MAX,\n" \
+ "\tSCHAR_MAX,\n" \
+ "\tSHRT_MAX,\n" \
+ "\tINT_MAX,\n" \
+ "\tLONG_MAX,\n"
+#define END_KERNEL_CHK ;
+#define KERNEL_CHK_SIZEOF( sym ) KERNEL_CHK_SIZEOF_( sym )
+#define KERNEL_CHK_SIZEOF_( sym ) "\tsizeof(" #sym "),\n"
+#define KERNEL_CHK_OFFSETOF( type, member ) "\toffsetof(" #type ", " #member "),\n"
+#define KERNEL_CHK_VALUEOF( expr ) "\t" #expr ",\n"
+
+#else
+
+#define BEGIN_KERNEL_CHK enum { magic_number, TKERNEL_PRID, \
+ valueof_CHAR_BIT, \
+ valueof_CHAR_MAX, \
+ valueof_SCHAR_MAX, \
+ valueof_SHRT_MAX, \
+ valueof_INT_MAX, \
+ valueof_LONG_MAX,
+#define END_KERNEL_CHK kernel_chk_table_size };
+#define KERNEL_CHK_SIZEOF( sym ) sizeof_##sym,
+#define KERNEL_CHK_OFFSETOF( type, member ) offsetof_##type##_##member,
+#define KERNEL_CHK_VALUEOF( expr ) valueof_##expr,
+
+#endif
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+#include <cstring>
+#include <algorithm>
+#include <iostream>
+#include <iterator>
+#include "toppers/io.hpp"
+#include "toppers/cpp.hpp"
+#include "toppers/global.hpp"
+#include "toppers/diagnostics.hpp"
+#include "toppers/itronx/preprocess.hpp"
+#include <boost/spirit/include/classic.hpp>
+
+namespace toppers
+{
+ namespace itronx
+ {
+
+ /*!
+ * \brief 静的API `INCLUDE'の展開
+ * \param[in] in 入力ファイルの内容
+ * \param[out] out 出力ファイルの内容
+ * \param[in] codeset 文字コード
+ * \param[out] dependencies 依存関係の格納先(NULLの場合は格納しない)
+ * \param[out] onces #pragma onceが記述されていたファイル名の格納先(NULLの場合は格納しない)
+ *
+ * `INCLUDE' の引数は、μITRON 仕様のものとは異なり、二重引用符で囲まずに #include 指令と
+ * 同じ形式を用いる。
+ */
+ void expand_include( text const& in, text& out, codeset_t codeset, std::set< std::string >* dependencies, std::set< std::string >* onces )
+ {
+ typedef text::container::const_iterator const_row_iterator;
+ typedef std::string::size_type size_type;
+ size_type const npos = std::string::npos;
+ const_row_iterator first( in.begin().get_row() ), last( in.end().get_row() );
+
+ out.set_line( first->line.file, first->line.line );
+ for ( const_row_iterator iter( first ); iter != last; ++iter )
+ {
+ std::string const& buf = iter->buf;
+ char state = 0;
+
+ for ( size_type i = 0, n = buf.size(); i != n; ++i )
+ {
+ char c = buf[i];
+ if ( c == '\'' || c == '\"' )
+ {
+ if ( state == 0 )
+ {
+ state = c; // 文字(列)リテラル開始
+ }
+ else if ( buf[i - 1] != '\\' ) // \' または \" ではない
+ {
+ state = 0; // 文字(列)リテラル終了
+ }
+ else if ( ( codeset == shift_jis ) && ( i >= 2 ) && is_lead< shift_jis >( buf[i - 2] ) )
+ {
+ state = 0;
+ }
+ out.push_back( c );
+ }
+ else if ( state != 0 ) // 文字(列)リテラル内
+ {
+ out.push_back( c );
+ }
+ else
+ {
+ using namespace boost::spirit::classic;
+ std::string headername;
+ if ( iter == last )
+ {
+ return;
+ }
+ text::const_iterator iter2( iter, i );
+ if ( iter2 == in.end() )
+ {
+ break;
+ }
+ parse_info< text::const_iterator > info
+ = parse( iter2, in.end(),
+ ( str_p( "INCLUDE" ) >> *space_p
+ >> '(' >> *space_p
+ >> '\"' >> ( +( anychar_p - '\"' ) )[ assign( headername ) ] >> '\"' >> *space_p
+ >> ')' >> *space_p >> ';' ) ); // 行番号がずれるので、スキップパーサは使用しない
+ if ( info.hit )
+ {
+ std::vector< std::string > include_paths = get_global< std::vector< std::string > >( "include-path" );
+ std::string hname = search_include_file( include_paths.begin(), include_paths.end(), headername );
+ if ( hname.empty() ) // ヘッダ名が見つからない
+ {
+ fatal( iter->line, _( "cannot open file `%1%\'" ), headername );
+ }
+ else if ( onces == 0 || onces->find( hname ) == onces->end() )
+ {
+ if ( dependencies != 0 )
+ {
+ dependencies->insert( hname );
+ }
+ out.push_back( ' ' ); // ダミーを挿入しておかないと行番号がずれる
+ preprocess( hname, out, codeset, dependencies, onces ); // ヘッダ名で指定されたファイルに対して前処理を再帰的に行う
+ iter = info.stop.get_row();
+ i = info.stop.get_col() - 1;
+ if ( iter != last )
+ {
+ out.set_line( iter->line.file, iter->line.line );
+ }
+ }
+ }
+ else
+ {
+ if ( iter2.get_col() == 0 )
+ {
+ info = parse( iter2, in.end(),
+ ( *( space_p - eol_p ) >>
+ ch_p( '#' ) >> *( space_p - eol_p ) >> "pragma" >> *( space_p - eol_p )
+ >> "once"
+ >> *( space_p - eol_p ) >> eol_p ) );
+ if ( info.hit )
+ {
+ if ( onces != 0 )
+ {
+ onces->insert( iter2.line().file );
+ }
+ out.push_back( '\n' );
+ iter = info.stop.get_row();
+ if ( iter != last )
+ {
+// out.set_line( iter->line.file, iter->line.line );
+ }
+ --iter; // インクリメントされるのでいったん戻す。
+ break;
+ }
+ }
+ if ( parse( iter2, in.end(),
+ ( str_p( "INCLUDE" ) >> *space_p >> '(' >> +( anychar_p - ')' ) >> ')' >> *space_p >> ';' ) ).hit )
+ {
+ warning( iter->line, _( "probably, %1% argument of `%2%\' is illegal" ), _( "1st" ), "INCLUDE" );
+ }
+ out.push_back( c );
+ }
+ }
+ }
+ }
+ }
+
+ /*!
+ * \brief コンフィギュレーションファイルの前処理
+ * \param[in] file コンフィギュレーションファイル名
+ * \param[out] result 前処理後の内容
+ * \param[in] codeset 文字コード
+ * \param[out] dependencies 依存関係の格納先(NULLの場合は格納しない)
+ * \param[out] onces #pragma onceが記述されていたファイル名の格納先(NULLの場合は格納しない)
+ */
+ void preprocess( std::string const& file, text& result, codeset_t codeset, std::set< std::string >* dependencies, std::set< std::string >* onces )
+ {
+ std::string buf;
+ read( file, buf );
+ if ( buf.empty() )
+ {
+ return;
+ }
+ text txt;
+ txt.set_line( file, 1 );
+ remove_comment( buf.begin(), buf.end(), std::back_inserter( txt ), codeset );
+ expand_include( txt, result, codeset, dependencies, onces );
+ }
+
+ }
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/*!
+ * \file toppers/itronx/preprocess.hpp
+ * \brief システムコンフィギュレーションファイルの前処理に関する宣言定義
+ */
+#ifndef TOPPERS_ITRONX_PREPROCESSOR_HPP_
+#define TOPPERS_ITRONX_PREPROCESSOR_HPP_
+
+#include <string>
+#include <set>
+#include "toppers/text.hpp"
+#include "toppers/cpp.hpp"
+
+namespace toppers
+{
+ namespace itronx
+ {
+
+ void expand_include( text const& in, text& out, codeset_t codeset = ascii, std::set< std::string >* dependencies = 0, std::set< std::string >* onces = 0 );
+ void preprocess( std::string const& file, text& result, codeset_t codeset = ascii, std::set< std::string >* dependencies = 0, std::set< std::string >* onces = 0 );
+
+ }
+}
+
+#endif // ! TOPPERS_ITRONX_PREPROCESSOR_HPP_
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+#include <cctype>
+#include <sstream>
+#include "toppers/diagnostics.hpp"
+#include "toppers/itronx/static_api.hpp"
+#include "toppers/itronx/static_api_parser.hpp"
+#include <boost/spirit/include/classic.hpp>
+#include <boost/lexical_cast.hpp>
+
+namespace toppers
+{
+ namespace itronx
+ {
+ namespace
+ {
+ class find_api_predicate
+ {
+ public:
+ explicit find_api_predicate( std::string const& api_name ) : api_name_( api_name ) {}
+ bool operator()( static_api::info const& info ) const
+ {
+ return info.api_name == api_name_;
+ }
+ private:
+ std::string api_name_;
+ };
+ }
+
+ /*!
+ * \brief 静的APIの構文解析
+ * \param[in,out] next テキストの読み込み位置、兼構文解析後の次の読み込み位置の格納先
+ * \param[in] last テキストの終端位置
+ * \param[in] info_map 静的API情報マップ
+ * \param[in] ucn 国際文字名を有効にする場合は true を指定する。
+ * \param[in] codeset 文字コード
+ * \retval true 成功
+ * \retval false 失敗
+ */
+ bool static_api::parse( text::const_iterator& next, text::const_iterator last,
+ std::map< std::string, info > const& info_map,
+ bool ucn, codeset_t codeset )
+ {
+ boost::spirit::classic::parse_info< text::const_iterator > pi;
+ std::vector< std::string > tokens;
+ c_const_expr_parser cexpr_p( ucn, codeset );
+ static_api_parser parser( tokens, cexpr_p );
+ static_api temp;
+
+ text::const_iterator next_temp;
+ for ( next_temp = next; next_temp != last; ++next_temp )
+ {
+ if ( !std::isspace( static_cast< unsigned char >( *next_temp ) ) )
+ {
+ break;
+ }
+ }
+ if ( next_temp == last )
+ {
+ return false;
+ }
+
+ // エラーメッセージ用の行番号
+ // この行番号は、静的APIの開始位置のものであるため、エラー発生箇所そのものズバリを指すことはできない。
+ temp.line_ = next_temp.line();
+
+ pi = boost::spirit::classic::parse( next_temp, last, parser, boost::spirit::classic::space_p );
+ if ( !pi.hit )
+ {
+ return false;
+ }
+
+ // 静的APIが存在するかどうかの判定およびシグニチャの取得
+ std::string api_name( tokens.front() );
+ std::map< std::string, info >::const_iterator info_iter = info_map.find( api_name );
+ info const* pinfo = 0;
+ if ( info_iter != info_map.end() )
+ {
+ pinfo = &info_iter->second;
+ temp.pinfo_ = pinfo;
+ }
+ else
+ {
+ error( temp.line_, _( "static API `%1%\' is unknown" ), api_name );
+ return false;
+ }
+
+ // 各パラメータの解析
+ std::istringstream iss( pinfo->params );
+ int order = 0; // パラメータリスト内の順序
+ bool param_list = false; // パラメータリスト解析中フラグ
+ std::string symbol;
+ bool skip = false;
+
+ for ( std::vector< std::string >::const_iterator iter( tokens.begin() + 1 ), last( tokens.end() );
+ iter != last;
+ ++iter )
+ {
+ if ( !param_list )
+ {
+ iss >> symbol;
+ if ( symbol.size() > 3 && symbol.substr( symbol.size() - 3 ) == "..." )
+ {
+ param_list = true;
+ order = 0;
+ symbol.resize( symbol.size() - 3 );
+ }
+ }
+ if ( symbol == "{" || symbol == "}" )
+ {
+ if ( symbol != *iter )
+ {
+ error( temp.line_, _( "missing token `%1%\'" ), symbol );
+ --iter;
+ }
+ }
+ else if ( *iter == "{" || *iter == "}" )
+ {
+ if ( param_list && *iter == "}" )
+ {
+ iss >> symbol;
+ if ( symbol != "}" )
+ {
+ error( temp.line_, _( "illegal token `%1%\'" ), *iter );
+ }
+ param_list = false;
+ }
+ else if ( *symbol.rbegin() == '\?' ) // 省略可能パラメータのスキップ
+ {
+ skip = true;
+ }
+ else
+ {
+ error( temp.line_, _( "illegal token `%1%\'" ), *iter );
+ }
+ }
+ else
+ {
+ parameter value;
+ value.symbol = symbol;
+ if ( param_list )
+ {
+ value.symbol += boost::lexical_cast< std::string >( order++ );
+ }
+ value.text = *iter;
+ value.value = 0;
+ temp.params_.push_back( value );
+ }
+ }
+ if ( !iss.eof() )
+ {
+ iss >> symbol;
+ if ( symbol != "}" )
+ {
+ error( temp.line_, _( "few parameters for static API `%s\'" ), api_name );
+ }
+ else if ( !skip )
+ {
+ error( temp.line_, _( "missing token `%1%\'" ), symbol );
+ }
+ else
+ {
+ skip = false;
+ }
+ }
+ next = pi.stop;
+ swap( temp );
+ return true;
+ }
+
+ bool static_api::set_block( char const* type, std::string const& id )
+ {
+ for ( std::vector< parameter >::const_iterator iter( params_.begin() ), last( params_.end() );
+ iter != last;
+ ++iter )
+ {
+ if ( iter->symbol == type )
+ {
+ return false;
+ }
+ }
+ parameter value;
+ value.symbol = type;
+ value.text = id;
+ value.value = 0;
+ params_.push_back( value );
+ return true;
+ }
+
+ static_api::size_type static_api::count_integer_params() const
+ {
+ size_type result = 0;
+ for ( std::vector< parameter >::const_iterator iter( params_.begin() ), last( params_.end() );
+ iter != last;
+ ++iter )
+ {
+ if ( !iter->symbol.empty()
+ && ( ( iter->symbol[0] == '.' ) || ( iter->symbol[0] == '+' ) ) )
+ {
+ ++result;
+ }
+ }
+ return result;
+ }
+
+ }
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/*!
+ * \file toppers/itronx/static_api.hpp
+ * \brief 静的API情報の解析と管理に関する宣言定義
+ *
+ * このファイルで定義されるクラス
+ * \code
+ * class static_api;
+ * \endcode
+ */
+#ifndef TOPPERS_ITRONX_STATIC_API_HPP_
+#define TOPPERS_ITRONX_STATIC_API_HPP_
+
+#include <string>
+#include <map>
+#include <set>
+#include <algorithm>
+#include "toppers/workaround.hpp"
+#include "toppers/text.hpp"
+#include "toppers/codeset.hpp"
+#include "toppers/diagnostics.hpp"
+#include <boost/any.hpp>
+#include <boost/optional.hpp>
+
+namespace toppers
+{
+ namespace itronx
+ {
+
+ /*!
+ * \class static_api static_api.hpp "toppers/itronx/static_api.hpp"
+ * \brief コンフィギュレーションファイルに記述された静的APIの情報を管理するためのクラス
+ */
+ class static_api
+ {
+ public:
+ /*!
+ * \struct info static_api.hpp "toppers/itronx/static_api.hpp"
+ * \brief 静的APIの仕様に関する情報
+ *
+ * static_api::info の params メンバ内の各要素に付けられた接頭辞の意味は次のとおり
+ *
+ * - #: オブジェクト識別子
+ * - %: オブジェクト識別子で、かつ自動割付けの対象とならないもの
+ * - .: 符号無し整数定数式パラメータ
+ * - +: 符号付き整数定数式パラメータ
+ * - $: 文字列定数式パラメータ
+ * - &: 一般定数式パラメータ
+ *
+ * なお、{ および } も便宜的にパラメータの一種として扱っている(構文解析に必要なため)。
+ */
+ struct info
+ {
+ char const* type; //!< カーネルオブジェクトの種別を表す三文字("tsk", "sem"等)
+ char const* api_name; //!< 静的API名("CRE_TSK", "CRE_SEM"等)
+ char const* params; //!< パラメータ並び
+ int id_pos; //!< パラメータのうちID番号の位置(-1の場合はID番号無し)
+ bool slave; //!< 他の静的APIに対して従属関係にある場合にtrue("DEF_TEX"等)
+ };
+ /*!
+ * \struct parameter static_api.hpp "toppers/itronx/static_api.hpp"
+ * \brief 静的APIのパラメータに関する情報
+ */
+ struct parameter
+ {
+ std::string symbol; //!< 仮引数名
+ std::string text; //!< 実引数の字面
+ boost::optional< std::tr1::intmax_t > value; //!< 実引数の値
+ std::string string;
+ };
+ typedef std::vector< parameter > parameter_container;
+ typedef parameter_container::iterator iterator;
+ typedef parameter_container::const_iterator const_iterator;
+ typedef parameter_container::reference reference;
+ typedef parameter_container::const_reference const_reference;
+ typedef parameter_container::size_type size_type;
+
+ char const* api_name() const { return pinfo_ != 0 ? pinfo_->api_name : ""; }
+ info const* get_info() const { return pinfo_; }
+
+ parameter_container const& params() const { return params_; }
+ iterator begin() { return params_.begin(); }
+ const_iterator begin() const { return params_.begin(); }
+ iterator end() { return params_.end(); }
+ const_iterator end() const { return params_.end(); }
+ reference at( size_type pos ) { return params_.at( pos ); }
+ reference at( std::string const& symbol )
+ {
+ iterator iter = std::find_if( params_.begin(), params_.end(), match_param_symbol( symbol ) );
+ if ( iter == params_.end() )
+ {
+ throw std::out_of_range( "out of range" );
+ }
+ return *iter;
+ }
+ const_reference at( size_type pos ) const { return params_.at( pos ); }
+ const_reference at( std::string const& symbol ) const
+ {
+ const_iterator iter = std::find_if( params_.begin(), params_.end(), match_param_symbol( symbol ) );
+ if ( iter == params_.end() )
+ {
+ throw std::out_of_range( "out of range" );
+ }
+ return *iter;
+ }
+ parameter id() const
+ {
+ if ( pinfo_->id_pos < 0 )
+ {
+ return parameter();
+ }
+ return at( pinfo_->id_pos );
+ }
+
+ text_line const& line() const { return line_; }
+ void line( text_line const& value ) { line_ = value; }
+ size_type count_integer_params() const;
+
+ //! オブジェクトの交換
+ void swap( static_api& other )
+ {
+ std::swap( pinfo_, other.pinfo_ );
+ params_.swap( other.params_ );
+ line_.swap( other.line_ );
+ }
+
+ bool parse( text::const_iterator& next, text::const_iterator last,
+ std::map< std::string, info > const& info_map,
+ bool ucn = false, codeset_t codeset = ascii );
+
+ bool set_class( std::string const& id )
+ {
+ return set_block( "*CLASS", id );
+ }
+ bool set_domain( std::string const& id )
+ {
+ return set_block( "*DOMAIN", id );
+ }
+
+ /*!
+ * \brief ID番号の割付け
+ * \param[in] first ID番号を割り付ける static_api 列の先頭位置
+ * \param[in] last ID番号を割り付ける static_api 列の終端 + 1
+ */
+ template < class ForwardIterator >
+ static void assign_id( ForwardIterator first, ForwardIterator last )
+ {
+ std::map< std::string, long > id_map;
+ std::map< std::string, std::set< std::string > > slave_id_set;
+ std::vector< std::string > id_res;
+ typedef std::vector< std::string >::size_type size_type;
+
+ // 予約済みのID番号を洗い出す
+ for ( ForwardIterator iter( first ); iter != last; ++iter )
+ {
+ static_api::info const* info = iter->get_info();
+ if ( info->id_pos >= 0 )
+ {
+ if ( !info->slave )
+ {
+ if ( iter->at( info->id_pos ).symbol[0] == '#' )
+ {
+ boost::optional< std::tr1::int64_t > id_value = *iter->at( info->id_pos ).value;
+ if ( id_value )
+ {
+ long id = static_cast< long >( *id_value );
+ if ( id > 0 )
+ {
+ long n = static_cast< long >( id_res.size() );
+ if ( n < id + 1 )
+ {
+ n = id + 1;
+ }
+ id_res.resize( n );
+ std::string name( iter->at( info->id_pos ).text );
+ if ( !id_res[ id ].empty() )
+ {
+ fatal( _( "%1% `%2%\' in %3% is duplicated" ), iter->at( info->id_pos ).symbol.c_str() + 1, id, info->api_name );
+ }
+ id_res[ id ] = name;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // 予約されていないID番号を自動割付け
+ long id = 1;
+ for ( ForwardIterator iter( first ); iter != last; ++iter )
+ {
+ static_api::info const* info = iter->get_info();
+ if ( info->id_pos >= 0 )
+ {
+ std::string name( iter->at( info->id_pos ).text );
+ if ( !info->slave )
+ {
+ long id_value = -1;
+ if ( iter->at( info->id_pos ).symbol[0] == '#' )
+ {
+ std::vector< std::string >::iterator id_iter( std::find( id_res.begin(), id_res.end(), name ) );
+ if ( id_iter != id_res.end() ) // 割り付け済みの場合...
+ {
+ id_value = id_iter - id_res.begin();
+ }
+ else // まだ割り付けられていない場合...
+ {
+ long n = static_cast< long >( id_res.size() );
+ while ( id < n && !id_res[ id ].empty() )
+ {
+ ++id;
+ }
+ if ( n < id + 1 )
+ {
+ n = id + 1;
+ }
+ id_res.resize( n );
+ id_res[ id ] = name;
+ id_value = id;
+ iter->at( info->id_pos ).value = id_value;
+ }
+ if ( id_map.find( name ) != id_map.end() )
+ {
+ fatal( iter->line(), _( "E_OBJ: `%1%\' is duplicated" ), name );
+ }
+ }
+ else if ( iter->at( info->id_pos ).value )
+ {
+ id_value = static_cast< long >( iter->at( info->id_pos ).value.get() );
+ }
+ id_map[ name ] = id_value;
+ }
+ else // slave
+ {
+ if ( id_map[ name ] < 1 )
+ {
+ fatal( iter->line(), _( "`%1%\' is undefined" ), iter->at( info->id_pos ).text );
+ }
+ std::set< std::string >& set = slave_id_set[ info->api_name ];
+ if ( set.find( name ) != set.end() ) // DEF_TEX重複定義の判定
+ {
+ fatal( iter->line(), _( "E_OBJ: `%1%\' is duplicated" ), iter->at( info->id_pos ).text );
+ }
+ set.insert( name );
+ }
+ }
+ }
+
+ if ( !id_res.empty() && std::find( id_res.begin() + 1, id_res.end(), std::string() ) != id_res.end() )
+ {
+ error( _( "`%1%\' id numbers do not continue" ), first->get_info()->type );
+ }
+ }
+ private:
+ class match_param_symbol
+ {
+ public:
+ explicit match_param_symbol( std::string const& symbol ) : symbol_( symbol ) {}
+ bool operator()( parameter const& param ) const
+ {
+ return param.symbol == symbol_;
+ }
+ private:
+ std::string symbol_;
+ };
+
+ bool set_block( char const* type, std::string const& id );
+
+ info const* pinfo_;
+ std::vector< parameter > params_;
+ text_line line_;
+ };
+
+ }
+}
+
+#endif // ! TOPPERS_ITRONX_STATIC_API_HPP_
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2005-2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/*!
+ * \file toppers/itronx/static_api_parser.hpp
+ * \brief 静的APIの文法に関する宣言定義
+ *
+ * このファイルで定義されるクラス
+ * \code
+ * struct static_api_parser;
+ * struct static_api_parser::error_handler;
+ * struct static_api_parser::definition< Scanner >;
+ * \endcode
+ */
+#ifndef TOPPERS_ITRONX_STATIC_API_PARSER_HPP_
+#define TOPPERS_ITRONX_STATIC_API_PARSER_HPP_
+
+#include "toppers/diagnostics.hpp"
+#include "toppers/c_expr.hpp"
+#include <boost/spirit/include/classic_error_handling.hpp>
+
+namespace toppers
+{
+ namespace itronx
+ {
+
+ /*!
+ * \struct static_api_parser static_api_parser.hpp "toppers/itronx/static_api_parser.hpp"
+ * \brief 静的APIの構文解析クラス
+ */
+ struct static_api_parser : boost::spirit::classic::grammar< static_api_parser >
+ {
+ enum rule_id_t
+ {
+ id_top = 1, id_api_name, id_parameter_list, id_parameter, id_packet, id_cexpr
+ };
+ enum expected_t
+ {
+ open_paren_expected, close_paren_expected, open_brace_expected, close_brace_expected,
+ comma_expected, semicolon_expected
+ };
+
+ /*!
+ * \struct error_handler static_api_parser.hpp "toppers/itronx/static_api_parser.hpp"
+ * \brief 静的APIの構文解析におけるエラー処理ファンクタ
+ */
+ struct error_handler
+ {
+ template < class Scanner, class Error >
+ boost::spirit::classic::error_status<> operator()( Scanner const& scan, Error const& error ) const
+ {
+ typename Error::iterator_t iter( error.where );
+ std::string str;
+ text_line ln;
+ if ( iter != scan.last )
+ {
+ while ( *iter != '\0' && *iter != '\n' )
+ {
+ ++iter;
+ }
+ str = '\"' + std::string( error.where, iter ) + '\"';
+ ln = get_text_line( error.where );
+ }
+ else
+ {
+ str = "\"end of file\"";
+ ln = get_text_line( iter - 1 );
+ }
+
+ switch ( error.descriptor )
+ {
+ case open_paren_expected:
+ toppers::fatal( ln, _( "missing `%1%\' before %2%" ), '(', str );
+ break;
+ case close_paren_expected:
+ toppers::fatal( ln, _( "missing `%1%\' before %2%" ), ')', str );
+ break;
+ case close_brace_expected:
+ toppers::fatal( ln, _( "missing `%1%\' before %2%" ), '}', str );
+ break;
+ case semicolon_expected:
+ toppers::fatal( ln, _( "missing `%1%\' before %2%" ), ';', str );
+ break;
+ }
+ return boost::spirit::classic::error_status<>( boost::spirit::classic::error_status<>::fail );
+ }
+ };
+
+ /*!
+ * \struct definition static_api_parser.hpp "toppers/itronx/static_api_parser.hpp"
+ * \brief 静的APIの構文解析における文法定義
+ */
+ template < class Scanner >
+ struct definition
+ {
+ typedef boost::spirit::classic::rule< Scanner, boost::spirit::classic::dynamic_parser_tag > rule_t;
+ typedef boost::spirit::classic::guard< expected_t > guard_t;
+ typedef boost::spirit::classic::assertion< expected_t > assertion_t;
+
+ c_strlit_parser_t const c_strlit_p;
+ c_ident_parser_t const c_ident_p;
+
+ rule_t top, api_name, parameter_list, parameter, packet, cexpr;
+ guard_t guard_api, guard_packet;
+ assertion_t expect_open_paren,
+ expect_close_paren,
+ expect_close_brace,
+ expect_comma, expect_semicolon;
+
+ /*!
+ * \brief コンストラクタ
+ * \param self 構文解析クラス(文法クラス)への参照
+ */
+ definition( static_api_parser const& self )
+ : c_strlit_p( c_strlit_parser( self.cexpr_p_.codeset_ ) ),
+ c_ident_p( c_ident_parser( self.cexpr_p_.ucn_, self.cexpr_p_.c_plus_plus_ ) ),
+ expect_open_paren( open_paren_expected ),
+ expect_close_paren( close_paren_expected ),
+ expect_close_brace( close_brace_expected ),
+ expect_comma( comma_expected ),
+ expect_semicolon( semicolon_expected )
+ {
+ using namespace boost::spirit::classic;
+ set_id();
+ top =
+ guard_api
+ (
+ api_name >>
+ str_p( "(" ) >>
+ !parameter_list >>
+ expect_close_paren( str_p( ")" ) ) >>
+ expect_semicolon( ch_p( ';' ) )
+ )
+ [
+ error_handler()
+ ];
+ api_name =
+ c_ident_p[ push_back_a( self.tokens_ ) ];
+ parameter_list =
+ parameter % ',';
+ parameter =
+ packet | cexpr;
+ packet =
+ guard_packet
+ (
+ str_p( "{" )[ push_back_a( self.tokens_ ) ] >>
+ parameter_list >>
+ expect_close_brace( str_p( "}" )[ push_back_a( self.tokens_ ) ] )
+ )
+ [
+ error_handler()
+ ];
+ cexpr =
+ self.cexpr_p_[ push_back_a( self.tokens_ ) ];
+ }
+ void set_id()
+ {
+ top.set_id( id_top );
+ api_name.set_id( id_api_name );
+ parameter_list.set_id( id_parameter_list );
+ parameter.set_id( id_parameter );
+ packet.set_id( id_packet );
+ cexpr.set_id( id_cexpr );
+ }
+ rule_t const& start() const { return top; }
+ };
+ /*!
+ * \brief コンストラクタ
+ * \param tokens 静的APIの構成トークンの格納先
+ * \param cexpr_p C言語の定数式構文解析関数オブジェクト
+ */
+ explicit static_api_parser( std::vector< std::string >& tokens, c_const_expr_parser const& cexpr_p )
+ : tokens_( tokens ), cexpr_p_( cexpr_p )
+ {
+ }
+
+ std::vector< std::string >& tokens_;
+ c_const_expr_parser const& cexpr_p_;
+ };
+
+ }
+}
+
+#endif // ! TOPPERS_ITRONX_STATIC_API_PARSER_HPP_
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+#include <cstdlib>
+#include <cctype>
+#include <cerrno>
+#include <algorithm>
+#include <functional>
+#include <iterator>
+#include <sstream>
+#include <fstream>
+#include <limits>
+#include "toppers/workaround.hpp"
+#include "toppers/io.hpp"
+#include "toppers/cpp.hpp"
+#include "toppers/global.hpp"
+#include "toppers/macro_processor.hpp"
+#include "toppers/diagnostics.hpp"
+#include "toppers/misc.hpp"
+#include <boost/spirit/include/classic.hpp>
+#include <boost/spirit/include/classic_dynamic.hpp>
+#include <boost/spirit/include/classic_parse_tree.hpp>
+#include <boost/lexical_cast.hpp>
+
+// 非標準マクロの定義を除去
+#ifdef max
+#undef max
+#endif
+#ifdef min
+#undef min
+#endif
+
+#define DEBUG_TRACE 0
+
+namespace toppers
+{
+
+ namespace
+ {
+
+ struct expr_error {};
+
+ /*!
+ * \struct parser macro_processor.cpp "toppers/macro_processor.cpp"
+ * \brief マクロ内に記述される式のパーサ
+ */
+ struct parser : boost::spirit::classic::grammar< parser >
+ {
+ enum rule_id_t
+ {
+ id_other = 0,
+
+ id_expression, id_assignment_expr, id_logical_or_expr, id_logical_and_expr,
+ id_or_expr, id_xor_expr, id_and_expr, id_equality_expr, id_relational_expr,
+ id_shift_expr, id_additive_expr, id_multiplicative_expr, id_unary_expr,
+ id_postfix_expr, id_primary_expr, id_lvalue_expr, id_identifier, id_constant,
+ id_string_literal, id_ordered_list, id_ordered_sequence, id_ordered_item,
+
+ id_root, id_top,
+ id_function_, id_if_, id_foreach_, id_joineach_, id_error_, id_warning_,
+ id_file_, id_expr_, id_plain,
+
+ id_illegal = -1
+ };
+ enum expected_t
+ {
+ doller_expected, end_expected, close_paren_expected, close_brace_expected,
+ close_bracket_expected
+ };
+
+ /*!
+ * \struct error_handler static_api_parser.hpp "toppers/itronx/static_api_parser.hpp"
+ * \brief 静的APIの構文解析におけるエラー処理ファンクタ
+ */
+ struct error_handler
+ {
+ template < class Scanner, class Error >
+ boost::spirit::classic::error_status<> operator()( Scanner const& scan, Error const& error ) const
+ {
+ typename Error::iterator_t iter( error.where );
+ while ( iter != scan.last && *iter != '\0' && *iter != '\n' )
+ {
+ ++iter;
+ }
+ std::string str;
+ if ( error.where == iter )
+ {
+ str = _( "end of line" );
+ }
+ else
+ {
+ str = '\"' + std::string( error.where, iter ) + '\"';
+ }
+
+ text_line ln;
+ if ( error.where != scan.last )
+ {
+ ln = get_text_line( error.where );
+ }
+ else
+ {
+ // テンプレートファイルの最終行を求める
+ typename Error::iterator_t prev( scan.first );
+ for ( iter = scan.first; iter != scan.last; ++iter )
+ {
+ prev = iter;
+ }
+ ln = get_text_line( prev );
+ }
+ switch ( error.descriptor )
+ {
+ case doller_expected:
+ toppers::fatal( ln, _( "missing `%1%\' before %2%" ), '$', str );
+ break;
+ case end_expected:
+ toppers::fatal( ln, _( "missing `%1%\' before %2%" ), "$END$", str );
+ break;
+ case close_paren_expected:
+ toppers::fatal( ln, _( "missing `%1%\' before %2%" ), ")", str );
+ break;
+ case close_brace_expected:
+ toppers::fatal( ln, _( "missing `%1%\' before %2%" ), "}", str );
+ break;
+ case close_bracket_expected:
+ toppers::fatal( ln, _( "missing `%1%\' before %2%" ), "]", str );
+ break;
+ }
+ return boost::spirit::classic::error_status<>( boost::spirit::classic::error_status<>::fail );
+ }
+ };
+
+
+ template < class Scanner >
+ struct definition
+ {
+ typedef boost::spirit::classic::rule< Scanner, boost::spirit::classic::dynamic_parser_tag > rule_t;
+ typedef boost::spirit::classic::guard< expected_t > guard_t;
+ typedef boost::spirit::classic::assertion< expected_t > assertion_t;
+
+ rule_t expression,
+ assignment_expr,
+ logical_or_expr,
+ logical_and_expr,
+ or_expr,
+ xor_expr,
+ and_expr,
+ equality_expr,
+ relational_expr,
+ shift_expr,
+ additive_expr,
+ multiplicative_expr,
+ unary_expr,
+ postfix_expr,
+ primary_expr,
+ lvalue_expr,
+ identifier,
+ constant,
+ string_literal,
+ ordered_list,
+ ordered_sequence,
+ ordered_item;
+
+ rule_t root,
+ top,
+ function_,
+ if_,
+ foreach_,
+ joineach_,
+ error_,
+ warning_,
+ file_,
+ expr_,
+ call,
+ plain;
+
+ guard_t guard_function_,
+ guard_if_,
+ guard_foreach_,
+ guard_joineach_,
+ guard_expr,
+ guard_postfix_expr,
+ guard_lvalue_expr,
+ guard_ordered_list;
+
+ assertion_t expect_doller,
+ expect_end,
+ expect_close_paren,
+ expect_close_brace,
+ expect_close_bracket;
+
+ definition( parser const& self )
+ : expect_doller( doller_expected ),
+ expect_end( end_expected ),
+ expect_close_paren( close_paren_expected ),
+ expect_close_brace( close_brace_expected ),
+ expect_close_bracket( close_bracket_expected )
+ {
+ using namespace boost::spirit::classic;
+
+ set_id();
+
+ expression =
+ logical_or_expr;
+ assignment_expr =
+ lvalue_expr >> '=' >> expression;
+ logical_or_expr =
+ logical_and_expr >> *( "||" >> logical_and_expr );
+ logical_and_expr =
+ or_expr >> *( "&&" >> or_expr );
+ or_expr =
+ xor_expr >> *( '|' >> xor_expr );
+ xor_expr =
+ and_expr >> *( '^' >> and_expr );
+ and_expr =
+ equality_expr >> *( '&' >> equality_expr );
+ equality_expr =
+ relational_expr >> *( ( str_p( "==" ) | "!=" ) >> relational_expr );
+ relational_expr =
+ shift_expr >> *( ( str_p( "<=" ) | ">=" | "<" | ">" ) >> shift_expr );
+ shift_expr =
+ additive_expr >> *( ( str_p( "<<" ) | ">>" ) >> additive_expr );
+ additive_expr =
+ multiplicative_expr >> *( chset<>( "+-" ) >> multiplicative_expr );
+ multiplicative_expr =
+ unary_expr >> *( chset<>( "*/%" ) >> unary_expr );
+ unary_expr =
+ *chset<>( "-+~!@" ) >> postfix_expr;
+ postfix_expr =
+ guard_postfix_expr
+ (
+ ( identifier >> '(' >> *( expression % ',' ) >> expect_close_paren( ch_p( ')' ) ) )
+ | primary_expr
+ )
+ [
+ error_handler()
+ ];
+ primary_expr =
+ lvalue_expr | ordered_list | constant | string_literal
+ | ( '(' >> expression >> ')' );
+ lvalue_expr =
+ guard_lvalue_expr
+ (
+ ( identifier >> '[' >> expression >> expect_close_bracket( ch_p( ']' ) ) )
+ | identifier
+ )
+ [
+ error_handler()
+ ];
+ identifier =
+ leaf_node_d[ lexeme_d[ ( alpha_p | '_' ) >> *( alnum_p | '_' | '.' ) ] ];
+ constant =
+ leaf_node_d
+ [
+ lexeme_d
+ [
+ if_p( '0' ) // 16進または8進
+ [
+ !(
+ ( ( ch_p( 'x' ) | 'X' ) >> ( hex_p | +xdigit_p ) )
+ | ( oct_p | +chset<>( "0-7" ) )
+ )
+ ]
+ .else_p // 10進
+ [
+ ( int_p | +digit_p )
+ ]
+ ]
+ ];
+ string_literal =
+ leaf_node_d[ lexeme_d[ '\"' >> *( c_escape_ch_p - '\"' ) >> '\"' ] ];
+ ordered_list =
+ guard_ordered_list
+ (
+ '{' >> !( ( ordered_sequence | ordered_item ) >> *( ';' >> ( ordered_sequence | ordered_item ) ) ) >> expect_close_brace( ch_p( '}' ) )
+ )
+ [
+ error_handler()
+ ];
+ ordered_sequence =
+ ( constant >> ',' >> constant >> ',' >> "..." >> ',' >> constant );
+ ordered_item =
+ expression >> *( ',' >> expression );
+
+ root =
+ top >> lexeme_d[ !space_p ];
+ top =
+ *( function_ | if_ | foreach_ | joineach_ | warning_ | error_ | file_ | expr_ | plain );
+ function_ =
+ guard_function_
+ (
+ "$FUNCTION" >> identifier >> expect_doller( ch_p( '$' ) ) >> top >> expect_end( str_p( "$END$" ) )
+ )
+ [
+ error_handler()
+ ];
+ if_ =
+ guard_if_
+ (
+ ( "$IF" >> expression >> expect_doller( ch_p( '$' ) ) >> top >> "$ELSE$" >> top >> expect_end( str_p( "$END$" ) ) )
+ | ( "$IF" >> expression >> expect_doller( ch_p( '$' ) ) >> top >> expect_end( str_p( "$END$" ) ) )
+ )
+ [
+ error_handler()
+ ];
+ foreach_ =
+ guard_foreach_
+ (
+ "$FOREACH" >> identifier >> expression >> expect_doller( ch_p( '$' ) ) >> top >> expect_end( str_p( "$END$" ) )
+ )
+ [
+ error_handler()
+ ];
+ joineach_ =
+ guard_joineach_
+ (
+ "$JOINEACH" >> identifier >> expression >> expression >> expect_doller( ch_p( '$' ) ) >> top >> expect_end( str_p( "$END$" ) )
+ )
+ [
+ error_handler()
+ ];
+ warning_ =
+ "$WARNING$" >> top >> "$END$" >> !eol_p
+ | "$WARNING" >> expression >> '$' >> top >> "$END$";
+ error_ =
+ "$ERROR$" >> top >> "$END$" >> !eol_p
+ | "$ERROR" >> expression >> '$' >> top >> "$END$";
+ file_ =
+ "$FILE" >> string_literal >> '$';
+ expr_ =
+ guard_expr
+ (
+ ( ( '$' >> ( assignment_expr | expression ) >> expect_doller( ch_p( '$' ) ) ) - "$END$" - "$ELSE$" )
+ )
+ [
+ error_handler()
+ ];
+ plain =
+ leaf_node_d[ lexeme_d[ +( anychar_p - '$' ) | "$$" ] ];
+ }
+ rule_t const& start() const { return root; }
+ void set_id()
+ {
+ expression.set_id( id_expression );
+ assignment_expr.set_id( id_assignment_expr );
+ logical_or_expr.set_id( id_logical_or_expr );
+ logical_and_expr.set_id( id_logical_and_expr );
+ or_expr.set_id( id_or_expr );
+ xor_expr.set_id( id_xor_expr );
+ and_expr.set_id( id_and_expr );
+ equality_expr.set_id( id_equality_expr );
+ relational_expr.set_id( id_relational_expr );
+ shift_expr.set_id( id_shift_expr );
+ additive_expr.set_id( id_additive_expr );
+ multiplicative_expr.set_id( id_multiplicative_expr );
+ unary_expr.set_id( id_unary_expr );
+ postfix_expr.set_id( id_postfix_expr );
+ primary_expr.set_id( id_primary_expr );
+ lvalue_expr.set_id( id_lvalue_expr );
+ identifier.set_id( id_identifier );
+ constant.set_id( id_constant );
+ string_literal.set_id( id_string_literal );
+ ordered_list.set_id( id_ordered_list );
+ ordered_sequence.set_id( id_ordered_sequence );
+ ordered_item.set_id( id_ordered_item );
+
+ root.set_id( id_root );
+ top.set_id( id_top );
+ function_.set_id( id_function_ );
+ if_.set_id( id_if_ );
+ foreach_.set_id( id_foreach_ );
+ joineach_.set_id( id_joineach_ );
+ error_.set_id( id_error_ );
+ warning_.set_id( id_warning_ );
+ file_.set_id( id_file_ );
+ expr_.set_id( id_expr_ );
+ plain.set_id( id_plain );
+ }
+ };
+
+ parser()
+ {
+ }
+ };
+
+ typedef macro_processor::element element;
+ typedef macro_processor::var_t var_t;
+ typedef macro_processor::context context;
+
+ //! 変数が保持する数値の参照
+ std::tr1::int64_t get_i( var_t const& var, context const* p_ctx )
+ {
+ if ( var.empty() )
+ {
+ fatal( p_ctx->line, _( "non-value is referred" ) );
+ return 0;
+ }
+ element e = var.front();
+ if ( !e.i )
+ {
+ fatal( p_ctx->line, _( "non-value is referred" ) );
+ return 0;
+ }
+ return e.i.get();
+ }
+ //! 変数が保持する文字列の参照
+ std::string get_s( var_t const& var, context const* p_ctx )
+ {
+ if ( var.empty() )
+ {
+ return "";
+ }
+ std::string result;
+ for ( var_t::const_iterator iter( var.begin() ), last( var.end() ); iter != last; ++iter )
+ {
+ if ( !iter->s.empty() )
+ {
+ result += iter->s;
+ }
+ else if ( !iter->v.empty() )
+ {
+ result += iter->v;
+ }
+ else if ( iter->i )
+ {
+ result += boost::lexical_cast< std::string >( iter->i.get() );
+ }
+ if ( boost::next( iter ) != last )
+ {
+ result += ",";
+ }
+ }
+ return result;
+ }
+
+ typedef boost::spirit::classic::tree_node< boost::spirit::classic::node_iter_data< text::const_iterator > > tree_node_t;
+ bool eval_node( tree_node_t const& node, context* p_ctx );
+
+ //! 代入式
+ bool assignment_expr( tree_node_t const& node, context* p_ctx )
+ {
+ // 0 1 2
+ // lhs = rhs
+ if ( eval_node( node.children[ 0 ], p_ctx ) )
+ {
+ var_t lhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ std::string name( get_s( lhs, p_ctx ) );
+ if ( eval_node( node.children[ 2 ], p_ctx ) )
+ {
+ var_t rhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ var_t old_var( p_ctx->var_map[ name ] );
+ p_ctx->var_map[ name ] = rhs;
+ }
+ }
+ return true;
+ }
+
+ //! 論理和式
+ bool logical_or_expr( tree_node_t const& node, context* p_ctx )
+ {
+ // 0 1 2
+ // lhs || rhs ...
+ bool result = true;
+
+ if ( eval_node( node.children[ 0 ], p_ctx ) )
+ {
+ std::size_t const n = node.children.size();
+ if ( n == 1 ) // 左辺のみ
+ {
+ return true;
+ }
+ var_t lhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ for ( std::size_t i = 2; i < n; i += 2 )
+ {
+ std::tr1::int64_t value = 0;
+ try
+ {
+ value = get_i( lhs, p_ctx );
+ }
+ catch ( expr_error& )
+ {
+ error( node.children[ 0 ].value.begin().line(), _( "`%1%\' does not have a value" ), get_s( lhs, p_ctx ) );
+ throw;
+ }
+ if ( value )
+ {
+ break;
+ }
+ result = eval_node( node.children[ i ], p_ctx );
+ var_t rhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ element e;
+ std::tr1::int64_t value2 = 0;
+ try
+ {
+ value2 = get_i( rhs, p_ctx );
+ }
+ catch ( expr_error& )
+ {
+ error( node.children[ i ].value.begin().line(), _( "`%1%\' does not have a value" ), get_s( lhs, p_ctx ) );
+ throw;
+ }
+ e.i = ( value || value2 );
+ lhs[ 0 ] = e;
+ }
+ p_ctx->stack.push( lhs );
+ }
+ return result;
+ }
+
+ //! 論理積式
+ bool logical_and_expr( tree_node_t const& node, context* p_ctx )
+ {
+ // 0 1 2
+ // lhs && rhs ...
+ bool result = true;
+
+ if ( eval_node( node.children[ 0 ], p_ctx ) )
+ {
+ std::size_t const n = node.children.size();
+ if ( n == 1 ) // 左辺のみ
+ {
+ return true;
+ }
+ var_t lhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ for ( std::size_t i = 2; i < n; i += 2 )
+ {
+ std::tr1::int64_t value = 0;
+ try
+ {
+ value = get_i( lhs, p_ctx );
+ }
+ catch ( expr_error& )
+ {
+ error( node.children[ 0 ].value.begin().line(), _( "`%1%\' does not have a value" ), get_s( lhs, p_ctx ) );
+ throw;
+ }
+ if ( !value )
+ {
+ break;
+ }
+ result = eval_node( node.children[ i ], p_ctx );
+ var_t rhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ element e;
+ std::tr1::int64_t value2 = 0;
+ try
+ {
+ value2 = get_i( rhs, p_ctx );
+ }
+ catch ( expr_error& )
+ {
+ error( node.children[ i ].value.begin().line(), _( "`%1%\' does not have a value" ), get_s( lhs, p_ctx ) );
+ throw;
+ }
+ e.i = ( value && value2 );
+ lhs[ 0 ] = e;
+ }
+ p_ctx->stack.push( lhs );
+ }
+ return result;
+ }
+
+ //! ビット和式
+ bool or_expr( tree_node_t const& node, context* p_ctx )
+ {
+ // 0 1 2
+ // lhs | rhs ...
+ if ( eval_node( node.children[ 0 ], p_ctx ) )
+ {
+ std::size_t const n = node.children.size();
+ if ( n == 1 ) // 左辺のみ
+ {
+ return true;
+ }
+ var_t lhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ for ( std::size_t i = 1; ( i < n ) && eval_node( node.children[ i+1 ], p_ctx ); i += 2 )
+ {
+ var_t rhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ element e;
+ e.i = ( get_i( lhs, p_ctx ) | get_i( rhs, p_ctx ) );
+ lhs[ 0 ] = e;
+ }
+ p_ctx->stack.push( lhs );
+ }
+ return true;
+ }
+
+ //! 排他的論理和式
+ bool xor_expr( tree_node_t const& node, context* p_ctx )
+ {
+ // 0 1 2
+ // lhs ^ rhs ...
+ if ( eval_node( node.children[ 0 ], p_ctx ) )
+ {
+ std::size_t const n = node.children.size();
+ if ( n == 1 ) // 左辺のみ
+ {
+ return true;
+ }
+ var_t lhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ for ( std::size_t i = 1; ( i < n ) && eval_node( node.children[ i+1 ], p_ctx ); i += 2 )
+ {
+ var_t rhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ element e;
+ e.i = ( get_i( lhs, p_ctx ) ^ get_i( rhs, p_ctx ) );
+ lhs[ 0 ] = e;
+ }
+ p_ctx->stack.push( lhs );
+ }
+ return true;
+ }
+
+ //! ビット積式
+ bool and_expr( tree_node_t const& node, context* p_ctx )
+ {
+ // 0 1 2
+ // lhs & rhs ...
+ if ( eval_node( node.children[ 0 ], p_ctx ) )
+ {
+ std::size_t const n = node.children.size();
+ if ( n == 1 ) // 左辺のみ
+ {
+ return true;
+ }
+ var_t lhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ for ( std::size_t i = 1; ( i < n ) && eval_node( node.children[ i+1 ], p_ctx ); i += 2 )
+ {
+ var_t rhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ element e;
+ e.i = ( get_i( lhs, p_ctx ) & get_i( rhs, p_ctx ) );
+ lhs[ 0 ] = e;
+ }
+ p_ctx->stack.push( lhs );
+ }
+ return true;
+ }
+
+ //! 等価式(==、!=)
+ bool equality_expr( tree_node_t const& node, context* p_ctx )
+ {
+ // 0 1 2
+ // lhs op rhs ...
+ if ( eval_node( node.children[ 0 ], p_ctx ) )
+ {
+ std::size_t const n = node.children.size();
+ if ( n == 1 ) // 左辺のみ
+ {
+ return true;
+ }
+ var_t lhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ for ( std::size_t i = 1; ( i < n ) && eval_node( node.children[ i+1 ], p_ctx ); i += 2 )
+ {
+ var_t rhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ std::string op( node.children[ i ].value.begin(), node.children[ i ].value.end() );
+ std::tr1::int64_t value;
+ if ( op == "==" )
+ {
+ value = ( get_i( lhs, p_ctx ) == get_i( rhs, p_ctx ) );
+ }
+ else
+ {
+ value = ( get_i( lhs, p_ctx ) != get_i( rhs, p_ctx ) );
+ }
+ element e;
+ e.i = value;
+ lhs[ 0 ] = e;
+ }
+ p_ctx->stack.push( lhs );
+ }
+ return true;
+ }
+
+ //! 関係式(不等号)
+ bool relational_expr( tree_node_t const& node, context* p_ctx )
+ {
+ // 0 1 2
+ // lhs op rhs ...
+ if ( eval_node( node.children[0], p_ctx ) )
+ {
+ std::size_t const n = node.children.size();
+ if ( n == 1 ) // 左辺のみ
+ {
+ return true;
+ }
+ var_t lhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ for ( std::size_t i = 1; ( i < n ) && eval_node( node.children[ i+1 ], p_ctx ); i += 2 )
+ {
+ var_t rhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ std::string op( node.children[i].value.begin(), node.children[ i ].value.end() );
+ std::tr1::int64_t value;
+ if ( op == "<" )
+ {
+ value = ( get_i( lhs, p_ctx ) < get_i( rhs, p_ctx ) );
+ }
+ else if ( op == "<=" )
+ {
+ value = ( get_i( lhs, p_ctx ) <= get_i( rhs, p_ctx ) );
+ }
+ else if ( op == ">" )
+ {
+ value = ( get_i( lhs, p_ctx ) > get_i( rhs, p_ctx ) );
+ }
+ else
+ {
+ value = ( get_i( lhs, p_ctx ) >= get_i( rhs, p_ctx ) );
+ }
+ element e;
+ e.i = value;
+ lhs[ 0 ] = e;
+ }
+ p_ctx->stack.push( lhs );
+ }
+ return true;
+ }
+
+ //! シフト式
+ bool shift_expr( tree_node_t const& node, context* p_ctx )
+ {
+ // 0 1 2
+ // lhs op rhs ...
+ if ( eval_node( node.children[ 0 ], p_ctx ) )
+ {
+ std::size_t const n = node.children.size();
+ if ( n == 1 ) // 左辺のみ
+ {
+ return true;
+ }
+ var_t lhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ for ( std::size_t i = 1; ( i < n ) && eval_node( node.children[ i+1 ], p_ctx ); i += 2 )
+ {
+ var_t rhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ std::string op( node.children[ i ].value.begin(), node.children[ i ].value.end() );
+ std::tr1::int64_t value = get_i( lhs, p_ctx );
+ std::tr1::int64_t shift = get_i( rhs, p_ctx );
+ if ( shift < 0 ) // 負の値でシフトしようとした
+ {
+ error( node.children[ 0 ].value.begin().line(), _( "shift with nagative value `%1%\'" ), shift );
+ }
+ if ( shift > 64 )
+ {
+ error( node.children[ 0 ].value.begin().line(), _( "shift with too large value `%1%\'" ), shift );
+ }
+ if ( op == "<<" )
+ {
+ if ( value < 0 )
+ { // 負の値のシフトはできない
+ error( node.children[0].value.begin().line(), _( "negative value `%1%\' is shift" ), value );
+ }
+ else if ( shift != 0 && static_cast< std::tr1::int64_t >( static_cast< std::tr1::uint64_t >( 1 ) << ( 63 - shift ) ) <= value )
+ { // シフトの結果が負になる
+ error( node.children[0].value.begin().line(), _( "shift with too large value `%1%\'" ), shift );
+ }
+ value = value << shift;
+ }
+ else
+ {
+ if ( value < 0 ) // 強制的に算術シフトさせる
+ {
+ value = static_cast< std::tr1::int64_t >( ( static_cast< std::tr1::uint64_t >( value ) >> shift ) | ( ~static_cast< std::tr1::uint64_t >( 0 ) << shift ) );
+ }
+ else
+ {
+ value = value >> shift;
+ }
+ }
+ element e;
+ e.i = value;
+ lhs[ 0 ] = e;
+ }
+ p_ctx->stack.push( lhs );
+ }
+ return true;
+ }
+
+ //! 加減式
+ bool additive_expr( tree_node_t const& node, context* p_ctx )
+ {
+ // 0 1 2
+ // lhs op rhs ...
+ if ( eval_node( node.children[ 0 ], p_ctx ) )
+ {
+ std::size_t const n = node.children.size();
+ if ( n == 1 ) // 左辺のみ
+ {
+ return true;
+ }
+ var_t lhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ for ( std::size_t i = 1; ( i < n ) && eval_node( node.children[ i+1 ], p_ctx ); i += 2 )
+ {
+ var_t rhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ std::string op( node.children[ i ].value.begin(), node.children[ i ].value.end() );
+ std::tr1::int64_t x = get_i( lhs, p_ctx );
+ std::tr1::int64_t y = get_i( rhs, p_ctx );
+ element e;
+ if ( op == "+" )
+ {
+ if ( ( y > 0 && ( std::numeric_limits< std::tr1::int64_t >::max() - y ) < x )
+ || ( y < 0 && ( std::numeric_limits< std::tr1::int64_t >::min() - y ) > x ) )
+ {
+ error( node.children[ 0 ].value.begin().line(), _( "overflow at `%1%\'" ), get_s( lhs, p_ctx ) + "+" + get_s( rhs, p_ctx ) );
+ // e.i に値はセットされない
+ }
+ else
+ {
+ e.i = x + y;
+ }
+ }
+ else // "-"
+ {
+ if ( ( y < 0 && ( std::numeric_limits< std::tr1::int64_t >::max() + y ) < x )
+ || ( y > 0 && ( std::numeric_limits< std::tr1::int64_t >::min() + y ) > x ) )
+ {
+ error( node.children[ 0 ].value.begin().line(), _( "overflow at `%1%\'" ), get_s( lhs, p_ctx ) + "-" + get_s( rhs, p_ctx ) );
+ // e.i に値はセットされない
+ }
+ else
+ {
+ e.i = x - y;
+ }
+ }
+ lhs[ 0 ] = e;
+ }
+ p_ctx->stack.push( lhs );
+ }
+ return true;
+ }
+
+ //! 乗除式
+ bool multiplicative_expr( tree_node_t const& node, context* p_ctx )
+ {
+ // 0 1 2
+ // lhs op rhs ...
+ if ( eval_node( node.children[ 0 ], p_ctx ) )
+ {
+ std::size_t const n = node.children.size();
+ if ( n == 1 ) // 左辺のみ
+ {
+ return true;
+ }
+ var_t lhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ for ( std::size_t i = 1; ( i < n ) && eval_node( node.children[ i+1 ], p_ctx ); i += 2 )
+ {
+ var_t rhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ std::string op( node.children[i].value.begin(), node.children[i].value.end() );
+ std::tr1::int64_t x = get_i( lhs, p_ctx );
+ std::tr1::int64_t y = get_i( rhs, p_ctx );
+ element e;
+ if ( op == "*" )
+ {
+ if ( ( x == 0 ) || ( y == 0 ) )
+ {
+ e.i = 0;
+ }
+ else if ( ( ( x < 0 ) == ( y < 0 ) ) && ( std::numeric_limits< std::tr1::int64_t >::max() / y < x )
+ || ( ( x < 0 ) != ( y < 0 ) ) && ( std::numeric_limits< std::tr1::int64_t >::min() / y > x ) )
+ {
+ error( node.children[0].value.begin().line(), _( "overflow at `%1%\'" ), get_s( lhs, p_ctx ) + "*" + get_s( rhs, p_ctx ) );
+ // e.i に値はセットされない
+ }
+ else
+ {
+ e.i = x * y;
+ }
+ }
+ else
+ {
+ if ( y == 0 )
+ {
+ error( node.value.begin().line(), _( "devide by zero" ) );
+ // e.i には値がセットされない
+ }
+ else
+ {
+ std::tr1::int64_t value;
+ // 本当はここで一方のオペランドが負の場合の処理を行う必要がある。
+ // そんな変な処理系は実質的にないので放置
+ if ( op == "/" )
+ {
+ value = ( x / y );
+ }
+ else // "%"
+ {
+ value = ( x % y );
+ }
+ e.i = value;
+ }
+ }
+ lhs[ 0 ] = e;
+ }
+ p_ctx->stack.push( lhs );
+ }
+ return true;
+ }
+
+ //! 単項式(後置式、単項演算子 一次式)
+ bool unary_expr( tree_node_t const& node, context* p_ctx )
+ {
+ // 0 1..n-2 n-1
+ // op ...... primary_expr
+ if ( eval_node( node.children[ node.children.size() - 1 ], p_ctx ) )
+ {
+ std::size_t const n = node.children.size();
+ if ( n == 1 ) // 一次式のみ
+ {
+ return true;
+ }
+ var_t expr( p_ctx->stack.top() ); p_ctx->stack.pop();
+ for ( long i = static_cast< long >( n ) - 2, t = 0; i >= 0 && eval_node( node.children[i+1], p_ctx ); i-- )
+ {
+ std::string op( node.children[ i ].value.begin(), node.children[ i ].value.end() );
+ element e;
+ std::tr1::int64_t value = 0;
+ if ( op != "@" )
+ {
+ try
+ {
+ value = get_i( expr, p_ctx );
+ }
+ catch ( expr_error& )
+ {
+ error( node.children[0].value.begin().line(), _( "`%1%\' is undefined" ), get_s( expr, p_ctx ) );
+ throw;
+ }
+ if ( op == "+" )
+ {
+ e.i = +value;
+ }
+ else if ( op == "-" )
+ {
+ if ( value == std::numeric_limits< std::tr1::int64_t >::min() )
+ {
+ error( node.children[0].value.begin().line(), _( "overflow at `%1%\'" ), "-" + get_s( expr, p_ctx ) );
+ // e.i に値はセットされない
+ }
+ else
+ {
+ e.i = -value;
+ }
+ }
+ else if ( op == "~" )
+ {
+ e.i = ~value;
+ }
+ else if ( op == "!" )
+ {
+ e.i = !value;
+ }
+ value = *e.i;
+ }
+ else // op == "@" (値属性 → 文字列属性)
+ {
+ if ( expr.front().i )
+ {
+ e.s = boost::lexical_cast< std::string >( *expr.front().i );
+ }
+ else
+ {
+ e.s = expr.front().v;
+ }
+ }
+ expr[ 0 ] = e; // 演算結果を累積する
+ if ( i == t )
+ {
+ break;
+ }
+ }
+ p_ctx->stack.push( expr );
+ }
+ return true;
+ }
+
+ //! 後置式(関数呼び出し、一次式)
+ bool postfix_expr( tree_node_t const& node, context* p_ctx )
+ {
+ // 0 1 2 3 4..2+2*n-1 2+2*n 2+2*n+1
+ // identifier ( arg0 , .......... argn )
+ // primary_expr
+ if ( eval_node( node.children[0], p_ctx ) )
+ {
+ if ( node.children.size() > 1 ) // 関数の呼び出し
+ {
+ var_t ident( p_ctx->stack.top() ); p_ctx->stack.pop();
+ std::string func_name( get_s( ident, p_ctx ) );
+ std::map< std::string, macro_processor::func_t >::const_iterator iter( p_ctx->func_map.find( func_name ) );
+ if ( iter == p_ctx->func_map.end() ) // そんな関数はない
+ {
+ error( node.children[ 0 ].value.begin().line(), _( "function `%1%\' is undefined" ), func_name );
+ p_ctx->stack.push( var_t() );
+ }
+ else // 関数を呼び出す
+ {
+ std::vector< var_t > arg_list;
+ for ( std::size_t i = 0, n = node.children.size() - 1; 2 + 2*i < n; i++ )
+ {
+ if ( eval_node( node.children[ 2 + 2*i ], p_ctx ) )
+ {
+ var_t arg( p_ctx->stack.top() ); p_ctx->stack.pop();
+ arg_list.push_back( arg );
+ }
+ }
+ var_t result;
+ if ( iter->second.f != 0 ) // 組み込み関数
+ {
+ result = ( *iter->second.f )( node.children[0].value.begin().line(), arg_list, p_ctx );
+ }
+ else if ( iter->second.node != 0 ) // ユーザー定義関数
+ {
+ // ARGC
+ {
+ element e;
+ e.i = static_cast< std::tr1::int64_t >( arg_list.size() + 1 );
+ p_ctx->var_map[ "ARGC" ] = var_t( 1, e );
+ }
+
+ // ARGV
+ {
+ element e;
+ e.s = func_name;
+ p_ctx->var_map[ "ARGV[0]" ] = var_t( 1, e );
+
+ std::size_t n = arg_list.size() + 1;
+ for ( std::size_t i = 1; i < n; i++ )
+ {
+ std::string argv_i = boost::str( boost::format( "ARGV[%d]" ) % i );
+ p_ctx->var_map[ argv_i ] = arg_list[ i - 1 ];
+ }
+
+ std::string argv_n = boost::str( boost::format( "ARGV[%d]" ) % n );
+ p_ctx->var_map[ argv_n ] = var_t();
+ }
+
+ tree_node_t const* func_body_node = reinterpret_cast< tree_node_t const* >( iter->second.node );
+ if ( !eval_node( *func_body_node, p_ctx ) )
+ {
+ // 呼び出し失敗
+ p_ctx->stack.push( result );
+ return false;
+ }
+
+ result = p_ctx->var_map[ "RESULT" ];
+ }
+ p_ctx->stack.push( result );
+ }
+ }
+ }
+ return true;
+ }
+
+ //! 一次式(左辺値式、(式))
+ bool primary_expr( tree_node_t const& node, context* p_ctx )
+ {
+ bool result = true;
+
+ if ( node.children.size() == 1 )
+ {
+ result = eval_node( node.children[0], p_ctx );
+ if ( node.children[ 0 ].value.id() == parser::id_lvalue_expr )
+ {
+ var_t ident( p_ctx->stack.top() ); p_ctx->stack.pop();
+ std::string name( get_s( ident, p_ctx ) );
+ var_t value( p_ctx->var_map[ name ] );
+ p_ctx->stack.push( value );
+ }
+ }
+ else
+ {
+ // 0 1 2
+ // ( expression )
+ result = eval_node( node.children[1], p_ctx );
+ }
+ return result;
+ }
+
+ //! 左辺値式(変数、配列変数)
+ bool lvalue_expr( tree_node_t const& node, context* p_ctx )
+ {
+ // 0 1 2 3
+ // identifier
+ // identifier [ expression ]
+ if ( eval_node( node.children[ 0 ], p_ctx ) )
+ {
+ if ( ( node.children.size() > 1 ) && eval_node( node.children[ 2 ], p_ctx ) )
+ {
+ var_t expr( p_ctx->stack.top() ); p_ctx->stack.pop();
+ var_t ident( p_ctx->stack.top() ); p_ctx->stack.pop();
+ element e;
+ std::string subscript;
+ try
+ {
+ std::tr1::int64_t i = get_i( expr, p_ctx );
+ subscript = boost::lexical_cast< std::string >( i );
+ }
+ catch ( expr_error& )
+ {
+ subscript = get_s( expr, p_ctx );
+ error( node.children[ 0 ].value.begin().line(), _( "`%1%\' does not have a value" ), subscript );
+ throw;
+ }
+ e.s = ( boost::format( "%s[%s]" ) % get_s( ident, p_ctx ) % subscript ).str();
+ p_ctx->stack.push( var_t( 1, e ) );
+ }
+ }
+ return true;
+ }
+
+ //! 識別子
+ bool identifier( tree_node_t const& node, context* p_ctx )
+ {
+ element e;
+ std::string ident( node.children[0].value.begin(), node.children[0].value.end() );
+ std::string::size_type n = ident.find_first_not_of( " \t\r\n" );
+ e.s = ident.c_str() + n;
+ p_ctx->stack.push( var_t( 1, e ) );
+ return true;
+ }
+
+ //! 整数定数
+ bool constant( tree_node_t const& node, context* p_ctx )
+ {
+ element e;
+ e.s.assign( node.children[0].value.begin(), node.children[0].value.end() );
+
+ // Boost 1.39.0?以上で、0の前の空白を含めてトークンとしてしまう不具合の対策
+ std::string::size_type pos = e.s.find_first_not_of( " \t\n" );
+ if (pos != std::string::npos )
+ {
+ e.s = e.s.substr( pos );
+ }
+
+ std::istringstream iss( e.s );
+ iss.unsetf( std::ios_base::basefield );
+ std::tr1::int64_t value;
+ iss >> value;
+ if ( iss.bad() )
+ {
+ error( node.children[0].value.begin().line(), _( "overflow at `%1%\'" ), e.s );
+ }
+ e.i = value;
+ p_ctx->stack.push( var_t( 1, e ) );
+ return true;
+ }
+
+ //! 文字列
+ bool string_literal( tree_node_t const& node, context* p_ctx )
+ {
+ // 0 1..n-2 n-1
+ // " ...... "
+ element e;
+ // ここで構文エラー例外になることはあり得ない。(構文解析後なので)
+ e.s = expand_quote( std::string( node.children[0].value.begin(), node.children[0].value.end() ) );
+ p_ctx->stack.push( var_t( 1, e ) );
+ return true;
+ }
+
+ //! 順序付きリスト
+ bool ordered_list( tree_node_t const& node, context* p_ctx )
+ {
+ // 0 1 2 n-1
+ // { ordered_sequence ; ... }
+ // { ordered_item ; ... }
+ if ( node.children.size() < 3 )
+ {
+ p_ctx->stack.push( var_t() );
+ }
+ else if ( eval_node( node.children[1], p_ctx ) )
+ {
+ var_t lhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ for ( std::size_t i = 1, n = node.children.size(); ( i+2 < n ) && eval_node( node.children[i+2], p_ctx ); i += 2 )
+ {
+ var_t rhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ std::copy( rhs.begin(), rhs.end(), std::back_inserter( lhs ) );
+ }
+ p_ctx->stack.push( lhs );
+ }
+ return true;
+ }
+
+ //! 順序付きリスト(等差数列)
+ bool ordered_sequence( tree_node_t const& node, context* p_ctx )
+ {
+ // 0 1 2 3 4 5 6
+ // int , int , ... , int
+ if ( eval_node( node.children[0], p_ctx ) )
+ {
+ var_t first( p_ctx->stack.top() ); p_ctx->stack.pop();
+ if ( eval_node( node.children[ 2 ], p_ctx ) )
+ {
+ var_t second( p_ctx->stack.top() ); p_ctx->stack.pop();
+ if ( eval_node( node.children[ 6 ], p_ctx ) )
+ {
+ var_t last( p_ctx->stack.top() ); p_ctx->stack.pop();
+ std::tr1::int64_t a0 = get_i( first, p_ctx );
+ std::tr1::int64_t a1 = get_i( second, p_ctx );
+ std::tr1::int64_t an = get_i( last, p_ctx );
+ std::tr1::int64_t d = a1 - a0;
+ if ( ( an - a0 ) % d != 0 )
+ {
+ error( node.children[ 0 ].value.begin().line(), _( "illegal arithmetic sequence" ) );
+ }
+ else
+ {
+ for ( std::tr1::int64_t i = a1, t = an + d; i != t; i += d )
+ {
+ element e;
+ e.i = i;
+ first.push_back( e );
+ }
+ first[ 1 ].s = second[0].s;
+ first.back().s = last[ 0 ].s;
+ }
+ p_ctx->stack.push( first );
+ }
+ }
+ }
+ return true;
+ }
+
+ //! 順序付きリスト(列記)
+ bool ordered_item( tree_node_t const& node, context* p_ctx )
+ {
+ // 0 1 2
+ // int , int ...
+ if ( eval_node( node.children[ 0 ], p_ctx ) )
+ {
+ var_t lhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ for ( std::size_t i = 1, n = node.children.size(); ( i < n ) && eval_node( node.children[ i+1 ], p_ctx ); i += 2 )
+ {
+ var_t rhs( p_ctx->stack.top() ); p_ctx->stack.pop();
+ lhs.push_back( rhs[ 0 ] );
+ }
+ p_ctx->stack.push( lhs );
+ }
+ return true;
+ }
+
+ //! トップレベル
+ bool top( tree_node_t const& node, context* p_ctx )
+ {
+ bool result = true;
+
+ for ( std::size_t i = 0, n = node.children.size(); i < n; i++ )
+ {
+ for ( text::const_iterator iter( node.children[ i ].value.begin() ), last( node.children[ i ].value.end() );
+ iter != last;
+ ++iter )
+ {
+ char c = *iter;
+ if ( !std::isspace( static_cast< unsigned char >( c ) ) )
+ {
+ break;
+ }
+ if ( c != '\n' )
+ {
+ p_ctx->target_file << c;
+ }
+ }
+ result &= eval_node( node.children[i], p_ctx );
+ }
+ return result;
+ }
+
+ //! $FUNCTION命令
+ bool function_( tree_node_t const& node, context* p_ctx )
+ {
+ bool result = true;
+
+ if ( node.children.empty() )
+ {
+ fatal( node.value.begin().line(), "no body of %1%", "'FUNCTION'" );
+ }
+
+ if ( p_ctx->in_function )
+ {
+ fatal( node.value.begin().line(), "function cannot be nested" );
+ }
+ p_ctx->in_function = true;
+
+ // 0 1 2 3 4
+ // $FUNCTION identifier $ top $END$
+ if ( eval_node( node.children[ 1 ], p_ctx ) ) // identifier
+ {
+ var_t ident( p_ctx->stack.top() ); p_ctx->stack.pop();
+ macro_processor::func_t func;
+ func.name = get_s( ident, p_ctx );
+ func.node = &node.children[ 3 ];
+ func.f = 0; // 組み込み関数ではないので
+ p_ctx->func_map[ func.name ] = func;
+ }
+ else
+ {
+ result = false;
+ }
+ p_ctx->in_function = false;
+ return result;
+ }
+
+ //! $IF命令
+ bool if_( tree_node_t const& node, context* p_ctx )
+ {
+ bool result = true;
+
+ if ( node.children.empty() )
+ {
+ fatal( node.value.begin().line(), "no body of %1%", "'IF' or 'ELSE'" );
+ }
+
+ // 0 1 2 3 4 5 6
+ // $IF expression $ top $END$
+ // $IF expression $ top $ELSE$ top $END$
+ if ( eval_node( node.children[ 1 ], p_ctx ) ) // expression
+ {
+ var_t expr( p_ctx->stack.top() ); p_ctx->stack.pop();
+ bool cond = false;
+ try
+ {
+ cond = !!get_i( expr, p_ctx );
+ }
+ catch ( expr_error& )
+ {
+ error( node.children[ 0 ].value.begin().line(), _( "`%1%\' does not have a value" ), get_s( expr, p_ctx ) );
+ throw;
+ }
+ if ( cond ) // $IF expr$
+ {
+ result &= eval_node( node.children[ 3 ], p_ctx ); // top
+ }
+ else if ( node.children.size() == 7 ) // $ELSE$
+ {
+ result &= eval_node( node.children[ 5 ], p_ctx ); // top
+ }
+ }
+ return result;
+ }
+
+ //! FOREACH命令
+ bool foreach_( tree_node_t const& node, context* p_ctx )
+ {
+ bool result = true;
+
+ if ( node.children.empty() )
+ {
+ fatal( node.value.begin().line(), "no body of %1%", "'FOREACH'" );
+ }
+
+ // 0 1 2 3 4 5
+ // $FOREACH identifier order_list $ top $END$
+ if ( eval_node( node.children[1], p_ctx ) ) // identifier
+ {
+ var_t ident( p_ctx->stack.top() ); p_ctx->stack.pop();
+ if ( eval_node( node.children[ 2 ], p_ctx ) ) // order_list
+ {
+ var_t order_list( p_ctx->stack.top() ); p_ctx->stack.pop();
+ if ( !order_list.empty() )
+ {
+ for ( var_t::const_iterator iter( order_list.begin() ), last( order_list.end() ); iter != last; ++iter )
+ {
+ p_ctx->var_map[ get_s( ident, p_ctx ) ] = var_t( 1, *iter );
+ result &= eval_node( node.children[ 4 ], p_ctx ); // top
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ //! $JOINEACH命令
+ bool joineach_( tree_node_t const& node, context* p_ctx )
+ {
+ bool result = true;
+
+ if ( node.children.empty() )
+ {
+ fatal( node.value.begin().line(), "no body of %1%", "'JOINEACH'" );
+ }
+
+ // 0 1 2 3 4 5 6
+ // $JOINEACH identifier order_list delimitor $ top $END$
+ if ( eval_node( node.children[ 1 ], p_ctx ) ) // identifier
+ {
+ var_t ident( p_ctx->stack.top() ); p_ctx->stack.pop();
+ if ( eval_node( node.children[ 2 ], p_ctx ) ) // order_list
+ {
+ var_t order_list( p_ctx->stack.top() ); p_ctx->stack.pop();
+ if ( !order_list.empty() && order_list[0].i )
+ {
+ if ( eval_node( node.children[ 3 ], p_ctx ) ) // delimitor
+ {
+ var_t delimitor( p_ctx->stack.top() ); p_ctx->stack.pop();
+ for ( var_t::const_iterator iter( order_list.begin() ), last( order_list.end() ); iter != last; ++iter )
+ {
+ p_ctx->var_map[ get_s( ident, p_ctx ) ] = var_t( 1, *iter );
+ result &= eval_node( node.children[ 5 ], p_ctx ); // top
+ if ( boost::next( iter ) != last )
+ {
+ p_ctx->target_file << get_s( delimitor, p_ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ //! $ERROR命令
+ bool error_( tree_node_t const& node, context* p_ctx )
+ {
+ // 0 1 2 3 4
+ // $ERROR$ top $END$
+ // $WARNING$ top $END$
+ // $ERROR expr $ top $END$
+ // $WARNING expr $ top $END$
+
+ if ( node.children.empty() )
+ {
+ fatal( node.value.begin().line(), "no body of %1%", "'ERROR' or 'WARNING'" );
+ }
+
+ output_file of = p_ctx->target_file;
+ p_ctx->target_file = output_file( "stderr", std::ios_base::out ); // 出力先を一時的に標準エラー出力に切り替える。
+
+ bool is_error = ( static_cast< parser::rule_id_t >( node.value.id().to_long() ) == parser::id_error_ );
+
+ p_ctx->target_file << get_program_name() << ':';
+
+ bool has_expr = ( node.children.size() > 3 );
+
+ if ( has_expr && eval_node( node.children[1], p_ctx ) ) // expr
+ {
+ var_t expr( p_ctx->stack.top() ); p_ctx->stack.pop();
+ if ( !expr.empty() )
+ {
+ if ( !expr.front().s.empty() )
+ {
+ p_ctx->target_file << expr.front().s << ':';
+ }
+ if ( expr.front().i )
+ {
+ p_ctx->target_file << expr.front().i.get() << ':';
+ }
+ }
+ }
+
+ p_ctx->target_file << ( is_error ? " error: " : " warning: " );
+
+ bool result = eval_node( node.children[has_expr ? 3 : 1], p_ctx ); // top
+ p_ctx->target_file << '\n';
+ p_ctx->target_file = of;
+
+ if ( is_error )
+ {
+ increment_error_count(); // error関数を使わないので、明示的にエラーカウントを操作する。
+ }
+ return result;
+ }
+
+ //! $WARNING命令
+ bool warning_( tree_node_t const& node, context* p_ctx )
+ {
+ return error_( node, p_ctx );
+ }
+
+ //! $FILE命令
+ bool file_( tree_node_t const& node, context* p_ctx )
+ {
+ // 0 1 2
+ // $FILE string-literal $
+ if ( eval_node( node.children[1], p_ctx ) ) // string-literal
+ {
+ var_t filename( p_ctx->stack.top() ); p_ctx->stack.pop();
+ p_ctx->target_file << '\n';
+ p_ctx->target_file = output_file( get_s( filename, p_ctx ), std::ios_base::out );
+ }
+ return true;
+ }
+
+ //! 式
+ bool expr_( tree_node_t const& node, context* p_ctx )
+ {
+ // 0 1 2
+ // $ expression $
+ if ( eval_node( node.children[ 1 ], p_ctx ) ) // expression
+ {
+ if ( node.children[1].value.id().to_long() == parser::id_expression )
+ {
+ var_t expr( p_ctx->stack.top() ); p_ctx->stack.pop();
+ p_ctx->target_file << get_s( expr, p_ctx );
+ }
+ }
+ return true;
+ }
+
+ // マクロ命令以外
+ bool plain( tree_node_t const& node, context* p_ctx )
+ {
+ std::string buf;
+ buf.reserve( node.children[ 0 ].value.end() - node.children[ 0 ].value.begin() );
+ for ( text::const_iterator iter( node.children[ 0 ].value.begin() ), last( node.children[0].value.end() ); iter != last; ++iter )
+ {
+ if ( *iter == '$' )
+ {
+ ++iter;
+ }
+ switch ( char c = *iter )
+ {
+ case '\r':
+ case '\n':
+ break;
+ default:
+ buf.push_back( c );
+ break;
+ }
+ }
+ p_ctx->target_file << buf;
+ return true;
+ }
+
+ // 構文木の各ノードの評価
+ bool eval_node( tree_node_t const& node, context* p_ctx )
+ {
+ bool result = true;
+ if ( p_ctx != 0 )
+ {
+ p_ctx->line = node.value.begin().line();
+ }
+
+#if defined( _MSC_VER ) && DEBUG_TRACE
+ ::OutputDebugString( ( boost::format( "%s:%d:%s\n" )
+ % node.children[ 0 ].value.begin().line().file
+ % node.children[ 0 ].value.begin().line().line
+ % std::string( node.children[ 0 ].value.begin(), node.children[ 0 ].value.end() )
+ ).str().c_str() );
+#endif
+
+ switch ( parser::rule_id_t id = static_cast< parser::rule_id_t >( node.value.id().to_long() ) )
+ {
+ case parser::id_expression:
+ result = eval_node( node.children[ 0 ], p_ctx );
+ break;
+ case parser::id_assignment_expr:
+ result = assignment_expr( node, p_ctx );
+ break;
+ case parser::id_logical_or_expr:
+ result = logical_or_expr( node, p_ctx );
+ break;
+ case parser::id_logical_and_expr:
+ result = logical_and_expr( node, p_ctx );
+ break;
+ case parser::id_or_expr:
+ result = or_expr( node, p_ctx );
+ break;
+ case parser::id_xor_expr:
+ result = xor_expr( node, p_ctx );
+ break;
+ case parser::id_and_expr:
+ result = and_expr( node, p_ctx );
+ break;
+ case parser::id_equality_expr:
+ result = equality_expr( node, p_ctx );
+ break;
+ case parser::id_relational_expr:
+ result = relational_expr( node, p_ctx );
+ break;
+ case parser::id_shift_expr:
+ result = shift_expr( node, p_ctx );
+ break;
+ case parser::id_additive_expr:
+ result = additive_expr( node, p_ctx );
+ break;
+ case parser::id_multiplicative_expr:
+ result = multiplicative_expr( node, p_ctx );
+ break;
+ case parser::id_unary_expr:
+ result = unary_expr( node, p_ctx );
+ break;
+ case parser::id_postfix_expr:
+ result = postfix_expr( node, p_ctx );
+ break;
+ case parser::id_primary_expr:
+ result = primary_expr( node, p_ctx );
+ break;
+ case parser::id_lvalue_expr:
+ result = lvalue_expr( node, p_ctx );
+ break;
+ case parser::id_identifier:
+ result = identifier( node, p_ctx );
+ break;
+ case parser::id_constant:
+ result = constant( node, p_ctx );
+ break;
+ case parser::id_string_literal:
+ result = string_literal( node, p_ctx );
+ break;
+ case parser::id_ordered_list:
+ result = ordered_list( node, p_ctx );
+ break;
+ case parser::id_ordered_sequence:
+ result = ordered_sequence( node, p_ctx );
+ break;
+ case parser::id_ordered_item:
+ result = ordered_item( node, p_ctx );
+ break;
+ case parser::id_root:
+ result = eval_node( node.children[0], p_ctx );
+ break;
+ case parser::id_top:
+ result = top( node, p_ctx );
+ break;
+ case parser::id_function_:
+ result = function_( node, p_ctx );
+ break;
+ case parser::id_if_:
+ result = if_( node, p_ctx );
+ break;
+ case parser::id_foreach_:
+ result = foreach_( node, p_ctx );
+ break;
+ case parser::id_joineach_:
+ result = joineach_( node, p_ctx );
+ break;
+ case parser::id_error_:
+ result = error_( node, p_ctx );
+ break;
+ case parser::id_warning_:
+ result = warning_( node, p_ctx );
+ break;
+ case parser::id_file_:
+ result = file_( node, p_ctx );
+ break;
+ case parser::id_expr_:
+ result = expr_( node, p_ctx );
+ break;
+ case parser::id_plain:
+ result = plain( node, p_ctx );
+ break;
+ default:
+ result = false;
+ break;
+ }
+ return result;
+ }
+
+ bool eval_text( text::const_iterator first, text::const_iterator last, context* p_ctx )
+ {
+ using namespace boost::spirit::classic;
+ typedef text::const_iterator iterator_t;
+ tree_parse_info< iterator_t, node_iter_data_factory<> > info;
+ info = pt_parse( first, last, parser(), space_p, node_iter_data_factory<>() );
+ if ( info.full && !info.trees.empty() )
+ {
+ bool result;
+ if ( info.length <= 0 )
+ {
+ result = true;
+ }
+ else
+ {
+ result = eval_node( info.trees[ 0 ], p_ctx );
+ }
+ return result;
+ }
+ else
+ {
+ fatal( info.stop.line(), _( "syntax error" ) );
+ }
+ return false;
+ }
+
+ }
+
+ std::tr1::int64_t macro_processor::to_integer( var_t const& var, context const* p_ctx )
+ {
+ return get_i( var, p_ctx );
+ }
+
+ std::string macro_processor::to_string( var_t const& var, context const* p_ctx )
+ {
+ return get_s( var, p_ctx );
+ }
+
+ macro_processor::macro_processor()
+ : p_ctx_( new context )
+ {
+ }
+
+ macro_processor::macro_processor( macro_processor const& other )
+ : p_ctx_( new context( *other.p_ctx_ ) )
+ {
+ }
+
+ macro_processor::macro_processor( text const& in )
+ : p_ctx_( new context )
+ {
+ evaluate( in );
+ }
+
+ macro_processor::~macro_processor()
+ {
+ delete p_ctx_;
+ p_ctx_ = 0;
+ }
+
+ macro_processor& macro_processor::operator=( macro_processor const& other )
+ {
+ macro_processor t( *this );
+ swap( t );
+ return *this;
+ }
+
+ void macro_processor::swap( macro_processor& other )
+ {
+ std::swap( p_ctx_, other.p_ctx_ );
+ }
+
+ void macro_processor::evaluate( text const& in )
+ {
+ try
+ {
+ for ( func_t const* p_bf = builtin_function_table; !p_bf->name.empty(); p_bf++ )
+ {
+ p_ctx_->func_map[ p_bf->name ] = *p_bf;
+ }
+ if ( !eval_text( in.begin(), in.end(), p_ctx_ ) )
+ {
+ fatal( _( "macro processing error" ) );
+ }
+ }
+ catch ( expr_error& )
+ {
+ fatal( _( "macro processing error" ) );
+ }
+ }
+
+ void macro_processor::set_var( std::string const& name, var_t const& value )
+ {
+#if defined( _MSC_VER ) && /* DEBUG_TRACE */ 1
+ std::string s( "$" + name + " = " + get_s( value, p_ctx_ ) + "$" );
+ if ( !value.empty() && value[ 0 ].i )
+ {
+ s += "(" + boost::lexical_cast< std::string >( get_i( value, p_ctx_ ) ) + ")";
+ }
+ s += "\n";
+ ::OutputDebugString( s.c_str() );
+#endif
+ p_ctx_->var_map[ name ] = value;
+ }
+
+ void macro_processor::set_var( std::string const& name, long name2, var_t const& value )
+ {
+ set_var( ( boost::format( "%s[%d]" ) % name % name2 ).str(), value );
+ }
+
+ macro_processor::var_t const& macro_processor::get_var( std::string const& name ) const
+ {
+ return p_ctx_->var_map[ name ];
+ }
+
+ macro_processor::var_t const& macro_processor::get_var( std::string const& name, long name2 ) const
+ {
+ return get_var( ( boost::format( "%s[%d]" ) % name % name2 ).str() );
+ }
+
+ /*!
+ * \brief コメントの除去
+ * \param[in] first 処理対象シーケンスの先頭位置
+ * \param[in] last 処理対象シーケンスの終端位置の次
+ * \param[out] result 処理結果の格納先
+ * \return 処理完了後の result の値
+ *
+ * 「$ + 空白類文字」で始まり、改行で終わるコメントを除去します。
+ */
+ void macro_processor::remove_comment( text const& in, text& out )
+ {
+ text::const_iterator first( in.begin() ), last( in.end() );
+ std::back_insert_iterator< text > result( std::back_inserter( out ) );
+ out.set_line( first.line().file, first.line().line );
+
+ for ( text::const_iterator iter; ( iter = std::find( first, last, '\n' ) ) != last ; first = iter + 1 )
+ {
+ std::string buf( first, iter );
+ if ( ( ( buf[0] == '$' ) && ( buf.size() >= 2 ) && std::isspace( static_cast< unsigned char >( buf[1] ) ) ) )
+ {
+ *result = '\n';
+ }
+ else
+ {
+ // コメント行以外は行頭の空白類を除去する。
+ first = std::find_if( first, iter, std::not1( std::ptr_fun< char, bool >( &toppers::isspace ) ) );
+ result = std::copy( first, iter + 1, result );
+ }
+ }
+ }
+
+ void macro_processor::expand_include( text const& in, text& out )
+ {
+ typedef text::container::const_iterator const_row_iterator;
+ typedef std::string::size_type size_type;
+ size_type const npos = std::string::npos;
+std::string debug_str;
+
+ if ( in.empty() ) // 空のファイルが入力された場合の対策
+ {
+ return;
+ }
+
+ const_row_iterator first( in.begin().get_row() ), last( in.end().get_row() );
+
+ out.set_line( first->line.file, first->line.line );
+ for ( const_row_iterator iter( first ); iter != last; ++iter )
+ {
+ std::string const& buf = iter->buf;
+
+ for ( size_type i = 0, n = buf.size(); i != n; ++i )
+ {
+ using namespace boost::spirit::classic;
+ char c = buf[i];
+ std::string headername;
+ text::const_iterator iter2( iter, i );
+ if ( iter2 == in.end() )
+ {
+ break;
+ }
+ parse_info< text::const_iterator > info
+ = parse( iter2, in.end(),
+ ( ch_p( '$' ) >> str_p( "INCLUDE" ) >> *space_p
+ >> '\"' >> ( +( anychar_p - '\"' ) )[ assign( headername ) ] >> '\"'
+ >> '$' ) );
+ if ( info.hit )
+ {
+ std::vector< std::string > include_paths = get_global< std::vector< std::string > >( "include-path" );
+ std::string hname = search_include_file( include_paths.begin(), include_paths.end(), headername );
+ if ( hname.empty() )
+ {
+ fatal( iter->line, _( "cannot open file `%1%\'" ), headername );
+ }
+ else
+ {
+ text t;
+ t.set_line( hname, 1 );
+ std::ifstream ifs( hname.c_str() );
+ t.append( ifs );
+
+ preprocess( t, out );
+ iter = info.stop.get_row();
+ i = info.stop.get_col() - 1;
+ out.set_line( iter->line.file, iter->line.line );
+ }
+ }
+ else
+ {
+ out.push_back( c );
+ debug_str.push_back( c );
+ if ( c == '\n' )
+ {
+// ::OutputDebugString( ( out.get_line().file + ":" + boost::lexical_cast< std::string >( out.get_line().line ) + ":" ).c_str() );
+// ::OutputDebugString( debug_str.c_str() );
+ debug_str.clear();
+ }
+ }
+ }
+ }
+ }
+
+ void macro_processor::preprocess( text const& in, text& out )
+ {
+ if ( in.empty() )
+ {
+ return;
+ }
+ text temp;
+ macro_processor::remove_comment( in, temp );
+ expand_include( temp, out );
+ }
+
+ void macro_processor::add_builtin_function( func_t const& f )
+ {
+ p_ctx_->func_map[ f.name ] = f;
+ }
+
+ macro_processor::var_t macro_processor::call_user_function( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx )
+ {
+ if ( arg_list.empty() )
+ {
+ return var_t();
+ }
+
+ func_t func = p_ctx->func_map[ get_s( arg_list.front(), p_ctx ) ];
+ if ( func.name.empty() )
+ {
+ fatal( line, "function is not defined" );
+ return var_t();
+ }
+
+ // ARGC
+ {
+ element e;
+ e.i = static_cast< std::tr1::int64_t >( arg_list.size() );
+ p_ctx->var_map[ "ARGC" ] =var_t( 1, e );
+ }
+
+ // ARGV
+ {
+ std::size_t n = arg_list.size();
+ for ( std::size_t i = 0; i < n; i++ )
+ {
+ std::string argv_i = boost::str( boost::format( "ARGV[%d]" ) % i );
+ p_ctx->var_map[ argv_i ] = arg_list[ i ];
+ }
+
+ std::string argv_n = boost::str( boost::format( "ARGV[%d]" ) % n );
+ p_ctx->var_map[ argv_n ] = var_t();
+ }
+
+ tree_node_t const* func_body_node = reinterpret_cast< tree_node_t const* >( func.node );
+ if ( !eval_node( *func_body_node, p_ctx ) )
+ {
+ return var_t();
+ }
+
+ return p_ctx->var_map[ "RESULT" ];
+ }
+
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/*!
+ * \file toppers/macro_processor.hpp
+ * \brief マクロ処理のための宣言定義
+ *
+ * このファイルで定義されるクラス
+ * \code
+ * class macro_processor;
+ * \endcode
+ */
+#ifndef TOPPERS_MACRO_PROCESSOR_HPP_
+#define TOPPERS_MACRO_PROCESSOR_HPP_
+
+#include <string>
+#include <vector>
+#include <stack>
+#include <map>
+#include "toppers/workaround.hpp"
+#include "toppers/output_file.hpp"
+#include "toppers/text.hpp"
+
+namespace toppers
+{
+
+ class macro_processor
+ {
+ public:
+ struct context;
+
+ /*!
+ * \struct element macro_processor.hpp "toppers/macro_processor.hpp"
+ * \brief マクロ中で使用する変数の値
+ *
+ * 正確には、変数の値は常に順序付きリストとして扱われます。element は順序付きリストの 1 要素を表します。
+ */
+ struct element
+ {
+ boost::optional< std::tr1::int64_t > i;
+ std::string v;
+ std::string s;
+ };
+ /*!
+ * \brief マクロ中で使用する変数を表現する型
+ */
+ typedef std::vector< element > var_t;
+
+ /*!
+ * \struct func_t macro_processor.hpp "toppers/macro_processor.hpp"
+ * \brief マクロ内で扱う関数を表現する型
+ * \note 元々単純な構造体であったため、互換性のため、集成体と特性を維持させている。
+ * \attention node の初期化忘れに要注意
+ */
+ struct func_t
+ {
+ std::string name; //!< 関数名
+ var_t ( * f )( text_line const& line, std::vector< var_t > const&, context* ); //!< 処理内容
+ void const* node;
+ };
+
+ struct context
+ {
+ std::stack< var_t > stack;
+ std::map< std::string, var_t > var_map;
+ std::map< std::string, func_t > func_map;
+ bool in_function;
+ output_file target_file;
+ text_line line;
+ context() : in_function( false ) {}
+ };
+
+ macro_processor();
+ macro_processor( macro_processor const& other );
+ explicit macro_processor( text const& in );
+ ~macro_processor();
+ macro_processor& operator=( macro_processor const& other );
+ void swap( macro_processor& other );
+ void evaluate( text const& in );
+ void set_var( std::string const& name, var_t const& value );
+ void set_var( std::string const& name, long name2, var_t const& value );
+ var_t const& get_var( std::string const& name ) const;
+ var_t const& get_var( std::string const& name, long name2 ) const;
+ void add_builtin_function( func_t const& f );
+
+ static void remove_comment( text const& in, text& out );
+ static void expand_include( text const& in, text& out );
+ static void preprocess( text const& in, text& out );
+ static std::tr1::int64_t to_integer( var_t const& var, context const* p_ctx );
+ static std::string to_string( var_t const& var, context const* p_ctx );
+ static bool check_arity( text_line const& line, std::size_t arity, std::size_t valid, char const* function_name );
+ static var_t call_user_function( text_line const& line, std::vector< var_t > const& arg_list, context* p_ctx );
+ private:
+ context* p_ctx_;
+ static func_t const builtin_function_table[];
+ };
+
+ inline bool operator == ( macro_processor::element const& lhs, macro_processor::element const& rhs )
+ {
+ return lhs.i == rhs.i;
+ }
+
+ inline bool operator < ( macro_processor::element const& lhs, macro_processor::element const& rhs )
+ {
+ return lhs.i < rhs.i;
+ }
+
+ struct element_eq
+ {
+ explicit element_eq( std::tr1::int64_t value ) : value_( value ) {}
+ bool operator()( toppers::macro_processor::element const& e ) const
+ {
+ return e.i && ( e.i.get() == value_ );
+ }
+ std::tr1::int64_t value_;
+ };
+
+}
+
+#endif // ! TOPPERS_MACRO_PROCESSOR_HPP_
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2005-2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/*
+ * toppers/mbchar_parser.cpp
+ */
+#include "toppers/c_parser.hpp"
+
+namespace toppers
+{
+
+ //! ASCII文字パーサー
+ boost::spirit::classic::functor_parser< detail::mbchar_parse_functor< ascii > > const ascii_p;
+
+ //! ShiftJIS文字パーサー
+ boost::spirit::classic::functor_parser< detail::mbchar_parse_functor< shift_jis > > const shift_jis_p;
+
+ //! EUC-JP文字パーサー
+ boost::spirit::classic::functor_parser< detail::mbchar_parse_functor< euc_jp > > const euc_jp_p;
+
+ //! UTF-8文字パーサー
+ boost::spirit::classic::functor_parser< detail::mbchar_parse_functor< utf8 > > const utf8_p;
+
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2005-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/*!
+ * \file toppers/misc.hpp
+ * \brief 雑多なライブラリのための宣言定義
+ */
+#ifndef TOPPERS_MISC_HPP_
+#define TOPPERS_MISC_HPP_
+
+#include <stdexcept>
+#include <locale>
+#include <iosfwd>
+#include <string>
+#include <algorithm>
+#include <cctype>
+#include <cwchar>
+#include <cwctype>
+#include <cstdlib>
+#include "toppers/codeset.hpp"
+#include <boost/scoped_array.hpp>
+
+// workaround
+#include <ctype.h>
+#include <wctype.h>
+
+#define TOPPERS_STRINGIFY( s ) TOPPERS_STRINGIFY_( s )
+#define TOPPERS_STRINGIFY_( s ) # s
+
+namespace toppers
+{
+
+ /*!
+ * \class conversion_error misc.hpp "toppers/misc.hpp"
+ * \brief 変換エラー例外クラス
+ */
+ class conversion_error : public std::runtime_error
+ {
+ public:
+ /*!
+ * \brief コンストラクタ
+ * \param what 例外原因文字列
+ */
+ explicit conversion_error( std::string const& what ) : std::runtime_error( what ) {}
+ };
+
+ /*!
+ * \brief シングルバイト文字から CharT 型(多くは wchar_t 型)文字への変換
+ * \param ch シングルバイト文字
+ * \return CharT 型文字を返す
+ */
+ template < typename CharT >
+ inline CharT widen( char ch )
+ {
+ return std::use_facet< std::ctype< CharT > >( std::locale() ).widen( ch );
+ }
+
+ template <>
+ inline char widen< char >( char ch )
+ {
+ return ch;
+ }
+
+ template <>
+ inline unsigned char widen< unsigned char >( char ch )
+ {
+ return static_cast< unsigned char >( ch );
+ }
+
+ template <>
+ inline wchar_t widen< wchar_t >( char ch )
+ {
+#if defined( __MINGW32__ )
+ wchar_t wc = wchar_t( -1 );
+ if ( std::mbtowc( &wc, &ch, 1 ) < 0 )
+ {
+ return WEOF;
+ }
+ return wc;
+#elif defined( __CYGWIN__ )
+ return static_cast< wchar_t >( static_cast< unsigned char >( ch ) );
+#else
+ return static_cast< wchar_t >( std::btowc( static_cast< unsigned char >( ch ) ) );
+#endif
+ }
+
+ /*!
+ * \brief シングルバイト文字列から CharT 型文字列への変換
+ * \param str シングルバイト文字列
+ * \return CharT 型文字列を返す
+ */
+ template < typename CharT >
+ std::basic_string< CharT > const widen( std::string const& str );
+
+ template <>
+ inline std::basic_string< char > const widen( std::string const& str )
+ {
+ return str;
+ }
+
+ template <>
+ inline std::basic_string< wchar_t > const widen( std::string const& str )
+ {
+ boost::scoped_array< wchar_t > t( new wchar_t[str.size()+1] );
+ if ( std::mbstowcs( t.get(), str.c_str(), str.size() ) == size_t( -1 ) )
+ {
+ static conversion_error x( "in function widen" );
+ throw x;
+ }
+ return t.get();
+ }
+
+#undef tolower
+
+ /*!
+ * \brief 小文字への変換
+ * \param ch 変換対象の文字
+ * \return ch が大文字であれば対応する小文字を、それ以外は ch を返す
+ */
+ inline char tolower( char ch )
+ {
+ return static_cast< char >( std::tolower( static_cast< unsigned char >( ch ) ) );
+ }
+
+ /*!
+ * \brief 文字列を小文字に変換
+ * \param str 変換対象の文字
+ * \return str に含まれる大文字を小文字に変換した文字列を返す
+ */
+ inline std::string const tolower( std::string str )
+ {
+ char ( *f )( char ) = &tolower;
+ std::transform( str.begin(), str.end(), str.begin(), f );
+ return str;
+ }
+
+ /*!
+ * \brief ワイド文字列を小文字に変換
+ * \param str 変換対象の文字
+ * \return str に含まれる大文字を小文字に変換したワイド文字列を返す
+ */
+ template < class Traits, class Allocator >
+ std::basic_string< wchar_t, Traits, Allocator > const tolower( std::basic_string< wchar_t, Traits, Allocator > str )
+ {
+ wint_t ( *f )( wint_t ) = &towlower;
+ std::transform( str.begin(), str.end(), str.begin(), f );
+ return str;
+ }
+
+#undef toupper
+
+ /*!
+ * \brief 大文字への変換
+ * \param ch 変換対象の文字
+ * \return ch が小文字であれば対応する大文字を、それ以外は ch を返す
+ */
+ inline char toupper( char ch )
+ {
+ return static_cast< char >( std::toupper( static_cast< unsigned char >( ch ) ) );
+ }
+
+ /*!
+ * \brief 文字列を大文字に変換
+ * \param str 変換対象の文字
+ * \return str に含まれる小文字を大文字に変換した文字列を返す
+ */
+ inline std::string const toupper( std::string str )
+ {
+ char ( *f )( char ) = &toupper;
+ std::transform( str.begin(), str.end(), str.begin(), f );
+ return str;
+ }
+
+ /*!
+ * \brief ワイド文字列を大文字に変換
+ * \param str 変換対象の文字
+ * \return str に含まれる小文字を大文字に変換したワイド文字列を返す
+ */
+ template < class Traits, class Allocator >
+ std::basic_string< wchar_t, Traits, Allocator > const toupper( std::basic_string< wchar_t, Traits, Allocator > str )
+ {
+ wint_t ( *f )( wint_t ) = &towupper;
+ std::transform( str.begin(), str.end(), str.begin(), f );
+ return str;
+ }
+
+#undef isspace
+
+ /*!
+ * \brief 空白類の判別
+ *
+ */
+ inline bool isspace( char ch )
+ {
+ return std::isspace( static_cast< unsigned char >( ch ) ) != 0;
+ }
+
+ /*!
+ * \brief 指定文字で区切られたリスト出力
+ * \param first 出力する先頭要素位置
+ * \param last 出力する終端要素位置+1
+ * \param ostr 出力ストリーム
+ * \param pred 各要素を受け取り出力値を返す述語
+ * \param delim 区切文字
+ *
+ * この関数は区間 [first, last) の各要素を pred に渡して得られる値を delim
+ * で区切って ostr に出力します。\n
+ * 終端の要素の後には delim は出力されず、要素と要素の間にのみ delim が
+ * 出力されます。
+ */
+ template < class InputIterator, typename CharT, class Traits, class Pred >
+ void output_list( InputIterator first, InputIterator last, std::basic_ostream< CharT, Traits >& ostr, Pred pred, CharT const* delim = 0 )
+ {
+ if ( delim == 0 )
+ {
+ static CharT const null_delim[] = { 0 };
+ delim = null_delim;
+ }
+
+ for ( bool f = false; first != last; ++first )
+ {
+ if ( f )
+ {
+ ostr << delim;
+ }
+ ostr << pred( *first );
+ f = true;
+ }
+ }
+
+ template < typename CharT, class Traits, class Allocator >
+ std::basic_string< CharT, Traits, Allocator > trim( std::basic_string< CharT, Traits, Allocator > const& str, std::basic_string< CharT, Traits, Allocator > const& ws )
+ {
+ if ( str.empty() || ws.empty() )
+ {
+ return str;
+ }
+ typename std::basic_string< CharT, Traits, Allocator >::size_type first = str.find_first_not_of( ws, 0 );
+ for ( typename std::basic_string< CharT, Traits, Allocator >::size_type i = str.size() - 1; i >= 0; i-- )
+ {
+ if ( ws.find( str[ i ] ) == ws.npos )
+ {
+ return str.substr( first, i );
+ }
+ }
+ return str.substr( first );
+ }
+
+}
+
+#endif // ! TOPPERS_MISC_HPP_
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2005-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/*
+ * toppers/nm_symbol.cpp
+ */
+#include "toppers/nm_symbol.hpp"
+#include <istream>
+#include <sstream>
+#include <cctype>
+
+namespace toppers
+{
+
+ /*!
+ * \brief シンボルテーブルのロード
+ * \param istr 入力ストリーム
+ */
+ void nm_symbol::load( std::istream& istr )
+ {
+ while ( istr )
+ {
+ std::string buf;
+ std::getline( istr, buf );
+ std::istringstream isstr( buf );
+
+ unsigned long address = 0;
+ char type;
+ std::string symbol;
+ if ( !std::isspace( static_cast< unsigned char >( buf[0] ) ) )
+ {
+ isstr >> std::hex >> address;
+ }
+ isstr >> type >> symbol;
+
+ if ( !symbol.empty() )
+ {
+ entry e;
+ e.address = address;
+ e.type = static_cast< unsigned char >( type );
+ symbol_map_[symbol] = e;
+ }
+ }
+ }
+
+ /*!
+ * \brief シンボルの探索
+ * \param symbol 探索するシンボル文字列
+ * \return シンボルに対応するエントリを返す
+ */
+ nm_symbol::entry const nm_symbol::find( std::string const& symbol ) const
+ {
+ std::map< std::string, entry >::const_iterator iter( symbol_map_.find( symbol ) );
+ entry e = { 0, -1 };
+ if ( iter != symbol_map_.end() )
+ {
+ e = iter->second;
+ }
+ else
+ {
+ iter = symbol_map_.find( "_" + symbol ); // 識別子に'_'が付加される場合に対応
+ if ( iter != symbol_map_.end() )
+ {
+ e = iter->second;
+ }
+ }
+ return e;
+ }
+
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2005-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/*!
+ * \file toppers/nm_symbol.hpp
+ * \brief "nm"コマンドで得られるシンボルテーブルを扱うための宣言定義
+ *
+ * このファイルで定義されるクラス
+ * \code
+ * class nm_symbol;
+ * \endcode
+ */
+#ifndef TOPPERS_NM_SYMBOL_HPP_
+#define TOPPERS_NM_SYMBOL_HPP_
+
+#include "toppers/config.hpp"
+#include <iosfwd>
+#include <string>
+#include <map>
+
+namespace toppers
+{
+
+ /*!
+ * \class nm_symbol nm_symbol.hpp "toppers/nm_symbol.hpp"
+ * \brief `nm'コマンドで得られるシンボルテーブルを扱うためのクラス
+ *
+ * \sa nm_symbol::entry
+ */
+ class nm_symbol
+ {
+ public:
+ /*!
+ * \struct entry nm_symbol.hpp "toppers/nm_symbol.hpp"
+ * \brief アドレスとタイプ情報を格納する構造体
+ *
+ * `nm'コマンドの出力結果が、
+ * \code
+ * 01234567 T foo
+ * \endcode
+ * となった場合、0x01234567が address に、'T'が type に格納されます。
+ */
+ struct entry
+ {
+ unsigned long address;
+ int type;
+ };
+
+ /*!
+ * \brief デフォルトコンストラクタ
+ */
+ nm_symbol() {}
+ /*!
+ * \brief コンストラクタ
+ * \param istr 入力ストリーム
+ */
+ explicit nm_symbol( std::istream& istr ) { load( istr ); }
+
+ void load( std::istream& istr );
+ entry const find( std::string const& symbol ) const;
+ private:
+ std::map< std::string, entry > symbol_map_;
+ };
+
+}
+
+#endif // ! TOPPERS_NM_SYMBOL_HPP_
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+#include <map>
+#include <iostream>
+#include <sstream>
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/operations.hpp>
+#include "toppers/workaround.hpp"
+#include "toppers/output_file.hpp"
+#include "toppers/io.hpp"
+#include "toppers/global.hpp"
+#include "toppers/diagnostics.hpp"
+
+namespace toppers
+{
+ namespace
+ {
+ struct context
+ {
+ std::ostringstream ostr;
+ std::string tempname;
+ };
+
+ typedef std::map< std::string, std::tr1::shared_ptr< context > > context_map;
+
+ inline context_map& get_context_map()
+ {
+ static context_map m;
+ return m;
+ }
+ }
+
+ /*!
+ * \brief 出力ストリームの参照
+ * \return 出力ストリーム
+ *
+ * 設定されているファイルに出力するための出力ストリームを返す。
+ * 既に出力ストリームが生成されている場合はその参照を返し、そうでなければ新たに出力ストリームを生成する。
+ *
+ * ファイル名として、"stdout"が設定されていれば標準出力、"stderr"が設定されていれば標準エラー出力になる。
+ */
+ std::ostream& output_file::ostr() const
+ {
+ if ( filename_ == "stdout" )
+ {
+ return std::cout;
+ }
+ else if ( filename_ == "stderr" )
+ {
+ return std::cerr;
+ }
+
+ std::string path( path_name( filename_ ) );
+ context_map::const_iterator iter( get_context_map().find( path ) );
+ if ( iter == get_context_map().end() )
+ {
+ std::tr1::shared_ptr< context > ctx( new context );
+ get_context_map().insert( std::make_pair( path, ctx ) );
+ return ctx->ostr;
+ }
+ return iter->second->ostr;
+ }
+
+ /*!
+ * \brief メモリ上に格納されている内容を実際にファイルに出力する。
+ *
+ * context_map としてメモリ上に格納された内容を、それぞれのファイルに対して出力する。
+ * 出力するにあたり、まず元のファイルを .org を付けたファイル名に変更する。
+ * ここで、以前にあった .org は破壊される。
+ * ファイルを順に書き込み、途中でエラーが発生した場合は、.org を元のファイル名に戻す。
+ * 途中でひとつでもエラーが発生した場合は、全ファイルについて .org を元に戻す。
+ * 以前にあった .org は復活しない。
+ */
+ void output_file::save()
+ {
+ namespace fs = boost::filesystem;
+ std::vector< std::string > saved_files;
+
+ try
+ {
+ for ( context_map::const_iterator iter( get_context_map().begin() ), last( get_context_map().end() );
+ iter != last;
+ ++iter )
+ {
+ if ( iter->first != "" )
+ {
+ fs::path filename( iter->first, fs::native );
+ fs::path backup( iter->first + ".org", fs::native );
+ bool existed = fs::exists( filename );
+
+ try
+ {
+ std::string file( filename.native_file_string() );
+ if ( existed )
+ {
+ fs::rename( filename, backup );
+ }
+ write( file, iter->second->ostr.str() ); // ここで書き込む
+ saved_files.push_back( file );
+ fs::remove( backup );
+ }
+ catch ( ... )
+ {
+ if ( existed )
+ {
+ fs::remove( filename );
+ fs::rename( backup, filename );
+ }
+ throw;
+ }
+ }
+ }
+ }
+ catch ( ... )
+ {
+ // すでに書き込んだファイルを元に戻す。
+ for ( std::vector< std::string >::const_iterator iter( saved_files.begin() ), last( saved_files.end() );
+ iter != last;
+ ++iter )
+ {
+ fs::path filename( *iter, fs::native );
+ fs::remove( filename );
+ fs::path backup( *iter + ".org", fs::native );
+ if ( fs::exists( backup ) )
+ {
+ fs::rename( backup, filename );
+ }
+ }
+ throw;
+ }
+ }
+
+ /*!
+ * \brief 指定したファイル名に対応したパス名を返す。
+ * \param[in] filename ファイル名
+ * \return パス名
+ *
+ * --output-directory オプションで指定した出力先ディレクトリを反映したパス名を生成する。
+ * ただし、下記のファイル名の場合はそのままの文字列を返す。
+ * - "stdout"
+ * - "stderr"
+ * - ""
+ */
+ std::string output_file::path_name( std::string const& filename )
+ {
+ if ( filename == "stdin" || filename == "stderr" || filename == "" )
+ {
+ return filename;
+ }
+ namespace fs = boost::filesystem;
+ boost::any output_directory = global( "output-directory" );
+ if ( output_directory.empty() )
+ {
+ return filename;
+ }
+ fs::path dir( get_global< std::string >( "output-directory" ), fs::native );
+ return ( dir/filename ).native_file_string();
+ }
+
+ /*!
+ * \brief 指定ファイルへの書き込みデータを参照
+ * \param[in] filename 出力先のファイル名
+ * \return 書き込みデータ
+ */
+ std::string output_file::get_file_data( std::string const& filename )
+ {
+ context_map::const_iterator iter( get_context_map().find( path_name( filename ) ) ), last( get_context_map().end() );
+ if ( iter != last )
+ {
+ return iter->second->ostr.str();
+ }
+ return "";
+ }
+
+ /*!
+ * \brief 指定ファイルへの書き込みデータを設定
+ * \param[in] filename 出力先のファイル名
+ * \param[in] data 書き込みデータ
+ * \retval true 設定成功
+ * \retval false 設定失敗
+ */
+ bool output_file::set_file_data( std::string const& filename, std::string const& data )
+ {
+ output_file ofile( filename, std::ios_base::out );
+ dynamic_cast< std::ostringstream& >( ofile.ostr() ).str( data );
+ return true;
+ }
+
+ /*!
+ * \brief メモリ上に格納されている書き込みようデータを消去
+ * \param[in] filename 出力先のファイル名
+ * \retval true データの消去成功
+ * \retval false 指定したファイルへの出力データが存在しない
+ */
+ bool output_file::clear_file_data( std::string const& filename )
+ {
+ context_map::const_iterator iter( get_context_map().find( path_name( filename ) ) ), last( get_context_map().end() );
+ if ( iter != last )
+ {
+ iter->second->ostr.str( "" );
+ return true;
+ }
+ return false;
+ }
+
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/*!
+ * \file toppers/output_file.hpp
+ * \brief 出力ファイル管理を扱うための宣言定義
+ *
+ * このファイルで定義されるクラス
+ * \code
+ * class output_file;
+ * \endcode
+ */
+#ifndef TOPPERS_OUTPUT_FILE_HPP_
+#define TOPPERS_OUTPUT_FILE_HPP_
+
+#include <ostream>
+#include <string>
+#include "toppers/config.hpp"
+
+namespace toppers
+{
+
+ /*!
+ * \class output_file output_file.hpp "toppers/output_file.hpp"
+ * \brief 出力ファイル管理クラス
+ */
+ class output_file
+ {
+ public:
+ output_file() : omode_( static_cast< std::ios_base::openmode >( 0 ) ) {}
+ output_file( std::string const& filename, std::ios_base::openmode omode )
+ : filename_( filename ), omode_( omode ), enable_( true ) {}
+ virtual ~output_file() {}
+
+ std::ostream& ostr() const;
+ std::string const& file_name() const { return filename_; }
+ bool is_enable() const { return enable_; }
+ void enable( bool flag = true ) { enable_ = flag; }
+ void push_back( char c )
+ {
+ if ( enable_ )
+ {
+ ostr() << c;
+ }
+ }
+
+ static std::string path_name( std::string const& filename );
+ static std::string get_file_data( std::string const& filename );
+ static bool set_file_data( std::string const& filename, std::string const& data );
+ static bool clear_file_data( std::string const& filename );
+ static void save();
+ private:
+ std::string filename_;
+ std::ios_base::openmode omode_;
+ bool enable_;
+ };
+
+ template < typename T >
+ inline output_file const& operator << ( output_file const& ofile, T const& value )
+ {
+ if ( ofile.is_enable() )
+ {
+ ofile.ostr() << value;
+ }
+ return ofile;
+ }
+
+}
+
+#endif // ! TOPPERS_OUTPUT_FILE_HPP_
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2005-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/*
+ * toppers/s_record.cpp
+ */
+#include "toppers/s_record.hpp"
+#include <istream>
+#include <algorithm>
+#include <cctype>
+#include <cstring>
+
+namespace toppers
+{
+
+ /*!
+ * \brief Sレコードのロード
+ * \param istr 入力ストリーム
+ */
+ void s_record::load( std::istream& istr )
+ {
+ int type = -1;
+
+ while ( istr )
+ {
+ std::string buf;
+ std::getline( istr, buf );
+ if ( buf.empty() )
+ {
+ break;
+ }
+ record rec = read_record( buf );
+
+ // あまり厳密には処理しない
+ if ( '1' <= rec.type && rec.type <= '3' )
+ {
+ bool done = false;
+ typedef std::vector< value_type >::iterator iterator;
+ for ( iterator iter( data_.begin() ), last( data_.end() ); iter != last; ++iter )
+ {
+ if ( rec.address == iter->first + iter->second.size() )
+ {
+ std::copy( rec.data.begin(), rec.data.end(), std::back_inserter( iter->second ) );
+ done = true;
+ }
+ }
+ if ( !done )
+ {
+ data_.push_back( value_type( rec.address, std::vector< unsigned char >( rec.data.begin(), rec.data.end() ) ) );
+ }
+ }
+ type = rec.type;
+ }
+
+ cache_ = data_.begin();
+ }
+
+ /*!
+ * \brief 指定アドレスのバイトデータ取得
+ * \param address アドレス指定
+ * \return address で指定したアドレスのバイトデータを返す
+ */
+ int s_record::operator[]( size_type address ) const
+ {
+ typedef std::vector< value_type >::const_iterator const_iterator;
+ if ( cache_ != data_.end() )
+ {
+ const_iterator iter( cache_ );
+ if ( iter->first <= address && address < iter->first + iter->second.size() )
+ {
+ return iter->second.at( address - iter->first );
+ }
+ }
+ for ( const_iterator iter( cache_ ), last( data_.end() ); iter != last; ++iter )
+ {
+ if ( iter->first <= address && address < iter->first + iter->second.size() )
+ {
+ cache_ = iter;
+ return iter->second.at( address - iter->first );
+ }
+ }
+ for ( const_iterator iter( data_.begin() ), last( cache_ ); iter != last; ++iter )
+ {
+ if ( iter->first <= address && address < iter->first + iter->second.size() )
+ {
+ cache_ = iter;
+ return iter->second.at( address - iter->first );
+ }
+ }
+ return -1;
+ }
+
+ /*!
+ * \brief Sレコード中の整数値読み込み
+ * \param base 読み込み位置の先頭アドレス
+ * \param size 整数値のバイト数
+ * \param little_endian リトルエンディアンなら true、ビッグエンディアンなら false を指定
+ * \return 読み込んだ整数値を返す
+ */
+ boost::uintmax_t s_record::get_value( std::size_t base, std::size_t size, bool little_endian ) const
+ {
+ boost::uintmax_t value = 0;
+ if ( little_endian )
+ {
+ for ( long j = static_cast< long >( size-1 ); j >= 0; j-- )
+ {
+ int t = ( *this )[ base + j ];
+ if ( t < 0 )
+ {
+ throw data_error();
+ }
+ value = ( value << 8 ) | ( t & 0xff );
+ }
+ }
+ else
+ {
+ for ( std::size_t j = 0; j < size; j++ )
+ {
+ int t = ( *this )[ base + j ];
+ if ( t < 0 )
+ {
+ throw data_error();
+ }
+ value = ( value << 8 ) | ( t & 0xff );
+ }
+ }
+ return value;
+ }
+
+ unsigned long s_record::lower_bound() const
+ {
+ return data_.front().first;
+ }
+
+ unsigned long s_record::upper_bound() const
+ {
+ return data_.back().first + data_.back().second.size();
+ }
+
+ /*!
+ * \brief Sレコードの1行読み込み
+ * \param rec_buf 1行バッファ
+ * \return 読み込み結果を返す
+ */
+ s_record::record const s_record::read_record( std::string const& rec_buf )
+ {
+ std::string buf( rec_buf );
+
+ // 行末に'\r'または'\n'が残留している場合の対策
+ while ( std::isspace( static_cast< unsigned char >( *buf.rbegin() ) ) )
+ {
+ buf = buf.substr( 0, buf.size()-1 );
+ }
+
+ if ( buf.size() < 10 || buf[0] != 'S' )
+ {
+ throw format_error();
+ }
+ int ch = static_cast< unsigned char >( buf[1] );
+ int address_length = 4;
+ std::string::size_type size = buf.size();
+
+ switch ( ch )
+ {
+ case '1':
+ case '9':
+ address_length = 4;
+ break;
+ case '2':
+ case '8':
+ address_length = 6;
+ break;
+ case '3':
+ case '7':
+ address_length = 8;
+ break;
+ default:
+ if ( !std::isdigit( static_cast< unsigned char >( ch ) ) )
+ {
+ throw format_error();
+ }
+ break;
+ }
+
+ record rec;
+ rec.type = ch;
+ rec.length = xdigit_to_int( buf[2] ) << 4 | xdigit_to_int( buf[3] );
+ if ( rec.length * 2u + 4 != buf.size() )
+ {
+ throw format_error();
+ }
+ rec.length -= address_length/2 + 1; // アドレスとチェックサムの長さを引いて、データ長に直す
+
+ rec.address = 0;
+ int base = 4;
+ for ( int i = 0; i < address_length; i++ )
+ {
+ rec.address = rec.address << 4 | xdigit_to_int( buf[base+i] );
+ }
+
+ base += address_length;
+ rec.data.reserve( rec.length );
+ for ( int i = 0; i < rec.length; i++ )
+ {
+ rec.data.push_back( static_cast< unsigned char >( xdigit_to_int( buf[base+i*2] ) << 4 | xdigit_to_int( buf[base+i*2+1] ) ) );
+ }
+
+ rec.checksum = xdigit_to_int( buf[size-2] ) << 4 | xdigit_to_int( buf[size-1] );
+
+ // チェックサム判定は省略
+
+ return rec;
+ }
+
+ /*!
+ * \brief 十六進数字から数値への変換
+ * \param ch 十六進数字(文字)
+ * \return ch に対応する数値
+ */
+ int s_record::xdigit_to_int( int ch )
+ {
+ static char const xdigits[] = "0123456789abcdef";
+
+ ch = std::tolower( static_cast< unsigned char >( ch ) );
+ char const* s = std::strchr( xdigits, ch );
+ if ( s == 0 )
+ {
+ return -1;
+ }
+ return s - xdigits;
+ }
+
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2005-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/*!
+ * \file toppers/s_record.hpp
+ * \brief モトローラSレコードを扱うための宣言定義
+ *
+ * このファイルで定義されるクラス
+ * \code
+ * class s_record;
+ * struct s_record::record;
+ * class s_record::format_error;
+ * class s_record::checksum_error;
+ * \endcode
+ */
+#ifndef TOPPERS_S_RECORD_HPP_
+#define TOPPERS_S_RECORD_HPP_
+
+#include "toppers/config.hpp"
+#include <iosfwd>
+#include <string>
+#include <vector>
+#include <utility>
+#include <stdexcept>
+#include <boost/cstdint.hpp>
+
+namespace toppers
+{
+
+ /*!
+ * \class s_record s_record.hpp "toppers/s_recored.hpp"
+ * \brief モトローラSレコードを扱うためのクラス
+ *
+ * \sa s_record::record, s_record::format_error, s_record::checksum_error
+ */
+ class s_record
+ {
+ public:
+ typedef std::pair< unsigned long, std::vector< unsigned char > > value_type;
+ typedef std::vector< value_type >::size_type size_type;
+
+ /*!
+ * \struct record s_record.hpp "toppers/s_record.hpp"
+ * \brief Sレコードの1行レコード情報を格納するための構造体
+ */
+ struct record
+ {
+ int type;
+ int length;
+ unsigned long address;
+ std::vector< unsigned char > data;
+ int checksum;
+ };
+
+ /*!
+ * \class data_error s_record.hpp "toppers/s_record.hpp"
+ * \brief Sレコードのデータエラー例外クラス
+ */
+ class data_error : public std::runtime_error
+ {
+ public:
+ data_error() : std::runtime_error( "S-record data error" ) {}
+ };
+ /*!
+ * \class format_error s_record.hpp "toppers/s_record.hpp"
+ * \brief Sレコードの書式エラー例外クラス
+ */
+ class format_error : public std::runtime_error
+ {
+ public:
+ format_error() : std::runtime_error( "S-record format error" ) {}
+ };
+ /*!
+ * \class checksum_error s_record.hpp "toppers/s_record.hpp"
+ * \brief Sレコードのチェックサムエラー例外クラス
+ */
+ class checksum_error : public std::runtime_error
+ {
+ public:
+ checksum_error() : std::runtime_error( "S-record checksum error" ) {}
+ };
+
+ /*!
+ * \brief デフォルトコンストラクタ
+ */
+ s_record() : cache_( data_.end() ) {}
+ /*!
+ * \brief コンストラクタ
+ * \param istr 入力ストリーム
+ *
+ * s_record クラスの生成と同時にデータのロードを行います。
+ */
+ explicit s_record( std::istream& istr ) { load( istr ); }
+ /*!
+ * \brief デストラクタ
+ */
+ virtual ~s_record() {}
+
+ void load( std::istream& istr );
+ int operator[]( size_type address ) const;
+ boost::uintmax_t get_value( std::size_t base, std::size_t size, bool little_endian ) const;
+ unsigned long lower_bound() const;
+ unsigned long upper_bound() const;
+ protected:
+ static record const read_record( std::string const& rec_buf );
+ static int xdigit_to_int( int ch );
+ private:
+ std::vector< value_type > data_;
+ mutable std::vector< value_type >::const_iterator cache_;
+ };
+
+}
+
+#endif // ! TOPPERS_S_RECORD_HPP_
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2005-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/*!
+ * \file toppers/text.hpp
+ * \brief テキストデータ管理に関する宣言定義
+ *
+ * このファイルで定義されるクラス
+ * \code
+ * class basic_text< Container, CharT, Traits, Allocator >;
+ * \endcode
+ */
+#ifndef TOPPERS_TEXT_HPP_
+#define TOPPERS_TEXT_HPP_
+
+#include <algorithm>
+#include <iterator>
+#include <vector>
+#include <numeric>
+#include "toppers/text_line.hpp"
+#include "toppers/misc.hpp"
+#include <boost/utility.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/format.hpp>
+
+namespace toppers
+{
+
+ /*!
+ * \class basic_text text.hpp "toppers/text.hpp"
+ * \brief テキストデータ管理テンプレートクラス
+ *
+ * ファイルから読み込んだテキストデータの管理を行うためのクラスです。
+ * このクラスでは、テキストデータを単なる文字列としてではなく、入力元の
+ * ファイル名と行番号を付加した形で管理します。
+ *
+ * \note このクラスはテキスト編集の用途を想定したものではありません。
+ */
+ template
+ <
+ template < typename, class > class Container,
+ typename CharT,
+ class Traits = std::char_traits< CharT >,
+ class Allocator = std::allocator< CharT >
+ >
+ class basic_text
+ {
+ public:
+ typedef basic_text< Container, CharT, Traits, Allocator > self_t;
+ typedef std::basic_string< CharT, Traits, Allocator > string_type;
+ typedef ::toppers::text_line line_type;
+ typedef basic_line_buf< CharT, Traits, Allocator > line_buf;
+
+ // 以下は一般的なコンテナとの互換のための型定義
+ ////////////////////////////////////////////////////////////////////////////////
+ typedef CharT value_type;
+ typedef Container< line_buf, std::allocator< line_buf > > container;
+ typedef value_type& reference;
+ typedef value_type const& const_reference;
+ typedef value_type* pointer;
+ typedef value_type const* const_pointer;
+ typedef Allocator allocator_type;
+ typedef typename Allocator::difference_type difference_type;
+ typedef typename Allocator::size_type size_type;
+
+ /*!
+ * \class const_iterator text.hpp "toppers/text.hpp"
+ * \brief toppers::basic_text のイテレータ
+ */
+ class const_iterator : public boost::iterator_facade< const_iterator, CharT, boost::random_access_traversal_tag, CharT const& >
+ {
+ friend class boost::iterator_core_access;
+ public:
+ typedef boost::iterator_facade< const_iterator, CharT, boost::random_access_traversal_tag, CharT const& > base_t;
+ typedef typename container::const_iterator row_iterator;
+ typedef typename base_t::value_type value_type;
+ typedef typename base_t::reference reference;
+ typedef typename base_t::pointer pointer;
+ typedef typename base_t::difference_type difference_type;
+
+ const_iterator() : row_(), col_( 0 ) {}
+ const_iterator( row_iterator row, size_type col = 0 ) : row_( row ), col_( col ) {}
+ line_type const& line() const { return row_->line; }
+ row_iterator const& get_row() const { return row_; }
+ size_type get_col() const { return col_; }
+ protected:
+ reference dereference() const { return row_->buf[col_]; }
+ bool equal( const_iterator const& rhs ) const { return row_ == rhs.row_ && col_ == rhs.col_; }
+ void increment() { if ( ++col_ == row_->buf.size() ) { col_ = 0; ++row_; } }
+ void decrement() { if ( col_ == 0 ) col_ = ( --row_ )->buf.size(); --col_; }
+ void advance( difference_type n )
+ {
+ typename container::const_iterator row = row_;
+ difference_type col = static_cast< difference_type >( col_ );
+ if ( n >= 0 )
+ {
+ while ( static_cast< size_type>( col + n ) > row->buf.size() )
+ {
+ n -= row->buf.size() - col;
+ ++row;
+ col = 0;
+ }
+ col += n;
+ if ( col == row->buf.size() )
+ {
+ col = 0;
+ ++row;
+ }
+ }
+ else // n < 0
+ {
+ while ( col + n < -1 )
+ {
+ n += col;
+ --row;
+ col = row->buf.size() - 1;
+ }
+ col += n;
+ if ( col == -1 )
+ {
+ --row;
+ col = row->buf.size() - 1;
+ }
+ }
+ row_ = row;
+ col_ = col;
+ }
+ difference_type distance_to( const_iterator const& rhs ) const
+ {
+ difference_type n;
+ typename container::const_iterator row = row_;
+ if ( rhs.row_ < row_ )
+ {
+ n = -static_cast< difference_type >( col_ + ( rhs.row_->buf.size() - rhs.col_ ) );
+ while ( --row != rhs.row_ )
+ {
+ n -= row->buf.size();
+ }
+ }
+ else if ( row_ < rhs.row_ )
+ {
+ n = col_ + rhs.col_;
+ while ( ++row != rhs.row_ )
+ {
+ n += row->buf.size();
+ }
+ }
+ else
+ {
+ n = static_cast< difference_type >( rhs.col_ ) - static_cast< difference_type >( col_ );
+ }
+ return n;
+ }
+ private:
+ typename container::const_iterator row_;
+ size_type col_;
+ };
+
+ /*!
+ * \class iterator text.hpp "toppers/text.hpp"
+ * \brief toppers::basic_text のイテレータ
+ */
+ class iterator : public const_iterator
+ {
+ public:
+ typedef typename container::iterator row_iterator;
+ typedef typename const_iterator::value_type value_type;
+ typedef typename const_iterator::reference reference;
+ typedef typename const_iterator::pointer pointer;
+ typedef typename const_iterator::difference_type difference_type;
+
+ iterator() {}
+ explicit iterator( row_iterator row, size_type col = 0 ) : const_iterator( row, col ) {}
+ value_type& operator*() const { return const_cast< value_type& >( const_iterator::dereference() ); }
+ iterator& operator++() { const_iterator::increment(); return *this; }
+ iterator operator++( int ) { iterator t( *this ); const_iterator::increment(); return t; }
+ iterator& operator--() { const_iterator::decrement(); return *this; }
+ iterator operator--( int ) { iterator t( *this ); const_iterator::decrement(); return t; }
+ };
+
+ typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
+ typedef std::reverse_iterator< iterator > reverse_iterator;
+
+ public:
+ /*!
+ * \brief デフォルトコンストラクタ
+ */
+ basic_text() {}
+
+ /*!
+ * \brief コンストラクタ
+ * \param first 初期化に用いるデータ列の先頭
+ * \param last 初期化に用いるデータ列の終端+1
+ */
+ basic_text( const_iterator const& first, const_iterator const& last )
+ {
+ if ( first != last )
+ {
+ init( first, last );
+ }
+ }
+
+ /*!
+ * \brief コンストラクタ
+ * \param first 初期化に用いるデータ列の先頭
+ * \param last 初期化に用いるデータ列の終端+1
+ * \note ファイル名は"unknown"になります。
+ */
+ template < class InputIterator >
+ basic_text( InputIterator first, InputIterator last )
+ {
+ if ( first != last )
+ {
+ init( first, last, append_directive );
+ }
+ }
+
+ /*!
+ * \brief コンストラクタ
+ * \param first 初期化に用いるデータ列の先頭
+ * \param last 初期化に用いるデータ列の終端+1
+ * \param directive 1行をコンテナに格納するための処理
+ * \note ファイル名は"unknown"になります。
+ *
+ * directive は void directive( container& cont, line_buf& buf )の形式を
+ * とる関数へのポインタまたはファンクタであることを想定しています。
+ * cont は内部でデータの格納に使用するコンテナ、 buf は1行分の文字
+ * 列とファイル名・行番号を格納したバッファです。
+ */
+ template < class InputIterator, class Directive >
+ basic_text( InputIterator first, InputIterator last, Directive directive )
+ {
+ if ( first != last )
+ {
+ init( first, last, directive );
+ }
+ }
+
+ /*!
+ * \brief コンストラクタ
+ * \param istr 初期化に用いる入力ストリーム
+ * \note ファイル名は"unknown"になります。
+ */
+ basic_text( std::basic_istream< CharT, Traits >& istr )
+ {
+ init( istr, append_directive );
+ }
+
+ /*!
+ * \brief コンストラクタ
+ * \param istr 初期化に用いる入力ストリーム
+ * \param directive 1行をコンテナに格納するための処理
+ * \note ファイル名は"unknown"になります。
+ *
+ * directive は void directive( container& cont, line_buf& buf )の形式を
+ * とる関数へのポインタまたはファンクタであることを想定しています。
+ * cont は内部でデータの格納に使用するコンテナ、 buf は1行分の文字
+ * 列とファイル名・行番号を格納したバッファです。
+ */
+ template < class Directive >
+ basic_text( std::basic_istream< CharT, Traits >& istr, Directive directive )
+ {
+ init( istr, directive );
+ }
+
+ /*!
+ * \brief 先頭位置の取得
+ * \return 先頭文字へのイテレータを返す
+ */
+ const_iterator begin() const
+ {
+ return const_iterator( container_.begin() );
+ }
+
+ /*!
+ * \brief 先頭位置の取得
+ * \return 先頭文字へのイテレータを返す
+ */
+ iterator begin()
+ {
+ return iterator( container_.begin() );
+ }
+
+ /*!
+ * \brief 終端位置+1の取得
+ * \return 終端文字の次要素へのイテレータを返す
+ */
+ const_iterator end() const
+ {
+ return const_iterator( container_.end() );
+ }
+
+ /*!
+ * \brief 終端位置+1の取得
+ * \return 終端文字の次要素へのイテレータを返す
+ */
+ iterator end()
+ {
+ return iterator( container_.end() );
+ }
+
+ /*!
+ * \brief 逆順先頭位置の取得
+ * \return 逆順先頭文字への逆イテレータを返す
+ */
+ const_reverse_iterator rbegin() const
+ {
+ string_type const* pbuf = &container_.back().buf;
+ return const_reverse_iterator( container_.rbegin() + pbuf->empty() ? 0 : pbuf->size()-1 );
+ }
+
+ /*!
+ * \brief 逆順先頭位置の取得
+ * \return 逆順先頭文字への逆イテレータを返す
+ */
+ reverse_iterator rbegin()
+ {
+ string_type* pbuf = &container_.back().buf;
+ return reverse_iterator( container_.rbegin() + pbuf->empty() ? 0 : pbuf->size()-1 );
+ }
+
+ /*!
+ * \brief 逆順終端位置+1の取得
+ * \return 逆順終端文字の次要素への逆イテレータを返す
+ */
+ const_reverse_iterator rend() const
+ {
+ return const_reverse_iterator( container_.rend() );
+ }
+
+ /*!
+ * \brief 逆順終端位置+1の取得
+ * \return 逆順終端文字の次要素への逆イテレータを返す
+ */
+ reverse_iterator rend()
+ {
+ return reverse_iterator( container_.rend() );
+ }
+
+ /*!
+ * \brief 先頭文字の参照
+ * \return 先頭文字への参照を返す
+ */
+ const_reference front() const
+ {
+ return container_.front().buf[0];
+ }
+
+ /*!
+ * \brief 先頭文字の参照
+ * \return 先頭文字への参照を返す
+ */
+ reference front()
+ {
+ return container_.front().buf[0];
+ }
+
+ /*!
+ * \brief 終端文字の参照
+ * \return 終端文字への参照を返す
+ */
+ const_reference back() const
+ {
+ string_type const* pbuf = &container_.back().buf;
+ return pbuf->at( pbuf->size()-1 );
+ }
+
+ /*!
+ * \brief 終端文字の参照
+ * \return 終端文字への参照を返す
+ */
+ reference back()
+ {
+ string_type* pbuf = &container_.back().buf;
+ return pbuf->at( pbuf->size()-1 );
+ }
+
+ /*!
+ * \brief 指定位置の文字の参照
+ * \return 指定位置の文字への参照を返す
+ */
+ const_reference at( size_type pos ) const
+ {
+ return container_.front().buf[pos];
+ }
+
+ /*!
+ * \brief 指定位置の文字の参照
+ * \return 指定位置の文字への参照を返す
+ */
+ reference at( size_type pos )
+ {
+ return container_.front().buf[pos];
+ }
+
+ /*!
+ * \brief 指定範囲のテキストデータを追加
+ * \param first 追加に用いるデータ列の先頭
+ * \param last 追加に用いるデータ列の終端+1
+ */
+ void append( const_iterator const& first, const_iterator const& last )
+ {
+ if ( first != last )
+ {
+ self_t t( *this );
+ t.init( first, last );
+ swap( t );
+ }
+ }
+
+ /*!
+ * \brief 指定範囲のテキストデータを追加
+ * \param first 追加に用いるデータ列の先頭
+ * \param last 追加に用いるデータ列の終端+1
+ * \note ファイル名と行番号は追加先の終端のものを継続します。
+ * 追加先にデータがない場合は"unknown"になります。
+ */
+ template < class InputIterator >
+ void append( InputIterator first, InputIterator last )
+ {
+ append( first, last, append_directive );
+ }
+
+ /*!
+ * \brief 指定範囲のテキストデータを追加
+ * \param first 追加に用いるデータ列の先頭
+ * \param last 追加に用いるデータ列の終端+1
+ * \param directive 1行をコンテナに格納するための処理
+ * \note ファイル名と行番号は追加先の終端のものを継続します。
+ * 追加先にデータがない場合は"unknown"になります。
+ *
+ * directive は void directive( container& cont, line_buf& buf )の形式を
+ * とる関数へのポインタまたはファンクタであることを想定しています。
+ * cont は内部でデータの格納に使用するコンテナ、 buf は1行分の文字
+ * 列とファイル名・行番号を格納したバッファです。
+ */
+ template < class InputIterator, class Directive >
+ void append( InputIterator first, InputIterator last, Directive directive )
+ {
+ if ( first != last )
+ {
+ self_t t( *this );
+ t.init( first, last, directive );
+ swap( t );
+ }
+ }
+
+ /*!
+ * \brief 指定範囲のテキストデータを追加
+ * \param istr 追加に用いる入力ストリーム
+ * \note ファイル名と行番号は追加先の終端のものを継続します。
+ * 追加先にデータがない場合は"unknown"になります。
+ */
+ void append( std::basic_istream< CharT, Traits >& istr )
+ {
+ append( istr, append_directive );
+ }
+
+ /*!
+ * \brief 指定範囲のテキストデータを追加
+ * \param istr 追加に用いる入力ストリーム
+ * \param directive 1行をコンテナに格納するための処理
+ * \note ファイル名と行番号は追加先の終端のものを継続します。
+ * 追加先にデータがない場合は"unknown"になります。
+ *
+ * directive は void directive( container& cont, line_buf& buf )の形式を
+ * とる関数へのポインタまたはファンクタであることを想定しています。
+ * cont は内部でデータの格納に使用するコンテナ、 buf は1行分の文字
+ * 列とファイル名・行番号を格納したバッファです。
+ */
+ template < class Directive >
+ void append( std::basic_istream< CharT, Traits >& istr, Directive directive )
+ {
+ self_t t( *this );
+ t.init( istr, directive );
+ swap( t );
+ }
+
+ /*!
+ * \brief 指定範囲のテキストデータを代入
+ * \param first 代入に用いるデータ列の先頭
+ * \param last 代入に用いるデータ列の終端+1
+ */
+ void assign( const_iterator const& first, const_iterator const& last )
+ {
+ self_t t( first, last );
+ swap( t );
+ }
+
+ /*!
+ * \brief 指定範囲のテキストデータを代入
+ * \param first 代入に用いるデータ列の先頭
+ * \param last 代入に用いるデータ列の終端+1
+ * \note ファイル名は"unknown"になります。
+ */
+ template < class InputIterator >
+ void assign( InputIterator first, InputIterator last )
+ {
+ self_t t( first, last, append_directive );
+ swap( t );
+ }
+
+ /*!
+ * \brief 指定範囲のテキストデータを代入
+ * \param first 代入に用いるデータ列の先頭
+ * \param last 代入に用いるデータ列の終端+1
+ * \param directive 1行をコンテナに格納するための処理
+ * \note ファイル名は"unknown"になります。
+ *
+ * directive は void directive( container& cont, line_buf& buf )の形式を
+ * とる関数へのポインタまたはファンクタであることを想定しています。
+ * cont は内部でデータの格納に使用するコンテナ、 buf は1行分の文字
+ * 列とファイル名・行番号を格納したバッファです。
+ */
+ template < class InputIterator, class Directive >
+ void assign( InputIterator first, InputIterator last, Directive directive )
+ {
+ self_t t( first, last, directive );
+ swap( t );
+ }
+
+ /*!
+ * \brief 指定範囲のテキストデータを代入
+ * \param istr 代入に用いる入力ストリーム
+ * \note ファイル名と行番号は代入先の終端のものを継続します。
+ * 追加先にデータがない場合は"unknown"になります。
+ */
+ void assign( std::basic_istream< CharT, Traits >& istr )
+ {
+ self_t t( istr, append_directive );
+ swap( t );
+ }
+
+ /*!
+ * \brief 指定範囲のテキストデータを代入
+ * \param istr 代入に用いる入力ストリーム
+ * \param directive 1行をコンテナに格納するための処理
+ * \note ファイル名と行番号は代入先の終端のものを継続します。
+ * 追加先にデータがない場合は"unknown"になります。
+ *
+ * directive は void directive( container& cont, line_buf& buf )の形式を
+ * とる関数へのポインタまたはファンクタであることを想定しています。
+ * cont は内部でデータの格納に使用するコンテナ、 buf は1行分の文字
+ * 列とファイル名・行番号を格納したバッファです。
+ */
+ template < class Directive >
+ void assign( std::basic_istream< CharT, Traits >& istr, Directive directive )
+ {
+ self_t t( istr, directive );
+ swap( t );
+ }
+
+ /*!
+ * \brief 終端に文字を追加
+ * \param value 追加する文字
+ */
+ void push_back( value_type value )
+ {
+ if ( container_.empty() || container_.back().line.file != line_.file )
+ {
+ line_buf buf( initial_line(), string_type( 1, value ) );
+ container_.push_back( buf );
+ }
+ else
+ {
+ string_type const* pbuf = &container_.back().buf;
+ if ( pbuf->at( pbuf->size()-1 ) == widen( '\n' ) )
+ {
+ ++line_.line;
+ line_buf buf( initial_line(), string_type( 1, value ) );
+ container_.push_back( buf );
+ }
+ else
+ {
+ container_.back().buf += value;
+ }
+ }
+ }
+
+ /*!
+ * \brief 終端から文字を削除
+ */
+ void pop_back()
+ {
+ if ( container_.empty() )
+ {
+ container_.pop_back();
+ }
+ else
+ {
+ string_type const* pbuf = &container_.back().buf;
+ pbuf->resize( pbuf->size()-1 );
+ if ( container_.back().buf.empty() )
+ {
+ container_.pop_back();
+ }
+ }
+ }
+
+ /*!
+ * \brief コンテナが空かどうかの判別
+ * \return 空の場合は true を返す
+ */
+ bool empty() const
+ {
+ return container_.empty();
+ }
+
+ /*!
+ * \brief コンテナのサイズ
+ * \return コンテナに含まれている文字数を返す
+ */
+ size_type size() const
+ {
+ return std::accumulate( container_.begin(), container_.end(), size_type( 0 ), add_line_size );
+ }
+
+ /*!
+ * \brief コンテナの交換
+ * \param other 交換対象となるコンテナ
+ */
+ void swap( self_t& other )
+ {
+ container_.swap( other.container_ );
+ line_.swap( other.line_ );
+ }
+
+ /*!
+ * \brief コンテナのクリア
+ */
+ void clear()
+ {
+ container_.clear();
+ line_.file.clear();
+ line_.line = 0;
+ }
+
+ void set_line( std::string const& file, long line )
+ {
+ line_.file = file;
+ line_.line = line;
+ }
+
+ line_type get_line() const
+ {
+ return line_;
+ }
+ private:
+ //! 同種のコンテナを入力元とする初期化処理
+ void init( const_iterator const& first, const_iterator const& last )
+ {
+ line_buf buf( *first.get_row() );
+ if ( first.get_col() > 0 )
+ {
+ buf.buf = buf.buf.substr( first.get_col() );
+ }
+ container_.push_back( buf );
+ std::copy( boost::next( first ).get_row(), last.get_row(), std::back_inserter( container_ ) );
+ buf = *last.get_row();
+ buf.buf = buf.buf.substr( 0, last.get_col() );
+ container_.push_back( buf );
+ line_ = buf.line;
+ }
+
+ //! 異種のコンテナを入力元とする初期化処理
+ template < class InputIterator, class Directive >
+ void init( InputIterator first, InputIterator last, Directive directive )
+ {
+ line_buf buf( initial_line() );
+ value_type const nl = widen( '\n' );
+ for ( InputIterator iter = first; iter != last; ++iter )
+ {
+ value_type ch = *iter;
+ buf.buf += ch;
+ if ( ch == nl )
+ {
+ directive( container_, buf );
+ line_ = buf.line;
+ }
+ }
+ if ( !buf.buf.empty() )
+ {
+ container_.push_back( buf );
+ }
+ line_ = buf.line;
+ }
+
+ //! 入力ストリームを入力元とする初期化処理
+ template < class Directive >
+ void init( std::basic_istream< CharT, Traits >& istr, Directive directive )
+ {
+ line_buf buf( initial_line() );
+ value_type const nl = widen( '\n' );
+ while ( istr )
+ {
+ value_type ch;
+ istr.get( ch );
+ buf.buf += ch;
+ if ( ch == nl )
+ {
+ directive( container_, buf );
+ line_ = buf.line;
+ }
+ }
+ if ( !buf.buf.empty() )
+ {
+ container_.push_back( buf );
+ }
+ line_ = buf.line;
+ }
+
+ //! ファイル名・行番号の初期情報の取得
+ line_type const initial_line() const
+ {
+ if ( line_.line > 0 )
+ {
+ return line_;
+ }
+ if ( container_.empty() )
+ {
+ return line_type( "unknown", 1 );
+ }
+ return container_.back().line;
+ }
+
+ //! シングルバイト文字から別形式の文字型への変換
+ static value_type widen( char ch )
+ {
+ return ::toppers::widen< value_type >( ch );
+ }
+
+ //! size 関数内で使用する累算処理
+ static size_type add_line_size( size_type value, line_buf const& buf )
+ {
+ return value + buf.buf.size();
+ }
+
+ //! Directive のデフォルト処理
+ static void append_directive( container& cont, line_buf& buf )
+ {
+ cont.push_back( buf );
+ ++buf.line.line;
+ buf.buf.clear();
+ }
+ private:
+ container container_;
+ line_type line_;
+ };
+
+ typedef basic_text< std::vector, char > text;
+
+ inline text_line const& get_text_line( text::const_iterator iter )
+ {
+ return iter.line();
+ }
+
+ inline text_line const& get_text_line( text::iterator iter )
+ {
+ return iter.line();
+ }
+
+}
+
+#endif // ! TOPPERS_TEXT_HPP_
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2005-2008 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/*!
+ * \file toppers/text_line.hpp
+ * \brief テキストデータの行に関する宣言定義
+ *
+ * このファイルで定義されるクラス
+ * \code
+ * struct text_line;
+ * struct basic_line_buf< CharT, Traits, Allocator >;
+ * \endcode
+ */
+#ifndef TOPPERS_TEXTLINE_HPP_
+#define TOPPERS_TEXTLINE_HPP_
+
+#include <iosfwd>
+#include <string>
+#include <algorithm>
+#include "toppers/config.hpp"
+
+namespace toppers
+{
+
+ /*!
+ * \struct text_line text_line.hpp "toppers/text_line.hpp"
+ * \brief ファイル名と行番号の保持クラス
+ */
+ struct text_line
+ {
+ std::string file; //!< ファイル名
+ long line; //!< 行番号(1〜)
+
+ /*!
+ * \brief デフォルトコンストラクタ
+ */
+ text_line()
+ : line( 0 )
+ {
+ }
+ /*!
+ * \brief コンストラクタ
+ * \param filename ファイル名
+ * \param lineno 行番号
+ */
+ explicit text_line( std::string const& filename, long lineno = 0 )
+ : file( filename ), line( lineno )
+ {
+ }
+ /*!
+ * \brief コンストラクタ
+ * \param filename ファイル名
+ * \param lineno 行番号
+ */
+ explicit text_line( char const* filename, long lineno = 0 )
+ : file( filename ), line( lineno )
+ {
+ }
+ /*!
+ * \brief オブジェクトの交換
+ * \param other 交換対象のオブジェクト
+ */
+ void swap( text_line& other ) throw()
+ {
+ std::swap( line, other.line );
+ file.swap( other.file );
+ }
+ };
+
+ /*!
+ * \struct line_buf text_line.hpp "toppers/text_line.hpp"
+ * \brief 1 行テキストの管理クラス
+ */
+ template
+ <
+ typename CharT,
+ class Traits = std::char_traits< CharT >,
+ class Allocator = std::allocator< CharT >
+ >
+ struct basic_line_buf
+ {
+ typedef std::basic_string< CharT, Traits, Allocator > string_type;
+
+ string_type buf; //!< 行データを表す文字列
+ text_line line; //!< 行番号情報
+
+ /*!
+ * \brief デフォルトコンストラクタ
+ */
+ basic_line_buf()
+ {
+ }
+ /*!
+ * \brief コンストラクタ
+ * \param line 行番号情報
+ */
+ basic_line_buf( text_line const& line )
+ : line( line )
+ {
+ }
+ /*!
+ * \brief コンストラクタ
+ * \param line 行番号情報
+ * \param data 行データ
+ */
+ basic_line_buf( text_line const& line, string_type const& data )
+ : buf( data ), line( line )
+ {
+ }
+ };
+
+ //! char 版の 1 行テキスト管理クラス
+ typedef basic_line_buf< char > line_buf;
+
+ /*!
+ * \brief イテレータが保持する行番号情報の取得
+ * \param iter イテレータ
+ * \return 行番号情報への参照を返す
+ *
+ * iter で指定したイテレータが行番号情報を保持しているなら、その行番号情報を返します。
+ * 行番号情報を保持していない場合はダミーオブジェクトへの参照を返します。
+ */
+ template < class Iterator >
+ inline text_line const& get_text_line( Iterator iter )
+ {
+ static text_line dummy;
+ return dummy;
+ }
+
+}
+
+#endif // ! TOPPERS_TEXTLINE_HPP_
--- /dev/null
+<?xml version="1.0" encoding="shift_jis"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="toppers"
+ ProjectGUID="{101BA469-E065-401C-86F9-789B5F2C85AB}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="4"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=".."
+ PreprocessorDefinitions="_SCL_SECURE_NO_WARNINGS=1"
+ StringPooling="TRUE"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ SmallerTypeCheck="TRUE"
+ RuntimeLibrary="1"
+ BufferSecurityCheck="TRUE"
+ EnableFunctionLevelLinking="TRUE"
+ TreatWChar_tAsBuiltInType="TRUE"
+ ForceConformanceInForLoopScope="TRUE"
+ RuntimeTypeInfo="TRUE"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/toppers.lib"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="4"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="0"
+ EnableIntrinsicFunctions="TRUE"
+ ImproveFloatingPointConsistency="FALSE"
+ FavorSizeOrSpeed="2"
+ AdditionalIncludeDirectories=".."
+ PreprocessorDefinitions="_SCL_SECURE_NO_WARNINGS=1"
+ StringPooling="TRUE"
+ RuntimeLibrary="0"
+ TreatWChar_tAsBuiltInType="TRUE"
+ ForceConformanceInForLoopScope="TRUE"
+ RuntimeTypeInfo="TRUE"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="FALSE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/toppers.lib"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="ソース ファイル"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+ <File
+ RelativePath=".\builtin_function.cpp">
+ </File>
+ <File
+ RelativePath=".\c_chlit_parser.cpp">
+ </File>
+ <File
+ RelativePath=".\c_ident_parser.cpp">
+ </File>
+ <File
+ RelativePath=".\c_int_parser.cpp">
+ </File>
+ <File
+ RelativePath=".\c_keywords.cpp">
+ </File>
+ <File
+ RelativePath=".\c_plus_plus_keywords.cpp">
+ </File>
+ <File
+ RelativePath=".\c_strlit_parser.cpp">
+ </File>
+ <File
+ RelativePath=".\cpp.cpp">
+ </File>
+ <File
+ RelativePath=".\diagnostics.cpp">
+ </File>
+ <File
+ RelativePath=".\gettext.cpp">
+ </File>
+ <File
+ RelativePath=".\global.cpp">
+ </File>
+ <File
+ RelativePath=".\io.cpp">
+ </File>
+ <File
+ RelativePath=".\macro_processor.cpp">
+ </File>
+ <File
+ RelativePath=".\mbchar_parser.cpp">
+ </File>
+ <File
+ RelativePath=".\nm_symbol.cpp">
+ </File>
+ <File
+ RelativePath=".\output_file.cpp">
+ </File>
+ <File
+ RelativePath=".\s_record.cpp">
+ </File>
+ <File
+ RelativePath=".\ucn_parser.cpp">
+ </File>
+ </Filter>
+ <Filter
+ Name="ヘッダー ファイル"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
+ <File
+ RelativePath=".\c_expr.hpp">
+ </File>
+ <File
+ RelativePath=".\c_parser.hpp">
+ </File>
+ <File
+ RelativePath=".\c_pp_line.hpp">
+ </File>
+ <File
+ RelativePath=".\codeset.hpp">
+ </File>
+ <File
+ RelativePath=".\config.hpp">
+ </File>
+ <File
+ RelativePath=".\cpp.hpp">
+ </File>
+ <File
+ RelativePath=".\csv.hpp">
+ </File>
+ <File
+ RelativePath=".\debug.hpp">
+ </File>
+ <File
+ RelativePath=".\diagnostics.hpp">
+ </File>
+ <File
+ RelativePath=".\gettext.hpp">
+ </File>
+ <File
+ RelativePath=".\global.hpp">
+ </File>
+ <File
+ RelativePath=".\io.hpp">
+ </File>
+ <File
+ RelativePath=".\macro_processor.hpp">
+ </File>
+ <File
+ RelativePath=".\misc.hpp">
+ </File>
+ <File
+ RelativePath=".\nm_symbol.hpp">
+ </File>
+ <File
+ RelativePath=".\output_file.hpp">
+ </File>
+ <File
+ RelativePath=".\s_record.hpp">
+ </File>
+ <File
+ RelativePath=".\text.hpp">
+ </File>
+ <File
+ RelativePath=".\text_line.hpp">
+ </File>
+ <File
+ RelativePath=".\workaround.hpp">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2005-2010 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/*
+ * toppers/ucn_parser.cpp
+ */
+#include "toppers/c_parser.hpp"
+
+namespace toppers
+{
+
+ //! 国際文字名パーサー
+ boost::spirit::classic::functor_parser< detail::ucn_parse_functor > const ucn_p;
+
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by TAKAGI Nobuhisa
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/*!
+ * \file toppers/workaroound.hpp
+ * \brief 処理系未対応の機能に対する代替手段
+ */
+#ifndef TOPPERS_WORKAROUND_HPP_
+#define TOPPERS_WORKAROUND_HPP_
+
+#include "toppers/config.hpp"
+
+#ifndef __STDC_CONSTANT_MACROS
+#define __STDC_CONSTANT_MACROS
+#endif
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS
+#endif
+
+#ifdef TOPPERS_HAS_TR1_LIBRARY
+
+#include <memory>
+#include <cstdint>
+
+#else
+
+#define BOOST_SP_DISABLE_THREADS 1 // shared_ptr の排他制御を抑止
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+#include <boost/cstdint.hpp>
+
+namespace std
+{
+ namespace tr1
+ {
+ using namespace boost;
+ }
+}
+
+#endif
+
+#endif // ! TOPPERS_WORKAROUND_HPP_
--- /dev/null
+PACKAGE asp_arch_arm_m_gcc
+
+cmsis/LPC17xx.h
+cmsis/core_cm3.h
+cmsis/system_LPC17xx.h
+MANIFEST
+Makefile.chip
+chip.tf
+chip_cfg1_out.h
+chip_check.tf
+chip_config.c
+chip_config.h
+chip_kernel.h
+chip_serial.cfg
+chip_serial.h
+chip_sil.h
+chip_stddef.h
+chip_syssvc.h
+chip_test.h
+chip_timer.cfg
+chip_timer.h
+chip_user.txt
+lpc17xx.h
+chip_rename.def
+chip_rename.h
+chip_unrename.h
\ No newline at end of file
--- /dev/null
+#
+# Makefile のチップ依存部(LPC17xx用)
+#
+
+#
+# ディレクトリの定義
+#
+CHIPDIR = $(SRCDIR)/chip/$(CHIP)_$(TOOL)
+
+#
+# GNU開発環境のターゲットアーキテクチャの定義
+#
+GCC_TARGET = arm-none-eabi
+
+#
+# コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(CHIPDIR) -I$(CHIPDIR)/cmsis/core -I$(CHIPDIR)/cmsis/device -I$(SRCDIR)/pdic/common -I$(SRCDIR)/pdic/i2c -I$(SRCDIR)/pdic/spi -I$(SRCDIR)/pdic/uart -I$(SRCDIR)/pdic/gpio -I$(SRCDIR)/pdic/ssp -I$(SRCDIR)/pdic/adc -I$(SRCDIR)/pdic/rtc
+CDEFS := $(CDEFS)
+COPTS := $(COPTS) -mcpu=cortex-m3
+
+#
+# カーネルに関する定義
+#
+KERNEL_DIR := $(KERNEL_DIR) $(CHIPDIR)
+KERNEL_ASMOBJS := $(KERNEL_ASMOBJS)
+KERNEL_COBJS := $(KERNEL_COBJS) chip_config.o prc_timer.o core_cm3.o system_LPC17xx.o
+KERNEL_CFLAGS := $(KERNEL_CFLAGS) -fno-strict-aliasing -mcpu=cortex-m3
+
+#
+# システムサービスに関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR) $(SRCDIR)/pdic/common $(SRCDIR)/pdic/i2c $(SRCDIR)/pdic/spi $(SRCDIR)/pdic/uart $(SRCDIR)/pdic/gpio $(SRCDIR)/pdic/ssp $(SRCDIR)/pdic/adc $(SRCDIR)/pdic/rtc
+SYSSVC_COBJS := $(SYSSVC_COBJS) lpc17xx_clkpwr.o lpc17xx_libcfg_default.o lpc17xx_pinsel.o lpc17xx_i2c.o lpc17xx_spi.o lpc17xx_gpio.o uart.o lpc17xx_ssp.o lpc17xx_adc.o lpc17xx_rtc.o lpc17xx_uart.o
+
+
+#
+# トレースログに関する設定
+#
+ifeq ($(ENABLE_TRACE),true)
+ COPTS := $(COPTS) -DTOPPERS_ENABLE_TRACE
+ KERNEL_DIR := $(KERNEL_DIR) $(SRCDIR)/arch/logtrace
+ KERNEL_COBJS := $(KERNEL_COBJS) trace_config.o trace_dump.o
+endif
+
+#
+# ROM化時は ROM_BOOTをtrueに定義する
+#
+ifeq ($(ROM_BOOT),true)
+ CDEFS := $(CDEFS) -DROM_BOOT
+endif
+
+#
+# スタートアップモジュールに関する定義
+#
+# ldファイルに「STARTUP(start.o)」を記述したため,スタートアップモジュー
+# ルの名前をHIDDEN_OBJSに定義する.また,LDFLAGSに-nostdlibを追加している.
+#
+HIDDEN_OBJS = start.o
+
+$(HIDDEN_OBJS): %.o: %.S
+ $(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(HIDDEN_OBJS:.o=.d): %.d: %.S
+ @$(PERL) $(SRCDIR)/utils/makedep -C $(CC) \
+ -O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+LDFLAGS := -nostdlib $(LDFLAGS)
+
+#
+# 依存関係の定義
+#
+kernel_cfg.timestamp: $(CHIPDIR)/chip.tf
+$(OBJFILE): $(CHIPDIR)/chip_check.tf
+
+#
+# プロセッサ依存部のインクルード
+#
+include $(SRCDIR)/arch/$(PRC)_$(TOOL)/Makefile.prc
--- /dev/null
+$
+$ パス2のターゲット依存テンプレート(NXP LPC17XX汎用)
+$
+
+$
+$ プロセッサ依存のテンプレートファイルのインクルード
+$
+$INCLUDE"arm_m_gcc/prc.tf"$
--- /dev/null
+/**
+ * \addtogroup TOPPERS_CHIP
+ * \{
+ */
+
+/**
+ * \file chip_cfg1_out.h
+ * \brief cfg1_out.cをリンクするために必要なスタブの定義
+ */
+
+/*
+ * コア依存のスタブの定義を読み込む
+ */
+#include "arm_m_gcc/prc_cfg1_out.h"
+
+/**
+ * \}
+ */
--- /dev/null
+$
+$ パス3のチップ依存テンプレート(NXP LPC17XX汎用)
+$
+
+$
+$ パス3のプロセッサ依存のテンプレートのインクルード
+$
+$INCLUDE"arm_m_gcc/prc_check.tf"$
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ * Copyright (C) 2010 by TOPPERS/ASP for LPC project
+ * http://sourceforge.jp/projects/toppersasp4lpc/
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/**
+ * \addtogroup TOPPERS_CHIP
+ * \{
+ */
+/**
+ * \file chip_config.c
+ * \brief カーネル実装のチップ依存モジュール(LPC17xx汎用)
+ */
+#include "kernel_impl.h"
+#include <sil.h>
+#include "lpc17xx.h"
+#include "target_serial.h"
+#include "target_syssvc.h"
+
+void chip_initialize(void)
+{
+ /*
+ * プロセッサ依存部の初期化
+ */
+ prc_initialize();
+}
+
+void chip_exit(void)
+{
+ /* チップ依存部の終了処理 */
+ prc_terminate();
+}
+
+void chip_fput_log(char_t c)
+{
+ /*
+ * Newlineなら、CRも追加する
+ */
+ if (c == '\n') {
+ sio_pol_snd_chr('\r', SIO_PORTID);
+ }
+ sio_pol_snd_chr(c, SIO_PORTID);
+}
+
+/**
+ * \brief 低レベルのターゲット依存の初期化
+ * \details
+ * メモリ初期化の前に呼び出される
+ * CCRのSTKALIGNビットをクリアする
+ * このビットはCORTEX-M3コアがR1からR2に変化する過程で"1"に変更された。
+ * クリアしないとTOPPERS/ASPはクラッシュする。
+ */
+void hardware_init_hook()
+{
+ SCB->CCR &= ~SCB_CCR_STKALIGN_Msk;
+}
+
+/**
+ * \}
+ */
+
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ * Copyright (C) 2010 by TOPPERS/ASP for LPC project
+ * http://sourceforge.jp/projects/toppersasp4lpc/
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+#ifndef TOPPERS_CHIP_CONFIG_H
+#define TOPPERS_CHIP_CONFIG_H
+/**
+ * \addtogroup TOPPERS_CHIP
+ * \{
+ */
+
+/**
+ * \file chip_config.h
+ * \brief カーネル実装のチップ依存部モジュール(NXP LPC17XX用汎用)
+ * \details
+ * カーネルのターゲット依存部のインクルードファイル.kernel_impl.hのター
+ * ゲット依存部の位置付けとなす.
+ */
+
+/*
+ * チップ依存部の読み込み
+ */
+#include "lpc17xx.h"
+
+/*
+ * トレースログに関する設定
+ */
+#ifdef TOPPERS_ENABLE_TRACE
+#include "logtrace/trace_config.h"
+#endif /* TOPPERS_ENABLE_TRACE */
+
+
+
+
+/**
+ * \brief 非タスクコンテキスト用スタックポインタの初期値を格納する変数
+ * \details
+ * porting.txtは、*_kernel_istkptを変数として使い、そこに非タスクコンテキスト用
+ * スタックポインタの初期値を格納することを要請している。LPC1763の場合、*_kernel_istkptの
+ * 値は、SRAM実行とROM実行で異なる。これに対応するため、LDスクリプトで例外ベクトルの先頭を
+ * 指す値、_vector_start_lmaを作り、_kernel_istkptとして使用している。
+ */
+#define _kernel_istkpt _vector_start_lma
+
+#ifndef DEFAULT_ISTKSZ
+/**
+ * \brief デフォルトの非タスクコンテキスト用のスタック領域の定義
+ * \details
+ * 割り込み用のスタックのサイズを指定する。8の倍数として指定すること。このマクロは
+ * ターゲット依存部で指定していない場合にのみ使用される。
+ */
+#define DEFAULT_ISTKSZ (2048)
+#endif
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/**
+ * \brief チップ依存の初期化
+ * \details
+ * この館数はtarget_initializeから呼ぶことを前提としている。
+ */
+extern void chip_initialize(void);
+
+/**
+ * \brief チップの終了処理
+ * \details
+ * システムを終了する時に使う.この関数はtarget_exit()から
+ * 呼ぶことを前提としており、prc_terminate()を呼び、処理が終了すると制御を戻す。
+ */
+extern void chip_exit(void);
+
+/**
+ * \brief システムログの低レベル出力のための文字出力
+ * \param c 出力キャラクタ
+ * \details
+ * コンソールに1文字出力する。
+ */
+extern void chip_fput_log(char_t c);
+
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ * プロセッサ依存モジュール(ARM-M用)
+ */
+#include "arm_m_gcc/prc_config.h"
+
+#endif /* TOPPERS_CHIP_CONFIG_H */
+
+/**
+ * \}
+ */
+
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ * Copyright (C) 2010 by TOPPERS/ASP for LPC project
+ * http://sourceforge.jp/projects/toppersasp4lpc/
+ *
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/**
+ * \addtogroup TOPPERS_CHIP
+ * \{
+ */
+
+
+/**
+ * \file chip_kernel.h
+ * \brief kernel.hのターゲット依存部(NXP LPC17XX汎用)
+ * \details
+ * このインクルードファイルは,kernel.hでインクルードされる.他のファ
+ * イルから直接インクルードすることはない.このファイルをインクルード
+ * する前に,t_stddef.hがインクルードされるので,それらに依存してもよ
+ * い.
+ */
+
+#ifndef TOPPERS_CHIP_KERNEL_H
+#define TOPPERS_CHIP_KERNEL_H
+
+/**
+ * \brief 割込み優先度の最小値(最高値)。
+ * \details
+ * SoC設計者によるCORTEX-M3のコンフィギュレーションに従った値を
+ * 指定する。詳細は prc_user.txtを参照
+ */
+#define TMIN_INTPRI (-31)
+
+/**
+ * \brief サポートする機能の定義
+ * \details
+ * get_utim()関数をアプリケーションに提供することを宣言する。
+ */
+#define TOPPERS_SUPPORT_GET_UTM /* get_utmをサポートする */
+
+/**
+ * \brief タイムティックの周期の分子
+ * \details
+ * porting.txtの5章で要請されており、タイマーの割り込み周期から
+ * 1mSのシステム・タイマーを作るために宣言する。タイマーの割り込み
+ * 周期が1mSなら、1でいい。
+ */
+#define TIC_NUME 1U
+
+/**
+ * \brief タイムティックの周期の分母
+ * \details
+ * porting.txtの5章で要請されており、タイマーの割り込み周期から
+ * 1mSのシステム・タイマーを作るために宣言する。タイマーの割り込み
+ * 周期が1mSなら、1でいい。
+ */
+#define TIC_DENO 1U
+
+/*
+ * プロセッサで共通な定義
+ */
+#include "arm_m_gcc/prc_kernel.h"
+
+#endif /* TOPPERS_CHIP_KERNEL_H */
+
+/**
+ * \}
+ */
+
+
--- /dev/null
+INCLUDE "arm_m_gcc/prc"
+
+chip_initialize
+initPLL0
+chip_exit
+chip_fput_log
\ No newline at end of file
--- /dev/null
+/* This file is generated from chip_rename.def by genrename. */
+
+#ifndef TOPPERS_CHIP_RENAME_H
+#define TOPPERS_CHIP_RENAME_H
+
+
+#define chip_initialize _kernel_chip_initialize
+#define chip_exit _kernel_chip_exit
+#define chip_fput_log _kernel_chip_fput_log
+
+#ifdef TOPPERS_LABEL_ASM
+
+
+#define _chip_initialize __kernel_chip_initialize
+#define _chip_exit __kernel_chip_exit
+#define _chip_fput_log __kernel_chip_fput_log
+
+#endif /* TOPPERS_LABEL_ASM */
+
+#include "arm_m_gcc/prc_rename.h"
+
+#endif /* TOPPERS_CHIP_RENAME_H */
--- /dev/null
+/*
+ * SIOドライバ(UART汎用)のコンフィグレーションファイル
+ */
+
+#include "target_serial.h"
+ATT_INI({ TA_NULL, 0, sio_initialize });
+ATT_ISR({ TA_NULL, SIO_PORTID, INTNO_SIO, sio_isr, 1 });
+CFG_INT(INTNO_SIO, { TA_ENAINT | INTATR_SIO, INTPRI_SIO });
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ * Copyright (C) 2010 by TOPPERS/ASP for LPC project
+ * http://sourceforge.jp/projects/toppersasp4lpc/
+ *
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/**
+ * \addtogroup TOPPERS_CHIP
+ * \{
+ */
+
+/**
+ * \file chip_serial.h
+ * \brief シリアルI/Oデバイス(SIO)ドライバ(UART汎用)
+ * \details
+ * このファイルはasp/pdic/uart/uart.hをそのまま読み込む。
+ * それによって、あらかじめ用意されているuartドライバを使用する。
+ */
+
+#ifndef TOPPERS_CHIP_SERIAL_H
+#define TOPPERS_CHIP_SERIAL_H
+
+#include "../../pdic/uart/uart.h"
+
+
+#endif /* TOPPERS_CHIP_SERIAL_H */
+/**
+ * \}
+ */
+
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ * Copyright (C) 2010 by TOPPERS/ASP for LPC project
+ * http://sourceforge.jp/projects/toppersasp4lpc/
+ *
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/**
+ * \addtogroup TOPPERS_CHIP
+ * \{
+ */
+
+/**
+ * \file chip_sil.h
+ * \brief sil.hのチップ依存部(NXP LPC17XX汎用)
+ * \details
+ * このインクルードファイルは,sil.hの先頭でインクルードされる.他のファ
+ * イルからは直接インクルードすることはない.このファイルをインクルー
+ * ドする前に,t_stddef.hがインクルードされるので,それらに依存しても
+ * よい.
+ */
+
+#ifndef TOPPERS_CHIP_SIL_H
+#define TOPPERS_CHIP_SIL_H
+
+/**
+ * \brief プロセッサのエンディアン宣言
+ * \details
+ * プロセッサがリトル・エンディアンの場合には、このマクロを宣言する。
+ * LPC17xxはリトル・エンディアンとして設計されている。
+ */
+#define SIL_ENDIAN_LITTLE
+
+/**
+ * \brief リセット時のMSP設定
+ * \details
+ * INIT_MSPを宣言すると、start.Sの中でリセット直後にMSPに初期値を代入する。
+ * この操作はLPC1700においてRAM上でGDBからダウンロードしたソフトを実行する場合に必要になる。
+ *
+ * デバッグ時に便利なので、ROM化、SRAM実行いずれの場合もメモリ量で困っていない限り、
+ * INIT_MSPを宣言しておくとよい。
+ */
+
+#define INIT_MSP
+
+/*
+ * プロセッサで共通な定義
+ */
+#include "arm_m_gcc/prc_sil.h"
+
+
+#endif /* TOPPERS_CHIP_SIL_H */
+/**
+ * \}
+ */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ * Copyright (C) 2010 by TOPPERS/ASP for LPC project
+ * http://sourceforge.jp/projects/toppersasp4lpc/
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/**
+ * \addtogroup TOPPERS_CHIP
+ * \{
+ */
+
+/**
+ * \file chip_stddef.h
+ * \brief t_stddef.hのチップ依存部(NXP LPC17xx用)
+ * \details
+ * このインクルードファイルは,target_stddef.hの先頭でインクルードされる.
+ * 他のファイルからは直接インクルードすることはない.他のインクルード
+ * ファイルに先立って処理されるため,他のインクルードファイルに依存し
+ * てはならない.
+ */
+
+#ifndef TOPPERS_CHIP_STDDEF_H
+#define TOPPERS_CHIP_STDDEF_H
+
+/**
+ * \brief ターゲットを識別するためのマクロの定義
+ * \details
+ * 各種のチップに対応可能なコードの中で、LPC17xxに依存する部分がある場合は
+ * このマクロによる条件コンパイルにする。
+ *
+ * ターゲット依存部とはっきり区別するため、チップ依存部の識別名の前にTOPPERS_CHIP_を
+ * つけることを推奨する。
+ */
+#define TOPPERS_CHIP_LPC17XX /* チップ略称 */
+
+
+/*
+ * 開発環境で共通な定義
+ */
+#ifndef TOPPERS_MACRO_ONLY
+#include "stdint.h"
+#endif
+
+/**
+ * \brief 標準浮動小数点型を使う
+ * \details
+ * IEEE標準の浮動小数点型を使うことを宣言。version.txt参照
+ */
+#define TOPPERS_STDFLOAT_TYPE1
+#include "gcc/tool_stddef.h"
+
+/*
+ * プロセッサで共通な定義
+ */
+#include "arm_m_gcc/prc_stddef.h"
+
+#endif /* TOPPERS_CHIP_STDDEF_H */
+
+/**
+ * \}
+ */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ * Copyright (C) 2010 by TOPPERS/ASP for LPC project
+ * http://sourceforge.jp/projects/toppersasp4lpc/
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/**
+ * \addtogroup TOPPERS_CHIP
+ * \{
+ */
+
+
+/**
+ * \file chip_syssvc.h
+ * \brief システムサービスのチップ依存部(NXP LPC17xx用)
+ * \details
+ * システムサービスのターゲット依存部のインクルードファイル.このファ
+ * イルの内容は,コンポーネント記述ファイルに記述され,このファイルは
+ * 無くなる見込み.
+ */
+
+#ifndef TOPPERS_CHIP_SYSSVC_H
+#define TOPPERS_CHIP_SYSSVC_H
+
+/*
+ * ターゲットシステムのハードウェア資源の定義
+ */
+#include "lpc17xx.h"
+
+/*
+ * トレースログに関する設定
+ */
+#ifdef TOPPERS_TRACE_ENABLE
+#include "logtrace/trace_config.h"
+#endif /* TOPPERS_TRACE_ENABLE */
+
+
+/**
+ * \brief 起動メッセージ
+ * \details
+ * 起動メッセージにチップ依存部の著作権表示を
+ * 追加するためのマクロ.
+ */
+#ifdef PRC_COPYRIGHT
+#define CHIP_COPYRIGHT PRC_COPYRIGHT "Copyright (C) 2010 by TOPPERS/ASP for LPC project\n http://sourceforge.jp/projects/toppersasp4lpc/\n"
+#else
+#define CHIP_COPYRIGHT "Copyright (C) 2010 by TOPPERS/ASP for LPC project\n http://sourceforge.jp/projects/toppersasp4lpc/\n"
+#endif /* CHIP_COPYRIGHT */
+
+
+/**
+ * \brief UARTへの入力クロック
+ * \details
+ * 内蔵UARTのクロック周波数を指定する。単位はHz。LPC17xxはそれぞれのUARTに対して
+ * 独立した周波数を入力できるが、今回の実装ではtarget_serial.cはすべてのUARTに
+ * 同じクロックが入力されれると仮定している。
+ *
+ * この実装では、UART用のペリフェラル・クロックの分周比は1/4であり、これはリセット値である。
+ */
+#define SIO_UART_CLOCK (SYS_CLOCK/4)
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/**
+ * \brief システムログの低レベル出力のための文字出力
+ * \details
+ * ターゲット依存の方法で,文字cを表示/出力/保存する.LPC17XXの実装では、
+ * pdic/uartのポーリングによる出力ルーチンを呼ぶ。
+ *
+ * このルーチンを呼ぶ前に、初期化として #target_uart_init()を一度呼ばなければ
+ * ならない。ターゲット依存部の#target_initialize()で呼ぶとよい。
+ */
+extern void chip_fput_log(char_t c);
+
+#endif /* TOPPERS_MACRO_ONLY */
+#endif /* TOPPERS_CHIP_SYSSVC_H */
+
+/**
+ * \}
+ */
+
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ * Copyright (C) 2010 by TOPPERS/ASP for LPC project
+ * http://sourceforge.jp/projects/toppersasp4lpc/
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/**
+ * \addtogroup TOPPERS_CHIP
+ * \{
+ */
+
+
+/**
+ * \file chip_test.h
+ * \brief テストプログラムのチップ依存定義(NXP LPC17xx用)
+ */
+
+#ifndef TOPPERS_CHIP_TEST_H
+#define TOPPERS_CHIP_TEST_H
+
+
+/*
+ * プロセッサ依存モジュール(ARM-M用)
+ */
+#include "arm_m_gcc/prc_test.h"
+
+#endif /* TOPPERS_CHIP_TEST_H */
+
+/**
+ * \}
+ */
+
--- /dev/null
+#include "target_timer.h"
+
+INCLUDE("arm_m_gcc/prc_timer.cfg");
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ * Copyright (C) 2010 by TOPPERS/ASP for LPC project
+ * http://sourceforge.jp/projects/toppersasp4lpc/
+ *
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/**
+ * \addtogroup TOPPERS_CHIP
+ * \{
+ */
+
+/**
+ * \file chip_timer.h
+ * \brief タイマドライバ(NXP LPC17XX汎用)
+ */
+
+#ifndef TOPPERS_CHIP_TIMER_H
+#define TOPPERS_CHIP_TIMER_H
+
+#include "target_syssvc.h"
+
+/**
+ * \brief CPUコアクロックとタイマー割り込み周期の比
+ */
+#define TIMER_CLOCK (SYS_CLOCK / 1000)
+
+/**
+ * \brief 割込み優先度
+ * \details
+ * タイマ割込みハンドラ登録のための定数。コンフィギュレータが静的コンフィギュレーション時に、タイマー登録用
+ * 引数として使う。
+ */
+#define INTPRI_TIMER (-6)
+
+/**
+ * \brief 割込み属性
+ * \details
+ * タイマ割込みハンドラ登録のための定数。コンフィギュレータが静的コンフィギュレーション時に、タイマー登録用
+ * 引数として使う。この値は0でいい。
+ */
+#define INTATR_TIMER 0U
+
+/*
+ * プロセッサ依存部で定義する
+ */
+#include "arm_m_gcc/prc_timer.h"
+
+#endif /* TOPPERS_CHIP_TIMER_H */
+
+/**
+ * \}
+ */
--- /dev/null
+/* This file is generated from chip_rename.def by genrename. */
+
+/* This file is included only when chip_rename.h has been included. */
+#ifdef TOPPERS_CHIP_RENAME_H
+#undef TOPPERS_CHIP_RENAME_H
+
+
+#undef chip_initialize
+#undef chip_exit
+#undef chip_fput_log
+
+#ifdef TOPPERS_LABEL_ASM
+
+
+#undef _chip_initialize
+#undef _chip_exit
+#undef _chip_fput_log
+
+#endif /* TOPPERS_LABEL_ASM */
+
+#include "arm_m_gcc/prc_unrename.h"
+
+#endif /* TOPPERS_CHIP_RENAME_H */
--- /dev/null
+=====================================================================
+ CHIP_LPC17XXチップ依存部 (asp-1.6.0対応)
+ Last Modified: 2010/Oct/23
+=====================================================================
+
+このチップ依存部は、TOPPERS/ASP 1.3.2対応 CQ-STARM依存部を元に開発した。
+
+(1) 対応しているターゲットシステムの種類・構成,バージョン番号
+
+ ・ターゲットハードウェア(ボード等)の名称と対応している構成
+ NXP製LPC17シリーズに共有のチップ依存部
+
+ ・ターゲット略称
+ lpc17xx_gcc
+
+ ・ターゲット非依存部のバージョン番号
+ 1.6
+
+ ・プロセッサ,チップ,開発環境依存部の構成とバージョン番号
+ 1.6.1
+
+ ・使用するPDICとバージョン番号
+ ターゲットに選択は任せてあるが、標準でpdic/uartを用意している。
+
+(2) 使用する開発環境と動作検証した条件(バージョン,オプション等)
+
+ ・言語処理系(コンパイラ,アセンブラ,リンカ等)
+ gcc version 4.4.1 (Sourcery G++ Lite 2010q1-188)
+
+ ・デバッグ環境
+ GNU gdb (Sourcery G++ Lite 2010q1-188) 7.0.50.20100218-cvs
+ Open On-Chip Debugger 0.4.0 (2010-08-12-22:40)
+ HJ/LINK USB
+
+(3) ターゲット定義事項の規定
+(3-1) データ型に関する規定
+(3-2) 割込み処理に関する規定
+
+ 以下の割り込みベクトル用インデックスを使用している。INHNO_XXXおよびINTNO_XXXも同じ値を持つ。
+
+#define IRQ_VECTOR_WDT (16+WDT_IRQn)
+#define IRQ_VECTOR_TIMER0 (16+TIMER0_IRQn)
+#define IRQ_VECTOR_TIMER1 (16+TIMER1_IRQn)
+#define IRQ_VECTOR_TIMER2 (16+TIMER2_IRQn)
+#define IRQ_VECTOR_TIMER3 (16+TIMER3_IRQn)
+#define IRQ_VECTOR_UART0 (16+UART0_IRQn)
+#define IRQ_VECTOR_UART1 (16+UART1_IRQn)
+#define IRQ_VECTOR_UART2 (16+UART2_IRQn)
+#define IRQ_VECTOR_UART3 (16+UART3_IRQn)
+#define IRQ_VECTOR_PWM1 (16+PWM1_IRQn)
+#define IRQ_VECTOR_I2C0 (16+I2C0_IRQn)
+#define IRQ_VECTOR_I2C1 (16+I2C1_IRQn)
+#define IRQ_VECTOR_I2C2 (16+I2C2_IRQn)
+#define IRQ_VECTOR_SPI (16+SPI_IRQn)
+#define IRQ_VECTOR_SSP0 (16+SSP0_IRQn)
+#define IRQ_VECTOR_SSP1 (16+SSP1_IRQn)
+#define IRQ_VECTOR_PLL0 (16+PLL0_IRQn)
+#define IRQ_VECTOR_RTC (16+RTC_IRQn)
+#define IRQ_VECTOR_EINT0 (16+EINT0_IRQn)
+#define IRQ_VECTOR_EINT1 (16+EINT1_IRQn)
+#define IRQ_VECTOR_EINT2 (16+EINT2_IRQn)
+#define IRQ_VECTOR_EINT3 (16+EINT3_IRQn)
+#define IRQ_VECTOR_ADC (16+ADC_IRQn)
+#define IRQ_VECTOR_BOD (16+BOD_IRQn)
+#define IRQ_VECTOR_USB (16+USB_IRQn)
+#define IRQ_VECTOR_CAN (16+CAN_IRQn)
+#define IRQ_VECTOR_DMA (16+DMA_IRQn)
+#define IRQ_VECTOR_I2S (16+I2S_IRQn)
+#define IRQ_VECTOR_ENET (16+ENET_IRQn)
+#define IRQ_VECTOR_RIT (16+RIT_IRQn)
+#define IRQ_VECTOR_MCPWM (16+MCPWM_IRQn)
+#define IRQ_VECTOR_QEI (16+QEI_IRQn)
+#define IRQ_VECTOR_PLL1 (16+PLL1_IRQn)
+#define IRQ_VECTOR_USBActivity (16+USBActivity_IRQn)
+#define IRQ_VECTOR_CANActivity (16+CANActivity_IRQn)
+
+(3-3) カーネル管理外の割込みに関する規定
+(3-4) CPU例外処理に関する規定
+(3-5) 性能評価用システム時刻の参照に関する規定
+(3-6) オーバランハンドラ機能拡張のサポートに関する規定
+(3-7) その他
+
+(4) カーネルの起動/終了処理に関する情報
+ ・用意しているスタートアップモジュールの処理内容
+ chip_initialize()では、prc_initialize()を呼び出してプロセッサを初期化する。
+
+ ・hardware_init_hook
+ SCB_CCR_STKALIGN_Mskをクリアして、例外割り込みのアライメントをCORETX-M3 rev 1に
+ あわせている。
+
+ ・カーネルを終了した後の振舞い
+ chip_exit()はprc_terminate()を呼ぶ。
+
+
+(5) メモリマップ
+ ターゲット依存部で決定するので、チップ依存部はメモリマップを操作しない。
+
+(6) タイマドライバ関連の情報
+
+ ・タイムティックの周期,その変更方法
+ タイムティックはchip_timer.hによって変更できる。周期を変更した場合、
+ chip_kernel.hのTIC_NUME, TIC_DENOを変更して1mSを生成する方法をカーネルに知らせる。
+
+ ・使用するリソース(タイマ)
+ SYSTICKタイマーを使う。
+
+ ・タイマ割込みの割込み優先度の変更方法
+ chip_timer.hのINTPRI_TIMERを変更する。
+
+ ・オーバランタイマ割込みの割込み優先度の変更方法
+
+(7) シリアルインタフェースドライバの情報
+
+ target_user.txtを参照。
+
+(8) システムログ機能の情報
+
+ ・システムログの低レベル出力の実現方法
+ target_config.hのtarget_fput_log()が使用できるよう、chip_fput_log()を用意している。
+
+(9) システム構築手順
+
+ target_user.txt参照
+
+(10) ターゲットシステム固有の注意事項
+
+(10) 類似のターゲットにポーティングする開発者向けの参考情報
+ CORTEX-M3を使った他のチップにポーティングする場合には、以下のオブジェクトを修正する
+
+ lpc17xx.h (名前をチップ識別名に変更する)
+ CMSIS インクルードするCMSISヘッダファイルを変更する
+ TMAX_INTNO 最大の割り込みインデックス番号
+ TBITW_IPRI NVICの割り込み優先順位のビット幅
+ TBITW_SUBIPRI NVICのサブプライオリティのビット幅
+ 割り込みベクトル番号 チップに沿った宣言に変更する。
+
+ chip_config.h
+ initPLL0() PLL初期化シーケンスはチップ依存である
+
+ target_config.c
+ chip_initilaize() 初期火事にチップ依存の特殊処理が必要なら変更する
+ chip_exit() 終了時にチップ依存の特殊処理が必要なら変更する
+ chip_fput_log() 使用するSIOドライバが変わるなら変更する
+ initPLL0() PLL初期化シーケンスはチップ依存である
+ hardware_init_hook チップに強く依存するので必ず変更する
+
+ chip_stddef.h
+ TOPPERS_CHIP_LPC17XX ターゲット識別マクロ。ターゲット識別名を大文字にし、頭に
+ TOPPERS_CHIP_をつける。
+
+ chip_syssvc.h
+ SIO_UART_CLOCK pdc/uartを使用する場合、UARTに入力されるクロックの周波数を宣言する
+ CHIP_COPYRIGHT チップ依存部の著作権表示文字列
+
+ chip_timer.h
+ TIMER_CLOCK CPUクロックとタイマー周期の比
+
+ LPC1700では、SYS_CLOCKを「CPUコアへの入力」としているが、チップによっては「PLLの出力」とする
+ ほうがよい。
+
+(12) ディレクトリ構成・ファイル構成
+ target_user.txtを参照。
+
+(13) バージョン履歴
+
+2010/Oct/23
+ ver 1.6.0
+
+
+
+
+
--- /dev/null
+/**************************************************************************//**\r
+ * @file core_cm3.h\r
+ * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File\r
+ * @version V1.30\r
+ * @date 30. October 2009\r
+ *\r
+ * @note\r
+ * Copyright (C) 2009 ARM Limited. All rights reserved.\r
+ *\r
+ * @par\r
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M\r
+ * processor based microcontrollers. This file can be freely distributed\r
+ * within development tools that are supporting such ARM based processors.\r
+ *\r
+ * @par\r
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED\r
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.\r
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR\r
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.\r
+ *\r
+ ******************************************************************************/\r
+\r
+#ifndef __CM3_CORE_H__\r
+#define __CM3_CORE_H__\r
+\r
+/** @addtogroup CMSIS_CM3_core_LintCinfiguration CMSIS CM3 Core Lint Configuration\r
+ *\r
+ * List of Lint messages which will be suppressed and not shown:\r
+ * - Error 10: \n\r
+ * register uint32_t __regBasePri __asm("basepri"); \n\r
+ * Error 10: Expecting ';'\r
+ * .\r
+ * - Error 530: \n\r
+ * return(__regBasePri); \n\r
+ * Warning 530: Symbol '__regBasePri' (line 264) not initialized\r
+ * .\r
+ * - Error 550: \n\r
+ * __regBasePri = (basePri & 0x1ff); \n\r
+ * Warning 550: Symbol '__regBasePri' (line 271) not accessed\r
+ * .\r
+ * - Error 754: \n\r
+ * uint32_t RESERVED0[24]; \n\r
+ * Info 754: local structure member '<some, not used in the HAL>' (line 109, file ./cm3_core.h) not referenced\r
+ * .\r
+ * - Error 750: \n\r
+ * #define __CM3_CORE_H__ \n\r
+ * Info 750: local macro '__CM3_CORE_H__' (line 43, file./cm3_core.h) not referenced\r
+ * .\r
+ * - Error 528: \n\r
+ * static __INLINE void NVIC_DisableIRQ(uint32_t IRQn) \n\r
+ * Warning 528: Symbol 'NVIC_DisableIRQ(unsigned int)' (line 419, file ./cm3_core.h) not referenced\r
+ * .\r
+ * - Error 751: \n\r
+ * } InterruptType_Type; \n\r
+ * Info 751: local typedef 'InterruptType_Type' (line 170, file ./cm3_core.h) not referenced\r
+ * .\r
+ * Note: To re-enable a Message, insert a space before 'lint' *\r
+ *\r
+ */\r
+\r
+/*lint -save */\r
+/*lint -e10 */\r
+/*lint -e530 */\r
+/*lint -e550 */\r
+/*lint -e754 */\r
+/*lint -e750 */\r
+/*lint -e528 */\r
+/*lint -e751 */\r
+\r
+\r
+/** @addtogroup CMSIS_CM3_core_definitions CM3 Core Definitions\r
+ This file defines all structures and symbols for CMSIS core:\r
+ - CMSIS version number\r
+ - Cortex-M core registers and bitfields\r
+ - Cortex-M core peripheral base address\r
+ @{\r
+ */\r
+\r
+#ifdef __cplusplus\r
+ extern "C" {\r
+#endif\r
+\r
+#define __CM3_CMSIS_VERSION_MAIN (0x01) /*!< [31:16] CMSIS HAL main version */\r
+#define __CM3_CMSIS_VERSION_SUB (0x30) /*!< [15:0] CMSIS HAL sub version */\r
+#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16) | __CM3_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */\r
+\r
+#define __CORTEX_M (0x03) /*!< Cortex core */\r
+\r
+#include <stdint.h> /* Include standard types */\r
+\r
+#if defined (__ICCARM__)\r
+ #include <intrinsics.h> /* IAR Intrinsics */\r
+#endif\r
+\r
+\r
+#ifndef __NVIC_PRIO_BITS\r
+ #define __NVIC_PRIO_BITS 4 /*!< standard definition for NVIC Priority Bits */\r
+#endif\r
+\r
+\r
+\r
+\r
+/**\r
+ * IO definitions\r
+ *\r
+ * define access restrictions to peripheral registers\r
+ */\r
+\r
+#ifdef __cplusplus\r
+ #define __I volatile /*!< defines 'read only' permissions */\r
+#else\r
+ #define __I volatile const /*!< defines 'read only' permissions */\r
+#endif\r
+#define __O volatile /*!< defines 'write only' permissions */\r
+#define __IO volatile /*!< defines 'read / write' permissions */\r
+\r
+\r
+\r
+/*******************************************************************************\r
+ * Register Abstraction\r
+ ******************************************************************************/\r
+/** @addtogroup CMSIS_CM3_core_register CMSIS CM3 Core Register\r
+ @{\r
+*/\r
+\r
+\r
+/** @addtogroup CMSIS_CM3_NVIC CMSIS CM3 NVIC\r
+ memory mapped structure for Nested Vectored Interrupt Controller (NVIC)\r
+ @{\r
+ */\r
+typedef struct\r
+{\r
+ __IO uint32_t ISER[8]; /*!< Offset: 0x000 Interrupt Set Enable Register */\r
+ uint32_t RESERVED0[24];\r
+ __IO uint32_t ICER[8]; /*!< Offset: 0x080 Interrupt Clear Enable Register */\r
+ uint32_t RSERVED1[24];\r
+ __IO uint32_t ISPR[8]; /*!< Offset: 0x100 Interrupt Set Pending Register */\r
+ uint32_t RESERVED2[24];\r
+ __IO uint32_t ICPR[8]; /*!< Offset: 0x180 Interrupt Clear Pending Register */\r
+ uint32_t RESERVED3[24];\r
+ __IO uint32_t IABR[8]; /*!< Offset: 0x200 Interrupt Active bit Register */\r
+ uint32_t RESERVED4[56];\r
+ __IO uint8_t IP[240]; /*!< Offset: 0x300 Interrupt Priority Register (8Bit wide) */\r
+ uint32_t RESERVED5[644];\r
+ __O uint32_t STIR; /*!< Offset: 0xE00 Software Trigger Interrupt Register */\r
+} NVIC_Type;\r
+/*@}*/ /* end of group CMSIS_CM3_NVIC */\r
+\r
+\r
+/** @addtogroup CMSIS_CM3_SCB CMSIS CM3 SCB\r
+ memory mapped structure for System Control Block (SCB)\r
+ @{\r
+ */\r
+typedef struct\r
+{\r
+ __I uint32_t CPUID; /*!< Offset: 0x00 CPU ID Base Register */\r
+ __IO uint32_t ICSR; /*!< Offset: 0x04 Interrupt Control State Register */\r
+ __IO uint32_t VTOR; /*!< Offset: 0x08 Vector Table Offset Register */\r
+ __IO uint32_t AIRCR; /*!< Offset: 0x0C Application Interrupt / Reset Control Register */\r
+ __IO uint32_t SCR; /*!< Offset: 0x10 System Control Register */\r
+ __IO uint32_t CCR; /*!< Offset: 0x14 Configuration Control Register */\r
+ __IO uint8_t SHP[12]; /*!< Offset: 0x18 System Handlers Priority Registers (4-7, 8-11, 12-15) */\r
+ __IO uint32_t SHCSR; /*!< Offset: 0x24 System Handler Control and State Register */\r
+ __IO uint32_t CFSR; /*!< Offset: 0x28 Configurable Fault Status Register */\r
+ __IO uint32_t HFSR; /*!< Offset: 0x2C Hard Fault Status Register */\r
+ __IO uint32_t DFSR; /*!< Offset: 0x30 Debug Fault Status Register */\r
+ __IO uint32_t MMFAR; /*!< Offset: 0x34 Mem Manage Address Register */\r
+ __IO uint32_t BFAR; /*!< Offset: 0x38 Bus Fault Address Register */\r
+ __IO uint32_t AFSR; /*!< Offset: 0x3C Auxiliary Fault Status Register */\r
+ __I uint32_t PFR[2]; /*!< Offset: 0x40 Processor Feature Register */\r
+ __I uint32_t DFR; /*!< Offset: 0x48 Debug Feature Register */\r
+ __I uint32_t ADR; /*!< Offset: 0x4C Auxiliary Feature Register */\r
+ __I uint32_t MMFR[4]; /*!< Offset: 0x50 Memory Model Feature Register */\r
+ __I uint32_t ISAR[5]; /*!< Offset: 0x60 ISA Feature Register */\r
+} SCB_Type;\r
+\r
+/* SCB CPUID Register Definitions */\r
+#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */\r
+#define SCB_CPUID_IMPLEMENTER_Msk (0xFFul << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */\r
+\r
+#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */\r
+#define SCB_CPUID_VARIANT_Msk (0xFul << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */\r
+\r
+#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */\r
+#define SCB_CPUID_PARTNO_Msk (0xFFFul << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */\r
+\r
+#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */\r
+#define SCB_CPUID_REVISION_Msk (0xFul << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */\r
+\r
+/* SCB Interrupt Control State Register Definitions */\r
+#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */\r
+#define SCB_ICSR_NMIPENDSET_Msk (1ul << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */\r
+\r
+#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */\r
+#define SCB_ICSR_PENDSVSET_Msk (1ul << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */\r
+\r
+#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */\r
+#define SCB_ICSR_PENDSVCLR_Msk (1ul << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */\r
+\r
+#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */\r
+#define SCB_ICSR_PENDSTSET_Msk (1ul << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */\r
+\r
+#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */\r
+#define SCB_ICSR_PENDSTCLR_Msk (1ul << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */\r
+\r
+#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */\r
+#define SCB_ICSR_ISRPREEMPT_Msk (1ul << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */\r
+\r
+#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */\r
+#define SCB_ICSR_ISRPENDING_Msk (1ul << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */\r
+\r
+#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */\r
+#define SCB_ICSR_VECTPENDING_Msk (0x1FFul << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */\r
+\r
+#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */\r
+#define SCB_ICSR_RETTOBASE_Msk (1ul << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */\r
+\r
+#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */\r
+#define SCB_ICSR_VECTACTIVE_Msk (0x1FFul << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */\r
+\r
+/* SCB Interrupt Control State Register Definitions */\r
+#define SCB_VTOR_TBLBASE_Pos 29 /*!< SCB VTOR: TBLBASE Position */\r
+#define SCB_VTOR_TBLBASE_Msk (0x1FFul << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */\r
+\r
+#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */\r
+#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFul << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */\r
+\r
+/* SCB Application Interrupt and Reset Control Register Definitions */\r
+#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */\r
+#define SCB_AIRCR_VECTKEY_Msk (0xFFFFul << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */\r
+\r
+#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */\r
+#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFul << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */\r
+\r
+#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */\r
+#define SCB_AIRCR_ENDIANESS_Msk (1ul << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */\r
+\r
+#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */\r
+#define SCB_AIRCR_PRIGROUP_Msk (7ul << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */\r
+\r
+#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */\r
+#define SCB_AIRCR_SYSRESETREQ_Msk (1ul << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */\r
+\r
+#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */\r
+#define SCB_AIRCR_VECTCLRACTIVE_Msk (1ul << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */\r
+\r
+#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */\r
+#define SCB_AIRCR_VECTRESET_Msk (1ul << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */\r
+\r
+/* SCB System Control Register Definitions */\r
+#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */\r
+#define SCB_SCR_SEVONPEND_Msk (1ul << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */\r
+\r
+#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */\r
+#define SCB_SCR_SLEEPDEEP_Msk (1ul << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */\r
+\r
+#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */\r
+#define SCB_SCR_SLEEPONEXIT_Msk (1ul << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */\r
+\r
+/* SCB Configuration Control Register Definitions */\r
+#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */\r
+#define SCB_CCR_STKALIGN_Msk (1ul << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */\r
+\r
+#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */\r
+#define SCB_CCR_BFHFNMIGN_Msk (1ul << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */\r
+\r
+#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */\r
+#define SCB_CCR_DIV_0_TRP_Msk (1ul << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */\r
+\r
+#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */\r
+#define SCB_CCR_UNALIGN_TRP_Msk (1ul << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */\r
+\r
+#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */\r
+#define SCB_CCR_USERSETMPEND_Msk (1ul << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */\r
+\r
+#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */\r
+#define SCB_CCR_NONBASETHRDENA_Msk (1ul << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */\r
+\r
+/* SCB System Handler Control and State Register Definitions */\r
+#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */\r
+#define SCB_SHCSR_USGFAULTENA_Msk (1ul << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */\r
+\r
+#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */\r
+#define SCB_SHCSR_BUSFAULTENA_Msk (1ul << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */\r
+\r
+#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */\r
+#define SCB_SHCSR_MEMFAULTENA_Msk (1ul << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */\r
+\r
+#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */\r
+#define SCB_SHCSR_SVCALLPENDED_Msk (1ul << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */\r
+\r
+#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */\r
+#define SCB_SHCSR_BUSFAULTPENDED_Msk (1ul << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */\r
+\r
+#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */\r
+#define SCB_SHCSR_MEMFAULTPENDED_Msk (1ul << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */\r
+\r
+#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */\r
+#define SCB_SHCSR_USGFAULTPENDED_Msk (1ul << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */\r
+\r
+#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */\r
+#define SCB_SHCSR_SYSTICKACT_Msk (1ul << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */\r
+\r
+#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */\r
+#define SCB_SHCSR_PENDSVACT_Msk (1ul << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */\r
+\r
+#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */\r
+#define SCB_SHCSR_MONITORACT_Msk (1ul << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */\r
+\r
+#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */\r
+#define SCB_SHCSR_SVCALLACT_Msk (1ul << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */\r
+\r
+#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */\r
+#define SCB_SHCSR_USGFAULTACT_Msk (1ul << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */\r
+\r
+#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */\r
+#define SCB_SHCSR_BUSFAULTACT_Msk (1ul << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */\r
+\r
+#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */\r
+#define SCB_SHCSR_MEMFAULTACT_Msk (1ul << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */\r
+\r
+/* SCB Configurable Fault Status Registers Definitions */\r
+#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */\r
+#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFul << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */\r
+\r
+#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */\r
+#define SCB_CFSR_BUSFAULTSR_Msk (0xFFul << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */\r
+\r
+#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */\r
+#define SCB_CFSR_MEMFAULTSR_Msk (0xFFul << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */\r
+\r
+/* SCB Hard Fault Status Registers Definitions */\r
+#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */\r
+#define SCB_HFSR_DEBUGEVT_Msk (1ul << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */\r
+\r
+#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */\r
+#define SCB_HFSR_FORCED_Msk (1ul << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */\r
+\r
+#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */\r
+#define SCB_HFSR_VECTTBL_Msk (1ul << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */\r
+\r
+/* SCB Debug Fault Status Register Definitions */\r
+#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */\r
+#define SCB_DFSR_EXTERNAL_Msk (1ul << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */\r
+\r
+#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */\r
+#define SCB_DFSR_VCATCH_Msk (1ul << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */\r
+\r
+#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */\r
+#define SCB_DFSR_DWTTRAP_Msk (1ul << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */\r
+\r
+#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */\r
+#define SCB_DFSR_BKPT_Msk (1ul << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */\r
+\r
+#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */\r
+#define SCB_DFSR_HALTED_Msk (1ul << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */\r
+/*@}*/ /* end of group CMSIS_CM3_SCB */\r
+\r
+\r
+/** @addtogroup CMSIS_CM3_SysTick CMSIS CM3 SysTick\r
+ memory mapped structure for SysTick\r
+ @{\r
+ */\r
+typedef struct\r
+{\r
+ __IO uint32_t CTRL; /*!< Offset: 0x00 SysTick Control and Status Register */\r
+ __IO uint32_t LOAD; /*!< Offset: 0x04 SysTick Reload Value Register */\r
+ __IO uint32_t VAL; /*!< Offset: 0x08 SysTick Current Value Register */\r
+ __I uint32_t CALIB; /*!< Offset: 0x0C SysTick Calibration Register */\r
+} SysTick_Type;\r
+\r
+/* SysTick Control / Status Register Definitions */\r
+#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */\r
+#define SysTick_CTRL_COUNTFLAG_Msk (1ul << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */\r
+\r
+#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */\r
+#define SysTick_CTRL_CLKSOURCE_Msk (1ul << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */\r
+\r
+#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */\r
+#define SysTick_CTRL_TICKINT_Msk (1ul << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */\r
+\r
+#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */\r
+#define SysTick_CTRL_ENABLE_Msk (1ul << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */\r
+\r
+/* SysTick Reload Register Definitions */\r
+#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */\r
+#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */\r
+\r
+/* SysTick Current Register Definitions */\r
+#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */\r
+#define SysTick_VAL_CURRENT_Msk (0xFFFFFFul << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */\r
+\r
+/* SysTick Calibration Register Definitions */\r
+#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */\r
+#define SysTick_CALIB_NOREF_Msk (1ul << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */\r
+\r
+#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */\r
+#define SysTick_CALIB_SKEW_Msk (1ul << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */\r
+\r
+#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */\r
+#define SysTick_CALIB_TENMS_Msk (0xFFFFFFul << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */\r
+/*@}*/ /* end of group CMSIS_CM3_SysTick */\r
+\r
+\r
+/** @addtogroup CMSIS_CM3_ITM CMSIS CM3 ITM\r
+ memory mapped structure for Instrumentation Trace Macrocell (ITM)\r
+ @{\r
+ */\r
+typedef struct\r
+{\r
+ __O union\r
+ {\r
+ __O uint8_t u8; /*!< Offset: ITM Stimulus Port 8-bit */\r
+ __O uint16_t u16; /*!< Offset: ITM Stimulus Port 16-bit */\r
+ __O uint32_t u32; /*!< Offset: ITM Stimulus Port 32-bit */\r
+ } PORT [32]; /*!< Offset: 0x00 ITM Stimulus Port Registers */\r
+ uint32_t RESERVED0[864];\r
+ __IO uint32_t TER; /*!< Offset: ITM Trace Enable Register */\r
+ uint32_t RESERVED1[15];\r
+ __IO uint32_t TPR; /*!< Offset: ITM Trace Privilege Register */\r
+ uint32_t RESERVED2[15];\r
+ __IO uint32_t TCR; /*!< Offset: ITM Trace Control Register */\r
+ uint32_t RESERVED3[29];\r
+ __IO uint32_t IWR; /*!< Offset: ITM Integration Write Register */\r
+ __IO uint32_t IRR; /*!< Offset: ITM Integration Read Register */\r
+ __IO uint32_t IMCR; /*!< Offset: ITM Integration Mode Control Register */\r
+ uint32_t RESERVED4[43];\r
+ __IO uint32_t LAR; /*!< Offset: ITM Lock Access Register */\r
+ __IO uint32_t LSR; /*!< Offset: ITM Lock Status Register */\r
+ uint32_t RESERVED5[6];\r
+ __I uint32_t PID4; /*!< Offset: ITM Peripheral Identification Register #4 */\r
+ __I uint32_t PID5; /*!< Offset: ITM Peripheral Identification Register #5 */\r
+ __I uint32_t PID6; /*!< Offset: ITM Peripheral Identification Register #6 */\r
+ __I uint32_t PID7; /*!< Offset: ITM Peripheral Identification Register #7 */\r
+ __I uint32_t PID0; /*!< Offset: ITM Peripheral Identification Register #0 */\r
+ __I uint32_t PID1; /*!< Offset: ITM Peripheral Identification Register #1 */\r
+ __I uint32_t PID2; /*!< Offset: ITM Peripheral Identification Register #2 */\r
+ __I uint32_t PID3; /*!< Offset: ITM Peripheral Identification Register #3 */\r
+ __I uint32_t CID0; /*!< Offset: ITM Component Identification Register #0 */\r
+ __I uint32_t CID1; /*!< Offset: ITM Component Identification Register #1 */\r
+ __I uint32_t CID2; /*!< Offset: ITM Component Identification Register #2 */\r
+ __I uint32_t CID3; /*!< Offset: ITM Component Identification Register #3 */\r
+} ITM_Type;\r
+\r
+/* ITM Trace Privilege Register Definitions */\r
+#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */\r
+#define ITM_TPR_PRIVMASK_Msk (0xFul << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */\r
+\r
+/* ITM Trace Control Register Definitions */\r
+#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */\r
+#define ITM_TCR_BUSY_Msk (1ul << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */\r
+\r
+#define ITM_TCR_ATBID_Pos 16 /*!< ITM TCR: ATBID Position */\r
+#define ITM_TCR_ATBID_Msk (0x7Ful << ITM_TCR_ATBID_Pos) /*!< ITM TCR: ATBID Mask */\r
+\r
+#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */\r
+#define ITM_TCR_TSPrescale_Msk (3ul << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */\r
+\r
+#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */\r
+#define ITM_TCR_SWOENA_Msk (1ul << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */\r
+\r
+#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */\r
+#define ITM_TCR_DWTENA_Msk (1ul << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */\r
+\r
+#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */\r
+#define ITM_TCR_SYNCENA_Msk (1ul << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */\r
+\r
+#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */\r
+#define ITM_TCR_TSENA_Msk (1ul << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */\r
+\r
+#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */\r
+#define ITM_TCR_ITMENA_Msk (1ul << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */\r
+\r
+/* ITM Integration Write Register Definitions */\r
+#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */\r
+#define ITM_IWR_ATVALIDM_Msk (1ul << ITM_IWR_ATVALIDM_Pos) /*!< ITM IWR: ATVALIDM Mask */\r
+\r
+/* ITM Integration Read Register Definitions */\r
+#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */\r
+#define ITM_IRR_ATREADYM_Msk (1ul << ITM_IRR_ATREADYM_Pos) /*!< ITM IRR: ATREADYM Mask */\r
+\r
+/* ITM Integration Mode Control Register Definitions */\r
+#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */\r
+#define ITM_IMCR_INTEGRATION_Msk (1ul << ITM_IMCR_INTEGRATION_Pos) /*!< ITM IMCR: INTEGRATION Mask */\r
+\r
+/* ITM Lock Status Register Definitions */\r
+#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */\r
+#define ITM_LSR_ByteAcc_Msk (1ul << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */\r
+\r
+#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */\r
+#define ITM_LSR_Access_Msk (1ul << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */\r
+\r
+#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */\r
+#define ITM_LSR_Present_Msk (1ul << ITM_LSR_Present_Pos) /*!< ITM LSR: Present Mask */\r
+/*@}*/ /* end of group CMSIS_CM3_ITM */\r
+\r
+\r
+/** @addtogroup CMSIS_CM3_InterruptType CMSIS CM3 Interrupt Type\r
+ memory mapped structure for Interrupt Type\r
+ @{\r
+ */\r
+typedef struct\r
+{\r
+ uint32_t RESERVED0;\r
+ __I uint32_t ICTR; /*!< Offset: 0x04 Interrupt Control Type Register */\r
+#if ((defined __CM3_REV) && (__CM3_REV >= 0x200))\r
+ __IO uint32_t ACTLR; /*!< Offset: 0x08 Auxiliary Control Register */\r
+#else\r
+ uint32_t RESERVED1;\r
+#endif\r
+} InterruptType_Type;\r
+\r
+/* Interrupt Controller Type Register Definitions */\r
+#define InterruptType_ICTR_INTLINESNUM_Pos 0 /*!< InterruptType ICTR: INTLINESNUM Position */\r
+#define InterruptType_ICTR_INTLINESNUM_Msk (0x1Ful << InterruptType_ICTR_INTLINESNUM_Pos) /*!< InterruptType ICTR: INTLINESNUM Mask */\r
+\r
+/* Auxiliary Control Register Definitions */\r
+#define InterruptType_ACTLR_DISFOLD_Pos 2 /*!< InterruptType ACTLR: DISFOLD Position */\r
+#define InterruptType_ACTLR_DISFOLD_Msk (1ul << InterruptType_ACTLR_DISFOLD_Pos) /*!< InterruptType ACTLR: DISFOLD Mask */\r
+\r
+#define InterruptType_ACTLR_DISDEFWBUF_Pos 1 /*!< InterruptType ACTLR: DISDEFWBUF Position */\r
+#define InterruptType_ACTLR_DISDEFWBUF_Msk (1ul << InterruptType_ACTLR_DISDEFWBUF_Pos) /*!< InterruptType ACTLR: DISDEFWBUF Mask */\r
+\r
+#define InterruptType_ACTLR_DISMCYCINT_Pos 0 /*!< InterruptType ACTLR: DISMCYCINT Position */\r
+#define InterruptType_ACTLR_DISMCYCINT_Msk (1ul << InterruptType_ACTLR_DISMCYCINT_Pos) /*!< InterruptType ACTLR: DISMCYCINT Mask */\r
+/*@}*/ /* end of group CMSIS_CM3_InterruptType */\r
+\r
+\r
+#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1)\r
+/** @addtogroup CMSIS_CM3_MPU CMSIS CM3 MPU\r
+ memory mapped structure for Memory Protection Unit (MPU)\r
+ @{\r
+ */\r
+typedef struct\r
+{\r
+ __I uint32_t TYPE; /*!< Offset: 0x00 MPU Type Register */\r
+ __IO uint32_t CTRL; /*!< Offset: 0x04 MPU Control Register */\r
+ __IO uint32_t RNR; /*!< Offset: 0x08 MPU Region RNRber Register */\r
+ __IO uint32_t RBAR; /*!< Offset: 0x0C MPU Region Base Address Register */\r
+ __IO uint32_t RASR; /*!< Offset: 0x10 MPU Region Attribute and Size Register */\r
+ __IO uint32_t RBAR_A1; /*!< Offset: 0x14 MPU Alias 1 Region Base Address Register */\r
+ __IO uint32_t RASR_A1; /*!< Offset: 0x18 MPU Alias 1 Region Attribute and Size Register */\r
+ __IO uint32_t RBAR_A2; /*!< Offset: 0x1C MPU Alias 2 Region Base Address Register */\r
+ __IO uint32_t RASR_A2; /*!< Offset: 0x20 MPU Alias 2 Region Attribute and Size Register */\r
+ __IO uint32_t RBAR_A3; /*!< Offset: 0x24 MPU Alias 3 Region Base Address Register */\r
+ __IO uint32_t RASR_A3; /*!< Offset: 0x28 MPU Alias 3 Region Attribute and Size Register */\r
+} MPU_Type;\r
+\r
+/* MPU Type Register */\r
+#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */\r
+#define MPU_TYPE_IREGION_Msk (0xFFul << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */\r
+\r
+#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */\r
+#define MPU_TYPE_DREGION_Msk (0xFFul << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */\r
+\r
+#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */\r
+#define MPU_TYPE_SEPARATE_Msk (1ul << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */\r
+\r
+/* MPU Control Register */\r
+#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */\r
+#define MPU_CTRL_PRIVDEFENA_Msk (1ul << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */\r
+\r
+#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */\r
+#define MPU_CTRL_HFNMIENA_Msk (1ul << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */\r
+\r
+#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */\r
+#define MPU_CTRL_ENABLE_Msk (1ul << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */\r
+\r
+/* MPU Region Number Register */\r
+#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */\r
+#define MPU_RNR_REGION_Msk (0xFFul << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */\r
+\r
+/* MPU Region Base Address Register */\r
+#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */\r
+#define MPU_RBAR_ADDR_Msk (0x7FFFFFFul << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */\r
+\r
+#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */\r
+#define MPU_RBAR_VALID_Msk (1ul << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */\r
+\r
+#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */\r
+#define MPU_RBAR_REGION_Msk (0xFul << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */\r
+\r
+/* MPU Region Attribute and Size Register */\r
+#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: XN Position */\r
+#define MPU_RASR_XN_Msk (1ul << MPU_RASR_XN_Pos) /*!< MPU RASR: XN Mask */\r
+\r
+#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: AP Position */\r
+#define MPU_RASR_AP_Msk (7ul << MPU_RASR_AP_Pos) /*!< MPU RASR: AP Mask */\r
+\r
+#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: TEX Position */\r
+#define MPU_RASR_TEX_Msk (7ul << MPU_RASR_TEX_Pos) /*!< MPU RASR: TEX Mask */\r
+\r
+#define MPU_RASR_S_Pos 18 /*!< MPU RASR: Shareable bit Position */\r
+#define MPU_RASR_S_Msk (1ul << MPU_RASR_S_Pos) /*!< MPU RASR: Shareable bit Mask */\r
+\r
+#define MPU_RASR_C_Pos 17 /*!< MPU RASR: Cacheable bit Position */\r
+#define MPU_RASR_C_Msk (1ul << MPU_RASR_C_Pos) /*!< MPU RASR: Cacheable bit Mask */\r
+\r
+#define MPU_RASR_B_Pos 16 /*!< MPU RASR: Bufferable bit Position */\r
+#define MPU_RASR_B_Msk (1ul << MPU_RASR_B_Pos) /*!< MPU RASR: Bufferable bit Mask */\r
+\r
+#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */\r
+#define MPU_RASR_SRD_Msk (0xFFul << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */\r
+\r
+#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */\r
+#define MPU_RASR_SIZE_Msk (0x1Ful << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */\r
+\r
+#define MPU_RASR_ENA_Pos 0 /*!< MPU RASR: Region enable bit Position */\r
+#define MPU_RASR_ENA_Msk (0x1Ful << MPU_RASR_ENA_Pos) /*!< MPU RASR: Region enable bit Disable Mask */\r
+\r
+/*@}*/ /* end of group CMSIS_CM3_MPU */\r
+#endif\r
+\r
+\r
+/** @addtogroup CMSIS_CM3_CoreDebug CMSIS CM3 Core Debug\r
+ memory mapped structure for Core Debug Register\r
+ @{\r
+ */\r
+typedef struct\r
+{\r
+ __IO uint32_t DHCSR; /*!< Offset: 0x00 Debug Halting Control and Status Register */\r
+ __O uint32_t DCRSR; /*!< Offset: 0x04 Debug Core Register Selector Register */\r
+ __IO uint32_t DCRDR; /*!< Offset: 0x08 Debug Core Register Data Register */\r
+ __IO uint32_t DEMCR; /*!< Offset: 0x0C Debug Exception and Monitor Control Register */\r
+} CoreDebug_Type;\r
+\r
+/* Debug Halting Control and Status Register */\r
+#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */\r
+#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFul << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */\r
+\r
+#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */\r
+#define CoreDebug_DHCSR_S_RESET_ST_Msk (1ul << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */\r
+\r
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */\r
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1ul << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */\r
+\r
+#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */\r
+#define CoreDebug_DHCSR_S_LOCKUP_Msk (1ul << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */\r
+\r
+#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */\r
+#define CoreDebug_DHCSR_S_SLEEP_Msk (1ul << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */\r
+\r
+#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */\r
+#define CoreDebug_DHCSR_S_HALT_Msk (1ul << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */\r
+\r
+#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */\r
+#define CoreDebug_DHCSR_S_REGRDY_Msk (1ul << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */\r
+\r
+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */\r
+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1ul << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */\r
+\r
+#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */\r
+#define CoreDebug_DHCSR_C_MASKINTS_Msk (1ul << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */\r
+\r
+#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */\r
+#define CoreDebug_DHCSR_C_STEP_Msk (1ul << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */\r
+\r
+#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */\r
+#define CoreDebug_DHCSR_C_HALT_Msk (1ul << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */\r
+\r
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */\r
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1ul << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */\r
+\r
+/* Debug Core Register Selector Register */\r
+#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */\r
+#define CoreDebug_DCRSR_REGWnR_Msk (1ul << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */\r
+\r
+#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */\r
+#define CoreDebug_DCRSR_REGSEL_Msk (0x1Ful << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */\r
+\r
+/* Debug Exception and Monitor Control Register */\r
+#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */\r
+#define CoreDebug_DEMCR_TRCENA_Msk (1ul << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */\r
+\r
+#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */\r
+#define CoreDebug_DEMCR_MON_REQ_Msk (1ul << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */\r
+\r
+#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */\r
+#define CoreDebug_DEMCR_MON_STEP_Msk (1ul << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */\r
+\r
+#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */\r
+#define CoreDebug_DEMCR_MON_PEND_Msk (1ul << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */\r
+\r
+#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */\r
+#define CoreDebug_DEMCR_MON_EN_Msk (1ul << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */\r
+\r
+#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */\r
+#define CoreDebug_DEMCR_VC_HARDERR_Msk (1ul << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */\r
+\r
+#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */\r
+#define CoreDebug_DEMCR_VC_INTERR_Msk (1ul << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */\r
+\r
+#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */\r
+#define CoreDebug_DEMCR_VC_BUSERR_Msk (1ul << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */\r
+\r
+#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */\r
+#define CoreDebug_DEMCR_VC_STATERR_Msk (1ul << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */\r
+\r
+#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */\r
+#define CoreDebug_DEMCR_VC_CHKERR_Msk (1ul << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */\r
+\r
+#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */\r
+#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1ul << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */\r
+\r
+#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */\r
+#define CoreDebug_DEMCR_VC_MMERR_Msk (1ul << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */\r
+\r
+#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */\r
+#define CoreDebug_DEMCR_VC_CORERESET_Msk (1ul << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */\r
+/*@}*/ /* end of group CMSIS_CM3_CoreDebug */\r
+\r
+\r
+/* Memory mapping of Cortex-M3 Hardware */\r
+#define SCS_BASE (0xE000E000) /*!< System Control Space Base Address */\r
+#define ITM_BASE (0xE0000000) /*!< ITM Base Address */\r
+#define CoreDebug_BASE (0xE000EDF0) /*!< Core Debug Base Address */\r
+#define SysTick_BASE (SCS_BASE + 0x0010) /*!< SysTick Base Address */\r
+#define NVIC_BASE (SCS_BASE + 0x0100) /*!< NVIC Base Address */\r
+#define SCB_BASE (SCS_BASE + 0x0D00) /*!< System Control Block Base Address */\r
+\r
+#define InterruptType ((InterruptType_Type *) SCS_BASE) /*!< Interrupt Type Register */\r
+#define SCB ((SCB_Type *) SCB_BASE) /*!< SCB configuration struct */\r
+#define SysTick ((SysTick_Type *) SysTick_BASE) /*!< SysTick configuration struct */\r
+#define NVIC ((NVIC_Type *) NVIC_BASE) /*!< NVIC configuration struct */\r
+#define ITM ((ITM_Type *) ITM_BASE) /*!< ITM configuration struct */\r
+#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */\r
+\r
+#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1)\r
+ #define MPU_BASE (SCS_BASE + 0x0D90) /*!< Memory Protection Unit */\r
+ #define MPU ((MPU_Type*) MPU_BASE) /*!< Memory Protection Unit */\r
+#endif\r
+\r
+/*@}*/ /* end of group CMSIS_CM3_core_register */\r
+\r
+\r
+/*******************************************************************************\r
+ * Hardware Abstraction Layer\r
+ ******************************************************************************/\r
+\r
+#if defined ( __CC_ARM )\r
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */\r
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */\r
+\r
+#elif defined ( __ICCARM__ )\r
+ #define __ASM __asm /*!< asm keyword for IAR Compiler */\r
+ #define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */\r
+\r
+#elif defined ( __GNUC__ )\r
+ #define __ASM __asm /*!< asm keyword for GNU Compiler */\r
+ #define __INLINE inline /*!< inline keyword for GNU Compiler */\r
+\r
+#elif defined ( __TASKING__ )\r
+ #define __ASM __asm /*!< asm keyword for TASKING Compiler */\r
+ #define __INLINE inline /*!< inline keyword for TASKING Compiler */\r
+\r
+#endif\r
+\r
+\r
+/* ################### Compiler specific Intrinsics ########################### */\r
+\r
+#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/\r
+/* ARM armcc specific functions */\r
+\r
+#define __enable_fault_irq __enable_fiq\r
+#define __disable_fault_irq __disable_fiq\r
+\r
+#define __NOP __nop\r
+#define __WFI __wfi\r
+#define __WFE __wfe\r
+#define __SEV __sev\r
+#define __ISB() __isb(0)\r
+#define __DSB() __dsb(0)\r
+#define __DMB() __dmb(0)\r
+#define __REV __rev\r
+#define __RBIT __rbit\r
+#define __LDREXB(ptr) ((unsigned char ) __ldrex(ptr))\r
+#define __LDREXH(ptr) ((unsigned short) __ldrex(ptr))\r
+#define __LDREXW(ptr) ((unsigned int ) __ldrex(ptr))\r
+#define __STREXB(value, ptr) __strex(value, ptr)\r
+#define __STREXH(value, ptr) __strex(value, ptr)\r
+#define __STREXW(value, ptr) __strex(value, ptr)\r
+\r
+\r
+/* intrinsic unsigned long long __ldrexd(volatile void *ptr) */\r
+/* intrinsic int __strexd(unsigned long long val, volatile void *ptr) */\r
+/* intrinsic void __enable_irq(); */\r
+/* intrinsic void __disable_irq(); */\r
+\r
+\r
+/**\r
+ * @brief Return the Process Stack Pointer\r
+ *\r
+ * @return ProcessStackPointer\r
+ *\r
+ * Return the actual process stack pointer\r
+ */\r
+extern uint32_t __get_PSP(void);\r
+\r
+/**\r
+ * @brief Set the Process Stack Pointer\r
+ *\r
+ * @param topOfProcStack Process Stack Pointer\r
+ *\r
+ * Assign the value ProcessStackPointer to the MSP\r
+ * (process stack pointer) Cortex processor register\r
+ */\r
+extern void __set_PSP(uint32_t topOfProcStack);\r
+\r
+/**\r
+ * @brief Return the Main Stack Pointer\r
+ *\r
+ * @return Main Stack Pointer\r
+ *\r
+ * Return the current value of the MSP (main stack pointer)\r
+ * Cortex processor register\r
+ */\r
+extern uint32_t __get_MSP(void);\r
+\r
+/**\r
+ * @brief Set the Main Stack Pointer\r
+ *\r
+ * @param topOfMainStack Main Stack Pointer\r
+ *\r
+ * Assign the value mainStackPointer to the MSP\r
+ * (main stack pointer) Cortex processor register\r
+ */\r
+extern void __set_MSP(uint32_t topOfMainStack);\r
+\r
+/**\r
+ * @brief Reverse byte order in unsigned short value\r
+ *\r
+ * @param value value to reverse\r
+ * @return reversed value\r
+ *\r
+ * Reverse byte order in unsigned short value\r
+ */\r
+extern uint32_t __REV16(uint16_t value);\r
+\r
+/**\r
+ * @brief Reverse byte order in signed short value with sign extension to integer\r
+ *\r
+ * @param value value to reverse\r
+ * @return reversed value\r
+ *\r
+ * Reverse byte order in signed short value with sign extension to integer\r
+ */\r
+extern int32_t __REVSH(int16_t value);\r
+\r
+\r
+#if (__ARMCC_VERSION < 400000)\r
+\r
+/**\r
+ * @brief Remove the exclusive lock created by ldrex\r
+ *\r
+ * Removes the exclusive lock which is created by ldrex.\r
+ */\r
+extern void __CLREX(void);\r
+\r
+/**\r
+ * @brief Return the Base Priority value\r
+ *\r
+ * @return BasePriority\r
+ *\r
+ * Return the content of the base priority register\r
+ */\r
+extern uint32_t __get_BASEPRI(void);\r
+\r
+/**\r
+ * @brief Set the Base Priority value\r
+ *\r
+ * @param basePri BasePriority\r
+ *\r
+ * Set the base priority register\r
+ */\r
+extern void __set_BASEPRI(uint32_t basePri);\r
+\r
+/**\r
+ * @brief Return the Priority Mask value\r
+ *\r
+ * @return PriMask\r
+ *\r
+ * Return state of the priority mask bit from the priority mask register\r
+ */\r
+extern uint32_t __get_PRIMASK(void);\r
+\r
+/**\r
+ * @brief Set the Priority Mask value\r
+ *\r
+ * @param priMask PriMask\r
+ *\r
+ * Set the priority mask bit in the priority mask register\r
+ */\r
+extern void __set_PRIMASK(uint32_t priMask);\r
+\r
+/**\r
+ * @brief Return the Fault Mask value\r
+ *\r
+ * @return FaultMask\r
+ *\r
+ * Return the content of the fault mask register\r
+ */\r
+extern uint32_t __get_FAULTMASK(void);\r
+\r
+/**\r
+ * @brief Set the Fault Mask value\r
+ *\r
+ * @param faultMask faultMask value\r
+ *\r
+ * Set the fault mask register\r
+ */\r
+extern void __set_FAULTMASK(uint32_t faultMask);\r
+\r
+/**\r
+ * @brief Return the Control Register value\r
+ *\r
+ * @return Control value\r
+ *\r
+ * Return the content of the control register\r
+ */\r
+extern uint32_t __get_CONTROL(void);\r
+\r
+/**\r
+ * @brief Set the Control Register value\r
+ *\r
+ * @param control Control value\r
+ *\r
+ * Set the control register\r
+ */\r
+extern void __set_CONTROL(uint32_t control);\r
+\r
+#else /* (__ARMCC_VERSION >= 400000) */\r
+\r
+/**\r
+ * @brief Remove the exclusive lock created by ldrex\r
+ *\r
+ * Removes the exclusive lock which is created by ldrex.\r
+ */\r
+#define __CLREX __clrex\r
+\r
+/**\r
+ * @brief Return the Base Priority value\r
+ *\r
+ * @return BasePriority\r
+ *\r
+ * Return the content of the base priority register\r
+ */\r
+static __INLINE uint32_t __get_BASEPRI(void)\r
+{\r
+ register uint32_t __regBasePri __ASM("basepri");\r
+ return(__regBasePri);\r
+}\r
+\r
+/**\r
+ * @brief Set the Base Priority value\r
+ *\r
+ * @param basePri BasePriority\r
+ *\r
+ * Set the base priority register\r
+ */\r
+static __INLINE void __set_BASEPRI(uint32_t basePri)\r
+{\r
+ register uint32_t __regBasePri __ASM("basepri");\r
+ __regBasePri = (basePri & 0xff);\r
+}\r
+\r
+/**\r
+ * @brief Return the Priority Mask value\r
+ *\r
+ * @return PriMask\r
+ *\r
+ * Return state of the priority mask bit from the priority mask register\r
+ */\r
+static __INLINE uint32_t __get_PRIMASK(void)\r
+{\r
+ register uint32_t __regPriMask __ASM("primask");\r
+ return(__regPriMask);\r
+}\r
+\r
+/**\r
+ * @brief Set the Priority Mask value\r
+ *\r
+ * @param priMask PriMask\r
+ *\r
+ * Set the priority mask bit in the priority mask register\r
+ */\r
+static __INLINE void __set_PRIMASK(uint32_t priMask)\r
+{\r
+ register uint32_t __regPriMask __ASM("primask");\r
+ __regPriMask = (priMask);\r
+}\r
+\r
+/**\r
+ * @brief Return the Fault Mask value\r
+ *\r
+ * @return FaultMask\r
+ *\r
+ * Return the content of the fault mask register\r
+ */\r
+static __INLINE uint32_t __get_FAULTMASK(void)\r
+{\r
+ register uint32_t __regFaultMask __ASM("faultmask");\r
+ return(__regFaultMask);\r
+}\r
+\r
+/**\r
+ * @brief Set the Fault Mask value\r
+ *\r
+ * @param faultMask faultMask value\r
+ *\r
+ * Set the fault mask register\r
+ */\r
+static __INLINE void __set_FAULTMASK(uint32_t faultMask)\r
+{\r
+ register uint32_t __regFaultMask __ASM("faultmask");\r
+ __regFaultMask = (faultMask & 1);\r
+}\r
+\r
+/**\r
+ * @brief Return the Control Register value\r
+ *\r
+ * @return Control value\r
+ *\r
+ * Return the content of the control register\r
+ */\r
+static __INLINE uint32_t __get_CONTROL(void)\r
+{\r
+ register uint32_t __regControl __ASM("control");\r
+ return(__regControl);\r
+}\r
+\r
+/**\r
+ * @brief Set the Control Register value\r
+ *\r
+ * @param control Control value\r
+ *\r
+ * Set the control register\r
+ */\r
+static __INLINE void __set_CONTROL(uint32_t control)\r
+{\r
+ register uint32_t __regControl __ASM("control");\r
+ __regControl = control;\r
+}\r
+\r
+#endif /* __ARMCC_VERSION */\r
+\r
+\r
+\r
+#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/\r
+/* IAR iccarm specific functions */\r
+\r
+#define __enable_irq __enable_interrupt /*!< global Interrupt enable */\r
+#define __disable_irq __disable_interrupt /*!< global Interrupt disable */\r
+\r
+static __INLINE void __enable_fault_irq() { __ASM ("cpsie f"); }\r
+static __INLINE void __disable_fault_irq() { __ASM ("cpsid f"); }\r
+\r
+#define __NOP __no_operation /*!< no operation intrinsic in IAR Compiler */\r
+static __INLINE void __WFI() { __ASM ("wfi"); }\r
+static __INLINE void __WFE() { __ASM ("wfe"); }\r
+static __INLINE void __SEV() { __ASM ("sev"); }\r
+static __INLINE void __CLREX() { __ASM ("clrex"); }\r
+\r
+/* intrinsic void __ISB(void) */\r
+/* intrinsic void __DSB(void) */\r
+/* intrinsic void __DMB(void) */\r
+/* intrinsic void __set_PRIMASK(); */\r
+/* intrinsic void __get_PRIMASK(); */\r
+/* intrinsic void __set_FAULTMASK(); */\r
+/* intrinsic void __get_FAULTMASK(); */\r
+/* intrinsic uint32_t __REV(uint32_t value); */\r
+/* intrinsic uint32_t __REVSH(uint32_t value); */\r
+/* intrinsic unsigned long __STREX(unsigned long, unsigned long); */\r
+/* intrinsic unsigned long __LDREX(unsigned long *); */\r
+\r
+\r
+/**\r
+ * @brief Return the Process Stack Pointer\r
+ *\r
+ * @return ProcessStackPointer\r
+ *\r
+ * Return the actual process stack pointer\r
+ */\r
+extern uint32_t __get_PSP(void);\r
+\r
+/**\r
+ * @brief Set the Process Stack Pointer\r
+ *\r
+ * @param topOfProcStack Process Stack Pointer\r
+ *\r
+ * Assign the value ProcessStackPointer to the MSP\r
+ * (process stack pointer) Cortex processor register\r
+ */\r
+extern void __set_PSP(uint32_t topOfProcStack);\r
+\r
+/**\r
+ * @brief Return the Main Stack Pointer\r
+ *\r
+ * @return Main Stack Pointer\r
+ *\r
+ * Return the current value of the MSP (main stack pointer)\r
+ * Cortex processor register\r
+ */\r
+extern uint32_t __get_MSP(void);\r
+\r
+/**\r
+ * @brief Set the Main Stack Pointer\r
+ *\r
+ * @param topOfMainStack Main Stack Pointer\r
+ *\r
+ * Assign the value mainStackPointer to the MSP\r
+ * (main stack pointer) Cortex processor register\r
+ */\r
+extern void __set_MSP(uint32_t topOfMainStack);\r
+\r
+/**\r
+ * @brief Reverse byte order in unsigned short value\r
+ *\r
+ * @param value value to reverse\r
+ * @return reversed value\r
+ *\r
+ * Reverse byte order in unsigned short value\r
+ */\r
+extern uint32_t __REV16(uint16_t value);\r
+\r
+/**\r
+ * @brief Reverse bit order of value\r
+ *\r
+ * @param value value to reverse\r
+ * @return reversed value\r
+ *\r
+ * Reverse bit order of value\r
+ */\r
+extern uint32_t __RBIT(uint32_t value);\r
+\r
+/**\r
+ * @brief LDR Exclusive (8 bit)\r
+ *\r
+ * @param *addr address pointer\r
+ * @return value of (*address)\r
+ *\r
+ * Exclusive LDR command for 8 bit values)\r
+ */\r
+extern uint8_t __LDREXB(uint8_t *addr);\r
+\r
+/**\r
+ * @brief LDR Exclusive (16 bit)\r
+ *\r
+ * @param *addr address pointer\r
+ * @return value of (*address)\r
+ *\r
+ * Exclusive LDR command for 16 bit values\r
+ */\r
+extern uint16_t __LDREXH(uint16_t *addr);\r
+\r
+/**\r
+ * @brief LDR Exclusive (32 bit)\r
+ *\r
+ * @param *addr address pointer\r
+ * @return value of (*address)\r
+ *\r
+ * Exclusive LDR command for 32 bit values\r
+ */\r
+extern uint32_t __LDREXW(uint32_t *addr);\r
+\r
+/**\r
+ * @brief STR Exclusive (8 bit)\r
+ *\r
+ * @param value value to store\r
+ * @param *addr address pointer\r
+ * @return successful / failed\r
+ *\r
+ * Exclusive STR command for 8 bit values\r
+ */\r
+extern uint32_t __STREXB(uint8_t value, uint8_t *addr);\r
+\r
+/**\r
+ * @brief STR Exclusive (16 bit)\r
+ *\r
+ * @param value value to store\r
+ * @param *addr address pointer\r
+ * @return successful / failed\r
+ *\r
+ * Exclusive STR command for 16 bit values\r
+ */\r
+extern uint32_t __STREXH(uint16_t value, uint16_t *addr);\r
+\r
+/**\r
+ * @brief STR Exclusive (32 bit)\r
+ *\r
+ * @param value value to store\r
+ * @param *addr address pointer\r
+ * @return successful / failed\r
+ *\r
+ * Exclusive STR command for 32 bit values\r
+ */\r
+extern uint32_t __STREXW(uint32_t value, uint32_t *addr);\r
+\r
+\r
+\r
+#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/\r
+/* GNU gcc specific functions */\r
+\r
+static __INLINE void __enable_irq() { __ASM volatile ("cpsie i"); }\r
+static __INLINE void __disable_irq() { __ASM volatile ("cpsid i"); }\r
+\r
+static __INLINE void __enable_fault_irq() { __ASM volatile ("cpsie f"); }\r
+static __INLINE void __disable_fault_irq() { __ASM volatile ("cpsid f"); }\r
+\r
+static __INLINE void __NOP() { __ASM volatile ("nop"); }\r
+static __INLINE void __WFI() { __ASM volatile ("wfi"); }\r
+static __INLINE void __WFE() { __ASM volatile ("wfe"); }\r
+static __INLINE void __SEV() { __ASM volatile ("sev"); }\r
+static __INLINE void __ISB() { __ASM volatile ("isb"); }\r
+static __INLINE void __DSB() { __ASM volatile ("dsb"); }\r
+static __INLINE void __DMB() { __ASM volatile ("dmb"); }\r
+static __INLINE void __CLREX() { __ASM volatile ("clrex"); }\r
+\r
+\r
+/**\r
+ * @brief Return the Process Stack Pointer\r
+ *\r
+ * @return ProcessStackPointer\r
+ *\r
+ * Return the actual process stack pointer\r
+ */\r
+extern uint32_t __get_PSP(void);\r
+\r
+/**\r
+ * @brief Set the Process Stack Pointer\r
+ *\r
+ * @param topOfProcStack Process Stack Pointer\r
+ *\r
+ * Assign the value ProcessStackPointer to the MSP\r
+ * (process stack pointer) Cortex processor register\r
+ */\r
+extern void __set_PSP(uint32_t topOfProcStack);\r
+\r
+/**\r
+ * @brief Return the Main Stack Pointer\r
+ *\r
+ * @return Main Stack Pointer\r
+ *\r
+ * Return the current value of the MSP (main stack pointer)\r
+ * Cortex processor register\r
+ */\r
+extern uint32_t __get_MSP(void);\r
+\r
+/**\r
+ * @brief Set the Main Stack Pointer\r
+ *\r
+ * @param topOfMainStack Main Stack Pointer\r
+ *\r
+ * Assign the value mainStackPointer to the MSP\r
+ * (main stack pointer) Cortex processor register\r
+ */\r
+extern void __set_MSP(uint32_t topOfMainStack);\r
+\r
+/**\r
+ * @brief Return the Base Priority value\r
+ *\r
+ * @return BasePriority\r
+ *\r
+ * Return the content of the base priority register\r
+ */\r
+extern uint32_t __get_BASEPRI(void);\r
+\r
+/**\r
+ * @brief Set the Base Priority value\r
+ *\r
+ * @param basePri BasePriority\r
+ *\r
+ * Set the base priority register\r
+ */\r
+extern void __set_BASEPRI(uint32_t basePri);\r
+\r
+/**\r
+ * @brief Return the Priority Mask value\r
+ *\r
+ * @return PriMask\r
+ *\r
+ * Return state of the priority mask bit from the priority mask register\r
+ */\r
+extern uint32_t __get_PRIMASK(void);\r
+\r
+/**\r
+ * @brief Set the Priority Mask value\r
+ *\r
+ * @param priMask PriMask\r
+ *\r
+ * Set the priority mask bit in the priority mask register\r
+ */\r
+extern void __set_PRIMASK(uint32_t priMask);\r
+\r
+/**\r
+ * @brief Return the Fault Mask value\r
+ *\r
+ * @return FaultMask\r
+ *\r
+ * Return the content of the fault mask register\r
+ */\r
+extern uint32_t __get_FAULTMASK(void);\r
+\r
+/**\r
+ * @brief Set the Fault Mask value\r
+ *\r
+ * @param faultMask faultMask value\r
+ *\r
+ * Set the fault mask register\r
+ */\r
+extern void __set_FAULTMASK(uint32_t faultMask);\r
+\r
+/**\r
+ * @brief Return the Control Register value\r
+*\r
+* @return Control value\r
+ *\r
+ * Return the content of the control register\r
+ */\r
+extern uint32_t __get_CONTROL(void);\r
+\r
+/**\r
+ * @brief Set the Control Register value\r
+ *\r
+ * @param control Control value\r
+ *\r
+ * Set the control register\r
+ */\r
+extern void __set_CONTROL(uint32_t control);\r
+\r
+/**\r
+ * @brief Reverse byte order in integer value\r
+ *\r
+ * @param value value to reverse\r
+ * @return reversed value\r
+ *\r
+ * Reverse byte order in integer value\r
+ */\r
+extern uint32_t __REV(uint32_t value);\r
+\r
+/**\r
+ * @brief Reverse byte order in unsigned short value\r
+ *\r
+ * @param value value to reverse\r
+ * @return reversed value\r
+ *\r
+ * Reverse byte order in unsigned short value\r
+ */\r
+extern uint32_t __REV16(uint16_t value);\r
+\r
+/**\r
+ * @brief Reverse byte order in signed short value with sign extension to integer\r
+ *\r
+ * @param value value to reverse\r
+ * @return reversed value\r
+ *\r
+ * Reverse byte order in signed short value with sign extension to integer\r
+ */\r
+extern int32_t __REVSH(int16_t value);\r
+\r
+/**\r
+ * @brief Reverse bit order of value\r
+ *\r
+ * @param value value to reverse\r
+ * @return reversed value\r
+ *\r
+ * Reverse bit order of value\r
+ */\r
+extern uint32_t __RBIT(uint32_t value);\r
+\r
+/**\r
+ * @brief LDR Exclusive (8 bit)\r
+ *\r
+ * @param *addr address pointer\r
+ * @return value of (*address)\r
+ *\r
+ * Exclusive LDR command for 8 bit value\r
+ */\r
+extern uint8_t __LDREXB(uint8_t *addr);\r
+\r
+/**\r
+ * @brief LDR Exclusive (16 bit)\r
+ *\r
+ * @param *addr address pointer\r
+ * @return value of (*address)\r
+ *\r
+ * Exclusive LDR command for 16 bit values\r
+ */\r
+extern uint16_t __LDREXH(uint16_t *addr);\r
+\r
+/**\r
+ * @brief LDR Exclusive (32 bit)\r
+ *\r
+ * @param *addr address pointer\r
+ * @return value of (*address)\r
+ *\r
+ * Exclusive LDR command for 32 bit values\r
+ */\r
+extern uint32_t __LDREXW(uint32_t *addr);\r
+\r
+/**\r
+ * @brief STR Exclusive (8 bit)\r
+ *\r
+ * @param value value to store\r
+ * @param *addr address pointer\r
+ * @return successful / failed\r
+ *\r
+ * Exclusive STR command for 8 bit values\r
+ */\r
+extern uint32_t __STREXB(uint8_t value, uint8_t *addr);\r
+\r
+/**\r
+ * @brief STR Exclusive (16 bit)\r
+ *\r
+ * @param value value to store\r
+ * @param *addr address pointer\r
+ * @return successful / failed\r
+ *\r
+ * Exclusive STR command for 16 bit values\r
+ */\r
+extern uint32_t __STREXH(uint16_t value, uint16_t *addr);\r
+\r
+/**\r
+ * @brief STR Exclusive (32 bit)\r
+ *\r
+ * @param value value to store\r
+ * @param *addr address pointer\r
+ * @return successful / failed\r
+ *\r
+ * Exclusive STR command for 32 bit values\r
+ */\r
+extern uint32_t __STREXW(uint32_t value, uint32_t *addr);\r
+\r
+\r
+#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/\r
+/* TASKING carm specific functions */\r
+\r
+/*\r
+ * The CMSIS functions have been implemented as intrinsics in the compiler.\r
+ * Please use "carm -?i" to get an up to date list of all instrinsics,\r
+ * Including the CMSIS ones.\r
+ */\r
+\r
+#endif\r
+\r
+\r
+/** @addtogroup CMSIS_CM3_Core_FunctionInterface CMSIS CM3 Core Function Interface\r
+ Core Function Interface containing:\r
+ - Core NVIC Functions\r
+ - Core SysTick Functions\r
+ - Core Reset Functions\r
+*/\r
+/*@{*/\r
+\r
+/* ########################## NVIC functions #################################### */\r
+\r
+/**\r
+ * @brief Set the Priority Grouping in NVIC Interrupt Controller\r
+ *\r
+ * @param PriorityGroup is priority grouping field\r
+ *\r
+ * Set the priority grouping field using the required unlock sequence.\r
+ * The parameter priority_grouping is assigned to the field\r
+ * SCB->AIRCR [10:8] PRIGROUP field. Only values from 0..7 are used.\r
+ * In case of a conflict between priority grouping and available\r
+ * priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.\r
+ */\r
+static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)\r
+{\r
+ uint32_t reg_value;\r
+ uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */\r
+\r
+ reg_value = SCB->AIRCR; /* read old register configuration */\r
+ reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */\r
+ reg_value = (reg_value |\r
+ (0x5FA << SCB_AIRCR_VECTKEY_Pos) |\r
+ (PriorityGroupTmp << 8)); /* Insert write key and priorty group */\r
+ SCB->AIRCR = reg_value;\r
+}\r
+\r
+/**\r
+ * @brief Get the Priority Grouping from NVIC Interrupt Controller\r
+ *\r
+ * @return priority grouping field\r
+ *\r
+ * Get the priority grouping from NVIC Interrupt Controller.\r
+ * priority grouping is SCB->AIRCR [10:8] PRIGROUP field.\r
+ */\r
+static __INLINE uint32_t NVIC_GetPriorityGrouping(void)\r
+{\r
+ return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */\r
+}\r
+\r
+/**\r
+ * @brief Enable Interrupt in NVIC Interrupt Controller\r
+ *\r
+ * @param IRQn The positive number of the external interrupt to enable\r
+ *\r
+ * Enable a device specific interupt in the NVIC interrupt controller.\r
+ * The interrupt number cannot be a negative value.\r
+ */\r
+static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)\r
+{\r
+ NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */\r
+}\r
+\r
+/**\r
+ * @brief Disable the interrupt line for external interrupt specified\r
+ *\r
+ * @param IRQn The positive number of the external interrupt to disable\r
+ *\r
+ * Disable a device specific interupt in the NVIC interrupt controller.\r
+ * The interrupt number cannot be a negative value.\r
+ */\r
+static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)\r
+{\r
+ NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */\r
+}\r
+\r
+/**\r
+ * @brief Read the interrupt pending bit for a device specific interrupt source\r
+ *\r
+ * @param IRQn The number of the device specifc interrupt\r
+ * @return 1 = interrupt pending, 0 = interrupt not pending\r
+ *\r
+ * Read the pending register in NVIC and return 1 if its status is pending,\r
+ * otherwise it returns 0\r
+ */\r
+static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)\r
+{\r
+ return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */\r
+}\r
+\r
+/**\r
+ * @brief Set the pending bit for an external interrupt\r
+ *\r
+ * @param IRQn The number of the interrupt for set pending\r
+ *\r
+ * Set the pending bit for the specified interrupt.\r
+ * The interrupt number cannot be a negative value.\r
+ */\r
+static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)\r
+{\r
+ NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */\r
+}\r
+\r
+/**\r
+ * @brief Clear the pending bit for an external interrupt\r
+ *\r
+ * @param IRQn The number of the interrupt for clear pending\r
+ *\r
+ * Clear the pending bit for the specified interrupt.\r
+ * The interrupt number cannot be a negative value.\r
+ */\r
+static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)\r
+{\r
+ NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */\r
+}\r
+\r
+/**\r
+ * @brief Read the active bit for an external interrupt\r
+ *\r
+ * @param IRQn The number of the interrupt for read active bit\r
+ * @return 1 = interrupt active, 0 = interrupt not active\r
+ *\r
+ * Read the active register in NVIC and returns 1 if its status is active,\r
+ * otherwise it returns 0.\r
+ */\r
+static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)\r
+{\r
+ return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */\r
+}\r
+\r
+/**\r
+ * @brief Set the priority for an interrupt\r
+ *\r
+ * @param IRQn The number of the interrupt for set priority\r
+ * @param priority The priority to set\r
+ *\r
+ * Set the priority for the specified interrupt. The interrupt\r
+ * number can be positive to specify an external (device specific)\r
+ * interrupt, or negative to specify an internal (core) interrupt.\r
+ *\r
+ * Note: The priority cannot be set for every core interrupt.\r
+ */\r
+static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)\r
+{\r
+ if(IRQn < 0) {\r
+ SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */\r
+ else {\r
+ NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */\r
+}\r
+\r
+/**\r
+ * @brief Read the priority for an interrupt\r
+ *\r
+ * @param IRQn The number of the interrupt for get priority\r
+ * @return The priority for the interrupt\r
+ *\r
+ * Read the priority for the specified interrupt. The interrupt\r
+ * number can be positive to specify an external (device specific)\r
+ * interrupt, or negative to specify an internal (core) interrupt.\r
+ *\r
+ * The returned priority value is automatically aligned to the implemented\r
+ * priority bits of the microcontroller.\r
+ *\r
+ * Note: The priority cannot be set for every core interrupt.\r
+ */\r
+static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)\r
+{\r
+\r
+ if(IRQn < 0) {\r
+ return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M3 system interrupts */\r
+ else {\r
+ return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */\r
+}\r
+\r
+\r
+/**\r
+ * @brief Encode the priority for an interrupt\r
+ *\r
+ * @param PriorityGroup The used priority group\r
+ * @param PreemptPriority The preemptive priority value (starting from 0)\r
+ * @param SubPriority The sub priority value (starting from 0)\r
+ * @return The encoded priority for the interrupt\r
+ *\r
+ * Encode the priority for an interrupt with the given priority group,\r
+ * preemptive priority value and sub priority value.\r
+ * In case of a conflict between priority grouping and available\r
+ * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.\r
+ *\r
+ * The returned priority value can be used for NVIC_SetPriority(...) function\r
+ */\r
+static __INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)\r
+{\r
+ uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */\r
+ uint32_t PreemptPriorityBits;\r
+ uint32_t SubPriorityBits;\r
+\r
+ PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;\r
+ SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;\r
+\r
+ return (\r
+ ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) |\r
+ ((SubPriority & ((1 << (SubPriorityBits )) - 1)))\r
+ );\r
+}\r
+\r
+\r
+/**\r
+ * @brief Decode the priority of an interrupt\r
+ *\r
+ * @param Priority The priority for the interrupt\r
+ * @param PriorityGroup The used priority group\r
+ * @param pPreemptPriority The preemptive priority value (starting from 0)\r
+ * @param pSubPriority The sub priority value (starting from 0)\r
+ *\r
+ * Decode an interrupt priority value with the given priority group to\r
+ * preemptive priority value and sub priority value.\r
+ * In case of a conflict between priority grouping and available\r
+ * priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set.\r
+ *\r
+ * The priority value can be retrieved with NVIC_GetPriority(...) function\r
+ */\r
+static __INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority)\r
+{\r
+ uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */\r
+ uint32_t PreemptPriorityBits;\r
+ uint32_t SubPriorityBits;\r
+\r
+ PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;\r
+ SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;\r
+\r
+ *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1);\r
+ *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1);\r
+}\r
+\r
+\r
+\r
+/* ################################## SysTick function ############################################ */\r
+\r
+#if (!defined (__Vendor_SysTickConfig)) || (__Vendor_SysTickConfig == 0)\r
+\r
+/**\r
+ * @brief Initialize and start the SysTick counter and its interrupt.\r
+ *\r
+ * @param ticks number of ticks between two interrupts\r
+ * @return 1 = failed, 0 = successful\r
+ *\r
+ * Initialise the system tick timer and its interrupt and start the\r
+ * system tick timer / counter in free running mode to generate\r
+ * periodical interrupts.\r
+ */\r
+static __INLINE uint32_t SysTick_Config(uint32_t ticks)\r
+{\r
+ if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */\r
+\r
+ SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */\r
+ NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */\r
+ SysTick->VAL = 0; /* Load the SysTick Counter Value */\r
+ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |\r
+ SysTick_CTRL_TICKINT_Msk |\r
+ SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */\r
+ return (0); /* Function successful */\r
+}\r
+\r
+#endif\r
+\r
+\r
+\r
+\r
+/* ################################## Reset function ############################################ */\r
+\r
+/**\r
+ * @brief Initiate a system reset request.\r
+ *\r
+ * Initiate a system reset request to reset the MCU\r
+ */\r
+static __INLINE void NVIC_SystemReset(void)\r
+{\r
+ SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |\r
+ (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |\r
+ SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */\r
+ __DSB(); /* Ensure completion of memory access */\r
+ while(1); /* wait until reset */\r
+}\r
+\r
+/*@}*/ /* end of group CMSIS_CM3_Core_FunctionInterface */\r
+\r
+\r
+\r
+/* ##################################### Debug In/Output function ########################################### */\r
+\r
+/** @addtogroup CMSIS_CM3_CoreDebugInterface CMSIS CM3 Core Debug Interface\r
+ Core Debug Interface containing:\r
+ - Core Debug Receive / Transmit Functions\r
+ - Core Debug Defines\r
+ - Core Debug Variables\r
+*/\r
+/*@{*/\r
+\r
+extern volatile int ITM_RxBuffer; /*!< variable to receive characters */\r
+#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< value identifying ITM_RxBuffer is ready for next character */\r
+\r
+\r
+/**\r
+ * @brief Outputs a character via the ITM channel 0\r
+ *\r
+ * @param ch character to output\r
+ * @return character to output\r
+ *\r
+ * The function outputs a character via the ITM channel 0.\r
+ * The function returns when no debugger is connected that has booked the output.\r
+ * It is blocking when a debugger is connected, but the previous character send is not transmitted.\r
+ */\r
+static __INLINE uint32_t ITM_SendChar (uint32_t ch)\r
+{\r
+ if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk) && /* Trace enabled */\r
+ (ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */\r
+ (ITM->TER & (1ul << 0) ) ) /* ITM Port #0 enabled */\r
+ {\r
+ while (ITM->PORT[0].u32 == 0);\r
+ ITM->PORT[0].u8 = (uint8_t) ch;\r
+ }\r
+ return (ch);\r
+}\r
+\r
+\r
+/**\r
+ * @brief Inputs a character via variable ITM_RxBuffer\r
+ *\r
+ * @return received character, -1 = no character received\r
+ *\r
+ * The function inputs a character via variable ITM_RxBuffer.\r
+ * The function returns when no debugger is connected that has booked the output.\r
+ * It is blocking when a debugger is connected, but the previous character send is not transmitted.\r
+ */\r
+static __INLINE int ITM_ReceiveChar (void) {\r
+ int ch = -1; /* no character available */\r
+\r
+ if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) {\r
+ ch = ITM_RxBuffer;\r
+ ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */\r
+ }\r
+\r
+ return (ch);\r
+}\r
+\r
+\r
+/**\r
+ * @brief Check if a character via variable ITM_RxBuffer is available\r
+ *\r
+ * @return 1 = character available, 0 = no character available\r
+ *\r
+ * The function checks variable ITM_RxBuffer whether a character is available or not.\r
+ * The function returns '1' if a character is available and '0' if no character is available.\r
+ */\r
+static __INLINE int ITM_CheckChar (void) {\r
+\r
+ if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) {\r
+ return (0); /* no character available */\r
+ } else {\r
+ return (1); /* character available */\r
+ }\r
+}\r
+\r
+/*@}*/ /* end of group CMSIS_CM3_core_DebugInterface */\r
+\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+/*@}*/ /* end of group CMSIS_CM3_core_definitions */\r
+\r
+#endif /* __CM3_CORE_H__ */\r
+\r
+/*lint -restore */\r
--- /dev/null
+/**************************************************************************//**\r
+ * @file LPC17xx.h\r
+ * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File for\r
+ * NXP LPC17xx Device Series\r
+ * @version V1.07\r
+ * @date 19. October 2009\r
+ *\r
+ * @note\r
+ * Copyright (C) 2009 ARM Limited. All rights reserved.\r
+ *\r
+ * @par\r
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M\r
+ * processor based microcontrollers. This file can be freely distributed\r
+ * within development tools that are supporting such ARM based processors.\r
+ *\r
+ * @par\r
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED\r
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.\r
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR\r
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.\r
+ *\r
+ ******************************************************************************/\r
+\r
+\r
+#ifndef __LPC17xx_H__\r
+#define __LPC17xx_H__\r
+\r
+/*\r
+ * ==========================================================================\r
+ * ---------- Interrupt Number Definition -----------------------------------\r
+ * ==========================================================================\r
+ */\r
+\r
+typedef enum IRQn\r
+{\r
+/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/\r
+ NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */\r
+ MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */\r
+ BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */\r
+ UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */\r
+ SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */\r
+ DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */\r
+ PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */\r
+ SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */\r
+\r
+/****** LPC17xx Specific Interrupt Numbers *******************************************************/\r
+ WDT_IRQn = 0, /*!< Watchdog Timer Interrupt */\r
+ TIMER0_IRQn = 1, /*!< Timer0 Interrupt */\r
+ TIMER1_IRQn = 2, /*!< Timer1 Interrupt */\r
+ TIMER2_IRQn = 3, /*!< Timer2 Interrupt */\r
+ TIMER3_IRQn = 4, /*!< Timer3 Interrupt */\r
+ UART0_IRQn = 5, /*!< UART0 Interrupt */\r
+ UART1_IRQn = 6, /*!< UART1 Interrupt */\r
+ UART2_IRQn = 7, /*!< UART2 Interrupt */\r
+ UART3_IRQn = 8, /*!< UART3 Interrupt */\r
+ PWM1_IRQn = 9, /*!< PWM1 Interrupt */\r
+ I2C0_IRQn = 10, /*!< I2C0 Interrupt */\r
+ I2C1_IRQn = 11, /*!< I2C1 Interrupt */\r
+ I2C2_IRQn = 12, /*!< I2C2 Interrupt */\r
+ SPI_IRQn = 13, /*!< SPI Interrupt */\r
+ SSP0_IRQn = 14, /*!< SSP0 Interrupt */\r
+ SSP1_IRQn = 15, /*!< SSP1 Interrupt */\r
+ PLL0_IRQn = 16, /*!< PLL0 Lock (Main PLL) Interrupt */\r
+ RTC_IRQn = 17, /*!< Real Time Clock Interrupt */\r
+ EINT0_IRQn = 18, /*!< External Interrupt 0 Interrupt */\r
+ EINT1_IRQn = 19, /*!< External Interrupt 1 Interrupt */\r
+ EINT2_IRQn = 20, /*!< External Interrupt 2 Interrupt */\r
+ EINT3_IRQn = 21, /*!< External Interrupt 3 Interrupt */\r
+ ADC_IRQn = 22, /*!< A/D Converter Interrupt */\r
+ BOD_IRQn = 23, /*!< Brown-Out Detect Interrupt */\r
+ USB_IRQn = 24, /*!< USB Interrupt */\r
+ CAN_IRQn = 25, /*!< CAN Interrupt */\r
+ DMA_IRQn = 26, /*!< General Purpose DMA Interrupt */\r
+ I2S_IRQn = 27, /*!< I2S Interrupt */\r
+ ENET_IRQn = 28, /*!< Ethernet Interrupt */\r
+ RIT_IRQn = 29, /*!< Repetitive Interrupt Timer Interrupt */\r
+ MCPWM_IRQn = 30, /*!< Motor Control PWM Interrupt */\r
+ QEI_IRQn = 31, /*!< Quadrature Encoder Interface Interrupt */\r
+ PLL1_IRQn = 32, /*!< PLL1 Lock (USB PLL) Interrupt */\r
+ USBActivity_IRQn = 33, /*!< USB Activity Interrupt */\r
+ CANActivity_IRQn = 34, /*!< CAN Activity Interrupt */\r
+} IRQn_Type;\r
+\r
+\r
+/*\r
+ * ==========================================================================\r
+ * ----------- Processor and Core Peripheral Section ------------------------\r
+ * ==========================================================================\r
+ */\r
+\r
+/* Configuration of the Cortex-M3 Processor and Core Peripherals */\r
+#define __MPU_PRESENT 1 /*!< MPU present or not */\r
+#define __NVIC_PRIO_BITS 5 /*!< Number of Bits used for Priority Levels */\r
+#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */\r
+\r
+\r
+#include "core_cm3.h" /* Cortex-M3 processor and core peripherals */\r
+#include "system_LPC17xx.h" /* System Header */\r
+\r
+\r
+/******************************************************************************/\r
+/* Device Specific Peripheral registers structures */\r
+/******************************************************************************/\r
+\r
+#if defined ( __CC_ARM )\r
+#pragma anon_unions\r
+#endif\r
+\r
+/*------------- System Control (SC) ------------------------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t FLASHCFG; /* Flash Accelerator Module */\r
+ uint32_t RESERVED0[31];\r
+ __IO uint32_t PLL0CON; /* Clocking and Power Control */\r
+ __IO uint32_t PLL0CFG;\r
+ __I uint32_t PLL0STAT;\r
+ __O uint32_t PLL0FEED;\r
+ uint32_t RESERVED1[4];\r
+ __IO uint32_t PLL1CON;\r
+ __IO uint32_t PLL1CFG;\r
+ __I uint32_t PLL1STAT;\r
+ __O uint32_t PLL1FEED;\r
+ uint32_t RESERVED2[4];\r
+ __IO uint32_t PCON;\r
+ __IO uint32_t PCONP;\r
+ uint32_t RESERVED3[15];\r
+ __IO uint32_t CCLKCFG;\r
+ __IO uint32_t USBCLKCFG;\r
+ __IO uint32_t CLKSRCSEL;\r
+ uint32_t RESERVED4[12];\r
+ __IO uint32_t EXTINT; /* External Interrupts */\r
+ uint32_t RESERVED5;\r
+ __IO uint32_t EXTMODE;\r
+ __IO uint32_t EXTPOLAR;\r
+ uint32_t RESERVED6[12];\r
+ __IO uint32_t RSID; /* Reset */\r
+ uint32_t RESERVED7[7];\r
+ __IO uint32_t SCS; /* Syscon Miscellaneous Registers */\r
+ __IO uint32_t IRCTRIM; /* Clock Dividers */\r
+ __IO uint32_t PCLKSEL0;\r
+ __IO uint32_t PCLKSEL1;\r
+ uint32_t RESERVED8[4];\r
+ __IO uint32_t USBIntSt; /* USB Device/OTG Interrupt Register */\r
+ __IO uint32_t DMAREQSEL;\r
+ __IO uint32_t CLKOUTCFG; /* Clock Output Configuration */\r
+ } LPC_SC_TypeDef;\r
+\r
+/*------------- Pin Connect Block (PINCON) -----------------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t PINSEL0;\r
+ __IO uint32_t PINSEL1;\r
+ __IO uint32_t PINSEL2;\r
+ __IO uint32_t PINSEL3;\r
+ __IO uint32_t PINSEL4;\r
+ __IO uint32_t PINSEL5;\r
+ __IO uint32_t PINSEL6;\r
+ __IO uint32_t PINSEL7;\r
+ __IO uint32_t PINSEL8;\r
+ __IO uint32_t PINSEL9;\r
+ __IO uint32_t PINSEL10;\r
+ uint32_t RESERVED0[5];\r
+ __IO uint32_t PINMODE0;\r
+ __IO uint32_t PINMODE1;\r
+ __IO uint32_t PINMODE2;\r
+ __IO uint32_t PINMODE3;\r
+ __IO uint32_t PINMODE4;\r
+ __IO uint32_t PINMODE5;\r
+ __IO uint32_t PINMODE6;\r
+ __IO uint32_t PINMODE7;\r
+ __IO uint32_t PINMODE8;\r
+ __IO uint32_t PINMODE9;\r
+ __IO uint32_t PINMODE_OD0;\r
+ __IO uint32_t PINMODE_OD1;\r
+ __IO uint32_t PINMODE_OD2;\r
+ __IO uint32_t PINMODE_OD3;\r
+ __IO uint32_t PINMODE_OD4;\r
+ __IO uint32_t I2CPADCFG;\r
+} LPC_PINCON_TypeDef;\r
+\r
+/*------------- General Purpose Input/Output (GPIO) --------------------------*/\r
+typedef struct\r
+{\r
+ union {\r
+ __IO uint32_t FIODIR;\r
+ struct {\r
+ __IO uint16_t FIODIRL;\r
+ __IO uint16_t FIODIRH;\r
+ };\r
+ struct {\r
+ __IO uint8_t FIODIR0;\r
+ __IO uint8_t FIODIR1;\r
+ __IO uint8_t FIODIR2;\r
+ __IO uint8_t FIODIR3;\r
+ };\r
+ };\r
+ uint32_t RESERVED0[3];\r
+ union {\r
+ __IO uint32_t FIOMASK;\r
+ struct {\r
+ __IO uint16_t FIOMASKL;\r
+ __IO uint16_t FIOMASKH;\r
+ };\r
+ struct {\r
+ __IO uint8_t FIOMASK0;\r
+ __IO uint8_t FIOMASK1;\r
+ __IO uint8_t FIOMASK2;\r
+ __IO uint8_t FIOMASK3;\r
+ };\r
+ };\r
+ union {\r
+ __IO uint32_t FIOPIN;\r
+ struct {\r
+ __IO uint16_t FIOPINL;\r
+ __IO uint16_t FIOPINH;\r
+ };\r
+ struct {\r
+ __IO uint8_t FIOPIN0;\r
+ __IO uint8_t FIOPIN1;\r
+ __IO uint8_t FIOPIN2;\r
+ __IO uint8_t FIOPIN3;\r
+ };\r
+ };\r
+ union {\r
+ __IO uint32_t FIOSET;\r
+ struct {\r
+ __IO uint16_t FIOSETL;\r
+ __IO uint16_t FIOSETH;\r
+ };\r
+ struct {\r
+ __IO uint8_t FIOSET0;\r
+ __IO uint8_t FIOSET1;\r
+ __IO uint8_t FIOSET2;\r
+ __IO uint8_t FIOSET3;\r
+ };\r
+ };\r
+ union {\r
+ __O uint32_t FIOCLR;\r
+ struct {\r
+ __O uint16_t FIOCLRL;\r
+ __O uint16_t FIOCLRH;\r
+ };\r
+ struct {\r
+ __O uint8_t FIOCLR0;\r
+ __O uint8_t FIOCLR1;\r
+ __O uint8_t FIOCLR2;\r
+ __O uint8_t FIOCLR3;\r
+ };\r
+ };\r
+} LPC_GPIO_TypeDef;\r
+\r
+typedef struct\r
+{\r
+ __I uint32_t IntStatus;\r
+ __I uint32_t IO0IntStatR;\r
+ __I uint32_t IO0IntStatF;\r
+ __O uint32_t IO0IntClr;\r
+ __IO uint32_t IO0IntEnR;\r
+ __IO uint32_t IO0IntEnF;\r
+ uint32_t RESERVED0[3];\r
+ __I uint32_t IO2IntStatR;\r
+ __I uint32_t IO2IntStatF;\r
+ __O uint32_t IO2IntClr;\r
+ __IO uint32_t IO2IntEnR;\r
+ __IO uint32_t IO2IntEnF;\r
+} LPC_GPIOINT_TypeDef;\r
+\r
+/*------------- Timer (TIM) --------------------------------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t IR;\r
+ __IO uint32_t TCR;\r
+ __IO uint32_t TC;\r
+ __IO uint32_t PR;\r
+ __IO uint32_t PC;\r
+ __IO uint32_t MCR;\r
+ __IO uint32_t MR0;\r
+ __IO uint32_t MR1;\r
+ __IO uint32_t MR2;\r
+ __IO uint32_t MR3;\r
+ __IO uint32_t CCR;\r
+ __I uint32_t CR0;\r
+ __I uint32_t CR1;\r
+ uint32_t RESERVED0[2];\r
+ __IO uint32_t EMR;\r
+ uint32_t RESERVED1[12];\r
+ __IO uint32_t CTCR;\r
+} LPC_TIM_TypeDef;\r
+\r
+/*------------- Pulse-Width Modulation (PWM) ---------------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t IR;\r
+ __IO uint32_t TCR;\r
+ __IO uint32_t TC;\r
+ __IO uint32_t PR;\r
+ __IO uint32_t PC;\r
+ __IO uint32_t MCR;\r
+ __IO uint32_t MR0;\r
+ __IO uint32_t MR1;\r
+ __IO uint32_t MR2;\r
+ __IO uint32_t MR3;\r
+ __IO uint32_t CCR;\r
+ __I uint32_t CR0;\r
+ __I uint32_t CR1;\r
+ __I uint32_t CR2;\r
+ __I uint32_t CR3;\r
+ uint32_t RESERVED0;\r
+ __IO uint32_t MR4;\r
+ __IO uint32_t MR5;\r
+ __IO uint32_t MR6;\r
+ __IO uint32_t PCR;\r
+ __IO uint32_t LER;\r
+ uint32_t RESERVED1[7];\r
+ __IO uint32_t CTCR;\r
+} LPC_PWM_TypeDef;\r
+\r
+/*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/\r
+typedef struct\r
+{\r
+ union {\r
+ __I uint8_t RBR;\r
+ __O uint8_t THR;\r
+ __IO uint8_t DLL;\r
+ uint32_t RESERVED0;\r
+ };\r
+ union {\r
+ __IO uint8_t DLM;\r
+ __IO uint32_t IER;\r
+ };\r
+ union {\r
+ __I uint32_t IIR;\r
+ __O uint8_t FCR;\r
+ };\r
+ __IO uint8_t LCR;\r
+ uint8_t RESERVED1[7];\r
+ __I uint8_t LSR;\r
+ uint8_t RESERVED2[7];\r
+ __IO uint8_t SCR;\r
+ uint8_t RESERVED3[3];\r
+ __IO uint32_t ACR;\r
+ __IO uint8_t ICR;\r
+ uint8_t RESERVED4[3];\r
+ __IO uint8_t FDR;\r
+ uint8_t RESERVED5[7];\r
+ __IO uint8_t TER;\r
+ uint8_t RESERVED6[39];\r
+ __I uint8_t FIFOLVL;\r
+} LPC_UART_TypeDef;\r
+\r
+typedef struct\r
+{\r
+ union {\r
+ __I uint8_t RBR;\r
+ __O uint8_t THR;\r
+ __IO uint8_t DLL;\r
+ uint32_t RESERVED0;\r
+ };\r
+ union {\r
+ __IO uint8_t DLM;\r
+ __IO uint32_t IER;\r
+ };\r
+ union {\r
+ __I uint32_t IIR;\r
+ __O uint8_t FCR;\r
+ };\r
+ __IO uint8_t LCR;\r
+ uint8_t RESERVED1[7];\r
+ __I uint8_t LSR;\r
+ uint8_t RESERVED2[7];\r
+ __IO uint8_t SCR;\r
+ uint8_t RESERVED3[3];\r
+ __IO uint32_t ACR;\r
+ __IO uint8_t ICR;\r
+ uint8_t RESERVED4[3];\r
+ __IO uint8_t FDR;\r
+ uint8_t RESERVED5[7];\r
+ __IO uint8_t TER;\r
+ uint8_t RESERVED6[39];\r
+ __I uint8_t FIFOLVL;\r
+} LPC_UART0_TypeDef;\r
+\r
+typedef struct\r
+{\r
+ union {\r
+ __I uint8_t RBR;\r
+ __O uint8_t THR;\r
+ __IO uint8_t DLL;\r
+ uint32_t RESERVED0;\r
+ };\r
+ union {\r
+ __IO uint8_t DLM;\r
+ __IO uint32_t IER;\r
+ };\r
+ union {\r
+ __I uint32_t IIR;\r
+ __O uint8_t FCR;\r
+ };\r
+ __IO uint8_t LCR;\r
+ uint8_t RESERVED1[3];\r
+ __IO uint8_t MCR;\r
+ uint8_t RESERVED2[3];\r
+ __I uint8_t LSR;\r
+ uint8_t RESERVED3[3];\r
+ __I uint8_t MSR;\r
+ uint8_t RESERVED4[3];\r
+ __IO uint8_t SCR;\r
+ uint8_t RESERVED5[3];\r
+ __IO uint32_t ACR;\r
+ uint32_t RESERVED6;\r
+ __IO uint32_t FDR;\r
+ uint32_t RESERVED7;\r
+ __IO uint8_t TER;\r
+ uint8_t RESERVED8[27];\r
+ __IO uint8_t RS485CTRL;\r
+ uint8_t RESERVED9[3];\r
+ __IO uint8_t ADRMATCH;\r
+ uint8_t RESERVED10[3];\r
+ __IO uint8_t RS485DLY;\r
+ uint8_t RESERVED11[3];\r
+ __I uint8_t FIFOLVL;\r
+} LPC_UART1_TypeDef;\r
+\r
+/*------------- Serial Peripheral Interface (SPI) ----------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t SPCR;\r
+ __I uint32_t SPSR;\r
+ __IO uint32_t SPDR;\r
+ __IO uint32_t SPCCR;\r
+ uint32_t RESERVED0[3];\r
+ __IO uint32_t SPINT;\r
+} LPC_SPI_TypeDef;\r
+\r
+/*------------- Synchronous Serial Communication (SSP) -----------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t CR0;\r
+ __IO uint32_t CR1;\r
+ __IO uint32_t DR;\r
+ __I uint32_t SR;\r
+ __IO uint32_t CPSR;\r
+ __IO uint32_t IMSC;\r
+ __IO uint32_t RIS;\r
+ __IO uint32_t MIS;\r
+ __IO uint32_t ICR;\r
+ __IO uint32_t DMACR;\r
+} LPC_SSP_TypeDef;\r
+\r
+/*------------- Inter-Integrated Circuit (I2C) -------------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t I2CONSET;\r
+ __I uint32_t I2STAT;\r
+ __IO uint32_t I2DAT;\r
+ __IO uint32_t I2ADR0;\r
+ __IO uint32_t I2SCLH;\r
+ __IO uint32_t I2SCLL;\r
+ __O uint32_t I2CONCLR;\r
+ __IO uint32_t MMCTRL;\r
+ __IO uint32_t I2ADR1;\r
+ __IO uint32_t I2ADR2;\r
+ __IO uint32_t I2ADR3;\r
+ __I uint32_t I2DATA_BUFFER;\r
+ __IO uint32_t I2MASK0;\r
+ __IO uint32_t I2MASK1;\r
+ __IO uint32_t I2MASK2;\r
+ __IO uint32_t I2MASK3;\r
+} LPC_I2C_TypeDef;\r
+\r
+/*------------- Inter IC Sound (I2S) -----------------------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t I2SDAO;\r
+ __IO uint32_t I2SDAI;\r
+ __O uint32_t I2STXFIFO;\r
+ __I uint32_t I2SRXFIFO;\r
+ __I uint32_t I2SSTATE;\r
+ __IO uint32_t I2SDMA1;\r
+ __IO uint32_t I2SDMA2;\r
+ __IO uint32_t I2SIRQ;\r
+ __IO uint32_t I2STXRATE;\r
+ __IO uint32_t I2SRXRATE;\r
+ __IO uint32_t I2STXBITRATE;\r
+ __IO uint32_t I2SRXBITRATE;\r
+ __IO uint32_t I2STXMODE;\r
+ __IO uint32_t I2SRXMODE;\r
+} LPC_I2S_TypeDef;\r
+\r
+/*------------- Repetitive Interrupt Timer (RIT) -----------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t RICOMPVAL;\r
+ __IO uint32_t RIMASK;\r
+ __IO uint8_t RICTRL;\r
+ uint8_t RESERVED0[3];\r
+ __IO uint32_t RICOUNTER;\r
+} LPC_RIT_TypeDef;\r
+\r
+/*------------- Real-Time Clock (RTC) ----------------------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint8_t ILR;\r
+ uint8_t RESERVED0[7];\r
+ __IO uint8_t CCR;\r
+ uint8_t RESERVED1[3];\r
+ __IO uint8_t CIIR;\r
+ uint8_t RESERVED2[3];\r
+ __IO uint8_t AMR;\r
+ uint8_t RESERVED3[3];\r
+ __I uint32_t CTIME0;\r
+ __I uint32_t CTIME1;\r
+ __I uint32_t CTIME2;\r
+ __IO uint8_t SEC;\r
+ uint8_t RESERVED4[3];\r
+ __IO uint8_t MIN;\r
+ uint8_t RESERVED5[3];\r
+ __IO uint8_t HOUR;\r
+ uint8_t RESERVED6[3];\r
+ __IO uint8_t DOM;\r
+ uint8_t RESERVED7[3];\r
+ __IO uint8_t DOW;\r
+ uint8_t RESERVED8[3];\r
+ __IO uint16_t DOY;\r
+ uint16_t RESERVED9;\r
+ __IO uint8_t MONTH;\r
+ uint8_t RESERVED10[3];\r
+ __IO uint16_t YEAR;\r
+ uint16_t RESERVED11;\r
+ __IO uint32_t CALIBRATION;\r
+ __IO uint32_t GPREG0;\r
+ __IO uint32_t GPREG1;\r
+ __IO uint32_t GPREG2;\r
+ __IO uint32_t GPREG3;\r
+ __IO uint32_t GPREG4;\r
+ __IO uint8_t RTC_AUXEN;\r
+ uint8_t RESERVED12[3];\r
+ __IO uint8_t RTC_AUX;\r
+ uint8_t RESERVED13[3];\r
+ __IO uint8_t ALSEC;\r
+ uint8_t RESERVED14[3];\r
+ __IO uint8_t ALMIN;\r
+ uint8_t RESERVED15[3];\r
+ __IO uint8_t ALHOUR;\r
+ uint8_t RESERVED16[3];\r
+ __IO uint8_t ALDOM;\r
+ uint8_t RESERVED17[3];\r
+ __IO uint8_t ALDOW;\r
+ uint8_t RESERVED18[3];\r
+ __IO uint16_t ALDOY;\r
+ uint16_t RESERVED19;\r
+ __IO uint8_t ALMON;\r
+ uint8_t RESERVED20[3];\r
+ __IO uint16_t ALYEAR;\r
+ uint16_t RESERVED21;\r
+} LPC_RTC_TypeDef;\r
+\r
+/*------------- Watchdog Timer (WDT) -----------------------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint8_t WDMOD;\r
+ uint8_t RESERVED0[3];\r
+ __IO uint32_t WDTC;\r
+ __O uint8_t WDFEED;\r
+ uint8_t RESERVED1[3];\r
+ __I uint32_t WDTV;\r
+ __IO uint32_t WDCLKSEL;\r
+} LPC_WDT_TypeDef;\r
+\r
+/*------------- Analog-to-Digital Converter (ADC) ----------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t ADCR;\r
+ __IO uint32_t ADGDR;\r
+ uint32_t RESERVED0;\r
+ __IO uint32_t ADINTEN;\r
+ __I uint32_t ADDR0;\r
+ __I uint32_t ADDR1;\r
+ __I uint32_t ADDR2;\r
+ __I uint32_t ADDR3;\r
+ __I uint32_t ADDR4;\r
+ __I uint32_t ADDR5;\r
+ __I uint32_t ADDR6;\r
+ __I uint32_t ADDR7;\r
+ __I uint32_t ADSTAT;\r
+ __IO uint32_t ADTRM;\r
+} LPC_ADC_TypeDef;\r
+\r
+/*------------- Digital-to-Analog Converter (DAC) ----------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t DACR;\r
+ __IO uint32_t DACCTRL;\r
+ __IO uint16_t DACCNTVAL;\r
+} LPC_DAC_TypeDef;\r
+\r
+/*------------- Motor Control Pulse-Width Modulation (MCPWM) -----------------*/\r
+typedef struct\r
+{\r
+ __I uint32_t MCCON;\r
+ __O uint32_t MCCON_SET;\r
+ __O uint32_t MCCON_CLR;\r
+ __I uint32_t MCCAPCON;\r
+ __O uint32_t MCCAPCON_SET;\r
+ __O uint32_t MCCAPCON_CLR;\r
+ __IO uint32_t MCTIM0;\r
+ __IO uint32_t MCTIM1;\r
+ __IO uint32_t MCTIM2;\r
+ __IO uint32_t MCPER0;\r
+ __IO uint32_t MCPER1;\r
+ __IO uint32_t MCPER2;\r
+ __IO uint32_t MCPW0;\r
+ __IO uint32_t MCPW1;\r
+ __IO uint32_t MCPW2;\r
+ __IO uint32_t MCDEADTIME;\r
+ __IO uint32_t MCCCP;\r
+ __IO uint32_t MCCR0;\r
+ __IO uint32_t MCCR1;\r
+ __IO uint32_t MCCR2;\r
+ __I uint32_t MCINTEN;\r
+ __O uint32_t MCINTEN_SET;\r
+ __O uint32_t MCINTEN_CLR;\r
+ __I uint32_t MCCNTCON;\r
+ __O uint32_t MCCNTCON_SET;\r
+ __O uint32_t MCCNTCON_CLR;\r
+ __I uint32_t MCINTFLAG;\r
+ __O uint32_t MCINTFLAG_SET;\r
+ __O uint32_t MCINTFLAG_CLR;\r
+ __O uint32_t MCCAP_CLR;\r
+} LPC_MCPWM_TypeDef;\r
+\r
+/*------------- Quadrature Encoder Interface (QEI) ---------------------------*/\r
+typedef struct\r
+{\r
+ __O uint32_t QEICON;\r
+ __I uint32_t QEISTAT;\r
+ __IO uint32_t QEICONF;\r
+ __I uint32_t QEIPOS;\r
+ __IO uint32_t QEIMAXPOS;\r
+ __IO uint32_t CMPOS0;\r
+ __IO uint32_t CMPOS1;\r
+ __IO uint32_t CMPOS2;\r
+ __I uint32_t INXCNT;\r
+ __IO uint32_t INXCMP;\r
+ __IO uint32_t QEILOAD;\r
+ __I uint32_t QEITIME;\r
+ __I uint32_t QEIVEL;\r
+ __I uint32_t QEICAP;\r
+ __IO uint32_t VELCOMP;\r
+ __IO uint32_t FILTER;\r
+ uint32_t RESERVED0[998];\r
+ __O uint32_t QEIIEC;\r
+ __O uint32_t QEIIES;\r
+ __I uint32_t QEIINTSTAT;\r
+ __I uint32_t QEIIE;\r
+ __O uint32_t QEICLR;\r
+ __O uint32_t QEISET;\r
+} LPC_QEI_TypeDef;\r
+\r
+/*------------- Controller Area Network (CAN) --------------------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t mask[512]; /* ID Masks */\r
+} LPC_CANAF_RAM_TypeDef;\r
+\r
+typedef struct /* Acceptance Filter Registers */\r
+{\r
+ __IO uint32_t AFMR;\r
+ __IO uint32_t SFF_sa;\r
+ __IO uint32_t SFF_GRP_sa;\r
+ __IO uint32_t EFF_sa;\r
+ __IO uint32_t EFF_GRP_sa;\r
+ __IO uint32_t ENDofTable;\r
+ __I uint32_t LUTerrAd;\r
+ __I uint32_t LUTerr;\r
+ __IO uint32_t FCANIE;\r
+ __IO uint32_t FCANIC0;\r
+ __IO uint32_t FCANIC1;\r
+} LPC_CANAF_TypeDef;\r
+\r
+typedef struct /* Central Registers */\r
+{\r
+ __I uint32_t CANTxSR;\r
+ __I uint32_t CANRxSR;\r
+ __I uint32_t CANMSR;\r
+} LPC_CANCR_TypeDef;\r
+\r
+typedef struct /* Controller Registers */\r
+{\r
+ __IO uint32_t MOD;\r
+ __O uint32_t CMR;\r
+ __IO uint32_t GSR;\r
+ __I uint32_t ICR;\r
+ __IO uint32_t IER;\r
+ __IO uint32_t BTR;\r
+ __IO uint32_t EWL;\r
+ __I uint32_t SR;\r
+ __IO uint32_t RFS;\r
+ __IO uint32_t RID;\r
+ __IO uint32_t RDA;\r
+ __IO uint32_t RDB;\r
+ __IO uint32_t TFI1;\r
+ __IO uint32_t TID1;\r
+ __IO uint32_t TDA1;\r
+ __IO uint32_t TDB1;\r
+ __IO uint32_t TFI2;\r
+ __IO uint32_t TID2;\r
+ __IO uint32_t TDA2;\r
+ __IO uint32_t TDB2;\r
+ __IO uint32_t TFI3;\r
+ __IO uint32_t TID3;\r
+ __IO uint32_t TDA3;\r
+ __IO uint32_t TDB3;\r
+} LPC_CAN_TypeDef;\r
+\r
+/*------------- General Purpose Direct Memory Access (GPDMA) -----------------*/\r
+typedef struct /* Common Registers */\r
+{\r
+ __I uint32_t DMACIntStat;\r
+ __I uint32_t DMACIntTCStat;\r
+ __O uint32_t DMACIntTCClear;\r
+ __I uint32_t DMACIntErrStat;\r
+ __O uint32_t DMACIntErrClr;\r
+ __I uint32_t DMACRawIntTCStat;\r
+ __I uint32_t DMACRawIntErrStat;\r
+ __I uint32_t DMACEnbldChns;\r
+ __IO uint32_t DMACSoftBReq;\r
+ __IO uint32_t DMACSoftSReq;\r
+ __IO uint32_t DMACSoftLBReq;\r
+ __IO uint32_t DMACSoftLSReq;\r
+ __IO uint32_t DMACConfig;\r
+ __IO uint32_t DMACSync;\r
+} LPC_GPDMA_TypeDef;\r
+\r
+typedef struct /* Channel Registers */\r
+{\r
+ __IO uint32_t DMACCSrcAddr;\r
+ __IO uint32_t DMACCDestAddr;\r
+ __IO uint32_t DMACCLLI;\r
+ __IO uint32_t DMACCControl;\r
+ __IO uint32_t DMACCConfig;\r
+} LPC_GPDMACH_TypeDef;\r
+\r
+/*------------- Universal Serial Bus (USB) -----------------------------------*/\r
+typedef struct\r
+{\r
+ __I uint32_t HcRevision; /* USB Host Registers */\r
+ __IO uint32_t HcControl;\r
+ __IO uint32_t HcCommandStatus;\r
+ __IO uint32_t HcInterruptStatus;\r
+ __IO uint32_t HcInterruptEnable;\r
+ __IO uint32_t HcInterruptDisable;\r
+ __IO uint32_t HcHCCA;\r
+ __I uint32_t HcPeriodCurrentED;\r
+ __IO uint32_t HcControlHeadED;\r
+ __IO uint32_t HcControlCurrentED;\r
+ __IO uint32_t HcBulkHeadED;\r
+ __IO uint32_t HcBulkCurrentED;\r
+ __I uint32_t HcDoneHead;\r
+ __IO uint32_t HcFmInterval;\r
+ __I uint32_t HcFmRemaining;\r
+ __I uint32_t HcFmNumber;\r
+ __IO uint32_t HcPeriodicStart;\r
+ __IO uint32_t HcLSTreshold;\r
+ __IO uint32_t HcRhDescriptorA;\r
+ __IO uint32_t HcRhDescriptorB;\r
+ __IO uint32_t HcRhStatus;\r
+ __IO uint32_t HcRhPortStatus1;\r
+ __IO uint32_t HcRhPortStatus2;\r
+ uint32_t RESERVED0[40];\r
+ __I uint32_t Module_ID;\r
+\r
+ __I uint32_t OTGIntSt; /* USB On-The-Go Registers */\r
+ __IO uint32_t OTGIntEn;\r
+ __O uint32_t OTGIntSet;\r
+ __O uint32_t OTGIntClr;\r
+ __IO uint32_t OTGStCtrl;\r
+ __IO uint32_t OTGTmr;\r
+ uint32_t RESERVED1[58];\r
+\r
+ __I uint32_t USBDevIntSt; /* USB Device Interrupt Registers */\r
+ __IO uint32_t USBDevIntEn;\r
+ __O uint32_t USBDevIntClr;\r
+ __O uint32_t USBDevIntSet;\r
+\r
+ __O uint32_t USBCmdCode; /* USB Device SIE Command Registers */\r
+ __I uint32_t USBCmdData;\r
+\r
+ __I uint32_t USBRxData; /* USB Device Transfer Registers */\r
+ __O uint32_t USBTxData;\r
+ __I uint32_t USBRxPLen;\r
+ __O uint32_t USBTxPLen;\r
+ __IO uint32_t USBCtrl;\r
+ __O uint32_t USBDevIntPri;\r
+\r
+ __I uint32_t USBEpIntSt; /* USB Device Endpoint Interrupt Regs */\r
+ __IO uint32_t USBEpIntEn;\r
+ __O uint32_t USBEpIntClr;\r
+ __O uint32_t USBEpIntSet;\r
+ __O uint32_t USBEpIntPri;\r
+\r
+ __IO uint32_t USBReEp; /* USB Device Endpoint Realization Reg*/\r
+ __O uint32_t USBEpInd;\r
+ __IO uint32_t USBMaxPSize;\r
+\r
+ __I uint32_t USBDMARSt; /* USB Device DMA Registers */\r
+ __O uint32_t USBDMARClr;\r
+ __O uint32_t USBDMARSet;\r
+ uint32_t RESERVED2[9];\r
+ __IO uint32_t USBUDCAH;\r
+ __I uint32_t USBEpDMASt;\r
+ __O uint32_t USBEpDMAEn;\r
+ __O uint32_t USBEpDMADis;\r
+ __I uint32_t USBDMAIntSt;\r
+ __IO uint32_t USBDMAIntEn;\r
+ uint32_t RESERVED3[2];\r
+ __I uint32_t USBEoTIntSt;\r
+ __O uint32_t USBEoTIntClr;\r
+ __O uint32_t USBEoTIntSet;\r
+ __I uint32_t USBNDDRIntSt;\r
+ __O uint32_t USBNDDRIntClr;\r
+ __O uint32_t USBNDDRIntSet;\r
+ __I uint32_t USBSysErrIntSt;\r
+ __O uint32_t USBSysErrIntClr;\r
+ __O uint32_t USBSysErrIntSet;\r
+ uint32_t RESERVED4[15];\r
+\r
+ __I uint32_t I2C_RX; /* USB OTG I2C Registers */\r
+ __O uint32_t I2C_WO;\r
+ __I uint32_t I2C_STS;\r
+ __IO uint32_t I2C_CTL;\r
+ __IO uint32_t I2C_CLKHI;\r
+ __O uint32_t I2C_CLKLO;\r
+ uint32_t RESERVED5[823];\r
+\r
+ union {\r
+ __IO uint32_t USBClkCtrl; /* USB Clock Control Registers */\r
+ __IO uint32_t OTGClkCtrl;\r
+ };\r
+ union {\r
+ __I uint32_t USBClkSt;\r
+ __I uint32_t OTGClkSt;\r
+ };\r
+} LPC_USB_TypeDef;\r
+\r
+/*------------- Ethernet Media Access Controller (EMAC) ----------------------*/\r
+typedef struct\r
+{\r
+ __IO uint32_t MAC1; /* MAC Registers */\r
+ __IO uint32_t MAC2;\r
+ __IO uint32_t IPGT;\r
+ __IO uint32_t IPGR;\r
+ __IO uint32_t CLRT;\r
+ __IO uint32_t MAXF;\r
+ __IO uint32_t SUPP;\r
+ __IO uint32_t TEST;\r
+ __IO uint32_t MCFG;\r
+ __IO uint32_t MCMD;\r
+ __IO uint32_t MADR;\r
+ __O uint32_t MWTD;\r
+ __I uint32_t MRDD;\r
+ __I uint32_t MIND;\r
+ uint32_t RESERVED0[2];\r
+ __IO uint32_t SA0;\r
+ __IO uint32_t SA1;\r
+ __IO uint32_t SA2;\r
+ uint32_t RESERVED1[45];\r
+ __IO uint32_t Command; /* Control Registers */\r
+ __I uint32_t Status;\r
+ __IO uint32_t RxDescriptor;\r
+ __IO uint32_t RxStatus;\r
+ __IO uint32_t RxDescriptorNumber;\r
+ __I uint32_t RxProduceIndex;\r
+ __IO uint32_t RxConsumeIndex;\r
+ __IO uint32_t TxDescriptor;\r
+ __IO uint32_t TxStatus;\r
+ __IO uint32_t TxDescriptorNumber;\r
+ __IO uint32_t TxProduceIndex;\r
+ __I uint32_t TxConsumeIndex;\r
+ uint32_t RESERVED2[10];\r
+ __I uint32_t TSV0;\r
+ __I uint32_t TSV1;\r
+ __I uint32_t RSV;\r
+ uint32_t RESERVED3[3];\r
+ __IO uint32_t FlowControlCounter;\r
+ __I uint32_t FlowControlStatus;\r
+ uint32_t RESERVED4[34];\r
+ __IO uint32_t RxFilterCtrl; /* Rx Filter Registers */\r
+ __IO uint32_t RxFilterWoLStatus;\r
+ __IO uint32_t RxFilterWoLClear;\r
+ uint32_t RESERVED5;\r
+ __IO uint32_t HashFilterL;\r
+ __IO uint32_t HashFilterH;\r
+ uint32_t RESERVED6[882];\r
+ __I uint32_t IntStatus; /* Module Control Registers */\r
+ __IO uint32_t IntEnable;\r
+ __O uint32_t IntClear;\r
+ __O uint32_t IntSet;\r
+ uint32_t RESERVED7;\r
+ __IO uint32_t PowerDown;\r
+ uint32_t RESERVED8;\r
+ __IO uint32_t Module_ID;\r
+} LPC_EMAC_TypeDef;\r
+\r
+#if defined ( __CC_ARM )\r
+#pragma no_anon_unions\r
+#endif\r
+\r
+\r
+/******************************************************************************/\r
+/* Peripheral memory map */\r
+/******************************************************************************/\r
+/* Base addresses */\r
+#define LPC_FLASH_BASE (0x00000000UL)\r
+#define LPC_RAM_BASE (0x10000000UL)\r
+#ifdef __LPC17XX_REV00\r
+#define LPC_AHBRAM0_BASE (0x20000000UL)\r
+#define LPC_AHBRAM1_BASE (0x20004000UL)\r
+#else\r
+#define LPC_AHBRAM0_BASE (0x2007C000UL)\r
+#define LPC_AHBRAM1_BASE (0x20080000UL)\r
+#endif\r
+#define LPC_GPIO_BASE (0x2009C000UL)\r
+#define LPC_APB0_BASE (0x40000000UL)\r
+#define LPC_APB1_BASE (0x40080000UL)\r
+#define LPC_AHB_BASE (0x50000000UL)\r
+#define LPC_CM3_BASE (0xE0000000UL)\r
+\r
+/* APB0 peripherals */\r
+#define LPC_WDT_BASE (LPC_APB0_BASE + 0x00000)\r
+#define LPC_TIM0_BASE (LPC_APB0_BASE + 0x04000)\r
+#define LPC_TIM1_BASE (LPC_APB0_BASE + 0x08000)\r
+#define LPC_UART0_BASE (LPC_APB0_BASE + 0x0C000)\r
+#define LPC_UART1_BASE (LPC_APB0_BASE + 0x10000)\r
+#define LPC_PWM1_BASE (LPC_APB0_BASE + 0x18000)\r
+#define LPC_I2C0_BASE (LPC_APB0_BASE + 0x1C000)\r
+#define LPC_SPI_BASE (LPC_APB0_BASE + 0x20000)\r
+#define LPC_RTC_BASE (LPC_APB0_BASE + 0x24000)\r
+#define LPC_GPIOINT_BASE (LPC_APB0_BASE + 0x28080)\r
+#define LPC_PINCON_BASE (LPC_APB0_BASE + 0x2C000)\r
+#define LPC_SSP1_BASE (LPC_APB0_BASE + 0x30000)\r
+#define LPC_ADC_BASE (LPC_APB0_BASE + 0x34000)\r
+#define LPC_CANAF_RAM_BASE (LPC_APB0_BASE + 0x38000)\r
+#define LPC_CANAF_BASE (LPC_APB0_BASE + 0x3C000)\r
+#define LPC_CANCR_BASE (LPC_APB0_BASE + 0x40000)\r
+#define LPC_CAN1_BASE (LPC_APB0_BASE + 0x44000)\r
+#define LPC_CAN2_BASE (LPC_APB0_BASE + 0x48000)\r
+#define LPC_I2C1_BASE (LPC_APB0_BASE + 0x5C000)\r
+\r
+/* APB1 peripherals */\r
+#define LPC_SSP0_BASE (LPC_APB1_BASE + 0x08000)\r
+#define LPC_DAC_BASE (LPC_APB1_BASE + 0x0C000)\r
+#define LPC_TIM2_BASE (LPC_APB1_BASE + 0x10000)\r
+#define LPC_TIM3_BASE (LPC_APB1_BASE + 0x14000)\r
+#define LPC_UART2_BASE (LPC_APB1_BASE + 0x18000)\r
+#define LPC_UART3_BASE (LPC_APB1_BASE + 0x1C000)\r
+#define LPC_I2C2_BASE (LPC_APB1_BASE + 0x20000)\r
+#define LPC_I2S_BASE (LPC_APB1_BASE + 0x28000)\r
+#define LPC_RIT_BASE (LPC_APB1_BASE + 0x30000)\r
+#define LPC_MCPWM_BASE (LPC_APB1_BASE + 0x38000)\r
+#define LPC_QEI_BASE (LPC_APB1_BASE + 0x3C000)\r
+#define LPC_SC_BASE (LPC_APB1_BASE + 0x7C000)\r
+\r
+/* AHB peripherals */\r
+#define LPC_EMAC_BASE (LPC_AHB_BASE + 0x00000)\r
+#define LPC_GPDMA_BASE (LPC_AHB_BASE + 0x04000)\r
+#define LPC_GPDMACH0_BASE (LPC_AHB_BASE + 0x04100)\r
+#define LPC_GPDMACH1_BASE (LPC_AHB_BASE + 0x04120)\r
+#define LPC_GPDMACH2_BASE (LPC_AHB_BASE + 0x04140)\r
+#define LPC_GPDMACH3_BASE (LPC_AHB_BASE + 0x04160)\r
+#define LPC_GPDMACH4_BASE (LPC_AHB_BASE + 0x04180)\r
+#define LPC_GPDMACH5_BASE (LPC_AHB_BASE + 0x041A0)\r
+#define LPC_GPDMACH6_BASE (LPC_AHB_BASE + 0x041C0)\r
+#define LPC_GPDMACH7_BASE (LPC_AHB_BASE + 0x041E0)\r
+#define LPC_USB_BASE (LPC_AHB_BASE + 0x0C000)\r
+\r
+/* GPIOs */\r
+#define LPC_GPIO0_BASE (LPC_GPIO_BASE + 0x00000)\r
+#define LPC_GPIO1_BASE (LPC_GPIO_BASE + 0x00020)\r
+#define LPC_GPIO2_BASE (LPC_GPIO_BASE + 0x00040)\r
+#define LPC_GPIO3_BASE (LPC_GPIO_BASE + 0x00060)\r
+#define LPC_GPIO4_BASE (LPC_GPIO_BASE + 0x00080)\r
+\r
+\r
+/******************************************************************************/\r
+/* Peripheral declaration */\r
+/******************************************************************************/\r
+#define LPC_SC ((LPC_SC_TypeDef *) LPC_SC_BASE )\r
+#define LPC_GPIO0 ((LPC_GPIO_TypeDef *) LPC_GPIO0_BASE )\r
+#define LPC_GPIO1 ((LPC_GPIO_TypeDef *) LPC_GPIO1_BASE )\r
+#define LPC_GPIO2 ((LPC_GPIO_TypeDef *) LPC_GPIO2_BASE )\r
+#define LPC_GPIO3 ((LPC_GPIO_TypeDef *) LPC_GPIO3_BASE )\r
+#define LPC_GPIO4 ((LPC_GPIO_TypeDef *) LPC_GPIO4_BASE )\r
+#define LPC_WDT ((LPC_WDT_TypeDef *) LPC_WDT_BASE )\r
+#define LPC_TIM0 ((LPC_TIM_TypeDef *) LPC_TIM0_BASE )\r
+#define LPC_TIM1 ((LPC_TIM_TypeDef *) LPC_TIM1_BASE )\r
+#define LPC_TIM2 ((LPC_TIM_TypeDef *) LPC_TIM2_BASE )\r
+#define LPC_TIM3 ((LPC_TIM_TypeDef *) LPC_TIM3_BASE )\r
+#define LPC_RIT ((LPC_RIT_TypeDef *) LPC_RIT_BASE )\r
+#define LPC_UART0 ((LPC_UART_TypeDef *) LPC_UART0_BASE )\r
+#define LPC_UART1 ((LPC_UART1_TypeDef *) LPC_UART1_BASE )\r
+#define LPC_UART2 ((LPC_UART_TypeDef *) LPC_UART2_BASE )\r
+#define LPC_UART3 ((LPC_UART_TypeDef *) LPC_UART3_BASE )\r
+#define LPC_PWM1 ((LPC_PWM_TypeDef *) LPC_PWM1_BASE )\r
+#define LPC_I2C0 ((LPC_I2C_TypeDef *) LPC_I2C0_BASE )\r
+#define LPC_I2C1 ((LPC_I2C_TypeDef *) LPC_I2C1_BASE )\r
+#define LPC_I2C2 ((LPC_I2C_TypeDef *) LPC_I2C2_BASE )\r
+#define LPC_I2S ((LPC_I2S_TypeDef *) LPC_I2S_BASE )\r
+#define LPC_SPI ((LPC_SPI_TypeDef *) LPC_SPI_BASE )\r
+#define LPC_RTC ((LPC_RTC_TypeDef *) LPC_RTC_BASE )\r
+#define LPC_GPIOINT ((LPC_GPIOINT_TypeDef *) LPC_GPIOINT_BASE )\r
+#define LPC_PINCON ((LPC_PINCON_TypeDef *) LPC_PINCON_BASE )\r
+#define LPC_SSP0 ((LPC_SSP_TypeDef *) LPC_SSP0_BASE )\r
+#define LPC_SSP1 ((LPC_SSP_TypeDef *) LPC_SSP1_BASE )\r
+#define LPC_ADC ((LPC_ADC_TypeDef *) LPC_ADC_BASE )\r
+#define LPC_DAC ((LPC_DAC_TypeDef *) LPC_DAC_BASE )\r
+#define LPC_CANAF_RAM ((LPC_CANAF_RAM_TypeDef *) LPC_CANAF_RAM_BASE)\r
+#define LPC_CANAF ((LPC_CANAF_TypeDef *) LPC_CANAF_BASE )\r
+#define LPC_CANCR ((LPC_CANCR_TypeDef *) LPC_CANCR_BASE )\r
+#define LPC_CAN1 ((LPC_CAN_TypeDef *) LPC_CAN1_BASE )\r
+#define LPC_CAN2 ((LPC_CAN_TypeDef *) LPC_CAN2_BASE )\r
+#define LPC_MCPWM ((LPC_MCPWM_TypeDef *) LPC_MCPWM_BASE )\r
+#define LPC_QEI ((LPC_QEI_TypeDef *) LPC_QEI_BASE )\r
+#define LPC_EMAC ((LPC_EMAC_TypeDef *) LPC_EMAC_BASE )\r
+#define LPC_GPDMA ((LPC_GPDMA_TypeDef *) LPC_GPDMA_BASE )\r
+#define DMAREQSEL (*(__IO uint32_t *) ( 0x4000C1C4))\r
+#define LPC_GPDMACH0 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH0_BASE )\r
+#define LPC_GPDMACH1 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH1_BASE )\r
+#define LPC_GPDMACH2 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH2_BASE )\r
+#define LPC_GPDMACH3 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH3_BASE )\r
+#define LPC_GPDMACH4 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH4_BASE )\r
+#define LPC_GPDMACH5 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH5_BASE )\r
+#define LPC_GPDMACH6 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH6_BASE )\r
+#define LPC_GPDMACH7 ((LPC_GPDMACH_TypeDef *) LPC_GPDMACH7_BASE )\r
+#define LPC_USB ((LPC_USB_TypeDef *) LPC_USB_BASE )\r
+\r
+#endif // __LPC17xx_H__\r
--- /dev/null
+/**************************************************************************//**\r
+ * @file system_LPC17xx.h\r
+ * @brief CMSIS Cortex-M3 Device Peripheral Access Layer Header File\r
+ * for the NXP LPC17xx Device Series\r
+ * @version V1.02\r
+ * @date 08. September 2009\r
+ *\r
+ * @note\r
+ * Copyright (C) 2009 ARM Limited. All rights reserved.\r
+ *\r
+ * @par\r
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M\r
+ * processor based microcontrollers. This file can be freely distributed\r
+ * within development tools that are supporting such ARM based processors.\r
+ *\r
+ * @par\r
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED\r
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.\r
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR\r
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.\r
+ *\r
+ ******************************************************************************/\r
+\r
+\r
+#ifndef __SYSTEM_LPC17xx_H\r
+#define __SYSTEM_LPC17xx_H\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#include <stdint.h>\r
+\r
+extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */\r
+\r
+\r
+/**\r
+ * Initialize the system\r
+ *\r
+ * @param none\r
+ * @return none\r
+ *\r
+ * @brief Setup the microcontroller system.\r
+ * Initialize the System and update the SystemCoreClock variable.\r
+ */\r
+extern void SystemInit (void);\r
+\r
+/**\r
+ * Update SystemCoreClock variable\r
+ *\r
+ * @param none\r
+ * @return none\r
+ *\r
+ * @brief Updates the SystemCoreClock with current core Clock\r
+ * retrieved from cpu registers.\r
+ */\r
+extern void SystemCoreClockUpdate (void);\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* __SYSTEM_LPC17xx_H */\r
--- /dev/null
+/**************************************************************************//**\r
+ * @file core_cm3.c\r
+ * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Source File\r
+ * @version V1.30\r
+ * @date 30. October 2009\r
+ *\r
+ * @note\r
+ * Copyright (C) 2009 ARM Limited. All rights reserved.\r
+ *\r
+ * @par\r
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M \r
+ * processor based microcontrollers. This file can be freely distributed \r
+ * within development tools that are supporting such ARM based processors. \r
+ *\r
+ * @par\r
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED\r
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.\r
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR\r
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.\r
+ *\r
+ ******************************************************************************/\r
+\r
+#include <stdint.h>\r
+\r
+/* define compiler specific symbols */\r
+#if defined ( __CC_ARM )\r
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */\r
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */\r
+\r
+#elif defined ( __ICCARM__ )\r
+ #define __ASM __asm /*!< asm keyword for IAR Compiler */\r
+ #define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */\r
+\r
+#elif defined ( __GNUC__ )\r
+ #define __ASM __asm /*!< asm keyword for GNU Compiler */\r
+ #define __INLINE inline /*!< inline keyword for GNU Compiler */\r
+\r
+#elif defined ( __TASKING__ )\r
+ #define __ASM __asm /*!< asm keyword for TASKING Compiler */\r
+ #define __INLINE inline /*!< inline keyword for TASKING Compiler */\r
+\r
+#endif\r
+\r
+\r
+/* ################### Compiler specific Intrinsics ########################### */\r
+\r
+#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/\r
+/* ARM armcc specific functions */\r
+\r
+/**\r
+ * @brief Return the Process Stack Pointer\r
+ *\r
+ * @return ProcessStackPointer\r
+ *\r
+ * Return the actual process stack pointer\r
+ */\r
+__ASM uint32_t __get_PSP(void)\r
+{\r
+ mrs r0, psp\r
+ bx lr\r
+}\r
+\r
+/**\r
+ * @brief Set the Process Stack Pointer\r
+ *\r
+ * @param topOfProcStack Process Stack Pointer\r
+ *\r
+ * Assign the value ProcessStackPointer to the MSP \r
+ * (process stack pointer) Cortex processor register\r
+ */\r
+__ASM void __set_PSP(uint32_t topOfProcStack)\r
+{\r
+ msr psp, r0\r
+ bx lr\r
+}\r
+\r
+/**\r
+ * @brief Return the Main Stack Pointer\r
+ *\r
+ * @return Main Stack Pointer\r
+ *\r
+ * Return the current value of the MSP (main stack pointer)\r
+ * Cortex processor register\r
+ */\r
+__ASM uint32_t __get_MSP(void)\r
+{\r
+ mrs r0, msp\r
+ bx lr\r
+}\r
+\r
+/**\r
+ * @brief Set the Main Stack Pointer\r
+ *\r
+ * @param topOfMainStack Main Stack Pointer\r
+ *\r
+ * Assign the value mainStackPointer to the MSP \r
+ * (main stack pointer) Cortex processor register\r
+ */\r
+__ASM void __set_MSP(uint32_t mainStackPointer)\r
+{\r
+ msr msp, r0\r
+ bx lr\r
+}\r
+\r
+/**\r
+ * @brief Reverse byte order in unsigned short value\r
+ *\r
+ * @param value value to reverse\r
+ * @return reversed value\r
+ *\r
+ * Reverse byte order in unsigned short value\r
+ */\r
+__ASM uint32_t __REV16(uint16_t value)\r
+{\r
+ rev16 r0, r0\r
+ bx lr\r
+}\r
+\r
+/**\r
+ * @brief Reverse byte order in signed short value with sign extension to integer\r
+ *\r
+ * @param value value to reverse\r
+ * @return reversed value\r
+ *\r
+ * Reverse byte order in signed short value with sign extension to integer\r
+ */\r
+__ASM int32_t __REVSH(int16_t value)\r
+{\r
+ revsh r0, r0\r
+ bx lr\r
+}\r
+\r
+\r
+#if (__ARMCC_VERSION < 400000)\r
+\r
+/**\r
+ * @brief Remove the exclusive lock created by ldrex\r
+ *\r
+ * Removes the exclusive lock which is created by ldrex.\r
+ */\r
+__ASM void __CLREX(void)\r
+{\r
+ clrex\r
+}\r
+\r
+/**\r
+ * @brief Return the Base Priority value\r
+ *\r
+ * @return BasePriority\r
+ *\r
+ * Return the content of the base priority register\r
+ */\r
+__ASM uint32_t __get_BASEPRI(void)\r
+{\r
+ mrs r0, basepri\r
+ bx lr\r
+}\r
+\r
+/**\r
+ * @brief Set the Base Priority value\r
+ *\r
+ * @param basePri BasePriority\r
+ *\r
+ * Set the base priority register\r
+ */\r
+__ASM void __set_BASEPRI(uint32_t basePri)\r
+{\r
+ msr basepri, r0\r
+ bx lr\r
+}\r
+\r
+/**\r
+ * @brief Return the Priority Mask value\r
+ *\r
+ * @return PriMask\r
+ *\r
+ * Return state of the priority mask bit from the priority mask register\r
+ */\r
+__ASM uint32_t __get_PRIMASK(void)\r
+{\r
+ mrs r0, primask\r
+ bx lr\r
+}\r
+\r
+/**\r
+ * @brief Set the Priority Mask value\r
+ *\r
+ * @param priMask PriMask\r
+ *\r
+ * Set the priority mask bit in the priority mask register\r
+ */\r
+__ASM void __set_PRIMASK(uint32_t priMask)\r
+{\r
+ msr primask, r0\r
+ bx lr\r
+}\r
+\r
+/**\r
+ * @brief Return the Fault Mask value\r
+ *\r
+ * @return FaultMask\r
+ *\r
+ * Return the content of the fault mask register\r
+ */\r
+__ASM uint32_t __get_FAULTMASK(void)\r
+{\r
+ mrs r0, faultmask\r
+ bx lr\r
+}\r
+\r
+/**\r
+ * @brief Set the Fault Mask value\r
+ *\r
+ * @param faultMask faultMask value\r
+ *\r
+ * Set the fault mask register\r
+ */\r
+__ASM void __set_FAULTMASK(uint32_t faultMask)\r
+{\r
+ msr faultmask, r0\r
+ bx lr\r
+}\r
+\r
+/**\r
+ * @brief Return the Control Register value\r
+ * \r
+ * @return Control value\r
+ *\r
+ * Return the content of the control register\r
+ */\r
+__ASM uint32_t __get_CONTROL(void)\r
+{\r
+ mrs r0, control\r
+ bx lr\r
+}\r
+\r
+/**\r
+ * @brief Set the Control Register value\r
+ *\r
+ * @param control Control value\r
+ *\r
+ * Set the control register\r
+ */\r
+__ASM void __set_CONTROL(uint32_t control)\r
+{\r
+ msr control, r0\r
+ bx lr\r
+}\r
+\r
+#endif /* __ARMCC_VERSION */ \r
+\r
+\r
+\r
+#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/\r
+/* IAR iccarm specific functions */\r
+#pragma diag_suppress=Pe940\r
+\r
+/**\r
+ * @brief Return the Process Stack Pointer\r
+ *\r
+ * @return ProcessStackPointer\r
+ *\r
+ * Return the actual process stack pointer\r
+ */\r
+uint32_t __get_PSP(void)\r
+{\r
+ __ASM("mrs r0, psp");\r
+ __ASM("bx lr");\r
+}\r
+\r
+/**\r
+ * @brief Set the Process Stack Pointer\r
+ *\r
+ * @param topOfProcStack Process Stack Pointer\r
+ *\r
+ * Assign the value ProcessStackPointer to the MSP \r
+ * (process stack pointer) Cortex processor register\r
+ */\r
+void __set_PSP(uint32_t topOfProcStack)\r
+{\r
+ __ASM("msr psp, r0");\r
+ __ASM("bx lr");\r
+}\r
+\r
+/**\r
+ * @brief Return the Main Stack Pointer\r
+ *\r
+ * @return Main Stack Pointer\r
+ *\r
+ * Return the current value of the MSP (main stack pointer)\r
+ * Cortex processor register\r
+ */\r
+uint32_t __get_MSP(void)\r
+{\r
+ __ASM("mrs r0, msp");\r
+ __ASM("bx lr");\r
+}\r
+\r
+/**\r
+ * @brief Set the Main Stack Pointer\r
+ *\r
+ * @param topOfMainStack Main Stack Pointer\r
+ *\r
+ * Assign the value mainStackPointer to the MSP \r
+ * (main stack pointer) Cortex processor register\r
+ */\r
+void __set_MSP(uint32_t topOfMainStack)\r
+{\r
+ __ASM("msr msp, r0");\r
+ __ASM("bx lr");\r
+}\r
+\r
+/**\r
+ * @brief Reverse byte order in unsigned short value\r
+ *\r
+ * @param value value to reverse\r
+ * @return reversed value\r
+ *\r
+ * Reverse byte order in unsigned short value\r
+ */\r
+uint32_t __REV16(uint16_t value)\r
+{\r
+ __ASM("rev16 r0, r0");\r
+ __ASM("bx lr");\r
+}\r
+\r
+/**\r
+ * @brief Reverse bit order of value\r
+ *\r
+ * @param value value to reverse\r
+ * @return reversed value\r
+ *\r
+ * Reverse bit order of value\r
+ */\r
+uint32_t __RBIT(uint32_t value)\r
+{\r
+ __ASM("rbit r0, r0");\r
+ __ASM("bx lr");\r
+}\r
+\r
+/**\r
+ * @brief LDR Exclusive (8 bit)\r
+ *\r
+ * @param *addr address pointer\r
+ * @return value of (*address)\r
+ *\r
+ * Exclusive LDR command for 8 bit values)\r
+ */\r
+uint8_t __LDREXB(uint8_t *addr)\r
+{\r
+ __ASM("ldrexb r0, [r0]");\r
+ __ASM("bx lr"); \r
+}\r
+\r
+/**\r
+ * @brief LDR Exclusive (16 bit)\r
+ *\r
+ * @param *addr address pointer\r
+ * @return value of (*address)\r
+ *\r
+ * Exclusive LDR command for 16 bit values\r
+ */\r
+uint16_t __LDREXH(uint16_t *addr)\r
+{\r
+ __ASM("ldrexh r0, [r0]");\r
+ __ASM("bx lr");\r
+}\r
+\r
+/**\r
+ * @brief LDR Exclusive (32 bit)\r
+ *\r
+ * @param *addr address pointer\r
+ * @return value of (*address)\r
+ *\r
+ * Exclusive LDR command for 32 bit values\r
+ */\r
+uint32_t __LDREXW(uint32_t *addr)\r
+{\r
+ __ASM("ldrex r0, [r0]");\r
+ __ASM("bx lr");\r
+}\r
+\r
+/**\r
+ * @brief STR Exclusive (8 bit)\r
+ *\r
+ * @param value value to store\r
+ * @param *addr address pointer\r
+ * @return successful / failed\r
+ *\r
+ * Exclusive STR command for 8 bit values\r
+ */\r
+uint32_t __STREXB(uint8_t value, uint8_t *addr)\r
+{\r
+ __ASM("strexb r0, r0, [r1]");\r
+ __ASM("bx lr");\r
+}\r
+\r
+/**\r
+ * @brief STR Exclusive (16 bit)\r
+ *\r
+ * @param value value to store\r
+ * @param *addr address pointer\r
+ * @return successful / failed\r
+ *\r
+ * Exclusive STR command for 16 bit values\r
+ */\r
+uint32_t __STREXH(uint16_t value, uint16_t *addr)\r
+{\r
+ __ASM("strexh r0, r0, [r1]");\r
+ __ASM("bx lr");\r
+}\r
+\r
+/**\r
+ * @brief STR Exclusive (32 bit)\r
+ *\r
+ * @param value value to store\r
+ * @param *addr address pointer\r
+ * @return successful / failed\r
+ *\r
+ * Exclusive STR command for 32 bit values\r
+ */\r
+uint32_t __STREXW(uint32_t value, uint32_t *addr)\r
+{\r
+ __ASM("strex r0, r0, [r1]");\r
+ __ASM("bx lr");\r
+}\r
+\r
+#pragma diag_default=Pe940\r
+\r
+\r
+#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/\r
+/* GNU gcc specific functions */\r
+\r
+/**\r
+ * @brief Return the Process Stack Pointer\r
+ *\r
+ * @return ProcessStackPointer\r
+ *\r
+ * Return the actual process stack pointer\r
+ */\r
+uint32_t __get_PSP(void) __attribute__( ( naked ) );\r
+uint32_t __get_PSP(void)\r
+{\r
+ uint32_t result=0;\r
+\r
+ __ASM volatile ("MRS %0, psp\n\t" \r
+ "MOV r0, %0 \n\t"\r
+ "BX lr \n\t" : "=r" (result) );\r
+ return(result);\r
+}\r
+\r
+/**\r
+ * @brief Set the Process Stack Pointer\r
+ *\r
+ * @param topOfProcStack Process Stack Pointer\r
+ *\r
+ * Assign the value ProcessStackPointer to the MSP \r
+ * (process stack pointer) Cortex processor register\r
+ */\r
+void __set_PSP(uint32_t topOfProcStack) __attribute__( ( naked ) );\r
+void __set_PSP(uint32_t topOfProcStack)\r
+{\r
+ __ASM volatile ("MSR psp, %0\n\t"\r
+ "BX lr \n\t" : : "r" (topOfProcStack) );\r
+}\r
+\r
+/**\r
+ * @brief Return the Main Stack Pointer\r
+ *\r
+ * @return Main Stack Pointer\r
+ *\r
+ * Return the current value of the MSP (main stack pointer)\r
+ * Cortex processor register\r
+ */\r
+uint32_t __get_MSP(void) __attribute__( ( naked ) );\r
+uint32_t __get_MSP(void)\r
+{\r
+ uint32_t result=0;\r
+\r
+ __ASM volatile ("MRS %0, msp\n\t" \r
+ "MOV r0, %0 \n\t"\r
+ "BX lr \n\t" : "=r" (result) );\r
+ return(result);\r
+}\r
+\r
+/**\r
+ * @brief Set the Main Stack Pointer\r
+ *\r
+ * @param topOfMainStack Main Stack Pointer\r
+ *\r
+ * Assign the value mainStackPointer to the MSP \r
+ * (main stack pointer) Cortex processor register\r
+ */\r
+void __set_MSP(uint32_t topOfMainStack) __attribute__( ( naked ) );\r
+void __set_MSP(uint32_t topOfMainStack)\r
+{\r
+ __ASM volatile ("MSR msp, %0\n\t"\r
+ "BX lr \n\t" : : "r" (topOfMainStack) );\r
+}\r
+\r
+/**\r
+ * @brief Return the Base Priority value\r
+ *\r
+ * @return BasePriority\r
+ *\r
+ * Return the content of the base priority register\r
+ */\r
+uint32_t __get_BASEPRI(void)\r
+{\r
+ uint32_t result=0;\r
+ \r
+ __ASM volatile ("MRS %0, basepri_max" : "=r" (result) );\r
+ return(result);\r
+}\r
+\r
+/**\r
+ * @brief Set the Base Priority value\r
+ *\r
+ * @param basePri BasePriority\r
+ *\r
+ * Set the base priority register\r
+ */\r
+void __set_BASEPRI(uint32_t value)\r
+{\r
+ __ASM volatile ("MSR basepri, %0" : : "r" (value) );\r
+}\r
+\r
+/**\r
+ * @brief Return the Priority Mask value\r
+ *\r
+ * @return PriMask\r
+ *\r
+ * Return state of the priority mask bit from the priority mask register\r
+ */\r
+uint32_t __get_PRIMASK(void)\r
+{\r
+ uint32_t result=0;\r
+\r
+ __ASM volatile ("MRS %0, primask" : "=r" (result) );\r
+ return(result);\r
+}\r
+\r
+/**\r
+ * @brief Set the Priority Mask value\r
+ *\r
+ * @param priMask PriMask\r
+ *\r
+ * Set the priority mask bit in the priority mask register\r
+ */\r
+void __set_PRIMASK(uint32_t priMask)\r
+{\r
+ __ASM volatile ("MSR primask, %0" : : "r" (priMask) );\r
+}\r
+\r
+/**\r
+ * @brief Return the Fault Mask value\r
+ *\r
+ * @return FaultMask\r
+ *\r
+ * Return the content of the fault mask register\r
+ */\r
+uint32_t __get_FAULTMASK(void)\r
+{\r
+ uint32_t result=0;\r
+ \r
+ __ASM volatile ("MRS %0, faultmask" : "=r" (result) );\r
+ return(result);\r
+}\r
+\r
+/**\r
+ * @brief Set the Fault Mask value\r
+ *\r
+ * @param faultMask faultMask value\r
+ *\r
+ * Set the fault mask register\r
+ */\r
+void __set_FAULTMASK(uint32_t faultMask)\r
+{\r
+ __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );\r
+}\r
+\r
+/**\r
+ * @brief Return the Control Register value\r
+* \r
+* @return Control value\r
+ *\r
+ * Return the content of the control register\r
+ */\r
+uint32_t __get_CONTROL(void)\r
+{\r
+ uint32_t result=0;\r
+\r
+ __ASM volatile ("MRS %0, control" : "=r" (result) );\r
+ return(result);\r
+}\r
+\r
+/**\r
+ * @brief Set the Control Register value\r
+ *\r
+ * @param control Control value\r
+ *\r
+ * Set the control register\r
+ */\r
+void __set_CONTROL(uint32_t control)\r
+{\r
+ __ASM volatile ("MSR control, %0" : : "r" (control) );\r
+}\r
+\r
+\r
+/**\r
+ * @brief Reverse byte order in integer value\r
+ *\r
+ * @param value value to reverse\r
+ * @return reversed value\r
+ *\r
+ * Reverse byte order in integer value\r
+ */\r
+uint32_t __REV(uint32_t value)\r
+{\r
+ uint32_t result=0;\r
+ \r
+ __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );\r
+ return(result);\r
+}\r
+\r
+/**\r
+ * @brief Reverse byte order in unsigned short value\r
+ *\r
+ * @param value value to reverse\r
+ * @return reversed value\r
+ *\r
+ * Reverse byte order in unsigned short value\r
+ */\r
+uint32_t __REV16(uint16_t value)\r
+{\r
+ uint32_t result=0;\r
+ \r
+ __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );\r
+ return(result);\r
+}\r
+\r
+/**\r
+ * @brief Reverse byte order in signed short value with sign extension to integer\r
+ *\r
+ * @param value value to reverse\r
+ * @return reversed value\r
+ *\r
+ * Reverse byte order in signed short value with sign extension to integer\r
+ */\r
+int32_t __REVSH(int16_t value)\r
+{\r
+ uint32_t result=0;\r
+ \r
+ __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );\r
+ return(result);\r
+}\r
+\r
+/**\r
+ * @brief Reverse bit order of value\r
+ *\r
+ * @param value value to reverse\r
+ * @return reversed value\r
+ *\r
+ * Reverse bit order of value\r
+ */\r
+uint32_t __RBIT(uint32_t value)\r
+{\r
+ uint32_t result=0;\r
+ \r
+ __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );\r
+ return(result);\r
+}\r
+\r
+/**\r
+ * @brief LDR Exclusive (8 bit)\r
+ *\r
+ * @param *addr address pointer\r
+ * @return value of (*address)\r
+ *\r
+ * Exclusive LDR command for 8 bit value\r
+ */\r
+uint8_t __LDREXB(uint8_t *addr)\r
+{\r
+ uint8_t result=0;\r
+ \r
+ __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );\r
+ return(result);\r
+}\r
+\r
+/**\r
+ * @brief LDR Exclusive (16 bit)\r
+ *\r
+ * @param *addr address pointer\r
+ * @return value of (*address)\r
+ *\r
+ * Exclusive LDR command for 16 bit values\r
+ */\r
+uint16_t __LDREXH(uint16_t *addr)\r
+{\r
+ uint16_t result=0;\r
+ \r
+ __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );\r
+ return(result);\r
+}\r
+\r
+/**\r
+ * @brief LDR Exclusive (32 bit)\r
+ *\r
+ * @param *addr address pointer\r
+ * @return value of (*address)\r
+ *\r
+ * Exclusive LDR command for 32 bit values\r
+ */\r
+uint32_t __LDREXW(uint32_t *addr)\r
+{\r
+ uint32_t result=0;\r
+ \r
+ __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );\r
+ return(result);\r
+}\r
+\r
+/**\r
+ * @brief STR Exclusive (8 bit)\r
+ *\r
+ * @param value value to store\r
+ * @param *addr address pointer\r
+ * @return successful / failed\r
+ *\r
+ * Exclusive STR command for 8 bit values\r
+ */\r
+uint32_t __STREXB(uint8_t value, uint8_t *addr)\r
+{\r
+ uint32_t result=0;\r
+ \r
+ __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );\r
+ return(result);\r
+}\r
+\r
+/**\r
+ * @brief STR Exclusive (16 bit)\r
+ *\r
+ * @param value value to store\r
+ * @param *addr address pointer\r
+ * @return successful / failed\r
+ *\r
+ * Exclusive STR command for 16 bit values\r
+ */\r
+uint32_t __STREXH(uint16_t value, uint16_t *addr)\r
+{\r
+ uint32_t result=0;\r
+ \r
+ __ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );\r
+ return(result);\r
+}\r
+\r
+/**\r
+ * @brief STR Exclusive (32 bit)\r
+ *\r
+ * @param value value to store\r
+ * @param *addr address pointer\r
+ * @return successful / failed\r
+ *\r
+ * Exclusive STR command for 32 bit values\r
+ */\r
+uint32_t __STREXW(uint32_t value, uint32_t *addr)\r
+{\r
+ uint32_t result=0;\r
+ \r
+ __ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );\r
+ return(result);\r
+}\r
+\r
+\r
+#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/\r
+/* TASKING carm specific functions */\r
+\r
+/*\r
+ * The CMSIS functions have been implemented as intrinsics in the compiler.\r
+ * Please use "carm -?i" to get an up to date list of all instrinsics,\r
+ * Including the CMSIS ones.\r
+ */\r
+\r
+#endif\r
--- /dev/null
+/*
+ * TOPPERS/JSP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Just Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ * Copyright (C) 2010 by TOPPERS/ASP for LPC project
+ * http://sourceforge.jp/projects/toppersasp4lpc/
+ *
+ * 上記著作権者は,Free Software Foundation によって公表されている
+ * GNU General Public License の Version 2 に記述されている条件か,以
+ * 下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェア(本ソフトウェ
+ * アを改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
+ * 利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを再利用可能なバイナリコード(リロケータブルオブ
+ * ジェクトファイルやライブラリなど)の形で利用する場合には,利用
+ * に伴うドキュメント(利用者マニュアルなど)に,上記の著作権表示,
+ * この利用条件および下記の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを再利用不可能なバイナリコードの形または機器に組
+ * み込んだ形で利用する場合には,次のいずれかの条件を満たすこと.
+ * (a) 利用に伴うドキュメント(利用者マニュアルなど)に,上記の著作
+ * 権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 利用の形態を,別に定める方法によって,上記著作権者に報告する
+ * こと.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者を免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者は,
+ * 本ソフトウェアに関して,その適用可能性も含めて,いかなる保証も行わ
+ * ない.また,本ソフトウェアの利用により直接的または間接的に生じたい
+ * かなる損害に関しても,その責任を負わない.
+ *
+ */
+
+/**
+ * \ingroup TOPPERS_ASP
+ * \defgroup TOPPERS_CHIP LPC17XX チップ依存部
+ * \{
+ */
+/**
+ * \file lpc17xx.h
+ * \details NXP LPC17xxシリーズのハードウェア宣言
+ */
+#ifndef TOPPERS_CHIP_LPC17XX_H
+#define TOPPERS_CHIP_LPC17XX_H
+
+#include <sil.h>
+
+/*
+ * CORTEX-M3 CPUの依存部のインクルード
+ */
+#include "arm_m_gcc/arm_m.h"
+#ifndef TOPPERS_MACRO_ONLY
+#include "LPC17xx.h"
+#endif
+
+/**
+ * \brief 割込み番号の最大値
+ * \details
+ * CORTEX-M3のNVIC割り込みコントローラは任意個の割り込み源を持つ。このマクロは、
+ * 最大の割り込み番号の値を表す。
+ */
+#define TMAX_INTNO (16 + 34) // LPC1768の最大割り込み番号は16+32
+
+/**
+ * \brief 割込み優先度のビット幅
+ * \details
+ * CORTEX-M3のNVIC割り込みコントローラはSoC実装者の判断で最大8bitの割り込み優先値を
+ * 持つことができる。TBITW_IPRIは、その優先値を表すフィールドの幅を示す。フィールド幅は
+ * SoC設計者が決める。通常はユーザーズマニュアルなどに書いてある。
+ *
+ * LPC17xxでは5bitである。
+ */
+#define TBITW_IPRI 5 // LPC1768 の優先度は32順位5bit
+
+/**
+ * \brief 割込み優先度ビット幅中のサブ優先度のビット幅
+ * \details
+ * サブ優先度はAIRCRレジスタで指定できる。無指定の場合、0ビットが使われる。
+ */
+#define TBITW_SUBIPRI 0
+
+/**
+ * \brief 割込みベクタ番号定義
+ * \details
+ * NXP提供のCMSIS LPC17xx.hで宣言されているXXXX_IRQnに以下のスクリプトを適応して生成した。irqsは、宣言を格納したファイル名である。
+ * \code
+ * sed -e "s/ //" < irqs | sed -e "s/_.*$//" | awk '{print("#define IRQ_VECTOR_"$1"\t\t(16+"$1"_IRQn)")}' -
+ * \endcode
+ * XXX_IRQnはCMSISの定義により、NVICの割り込み番号である。これはCORTEX-M3の例外番号から16を引いたものである。TOPPERS/ASPのCORTEX-M3実装では
+ * IRQ_VECTOR_XXXXを例外番号として宣言している。つまりXXX_IRQnに16を足す。
+ */
+#define IRQ_VECTOR_WDT (16+WDT_IRQn)
+#define IRQ_VECTOR_TIMER0 (16+TIMER0_IRQn)
+#define IRQ_VECTOR_TIMER1 (16+TIMER1_IRQn)
+#define IRQ_VECTOR_TIMER2 (16+TIMER2_IRQn)
+#define IRQ_VECTOR_TIMER3 (16+TIMER3_IRQn)
+#define IRQ_VECTOR_UART0 (16+UART0_IRQn)
+#define IRQ_VECTOR_UART1 (16+UART1_IRQn)
+#define IRQ_VECTOR_UART2 (16+UART2_IRQn)
+#define IRQ_VECTOR_UART3 (16+UART3_IRQn)
+#define IRQ_VECTOR_PWM1 (16+PWM1_IRQn)
+#define IRQ_VECTOR_I2C0 (16+I2C0_IRQn)
+#define IRQ_VECTOR_I2C1 (16+I2C1_IRQn)
+#define IRQ_VECTOR_I2C2 (16+I2C2_IRQn)
+#define IRQ_VECTOR_SPI (16+SPI_IRQn)
+#define IRQ_VECTOR_SSP0 (16+SSP0_IRQn)
+#define IRQ_VECTOR_SSP1 (16+SSP1_IRQn)
+#define IRQ_VECTOR_PLL0 (16+PLL0_IRQn)
+#define IRQ_VECTOR_RTC (16+RTC_IRQn)
+#define IRQ_VECTOR_EINT0 (16+EINT0_IRQn)
+#define IRQ_VECTOR_EINT1 (16+EINT1_IRQn)
+#define IRQ_VECTOR_EINT2 (16+EINT2_IRQn)
+#define IRQ_VECTOR_EINT3 (16+EINT3_IRQn)
+#define IRQ_VECTOR_ADC (16+ADC_IRQn)
+#define IRQ_VECTOR_BOD (16+BOD_IRQn)
+#define IRQ_VECTOR_USB (16+USB_IRQn)
+#define IRQ_VECTOR_CAN (16+CAN_IRQn)
+#define IRQ_VECTOR_DMA (16+DMA_IRQn)
+#define IRQ_VECTOR_I2S (16+I2S_IRQn)
+#define IRQ_VECTOR_ENET (16+ENET_IRQn)
+#define IRQ_VECTOR_RIT (16+RIT_IRQn)
+#define IRQ_VECTOR_MCPWM (16+MCPWM_IRQn)
+#define IRQ_VECTOR_QEI (16+QEI_IRQn)
+#define IRQ_VECTOR_PLL1 (16+PLL1_IRQn)
+#define IRQ_VECTOR_USBActivity (16+USBActivity_IRQn)
+#define IRQ_VECTOR_CANActivity (16+CANActivity_IRQn)
+
+
+/**
+ * \brief 割込みハンドラ番号定義
+ * \details
+ * NXP提供のCMSIS LPC17xx.hで宣言されているXXXX_IRQnに以下のスクリプトを適応して生成した。irqsは、宣言を格納したファイル名である。
+ * \code
+ * sed -e "s/ //" < irqs | sed -e "s/_.*$//" | awk '{print("#define INHNO_"$1"\t\tIRQ_VECTOR_"$1)}' -
+ * \endcode
+ * XXX_IRQnはCMSISの定義により、NVICの割り込み番号である。これはCORTEX-M3の例外番号から16を引いたものである。TOPPERS/ASPのCORTEX-M3実装では
+ * INHNO_XXXXを例外番号として宣言している。つまりIRQ_VECTOR_XXXと同じ値である
+ */
+
+#define INHNO_WDT IRQ_VECTOR_WDT
+#define INHNO_TIMER0 IRQ_VECTOR_TIMER0
+#define INHNO_TIMER1 IRQ_VECTOR_TIMER1
+#define INHNO_TIMER2 IRQ_VECTOR_TIMER2
+#define INHNO_TIMER3 IRQ_VECTOR_TIMER3
+#define INHNO_UART0 IRQ_VECTOR_UART0
+#define INHNO_UART1 IRQ_VECTOR_UART1
+#define INHNO_UART2 IRQ_VECTOR_UART2
+#define INHNO_UART3 IRQ_VECTOR_UART3
+#define INHNO_PWM1 IRQ_VECTOR_PWM1
+#define INHNO_I2C0 IRQ_VECTOR_I2C0
+#define INHNO_I2C1 IRQ_VECTOR_I2C1
+#define INHNO_I2C2 IRQ_VECTOR_I2C2
+#define INHNO_SPI IRQ_VECTOR_SPI
+#define INHNO_SSP0 IRQ_VECTOR_SSP0
+#define INHNO_SSP1 IRQ_VECTOR_SSP1
+#define INHNO_PLL0 IRQ_VECTOR_PLL0
+#define INHNO_RTC IRQ_VECTOR_RTC
+#define INHNO_EINT0 IRQ_VECTOR_EINT0
+#define INHNO_EINT1 IRQ_VECTOR_EINT1
+#define INHNO_EINT2 IRQ_VECTOR_EINT2
+#define INHNO_EINT3 IRQ_VECTOR_EINT3
+#define INHNO_ADC IRQ_VECTOR_ADC
+#define INHNO_BOD IRQ_VECTOR_BOD
+#define INHNO_USB IRQ_VECTOR_USB
+#define INHNO_CAN IRQ_VECTOR_CAN
+#define INHNO_DMA IRQ_VECTOR_DMA
+#define INHNO_I2S IRQ_VECTOR_I2S
+#define INHNO_ENET IRQ_VECTOR_ENET
+#define INHNO_RIT IRQ_VECTOR_RIT
+#define INHNO_MCPWM IRQ_VECTOR_MCPWM
+#define INHNO_QEI IRQ_VECTOR_QEI
+#define INHNO_PLL1 IRQ_VECTOR_PLL1
+#define INHNO_USBActivity IRQ_VECTOR_USBActivity
+#define INHNO_CANActivity IRQ_VECTOR_CANActivity
+
+/**
+ * \brief TOPPERS/ASP割込み番号定義
+ * \details
+ * NXP提供のCMSIS LPC17xx.hで宣言されているXXXX_IRQnに以下のスクリプトを適応して生成した。irqsは、宣言を格納したファイル名である。
+ * \code
+ * sed -e "s/ //" < irqs | sed -e "s/_.*$//" | awk '{print("#define INTNO_"$1"\t\tIRQ_VECTOR_"$1)}' -
+ * \endcode
+ * XXX_IRQnはCMSISの定義により、NVICの割り込み番号である。これはCORTEX-M3の例外番号から16を引いたものである。TOPPERS/ASPのCORTEX-M3実装では
+ * INTNO_XXXXを例外番号として宣言している。つまりIRQ_VECTOR_XXXと同じ値である
+ */
+#define INTNO_WDT IRQ_VECTOR_WDT
+#define INTNO_TIMER0 IRQ_VECTOR_TIMER0
+#define INTNO_TIMER1 IRQ_VECTOR_TIMER1
+#define INTNO_TIMER2 IRQ_VECTOR_TIMER2
+#define INTNO_TIMER3 IRQ_VECTOR_TIMER3
+#define INTNO_UART0 IRQ_VECTOR_UART0
+#define INTNO_UART1 IRQ_VECTOR_UART1
+#define INTNO_UART2 IRQ_VECTOR_UART2
+#define INTNO_UART3 IRQ_VECTOR_UART3
+#define INTNO_PWM1 IRQ_VECTOR_PWM1
+#define INTNO_I2C0 IRQ_VECTOR_I2C0
+#define INTNO_I2C1 IRQ_VECTOR_I2C1
+#define INTNO_I2C2 IRQ_VECTOR_I2C2
+#define INTNO_SPI IRQ_VECTOR_SPI
+#define INTNO_SSP0 IRQ_VECTOR_SSP0
+#define INTNO_SSP1 IRQ_VECTOR_SSP1
+#define INTNO_PLL0 IRQ_VECTOR_PLL0
+#define INTNO_RTC IRQ_VECTOR_RTC
+#define INTNO_EINT0 IRQ_VECTOR_EINT0
+#define INTNO_EINT1 IRQ_VECTOR_EINT1
+#define INTNO_EINT2 IRQ_VECTOR_EINT2
+#define INTNO_EINT3 IRQ_VECTOR_EINT3
+#define INTNO_ADC IRQ_VECTOR_ADC
+#define INTNO_BOD IRQ_VECTOR_BOD
+#define INTNO_USB IRQ_VECTOR_USB
+#define INTNO_CAN IRQ_VECTOR_CAN
+#define INTNO_DMA IRQ_VECTOR_DMA
+#define INTNO_I2S IRQ_VECTOR_I2S
+#define INTNO_ENET IRQ_VECTOR_ENET
+#define INTNO_RIT IRQ_VECTOR_RIT
+#define INTNO_MCPWM IRQ_VECTOR_MCPWM
+#define INTNO_QEI IRQ_VECTOR_QEI
+#define INTNO_PLL1 IRQ_VECTOR_PLL1
+#define INTNO_USBActivity IRQ_VECTOR_USBActivity
+#define INTNO_CANActivity IRQ_VECTOR_CANActivity
+
+#ifndef TOPPERS_MACRO_ONLY
+
+#endif /* TOPPERS_MACRO_ONLY */
+#endif /* TOPPERS_CHIP_LPC17XX_H */
+
+/**
+ * \}
+ */
--- /dev/null
+/**************************************************************************//**\r
+ * @file system_LPC17xx.c\r
+ * @brief CMSIS Cortex-M3 Device Peripheral Access Layer Source File\r
+ * for the NXP LPC17xx Device Series\r
+ * @version V1.03\r
+ * @date 07. October 2009\r
+ *\r
+ * @note\r
+ * Copyright (C) 2009 ARM Limited. All rights reserved.\r
+ *\r
+ * @par\r
+ * ARM Limited (ARM) is supplying this software for use with Cortex-M\r
+ * processor based microcontrollers. This file can be freely distributed\r
+ * within development tools that are supporting such ARM based processors.\r
+ *\r
+ * @par\r
+ * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED\r
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.\r
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR\r
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.\r
+ *\r
+ ******************************************************************************/\r
+\r
+\r
+#include <stdint.h>\r
+#include "LPC17xx.h"\r
+\r
+/*\r
+//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------\r
+*/\r
+\r
+/*--------------------- Clock Configuration ----------------------------------\r
+//\r
+// <e> Clock Configuration\r
+// <h> System Controls and Status Register (SCS)\r
+// <o1.4> OSCRANGE: Main Oscillator Range Select\r
+// <0=> 1 MHz to 20 MHz\r
+// <1=> 15 MHz to 24 MHz\r
+// <e1.5> OSCEN: Main Oscillator Enable\r
+// </e>\r
+// </h>\r
+//\r
+// <h> Clock Source Select Register (CLKSRCSEL)\r
+// <o2.0..1> CLKSRC: PLL Clock Source Selection\r
+// <0=> Internal RC oscillator\r
+// <1=> Main oscillator\r
+// <2=> RTC oscillator\r
+// </h>\r
+//\r
+// <e3> PLL0 Configuration (Main PLL)\r
+// <h> PLL0 Configuration Register (PLL0CFG)\r
+// <i> F_cco0 = (2 * M * F_in) / N\r
+// <i> F_in must be in the range of 32 kHz to 50 MHz\r
+// <i> F_cco0 must be in the range of 275 MHz to 550 MHz\r
+// <o4.0..14> MSEL: PLL Multiplier Selection\r
+// <6-32768><#-1>\r
+// <i> M Value\r
+// <o4.16..23> NSEL: PLL Divider Selection\r
+// <1-256><#-1>\r
+// <i> N Value\r
+// </h>\r
+// </e>\r
+//\r
+// <e5> PLL1 Configuration (USB PLL)\r
+// <h> PLL1 Configuration Register (PLL1CFG)\r
+// <i> F_usb = M * F_osc or F_usb = F_cco1 / (2 * P)\r
+// <i> F_cco1 = F_osc * M * 2 * P\r
+// <i> F_cco1 must be in the range of 156 MHz to 320 MHz\r
+// <o6.0..4> MSEL: PLL Multiplier Selection\r
+// <1-32><#-1>\r
+// <i> M Value (for USB maximum value is 4)\r
+// <o6.5..6> PSEL: PLL Divider Selection\r
+// <0=> 1\r
+// <1=> 2\r
+// <2=> 4\r
+// <3=> 8\r
+// <i> P Value\r
+// </h>\r
+// </e>\r
+//\r
+// <h> CPU Clock Configuration Register (CCLKCFG)\r
+// <o7.0..7> CCLKSEL: Divide Value for CPU Clock from PLL0\r
+// <3-256><#-1>\r
+// </h>\r
+//\r
+// <h> USB Clock Configuration Register (USBCLKCFG)\r
+// <o8.0..3> USBSEL: Divide Value for USB Clock from PLL0\r
+// <0-15>\r
+// <i> Divide is USBSEL + 1\r
+// </h>\r
+//\r
+// <h> Peripheral Clock Selection Register 0 (PCLKSEL0)\r
+// <o9.0..1> PCLK_WDT: Peripheral Clock Selection for WDT\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// <o9.2..3> PCLK_TIMER0: Peripheral Clock Selection for TIMER0\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// <o9.4..5> PCLK_TIMER1: Peripheral Clock Selection for TIMER1\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// <o9.6..7> PCLK_UART0: Peripheral Clock Selection for UART0\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// <o9.8..9> PCLK_UART1: Peripheral Clock Selection for UART1\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// <o9.12..13> PCLK_PWM1: Peripheral Clock Selection for PWM1\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// <o9.14..15> PCLK_I2C0: Peripheral Clock Selection for I2C0\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// <o9.16..17> PCLK_SPI: Peripheral Clock Selection for SPI\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// <o9.20..21> PCLK_SSP1: Peripheral Clock Selection for SSP1\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// <o9.22..23> PCLK_DAC: Peripheral Clock Selection for DAC\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// <o9.24..25> PCLK_ADC: Peripheral Clock Selection for ADC\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// <o9.26..27> PCLK_CAN1: Peripheral Clock Selection for CAN1\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 6\r
+// <o9.28..29> PCLK_CAN2: Peripheral Clock Selection for CAN2\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 6\r
+// <o9.30..31> PCLK_ACF: Peripheral Clock Selection for ACF\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 6\r
+// </h>\r
+//\r
+// <h> Peripheral Clock Selection Register 1 (PCLKSEL1)\r
+// <o10.0..1> PCLK_QEI: Peripheral Clock Selection for the Quadrature Encoder Interface\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// <o10.2..3> PCLK_GPIO: Peripheral Clock Selection for GPIOs\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// <o10.4..5> PCLK_PCB: Peripheral Clock Selection for the Pin Connect Block\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// <o10.6..7> PCLK_I2C1: Peripheral Clock Selection for I2C1\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// <o10.10..11> PCLK_SSP0: Peripheral Clock Selection for SSP0\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// <o10.12..13> PCLK_TIMER2: Peripheral Clock Selection for TIMER2\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// <o10.14..15> PCLK_TIMER3: Peripheral Clock Selection for TIMER3\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// <o10.16..17> PCLK_UART2: Peripheral Clock Selection for UART2\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// <o10.18..19> PCLK_UART3: Peripheral Clock Selection for UART3\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// <o10.20..21> PCLK_I2C2: Peripheral Clock Selection for I2C2\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// <o10.22..23> PCLK_I2S: Peripheral Clock Selection for I2S\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// <o10.26..27> PCLK_RIT: Peripheral Clock Selection for the Repetitive Interrupt Timer\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// <o10.28..29> PCLK_SYSCON: Peripheral Clock Selection for the System Control Block\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// <o10.30..31> PCLK_MC: Peripheral Clock Selection for the Motor Control PWM\r
+// <0=> Pclk = Cclk / 4\r
+// <1=> Pclk = Cclk\r
+// <2=> Pclk = Cclk / 2\r
+// <3=> Pclk = Hclk / 8\r
+// </h>\r
+//\r
+// <h> Power Control for Peripherals Register (PCONP)\r
+// <o11.1> PCTIM0: Timer/Counter 0 power/clock enable\r
+// <o11.2> PCTIM1: Timer/Counter 1 power/clock enable\r
+// <o11.3> PCUART0: UART 0 power/clock enable\r
+// <o11.4> PCUART1: UART 1 power/clock enable\r
+// <o11.6> PCPWM1: PWM 1 power/clock enable\r
+// <o11.7> PCI2C0: I2C interface 0 power/clock enable\r
+// <o11.8> PCSPI: SPI interface power/clock enable\r
+// <o11.9> PCRTC: RTC power/clock enable\r
+// <o11.10> PCSSP1: SSP interface 1 power/clock enable\r
+// <o11.12> PCAD: A/D converter power/clock enable\r
+// <o11.13> PCCAN1: CAN controller 1 power/clock enable\r
+// <o11.14> PCCAN2: CAN controller 2 power/clock enable\r
+// <o11.15> PCGPIO: GPIOs power/clock enable\r
+// <o11.16> PCRIT: Repetitive interrupt timer power/clock enable\r
+// <o11.17> PCMC: Motor control PWM power/clock enable\r
+// <o11.18> PCQEI: Quadrature encoder interface power/clock enable\r
+// <o11.19> PCI2C1: I2C interface 1 power/clock enable\r
+// <o11.21> PCSSP0: SSP interface 0 power/clock enable\r
+// <o11.22> PCTIM2: Timer 2 power/clock enable\r
+// <o11.23> PCTIM3: Timer 3 power/clock enable\r
+// <o11.24> PCUART2: UART 2 power/clock enable\r
+// <o11.25> PCUART3: UART 3 power/clock enable\r
+// <o11.26> PCI2C2: I2C interface 2 power/clock enable\r
+// <o11.27> PCI2S: I2S interface power/clock enable\r
+// <o11.29> PCGPDMA: GP DMA function power/clock enable\r
+// <o11.30> PCENET: Ethernet block power/clock enable\r
+// <o11.31> PCUSB: USB interface power/clock enable\r
+// </h>\r
+//\r
+// <h> Clock Output Configuration Register (CLKOUTCFG)\r
+// <o12.0..3> CLKOUTSEL: Selects clock source for CLKOUT\r
+// <0=> CPU clock\r
+// <1=> Main oscillator\r
+// <2=> Internal RC oscillator\r
+// <3=> USB clock\r
+// <4=> RTC oscillator\r
+// <o12.4..7> CLKOUTDIV: Selects clock divider for CLKOUT\r
+// <1-16><#-1>\r
+// <o12.8> CLKOUT_EN: CLKOUT enable control\r
+// </h>\r
+//\r
+// </e>\r
+*/\r
+#define CLOCK_SETUP 1\r
+#define SCS_Val 0x00000020\r
+#define CLKSRCSEL_Val 0x00000001\r
+#define PLL0_SETUP 1\r
+#define PLL0CFG_Val 0x00050063\r
+#define PLL1_SETUP 1\r
+#define PLL1CFG_Val 0x00000023\r
+#define CCLKCFG_Val 0x00000003\r
+#define USBCLKCFG_Val 0x00000000\r
+#define PCLKSEL0_Val 0x00000000\r
+#define PCLKSEL1_Val 0x00000000\r
+#define PCONP_Val 0x042887DE\r
+#define CLKOUTCFG_Val 0x00000000\r
+\r
+\r
+/*--------------------- Flash Accelerator Configuration ----------------------\r
+//\r
+// <e> Flash Accelerator Configuration\r
+// <o1.0..11> Reserved\r
+// <o1.12..15> FLASHTIM: Flash Access Time\r
+// <0=> 1 CPU clock (for CPU clock up to 20 MHz)\r
+// <1=> 2 CPU clocks (for CPU clock up to 40 MHz)\r
+// <2=> 3 CPU clocks (for CPU clock up to 60 MHz)\r
+// <3=> 4 CPU clocks (for CPU clock up to 80 MHz)\r
+// <4=> 5 CPU clocks (for CPU clock up to 100 MHz)\r
+// <5=> 6 CPU clocks (for any CPU clock)\r
+// </e>\r
+*/\r
+#define FLASH_SETUP 1\r
+#define FLASHCFG_Val 0x0000303A\r
+\r
+/*\r
+//-------- <<< end of configuration section >>> ------------------------------\r
+*/\r
+\r
+/*----------------------------------------------------------------------------\r
+ Check the register settings\r
+ *----------------------------------------------------------------------------*/\r
+#define CHECK_RANGE(val, min, max) ((val < min) || (val > max))\r
+#define CHECK_RSVD(val, mask) (val & mask)\r
+\r
+/* Clock Configuration -------------------------------------------------------*/\r
+#if (CHECK_RSVD((SCS_Val), ~0x00000030))\r
+ #error "SCS: Invalid values of reserved bits!"\r
+#endif\r
+\r
+#if (CHECK_RANGE((CLKSRCSEL_Val), 0, 2))\r
+ #error "CLKSRCSEL: Value out of range!"\r
+#endif\r
+\r
+#if (CHECK_RSVD((PLL0CFG_Val), ~0x00FF7FFF))\r
+ #error "PLL0CFG: Invalid values of reserved bits!"\r
+#endif\r
+\r
+#if (CHECK_RSVD((PLL1CFG_Val), ~0x0000007F))\r
+ #error "PLL1CFG: Invalid values of reserved bits!"\r
+#endif\r
+\r
+#if ((CCLKCFG_Val != 0) && (((CCLKCFG_Val - 1) % 2)))\r
+ #error "CCLKCFG: CCLKSEL field does not contain only odd values or 0!"\r
+#endif\r
+\r
+#if (CHECK_RSVD((USBCLKCFG_Val), ~0x0000000F))\r
+ #error "USBCLKCFG: Invalid values of reserved bits!"\r
+#endif\r
+\r
+#if (CHECK_RSVD((PCLKSEL0_Val), 0x000C0C00))\r
+ #error "PCLKSEL0: Invalid values of reserved bits!"\r
+#endif\r
+\r
+#if (CHECK_RSVD((PCLKSEL1_Val), 0x03000300))\r
+ #error "PCLKSEL1: Invalid values of reserved bits!"\r
+#endif\r
+\r
+#if (CHECK_RSVD((PCONP_Val), 0x10100821))\r
+ #error "PCONP: Invalid values of reserved bits!"\r
+#endif\r
+\r
+#if (CHECK_RSVD((CLKOUTCFG_Val), ~0x000001FF))\r
+ #error "CLKOUTCFG: Invalid values of reserved bits!"\r
+#endif\r
+\r
+/* Flash Accelerator Configuration -------------------------------------------*/\r
+#if (CHECK_RSVD((FLASHCFG_Val), ~0x0000F07F))\r
+ #error "FLASHCFG: Invalid values of reserved bits!"\r
+#endif\r
+\r
+\r
+/*----------------------------------------------------------------------------\r
+ DEFINES\r
+ *----------------------------------------------------------------------------*/\r
+\r
+/*----------------------------------------------------------------------------\r
+ Define clocks\r
+ *----------------------------------------------------------------------------*/\r
+#define XTAL (12000000UL) /* Oscillator frequency */\r
+#define OSC_CLK ( XTAL) /* Main oscillator frequency */\r
+#define RTC_CLK ( 32000UL) /* RTC oscillator frequency */\r
+#define IRC_OSC ( 4000000UL) /* Internal RC oscillator frequency */\r
+\r
+\r
+/* F_cco0 = (2 * M * F_in) / N */\r
+#define __M (((PLL0CFG_Val ) & 0x7FFF) + 1)\r
+#define __N (((PLL0CFG_Val >> 16) & 0x00FF) + 1)\r
+#define __FCCO(__F_IN) ((2 * __M * __F_IN) / __N)\r
+#define __CCLK_DIV (((CCLKCFG_Val ) & 0x00FF) + 1)\r
+\r
+/* Determine core clock frequency according to settings */\r
+ #if (PLL0_SETUP)\r
+ #if ((CLKSRCSEL_Val & 0x03) == 1)\r
+ #define __CORE_CLK (__FCCO(OSC_CLK) / __CCLK_DIV)\r
+ #elif ((CLKSRCSEL_Val & 0x03) == 2)\r
+ #define __CORE_CLK (__FCCO(RTC_CLK) / __CCLK_DIV)\r
+ #else\r
+ #define __CORE_CLK (__FCCO(IRC_OSC) / __CCLK_DIV)\r
+ #endif\r
+ #else\r
+ #if ((CLKSRCSEL_Val & 0x03) == 1)\r
+ #define __CORE_CLK (OSC_CLK / __CCLK_DIV)\r
+ #elif ((CLKSRCSEL_Val & 0x03) == 2)\r
+ #define __CORE_CLK (RTC_CLK / __CCLK_DIV)\r
+ #else\r
+ #define __CORE_CLK (IRC_OSC / __CCLK_DIV)\r
+ #endif\r
+ #endif\r
+\r
+\r
+/*----------------------------------------------------------------------------\r
+ Clock Variable definitions\r
+ *----------------------------------------------------------------------------*/\r
+uint32_t SystemCoreClock = __CORE_CLK;/*!< System Clock Frequency (Core Clock)*/\r
+\r
+\r
+/*----------------------------------------------------------------------------\r
+ Clock functions\r
+ *----------------------------------------------------------------------------*/\r
+void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */\r
+{\r
+ /* Determine clock frequency according to clock register values */\r
+ if (((LPC_SC->PLL0STAT >> 24) & 3) == 3) { /* If PLL0 enabled and connected */\r
+ switch (LPC_SC->CLKSRCSEL & 0x03) {\r
+ case 0: /* Int. RC oscillator => PLL0 */\r
+ case 3: /* Reserved, default to Int. RC */\r
+ SystemCoreClock = (IRC_OSC *\r
+ ((2 * ((LPC_SC->PLL0STAT & 0x7FFF) + 1))) /\r
+ (((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1) /\r
+ ((LPC_SC->CCLKCFG & 0xFF)+ 1));\r
+ break;\r
+ case 1: /* Main oscillator => PLL0 */\r
+ SystemCoreClock = (OSC_CLK *\r
+ ((2 * ((LPC_SC->PLL0STAT & 0x7FFF) + 1))) /\r
+ (((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1) /\r
+ ((LPC_SC->CCLKCFG & 0xFF)+ 1));\r
+ break;\r
+ case 2: /* RTC oscillator => PLL0 */\r
+ SystemCoreClock = (RTC_CLK *\r
+ ((2 * ((LPC_SC->PLL0STAT & 0x7FFF) + 1))) /\r
+ (((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1) /\r
+ ((LPC_SC->CCLKCFG & 0xFF)+ 1));\r
+ break;\r
+ }\r
+ } else {\r
+ switch (LPC_SC->CLKSRCSEL & 0x03) {\r
+ case 0: /* Int. RC oscillator => PLL0 */\r
+ case 3: /* Reserved, default to Int. RC */\r
+ SystemCoreClock = IRC_OSC / ((LPC_SC->CCLKCFG & 0xFF)+ 1);\r
+ break;\r
+ case 1: /* Main oscillator => PLL0 */\r
+ SystemCoreClock = OSC_CLK / ((LPC_SC->CCLKCFG & 0xFF)+ 1);\r
+ break;\r
+ case 2: /* RTC oscillator => PLL0 */\r
+ SystemCoreClock = RTC_CLK / ((LPC_SC->CCLKCFG & 0xFF)+ 1);\r
+ break;\r
+ }\r
+ }\r
+\r
+}\r
+/* Exported types --------------------------------------------------------------*/\r
+/* Exported constants --------------------------------------------------------*/\r
+//extern unsigned long _sidata; /* start address for the initialization values of the .data section. defined in linker script */\r
+//extern unsigned long _sdata; /* start address for the .data section. defined in linker script */\r
+//extern unsigned long _edata; /* end address for the .data section. defined in linker script */\r
+//\r
+//extern unsigned long _sbss; /* start address for the .bss section. defined in linker script */\r
+//extern unsigned long _ebss; /* end address for the .bss section. defined in linker script */\r
+\r
+//void _init(void)\r
+//{\r
+// unsigned long *pulSrc, *pulDest;\r
+//\r
+// //\r
+// // Copy the data segment initializers from flash to SRAM in ROM mode\r
+// //\r
+//#if (__RAM_MODE__==0)\r
+// pulSrc = &_sidata;\r
+// for(pulDest = &_sdata; pulDest < &_edata; )\r
+// {\r
+// *(pulDest++) = *(pulSrc++);\r
+// }\r
+//#endif\r
+//\r
+//\r
+// //\r
+// // Zero fill the bss segment.\r
+// //\r
+// for(pulDest = &_sbss; pulDest < &_ebss; )\r
+// {\r
+// *(pulDest++) = 0;\r
+// }\r
+//}\r
+\r
+/**\r
+ * Initialize the system\r
+ *\r
+ * @param none\r
+ * @return none\r
+ *\r
+ * @brief Setup the microcontroller system.\r
+ * Initialize the System.\r
+ */\r
+void SystemInit (void)\r
+{\r
+\r
+#if (CLOCK_SETUP) /* Clock Setup */\r
+ LPC_SC->SCS = SCS_Val;\r
+ if (SCS_Val & (1 << 5)) { /* If Main Oscillator is enabled */\r
+ while ((LPC_SC->SCS & (1<<6)) == 0);/* Wait for Oscillator to be ready */\r
+ }\r
+\r
+ LPC_SC->CCLKCFG = CCLKCFG_Val; /* Setup Clock Divider */\r
+ LPC_SC->PCLKSEL0 = PCLKSEL0_Val; /* Peripheral Clock Selection */\r
+ LPC_SC->PCLKSEL1 = PCLKSEL1_Val;\r
+\r
+#if (PLL0_SETUP)\r
+ LPC_SC->CLKSRCSEL = CLKSRCSEL_Val; /* Select Clock Source for PLL0 */\r
+\r
+ LPC_SC->PLL0CFG = PLL0CFG_Val; /* configure PLL0 */\r
+ LPC_SC->PLL0FEED = 0xAA;\r
+ LPC_SC->PLL0FEED = 0x55;\r
+\r
+ LPC_SC->PLL0CON = 0x01; /* PLL0 Enable */\r
+ LPC_SC->PLL0FEED = 0xAA;\r
+ LPC_SC->PLL0FEED = 0x55;\r
+ while (!(LPC_SC->PLL0STAT & (1<<26)));/* Wait for PLOCK0 */\r
+\r
+ LPC_SC->PLL0CON = 0x03; /* PLL0 Enable & Connect */\r
+ LPC_SC->PLL0FEED = 0xAA;\r
+ LPC_SC->PLL0FEED = 0x55;\r
+ while (!(LPC_SC->PLL0STAT & ((1<<25) | (1<<24))));/* Wait for PLLC0_STAT & PLLE0_STAT */\r
+#endif\r
+\r
+#if (PLL1_SETUP)\r
+ LPC_SC->PLL1CFG = PLL1CFG_Val;\r
+ LPC_SC->PLL1FEED = 0xAA;\r
+ LPC_SC->PLL1FEED = 0x55;\r
+\r
+ LPC_SC->PLL1CON = 0x01; /* PLL1 Enable */\r
+ LPC_SC->PLL1FEED = 0xAA;\r
+ LPC_SC->PLL1FEED = 0x55;\r
+ while (!(LPC_SC->PLL1STAT & (1<<10)));/* Wait for PLOCK1 */\r
+\r
+ LPC_SC->PLL1CON = 0x03; /* PLL1 Enable & Connect */\r
+ LPC_SC->PLL1FEED = 0xAA;\r
+ LPC_SC->PLL1FEED = 0x55;\r
+ while (!(LPC_SC->PLL1STAT & ((1<< 9) | (1<< 8))));/* Wait for PLLC1_STAT & PLLE1_STAT */\r
+#else\r
+ LPC_SC->USBCLKCFG = USBCLKCFG_Val; /* Setup USB Clock Divider */\r
+#endif\r
+ LPC_SC->PCONP = PCONP_Val; /* Power Control for Peripherals */\r
+\r
+ LPC_SC->CLKOUTCFG = CLKOUTCFG_Val; /* Clock Output Configuration */\r
+#endif\r
+\r
+#if (FLASH_SETUP == 1) /* Flash Accelerator Setup */\r
+ LPC_SC->FLASHCFG = FLASHCFG_Val;\r
+#endif\r
+}\r
--- /dev/null
+#! /usr/bin/perl
+#
+# TOPPERS Software
+# Toyohashi Open Platform for Embedded Real-Time Systems/
+#
+# Copyright (C) 2001-2003 by Embedded and Real-Time Systems Laboratory
+# Toyohashi Univ. of Technology, JAPAN
+# Copyright (C) 2006-2009 by Embedded and Real-Time Systems Laboratory
+# Graduate School of Information Science, Nagoya Univ., JAPAN
+#
+# 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+# スコード中に含まれていること.
+# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+# の無保証規定を掲載すること.
+# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+# と.
+# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+# 作権表示,この利用条件および下記の無保証規定を掲載すること.
+# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+# 報告すること.
+# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+# 免責すること.
+#
+# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+# の責任を負わない.
+#
+# @(#) $Id: configure 1733 2010-02-03 03:50:52Z ertl-hiro $
+#
+
+require "getopt.pl";
+
+# オプションの定義
+#
+# -T <target> ターゲット名(必須)
+# -A <applname> アプリケーションプログラム名(デフォルトはsample1)
+# -a <appldir> アプリケーションのディレクトリ名
+# -U <applobjs> 他のアプリケーションプログラムファイル
+# (.oファイル名で指定.複数指定可)
+# -L <kernel_lib> カーネルライブラリ(libkernel.a)のディレクトリ名
+# (省略した場合,カーネルライブラリもmakeする)
+# -f カーネルを関数単位でコンパイルするかどうかの指定
+# -D <srcdir> カーネル等のソースの置かれているディレクトリ
+# -l <srclang> プログラミング言語(現時点ではcとc++のみサポート)
+# -t <templatedir> テンプレートディレクトリの指定(デフォルトはsample)
+# -m <makefile> テンプレートMakefile名の指定(デフォルトはMakefile)
+# -d <dbgenv> 実行環境の名称
+# -r トレースログ記録のサンプルコードを使用するかどうか
+# の指定
+# -p <perl> perlのパス名(明示的に指定する場合)
+# -g <cfg> コンフィギュレータ(cfg)のパス名
+
+# 使用例(1)
+#
+# % ../configure -T dve68k_gcc -D GDB_STUB -A perf1 -a ../test -U histogram.o
+#
+# 使用例(2)
+#
+# % ../configure -T macosx_gcc -L .
+# アプリケーションプログラムは sample1 になる.
+
+#
+# オプションの処理
+#
+do Getopt("TAaULDltmdpg");
+
+#
+# 変数の初期化
+#
+
+$target = $opt_T;
+$applname = $opt_A ? $opt_A : "sample1";
+$appldir = $opt_a ? $opt_a : "";
+$applobjs = $opt_U ? $opt_U : "";
+$kernel_lib = $opt_L ? $opt_L : "";
+$kernel_funcobjs = $opt_f ? "true" : "";
+$srclang = $opt_l ? $opt_l : "c";
+$makefile = $opt_m ? $opt_m : "Makefile";
+$dbgenv = $opt_d ? "TOPPERS_".$opt_d : "";
+$enable_trace = $opt_r ? "true" : "";
+
+#
+# オブジェクトファイル名の拡張子を返す
+#
+sub get_objext {
+ local(@uname);
+
+ use POSIX;
+ @uname = do uname();
+ if ($uname[0] =~ /^cygwin/i) {
+ return("exe");
+ }
+ else {
+ return("");
+ }
+}
+
+#
+# プログラムの場所を検索する
+#
+sub get_path {
+ local($progname, @pathlist) = @_;
+ local($path);
+
+ foreach $path (@pathlist) {
+ if (-x $path."/".$progname) {
+ return($path."/".$progname);
+ }
+ }
+ return("");
+}
+
+#
+# ファイルを変換する
+#
+sub convert {
+ local($infile, $outfile) = @_;
+ local($line, $varname, $varval);
+
+ print STDERR "configure: Generating $outfile from $infile.\n";
+ if (-f $outfile) {
+ print STDERR "configure: $outfile exists.",
+ " Save as $outfile.bak.\n";
+ rename($outfile, $outfile.".bak");
+ }
+ unless (open(INFILE, $infile)) {
+ print STDERR "configure: can't open $infile\n";
+ exit(1);
+ }
+ unless (open(OUTFILE, "> ".$outfile)) {
+ print STDERR "configure: can't open $outfile\n";
+ exit(1);
+ }
+
+ while ($line = <INFILE>) {
+ chop $line;
+ while ($line =~ /^(.*)\@\(([A-Za-z_]+)\)(.*)$/) {
+ $line = $1.$vartable{$2}.$3;
+ }
+ print OUTFILE $line,"\n";
+ }
+
+ close(INFILE);
+ close(OUTFILE);
+}
+
+#
+# サンプルを見つけてファイルを生成する
+#
+sub generate {
+ local($file, $mandatory) = @_;
+ local($path);
+
+ if ($sys) {
+ $path = $templatedir."/".$file.".".$cpu."-".$sys;
+ if (-f $path) {
+ do convert($path, $file);
+ return;
+ }
+
+ $path = $templatedir."/".$file.".".$sys;
+ if (-f $path) {
+ do convert($path, $file);
+ return;
+ }
+ }
+
+ $path = $templatedir."/".$file.".".$cpu;
+ if (-f $path) {
+ do convert($path, $file);
+ return;
+ }
+
+ $path = $templatedir."/".$file;
+ if ($mandatory || -f $path) {
+ do convert($path, $file);
+ }
+}
+
+#
+# ソースディレクトリ名を取り出す
+#
+$pwd = `pwd`; chop $pwd;
+if ($opt_D) {
+ $srcabsdir = $srcdir = $opt_D;
+}
+elsif ($0 =~ /(.*)\/configure/) {
+ $srcdir = $1;
+ if ($srcdir =~ /^\//) {
+ $srcabsdir = $srcdir;
+ }
+ else {
+ $srcabsdir = $pwd."/".$srcdir;
+ }
+}
+else {
+ $srcabsdir = $srcdir = $pwd;
+}
+
+$perl = $opt_p ? $opt_p : do get_path("perl", ("/usr/local/bin", "/usr/bin"));
+$cfg = $opt_g ? $opt_g : "\$(SRCDIR)/cfg/cfg/cfg";
+$cfgfile = $opt_g ? $opt_g : $srcdir."/cfg/cfg/cfg";
+$templatedir = $opt_t ? $opt_t : $srcdir."/sample";
+
+#
+# -Tオプションの確認
+#
+unless ($opt_T) {
+ print STDERR "configure: -T option is mandatory\n";
+ print STDERR "Installed targets are:\n";
+ foreach $targetname (<$srcdir/target/[a-zA-Z1-9]*>) {
+ $targetname =~ s|$srcdir/target/||;
+ print STDERR "\t$targetname\n";
+ }
+ exit(1);
+}
+
+#
+# 変数テーブルの作成
+#
+%vartable = ();
+$vartable{"TARGET"} = $target;
+$vartable{"APPLNAME"} = $applname;
+$vartable{"APPLDIR"} = $appldir;
+$vartable{"APPLOBJS"} = $applobjs;
+$vartable{"KERNEL_LIB"} = $kernel_lib;
+$vartable{"KERNEL_FUNCOBJS"} = $kernel_funcobjs;
+$vartable{"SRCDIR"} = $srcdir;
+$vartable{"SRCABSDIR"} = $srcabsdir;
+$vartable{"SRCLANG"} = $srclang;
+$vartable{"DBGENV"} = $dbgenv;
+$vartable{"ENABLE_TRACE"} = $enable_trace;
+$vartable{"PERL"} = $perl;
+$vartable{"CFG"} = $cfg;
+$objext = do get_objext();
+$vartable{"OBJEXT"} = $objext;
+
+#
+# ターゲットディレクトリのチェック
+#
+
+if (! -d $srcdir."/target/".$target) {
+ print STDERR "configure: $srcdir/target/$target not exist\n";
+ exit(1);
+}
+
+#
+# Makefile とアプリケーションファイルの生成
+#
+
+do generate($makefile, 1);
+do generate($applname.".c", 0);
+do generate($applname.".cpp", 0);
+do generate($applname.".h", 0);
+do generate($applname.".cfg", 0);
+
+#
+# cfg ができているかのチェック
+#
+
+if (!(-x ($objext == "" ? $cfgfile : $cfgfile.".".$objext))) {
+ print STDERR "Executable file of the configurator (cfg) is not found.\n";
+}
--- /dev/null
+
+ TOPPERS/ASPカーネルの仕様概要
+
+ 対応バージョン: Release 1.6
+ 最終更新: 2010年7月25日
+
+このドキュメントは,TOPPERS/ASPカーネルの仕様概要について説明したもので
+ある.μITRON4.0仕様のスタンダードプロファイルに対する拡張および変更箇
+所を中心に説明する.
+
+----------------------------------------------------------------------
+ TOPPERS/ASP Kernel
+ Toyohashi Open Platform for Embedded Real-Time Systems/
+ Advanced Standard Profile Kernel
+
+ Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ Graduate School of Information Science, Nagoya Univ., JAPAN
+
+ 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ スコード中に含まれていること.
+ (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ の無保証規定を掲載すること.
+ (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ と.
+ (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ 報告すること.
+ (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ 免責すること.
+
+ 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ の責任を負わない.
+
+ $Id: asp_spec.txt 1862 2010-07-25 11:49:51Z ertl-hiro $
+----------------------------------------------------------------------
+
+○前提となる文書
+
+[1] トロン協会: μITRON4.0仕様, Ver.4.02.00, 2004年.
+
+[2] トロン協会: μITRON4.0仕様 保護機能拡張(μITRON4.0/PX仕様),
+ Ver.1.00.00, 2002年.
+
+[3] TOPPERSプロジェクト: TOPPERS/JSPカーネル ユーザズマニュアル
+ Release 1.4.3対応, 最終更新: 2007年4月23日.
+
+[4] TOPPERSプロジェクト: TOPPERS標準割込み処理モデル, 最終更新: 2008年
+ 4月11日.
+
+○仕様の概略
+
+TOPPERS/ASPカーネルの仕様は,μITRON4.0仕様のスタンダードプロファイルを
+ベースに,次のような拡張・改良を加えたものである.
+
+・割込み処理機能については,TOPPERS標準割込み処理モデルに準拠させる.
+・μITRON4.0仕様のスタンダードプロファイル外の機能の一部を導入する.
+・一部の仕様について,μITRON4.0仕様に対して変更を加える.
+・JSPカーネルにおける独自の拡張機能を一部変更して実装する.
+・ASPカーネルにおける独自の拡張機能を新たに実装する.
+・システムコンフィギュレーション処理を全面的に見直す.
+・拡張機能を実装するための拡張パッケージをサポートする.
+・TOPPERS組込みコンポーネントシステム(TECS)を導入する.
+
+そのためASPカーネルは,μITRON4.0仕様に完全に準拠しているわけではなく,
+JSPカーネルの上位互換にもなっていない.
+
+μITRON4.0仕様では,実装独自に用意する静的APIおよびサービスコールの名称
+には,先頭にそれぞれ"V"および"v"の文字を付加するものとしているが,ASPカー
+ネルではこの規定は採用しない.
+
+以下では,μITRON4.0仕様のスタンダードプロファイルに対する拡張および変
+更箇所について説明する.
+
+○スタンダードプロファイル外の機能の一部導入
+
+μITRON4.0仕様には規定されているが,スタンダードプロファイルに含まれな
+い(または,含まれるとは限らない)機能として,次の機能を実装する.
+
+(1) イベントフラグの複数タスク待ち
+
+イベントフラグに対する複数タスク待ちの機能(TA_WMUL属性のイベントフラグ)
+を実装する.
+
+これにより,イベントフラグのセット(set_flg,iset_flg)で複数のタスクが
+起床される可能性が生じる.多くのタスクを同時に待ち解除した場合,カーネ
+ル内での割込み禁止時間が長くなるため,使用にあたっては注意が必要である.
+
+(2) アラームハンドラ
+
+アラームハンドラの機能を実装する.アラームハンドラ機能のために実装する
+静的APIおよびサービスコールは次の通りである.
+
+ CRE_ALM アラームハンドラの生成(静的API)
+ sta_alm アラームハンドラの動作開始
+ ista_alm アラームハンドラの動作開始(非タスクコンテキスト用)
+ stp_alm アラームハンドラの動作停止
+ istp_alm アラームハンドラの動作停止(非タスクコンテキスト用)
+
+(3) 割込みサービスルーチン
+
+スタンダードプロファイルでは,割込みハンドラと割込みサービスルーチンの
+いずれかをサポートすればよいことになっている.JSPカーネルでは割込みハン
+ドラのみを実装しているが,ASPカーネルではその両者を実装する.
+
+割込みサービスルーチンの仕様については,TOPPERS標準割込み処理モデルの規
+定に準拠する.割込みサービスルーチンを追加するサービスコールとして,次
+の静的APIを実装する.この静的APIの仕様については,TOPPERS標準割込み処理
+モデルにおいて,μITRON4.0仕様に対して拡張を加えている.
+
+ ATT_ISR 割込みサービスルーチンの追加(静的API)
+
+(4) 割込み管理機能
+
+スタンダードプロファイルに含まれない割込み管理機能として,次のサービス
+コールを実装する.JSPカーネルでは,これらのサービスコールを実装するかど
+うかはターゲット依存となっているが,ASPカーネルでは,TOPPERS標準割込み
+処理モデルの規定に準拠して,ターゲット非依存に実装する.
+
+ dis_int 割込みの禁止
+ ena_int 割込みの許可
+ chg_ipm 割込み優先度マスクの変更
+ get_ipm 割込み優先度マスクの参照
+
+(5) オブジェクトの状態参照機能
+
+主にデバッグ時向けの機能として,オブジェクトの状態参照機能を実装する.
+具体的には,次のサービスコールを実装する.
+
+ ref_tsk タスクの状態参照
+ ref_tex タスク例外処理の状態参照
+ ref_sem セマフォの状態参照
+ ref_flg イベントフラグの状態参照
+ ref_dtq データキューの状態参照
+ ref_mbx メールボックスの状態参照
+ ref_mpf 固定長メモリプールの状態参照
+ ref_cyc 周期ハンドラの状態参照
+ ref_alm アラームハンドラの状態参照
+
+○μITRON4.0仕様に対する変更
+
+(1) ITRON標準データ型の見直し
+
+サイズの決まった整数型(B,H, Wなど)などについて,C99に準拠した型の名
+称(int8_t,int16_t,int32_tなど)やそれと相性が良い名称に変更する.
+ITRON標準データ型(B,H, Wなど)を必要とするアプリケーションのために,
+itron.hを用意する.
+
+(2) 非タスクコンテキストからのext_tsk
+
+非タスクコンテキストからext_tskが呼ばれた場合,E_CTXエラーを返すものと
+する.これにともなって,ext_tskをリターンする可能性があるものとし,返り
+値の型をERとする.
+
+(3) CPU例外ハンドラで行える操作
+
+CPU例外ハンドラで行える操作については,TOPPERS標準割込み処理モデルに準
+拠することとし,JSPカーネルの仕様を踏襲せず,μITRON4.0仕様にも従わない.
+そのためのサービスコールとして,次のサービスコールを実装する.
+
+ xsns_dpn CPU例外発生時のディスパッチ保留状態の参照
+ xsns_xpn CPU例外発生時のタスク例外処理保留状態の参照
+
+(4) カーネルの用いる管理領域の分離
+
+μITRON4.0/PX仕様において導入されたμITRON4.0仕様に対する変更として,カー
+ネルの用いる管理領域の分離に関する仕様を一部採用する.
+
+まず,固定長メモリプールの実装において,カーネルの用いる管理領域を分離
+することに伴い,固定長メモリプールを生成する静的API(CRE_MPF)のパラメー
+タに,固定長メモリプール管理領域の先頭番地(mpfmb)を追加する.
+
+また,これにあわせて,データキューを生成する静的API(CRE_DTQ)の最後の
+パラメータの名称を,データキュー管理領域の先頭番地(dtqmb)に変更する.
+
+なお,メールボックスは,μITRON4.0仕様との互換性のために残している機能
+と位置付け,カーネルの用いる管理領域の分離は行わない.そのため,メール
+ボックスを生成する静的API(CRE_MBX)に対する変更はない.
+
+(5) 処理単位とメモリ領域のデータ型の見直し
+
+処理単位のエントリ番地のデータ型を,パラメータが反映されないFP型ではな
+く,処理単位毎の専用のデータ型とする.例えば,タスクのエントリ番地のデー
+タ型をTASK型,タスク例外処理ルーチンのデータ型をTEXRTN型とする.
+
+また,スタック領域と固定長メモリプール領域のデータ型を,それぞれSTK_T型
+とMPF_T型とする.
+
+(6) 値が0の定数(オブジェクト属性等)の見直し
+
+コーディングミスを防ぐために,値が0の定数の扱いを見直す.オブジェクト属
+性(TA_TFIFO等)については,値が0のものはデフォルト扱いして廃止し,定義
+をitron.hに移す.値が0のサービスコールの動作モード(TWF_ANDW)やオブジェ
+クトの状態(TTEX_ENA等)については,値を変更する.
+
+(7) 強制待ち要求ネストの廃止
+
+強制待ち要求をネストする機能を廃止する.言い換えると,強制待ち要求ネス
+ト数の最大値を1に固定する.これに伴い,frsm_tskは廃止し,itron.hにおい
+てfrsm_tskをrsm_tskにマクロ定義する.また,TMAX_SUSCNTの定義をitron.hに
+移す.
+
+(8) システム時刻の設定機能の廃止
+
+set_tim(システム時刻の設定)を廃止する.
+
+(9) 周期ハンドラの仕様変更
+
+sta_cycを呼び出した後,最初に周期ハンドラが起動される時刻を変更する.
+μITRON4.0仕様では,sta_cycを呼び出してから周期ハンドラの起動周期で指定
+した相対時間後としているが,ASPカーネルでは,起動位相で指定した相対時間
+後とする.
+
+○JSPカーネルにおける独自の拡張機能
+
+JSPカーネルにおける独自の拡張機能の中で,以下の機能を実装する.
+
+(1) 性能評価用システム時刻参照機能
+
+性能評価用システム時刻参照機能とは,ASPカーネル上で動作するタスクやASP
+カーネル自身の性能を計測するための,システム時刻をμ秒単位で読み出す機
+能である.この機能のためのサービスコールは次の通りである(JSPカーネルと
+は名称を変更した).
+
+ get_utm 性能評価用システム時刻の参照
+
+JSPカーネルからの仕様変更として,get_utmは任意のコンテキストから呼び出
+すことができるものする.また,性能評価用システム時刻の型(SYSUTM)を,
+ターゲット非依存部でulong_tに定義する.
+
+(2) 終了処理ルーチン機能
+
+ASPカーネルでは,システムの終了時に呼び出される終了処理ルーチンを登録す
+るための機能をサポートする.この機能のための静的APIは次の通りである.
+
+ ATT_TER 終了処理ルーチンの追加(静的API)
+
+(3) カーネル動作状態の参照
+
+カーネル上で動作するタスクから呼び出される関数が,カーネルの初期化完了
+前や終了処理開始後にも呼び出される可能性がある場合には,その中でカーネ
+ルのサービスコールを呼び出せるかを判別することが必要となる.この機能の
+ためのサービスコールは次の通りである(JSPカーネルとは名称を変更した).
+
+ sns_ker カーネル非動作状態の参照
+
+○ASPカーネルにおける独自の拡張機能
+
+(1) 割込み要求ラインの属性の設定
+
+割込み要求ラインの属性を設定する機能として,TOPPERS標準割込み処理モデル
+で規定された次の静的APIを実装する.
+
+ CFG_INT 割込み要求ラインの属性の設定(静的API)
+
+(2) 同期・通信オブジェクトの再初期化機能
+
+同期・通信オブジェクトを初期状態に戻すための機能として,次のサービスコー
+ルを実装する.
+
+ ini_sem セマフォの再初期化
+ ini_flg イベントフラグの再初期化
+ ini_dtq データキューの再初期化
+ ini_mbx メールボックスの再初期化
+ ini_mpf 固定長メモリプールの再初期化
+
+同期・通信オブジェクトの再初期化の際に,その同期・通信オブジェクトに対
+して待ち状態となっていたタスクはすべて待ち解除される.待ち解除されたタ
+スクに対しては,E_DLTを返す.E_DLTは,スタンダードプロファイルでは使用
+していないエラーコードである.
+
+そのため,これらのサービスコールにより,複数のタスクが起床される可能性
+が生じる.多くのタスクを同時に待ち解除した場合,カーネル内での割込み禁
+止時間が長くなるため,使用にあたっては注意が必要である.
+
+同期・通信オブジェクトを再初期化する際に,アプリケーション側との整合性
+を保つのはアプリケーションの責任である.具体的には,固定長メモリプール
+を再初期化する際には,そこから獲得済みのメモリブロックをそれ以降使わな
+いようにしなければならない.また,メールボックスを再初期化する際には,
+メールボックスに送信されたメッセージ領域を回収しなければならない.
+
+(3) 優先度データキューの新設
+
+優先度付きのデータキューの機能を新設する.優先度付きデータキュー機能の
+ために実装する静的APIおよびサービスコールは次の通りである.
+
+ CRE_PDQ 優先度データキューの生成
+ snd_pdq 優先度データキューへの送信
+ psnd_pdq 優先度データキューへの送信(ポーリング)
+ ipsnd_pdq 優先度データキューへの送信(ポーリング,非タスクコンテキスト)
+ tsnd_pdq 優先度データキューへの送信(タイムアウトあり)
+ rcv_pdq 優先度データキューからの受信
+ prcv_pdq 優先度データキューからの受信(ポーリング)
+ trcv_pdq 優先度データキューからの受信(タイムアウトあり)
+ ini_pdq 優先度データキューの再初期化
+ ref_pdq 優先度データキューの状態参照
+
+ここで,優先度データキューに蓄積されたデータの数が多い場合,優先度デー
+タキューへのデータの送信を行うサービスコール(snd_pdq,psnd_pdq,
+ipsnd_pdq,tsnd_pdq)の処理時間が長くなり,カーネル内での割込み禁止時間
+が長くなるため,使用にあたっては注意が必要である.
+
+(4) 自タスクの拡張情報の参照
+
+自タスクの拡張情報を参照するためのサービスコールを新設する.ライブラリ
+等の中で用いることを想定している.
+
+ get_inf 自タスクの拡張情報の参照
+
+(5) カーネルの終了
+
+致命的なエラーが起こった場合などにカーネルを終了させるためのサービスコー
+ルを新設する.この機能は,μITRON4.0仕様の機能分類では,システム構成管
+理機能に分類する(JSPカーネルでは,kernel_exitという名称で,実質的にこ
+の機能を用意していた).
+
+ ext_ker カーネルの終了
+
+ASPカーネルでは,このサービスコールからリターンすることはないが,保護機
+能を持ったカーネルではエラーリターンする可能性があるため,返り値の型を
+ERとする.
+
+これに伴って,JSPカーネルのkernel_startを,sta_kerに名称変更する.ただ
+し,sta_kerはサービスコールとは見なさないことにする.
+
+(6) 非タスクコンテキスト用のスタック領域の設定
+
+非タスクコンテキスト用のスタック領域の先頭番地とサイズを指定するための
+静的APIを新設する.また,この静的APIにより,非タスクコンテキスト用のス
+タック領域のサイズのみを指定することもできる.
+
+ DEF_ICS 非タスクコンテキスト用のスタック領域の定義
+
+○JSPカーネルにおける実装定義/実装依存規定からの変更
+
+μITRON4.0仕様で実装定義または実装依存とされている仕様の中で,以下のも
+のについてJSPカーネルから変更する.
+
+(1) アプリケーション向けのインクルードファイルの構成の整理
+
+カーネルを呼び出すアプリケーションからはkernel.hを,SILを呼び出すアプリ
+ケーションからはsil.hをインクルードすればよいものとし,t_services.hと
+s_services.hは廃止する.
+
+また,kernel.hとsil.hの共通部分としてt_stddef.hを用意し,カーネルとSIL
+のいずれも呼び出さないアプリケーションからは,t_stddef.hをインクルード
+すればよいものとする.itron.hは,μITRON4.0仕様との互換性が必要な場合に
+インクルードするものとする.
+
+(2) 割込み処理/例外処理関連の型の定義の変更
+
+割込みハンドラ番号の型(INHNO),割込み番号の型(INTNO),CPU例外ハンド
+ラ番号の型(EXCNO)を,ターゲット非依存部で,いずれもuint_t型に定義する.
+
+(3) 処理単位の実行開始/リターン時のシステム状態の規定
+
+処理単位の実行開始/リターン時のシステム状態について,μITRON4.0仕様に
+おいて実装依存であった点を厳密に規定し,ターゲットによる違いが生じない
+ようにする.
+
+(4) isig_timの扱いの変更
+
+システム時刻を更新する機構をカーネル内部に持つ扱いとし,サービスコール
+としてのisig_timは廃止する.
+
+(5) カーネルの用いる領域の指定方法
+
+JSPカーネルでは,カーネルの用いる領域はすべて自動割付けであったが,ASP
+カーネルでは,タスクのスタック領域と固定長メモリプールの固定長メモリプー
+ル領域については,静的APIで先頭番地を指定することもできるものとする(自
+動割付けもサポートする).
+
+(6) カーネル管理外の割込みの扱いの規定
+
+JSPカーネルではターゲット毎に定めていたカーネル管理外の割込みの扱いを,
+ASPカーネルでは,TOPPERS標準割込み処理モデルの規定に準拠して,可能な範
+囲で標準化する.ただし,NMI以外にカーネル管理外の割込みを設けるかや,ど
+の割込み優先度より高いものをカーネル管理外とするかは,ターゲット毎に定
+める.
+
+○システムコンフィギュレーション処理の見直し
+
+システムコンフィギュレーション処理を全面的に見直し,システムコンフィギュ
+レーションファイル中におけるC言語のプリプロセッサディレクティブの扱いと
+静的APIのパラメータの分類を変更した.
+
+○拡張パッケージのサポート
+
+ASPカーネルでは,いくつかの拡張機能を実装するために,次の拡張パッケージ
+をサポートしている.
+
+・ミューテックス機能拡張パッケージ(優先度継承ミューテックスを除く)
+・オーバランハンドラ機能拡張パッケージ
+・タスク優先度拡張パッケージ
+
+○TOPPERS組込みコンポーネントシステム(TECS)の導入
+
+デバイスドライバやシステムログ機能との接続にTOPPERS組込みコンポーネント
+システム(TECS)を導入する.また,カーネルオブジェクトをTECSのコンポー
+ネントとして扱えるようにする.
+
+なお,Release 1.6の時点では,TECSに対応するための修正は,TECSの配布パッ
+ケージに含まれており,ASPカーネルの配布パッケージには含まれていない.
+
+以上
--- /dev/null
+
+ TOPPERS/ASPカーネル
+ コンフィギュレータ仕様
+
+ 対応バージョン: Release 1.6.0
+ 最終更新: 2010年6月27日
+
+このドキュメントは,TOPPERS/ASPカーネルのコンフィギュレータが標準的に生
+成すべきファイルの内容について解説したものである.ターゲット依存に生成
+する内容については,このドキュメントの範囲外である.
+
+----------------------------------------------------------------------
+ TOPPERS/ASP Kernel
+ Toyohashi Open Platform for Embedded Real-Time Systems/
+ Advanced Standard Profile Kernel
+
+ Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ Graduate School of Information Science, Nagoya Univ., JAPAN
+
+ 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ スコード中に含まれていること.
+ (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ の無保証規定を掲載すること.
+ (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ と.
+ (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ 報告すること.
+ (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ 免責すること.
+
+ 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ の責任を負わない.
+
+ $Id: configurator.txt 1862 2010-07-25 11:49:51Z ertl-hiro $
+----------------------------------------------------------------------
+
+○目次
+
+・生成するファイルの種類
+・静的API一覧
+・カーネル構成・初期化ヘッダファイル(kernel_cfg.h)
+・カーネル構成・初期化ファイル(kernel_cfg.c)
+ (1) 固定生成部分
+ (2) インクルードディレクティブ(#include)の処理
+ (3-1) トレースログマクロのデフォルト定義
+ (3-2) オブジェクトのID番号を保持する変数の定義
+ (4) 各カーネルオブジェクトに関する定義
+ (5) 割込みに関する定義
+ (6) CPU例外に関する定義
+ (7) 非タスクコンテキスト用のスタック領域に関する定義
+ (8) タイムイベント管理に関する定義
+ (9) 各モジュールの初期化関数の定義
+ (10) 初期化ルーチンの実行関数の定義
+ (11) 終了処理ルーチンの実行関数の定義
+
+
+○生成するファイルの種類
+
+ASPカーネルのコンフィギュレータは,システムコンフィギュレーションファイ
+ルを処理して,カーネル構成・初期化ファイル(kernel_cfg.c)と構成・初期
+化ヘッダファイル(kernel_cfg.h)を生成する.また,コンフィギュレータの
+処理の途中に,必要な中間ファイルを生成する.
+
+
+○静的API一覧
+
+ASPカーネルのコンフィギュレータが処理する静的APIは次の通り.
+
+(1) タスク管理機能
+ CRE_TSK(ID tskid, { ATR tskatr, intptr_t exinf, TASK task,
+ PRI itskpri, SIZE stksz, STK_T *stk })
+
+(2) タスク例外処理機能
+ DEF_TEX(ID tskid, { ATR texatr, TEXRTN texrtn })
+
+(3) 同期・通信機能
+ CRE_SEM(ID semid, { ATR sematr, uint_t isemcnt, uint_t maxsem })
+ CRE_FLG(ID flgid, { ATR flgatr, FLGPTN iflgptn })
+ CRE_DTQ(ID dtqid, { ATR dtqatr, uint_t dtqcnt, void *dtqmb })
+ CRE_PDQ(ID pdqid, { ATR pdqatr, uint_t pdqcnt, PRI maxdpri, void *pdqmb })
+ CRE_MBX(ID mbxid, { ATR mbxatr, PRI maxmpri, void *mprihd })
+
+※ dtqmb,pdqmb,mprihdがNULLでない場合はサポートしない.
+
+(4) メモリプール管理機能
+ CRE_MPF(ID mpfid, { ATR mpfatr, uint_t blkcnt, uint_t blksz,
+ MPF_T *mpf, void *mpfmb })
+
+※ mpfmbがNULLでない場合はサポートしない.
+
+(5) 時間管理機能
+ CRE_CYC(ID cycid, { ATR cycatr, intptr_t exinf, CYCHDR cychdr,
+ RELTIM cyctim, RELTIM cycphs })
+ CRE_ALM(ID almid, { ATR almatr, intptr_t exinf, ALMHDR almhdr })
+
+(6) 割込み管理機能
+ CFG_INT(INTNO intno, { ATR intatr, PRI intpri })
+ ATT_ISR({ ATR isratr, intptr_t exinf, INTNO intno, ISR isr, PRI isrpri })
+ DEF_INH(INHNO inhno, { ATR inhatr, INTHDR inthdr })
+
+(7) CPU例外管理機能
+ DEF_EXC(EXCNO excno, { ATR excatr, EXCHDR exchdr })
+
+(8) システム構成管理機能
+ DEF_ICS({ SIZE istksz, STK_T *istk })
+ ATT_INI({ ATR iniatr, intptr_t exinf, INIRTN inirtn })
+ ATT_TER({ ATR teratr, intptr_t exinf, TERRTN terrtn })
+
+これらの静的APIのパラメータの内,ID型のパラメータはオブジェクト識別名,
+ポインタ型(void *,TASK,TEXRTN,CYCHDR,ALMHDR,ISR,INTHDR,EXCHDR,
+INIRTN,TERRTN,STK_T *,MPF_T *)およびintptr_t型のパラメータは一般定
+数式パラメータとする.その他のパラメータは,整数定数式パラメータとする.
+
+
+○カーネル構成・初期化ヘッダファイル(kernel_cfg.h)
+
+カーネル構成・初期化ヘッダファイル(kernel_cfg.h)には,次の定義を生成
+する.
+
+(1) 固定生成部分
+
+kernel_cfg.hが複数回インクルードされるのを防ぐための記述を生成する.具
+体的には,ファイルの先頭に次の行を生成する.
+
+#ifndef TOPPERS_KERNEL_CFG_H
+#define TOPPERS_KERNEL_CFG_H
+
+また,ファイルの末尾に次の行を生成する.
+
+#endif /* TOPPERS_KERNEL_CFG_H */
+
+(2) オブジェクト数の定義
+
+カーネルがサポートするオブジェクトの数をマクロ定義するプリプロセッサディ
+レクティブ(#define)を生成する.具体的には,次のような記述を生成する.
+
+#define TNUM_TSKID <タスクの数>
+#define TNUM_SEMID <セマフォの数>
+#define TNUM_FLGID <イベントフラグの数>
+#define TNUM_DTQID <データキューの数>
+#define TNUM_PDQID <優先度データキューの数>
+#define TNUM_MBXID <メールボックスの数>
+#define TNUM_MPFID <固定長メモリプールの数>
+#define TNUM_CYCID <周期ハンドラの数>
+#define TNUM_ALMID <アラームハンドラの数>
+
+(3) オブジェクトのID番号の定義
+
+コンフィギュレータがID番号を割り付けたオブジェクトの名前を,割り付けた
+ID番号にマクロ定義するプリプロセッサディレクティブ(#define)を生成する.
+例えば,次のような記述を生成する.
+
+#define TASK1 1
+#define TASK2 2
+#define SEM1 1
+
+○カーネル構成・初期化ファイル(kernel_cfg.c)
+
+(1) 固定生成部分
+
+kernel_cfg.c用のヘッダファイルとID自動割付け結果ファイルをインクルード
+するプリプロセッサディレクティブ(#include)を生成する.具体的には,次
+の行を生成する.
+
+#include "kernel/kernel_int.h"
+#include "kernel_cfg.h"
+
+(2) インクルードディレクティブ(#include)の処理
+
+システムコンフィギュレーションファイルに含まれるC言語プリプロセッサのイ
+ンクルードディレクティブ(#include)と同一のディレクティブ(#include)
+を生成する.例えば,
+
+#include "sample1.h"
+
+というインクルードディレクティブに対して,
+
+#include "sample1.h"
+
+というディレクティブを生成する.生成するディレクティブの順序は,システ
+ムコンフィギュレーションファイル中でのインクルードディレクティブの順序
+に一致させる.
+
+(3-1) トレースログマクロのデフォルト定義
+
+kernel_cfg.cの中で使用するトレースログマクロのデフォルト定義を生成する.
+具体的には,次の行を生成する.
+
+#ifndef LOG_ISR_ENTER
+#define LOG_ISR_ENTER(intno)
+#endif /* LOG_ISR_ENTER */
+
+#ifndef LOG_ISR_LEAVE
+#define LOG_ISR_LEAVE(intno)
+#endif /* LOG_ISR_LEAVE */
+
+(3-2) オブジェクトのID番号を保持する変数の定義
+
+コンフィギュレータに対するオプション指定(--external-id)により,コンフィ
+ギュレータがID 番号を割り付けたオブジェクトの名前の末尾に"_id"を付加し
+た名前の変数を生成する.変数は,const属性を付加したID型の変数とし,割り
+付けたID番号を値とする.例えば,次のような記述を生成する.
+
+const ID TASK1_id = 1;
+const ID TASK2_id = 2;
+const ID SEM1_id = 1;
+
+(4) 各カーネルオブジェクトに関する定義
+
+システムコンフィギュレーションファイル中に,オブジェクトを生成する静的
+API「CRE_XXX」が含まれる各カーネルオブジェクトに関して,オブジェクト生
+成のための定義を生成する.
+
+コンフィギュレータは,同じ種類のオブジェクトを生成する静的APIを集め,各
+オブジェクトにID番号を割り付ける.ID番号は,他のオブジェクトのID番号と
+重複がなく,ID番号が連続するように割り付ける.
+
+コンフィギュレータに対するオプション指定(--id-input-file)により,コン
+フィギュレータがオブジェクトに割り付けるID番号を指定することができる.
+同じ種類の異なるオブジェクトに対して同じID番号を指定したり,コンフィギュ
+レータがID番号をできる限り連続するように割り付けたとしてもID番号が連続
+しない場合には(ASPカーネルは,オブジェクトのID番号が連続していることを
+仮定して実装してある),コンフィギュレータはエラーを報告する.
+
+また,コンフィギュレータに対するオプション指定(--id-output-file)によ
+り,コンフィギュレータがID番号を割り付けたオブジェクトの名前と割り付け
+たID番号の組を,オプションで指定したファイルに出力する.
+
+各カーネルオブジェクトに関する定義の標準的な構成は,次の通りである.オ
+ブジェクトによって例外がある場合には,オブジェクト毎の項で説明する.
+
+(a) 最大のオブジェクトIDの変数の定義
+
+最大のオブジェクトIDを持つ変数の定義を生成する.具体的には,オブジェク
+トの省略記号を「XXX/xxx」とすると,次のような行を生成する.
+
+const ID _kernel_tmax_xxxid = (TMIN_XXXID + TNUM_XXXID - 1);
+
+(b) オブジェクトに必要なメモリ領域の定義
+
+オブジェクトによっては,オブジェクトに必要なメモリ領域の定義を生成する.
+具体的には,オブジェクト毎の項で説明する.
+
+(c) オブジェクトの初期化ブロックの定義
+
+オブジェクトの初期化ブロックの定義を生成する.具体的には,オブジェクト
+の省略記号を「XXX/xxx」とすると,次のような行を生成する.
+
+const XXXINIB _kernel_xxxinib_table[TNUM_XXXID] = {
+ <オブジェクトIDが1のオブジェクトの初期化情報>,
+ <オブジェクトIDが2のオブジェクトの初期化情報>,
+ ……
+ <オブジェクトIDがTNUM_XXXIDのオブジェクトの初期化情報>
+};
+
+オブジェクトの初期化情報の形式は,オブジェクト毎に異なる.具体的には,
+オブジェクト毎の項で説明する.
+
+(d) オブジェクトのコントロールブロックの定義
+
+オブジェクトのコントロールブロックの定義を生成する.具体的には,オブジェ
+クトの省略記号を「XXX/xxx」とすると,次のような行を生成する.
+
+XXXCB _kernel_xxxcb_table[TNUM_XXXID];
+
+(4-1) タスクに関する定義
+
+ASPカーネルは,タスクが一つもないケースに対応していないため,タスクに関
+する定義は必ず生成しなければならない.
+
+タスクの省略記号は「TSK」「tsk」である.ただし,タスク初期化ブロックの
+データ型はTINIB,その変数名は_kernel_tinib_table,タスクコントロールブ
+ロックのデータ型はTCB,その変数名は_kernel_tcb_table である(いずれも
+「TSK/tsk」に代えて「T/t」を用いている).
+
+タスク初期化ブロックには,「CRE_TSK」静的APIで指定される情報に加えて,
+「DEF_TEX」静的APIで指定される情報を含める.
+
+以下では,システムコンフィギュレーションファイルに次の静的APIが含まれ
+ている時に生成すべき情報について述べる.
+
+CRE_TSK(tskid, { tskatr, exinf, task, itskpri, stksz, stk });
+DEF_TEX(tskid, { texatr, texrtn });
+
+(4-1-1) タスクに必要なメモリ領域の定義
+
+タスクに必要なメモリ領域として,タスクのスタック領域がある.stkがNULLの
+場合には,生成するタスク毎に,指定されたサイズのスタック領域を確保する.
+具体的には,上記の静的APIに対して,次の定義を生成する.
+
+*stkがNULLの場合のみ生成
+static STK_T _kernel_stack_<タスク名>[COUNT_STK_T(stksz)];
+
+(4-1-2) タスクの初期化情報
+
+タスク初期化ブロック中に生成するタスクの初期化情報は,次の形式とする.
+
+ { (tskatr), (intptr_t)(exinf), (task), INT_PRIORITY(itskpri),
+ (stksz), (stk), (texatr), (texrtn) }
+
+ここで,stkがNULLの場合には,(stksz)に代えてROUND_STK_T(stksz)を,
+(stk)に代えて(_kernel_stack_<タスク名>)を生成する.CRE_TSKに対応する
+DEF_TEXがない場合には,texatrをTA_NULL,texrtnをNULLとする.
+
+(4-1-3) タスク生成順序テーブルの定義
+
+タスクに対しては,生成された順序(タスクを生成する静的APIが記述された
+順序)をテーブルに出力する必要がある.これは,タスクの生成された順序で,
+タスクの初期化(より具体的には,タスクの起動)を行う必要があるためであ
+る.
+
+具体的には,次のような行を生成する.
+
+const ID _kernel_torder_table[TNUM_TSKID] = {
+ <最初に生成されたタスクのタスクID>,
+ <2番目に生成されたタスクのタスクID>,
+ ……
+ <最後に生成されたタスクのタスクID>
+};
+
+(4-1-4) エラー条件
+
+タスクに関するエラー条件は次の通りである.
+
+*コンフィギュレータ本体が検出するもの
+・同じtskidに対するCRE_TSKが複数ある場合(E_OBJ)
+・DEF_TEXに対応するCRE_TSKがない場合(E_NOEXS)
+・同じtskidに対するDEF_TEXが複数ある場合(E_OBJ)
+
+*パス2で検出するもの
+・tskatrが([TA_ACT])でない場合(E_RSATR)
+ ※ ターゲット依存部でタスク属性を追加可(TARGET_TSKATR)
+・(TMIN_TPRI <= itskpri && itskpri <= TMAX_TPRI)でない場合(E_PAR)
+・stkszが0か,ターゲット定義の最小値(TARGET_MIN_STKSZ)よりも小さい場
+ 合(E_PAR)
+・stkszがスタック領域のサイズとして正しくない場合(E_PAR)
+ - ターゲット依存の値(CHECK_STKSZ_ALIGN)の倍数でない場合
+ ※ このエラーチェックは,stkがNULLでない場合にのみ行う
+・texatrが(TA_NULL)でない場合(E_RSATR)
+
+*パス3で検出するもの
+・taskとtexrtnがプログラムの開始番地として正しくない場合(E_PAR)
+ - ターゲット依存の値(CHECK_FUNC_ALIGN)の倍数でない場合
+ - NULLの場合(ターゲット依存,CHECK_FUNC_NONNULL)
+・stkがスタック領域の先頭番地として正しくない場合(E_PAR)
+ - ターゲット依存の値(CHECK_STACK_ALIGN)の倍数でない場合
+ - NULLの場合(ターゲット依存,CHECK_STACK_NONNULL)
+
+(4-2) セマフォに関する定義
+
+セマフォの省略記号は「SEM/sem」である.以下では,システムコンフィギュレー
+ションファイルに次の静的APIが含まれている時に生成すべき情報について述べ
+る.なお,セマフォに必要なメモリ領域はない.
+
+CRE_SEM(semid, { sematr, isemcnt, maxsem });
+
+(4-2-1) セマフォの初期化情報
+
+セマフォ初期化ブロック中に生成するセマフォの初期化情報は,次の形式とす
+る.
+
+ { (sematr), (isemcnt), (maxsem) }
+
+(4-2-2) エラー条件
+
+セマフォに関するエラー条件は次の通りである.
+
+*コンフィギュレータ本体が検出するもの
+・同じsemidに対するCRE_SEMが複数ある場合(E_OBJ)
+
+*パス2で検出するもの
+・sematrが([TA_TPRI])でない場合(E_RSATR)
+・(0 <= isemcnt && isemcnt <= maxsem)でない場合(E_PAR)
+・(1 <= maxsem && maxsem <= TMAX_MAXSEM)でない場合(E_PAR)
+
+(4-3) イベントフラグに関する定義
+
+イベントフラグの省略記号は「FLG/flg」である.以下では,システムコンフィ
+ギュレーションファイルに次の静的APIが含まれている時に生成すべき情報につ
+いて述べる.なお,イベントフラグに必要なメモリ領域はない.
+
+CRE_FLG(flgid, { flgatr, iflgptn });
+
+(4-3-1) イベントフラグの初期化情報
+
+イベントフラグ初期化ブロック中に生成するイベントフラグの初期化情報は,
+次の形式とする.
+
+ { (flgatr), (iflgptn) }
+
+(4-3-2) エラー条件
+
+イベントフラグに関するエラー条件は次の通りである.
+
+*コンフィギュレータ本体が検出するもの
+・同じflgidに対するCRE_FLGが複数ある場合(E_OBJ)
+
+*パス2で検出するもの
+・flgatrが([TA_TPRI]|[TA_WMUL]|[TA_CLR])でない場合(E_RSATR)
+
+(4-4) データキューに関する定義
+
+データキューの省略記号は「DTQ/dtq」である.以下では,システムコンフィギュ
+レーションファイルに次の静的APIが含まれている時に生成すべき情報について
+述べる.
+
+CRE_DTQ(dtqid, { dtqatr, dtqcnt, dtqmb });
+
+(4-4-1) データキューに必要なメモリ領域の定義
+
+データキューに必要なメモリ領域として,データキュー管理領域がある.生成
+するデータキュー毎に,必要なサイズのデータキュー管理領域を定義する.具
+体的には,上記の静的APIに対して,次の定義を生成する.
+
+*dtqcntが0でない場合のみ生成
+static intptr_t _kernel_dtqmb_<データキュー名>[dtqcnt];
+
+(4-4-2) データキューの初期化情報
+
+データキュー初期化ブロック中に生成するデータキューの初期化情報は,次の
+形式とする.
+
+ { (dtqatr), (dtqcnt), (_kernel_dtqmb_<データキュー名>) }
+
+ここで,dtqcntが0の場合には,_kernel_dtqmb_<データキュー名>に代えて,
+NULLを用いる.
+
+(4-4-3) エラー条件
+
+データキューに関するエラー条件は次の通りである.
+
+*コンフィギュレータ本体が検出するもの
+・同じdtqidに対するCRE_DTQが複数ある場合(E_OBJ)
+
+*パス2で検出するもの
+・dtqatrが([TA_TPRI])でない場合(E_RSATR)
+・dtqmbがNULLでない場合(E_NOSPT)
+
+(4-5) 優先度データキューに関する定義
+
+優先度データキューの省略記号は「PDQ/pdq」である.以下では,システムコ
+ンフィギュレーションファイルに次の静的APIが含まれている時に生成すべき情
+報について述べる.
+
+CRE_PDQ(ID pdqid, { pdqatr, pdqcnt, maxdpri, pdqmb });
+
+(4-5-1) 優先度データキューに必要なメモリ領域の定義
+
+優先度データキューに必要なメモリ領域として,優先度データキュー管理領域
+がある.生成する優先度データキュー毎に,必要なサイズの優先度データキュー
+管理領域を定義する.具体的には,上記の静的APIに対して,次の定義を生成す
+る.
+
+*pdqcntが0でない場合のみ生成
+static PDQMB _kernel_pdqmb_<優先度データキュー名>[pdqcnt];
+
+(4-5-2) 優先度データキューの初期化情報
+
+優先度データキュー初期化ブロック中に生成する優先度データキューの初期化
+情報は,次の形式とする.
+
+ { (pdqatr), (pdqcnt), (maxdpri), (_kernel_pdqmb_<優先度データキュー名>) }
+
+ここで,pdqcntが0の場合には,_kernel_pdqmb_<優先度データキュー名>に代え
+て,NULLを用いる.
+
+(4-5-3) エラー条件
+
+優先度データキューに関するエラー条件は次の通りである.
+
+*コンフィギュレータ本体が検出するもの
+・同じpdqidに対するCRE_PDQが複数ある場合(E_OBJ)
+
+*パス2で検出するもの
+・pdqatrが([TA_TPRI])でない場合(E_RSATR)
+・(TMIN_DPRI <= maxdpri && maxdpri <= TMAX_DPRI)でない場合(E_PAR)
+・pdqmbがNULLでない場合(E_NOSPT)
+
+(4-6) メールボックスに関する定義
+
+メールボックスの省略記号は「MBX/mbx」である.以下では,システムコンフィ
+ギュレーションファイルに次の静的APIが含まれている時に生成すべき情報につ
+いて述べる.なお,メールボックスに必要なメモリ領域はない.
+
+CRE_MBX(mbxid, { mbxatr, maxmpri, mprihd });
+
+(4-6-1) メールボックスの初期化情報
+
+メールボックス初期化ブロック中に生成するメールボックスの初期化情報は,
+次の形式とする.
+
+ { (mbxatr), (maxmpri) }
+
+(4-6-2) エラー条件
+
+メールボックスに関するエラー条件は次の通りである.
+
+*コンフィギュレータ本体が検出するもの
+・同じmbxidに対するCRE_MBXが複数ある場合(E_OBJ)
+
+*パス2で検出するもの
+・mbxatrが([TA_TPRI]|[TA_MPRI])でない場合(E_RSATR)
+・(TMIN_MPRI <= maxmpri && maxmpri <= TMAX_MPRI)でない場合(E_PAR)
+・mprihdがNULLでない場合(E_NOSPT)
+
+(4-7) 固定長メモリプールに関する定義
+
+固定長メモリプールの省略記号は「MPF/mpf」である.以下では,システムコ
+ンフィギュレーションファイルに次の静的APIが含まれている時に生成すべき情
+報について述べる.
+
+CRE_MPF(mpfid, { mpfatr, blkcnt, blksz, mpf, mpfmb });
+
+(4-7-1) 固定長メモリプールに必要なメモリ領域の定義
+
+固定長メモリプールに必要なメモリ領域として,固定長メモリプール領域と固
+定長メモリプール管理領域がある.生成する固定長メモリプール毎に,必要な
+サイズの固定長メモリプール領域(mpfがNULLの場合のみ)と固定長メモリプー
+ル管理領域を確保する.具体的には,上記の静的APIに対して,次の定義を生成
+する.
+
+*mpfがNULLの場合のみ生成
+static MPF_T _kernel_mpf_<固定長メモリプール名>[(blkcnt) * COUNT_MPF_T(blksz)];
+
+*必ず生成
+static MPFMB _kernel_mpfmb_<固定長メモリプール名>[blkcnt];
+
+(4-7-2) 固定長メモリプールの初期化情報
+
+固定長メモリプール初期化ブロック中に生成する固定長メモリプールの初期化
+情報は,次の形式とする.
+
+ { (mpfatr), (blkcnt), ROUND_MPF_T(blksz), mpf,
+ (_kernel_mpfmb_<固定長メモリプール名>) }
+
+ここで,mpfがNULLの場合には,mpfに代えて,_kernel_mpf_<固定長メモリプー
+ル名>を用いる.
+
+(4-7-3) エラー条件
+
+固定長メモリプールに関するエラー条件は次の通りである.
+
+*コンフィギュレータ本体が検出するもの
+・同じmpfidに対するCRE_MPFが複数ある場合(E_OBJ)
+
+*パス2で検出するもの
+・mpfatrが([TA_TPRI])でない場合(E_RSATR)
+・blkcntが0の場合(E_PAR)
+・blkszが0の場合(E_PAR)
+・mpfmbがNULLでない場合(E_NOSPT)
+
+*パス3で検出するもの
+・mpfが固定長メモリプール領域の先頭番地として正しくない場合(E_PAR)
+ - ターゲット依存の値(CHECK_MPF_ALIGN)の倍数でない場合
+ - NULLの場合(ターゲット依存,CHECK_MPF_NONNULL)
+
+(4-8) 周期ハンドラに関する定義
+
+周期ハンドラの省略記号は「CYC/cyc」である.以下では,システムコンフィ
+ギュレーションファイルに次の静的APIが含まれている時に生成すべき情報につ
+いて述べる.なお,周期ハンドラに必要なメモリ領域はない.
+
+CRE_CYC(cycid, { cycatr, exinf, cychdr, cyctim, cycphs });
+
+(4-8-1) 周期ハンドラの初期化情報
+
+周期ハンドラ初期化ブロック中に生成する周期ハンドラの初期化情報は,次の
+形式とする.
+
+ { (cycatr), (intptr_t)(exinf), (cychdr), (cyctim), (cycphs) }
+
+(4-8-2) エラー条件
+
+周期ハンドラに関するエラー条件は次の通りである.
+
+*コンフィギュレータ本体が検出するもの
+・同じcycidに対するCRE_CYCが複数ある場合(E_OBJ)
+
+*パス2で検出するもの
+・cycatrが([TA_STA])でない場合(E_RSATR)
+・(0 < cyctim && cyctim <= TMAX_RELTIM)でない場合(E_PAR)
+・(0 <= cycphs && cycphs <= TMAX_RELTIM)でない場合(E_PAR)
+・警告:cycatrにTA_STAが設定されていて,(cycphs == 0)の場合
+
+*パス3で検出するもの
+・cychdrがプログラムの開始番地として正しくない場合(E_PAR)
+ - ターゲット依存の値(CHECK_FUNC_ALIGN)の倍数でない場合
+ - NULLの場合(ターゲット依存,CHECK_FUNC_NONNULL)
+
+(4-9) アラームハンドラに関する定義
+
+アラームハンドラの省略記号は「ALM/alm」である.以下では,システムコン
+フィギュレーションファイルに次の静的APIが含まれている時に生成すべき情報
+について述べる.なお,アラームハンドラに必要なメモリ領域はない.
+
+CRE_ALM(ID almid, { almatr, (intptr_t)(exinf), almhdr });
+
+(4-9-1) アラームハンドラの初期化情報
+
+アラームハンドラ初期化ブロック中に生成するアラームハンドラの初期化情報
+は,次の形式とする.
+
+ { (almatr), (exinf), (almhdr) }
+
+(4-9-2) エラー条件
+
+アラームハンドラに関するエラー条件は次の通りである.
+
+*コンフィギュレータ本体が検出するもの
+・同じalmidに対するCRE_ALMが複数ある場合(E_OBJ)
+
+*パス2で検出するもの
+・almatrが(TA_NULL)でない場合(E_RSATR)
+
+*パス3で検出するもの
+・almhdrがプログラムの開始番地として正しくない場合(E_PAR)
+ - ターゲット依存の値(CHECK_FUNC_ALIGN)の倍数でない場合
+ - NULLの場合(ターゲット依存,CHECK_FUNC_NONNULL)
+
+(5) 割込みに関する定義
+
+割込みに関して生成する情報は,ターゲット毎に定めることができる.ターゲッ
+ト毎に定めない場合には,以下で述べるターゲットに依存しない標準的な情報
+を生成する.ターゲット毎に定める場合には,(5-1)と(5-3)に述べる情報は生
+成しない((5-2)に述べる情報は生成する).
+
+(5-1) 割込み要求ラインに関する定義
+
+割込み要求ラインの属性を設定する静的API「CFG_INT」で設定した割込み要求
+ラインに関する定義を生成する.具体的には次の通り.
+
+以下では,システムコンフィギュレーションファイルに次の静的APIが含まれ
+ている時に生成すべき情報について述べる.
+
+CFG_INT(INTNO intno, { intatr, intpri });
+
+(5-1-1) 設定する割込み要求ラインの数
+
+設定する割込み要求ラインの数をマクロ定義するプリプロセッサディレクティ
+ブ(#define)を生成する.また,その値を持つ変数の定義を生成する.具体的
+には,次のような行を生成する.
+
+#define TNUM_INTNO <設定する割込み要求ラインの数>
+const uint_t _kernel_tnum_intno = TNUM_INTNO;
+
+(5-1-2) 割込み要求ライン初期化ブロックの定義
+
+割込み要求ライン初期化ブロックを生成する.具体的には,次のような行を生
+成する.
+
+const INTINIB _kernel_intinib_table[TNUM_INTNO] = {
+ <割込み要求ライン1の初期化情報>,
+ <割込み要求ライン2の初期化情報>,
+ ……
+ <割込み要求ラインTNUM_INTNOの初期化情報>
+};
+
+この中の割込み要求ラインの初期化情報は,次の形式とする.
+
+ { (intno), (intatr), (intpri) }
+
+(5-1-3) エラー条件
+
+割込み要求ラインに関するエラー条件は次の通りである.
+
+*パス2で検出するもの
+・intnoがCFG_INTに対する割込み番号として正しくない場合(E_PAR)
+・intnoがCFG_INTによって設定済みの場合(E_OBJ)
+・intatrが([TA_ENAINT]|[TA_EDGE])でない場合(E_RSATR)
+ ※ ターゲット依存部で割込み属性を追加可(TARGET_INTATR)
+・カーネル管理に固定されているintnoに対して,intpriにTMIN_INTPRIよりも
+ 小さい値が指定された場合(E_OBJ)
+・カーネル管理外に固定されているintnoに対して,intpriにTMIN_INTPRIより
+ も小さい値が指定されなかった場合(E_OBJ)
+・intpriがCFG_INTに対する割込み優先度として正しくない場合(E_PAR)
+
+*必要に応じてターゲット依存部で検出するもの
+・intatrが割込み属性として設定できない値の場合(E_RSATR)
+・intpriが割込み優先度として設定できない値の場合(E_PAR)
+・同一の割込み優先度しか設定できない割込み要求ラインに対して,異なる割
+ 込み優先度を設定した場合(E_PAR)
+
+(5-2) 割込みサービスルーチンに関する定義
+
+(5-2-1) 割込みハンドラの生成
+
+システムコンフィギュレーションファイル中に含まれる割込みサービスルーチ
+ンを追加する静的API「ATT_ISR」に対して,同一の割込み番号に対して追加さ
+れた割込みサービスルーチンを順に呼び出す関数を生成する.
+
+具体的には,同一の割込み番号に対して割込みサービスルーチンを追加する
+
+ATT_ISR({ isratr_1, exinf_1, intno, isr_1, isrpri_1 });
+ATT_ISR({ isratr_2, exinf_2, intno, isr_2, isrpri_2 });
+ ……
+ATT_ISR({ isratr_n, exinf_n, intno, isr_n, isrpri_n });
+
+という静的APIに対して,次のような関数を生成する.ここで,isrpri_1,
+isrpri_2,……,isrpri_nは,値の小さい順に並べ替えられているものとする.
+値が同じものの間では,システムコンフィギュレーションファイル中での静的
+APIの順序の通りに並んでいるものとする.
+
+static void
+_kernel_inthdr_<intno>(void)
+{
+ PRI saved_ipm;
+
+ i_begin_int(intno);
+ saved_ipm = i_get_ipm();
+
+ LOG_ISR_ENTER(<intno>); /* ISR1の呼出し */
+ isr_1((intptr_t)(exinf_1));
+ LOG_ISR_LEAVE(intno);
+
+ if (i_sense_loc()) { /* ISRの呼出し前の状態に戻す */
+ i_unlock_cpu();
+ }
+ i_set_ipm(saved_ipm);
+
+ LOG_ISR_ENTER(<intno>); /* ISR2の呼出し */
+ isr_2((intptr_t)(exinf_2));
+ LOG_ISR_LEAVE(intno);
+
+ if (i_sense_loc()) { /* ISRの呼出し前の状態に戻す */
+ i_unlock_cpu();
+ }
+ i_set_ipm(saved_ipm);
+
+ ……
+
+ LOG_ISR_ENTER(<intno>); /* ISRnの呼出し */
+ isr_n((intptr_t)(exinf_n));
+ LOG_ISR_LEAVE(intno);
+
+ i_end_int(intno);
+}
+
+ここで,ISRnの呼出しの後に呼出し前の状態に戻さないのは,割込みハンドラ
+からのリターンにより,カーネルが元の状態に戻すためである.
+
+同一の割込み番号に対して追加された割込みサービスルーチンが1つのみの場合
+には,次のような関数を生成する.
+
+static void
+_kernel_inthdr_<intno>(void)
+{
+ i_begin_int(intno);
+ LOG_ISR_ENTER(intno);
+ isr_1((intptr_t)(exinf_1));
+ LOG_ISR_LEAVE(intno);
+ i_end_int(intno);
+}
+
+【課題】ここで,LOG_ISR_ENTER,LOG_ISR_LEAVEの引数をどうするかが課題と
+して残っている.ATT_ISRで登録されたISRに対してはISR IDが付与されないた
+め,IDでISRを区別することができない.やむなく割込み番号を渡しているが,
+拡張情報(exinf)も渡すべきかもしれない.
+
+(5-2-2) 割込みハンドラの定義に相当する処理
+
+上のように割込みハンドラを生成した場合には,次に説明する割込みハンドラ
+に関する定義において,システムコンフィギュレーションファイル中に次の静
+的APIが含まれているのと同様に処理する.
+
+DEF_INH(inhno, { TA_NULL, _kernel_inthdr_<intno> });
+
+ここでinhnoは,intnoに対応する割込みハンドラ番号である.
+
+(5-2-3) エラー条件
+
+割込みサービスルーチンに関するエラー条件は次の通りである.
+
+*パス2で検出するもの
+・isratrが(TA_NULL)でない場合(E_RSATR)
+ ※ ターゲット依存部で割込みサービスルーチン属性を追加可(TARGET_ISRATR)
+・intnoがATT_ISRに対する割込み番号として正しくない場合(E_PAR)
+ ※ intnoに対応するinhnoがない場合を含む
+・(TMIN_ISRPRI <= isrpri && isrpri <= TMAX_ISRPRI)でない場合(E_PAR)
+・intnoに対応するinhnoに対してDEF_INHがある場合(E_OBJ)
+・intnoに対するCFG_INTがない場合(E_OBJ)
+・intnoに対してCFG_INTで設定された割込み優先度がTMIN_INTPRIよりも小さい
+ 場合(E_OBJ)
+ ※ カーネル管理外のISRはサポートしないため
+
+*必要に応じてターゲット依存部で検出するもの
+・isrがプログラムの開始番地として正しくない場合(E_PAR)
+
+(5-3) 割込みハンドラに関する定義
+
+割込みハンドラを定義する静的API「DEF_INH」で定義した割込みハンドラ(上
+述の割込みサービスルーチンの追加によりコンフィギュレータが生成した割込
+みハンドラを含む)に関する定義を生成する.具体的には次の通り.
+
+以下では,システムコンフィギュレーションファイルに次の静的APIが含まれ
+ている時に生成すべき情報について述べる.
+
+DEF_INH(inhno, { inhatr, inthdr });
+
+(5-3-1) 定義する割込みハンドラの数
+
+定義する割込みハンドラの数をマクロ定義するプリプロセッサディレクティブ
+(#define)を生成する.また,その値を持つ変数の定義を生成する.具体的
+には,次のような行を生成する.
+
+#define TNUM_INHNO <定義する割込みハンドラの数>
+const uint_t _kernel_tnum_inhno = TNUM_INHNO;
+
+(5-3-2) 割込みハンドラの出入口処理
+
+定義する割込みハンドラ毎に,割込みハンドラの出入口処理ルーチンを生成す
+る.具体的には,次のような行を生成する.
+
+INTHDR_ENTRY(inhno, inhno_num, inthdr)
+
+ここでinhno_numは,inhno(割込みハンドラ番号)を数値で表現したもので,
+アセンブリ言語記述に使用するためのものである.
+
+(5-3-3) 割込みハンドラ初期化ブロックの定義
+
+割込みハンドラ初期化ブロックを生成する.具体的には,次のような行を生成
+する.
+
+const INHINIB _kernel_inhinib_table[TNUM_INHNO] = {
+ <割込みハンドラ1の初期化情報>,
+ <割込みハンドラ2の初期化情報>,
+ ……
+ <割込みハンドラTNUM_INHNOの初期化情報>
+};
+
+この中の割込みハンドラの初期化情報は,次の形式とする.
+
+ { (inhno), (inhatr), (FP)(INT_ENTRY(inhno, inthdr)) }
+
+(5-3-4) エラー条件
+
+割込みハンドラに関するエラー条件は次の通りである.
+
+*パス2で検出するもの
+・inhnoがDEF_INHに対する割込みハンドラ番号として正しくない場合(E_PAR)
+・inhnoがDEF_INHによって設定済みの場合(E_OBJ)
+#・inhnoに対応するintnoに対してATT_ISRがある場合(E_OBJ)
+# ※ inhnoに対応するintnoがない場合には,このチェックを行わない
+# → このチェックは,割込みサービスルーチン側で行う
+・inhatrが(TA_NULL)でない場合(E_RSATR)
+ ※ ターゲット依存部で割込みハンドラ属性を追加可(TARGET_INHATR)
+ ※ TA_NONKERNELを使う場合には,TARGET_INHATRに設定する
+・カーネル管理に固定されているinhnoに対して,inhatrにTA_NONKERNELが指定
+ されている場合(E_RSATR)
+・カーネル管理外に固定されているinhnoに対して,inhatrにTA_NONKERNELが指
+ 定されていない場合(E_RSATR)
+・inhnoに対応するintnoに対するCFG_INTがない場合(E_OBJ)
+ ※ inhnoに対応するintnoがないか,inhnoに対応するintnoがCFG_INTに対
+ する割込み番号として正しくない場合には,このチェックを行わない
+・inhatrにTA_NONKERNELが指定されておらず,inhnoに対応するintnoに対して
+ CFG_INTで設定された割込み優先度がTMIN_INTPRIよりも小さい場合(E_OBJ)
+ ※ inhnoに対応するintnoがないか,inhnoに対応するintnoがCFG_INTに対
+ する割込み番号として正しくない場合には,このチェックを行わない
+・inhatrにTA_NONKERNELが指定されており,inhnoに対応するintnoに対して
+ CFG_INTで設定された割込み優先度がTMIN_INTPRI以上である場合(E_OBJ)
+ ※ inhnoに対応するintnoがないか,inhnoに対応するintnoがCFG_INTに対
+ する割込み番号として正しくない場合には,このチェックを行わない
+
+*必要に応じてターゲット依存部で検出するもの
+・inthdrがプログラムの開始番地として正しくない場合(E_PAR)
+
+(6) CPU例外に関する定義
+
+CPU例外に関して生成する情報は,ターゲット毎に定めることができる.ターゲッ
+ト毎に定めない場合には,以下で述べるターゲットに依存しない標準的な情報
+を生成する.ターゲット毎に定める場合には,これらの情報は生成されない.
+
+システムコンフィギュレーションファイル中に,CPU例外ハンドラを定義する
+静的API「DEF_EXC」が含まれている場合に,CPU例外ハンドラに関する定義を
+生成する.
+
+以下では,システムコンフィギュレーションファイルに次の静的APIが含まれ
+ている時に生成すべき情報について述べる.
+
+DEF_EXC(excno, { excatr, exchdr });
+
+(6-1) 定義するCPU例外ハンドラの数
+
+定義するCPU例外ハンドラの数をマクロ定義するプリプロセッサディレクティ
+ブ(#define)を生成する.また,その値を持つ変数の定義を生成する.具体
+的には,次のような行を生成する.
+
+#define TNUM_EXCNO <定義するCPU例外ハンドラの数>
+const uint_t _kernel_tnum_excno = TNUM_EXCNO;
+
+(6-2) CPU例外ハンドラの出入口処理
+
+定義するCPU例外ハンドラ毎に,CPU例外ハンドラの出入口処理ルーチンを生成
+する.具体的には,次のような行を生成する.
+
+EXCHDR_ENTRY(excno, excno_num, exchdr)
+
+ここでexcno_numは,excno(CPU例外ハンドラ番号)を数値で表現したもので,
+アセンブリ言語記述に使用するためのものである.
+
+(6-3) CPU例外ハンドラ初期化ブロックの定義
+
+CPU例外ハンドラ初期化ブロックを生成する.具体的には,次のような行を生成
+する.
+
+const EXCINIB _kernel_excinib_table[TNUM_EXCNO] = {
+ <CPU例外ハンドラ1の初期化情報>,
+ <CPU例外ハンドラ2の初期化情報>,
+ ……
+ <CPU例外ハンドラTNUM_EXCNOの初期化情報>
+};
+
+この中のCPU例外ハンドラの初期化情報は,次の形式とする.
+
+ { (excno), (excatr), (FP)(EXC_ENTRY(excno, exchdr)) }
+
+(6-4) エラー条件
+
+CPU例外ハンドラに関するエラー条件は次の通りである.
+
+*パス2で検出するもの
+・excnoがDEF_EXCに対するCPU例外ハンドラ番号として正しくない場合(E_PAR)
+・excnoがDEF_EXCによって設定済みの場合(E_OBJ)
+・excatrが(TA_NULL)でない場合(E_RSATR)
+ ※ ターゲット依存部でCPU例外ハンドラ属性を追加可(TARGET_EXCATR)
+
+*必要に応じてターゲット依存部で検出するもの
+・exchdrがプログラムの開始番地として正しくない場合(E_PAR)
+
+(7) 非タスクコンテキスト用のスタック領域に関する定義
+
+非タスクコンテキスト用のスタック領域に関する定義は,必ず生成しなければ
+ならない.
+
+(7-1) DEF_ICSがない場合
+
+システムコンフィギュレーションファイルに,静的API「DEF_ICS」が含まれて
+いない場合には,次の行を生成する.
+
+#ifdef DEFAULT_ISTK
+
+#define TOPPERS_ISTKSZ DEFAULT_ISTKSZ
+#define TOPPERS_ISTK DEFAULT_ISTK
+
+#else /* DEFAULT_ISTK */
+
+static STK_T _kernel_istack[COUNT_STK_T(DEFAULT_ISTKSZ)];
+#define TOPPERS_ISTKSZ ROUND_STK_T(DEFAULT_ISTKSZ)
+#define TOPPERS_ISTK _kernel_istack
+
+#endif /* DEFAULT_ISTK */
+
+(7-2) DEF_ICSがある場合
+
+以下では,システムコンフィギュレーションファイルに次の静的APIが含まれて
+いる時に生成すべき情報について述べる.
+
+DEF_ICS({ istksz, istk });
+
+istkがNULLの場合には,指定されたサイズの非タスクコンテキスト用のスタッ
+ク領域を確保し,非タスクコンテキスト用のスタック領域の初期化情報を生成
+する.具体的には,上記の静的APIに対して,次の行を生成する.
+
+static STK_T _kernel_istack[COUNT_STK_T(istksz)];
+#define TOPPERS_ISTKSZ ROUND_STK_T(istksz)
+#define TOPPERS_ISTK _kernel_istack
+
+istkがNULLでない場合には,非タスクコンテキスト用のスタック領域の初期化
+情報を,次の形式で生成する.
+
+#define TOPPERS_ISTKSZ (istksz)
+#define TOPPERS_ISTK (istk)
+
+(7-3) 変数の生成
+
+DEF_ICSの有無によらず,次の定義を生成する.
+
+const SIZE _kernel_istksz = TOPPERS_ISTKSZ;
+STK_T *const _kernel_istk = TOPPERS_ISTK;
+
+#ifdef TOPPERS_ISTKPT
+STK_T *const _kernel_istkpt = TOPPERS_ISTKPT(TOPPERS_ISTK, TOPPERS_ISTKSZ);
+#endif /* TOPPERS_ISTKPT */
+
+(7-4) エラー条件
+
+非タスクコンテキスト用のスタック領域に関するエラー条件は次の通りである.
+
+*パス2で検出するもの
+・静的API「DEF_ICS」が複数ある(E_OBJ)
+・istkszがスタック領域のサイズとして正しくない場合(E_PAR)
+ - ターゲット依存の値(CHECK_STKSZ_ALIGN)の倍数でない場合
+ ※ このエラーチェックは,istkがNULLでない場合にのみ行う
+
+*パス3で検出するもの
+・istkがスタック領域の先頭番地として正しくない場合(E_PAR)
+ - ターゲット依存の値(CHECK_STACK_ALIGN)の倍数でない場合
+ - NULLの場合(ターゲット依存,CHECK_STACK_NONNULL)
+
+*必要に応じてターゲット依存部で検出するもの
+・istkszが小さすぎる場合(E_PAR)
+
+(8) タイムイベント管理に関する定義
+
+タイムイベント管理に関連して,次の定義を生成する.
+
+TMEVTN _kernel_tmevt_heap[TNUM_TSKID + TNUM_CYCID + TNUM_ALMID];
+
+(9) 各モジュールの初期化関数の定義
+
+各カーネルオブジェクトの管理,割込み管理,CPU例外ハンドラ管理の各機能を
+初期化関数を順に呼び出す関数(_kernel_initialize_object)を生成する.次
+の2つの初期化関数を除いては,使用しない機能の初期化関数は呼び出さない.
+
+ _kernel_initialize_interrupt
+ _kernel_initialize_exception
+
+すべての機能を使った場合に生成される関数は次の通りである.
+
+void
+_kernel_initialize_object(void)
+{
+ _kernel_initialize_task();
+ _kernel_initialize_semaphore();
+ _kernel_initialize_eventflag();
+ _kernel_initialize_dataqueue();
+ _kernel_initialize_pridataq();
+ _kernel_initialize_mailbox();
+ _kernel_initialize_mempfix();
+ _kernel_initialize_cyclic();
+ _kernel_initialize_alarm();
+ _kernel_initialize_interrupt();
+ _kernel_initialize_exception();
+}
+
+
+(10) 初期化ルーチンの実行関数の定義
+
+システムコンフィギュレーションファイル中に含まれる初期化ルーチンを追加
+する静的API「ATT_INI」に対して,追加した初期化ルーチンを順に呼び出す関
+数を生成する.具体的には,
+
+ATT_INI({ iniatr, exinf, inirtn });
+
+という静的APIに対して,
+
+ (inirtn)((intptr_t)(exinf));
+
+を呼び出す関数を,_kernel_call_inirtnという名前で生成する.初期化ルーチ
+ンを呼び出す順序は,システムコンフィギュレーションファイル中での静的
+APIの順序に一致させる.
+
+例えば,
+
+ATT_INI({ TA_NULL, 0, timer_initialize });
+ATT_INI({ TA_NULL, CONSOLE_PORTID, serial_initialize });
+
+という2つの静的APIがこの順序で記述された時に生成する関数は次の通りであ
+る.
+
+void
+_kernel_call_inirtn(void)
+{
+ (timer_initialize)((intptr_t)(0));
+ (serial_initialize)((intptr_t)(CONSOLE_PORTID));
+}
+
+(10-1) エラー条件
+
+初期化ルーチンに関するエラー条件は次の通りである.
+
+*パス2で検出するもの
+・iniatrが(TA_NULL)でない場合(E_RSATR)
+
+*必要に応じてターゲット依存部で検出するもの
+・inirtnがプログラムの開始番地として正しくない場合(E_PAR)
+
+(11) 終了処理ルーチンの実行関数の定義
+
+システムコンフィギュレーションファイル中に含まれる終了処理ルーチンを追
+加する静的API「ATT_TER」に対して,追加した終了処理ルーチンを順に呼び出
+す関数を生成する.具体的には,
+
+ATT_TER({ teratr, exinf, terrtn });
+
+という静的APIに対して,
+
+ (terrtn)((intptr_t)(exinf));
+
+を呼び出す関数を,_kernel_call_terrtnという名前で生成する.終了処理ルー
+チンを呼び出す順序は,システムコンフィギュレーションファイル中での静的
+APIの逆順に一致させる.
+
+例えば,
+
+ATT_TER({ TA_NULL, 0, timer_terminate });
+ATT_TER({ TA_NULL, CONSOLE_PORTID, serial_terminate });
+
+という2つの静的APIがこの順序で記述された時に生成する関数は次の通りであ
+る.
+
+void
+_kernel_call_terrtn(void)
+{
+ (serial_terminate)((intptr_t)(CONSOLE_PORTID));
+ (timer_terminate)((intptr_t)(0));
+}
+
+(11-1) エラー条件
+
+終了処理ルーチンに関するエラー条件は次の通りである.
+
+*パス2で検出するもの
+・teratrが(TA_NULL)でない場合(E_RSATR)
+
+*必要に応じてターゲット依存部で検出するもの
+・terrtnがプログラムの開始番地として正しくない場合(E_PAR)
+
+以上
--- /dev/null
+
+ TOPPERS/ASPカーネル
+ 設計メモ
+
+ 対応バージョン: Release 1.6.0
+ 最終更新: 2010年8月1日(作成中)
+
+このドキュメントは,TOPPERS/ASPカーネルの設計メモである.作成中のもので
+あり,網羅的ではない.
+
+----------------------------------------------------------------------
+ TOPPERS/ASP Kernel
+ Toyohashi Open Platform for Embedded Real-Time Systems/
+ Advanced Standard Profile Kernel
+
+ Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ Graduate School of Information Science, Nagoya Univ., JAPAN
+
+ 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ スコード中に含まれていること.
+ (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ の無保証規定を掲載すること.
+ (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ と.
+ (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ 報告すること.
+ (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ 免責すること.
+
+ 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ の責任を負わない.
+
+ $Id: design.txt 1877 2010-08-01 06:49:12Z ertl-hiro $
+----------------------------------------------------------------------
+
+○目次
+
+・TOPPERS/ASPカーネルの実装設計方針
+・システム状態とコンテキストの実装
+ - カーネル動作状態と非動作状態
+ - タスクコンテキストと非タスクコンテキスト
+ - 全割込みロック状態と全割込みロック解除状態
+ - CPUロック状態とCPUロック解除状態
+ - 割込み優先度マスク
+ - ディスパッチ禁止状態とディスパッチ許可状態
+ - ディスパッチ保留状態
+・タスク状態の管理とスケジューリング
+ - タスク状態の管理
+ - タスクスケジューラ
+・タスクディスパッチ処理の実装(★未完成)
+ - タスクディスパッチ処理の必要なタイミング
+ - タスクディスパッチャの構造
+・タスク例外処理機能の実装
+ - タスク例外処理ルーチンの実行開始条件とシステム状態(仕様の確認)
+ - タスク例外処理ルーチンの呼出し処理
+ - タスク例外処理ルーチンの実行開始が必要なタイミング
+ - タスク例外処理ルーチンの実行開始処理
+ - call_texrtnからdispatchを呼び出す処理について
+・CHECKマクロとgoto文の使用
+ - CHECKマクロの定義とその使用法
+ - 設計意図
+ - CHECKマクロを使用してよい条件
+ - 問題を生じることがない根拠
+・ext_tsk,ext_kerの返り値
+・カーネルのデータ構造に対するvolatile宣言について
+・型キャストに伴う警告メッセージ
+・優先度データキュー機能(未完成)
+・性能評価用システム時刻参照機能
+ - 必要性と使途
+ - API仕様
+ - 実装
+・タスク例外処理禁止フラグをenatexで実装している理由
+
+
+○TOPPERS/ASPカーネルの実装設計方針
+
+TOPPERS/ASPカーネル(以下,ASPカーネル)は,TOPPERS新世代カーネルの基盤
+となるリアルタイムカーネルである.TOPPERS新世代カーネル仕様の設計方針と,
+ASPカーネルの適用対象領域と設計方針については,TOPPERS新世代カーネル統
+合仕様書に述べられている.
+
+以下では,ASPカーネルの実装設計方針について述べるが,仕様設計方針とも関
+連しており,明確に分離できない部分もある.
+
+TOPPERS/ASPカーネルの実装設計を行うにあたり,次の方針を設定する.
+
+(1) ソースコードの読みやすさ・改造しやすさを重視する
+
+ソースコードが読みやすいことは,オープンソースソフトウェアの品質を向上
+させる上で最も重要な特性である.ソースコードを理解している技術者が増え
+ることで,問題を早期に発見することができ,サポート体制も充実させること
+ができる.また,ソースコードが読みやすいことは,シンプルな設計がされて
+いることも意味しており,信頼性向上にもつながる.さらに,技術者教育のた
+めの教材とする観点からも,ソースコードが読みやすいことは重要となる.
+
+改造しやすいことは,システム毎の要求にあわせたチューニングが行いやすい
+ことを意味しており,擦り合わせ型の開発を支援する性質である.また,ASPカー
+ネルを基盤としてTOPPERS新世代カーネルシリーズを開発していく上でも,改造
+しやすいことは必須の条件である.
+
+(2) 新しいターゲットシステムへのポーティングが容易な構造とする
+
+組込みシステムには多様なハードウェアが用いられるため,それらに容易にポー
+ティングできることは重要な性質である.そのために,実行性能に配慮しつつ
+ハードウェアを抽象化し,ターゲットシステムに依存する部分(ターゲット依
+存部)と依存しない部分(ターゲット非依存部)を明確に分離する.また,開
+発環境(コンパイラなど)に依存する部分も明確に分離する.
+
+(3) 検証が容易な構造とする
+
+信頼性を確保するために,検証が容易な構造とする.
+
+具体的には,サービスコールのほとんど全体を割込み禁止で実行することとし,
+サービスコールの処理途中で割込みを許可しない.この構造は,読みやすく改
+造しやすいソースコードにするためにも有効である.これにより割込み応答性
+が犠牲になるが,それによって問題を生じるアプリケーションは少数であり,
+やむをえないものと考える.
+
+また,条件コンパイル等によりコンフィギュレーションできる箇所を増やすと,
+細かな最適化ができる一方で,検証すべき組合せが増えることから,コンフィ
+ギュレーションできる箇所は必要最低限とする.
+
+(4) 実行性能とメモリ使用量に配慮する
+
+上記の方針を満たした上で,高い実行性能と小さいメモリ使用量を達成できる
+ような実装を行う.実行性能を向上させる際には,平均性能の向上よりも,最
+悪時性能の向上を重視する.
+
+ソースコードの読みやすさを重視すると言っても,実行性能の悪いアルゴリズ
+ムを安易に採用することはせず,高い実行性能を達成できるアルゴリズムを用
+いる.ただし,新しいターゲットシステムへのポーティングを容易にするため
+に大部分をC言語で実装しており,すべてをアセンブリ言語で記述した場合に比
+べて実行性能が落ちるのはやむをえない.
+
+メモリ使用量については,RAMの使用量を削減することに重点を置いた設計を行
+うが,上記の方針および実行性能とのトレードオフを考慮し,ぎりぎりまでの
+削減は行わない.
+
+(5) スケーラビリティに配慮する
+
+様々な規模のシステムに適用できるスケーラビリティをもった構造とする.特
+に,小規模なシステムに適用する際に,使用しない機能をカーネルが持ってい
+ることによるメモリ使用量の増加が最小限になるように配慮する.
+
+具体的には,アプリケーションとカーネルを1つのロードモジュールにリンクす
+る方法(1リンクモデル)を想定し,カーネルを関数単位でライブラリ化して,
+使用する関数のみがリンクされる構造とする.これは一種のコンフィギュレー
+ションであるが,この方法は,条件コンパイルによるコンフィギュレーション
+とは違い,検証工数に与える影響が小さい.
+
+また,固定的に使用するRAM領域を減らし,スタックに置ける情報はできる限り
+スタック上に置く.
+
+
+○システム状態とコンテキストの実装
+
+この章では,「TOPPERS新世代カーネル統合仕様書」の「2.5 システム状態とコ
+ンテキスト」の節に規定されているシステム状態とコンテキストの実装方法に
+ついて記述する.
+
+●カーネル動作状態と非動作状態
+
+カーネルの動作状態を管理するために,カーネル動作状態フラグ(kerflg)を
+用意する.kerflgは,スタートアップモジュールでfalse(=0)に初期化する.
+また,カーネル動作の開始時にtrueにし,カーネル動作の終了時にfalseにする.
+
+----------------------------------------
+bool_t kerflg = false;
+----------------------------------------
+
+kerflgは,sns_kerで参照する.カーネル非動作状態でsns_ker以外のサービス
+コールを呼び出した場合の動作は保証する必要がないため,他のサービスコー
+ルではkerflgを参照しない.
+
+●タスクコンテキストと非タスクコンテキスト
+
+タスクコンテキストと非タスクコンテキストの切換えは,ターゲットハードウェ
+アおよびターゲット依存部に委ねる.また,どちらのコンテキストで実行中で
+あるかを判別する関数(sense_context)も,ターゲット依存部で用意すること
+とする.
+
+●全割込みロック状態と全割込みロック解除状態
+
+全割込みロックフラグの管理はターゲット依存部に委ね,全割込みロック状態
+に遷移させるマクロ(SIL_LOC_INT)と,元の状態に戻すマクロ(SIL_UNL_INT)
+は,SILのターゲット依存部で用意することとする.全割込みロック状態である
+か否かを判別する機能は,必要がないために用意していない.
+
+全割込みロック状態でsns_kerとext_ker以外のサービスコールを呼び出した場
+合の動作は保証する必要がないため,サービスコール中で全割込みロック状態
+であることを判別する必要はない.
+
+●CPUロック状態とCPUロック解除状態
+
+CPUロックフラグの管理はターゲット依存部に委ね,CPUロック状態に遷移させ
+る関数(t_lock_cpu/i_lock_cpu/x_lock_cpu)と,CPUロック解除状態に遷移
+させる関数(t_unlock_cpu/i_unlock_cpu/x_unlock_cpu)は,ターゲット依
+存部で用意することとする.また,CPUロック状態であるか否かを判別する関数
+(t_sense_lock/i_sense_lock/x_sense_lock)も,ターゲット依存部で用意
+することとする.
+
+●割込み優先度マスク
+
+割込み優先度マスクの管理はターゲット依存部に委ね,割込み優先度マスクを
+設定する関数(t_set_ipm/i_set_ipm/x_set_ipm)と,それを参照する関数
+(t_get_ipm/i_get_ipm/x_get_ipm)は,ターゲット依存部で用意することと
+する.
+
+●ディスパッチ禁止状態とディスパッチ許可状態
+
+ディスパッチ禁止フラグを管理するために,フラグ(disdsp)を用意する.
+disdspは,カーネルの初期化時にfalseに初期化する.
+
+----------------------------------------
+bool_t disdsp;
+----------------------------------------
+
+●ディスパッチ保留状態
+
+ディスパッチ保留状態は,非タスクコンテキストの実行中,全割込みロック状
+態,CPUロック状態,割込み優先度マスクが全解除でない状態,ディスパッチ禁
+止状態のいずれか(または,それらが重なった状態)である.
+
+ディスパッチ保留状態でないことを効率的に判別するために,割込み優先度マ
+スク全解除状態であり,ディスパッチ許可状態である(ディスパッチ禁止状態
+でない)ことを示すフラグ(dspflg)を用意する.dspflgは,カーネルの初期
+化時にtrueに初期化する.また,割込み優先度マスクの値が変更されるか,割
+込み禁止フラグが変更される度に更新する.
+
+----------------------------------------
+bool_t dspflg;
+----------------------------------------
+
+
+○タスク状態の管理とスケジューリング
+
+●タスク状態の管理
+
+タスク管理ブロック(TCB)中のタスク状態を管理するフィールド(tstat)で
+は,タスク状態が次のいずれであるかを管理する.
+
+ ・実行できる状態
+ ・休止状態
+ ・(狭義の)待ち状態
+ ・強制待ち状態
+ ・二重待ち状態
+
+タスクが実行できる状態の時に,実行状態であるか実行可能状態であるかは,
+このフィールドでは管理せず,実行状態のタスクのTCBを指すポインタ変数
+(p_runtsk)によって判別する.実行状態のタスクがない場合は,p_runtskは
+NULLにする.
+
+----------------------------------------
+TCB *p_runtsk;
+----------------------------------------
+
+p_runtskは,カーネルの初期化時にNULLに初期化し,ディスパッチャにおいて
+更新する.サービスコールの処理の中で自タスクに関する情報を参照する場合
+は,p_runtskを用いる.
+
+●タスクスケジューラ
+
+タスクスケジューラは,実行できる状態のタスクの中から,最も優先順位が高
+いタスク(これを,最高優先順位のタスクと呼ぶ)を決定し,そのタスクの
+TCBを指すポインタ変数(p_schedtsk)を設定する.
+
+----------------------------------------
+TCB *p_schedtsk;
+----------------------------------------
+
+タスクスケジューラに対しては,どのタスクが実行できる状態であるかを知ら
+せる必要がある.そのため,タスクスケジューラは,次の2つの関数を用意する.
+
+ ・タスクが実行できる状態に遷移したことを知らせる関数(make_runnable)
+ ・タスクが実行できる状態から他の状態へ遷移したことを知らせる関数
+ (make_non_runnable)
+
+また,処理の効率化のために,上の2つの関数を用いずにレディキューを直接操
+作してタスクスケジュールを行う関数として,次の2つの関数を用意する.
+
+ ・タスクの優先度の変更(change_priority)
+ ・レディキューの回転(rotate_ready_queue)
+
+
+○タスクディスパッチ処理の実装
+
+●タスクディスパッチ処理の必要なタイミング
+
+タスクディスパッチは,実行状態のタスク(p_runtsk)と最高優先順位のタス
+ク(p_schedtsk)が一致しておらず,ディスパッチ保留状態でない場合に行う.
+このことから,タスクディスパッチ処理を行う必要があるのは,次の3つの場合
+である.
+
+(1) 実行状態のタスクが実行できる状態でなくなる
+
+自タスクを広義の待ち状態に遷移させるサービスコールや,自タスクを終了さ
+せるサービスコールにおいて,タスクディスパッチ処理を行う必要がある.
+
+(2) 最高優先順位のタスクが変化する
+
+タスクの起動,タスクの待ち解除,タスクの強制待ちからの再開,タスクの優
+先度の変更,タスクの優先順位の回転を行うサービスコールにおいて,最高優
+先順位のタスクが変化し,ディスパッチ保留状態でない場合には,タスクディ
+スパッチ処理を行う必要がある.
+
+(3) ディスパッチ保留状態が解除される
+
+ディスパッチ保留状態とは,非タスクコンテキストの実行中,CPUロック状態,
+割込み優先度マスクが全解除でない状態,ディスパッチ禁止状態の総称である
+ため,これらの状態のいずれかが遷移するタイミングで,タスクディスパッチ
+処理を行う必要がある.具体的には,次のタイミングが該当する.
+
+(3-1) 非タスクコンテキストからタスクコンテキストに遷移する
+
+割込みハンドラまたはCPU例外ハンドラからタスクにリターンする際に,タスク
+ディスパッチ処理を行う必要がある.
+
+(3-2) CPUロック状態が解除される
+
+CPUロック状態においては,上記の(1)や(2)の状況を作り出すサービスコールを
+呼び出すことができないため,CPUロック状態の解除時には,タスクディスパッ
+チ処理を行う必要がない.
+
+(3-3) 割込み優先度マスクが全解除される
+
+割込み優先度マスクの変更(chg_ipm)により割込み優先度マスクが全解除され
+る場合に,タスクディスパッチ処理を行う必要がある.
+
+また,タスクの終了,タスク例外処理ルーチンからのリターン,割込みハンド
+ラからのリターン,割込みサービスルーチンからのリターン,タイムイベント
+ハンドラからのリターン,CPU例外ハンドラからのリターンによって,割込み優
+先度マスクが全解除される場合があり,その場合には,タスクディスパッチ処
+理を行う必要がある.ただし,割込みサービスルーチンおよびタイムイベント
+ハンドラからのリターンについては,リターン後も非タスクコンテキストであ
+り,タスクディスパッチ保留状態が継続することから,タスクディスパッチ処
+理を行う必要がない.
+
+(3-4) ディスパッチ許可状態になる
+
+ディスパッチの許可(ena_dsp)において,タスクディスパッチ処理を行う必要
+がある.
+
+また,タスクの終了とタスク例外処理ルーチンからのリターンによって,ディ
+スパッチ許可状態になる場合があり,その場合には,タスクディスパッチ処理
+を行う必要がある.
+
+これに加えて,カーネルの動作開始時にも,タスクディスパッチ処理を呼び出
+す.
+
+●タスクディスパッチャの構造
+
+タスクディスパッチャの主な機能は,切換え前のタスクのコンテキスト(プロ
+セッサの汎用レジスタ等)をメモリ上に保存し,切換え後のタスクのコンテキ
+ストをメモリ上から復帰することである.ここで,保存/復帰しなければなら
+ないレジスタは,タスクディスパッチャが実行される状況によって,次のよう
+な違いがある.
+
+・タスクが割込み(または,CPU例外)によりプリエンプトされる場合には,す
+ べてのレジスタを保存しなければならない.また,その状態から実行再開す
+ る場合には,すべてのレジスタを復帰しなければならない.
+
+・タスクが自発的にタスクディスパッチャを呼び出す場合には,スクラッチレ
+ ジスタ(caller saved register)以外のレジスタを保存すればよい.また,
+ その状態から実行再開する場合には,スクラッチレジスタ以外のレジスタを
+ 復帰すればよい.
+
+・タスクが終了する場合には,どのレジスタも保存する必要がない.
+
+・タスクが実行開始する場合には,どのレジスタも復帰する必要がない.
+
+そこで,それぞれの状況で必要最低限のレジスタのみを保存/復帰するために,
+タスクディスパッチ処理を,(a) コンテキストの保存処理,(b) 実行するタス
+クの選択処理,(c) コンテキストの復帰処理の3つのステップで構成し,(a)と
+(c)のステップについては,タスクディスパッチャが実行される状況毎に用意す
+る.具体的には,次の各処理を行うルーチンを用意する.
+
+(a) コンテキストの保存処理
+ (a-1) タスクが自発的に呼び出した場合の保存処理(dispatch)
+ (a-2) 割込みハンドラの出口で呼び出された場合の保存処理(ret_int)
+ (a-3) CPU例外ハンドラの出口で呼び出された場合の保存処理(ret_exc)
+ (a-4) タスクの終了時の処理(exit_and_dispatch)
+ (a-5) カーネルの動作開始時の処理(start_dispatch)
+(b) 実行するタスクの選択(ディスパッチャ本体,dispatcher)
+(c) コンテキストの復帰処理
+ (c-1) タスクが自発的に呼び出した場合の復帰処理(dispatch_r)
+ (c-2) 割込みハンドラの出口で呼び出された場合の復帰処理(ret_int_r)
+ (c-3) CPU例外ハンドラの出口で呼び出された場合の復帰処理(ret_exc_r)
+ (c-4) タスクの実行開始時の処理(start_r)
+
+
+○タスク例外処理機能の実装
+
+●タスク例外処理ルーチンの実行開始条件とシステム状態(仕様の確認)
+
+タスク例外処理ルーチンは,次の5つの条件が揃った場合に実行が開始される.
+
+ ・タスク例外処理許可状態である
+ ・保留例外要因が0でない
+ ・タスクが実行状態である
+ ・タスクコンテキストが実行されている
+ ・CPUロック状態でない
+
+また,タスク例外処理ルーチンの起動/リターン時のシステム状態に関する仕
+様は次の通りである.
+
+ CPUロック 割込み優先度 ディスパッチ
+ フラグ マスク 禁止フラグ
+------------------------------------------------------------
+【タスク例外処理ルーチン】
+実行開始条件 解除 任意 任意
+実行開始時処理 そのまま そのまま そのまま
+リターン前 原則解除(*1) 原則元に(*1) 原則元に(*1)
+リターン時処理 解除する 元に戻す(*4) 元に戻す(*4)
+------------------------------------------------------------
+
+●タスク例外処理ルーチンの呼出し処理
+
+タスク例外処理ルーチンを呼び出す処理は,次の流れとなる.この関数は,
+CPUロック状態で呼び出すことを想定している.
+
+----------------------------------------
+void
+call_texrtn(void)
+{
+ TEXPTN texptn;
+
+ texptn = p_runtsk->texptn;
+ p_runtsk->texptn = 0U;
+
+ タスク例外処理禁止状態にする
+ ディスパッチ禁止フラグを保存する
+ 割込み優先度マスクを保存する
+
+ CPUロック解除状態にする
+ タスク例外処理ルーチンを呼び出す
+ CPUロック状態にする
+
+ 割込み優先度マスクを元に戻す
+ ディスパッチ禁止フラグを元に戻す
+ タスク例外処理禁止状態にする … (*2)
+
+ 必要な場合にはディスパッチを行う … (*1)
+
+ タスク例外処理許可状態にする
+}
+----------------------------------------
+
+(*1)において,必要な場合にタスク切換えを行うのは,割込み優先度マスクと
+ディスパッチ禁止フラグを元に戻した結果,ディスパッチ保留状態が解除され,
+ディスパッチが必要になる場合があるためである.
+
+また,ディスパッチを行う前にタスク例外処理禁止状態にする(*2)理由につい
+ては,「call_texrtnからdispatchを呼び出す処理について」の節を参照するこ
+と.
+
+●タスク例外処理ルーチンの実行開始が必要なタイミング
+
+タスク例外処理ルーチンは,前述の5つの条件が揃った場合に実行開始すべきで
+あるため,5つの条件のいずれかを新たに満たすようになる可能性のあるタイミ
+ングで,タスク例外処理ルーチンの実行開始が必要になる.
+
+以下では,5つの条件のいずれかを新たに満たすようになるタイミングについて
+検討する.
+
+(1) タスク例外処理許可状態である
+
+タスク例外処理の許可(ena_tex)によって,タスク例外処理許可状態になる.
+また,タスク例外処理ルーチンからのリターンによっても,タスク例外処理許
+可状態になる.
+
+(2) 保留例外要因が0でない
+
+タスク例外処理の要求(ras_tex,iras_tex)によって,タスクの保留例外要因
+が0でなくなる.ただし,非タスクコンテキストからのタスク例外処理の要求
+(iras_tex)では,(4)の条件が満たされないため,タスク例外処理ルーチンの
+実行開始は必要ない.
+
+(3) タスクが実行状態である
+
+タスクディスパッチャにより,切換え後のタスクが実行状態になる.
+
+(4) タスクコンテキストが実行されている
+
+割込みハンドラおよびCPU例外ハンドラからのリターンによって,タスクコンテ
+キストに戻る場合がある.
+
+(5) CPUロック状態でない
+
+CPUロック状態の解除(unl_cpu,iunl_cpu)によって,CPUロック状態でなくな
+る.ただし,非タスクコンテキストでのCPUロック状態の解除(iunl_cpu)では,
+(4)の条件が満たされないため,タスク例外処理ルーチンの実行開始は必要ない.
+
+また,タスクの終了,タスク例外処理ルーチンからのリターン,割込みハンド
+ラからのリターン,割込みサービスルーチンからのリターン,タイムイベント
+ハンドラからのリターン,CPU例外ハンドラからのリターンによって,CPUロッ
+ク状態でなくなる場合もある.
+
+ただし,割込みサービスルーチンおよびタイムイベントハンドラからのリター
+ンについては,リターン後も非タスクコンテキストの実行が続き,(4)の条件が
+満たされないため,タスク例外処理ルーチンの実行開始は必要ない.
+
+タスクの終了時については,タスクの終了後は別のタスクへ切り換わるため,
+切り換わった後のタスクに対するタスク例外処理ルーチンの実行開始を,タス
+クディスパッチ後の処理で行えばよい.
+
+以上より,重複するケースを考慮すると,タスク例外処理ルーチンの実行開始
+が必要になる可能性があるのは,以下の処理である.
+
+(a) タスク例外処理の許可(ena_tex)… (1)
+(b) タスク例外処理ルーチンの出口処理 … (1)(5)
+(c) タスク例外処理の要求(ras_tex)… (2)
+(d) タスクディスパッチ後の処理 … (3)(5)
+ (d-1) dispatch_r
+ (d-2) ret_int_r
+ (d-3) ret_exc_r
+ (d-4) start_r
+(e) 割込みハンドラの出口処理 … (4)(5)
+(f) CPU例外ハンドラの出口処理 … (4)(5)
+(g) CPUロック状態の解除(unl_cpu)… (5)
+
+この中で(d-4)に関しては,タスクの実行開始直後はタスク例外処理禁止状態で
+あり(自タスクがena_texするまでは,タスク例外が許可されない),(1)の条
+件が満たされないため,タスク例外処理ルーチンの実行開始は必要ない.
+
+また(g)に関しては,次に述べる理由により,CPUロック状態が継続している間
+に他の4つの条件が新たに満たされることはないため,タスク例外処理ルーチン
+の実行開始は必要ない.
+
+CPUロック状態では,まず,タスク例外処理の許可(ena_tex)とタスク例外処
+理の要求(ras_tex,iras_tex)を行うことはできず,タスクディスパッチも起
+こらない.CPUロック状態でタスク例外処理ルーチンからリターンすることはで
+きるが,この場合はCPUロック状態も解除され,CPUロック状態が継続しない.
+CPUロック状態で割込みハンドラからリターンした場合も,これと同様である.
+
+最後に,CPUロック状態でCPU例外ハンドラからリターンした場合が問題になる.
+これについては,CPU例外が発生した時に,CPUロック状態であった場合と,
+CPUロック解除状態であった場合に分けて考える.CPUロック解除状態であった
+場合には,CPU例外ハンドラからのリターンにより,CPUロック状態が解除され
+るため,割込みハンドラからリターンした場合と同様である.CPUロック状態で
+あった場合には,起動されるCPU例外ハンドラはカーネル管理外のCPU例外ハン
+ドラであるため,その中で(1)〜(3)の条件が新たに満たされることはない.
+CPU例外ハンドラの実行前後で(4)の条件は保存されることから,CPU例外ハンド
+ラからのリターンによって,(1)〜(4)の条件はCPU例外の発生前に戻り,新たに
+満たされることはない.
+
+●タスク例外処理ルーチンの実行開始処理
+
+ここでは,前の節で検討したタスク例外処理ルーチンの実行開始が必要なタイ
+ミングのそれぞれについて,実行開始処理の実装方法について述べる.
+
+(a) タスク例外処理の許可(ena_tex)
+
+ena_texがタスクから呼び出された場合には,自タスクに対して「タスクが実行
+状態である」「タスクコンテキストが実行されている」の2条件は満たされてお
+り,「タスク例外処理許可状態である」の条件はena_texの処理により満たされ
+る.そのため,「保留例外要因が0でない」が満たされている場合には,タスク
+例外処理ルーチンを呼び出す.
+
+ena_texの本体の処理(エラー処理を除く)は次の通り.
+
+----------------------------------------
+ p_runtsk->enatex = true;
+ if (p_runtsk->texptn != 0U) {
+ call_texrtn();
+ }
+----------------------------------------
+
+(b) タスク例外処理ルーチンの出口処理
+
+タスク例外処理ルーチンの出口処理(call_texrtnの後半)では,自タスクに対
+して「タスクが実行状態である」「タスクコンテキストが実行されている」の
+2条件は満たされており,「タスク例外処理許可状態である」の条件が出口処理
+で満たされる.そのため,「保留例外要因が0でない」が満たされている場合に
+は,タスク例外処理ルーチンを呼び出す必要がある.
+
+ただし,タスク例外処理ルーチンの出口処理で単純にcall_texrtnを呼び出すと,
+call_texrtnの中からcall_texrtnを呼び出すことになり,タスク例外処理が繰
+り返し要求された場合に,スタックの使用量に上限がなくなる.そこで,タス
+ク例外処理ルーチンの出口処理で「保留例外要因が0でない」場合には,
+call_texrtnの中でループさせる.
+
+修正したcall_texrtnの流れは次の通り.
+
+----------------------------------------
+void
+call_texrtn(void)
+{
+ TEXPTN texptn;
+
+ ディスパッチ禁止フラグを保存する … (*3)
+ 割込み優先度マスクを保存する … (*3)
+ タスク例外処理禁止状態にする … (*6)
+
+ do {
+ texptn = p_runtsk->texptn;
+ p_runtsk->texptn = 0U;
+
+ CPUロック解除状態にする
+ タスク例外処理ルーチンを呼び出す
+ CPUロック状態にする
+
+ 割込み優先度マスクを元に戻す … (*4)
+ ディスパッチ禁止フラグを元に戻す … (*4)
+ タスク例外処理禁止状態にする … (*2)
+
+ 必要な場合にはディスパッチを行う … (*1)
+ } while (p_runtsk->texptn != 0U);
+
+ タスク例外処理許可状態にする … (*5)
+}
+----------------------------------------
+
+タスク例外処理ルーチンの呼出し前にディスパッチ禁止フラグと割込み優先度
+マスクを保存する処理は,(*4)においてそれらを元の状態に戻すことから,ルー
+プの外(*3)で行うのが効率がよい.また,タスク例外処理ルーチンの呼出し前
+にタスク例外処理禁止状態にする処理は,(*2)においてタスク例外処理禁止状
+態にすることから,ループ外(*6)で行うのが効率がよい.
+
+また,タスク例外処理ルーチンの呼出し後にタスク例外処理許可状態にする処
+理も,ループの外(*5)で行う方が効率がよい.
+
+(c) タスク例外処理の要求(ras_tex)
+
+ras_texがタスクから呼び出された場合で,対象タスクが自タスクの場合には,
+自タスクに対して「タスクが実行状態である」「タスクコンテキストが実行さ
+れている」の2条件は満たされており,「保留例外要因が0でない」の条件は
+ras_texの処理により満たされる(ras_texのパラメータrasptnが0の場合はエラー
+となるため).そのため,対象タスクが自タスクであり,「タスク例外処理許
+可状態である」が満たされている場合には,タスク例外処理ルーチンを呼び出
+す.
+
+ras_texの本体の処理(エラー処理を除く)は次の通り.
+
+----------------------------------------
+ p_tcb->texptn |= rasptn;
+ if (p_tcb == p_runtsk && p_runtsk->enatex) {
+ call_texrtn();
+ }
+----------------------------------------
+
+(d-1) dispatch_r
+
+dispatch_rにおいては,dispatch_rからのリターン先のタスクに対して,「タ
+スクが実行状態である」「タスクコンテキストが実行されている」の2条件は満
+たされている.そのため,「タスク例外処理許可状態である」「保留例外要因
+が0でない」の2条件が満たされている場合には,タスク例外処理ルーチンを呼
+び出す必要がある.
+
+これを実現するために,タスクコンテキストからのディスパッチ処理を次のよ
+うに修正する.
+
+----------------------------------------
+void
+dispatch(void)
+{
+ ………
+
+ dispatch_r:
+ スクラッチレジスタを除くすべてのレジスタをスタックから復帰する
+ calltex();
+}
+----------------------------------------
+
+ここでcalltexは,「タスク例外処理許可状態である」「保留例外要因が0でな
+い」の2条件が満たされている場合にcall_texrtnを呼び出す関数である.
+
+----------------------------------------
+void
+calltex(void)
+{
+ if (p_runtsk->enatex && p_runtsk->texptn != 0U) {
+ call_texrtn();
+ }
+}
+----------------------------------------
+
+(d-2) ret_int_r
+(d-3) ret_exc_r
+
+ret_int_r/ret_exc_rは,割込みハンドラ/CPU例外ハンドラの出口処理でディ
+スパッチを行ったタスクが,実行を再開する際の処理である.そのため,
+ret_int_r/ret_exc_rからのリターン先のタスクに対して,「タスクが実行状
+態である」「タスクコンテキストが実行されている」の2条件は満たされている.
+そのため,「タスク例外処理許可状態である」「保留例外要因が0でない」の2
+条件が満たされている場合には,タスク例外処理ルーチンを呼び出す必要があ
+る.
+
+これを実現するために,割込みハンドラ/CPU例外ハンドラの出入口処理を次の
+ように修正する.
+
+----------------------------------------
+void
+<割込みの出入口処理>(void)
+{
+ ………
+
+ ret_int_r:
+ スクラッチレジスタを除くすべてのレジスタをスタックから復帰する
+ calltex();
+ }
+ ………
+}
+----------------------------------------
+void
+<CPU例外の出入口処理>(void)
+{
+ ………
+
+ ret_exc_r:
+ スクラッチレジスタを除くすべてのレジスタを
+ スタックから復帰する
+ calltex();
+ }
+ ………
+}
+----------------------------------------
+
+(e) 割込みハンドラの出口処理
+(f) CPU例外ハンドラの出口処理
+
+割込みハンドラ/CPU例外ハンドラからタスクへリターンする場合には,リター
+ン先のタスクに対して,「タスクが実行状態である」「タスクコンテキストが
+実行されている」の2条件は満たされている.そのため,「タスク例外処理許可
+状態である」「保留例外要因が0でない」の2条件が満たされている場合には,
+タスク例外処理ルーチンを呼び出す必要がある.
+
+割込みハンドラ/CPU例外ハンドラの呼出し前と呼出し後でこれらの条件が変化
+するのは,実行状態のタスクが変化した時と,割込みハンドラ/CPU例外ハンド
+ラ中でiras_texが呼び出された場合である.割込みハンドラ/CPU例外ハンドラ
+からはena_texを呼び出せないため,「タスク例外処理許可状態である」の条件
+が変化することはない.
+
+この2つの中で,実行状態のタスクが変化するケースは,ret_int_r/ret_exc_r
+で考慮済みである.割込みハンドラ/CPU例外ハンドラ中でiras_texが呼び出さ
+れた場合には,reqflgがtrueになるため,タスク例外処理ルーチンの実行開始
+処理は,reqflgがtrueの時にのみ行えばよい.
+
+これを実現するために,上で修正した割込みハンドラ/CPU例外ハンドラの出入
+口処理を,さらに次のように修正する.
+
+----------------------------------------
+void
+<割込みの出入口処理>(void)
+{
+ ………
+
+ if (タスクコンテキストで割込み発生) {
+ ………
+ if (reqflg) {
+ ………
+
+ ret_int_r:
+ スクラッチレジスタを除くすべてのレジスタをスタックから復帰する
+ }
+ calltex();
+ }
+ }
+ ………
+}
+----------------------------------------
+void
+<CPU例外の出入口処理>(void)
+{
+ ………
+ if (タスクコンテキストでCPU例外発生) {
+ ………
+ if (reqflg) {
+
+ ret_exc_r:
+ スクラッチレジスタを除くすべてのレジスタを
+ スタックから復帰する
+ }
+ calltex();
+ }
+ }
+ ………
+}
+----------------------------------------
+
+●call_texrtnからdispatchを呼び出す処理について
+
+dispatch_rから(ターゲットによってはcalltexを経由して)call_texrtnを呼
+び出し,call_texrtnからdispatchを呼び出すため,この2つの関数は相互再帰
+呼出しをしている.ここでは,この実装で支障のない理由を説明する.
+
+call_texrtnからdispatchを呼び出すのは,ディスパッチが保留されていない状
+態で呼び出されたタスク例外処理ルーチンが,その実行中にディスパッチ保留
+状態に遷移し,さらにタスクディスパッチを必要とする処理を行い,ディスパッ
+チ保留状態を解除しないままリターンした場合である.この場合,call_texrtn
+の中でディスパッチ保留状態を解除した後に,dispatchを呼び出してタスクディ
+スパッチを行う.つまり,call_texrtnからdispatchを呼び出す処理は,タスク
+例外処理ルーチンの中でディスパッチ保留状態を解除すべきであったのを,解
+除せずにリターンした場合を救済するためのものである.以下,この振舞いを
+「救済ケース」と呼ぶ.
+
+そこで,比較のために,タスク例外処理ルーチンの最後で,正しくディスパッ
+チ保留状態を解除してからリターンした場合の振舞いを考える.この場合には,
+ディスパッチ保留状態を解除するサービスコール(ena_dsp,chg_ipm)の中で,
+dispatchが呼び出されてタスクディスパッチが起こる.以下,この振舞いを
+「正常ケース」と呼ぶ.
+
+正常ケースと救済ケースを比較すると,call_texrtn→タスク例外処理ルーチン
+→サービスコール→dispatchの順でdispatchが呼び出されるか,call_texrtnか
+ら直接dispatchが呼び出されるかの違いということになり,救済ケースの方が
+スタックの使用量は少ない.つまり,正常ケースの動きを想定してスタック領
+域が用意してあれば,救済ケースでも問題なく動作することになる.
+
+ここで,正常ケースと救済ケースで,上記以外に違いがないことが重要である.
+具体的には,call_texrtnの中で,タスク例外処理許可状態にする(p_runtsk
+->enatexをtrueにする)前に,dispatchを呼び出すことが重要である.タスク
+例外処理許可状態にした後にdispatchを呼び出すと,出口のdispatch_rで,再
+びタスク例外処理ルーチンを実行してしまう可能性があり,救済ケースの方が
+スタックの使用量が増えてしまう.
+
+タスク例外処理ルーチンの中で,タスク例外処理許可状態にしたままリターン
+した場合には,call_texrtnから呼び出したdispatchの出口のdispatch_rで再び
+タスク例外処理ルーチンを実行してしまう可能性がある.この場合も,タスク
+例外処理ルーチンの最後で,ディスパッチ保留状態を解除してからリターンし
+た場合よりはスタックの使用量が少ないが,タスク例外処理禁止状態にした後
+にディスパッチ保留状態を解除してリターンした場合よりは,スタックの使用
+量が増える場合がある.そこで,このような状況が起こらないように,
+dispatchを呼ぶ前にp_runtsk->enatexをfalseにする.
+
+
+○CHECKマクロとgoto文の使用
+
+ASPカーネルの実装においては,サービスコールの静的なエラーをチェックする
+ために,名称が"CHECK_"で始まる一連のマクロ(これらを,CHECKマクロと総称
+する)を用いている.
+
+CHECKマクロの定義中にはgoto文を含んでいるが,MISRA-Cなどのコーディング
+ルールではgoto文の使用を禁止しており,goto文を使うべきではないという意
+見も多い.また,マクロの定義中にgoto文を使用することが問題であるという
+意見もある.
+
+ここでは,定義中にgoto文を含むCHECKマクロを用いる設計意図とそれを使用し
+てよい条件,CHECKマクロの使用によりソフトウェアの信頼性に問題が生じるこ
+とがないことを論証する.
+
+なお,ASPカーネルのカーネル本体の実装では,CHECKマクロ以外にgoto文を用
+いている箇所はない(一部のシステムサービスでは,これ以外の方法でgoto文
+を用いている).
+
+●CHECKマクロの定義とその使用法
+
+kernel/check.hには,25個のCHECKマクロが定義されているが,いずれも次のパ
+ターンで定義されている.ここでXXXXXには,チェックしたいエラーの種類を表
+す文字列が入る.
+
+----------------------------------------
+#define CHECK_XXXXX(<……>) { \
+ if (<エラー条件>) { \
+ ercd = <エラーコード>; \
+ goto error_exit; \
+ } \
+}
+----------------------------------------
+
+これらのCHECKマクロは,多くのサービスコールの処理関数中で,次のように使
+用されている.
+
+----------------------------------------
+ER
+<サービスコール名>(……)
+{
+ <ローカル変数の宣言>
+ ER ercd;
+
+ LOG_XXX_YYY_ENTER(……);
+ CHECK_XXXXX(……);
+ CHECK_YYYYY(……);
+
+ <サービスコール処理本体>
+
+ error_exit:
+ LOG_XXX_YYY_LEAVE(……);
+ return(ercd);
+}
+----------------------------------------
+
+この例では,CHECKマクロを2つ使用しているが,1つのみ使用している場合もあ
+れば,3つ以上使用している場合もある.また,複数のCHECKマクロの間に,ロー
+カル変数への代入文が入る場合もある(例えば,ter_tskの処理関数).
+
+●設計意図
+
+CHECKマクロを使用する意図は,ほとんどのサービスコールで必要な静的エラー
+のチェックコードをパターン化し,ソースコードの簡潔さを保つことで読みや
+すさを向上させるとともに,記述ミスの可能性を減らすことである.
+
+ちなみに,CHECKマクロを使用しない場合,上に示したサービスコールの処理関
+数は,次のように記述することになる.
+
+----------------------------------------
+ER
+<サービスコール名>(……)
+{
+ <ローカル変数の宣言>
+ ER ercd;
+
+ LOG_XXX_YYY_ENTER(……);
+ if (<XXXXXのエラー条件>) {
+ ercd = <XXXXXのエラーコード>;
+ }
+ else {
+ if (<YYYYYのエラー条件>) {
+ ercd = <YYYYYのエラーコード>;
+ }
+ else {
+
+ <サービスコール処理本体>
+
+ }
+ }
+ LOG_XXX_YYY_LEAVE(……);
+ return(ercd);
+}
+----------------------------------------
+
+CHECKマクロの内容を知っているという前提の下では,元のソースコードの方が
+読みやすいのは明らかである.
+
+なお,このようなCHECKマクロの定義には,goto文の使用が不可避である.
+
+●CHECKマクロを使用してよい条件
+
+CHECKマクロは,次の条件を満たすように使用しなければならない.
+
+(1) CHECKマクロは,サービスコール処理関数の先頭部分で,サービスコール入
+ 口のログを出した後,クリティカルセクションに入る前までに,処理関数
+ のトップレベルで用いる.
+
+(2) サービスコール処理関数の末尾部分で,クリティカルセクションを抜けた
+ 後,サービスコール出口のログを出す前に,処理関数のトップレベルに,
+ error_exitラベルを置く.
+
+●問題を生じることがない根拠
+
+このような方法でgoto文を使用しても,ソフトウェアの信頼性に問題が生じる
+ことがないことを主張するには,そもそも,MISRA-Cなどのコーディングルール
+でgoto文の使用を禁止している根拠,言い換えると,goto文の使用によりソフ
+トウェアの信頼性に問題が生じる可能性のある理由を明らかにする必要がある.
+
+MISRA-Cのドキュメントでは,goto文の使用を禁止する根拠についてあまり明確
+になっておらず,ここではその根拠を次のように推測する.
+
+・処理の流れが複雑になり,プログラムの意図が読みにくくなる(いわゆる,
+ スパゲッティプログラムになる).
+
+CHECKマクロの場合には,goto文をエラー発生時の強制脱出に用いており,ラベ
+ルもerror_exitとするなど,プログラムの意図は明らかである.一方,このよ
+うにgoto文をエラー時の強制脱出に用いる場合には,次の点もgoto文の使用を
+禁止する根拠になりうる.
+
+・goto文で強制脱出することにより,脱出時に行わなければならない後処理が
+ 飛ばされるおそれがある.
+
+ただしこの点についても,CHECKマクロを上記の使用条件を満たして使う限りは,
+脱出時に行わなければならない後処理はなく,CHECKマクロの使用によりソフト
+ウェアの信頼性に問題が生じることはない.
+
+問題を生じることがないことを論証するもう1つ方法は,コーディングルールに
+合致しないプログラムが,コーディングルールに合致したプログラムと等価で
+あることを示す方法である.
+
+すでに「設計意図」の節で述べたように,CHECKマクロを使用したプログラムは,
+goto文を使用しない等価なプログラムに書き換えることができるが,より一般
+的には,次のことが言える.
+
+else部を持たないif文のthen部の最後に,if文より下(前方)にあり,if文と
+同じブロック内の同じ階層のラベルへ分岐するgoto文がある場合には,if文と
+ラベルの間の文をelse部にすることにより,goto文を使わない等価なプログラ
+ムに書き換えることができる.
+
+例として,goto文を使った次のプログラムを考える.
+
+----------------------------------------
+ {
+ /* if文の前の文 */
+ if (....) {
+ /* then部の文 */
+ goto <ラベル>;
+ }
+ /* if文とラベルの間の文 */
+ <ラベル>:
+ /* ラベルより後ろの文 */
+ }
+----------------------------------------
+
+このプログラムは,goto文を使わない次のプログラムと等価である.
+
+----------------------------------------
+ {
+ /* if文の前の文 */
+ if (....) {
+ /* then部の文 */
+ }
+ else {
+ /* if文とラベルの間の文 */
+ }
+ /* ラベルより後ろの文 */
+ }
+----------------------------------------
+
+この条件に合致するgoto文が複数ある場合には,下にあるgoto文から順に上記
+の方法によって書き換えることで,goto文を使わない等価なプログラムに書き
+換えることができる.
+
+CHECKマクロの使用方法は,上記のgoto文の使用方法に合致するため,goto文を
+使用しない等価なプログラムに書き換えることができる.よって,このCHECKマ
+クロにより問題を生じることはない.
+
+
+○ext_tsk,ext_kerの返り値
+
+μITRON4.0仕様では,ext_tskはリターンすることのないサービスコールとなっ
+ているが,TOPPERS新世代カーネルにおいては,このサービスコールの返り値を
+ER型に変更し,非タスクコンテキストから呼ばれた場合には,E_CTXエラーを返
+り値としてリターンすることとする.
+
+この仕様に対するいくつかの対案を検討したが,以下の理由で採用しない.
+
+・JSPカーネルのように,危険の可能性を検出しながら実行を継続する方法は,
+ 信頼性・安全性を重視するシステムでは望ましくない.信頼性・安全性を重
+ 視するシステムでは,危険の可能性を検出したら,早期にリカバリをすべき
+ である.
+
+・ASPカーネルの当初案のカーネルをダウンさせる方法は,アプリケーション側
+ で回復する余地をなくすという意味で望ましくない.
+
+・過去の互換性を保つために,型をvoidとしたまま,非タスクコンテキストか
+ ら呼ばれた場合にはリターンするとする方法は,カーネルの仕様変更に気づ
+ きにくくなるという意味で望ましくない.また,他のエラーコード(例えば
+ E_NOSPT)を返す余地をなくしている.
+
+・一種のCPU例外を呼び出すことにする方法は,カーネル仕様全体の整合性を考
+ えて採用しなかった.ここで一種のCPU例外を導入するよりも,サービスコー
+ ルがエラーを返した場合に呼ばれるOSEK/VDX OS仕様のエラーフックに相当す
+ る機能を導入した方が有用性が高いと思われるためである.
+
+この変更により,さらに,CPUロック状態やディスパッチ禁止状態でext_tskが
+呼ばれた場合にもエラーリターンする方法が考えられるが,タスクのメインルー
+チンからのリターンとext_tskが等価にならないため,採用しない.また,他の
+処理単位からのリターン方法と整合させる意味もある(例えば,割込みハンド
+ラからCPUロック状態のままリターンした場合の扱い).
+
+これにあわせて,ext_kerについても,返り値をER型に変更する.ASPカーネル
+では,ext_kerがエラーを返すことはないが,HRPカーネルでは,E_OACVエラー
+を返す場合がある.
+
+なお,μITRON4.0仕様では,exd_tskもリターンすることのないサービスコール
+となっているが,TOPPERS新世代カーネルでは,exd_tskはサポートしていない.
+
+
+○カーネルのデータ構造に対するvolatile宣言について(クリティカルセクショ
+ンの出入処理の実現に関する制約)
+
+カーネル内のデータ構造は,並行実行される他の処理単位(割込みハンドラや
+タスク)からもアクセスされる可能性があるため,volatile宣言が必要ではな
+いかと考えられる.実際,クリティカルセクション内でカーネル変数を読むコー
+ドが,コンパイラの最適化によりクリティカルセクション外に移動され,それ
+が原因となった問題事例も報告されている.
+
+カーネル内のすべてのデータ構造にvolatile宣言をつける方法は,安全ではあ
+るが,最適化が抑止されるために,カーネルのサイズや性能には悪影響を与え
+る.そこでASPカーネルでは,次の方法でvolatile宣言の必要性をなくすことと
+する.
+
+ASPカーネルにおいては,並行実行される他の処理単位から書き換えられる可能
+性のあるデータ構造は,すべて,CPUロック状態または全割込みロック状態によ
+るクリティカルセクション内でアクセスしている.クリティカルセクション内
+でのデータ構造のアクセスが,コンパイラの最適化によりクリティカルセクショ
+ン外に移動されないようにするには,コンパイラに対して,クリティカルセク
+ションの出入処理により,メモリ上のデータ構造が書き変わる可能性があるこ
+とを知らせればよい.
+
+具体的には,クリティカルセクションの出入処理を関数によって実現すれば,
+このような最適化を抑止することができる.しかし,ASPカーネルの多くのター
+ゲット依存部において,クリティカルセクションの出入処理はマクロやインラ
+イン関数により実装されており,上のような最適化を抑止できない.
+
+そこで,クリティカルセクションの出入処理を実現する場合には,メモリ上の
+データ構造が書き変わる可能性があることを,何らかの方法でコンパイラに知
+らせなければならないという制約を設ける.GNU開発環境では,次のいずれかの
+方法でこの制約を満たすことができる.
+
+(a) クリティカルセクションの出入処理の全体または出入処理の本質的な部分
+ (具体的には,割込み禁止/許可する処理)を(インラインでない)通常
+ の関数により実現する.
+
+(b) クリティカルセクションの出入処理の本質的な部分をインラインアセンブ
+ ラによって実現している場合には,そのインラインアセンブラのclobber変
+ 数リストに"memory"を追加する.
+
+(c) クリティカルセクションの出入処理の本質的な部分が,マクロやインライ
+ ン関数呼出しで実現している場合には,クリティカルセクションに入る処
+ 理の最後と出る処理の先頭に,Asm("":::"memory")という記述を入れる.
+
+なお,この制約が適用されるクリティカルセクションの出入処理は,以下のも
+のである.
+
+ SIL_LOC_INT
+ SIL_UNL_INT
+ t_lock_cpu, i_lock_cpu, x_lock_cpu
+ t_unlock_cpu, i_unlock_cpu, x_unlock_cpu
+
+
+○型キャストに伴う警告メッセージ
+
+GCCで-O2オプションをつけてコンパイルした場合に,カーネルのソースコード
+中の数箇所で,次の警告メッセージが出る(GCCのバージョンにもよる).
+
+warning: dereferencing type-punned pointer will break strict-aliasing rules
+
+これは,GCCに-O2オプションをつけると,コンパイラがC言語のstrict
+aliasing ruleを前提とするためである.コンパイラにstrict aliasing ruleを
+適用させないためには,GCCのオプションに-fno-strict-aliasingを指定すれば
+よい.これにより,警告メッセージは抑止されるが,strict aliasing ruleを
+前提とした最適化は行われなくなる.
+
+ASPカーネルに実装においては,strict aliasing ruleを前提とした最適化を行っ
+てもよく,この警告メッセージを無視しても差し支えない.以下では,この警
+告メッセージを無視しても差し支えない理由を述べる.
+
+警告メッセージが出る例として,semaphore.c中の次の行について検討する.
+
+ wobj_make_wait((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem);
+
+この警告メッセージの原因は,直接的には,&winfo_semを(WINFO_WOBJ *)にキャ
+ストしていることであるが,本質的な原因は,このコードがC言語のstrict
+aliasing ruleに従わない代入文の原因になる可能性があり,このルールに依存
+した最適化が誤った結果を引き起こす可能性があることである.
+
+C言語のstrict aliasing ruleは,互換性のない異なる型を通して,オーバラッ
+プするメモリ領域をアクセスする代入文を使用してはならないというものであ
+る(使用した場合の振舞いは未定義になる).このケースでは,(WINFO_SEM
+*)型のポインタ経由と(WINFO_WOBJ *)型のポインタ経由で,オーバラップする
+メモリ領域をアクセスする代入文を使用してはならないことになる.また,警
+告メッセージの原因になってはいないが,(SEMCB *)型のポインタ経由と
+(WOBJCB *)型のポインタ経由で,オーバラップするメモリ領域をアクセスする
+代入文を使用してはならない.
+
+ASPカーネルの実装においては,semaphore.c中の関数においては,(SEMCB *)型
+および(WINFO_SEM *)型のポインタを使用しており,(WOBJCB *)型および
+(WINFO_WOBJ *)型のポインタ経由でメモリ領域をアクセスすることはない.一
+方,そこから呼び出されるwait.c中の関数においては,(WOBJCB *)型および
+(WINFO_WOBJ *)型のポインタを使用しており,(SEMCB *)型および(WINFO_SEM
+*)型のポインタ経由でメモリ領域をアクセスすることはない.
+
+strict aliasing ruleに従わない代入文の問題点は,このルールに依存した最
+適化が誤った結果を引き起こす可能性があることであるが,異なるコンパイル
+単位をまたいで最適化が行われることはないため,これにより問題が起こるこ
+とはないと言うことができる.
+
+同じ議論は,他のソースファイル(eventflag.c,dataqueue.c,pridataq.c,
+mailbox.c,mempfix.c)中の警告メッセージについても,そのまま当てはまる.
+
+
+○優先度データキュー機能(未完成)
+
+●導入の経緯
+
+●API仕様
+
+CRE_PDQ(ID pdqid, { ATR pdqatr, uint_t pdqcnt, PRI maxdpri, void *pdqmb });
+ER snd_pdq(ID pdqid, intptr_t data, PRI datapri);
+ER psnd_pdq(ID pdqid, intptr_t data, PRI datapri);
+ER ipsnd_pdq(ID pdqid, intptr_t data, PRI datapri);
+ER tsnd_pdq(ID pdqid, intptr_t data, PRI datapri, TMO tmout);
+ER rcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri);
+ER prcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri);
+ER trcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri, TMO tmout);
+ER ini_pdq(ID pdqid);
+ER ref_pdq(ID pdqid, T_RPDQ *pk_rpdq);
+
+●実装
+
+<未完成>
+
+
+○性能評価用システム時刻参照機能
+
+●必要性と使途
+
+ASPカーネルには,ASPカーネル上で動作するタスクやASPカーネル自身の性能を
+計測するために,システム時刻より精度の高い性能評価用システム時刻を読み
+出す機能をサポートする.性能評価用システム時刻は,マイクロ秒単位で表現
+されるが,実際の精度はターゲット依存である.
+
+この機能を用いてあるプログラムの実行時間を計測するには,その実行直前と
+実行直後に性能評価用システム時刻を読み出し,その差を求める.そのため,
+性能評価用システム時刻は常に相対値を使用し,性能評価用システム時刻の絶
+対値を使用することは想定していない.
+
+●API仕様
+
+性能評価用システム時刻参照機能では,次のデータ型を用いる.
+
+ SYSUTM 性能評価用システム時刻(符号無し整数,単位はマイクロ秒,
+ 32ビット以上)
+
+SYSUTM型は,ターゲット非依存部においてulong_t型(すなわち,unsigned
+long型)に定義されており,そのサイズは,32ビット以上で,ターゲット定義
+である.
+
+性能評価用システム時刻がSYSUTM型で表現できる範囲を超えた(つまり,オー
+バフローした)場合,性能評価用システム時刻は0に戻る.評価対象プログラム
+の実行前後の性能評価用システム時刻の差を求める場合には,計測する時間が
+SYSUTM型で表現できる範囲である限り,0に戻ることを特別に考慮する必要はな
+い.
+
+SYSUTM型が32ビットの場合,性能評価用システム時刻は約71分でオーバフロー
+する.そのため,この機能を71分を越える時間の測定に使った場合の動作は保
+証されない.
+
+性能評価用システム時刻参照機能のためのサービスコールの仕様については,
+「TOPPERS新世代カーネル統合仕様書」の「4.6.1 システム時刻管理」の節を参
+照すること.
+
+●実装
+
+時刻をマイクロ秒単位で取得するために,周期的なタイムティックを供給する
+タイマの現在値(タイマはカウントアップするものと仮定する)を読み出し,
+それをマイクロ秒単位に換算した値に,現在のシステム時刻(ミリ秒単位で表
+現される)を1000倍した値を加えたものを性能評価用システム時刻とする.現
+在のシステム時刻を1000倍する際に,オーバフローが発生する可能性があるが,
+無視してかまわない.
+
+ただし,システム時刻の現在値とタイマの現在値を一貫した状態で読み出すの
+は容易ではない.両方の値を順に読み出すと,読出しの間にタイマがオーバフ
+ローして割込み要求が発生した場合に,片方はオーバフロー前の値,もう片方
+はオーバフロー後の値を読んでしまい,誤った性能評価用システム時刻を取得
+してしまう.
+
+この問題を解決する方法はいくつか考えられるが,どの方法を採用するの決定
+にあたり,次の要求事項を設定した.
+
+(1) 多くのターゲットシステムで実現できること.
+
+(2) サービスコールの実行時間が可能な限り一定となること.言い換えると,
+ 条件によってサービスコールの実行時間が大きく変動しないこと.
+
+(3) サービスコール中の可能な限り同じタイミングの時刻を返すこと.言い換
+ えると,条件によって時刻を読み取るタイミングが変動しないこと.
+
+(4) 調整する必要のあるパラメータを最小限とすること.
+
+これらの要求事項を満たす方法として,次の方法を用いることにした.
+
+まず,NMIを除くすべての割込みを禁止した状態で,システム時刻の現在値,タ
+イマの現在値(1回目),タイマ割込み要求の有無,タイマの現在値(2回目)
+を,この順で読み出す.割込みを禁止しているため,この間にシステム時刻の
+現在値が変化することはなく,システム時刻の現在値を読み出す順番はどこで
+もよい.また,タイマの現在値の2回目の読出しは,タイマ割込み要求があった
+場合にのみ必要となるが,(2)の要求から,タイマ割込み要求の有無によらず読
+み出すこととする.
+
+これらの値を読み出した後,割込み禁止を解除し,次の処理を行う.まず,タ
+イマ割込み要求がなかった場合には,システム時刻の現在値と,1回目に読んだ
+タイマの現在値は一貫した値であることが保証できるため,これらの値から性
+能評価用システム時刻の現在値を求める.
+
+次にタイマ割込み要求があった場合には,1回目に読んだタイマの現在値が,タ
+イマ割込み要求発生前の値(オーバフロー前の値)である場合と,発生後の値
+(オーバフロー後の値)である場合の両方の可能性が考えられる.このどちら
+の場合であったかを,2回目に読んだタイマの現在値を使って,次のように決定
+する.2回目の値は,タイマ割込み要求発生後の値(オーバフロー後の値)であ
+ることが保証できるため,1回目の値が2回目の値よりも大きい場合には,その
+間にオーバフローがあったものと推測できる.つまり,1回目の値はオーバフロー
+前の値ということになり,システム時刻の現在値と一貫した値であるとして性
+能評価用システム時刻の現在値を求める.逆に,1回目の値が2回目の値と同じ
+かそれより小さい場合には,1回目の値はオーバフロー後の値であると推測でき
+る.この場合には,次のタイムティックのシステム時刻を求め,その値と1回目
+の値が一貫した値であるとして性能評価用システム時刻の現在値を求める.
+
+ここで,タイマ割込み要求があった場合には,2回目に読んだタイマの現在値を
+用いる方法が考えられるが,(3)の要求を満たさなくなるために採用しなかった.
+また,JSPカーネルと同様の方法は,(4)の要求を満たさないために採用しなかっ
+た.
+
+上で「推測できる」としたのは,この推測が成り立たなくなるケースがあるた
+めである.この推測が成り立たなくなるケースは,次の2つの場合に分けて分析
+することができる.
+
+(a) 1回目の値がオーバフロー後の値であるにもかかわらず,1回目の値が2回目
+ の値よりも大きくなる場合
+
+このようなケースは,タイマ割込みが要求されているにもかかわらずサービス
+されない状態が長時間続くか,タイマの現在値を1回目に読んでから2回目に読
+むまでの間に長い時間がかかった結果,その間に(再度)オーバフローが発生
+した場合に起こる.つまり,タイマ割込みがサービスされない時間が,タイム
+ティックの周期よりも長くなった場合である.このような場合には,システム
+時刻の更新も正しく行われなくなる.
+
+(b) 1回目の値がオーバフロー前の値であるにもかかわらず,1回目の値が2回目
+ の値と同じかそれよりも小さくなる場合
+
+このようなケースは,タイマの現在値を1回目に読んでから2回目に読むまでの
+間に,タイマがほぼ1周分カウントアップした場合に起こる.この場合も,タイ
+マ割込みが禁止されている時間が,タイムティックの周期よりも長かったこと
+になり,システム時刻の更新が正しく行えなくなる.
+
+いずれのケースも,タイマ割込みが長時間禁止されている,タイマ割込みより
+も優先度の高い割込み処理が長時間続けて実行された,シミュレーション環境
+においてシミュレータのプロセスが長時間スケジュールされなかったなどの理
+由で,システム時刻の更新が正しく行えない状況に相当する.そこでこの状況
+を,サービスコール使用上の注意事項に盛り込む.
+
+実際のコードにおいては,システム時刻の現在値は変数に保持されていないた
+め(上位桁はcurrent_timeに保持されているが,下位桁を保持する変数がな
+い),次のタイムティックのシステム時刻を用いて計算している.そのため,
+タイマの現在値がオーバフロー後の値であると判断した場合を除いては,タイ
+ムティックの周期時間を,求めた性能評価用システム時刻から減算する.この
+処理により,サービスコールの実行時間が変動することになるが,if文の内容
+が(コンパイラの最適化を仮定すると)定数値の減算1回なので,変動はわずか
+である.
+
+このサービスコールは,任意の状態から呼び出すことができるため,SILの全割
+込みロック機能を用いて,サービスコール内部のクリティカルセクションを実
+現する.
+
+
+○タスク例外処理禁止フラグをenatexで実装している理由
+
+タスク例外処理禁止フラグは,TCB中のenatexフィールド(タスク例外処理許可
+状態であることを示す)の形で保持している.このフィールドをdistexとせず
+enatexとしたのは,JSPカーネルにおいてタスクディスパッチ禁止フラグを
+enadspの形で保持したのと整合させたためである.
+
+ASPカーネルでは,enadspはdisdspに変更になったことから,enatexもdistexに
+変更した方が良かったと思われる.
+
+以上
--- /dev/null
+
+ TOPPERS/ASPカーネル
+ 機能拡張・チューニングガイド
+
+ 対応バージョン: Release 1.6.0
+ 最終更新: 2010年2月9日
+
+このドキュメントは,TOPPERS/ASPカーネルを,機能拡張・チューニングするた
+めの方法(またはヒント)を説明するものである.
+
+----------------------------------------------------------------------
+ TOPPERS/ASP Kernel
+ Toyohashi Open Platform for Embedded Real-Time Systems/
+ Advanced Standard Profile Kernel
+
+ Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ Graduate School of Information Science, Nagoya Univ., JAPAN
+
+ 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ スコード中に含まれていること.
+ (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ の無保証規定を掲載すること.
+ (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ と.
+ (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ 報告すること.
+ (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ 免責すること.
+
+ 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ の責任を負わない.
+
+ $Id: extension.txt 1862 2010-07-25 11:49:51Z ertl-hiro $
+----------------------------------------------------------------------
+
+○目次
+
+・エラーチェックの省略
+・タイムティックの周期の変更
+・特殊目的のレジスタの扱い
+・ミューテックス機能拡張パッケージ
+・オーバランハンドラ機能拡張パッケージ
+・タスク優先度拡張パッケージ
+・CPU例外ハンドラの直接呼出し
+
+
+○エラーチェックの省略
+
+サービスコールのオーバヘッドを削減するために,静的なエラーのチェックを
+省略する場合がある.ASPカーネルにおいては,静的なエラーのチェックはすべ
+てCHECKマクロを用いて行っているため,kernel/check.h中のCHECKマクロを編
+集することで,静的なエラーのチェックを省略することができる.
+
+例えば,タスクIDのチェックを省略したい場合には,CHECK_TSKIDマクロと
+CHECK_TSKID_SELFマクロを,次のように修正すればよい.
+
+#define CHECK_TSKID(tskid) ((void)(tskid))
+#define CHECK_TSKID_SELF(tskid) ((void)(tskid))
+
+これらのマクロの定義を空にする方法もあるが,パラメータに副作用のある式
+が書かれている可能性を考えると(副作用のある式は書くべきではないが,書
+かれているコードが入ってくる可能性が全くないとは言えない),上の定義の
+方が安全である.副作用のない式であれば,最適化によって削除することがで
+きるため,実行時効率には影響がないと期待できる.ただし,最適化によって
+削除されない場合には,副作用のある式が書かれていないことを確認した上で,
+マクロの定義を空にしてもよい.
+
+
+○タイムティックの周期の変更
+
+ASPカーネルでは,カーネルへタイムティックを供給する周期は1ミリ秒が標準
+となっているが,低速なプロセッサでは1ミリ秒毎に割込みを処理するオーバヘッ
+ドが問題になる場合がある.そこで,アプリケーションが必要とする時間精度
+が粗い場合には,タイムティックの周期を長くすることで,プロセッサの処理
+負荷を低減する方法がある.
+
+タイムティックの周期の与え方はターゲット依存であるため,これが変更でき
+るかどうかは,ターゲット依存部のタイマドライバの実装を調べる必要がある.
+標準的には,target_kernel.h(またはそこからインクルードされるファイル)
+中に定義されているTIC_NUMEとTIC_DENOを書き換えることで,変更できるよう
+に実装されている.
+
+
+○特殊目的のレジスタの扱い
+
+FPUレジスタやDSPレジスタなどの特殊目的のレジスタ(以下,特殊レジスタ)
+を持つプロセッサでは,レジスタの扱いについて大きく次の3つの方法が考えら
+れる.
+
+(1) 特殊レジスタをタスクのコンテキストに含めない
+
+1つのタスクのみが特殊レジスタを使用する場合には,特殊レジスタをタスクの
+コンテキストに含める必要がなく,カーネルで管理する必要がない.
+
+(2) 特殊レジスタをタスクのコンテキストに含める
+
+複数のタスクが特殊レジスタを使用する場合には,特殊レジスタをタスクのコ
+ンテキストに含める方法が最も単純である.そのためには,タスクディスパッ
+チャと割込みハンドラ/CPU例外ハンドラの出入口で,特殊レジスタを保存/復帰
+するコードを追加する必要がある.実際の保存/復帰場所は,スクラッチレジス
+タとそれ以外のレジスタで異なるため,注意が必要である.
+
+(3) 特殊レジスタをコンテキストに含めるかどうかをタスク毎に指定する
+
+特殊レジスタを使用するタスクと使用しないタスクがある場合で,すべてのタ
+スクのコンテキストに特殊レジスタを含める方法ではオーバヘッドが問題にな
+る場合には,特殊レジスタをコンテキストに含めるかどうかをタスク毎に指定
+する方法が有力である.これを実現する方法は次の通りである.
+
+まず,特殊レジスタをコンテキストに含めるかどうかを指定するタスク属性を
+設ける.例えば,FPUレジスタであれば,タスク属性にTA_FPUを設ける.タスク
+ディスパッチャでは,タスク属性を見て,その属性が設定されていれば特殊レ
+ジスタを保存/復帰する.
+
+ハードウェア的に特殊レジスタがディスエーブルできる場合には,その属性が
+設定されていないタスクに切り換える時に特殊レジスタをディスエーブルする
+と,誤って特殊レジスタを使った場合を検出できる.
+
+さらに,割込みハンドラ(ISR,周期ハンドラ,アラームハンドラを含む)や
+CPU例外ハンドラで特殊レジスタを使用する場合には,これらの処理単位にも
+特殊レジスタを使用するかどうかの属性を設ける方法が考えられる.
+
+ここで,タスク(または他の処理単位)が特殊レジスタを使用するかどうかは,
+コンパイラやライブラリに依存する場合があるため,注意が必要である.例え
+ば,浮動小数点演算を含まないプログラムであっても,コンパイラがその方が
+性能が高いと判断すれば,浮動小数点命令を生成する場合がある.
+
+
+○ミューテックス機能拡張パッケージ
+
+ASPカーネルに,ミューテックス機能を追加するための拡張パッケージを用意し
+ている.ただし,優先度逆転を制御するための仕組みとして,優先度上限ミュー
+テックス(TA_CEILING属性のミューテックス)のみをサポートし,優先度継承
+ミューテックス(TA_INHERIT属性のミューテックス)はサポートしていない.
+
+拡張パッケージは,extension/mutexディレクトリに置いてある.拡張パッケー
+ジを使用する場合には,UNIXであれば,ASPカーネルのソースファイルのトップ
+ディレクトリで,
+
+ % cp -r extension/mutex/* .
+
+を実行する.この時,元の(拡張前の)ソースファイルは上書きされてしまう
+ため,拡張しないカーネルも使用したい場合には,別のディレクトリにソース
+ファイルを展開して,上のコマンドを実行すること.また,複数の拡張パッケー
+ジを使う場合には,それらが衝突する可能性があるので,注意が必要である.
+
+ミューテックス機能拡張パッケージでは,TOPPERS_SUPPORT_MUTEXがkernel.h中
+で定義されているので,これを用いてミューテックス機能を使用できるかどう
+かを判別することができる.
+
+
+○オーバランハンドラ機能拡張パッケージ
+
+ASPカーネルに,オーバランハンドラ機能を追加するための拡張パッケージを用
+意している.ただし,この拡張パッケージを使うためには,ターゲット依存部
+が対応している必要がある.
+
+拡張パッケージは,extension/ovrhdrディレクトリに置いてある.拡張パッケー
+ジの使用方法は,ミューテックス機能と同様である.
+
+オーバランハンドラ機能拡張パッケージで,ターゲット依存部が拡張パッケー
+ジに対応している場合には,TOPPERS_SUPPORT_OVRHDRがkernel.h中で定義され
+るので,これを用いてオーバランタイマ機能が使用できるかどうかを判別する
+ことができる.
+
+
+○タスク優先度拡張パッケージ
+
+タスク優先度を最大256段階に拡張するための拡張パッケージを用意している.
+この拡張パッケージは,タスク優先度に加えて,データ優先度,メッセージ優
+先度,割込みサービスルーチン優先度も256段階に拡張する.
+
+拡張パッケージは,extension/pri_levelディレクトリに置いてある.拡張パッ
+ケージの使用方法は,ミューテックス機能と同様である.
+
+タスク優先度拡張パッケージでは,TOPPERS_SUPPORT_PRI_LEVELがkernel.h中で
+定義されているので,これを用いてタスク優先度の範囲が拡張されているかど
+うかを判別することができる.
+
+
+○CPU例外ハンドラの直接呼出し
+
+CPU例外ハンドラの出入口処理は,CPU例外が発生しないように実装しなければ
+ならないが,これが防げないターゲットにおいては,CPU例外ハンドラの出入口
+処理を経由せずに,アプリケーションが用意したCPU例外ハンドラを直接実行す
+る方法を用意するのが望ましい.これを,CPU例外ハンドラの直接呼出しと呼ぶ.
+
+ここでは,ハードウェアでベクタテーブルを持つプロセッサにおいて,ターゲッ
+ト依存部のみの修正により,CPU例外ハンドラの直接呼出しの機能を追加する方
+法について説明する.
+
+●TA_DIRECT属性の導入
+
+CPU例外ハンドラの直接呼出しを指定するために,CPU例外ハンドラ属性に,
+TA_DIRECT属性を導入する.
+
+●ターゲット依存部の修正箇所
+
+TA_DIRECTの値を,target_kernel.h(または,そこからインクルードされるファ
+イル)で定義し,その値をコンフィギュレータが取り出せるように,
+target_def.csv(または,それに代わるファイル)に次の行を追加する.
+
+TA_DIRECT,TA_DIRECT
+
+次に,target.tf(または,そこからインクルードされるファイル)で,
+TARGET_INHATRに設定される値に,TA_DIRECTを追加する.例えば,TARGET_INHATR
+にTA_NONKERNELのみが設定されていた場合には,次のように修正する.
+
+$TARGET_INHATR = TA_NONKERNEL | TA_DIRECT$
+
+次に,OMIT_INITILIZE_EXCEPTIONを用いて,CPU例外ハンドラの出入口処理を生
+成するための記述とCPU例外ハンドラ初期化ブロックの標準の定義が生成される
+のを抑止し,それによって抑止される部分をtarget.tfにコピーした上で,以下
+の修正を加える.
+
+CPU例外ハンドラの出入口処理を生成するための記述(EXCHDR_ENTRYのリスト)
+を生成する部分は,次のように修正する.
+
+$FOREACH excno EXC.ORDER_LIST$
+ $IF (EXC.EXCATR[excno] & TA_DIRECT) == 0$
+ EXCHDR_ENTRY($EXC.EXCNO[excno]$, $+EXC.EXCNO[excno]$, $EXC.EXCHDR[excno]$)$NL$
+ $END$
+$END$
+
+また,CPU例外ハンドラ初期化ブロックの定義を生成する部分は,次のように修
+正する.
+
+const EXCINIB _kernel_excinib_table[TNUM_EXCNO] = {$NL$
+$JOINEACH excno EXC.ORDER_LIST ",\n"$
+ $IF (EXC.EXCATR[excno] & TA_DIRECT) == 0$
+ $TAB${ ($EXC.EXCNO[excno]$), ($EXC.EXCATR[excno]$), (FP)(EXC_ENTRY($EXC.EXCNO[excno]$, $EXC.EXCHDR[excno]$)) }
+ $ELSE$
+ $TAB${ ($EXC.EXCNO[excno]$), ($EXC.EXCATR[excno]$), (FP)($EXC.EXCHDR[excno]$) }
+ $END$
+$END$$NL$
+};$NL$
+
+以上
--- /dev/null
+
+ TOPPERS/ASPカーネル
+ ターゲット依存部 ポーティングガイド
+
+ 対応バージョン: Release 1.6.0
+ 最終更新: 2010年7月29日
+
+このドキュメントは,TOPPERS/ASPカーネルを,未サポートのターゲットシステ
+ムにポーティングするために必要となるターゲット依存部の実装方法を説明す
+るものである.
+
+----------------------------------------------------------------------
+ TOPPERS/ASP Kernel
+ Toyohashi Open Platform for Embedded Real-Time Systems/
+ Advanced Standard Profile Kernel
+
+ Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ Graduate School of Information Science, Nagoya Univ., JAPAN
+
+ 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ スコード中に含まれていること.
+ (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ の無保証規定を掲載すること.
+ (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ と.
+ (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ 報告すること.
+ (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ 免責すること.
+
+ 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ の責任を負わない.
+
+ $Id: porting.txt 1875 2010-07-29 16:21:36Z ertl-hiro $
+----------------------------------------------------------------------
+
+○目次
+
+1.共通事項
+ 1.1 ターゲット依存部の構成
+ 1.2 名前の衝突の防止
+ 1.3 多重インクルードの防止
+ 1.4 アセンブリ言語とのヘッダファイルの共用
+ 1.5 インクルード記述の方法
+ 1.6 クリティカルセクションの出入処理の実現に関する制約
+2.システム構築環境のターゲット依存部
+ 2.1 ターゲット略称とターゲット依存部のディレクトリ
+ 2.2 Makefileのターゲット依存部
+ 2.3 開発環境名とコマンド名の設定
+ 2.4 コンパイルオプションとオブジェクトファイルの設定
+ 2.5 オフセットファイルの生成方法
+ 2.5.1 makeoffset.cの記述方法
+ 2.6 リンク方法の設定
+ 2.7 依存関係の定義
+ 2.8 その他の設定
+3.TOPPERS共通定義のターゲット依存部
+ 3.1 ターゲット識別マクロ
+ 3.2 整数型の最大値・最小値・ビット数
+ 3.3 サイズの指定された整数型,その最大値・最小値,整数定数を作るマクロ
+ 3.4 サイズの指定された浮動小数点型,その最大値・最小値のマクロ
+ 3.5 コンパイラの拡張機能のためのマクロ定義
+ 3.6 標準的な定義の上書き
+ 3.7 アサーションのための定義
+4.システムインタフェースレイヤ(SIL)のターゲット依存部
+ 4.1 全割込みロック状態の管理
+ 4.2 微少時間待ち
+ 4.3 プロセッサのエンディアン
+ 4.4 メモリ空間アクセス関数
+ 4.5 I/O空間アクセス関数
+5.カーネルAPIのターゲット依存部
+ 5.1 ターゲット定義でサポートする機能
+ 5.2 割込み優先度の範囲
+ 5.3 タイムティックの定義
+ 5.4 メモリ領域確保のための型定義
+ 5.5 ビットパターンのビット数
+ 5.6 メモリ領域確保のためのマクロ
+ 5.7 オーバランハンドラ機能拡張のための定義(オプション)
+6.カーネル実装のターゲット依存部
+ 6.1 カーネル実装のターゲット依存部の共通事項
+ 6.1.1 カーネル実装のターゲット依存部の構成要素
+ 6.1.2 ターゲット依存部の関数の命名規則
+ 6.2 トレースログ機能への対応
+ 6.3 システム状態の管理
+ 6.3.1 全割込みロック状態の管理
+ 6.3.2 コンテキストの管理
+ 6.3.3 CPUロック状態の管理
+ 6.4 割込みに関連するシステム状態の管理
+ 6.4.1 割込み優先度マスクの管理
+ 6.4.2 割込み要求禁止フラグの管理
+ 6.4.3 割込み要求のクリア
+ 6.4.4 割込み要求のプローブ
+ 6.4.5 割込みハンドラの先頭処理と末尾処理
+ 6.5 タスクディスパッチャ
+ 6.5.1 タスクコンテキストブロックとタスク初期化コンテキストブロック
+ 6.5.2 ディスパッチャ本体
+ 6.5.3 タスクコンテキストからのディスパッチ
+ 6.5.4 ディスパッチャの動作開始
+ 6.5.5 現在のコンテキストを捨ててディスパッチ
+ 6.5.6 タスクの起動処理
+ 6.6 割込みハンドラ
+ 6.6.1 割込みハンドラの出入口処理
+ 6.6.2 割込みハンドラ毎の出入口処理の生成
+ 6.6.3 割込みハンドラの設定
+ 6.6.4 割込み要求ラインの属性の設定
+ 6.6.5 割込み管理機能の初期化処理の変更
+ 6.6.6 デフォルトの割込みハンドラ
+ 6.6.7 カーネル管理外の割込み
+ 6.7 CPU例外ハンドラとCPU例外発生時のシステム状態の参照
+ 6.7.1 CPU例外ハンドラの出入口処理
+ 6.7.2 CPU例外ハンドラの出入口処理の生成
+ 6.7.3 CPU例外ハンドラの設定
+ 6.7.4 CPU例外管理機能の初期化処理の変更
+ 6.7.5 デフォルトのCPU例外ハンドラ
+ 6.7.6 CPU例外発生時のシステム状態の参照
+ 6.8 カーネルの起動・終了とスタック領域など
+ 6.9 カーネル内部のチューニング
+ 6.9.1 ビットマップサーチ
+ 6.9.2 ビットフィールド
+ 6.10 カーネル実装に関するその他の定義
+ 6.10.1 非タスクコンテキスト用のスタック領域
+ 6.10.2 空ラベルの定義
+ 6.11 トレースログ機能に関する設定
+ 6.11.1 取得できるトレースログの種類とマクロ
+ 6.11.2 トレースログ記録のサンプルコード
+ 6.12 カーネル実装のターゲット依存部のためのリネーム記述
+ 6.13 タイマドライバ
+ 6.13.1 タイマドライバのファイル構成
+ 6.13.2 タイマの初期化・終了処理・割込み処理
+ 6.13.3 性能評価用システム時刻の参照のための機能
+ 6.14 オーバランタイマドライバ(オプション)
+ 6.14.1 オーバランタイマドライバのファイル構成
+ 6.14.2 オーバランタイマの操作と割込み処理
+7.コンフィギュレータ設定ファイルのターゲット依存部
+ 7.1 設定ファイルとターゲット依存部の位置付け
+ 7.2 パス2のテンプレートファイルのターゲット依存部
+ 7.2.1 ターゲット非依存部をインクルードする前に定義すべき変数
+ 7.2.2 ターゲット非依存部で定義される変数
+ 7.3 パス3のテンプレートファイルのターゲット依存部
+ 7.4 cfg1_out.cのリンクに必要なスタブの定義ファイル
+8.システムサービス等のターゲット依存部
+ 8.0 システムサービスのターゲット依存部
+ 8.1 システムログ機能のターゲット依存定義
+ 8.2 ログタスクのターゲット依存定義
+ 8.3 シリアルインタフェースドライバのターゲット依存部
+ 8.3.1 変数,データ型,管理関数
+ 8.3.2 デバイスサービスルーチン
+ 8.3.3 コールバックルーチン
+ 8.4 カーネル起動メッセージの出力のターゲット依存定義
+ 8.5 サンプルプログラムとテストプログラムのターゲット依存定義
+ 8.6 実行時間分布集計モジュールのターゲット依存定義
+9.その他
+ 9.1 ドキュメント
+ 9.2 パッケージ記述ファイル
+10.リファレンス
+ 10.1 ターゲット依存部のファイル一覧
+
+
+1.共通事項
+
+1.1 ターゲット依存部の構成
+
+ターゲット依存部は,targetディレクトリの下に,ターゲットハードウェアと
+開発環境の組み合わせ毎に用意する.ただし,ターゲット依存部の再利用性を
+考慮し,プロセッサ,チップ,開発環境のみに依存する部分を,プロセッサ依
+存部,チップ依存部,開発環境依存部という形で切り分けてもよい.切り分け
+方は,ターゲット依存部の実装に任されている.プロセッサ依存部,チップ依
+存部,開発環境依存部は,archディレクトリの下に置く.
+
+ASPカーネルのターゲット依存部は,システム構築環境(Makefile等)のターゲッ
+ト依存部,TOPPERS共通定義(t_stddef.h)のターゲット依存部,システムイン
+タフェースレイヤ(SIL,sil.h)のターゲット依存部,カーネルAPI(kernel.h)
+のターゲット依存部,カーネル実装のターゲット依存部(コンフィギュレータ
+設定ファイルのターゲット依存部を含む),システムサービスのターゲット依
+存部,ターゲット依存部に関するドキュメント等で構成される.
+
+1.2 名前の衝突の防止
+
+TOPPERSプロジェクトが提供するソフトウェアのために,TOPPERS_で始まるシン
+ボルを予約している.ヘッダファイル中に記述され,アプリケーションから参
+照できる内部シンボルは,TOPPERS_で始まる名前とする.
+
+また,_kernel_で始まるシンボルは,カーネル内部の変数や関数のために予約
+している.カーネル内部の変数や関数の名前で,リンク時にアプリケーション
+の名前と衝突する可能性があるものは,リネーム記述にリストアップすること
+で,コンパイル時に_kernel_で始まる名前に置き換えることとしている.
+
+1.3 多重インクルードの防止
+
+すべてのヘッダファイルは,多重にインクルードされるのを防止するための条
+件コンパイル記述を入れることとする.例えば,target_config.hであれば,ファ
+イルの先頭に
+
+#ifndef TOPPERS_TARGET_CONFIG_H
+#define TOPPERS_TARGET_CONFIG_H
+
+を,ファイルの末尾に
+
+#endif /* TOPPERS_TARGET_CONFIG_H */
+
+を記述する.
+
+1.4 アセンブリ言語とのヘッダファイルの共用
+
+ASPカーネルのヘッダファイルの多くは,アセンブリ言語のソースファイルから
+もインクルードできるようにするために,次のルールに従って記述するものと
+する.
+
+・TOPPERS_MACRO_ONLYがマクロ定義されている場合には,アセンブリ言語では
+ 解釈できない記述(マクロ定義以外の記述)を除くように記述する.
+
+・符号無し整数型の定数値は,UINT_CやULONG_Cなどの整数定数を作るためのマ
+ クロを用いて記述する.ただし,アセンブリ言語のソースファイルからもイ
+ ンクルードできるファイル中であっても,C言語のみで用いる定数をこれらの
+ マクロを使って記述する必要はない.
+
+また,カーネル実装においては,次のルールに従うものとする.
+
+・アセンブリ言語からも用いる定数の定義中に型キャストを用いる場合には,
+ CASTマクロを用いて記述する.
+
+アセンブリ言語からヘッダファイルをインクルードする際には,必要に応じて,
+TOPPERS_MACRO_ONLY,UINC_C,ULONG_C,CASTをマクロ定義してから,インクルー
+ドしなければならない.
+
+1.5 インクルード記述の方法
+
+開発環境で用意されている標準ヘッダファイルおよびincludeディレクトリ下の
+標準ヘッダファイルは,「#include <...>」によりインクルードする.
+
+その他のヘッダファイルは,「#include "..."」によりインクルードする.ヘッ
+ダファイルが,カレントディレクトリやインクルードするファイルと同じディ
+レクトリ以外のディレクトリに置かれている場合には,次のようにパス指定を
+行う.
+
+・ターゲット依存部(target/<ターゲット名>)のディレクトリに置かれている
+ 場合は,パス指定を行わず,ファイル名のみを記述する.
+ 例)#include "target_config.h"
+
+・archディレクトリ下のディレクトリに置かれている場合には,archディレク
+ トリからの相対パスで記述する.
+ 例)#include "m68k_gcc/prc_config.h"
+
+・その他の場合には,ソースプログラムのルートディレクトリ(configureが置
+ かれているディレクトリ)からの相対パスで記述する.
+ 例)#include "pdic/upd72001/upd72001.h"
+
+・カーネルを構成するファイルから,kernelディレクトリ下のヘッダファイル
+ をインクルードする場合は,パス指定を行わず,ファイル名のみを記述する.
+ 例)#include "kernel_impl.h"
+
+1.6 クリティカルセクションの出入処理の実現に関する制約
+
+カーネル内で用いるクリティカルセクションの出入処理を実現する場合には,
+次の2つの条件を満たすように実装しなければならない.
+
+(1-6-1) 出入処理から抜けた時点では,割込みの禁止/許可が完了していなけ
+ればならない.例えば,割込み禁止/許可命令を実行してから実際に割込みが
+禁止/許可されるまで何命令か遅延するプロセッサの場合には,出入処理の中
+にNOP命令を入れるなどの方法で,出入処理を抜けた時点では,割込みが禁止/
+許可された状態になっていることを保証しなければならない.
+
+(1-6-2) メモリ上のデータ構造が書き変わる可能性があることを,何らかの方
+法でコンパイラに知らせなければならない.GNU開発環境では,次のいずれかの
+方法でこの制約を満たすことができる.
+
+(a) クリティカルセクションの出入処理の全体または出入処理の本質的な部分
+ (具体的には,割込み禁止/許可する処理)を(インラインでない)通常
+ の関数により実現する.
+
+(b) クリティカルセクションの出入処理の本質的な部分をインラインアセンブ
+ ラによって実現している場合には,そのインラインアセンブラのclobber変
+ 数リストに"memory"を追加する.
+
+(c) クリティカルセクションの出入処理の本質的な部分が,マクロやインライ
+ ン関数呼出しで実現している場合には,クリティカルセクションに入る処
+ 理の最後と出る処理の先頭に,Asm("":::"memory")という記述を入れる.
+
+このような制約を設ける理由については,「TOPPERS/ASPカーネル 設計メモ」
+の「カーネルのデータ構造に対するvolatile宣言について」の節を参照するこ
+と.
+
+
+2.システム構築環境のターゲット依存部
+
+この章の説明は,GNU開発環境(GCC,GAS,BINUTILS,GNU Make)を用いること
+を想定して記述してある.それ以外の開発環境を用いる場合には,開発環境に
+あわせて修正する必要がある.
+
+2.1 ターゲット略称とターゲット依存部のディレクトリ
+
+新しいターゲット依存部を作成する時は,まず,ターゲット略称を定める.ター
+ゲット略称は,システム略称と開発環境略称を"_"で連結したものとする.シス
+テム略称に用いる文字は英小文字と数字と"_"に,開発環境略称に用いる文字は
+英小文字と数字に限定する.GNU開発環境の開発環境略称は,"gcc"とする.例
+えば,システム略称が"dve68k"で,GNU開発環境を用いる場合には,ターゲット
+略称は"dve68k_gcc"となる.
+
+ターゲット依存部のファイルを置くために,targetディレクトリの下に,ター
+ゲット略称を名称とするディレクトリを作成する.これをターゲット依存部ディ
+レクトリと呼ぶ.
+
+ターゲット依存部からプロセッサ依存部やチップ依存部を切り分ける場合には,
+依存部略称を定める.依存部略称は,プロセッサやチップの略称と開発環境略
+称を"_"で連結したものとする.プロセッサやチップの略称に用いる文字は,英
+小文字と数字と"_"に限定する.例えば,プロセッサ略称が"m68k"で,GNU開発
+環境を用いる場合には,依存部略称は"m68k_gcc"となる.
+
+また,ターゲット依存部から開発環境依存部を切り分ける場合には,開発環境
+略称を依存部略称とする.例えば,GNU開発環境依存部の依存部略称は,"gcc"
+となる.
+
+これらの依存部のファイルを置くために,archディレクトリの下に,依存部略
+称を名称とするディレクトリを作成する.
+
+なお,GNU開発環境以外の開発環境を用いる場合には,コンフィギュレーション
+スクリプト(configure),サンプルのMakefile(sample/Makefile),一部の
+ユーティリティプログラム(utils/genoffset,utils/makedep)を,その開発
+環境用に用意する必要がある場合がある.その場合には,これらのファイルを,
+ターゲット依存部ディレクトリか開発環境依存部ディレクトリに置くものとす
+る.また,開発環境用のプロジェクトファイルが必要な場合には,ターゲット
+依存部ディレクトリに置くものとする.
+
+2.2 Makefileのターゲット依存部
+
+Makefileのターゲット依存部は,ターゲット依存部ディレクトリに置いた
+Makefile.targetまたはそこからインクルードされるファイル(プロセッサ・チッ
+プ・開発環境依存部で用意されるファイルなど)に含める.
+
+2.3 開発環境名とコマンド名の設定
+
+開発環境名とコマンド名を設定するために,Makefileのターゲット依存部で次
+の変数を定義する.
+
+(2-3-1) TOOL 開発環境名
+
+開発環境名に定義する.GNU開発環境を用いる場合には,gccに定義する.
+
+(2-3-2) GCC_TARGET GNU開発環境のターゲット名
+
+GNU開発環境を用いる場合に,GNU開発環境をconfigureする場合に指定するター
+ゲット名に定義する.ここで指定したターゲット名は,開発環境のコマンド名
+の先頭に付与される文字列となる.例えば,GCC_TARGETをm68k-unknown-elfに
+定義した場合には,コンパイラとしてm68k-unknown-elf-gccが使われる.この
+変数が定義されない場合には,単なるgccが使われる.
+
+(2-3-3) CC Cコンパイラドライバの名称
+(2-3-4) CXX C++コンパイラドライバの名称
+(2-3-5) AS アセンブラの名称
+(2-3-6) LD リンカの名称
+(2-3-7) AR アーカイバの名称
+(2-3-8) NM nmプログラムの名称
+(2-3-9) RANLIB ranlibプログラムの名称
+(2-3-10) OBJCOPY objcopyプログラムの名称
+(2-3-11) OBJDUMP objdumpプログラムの名称
+
+GNU開発環境以外の開発環境を用いる場合に,それぞれのコマンドの名称に定義
+する.対応するコマンドがない場合や,コマンドパラメータが異なる場合には,
+Makefile中でそのコマンドを呼び出している部分を変更する必要がある.
+
+GNU開発環境では,これらはGCC_TARGETを用いて定義されるので,定義する必要
+はない.
+
+2.4 コンパイルオプションとオブジェクトファイルの設定
+
+Makefileのターゲット依存部で以下で説明する変数を定義する時には,":="を
+用いて,それまでの定義に追加する形で行う.例えば,コンパイラに対するそ
+の他のオプションとして「-Wall -g -O2」を追加したい場合には,「COPTS :=
+$(COPTS) -Wall -g -O2」という記述をMakefileのターゲット依存部に含める.
+
+(2-4-1) COPTS コンパイラに対するその他のオプション
+(2-4-2) CDEFS マクロ定義オプション(-Dオプション)
+(2-4-3) INCLUDES ヘッダファイルの置かれたディレクトリ指定オ
+ プション(-Iオプション)
+(2-4-4) LDFLAGS リンカに対するその他のオプション
+(2-4-5) LIBS ライブラリリンク指定のためのオプション
+
+ターゲットに依存して,すべてのソースファイルに共通するコンパイルオプショ
+ンの追加が必要な場合には,オプションの種類毎に上に示した変数に定義する.
+
+ほとんどの場合に,ターゲット依存部ディレクトリのMakefile.targetには,以
+下の記述を含める必要がある.
+
+----------------------------------------
+INCLUDES := $(INCLUDES) -I$(TARGETDIR)
+----------------------------------------
+
+ここでTARGETDIRは,ターゲット依存部ディレクトリに定義されている.また
+SRCDIRは,Makefileにおいて,ソースプログラムのルートディレクトリ
+(configureが置かれているディレクトリ)に定義されている.
+
+コンパイラの問題等で,警告メッセージが出ることを防げない状況以外では,
+COPTSに-Werrorを追加することを推奨する.
+
+----------------------------------------
+COPTS := $(COPTS) -Werror
+----------------------------------------
+
+カーネルのコンパイル時に,dereferencing type-punned pointer will break
+strict-aliasing rulesという警告が出る場合には,以下を追加するとよい.こ
+の警告メッセージに関する詳細は,「TOPPERS/ASPカーネル 設計メモ」の「型
+キャストに伴う警告メッセージ」の節を参照すること.
+
+----------------------------------------
+KERNEL_CFLAGS := $(KERNEL_CFLAGS) -fno-strict-aliasing
+----------------------------------------
+
+また,アセンブリ言語レベルの識別名が,C言語レベルの識別名の先頭に"_"が
+付いたものになる場合には,CDEFSに-DTOPPERS_LABEL_ASMを追加する.
+
+(2-4-6) SYSSVC_DIR システムサービスのソースが置かれたディレクトリ
+(2-4-7) SYSSVC_ASMOBJS アセンブリ言語で記述されたシステムサービスの
+ オブジェクト
+(2-4-8) SYSSVC_COBJS C言語で記述されたシステムサービスのオブジェクト
+(2-4-9) SYSSVC_CFLAGS システムサービスに対するコンパイルオプション
+(2-4-10) SYSSVC_LIBS システムサービスに対するライブラリリンク指定
+
+ターゲットに依存して,システムサービス(システムログタスクやデバイスド
+ライバなど)のソースが置かれたディレクトリ,システムサービスを構成する
+オブジェクトファイルのリスト,それらをコンパイルする際に適用するコンパ
+イルオプション,その構成に必要なライブラリリンク指定を追加する場合には,
+上に示した変数に定義する.
+
+(2-4-11) KERNEL_DIR カーネルのソースが置かれたディレクトリ
+(2-4-12) KERNEL_ASMOBJS アセンブリ言語で記述されたカーネルのオブジェクト
+(2-4-13) KERNEL_COBJS C言語で記述されたカーネルのオブジェクト
+(2-4-14) KERNEL_CFLAGS カーネルに対するコンパイルオプション
+
+ターゲットに依存して,カーネルのソースが置かれたディレクトリ,カーネル
+を構成するオブジェクトファイルのリスト,それらをコンパイルする際に適用
+するコンパイルオプションを追加する場合には,上に示した変数に定義する.
+
+ほとんどの場合に,ターゲット依存部ディレクトリのMakefile.targetには,以
+下の記述を含める必要がある.
+
+----------------------------------------
+KERNEL_DIR := $(KERNEL_DIR) $(TARGETDIR)
+KERNEL_ASMOBJS := $(KERNEL_ASMOBJS) target_support.o
+KERNEL_COBJS := $(KERNEL_COBJS) target_config.o target_timer.o
+----------------------------------------
+
+(2-4-15) CFG_TABS コンフィギュレータに対するオプション
+
+ターゲットに依存して,コンフィギュレータに対するオプションを追加する場
+合には,上に示した変数に定義する.具体的には,コンフィギュレータの値取
+得シンボルテーブルのターゲット依存部(target_def.csv)がある場合には,
+それを指定するオプションを追加する必要がある.
+
+ほとんどの場合に,ターゲット依存部ディレクトリのMakefile.targetには,以
+下の記述を含める必要がある.
+
+----------------------------------------
+CFG_TABS := $(CFG_TABS) --cfg1-def-table $(TARGETDIR)/target_def.csv
+----------------------------------------
+
+(2-4-16) CFG1_OUT_LDFLAGS cfg1_out.cに対するリンクオプション
+
+ターゲットに依存して,cfg1_out.cをリンクする際に適用するオプションを追
+加する場合には,上に示した変数に定義する.
+
+(2-4-17) CFG_OBJS システムコンフィギュレーションのためのオブ
+ ジェクト
+
+ターゲットに依存して,システムコンフィギュレーションのためのオブジェク
+トファイルを(kernel_cfg.o以外に)追加する場合には,上に示した変数に定
+義する.この場合,追加したオブジェクトファイルの作成ルール(コンパイル/
+アセンブルルールと依存関係作成ルール)を,Makefileのターゲット依存部に
+記述する必要がある.
+
+(2-4-18) CFG2_OUT
+
+ターゲットに依存して,コンフィギュレータのパス2でkernel_cfg.cと
+kernel_cfg.h以外のファイルを生成する場合には,上に示した変数に定義する.
+
+(2-4-19) OMIT_WARINIG_ALL
+(2-4-20) OMIT_OPTIMIZATION
+
+サンプルのMakefileでは,コンパイラに対するオプションに「-Wall -g -O2」
+を追加する.-Wallを追加したくない場合には,Makefileのターゲット依存部で
+OMIT_WARNING_ALLを"true"に定義する.-O2を追加したくない場合には,
+Makefileのターゲット依存部でOMIT_OPTIMIZATIONを"true"に定義する.
+
+2.5 オフセットファイルの生成方法
+
+アセンブリ言語で記述されるプログラムから,C言語の構造体にアクセスする場
+合には,構造体の各フィールドのオフセットを参照することが必要である.
+ASPカーネルでは,必要なオフセット値を求めてファイル(標準ではoffset.h)
+に生成するための仕組みとして,makeoffset.cとgenoffsetを用意している.
+makeoffset.cは,どのオフセット値をファイルに生成するかを指定するもので,
+ターゲット依存部で用意する必要がある.genoffsetは,現時点ではGNU開発環
+境にのみ対応している.
+
+makeoffset.cとgenoffsetを使うことで,例えば,TCB中のtexptnフィールドの
+オフセット値をTCB_texptnにマクロ定義することや,TCB中のタスクコンテキス
+トブロック(tskctxb)に含まれるpcフィールドのオフセット値をTCB_pcにマク
+ロ定義することができる.また,TCB中のenatexフィールドのオフセット値,ビッ
+ト位置,ビットマスクを,それぞれTCB_enatex,TCB_enatex_bit,
+TCB_enatex_maskにマクロ定義することができる.
+
+GNU開発環境以外を用いる場合など,この仕組みでオフセットファイルを生成で
+きない時には,offset.hをターゲット依存部で用意し,Makefileのターゲット
+依存部でOMIT_MAKEOFFSETを"true"に定義する.
+
+拡張パッケージの中には,TCBにフィールドを追加するものがあるため,TCB中
+のフィールドのオフセット値は変化する.makeoffset.cとgenoffsetを使う場合
+でも,offset.hをターゲット依存部で用意する場合でも,拡張パッケージに対
+応するためには,このことを考慮する必要がある.
+
+2.5.1 makeoffset.cの記述方法
+
+makeoffset.cを記述する場合には,既存のターゲット依存部に含まれる
+makeoffset.cを修正するのが近道である.標準的なmakeoffset.cは,以下の6つ
+の部分で構成されている.なお,makeoffset.cを新たに記述した際には,
+offset.hに妥当な定義が生成されていることを確認するべきである.
+
+(1) 必要なファイルのインクルード
+
+オフセット値を求めたいフィールドを含む構造体を定義するヘッダファイルを
+インクルードする.TCB中のフィールドのオフセット値を求めたい場合には,以
+下の3行を含めればよい.
+
+#include "kernel_impl.h"
+#include "task.h"
+#include "sil.h"
+
+(2) オフセット値出力用マクロの定義
+
+構造体中のフィールドのオフセット値の定義を生成するために用いるマクロ
+(OFFSET_DEFとOFFSET_DEF2)の定義.これらのマクロの定義は,修正する必要
+がない.
+
+(3) オフセット値出力用関数の定義
+
+構造体中のフィールドのオフセット値の定義を生成するための関数
+(makeoffset)の定義.オフセット値のマクロ定義を生成したいフィールド毎
+に,次のいずれかのマクロを記述する.
+
+(2-5-1-1) OFFSET_DEF(TYPE, FIELD)
+
+TYPEに構造体のデータ型名,FIELDにその構造体中のフィールドを指定すると,
+TYPE_FIELDという名前のシンボルに,そのフィールドのオフセット値をマクロ
+定義する記述を生成する.
+
+(2-5-1-2) OFFSET_DEF2(TYPE, FIELD, FIELDNAME)
+
+TYPEに構造体のデータ型名,FIELDにその構造体中のフィールドを指定すると,
+TYPE_FIELDNAMEという名前のシンボルに,そのフィールドのオフセット値をマ
+クロ定義する記述を生成する.構造体に含まれる構造体中のフィールドのオフ
+セット値を求めたい場合には,こちらのマクロを使用する.
+
+(4) エンディアンを参照するための関数の定義
+
+SILで定義されたエンディアンを参照するための関数(sil_endian)の定義.こ
+の関数の定義は,修正する必要がない.
+
+(5) ビットオフセット値出力のための参照定義
+
+初期値を持った変数定義に対して,コンパイラが生成するアセンブリ命令を参
+照するための変数(BIT_REF_4,BIT_REF_2,BIT_REF_1)の定義.これらの定義
+は,ほとんどの場合に修正する必要がない.ただし,uint8_t型のサポートされ
+ていないターゲットでは,BIT_REF_1の定義は削除する必要がある.また,ポイ
+ンタが64ビットのターゲット等では,BIT_REF_8の定義を追加しなければならな
+いと思われる.
+
+(6) ビットオフセット値出力用変数の定義
+
+ビットのオフセット値,ビット位置,ビットマスクの定義を生成するためのデー
+タ型の定義.これらの定義を生成したいビットフィールド毎に,以下の説明す
+る変数を定義する.
+
+構造体のデータ型名がTYPE,その構造体中のビットフィールド名がFIELDの場合
+に,データ型がTYPEで,変数名がBIT_xy_TYPE_FIELDの変数を定義する.また,
+その変数を,対象のビットのみが1で,他のすべてのビットが0になるように初
+期化する.ここで,xはエンディアンを指定する文字で,B(ビッグエンディア
+ン)またはL(リトルエンディアン)を指定する.またyには,ビットのオフセッ
+ト,ビット位置,ビットマスクを,8ビット単位(バイト単位)で求める場合に
+はBを,16ビット単位で求める場合にはHを,32ビット単位で求める場合にはWを
+指定する.
+
+これにより,TYPE_FIELDという名前のシンボルにそのビットのオフセット,
+TYPE_FIELD_bitという名前のシンボルにビット位置,TYPE_FIELD_maskという名
+前のシンボルにビットマスクをマクロ定義する記述を生成する.なお,ビット
+位置は,LSBを0とした値(ビットリトルエンディアンを想定)を求める.
+
+2.6 リンク方法の設定
+
+(2-6-1) LDSCRIPT リンカスクリプトのファイル名
+
+開発環境に標準のリンカスクリプトが使用できない場合には,ターゲット依存
+部でリンカスクリプトを用意し,そのファイル名をこの変数に定義する.
+
+(2-6-2) TEXT_START_ADDRESS テキストセクションの先頭番地
+(2-6-3) DATA_START_ADDRESS データセクションの先頭番地
+
+各セクションの先頭番地の指定が必要な場合には,これらの変数に先頭番地を
+定義する.
+
+(2-6-4) START_OBJS 先頭にリンクすべきモジュール名
+(2-6-5) END_OBJS 最後にリンクすべきモジュール名
+
+ターゲットによっては,ロードモジュールの先頭と最後にリンクすべきモジュー
+ルを,ターゲット依存部で用意する必要がある.多くの場合,スタートアップ
+モジュールをロードモジュールの先頭にリンクする必要がある.
+
+ロードモジュールの先頭にリンクすべきプログラムがある場合には,Makefile
+のターゲット依存部において,そのオブジェクトファイル名をSTART_OBJSに定
+義し,それに対するコンパイルルールと依存関係作成ルールを定義する.ロー
+ドモジュールの最後にリンクすべきモジュールがある場合には,そのオブジェ
+クトファイル名をEND_OBJSに定義し,それに対するコンパイルルールと依存関
+係作成ルールを定義する.また,標準のスタートアップモジュール(crt0.o)
+をリンクしないように,LDFLAGSに-nostdlibを追加する必要がある.さら
+に,-nostdlibをつけることで標準ライブラリがリンクされなくなるため,
+LIBSに-lgccを追加しなければならない.
+
+例えば,スタートアップモジュールのソースファイルがstart.Sの場合には,
+Makefileのターゲット依存部に次のような記述を入れるとよい.
+
+----------------------------------------
+# スタートアップモジュールのオブジェクトファイル名
+START_OBJS = start.o
+
+# スタートアップモジュールのコンパイルルール
+$(START_OBJS): %.o: %.S
+ $(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+# スタートアップモジュールの依存関係作成ルール
+$(START_OBJS:.o=.d): %.d: %.S
+ @$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+ -O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+# リンカに対するオプション
+LDFLAGS := -nostdlib $(LDFLAGS)
+LIBS := $(LIBS) -lgcc
+----------------------------------------
+
+また,GNU開発環境で,コンパイラに標準のcrtbegin.oとcrtend.oを用いる場合
+には,Makefile のターゲット依存部に次のような記述を入れるとよい.
+
+----------------------------------------
+# オブジェクトファイル名
+START_OBJS = $(shell $(CC) -print-file-name=crtbegin.o)
+END_OBJS = $(shell $(CC) -print-file-name=crtend.o)
+
+# 依存関係作成ルール
+$(START_OBJS:.o=.d): %.d:
+$(END_OBJS:.o=.d): %.d:
+
+# リンカに対するオプション
+LDFLAGS := -nostdlib $(LDFLAGS)
+LIBS := $(LIBS) -lgcc
+----------------------------------------
+
+この場合,これらのファイルをコンパイルすることはないため,コンパイルルー
+ルは不要である.また,依存関係作成ルールはダミーでよい(依存関係作成ルー
+ルがないとエラーになる).
+
+(2-6-6) HIDDEN_OBJS 指定しなくてもリンクされるモジュール名
+
+ロードモジュールにリンクすべきモジュールを,リンカに対するパラメータで
+はなく,リンカスクリプト中に(例えば,GNU開発環境のリンカスクリプトの
+STARTUPを使って)記述する場合には,そのオブジェクトファイル名を,
+(START_OBJSまたはEND_OBJSではなく)HIDDEN_OBJSに定義し,それに対するコ
+ンパイルルールと依存関係作成ルールを定義する.HIDDEN_OBJSに定義したモ
+ジュールは,リンカに対するパラメータからは除外される.LIBSとLDFLAGSにつ
+いては,START_OBJSまたはEND_OBJSを用いる場合と同様である.
+
+例えば,スタートアップモジュールのソースファイルがstart.Sで,start.oを
+リンクすることをリンカスクリプト中に記述する場合には,Makefileのターゲッ
+ト依存部に次のような記述を入れるとよい.
+
+----------------------------------------
+# スタートアップモジュールのオブジェクトファイル名
+HIDDEN_OBJS = start.o
+
+# スタートアップモジュールのコンパイルルール
+$(HIDDEN_OBJS): %.o: %.S
+ $(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+# スタートアップモジュールの依存関係作成ルール
+$(HIDDEN_OBJS:.o=.d): %.d: %.S
+ @$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+ -O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+# リンカに対するオプション
+LDFLAGS := -nostdlib $(LDFLAGS)
+LIBS := $(LIBS) -lgcc
+----------------------------------------
+
+2.7 依存関係の定義
+
+コンフィギュレータの各パスに対して,ターゲット依存のファイルへの依存関
+係を定義する.具体的には,パス1,パス2,パス3が依存するファイルを,それ
+ぞれcfg1_out.c,kernel_cfg.timestamp,$(OBJFILE)に対する依存関係の形で
+記述する.
+
+ほとんどの場合に,ターゲット依存部ディレクトリのMakefile.targetには,以
+下の記述を含める必要がある.
+
+----------------------------------------
+cfg1_out.c: $(TARGETDIR)/target_def.csv
+kernel_cfg.timestamp: $(TARGETDIR)/target.tf
+$(OBJFILE): $(TARGETDIR)/target_check.tf
+----------------------------------------
+
+2.8 その他の設定
+
+(2-8-1) CLEAN_FILES cleanにより削除するファイル名
+
+cleanにより削除するファイルをターゲット依存部で追加したい場合には,ファ
+イル名をこの変数に追加定義する.
+
+(2-8-2) REALCLEAN_FILES realcleanにより削除するファイル名
+
+realcleanにより削除するファイルをターゲット依存部で追加したい場合には,
+ファイル名をこの変数に追加定義する.
+
+
+3.TOPPERS共通定義のターゲット依存部
+
+TOPPERS共通定義(t_stddef.h)のターゲット依存部は,target_stddef.hまた
+はそこからインクルードされるファイル(プロセッサ・チップ・開発環境依存
+部で用意されるヘッダファイルなど)に含める.
+
+3.1 ターゲット識別マクロ
+
+アプリケーションやシステムサービスでターゲットを識別するために,
+"TOPPERS_"にシステム略称を大文字にした文字列を連結したもの(例えば,
+"TOPPERS_DVE68K")をマクロ定義する.
+
+また,ターゲット依存部からプロセッサ依存部やチップ依存部を切り分けた場
+合には,"TOPPERS_"に依存部略称を大文字にした文字列を連結したもの(例え
+ば,"TOPPERS_M68K")をマクロ定義する.
+
+3.2 整数型の最大値・最小値・ビット数
+
+(3-2-1) INT_MAX intに格納できる最大値(C90準拠)
+(3-2-2) INT_MIN intに格納できる最小値(C90準拠)
+(3-2-3) UINT_MAX unsigned intに格納できる最大値(C90準拠)
+(3-2-4) LONG_MAX longに格納できる最大値(C90準拠)
+(3-2-5) LONG_MIN longに格納できる最小値(C90準拠)
+(3-2-6) ULONG_MAX unsigned longに格納できる最大値(C90準拠)
+(3-2-7) CHAR_BIT char型のビット数(C90準拠)
+
+整数型の最大値・最小値・ビット数を,これらのシンボルにマクロに定義する.
+
+これらのマクロは,C90に準拠したものである.開発環境にC90に準拠した
+limits.hが用意されている場合には,これらのマクロを定義することに代えて,
+limits.hをインクルードすればよい.
+
+3.3 サイズの指定された整数型,その最大値・最小値,整数定数を作るマクロ
+
+(3-3-1) int8_t 符号付き8ビット整数(オプション,C99準拠)
+(3-3-2) uint8_t 符号無し8ビット整数(オプション,C99準拠)
+(3-3-3) int16_t 符号付き16ビット整数(C99準拠)
+(3-3-4) uint16_t 符号無し16ビット整数(C99準拠)
+(3-3-5) int32_t 符号付き32ビット整数(C99準拠)
+(3-3-6) uint32_t 符号無し32ビット整数(C99準拠)
+(3-3-7) int64_t 符号付き64ビット整数(オプション,C99準拠)
+(3-3-8) uint64_t 符号無し64ビット整数(オプション,C99準拠)
+(3-3-9) int128_t 符号付き128ビット整数(オプション,C99準拠)
+(3-3-10) uint128_t 符号無し128ビット整数(オプション,C99準拠)
+(3-3-11) int_least8_t 8ビット以上の符号付き整数(C99準拠)
+(3-3-12) uint_least8_t 8ビット以上の符号無し整数(C99準拠)
+(3-3-13) intptr_t ポインタを格納できるサイズの符号付き整数(C99準拠)
+(3-3-14) uintptr_t ポインタを格納できるサイズの符号無し整数(C99準拠)
+(3-3-15) INT8_MAX int8_tに格納できる最大値(オプション,C99準拠)
+(3-3-16) INT8_MIN int8_tに格納できる最小値(オプション,C99準拠)
+(3-3-17) UINT8_MAX uint8_tに格納できる最大値(オプション,C99準拠)
+(3-3-18) INT16_MAX int16_tに格納できる最大値(C99準拠)
+(3-3-19) INT16_MIN int16_tに格納できる最小値(C99準拠)
+(3-3-20) UINT16_MAX uint16_tに格納できる最大値(C99準拠)
+(3-3-21) INT32_MAX int32_tに格納できる最大値(C99準拠)
+(3-3-22) INT32_MIN int32_tに格納できる最小値(C99準拠)
+(3-3-23) UINT32_MAX uint32_tに格納できる最大値(C99準拠)
+(3-3-24) INT64_MAX int64_tに格納できる最大値(オプション,C99準拠)
+(3-3-25) INT64_MIN int64_tに格納できる最小値(オプション,C99準拠)
+(3-3-26) UINT64_MAX uint64_tに格納できる最大値(オプション,C99準拠)
+(3-3-27) INT128_MAX int128_tに格納できる最大値(オプション,C99準拠)
+(3-3-28) INT128_MIN int128_tに格納できる最小値(オプション,C99準拠)
+(3-3-29) UINT128_MAX uint128_tに格納できる最大値(オプション,C99準拠)
+(3-3-30) INT_LEAST8_MAX int_least8_tに格納できる最大値(C99準拠)
+(3-3-31) INT_LEAST8_MIN int_least8_tに格納できる最小値(C99準拠)
+(3-3-32) UINT_LEAST8_MAX uint_least8_tに格納できる最大値(C99準拠)
+(3-3-33) INT8_C(val) int_least8_t型の定数を作るマクロ(C99準拠)
+(3-3-34) UINT8_C(val) uint_least8_t型の定数を作るマクロ(C99準拠)
+(3-3-35) INT16_C(val) int16_t型の定数を作るマクロ(C99準拠)
+(3-3-36) UINT16_C(val) uint16_t型の定数を作るマクロ(C99準拠)
+(3-3-37) INT32_C(val) int32_t型の定数を作るマクロ(C99準拠)
+(3-3-38) UINT32_C(val) uint32_t型の定数を作るマクロ(C99準拠)
+(3-3-39) INT64_C(val) int64_t型の定数を作るマクロ(オプション,C99準拠)
+(3-3-40) UINT64_C(val) uint64_t型の定数を作るマクロ(オプション,C99準拠)
+(3-3-41) INT128_C(val) int128_t型の定数を作るマクロ(オプション,C99準拠)
+(3-3-42) UINT128_C(val) uint128_t型の定数を作るマクロ(オプション,C99準拠)
+
+指定されたサイズの整数型を,これらのシンボルに型定義する.また,データ
+型に格納できる最大値・最小値と,整数定数を作るマクロを,これらのシンボ
+ルにマクロ定義する.
+
+これらのデータ型およびマクロは,C99に準拠したものである.開発環境にC99
+に準拠したstdint.hが用意されている場合には,これらのデータ型およびマク
+ロを定義することに代えて,stdint.hをインクルードすればよい.
+
+上でオプションと記述したものは,該当するデータ型がコンパイラでサポート
+されている場合にのみ定義することを示す.
+
+3.4 サイズの指定された浮動小数点型,その最大値・最小値のマクロ
+
+(3-4-1) float32_t IEEE754準拠の32ビット単精度浮動小数点数(オプ
+ ション)
+(3-4-2) double64_t IEEE754準拠の64ビット倍精度浮動小数点数(オプ
+ ション)
+(3-4-3) FLOAT32_MIN float32_tに格納できる最小の正規化された正の浮
+ 動小数点数(オプション)
+(3-4-4) FLOAT32_MAX float32_tに格納できる表現可能な最大の有限浮動
+ 小数点数(オプション)
+(3-4-5) DOUBLE64_MIN double64_tに格納できる最小の正規化された正の浮
+ 動小数点数(オプション)
+(3-4-6) DOUBLE64_MAX double64_tに格納できる表現可能な最大の有限浮動
+ 小数点数(オプション)
+
+指定されたサイズ・表現形式の浮動小数点型を,これらのシンボルに型定義す
+る.また,データ型に格納できる最大値・最小値を,これらのシンボルにマク
+ロ定義する.
+
+いずれも,該当するデータ型がコンパイラでサポートされている場合にのみ定
+義する.
+
+3.5 コンパイラの拡張機能のためのマクロ定義
+
+コンパイラの拡張機能を用いるためのマクロとして,必要に応じて,以下のマ
+クロの定義を含める.
+
+(3-5-1) inline(オプション,デフォルトは未定義)
+(3-5-2) Inline(オプション,デフォルトはstatic inline)
+
+インライン関数であることを示す指定.Inlineは,コンパイル単位にローカル
+なインライン関数であることを示す.
+
+(3-5-3) asm(オプション,デフォルトは未定義)
+(3-5-4) Asm(オプション,デフォルトは未定義)
+
+インラインアセンブラを記述するための指定.Asmは,最適化により削除しては
+ならないことを示す.これらは,ターゲット依存部でのみ使うマクロであるた
+め,ターゲット依存部で使わないなら定義する必要はない.
+
+(3-5-5) offsetof(structure, field)(オプション,デフォルトの定義あり)
+
+構造体structureの中での,フィールドfieldのオフセットを求めるマクロ.
+
+(3-5-6) alignof(type)(オプション,デフォルトの定義あり)
+
+データ型typeのアラインメント単位を求めるマクロ.
+
+(3-5-7) NoReturn(オプション,デフォルトは未定義)
+
+リターンすることのない関数であることを示す指定.これは,ターゲット依存
+部のみ使うマクロであるため,ターゲット依存部で使わないなら定義する必要
+はない.
+
+3.6 標準的な定義の上書き
+
+t_stddef.hに含まれるTOPPERS共通定義の標準的な定義を上書きする場合には,
+以下のマクロを定義する.
+
+(3-6-1) TOPPERS_bool(オプション,デフォルトはint)
+(3-6-2) TOPPERS_size(オプション,デフォルトはuintptr_t)
+(3-6-3) TOPPERS_fp(オプション,デフォルトは他と互換性のない関数ポインタ)
+
+それぞれ,bool_t,SIZE,FPに型定義すべきデータ型.
+
+(3-6-4) UINT_C(val)(オプション,デフォルトはUを付加)
+(3-6-5) ULONG_C(val)(オプション,デフォルトはULを付加)
+
+それぞれ,unsigned uint型,unsigned long型の定数を作るためのマクロ.
+
+(3-6-6) NULL(オプション,デフォルトは0)
+
+C90準拠のC言語環境では,NULLの定義はstddef.hに含まれているため,これを
+インクルードしてもよい.
+
+(3-6-7) ERCD(mercd, sercd)(オプション)
+(3-6-8) MERCD(ercd)(オプション)
+(3-6-9) SERCD(ercd)(オプション)
+
+ERCD,MERCD,SERCDの標準の定義は,符号付き整数が2の補数で表現されており,
+右シフト演算子(>>)が算術シフトされることを仮定している.多くのコンパ
+イラでこの仮定が成り立つが,そうでない場合には,ターゲット依存部でこれ
+らの定義を上書きする必要がある.
+
+(3-6-10) ALIGN_TYPE(addr, type)(オプション)
+
+アドレスaddrが,データ型typeのアラインメント単位にアラインしているか
+チェックするマクロ.
+
+3.7 アサーションのための定義
+
+t_stddef.hには,assertの定義が含まれる.assertが失敗した場合(assertの
+パラメータがfalseになった場合)の処理を,ターゲット依存に用意する必要が
+ある.これらの定義は,assertマクロを使用する前であれば,t_stddef.h以降
+にインクルードされるファイルに含まれていてもよい.なお,assertを無効に
+する(NDEBUGをマクロ定義してコンパイルする)場合には,これらを用意する
+必要はない.
+
+(3-7-1) TOPPERS_assert_abort(void)
+
+assertが失敗した場合に,プログラムを停止させる関数.システム開発中はデ
+バッガに落とすのが理想的である.システム稼働時には例外処理を行わせるこ
+とになる.
+
+(3-7-2) TOPPERS_assert_fail(exp, file, line)
+
+assertが失敗した時の情報を表示/記録するためのマクロ.システムログ機能を
+用いる場合には,t_syslog.hにシステムログ機能に記録するための定義が含ま
+れているので,ターゲット依存部で用意する必要はない.
+
+
+4.システムインタフェースレイヤ(SIL)のターゲット依存部
+
+システムインタフェースレイヤ(SIL,sil.h)のターゲット依存部の定義は,
+target_sil.hまたはそこからインクルードされるファイル(プロセッサ・チッ
+プ・開発環境依存部で用意されるヘッダファイルなど)に含める.
+
+SILのサービスコールは,任意のシステム状態で呼び出すことができる.そのた
+め,SILのターゲット依存部の関数は,任意のシステム状態で呼び出せるように
+実装しなければならない.
+
+4.1 全割込みロック状態の管理
+
+SILのターゲット依存部では,全割込みロック状態へ遷移する機能と,元の状態
+へ戻す機能(元の状態を記憶するために変数を使う)を提供する.全割込みロッ
+ク状態であるかを判別する機能は提供する必要がない.
+
+SILの機能は,カーネルを使用しない場合にも使用できる必要がある.そのため,
+全割込みロック状態への遷移と元の状態への復帰は,カーネルを用いず,プロ
+セッサのリソースを直接操作することによって実現する.また,全割込みロッ
+ク状態への遷移と元の状態への復帰は,全割込みロック状態やCPUロック状態で
+も行える必要がある.
+
+保護機能を持ったカーネルでは,ユーザタスクからプロセッサのリソースを直
+接操作することができないため,ユーザタスクからはこれらの機能を用いるこ
+とができない.用いた場合の振舞いはターゲットプロセッサに依存するが,典
+型的には,特権命令違反などのCPU例外が発生することになる.
+
+(4-1-1) SIL_PRE_LOC
+
+全割込みロックフラグの状態を保存するための変数を定義するマクロ.型名の
+後に,変数名を続けたものに定義する.変数名は,他の名前と衝突しないよう
+に,"TOPPERS_"で始まる名前にする.
+
+(4-1-2) SIL_LOC_INT()
+
+現在の全割込みロックフラグの状態をSIL_PRE_LOCで定義した変数に保存し,全
+割込みロック状態に遷移させるマクロ.このマクロを実現する際には,「1.6
+クリティカルセクションの出入処理の実現に関する制約」の節に記述されてい
+る制約に従わなければならない.
+
+(4-1-3) SIL_UNL_INT()
+
+SIL_LOC_INT()によって変数に保存した状態に戻すマクロ.このマクロを実現す
+る際には,「1.6 クリティカルセクションの出入処理の実現に関する制約」の
+節に記述されている制約に従わなければならない.
+
+4.2 微少時間待ち
+
+(4-2-1) void sil_dly_nse(ulong_t dlytim)
+
+dlytimで指定された以上の時間(単位はナノ秒),ループなどによって待つ関
+数.
+
+以下の関数と等価な処理を,アセンブリ言語で記述する方法を,標準的な実装
+方法とする.アセンブリ言語で記述するのは,コンパイラの最適化に依存しな
+いようにするためである.またこの関数は,キャッシュ等の影響を受けないよ
+うに,できる限りメモリアクセスを行わないように実装すべきである.
+
+ void sil_dly_nse(ulong_t dlytim)
+ {
+ dlytim -= SIL_DLY_TIM1;
+ if (結果が0より大きい) {
+ do {
+ dlytim -= SIL_DLY_TIM2;
+ } while (結果が0より大きい);
+ }
+ }
+
+この関数の動作は次の通りである.dlytimがSIL_DLY_TIM1以下の場合には,最
+初のif文の条件が成立せず,すぐに関数から抜ける.dlytimがSIL_DLY_TIM1よ
+り大きく,(SIL_DLY_TIM1+SIL_DLY_TIM2)以下の場合には,最初のif文の条件は
+成立するが,doループは1回も回らずに関数から抜ける.dlytimが
+(SIL_DLY_TIM1+SIL_DLY_TIM2)より大きく,(SIL_DLY_TIM1+SIL_DLY_TIM2*2)以
+下の場合には,doループを1回だけ回って関数から抜ける.その後,dlytimが
+SIL_DLY_TIM2大きくなる度に,whileループを回る回数が1回ずつ増える.
+
+なお,この関数をアセンブリ言語(または,C言語)で記述する場合,どのファ
+イルに記述するかが問題になる.SILのターゲット依存部には,標準では,アセ
+ンブリ言語(または,C言語)の関数定義を記述するためのファイルを用意して
+いない.ターゲット依存で用意してもよいが,例外的に,カーネル実装のター
+ゲット依存モジュール(target_support.Sまたはtarget_config.c)に記述して
+もよいことにする.
+
+(4-2-2) SIL_DLY_TIM1(オプション)
+(4-2-3) SIL_DLY_TIM2(オプション)
+
+sil_dly_nseを上記の標準的な方法で実現した場合,この2つの定数をターゲッ
+ト依存部でマクロ定義する.
+
+SIL_DLY_TIM2は,上記の関数において,doループ1回の実行時間(単位はナノ秒)
+に設定する.ターゲットプロセッサの命令セットにもよるが,おおよそ,減算
+命令と条件分岐命令各1回の実行時間になる.SIL_DLY_TIM2が決まれば,関数呼
+出しも含めた全体の時間がdlytimで指定された以上の時間になるように,
+SIL_DLY_TIM1を決める.
+
+この2つの定数値の決定を支援するプログラムとして,testディレクトリに,
+test_dlynseを用意している.test_dlynseを実行すると,次のような出力が得
+られる.
+
+-- for fitting parameters --
+sil_dly_nse(0): 430 OK
+sil_dly_nse(420): 430 OK
+sil_dly_nse(510): 520 OK
+sil_dly_nse(600): 610 OK
+<中略>
+-- for checking boundary conditions --
+sil_dly_nse(421): 520 OK
+sil_dly_nse(511): 610 OK
+sil_dly_nse(601): 700 OK
+
+"for fitting parameters"に続く出力は,sil_dly_nse(dlytim)を呼び出した場
+合の待ち時間を測定した結果である.このプログラムを用いて,":"の右側の数
+値が,dlytimよりも大きい範囲でなるべく近い値になるように,2つの定数値を
+調整する."for checking boundary conditions"に続く出力は,プログラムの
+妥当性をチェックするためのもので,":"の右側の数値が,dlytimよりも大きい
+ことを確認する(近い値になる必要はない).
+
+4.3 プロセッサのエンディアン
+
+(4-3-1) SIL_ENDIAN_BIG
+(4-3-2) SIL_ENDIAN_LITTLE
+
+プロセッサのエンディアンにより,いずれか片方のシンボルをマクロ定義する.
+
+(4-3-3) TOPPERS_SIL_REV_ENDIAN_UINT16(オプション)
+(4-3-4) TOPPERS_SIL_REV_ENDIAN_UINT32(オプション)
+
+それぞれ,16ビット,32ビットの符号無し整数のエンディアンを反転させるマ
+クロ.プロセッサがエンディアン反転のための命令を持つ場合には,その命令
+を用いて実現する.これらのシンボルをマクロ定義しない場合には,デフォル
+トの定義が使われる.
+
+4.4 メモリ空間アクセス関数
+
+(4-4-1) TOPPERS_OMIT_SIL_ACCESS
+
+標準のメモリ空間アクセス関数を使用せず,ターゲット依存部で用意する場合
+には,このシンボルをマクロ定義する.
+
+(4-4-2) TOPPERS_OMIT_SIL_REH_LEM
+(4-4-3) TOPPERS_OMIT_SIL_WRH_LEM
+(4-4-4) TOPPERS_OMIT_SIL_REH_BEM
+(4-4-5) TOPPERS_OMIT_SIL_WRH_BEM
+(4-4-6) TOPPERS_OMIT_SIL_REW_LEM
+(4-4-7) TOPPERS_OMIT_SIL_WRW_LEM
+(4-4-8) TOPPERS_OMIT_SIL_REW_BEM
+(4-4-9) TOPPERS_OMIT_SIL_WRW_BEM
+
+それぞれ,標準のsil_reh_lem,sil_wrh_lem,sil_reh_bem,sil_wrh_bem,
+sil_rew_lem,sil_wrw_lem,sil_rew_bem,sil_wrw_bemを使用せず,ターゲッ
+ト依存部で用意する場合には,これらのシンボルをマクロ定義する.
+
+4.5 I/O空間アクセス関数
+
+メモリ空間とは別にI/O空間を持つプロセッサでは,I/O空間にあるデバイスレ
+ジスタをアクセスするための関数として,sil_reb_iop,sil_wrb_iop,
+sil_reh_iop,sil_wrh_iop,sil_reh_lep,sil_wrh_lep,sil_reh_bep,
+sil_wrh_bep,sil_rew_iop,sil_wrw_iop,sil_rew_lep,sil_wrw_lep,
+sil_rew_bep,sil_wrw_bepの中で必要なものを,ターゲット依存部で用意する.
+
+
+5.カーネルAPIのターゲット依存部
+
+カーネルAPI(kernel.h)のターゲット依存部の定義は,target_kernel.hまた
+はそこからインクルードされるファイル(プロセッサ・チップ・開発環境依存
+部で用意されるヘッダファイルなど)に含める.
+
+5.1 ターゲット定義でサポートする機能
+
+(5-1-1) TOPPERS_TARGET_SUPPORT_DIS_INT dis_intをサポートする
+(5-1-2) TOPPERS_TARGET_SUPPORT_ENA_INT ena_intをサポートする
+(5-1-3) TOPPERS_TARGET_SUPPORT_GET_UTM get_utmをサポートする
+
+dis_int,ena_int,get_utmをサポートする場合に,それぞれのシンボルをマク
+ロ定義する.
+
+5.2 割込み優先度の範囲
+
+(5-2-1) TMIN_INTPRI 割込み優先度の最小値(最高値)
+(5-2-2) TMAX_INTPRI 割込み優先度の最大値(最低値)
+
+それぞれ,カーネル管理の割込み優先度の最小値(=優先度が最高),カーネ
+ル管理の割込み優先度の最大値(優先度が最低)に定義する.TMAX_INTPRIは-1
+に固定されているが,対称性のために,ターゲット依存部で定義することにし
+ている.
+
+5.3 タイムティックの定義
+
+(5-3-1) TIC_NUME タイムティックの周期の分子
+(5-3-2) TIC_DENO タイムティックの周期の分母
+
+タイムティックの周期(signal_timeを呼び出す周期)を,ミリ秒単位で,
+TIC_NUME/TIC_DENOに定義する.例えば,タイムティックの周期が1/30秒の場合
+には,TIC_NUMEを100に,TIC_DENOを3に定義すればよい.
+
+タイムティックの周期は,1ミリ秒とする(つまり,TIC_NUME,TIC_DENOとも1
+に定義する)ことを推奨するが,シミュレーション環境や性能の低いプロセッ
+サでそれが適切でない場合には,それ以外の値としてもよい.その場合でも,
+可能な限り,1ミリ秒の倍数である(つまり,TIC_DENOを1に定義する)ことが
+望ましい.
+
+TIC_NUMEとTIC_DENOの定義を変更することで,タイムティックの周期を変更で
+きるようにタイマドライバを実装する場合には,この2つの定数の定義はデフォ
+ルト値を与えていることになる.そこで,これらの定義を「#ifndef TIC_NUME」
+「#endif」で囲んで記述する.
+
+5.4 メモリ領域確保のための型定義
+
+(5-4-1) TOPPERS_STK_T スタック領域を確保するための型(オプション)
+(5-4-2) TOPPERS_MPF_T 固定長メモリプール領域を確保するための型(オプション)
+
+スタック領域と固定長メモリプール領域は,標準では,intptr_t型の配列とし
+て確保するが,より大きい単位でアラインさせたいなどの理由で,それ以外の
+型の配列として確保する場合には,それぞれTOPPERS_STK_TとTOPPERS_MPF_Tを,
+配列のベースとなるデータ型にマクロ定義する.
+
+5.5 ビットパターンのビット数
+
+(5-5-1) TBIT_TEXPTN タスク例外要因のビット数(オプション)
+(5-5-2) TBIT_FLGPTN イベントフラグのビット数(オプション)
+
+TBIT_TEXPTN,TBIT_FLGPTNの標準の定義では,整数型の有効ビット数が,その
+型のsizeofにCHAR_BITを乗じたものと一致していることを仮定している.多く
+のコンパイラでこの仮定が成り立つが,そうでない場合には,ターゲット依存
+部でこれらの定義を上書きする必要がある.ただし,これらの値は16以上でな
+ければならない.
+
+5.6 メモリ領域確保のためのマクロ
+
+(5-6-1) TOPPERS_ROUND_SZ(オプション)
+(5-6-2) TOPPERS_COUNT_SZ(オプション)
+
+TOPPERS_COUNT_SZ(sz, unit)は,sz/unitを切り上げた値を求めるマクロで,サ
+イズがszのメモリ領域をサイズがunitのデータ型の配列で確保する場合の要素
+数を求めるために用いる.TOPPERS_ROUND_SZ(sz, unit)は,sz/unitを切り上げ
+たものにunitをかけた値を求めるマクロで,サイズがszのメモリ領域をサイズ
+がunitのデータ型の配列で確保する場合のトータルサイズを求めるために用い
+る.
+
+それぞれ,標準のTOPPERS_ROUND_SZ,TOPPERS_COUNT_SZが適切でなく,ターゲッ
+ト依存部で用意する場合には,これらのシンボルを適切な値にマクロ定義する.
+
+5.7 オーバランハンドラ機能拡張のための定義(オプション)
+
+オーバランハンドラ機能拡張パッケージをサポートする(使用できるようにす
+る)場合には,次の3つを実施することが必要である.
+
+・この節で説明する定義を行う.
+・6章に示すコード中で,TOPPERS_SUPPORT_OVRHDRがマクロ定義されている場
+ 合にのみ有効となるコードを実装する.
+・オーバランタイマドライバを用意する.オーバランタイマドライバについて
+ は,「6.14 オーバランタイマドライバ」の節を参照すること.
+
+(5-7-1) TOPPERS_TARGET_SUPPORT_OVRHDR
+
+オーバランハンドラ機能拡張パッケージをサポートする場合には,このシンボ
+ルをマクロ定義する.
+
+(5-7-2) TMAX_OVRTIM(オプション,デフォルトはULONG_MAX)
+
+プロセッサ時間としてオーバランタイマに設定できる最大値(単位はマイクロ
+秒)にマクロ定義する.
+
+
+6.カーネル実装のターゲット依存部
+
+6.1 カーネル実装のターゲット依存部の共通事項
+
+6.1.1 カーネル実装のターゲット依存部の構成要素
+
+カーネル実装のターゲット依存部は,以下の要素で構成される.
+
+(a) カーネル実装のターゲット依存の定義
+
+カーネル実装のターゲット非依存部から参照されるターゲット依存の定義は,
+target_config.hまたはそこからインクルードされるファイル(プロセッサ・チッ
+プ・開発環境依存部で用意されるヘッダファイルなど)に含める.
+
+ターゲットのハードウェア資源(割込みハンドラ番号やCPU例外ハンドラ番号,
+デバイスレジスタの番地など)の定義は,システムサービスやアプリケーショ
+ンにも有用であるため,カーネル実装のみに有用な定義を含むファイルとは切
+り分けて,独立したヘッダファイルに含める.このヘッダファイルの標準的な
+名称を,システム略称.h(または,チップ略称.h,プロセッサ略称.h)とする.
+
+(b) カーネル実装のターゲット依存モジュール
+
+カーネル実装のターゲット依存の変数定義や関数を含むモジュール.C言語で記
+述される部分をtarget_config.c,アセンブリ言語で記述される部分を
+target_support.Sに含める.プロセッサ・チップ・開発環境依存部を切り分け
+ることや,ファイルが大きくなる場合に複数のファイルに分割することも可能
+である.
+
+(c) カーネル実装のターゲット依存部のためのリネーム記述
+
+カーネル実装のターゲット依存部の変数名や関数名を,先頭に_kernel_を付与
+した名前にリネームするためのモジュール.target_rename.defを用意し,ツー
+ル(utils/genrename)により,target_rename.hとtarget_unrename.hを生成す
+る.プロセッサ・チップ・開発環境依存部を切り分ける場合には,リネーム記
+述も切り分ける.
+
+(d) タイマドライバ
+
+カーネルにタイムティックを通知する(signal_timeを周期的に呼び出す)ため
+のタイマドライバのヘッダファイル,実装ファイル,システムコンフィギュレー
+ションファイルを,それぞれ,target_timer.h,target_timer.c,
+target_timer.cfgに含める.プロセッサ・チップ・開発環境依存部を切り分け
+ることも可能である.
+
+また,オーバランハンドラ機能拡張パッケージをサポートする場合には,オー
+バランハンドラを起動する(call_ovrhdrを呼び出す)ためのオーバランタイマ
+ドライバも,同じファイルに含める.
+
+なお,この章に示すコード中で,TOPPERS_SUPPORT_OVRHDRがマクロ定義されて
+いる場合にのみ有効となるコードは,オーバランハンドラ機能拡張パッケージ
+をサポートしない場合には,実装する必要がない.
+
+(e) コンフィギュレータ設定ファイル
+
+コンフィギュレータの設定ファイルのターゲット依存部を,target_def.csv,
+target.tf,target_check.tfに用意する.コンフィギュレータ設定ファイルの
+記述方法については,7章で説明する.
+
+6.1.2 ターゲット依存部の関数の命名規則
+
+カーネル実装のターゲット依存部を構成する関数の中で,t_で始まるものはタ
+スクコンテキスト専用,i_で始まるものは非タスクコンテキスト専用,x_で始
+まるものはいずれのコンテキストからでも呼び出すことができる関数である.
+
+6.2 トレースログ機能への対応
+
+カーネルのトレースログ機能の中で,ディスパッチャ,割込みハンドラ,CPU例
+外ハンドラの開始・終了のトレースログ取得は,ターゲット依存部で実装する
+必要がある.ほとんどのターゲットシステムにおいて,それらの処理はアセン
+ブリ言語で記述されており,ターゲット非依存部向けのトレースログマクロと
+同じ方法(トレースログマクロを,トレースログ取得処理のC言語記述にマクロ
+定義する方法)は,用いることができない.
+
+そこで,アセンブリ言語で記述されている処理中にトレースログ取得を埋め込
+む場合には,トレースログマクロが定義されていれば,それが何に定義されて
+いるかは無視して,標準的なトレースログ関数がC言語で記述されていると想定
+して,それを呼び出すようにコーディングする.
+
+具体的には,下の表の左側に示したトレースログマクロが定義されていれば,
+表の右側に示したC言語記述と同等の処理を行うようにコーディングする.
+
+ トレースログマクロ トレースログ取得処理
+ -----------------------------------------------
+ LOG_DSP_ENTER log_dsp_enter(p_runtsk)
+ LOG_DSP_LEAVE log_dsp_leave(p_runtsk)
+ LOG_INH_ENTER log_inh_enter(inhno)
+ LOG_INH_LEAVE log_inh_leave(inhno)
+ LOG_EXC_ENTER log_exc_enter(excno)
+ LOG_EXC_LEAVE log_exc_leave(excno)
+
+6.3 システム状態の管理
+
+ASPカーネルを新たなターゲットシステムにポーティングする際に,最も重要な
+作業は,カーネルが定義するシステム状態を,ハードウェア(プロセッサ)上
+でどのように実現するかである.以下の説明は,TOPPERS新世代カーネルにおけ
+るシステム状態の定義・意味を知っていることを前提に記述している.
+
+6.3.1 全割込みロック状態の管理
+
+全割込みロック状態は,NMIを除くすべての割込みをマスクした状態である.全
+割込みロック状態を管理する機能は,システムインタフェースレイヤ(SIL)に
+よって提供され,カーネルは全割込みロック状態を管理しない.
+
+全割込みロック状態では,sns_kerとext_ker以外のカーネルのサービスコール
+を呼ぶことはできないものとしており,呼んだ場合には何が起こるか保証して
+いない.sns_kerとext_kerから呼び出す処理は,トレースログ取得処理とSILの
+サービスコールを除くと,call_exit_kernelのみである.そのため,
+call_exit_kernelから呼び出すものを除いて,カーネルのターゲット依存部の
+関数が,全割込みロック状態で呼び出される状況は考える必要がない.
+
+6.3.2 コンテキストの管理
+
+処理単位が実行されるコンテキストは,タスクコンテキストと非タスクコンテ
+キストに分類される.
+
+ターゲット依存部は,実行中の処理単位が,タスクコンテキストで実行されて
+いるか非タスクコンテキストで実行されているかを判別する機能を提供する.
+また,CPU例外が発生したコンテキストについて判別する機能を提供する.
+
+ターゲット依存部では,割込みハンドラとCPU例外ハンドラの入口処理で非タス
+クコンテキストに切り換え,それらの出口処理で元のコンテキストに戻す.ま
+た,ディスパッチャの内部で一時的に非タスクコンテキストに切り換える.
+
+(6-3-2-1) bool_t sense_context(void)
+
+実行中の処理単位が,タスクコンテキストで実行されている場合にはfalse,非
+タスクコンテキストで実行されている場合にはtrueを返す関数.この関数は,
+CPUロック状態でもCPUロック解除状態でも呼び出せるように実装しなければな
+らない.
+
+6.3.3 CPUロック状態の管理
+
+ターゲット依存部は,CPUロック状態へ遷移する機能,CPUロック解除状態へ遷
+移する機能,CPUロック状態であるかを判別する機能を提供する.
+
+(6-3-3-1) void t_lock_cpu(void)
+(6-3-3-2) void i_lock_cpu(void)
+(6-3-3-3) void x_lock_cpu(void)
+
+CPUロック解除状態から,CPUロック状態へ遷移させる関数.これらの関数は,
+CPUロック状態で呼び出されることはなく,呼び出された場合の動作は保証する
+必要がない.
+
+これらの関数を実現する際には,「1.6 クリティカルセクションの出入処理の
+実現に関する制約」の節に記述されている制約に従わなければならない.
+
+(6-3-3-4) void t_unlock_cpu(void)
+(6-3-3-5) void i_unlock_cpu(void)
+(6-3-3-6) void x_unlock_cpu(void)
+
+CPUロック状態から,CPUロック解除状態へ遷移させる関数.これらの関数は,
+CPUロック解除状態で呼び出されることはなく,呼び出された場合の動作は保証
+する必要がない.
+
+タスクコンテキストでCPUロック状態に遷移した場合には,CPUロック解除状態
+に戻るのはタスクコンテキストに限られ,非タスクコンテキストでCPUロック解
+除状態に戻ることはない.言い換えると,t_unlock_cpuが呼び出されるのは,
+t_lock_cpuによってCPUロック状態になっている時である.i_lock_cpuによって
+CPUロック状態になっている時には,t_unlock_cpuが呼び出されることはない.
+
+同様に,非タスクコンテキストでCPUロック状態に遷移した場合には,CPUロッ
+ク解除状態に戻るのは非タスクコンテキストに限られ,タスクコンテキストで
+CPUロック解除状態に戻ることはない.言い換えると,i_unlock_cpuが呼び出さ
+れるのは,i_lock_cpuによってCPUロック状態になっている時である.
+t_lock_cpuによってCPUロック状態になっている時には,i_unlock_cpuが呼び出
+されることはない.
+
+これらの関数を実現する際には,「1.6 クリティカルセクションの出入処理の
+実現に関する制約」の節に記述されている制約に従わなければならない.
+
+(6-3-3-7) bool_t t_sense_lock(void)
+(6-3-3-8) bool_t i_sense_lock(void)
+(6-3-3-9) bool_t x_sense_lock(void)
+
+現在のシステム状態が,CPUロック状態の場合はtrue,CPUロック解除状態の場
+合にはfalseを返す関数.
+
+これらの関数が全割込みロック状態で呼び出される状況は考える必要がないこ
+とから,全割込みロック状態とCPUロック状態を区別できる必要はない.NMI以
+外にカーネルの管理外の割込みを設けない場合には,全割込みロック状態と
+CPUロック状態が全く同一の状態でもかまわない.
+
+6.4 割込みに関連するシステム状態の管理
+
+6.4.1 割込み優先度マスクの管理
+
+ターゲット依存部は,割込み優先度マスクを設定する機能と,割込み優先度マ
+スクを参照する機能を提供する.
+
+(6-4-1-1) bool_t VALID_INTPRI_CHGIPM(PRI intpri)(オプション)
+
+intpriが,chg_ipmに対する割込み優先度として有効な値である場合にtrue,そ
+うでない場合にfalseを返すマクロ.標準では,TMIN_INTPRI以上,TIPM_ENAALL
+(=0)以下の値がchg_ipmに対する割込み優先度として有効であるが,ターゲッ
+ト依存部でこのマクロを定義することで,TMIN_INTPRIよりも小さい値を有効と
+することができる(有効な値の範囲を狭めてはならない).
+
+(6-4-1-2) void x_set_ipm(PRI intpri)
+(6-4-1-3) void t_set_ipm(PRI intpri)
+(6-4-1-4) void i_set_ipm(PRI intpri)
+
+割込み優先度マスクの値をintpriに設定する関数.
+
+これらの関数は,CPUロック状態でもCPUロック解除状態でも呼び出せるように
+実装するのが望ましい.ただし,x_set_ipmとt_set_ipmは,ターゲット非依存
+部がCPUロック解除状態で呼び出すことはないため,CPUロック解除状態で呼び
+出された場合の動作は保証する必要がない.i_set_ipmは,CPUロック状態でも
+CPUロック解除状態でも呼び出せるように実装しなければならない.
+
+また,これらの関数は,VALID_INTPRI_CHGIPM(intpri)がtrueを返すintpriに対
+してのみ呼ばれる.intpriにそうでない値が渡された場合の動作は保証する必
+要がない.
+
+(6-4-1-5) PRI x_get_ipm(void)
+(6-4-1-6) PRI t_get_ipm(void)
+(6-4-1-7) PRI i_get_ipm(void)
+
+割込み優先度マスクの値を参照して返す関数.
+
+これらの関数は,CPUロック状態でもCPUロック解除状態でも呼び出せるように
+実装するのが望ましい.ただし,x_get_ipmとt_get_ipmは,ターゲット非依存
+部がCPUロック解除状態で呼び出すことはないため,CPUロック解除状態で呼び
+出された場合の動作は保証する必要がない.i_get_ipmは,CPUロック状態でも
+CPUロック解除状態でも呼び出せるように実装しなければならない.
+
+割込み優先度マスクを用いてカーネル管理の割込みをすべてマスクした状態は,
+CPUロック状態と区別できることが必要である.具体的には,CPUロック解除状
+態において,x_set_ipmを用いてカーネル管理の割込みをすべてマスクした場合
+でも,x_sense_lockはfalseを返す.
+
+それに対して,割込み優先度マスクを用いてNMIを除くすべての割込みをマスク
+できる場合,その状態と全割込みロック状態を区別できる必要はなく,全く同
+一の状態でもかまわない.
+
+6.4.2 割込み要求禁止フラグの管理
+
+ターゲット依存部は,割込み要求禁止フラグをセットする機能とクリアする機
+能を提供する.
+
+(6-4-2-1) bool_t VALID_INTNO_DISINT(INTNO intno)
+
+intnoが,dis_int/ena_intに対する割込み番号として有効な値である場合に
+true,そうでない場合にfalseを返すマクロ.割込み要求禁止フラグがセット/
+クリアできないintnoに対しては,このマクロがfalseを返すようにする.
+
+(6-4-2-2) bool_t x_disable_int(INTNO intno)
+(6-4-2-3) bool_t t_disable_int(INTNO intno)
+(6-4-2-4) bool_t i_disable_int(INTNO intno)
+
+intnoで指定された割込み要求ラインに対する割込み要求禁止フラグをセットし,
+trueを返す関数.指定された割込み要求ラインに対して,割込み属性が設定さ
+れていない場合には,falseを返す.
+
+これらの関数は,ターゲット非依存部がCPUロック解除状態で呼び出すことはな
+いため,CPUロック解除状態で呼び出された場合の動作は保証する必要がない.
+ただし,ターゲット依存部からCPUロック解除状態で呼び出す場合には,保証す
+る必要がある.
+
+また,これらの関数は,VALID_INTNO_DISINT(intno)がtrueとなるintnoに対し
+てのみ呼ばれる.intnoにそうでない値が渡された場合の動作は保証する必要が
+ない.
+
+dis_intサービスコールをサポートする場合(TOPPERS_SUPPORT_DIS_INTをマク
+ロ定義する場合)には,t_disable_intが用意されていなければならない.
+
+(6-4-2-5) bool_t x_enable_int(INTNO intno)
+(6-4-2-6) bool_t t_enable_int(INTNO intno)
+(6-4-2-7) bool_t i_enable_int(INTNO intno)
+
+intnoで指定された割込み要求ラインに対する割込み要求禁止フラグをクリアし,
+trueを返す関数.指定された割込み要求ラインに対して,割込み属性が設定さ
+れていない場合には,falseを返す.
+
+これらの関数は,ターゲット非依存部がCPUロック解除状態で呼び出すことはな
+いため,CPUロック解除状態で呼び出された場合の動作は保証する必要がない.
+ただし,ターゲット依存部からCPUロック解除状態で呼び出す場合には,保証す
+る必要がある.
+
+また,これらの関数は,VALID_INTNO_DISINT(intno)がtrueとなるintnoに対し
+てのみ呼ばれる.intnoにそうでない値が渡された場合の動作は保証する必要が
+ない.
+
+ena_intサービスコールをサポートする場合(TOPPERS_SUPPORT_ENA_INTをマク
+ロ定義する場合)には,t_enable_intが用意されていなければならない.
+
+6.4.3 割込み要求のクリア
+
+(6-4-3-1) void x_clear_int(INTNO intno)
+(6-4-3-2) void t_clear_int(INTNO intno)
+(6-4-3-3) void i_clear_int(INTNO intno)
+
+intnoで指定された割込み要求ラインがエッジトリガである場合に,トリガされ
+た割込み要求をクリアする関数.intnoで指定された割込み要求ラインがレベル
+トリガである場合には何もしない.
+
+ASPカーネルのターゲット非依存部では,これらの関数を呼び出していないが,
+ターゲット依存部やシステムサービスで呼び出す可能性が高いため,用意する
+こととしている.そのため,これらの関数がどのようなシステム状態で呼び出
+せるかは,ターゲット依存部内で一貫していればよい.
+
+6.4.4 割込み要求のプローブ
+
+(6-4-4-1) bool_t x_probe_int(INTNO intno)
+(6-4-4-2) bool_t t_probe_int(INTNO intno)
+(6-4-4-3) bool_t i_probe_int(INTNO intno)
+
+intnoで指定された割込み要求ラインに対して,割込みが要求されている場合に
+true,そうでない場合にfalseを返す関数.
+
+ASPカーネルのターゲット非依存部では,これらの関数を呼び出していないが,
+ターゲット依存部やシステムサービスで呼び出す可能性が高いため,用意する
+こととしている.そのため,これらの関数がどのようなシステム状態で呼び出
+せるかは,ターゲット依存部内で一貫していればよい.
+
+6.4.5 割込みハンドラの先頭処理と末尾処理
+
+(6-4-5-1) void i_begin_int(INTNO intno)
+
+intnoで指定された割込み要求ラインに対する割込みハンドラの先頭で行うべき
+処理を行う関数.ここで行うべき処理としては,割込み要求ラインがエッジト
+リガである場合のトリガされた割込み要求のクリアが挙げられる.
+
+intnoに対して登録された割込みサービスルーチンを呼び出す割込みハンドラの
+先頭で呼び出される.そのためこの関数は,割込みハンドラの先頭(通常は
+CPUロック解除状態)で呼び出せるように実装しなければならない.
+
+(6-4-5-2) void i_end_int(INTNO intno)
+
+intnoで指定された割込み要求ラインに対する割込みハンドラの末尾で行うべき
+処理を行う関数.ここで行うべき処理としては,割込みコントローラ(IRC)に
+対する割込み処理の終了を通知が挙げられる.
+
+intnoに対して登録された割込みサービスルーチンを呼び出す割込みハンドラの
+末尾で呼び出される.そのためこの関数は,割込みハンドラの末尾(通常は
+CPUロック解除状態)で呼び出せるように実装しなければならない.
+
+6.5 タスクディスパッチャ
+
+6.5.1 タスクコンテキストブロックとタスク初期化コンテキストブロック
+
+(6-5-1-1) TSKCTXB
+
+ターゲット依存のタスクコンテキストを保存するために,TCB中に持つことが必
+要なデータ構造の型を,TSKCTXBに定義する.標準的には,TSKCTXBには,タス
+クのスタックポインタと実行再開番地を格納する.
+
+(6-5-1-2) USE_TSKINICTXB(オプション)
+(6-5-1-3) TSKINICTXB(オプション)
+
+ターゲット依存の情報をタスク初期化ブロック(TINIB)に入れたい場合や,
+TINIB中のスタック領域とサイズと先頭番地の持ち方をターゲット依存に変更し
+たい場合には,USE_TSKINICTXBをマクロ定義し,TINIB中に持つことが必要なデー
+タ構造の型を,TSKINICTXBに定義する.
+
+USE_TSKINICTXBをマクロ定義すると,TINIB中にスタック領域とサイズと先頭番
+地が含まれなくなるため,それに代わる情報をTSKINICTXB中に持つ必要がある.
+また,コンフィギュレータのパス2のテンプレートファイルのターゲット非依存
+部で,TSKINICTXBの初期化情報を生成するためのGENERATE_TSKINICTXBを定義す
+る必要がある.
+
+6.5.2 ディスパッチャ本体
+
+ディスパッチャ本体(dispatcher)は,ターゲット非依存部から直接呼び出さ
+れることはなく,カーネルのターゲット依存部の内部からのみ呼び出される.
+dispatcherは,タスクコンテキスト・CPUロック状態・割込み優先度マスク全解
+除状態・ディスパッチ許可状態で呼び出される.
+
+dispatcherの処理内容は次の通り.
+
+----------------------------------------
+void
+dispatcher(void)
+{
+#ifdef LOG_DSP_ENTER
+ log_dsp_enter(p_runtsk);
+#endif /* LOG_DSP_ENTER */
+ dispatcher_0:
+ while ((p_runtsk = p_schedtsk) == NULL) {
+ 割込みを許可したらCPUロック解除状態になるよう準備する
+ 非タスクコンテキストに切り換える … (*1)
+ do {
+ 割込みをすべて許可し,割込み発生を待つ … (*2)
+ 割込み許可前の状態に戻す(=カーネル管理の割込みを禁止する)
+ } while (!reqflg);
+ reqflg = false;
+ タスクコンテキストに戻す … (*1)
+ CPUロック状態に戻す ... (*3)
+ }
+ 自タスク(p_runtsk)のTCBからスタックポインタを復帰する
+#ifdef LOG_DSP_LEAVE
+ log_dsp_leave(p_runtsk);
+#endif /* LOG_DSP_LEAVE */
+ 自タスクのTCBから実行再開番地を復帰し,そこへ分岐する … (*a)
+}
+----------------------------------------
+
+割込み発生を待つ間に非タスクコンテキストに切り換えるのは,この間に実行
+される割込みハンドラ内で,タスクディスパッチをしないようにするためであ
+る.この時,割込みハンドラが,非タスクコンテキスト用のスタックを使うよ
+うにしなければならない.通常は,非タスクコンテキストに切り換える際に非
+タスクコンテキスト用のスタックに切り換え,タスクコンテキストに戻す際に
+元のスタックに切り換える.
+
+ターゲットによっては(特に,シミュレーション環境の場合),強制的に非タ
+スクコンテキストに切り換えることが難しい場合がある.その場合には,この
+間に実行される割込みハンドラ内でタスクディスパッチをしないような仕組み
+を実装することで,非タスクコンテキストへの切換えを省略することができる.
+
+(*1)の非タスクコンテキストに切り換える処理とタスクコンテキストに戻す処
+理は,doループの中で行ってもよい(ターゲットによっては,割込みの許可/
+禁止とまとめて処理した方が効率が良い).
+
+(*2)において,割込みを許可する処理と,割込み発生を待つ処理とは,不可分
+に行なう必要がある.これを不可分に行なわない場合,割込みを許可した直後
+に割込みが入り,その中でタスクが実行可能状態になると,実行すべきタスク
+があるにもかかわらずプロセッサが割込み待ちになってしまう.
+
+また,(*2)において,割込み発生を待つ命令が用意されていない場合や,それ
+を発行するのが不都合な場合には,割込みをすべて許可して割込みを受け付け
+られる状態になった後に,割込み発生を待たずに次に進んでもよい.この場合,
+その外側のdoループによって,割込み発生を待つことになる.
+
+CPUロックを解除するための情報(例えば,CPUロック前の割込み優先度マスク)
+を変数に保持している場合には,(*3)でCPUロック状態に戻す際に,その変数の
+値も元に戻っている必要がある.特に,その変数が,割込み待ちの間に実行し
+た割込みハンドラ内で書き換えられる場合は,元の値に戻すことが必要である.
+
+割込み待ちの間は,p_runtskをNULL(=0)に設定しなければならない(上の処
+理内容をそのまま実装すればこうなる).このように設定しないと,割込みハ
+ンドラからiget_tidを呼び出した際の動作が仕様に合致しなくなる.
+
+(*a)において,実行再開番地は,TCBではなく,スタックに保存/復帰する方法
+もある.この場合,タスクの実行開始前にスタックを使ってはならないため,
+タスクの起動処理を例外扱いする必要がある.
+
+dispatcherをアセンブリ言語で記述する場合には,トレースログ取得処理は,
+「6.2 トレースログ機能への対応」の節で記述した方法でコーディングするこ
+と.なお,log_dsp_enterは切換え前のタスクのスタックで,log_dsp_leave は
+切換え後のタスクのスタックで実行する.
+
+6.5.3 タスクコンテキストからのディスパッチ
+
+(6-5-3-1) void dispatch(void)
+(6-5-3-2) OMIT_CALLTEX(オプション)
+
+タスクコンテキストからのディスパッチ(dispatch)は,タスクコンテキスト
+用のサービスコール処理においてタスク切換えが必要になった場合に,ターゲッ
+ト非依存部のサービスコール処理関数から呼び出される.
+
+dispatchは,タスクコンテキスト・CPUロック状態・割込み優先度マスク全解除
+状態・ディスパッチ許可状態で呼び出される.
+
+dispatchの処理内容は次の通り.
+
+----------------------------------------
+void
+dispatch(void)
+{
+#ifdef TOPPERS_SUPPORT_OVRHDR
+ ovrtimer_stop(); /* オーバランタイマの停止 */
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+ スクラッチレジスタを除くすべてのレジスタをスタックに保存する
+ スタックポインタを自タスク(p_runtsk)のTCBに保存する
+ dispatch_rを,実行再開番地として自タスクのTCBに保存する … (*a)
+ dispatcherに分岐する
+
+ dispatch_r:
+ スクラッチレジスタを除くすべてのレジスタをスタックから復帰する
+#ifdef TOPPERS_SUPPORT_OVRHDR
+ ovrtimer_start(); /* オーバランタイマの動作開始 */
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+ calltex(); … (*b)
+}
+----------------------------------------
+
+dispatchを呼び出したタスクが次に実行される時には,実行再開番地として登
+録したdispatch_rに戻ってくる.dispatch_rには,dispatcherのみから分岐し,
+その時の状態は,タスクコンテキスト・CPUロック状態・割込み優先度マスク全
+解除状態・ディスパッチ許可状態である.
+
+(*b)でcalltexを呼ぶ代わりに,calltexの処理内容(p_runtsk->enatexがtrue
+で,p_runtsk->texptnが0でない場合に,call_texrtnを呼ぶ)をここにインラ
+イン展開した方が効率がよい.ターゲット非依存部のcalltexを使わない場合に
+は,OMIT_CALLTEXをマクロ定義することで,ターゲット非依存部からcalltexを
+取り除くことができる.
+
+6.5.4 ディスパッチャの動作開始
+
+(6-5-4-1) void start_dispatch(void)
+
+ディスパッチャの動作開始(start_dispatch)は,カーネル起動時に,カーネ
+ルの初期化処理から呼び出される.start_dispatchは,リターンすることのな
+い関数である.
+
+start_dispatchは,非タスクコンテキストで,NMIを除くすべての割込みをマス
+クした状態(全割込みロック状態と同等の状態)で呼び出される.start_dispatch
+内で,タスクコンテキストに切り換え,CPUロック状態・割込み優先度マスク全
+解除状態にしなければならない.
+
+start_dispatchの処理内容は次の通り.
+
+----------------------------------------
+void
+start_dispatch(void)
+{
+ タスクコンテキストに切り換える
+ CPUロック状態・割込み優先度マスク全解除状態にする
+ dispatcher_0に分岐する
+}
+----------------------------------------
+
+6.5.5 現在のコンテキストを捨ててディスパッチ
+
+(6-5-5-1) void exit_and_dispatch(void)
+
+現在のコンテキストを捨ててディスパッチ(exit_and_dispatch)は,自タスク
+を終了させるサービスコール処理関数から呼び出される.exit_and_dispatchは,
+リターンすることのない関数である.
+
+exit_and_dispatchは,タスクコンテキスト・CPUロック状態・割込み優先度マ
+スク全解除状態・ディスパッチ許可状態で呼び出される.
+
+exit_and_dispatchの処理内容は次の通り.
+
+----------------------------------------
+void
+exit_and_dispatch(void)
+{
+ dispatcherに分岐する
+}
+----------------------------------------
+
+6.5.6 タスクの起動処理
+
+(6-5-6-1) void activate_context(TCB *p_tcb)
+
+タスクの起動処理(activate_context)は,タスクを休止状態から実行できる
+状態にする時に呼ばれ,指定されたタスクのTCB中のスタックポインタを初期化
+し,実行再開番地をタスク開始時処理(start_r)に設定する.この時点では,
+指定されたタスクのスタック領域を使ってはならない.
+
+指定されたタスクが最初に実行される時には,指定されたタスクを自タスクと
+して,実行再開番地として登録したstart_rに分岐してくる.start_rには,
+dispatcherのみから分岐し,その時の状態は,タスクコンテキスト・CPUロック
+状態・割込み優先度マスク全解除状態・ディスパッチ許可状態である.
+
+start_rは,CPUロック状態を解除した後,タスクの起動番地を呼び出す.さら
+に,タスクの起動番地から戻ってきた場合には,ext_tskを呼び出す.
+
+activate_contextとstart_rの処理内容は次の通り.
+
+----------------------------------------
+void
+activate_context(TCB *p_tcb)
+{
+ 指定されたタスク(p_tcb)のTCB中のスタックポインタを初期化する
+ start_rを,実行再開番地として自タスクのTCBに保存する … (*a)
+ return;
+
+ start_r:
+#ifdef TOPPERS_SUPPORT_OVRHDR
+ ovrtimer_start(); /* オーバランタイマの動作開始 */
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+ CPUロック解除状態にする
+ 自タスク(p_runtsk)の起動番地を,拡張情報をパラメータとして呼び出す
+ ext_tskに分岐する ... (*c)
+}
+----------------------------------------
+
+(*c)でext_tskを呼ぶ代わりに,自タスクの起動番地を呼び出す時の返り番地を
+ext_tskの番地としておく方法がある.
+
+(*a)において,実行再開番地をスタックに保存/復帰する方法をとる場合には,
+この時点でスタックを使ってはならないため,この処理を例外扱いしなければ
+ならない.
+
+6.6 割込みハンドラ
+
+6.6.1 割込みハンドラの出入口処理
+
+カーネル管理の割込みの出入口処理の方法は,プロセッサによって大きく異な
+るが,おおよその処理内容は次の通り.
+
+----------------------------------------
+void
+<割込みの出入口処理>(void)
+{
+ 少なくともカーネル管理の割込みを禁止した状態にする … (*f)
+ スクラッチレジスタをスタックに保存する
+ if (タスクコンテキストで割込み発生) {
+#ifdef TOPPERS_SUPPORT_OVRHDR
+ ovrtimer_stop(); /* オーバランタイマの停止 */
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+ スタックを非タスクコンテキスト用のスタックに切り換え,
+ 非タスクコンテキストに切り換える
+ }
+
+ この割込みよりも優先度の高い割込みのみを受け付けられるようにして,
+ CPUロック解除状態にする
+#ifdef LOG_INH_ENTER
+ log_inh_enter(割込みハンドラ番号);
+#endif /* LOG_INH_ENTER */
+ 割込みハンドラを呼び出す
+#ifdef LOG_INH_LEAVE
+ log_inh_leave(割込みハンドラ番号);
+#endif /* LOG_INH_LEAVE */
+
+ ret_int:
+ if (タスクコンテキストで割込み発生) {
+ (少なくとも)カーネル管理の割込みを禁止した状態にする … (*d)
+ スタックをタスク用のスタックに戻し,タスクコンテキストに切り換える
+ if (reqflg) {
+ reqflg = false;
+ CPUロック状態にする … (*e)
+ if (dspflg && p_runtsk != p_schedtsk) {
+ スクラッチレジスタを除くすべてのレジスタをスタックに保存する
+ スタックポインタを自タスク(p_runtsk)のTCBに保存する
+ ret_int_rを,実行再開番地として自タスクのTCBに保存する … (*a)
+ dispatcherに分岐する
+
+ ret_int_r:
+ スクラッチレジスタを除くすべてのレジスタをスタックから復帰する
+ }
+#ifdef TOPPERS_SUPPORT_OVRHDR
+ ovrtimer_start(); /* オーバランタイマの動作開始 */
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+ calltex(); … (*b)
+ }
+#ifdef TOPPERS_SUPPORT_OVRHDR
+ else {
+ ovrtimer_start(); /* オーバランタイマの動作開始 */
+ }
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+ }
+ 割込み処理からのリターン後に,CPUロック解除状態に戻るように準備する
+ スクラッチレジスタをスタックから復帰する
+ 割込み処理からのリターン
+}
+----------------------------------------
+
+割込みの受付けによりすべての割込みが禁止されないプロセッサでは,(*f)に
+おいて,少なくともカーネル管理の割込みを禁止する.この理由は次の通りで
+ある.
+
+割込みの入口処理において,スタックを非タスクコンテキスト用のスタックに
+切り換える前に多重割込みが発生すると,タスクのスタック領域が使用される.
+上記のようなプロセッサでは,スタックの切換え前に,最大で割込み優先度の
+段数分の多重割込みが発生することを防ぐことはできず,各タスクのスタック
+領域を確保する際に,その分を見込んで確保しなければならない.各タスクの
+スタック領域をなるべく小さくするためには,スタックをなるべく使用しない
+内に,多重割込みを禁止するのが望ましい.そのため,スクラッチレジスタを
+スタックに保存する前に,割込みを禁止する.ただし,割込みの禁止処理に必
+要な最低限のレジスタについては,割込みの禁止に先立ってスタックに保存す
+る必要がある.
+
+同様のことは,カーネル管理外の割込みにも当てはまる.すなわち,カーネル
+管理外の割込みについても,スタックをなるべく使用しない内に禁止するのが
+望ましい.このことから,カーネル管理外の割込みを使用する場合には,(*f)
+において,すべての割込みを禁止した状態にするのが望ましいことになる.ま
+た,カーネル管理外の割込み処理においても,非タスクコンテキスト用のスタッ
+クに切り換えることが望ましいが,これはカーネルの管轄外である.
+
+(*d)においては,カーネル管理の割込みを禁止するだけで,CPUロック状態にす
+る必要はない.例えば,CPUロック状態であることを示す変数を用意している場
+合には,(*d)の時点ではその変数をCPUロック状態を示す値に変更する必要はな
+く,(*e)において変更すればよい.
+
+タスクの実行中に割込みが発生し,上の処理中でdispatcherに分岐した場合,
+そのタスクが次に実行される時には,実行再開番地として登録したret_int_rに
+戻ってくる.ret_int_rには,dispatcherのみから分岐し,その時の状態は,タ
+スクコンテキスト・CPUロック状態・割込み優先度マスク全解除状態・ディスパッ
+チ許可状態である.
+
+割込みの出入口処理をアセンブリ言語で記述する場合には,トレースログ取得
+処理は,「6.2 トレースログ機能への対応」の節で記述した方法でコーディン
+グすること.
+
+6.6.2 割込みハンドラ毎の出入口処理の生成
+
+割込みベクトルをハードウェアで実現している場合など,割込みハンドラ毎に
+出入口処理を用意した方が効率が良いターゲットのために,割込みハンドラ毎
+に出入口処理を生成する機構を用意している.
+
+以下のマクロは,標準の割込み管理機能の初期化処理を用いた場合のみ,ター
+ゲット非依存部で使われる.割込み管理機能の初期化処理をターゲット依存部
+で用意し,その中でこれらのマクロを使わない場合には,これらのマクロを用
+意する必要はない.
+
+(6-6-2-1) INT_ENTRY(inhno, inthdr)
+
+割込みハンドラ番号がinhno,割込みハンドラの関数名がinthdrである割込みハ
+ンドラの出入口処理のラベルを作るマクロ.INTHDR_ENTRYを用いて割込みハン
+ドラ毎に出入口処理を生成する場合には,次のように定義する.
+
+#define INT_ENTRY(inhno, inthdr) _kernel_##inthdr##_##inhno
+
+割込みハンドラ毎に出入口処理を作る必要がない場合には,次のように定義し
+て,割込みハンドラの関数名をそのまま返す.
+
+#define INT_ENTRY(inhno, inthdr) inthdr
+
+(6-6-2-2) INTHDR_ENTRY(inhno, inhno_num, inthdr)
+
+割込みハンドラ番号がinhno,割込みハンドラの関数名がinthdrである割込みハ
+ンドラの出入口処理を生成するマクロ.inhno_numには,アセンブリ言語記述用
+に,割込みハンドラ番号が数値で渡される.割込みハンドラ毎に出入口処理を
+作る必要がない場合には,空に定義する.
+
+6.6.3 割込みハンドラの設定
+
+(6-6-3-1) bool_t VALID_INHNO_DEFINH(INHNO inhno)(オプション)
+
+inhnoが,DEF_INHに対する割込みハンドラ番号として有効な値である場合に
+true,そうでない場合にfalseを返すマクロ.
+
+ASPカーネルのターゲット非依存部では,このマクロは使われていないため,ター
+ゲット依存部で使わないなら,用意する必要がない.
+
+(6-6-3-2) void x_define_inh(INHNO inhno, FP int_entry)
+
+inhnoで指定された割込みハンドラの出入口処理の番地をint_entryに設定する.
+
+この関数は,標準の割込み管理機能の初期化処理を用いた場合のみ,ターゲッ
+ト非依存部から呼び出される.割込み管理機能の初期化処理をターゲット依存
+部で用意し,その中でこの関数を呼び出さない場合には,この関数を用意する
+必要はない.
+
+この関数は,ターゲット非依存部のカーネル初期化処理から呼び出されるため,
+カーネルの初期化処理(NMIを除くすべての割込みがマスクされている)から呼
+び出せるように実装すればよい.
+
+指定された割込みハンドラ番号がDEF_INHに対するものとして有効な値でない場
+合の動作は保証する必要がない(assertでエラーとするのが望ましい).これ
+は,コンフィギュレータが,パス2のテンプレートファイルのターゲット依存部
+で定義するINHNO_DEFINH_VALIDを用いてエラーを検出するためである.
+
+6.6.4 割込み要求ラインの属性の設定
+
+(6-6-4-1) bool_t VALID_INTNO_CFGINT(INTNO intno)(オプション)
+
+intnoが,CFG_INTに対する割込み番号として有効な値である場合にtrue,そう
+でない場合にfalseを返すマクロ.割込み要求ラインの属性を設定できない
+intnoに対しては,このマクロがfalseを返すようにする.
+
+ASPカーネルのターゲット非依存部では,このマクロは使われていないため,ター
+ゲット依存部で使わないなら,用意する必要がない.
+
+(6-6-4-2) void x_config_int(INTNO intno, ATR intatr, PRI intpri)
+
+intnoで指定された割込み要求ラインの割込み属性を,intatrで指定された通り
+に設定する.また,割込み優先度を,intpriで指定された値に設定する.
+
+この関数は,標準の割込み管理機能の初期化処理を用いた場合のみ,ターゲッ
+ト非依存部から呼び出される.割込み管理機能の初期化処理をターゲット依存
+部で用意し,その中でこの関数を呼び出さない場合には,この関数を用意する
+必要はない.
+
+この関数は,ターゲット非依存部のカーネル初期化処理から呼び出されるため,
+カーネルの初期化処理(NMIを除くすべての割込みがマスクされている)から呼
+び出せるように実装すればよい.
+
+intatrとして設定できる割込み属性は次の通り.
+
+ TA_ENAINT 0x01 割込み要求禁止フラグをクリア
+ TA_EDGE 0x02 エッジトリガ
+
+この他に,ターゲット定義で割込み属性を追加してもよい.ターゲット定義で
+追加するために,以下の属性名が予約されている.
+
+ TA_POSEDGE ポジティブエッジトリガ
+ TA_NEGEDGE ネガティブエッジトリガ
+ TA_BOTHEDGE 両エッジトリガ
+ TA_LOWLEVEL ローレベルトリガ
+ TA_HIGHLEVEL ハイレベルトリガ
+
+これらの属性名をターゲット定義で追加する場合には,その属性値を決定し,
+定義をtarget_kernel.h(または,そこからインクルードされるファイル)に含
+める.また,コンフィギュレータテンプレートファイルから参照できるように,
+target_def.csv(または,そこからインクルードされるファイル)に含め,コ
+ンフィギュレータテンプレートファイルのターゲット非依存部でエラーとなら
+ないように,target.tf(または,そこからインクルードされるファイル)で
+TARGET_INTATRに設定する.
+
+指定された割込み番号がCFG_INTに対するものとして有効な値でない場合や,そ
+の割込み要求ラインに対して設定できない属性を指定した場合,設定できない
+割込み優先度を指定した場合の動作は保証する必要がない(assertでエラーと
+するのが望ましい).このようなケースは,コンフィギュレータでエラーを検
+出すべきである.コンフィギュレータテンプレートファイルのターゲット非依
+存部は,パス2のテンプレートファイルのターゲット依存部で定義する
+INTNO_CFGINT_VALID,TARGET_INTATR,INTPRI_CFGINT_VALIDを用いてエラーを
+検出するが,標準の割込み属性(TA_ENAINT,TA_EDGE)が設定できない場合や,
+設定できない属性や割込み優先度が割込み要求ラインによって異なる場合には,
+コンフィギュレータテンプレートファイルのターゲット依存部で検出しなけれ
+ばならない.
+
+6.6.5 割込み管理機能の初期化処理の変更
+
+(6-6-5-1) OMIT_INITIALIZE_INTERRUPT(オプション)
+
+割込み管理機能の初期化処理をターゲット依存部で用意し,ターゲット非依存
+部に含まれる標準の割込み管理機能の初期化処理を用いない場合には,このシ
+ンボルをマクロ定義する.
+
+このシンボルをマクロ定義すると,INHINIB,INTINIB,initialize_interrupt
+の定義が,カーネルのターゲット非依存部から取り除かれる.また,
+TNUM_INHNO,tnum_inhno,inhinib_table,TNUM_INTNO,tnum_intno,
+intinib_tableの定義と,割込みハンドラ毎の出入口処理を生成するための記述
+(INTHDR_ENTRYマクロのリスト)が,コンフィギュレータのパス2のテンプレー
+トファイルのターゲット非依存部によってkernel_cfg.cに生成されなくなる.
+ただし,コンフィギュレータのパス2のテンプレートファイルのターゲット依存
+部で,USE_INHINIB_TABLEとUSE_INTINIB_TABLEを設定することで,その一部
+分をkernel_cfg.cに生成することが可能である.
+
+(6-6-5-2) void initialize_interrupt(void)(オプション)
+
+OMIT_INITIALIZE_INTERRUPTをマクロ定義した場合には,この関数をターゲット
+依存部で用意する.OMIT_INITIALIZE_INTERRUPTをマクロ定義することにより取
+り除かれるその他のデータ型,変数,マクロは,この関数で使用する場合にの
+み用意すればよい.
+
+6.6.6 デフォルトの割込みハンドラ
+
+(6-6-6-1) default_int_handler(void)(オプション)
+
+コンフィギュレータにより割込みハンドラのテーブルを生成する場合などには,
+割込みハンドラを登録しなかった割込みハンドラ番号に対して,デフォルトの
+割込みハンドラとして,default_int_handlerを登録する.
+
+default_int_handlerは,標準のものをターゲット依存部で用意するが,ユーザ
+が用意したもので置き換えられるように,OMIT_DEFAULT_INT_HANDLERをマクロ
+定義した場合には,ターゲット依存部で定義しないようにする.なお,ユーザ
+が用意する場合の名称は,_kernel_default_int_handlerとなる.
+
+6.6.7 カーネル管理外の割込み
+
+カーネル管理外の割込みハンドラは,カーネル内の割込み出入口処理を経由せ
+ずに実行するのが基本である.
+
+ただし,すべての割込みで同じアドレスに分岐するプロセッサでは,カーネル
+内の割込み出入口処理を全く経由せずにカーネル管理外の割込みハンドラを実
+行することができないため,割込み出入口処理のなるべく早いタイミングで,
+カーネル管理外の割込みであるかを判別し,処理内容を分ける必要がある.具
+体的には,カーネル管理外の割込みの出入口処理では,オーバランハンドラの
+停止と動作開始を行ってはならない.また,reqflgをチェックし,タスク切換
+えやタスク例外処理ルーチンの呼出しを行う必要がない.さらに,NMIの出入口
+処理では,トレースログ取得処理(log_inh_enterおよびlog_inh_leave)を呼
+び出してはならない.
+
+カーネル管理外の割込みハンドラを実行する際に,カーネル内の割込み出入口
+処理の一部分を経由する場合には,CPU例外が起こる可能性を極力減らすととも
+に,CPU例外を起こす可能性がある場合には,その可能性をターゲット依存部の
+ユーザーズマニュアルに記載しなければならない.
+
+次に,カーネル管理外の割込みの設定方法に関して,「TOPPERS新世代カーネル
+統合仕様書」の「2.7.8 カーネル管理外の割込みの設定方法」の節の3つの方法
+のいずれを採用するかを決定する.
+
+(a-1)または(a-2)を採用し,カーネル管理外とした割込みに対して,カーネル
+のAPIによる割込みハンドラの登録と割込み要求ラインの属性の設定をサポート
+しない場合には,それに代わる方法をターゲット依存部のユーザーズマニュア
+ルに記述する.
+
+(a-1)または(a-2)を採用してカーネルのAPIによる割込みハンドラの登録や割込
+み要求ラインの属性の設定をサポートする場合や,(b)を採用した場合には,ター
+ゲット依存部においてそれを実現する必要がある.
+
+カーネル管理外の割込みに対して,DEF_INHによる割込みハンドラの登録をサポー
+トするには,次の設定が必要になる.
+
+・TARGET_INHATRに,TA_NONKERNELを設定する.
+
+・(a-1)または(a-2)を採用した場合には,INHNO_DEFINH_VALIDに,カーネル管
+ 理外とした割込みに対応する割込みハンドラ番号を含める.また,
+ VALID_INHNO_DEFINHを,カーネル管理外とした割込みハンドラ番号を有効な
+ 値と判定するようにする.
+
+・(a-1)または(a-2)を採用した場合には,INHNO_FIX_KERNELにカーネル管理と
+ した割込みハンドラ番号のリストを,INHNO_FIX_NONKERNELにカーネル管理外
+ とした割込みハンドラ番号のリスト設定する.
+
+・DEF_INHがカーネル管理外の割込みに対応できるようにする.標準の割込み管
+ 理機能の初期化処理を用いる場合には,x_define_inhをカーネル管理外の割
+ 込みに対応させる.
+
+・必要な場合には,TA_NONKERNEL属性が設定された割込みハンドラをカーネル
+ 管理外と扱うように,カーネル内の割込み出入口処理を修正する.標準の割
+ 込み管理機能の初期化処理を用いる場合,カーネル管理外の割込みに対して
+ は,カーネル内の割込み出入口処理を生成せず,アプリケーションが登録し
+ た割込みハンドラを直接呼び出すように,ターゲット非依存部により設定さ
+ れるため,ターゲット依存部では対応する必要がない.
+
+カーネル管理外の割込みに対して,CFG_INTによる割込み要求ラインの属性の設
+定をサポートするには,次の設定が必要になる.
+
+・(a-1)または(a-2)を採用した場合には,INTNO_CFGINT_VALIDに,カーネル管
+ 理外とした割込みに対応する割込み番号を含める.また,VALID_INTNO_CFGINT
+ を,カーネル管理外とした割込み番号を有効な値と判定するようにする.
+
+・(a-1)または(a-2)を採用した場合には,INTNO_FIX_KERNELにカーネル管理と
+ した割込み番号のリストを,INTNO_FIX_NONKERNELにカーネル管理外とした割
+ 込み番号のリスト設定する.
+
+・INTPRI_CFGINT_VALIDに,カーネル管理外の割込みとなる優先度を含める.
+
+・CFG_INTがカーネル管理外の割込みに対応できるようにする.標準の割込み管
+ 理機能の初期化処理を用いる場合には,x_config_intをカーネル管理外の割
+ 込みに対応させる.
+
+chg_ipmにより,(NMI以外の)カーネル管理外の割込みをマスクできるように
+する場合には,次の設定が必要になる.
+
+・VALID_INTPRI_CHGIPMを,カーネル管理外の割込みとなる優先度を有効な値と
+ 判定するようにする.
+
+・t_set_ipmを,カーネル管理外の割込みとなる優先度を扱えるようにする.
+
+6.7 CPU例外ハンドラとCPU例外発生時のシステム状態の参照
+
+6.7.1 CPU例外ハンドラの出入口処理
+
+CPU例外の出入口処理の方法はプロセッサによって大きく異なるが,おおよその
+処理内容は次の通り.
+
+----------------------------------------
+void
+<CPU例外の出入口処理>(void)
+{
+ スクラッチレジスタをスタックに保存する
+ if (カーネル管理外のCPU例外) {
+ if (タスクコンテキストでCPU例外発生) {
+ スタックを非タスクコンテキスト用のスタックに切り換え,
+ 非タスクコンテキストに切り換える
+ }
+ システム状態(コンテキストは除く)を,CPU例外発生時の状態にする
+ CPU例外ハンドラを,CPU例外の情報を記憶している領域の先頭番地を
+ パラメータ(p_excinf)として呼び出す
+ if (タスクコンテキストでCPU例外発生) {
+ スタックをタスク用のスタックに戻し,タスクコンテキストに切り換える
+ }
+ CPU例外処理からのリターン後に,CPU例外発生時のシステム状態に
+ 戻るように準備する
+ }
+ else {
+ if (タスクコンテキストでCPU例外発生) {
+#ifdef TOPPERS_SUPPORT_OVRHDR
+ (少なくとも)カーネル管理の割込みを禁止した状態にする
+ ovrtimer_stop(); /* オーバランタイマの停止 */
+ (必要なら)元の状態に戻す
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+ スタックを非タスクコンテキスト用のスタックに切り換え,
+ 非タスクコンテキストに切り換える
+ }
+ システム状態(コンテキストは除く)を,CPU例外発生時の状態にする
+ (CPU例外発生時の割込み優先度マスクよりも優先度の高い割込み
+ のみを受け付けられるようにして,CPUロック解除状態にする)
+
+#ifdef LOG_EXC_ENTER
+ log_exc_enter(CPU例外ハンドラ番号);
+#endif /* LOG_EXC_ENTER */
+ CPU例外ハンドラを,CPU例外の情報を記憶している領域の先頭番地を
+ パラメータ(p_excinf)として呼び出す
+#ifdef LOG_EXC_LEAVE
+ log_exc_leave(CPU例外ハンドラ番号);
+#endif /* LOG_EXC_LEAVE */
+
+ ret_exc:
+ if (タスクコンテキストでCPU例外発生) {
+ (少なくとも)カーネル管理の割込みを禁止した状態にする … (*d)
+ スタックをタスク用のスタックに戻し,タスクコンテキストに切り換える
+ if (reqflg) {
+ reqflg = false;
+ CPUロック状態にする … (*e)
+ if (dspflg && p_runtsk != p_schedtsk) {
+ スクラッチレジスタを除くすべてのレジスタをスタックに保存する
+ スタックポインタを自タスク(p_runtsk)のTCBに保存する
+ ret_exc_rを,実行再開番地として自タスクのTCBに保存する
+ … (*a)
+ dispatcherに分岐する
+
+ ret_exc_r:
+ スクラッチレジスタを除くすべてのレジスタを
+ スタックから復帰する
+ }
+#ifdef TOPPERS_SUPPORT_OVRHDR
+ ovrtimer_start(); /* オーバランタイマの動作開始 */
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+ calltex(); … (*b)
+ }
+#ifdef TOPPERS_SUPPORT_OVRHDR
+ else {
+ ovrtimer_start(); /* オーバランタイマの動作開始 */
+ }
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+ }
+ CPU例外処理からのリターン後に,CPUロック解除状態に戻るように準備する
+ }
+ スクラッチレジスタをスタックから復帰する
+ CPU例外処理からのリターン
+}
+----------------------------------------
+
+CPU例外ハンドラは,非コンテキストに切り換えることを除いては,CPU例外発
+生時と同じシステム状態で呼び出さなければならない.例えば,CPU例外がCPU
+ロック状態で発生した場合にはCPUロック状態,CPUロック解除状態で発生した
+場合にはCPUロック解除状態で,CPU例外ハンドラを呼び出さなければならない.
+CPUロック状態で発生したCPU例外は,カーネル管理外のCPU例外となるため,カー
+ネル管理のCPU例外ハンドラについては,CPUロック解除状態で呼び出すことに
+なる.
+
+カーネル管理外のCPU例外であることは,exc_sense_unlockがfalseを返す条件
+と,タスクコンテキストであることを調べないだけの違いであり,ほぼ同じコー
+ドで判定することができる.
+
+上のコードでは,カーネル管理外のCPU例外に対して,トレースログ取得処理
+(log_exc_enterおよびlog_exc_leave)を呼び出していないが,全割込みロッ
+ク状態かNMIの処理中にCPU例外が発生した場合を除外すれば,呼び出してもか
+まわない.全割込みロック状態かNMIの処理中に発生したCPU例外の場合には,
+トレースログ取得処理を呼び出してはならない.
+
+CPU例外ハンドラを実行する際に経由する部分では,CPU例外が起こる可能性を
+極力減らすとともに,CPU例外を起こす可能性がある場合(例えば,スクラッチ
+レジスタをスタックに保存する時に,バスエラーなどのCPU例外が発生する可能
+性が考えられる)には,その可能性をターゲット依存部のユーザーズマニュア
+ルに記載しなければならない.
+
+ret_exc以降の処理は,割込みの出入口処理のret_int以降の処理と同じである
+ため,ターゲットによっては,共通のルーチンを用いることができる可能性が
+ある.
+
+CPU例外の出入口処理をアセンブリ言語で記述する場合には,トレースログ取得
+処理は,「6.2 トレースログ機能への対応」の節で記述した方法でコーディン
+グすること.
+
+6.7.2 CPU例外ハンドラの出入口処理の生成
+
+CPU例外ベクトルをハードウェアで実現している場合など,CPU例外ハンドラ毎
+に出入口処理を用意した方が効率が良いターゲットのために,CPU例外ハンドラ
+毎に出入口処理を生成する機構を用意している.
+
+以下のマクロは,標準のCPU例外管理機能の初期化処理を用いた場合のみ,ター
+ゲット非依存部で使われる.CPU例外管理機能の初期化処理をターゲット依存部
+で用意し,その中でこれらのマクロを使わない場合には,これらのマクロを用
+意する必要はない.
+
+(6-7-2-1) EXC_ENTRY(excno, exchdr)
+
+CPU例外ハンドラ番号がexcno,CPU例外ハンドラの関数名がexchdrであるCPU例
+外ハンドラの出入口処理のラベルを作るマクロ.EXCHDR_ENTRYを用いてCPU例外
+ハンドラ毎に出入口処理を生成する場合には,次のように定義する.
+
+#define EXC_ENTRY(excno, exchdr) _kernel_##exchdr##_##excno
+
+CPU例外ハンドラ毎に出入口処理を作る必要がない場合には,次のように定義し
+て,CPU例外ハンドラの関数名をそのまま返す.
+
+#define EXC_ENTRY(excno, exchdr) exchdr
+
+(6-7-2-2) EXCHDR_ENTRY(excno, excno_num, exchdr)
+
+CPU例外ハンドラ番号がexcno,CPU例外ハンドラの関数名がexchdrであるCPU例
+外ハンドラの出入口処理を生成するマクロ.excno_numには,アセンブリ言語記
+述用に,CPU例外ハンドラ番号が数値で渡される.CPU例外ハンドラ毎に出入口
+処理を作る必要がない場合には,空に定義する.
+
+6.7.3 CPU例外ハンドラの設定
+
+(6-7-3-1) bool_t VALID_EXCNO_DEFEXC(EXCNO excno)(オプション)
+
+excnoが,DEF_EXCに対するCPU例外ハンドラ番号として有効な値である場合に
+true,そうでない場合にfalseを返すマクロ.
+
+ASPカーネルのターゲット非依存部では,このマクロは使われていないため,ター
+ゲット依存部で使わないなら,用意する必要がない.
+
+(6-7-3-2) void x_define_exc(EXCNO excno, FP exc_entry)
+
+excnoで指定されたCPU例外ハンドラの出入口処理の番地をexc_entryに設定する.
+
+この関数は,標準のCPU例外管理機能の初期化処理を用いた場合のみ,ターゲッ
+ト非依存部から呼び出される.CPU例外管理機能の初期化処理をターゲット依存
+部で用意し,その中でこの関数を呼び出さない場合には,この関数を用意する
+必要はない.
+
+この関数は,ターゲット非依存部のカーネル初期化処理から呼び出されるため,
+カーネルの初期化処理(NMIを除くすべての割込みがマスクされている)から呼
+び出せるように実装すればよい.
+
+指定されたCPU例外ハンドラ番号がDEF_EXCに対するものとして有効な値でない
+場合の動作は保証する必要がない(assertでエラーとするのが望ましい).こ
+れは,コンフィギュレータが,パス2のテンプレートファイルのターゲット依存
+部で定義するEXCNO_DEFEXC_VALIDを用いてエラーを検出するためである.
+
+6.7.4 CPU例外管理機能の初期化処理の変更
+
+(6-7-4-1) OMIT_INITIALIZE_EXCEPTION(オプション)
+
+CPU例外管理機能の初期化処理をターゲット依存部で用意し,ターゲット非依存
+部に含まれる標準の割込み管理機能の初期化処理を用いない場合には,このシ
+ンボルをマクロ定義する.
+
+このシンボルをマクロ定義すると,EXCINIBとinitialize_exceptionの定義が,
+カーネルのターゲット非依存部から取り除かれる.また,TNUM_EXCNO,
+tnum_excno,excinib_tableの定義と,CPU例外ハンドラ毎の出入口処理を生成
+するための記述(EXCHDR_ENTRYマクロのリスト)を,コンフィギュレータのパ
+ス2のテンプレートファイルのターゲット非依存部によってkernel_cfg.cに生成
+されなくなる.
+
+(6-7-4-2) void initialize_exception(void)(オプション)
+
+OMIT_INITIALIZE_EXCEPTIONをマクロ定義した場合には,この関数をターゲット
+依存部で用意する.OMIT_INITIALIZE_EXCEPTIONをマクロ定義することにより取
+り除かれるその他のデータ型,変数,マクロは,この関数で使用する場合にの
+み用意すればよい.
+
+6.7.5 デフォルトのCPU例外ハンドラ
+
+(6-7-5-1) default_exc_handler(void)(オプション)
+
+コンフィギュレータによりCPU例外ハンドラのテーブルを生成する場合などには,
+CPU例外ハンドラを登録しなかったCPU例外ハンドラ番号に対して,デフォルト
+のCPU例外ハンドラとして,default_exc_handlerを登録する.
+
+default_exc_handlerは,標準のものをターゲット依存部で用意するが,ユーザ
+が用意したもので置き換えられるように,OMIT_DEFAULT_EXC_HANDLERをマクロ
+定義した場合には,ターゲット依存部で定義しないようにする.なお,ユーザ
+が用意する場合の名称は,_kernel_default_exc_handlerとなる.
+
+6.7.6 CPU例外発生時のシステム状態の参照
+
+(6-7-6-1) bool_t exc_sense_intmask(void *p_excinf)
+
+CPU例外の発生した時のシステム状態が,カーネル実行中でなく,タスクコンテ
+キストであり,全割込みロック状態でなく,CPUロック状態でなく,(モデル上
+の)割込み優先度マスク全解除状態である時にtrue,そうでない時にfalseを返
+す関数.CPU例外がカーネル管理外の割込み処理中で発生した場合にもfalseを
+返す.
+
+p_excinfには,CPU例外の情報を記憶している領域の先頭番地が渡される.
+
+(6-7-6-2) bool_t exc_sense_unlock(void *p_excinf)
+
+CPU例外の発生した時のシステム状態が,カーネル実行中でなく,タスクコンテ
+キストであり,全割込みロック状態でなく,CPUロック状態でない時にtrue,そ
+うでない時にfalseを返す関数.CPU例外がカーネル管理外の割込み処理中で発
+生した場合にもfalseを返す.
+
+ターゲットによっては,全割込みロック(またはCPUロック)を小さいオーバヘッ
+ドで実現しようとすると,CPU例外ハンドラの中で,全割込みロック状態(また
+はCPUロック状態)と割込み優先度マスクを高いレベルに設定した状態を区別で
+きない場合がある.また,カーネル管理外の割込み処理中やカーネル実行中で
+あることを正確に判断することも難しい.そこで,ターゲット定義で,割込み
+優先度マスクをTMIN_INTPRIと同じかそれよりも高い値に設定している状態で発
+生したCPU例外をカーネル管理外のCPU例外と扱うこととし,それに対して
+falseを返すこととしてもよい.
+
+p_excinfには,CPU例外の情報を記憶している領域の先頭番地が渡される.
+
+6.8 カーネルの起動・終了とスタック領域など
+
+(6-8-1) スタートアップモジュール
+
+カーネルのスタートアップモジュールは,システムのリセット後に最初に実行
+されるプログラムである.スタートアップモジュールは,標準的には,プロセッ
+サ依存部またはチップ依存部で用意し以下の処理を行うが,それにこだわる必
+要はない.具体的には,開発環境に用意されているスタートアップモジュール
+を用いる方法(この場合,ターゲット依存部でmain関数を用意する必要がある)
+や,アプリケーションで用意する場合が考えられる.
+
+(a) プロセッサ状態の初期化
+
+プロセッサモード,スタックポインタ,フレームポインタ等,プロセッサの状
+態を初期化する.また,NMIを除くすべての割込みをマスクした状態(全割込み
+ロック状態と同等の状態)とする.DRAMコントローラの初期化など,メモリを
+アクセスするために必要な初期化処理をここで行ってもよい(次の
+hardware_init_hookで行ってもよい).
+
+(b) hardware_init_hookを呼び出す
+
+システムのリセット後すぐに行う必要のあるターゲットシステム依存の初期化
+処理を行うために,hardware_init_hookを呼び出す.hardware_init_hookが用
+意されていない場合は,何もしない.GNU開発環境では,リンカスクリプト中の
+weak definitionにより,hardware_init_hookが用意されていない場合の値を0
+とすることで,これを実現できる.weak definitionの機能を持たない開発環境
+では,hardware_init_hookを必ず呼び出すことにする.
+
+hardware_init_hookは,ターゲット依存部で用意するのが標準であるが,シス
+テムのリセット後すぐに行う必要のある初期化処理を追加するために,アプリ
+ケーションで用意したものを用いる場合もある.
+
+メモリアクセスに必要な初期化処理をhardware_init_hookで行う場合には,こ
+れを呼び出す時点でメモリにアクセスすることができないため,関数(サブルー
+チン)を呼び出すためにスタックを使用するプロセッサでは,戻り番地を汎用
+レジスタに入れて呼び出すといった工夫が必要である.この場合,
+hardware_init_hookをC言語で記述することはできなくなるが,やむをえない.
+
+(c) bssセクションとdataセクションの初期化
+
+bssセクションをクリアし,dataセクションに初期値を設定する.
+
+ただし,カーネル本体は,kerflgがfalse(=0)に初期化されること以外に,
+これらのセクションが初期化されることに依存していないため,スタートアッ
+プモジュールをアプリケーションで用意する場合で,システムサービスやアプ
+リケーションがこれらのセクションが初期化されることに依存していない場合
+には,システムの起動時間を短縮するために,kerflgをfalseに初期化するだけ
+で十分である.
+
+(d) software_init_hookを呼び出す
+
+開発環境(特にライブラリ)に依存して必要な初期化処理を行うために,
+software_init_hookを呼び出す.software_init_hookが用意されていない場合
+は,何もしない.GNU開発環境では,リンカスクリプト中のweak definitionに
+より,software_init_hookが用意されていない場合の値を0とすることで,これ
+を実現できる.weak definitionの機能を持たない開発環境では,
+software_init_hookを必ず呼び出すことにする.
+
+software_init_hookは,ターゲット依存部で用意するのが標準である.
+
+(e) sta_kerへ分岐
+
+sta_kerを呼び出す.sta_kerは,NMIを除くすべての割込みをマスクした状態
+(全割込みロック状態と同等の状態)で呼び出さなければならない.sta_kerか
+らはリターンすることがないため,スタートアップモジュールに戻ってくるこ
+とは考える必要がない.
+
+(6-8-2) void target_initialize(void)
+
+ターゲット依存部の初期化を行う関数.sta_kerの最初で呼び出される.プロセッ
+サ・チップ・開発環境依存の初期化処理を,それらの依存部に切り分けること
+も可能である.
+
+この関数は,あくまでもカーネルのターゲット依存部の初期化処理を行うため
+のものである.アプリケーションに必要な初期化処理は,初期化ルーチンで行
+うのが基本であるが,システムのリセット後すぐに行う必要がある場合には,
+hardware_init_hookを用いる.
+
+(6-8-3) void call_exit_kernel(void)
+
+非タスクコンテキストに切り換えて,exit_kernelへ分岐する関数.ext_kerか
+ら呼び出される.exit_kernelからはリターンすることがないため,この関数に
+戻ってくることは考える必要がない.
+
+非タスクコンテキストに切り換えるのは,終了処理ルーチンを,非タスクコン
+テキスト用のスタックで実行するためである.終了処理ルーチンをタスク用の
+スタックで実行すると,各タスクのスタック領域のサイズを決定する際に,終
+了処理ルーチンが使用するスタック領域を考慮しなければならない.これには,
+終了処理ルーチンが使用するスタック領域が大きい場合に各タスクのスタック
+領域を無駄に大きくしなければならないことに加えて,意図しないスタックオー
+バーフローが発生する可能性を高めるという問題がある.
+
+この関数は,全割込みロック状態で呼ばれるため,全割込みロック状態から呼
+び出すことができない関数を呼ばないように実装しなければならない.
+
+(6-8-4) void target_exit(void)
+
+ターゲット依存部の終了処理を行う関数.この関数は,カーネル終了処理の最
+後に呼び出され,リターンしてはならない.プロセッサ・チップ・開発環境依
+存の終了処理を,それらの依存部に切り分けることも可能である.
+
+この関数では,最初に,atexitによって登録された関数とデストラクタを呼び
+出すことを意図しており,標準的には,software_term_hookを呼び出す.
+software_term_hookが用意されていない場合は,何もしない.GNU開発環境では,
+リンカスクリプト中のweak definitionにより,software_term_hookが用意され
+ていない場合の値を0とすることで,これを実現できる.weak definitionの機
+能を持たない開発環境では,software_term_hookを必ず呼び出すことにする.
+
+この関数は,全割込みロック状態で呼ばれるため,全割込みロック状態から呼
+び出すことができない関数を呼ばないように実装しなければならない.
+
+6.9 カーネル内部のチューニング
+
+6.9.1 ビットマップサーチ
+
+(6-9-1-1) OMIT_BITMAP_SEARCH(オプション)
+(6-9-1-2) uint_t bitmap_search(uint16_t bitmap)(オプション)
+
+ターゲット非依存部で,uint16_t型の整数値(bitmap)中の1のビットの内,最
+も下位(右)のものをサーチし,そのビット番号を返す関数bitmap_searchを用
+意している.ここで,ビット番号は最下位ビットを0とし,bitmapに0を指定し
+てはならないものとしている.
+
+ビットサーチ命令を持つプロセッサでは,bitmap_searchを,ビットサーチ命令
+を使うように書き直した方が効率が良い場合がある.このような場合には,ター
+ゲット依存部でビットサーチ命令を使ったbitmap_searchを定義し,
+OMIT_BITMAP_SEARCHをマクロ定義する.
+
+標準ライブラリにビットサーチ命令を用いたffsがある場合,bitmap_searchを
+(ffs(bitmap) - 1)に定義するとよい.
+
+(6-9-1-3) uint16_t PRIMAP_BIT(PRI pri)(オプション)
+
+ビットサーチ命令のサーチ方向が逆などの理由で,優先度とビットとの対応を
+変更したい場合には,PRIMAP_BITをマクロ定義する.
+
+6.9.2 ビットフィールド
+
+(6-9-2-1) BIT_FIELD_UINT(オプション)
+
+8ビット以下の幅のビットフィールドで,符号無し整数値を保持したい場合に用
+いるべきデータ型.デフォルトの定義はunsigned intとなっているが,ターゲッ
+トやツール依存で,unsigned charまたはunsigned shortに定義した方が効率が
+良い場合がある.
+
+(6-9-2-2) BIT_FIELD_BOOL(オプション)
+
+1ビット幅のビットフィールドで,ブール値を保持したい場合に用いるべきデー
+タ型.デフォルトではBIT_FIELD_UINTと同一に定義しているが,ブール値を保
+持することを明示するために別の名前としている.
+
+(6-9-2-3) TBIT_TCB_PRIORITY(オプション)
+
+現在優先度(および,ミューテックス拡張におけるベース優先度)を保持する
+ためのTCB中のフィールドのビット数.デフォルトでは8ビットに定義している
+が,それ以外に定義したい場合に,ビット数をこの名前にマクロ定義する.
+
+6.10 カーネル実装に関するその他の定義
+
+6.10.1 非タスクコンテキスト用のスタック領域
+
+(6-10-1-1) DEFAULT_ISTKSZ
+
+DEF_ICSにより非タスクコンテキスト用のスタック領域が指定されない場合の,
+デフォルトのスタック領域のサイズ.
+
+(6-10-1-2) DEFAULT_ISTK(オプション)
+
+DEF_ICSにより非タスクコンテキスト用のスタック領域が指定されない場合の,
+デフォルトのスタック領域の先頭番地.このマクロが定義されない場合には,
+サイズがDEFAULT_ISTKSZのスタック領域が,配列により確保される.
+
+(6-10-1-3) STK_T *TOPPERS_ISTKPT(STK_T *istk, SIZE istksz)(オプション)
+
+非タスクコンテキスト用のスタックポインタの初期値を保持する変数(istkpt)
+を用いる場合に,このシンボルに,スタック領域の先頭番地(istk)とスタッ
+ク領域のサイズ(istksz)から,スタックポインタの初期値を求めるマクロを
+定義する.
+
+6.10.2 空ラベルの定義
+
+(6-10-2-1) TOPPERS_EMPTY_LABEL(type, symbol)(オプション)
+
+リンクエラーを防ぐために,データ型typeの配列である変数symbolに定義を与
+えるためのマクロ.与えた定義が参照されることはないため,どのような定義
+を与えてもよい.
+
+デフォルトでは,symbolを,要素型がtypeでサイズが0の配列に定義している.
+サイズが0の配列がエラーとならないコンパイラ(GCCはこれに該当)を用いる
+場合には,ターゲット依存部で定義する必要はない.
+
+6.11 トレースログ機能に関する設定
+
+ASPカーネルのソースコードには,カーネルの実行トレースログを取得するため
+のマクロ等が埋め込んである.デフォルトでは,これらのマクロは空に定義さ
+れてトレースログの取得は行わないが,これらのマクロを適切に定義すること
+でトレースログの取得を行うことができる.
+
+6.11.1 取得できるトレースログの種類とマクロ
+
+取得できるトレースログの種類と,それを取得するために定義するマクロは次
+の通りである.
+
+(a) カーネルの動作開始と終了
+
+次のマクロを定義することで,カーネルの動作開始時と終了時のトレースログ
+を取得することができる.
+
+ LOG_KER_ENTER カーネルが動作を開始する直前(初期化の完了後)
+ LOG_KER_LEAVE カーネルの終了(ext_ker)が呼ばれた直後(終了処
+ 理の実行前)
+
+(b) 処理単位の実行開始と終了
+
+次のマクロを定義することで,割込みハンドラ(INH),割込みサービスルーチ
+ン(ISR),周期ハンドラ(CYC),アラームハンドラ(ALM),CPU例外ハンド
+ラ(EXC),タスク例外処理ルーチン(TEX)の実行開始前と終了後のトレース
+ログを取得することができる.
+
+ LOG_<処理単位略号>_ENTER 処理単位の実行開始直前
+ LOG_<処理単位略号>_LEAVE 処理単位の終了直後
+
+割込みハンドラは,アプリケーションが登録したもののみを対象とし,割込み
+サービスルーチンを呼び出すためにカーネル内に生成されるものは対象としな
+い.タスクの実行開始と終了は,他の方法で取得できるため,この方法は用意
+していない.
+
+なお,割込みハンドラとCPU例外ハンドラの実行開始と終了のトレースログ取得
+は,ターゲット依存部で実装する必要がある.詳しくは,「6.2 トレースログ
+機能への対応」「6.6.1 割込みハンドラの出入口処理」「6.7.1 CPU例外ハンド
+ラの出入口処理」の節を参照すること.
+
+(c) タスク状態の変化
+
+次のマクロを定義することで,タスク状態が変化した時のトレースログを取得
+することができる.ただし,実行状態と実行可能状態の間の遷移は,他の方法
+で取得できるため,このマクロでは取得できない.
+
+ LOG_TSKSTAT タスク状態の変化
+
+(d) ディスパッチャの実行開始と終了
+
+次のマクロを定義することで,ディスパッチャが実行開始する時と,終了する
+時のトレースログを取得することができる.
+
+ LOG_DSP_ENTER ディスパッチャの実行開始
+ LOG_DSP_LEAVE ディスパッチャの終了
+
+ディスパッチャの実行開始は,タスクが実行状態から実行可能状態に遷移する
+タイミングであるため,実行可能状態へ遷移するタスクのTCBへのポインタをパ
+ラメータとする.逆に,ディスパッチャの終了は,タスクが実行可能状態から
+実行状態に遷移するタイミングであるため,実行状態へ遷移するタスクのTCBへ
+のポインタをパラメータとする.
+
+ASPカーネルでは,実行できるタスクがなく,カーネルがアイドル状態になる場
+合には,ディスパッチャの中に留まる.そのため,アイドル状態への遷移とア
+イドル状態から他の状態への遷移は,このマクロでは取得できない.
+
+なお,ディスパッチャの実行開始と終了のトレースログ取得は,ターゲット依
+存部で実装する必要がある.詳しくは,「6.2 トレースログ機能への対応」と
+「6.5.2 ディスパッチャ本体」の節を参照すること.
+
+(e) サービスコールの入口と出口
+
+次のマクロを定義することで,各サービスコールの入口と出口のトレースログ
+を取得することができる.
+
+ LOG_<サービスコールの大文字表記>_ENTER サービスコール名の入口
+ LOG_<サービスコールの大文字表記>_LEAVE サービスコール名の出口
+
+それぞれのマクロの名称やパラメータの詳細については,カーネルのソースコー
+ドを参照すること.
+
+6.11.2 トレースログ記録のサンプルコード
+
+トレースログを記録する方法の一例として,メモリ上にトレースログを記録す
+るためのサンプルコードをarch/logtraceディレクトリに用意している.このサ
+ンプルコードは,システムログ機能と同様のトレースログ機能を用意し,トレー
+スログ情報をメモリ上に記録するとともに,それを読み出して表示する機能を
+実現している.
+
+このサンプルコードを組み込む方法は次の通りである.
+
+(1) target_config.hおよびtarget_syssvc.hに,次の記述を追加する.
+
+ #ifdef TOPPERS_ENABLE_TRACE
+ #include "logtrace/trace_config.h"
+ #endif /* TOPPERS_ENABLE_TRACE */
+
+(2) Makefile.targetに,次の記述を追加する.
+
+ ifeq ($(ENABLE_TRACE),true)
+ COPTS := $(COPTS) -DTOPPERS_ENABLE_TRACE
+ KERNEL_DIR := $(KERNEL_DIR) $(SRCDIR)/arch/logtrace
+ KERNEL_COBJS := $(KERNEL_COBJS) trace_config.o trace_dump.o
+ endif
+
+(3) スタートアップモジュールで,bssセクションのクリアを省略している場合
+ には,trace_modeをTRACE_STOP(=0)に初期化するコードを追加する.こ
+ れは,トレースログ機能が初期化される前に書き込まれるトレースログを
+ 無視するためである.
+
+このサンプルコードを用いて,トレースログを記録・ダンプする方法の例につ
+いては,「TOPPERS/ASPカーネル ユーザーズマニュアル」の「11.5 トレースロ
+グ記録のサンプルコードの使用方法」の節を参照すること.
+
+なお,このサンプルコードでは,ディスパッチャの出口,タスクの状態遷移,
+システムログの出力の3つのトレースログのみを記録している.他のトレースロ
+グを記録したい場合には,trace_config.h(およびtrace_dump.c)を修正する
+必要がある.なお,カーネルのトレースログを網羅的に記録するためのコード
+は,TLV(TraceLogVisualizer)の配布パッケージに含まれている.
+
+6.12 カーネル実装のターゲット依存部のためのリネーム記述
+
+カーネル内部に閉じて使われる関数や変数などの名称で,オブジェクトファイ
+ルのシンボル表に登録されて外部から参照できる名称は,C言語レベルで,先頭
+が"_kernel_"または"_KERNEL_"である名称としなければならないが,ASPカーネ
+ルでは,ソースコードをコンパクトに保ちつつこれを実現するために,リネー
+ム記述ファイルを導入している.
+
+具体的には,リネームすべき名称をリストアップしたxxx_rename.defを用意し,
+このファイルからツール(utils/genrename)により,名称をリネームするため
+のマクロ定義を含むxxx_rename.hと,それらのマクロ定義を解除するための
+xxx_unrename.hを生成する.ツールの起動方法は次の通りである.
+
+ % genrename xxx
+
+xxx_rename.defには,リネームすべき名称を1行に1つ記述する.xxxxという名
+称が記述されている場合,xxx_rename.hには次のような記述が生成される.
+
+#define xxxx _kernel_xxxx
+#ifdef TOPPERS_LABEL_ASM
+#define _xxxx __kernel_xxxx
+#endif /* TOPPERS_LABEL_ASM */
+
+また,xxx_unrename.hには次のような記述が生成される.
+
+#undef xxxx
+#ifdef TOPPERS_LABEL_ASM
+#undef _xxxx
+#endif /* TOPPERS_LABEL_ASM */
+
+xxx_rename.defの中には,他のリネーム記述を取り込むために,「INCLUDE
+"yyy"」または「INCLUDE <yyy>」という記述を含めることができる.この記述
+がされている場合,xxx_rename.hには「#include "yyy_rename.h"」または
+「#include <yyy_rename.h>」という記述が,xxx_unrename.hには「#include
+"yyy_unrename.h"」または「#include <yyy_unrename.h>」という記述が生成さ
+れる.
+
+xxx_rename.defの中の"#"で始まる行はコメントとして読み飛ばされる.また,
+空行も無視される.
+
+カーネルのターゲット非依存部で使われる名称をリネームするために,kernel
+ディレクトリに,kernel_rename.defと,そこから生成したkernel_rename.hお
+よびkernel_unrename.hが用意されている.kernel_rename.defには,
+「INCLUDE "target"」という記述が含まれており,ターゲット依存部のリネー
+ム記述を取り込むようになっている.ターゲット依存部で定義し,ターゲット
+非依存部で参照される名称は,ターゲット依存部のリネーム記述に含める.
+
+ターゲット依存部では,ターゲット依存部で使われる名称をリネームするため
+に,target_rename.defと,そこから生成したtarget_rename.hおよび
+target_unrename.hを用意する.ターゲット依存部からプロセッサ・チップ・開
+発環境依存部を切り分ける場合には,target_rename.defにINCLUDE記述を入れ,
+プロセッサ・チップ・開発環境依存部のリネーム記述を取り込むようにする.
+
+6.13 タイマドライバ
+
+タイマドライバは,カーネルにタイムティックを通知するためのタイマドライ
+バである.
+
+6.13.1 タイマドライバのファイル構成
+
+タイマドライバを組み込むための静的APIを記述したシステムコンフィギュレー
+ションファイルを,target_timer.cfgに用意する.このファイルには,タイマ
+ドライバを初期化するための初期化ルーチンの追加,タイマドライバを終了さ
+せるための終了処理ルーチンの追加,タイマ割込みのための割込みハンドラの
+定義(または,割込みサービスルーチンの追加),タイマ割込みのための割込
+み要求ラインの属性の設定の静的APIなどを含むことになる.
+
+タイマドライバを呼び出すために必要な定義を含むヘッダファイルを,
+target_timer.hに用意する.また,タイマドライバの実装ファイルを
+target_timer.cに用意する.
+
+タイムティックの通知により行う処理の多くは,タスクの起動や待ち解除を行
+うものであるため,タイマ割込みの割込み優先度は,割込みの中で最低の優先
+度で十分である.ただし,周期ハンドラやアラームハンドラの実行開始遅れが
+問題になる場合には,タイマ割込みの割込み優先度をより高い値に設定したい.
+そこで,タイマ割込みの割込み優先度を変更する方法を,ターゲット依存部の
+ユーザーズマニュアルに記載すべきである.
+
+6.13.2 タイマの初期化・終了処理・割込み処理
+
+(6-13-2-1) void target_timer_initialize(intptr_t exinf)
+
+タイマを初期化し,タイマ割込みを周期的に発生させる関数.タイマ割込みの
+周期は,TIC_NUMEとTIC_DENOで指定された時間と一致させる(「5.2 タイム
+ティックの定義」の節を参照).
+
+この関数は,target_timer.cfg中に記述する静的APIにより,初期化ルーチンと
+してカーネルに登録することを想定している.
+
+(6-13-2-2) void target_timer_terminate(intptr_t exinf)
+
+タイマの動作を停止させ,タイマ割込みを発生しないようにする関数.
+
+この関数は,target_timer.cfg中に記述する静的APIにより,終了処理ルーチン
+としてカーネルに登録することを想定している.
+
+(6-13-2-3) void target_timer_handler(void)
+ または void target_timer_isr(intptr_t exinf)
+
+タイマ割込みにより起動される割込み処理プログラム.割込みハンドラとして
+実現する場合にはtarget_timer_handler,割込みサービスルーチンとして実現
+する場合にはtarget_timer_isrの名称とする.ターゲット非依存部の
+signal_timeを呼び出す.
+
+target_timer_handlerは,標準的には次のように定義する.
+
+----------------------------------------
+void
+target_timer_handler(void)
+{
+ i_begin_int(<タイマ割込みの割込み番号>);
+ signal_time();
+ i_end_int(<タイマ割込みの割込み番号>);
+}
+----------------------------------------
+
+この関数は,target_timer.cfg中に記述する静的APIにより,割込みハンドラま
+たは割込みサービスルーチンとしてカーネルに登録することを想定している.
+
+6.13.3 性能評価用システム時刻の参照のための機能
+
+性能評価用システム時刻の参照機能(get_utm)をサポートする場合には,タイ
+マドライバで,以下のデータ型や関数などを用意する.
+
+(6-13-3-1) OMIT_GET_UTM(オプション)
+
+ターゲット非依存部のget_utmの実装を使用せず,ターゲット依存部でget_utm
+を用意する場合には,このシンボルをマクロ定義する.このシンボルをマクロ
+定義した場合,以下のデータ型や関数などを用意する必要はない.
+
+(6-13-3-2) CLOCK
+
+タイマ値の内部表現のためのデータ型.
+
+(6-13-3-3) CLOCK target_timer_get_current(void)
+
+タイマの現在値を読み出し,内部表現で返す関数.タイマ値は,時間の経過と
+ともに増加することを想定している.ハードウェアのタイマが,タイマ値が減
+少するものである場合には,この関数内で増加する値となるように変換する.
+
+(6-13-3-4) bool_t target_timer_probe_int(void)
+
+タイマ割込み要求をチェックする関数.タイマ割込みが要求されている場合に
+true,要求されていない場合にfalseを返す.
+
+(6-13-3-5) TO_USEC(clock)
+
+タイマ値の内部表現を,1μ秒単位に変換するためのマクロ(または関数).
+targettimer_get_currentで読み出した値を,タイマ割込み発生からの経過時間
+(単位: 1μ秒)に変換するために用いる.
+
+6.14 オーバランタイマドライバ(オプション)
+
+オーバランタイマドライバは,オーバランハンドラを起動するためのタイマの
+ドライバである.オーバランハンドラ機能拡張パッケージをサポートしない場
+合には,オーバランタイマドライバを用意する必要はない.
+
+6.14.1 オーバランタイマドライバのファイル構成
+
+オーバランタイマドライバは,タイマドライバと同じファイルの中に記述する.
+オーバランタイマドライバのための記述は,TOPPERS_SUPPORT_OVRHDRがマクロ
+定義されている場合にのみ有効になるようにする.
+
+すなわち,オーバランタイマドライバを組み込むための静的APIは
+target_timer.cfgの中に記述する.このファイルには,オーバランタイマドラ
+イバを初期化するための初期化ルーチンの追加,オーバランタイマドライバを
+終了させるための終了処理ルーチンの追加,オーバランタイマ割込みのための
+割込みハンドラの定義(または,割込みサービスルーチンの追加),オーバラ
+ンタイマ割込みのための割込み要求ラインの属性の設定の静的APIなどを含むこ
+とになる.
+
+また,オーバランタイマドライバを呼び出すために必要な定義は
+target_timer.hの中に,オーバランタイマドライバの実装はtarget_timer.cの
+中に記述する.
+
+オーバランハンドラは,タスクのオーバランに対する処理を行うものであるた
+め,オーバランタイマ割込みの割込み優先度は,割込みの中で最低の優先度で
+十分である.ただし,オーバランタイマ割込みの割込み優先度をより高い値に
+設定したい場合もないとは言えないため,オーバランタイマ割込みの割込み優
+先度を変更する方法を,ターゲット依存部のユーザーズマニュアルに記載すべ
+きである.
+
+6.14.2 オーバランタイマの操作と割込み処理
+
+(6-14-2-1) void target_ovrtimer_initialize(intptr_t exinf)
+
+オーバランタイマの初期化処理を行う.タイマの動作開始は行わない.
+
+この関数は,target_timer.cfg中に記述する静的APIにより,初期化ルーチンと
+してカーネルに登録することを想定している.
+
+(6-14-2-2) void target_ovrtimer_terminate(intptr_t exinf)
+
+オーバランタイマを停止させ,オーバランタイマ割込みを発生しないようにす
+る.
+
+この関数は,target_timer.cfg中に記述する静的APIにより,終了処理ルーチン
+としてカーネルに登録することを想定している.
+
+(6-14-2-3) void target_ovrtimer_start(OVRTIM ovrtim)
+
+オーバランタイマに,残り時間ovrtimを設定し,動作開始する.ovrtimの単位
+はマイクロ秒とする.
+
+(6-14-2-4) OVRTIM target_ovrtimer_stop(void)
+
+オーバランタイマを停止し,タイマの残り時間を読み出す.もし残り時間が
+0(またはそれ未満)になっていた場合には,1を返す.また,オーバランタイ
+マからの割込みをクリアする.
+
+(6-14-2-5) OVRTIM target_ovrtimer_get_current(void)
+
+オーバランタイマの残り時間を読み出す.もし残り時間が0(またはそれ未満)
+になっていた場合には,0を返す.オーバランタイマからの割込みはクリアしな
+い.
+
+(6-14-2-6) void target_ovrtimer_handler(void)
+ または void target_ovrtimer_isr(intptr_t exinf)
+
+オーバランタイマ割込みにより起動される割込み処理プログラム.割込みハン
+ドラとして実現する場合にはtarget_ovrtimer_handler,割込みサービスルーチ
+ンとして実現する場合にはtarget_ovrtimer_isrの名称とする.ターゲット非依
+存部のcall_ovrhdrを呼び出す.
+
+target_timer_handlerは,標準的には次のように定義する.
+
+----------------------------------------
+void
+target_ovrtimer_handler(void)
+{
+ i_begin_int(<オーバランタイマ割込みの割込み番号>);
+ call_ovrhdr();
+ i_end_int(<オーバランタイマ割込みの割込み番号>);
+}
+----------------------------------------
+
+この関数は,target_timer.cfg中に記述する静的APIにより,割込みハンドラま
+たは割込みサービスルーチンとしてカーネルに登録することを想定している.
+
+
+7.コンフィギュレータ設定ファイルのターゲット依存部
+
+7.1 設定ファイルとターゲット依存部の位置付け
+
+ASPカーネルのコンフィギュレータは,設定ファイルの記述に従ってファイルの
+生成およびエラーチェックを行う.コンフィギュレータの設定ファイルには,
+以下の4つがある.
+
+(a) 静的APIテーブル
+
+静的APIの一覧と,各静的APIのパラメータについて記述したファイル.静的
+APIを拡張する場合以外は変更する必要がないため,ターゲット非依存部で用意
+している(kernel/kernel_api.csv).
+
+(b) 値取得シンボルテーブル
+
+コンフィギュレータのパス1において,パラメータ計算用C言語ファイルに出力
+し,値を求めたいシンボル(一般には式)を記述するためのファイル.ターゲッ
+ト非依存部では,ターゲットに依存せずに必要となるシンボルを記述したファ
+イルを用意している(kernel/kernel_def.csv).
+
+ターゲットに依存して必要となるシンボルがある場合には,targetディレクト
+リに置かれたtarget_def.csv中に記述する.target_def.csv中に記述して値を
+求めることができるシンボルは,kernel/kernel_int.hおよびそこからインクルー
+ドされるファイルで定義されていなければならない.kernel_int.hからは,
+target_stddef.h,target_kernel.h,target_config.hを(間接的に)インクルー
+ドしているため,これらのファイルおよびそこからインクルードされるファイ
+ルで定義されるターゲット依存のシンボルは,target_def.csv中に記述するこ
+とができる.
+
+ここで値を求めたシンボルの値は,コンフィギュレータのパス2およびパス3の
+テンプレートファイル中で参照することができる.
+
+(c) パス2のテンプレートファイル
+
+コンフィギュレータのパス2は,テンプレートファイルに従って,カーネルの構
+成・初期化ファイル(kernel_cfg.c),構成・初期化ヘッダファイル
+(kernel_cfg.h)などを生成する.このテンプレートファイルは,ターゲット
+非依存部とターゲット依存部に切り分けてあるが,他のファイルのターゲット
+依存部とは逆に,ターゲット依存部からターゲット非依存部をインクルードす
+る形になっている.
+
+具体的には,targetディレクトリに置かれたtarget.tfで,必要な変数を定義し
+た後,テンプレートファイルのターゲット非依存部(kernel/kernel.tf)をイ
+ンクルードする.kernel.tfでは,カーネルのターゲット非依存部で使用する変
+数定義等を生成する.kernel.tfをインクルードした後,target.tfでは,カー
+ネルのターゲット依存部で使用する変数定義等を生成する.target.tfから,プ
+ロセッサ依存部,チップ依存部を,開発環境依存部を切り分けてもよい.
+
+(d) パス3のテンプレートファイル
+
+コンフィギュレータのパス3は,テンプレートファイルに従って,静的APIの一
+般定数式パラメータのチェックを行う.このテンプレートファイルも,ターゲッ
+ト非依存部とターゲット依存部に切り分けてあり,ターゲット依存部からター
+ゲット非依存部をインクルードする形になっている.
+
+具体的には,targetディレクトリに置かれたtarget_check.tfで,必要な変数を
+定義した後,テンプレートファイルのターゲット非依存部
+(kernel/kernel_check.tf)をインクルードする.kernel_check.tfでは,カー
+ネルのターゲット非依存部で初期化ブロックに出力した一般定数式パラメータ
+のチェックを行う.kernel_check.tfをインクルードした後,target_check.tf
+では,ターゲットに依存するチェックを行う.target_check.tfから,プロセッ
+サ依存部,チップ依存部を,開発環境依存部を切り分けてもよい.
+
+なお,コンフィギュレータの詳細仕様と設定ファイルの記述方法については,
+別途PDFファイルの形で配布している「TOPPERS新世代カーネル用コンフィギュ
+レータ仕様」および「TOPPERS新世代カーネル用コンフィギュレータ内蔵マクロ
+プロセッサ仕様」を参照すること.
+
+7.2 パス2のテンプレートファイルのターゲット依存部
+
+以下では,パス2のテンプレートファイルのターゲット依存部を記述する上で必
+要な事項について説明する.
+
+7.2.1 ターゲット非依存部をインクルードする前に定義すべき変数
+
+target.tfからkernel.tfをインクルードする前に,次の変数を定義しておかな
+ければならない.
+
+(7-2-1) INTNO_ATTISR_VALID ATT_ISRで使用できる割込み番号
+(7-2-2) INHNO_ATTISR_VALID INTNO_ATTISR_VALIDに対応する割込ハンドラ番号
+(7-2-3) INHNO_DEFINH_VALID DEF_INTで使用できる割込みハンドラ番号
+(7-2-4) EXCNO_DEFEXC_VALID DEF_EXCで使用できるCPU例外ハンドラ番号
+(7-2-5) INTNO_CFGINT_VALID CFG_INTで使用できる割込み番号
+(7-2-6) INTPRI_CFGINT_VALID CFG_INTで使用できる割込み優先度
+
+APIで使用できる割込み番号/割込みハンドラ番号/CPU例外ハンドラ番号/割
+込み優先度のリストを,各変数に定義する.INHNO_ATTISR_VALIDには,
+INTNO_ATTISR_VALIDにリストアップした割込み番号に対応する割込みハンドラ
+番号のリストを定義する.
+
+(7-2-7) TARGET_TSKATR(オプション) ターゲット定義のタスク属性
+(7-2-8) TARGET_ISRATR(オプション) ターゲット定義のISR属性
+(7-2-9) TARGET_INHATR(オプション) ターゲット定義の割込みハンドラ属性
+(7-2-10) TARGET_INTATR(オプション) ターゲット定義の割込み属性
+(7-2-11) TARGET_EXCATR(オプション) ターゲット定義のCPU例外ハンドラ属性
+
+各オブジェクトの属性を,ターゲット定義に拡張する場合に,該当するオブジェ
+クト属性を示す変数に,拡張に使用するビットの論理和を定義する.これによ
+り,拡張に使用するビットが設定されている場合に,エラーになるのを防ぐ.
+
+(7-2-12) INTNO_FIX_KERNEL(オプション) カーネル管理に固定されている
+ 割込み番号
+(7-2-13) INHNO_FIX_KERNEL(オプション) カーネル管理に固定されている
+ 割込みハンドラ番号
+(7-2-14) INHNO_FIX_NONKERNEL(オプション) カーネル管理外に固定されている
+ 割込み番号
+(7-2-15) INHNO_FIX_NONKERNEL(オプション) カーネル管理外に固定されている
+ 割込みハンドラ番号
+
+カーネル管理またはカーネル管理外に固定されている割込みがある場合には,
+それらの割込み番号と割込みハンドラ番号のリストを,各変数に定義する.
+
+(7-2-16) USE_INHINIB_TABLE(オプション)
+
+OMIT_INITIALIZE_INTERRUPTを定義したが,割込みハンドラの初期化に必要な情
+報をkernel_cfg.cに生成したい場合には,この変数を1に設定する.具体的には,
+TNUM_INHNO,tnum_inhno,inhinib_tableの定義と,割込みハンドラ毎の出入口
+処理を生成するための記述(INTHDR_ENTRYマクロのリスト)が,ターゲット非
+依存部によって生成される.
+
+(7-2-17) USE_INTINIB_TABLE(オプション)
+
+OMIT_INITIALIZE_INTERRUPTを定義したが,割込み要求ラインの初期化に必要な
+情報をkernel_cfg.cに生成したい場合には,この変数を1に設定する.具体的に
+は,TNUM_INTNO,tnum_intno,intinib_tableの定義が,ターゲット非依存部に
+よって生成される.
+
+(7-2-18) TARGET_MIN_STKSZ(オプション)
+
+ターゲット定義で,タスクのスタックサイズの最小値を設定する場合には,こ
+の変数をスタックサイズの最小値に定義する.
+
+(7-2-19) CHECK_STKSZ_ALIGN(オプション)
+
+スタック領域のサイズがある値の倍数でなければならない場合に,この変数を
+その値に定義する.この変数を定義することで,kernel.tfにおいて,スタック
+領域のサイズが正しくない(この変数に定義した値の倍数でない)場合のエラー
+をチェックするようになる.チェックが必要ない場合には,この変数を定義し
+ない.
+
+(7-2-20) GENERATE_TSKINICTXB(オプション)
+
+USE_TSKINICTXBをマクロ定義した場合,TSKINICTXBの初期化情報を生成するた
+めテンプレートファイル関数GENERATE_TSKINICTXBを定義する.
+GENERATE_TSKINICTXBには,タスクIDがパラメータとして渡される.
+
+7.2.2 ターゲット非依存部で定義される変数
+
+kernel.tfの中では次の変数が定義されるため,kernel.tfをインクルードした
+後,target.tfの中でこれらを参照することができる.
+
+(7-3-1) INTNO[inhno] inhnoを対応するintnoに変換するための連想配列
+(7-3-2) INHNO[intno] intnoを対応するinhnoに変換するための連想配列
+
+7.3 パス3のテンプレートファイルのターゲット依存部
+
+以下では,パス3のテンプレートファイルのターゲット依存部を記述する上で必
+要な事項について説明する.
+
+target_check.tfからkernel_check.tfをインクルードする前に,必要に応じて,
+次の変数を定義しておかなければならない.
+
+(7-3-1) CHECK_FUNC_ALIGN(オプション) 関数のアライン単位
+(7-3-2) CHECK_FUNC_NONNULL(オプション)関数の非NULLチェック
+(7-3-3) CHECK_STACK_ALIGN(オプション) スタック領域のアライン単位
+(7-3-4) CHECK_STACK_NONNULL(オプション)スタック領域の非NULLチェック
+(7-3-5) CHECK_MPF_ALIGN(オプション) 固定長メモリプール領域のアライン単位
+(7-3-6) CHECK_MPF_NONNULL(オプション) 固定長メモリプール領域の非NULLチェック
+
+関数/スタック領域/固定長メモリプール領域の先頭番地のアラインメントの
+チェックを行う場合には,それぞれ,CHECK_FUNC_ALIGN/CHECK_STACK_ALIGN/
+CHECK_MPF_ALIGNをアライン単位に定義する.関数/スタック領域/固定長メモ
+リプール領域の先頭番地がNULLでないかのチェックを行う場合には,それぞれ
+CHECK_FUNC_NONNULL/CHECK_STACK_NONNULL/CHECK_MPF_NONNULLを1に定義する.
+チェックが必要ない場合には,該当する変数を定義しない.
+
+7.4 cfg1_out.cのリンクに必要なスタブの定義ファイル
+
+コンフィギュレータに関してターゲット依存に用意する必要があるファイルと
+して,設定ファイル以外に,cfg1_out.cをリンクするために必要なスタブの定
+義ファイルがある.
+
+コンフィギュレータのパス1では,静的APIの整数定数式パラメータの値をCコン
+パイラを用いて求めるために,cfg1_out.cを生成する.これをコンパイル,リ
+ンクしてオブジェクトファイルを生成する際に,スタートアップモジュールか
+ら参照されるシンボルの定義を与える必要がある.
+
+この定義を与えるために,cfg1_out.cから,ターゲット依存部の
+target_cfg1_out.hをインクルードしている.target_cfg1_out.h(または,そ
+こからインクルードされるファイル)には,スタートアップモジュールから参
+照されるシンボルのスタブの定義を含める.典型的には,以下のような定義を
+含める必要がある.
+
+----------------------------------------
+void sta_ker(void)
+{
+}
+
+void hardware_init_hook(void)
+{
+}
+
+void software_init_hook(void)
+{
+}
+
+const SIZE _kernel_istksz = 0;
+
+STK_T *const _kernel_istk = NULL;
+----------------------------------------
+
+
+8.システムサービス等のターゲット依存部
+
+8.0 システムサービスのターゲット依存部
+
+シリアルポート数やシステムログタスク関連の定数など,システムサービスの
+構成を決定するための定義をtarget_syssvc.hまたはそこからインクルードされ
+るファイル(プロセッサ・チップ・開発環境依存部で用意されるヘッダファイ
+ルなど)に含める.
+
+なお,TOPPERS組込みコンポーネントシステムが導入されると,このファイルの
+内容はコンポーネント記述ファイルに記述されることになり,このファイルは
+無くなる(または,大幅に縮小される)見込みである.
+
+8.1 システムログ機能のターゲット依存定義
+
+システムログ機能を使用する場合で,スタートアップモジュールでbssセクショ
+ンのクリアを省略している場合には,syslog_logmaskとsyslog_lowmask_notを
+0に初期化するコードを追加する.これは,システムログ機能が初期化される前
+に出力されたログ情報を,低レベル出力機能を用いて出力するためである.
+
+ターゲット依存部で提供すべきシステムログ機能のための定義は次の通りであ
+る.
+
+(8-1-1) TCNT_SYSLOG_BUFFER
+
+システムログ機能のログバッファのサイズを定義するマクロ.定義しない場合
+のデフォルト値は32.
+
+(8-1-2) void target_fput_log(char_t c)
+
+システムログの低レベル出力のための文字出力関数.ターゲット依存の方法で,
+文字cを表示/出力/保存する.
+
+この関数は,リエントラントに実装しなければならない.この関数内で排他制
+御が必要な場合には,SILを用いて全割込みロック状態にすること.また,全割
+込みロック状態で呼ばれる場合があるため,全割込みロック状態から呼び出す
+ことができない関数を呼ばないように実装しなければならない.
+
+低レベル出力をシリアルポート経由で行う場合で,シリアルインタフェースド
+ライバとポートを共用しないことが望ましいが,ポート数が足りないためにや
+むをえず共用する場合には,両者が競合しないように注意が必要である.具体
+的には,両者が同じ設定でシリアルI/Oデバイスを使うようにし,シリアルイン
+タフェースドライバの動作中に低レベル出力が行われても差し支えないように
+設計する.また,低レベル出力が動作開始後にシリアルインタフェースドライ
+バがシリアルI/Oデバイスを初期化すると,文字化けが起こる可能性があるため,
+共用するポートは,低レベル出力機能側で初期化し,シリアルインタフェース
+ドライバでは初期化しないようにするとよい.
+
+なお,この関数の本体を,どのファイルに記述するかが問題になる.システム
+サービスのターゲット依存部には,標準では,関数定義を記述するためのファ
+イルを用意していない.ターゲット依存で用意してもよいが,例外的に,カー
+ネル実装のターゲット依存モジュール(target_config.c)に記述してもよい.
+この場合,target_fput_logを,リネーム記述(target_rename.defなど)に含
+めてはならない.
+
+8.2 ログタスクのターゲット依存定義
+
+ターゲット依存部で提供すべきログタスクのための定義は次の通りである.こ
+れらの定義は,target_syssvc.hまたはそこからインクルードされるファイルに
+含める.
+
+(8-2-1) LOGTASK_PRIORITY(オプション)
+
+ログタスクの優先度を定義するマクロ.定義しない場合のデフォルト値は3.
+
+(8-2-2) LOGTASK_STACK_SIZE(オプション)
+
+ログタスクのスタックサイズを定義するマクロ.定義しない場合のデフォルト
+値は1024.
+
+(8-2-3) LOGTASK_PORTID(オプション)
+
+ログタスクの出力先のシリアルポート番号.定義しない場合のデフォルト値は1.
+
+(8-2-4) LOGTASK_INTERVAL(オプション)
+
+ログタスクの動作間隔(単位はミリ秒).定義しない場合のデフォルト値は10.
+
+(8-2-5) LOGTASK_FLUSH_WAIT(オプション)
+
+ログ出力を待ち合わせる処理において,タスクを待たせる単位となる時間(単
+位はミリ秒).定義しない場合のデフォルト値は1.
+
+8.3 シリアルインタフェースドライバのターゲット依存部
+
+ターゲット依存部で提供すべきシリアルインタフェースドライバのための定義
+は次の通りである.これらの定義は,別に指定がない限り,target_serial.hま
+たはそこからインクルードされるファイルに含め,必要なコンフィギュレーショ
+ン情報をtarget_serial.cfgに記述する.関数の実体が必要な場合には,
+target_serial.c等のファイルを用意する.
+
+シリアルインタフェースドライバの中で,ターゲットのシリアルI/Oデバイスに
+依存する部分を,シリアルI/Oデバイスドライバと呼ぶ.シリアルI/Oデバイス
+ドライバは,おおよそ,ITRONデバイスドライバ設計ガイドラインのPDICに相当
+する.PDICに相当するファイルで,他のシステムにも共通に使える可能性があ
+る場合には,pdicディレクトリに置く.
+
+8.3.1 変数,データ型,管理関数
+
+(8-3-1-1) TNUM_PORT
+
+シリアルインタフェースドライバがサポートするシリアルポート数を定義する
+マクロ.このマクロの定義は,target_syssvc.hまたはそこからインクルードさ
+れるファイルに含める.
+
+(8-3-1-2) void sio_initialize(intptr_t exinf)(オプション)
+
+シリアルI/Oデバイスドライバの初期化処理.target_serial.cfgに,この関数
+を初期化ルーチンとして登録する静的APIを含める.
+
+(8-3-1-3) void sio_terminate(intptr_t exinf)(オプション)
+
+シリアルI/Oデバイスドライバの終了処理.target_serial.cfgに,この関数を
+終了処理ルーチンとして登録する静的APIを含める.
+
+(8-3-1-4) void sio_isr(intptr_t exinf)
+
+シリアルI/Oデバイスの割込みサービスルーチン.target_serial.cfgに,この
+関数を割込みサービスルーチンとして登録する静的APIを含める.また,その静
+的APIに必要なシリアルI/Oデバイスの割込み番号などは,target_serial.hでマ
+クロ定義する.割込みサービスルーチンではなく,割込みハンドラとすること
+もできる.
+
+(8-3-1-5) SIOPCB
+
+シリアルI/Oポート管理ブロックのデータ型(target_serial.hには,データ型
+の宣言だけ含まれていればよい).
+
+(8-3-1-6) SIO_RDY_SNDとSIO_RDY_RCV
+
+送信可能コールバックの識別番号をSIO_RDY_SNDに,受信通知コールバックの識
+別番号をSIO_RDY_RCVにマクロ定義する.コールバックの禁止/許可を行なうサー
+ビスコール(sio_ena_cbrとsio_dis_cbr)で用いる.
+
+8.3.2 デバイスサービスルーチン
+
+以下のデバイスサービルルーチンは,(少なくとも)シリアルI/Oポートからの
+割込みがマスクされた状態で呼び出される.また,タスクコンテキスト,非タ
+スクコンテキストのいずれで呼び出される場合もある(いずれで呼び出されて
+も動作するようにしなければならない).
+
+(8-3-2-1) SIOPCB *sio_opn_por(ID siopid, intptr_t exinf)
+
+siopidで指定されるシリアルI/Oポートをオープンする関数.exinfはシリアル
+I/Oポートに対する拡張情報で,コールバックを呼ぶ時にポートを区別するた
+めに渡す.
+
+(8-3-2-2) void sio_cls_por(SIOPCB *siopcb)
+
+siopcbで指定されるシリアルI/Oポートをクローズする関数.
+
+(8-3-2-3) bool_t sio_snd_chr(SIOPCB *siopcb, char_t c)
+
+siopcbで指定されるシリアルI/Oポートに,cで示される文字を送信する関数.
+文字を送信レジスタに入れた場合にはtrueを,前に送信した文字の送信が終わっ
+ていないために,文字を送信レジスタに入れられなかった場合にはfalseを返す.
+
+(8-3-2-4) int_t sio_rcv_chr(SIOPCB *siopcb)
+
+siopcbで指定されるシリアルI/Oポートから文字を読む関数.文字を受信してい
+た場合,読んだ文字のコードは正の値として返し,文字を受信していない場合
+には-1を返す.
+
+(8-3-2-5) void sio_ena_cbr(SIOPCB *siopcb, uint_t cbrtn)
+
+siopcbで指定されるシリアルI/Oポートからの,cbrtnで指定されるコールバッ
+クを許可する.cbrtnには,SIO_RDY_SNDかSIO_RDY_RCVを指定できる.
+
+(8-3-2-6) void sio_dis_cbr(SIOPCB *siopcb, uint_t cbrtn)
+
+siopcbで指定されるシリアルI/Oポートからの,cbrtnで指定されるコールバッ
+クを禁止する.cbrtnには,SIO_RDY_SNDかSIO_RDY_RCVを指定できる.
+
+8.3.3 コールバックルーチン
+
+ターゲット依存部は,必要なタイミングで,シリアルインタフェースドライバ
+のターゲット非依存部に含まれる以下のコールバックルーチンを呼び出びださ
+なければならない.ただし,それぞれのコールバックが禁止されている時は,
+コールバックルーチンを呼び出してはならない.
+
+コールバックルーチンは,(少なくとも)シリアルI/Oポートからの割込みが禁
+止された状態で,非タスクコンテキストで呼び出す.exinfには,シリアルI/O
+ポートのオープン時に指定された拡張情報を渡す.
+
+(8-3-3-1) void sio_irdy_snd(intptr_t exinf)
+
+送信可能コールバックルーチン.シリアルI/Oポートに対して文字が送信できる
+状態になった場合に呼び出す.シリアルインタフェースドライバは,このコー
+ルバックルーチンの中で,sio_snd_chrを呼び出して次の文字を送信するか,送
+信すべき文字がない場合には送信可能コールバックを禁止する.
+
+(8-3-3-2) void sio_irdy_rcv(intptr_t exinf)
+
+受信通知コールバックルーチン.シリアルI/Oポートから文字を受信した場合に
+呼び出す.シリアルインタフェースドライバは,このコールバックルーチンの
+中で,必ずsio_rcv_chrを呼び出して受信した文字を取り出す.
+
+8.4 カーネル起動メッセージの出力のターゲット依存定義
+
+ターゲット依存部で提供すべきカーネル起動メッセージの出力のための定義は
+次の通りである.
+
+(8-4-1) TARGET_NAME
+
+ターゲットの名称に定義する.
+
+(8-4-2) TARGET_COPYRIGHT(オプション)
+
+カーネル起動メッセージに,ターゲット依存部の著作権表示を追加するための
+マクロ.デフォルトでは,ターゲット依存部の著作権表示を追加しない.
+
+8.5 サンプルプログラムとテストプログラムのターゲット依存定義
+
+ターゲット依存部で提供すべきサンプルプログラムおよびテストプログラムの
+ための定義は次の通りである.これらの定義は,target_test.h(またはそれら
+からインクルードされるファイル)に含める.
+
+(8-5-1) STACK_SIZE(オプション)
+
+サンプルプログラムおよびテストプログラムのタスクのスタックサイズを定義
+するマクロ.定義しない場合のデフォルト値は4096.デフォルト設定ではメモ
+リが不足する場合や,シミュレーション環境などで大きいスタック領域が必要
+な場合には,ターゲット依存部でこのマクロを設定するスタックサイズに定義
+する.
+
+(8-5-2) CPUEXC1(オプション)
+
+サンプルプログラムおよびテストプログラムで用いるCPU例外のCPU例外ハンド
+ラ番号を定義するマクロ.このマクロを定義しない場合,CPU例外ハンドラを使
+う部分がサンプルプログラムから除外される.CPU例外ハンドラのテストをする
+テストプログラムはコンパイルできない.
+
+(8-5-3) RAISE_CPU_EXCEPTION(オプション)
+
+CPUEXC1に定義したCPU例外を発生させるC言語のプログラムを定義するマクロ.
+CPUEXC1を定義した場合には必ず定義しなければならない.
+
+(8-5-4) CANNOT_RETURN_CPUEXC(オプション)
+
+ターゲットシステムの制約により,CPU例外ハンドラからリターンした後に,タ
+スクの実行を継続できない場合に定義するマクロ.このマクロを定義すると,
+CPU例外ハンドラのテストをするテストプログラムから,CPU例外ハンドラから
+リターンした後の処理が除外される.サンプルプログラムの該当部分は正しく
+動作しない.
+
+(8-5-5) TASK_PORTID(オプション)
+
+サンプルプログラムにおいて,コマンド文字を読み込むシリアルポート番号を
+定義するマクロ.定義しない場合のデフォルト値は1.
+
+(8-5-6) LOOP_REF(オプション)
+
+サンプルプログラムにおいて,プロセッサの速度を計測するためのループ回数
+を定義するマクロ.定義しない場合のデフォルト値は1000000.デフォルト設定
+では,値が大き過ぎて計測に時間がかかりすぎる場合や,値が小さ過ぎて計測
+結果が安定しない場合に,ターゲット依存部でこのマクロを設定するループ回
+数に定義する.
+
+(8-5-7) MEASURE_TWICE(オプション)
+
+サンプルプログラムにおいて,プロセッサの速度を2度計測する場合に定義する
+マクロ.シミュレーション環境などプロセッサの速度が変動する環境で,1度の
+計測では計測結果が安定しない場合に定義する.
+
+(8-5-8) TASK_LOOP(オプション)
+
+サンプルプログラムにおいて,プロセッサの速度を計測せずに,タスク内での
+ループ回数を固定する場合に,ループ回数を定義するマクロ.ループ全体の実
+行時間が0.4秒程度になるようなループ回数を,このマクロに定義する.
+
+8.6 実行時間分布集計モジュールのターゲット依存定義
+
+実行時間分布集計モジュールの設定をターゲット依存部で変更する場合に,ター
+ゲット依存部で提供すべき実行時間分布集計モジュールのための定義は次の通
+りである.これらの定義は,target_test.h(またはそこからインクルードされ
+るファイル)に含める.この他に,ターゲット依存で必要な初期化処理がある
+場合にも,ターゲット依存部に含める.
+
+(8-6-1) HISTTIM(オプション)
+
+実行時間計測用の時刻のデータ型を定義するマクロ.定義しない場合のデフォ
+ルトはSYSUTM.
+
+(8-6-2) void HIST_GET_TIM(HISTTIM *p_time)(オプション)
+
+実行時間計測用の現在時刻を*p_timeに取得する処理に定義するマクロ.定義し
+ない場合のデフォルトはget_utm.
+
+(8-6-3) uint_t HIST_CONV_TIM(HISTTIM time)(オプション)
+
+実行時間計測用の時刻の差(時間)を,実行時間分布集計用の値に変換する処
+理に定義するマクロ.時刻が過去に戻ったかオーバフローしたかの区別がつか
+ない場合には,最上位ビットが1の値(INT_MAXよりも大きい値)を返す.定義
+しない場合のデフォルトは,timeをuint_tにキャストする処理.
+
+(8-6-4) void HIST_BM_HOOK(void)(オプション)
+
+実行時間計測直前に行うべき処理に定義するマクロ.キャッシュのパージやフィ
+ル,メモリバリア処理等を行いたい場合には,このマクロに定義する.定義し
+ない場合のデフォルトは,空の処理になる.
+
+
+9.その他
+
+9.1 ドキュメント
+
+ターゲット依存部のユーザーズマニュアルを,target_user.txtに用意する.プ
+ロセッサ・チップ・開発環境依存部のユーザーズマニュアルを切り分けてもよ
+いし,ファイルが大きくなる場合には複数のファイルに分割してよいが,その
+場合には,target_user.txt中にそれらのファイル名を記述すること.
+
+ターゲット依存部のユーザーズマニュアルには,少なくとも次のような内容を
+記述することが望ましい.
+
+(1) 対応しているターゲットシステムの種類・構成,バージョン番号
+ ・ターゲットハードウェア(ボード等)の名称と対応している構成
+ ・ターゲット略称
+ ・ターゲット非依存部のバージョン番号
+ ・プロセッサ,チップ,開発環境依存部の構成とバージョン番号
+ ・使用するPDICとバージョン番号
+
+(2) 使用する開発環境と動作検証した条件(バージョン,オプション等)
+ ・言語処理系(コンパイラ,アセンブラ,リンカ等)
+ ・デバッグ環境
+
+(3) ターゲット定義事項の規定
+
+(3-1) データ型に関する規定
+ ・int_t型,long_t型のサイズ
+ ・char_t型,int_least8_t型,void *型,intptr_t型のサイズ
+ ・int8_t型,uint8_t型,int64_t型,uint64_t型,int128_t型,
+ uint128_t型,float32_t型,double64_t型のサポートの有無
+
+(3-2) 割込み処理に関する規定
+ ・割込みハンドラ番号と割込み番号の割当て,両者の対応
+ ・割込み優先度の段階数(TMIN_INTPRIの値)
+ ・dis_intとena_intのサポートの有無,その制限事項
+ ・CFG_INTの制限事項と拡張(ターゲット定義で使用できる割込み属性)
+ ・TOPPERS標準割込み処理モデルからのその他の逸脱
+
+(3-3) カーネル管理外の割込みに関する規定
+ ・TMIN_INTPRIは固定か設定できるか,その設定方法
+ ・NMI以外にカーネル管理外の割込みを設けるか(設けられるようにするか)
+ ・カーネル管理外の割込みの設定方法
+ ・カーネル管理外の割込みに対してDEF_INH,CFG_INTをサポートするか
+ ・カーネル管理外の割込みハンドラが実行開始される時のシステム状態と
+ コンテキスト
+ ・割込みハンドラの終了時に行われる処理
+ ・カーネル管理外の割込みハンドラの記述方法
+ ・カーネル内の割込み出入口処理で起こる可能性のあるCPU例外
+
+(3-4) CPU例外処理に関する規定
+ ・CPU例外ハンドラ番号の割当て
+ ・割込み優先度マスクをTMIN_INTPRIと同じかそれよりも高い値に設定して
+ いる状態で発生したCPU例外を,カーネル管理外のCPU例外と扱うか
+ ・カーネル内のCPU例外出入口処理で起こる可能性のあるCPU例外
+
+(3-5) 性能評価用システム時刻の参照に関する規定
+ ・get_utmのサポートの有無,その制限事項
+
+(3-6) オーバランハンドラ機能拡張のサポートに関する規定
+ ・オーバランハンドラ機能拡張パッケージのサポートの有無
+ ・プロセッサ時間に指定できる値の最大値(TMAX_OVRTIMの値)
+
+(3-7) その他
+ ・その他の制限事項
+ ・その他の拡張機能
+
+(4) カーネルの起動/終了処理に関する情報
+ ・用意しているスタートアップモジュールの処理内容
+ ・スタートアップモジュールからhardware_init_hookを呼び出している場
+ 合には,hardware_init_hookをアプリケーションで用意する場合の作成
+ 方法や制限事項など
+ ・カーネルを終了した後の振舞い
+
+(5) メモリマップ
+ ・デフォルトのメモリマップ,その変更方法
+
+(6) タイマドライバ関連の情報
+ ・タイムティックの周期,その変更方法
+ ・使用するリソース(タイマ)
+ ・タイマ割込みの割込み優先度の変更方法
+ ・オーバランタイマ割込みの割込み優先度の変更方法
+
+(7) シリアルインタフェースドライバの情報
+ ・使用するリソース(SIOコントローラ)
+ ・通信パラメータ(ボーレート,ビット数,パリティの有無,ストップビット)
+
+(8) システムログ機能の情報
+ ・システムログの低レベル出力の実現方法
+ ・通信パラメータ(ボーレート,ビット数,パリティの有無,ストップビット)
+
+(9) システム構築手順
+
+(10) ターゲットシステム固有の注意事項
+ ・タスクコンテキストに含まれるレジスタ,含まれないレジスタ
+
+(10) 類似のターゲットにポーティングする開発者向けの参考情報
+
+(12) ディレクトリ構成・ファイル構成
+
+(13) バージョン履歴
+
+また,必要に応じて,ターゲット依存部の設計メモを,target_design.txtに用
+意する.プロセッサ・チップ・開発環境依存部に関する設計メモを切り分けて
+もよいし,ファイルが大きくなる場合には複数のファイルに分割してもよいが,
+その場合には,target_design.txt中にそれらのファイル名を記述すること.
+
+9.2 パッケージ記述ファイル
+
+リリースパッケージ(個別パッケージおよび簡易パッケージ)を作成するため
+に,パッケージに含めるファイルを記述したパッケージ記述ファイルを用意す
+る.パッケージ記述ファイルの名称は,個別パッケージ用をMANIFEST,簡易パッ
+ケージ用をE_PACKAGEとする.
+
+例えば,arch/arm_gccディレクトリに置かれたMANIFESTファイルを用いて個別
+パッケージを作成する場合には,次のコマンドを実行する.
+
+ % utils/makerelease arch/arm_gcc/MANIFEST
+
+このコマンドにより,RELEASE/asp_arch_arm_gcc-<バージョン番号>.tar.gzが
+作成される.また,target/at91skyeye_gccディレクトリに置かれたE_PACKAGE
+ファイルを用いて簡易パッケージを作成する場合には,次のコマンドを実行す
+る.
+
+ % utils/makerelease target/at91skyeye_gcc/E_PACKAGE
+
+このコマンドにより,RELEASE/asp_at91skyeye_gcc-<バージョン番号>.tar.gz
+が作成される(RELEASEディレクトリがない場合には,ディレクトリが作られ
+る).
+
+なお,makereleaseユーティリティは,ASPカーネルのソースファイルが置かれ
+たディレクトリが,aspという名称であることを仮定している(異なる名称の場
+合でもパッケージは作成できるが,パッケージを展開した時に展開されるディ
+レクトリがaspでなくなる).また,標準のtarコマンドがGNU tarであること
+(正確には,zオプションに対応していること)を想定している.
+
+パッケージ記述ファイルには,パッケージに含めるファイル名を,パッケージ
+記述ファイルが置かれたディレクトリからの相対パス名で,1行に1つずつ記述
+する.また,必要に応じて,以下のディレクティブを含める.
+
+(a) E_PACKAGE <簡易パッケージ名>
+
+簡易パッケージ名を指定する.簡易パッケージ記述ファイル(E_PACKAGE)の先
+頭に記述する.簡易パッケージ名は,asp_<ターゲット略称>とする.例えば,
+ターゲット略称がat91skyeye_gccの場合には,asp_at91skyeye_gccとなる.個
+別パッケージと区別するために,簡易パッケージのファイル名には"target"を
+含めない.
+
+(b) PACKAGE <個別パッケージ名>
+
+個別パッケージ名を指定する.個別パッケージ記述ファイル(MANIFEST)の先
+頭に記述する.また,そこからインクルードされる各ファイルの先頭にも記述
+し,それをインクルードしている個別パッケージ名を指定する.ターゲット依
+存部の個別パッケージ名は,個別パッケージ記述ファイルが置かれたディレク
+トリの相対パス中の"/"を"_"に置き換えた文字列を,"asp_"の後につなげたも
+のとする.例えば,個別パッケージ記述ファイルがarch/arm_gcc/MANIFESTの場
+合には,asp_arch_arm_gccとなる.
+
+(c) VERSION <バージョン番号>
+
+パッケージのバージョン番号を指定する.簡易パッケージ記述ファイルおよび
+個別パッケージ記述ファイルの中に記述する.簡易パッケージにおいて,バー
+ジョン番号をパッケージ化した日付とする場合には,パッケージ番号の代わり
+に%dateと記述する.
+
+バージョン番号の付与方法については,「TOPPERS/ASPカーネル ユーザーズマ
+ニュアル」の「2.2 簡易パッケージ」および「2.3 個別パッケージ」の節を参
+照すること.
+
+(d) INCLUDE <ファイル名>
+
+別のパッケージ記述ファイルをインクルードする.簡易パッケージ記述ファイ
+ルからは,個別パッケージ記述ファイルのみをインクルードするのを原則とす
+る.個別パッケージ記述ファイルからインクルードされるファイル中で指定さ
+れる個別パッケージ名は,すべて一致していなければならない.
+
+
+10.リファレンス
+
+10.1 ターゲット依存部のファイル一覧
+
+標準的なターゲット依存部のファイル構成は次の通りである.
+
+Makefile.target Makefileのターゲット依存部(2章).
+
+target_stddef.h TOPPERS共通定義(t_stddef.h)のターゲット依存部(3
+ 章).アプリケーションとカーネルの両方からインクルー
+ ドされる.
+target_sil.h システムインタフェースレイヤ(sil.h)のターゲット依
+ 存部(4章).アプリケーションとカーネルの両方から
+ インクルードされる.
+target_kernel.h カーネルAPI(kernel.h)のターゲット依存部(5章).
+ アプリケーションとカーネルの両方からインクルードさ
+ れる.
+
+target_config.h カーネル実装のターゲット依存部のヘッダファイル(6
+ 章).カーネルのみからインクルードされる.
+target_config.c カーネル実装のターゲット依存部のC言語で記述される
+ 部分(6章,オプション).
+target_support.S カーネル実装のターゲット依存部のアセンブリ言語で記
+ 述される部分(6章,オプション).
+target_rename.def カーネル実装のターゲット依存部のためのリネーム記述
+ (6.12節).
+target_rename.h target_rename.defから生成されるファイル(6.12節).
+target_unrename.h target_rename.defから生成されるファイル(6.12節).
+target_timer.cfg タイマドライバのシステムコンフィギュレーションファ
+ イル(6.13節).
+target_timer.h タイマドライバのヘッダファイル(6.13節).カーネル
+ のみからインクルードされる.
+target_timer.c タイマドライバの実装ファイル(6.13節,オプション).
+システム略称.h ターゲットのハードウェア資源(割込みハンドラ番号や
+ CPU例外ハンドラ番号,デバイスレジスタの番地など)の
+ 定義を含むヘッダファイル.アプリケーションとカーネ
+ ルの両方からインクルードされる(6章,オプション).
+
+target_def.csv コンフィギュレータの値取得シンボルテーブルのターゲッ
+ ト依存部(7章,オプション).
+target.tf コンフィギュレータのパス2のテンプレートファイルの
+ ターゲット依存部(7.2節).
+target_check.tf コンフィギュレータのパス3のテンプレートファイル(7.3
+ 節).
+target_cfg1_out.h cfg1_out.cのリンクに必要なスタブの定義ファイル(7.4
+ 節).
+
+target_syssvc.h システムサービスのターゲット依存定義(8.0節).
+target_serial.cfg シリアルドライバのシステムコンフィギュレーションファ
+ イル(8.3節).
+target_serial.h シリアルドライバのヘッダファイル(8.3節).シリアル
+ ドライバのみからインクルードされる.
+target_serial.c シリアルドライバの実装ファイル(8.3節,オプション).
+target_test.h テストプログラムのターゲット依存定義(8.4節).
+
+target_user.txt ユーザーズマニュアル(9.1節)
+target_design.txt 設計メモ(9.1節,オプション)
+MANIFEST 個別パッケージに含めるファイルのリスト(9.2節,オプ
+ ション)
+E_PACKAGE 簡易パッケージに含めるファイルのリスト(9.2節,オプ
+ ション)
+
+以上
--- /dev/null
+
+ TOPPERS/ASPカーネル
+ ユーザーズマニュアル
+
+ 対応バージョン: Release 1.6.0
+ 最終更新: 2010年7月30日
+
+このドキュメントは,TOPPERS/ASPカーネルを使用するために必要な事項を説明
+するものである.
+
+----------------------------------------------------------------------
+ TOPPERS/ASP Kernel
+ Toyohashi Open Platform for Embedded Real-Time Systems/
+ Advanced Standard Profile Kernel
+
+ Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ Graduate School of Information Science, Nagoya Univ., JAPAN
+
+ 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ スコード中に含まれていること.
+ (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ の無保証規定を掲載すること.
+ (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ と.
+ (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ 報告すること.
+ (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ 免責すること.
+
+ 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ の責任を負わない.
+
+ $Id: user.txt 1878 2010-08-01 06:49:31Z ertl-hiro $
+----------------------------------------------------------------------
+
+○目次
+
+1.TOPPERS/ASPカーネルの概要
+ 1.1 TOPPERS/ASPカーネルの位置付け
+ 1.2 TOPPERS/ASPカーネルの仕様
+ 1.3 マイグレーションガイド
+ 1.4 機能拡張・チューニングガイド
+ 1.5 既知の問題
+2.ターゲット依存部
+ 2.1 ターゲット依存部の概要
+ 2.2 簡易パッケージ
+ 2.3 個別パッケージ
+3.クイックスタートガイド
+ 3.1 開発環境の準備
+ 3.2 コンフィギュレータの構築
+ 3.3 サンプルプログラムの構築と実行
+ 3.4 カーネルを関数単位でライブラリ化する方法
+ 3.5 アプリケーションとカーネルを別々に構築する方法
+4.ディレクトリ構成・ファイル構成
+ 4.1 配布パッケージのディレクトリ構成
+ 4.2 ターゲット非依存部のファイル構成
+5.コンフィギュレーションスクリプトの使い方
+6.Makefileの修正方法
+ 6.1 Makefileの変数定義
+ 6.2 コンパイルオプション
+7.コンフィギュレータの使い方
+8.システムサービス
+ 8.1 システムログ機能
+ 8.1.1 システムログ機能の位置付け
+ 8.1.2 ログバッファへの記録と低レベル出力
+ 8.1.3 ログ情報の種別
+ 8.1.4 ログ情報の重要度
+ 8.1.5 ログ情報のデータ構造
+ 8.1.6 システムログ機能のサービスコール
+ 8.1.7 システムログ機能のためのライブラリ関数とマクロ
+ 8.1.8 システムログ機能のその他のサービス
+ 8.2 シリアルインタフェースドライバ
+ 8.2.1 シリアルインタフェースドライバのサービスコール
+ 8.2.2 シリアルインタフェースドライバのその他のサービス
+ 8.3 システムログタスク
+ 8.3.1 システムログタスクのサービスコール
+ 8.3.2 システムログタスクのその他のサービス
+ 8.4 カーネル起動メッセージの出力
+9.サポートライブラリ
+ 9.1 基本的なライブラリ関数
+ 9.2 キュー操作ライブラリ関数
+ 9.3 システムログ出力用ライブラリ関数
+ 9.4 実行時間分布集計モジュール
+10.テストプログラム
+ 10.1 テストプログラム用ライブラリ
+ 10.2 カーネルの整合性検査
+ 10.3 機能テストプログラム
+ 10.4 性能評価プログラム
+11.使用上の注意とヒント
+ 11.1 タイマドライバの組込み
+ 11.2 assertマクロの処理
+ 11.3 システムログ機能の扱い
+ 11.4 オブジェクトIDの管理
+ 11.5 カーネルの内部シンボルのリネーム
+ 11.6 トレースログ記録のサンプルコードの使用方法
+ 11.7 システムの起動時の初期化処理
+12.参考情報
+ 12.1 利用条件と利用報告
+ 12.2 保証・適用性・サポート
+ 12.3 バグレポート
+ 12.4 ウェブサイト
+ 12.5 TOPPERSユーザーズメーリングリスト
+ 12.6 TOPPERSプロジェクトのメンバ向けのサービス
+ 12.7 TOPPERSプロジェクトへの参加
+13.リファレンス
+ 13.1 サービスコール一覧
+ 13.2 静的API一覧
+ 13.3 バージョン履歴
+
+
+1.TOPPERS/ASPカーネルの概要
+
+1.1 TOPPERS/ASPカーネルの位置付け
+
+TOPPERS/ASPカーネル(以下,ASPカーネル)は,TOPPERS新世代カーネルの基盤
+となるものとして,TOPPERSプロジェクトにおいて開発したリアルタイムカーネ
+ルである.μITRON4.0仕様のスタンダードプロファイル準拠のリアルタイムカー
+ネルであるTOPPERS/JSPカーネルを拡張・改良する形で開発した.
+
+1.2 TOPPERS/ASPカーネルの仕様
+
+ASPカーネルの仕様の概要については,「TOPPERS/ASPカーネルの仕様概要」を
+参照すること.また,ASPカーネルを含むTOPPERS新世代カーネルの仕様の詳細
+については,別途PDFファイルの形で配布している「TOPPERS新世代カーネル統
+合仕様書」を参照すること.
+
+1.3 マイグレーションガイド
+
+従来のTOPPERSカーネルや他のμITRON4.0仕様準拠のカーネルから,TOPPERS新
+世代カーネルに移行するための方法(またはヒント)を説明した「TOPPERS新世
+代カーネルへのマイグレーションガイド」を,別途PDFファイルの形で配布して
+いる.必要に応じて参照すること.
+
+1.4 機能拡張・チューニングガイド
+
+TOPPERS/ASPカーネルを,機能拡張・チューニングするための方法(またはヒン
+ト)を説明した「機能拡張・チューニングガイド」を用意している.拡張パッ
+ケージの使用方法は,「機能拡張・チューニングガイド」に含まれている.必
+要に応じて参照すること.
+
+1.5 既知の問題
+
+kernel_cfg.c(およびcfg1_out.c)は,カーネル,システムサービス,アプリ
+ケーションのいずれのインクルードファイルもインクルードし,いずれのシン
+ボルも参照する可能性がある.そのため,カーネル,システムサービス,アプ
+リケーションでシンボル等が衝突している場合や,コンパイルオプションが食
+い違っている場合に,kernel_cfg.c(およびcfg1_out.c)が正しくコンパイル
+できなくなる場合が考えられる.カーネルのシンボルをリネームするなどの方
+法で軽減されてはいるが,問題がなくなっているわけではない.
+
+システムコンフィギュレーションファイルから,コンフィギュレータに対する
+INCLUDEディレクティブにより他のコンフィギュレーションファイルをインクルー
+ドしている場合に,その中に含まれるC言語プリプロセッサのインクルードディ
+レクティブ(#include)で,コンフィギュレーションファイルの置かれている
+ディレクトリが,ファイルを検索するパスにはいらないという問題がある.例
+えば,syssvc/syslog.cfgに「#include "syslog.h"」と記述できないのは,こ
+の問題があるためである.
+
+現時点では,アドレスが64ビットの環境には対応していない.64ビットアドレ
+ス環境をサポートするための最大の課題は,モトローラSレコードフォーマット
+が64ビットアドレスに対応していないことである.
+
+
+2.ターゲット依存部
+
+2.1 ターゲット依存部の概要
+
+ASPカーネルのターゲット非依存部と,各種のターゲットシステムに対応するた
+めのターゲット依存部は,別々に開発されている.そのため,ASPカーネルが対
+応しているすべてのターゲット依存部を,バージョンを整合させてパッケージ
+化することは困難である.そこで,主に初級のユーザを対象にした簡易パッケー
+ジと,上級のユーザやカーネル開発者を対象にした個別パッケージを用意して
+いる.
+
+ASPカーネルを未サポートのターゲットシステムへポーティングするために必要
+な作業は,開発環境の構築と標準の開発環境との差異の吸収,カーネル自身の
+ポーティング,システムサービスのポーティングなどからなる.詳しくは,
+「ターゲット依存部 ポーティングガイド」を参照すること.
+
+2.2 簡易パッケージ
+
+簡易パッケージは,ASPカーネルが対応しているターゲットシステム毎に用意さ
+れ,そのターゲットシステム上でASPカーネルを動作させるために必要なファイ
+ル一式をパッケージ化したものである.簡易パッケージに含まれるファイルは,
+バージョンが整合していることが確認されている.
+
+簡易パッケージのバージョン番号は,パッケージ化した日付とすることを原則
+とするが,ターゲットシステム毎の事情によりこの原則に従わない場合がある.
+
+簡易パッケージは,基本的には,次に説明する個別パッケージを複数まとめた
+ものである.そのため,対象ターゲットシステムに必要のないファイルも含ま
+れている.また,簡易パッケージに含まれている個別パッケージのバージョン
+は,個別パッケージのMANIFESTファイルを参照することで知ることができる.
+
+2.3 個別パッケージ
+
+個別パッケージは,ASPカーネルの開発単位毎に,その開発単位で開発を担当し
+ているファイル一式をパッケージ化したものである.ASPカーネルのターゲット
+非依存部も,一つの個別パッケージとして配布される.ある個別パッケージを
+使用するためには,一般には,他の個別パッケージが必要となる.ターゲット
+依存部の個別パッケージを使用するために必要となる個別パッケージとそのバー
+ジョンについては,ターゲット依存部のユーザーズマニュアルを参照すること.
+使用する個別パッケージのバージョンを整合させることは,ユーザの責任であ
+る.
+
+個別パッケージのバージョン番号は,X.Y.Zの形で表現される.ターゲット非依
+存部のバージョン番号を,ASPカーネル全体のリリース番号とする.ターゲット
+依存部のバージョン番号は,XとYが,それが依存するターゲット非依存部と一
+致している.それに対して,Zは一致しているとは限らない.例えば,ターゲッ
+ト非依存部のバージョン1.1.0に対応するターゲット依存部は,バージョン
+1.1.Zの形となる.ターゲット依存部のみがバージョンアップした場合には,Z
+が変更される.
+
+使用する個別パッケージは,次の例のように,ターゲット非依存部の個別パッ
+ケージを展開したのと同じディレクトリで展開する.
+
+ % tar xvfz asp-1.1.0.tar.gz
+ % tar xvfz asp_arch_arm_gcc_1.1.2.tar.gz
+
+ターゲット非依存部の個別パッケージには,以下のターゲット依存部が含まれ
+ているが,これらは他のターゲットシステムにポーティングする際の参考にす
+るために用意しているものであり,その動作については未検証である.
+
+ target/dve68k_gcc DVE-68K/40(GNU開発環境)用ターゲット依存部
+ arch/m68k_gcc M68040(GNU開発環境)用プロセッサ依存部
+ pdic/upd72001 μPD72001用 簡易SIOドライバ
+
+
+3.クイックスタートガイド
+
+ここでは,ターゲット依存部が用意されているターゲットシステム上で,ASPカー
+ネル上で動作するサンプルプログラムを構築・動作させるまでの手順を示す.
+
+3.1 開発環境の準備
+
+ASPカーネルを用いたシステム構築には,以下のツールが必要である.
+
+ ホストシステム用のツール
+ perl 動作確認:5.10.0
+ GNU Make 動作確認:3.81
+
+ TOPPERS新世代カーネル用コンフィギュレータ
+ cfg 動作確認:1.6.0
+ ※ 1.5以前のバージョンでは動作しない.
+
+ ターゲットシステム用のツール(クロス開発環境)
+ 標準規格に準拠したCコンパイラ
+ アセンブラ,リンカ,ライブラリアン
+ シンボルファイル出力ツール,ヘキサファイル出力ツール
+ 標準Cライブラリ(必須ではない)
+
+ターゲットシステム用のツールにGNU開発環境を用いる場合には,以下のツール
+が必要である.
+
+ ターゲットシステム用のGNU開発環境ツール
+ BINUTILS(as,ld,ar,nm,ranlib,objcopy,objdump)
+ GCCまたはGCC-CORE(gccおよびそこから呼び出されるツール)
+ NEWLIB(標準Cライブラリ,必須ではない)
+
+動作確認されているターゲットシステム用のツールについては,ターゲット依
+存部のユーザーズマニュアルを参照すること.
+
+ターゲットシステム用の標準Cライブラリは,アプリケーションが標準Cライブ
+ラリを使用しない場合には,必要ない.ただし,コンパイラが標準Cライブラリ
+関数(memcpy,memsetなど)を呼び出すコードを生成する場合があり,その場
+合には標準Cライブラリが必要である.標準Cライブラリを用意する代わりに,
+生成したコードが呼び出す関数のみを自分で用意してもよい.
+
+以下では,これらのツールが用意できていることを前提に,UNIXマシン上での
+構築手順を説明する.また以下の説明では,makeコマンドがGNU Makeであるも
+のとする(ASPカーネルのサンプルのMakefileは,GNU Makeの拡張機能を用いて
+いる).
+
+3.2 コンフィギュレータの構築
+
+カーネルを構築する前に,まず,TOPPERS新世代カーネル用コンフィギュレータ
+を構築する必要がある.簡易パッケージに含まれていた場合など,コンフィギュ
+レータを実行ファイル形式で入手した場合には,このステップは必要ない.
+
+コンフィギュレータの構築には,以下のツールが必要である.
+
+ ホストシステム用のツール(セルフ開発環境)
+ C++コンパイラ,C++ライブラリ
+ 動作確認(Mac OS X環境):GNU C++ 4.2.1
+ Boost 動作確認:1.42.0
+ GNU Make 動作確認:3.81
+
+最初に,パッケージにコンフィギュレータのソースファイルが含まれていない
+場合には,コンフィギュレータのパッケージを,ASPカーネルのソースファイル
+を展開したディレクトリの下に展開する.
+
+ % cd asp
+ % tar xvfz cfg-1.6.0.tar.gz
+
+または,コンフィギュレータのパッケージを他のディレクトリに展開し,ASPカー
+ネルのソースファイルを展開したディレクトリからシンボリックリンクをはっ
+てもよい.
+
+ソースファイルが展開できると,cfgディレクトリに移動し,コンフィギュレー
+ションスクリプト(configure)でMakefileの環境依存部(Makefile.config)
+を生成した後,makeコマンドによりコンフィギュレータ(cfgプログラム)が構
+築できる.
+
+ % cd cfg
+ % ./configure
+ % make
+
+ただし,Boostをインストールしたディレクトリおよび名称が標準で想定してい
+るものとは違う場合には,configureの--with-headersおよび--with-libraries
+オプションにより,ヘッダファイルおよびライブラリの置かれたディレクトリ
+を指定する必要がある.
+
+また,ホストシステムによっては,最適化レベルを上げると正しくコンパイル
+できないことが知られている.そのような場合には,最適化レベルを下げるか,
+最適化を抑止するように,Makefileを修正する必要がある.
+
+なお,コンフィギュレータの使用方法については,「7.コンフィギュレータ
+の使い方」の章で説明する.
+
+3.3 サンプルプログラムの構築と実行
+
+次に,ASPカーネル上で動作するサンプルプログラムを構築する方法を説明する.
+
+まず,サンプルプログラムのオブジェクトファイルを置くディレクトリを作成
+し,コンフィギュレーションスクリプトを実行する.例えば,オブジェクトファ
+イルを置くディレクトリを,ASPカーネルのソースファイルを展開したディレ
+クトリの下のOBJという名称のディレクトリにする場合には,次のコマンドを
+実行する(ディレクトリの場所と名称は任意に決めてよい).
+
+ % cd asp
+ % mkdir OBJ
+ % cd OBJ
+ % perl ../configure -T <ターゲット略称>
+
+ここで,<ターゲット略称>は,targetディレクトリの下に置かれているターゲッ
+ト依存部ディレクトリの名称である.コンフィギュレーションスクリプトのオ
+プションについては,「5.コンフィギュレーションスクリプトの使い方」の
+章で説明する.
+
+コンフィギュレーションスクリプトの実行により,カレントディレクトリには,
+サンプルプログラムを構築するためのMakefile,サンプルプログラム用のコン
+フィギュレーションファイル(sample1.cfg),サンプルプログラム本体
+(sample1.hおよびsample1.c)が生成される.
+
+コンフィギュレーションスクリプトの実行後,必要であればMakefileを修正す
+る.Makefileの修正方法については,「6.Makefileの修正方法」の章で説明
+する.
+
+その後,make dependで依存関係ファイル(Makefile.depend)を生成した後,
+makeコマンドによりサンプルプログラムのロードモジュール(aspまたは
+asp.exe)が生成できる.依存関係ファイルの生成には若干時間がかかる.
+
+ % make depend
+ % make
+
+ここで構築したサンプルプログラム(sample1.h,sample1.c,sample1.cfg)
+は,ASPカーネルの基本的な動作を確認するためのものである.このプログラ
+ムの概要説明は,sample1.cの先頭のコメントにある.
+
+3.4 カーネルを関数単位でライブラリ化する方法
+
+前節の手順では,カーネルをファイル単位でコンパイルし,ライブラリ化して
+いたが,カーネルのコードサイズを縮小するためには,使用しないサービスコー
+ルはリンクしない方が望ましい.そこでASPカーネルでは,カーネルを関数単位
+でコンパイルし,ライブラリ化する方法を用意している.
+
+この方法でサンプルプログラムを構築するには,コンフィギュレーションスク
+リプトに,それを指示するオプション(-f)を付加するだけでよい.
+
+ % mkdir OBJ_LIB
+ % cd OBJ_LIB
+ % perl ../configure -T <ターゲット略称> -f
+
+ここで,OBJ_LIBというディレクトリの場所と名称は,任意に決めてよい.これ
+以降の手順は,前節と同じである.
+
+3.5 アプリケーションとカーネルを別々に構築する方法
+
+前節で説明した方法では,アプリケーションとカーネルを同時に生成するため,
+オブジェクトファイルを置くディレクトリに非常に多くのファイルが作成され
+て,扱いにくくなる.そこで,カーネルを修正する頻度が低い場合には,カー
+ネルは事前に構築しておき,後でアプリケーションだけを構築する方法を用意
+している.以下では,サンプルプログラムを構築を例に,その手順について説
+明する.
+
+まず,カーネルを構築するディレクトリを作成し,コンフィギュレーションス
+クリプトを実行する.例えば,カーネルを構築するディレクトリを,ASPカー
+ネルのソースファイルを展開したディレクトリの下のKERNEL_LIBという名称の
+ディレクトリにする場合には,次のコマンドを実行する(ディレクトリの場所
+と名称は任意に決めてよい).
+
+ % mkdir KERNEL_LIB
+ % cd KERNEL_LIB
+ % perl ../configure -T <ターゲット略称> -f
+
+これにより,カーネルを構築するディレクトリに,Makefile,sample1.cfg,
+sample1.h,sample1.cが生成されるが,Makefile以外は実質的には使用しない.
+
+make dependで依存関係ファイル(Makefile.depend)を生成した後,make
+libkernel.aによりカーネルライブラリ(libkernel.a)が生成できる.
+
+ % make depend
+ % make libkernel.a
+
+次に,アプリケーションを構築するディレクトリを作成し,コンフィギュレー
+ションスクリプトを実行する.例えば,アプリケーションを構築するディレク
+トリを,ASPカーネルのソースファイルを展開したディレクトリの下のAPLとい
+う名称のディレクトリにする場合には,次のコマンドを実行する(ディレクト
+リの場所と名称は任意に決めてよい).
+
+ % cd ..
+ % mkdir APL
+ % cd APL
+ % perl ../configure -T <ターゲット略称> -L ../KERNEL_LIB
+
+ここで-Lオプションには,カーネルを構築したディレクトリのパスを指定する.
+
+最後に,make dependで依存関係ファイル(Makefile.depend)を生成した後,
+makeコマンドによりサンプルプログラムのロードモジュール(aspまたは
+asp.exe)が生成できる.
+
+ % make depend
+ % make
+
+この手順では,アプリケーション構築時にはカーネルの再構築が必要かチェッ
+クしないため,カーネルのソースコードを修正した場合には,カーネルを構築
+したディレクトリでmake libkernel.aを再実行する必要がある.
+
+以上では,カーネルとアプリケーションを別々のディレクトリで構築したが,
+-Lオプションにカレントディレクトリ(ただし,"."という記述では不可)を指
+定することで,カーネルとアプリケーションを同じディレクトリで別々に構築
+することもできる.具体的には,次の手順となる.
+
+ % mkdir OBJ
+ % cd OBJ
+ % perl ../configure -T <ターゲット略称> -L ../OBJ
+ % make depend
+ % make libkernel.a
+ % make cleankernel
+ % make
+
+ここで,make cleankernelは,カーネルライブラリを生成するための中間ファ
+イルを削除するものである.この手順では,make dependによりカーネルライ
+ブラリに関する依存関係を生成しないため,カーネルのソースコードを修正し
+た場合には,必ずmake cleankernel(または,make clean)してから,make
+libkernel.aする必要があるので注意すること.
+
+なお,make realcleanすると,make dependとmakeにより生成したファイルをす
+べて削除する.それに対して,make cleanでは,make dependにより生成した依
+存関係ファイルは削除しない.
+
+
+4.ディレクトリ構成・ファイル構成
+
+4.1 配布パッケージのディレクトリ構成
+
+ include/ アプリケーション向けヘッダファイル
+ kernel/ カーネルソースファイル
+ syssvc/ システムサービスヘッダファイル,ソースファイル
+ library/ サポートライブラリソースファイル
+ target/ ターゲット依存部
+ arch/ ターゲット依存部の共通部分
+ gcc/ GCC開発環境依存部
+ logtrace/ トレースログ記録のサンプルコード
+ pdic/ PDIC(デバイスドライバのOS非依存部分)
+ utils/ ユーティリティプログラム
+ sample/ サンプルプログラムとMakefile
+ doc/ ドキュメント
+ test/ テストプログラム
+ extension/ 拡張パッケージ
+
+4.2 ターゲット非依存部のファイル構成
+
+ターゲット非依存部(テストプログラムと拡張パッケージは除く)の各ファイ
+ルの概要は次の通り.
+
+ README.txt TOPPERS/ASPカーネルの簡単な紹介
+ configure コンフィギュレーションスクリプト(GNU開発環境用)
+ MANIFEST 個別パッケージのファイルリスト
+
+ include/
+ kernel.h ASPカーネルを使用するための定義
+ sil.h システムインタフェースレイヤを使用するための定義
+ t_stddef.h TOPPERS共通ヘッダファイル
+ itron.h ITRON仕様共通規定のデータ型・定数・マクロ
+ t_syslog.h システムログ出力を行うための定義
+ t_stdlib.h 基本的なライブラリ関数を使用するための定義
+ queue.h キュー操作ライブラリを使用するための定義
+ test_lib.h テストプログラム用ライブラリを使用するための定義
+ histogram.h 実行時間分布集計モジュールを使用するための定義
+ log_output.h システムログのフォーマット出力を使用するための定義
+
+ kernel/
+ Makefile.kernel カーネルのファイル構成の定義
+ kernel_impl.h カーネル実装用標準ヘッダファイル
+ kernel_int.h kernel_cfg.c用のヘッダファイル
+ kernel_rename.def カーネルの内部識別名のリネーム定義
+ kernel_rename.h カーネルの内部識別名のリネーム
+ kernel_unrename.h カーネルの内部識別名のリネーム解除
+ kernel_api.csv コンフィギュレータの静的APIテーブル
+ kernel_def.csv コンフィギュレータの値取得シンボルテーブル
+ kernel.tf コンフィギュレータのパス2のテンプレートファイル
+ kernel_check.tf コンフィギュレータのパス3のテンプレートファイル
+ allfunc.h すべての関数をコンパイルするための定義
+ check.h エラーチェック用マクロ
+ startup.c カーネルの初期化と終了処理
+ task.h タスク操作ルーチン関連の定義
+ task.c タスク操作ルーチン
+ wait.h 待ち状態操作ルーチン関連の定義
+ wait.c 待ち状態操作ルーチン
+ time_event.h タイムイベント管理関連の定義
+ time_event.c タイムイベント管理
+ task_manage.c タスク管理機能
+ task_refer.c タスク状態参照機能
+ task_sync.c タスク付属同期機能
+ task_except.c タスク例外処理機能
+ semaphore.h セマフォ機能関連の定義
+ semaphore.c セマフォ機能
+ eventflag.h イベントフラグ機能関連の定義
+ eventflag.c イベントフラグ機能
+ dataqueue.h データキュー機能関連の定義
+ dataqueue.c データキュー機能
+ pridataq.h 優先度データキュー機能関連の定義
+ pridataq.c 優先度データキュー機能
+ mailbox.h メールボックス機能関連の定義
+ mailbox.c メールボックス機能
+ mempfix.h 固定長メモリプール機能関連の定義
+ mempfix.c 固定長メモリプール機能
+ time_manage.c システム時刻管理機能
+ cyclic.h 周期ハンドラ機能関連の定義
+ cyclic.c 周期ハンドラ機能
+ alarm.h アラームハンドラ機能関連の定義
+ alarm.c アラームハンドラ機能
+ sys_manage.c システム状態管理機能
+ interrupt.h 割込み管理機能関連の定義
+ interrupt.c 割込み管理機能
+ exception.h CPU例外管理機能関連の定義
+ exception.c CPU例外管理機能
+
+ syssvc/
+ banner.h カーネル起動メッセージの出力のための定義
+ banner.c カーネル起動メッセージの出力
+ banner.cfg カーネル起動メッセージの出力のコンフィギュレー
+ ションファイル
+ logtask.h システムログタスクを使用するための定義
+ logtask.c システムログタスク
+ logtask.cfg システムログタスクのコンフィギュレーションファイル
+ serial.h シリアルインタフェースドライバを使用するための定義
+ serial.c シリアルインタフェースドライバ
+ serial.cfg シリアルドライバのコンフィギュレーションファイル
+ syslog.h システムログ機能を使用するための定義
+ syslog.c システムログ機能
+ syslog.cfg システムログ機能のコンフィギュレーションファイル
+ vasyslog.c 可変数引数のシステムログライブラリ
+
+ library/
+ histogram.c 実行時間分布集計モジュール
+ log_output.c システムログのフォーマット出力
+ strerror.c エラーメッセージ文字列を返す関数
+ t_perror.c エラーメッセージの出力
+ test_lib.c テストプログラム用ライブラリ
+
+ arch/gcc/
+ MANIFEST 個別パッケージのファイルリスト
+ tool_stddef.h t_stddef.hの開発環境依存部(GCC用)
+
+ arch/logtrace/
+ MANIFEST 個別パッケージのファイルリスト
+ trace_config.h トレースログに関する設定
+ trace_config.c トレースログ機能
+ trace_dump.c トレースログのダンプ
+
+ utils/
+ applyrename ファイルにリネームを適用
+ genoffset offset.hの生成(GNU開発環境用)
+ genrename リネームヘッダファイルの生成
+ gentest テストプログラムの生成
+ makedep 依存関係リストの生成(GNU開発環境用)
+ makerelease リリースパッケージの生成
+
+ sample/
+ Makefile サンプルのMakefile(GNU開発環境用)
+ sample1.h サンプルプログラム(1)に関する定義
+ sample1.c サンプルプログラム(1)
+ sample1.cfg サンプルプログラム(1)のコンフィギュレーションファイル
+
+ doc/
+ user.txt ユーザーズマニュアル
+ asp_spec.txt TOPPERS/ASPカーネルの仕様概要
+ extension.txt 機能拡張・チューニングガイド
+ porting.txt ターゲット依存部 ポーティングガイド
+ configurator.txt コンフィギュレータ仕様
+ design.txt 設計メモ
+ version.txt 変更履歴
+
+
+5.コンフィギュレーションスクリプトの使い方
+
+コンフィギュレーションスクリプト(configure)は,ASPカーネルおよびアプ
+リケーションプログラムを構築するために必要な基本的なコンフィギュレーショ
+ンを行うためのプログラムである.
+
+ASPカーネルを用いてアプリケーションを作成する場合には,まずオブジェクト
+ファイルを置くディレクトリを作成し,そのディレクトリでコンフィギュレー
+ションスクリプトを実行する.オブジェクトファイルを置くディレクトリの場
+所と名称は,任意に決めてよい.
+
+コンフィギュレーションスクリプトに対するオプションは次の通り.
+
+ -T <ターゲット略称>
+ ターゲットシステムの名称を,targetディレクトリの下に置かれてい
+ るターゲット依存部ディレクトリの名称で指定する(必須).
+
+ -A <アプリケーションプログラム名>
+ アプリケーションプログラムの名称を指定する.省略した場合には,
+ サンプルプログラム(sample1)となる.
+
+ -a <アプリケーションのディレクトリ名>
+ アプリケーションプログラムのソースファイル(システムコンフィギュ
+ レーションファイルを除く)を置いたディレクトリ名を指定する.省
+ 略した場合には,オブジェクトファイルを置くディレクトリに置かれ
+ ていることを仮定する.システムコンフィギュレーションファイルは,
+ オブジェクトファイルを置くディレクトリに置くこと.
+
+ -U <オブジェクトファイル名>
+ アプリケーションプログラムのメインのオブジェクトファイル(-A
+ で指定したアプリケーションプログラム名に".o"を付加したもの)以
+ 外に,リンクすべきオブジェクトファイルの名称を,".o"を付加した
+ 形で指定する.""で囲むことによって,複数のファイルを指定するこ
+ とも可能である(-Uオプションを複数使ってはならない).
+
+ -L <カーネルライブラリのディレクトリ名>
+ 事前に構築したカーネルライブラリ(libkernel.a)を用いて,アプリ
+ ケーションのみを構築する場合には,このオプションにカーネルライ
+ ブラリの置かれたディレクトリ名を指定する.このオプションの使用
+ 例については,「3.5 アプリケーションとカーネルを別々に構築する
+ 方法」の節を参照すること.
+
+ -f
+ カーネルを関数単位でコンパイルしライブラリ化する場合に,このオ
+ プションを指定する.このオプションの使用例については,「3.4 カー
+ ネルを関数単位でライブラリ化する方法」の節を参照すること.
+
+ -D <ASPカーネルのソースディレクトリ名>
+ ASPカーネルのソースファイルを置いたディレクトリ名を指定する.省
+ 略した場合には,configureの置かれているディレクトリとなる.
+
+ -l <プログラミング言語>
+ アプリケーションプログラムのプログラミング言語を指定する.現時
+ 点では,cとc++のみをサポートしている.
+
+ -t <テンプレートディレクトリ名>
+ Makefileやサンプルプログラムのテンプレートの置かれたディレクト
+ リ名を指定する.省略した場合には,ASPカーネルのソースファイルを
+ 置いたディレクトリの下のsampleディレクトリとなる.
+
+ -m <テンプレートMakefile名>
+ Makefileのテンプレートとするファイル名を指定する.省略した場合
+ には,Makefileとなる.
+
+ -d <実行環境名>
+ ターゲットシステム上でのプログラムの実行環境(ないしは,デバッ
+ グ環境)の名称を指定する.このオプションを指定すると,実行環境
+ を指定するシンボル(TOPPERS_<デバッグ環境名>)がマクロ定義され
+ る.省略した場合には,実行環境を指定するシンボルはマクロ定義さ
+ れない.
+
+ -r
+ トレースログ記録のサンプルコードを有効にする場合に,このオプショ
+ ンを指定する.このオプションの使用例については,「11.5 トレース
+ ログ記録のサンプルコードの使用方法」の節を参照すること.
+
+ -p <perlのパス名>
+ perlのパス名を指定する.省略した場合には,/usr/local/binと
+ /usr/binを探索し,perlのパス名を決定する.
+
+ -g <コンフィギュレータのパス名>
+ コンフィギュレータ(cfg)のパス名を指定する.省略した場合には,
+ デフォルトのパス名(ASPカーネルのソースディレクトリの下の
+ cfg/cfg/cfg)となる.
+
+コンフィギュレーションスクリプトが行う処理は次の通りである.
+
+(1) Makefileの生成
+
+テンプレートディレクトリ(デフォルトでは,sample)から適切なMakefileを
+選択し,必要な箇所を書き換えて,Makefileを生成する.
+
+(2) サンプルプログラムの生成
+
+指定したアプリケーションプログラムがテンプレートディレクトリにある場合,
+適切なアプリケーションプログラムのソースファイルを選択し,必要な箇所を
+書き換えて,アプリケーションプログラムのソースファイル(例えば,
+sample1.h,sample1.c,sample1.cfg)を生成する.
+
+(3) コンフィギュレータが用意できているかのチェック
+
+コンフィギュレータ(cfg)の実行ファイルがあるかチェックし,ファイルがな
+い場合には,その旨を出力する.
+
+
+6.Makefileの修正方法
+
+前の章で説明したように,コンフィギュレーションスクリプトに与えるオプショ
+ン等からMakefileが生成されるが,コンフィギュレーションスクリプトで対応
+できない場合には,Makefileを直接修正する必要がある.ここでは,Makefile
+の中で,修正が必要となる可能性の高い箇所について説明する.
+
+なお,Makefileを修正した後にコンフィギュレーションスクリプトを再実行す
+ると,修正したMakefileが上書きされてしまうので注意すること(古いものが
+Makefile.bakに保存される).
+
+6.1 Makefileの変数定義
+
+(A) ターゲット略称
+
+TARGETには,ターゲットシステムの名称を,targetディレクトリの下に置かれ
+ているターゲット依存部ディレクトリの名称で指定する.この定義は,通常は,
+コンフィギュレーションスクリプトに対する-Tオプションにより行う.
+
+(B) オブジェクトファイルの拡張子
+
+Cygwin環境でコンパイルする時には,OBJEXTを"exe"に定義する必要がある.こ
+れは,Cygwin環境では,ロードモジュールのファイル名に拡張子".exe"が付加
+されるのに対応するためのものである.Cygwin環境であることを判定できれば,
+コンフィギュレーションスクリプトがこの定義を行う.
+
+(C) 実行環境(ターゲット依存)
+
+ターゲットによっては,実行環境に対応してターゲット依存部のコードを差し
+換える場合がある.これを可能にするために,実行環境の名称をDBGENVに定義
+している.この定義は,通常は,コンフィギュレーションスクリプトに対す
+る-Dオプションにより行う.どのターゲットがどの実行環境に対応しているか
+は,ターゲット依存部のユーザーズマニュアルを参照すること.
+
+(D) カーネルライブラリのディレクトリ名
+
+KERNEL_LIBには,カーネルライブラリの置かれたディレクトリ名を定義する.
+この定義は,通常は,コンフィギュレーションスクリプトに対する-Lオプショ
+ンにより行う.
+
+(E) カーネルを関数単位でコンパイルするかどうか
+
+KERNEL_FUNCOBJSは,カーネルを関数単位でコンパイルする場合にはtrueに定義
+し,ファイル単位でコンパイルする場合には未定義とする.この定義は,通常
+は,コンフィギュレーションスクリプトに対する-fオプションにより行う.
+
+(F) 共通コンパイルオプション
+
+すべてのプログラムに共通するコンパイルオプションの追加が必要な場合には,
+下の変数の定義を変更する.そのコンパイルオプションが,特定のターゲット
+で常に必要な場合には,ターゲット依存の定義を入れたMakefile.target等を修
+正すべきである.
+
+ CDEFS コンパイラに対する-Dオプションを記述する.
+ INCLUDES コンパイラに対する-Iオプションを記述する.
+ COPTS コンパイラに対するその他のオプションを記述する.
+ LDFLAGS リンカに対するオプションを記述する.
+ LIBS ライブラリリンクのためのオプションを記述する.
+
+追加の可能性のあるコンパイルオプションについては,「6.2 コンパイルオプ
+ション」の節を参照のこと.
+
+(G) アプリケーションプログラム名
+
+APPLNAMEには,アプリケーションプログラム名を定義する.システムコンフィ
+ギュレーションファイル名は,APPLNAMEに定義した名前に拡張子".cfg"を付加
+した名前とする.また,アプリケーションのメインファイルは,APPLNAMEに定
+義した名前に拡張子".c"を付加した名前とする.この定義は,通常は,コンフィ
+ギュレーションスクリプトに対する-Aオプションにより行う.
+
+(H) アプリケーションのディレクトリ名
+
+アプリケーションのソースファイルを,オブジェクトファイルを置くのとは別
+のディレクトリに置く場合には,APPLDIRにそのディレクトリ名を定義する.こ
+の定義は,通常は,コンフィギュレーションスクリプトに対する-aオプション
+により行う.アプリケーションのソースファイルを置くディレクトリが複数あ
+る場合には,APPL_DIRの定義を変更することで対応する.
+
+(I) アプリケーションのプログラムファイル名
+
+アプリケーションが複数のソースファイルで構成される場合には,そのオブジェ
+クトファイル名を,APPL_ASMOBJS,APPL_COBJS,APPL_CXXOBJSに列挙する.
+
+(J) アプリケーションのコンパイルオプション
+
+アプリケーションのコンパイルに必要なコンパイルオプションや,アプリケー
+ションがライブラリを必要とする場合には,APPL_CFLAGSおよびAPPL_LIBSに定
+義する.
+
+(K) ロードモジュールのファイル名
+
+標準のロードモジュールのファイル名をOBJNAMEに定義する.デフォルトはasp
+である.
+
+(L) ターゲットファイルの定義
+
+ターゲット"all"の依存ファイルとして,ロードモジュールの形式を指定する.
+具体的には,ELF形式の時は$(OBJFILE),バイナリ形式の時は$(OBJNAME).bin,
+モトローラ S形式の時は$(OBJNAME).srecを指定する.$(OBJFILE)は,Cygwin
+環境でOBJEXTを"exe"に定義した時には$(OBJNAME).exe,そうでない場合には
+$(OBJNAME)となる.
+
+(M) makedepのオプションの定義
+
+Cygwin環境でルートディレクトリが"cygdrive"でない場合には,makedepの-Rオ
+プションでルートディレクトリ名を与える必要がある.makedepのオプションは,
+次の例のように,MAKEDEP_OPTSに定義する.
+
+MAKEDEP_OPTS = -R cygdrive
+
+6.2 コンパイルオプション
+
+ASPカーネルのコード中には,assertマクロが使われている.assertマクロは,
+NDEBUGを定義することで,オブジェクトコード中から消すことができる.カー
+ネルのデバッグが終了すれば,-DNDEBUGを指定してコンパイルした方が効率が
+よくなる.
+
+ターゲット依存部において,コンパイルオプションに-Werror(警告をエラー扱
+いする)を指定している場合がある.そのようなターゲットにおいて,アプリ
+ケーションで警告が避けられない場合には,ターゲット依存部を修正してコン
+パイルオプションを削除する必要がある.
+
+また,TOPPERS_OMIT_SYSLOGを定義してコンパイルすることで,システムログ出
+力を抑止することができる.
+
+
+7.コンフィギュレータの使い方
+
+コンフィギュレータ(cfg)は,TOPPERS新世代カーネル統合仕様書の2.12.5節
+の記述の通り,3つのパスで構成される.
+
+コンフィギュレータは,システムコンフィギュレーションファイル名をパラメー
+タに取り,以下のオプションを持つ(重要なもののみ).
+
+ --help
+ オプションのリストと説明を表示する.
+
+ -v[--version]
+ コンフィギュレータのバージョンを表示する.
+
+ -k[--kernel]<カーネル名>
+ カーネルの名称を指定する.デフォルトはasp.
+
+ -p[--pass]<パス番号>
+ パス番号を指定する.1〜3のいずれか.
+
+ -I[--include-path]<インクルードパス名>
+ INCLUDEディレクティブにおいて,インクルードするコンフィギュレー
+ ションファイルを探すパス名を指定する.
+
+ -T[--template-file]<テンプレートファイル名>
+ テンプレートファイルの名称を指定する.パス2とパス3で有効.
+
+ --api-table <静的APIテーブルファイル名>
+ 静的APIテーブルのファイル名を指定する.
+
+ --cfg1-def-table <値取得シンボルテーブルファイル名>
+ 値取得シンボルテーブルのファイル名を指定する.
+
+ -r[--rom-image]<ロードモジュール名>
+ ロードモジュールをSレコードフォーマットの形に変換したファイルの
+ 名称を指定する.パス3でのみ有効.
+
+ -s [--symbol-table] <シンボルファイル名>
+ ロードモジュール中の各シンボルとアドレスの対応表を含むシンボル
+ ファイルの名称を指定する.パス3でのみ有効.
+
+ --id-output-file <ID番号出力ファイル名>
+ オブジェクトのID番号の割付け結果を,指定した名前のファイルに書
+ き出す.パス2でのみ有効.
+
+ --id-input-file <ID番号入力ファイル名>
+ オブジェクトのID番号の割付けを,指定した名前のファイルから取り
+ 込む.パス2でのみ有効.
+
+ --external-id
+ オブジェクトのID番号を保持する変数の定義を生成する.パス2でのみ
+ 有効.
+
+ -M[--print-dependencies]<ターゲットシンボル>
+ システムコンフィギュレーションファイルの依存関係を出力する.
+ Makefile中の依存関係を生成する際に用いる.
+
+コンフィギュレータの詳細仕様については,別途PDFファイルの形で配布してい
+る「TOPPERS新世代カーネル用コンフィギュレータ仕様」を参照すること.
+
+
+8.システムサービス
+
+8.1 システムログ機能
+
+システムログ機能は,カーネル内で発生した異常事象やカーネルのトレースロ
+グ,システムサービスやアプリケーションで発生した異常事象やトレースログ
+を,ログ情報として記録するための機能である.また,記録したログ情報を取
+り出す機能も持つ.
+
+システムログ機能は,システムコンフィギュレーションファイルでsyslog.cfg
+をインクルードすることで,システムに組み込むことができる.システムログ
+出力を行うソースファイルでは,t_syslog.hをインクルードする.また,シス
+テムログ機能のその他のサービスコールを呼び出すソースファイルでは,
+syslog.hをインクルードする.
+
+8.1.1 システムログ機能の位置付け
+
+システムログ機能は,カーネル内からも呼び出すことができるため,カーネル
+より下の階層のモジュールと位置付けることができる.この意味では,他のシ
+ステムサービスとは位置付けが異なる.
+
+一方,ログ情報をシステム外部に出力するためには,シリアルインタフェース
+ドライバなど,カーネル上で動作するシステムサービスを用いる必要がある.
+そこで,ログ情報をシステム外部に出力するためのサービス(これを,システ
+ムログタスクと呼ぶ)は,システムログ機能とは分離して実装することとし,
+システムログ機能はログ情報の記録・取出しのための機能に絞っている.
+
+以上のように,システムログ機能はカーネルより下の階層のモジュールである
+が,システムログ機能の中でログ時刻を取り出すために,カーネルの機能を必
+要とする.実装上は,カーネルの内部変数を直接参照している.そのため,カー
+ネルの実行開始前や終了後は,ログ時刻は正しく記録されない.
+
+8.1.2 ログバッファへの記録と低レベル出力
+
+上述したように,ログ情報をシステムの外部に出力するためには,カーネル上
+で動作するシステムサービスを用いる必要があるため,カーネルの動作を継続
+できないような重大な異常事象が起こった場合には,ログ情報を出力できなく
+なる.また,これらのシステムサービス自身をデバッグする場合にも,ログ情
+報の出力ができない.
+
+そこで,カーネル上で動作するシステムサービスが使えない場合にでもログ情
+報を出力するために,低レベル出力機能を用意する.低レベル出力機能は,ター
+ゲット依存に用意する低レベルの文字出力関数(target_fput_log)を用いてロ
+グ情報を出力する機能である.低レベルの文字出力関数は,ターゲット依存部
+で用意することとしているが,最終製品に組み込まれる場合などでは,文字を
+出力する方法がない状況も考えられる.そのような場合,低レベルの文字出力
+関数に送られた文字は,メモリ上に残しておくか,捨ててしまうしかない.
+
+ログ情報を,ログバッファへ記録するか低レベル出力機能を用いて出力するか
+の設定は,システムログ機能のサービスコール(syslog_msk_log)によって行
+うことができる.syslog_msk_logの使い方については後述する.デフォルトで
+は(システムログタスクを動作させず,syslog_msk_logも呼び出さない場合),
+すべてのログ情報を低レベル出力機能を用いて出力し,ログバッファには記録
+しない.
+
+低レベル出力機能を用いると,ログメッセージの作成処理(printf相当の処理)
+と低レベルの文字出力処理をカーネル内で行うために,カーネルの応答性が悪
+くなることに注意しなければならない.特に,低レベルの文字出力処理はデバ
+イスをポーリングする形で実装するのが通常で,その場合には,カーネルの応
+答性は実用的と言えない程に悪くなる.
+
+8.1.3 ログ情報の種別
+
+システムログ機能は,ログ情報に以下の種別を設けている.
+
+ LOG_TYPE_COMMENT コメント
+ LOG_TYPE_ASSERT アサーションの失敗
+ LOG_TYPE_INH 割込みハンドラ
+ LOG_TYPE_ISR 割込みサービスルーチン
+ LOG_TYPE_CYC 周期ハンドラ
+ LOG_TYPE_ALM アラームハンドラ
+ LOG_TYPE_OVR オーバランハンドラ
+ LOG_TYPE_EXC CPU例外ハンドラ
+ LOG_TYPE_TEX タスク例外処理ルーチン
+ LOG_TYPE_TSKSTAT タスク状態変化
+ LOG_TYPE_DSP ディスパッチャ
+ LOG_TYPE_SVC サービスコール
+
+ログ情報の種別の中で,LOG_TYPE_COMMENTとLOG_TYPE_ASSERT以外は,カーネル
+のトレースログに用いるためのものであるが,使用するかどうかはターゲット
+依存部に任されている.
+
+8.1.4 ログ情報の重要度
+
+システムログ機能は,ログ情報を出力する際に指定する重要度に基づいて,実
+際に出力するログ情報を動的に設定することができる.これは,UNIXのシステ
+ムログ機能をまねたもので,ログの重要度の種類や指定方法もUNIXのAPIを参考
+にしている.また,低レベル出力機能を用いて出力するログ情報も,重要度に
+基づいて動的に設定することができる.
+
+具体的には,ログの重要度として次の8段階を用意している.
+
+ LOG_EMERG カーネルの動作を継続できないエラー
+ LOG_ALERT
+ LOG_CRIT
+ LOG_ERROR 重要性の低いシステムエラー
+ LOG_WARNING 警告メッセージ.システムは安全に継続動作できる
+ LOG_NOTICE
+ LOG_INFO
+ LOG_DEBUG デバッグのためのメッセージ
+
+どの重要度のログ情報をログバッファに記録するかと,どの重要度のログ情報
+を低レベル出力機能を用いて出力するかは,システムログ機能のサービスコー
+ル(syslog_msk_log)によって設定することができる.
+
+8.1.5 ログ情報のデータ構造
+
+ログ情報を格納するためのデータ型として,SYSLOG構造体を用意している.
+SYSLOG構造体には,ログ情報の種別(logtypeフィールド),ログ時刻
+(logtimフィールド),その他のログ情報(loginfoフィールド)が含まれる.
+
+SYSLOG構造体に格納されたログ情報を出力する場合には,ログ時刻は出力関数
+(syslog_wri_log)によって書き込まれるため,出力関数を呼ぶ側で書き込む
+必要はない.
+
+8.1.6 システムログ機能のサービスコール
+
+システムログ機能の提供するサービスコールは次の通りである.これらのサー
+ビスコールを呼び出すソースファイルでは,syslog.hをインクルードする必要
+がある.
+
+(1) ER syslog_wri_log(uint_t prio, const SYSLOG *p_syslog)
+
+システムログ機能に,p_syslogで指定されるログ情報を,prioで指定される重
+要度で出力する(ログバッファへ記録するか低レベル出力機能を用いて出力す
+る).
+
+プロトタイプ宣言において,*p_syslogにconst指定がされているが,実際には,
+この関数の中で,*p_syslogのlogtimフィールドにシステム時刻を書き込んでい
+る.
+
+(2) ER_UINT syslog_rea_log(SYSLOG *p_syslog)
+
+ログバッファからログ情報を1つ取り出す.ログバッファが空の時はE_OBJ,そ
+うでない場合は,ログバッファのオーバフローにより失われたログ情報の数
+(ログ情報が失われていない場合は0)を返す.システムログタスクが用いるこ
+とを想定している.
+
+(3) ER syslog_msk_log(uint_t logmask, uint_t lowmask)
+
+ログバッファに記録すべきログ情報の重要度の示すビットマップ(logmask)と,
+低レベル出力機能を用いて出力すべきログ情報の重要度を示すビットマップ
+(lowmask)を設定する.ビットマップを作るためのマクロとして,LOG_MASKと
+LOG_UPTOを用意している.
+
+(4) ER_UINT syslog_ref_log(T_SYSLOG_RLOG *pk_rlog)
+
+システムログ機能の状態を参照する.具体的には,ログバッファに記録されて
+いるログ情報の数(T_SYSLOG_RLOG構造体のcountフィールド),ログバッファ
+のオーバフローにより失われたログ情報の数(lostフィールド),ログバッファ
+に記録すべきログ情報の重要度の示すビットマップ(logmaskフィールド),低
+レベル出力機能を用いて出力すべきログ情報の重要度を示すビットマップ
+(lowmaskフィールド)を参照することができる.
+
+8.1.7 システムログ機能のためのライブラリ関数とマクロ
+
+システムログ出力のためのライブラリ関数とマクロは次の通りである.これら
+だけを呼び出すソースファイルでは,t_syslog.hをインクルードすればよい.
+
+(1) void _syslog_n(uint_t prio, uint_t type, intptr_t arg1, ..., intptr_t argn)
+ ※ nは0〜6のいずれか.
+
+ログ種別がtype,パラメータがarg1〜argnのログ情報を,重要度prioで出力す
+るための関数.
+
+(2) void syslog_n(uint_t prio, const char *format, arg1, ..., argn)
+ ※ nは0〜5のいずれか.
+
+format文字列およびそれに続く引数から作成されるメッセージを,ログ種別が
+LOG_TYPE_COMMENTのログ情報として,重要度prioで出力するためのマクロ.
+
+formatはメッセージのフォーマット記述,arg1〜argnはフォーマット記述中で
+参照される値で,printfのフォーマット記述のサブセットとなっている.arg1〜
+argnは,このマクロ中でintptr_t型にキャストされるため,intptr_t型に型変
+換できる任意の型を渡すことができ,型チェックはされない.formatおよび
+arg1〜argnには,次の制限がある.
+
+・formatのフォーマット記述は,定数文字列を渡すことを想定しており,この
+マクロ処理を終えた後も変化してはならない.
+
+・format中に使えるフォーマット指定は次の通り.
+
+ %d 引数をint_t型とみなし,10進数で表示
+ %u 引数をuint_t型とみなし,10進数で表示
+ %x 引数をuint_t型とみなし,16進数(英文字は小文字)で表示
+ %X 引数をuint_t型とみなし,16進数(英文字は大文字)で表示
+ %p 引数をポインタとみなし,16進数(英文字は小文字)で表示
+ %c 引数を文字コードとみなし,文字を表示
+ %s 引数を文字列を示すポインタとみなし,文字列を表示
+ %% '%'を表示(引数は取らない)
+
+%d, %u, %x, %Xにおいては,'%'の直後に表示桁数を指定する10進数値を記述す
+ることができる.その場合,表示すべき文字列が指定した桁数に満たない場合
+には,指定した桁数内に右詰めで表示する.10進数値が'0'で始まる場合には,
+その間に'0'を埋める.
+
+また,intptr_t型のサイズがlong型のサイズ以上である環境においては,次の
+フォーマット指定も使用することができる.この他のフォーマット指定に'l'
+を付加した場合には無視する(%lcと%lsには対応していない).
+
+ %ld 引数をlong_t型とみなし,10進数で表示
+ %lu 引数をulong_t型とみなし,10進数で表示
+ %lx 引数をulong_t型とみなし,16進数(英文字は小文字)で表示
+ %lX 引数をulong_t型とみなし,16進数(英文字は大文字)で表示
+
+・arg1〜argnにポインタを渡す場合(%sに対応する引数の場合)に,ポインタ
+の指すデータは,このマクロ処理を終えた後も変化してはならない.定数文字
+列を渡すことを想定している.
+
+(3) void syslog(uint_t prio, const char *format, ...)
+
+format文字列およびそれに続く引数から作成されるメッセージを,ログ種別が
+LOG_TYPE_COMMENTのログ情報として,重要度prioで出力するための関数で,引
+数の数を可変にしたもの.formatに続く引数は最大5個まで.formatおよびそれ
+に続く引数には,syslog_nと同様の制限がある.
+
+このライブラリ関数は,可変数引数を処理するために内部で文字列をスキャン
+する.そのため,実行時間が長くなる可能性があり,割込み禁止状態で呼び出
+すべきではない.主にアプリケーションプログラムが用いることを想定してい
+る.
+
+(4) UINT LOG_MASK(UINT prio)
+
+重要度prioのみセットされたビットマップを作るマクロ.syslog_msk_logに渡
+す引数を作るために用いる.
+
+(5) UINT LOG_UPTO(UINT prio)
+
+重要度prio以上の重要度がすべてセットされたビットマップを作るマクロ.
+syslog_msk_logに渡す引数を作るために用いる.
+
+8.1.8 システムログ機能のその他のサービス
+
+システムログ機能は,前記のサービスコール等に加えて,初期化処理のための
+関数を持つ.
+
+(1) void syslog_initialize(intptr_t exinf)
+
+システムログ機能を初期化する.ログバッファにログ情報が記録されている場
+合には,消去される.syslog.cfgによって,カーネルに初期化ルーチンとして
+登録される.exinfは無視される.
+
+8.2 シリアルインタフェースドライバ
+
+シリアルインタフェースドライバは,シリアルポートを扱うためのドライバで
+ある.
+
+シリアルインタフェースドライバは,システムコンフィギュレーションファイ
+ルでserial.cfgをインクルードすることで,システムに組み込むことができる.
+シリアルインタフェースドライバを呼び出すソースファイルでは,serial.hを
+インクルードする.
+
+シリアルインタフェースドライバは,ポート毎にセマフォを2個ずつ使用する.
+セマフォを生成する静的APIは,serial.cfgに含まれている.
+
+8.2.1 シリアルインタフェースドライバのサービスコール
+
+シリアルインタフェースドライバを呼び出すサービスコールの仕様は次の通り
+である.この中で,シリアルポートのID番号(portid)の解釈はターゲット依
+存となる.
+
+これらのサービスコールは,非タスクコンテキストから呼び出すことはできな
+い.また,serial_rea_datとserial_wri_datは,ディスパッチ保留状態で呼び
+出すことはできない.いずれも,呼び出した場合にはE_CTXエラーとなる.
+
+(1) ER serial_opn_por(ID portid)
+
+portidで指定されたシリアルポートをオープンし,受信/送信が可能な状態に
+する.
+
+(2) ER serial_cls_por(ID portid)
+
+portidで指定されたシリアルポートをクローズする.
+
+(3) ER_UINT serial_rea_dat(ID portid, char_t *buf, uint_t len)
+
+portidで指定されたシリアルポートから,lenバイトの文字列を受信し,bufか
+らの領域に入れる.lenバイト受信するまで,待ち状態となる.受信した文字数
+またはエラーコードを返す.
+
+(4) ER_UINT serial_wri_dat(ID portid, const char_t *buf, uint_t len)
+
+portidで指定されたシリアルポートに,bufからのlenバイトの文字列を送信す
+る.lenバイト送信バッファに入れるまで,待ち状態となる.送信した文字数ま
+たはエラーコードを返す.
+
+(5) ER serial_ctl_por(ID portid, uint_t ioctl)
+
+portidで指定されたシリアルポートの制御情報を,ioctlで示される値に設定す
+る.
+
+ioctlには,以下の制御情報を表す定数を,ビット毎に論理和をとったものを
+指定する.
+
+ IOCTL_ECHO(エコーバックモード)
+ このビットを設定すると,シリアルインタフェースドライバがエコー
+ バックを行う.具体的には,バッファから文字を取り出す度に,その
+ 文字を書き出す.
+
+ IOCTL_CRLF(改行モード)
+ LF(line feed)を書き出すと,CR(carriage return)+LFに変換し
+ て書き出す.
+
+ IOCTL_FCSND(送信フロー制御)
+ 文字を送信する処理に対して,XON/XOFFによるフロー制御を行う.
+ すなわち,STOP(コントロール-S)を受信すると送信を停止し,
+ START(コントロール-Q)を受信すると送信を再開する.
+
+ IOCTL_FCANY(送信フロー制御で任意の文字で送信再開)
+ IOCTL_FCSNDを指定している時に,送信停止中に受信した任意の文字
+ で送信を再開する.
+
+ IOCTL_FCRCV(受信フロー制御)
+ 文字を受信する処理に対して,XON/XOFFによるフロー制御を行う.
+ すなわち,受信バッファの残り領域が少なくなるとSTOP(コントロー
+ ル-S)を送出し,残り領域が増えればSTART(コントロール-Q)を送
+ 出する.
+
+なお,オープン直後のデフォルトの設定値は(IOCTL_ECHO | IOCTL_CRLF |
+IOCTL_FCSND | IOCTL_FCRCV)である.
+
+(6) ER serial_ref_por(ID portid, T_SERIAL_RPOR *pk_rpor)
+
+portidで指定されたシリアルポートの状態を参照し,pk_rporで指定されるパケッ
+トに返す.パケット中のreacntには受信バッファ中の文字数を,wricntには送
+信バッファ中の文字数を返す.
+
+8.2.2 シリアルインタフェースドライバのその他のサービス
+
+シリアルインタフェースドライバは,前記のサービスコールに加えて,初期化
+処理と未送信文字の取出し処理を持つ.初期化処理は,カーネルに初期化ルー
+チンとして登録する.また,ターゲット依存で,初期化処理,終了処理,割込
+みサービスルーチンを持つ.これらの登録処理はserial.cfgに含まれる.
+
+(1) void serial_initialize(intptr_t exinf)
+
+シリアルインタフェースドライバを初期化する.カーネルに初期化ルーチンと
+して登録する.exinfは無視する.
+
+(2) bool_t serial_get_chr(ID portid, char_t *p_c)
+
+portidで指定されたシリアルポートの送信バッファ中の文字を,p_cの指す番地
+に取り出し,trueを返す関数.文字がなかった時には,falseを返す.終了処理
+ルーチン中で呼び出すことを想定している.
+
+8.3 システムログタスク
+
+システムログタスクは,システムログ機能からログ情報を取り出し,それをシ
+ステムの外部に出力するためのサービスである.
+
+ASPカーネルのリリースパッケージに含まれるシステムログタスクは,シリアル
+ポートにログ情報を文字列の形で出力するもので,システムログタスクの一例
+という位置付けで提供している.
+
+このシステムログタスクは,システムコンフィギュレーションファイルで
+logtask.cfgをインクルードすることで,システムに組み込むことができる.シ
+ステムログタスクのサービスを呼び出すソースファイルでは,logtask.hをイン
+クルードする.
+
+システムログタスクが実行開始されると,重要度がLOG_EMERGのログ情報を低レ
+ベル出力機能を用いて出力し,重要度がLOG_NOTICEかそれより高いログ情報を
+ログバッファに記録するように,システムログ機能の設定が変更される.
+
+8.3.1 システムログタスクのサービスコール
+
+システムログタスクのサービスを呼び出すサービスコールの仕様は次の通りで
+ある.
+
+(1) ER logtask_flush(uint_t count)
+
+システムログ機能のログバッファ中のログ情報の数がcount以下になるまで待つ.
+countが0の場合には,シリアルインタフェースドライバの送信バッファが空に
+なるのも待つ.
+
+8.3.2 システムログタスクのその他のサービス
+
+システムログタスクは,前記のサービスコールに加えて,メイン処理と終了処
+理を持つ.メイン処理はタスクとして,終了処理は終了処理ルーチンとして登
+録する.これらの登録処理はlogtask.cfgに含まれる.
+
+(1) void logtask_main(intptr_t exinf)
+
+システムログタスクのメイン処理.exinfには,ログ情報を出力するシリアルポー
+トのID番号を渡す.
+
+(2) void logtask_terminate(intptr_t exinf)
+
+システムログタスクの終了処理.シリアルインタフェースドライバの送信バッ
+ファに蓄積されたデータと,ログバッファに記録されたログ情報を,低レベル
+出力機能を用いて出力する.出力すべきログ情報がある場合には,それを出力
+する前に,"-- buffered messages --"という文字列を出力する.exinfは無視
+する.
+
+この関数を終了処理ルーチンとして登録することで,カーネル終了時点で未出
+力のログ情報のほとんどを出力することができる.ただし,未出力のログ情報
+の内,システムログタスクのメイン処理が,ログバッファから取り出したが,
+まだシリアルインタフェースドライバに送信していない情報は,この関数では
+出力できない.
+
+8.4 カーネル起動メッセージの出力
+
+カーネル起動メッセージの出力は,カーネルの起動時に,カーネルの名称やバー
+ジョン番号,著作権表示などを出力するための機能である.
+
+カーネル起動メッセージの出力は,システムコンフィギュレーションファイル
+でbanner.cfgをインクルードすることで,システムに組み込むことができる.
+
+カーネル起動メッセージの出力は,次の関数で構成される.
+
+(1) void print_banner(intptr_t exinf)
+
+システムログ機能を用いて,カーネル起動メッセージを出力する.banner.cfg
+によって,カーネルに初期化ルーチンとして登録される.exinfは無視される.
+
+
+9.サポートライブラリ
+
+サポートライブラリは,アプリケーションやシステムサービスを作成するため
+に利用できるライブラリ関数群である.
+
+9.1 基本的なライブラリ関数
+
+基本的なライブラリ関数を用いる場合には,t_stdlib.hをインクルードし,必
+要に応じてstrerror.cとt_perror.cをコンパイル・リンクする.
+
+(1) const char *itron_strerror(ER ercd)
+
+ercdで示されるエラーコードに対応するメインエラーコードの文字列を返す.
+
+(2) void t_perror(uint_t prio, const char *file, int_t line,
+ const char *expr, ER ercd);
+
+サービスコールがエラーを返した場合に用いることを想定した関数で,ファイ
+ル名,行番号,メインエラーコード等を,重要度prioで,システムログ機能を
+用いて出力する.
+
+9.2 キュー操作ライブラリ関数
+
+キュー操作ライブラリは,キューヘッダを含むリング構造のダブルリンクキュー
+を扱うライブラリである.キューヘッダの次エントリはキューの先頭のエント
+リ,前エントリはキューの末尾のエントリとする.また,キューの先頭のエン
+トリの前エントリと,キューの末尾のエントリの次エントリは,キューヘッダ
+とする.空のキューは,次エントリ,前エントリとも自分自身を指すキューヘッ
+ダであらわす.
+
+キュー操作ライブラリ関数を用いる場合には,queue.hをインクルードする.
+
+キューヘッダとエントリのためのデータ構造として,QUEUE構造体を用いる.
+QUEUE構造体の定義は次の通り.
+
+ typedef struct queue {
+ struct queue *p_next; /* 次エントリへのポインタ */
+ struct queue *p_prev; /* 前エントリへのポインタ */
+ } QUEUE;
+
+キュー操作のために用意している関数は次の通り.
+
+(1) void queue_initialize(QUEUE *p_queue);
+
+キューを初期化する.p_queueにはキューヘッダを指定する.
+
+(2) void queue_insert_prev(QUEUE *p_queue, QUEUE *p_entry);
+
+p_queueで指定するエントリの前に,p_entryで指定するエントリを挿入する.
+p_queueにキューヘッダを指定した場合には,キューの末尾にp_entryで指定す
+るエントリを挿入することになる.
+
+(3) void queue_insert_next(QUEUE *p_queue, QUEUE *p_entry);
+
+p_queueで指定するエントリの次に,p_entryで指定するエントリを挿入する.
+p_queueにキューヘッダを指定した場合には,キューの先頭にp_entryで指定す
+るエントリを挿入することになる.
+
+(4) void queue_delete(QUEUE *p_entry);
+
+p_entryで指定するエントリを,キューから削除する.
+
+(5) QUEUE *queue_delete_next(QUEUE *p_queue);
+
+p_queueで指定するエントリの次のエントリをキューから削除し,削除したエン
+トリを返す.p_queueにキューヘッダを指定した場合には,キューの先頭のエン
+トリを取り出すことになる.p_queueに空のキューを指定して呼び出してはなら
+ない.
+
+(6) bool_t queue_empty(QUEUE *p_queue);
+
+キューが空の場合にはtrue,そうでない場合にはfalseを返す.p_queueには
+キューヘッダを指定する.
+
+9.3 システムログ出力用ライブラリ関数
+
+システムログ出力用ライブラリ関数は,ログ情報をフォーマット出力するため
+に,システムログタスクおよびシステムログ機能で用いるための関数群である.
+
+システムログ出力用ライブラリ関数を用いる場合には,log_output.hをインク
+ルードし,log_output.cをコンパイル・リンクする.
+
+(1) void syslog_printf(const char *format, const intptr_t *args,
+ void (*putc)(char_t))
+
+formatで指定されるフォーマット記述とp_argsで指定される引数列から作成し
+たメッセージを,1文字出力関数putcを用いて出力する.
+
+(2) void syslog_print(const SYSLOG *p_sys, void (*putc)(char_t))
+
+p_syslogで指定されるログ情報を文字列に直し,1文字出力関数putcを用いて出
+力する.
+
+(3) void syslog_lostmsg(uint_t lost, void (*putc)(char_t))
+
+lost個のログ情報が失われた旨のメッセージを,1文字出力関数putcを用いて出
+力する.
+
+9.4 実行時間分布集計モジュール
+
+実行時間分布集計モジュールは,システムのリアルタイム性能を評価するため
+に,プログラム区間の実行時間を計測し,その分布を集計・表示するためのラ
+イブラリ関数群である.
+
+実行時間分布集計モジュールを用いる場合には,histogram.hをインクルードし,
+histogram.cをコンパイル・リンクする.
+
+実行時間分布集計モジュールは,複数のプログラム区間の実行時間を計測・集
+計・表示することができる.プログラム区間毎に,実行時間分布を記録するた
+めのデータ構造を持つ.どのデータ構造を用いるかを,ID番号(histid)で指
+定する.使用できるデータ構造の数は,TNUM_HISTで定義される.すなわち,
+ID番号として,1〜TNUM_HISTを指定することができる.TNUM_HISTは,デフォル
+ト値がhistgram.cの中で定義されており,コンパイルオプションやターゲット
+依存部(target_test.hまたはそこからインクルードされるファイル)により変
+更することができる.
+
+ターゲット依存部で設定を変更していない場合,実行時間分布集計モジュール
+は,カーネルの性能評価用システム時刻を参照する機能(get_utm)を用いて実
+行時間を計測する.そのため,実行時間はマイクロ秒単位で記録される(精度
+はターゲット依存).また,記録される時間には,計測のためのオーバヘッド
+(get_utmの実行時間+α)が含まれる.
+
+ターゲット依存部で設定を変更している場合の仕様については,ターゲット依
+存部のユーザーズマニュアルを参照すること.
+
+(1) void init_hist(ID histid, uint_t maxval, uint_t *hist)
+
+histidで指定されたデータ構造を初期化する.maxvalには記録する最大時間を,
+histには記録領域の先頭番地を指定する.histで始まる記憶領域は,要素数が
+maxvalに指定した値+1のuint_t型の配列として確保する.例えば,maxvalに
+1000を指定する場合には,histには要素数が1001のuint_t型の配列の先頭番地
+を渡す.
+
+(2) void begin_measure(ID histid)
+
+実行時間を計測するプログラム区間の直前に呼び出す関数.histidで指定され
+たデータ構造に,現在のシステム時刻を記録する.
+
+(3) void end_measure(ID histid)
+
+実行時間を計測するプログラム区間の直後に呼び出す関数.現在のシステム時
+刻と,histidで指定されたデータ構造に記録された開始時刻から,プログラム
+区間の実行時間を求め,その結果を記録する.
+
+(4) void print_hist(ID histid)
+
+システムログ機能を用いて,実行時間分布の計測結果を出力する.
+
+
+10.テストプログラム
+
+テストプログラムは,カーネルの機能テストおよび性能評価を行うためのプロ
+グラム群である.
+
+10.1 テストプログラム用ライブラリ
+
+テストプログラム用ライブラリは,プログラム中のチェックポイントが正しい
+順序で実行されたことなど,プログラムが正しく動作していることをチェック
+するための関数群である.プログラムが正しく動作していないことを検出した
+場合には,プログラムを終了させる.
+
+このライブラリ中でプログラムを終了させる時には,その時点で未出力のログ
+情報等を出力しようとするが,一部の情報が抜ける場合がある.詳しくは,
+「8.3.2 システムログタスクのその他のサービス」の節の(2)を参照すること.
+
+テストプログラム用ライブラリ関数を用いる場合には,test_lib.hをインクルー
+ドし,test_lib.cをコンパイル・リンクする.
+
+(1) void check_point(uint_t count)
+
+チェックポイントを通過する際に呼び出す関数.countには,何番目のチェック
+ポイントであるかを指定する(最初のチェックポイントでは1を指定する).
+countの値が,最初のチェックポイントにおいては1でない場合に,それ以降の
+チェックポイントにおいては,前のチェックポイント通過時にcountに指定した
+値に1を加えた値でない場合に,プログラムが正しく動作していないと見なし,
+プログラムを終了させる.
+
+(2) void check_finish(uint_t count)
+
+最後のチェックポイントに到達した際に呼び出す関数.countには,何番目の
+チェックポイントであるかを指定する(最初のチェックポイントでは1を指定す
+る).countの値が,前のチェックポイント通過時にcountに指定した値に1を加
+えた値でない場合に,プログラムが正しく動作していないと見なす.この関数
+は,プログラムが正しく動作している/いないに関わらず,プログラムを終了
+させる.
+
+(3) void check_assert(bool_t exp)
+
+expが真であることをチェックしたい場合に呼び出す関数.expが偽である場合
+に,プログラムが正しく動作していないと見なし,プログラムを終了させる.
+
+(4) void check_ercd(ER ercd, ER expected_ercd)
+
+ercdがexpected_ercdに一致していることをチェックしたい場合に呼び出す関数.
+ercdがexpected_ercdに一致していない場合に,プログラムが正しく動作してい
+ないと見なし,プログラムを終了させる.
+
+(5) void check_state(bool_t ctx, bool_t loc, PRI ipm,
+ bool_t dsp, bool_t dpn, bool_t tex)
+
+タスクコンテキストにおいて,システム状態が期待したものになっているか
+チェックしたい時に呼び出す関数.ctx,loc,dsp,dpn,texにはそれぞれ
+sns_ctx(),sns_loc(),sns_dsp(),sns_dpn(),sns_tex()の返値として期待さ
+れる値を,ipmにはget_ipm()で参照できる割込み優先度マスクとして期待され
+る値を指定する.この内のいずれかが期待される値と一致していない場合に,
+プログラムが正しく動作していないと見なし,プログラムを終了させる.
+
+(6) void check_state_i(bool_t ctx, bool_t loc,
+ bool_t dsp, bool_t dpn, bool_t tex)
+
+非タスクコンテキストにおいて,システム状態が期待したものになっているか
+チェックしたい時に呼び出す関数.ctx,loc,dsp,dpn,texにはそれぞれ
+sns_ctx(),sns_loc(),sns_dsp(),sns_dpn(),sns_tex()の返値として期待さ
+れる値を指定する.この内のいずれかが期待される値と一致していない場合に,
+プログラムが正しく動作していないと見なし,プログラムを終了させる.
+
+(7) void set_bit_func(BIT_FUNC bit_func)
+
+チェックポイントにおいて呼び出す自己診断関数を設定するための関数.
+
+(8) void syslog_flush(void)
+
+システムログ機能に記録されたログ情報を,低レベル出力機能に用いる文字出
+力関数により出力する.
+
+(9) void test_finish(void)
+
+プログラムを終了させる関数.チェックポイントを使用しない場合に,この関
+数を用いる.
+
+10.2 カーネルの整合性検査
+
+チェックポイントにおいて呼び出す自己診断に使うためのプログラムとして,
+カーネルの整合性検査を用意している.カーネルの整合性検査は,カーネル内
+の各データ構造の一貫性を検査する(現時点では未完成).
+
+カーネルの整合性検査を用いる場合には,bit_kernel.cをコンパイル・リンク
+する.
+
+(1) ER bit_kernel(void)
+
+カーネル内の各データ構造の一貫性を検査し,一貫性が確認できた場合にE_OK,
+できなかった場合にE_SYSエラーを返す関数.E_SYSエラーを返す際のサブエラー
+コードとして,一貫性が確認できなかった項目を示すコードを返す.
+
+10.3 機能テストプログラム
+
+testディレクトリに置かれた"test"で始まるプログラムは,カーネルの機能テ
+ストを行うためのプログラムである.
+
+なお,機能テストプログラムを構築する場合には,MakefileのAPPL_COBJSに,
+test_lib.oを追加する必要がある.コンフィギュレーションスクリプト
+(configure)を使用する場合には,オプションに-U test_lib.oを指定すれば
+よい.
+
+現バージョンで用意している性能評価プログラムは次の通り.
+
+(1) test_cpuexc1 CPU例外処理のテスト(1)
+(2) test_cpuexc2 CPU例外処理のテスト(2)
+(3) test_cpuexc3 CPU例外処理のテスト(3)
+(4) test_cpuexc4 CPU例外処理のテスト(4)
+(5) test_cpuexc5 CPU例外処理のテスト(5)
+(6) test_cpuexc6 CPU例外処理のテスト(6)
+(7) test_cpuexc7 CPU例外処理のテスト(7)
+(8) test_cpuexc8 CPU例外処理のテスト(8)
+(9) test_cpuexc9 CPU例外処理のテスト(9)
+(10) test_cpuexc10 CPU例外処理のテスト(10)
+(11) test_cpuexc11 CPU例外処理のテスト(11)
+(12) test_cpuexc12 CPU例外処理のテスト(12)
+(13) test_cpuexc13 CPU例外処理のテスト(13)
+(14) test_dlynse sil_dly_nseに関するテスト
+(15) test_sem1 セマフォ機能のテスト(1)
+(16) test_sem2 セマフォ機能のテスト(2)
+(17) test_sysstat1 システム状態に関するテスト(1)
+(18) test_task1 タスク管理モジュールのテスト(1)
+(19) test_tex1 タスク例外処理に関するテスト(1)
+(20) test_tex2 タスク例外処理に関するテスト(2)
+(21) test_utm1 get_utmに関するテスト(1)
+
+CPU例外処理のテストプログラムの一部は,CPU例外ハンドラからリターンした
+場合に,CPU例外を発生させた命令の次から実行が継続されることを前提に作成
+されている.この前提が成り立たない場合には,テストプログラムのターゲッ
+ト依存定義において,CANNOT_RETURN_CPUEXCをマクロ定義することが必要であ
+る.詳しくは,「ターゲット依存部 ポーティングガイド」を参照すること.
+
+10.4 性能評価プログラム
+
+testディレクトリに置かれた"perf"で始まるプログラムは,カーネルの性能評
+価を行うためのプログラムである.
+
+性能評価プログラムは,計測対象となる処理を繰り返し実行し,その実行時間
+を計測して,実行時間分布を表示する.
+
+計測した実行時間には,時間計測のオーバヘッド(時間計測処理の実行にかか
+る時間)が含まれる.計測対象の処理の正味の実行時間を求めるためには,計
+測された時間から,時間計測のオーバヘッドを計測するためのプログラム
+(perf0)で計測された時間を減算する必要がある.
+
+また,実行時間の計測は,別に記述がない限り割込みを許可したまま行うため,
+割込みハンドラ(少なくとも,タイマ割込みハンドラ)の処理時間が含まれた
+実行結果が計測される.
+
+カーネルの性能評価にあたっては,ハードウェア(特にキャッシュ)の設定に
+留意する必要がある.
+
+なお,性能評価プログラムを構築する場合には,MakefileのAPPL_COBJSに,
+test_lib.oとhistogram.oを追加する必要がある.コンフィギュレーションスク
+リプト(configure)を使用する場合には,オプションに-U "test_lib.o
+histogram.o"を指定すればよい.
+
+現バージョンで用意している性能評価プログラムは次の通り.
+
+(1) perf0 時間計測のオーバヘッドの評価
+
+時間計測のオーバヘッドを計測するためのプログラム.具体的には,空のプロ
+グラム(begin_mearsureとend_measureを続けて呼び出すプログラム)の実行時
+間を計測する.
+
+他の性能評価プログラムで計測された時間から,このプログラムで計測された
+時間を減算した時間が,計測対象の処理の正味の実行時間である.
+
+(2) perf1 slp_tsk,wup_tskによるタスク切換え時間の評価
+
+slp_tsk,wup_tskによるタスク切換え時間を計測するためのプログラム.具体
+的には,高い優先度のタスクが起床待ち状態である時に,低い優先度のタスク
+がwup_tskにより高い優先度のタスクを起床し,高い優先度のタスクに切り換わ
+るまでの時間と,高い優先度のタスクがslp_tskにより起床待ち状態となり,低
+い優先度のタスクに切り換わるまでの時間を計測する.
+
+(3) perf2 snd_pdqの処理時間の評価
+
+優先度データキューに蓄積されているデータの数により,snd_pdqの処理時間が
+どのように変化するかを計測するためのプログラム.具体的には,優先度デー
+タキュー中に高い優先度のデータがn個蓄積されている時に,snd_dtqにより低
+い優先度のデータを入れるのにかかる時間を計測する.nを0,10,20,30,40,
+50,100,200,300と変化させて計測する.
+
+(4) perf3 set_flgの処理時間の評価
+
+待ち解除するタスクの数により,set_flgの処理時間がどのように変化するかを
+計測するためのプログラム.具体的には,TA_WMUL属性のイベントフラグに対し
+て,n個のタスクが待っている時に,set_flgによりそのすべてを待ち解除する
+のにかかる時間を計測する.nを0,1,2,3,4,5,10,20と変化させて計測す
+る.
+
+(5) perf4 act_tsk,iact_tskの処理時間とタスク切換え時間の評価
+
+act_tsk,iact_tskの処理時間とタスク切換え時間を計測するためのプログラム.
+具体的には,(1) タスク切換えを起こさないact_tskの処理時間,(2) タスク切
+換えを起こすact_tskの処理時間(タスク切換え時間を含む),(3) タスク切換
+えを起こすiact_tskの処理時間(タスク切換え時間とタイマ割込み中で実行さ
+れるシステム時刻の更新処理時間を含む)の3つの時間を計測する.
+
+11.使用上の注意とヒント
+
+11.1 タイマドライバの組込み
+
+タイマドライバをシステムに組み込むために,システムコンフィギュレーショ
+ンファイルの先頭でtarget_timer.cfgをインクルードする必要がある.
+
+11.2 assertマクロの処理
+
+ASPカーネルのコード中には,assertマクロが使われている.assertマクロの定
+義はt_stddef.hに含まれ,assertが失敗した場合の最後の処理(通常は,プロ
+グラムを停止させる処理)は,ターゲット依存部のTOPPERS_assert_abortで決
+定される.
+
+assertが失敗した場合,システム開発中はデバッガに落とすのが望ましいが,
+システム稼働時の対処法は,システムに対する要件に依存する.そこで,ター
+ゲット依存部のTOPPERS_assert_abortを,システム要件に合致した適切な処理
+に置き換える必要がある.システム要件によっては,NDEBUGを定義してassert
+マクロの処理をオブジェクトコード中から消す(「6.2 コンパイルオプション」
+の節を参照)方法も考えられる.
+
+11.3 システムログ機能の扱い
+
+TOPPERS/ASPカーネルでは,システム開発時の利便性を考慮し,システムログ機
+能を組み込む設定をデフォルトとしている.
+
+それに対して,TOPPERS/ASPカーネルを用いたシステムを機器に組み込む場合は,
+システムログ機能が意味がない場合も多い.機器への組込みに際してのシステ
+ムログ機能の設定方法には,以下の方法が考えられる.
+
+(1) システムログ機能を用いない
+
+システムログ機能を一切使用しない場合には,システムログ機能をシステムに
+組み込まず(システムコンフィギュレーションファイルでsyslog.cfgをインク
+ルードしない),システムログ機能のサービスコールを呼び出すソースファイ
+ルをTOPPERS_OMIT_SYSLOGを定義してコンパイルすればよい.
+
+(2) ログ情報の蓄積のみを行う
+
+機器に組み込んだ状態で,シリアルポート等を介してシステムを外部と接続す
+ることができる場合には,システム稼働時にはログ情報の蓄積のみを行い,シ
+ステムに障害が起きた時などにログ情報を取り出すことで,障害の原因分析の
+助けとすることができる.
+
+具体的な設定方法として,次の2つの方法が考えられる.
+
+(2-1) 低レベル出力をメモリに蓄積する
+
+必要なログ情報を低レベル出力機能を用いて出力するように設定し,低レベル
+の文字出力関数(target_fput_log)に送られた文字をメモリ(典型的にはリン
+グバッファ)に蓄積するようにする.システムの障害時には,そのメモリ領域
+を読み出す.
+
+(2-2) システムログ機能のログバッファに蓄積する
+
+必要なログ情報をシステムログ機能のログバッファに記録するように設定する.
+システムログタスクを動作させないと,ログ情報はログバッファに蓄積されて
+いく.システムの障害時には,ログバッファの領域を読み出すか,システムロ
+グタスクを動作させてログ情報を出力させる.
+
+(3) 開発時の設定のままとする
+
+システムログ機能の設定を,システム開発時のまま変更せず,シリアルポート
+等にログ情報を垂れ流す方法も考えられる.
+
+11.4 オブジェクトIDの管理
+
+TOPPERS/ASPカーネルでは,オブジェクトのID番号を,コンフィギュレータが割
+り付ける方法が基本となっている.
+
+アプリケーションプログラム中でオブジェクトのID番号を参照する場合には,
+次の2つの方法が考えられる.
+
+(1) オブジェクト識別名を用いる
+
+オブジェクト生成のための静的API(CRE_YYY)の第1パラメータに記述したオブ
+ジェクト識別名を,アプリケーションプログラム中でも用いる方法.
+
+コンフィギュレータは,オブジェクト識別名を,割り付けたID番号にマクロ定
+義するC言語プリプロセッサのディレクティブ(#define)をkernel_cfg.hに生
+成するため,アプリケーションプログラムからkernel_cfg.hをインクルードす
+る必要がある.
+
+この方法は,オブジェクトコード中にID番号が直接埋め込まれるために実行効
+率が良い一方で,コンフィギュレータが実行されてkernel_cfg.hが書き換わる
+度に,アプリケーションプログラムの再コンパイルが必要になるという欠点が
+ある.そのため,アプリケーションプログラムを構成するファイルの中で,一
+部のファイルのみでオブジェクト識別名を参照する構成にするといった工夫を
+することが望ましい.
+
+(2) オブジェクトのID番号を保持する変数を用いる
+
+オブジェクトのID番号を保持するconst属性を付加した変数を用意し,アプリケー
+ションプログラム中では,その変数を用いる方法.
+
+例えば,TASK1というオブジェクト識別名のタスクに対して,次のような変数を
+用意する.
+
+const ID TASK1_id = TASK1;
+
+アプリケーションプログラム中では,この変数(TASK1_id)を用いることで,
+コンフィギュレータが実行されてkernel_cfg.hが書き換わる度に,上記の変数
+定義を含んだファイルのみを再コンパイルすればよいことになる.
+
+この方法は,アプリケーションプログラムの再コンパイルを最小限にできる利
+点がある一方で,変数のためのメモリ領域が必要になることに加えて,(プロ
+セッサによっては)変数アクセスのためのオーバヘッドが生じるという欠点が
+ある.また,定数ではなく変数であることから,他の変数の初期化には使えな
+いという制限がある.
+
+なお,TOPPERS/ASPカーネルのコンフィギュレータは,--external-idオプショ
+ンを付加することにより,上記の変数定義をkernel_cfg.c中に生成する機能を
+持っているので,すべてのオブジェクトIDをこの方法で参照する場合には,こ
+の機能を用いることを推奨する.
+
+コンフィギュレータによるID番号割付けのもう1つの課題として,コンフィギュ
+レーションファイルの修正により,オブジェクトIDの割付けが変わってしまう
+ことが挙げられる.これは,アプリケーションソフトウェアの設計仕様書にID
+番号が記載されている場合や,デバッグ作業においてID番号を直接扱っている
+場合に,作業効率を低下させる可能性が考えられる.
+
+この問題に対応するために,TOPPERS/ASPカーネルのコンフィギュレータに,
+ID番号の割付け結果をファイルに書き出す機能(--id-output-fileオプション)
+と,ID番号の割付けをファイルから取り込む機能(--id-input-fileオプション)
+を用意している.これらの機能を用いて,コンフィギュレータを実行する度に,
+前回に実行した時にファイルに書き出したID番号の割付けを取り込むことで,
+前回実行時と同じ割付けを行うことができる.ただし,TOPPERS/ASPカーネルで
+は,ID番号に抜けがあるのは許されないため,オブジェクトの数が減った場合
+には(ID番号が大きい方のオブジェクトが減った場合を除いて)エラーとなる.
+この場合には,ダミーのオブジェクトを生成する方法で回避するしかない.
+
+11.5 カーネルの内部シンボルのリネーム
+
+ASPカーネルでは,モジュール内部の名称が他のモジュール内部の名称と衝突す
+ることを避けるために,カーネルの内部シンボルは,C言語レベルで,先頭が
+"_kernel_"または"_KERNEL_"である名称としている.
+
+これをソースコードの可読性と両立させるために,ASPカーネルでは,ソースコー
+ドは自然な名前を用いて記述し,C言語プリプロセッサのマクロ定義(#define)
+を用いて,それを"_kernel_"または"_KERNEL_"で始まる名前(自然な名前が
+yyyyyの場合には,_kernel_yyyyy)にリネームする仕組みを用いている.
+
+具体的には,関連するディレクトリにxxx_rename.defを置き,そこからリネー
+ムのためのヘッダファイル(xxx_rename.hおよびxxx_unrename.h)を生成する
+ツール(utils/genrename)を用意している.
+
+この仕組みは,ソースコードの可読性向上に役立つ一方で,弊害もある.例え
+ば,多くのデバッガで,ソースコード中の名称とオブジェクトコード中の名称
+が異なるために,ソースコード中の変数名を指定して値を読んだり,関数名を
+指定してブレークポイントを置くといったことができない.
+
+この状況に対応するために,ASPカーネルでは,ソースコード中の該当する名称
+をリネームするためのユーティリティ(utils/applyrename)を用意している.
+applyrenameユーティリティに,リネーム定義ファイル(xxx_rename.def)のプ
+リフィックス(xxxの部分)と,リネームしたいファイルリストを与えると,リ
+ネーム処理を行なう.例えば,kernelディレクトリのすべてのファイルに対し
+て,カーネルの内部シンボルをリネームするには,次のコマンドを実行すれば
+よい.
+
+ % cd kernel
+ % ../utils/applyrename kernel *
+
+また,ターゲット依存部のディレクトリのすべてのファイルに対して,カーネ
+ルの内部シンボルをリネームするには,次のようなコマンドを実行すればよい.
+
+ % cd target/dve68k_gcc/
+ % ../../utils/applyrename target *
+ % ../../utils/applyrename ../../kernel/kernel *
+
+11.6 トレースログ記録のサンプルコードの使用方法
+
+トレースログ記録のサンプルコードがターゲット依存部に組み込まれている場
+合には,コンフィギュレーションスクリプトにそれを使用することを指示する
+オプション(-r)を付加することで,メモリ上にトレースログを記録する機能
+が有効になる.
+
+トレースログ記録の使用方法の一例として,システム起動時にトレースログの
+記録を開始し,システム終了時に記録したトレースログをダンプするためには,
+システムコンフィギュレーションファイルに次のような記述を追加する.
+
+ #include "logtrace/trace_config.h"
+ ATT_INI({ TA_NULL, TRACE_AUTOSTOP, trace_initialize });
+ ATT_TER({ TA_NULL, target_fput_log, trace_dump });
+
+ここで,初期化ルーチン(trace_initialize)への引数は,初期化直後のトレー
+スログの動作モードを指定するものである.指定できる動作モードについては,
+arch/logtrace/trace_config.h中のコメントに説明がある.
+
+終了処理ルーチン(trace_dump)は,記録されたトレースログをターゲット依
+存の低レベル出力機能(target_fput_log)を利用してダンプするためのもので
+ある.トレースログを別の方法で取り出す場合には,終了処理ルーチンを登録
+する必要はない.
+
+以上の方法では,trace_initializeを初期化ルーチンで,trace_dumpを終了処
+理ルーチンで呼び出しているため,初期化ルーチンを呼び出す前や終了処理ルー
+チンを呼び出した後には,トレースログ記録の機能を利用できない.初期化ルー
+チンを呼び出す前や終了処理ルーチンを呼び出した後に実行される処理(例え
+ば,カーネルオブジェクトの初期化処理や,trace_initializeよりも先に登録
+した初期化ルーチン,trace_dumpよりも先に登録した終了処理ルーチン)でト
+レースログ記録の機能を利用するためには,trace_initializeとtrace_dumpを
+適切な場所で呼ぶように修正することが必要である.
+
+11.7 システムの起動時の初期化処理
+
+システムの起動時にアプリケーションで必要となる初期化処理を行うための機
+能として初期化ルーチンが用意されているが,初期化ルーチンが実行されるよ
+りも早いタイミングで実行することが必要な初期化処理がある場合がある.
+
+このような場合に用いるために,標準的なスタートアップモジュールから,ター
+ゲットシステム依存の初期化フック(hardware_init_hook)を呼び出すことと
+している.hardware_init_hookは,カーネルのターゲット依存部で用意されて
+いるのが標準であるが,これをアプリケーションで用意したものに置き換え,
+その中でアプリケーションで必要となる初期化処理を行うことができる.
+
+ただし,hardware_init_hookの作成する場合には,bssセクションとdataセクショ
+ンが初期化されていないことや,ライブラリが初期化されていないこと,C言語
+で記述できるとは限らないことなどに注意が必要である.作成にあたっては,
+「ターゲット依存部 ポーティングガイド」を参照すること.
+
+カーネルのスタートアップモジュールがhardware_init_hookを呼び出すように
+実装されていない場合には,スタートアップモジュールをアプリケーションで
+用意したものに置き換える方法を推奨する.
+
+
+12.参考情報
+
+12.1 利用条件と利用報告
+
+ASPカーネルの利用条件は,各ファイルの先頭に表示されている.著作権は,各
+ファイルの先頭に表示されている著作権者が保有している.
+
+利用条件の(3)の(b)において,利用の形態をTOPPERSプロジェクトに報告する方
+法としては,ASPカーネルを利用した製品の名称と応用分野,製品化した会社名
+と業種等の情報を,以下のURLのページから報告するものとする.
+
+ http://www.toppers.jp/report.html
+
+またその際に,ASPカーネルを使用してのコメントやご意見もいただけると幸い
+である.
+
+12.2 保証・適用性・サポート
+
+ASPカーネルは無保証で提供されているものである.開発者およびTOPPERSプロ
+ジェクトは,ASPカーネルに関して,特定の使用目的に対する適合性も含めて,
+いかなる保証も行わない.また,ASPカーネルの利用により直接的または間接的
+に生じたいかなる損害に関しても,その責任を負わない.
+
+開発者およびTOPPERSプロジェクトは,ASPカーネルに関するサポートの約束は
+していない.ASPカーネルに関して質問がある場合は,後述のTOPPERSユーザー
+ズメーリングリストを利用していただけると幸いである.確実なサポートが必
+要な場合には,有償でサポートサービスを提供している会社に相談されたい.
+
+12.3 バグレポート
+
+ASPカーネルにバグや問題点を発見された場合には,後述のTOPPERSユーザーズ
+メーリングリストに報告して欲しい.
+
+メーリングリストにバグや問題点などを報告する場合には,必要に応じて次の
+情報を知らせて欲しい.
+
+ 使用しているカーネルに関する情報
+ ・ターゲット非依存部のバージョン
+ ・使用しているターゲット依存部とそのバージョン
+ ・TOPPERSプロジェクトからのリリースに対する改造箇所(あれば)
+
+ ターゲットシステムに関する情報
+ ・ターゲットプロセッサの種類
+ ・ターゲットボード等の種類
+
+ ホストに関する情報
+ ・OSのバージョン(サービスパックの適用状況も)
+ ・コンパイラなどの開発環境のバージョン(Cygwinのバージョンも)
+
+12.4 ウェブサイト
+
+TOPPERSプロジェクトのウェブサイトは,以下のURLにある.
+
+ http://www.toppers.jp/
+
+TOPPERSプロジェクトやASPカーネルに関する最新情報は,このウェブサイトか
+ら得ることができる.また,ASPカーネルの最新版は,このウェブサイトからダ
+ウンロードすることができる.
+
+12.5 TOPPERSユーザーズメーリングリスト
+
+ASPカーネルを含むTOPPERSプロジェクトの開発成果物のユーザに対する情報提
+供およびユーザ相互間の情報交換を容易にするために,TOPPERSユーザーズメー
+リングリスト(users@toppers.jp)を用意している.
+
+このメーリングリストには,誰でも自由に登録し,メールを送付することがで
+きる(登録者以外はメールを送付できない).また,送付されたメールは,誰
+でも自由にウェブサイトで読むことができる.
+
+メーリングリストへの登録方法については,以下のURLのページに説明がある.
+
+ http://www.toppers.jp/community.html
+
+12.6 TOPPERSプロジェクトのメンバ向けのサービス
+
+TOPPERSプロジェクトのメンバに対しては,上記に加えて,ASPカーネルに関連
+して次のサービスを用意している.
+
+(1) TOPPERS開発者メーリングリスト
+
+TOPPERSプロジェクトのメンバは,ASPカーネルに関する質問,バグや問題点な
+どの報告に,TOPPERS開発者メーリングリスト(dev@toppers.jp)を利用するこ
+とができる.
+
+(2) ASPカーネルの開発支援サイト
+
+ASPカーネルの開発支援のためのTRAC(バグトラッキングシステム)が,以下の
+URLにある(TRACへのアクセスには,会員パスワードが必要である).
+
+ http://dev.toppers.jp/proj/asp/
+
+TOPPERSプロジェクトのメンバは,このサイトから,ウェブインタフェースおよ
+びsubversionサーバにより,ASPカーネルの開発中のバージョンを得ることがで
+きる.また,バグトラッキングデータベースにアクセスすることができ,過去
+のバグ履歴へのアクセスや,バグの登録をすることができる.
+
+12.7 TOPPERSプロジェクトへの参加
+
+TOPPERSプロジェクトでは,何からの形でプロジェクトに貢献していただける方,
+プロジェクトで開発したソフトウェアをお使いの方,プロジェクトに興味をお
+持ちの方の参加を求めている.TOPPERSプロジェクトへの参加方法については,
+以下のページに説明がある.
+
+ http://www.toppers.jp/joinus.html
+
+
+13.リファレンス
+
+13.1 サービスコール一覧
+
+(1) タスク管理機能
+
+ ER ercd = act_tsk(ID tskid)
+ ER ercd = iact_tsk(ID tskid)
+ ER_UINT actcnt = can_act(ID tskid)
+ ER ercd = ext_tsk(void)
+ ER ercd = ter_tsk(ID tskid)
+ ER ercd = chg_pri(ID tskid, PRI tskpri)
+ ER ercd = get_pri(ID tskid, PRI *p_tskpri)
+ ER ercd = get_inf(intptr_t *p_exinf)
+ ER ercd = ref_tsk(ID tskid, T_RTSK *pk_rtsk)
+
+(2) タスク付属同期機能
+
+ ER ercd = slp_tsk(void)
+ ER ercd = tslp_tsk(TMO tmout)
+ ER ercd = wup_tsk(ID tskid)
+ ER ercd = iwup_tsk(ID tskid)
+ ER_UINT wupcnt = can_wup(ID tskid)
+ ER ercd = rel_wai(ID tskid)
+ ER ercd = irel_wai(ID tskid)
+ ER ercd = sus_tsk(ID tskid)
+ ER ercd = rsm_tsk(ID tskid)
+ ER ercd = dly_tsk(RELTIM dlytim)
+
+(3) タスク例外処理機能
+
+ ER ercd = ras_tex(ID tskid, TEXPTN rasptn)
+ ER ercd = iras_tex(ID tskid, TEXPTN rasptn)
+ ER ercd = dis_tex(void)
+ ER ercd = ena_tex(void)
+ bool_t state = sns_tex(void)
+ ER ercd = ref_tex(ID tskid, T_RTEX *pk_rtex)
+
+(4) 同期・通信機能
+
+ ER ercd = sig_sem(ID semid)
+ ER ercd = isig_sem(ID semid)
+ ER ercd = wai_sem(ID semid)
+ ER ercd = pol_sem(ID semid)
+ ER ercd = twai_sem(ID semid, TMO tmout)
+ ER ercd = ini_sem(ID semid)
+ ER ercd = ref_sem(ID semid, T_RSEM *pk_rsem)
+
+ ER ercd = set_flg(ID flgid, FLGPTN setptn)
+ ER ercd = iset_flg(ID flgid, FLGPTN setptn)
+ ER ercd = clr_flg(ID flgid, FLGPTN clrptn)
+ ER ercd = wai_flg(ID flgid, FLGPTN waiptn,
+ MODE wfmode, FLGPTN *p_flgptn)
+ ER ercd = pol_flg(ID flgid, FLGPTN waiptn,
+ MODE wfmode, FLGPTN *p_flgptn)
+ ER ercd = twai_flg(ID flgid, FLGPTN waiptn,
+ MODE wfmode, FLGPTN *p_flgptn, TMO tmout)
+ ER ercd = ini_flg(ID flgid)
+ ER ercd = ref_flg(ID flgid, T_RFLG *pk_rflg)
+
+ ER ercd = snd_dtq(ID dtqid, intptr_t data)
+ ER ercd = psnd_dtq(ID dtqid, intptr_t data)
+ ER ercd = ipsnd_dtq(ID dtqid, intptr_t data)
+ ER ercd = tsnd_dtq(ID dtqid, intptr_t data, TMO tmout)
+ ER ercd = fsnd_dtq(ID dtqid, intptr_t data)
+ ER ercd = ifsnd_dtq(ID dtqid, intptr_t data)
+ ER ercd = rcv_dtq(ID dtqid, intptr_t *p_data)
+ ER ercd = prcv_dtq(ID dtqid, intptr_t *p_data)
+ ER ercd = trcv_dtq(ID dtqid, intptr_t *p_data, TMO tmout)
+ ER ercd = ini_dtq(ID dtqid)
+ ER ercd = ref_dtq(ID dtqid, T_RDTQ *pk_rdtq)
+
+ ER ercd = snd_pdq(ID pdqid, intptr_t data, PRI datapri)
+ ER ercd = psnd_pdq(ID pdqid, intptr_t data, PRI datapri)
+ ER ercd = ipsnd_pdq(ID pdqid, intptr_t data, PRI datapri)
+ ER ercd = tsnd_pdq(ID pdqid, intptr_t data, PRI datapri, TMO tmout)
+ ER ercd = rcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri)
+ ER ercd = prcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri)
+ ER ercd = trcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri, TMO tmout)
+ ER ercd = ini_pdq(ID pdqid)
+ ER ercd = ref_pdq(ID pdqid, T_RPDQ *pk_rpdq)
+
+ ER ercd = snd_mbx(ID mbxid, T_MSG *pk_msg)
+ ER ercd = rcv_mbx(ID mbxid, T_MSG **ppk_msg)
+ ER ercd = prcv_mbx(ID mbxid, T_MSG **ppk_msg)
+ ER ercd = trcv_mbx(ID mbxid, T_MSG **ppk_msg, TMO tmout)
+ ER ercd = ini_mbx(ID mbxid)
+ ER ercd = ref_mbx(ID mbxid, T_RMBX *pk_rmbx)
+
+(5) メモリプール管理機能
+
+ ER ercd = get_mpf(ID mpfid, void **p_blk)
+ ER ercd = pget_mpf(ID mpfid, void **p_blk)
+ ER ercd = tget_mpf(ID mpfid, void **p_blk, TMO tmout)
+ ER ercd = rel_mpf(ID mpfid, void *blk)
+ ER ercd = ini_mpf(ID mpfid)
+ ER ercd = ref_mpf(ID mpfid, T_RMPF *pk_rmpf)
+
+(6) 時間管理機能
+
+ ER ercd = get_tim(SYSTIM *p_systim)
+ ER ercd = get_utm(SYSUTM *p_sysutm)
+
+ ER ercd = sta_cyc(ID cycid)
+ ER ercd = stp_cyc(ID cycid)
+ ER ercd = ref_cyc(ID cycid, T_RCYC *pk_rcyc)
+
+ ER ercd = sta_alm(ID almid, RELTIM almtim)
+ ER ercd = ista_alm(ID almid, RELTIM almtim)
+ ER ercd = stp_alm(ID almid)
+ ER ercd = istp_alm(ID almid)
+ ER ercd = ref_alm(ID almid, T_RALM *pk_ralm)
+
+(7) システム状態管理機能
+
+ ER ercd = rot_rdq(PRI tskpri)
+ ER ercd = irot_rdq(PRI tskpri)
+ ER ercd = get_tid(ID *p_tskid)
+ ER ercd = iget_tid(ID *p_tskid)
+ ER ercd = loc_cpu(void)
+ ER ercd = iloc_cpu(void)
+ ER ercd = unl_cpu(void)
+ ER ercd = iunl_cpu(void)
+ ER ercd = dis_dsp(void)
+ ER ercd = ena_dsp(void)
+ bool_t state = sns_ctx(void)
+ bool_t state = sns_loc(void)
+ bool_t state = sns_dsp(void)
+ bool_t state = sns_dpn(void)
+ bool_t state = sns_ker(void)
+ ER ercd = ext_ker(void)
+
+(8) 割込み管理機能
+
+ ER ercd = dis_int(INTNO intno)
+ ER ercd = ena_int(INTNO intno)
+ ER ercd = chg_ipm(PRI intpri)
+ ER ercd = get_ipm(PRI *p_intpri)
+
+(9) CPU例外管理機能
+
+ bool_t stat = xsns_dpn(void *p_excinf)
+ bool_t stat = xsns_xpn(void *p_excinf)
+
+13.2 静的API一覧
+
+(1) タスク管理機能
+
+ CRE_TSK(ID tskid, { ATR tskatr, intptr_t exinf, TASK task,
+ PRI itskpri, SIZE stksz, STK_T *stk })
+
+(3) タスク例外処理機能
+
+ DEF_TEX(ID tskid, { ATR texatr, TEXRTN texrtn })
+
+(4) 同期・通信機能
+
+ CRE_SEM(ID semid, { ATR sematr, uint_t isemcnt, uint_t maxsem })
+ CRE_FLG(ID flgid, { ATR flgatr, FLGPTN iflgptn })
+ CRE_DTQ(ID dtqid, { ATR dtqatr, uint_t dtqcnt, void *dtqmb })
+ CRE_PDQ(ID pdqid, { ATR pdqatr, uint_t pdqcnt, PRI maxdpri, void *pdqmb })
+ CRE_MBX(ID mbxid, { ATR mbxatr, PRI maxmpri, void *mprihd })
+
+(5) メモリプール管理機能
+
+ CRE_MPF(ID mpfid, { ATR mpfatr, uint_t blkcnt, uint_t blksz,
+ MPF_T *mpf, void *mpfmb })
+
+(6) 時間管理機能
+
+ CRE_CYC(ID cycid, { ATR cycatr, intptr_t exinf, CYCHDR cychdr,
+ RELTIM cyctim, RELTIM cycphs })
+ CRE_ALM(ID almid, { ATR almatr, intptr_t exinf, ALMHDR almhdr })
+
+(8) 割込み管理機能
+
+ ATT_ISR({ ATR isratr, intptr_t exinf, INTNO intno, ISR isr, PRI isrpri })
+ DEF_INH(INHNO inhno, { ATR inhatr, INTHDR inthdr })
+ CFG_INT(INTNO intno, { ATR intatr, PRI intpri })
+
+(9) CPU例外管理機能
+
+ DEF_EXC(EXCNO excno, { ATR excatr, EXCHDR exchdr })
+
+(10) システム構成管理機能
+
+ DEF_ICS({ SIZE istksz, STK_T *istk })
+ ATT_INI({ ATR iniatr, intptr_t exinf, INIRTN inirtn })
+ ATT_TER({ ATR teratr, intptr_t exinf, TERRTN terrtn })
+
+13.3 バージョン履歴
+
+ 2006年10月29日 Release 1.A.0 最初のリリース
+ 2007年2月20日 Release 1.A.1
+ 2007年2月20日 Release 1.A.2
+ 2007年7月12日 Release 1.B.0 コンフィギュレータを新バージョンに
+ 2007年7月12日 Release 1.B.1 ライセンス条件の入れ換え
+ 2007年7月16日 Release 1.B.2
+ 2007年7月21日 Release 1.B.3 ディレクトリ構成の変更
+ 2007年8月20日 Release 1.B.4 拡張パッケージの追加
+ 2007年10月16日 Release 1.B.5
+ 2007年11月15日 Release 1.0.0 正式版のリリース
+ 2007年12月23日 Release 1.1.0
+ 2008年3月19日 Release 1.2.0
+ 2008年3月21日 Release 1.2.1
+ 2008年4月12日 Release 1.3.0 一般公開に向けての最終修正
+ 2008年5月13日 Release 1.3.1 最初の一般公開版
+ 2008年8月21日 Release 1.3.2
+ 2009年5月11日 Release 1.4.0
+ 2010年6月28日 Release 1.5.0 拡張パッケージを一般公開
+ 2010年8月1日 Release 1.6.0 cfg-1.6に対応
+
+以上
--- /dev/null
+
+ TOPPERS/ASPカーネル
+ 変更履歴
+
+ 対応バージョン: Release 1.6.0
+ 最終更新: 2010年7月25日
+
+このドキュメントは,TOPPERS/ASPカーネルのRelease 1.0.0以降の変更履歴を,
+新しい方から順に記述したものである.
+
+----------------------------------------------------------------------
+ TOPPERS/ASP Kernel
+ Toyohashi Open Platform for Embedded Real-Time Systems/
+ Advanced Standard Profile Kernel
+
+ Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ Graduate School of Information Science, Nagoya Univ., JAPAN
+
+ 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ スコード中に含まれていること.
+ (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ の無保証規定を掲載すること.
+ (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ と.
+ (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ 報告すること.
+ (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ 免責すること.
+
+ 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ の責任を負わない.
+
+ $Id: version.txt 1871 2010-07-27 04:24:46Z ertl-hiro $
+----------------------------------------------------------------------
+
+ TOPPERS/ASPカーネル
+ Release 1.5.0 から 1.6.0 への変更点
+
+○変更点のリスト
+
+・cfgの新しいバージョン(1.6)に対応
+ - offsetof_TINIB_stkszとoffsetof_TINIB_stkの取得記述をターゲット非
+ 依存部に移動.
+
+・ユーティリティの修正
+ - genoffsetに,エンディアン指定をチェックする機能を追加.その際に,
+ コードを整理.
+
+・その他の修正
+ - TCBのpriorityフィールドを,条件があえばuint_8で定義するように修正.
+ - ターゲット依存部でSIL_ENDIAN_BIGもSIL_ENDIAN_LITTLEも定義されてい
+ ない場合に,sil.hでエラーを検出するように修正.
+ - システムログ機能のsysog_logmaskとsyslog_lowmask_notの初期値を修正.
+ - makereleaseを,ファイルの重複をチェックするように修正.
+ - test_utm1のエラーメッセージを修正.
+
+・ドキュメントの充実,コメントの修正
+
+・バージョン番号の更新
+ - カーネルのバージョン番号を更新.
+
+○ターゲット依存部の要修正箇所(1.5.0 → 1.6.0)
+
+(1) makeoffset.cの修正
+ - makeoffset.cに,sil_endian関数を追加する(これにより,genoffsetの
+ エンディアン指定をチェックする機能が有効になる).
+ - オーバランハンドラ拡張パッケージに対応する場合には,leftotmフィー
+ ルドが含まれているかを確認する.
+ - 生成されるoffset.hに変化がないことを確認する.
+
+(2) 値取得シンボルテーブルのターゲット依存部の修正
+ - 以下の2行をtarget_def.csv(またはそれに代わるファイル)から削除する.
+ offsetof_TINIB_stksz,"offsetof(TINIB,stksz)"
+ offsetof_TINIB_stk,"offsetof(TINIB,stk)"
+ ※ Release 1.5.0における修正を元に戻す.
+
+(3) target_fput_logの実装制限の確認(仕様が修正されたわけではない)
+ - target_fput_log全割込みロック状態で呼び出せるようになっているか確
+ 認する.
+
+----------------------------------------------------------------------
+
+ TOPPERS/ASPカーネル
+ Release 1.4.0 から 1.5.0 への変更点
+
+○変更点のリスト
+
+・カーネル管理外の割込みとCPU例外の扱いの見直し
+ - カーネル管理外の割込みの設定方法を整理・拡張.
+ - カーネル管理外の割込みハンドラは,カーネル内の出入口処理を経由し
+ ないことを基本とした(ターゲット依存).
+ - CPU例外ハンドラの出入口処理におけるカーネル管理外のCPU例外の扱い
+ を規定.
+
+・chg_ipmとget_ipmの仕様変更
+ - chg_ipmとget_ipmは,CPUロック状態では呼べないものとした.
+ - これに伴ってテストプログラムを修正.
+
+・タイマ割込み処理で呼び出したialm_timの基準時間の変更
+ - current_timeの更新後に,タイムイベントの処理を行うように変更.
+ - 有効な最小のシステム時刻としてmin_timeを導入.
+ - pend_updateを廃止.
+
+・タスクのスタックサイズの最小値チェックの追加
+ - スタックサイズが0の場合のエラーを,ターゲット非依存で検出.
+ - ターゲット依存で,タスクのスタックサイズの最小値を設定できるよう
+ にした.
+
+・タスク初期化コンテキストブロックの追加
+ - ターゲット依存で,タスク初期化コンテキストブロック(TSKINICTXB)
+ を使用できるようにした.
+
+・ターゲット依存部で定義する名称のリネーム方法の変更
+ - ターゲット依存部で定義し,ターゲット非依存部から参照する名称のリ
+ ネーム記述を,ターゲット依存部に移動.
+
+・拡張パッケージの追加
+ - ミューテックス機能拡張パッケージ,オーバランハンドラ機能拡張パッ
+ ケージ,タスク優先度拡張パッケージを,一般公開するファイルに追加.
+ - オーバランハンドラ機能拡張への対応方法を,ポーティングガイドに記載.
+
+・サポートする機能を識別するマクロの定義方法の変更
+ - ターゲット依存部でTOPPERS_TARGET_SUPPORT_XXXXXがマクロ定義されて
+ いれば,kernel.hでTOPPERS_SUPPORT_XXXXXをマクロ定義する方法に変更.
+
+・システムログ機能の修正
+ - syslog_initializeが呼ばれる前のログ情報の出力に対応.
+ - sysog_logmaskとsyslog_lowmask_notの初期値を修正.
+
+・テストライブラリの修正
+ - test_lib.hとtest_lib.cを,testディレクトリから,それぞれincludeと
+ libraryディレクトリに移動.
+ - syslog_flush関数を追加.logtask_flushの代わりに使用.
+ - test_finish関数を追加.テストプログラム中でext_kerの代わりに使用.
+ - 以上に伴ってテストプログラムを修正.
+
+・configureの拡張
+ - Makefileのテンプレートを指定するためのオプションを追加.
+
+・その他のバグフィックス
+ - kernel_impl.h中のマクロ名の修正.
+ - kernel.tf中の文法ミスの修正.
+
+・その他の修正
+ - CTXB型をTSKCTXB型に名称変更.
+ - ext_tskで,戻らないはずの処理から戻った場合には,E_SYSを返す.
+ - call_texrtnからdispatchを呼び出す処理を改善.
+ - make_non_waitを,wait.cからwait.hに移動.
+ - xsns_xpn中の冗長な条件式を削除.
+ - TA_DISINTとTA_LEVELをitron.hから削除.
+ - LOG_TEX_LEAVEの第2パラメータを削除.
+ - サンプルのMakefileに,OMIT_WARNING_ALLとOMIT_OPTIMIZATIONを追加.
+ - get_utmに関するテスト(1)(test_utm1)を追加.
+ - test_dlynse.cの表示を改善.
+
+・ドキュメントの充実,コメントの修正
+ - 機能拡張・チューニングガイドに関して,ユーザーズマニュアルに記載.
+ - キュー操作ライブラリ関数に関して,ユーザーズマニュアルに記載.
+ - システムの起動時の初期化処理に関して,ユーザーズマニュアルに記載.
+ - 設計メモを拡充.
+
+・バージョン番号の更新
+ - カーネル仕様のバージョン番号,カーネルのバージョン番号を更新.
+
+○ターゲット依存部の要修正箇所(1.4.0 → 1.5.0)
+
+(1) カーネル管理外の割込みの扱いの変更
+ - カーネル管理外の割込みハンドラの呼び出し方について,これまでの考
+ え方を変更した.「ターゲット依存部 ポーティングガイド」の6.6.7節
+ の記述通りに実装されているかチェックする.
+ - TA_NONKERNELを使用できるようにする場合には,target.tfで,
+ TARGET_INHATRにTA_NONKERNELを設定する.
+ - パス2のテンプレートファイルのターゲット非依存部に,
+ INTNO_FIX_KERNEL,INHNO_FIX_KERNEL,INTNO_FIX_NONKERNEL,
+ INHNO_FIX_NONKERNEL,USE_INHINIB_TABLE,USE_INTINIB_TABLEのサポー
+ トが追加されたので,使用できる場合には使用するように修正する.
+ - カーネル管理の割込みハンドラの出入口処理について,「ターゲット依
+ 存部 ポーティングガイド」の6.6.1節の記述通りに実装されていること
+ を確認する.
+
+(2) カーネル管理外のCPU例外の扱いの変更
+ - カーネル管理外のCPU例外ハンドラの呼び出し方について,これまでの考
+ え方を変更した.「ターゲット依存部 ポーティングガイド」の6.7.1節
+ の記述を参照して,実装を修正する.
+
+(3) ターゲット依存部で定義する名称のリネームの追加
+ - ターゲット依存部で定義し,ターゲット非依存部から参照する名称のリ
+ ネーム記述を,ターゲット依存部に追加する.ターゲット依存部とチッ
+ プ依存部の間でも同様の変更を行うことが望ましい.ただし,
+ arch/logtrace/trace_config.cで定義される名称については,ターゲッ
+ ト依存部でリネームする.
+
+(4) ターゲット依存部でサポートする機能を示すマクロの変更
+ - ターゲット依存部で定義しているTOPPERS_SUPPORT_DIS_INTを
+ TOPPERS_TARGET_SUPPORT_DIS_INTに,TOPPERS_SUPPORT_ENA_INTを
+ TOPPERS_TARGET_SUPPORT_ENA_INTに,TOPPERS_SUPPORT_GET_UTMを
+ TOPPERS_TARGET_SUPPORT_GET_UTMに,それぞれ変更する.
+
+(5) タスクコンテキストブロックの型名の変更
+ - CTXB型をTSKCTXB型に名称変更する.
+
+(6) 値取得シンボルテーブルのターゲット依存部の修正
+ - 以下の2行をtarget_def.csv(またはそれに代わるファイル)に加える.
+ offsetof_TINIB_stksz,"offsetof(TINIB,stksz)"
+ offsetof_TINIB_stk,"offsetof(TINIB,stk)"
+ ※ 新設されたUSE_TSKINICTXBを使う場合には必要ない.
+ ※ Release 1.6以降を用いる場合には,この修正は必要はない.
+
+(7) ログマクロの修正
+ - LOG_TEX_LEAVEの第2パラメータが削除されたので,LOG_TEX_LEAVEを定義
+ している場合には,その定義を変更する.
+
+(8) スタートアップモジュールの修正(bssセクションのクリアを省略している
+ 場合のみ)
+ - システムログ機能を使用する場合には,スタートアップモジュールに,
+ syslog_logmaskとsyslog_lowmask_notを0に初期化するコードを追加する.
+ - トレースログ記録のサンプルコードを組み込んでいる場合には,スター
+ トアップモジュールに,trace_modeを0に初期化するコードを追加する.
+
+(9) タスクのスタックサイズの最小値チェックの設定(オプション)
+ - ターゲット依存に,タスクのスタックサイズの最小値をチェックする場
+ 合には,最小値をTARGET_MIN_STKSZに定義する.
+
+(10) オーバランハンドラ機能拡張への対応(オプション)
+ - オーバランハンドラ機能拡張パッケージに対応する.対応方法について
+ は,「ターゲット依存部 ポーティングガイド」中の「#ifdef
+ TOPPERS_SUPPORT_OVRHDR」がある箇所と,5.7節と6.14節を参照すること.
+
+----------------------------------------------------------------------
+
+ TOPPERS/ASPカーネル
+ Release 1.3.2 から 1.4.0 への変更点
+
+○変更点のリスト
+
+・周期ハンドラの仕様変更
+ - sta_cycを呼び出した後,最初に周期ハンドラが起動される時刻を,起動
+ 周期後から,起動位相後に変更.
+
+・TSZ_MPFの定義を削除
+
+・call_atexitの廃止
+ - ターゲット非依存部からcall_atexitを呼び出すのをやめる.
+ call_atexitで行っていた処理(標準的にはsoftware_term_hookを呼び出
+ す処理)は,必要であればtarget_exitの先頭で行うこととする.
+
+・get_utmの問題の修正
+ - 周期ハンドラ,アラームハンドラの中でget_utmを呼ぶと,正しい時刻が
+ 返らない問題を修正.
+
+・スケジューラのモジュール性向上
+ - タスク状態(tstat)の変更を,make_runnableではなく,それを呼ぶ側
+ の関数で行うように修正.
+
+・テンプレート変数の値の自動取得
+ - OMIT_INITIALIZE_INTERRUPTとOMIT_INITIALIZE_EXCEPTIONの2つのテンプ
+ レート変数の値を,ヘッダファイルの定義から自動取得するように修正.
+
+・トレースログ機能の改善
+ - LOG_TEX_ENTER,LOG_TEX_LEAVEのパラメータに,p_runtskを追加.
+
+・実行時間分布集計モジュールの修正
+ - 時刻取得の方法をターゲット依存で変更できるように修正.
+ - TNUM_HISTの定義を,histgram.hからhistgram.cに移動.
+
+・コンフィギュレータの分離
+ - cfgは,ASPカーネルとは独立したパッケージとして配布することにする.
+
+・マイグレーションガイドの分離
+ - doc/migration.txtは,別途PDFファイルで配布することにする.
+
+・テストプログラム,性能評価プログラムの追加
+ - セマフォ機能のテスト(2)(test_sem2)を追加.
+ - act_tsk,iact_tskの処理時間の評価プログラム(perf4)を追加.
+
+・clean時に削除するファイル
+ - clean時に削除するファイルを,ターゲット依存部で定義するための変数
+ (CLEAN_FILES)を導入.
+
+・ユーティリティの修正
+ - makereleaseが使うディレクトリ名(asp)を,カレントディレクトリか
+ ら決定するように修正.
+ - makedepに,Cygwin環境におけるルートディレクトリ名を指定するため
+ の-Rオプションを追加.MakefileにMAKEDEP_OPTS変数を追加.
+ - gentestをアラームハンドラの複数回起動に対応できるように拡張.
+
+・その他のバグフィックス
+ - リネームするシンボルを修正.
+ - 割込みサービスルーチン,初期化ルーチン,終了処理ルーチンの先頭番
+ 地に関数名以外を記述した場合にも動作するように修正.
+ - Makefile.dependがない場合の問題を修正.
+
+・ドキュメントの充実,コメントの修正
+ - 各ドキュメントにTOPPERSライセンスと目次を追加.
+
+・バージョン番号の更新
+ - カーネル仕様のバージョン番号,カーネルのバージョン番号を更新.
+
+○ターゲット依存部の要修正箇所(1.3.2 → 1.4.0)
+
+(1) call_atexitの廃止
+ - call_atexitを廃止したため,ターゲット依存部から定義を削除する.
+ call_atexitで行っていた処理(標準的にはsoftware_term_hookを呼び出
+ す処理)は,必要であればtarget_exitの先頭で行う.
+
+(2) テンプレート変数の値の設定の削除
+ - OMIT_INITIALIZE_INTERRUPTとOMIT_INITIALIZE_EXCEPTIONの2つのテンプ
+ レート変数の値を,ヘッダファイルの定義から自動取得するように修正
+ したため,ターゲット依存部(target.tfまたはそこからインクルードさ
+ れるファイル)で値を定義していれば,その定義を削除する.
+
+(3) makedepを呼ぶ際のオプションの追加
+ - Makefileのターゲット依存部(Makefile.target等)でmakedepを呼んで
+ いる場合には,$(MAKEDEP_OPTS)を追加する.
+
+ 例)@$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+ -O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+(4) 簡易パッケージへのコンフィギュレータの追加
+ - コンフィギュレータ(cfg)がターゲット非依存部から分離されたため,
+ 簡易パッケージに入れる場合には,E_PACKAGEにcfgを含めるための記述
+ を追加する.
+
+ 例)INCLUDE ../../cfg/MANIFEST
+
+----------------------------------------------------------------------
+
+ TOPPERS/ASPカーネル
+ Release 1.3.1 から 1.3.2 への変更点
+
+○変更点のリスト
+
+・TMAX_RELTIMをユーザから参照できるマクロに
+ - TMAX_RELTIMの定義を,kernel/time_event.hからinclude/t_stddef.hに
+ 移動.
+
+・const指定の追加
+ - syslog_printf,syslog_print,syslog_wri_log,serial_wri_datのパラ
+ メータにconst指定を追加.
+
+・TMIN_ISRPRI,TMAX_ISRPRIの導入
+
+・実行時間分布集計モジュールで時間の逆転が疑われるケースの扱い
+ - 実行時間分布集計モジュールで時間の逆転が疑われる度数を計測するよ
+ うに修正.
+
+・システムログタスクの終了処理の修正
+ - ログバッファに残ったログ情報であることを示す文字列を出力するように
+ 修正.
+
+・コンフィギュレータの修正
+ - 順序付きリストの要素に式を使えるように変更.
+ - 静的APIのパラメータに型キャストが含まれるとパースできないバグの修正.
+ - #pragma onceを用いると行番号がずれるバグの修正.
+ - cfgファイルを指定しなかった場合のエラーメッセージの修正.
+
+・コンフィギュレータが生成するファイル
+ - コンフィギュレータがkernel_cfg.c以外のファイルを生成する場合に対
+ 応するための変数(CFG_OBJS,CFG2_OUT)を導入.
+
+・realclean時に削除するファイル
+ - realclean時に削除するファイルを,ターゲット依存部で定義するための
+ 変数(REALCLEAN_FILES)を導入.
+
+・テストプログラムの追加・拡充
+ - セマフォ機能のテスト(1)を追加.
+ - カーネルの整合性検査にセマフォ毎の検査を追加.
+
+・バグフィックス
+ - 非タスクコンテキスト用スタックの確保時のサイズの誤り.
+ - kernel.tf中のエラーメッセージの誤り.
+ - 実行時間分布集計モジュールにおける最大値の扱いのバグ.
+ - Makefile中のAPPLDIRに複数のディレクトリが定義されている時の扱い.
+ - test/perf.cで,計測回数を10000回になるように修正.
+ - DVE68Kターゲット依存部のtarget.tf中のエラーメッセージの誤り.
+
+・ドキュメントの充実,コメントの修正
+ - 各ドキュメントにTOPPERSライセンスと目次を追加.
+
+・バージョン番号の更新
+
+○ターゲット依存部の要修正箇所(1.3.1 → 1.3.2)
+
+特になし
+
+----------------------------------------------------------------------
+
+ TOPPERS/ASPカーネル
+ Release 1.3.0 から 1.3.1 への変更点
+
+○変更点のリスト
+
+・スタックサイズのエラーチェックを追加
+ - CRE_TSKのstk(タスクのスタック領域の先頭番地)がNULLでない場合に,
+ stkszを適切な値(ターゲット依存の値の倍数)に丸める処理をやめ,適
+ 切な値でない場合にエラーとするように修正.
+ - DEF_ICSのistk(非タスクコンテキスト用のスタック領域の先頭番地)が
+ NULLでない場合に,istkszが適切な値(ターゲット依存の値の倍数)で
+ ない場合のエラーのチェックを追加.
+
+・強制待ち要求ネストの廃止に伴う追加修正
+ - TMAX_SUSCNTの定義を,kernel.hからitron.hに移動.
+ - ref_tskで参照できる情報(T_RTSKのフィールド)からsuscntを削除.
+
+・kernel_api.csvの修正
+ - 各オブジェクトの属性のパラメータを,符号無しに修正.
+
+・kernel_def.csvの修正
+ - 符号付きのシンボルの定義に",signed"を付加.
+
+・itron.hの修正
+ - frsm_tskのタイプミスの修正.
+
+・コンフィギュレータの修正
+ - 組込み関数DUMP, TRACE, NOOPを追加.
+ - $FOREACH$や$IF$等の中身が何もないときに,internal errorになる不具
+ 合を修正(エラーメッセージの適切化).
+ - $INCLUDE$命令でインクルードしたtfの行番号がずれる不具合を修正.
+ - 64ビット整数が定義されていないと,CSVファイルでsをつけたレコード
+ が符号付きと扱われない不具合の修正.
+ - 型キャストのパース処理に関する不具合の修正.
+ - エラーの起こった行番号が正しくない不具合の修正.
+ - 同じtskidに対してDEF_TEXが複数あるエラーのチェックを行うように修正.
+ - DEF_TEXを使用した時に,TSK.TSKID[tskid]が0になる不具合の修正.
+ - DEF_INH,CFG_INT,DEF_EXCで同じオブジェクト番号に対する登録が重複し
+ た場合のエラーチェックを二重に行っている問題の修正.
+
+・配布するファイルの修正
+ - doc/api_spec.txt, ngki_spec.txt, sysstat.txtを除外.
+ - extensionディレクトリを除外.
+
+・ドキュメントの修正,コメントの修正
+
+・バージョン番号の更新
+
+○ターゲット依存部の要修正箇所(1.3.0 → 1.3.1)
+
+(1) スタックサイズのエラーチェックに関する修正箇所
+ - target.tfでkernel.tfをインクルードする前に,CHECK_STKSZ_ALIGNを,
+ スタックサイズがどの値の倍数になっていなければならないかを設定す
+ る.
+ 例)$CHECK_STKSZ_ALIGN = 4$
+
+(2) ターゲット依存部のユーザーズマニュアルについて
+ - ターゲット依存部のユーザーズマニュアルのファイル名と,そのファイ
+ ルに記述すべき内容を規定した.「ターゲット依存部 ポーティングガイ
+ ド」の「9.1 ドキュメント」の節を参照すること.
+
+----------------------------------------------------------------------
+
+ TOPPERS/ASPカーネル
+ Release 1.2.1 から 1.3.0 への変更点
+
+○変更点のリスト
+
+・set_tim(システム時刻の設定)の廃止
+
+・属性の変更
+ - TA_DISINTを廃止して,TA_ENAINTを復活.
+
+・拡張機能・ターゲット定義機能の有無を判別するマクロ名の変更
+ - TOPPERS_EXTENSION_MUTEXをTOPPERS_SUPPORT_MUTEXに.
+ - TOPPERS_EXTENSION_PRI_LEVELをTOPPERS_SUPPORT_PRI_LEVELに.
+ - SUPPORT_???_???をTOPPERS_SUPPORT_???_???に変更し,ターゲット依存
+ 部での定義をtarget_kernel.hに移動する.
+
+・型名・変数名・定数名の変更
+ - SYSUTIM → SYSUTM,sysutim → sysutm,p_sysutim → p_sysutm
+ - SIO_ERDY_SND → SIO_RDY_SND,SIO_ERDY_RCV → SIO_RDY_RCV
+ - sio_ierdy_snd → sio_irdy_snd,sio_ierdy_rcv → sio_irdy_rcv
+
+・cfg1_out.cのコンパイル/リンク方法の変更
+ - cfg1_out.cからtarget_cfg1_out.hをインクルードするように,コンフィ
+ ギュレータを変更.
+ - ターゲット依存部でtarget_cfg1_out.hを用意する.
+ - cfg1_out.cのリンクは,カーネルと同じ方法をとるように変更.
+
+・コンフィギュレータの修正
+ - cfg1_out.cに生成する内容の変更(前記と関連).
+ - boost 1.35.0に対応.
+
+・サンプルプログラムの修正
+ - タスク内でのループ回数を固定する機能(TASK_LOOP)を導入.
+
+・バグフィックス
+ - 固定長メモリプール領域の確保方法.
+ - DEF_TEXのエラーで,問題になったDEF_TEXの行番号を表示する.
+
+・用語の変更
+ -「割込みロック」→「全割込みロック」
+
+・ドキュメントの修正
+
+・バージョン番号の更新.
+
+○ターゲット依存部の要修正箇所(1.2.1 → 1.3.0)
+
+(1) TA_DISINTの廃止・TA_ENAINTの復活に伴う修正箇所
+ - TA_DISINTを使った判定をTA_ENAINTを使った判定に変更する.
+ 例)((intatr & TA_DISINT) == 0U) → ((intatr & TA_ENAINT) != 0U)
+ - CFG_INTの割込み属性にTA_DISINTが設定されていれば,それを消す.
+ 例)CFG_INT(INTNO_SIO, { TA_DISINT | INTATR_SIO, INTPRI_SIO });
+ → CFG_INT(INTNO_SIO, { INTATR_SIO, INTPRI_SIO });
+ - CFG_INTの割込み属性にTA_DISINTが設定されていなければ,TA_ENAINTを
+ 加える.
+ 例)CFG_INT(INTNO_TIMER, { INTATR_TIMER, INTPRI_TIMER });
+ → CFG_INT(INTNO_TIMER, { TA_ENAINT | INTATR_TIMER, INTPRI_TIMER });
+
+(2) 拡張機能・ターゲット定義機能の有無を判別するマクロ名の変更に伴う修正箇所
+ - SUPPORT_???_???をTOPPERS_SUPPORT_???_???に変更し,ターゲット依存
+ 部での定義をtarget_kernel.hに移動する.
+ TOPPERS_SUPPORT_DIS_INT dis_intをサポートする
+ TOPPERS_SUPPORT_ENA_INT ena_intをサポートする
+ TOPPERS_SUPPORT_GET_UTM get_utmをサポートする
+ - makeoffset.cで,TOPPERS_EXTENSION_MUTEXを参照している場合には,
+ TOPPERS_SUPPORT_MUTEXに変更する.
+
+(3) 型名・変数名・定数名の変更に伴う修正箇所
+ - SYSUTIM → SYSUTM,sysutim → sysutm,p_sysutim → p_sysutm
+ - SIO_ERDY_SND → SIO_RDY_SND,SIO_ERDY_RCV → SIO_RDY_RCV
+ - sio_ierdy_snd → sio_irdy_snd,sio_ierdy_rcv → sio_irdy_rcv
+ ★sysutimとerdyを大文字小文字を区別せずにサーチするとよい.
+
+(4) cfg1_out.cのコンパイル/リンク方法の変更に伴う修正箇所
+ - ターゲット依存部で,target_cfg1_out.hを用意する.詳しくは,「ター
+ ゲット依存部 ポーティングガイド」の7.4節を参照.
+ - 新たに用意したファイルをMANIFESTに追加する.
+
+(5) 警告メッセージへの対処
+ - Makefile.targetに,「COPTS := $(COPTS) -Werror」を追加することを
+ 検討する.カーネル内で厳密な別名規則による警告メッセージが出る場
+ 合には,「KERNEL_CFLAGS := $(KERNEL_CFLAGS) -fno-strict-aliasing」
+ を追加してもよい.
+
+(6) コメントの修正
+ -「割込みロック」→「全割込みロック」
+
+----------------------------------------------------------------------
+
+ TOPPERS/ASPカーネル
+ Release 1.2.0 から 1.2.1 への変更点
+
+○変更点のリスト
+
+・トレースログ記録のサンプルコードを組み込む方法の変更
+ - configureに-rオプションを追加.
+ - sample/Makefileの修正.
+
+・Makefileのコンフィギュレータ関連部分の変更
+ - コンフィギュレータに対するターゲット依存のオプションを,Makefile
+ のターゲット依存部で記述するように変更.
+ - コンフィギュレータの各パスのターゲット依存のファイルへの依存関係
+ を,Makefileのターゲット依存部で記述するように変更.
+
+・バージョン番号の更新.
+
+○ターゲット依存部の要修正箇所(1.1.0 → 1.2.1)
+
+(1) 新しいコンフィギュレータへの対応
+
+・target.tf中で,ヘッダファイルと重複した定数値の定義を行っている場合に
+ は,target_def.cvsに変数記述を行い,重複した定義を削除する.
+
+・コンフィギュレータに対するオプションに,target_def.cvsを読み込ませる
+ 指定を追加する.「ターゲット依存部 ポーティングガイド」2.4節の
+ (2-4-15) 項を参照.
+
+・target_check.tfを作成する.「ターゲット依存部 ポーティングガイド」
+ 7.3節参照.
+
+・コンフィギュレータの各パスに対して,ターゲット依存のファイルへの依存
+ 関係を定義する.「ターゲット依存部 ポーティングガイド」2.7節参照.
+
+(2) データ型と定数の変更・追加
+
+・BOOLをbool_tに,TRUEとFALSEをそれぞれtrueとfalseに変更する.ER_BOOLな
+ どを変更しないように注意すること.コメント中に記述されたこれらのデー
+ タ型と定数も変更すること.
+
+・charをchar_tに変更する.ただし,文字列定数が記述されることが多い引数
+ 等は,コンパイラの警告を避けるために,char *のままとする.ターゲット
+ 依存部で最低限変更しなければならないのは,以下の2箇所.
+
+ - target_fput_logの引数
+ - sio_snd_chrの第2引数
+
+・target_stddef.h(またはそこからインクルードされるファイル)に,サイズ
+ の指定された浮動小数点型(float32_tとdouble64_t),その最大値・最小値
+ のマクロの定義を追加する.「ターゲット依存部 ポーティングガイド」3.4
+ 節参照.開発環境がGCCでarch/gcc/tool_stddef.hを用いており,float型と
+ double型がそれぞれIEEE754準拠の単精度浮動小数点数と倍精度浮動小数点数
+ である場合には,arch/gcc/tool_stddef.hをインクルードする前に,
+ TOPPERS_STDFLOAT_TYPE1をマクロ定義すればよい.
+
+(3) トレースログ記録のサンプルコードの組込み(オプション)
+
+・ターゲット依存部を,トレースログ記録のサンプルコードを使用するように
+ 修正する.「ターゲット依存部 ポーティングガイド」6.11.2節参照.
+
+(4) TARGETDIR変数の使用
+
+・Makefileのターゲット依存部で,ターゲット依存部ディレクトリを参照して
+ いる箇所で,$(SRCDIR)/target/$(TARGET)を,$(TARGETDIR)に変更する.
+
+----------------------------------------------------------------------
+
+ TOPPERS/ASPカーネル
+ Release 1.1.0 から 1.2.0 への変更点
+
+○変更点のリスト
+
+・コンフィギュレータを新しいバージョンに差し換え
+ - パス1とパス3にもターゲット依存機能を追加.
+ - FMPカーネルのクラス記述に対応.
+ - 追加ファイル(ターゲット非依存部,cfg以下を除く)
+ kernel/kernel_api.csv, kernel_def.csv, kernel_check.tf
+ - 追加ファイル(ターゲット依存部)
+ target_def.csv, target_check.tf
+ - sample/Makefileを新しいコンフィギュレータに対応させる.
+ - ミューテックス機能拡張でコンフィギュレータのmakeを不要に.
+
+・データ型と定数の変更・追加
+ - BOOL型をbool_t型に変更.
+ BOOL → bool_t,TRUE → true,FALSE → false
+ 従来の定義をitron.hに追加.
+ - char型をchar_t型に変更.
+ ただし,文字列定数が記述されることが多い引数等は,コンパイラの
+ 警告を避けるために,char *のままとする.
+ - float32_t, double64_tの追加.
+
+・テストプログラムの追加・修正
+ - システムコンフィギュレーションファイルからインクルードするコンフィ
+ ギュレーションファイルの整理(ボトムアップ順序に).
+ - テストプログラムの生成スクリプト(utils/gentest)を作成.
+ - ミューテックス機能のテストプログラムを生成スクリプト対応に.
+ - ミューテックス機能拡張にtest_mutex7を追加.
+
+・システムサービスのヘッダファイルのインクルード記述の整理
+ - syssvcの下のヘッダファイルは,#include "syssvc/??????.h"でインク
+ ルードする(??????.cからインクルードする場合を除く).
+ - Makefileから,-I$(SRCDIR)/syssvcを削除.
+
+・カーネル起動メッセージの出力(banner)機能の独立
+ - syssvc/banner.cfg, banner.hを作成.
+ - syslog.cfgから関連する記述を削除.
+
+・t_syslog.hとsyslog.hの役割の変更
+ - t_syslog.hは,システムログ出力を行うための定義を含むヘッダファイ
+ ルとし,システムログ機能を操作するための定義は,syslog.hに移す.
+
+・シリアルインタフェースドライバのフラッシュ方法の変更
+ - シリアルインタフェースドライバの強制フラッシュ機能は廃止し,未送
+ 信文字の取出し機能を新設.これを用いた強制フラッシュ処理は,シス
+ テムログタスクの終了処理ルーチン側で実施.
+
+・タスクディスパッチの要否の判定方法の変更
+ - タスクディスパッチの必要な状態にする関数を,すべて,タスクディス
+ パッチの要否を返すようにし,p_runtskとp_schedtskの比較による判定
+ をなるべく使わないように修正.
+
+・トレースログ記録のサンプルコードの使用方法を規定
+ - ポーティングガイドの6.11.2節に,ターゲット依存部でトレースログ記
+ 録のサンプルコードを使用する方法を規定.
+ - DVE68Kターゲット依存部をそれに従うように修正.
+
+・TARGETDIR変数の導入
+ - sample/Makefileで,ターゲット依存部ディレクトリを示す変数
+ TARGETDIRを定義.
+ - これを使うように,ターゲット依存部を修正.
+
+・その他のバグフィックス
+ - kernel_rename.def:log_???_entry → log_???_enter
+
+・その他の修正
+ - T_RLOG → T_SYSLOG_RLOG
+ - syssvcの下のヘッダファイルにもthrow()を入れる.
+ - makerelease:RELEAEディレクトリがなければ作る.
+
+・ドキュメントの充実.コメントの追加・修正.
+ - doc/migration.txtを作成(現時点では未完成).
+
+・バージョン番号の更新.
+
+○ターゲット依存部の要修正箇所(1.1.0 → 1.2.0)
+
+(1) 新しいコンフィギュレータへの対応
+
+・target.tf中で,ヘッダファイルと重複した定数値の定義を行っている場合に
+ は,target_def.cvsに変数記述を行い,重複した定義を削除する.
+
+・target_check.tfを作成する.「ターゲット依存部 ポーティングガイド」
+ 7.3節参照.
+
+(2) データ型と定数の変更・追加
+
+・BOOLをbool_tに,TRUEとFALSEをそれぞれtrueとfalseに変更する.ER_BOOLな
+ どを変更しないように注意すること.コメント中に記述されたこれらのデー
+ タ型と定数も変更すること.
+
+・charをchar_tに変更する.ただし,文字列定数が記述されることが多い引数
+ 等は,コンパイラの警告を避けるために,char *のままとする.ターゲット
+ 依存部で最低限変更しなければならないのは,以下の2箇所.
+
+ - target_fput_logの引数
+ - sio_snd_chrの第2引数
+
+・target_stddef.h(またはそこからインクルードされるファイル)に,サイズ
+ の指定された浮動小数点型(float32_tとdouble64_t),その最大値・最小値
+ のマクロの定義を追加する.「ターゲット依存部 ポーティングガイド」3.4
+ 節参照.開発環境がGCCでarch/gcc/tool_stddef.hを用いており,float型と
+ double型がそれぞれIEEE754準拠の単精度浮動小数点数と倍精度浮動小数点数
+ である場合には,arch/gcc/tool_stddef.hをインクルードする前に,
+ TOPPERS_STDFLOAT_TYPE1をマクロ定義すればよい.
+
+(3) トレースログ記録のサンプルコードの使用方法に従った修正(オプション)
+
+・ターゲット依存部を,トレースログ記録のサンプルコードを使用するように
+ 修正する.「ターゲット依存部 ポーティングガイド」6.11.2節参照.
+
+(4) TARGETDIR変数の使用
+
+・Makefileのターゲット依存部で,ターゲット依存部ディレクトリを参照して
+ いる箇所で,$(SRCDIR)/target/$(TARGET)を,$(TARGETDIR)に変更する.
+
+----------------------------------------------------------------------
+
+ TOPPERS/ASPカーネル
+ Release 1.0.0 から 1.1.0 への変更点
+
+○変更点のリスト
+
+・frsm_tskをカーネルから削除.itron.hにマクロ定義として残す
+
+・カーネルのトレースログ機能の改修
+ - トレースログマクロを使う側のファイルで,デフォルト定義を与える.
+ - nulltraceを廃止.logtraceを修正.
+ - ターゲット依存部でのトレースログ取得方法を標準化.
+ - INTHDR_ENTRYとEXCHDR_ENTRYにパラメータを追加.
+ - target_putcを,target_fput_logにリネーム.
+
+・システムログ機能をカーネルから外して,システムサービスの位置付けに
+ - syslog.c,syslog.h,banner.cを,kernelからsyssvcに移動.
+ - システムログ機能のサービスコールの名称にsyslog_を付加.
+
+・システムサービスのディレクトリの位置付けの明確化
+ - logtask.hとserial.hを,includeからsyssvcに移動.
+ - vasyslog.cを,libraryからsyssvcに移動.
+
+・リリースパッケージの形態を整備
+ - utils/makereleaseを作成.utils/genmanifestを削除.
+ - MANIFESTファイルに,パッケージ名とバージョン番号を記述.
+ - MANIFESTファイルのINCLUDE記述を変更.
+
+・出入口処理の番地の変数/フィールド名の変更
+ - 割込みハンドラ/CPU例外ハンドラの出入口処理の番地(FP型)の変数/
+ フィールド名をint_entry/exc_entryに変更.コメントも修正.
+
+・DVE68K/M68K依存部の修正.
+ - target.tf中のエラーメッセージの修正.
+ - logtraceを使うように修正.
+
+・その他の修正.
+ - 固定長メモリプール初期化ブロックの生成に関するバグを修正.
+ - configureで,cfgが生成されているかのチェックを厳密化.
+ - sample/Makefileにおいて,ライブラリに関する依存記述の修正.
+ - sample/sample1.cfgにおいて,システムサービスの定義順を変更.
+ - extension/MANIFESTに,MANIFESTを追加.
+
+・ドキュメントの充実.コメントの追加・修正.
+
+・バージョン番号の更新.
+
+○ターゲット依存部の修正箇所(1.0.0 → 1.1.0)
+
+・カーネルのトレースログ機能の中で,ターゲット依存部で実装する必要があ
+ るものを実装する.詳しくは,porting.txtの6.1.2節,6.5.2節,6.6.1節,
+ 6.7.1節を参照すること.
+
+・INTHDR_ENTRYとEXCHDR_ENTRYに2番目のパラメータが追加されたのに対応する.
+
+・TARGET_NAMEとCOPYRIGHT_TARGETを,target_config.hからtarget_syssvc.hに
+ 移動する.COPYRIGHT_TARGETはTARGET_COPYRIGHTにリネームする.
+
+・target_putcをtarget_fput_logにリネームし,その宣言をtarget_config.hか
+ らtarget_syssvc.hに移動する.関数定義は,target_config.cに置いたまま
+ でよい.関数宣言・定義の上のコメントを修正する.
+
+・割込みハンドラの出入口処理の番地(FP型)の変数/フィールド名をinthdr
+ からint_entryに,CPU例外ハンドラの出入口処理の番地(FP型)の変数/
+ フィールド名をexchdrからexct_entryに,それぞれ変更する.これに関連す
+ るx_define_inhとx_define_excのコメントを修正する.
+
+・トレースログを記録しない場合には,target_config.hから「#include
+ "nulltrace/trace_config.h"」を削除する.
+
+・トレースログを記録する場合には,target_syssvc.hに「#include
+ "logtrace/trace_config.h"」を追加する.また,target_config.h中の
+ 「#include "logtrace/trace_config.h"」の位置を前の方に移動する.
+
+・MANIFESTとE_PACKAGEを作成/修正する.MANIFEST中に,必要に応じて,
+ PACKAGEディレクティブとVERSIONディレクティブを追加する.また,
+ INCLUDEディレクティブのパラメータを,ディレクトリ名からファイル名に変
+ 更する.ターゲットシステム毎に,E_PACKAGEを作成する.詳しくは,
+ user.txtの2章とporting.txtの9.1節を参照すること.
+
+----------------------------------------------------------------------
--- /dev/null
+PACKAGE asp
+
+MANIFEST
+
+mutex/include/kernel.h
+
+mutex/kernel/Makefile.kernel
+mutex/kernel/allfunc.h
+mutex/kernel/check.h
+mutex/kernel/kernel.tf
+mutex/kernel/kernel_api.csv
+mutex/kernel/kernel_def.csv
+mutex/kernel/kernel_impl.h
+mutex/kernel/kernel_int.h
+mutex/kernel/kernel_rename.def
+mutex/kernel/kernel_rename.h
+mutex/kernel/kernel_unrename.h
+mutex/kernel/mutex.c
+mutex/kernel/mutex.h
+mutex/kernel/sys_manage.c
+mutex/kernel/task.c
+mutex/kernel/task.h
+mutex/kernel/task_manage.c
+mutex/kernel/task_refer.c
+
+mutex/test/bit_kernel.c
+mutex/test/bit_mutex.c
+mutex/test/test_mutex.h
+mutex/test/test_mutex1.c
+mutex/test/test_mutex1.cfg
+mutex/test/test_mutex2.c
+mutex/test/test_mutex2.cfg
+mutex/test/test_mutex3.c
+mutex/test/test_mutex3.cfg
+mutex/test/test_mutex4.c
+mutex/test/test_mutex4.cfg
+mutex/test/test_mutex4.h
+mutex/test/test_mutex5.c
+mutex/test/test_mutex5.cfg
+mutex/test/test_mutex5.h
+mutex/test/test_mutex6.c
+mutex/test/test_mutex6.cfg
+mutex/test/test_mutex6.h
+mutex/test/test_mutex7.c
+mutex/test/test_mutex7.cfg
+mutex/test/test_mutex7.h
+mutex/test/test_mutex8.c
+mutex/test/test_mutex8.cfg
+mutex/test/test_mutex8.h
+
+ovrhdr/include/kernel.h
+
+ovrhdr/kernel/Makefile.kernel
+ovrhdr/kernel/allfunc.h
+ovrhdr/kernel/check.h
+ovrhdr/kernel/kernel.tf
+ovrhdr/kernel/kernel_api.csv
+ovrhdr/kernel/kernel_int.h
+ovrhdr/kernel/kernel_rename.def
+ovrhdr/kernel/kernel_rename.h
+ovrhdr/kernel/kernel_unrename.h
+ovrhdr/kernel/overrun.c
+ovrhdr/kernel/overrun.h
+ovrhdr/kernel/task.c
+ovrhdr/kernel/task.h
+ovrhdr/kernel/task_manage.c
+
+ovrhdr/sample/sample1.c
+ovrhdr/sample/sample1.cfg
+ovrhdr/sample/sample1.h
+
+pri_level/include/kernel.h
+pri_level/kernel/kernel_rename.def
+pri_level/kernel/kernel_rename.h
+pri_level/kernel/kernel_unrename.h
+pri_level/kernel/task.c
+pri_level/kernel/task.h
+pri_level/test/test_task1.h
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: kernel.h 1862 2010-07-25 11:49:51Z ertl-hiro $
+ */
+
+/*
+ * TOPPERS/ASPカーネル 標準ヘッダファイル
+ *
+ * TOPPERS/ASPカーネルがサポートするサービスコールの宣言と,必要なデー
+ * タ型,定数,マクロの定義を含むヘッダファイル.
+ *
+ * アセンブリ言語のソースファイルからこのファイルをインクルードする時
+ * は,TOPPERS_MACRO_ONLYを定義しておく.これにより,マクロ定義以外を
+ * 除くようになっている.
+ *
+ * このファイルをインクルードする前にインクルードしておくべきファイル
+ * はない.
+ */
+
+#ifndef TOPPERS_KERNEL_H
+#define TOPPERS_KERNEL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * TOPPERS共通のデータ型・定数・マクロ
+ */
+#include <t_stddef.h>
+
+/*
+ * ターゲット依存部
+ */
+#include "target_kernel.h"
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ * データ型の定義
+ */
+
+/*
+ * ビットパターンやオブジェクト番号の型定義
+ */
+typedef uint_t TEXPTN; /* タスク例外要因のビットパターン */
+typedef uint_t FLGPTN; /* イベントフラグのビットパターン */
+typedef uint_t INTNO; /* 割込み番号 */
+typedef uint_t INHNO; /* 割込みハンドラ番号 */
+typedef uint_t EXCNO; /* CPU例外ハンドラ番号 */
+
+/*
+ * 処理単位の型定義
+ */
+typedef void (*TASK)(intptr_t exinf);
+typedef void (*TEXRTN)(TEXPTN texptn, intptr_t exinf);
+typedef void (*CYCHDR)(intptr_t exinf);
+typedef void (*ALMHDR)(intptr_t exinf);
+typedef void (*ISR)(intptr_t exinf);
+typedef void (*INTHDR)(void);
+typedef void (*EXCHDR)(void *p_excinf);
+typedef void (*INIRTN)(intptr_t exinf);
+typedef void (*TERRTN)(intptr_t exinf);
+
+/*
+ * メモリ領域確保のための型定義
+ */
+#ifndef TOPPERS_STK_T
+#define TOPPERS_STK_T intptr_t
+#endif /* TOPPERS_STK_T */
+typedef TOPPERS_STK_T STK_T; /* スタック領域を確保するための型 */
+
+#ifndef TOPPERS_MPF_T
+#define TOPPERS_MPF_T intptr_t
+#endif /* TOPPERS_MPF_T */
+typedef TOPPERS_MPF_T MPF_T; /* 固定長メモリプール領域を確保するための型 */
+
+/*
+ * メッセージヘッダの型定義
+ */
+typedef struct t_msg { /* メールボックスのメッセージヘッダ */
+ struct t_msg *pk_next;
+} T_MSG;
+
+typedef struct t_msg_pri { /* 優先度付きメッセージヘッダ */
+ T_MSG msgque; /* メッセージヘッダ */
+ PRI msgpri; /* メッセージ優先度 */
+} T_MSG_PRI;
+
+/*
+ * パケット形式の定義
+ */
+typedef struct t_rtsk {
+ STAT tskstat; /* タスク状態 */
+ PRI tskpri; /* タスクの現在優先度 */
+ PRI tskbpri; /* タスクのベース優先度 */
+ STAT tskwait; /* 待ち要因 */
+ ID wobjid; /* 待ち対象のオブジェクトのID */
+ TMO lefttmo; /* タイムアウトするまでの時間 */
+ uint_t actcnt; /* 起動要求キューイング数 */
+ uint_t wupcnt; /* 起床要求キューイング数 */
+} T_RTSK;
+
+typedef struct t_rtex {
+ STAT texstat; /* タスク例外処理の状態 */
+ TEXPTN pndptn; /* 保留例外要因 */
+} T_RTEX;
+
+typedef struct t_rsem {
+ ID wtskid; /* セマフォの待ち行列の先頭のタスクのID番号 */
+ uint_t semcnt; /* セマフォの現在の資源数 */
+} T_RSEM;
+
+typedef struct t_rflg {
+ ID wtskid; /* イベントフラグの待ち行列の先頭のタスクのID番号 */
+ FLGPTN flgptn; /* イベントフラグの現在のビットパターン */
+} T_RFLG;
+
+typedef struct t_rdtq {
+ ID stskid; /* データキューの送信待ち行列の先頭のタスクのID番号 */
+ ID rtskid; /* データキューの受信待ち行列の先頭のタスクのID番号 */
+ uint_t sdtqcnt; /* データキュー管理領域に格納されているデータの数 */
+} T_RDTQ;
+
+typedef struct t_rpdq {
+ ID stskid; /* 優先度データキューの送信待ち行列の先頭のタスク
+ のID番号 */
+ ID rtskid; /* 優先度データキューの受信待ち行列の先頭のタスク
+ のID番号 */
+ uint_t spdqcnt; /* 優先度データキュー管理領域に格納されているデー
+ タの数 */
+} T_RPDQ;
+
+typedef struct t_rmbx {
+ ID wtskid; /* メールボックスの待ち行列の先頭のタスクのID番号 */
+ T_MSG *pk_msg; /* メッセージキューの先頭につながれたメッセージ
+ の先頭番地 */
+} T_RMBX;
+
+typedef struct t_rmtx {
+ ID htskid; /* ミューテックスをロックしているタスクのID番号 */
+ ID wtskid; /* ミューテックスの待ち行列の先頭のタスクのID番号 */
+} T_RMTX;
+
+typedef struct t_rmpf {
+ ID wtskid; /* 固定長メモリプールの待ち行列の先頭のタスクの
+ ID番号 */
+ uint_t fblkcnt; /* 固定長メモリプール領域の空きメモリ領域に割り
+ 付けることができる固定長メモリブロックの数 */
+} T_RMPF;
+
+typedef struct t_rcyc {
+ STAT cycstat; /* 周期ハンドラの動作状態 */
+ RELTIM lefttim; /* 次に周期ハンドラを起動する時刻までの相対時間 */
+} T_RCYC;
+
+typedef struct t_ralm {
+ STAT almstat; /* アラームハンドラの動作状態 */
+ RELTIM lefttim; /* アラームハンドラを起動する時刻までの相対時間 */
+} T_RALM;
+
+/*
+ * サービスコールの宣言
+ */
+
+/*
+ * タスク管理機能
+ */
+extern ER act_tsk(ID tskid) throw();
+extern ER iact_tsk(ID tskid) throw();
+extern ER_UINT can_act(ID tskid) throw();
+extern ER ext_tsk(void) throw();
+extern ER ter_tsk(ID tskid) throw();
+extern ER chg_pri(ID tskid, PRI tskpri) throw();
+extern ER get_pri(ID tskid, PRI *p_tskpri) throw();
+extern ER get_inf(intptr_t *p_exinf) throw();
+extern ER ref_tsk(ID tskid, T_RTSK *pk_rtsk) throw();
+
+/*
+ * タスク付属同期機能
+ */
+extern ER slp_tsk(void) throw();
+extern ER tslp_tsk(TMO tmout) throw();
+extern ER wup_tsk(ID tskid) throw();
+extern ER iwup_tsk(ID tskid) throw();
+extern ER_UINT can_wup(ID tskid) throw();
+extern ER rel_wai(ID tskid) throw();
+extern ER irel_wai(ID tskid) throw();
+extern ER sus_tsk(ID tskid) throw();
+extern ER rsm_tsk(ID tskid) throw();
+extern ER dly_tsk(RELTIM dlytim) throw();
+
+/*
+ * タスク例外処理機能
+ */
+extern ER ras_tex(ID tskid, TEXPTN rasptn) throw();
+extern ER iras_tex(ID tskid, TEXPTN rasptn) throw();
+extern ER dis_tex(void) throw();
+extern ER ena_tex(void) throw();
+extern bool_t sns_tex(void) throw();
+extern ER ref_tex(ID tskid, T_RTEX *pk_rtex) throw();
+
+/*
+ * 同期・通信機能
+ */
+extern ER sig_sem(ID semid) throw();
+extern ER isig_sem(ID semid) throw();
+extern ER wai_sem(ID semid) throw();
+extern ER pol_sem(ID semid) throw();
+extern ER twai_sem(ID semid, TMO tmout) throw();
+extern ER ini_sem(ID semid) throw();
+extern ER ref_sem(ID semid, T_RSEM *pk_rsem) throw();
+
+extern ER set_flg(ID flgid, FLGPTN setptn) throw();
+extern ER iset_flg(ID flgid, FLGPTN setptn) throw();
+extern ER clr_flg(ID flgid, FLGPTN clrptn) throw();
+extern ER wai_flg(ID flgid, FLGPTN waiptn,
+ MODE wfmode, FLGPTN *p_flgptn) throw();
+extern ER pol_flg(ID flgid, FLGPTN waiptn,
+ MODE wfmode, FLGPTN *p_flgptn) throw();
+extern ER twai_flg(ID flgid, FLGPTN waiptn,
+ MODE wfmode, FLGPTN *p_flgptn, TMO tmout) throw();
+extern ER ini_flg(ID flgid) throw();
+extern ER ref_flg(ID flgid, T_RFLG *pk_rflg) throw();
+
+extern ER snd_dtq(ID dtqid, intptr_t data) throw();
+extern ER psnd_dtq(ID dtqid, intptr_t data) throw();
+extern ER ipsnd_dtq(ID dtqid, intptr_t data) throw();
+extern ER tsnd_dtq(ID dtqid, intptr_t data, TMO tmout) throw();
+extern ER fsnd_dtq(ID dtqid, intptr_t data) throw();
+extern ER ifsnd_dtq(ID dtqid, intptr_t data) throw();
+extern ER rcv_dtq(ID dtqid, intptr_t *p_data) throw();
+extern ER prcv_dtq(ID dtqid, intptr_t *p_data) throw();
+extern ER trcv_dtq(ID dtqid, intptr_t *p_data, TMO tmout) throw();
+extern ER ini_dtq(ID dtqid) throw();
+extern ER ref_dtq(ID dtqid, T_RDTQ *pk_rdtq) throw();
+
+extern ER snd_pdq(ID pdqid, intptr_t data, PRI datapri) throw();
+extern ER psnd_pdq(ID pdqid, intptr_t data, PRI datapri) throw();
+extern ER ipsnd_pdq(ID pdqid, intptr_t data, PRI datapri) throw();
+extern ER tsnd_pdq(ID pdqid, intptr_t data,
+ PRI datapri, TMO tmout) throw();
+extern ER rcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri) throw();
+extern ER prcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri) throw();
+extern ER trcv_pdq(ID pdqid, intptr_t *p_data,
+ PRI *p_datapri, TMO tmout) throw();
+extern ER ini_pdq(ID pdqid) throw();
+extern ER ref_pdq(ID pdqid, T_RPDQ *pk_rpdq) throw();
+
+extern ER snd_mbx(ID mbxid, T_MSG *pk_msg) throw();
+extern ER rcv_mbx(ID mbxid, T_MSG **ppk_msg) throw();
+extern ER prcv_mbx(ID mbxid, T_MSG **ppk_msg) throw();
+extern ER trcv_mbx(ID mbxid, T_MSG **ppk_msg, TMO tmout) throw();
+extern ER ini_mbx(ID mbxid) throw();
+extern ER ref_mbx(ID mbxid, T_RMBX *pk_rmbx) throw();
+
+extern ER loc_mtx(ID mtxid) throw();
+extern ER ploc_mtx(ID mtxid) throw();
+extern ER tloc_mtx(ID mtxid, TMO tmout) throw();
+extern ER unl_mtx(ID mtxid) throw();
+extern ER ini_mtx(ID mtxid) throw();
+extern ER ref_mtx(ID mtxid, T_RMTX *pk_rmtx) throw();
+
+/*
+ * メモリプール管理機能
+ */
+extern ER get_mpf(ID mpfid, void **p_blk) throw();
+extern ER pget_mpf(ID mpfid, void **p_blk) throw();
+extern ER tget_mpf(ID mpfid, void **p_blk, TMO tmout) throw();
+extern ER rel_mpf(ID mpfid, void *blk) throw();
+extern ER ini_mpf(ID mpfid) throw();
+extern ER ref_mpf(ID mpfid, T_RMPF *pk_rmpf) throw();
+
+/*
+ * 時間管理機能
+ */
+extern ER get_tim(SYSTIM *p_systim) throw();
+extern ER get_utm(SYSUTM *p_sysutm) throw();
+
+extern ER sta_cyc(ID cycid) throw();
+extern ER stp_cyc(ID cycid) throw();
+extern ER ref_cyc(ID cycid, T_RCYC *pk_rcyc) throw();
+
+extern ER sta_alm(ID almid, RELTIM almtim) throw();
+extern ER ista_alm(ID almid, RELTIM almtim) throw();
+extern ER stp_alm(ID almid) throw();
+extern ER istp_alm(ID almid) throw();
+extern ER ref_alm(ID almid, T_RALM *pk_ralm) throw();
+
+/*
+ * システム状態管理機能
+ */
+extern ER rot_rdq(PRI tskpri) throw();
+extern ER irot_rdq(PRI tskpri) throw();
+extern ER get_tid(ID *p_tskid) throw();
+extern ER iget_tid(ID *p_tskid) throw();
+extern ER loc_cpu(void) throw();
+extern ER iloc_cpu(void) throw();
+extern ER unl_cpu(void) throw();
+extern ER iunl_cpu(void) throw();
+extern ER dis_dsp(void) throw();
+extern ER ena_dsp(void) throw();
+extern bool_t sns_ctx(void) throw();
+extern bool_t sns_loc(void) throw();
+extern bool_t sns_dsp(void) throw();
+extern bool_t sns_dpn(void) throw();
+extern bool_t sns_ker(void) throw();
+extern ER ext_ker(void) throw();
+
+/*
+ * 割込み管理機能
+ */
+extern ER dis_int(INTNO intno) throw();
+extern ER ena_int(INTNO intno) throw();
+extern ER chg_ipm(PRI intpri) throw();
+extern ER get_ipm(PRI *p_intpri) throw();
+
+/*
+ * CPU例外管理機能
+ */
+extern bool_t xsns_dpn(void *p_excinf) throw();
+extern bool_t xsns_xpn(void *p_excinf) throw();
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ * オブジェクト属性の定義
+ */
+#define TA_ACT UINT_C(0x02) /* タスクを起動された状態で生成 */
+
+#define TA_TPRI UINT_C(0x01) /* タスクの待ち行列を優先度順に */
+#define TA_MPRI UINT_C(0x02) /* メッセージキューを優先度順に */
+
+#define TA_WMUL UINT_C(0x02) /* 複数の待ちタスク */
+#define TA_CLR UINT_C(0x04) /* イベントフラグのクリア指定 */
+
+#define TA_CEILING UINT_C(0x03) /* 優先度上限プロトコル */
+
+#define TA_STA UINT_C(0x02) /* 周期ハンドラを動作状態で生成 */
+
+#define TA_NONKERNEL UINT_C(0x02) /* カーネル管理外の割込み */
+
+#define TA_ENAINT UINT_C(0x01) /* 割込み要求禁止フラグをクリア */
+#define TA_EDGE UINT_C(0x02) /* エッジトリガ */
+
+/*
+ * サービスコールの動作モードの定義
+ */
+#define TWF_ORW UINT_C(0x01) /* イベントフラグのOR待ち */
+#define TWF_ANDW UINT_C(0x02) /* イベントフラグのAND待ち */
+
+/*
+ * オブジェクトの状態の定義
+ */
+#define TTS_RUN UINT_C(0x01) /* 実行状態 */
+#define TTS_RDY UINT_C(0x02) /* 実行可能状態 */
+#define TTS_WAI UINT_C(0x04) /* 待ち状態 */
+#define TTS_SUS UINT_C(0x08) /* 強制待ち状態 */
+#define TTS_WAS UINT_C(0x0c) /* 二重待ち状態 */
+#define TTS_DMT UINT_C(0x10) /* 休止状態 */
+
+#define TTW_SLP UINT_C(0x0001) /* 起床待ち */
+#define TTW_DLY UINT_C(0x0002) /* 時間経過待ち */
+#define TTW_SEM UINT_C(0x0004) /* セマフォの資源獲得待ち */
+#define TTW_FLG UINT_C(0x0008) /* イベントフラグ待ち */
+#define TTW_SDTQ UINT_C(0x0010) /* データキューへの送信待ち */
+#define TTW_RDTQ UINT_C(0x0020) /* データキューからの受信待ち */
+#define TTW_SPDQ UINT_C(0x0100) /* 優先度データキューへの送信待ち */
+#define TTW_RPDQ UINT_C(0x0200) /* 優先度データキューからの受信待ち */
+#define TTW_MBX UINT_C(0x0040) /* メールボックスからの受信待ち */
+#define TTW_MPF UINT_C(0x2000) /* 固定長メモリブロックの獲得待ち */
+
+#define TTEX_ENA UINT_C(0x01) /* タスク例外処理許可状態 */
+#define TTEX_DIS UINT_C(0x02) /* タスク例外処理禁止状態 */
+
+#define TCYC_STP UINT_C(0x01) /* 周期ハンドラが動作していない */
+#define TCYC_STA UINT_C(0x02) /* 周期ハンドラが動作している */
+
+#define TALM_STP UINT_C(0x01) /* アラームハンドラが動作していない */
+#define TALM_STA UINT_C(0x02) /* アラームハンドラが動作している */
+
+/*
+ * その他の定数の定義
+ */
+#define TSK_SELF 0 /* 自タスク指定 */
+#define TSK_NONE 0 /* 該当するタスクがない */
+
+#define TPRI_SELF 0 /* 自タスクのベース優先度 */
+#define TPRI_INI 0 /* タスクの起動時優先度 */
+
+#define TIPM_ENAALL 0 /* 割込み優先度マスク全解除 */
+
+/*
+ * 構成定数とマクロ
+ */
+
+/*
+ * サポートする機能
+ */
+#ifdef TOPPERS_TARGET_SUPPORT_DIS_INT
+#define TOPPERS_SUPPORT_DIS_INT /* dis_intがサポートされている */
+#endif /* TOPPERS_TARGET_SUPPORT_DIS_INT */
+
+#ifdef TOPPERS_TARGET_SUPPORT_ENA_INT
+#define TOPPERS_SUPPORT_ENA_INT /* ena_intがサポートされている */
+#endif /* TOPPERS_TARGET_SUPPORT_ENA_INT */
+
+#ifdef TOPPERS_TARGET_SUPPORT_GET_UTM
+#define TOPPERS_SUPPORT_GET_UTM /* get_utmがサポートされている */
+#endif /* TOPPERS_TARGET_SUPPORT_GET_UTM */
+
+#define TOPPERS_SUPPORT_MUTEX /* ミューテックス機能拡張 */
+
+/*
+ * 優先度の範囲
+ */
+#define TMIN_TPRI 1 /* タスク優先度の最小値(最高値)*/
+#define TMAX_TPRI 16 /* タスク優先度の最大値(最低値)*/
+#define TMIN_DPRI 1 /* データ優先度の最小値(最高値)*/
+#define TMAX_DPRI 16 /* データ優先度の最大値(最低値)*/
+#define TMIN_MPRI 1 /* メッセージ優先度の最小値(最高値)*/
+#define TMAX_MPRI 16 /* メッセージ優先度の最大値(最低値)*/
+#define TMIN_ISRPRI 1 /* 割込みサービスルーチン優先度の最小値 */
+#define TMAX_ISRPRI 16 /* 割込みサービスルーチン優先度の最大値 */
+
+/*
+ * バージョン情報
+ */
+#define TKERNEL_MAKER UINT_C(0x0118) /* カーネルのメーカーコード */
+#define TKERNEL_PRID UINT_C(0x0007) /* カーネルの識別番号 */
+#define TKERNEL_SPVER UINT_C(0xf512) /* カーネル仕様のバージョン番号 */
+#define TKERNEL_PRVER UINT_C(0x1060) /* カーネルのバージョン番号 */
+
+/*
+ * キューイング回数の最大値
+ */
+#define TMAX_ACTCNT UINT_C(1) /* 起動要求キューイング数の最大値 */
+#define TMAX_WUPCNT UINT_C(1) /* 起床要求キューイング数の最大値 */
+
+/*
+ * ビットパターンのビット数
+ */
+#ifndef TBIT_TEXPTN /* タスク例外要因のビット数 */
+#define TBIT_TEXPTN (sizeof(TEXPTN) * CHAR_BIT)
+#endif /* TBIT_TEXPTN */
+
+#ifndef TBIT_FLGPTN /* イベントフラグのビット数 */
+#define TBIT_FLGPTN (sizeof(FLGPTN) * CHAR_BIT)
+#endif /* TBIT_FLGPTN */
+
+/*
+ * メモリ領域確保のためのマクロ
+ *
+ * 以下のTOPPERS_COUNT_SZとTOPPERS_ROUND_SZの定義は,unitが2の巾乗であ
+ * ることを仮定している.
+ */
+#ifndef TOPPERS_COUNT_SZ
+#define TOPPERS_COUNT_SZ(sz, unit) (((sz) + (unit) - 1) / (unit))
+#endif /* TOPPERS_COUNT_SZ */
+#ifndef TOPPERS_ROUND_SZ
+#define TOPPERS_ROUND_SZ(sz, unit) (((sz) + (unit) - 1) & ~((unit) - 1))
+#endif /* TOPPERS_ROUND_SZ */
+
+#define COUNT_STK_T(sz) TOPPERS_COUNT_SZ(sz, sizeof(STK_T))
+#define ROUND_STK_T(sz) TOPPERS_ROUND_SZ(sz, sizeof(STK_T))
+
+#define COUNT_MPF_T(blksz) TOPPERS_COUNT_SZ(blksz, sizeof(MPF_T))
+#define ROUND_MPF_T(blksz) TOPPERS_ROUND_SZ(blksz, sizeof(MPF_T))
+
+/*
+ * その他の構成定数
+ */
+#define TMAX_MAXSEM UINT_MAX /* セマフォの最大資源数の最大値 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_KERNEL_H */
--- /dev/null
+#
+# TOPPERS/ASP Kernel
+# Toyohashi Open Platform for Embedded Real-Time Systems/
+# Advanced Standard Profile Kernel
+#
+# Copyright (C) 2003 by Embedded and Real-Time Systems Laboratory
+# Toyohashi Univ. of Technology, JAPAN
+# Copyright (C) 2005-2009 by Embedded and Real-Time Systems Laboratory
+# Graduate School of Information Science, Nagoya Univ., JAPAN
+#
+# 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+# スコード中に含まれていること.
+# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+# の無保証規定を掲載すること.
+# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+# と.
+# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+# 作権表示,この利用条件および下記の無保証規定を掲載すること.
+# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+# 報告すること.
+# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+# 免責すること.
+#
+# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+# の責任を負わない.
+#
+# @(#) $Id: Makefile.kernel 1694 2010-01-01 15:59:09Z ertl-hiro $
+#
+
+#
+# カーネルのファイル構成の定義
+#
+
+#
+# 1つのソースファイルから複数のオブジェクトファイルを生成するように作
+# 成されたソースファイルのリスト
+#
+KERNEL_FCSRCS = startup.c task.c wait.c time_event.c \
+ task_manage.c task_refer.c task_sync.c task_except.c \
+ semaphore.c eventflag.c dataqueue.c pridataq.c mailbox.c \
+ mutex.c mempfix.c time_manage.c cyclic.c alarm.c \
+ sys_manage.c interrupt.c exception.c
+
+#
+# 各ソースファイルから生成されるオブジェクトファイルのリスト
+#
+startup = sta_ker.o ext_ker.o
+
+task = tskini.o tsksched.o tskrun.o tsknrun.o \
+ tskdmt.o tskact.o tskpri.o tskrot.o tsktex.o
+
+wait = waimake.o waicmp.o waitmo.o waitmook.o \
+ wairel.o wobjwai.o wobjwaitmo.o iniwque.o
+
+time_event = tmeini.o tmeup.o tmedown.o tmeins.o tmedel.o tmeltim.o sigtim.o
+
+task_manage = act_tsk.o iact_tsk.o can_act.o ext_tsk.o ter_tsk.o \
+ chg_pri.o get_pri.o get_inf.o
+
+task_refer = ref_tsk.o
+
+task_sync = slp_tsk.o tslp_tsk.o wup_tsk.o iwup_tsk.o can_wup.o \
+ rel_wai.o irel_wai.o sus_tsk.o rsm_tsk.o dly_tsk.o
+
+task_except = ras_tex.o iras_tex.o dis_tex.o ena_tex.o sns_tex.o ref_tex.o
+
+semaphore = semini.o sig_sem.o isig_sem.o \
+ wai_sem.o pol_sem.o twai_sem.o ini_sem.o ref_sem.o
+
+eventflag = flgini.o flgcnd.o set_flg.o iset_flg.o clr_flg.o \
+ wai_flg.o pol_flg.o twai_flg.o ini_flg.o ref_flg.o
+
+dataqueue = dtqini.o dtqenq.o dtqfenq.o dtqdeq.o dtqsnd.o dtqfsnd.o dtqrcv.o \
+ snd_dtq.o psnd_dtq.o ipsnd_dtq.o tsnd_dtq.o fsnd_dtq.o ifsnd_dtq.o \
+ rcv_dtq.o prcv_dtq.o trcv_dtq.o ini_dtq.o ref_dtq.o
+
+pridataq = pdqini.o pdqenq.o pdqdeq.o pdqsnd.o pdqrcv.o \
+ snd_pdq.o psnd_pdq.o ipsnd_pdq.o tsnd_pdq.o \
+ rcv_pdq.o prcv_pdq.o trcv_pdq.o ini_pdq.o ref_pdq.o
+
+mailbox = mbxini.o snd_mbx.o rcv_mbx.o prcv_mbx.o trcv_mbx.o \
+ ini_mbx.o ref_mbx.o
+
+mutex = mtxhook.o mtxini.o mtxchk.o mtxscan.o mtxcalc.o mtxrel.o mtxrela.o \
+ loc_mtx.o ploc_mtx.o tloc_mtx.o unl_mtx.o ini_mtx.o ref_mtx.o
+
+mempfix = mpfini.o mpfget.o get_mpf.o pget_mpf.o tget_mpf.o \
+ rel_mpf.o ini_mpf.o ref_mpf.o
+
+time_manage = get_tim.o get_utm.o
+
+cyclic = cycini.o sta_cyc.o stp_cyc.o ref_cyc.o cyccal.o
+
+alarm = almini.o sta_alm.o ista_alm.o stp_alm.o istp_alm.o ref_alm.o almcal.o
+
+sys_manage = rot_rdq.o irot_rdq.o get_tid.o iget_tid.o \
+ loc_cpu.o iloc_cpu.o unl_cpu.o iunl_cpu.o dis_dsp.o ena_dsp.o \
+ sns_ctx.o sns_loc.o sns_dsp.o sns_dpn.o sns_ker.o
+
+interrupt = intini.o dis_int.o ena_int.o chg_ipm.o get_ipm.o
+
+exception = excini.o xsns_dpn.o xsns_xpn.o
+
+#
+# 生成されるオブジェクトファイルの依存関係の定義
+#
+$(startup) $(startup:.o=.s) $(startup:.o=.d): startup.c
+$(task) $(task:.o=.s) $(task:.o=.d): task.c
+$(wait) $(wait:.o=.s) $(wait:.o=.d): wait.c
+$(time_event) $(time_event:.o=.s) $(time_event:.o=.d): time_event.c
+$(task_manage) $(task_manage:.o=.s) $(task_manage:.o=.d): task_manage.c
+$(task_refer) $(task_refer:.o=.s) $(task_refer:.o=.d): task_refer.c
+$(task_sync) $(task_sync:.o=.s) $(task_sync:.o=.d): task_sync.c
+$(task_except) $(task_except:.o=.s) $(task_except:.o=.d): task_except.c
+$(semaphore) $(semaphore:.o=.s) $(semaphore:.o=.d): semaphore.c
+$(eventflag) $(eventflag:.o=.s) $(eventflag:.o=.d): eventflag.c
+$(dataqueue) $(dataqueue:.o=.s) $(dataqueue:.o=.d): dataqueue.c
+$(pridataq) $(pridataq:.o=.s) $(pridataq:.o=.d): pridataq.c
+$(mailbox) $(mailbox:.o=.s) $(mailbox:.o=.d): mailbox.c
+$(mutex) $(mutex:.o=.s) $(mutex:.o=.d): mutex.c
+$(mempfix) $(mempfix:.o=.s) $(mempfix:.o=.d): mempfix.c
+$(time_manage) $(time_manage:.o=.s) $(time_manage:.o=.d): time_manage.c
+$(cyclic) $(cyclic:.o=.s) $(cyclic:.o=.d): cyclic.c
+$(alarm) $(alarm:.o=.s) $(alarm:.o=.d): alarm.c
+$(sys_manage) $(sys_manage:.o=.s) $(sys_manage:.o=.d): sys_manage.c
+$(interrupt) $(interrupt:.o=.s) $(interrupt:.o=.d): interrupt.c
+$(exception) $(exception:.o=.s) $(exception:.o=.d): exception.c
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2005-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: allfunc.h 1694 2010-01-01 15:59:09Z ertl-hiro $
+ */
+
+/*
+ * すべての関数をコンパイルするための定義
+ */
+
+#ifndef TOPPERS_ALLFUNC_H
+#define TOPPERS_ALLFUNC_H
+
+/* startup.c */
+#define TOPPERS_sta_ker
+#define TOPPERS_ext_ker
+
+/* task.c */
+#define TOPPERS_tskini
+#define TOPPERS_tsksched
+#define TOPPERS_tskrun
+#define TOPPERS_tsknrun
+#define TOPPERS_tskdmt
+#define TOPPERS_tskact
+#define TOPPERS_tskpri
+#define TOPPERS_tskrot
+#define TOPPERS_tsktex
+
+/* wait.c */
+#define TOPPERS_waimake
+#define TOPPERS_waicmp
+#define TOPPERS_waitmo
+#define TOPPERS_waitmook
+#define TOPPERS_wairel
+#define TOPPERS_wobjwai
+#define TOPPERS_wobjwaitmo
+#define TOPPERS_iniwque
+
+/* time_event.c */
+#define TOPPERS_tmeini
+#define TOPPERS_tmeup
+#define TOPPERS_tmedown
+#define TOPPERS_tmeins
+#define TOPPERS_tmedel
+#define TOPPERS_tmeltim
+#define TOPPERS_sigtim
+
+/* task_manage.c */
+#define TOPPERS_act_tsk
+#define TOPPERS_iact_tsk
+#define TOPPERS_can_act
+#define TOPPERS_ext_tsk
+#define TOPPERS_ter_tsk
+#define TOPPERS_chg_pri
+#define TOPPERS_get_pri
+#define TOPPERS_get_inf
+
+/* task_refer.c */
+#define TOPPERS_ref_tsk
+
+/* task_sync.c */
+#define TOPPERS_slp_tsk
+#define TOPPERS_tslp_tsk
+#define TOPPERS_wup_tsk
+#define TOPPERS_iwup_tsk
+#define TOPPERS_can_wup
+#define TOPPERS_rel_wai
+#define TOPPERS_irel_wai
+#define TOPPERS_sus_tsk
+#define TOPPERS_rsm_tsk
+#define TOPPERS_dly_tsk
+
+/* task_except.c */
+#define TOPPERS_ras_tex
+#define TOPPERS_iras_tex
+#define TOPPERS_dis_tex
+#define TOPPERS_ena_tex
+#define TOPPERS_sns_tex
+#define TOPPERS_ref_tex
+
+/* semaphore.c */
+#define TOPPERS_semini
+#define TOPPERS_sig_sem
+#define TOPPERS_isig_sem
+#define TOPPERS_wai_sem
+#define TOPPERS_pol_sem
+#define TOPPERS_twai_sem
+#define TOPPERS_ini_sem
+#define TOPPERS_ref_sem
+
+/* eventflag.c */
+#define TOPPERS_flgini
+#define TOPPERS_flgcnd
+#define TOPPERS_set_flg
+#define TOPPERS_iset_flg
+#define TOPPERS_clr_flg
+#define TOPPERS_wai_flg
+#define TOPPERS_pol_flg
+#define TOPPERS_twai_flg
+#define TOPPERS_ini_flg
+#define TOPPERS_ref_flg
+
+/* dataqueue.c */
+#define TOPPERS_dtqini
+#define TOPPERS_dtqenq
+#define TOPPERS_dtqfenq
+#define TOPPERS_dtqdeq
+#define TOPPERS_dtqsnd
+#define TOPPERS_dtqfsnd
+#define TOPPERS_dtqrcv
+#define TOPPERS_snd_dtq
+#define TOPPERS_psnd_dtq
+#define TOPPERS_ipsnd_dtq
+#define TOPPERS_tsnd_dtq
+#define TOPPERS_fsnd_dtq
+#define TOPPERS_ifsnd_dtq
+#define TOPPERS_rcv_dtq
+#define TOPPERS_prcv_dtq
+#define TOPPERS_trcv_dtq
+#define TOPPERS_ini_dtq
+#define TOPPERS_ref_dtq
+
+/* pridataq.c */
+#define TOPPERS_pdqini
+#define TOPPERS_pdqenq
+#define TOPPERS_pdqdeq
+#define TOPPERS_pdqsnd
+#define TOPPERS_pdqrcv
+#define TOPPERS_snd_pdq
+#define TOPPERS_psnd_pdq
+#define TOPPERS_ipsnd_pdq
+#define TOPPERS_tsnd_pdq
+#define TOPPERS_rcv_pdq
+#define TOPPERS_prcv_pdq
+#define TOPPERS_trcv_pdq
+#define TOPPERS_ini_pdq
+#define TOPPERS_ref_pdq
+
+/* mailbox.c */
+#define TOPPERS_mbxini
+#define TOPPERS_snd_mbx
+#define TOPPERS_rcv_mbx
+#define TOPPERS_prcv_mbx
+#define TOPPERS_trcv_mbx
+#define TOPPERS_ini_mbx
+#define TOPPERS_ref_mbx
+
+/* mutex.c */
+#define TOPPERS_mtxhook
+#define TOPPERS_mtxini
+#define TOPPERS_mtxchk
+#define TOPPERS_mtxscan
+#define TOPPERS_mtxcalc
+#define TOPPERS_mtxrel
+#define TOPPERS_mtxrela
+#define TOPPERS_loc_mtx
+#define TOPPERS_ploc_mtx
+#define TOPPERS_tloc_mtx
+#define TOPPERS_unl_mtx
+#define TOPPERS_ini_mtx
+#define TOPPERS_ref_mtx
+
+/* mempfix.c */
+#define TOPPERS_mpfini
+#define TOPPERS_mpfget
+#define TOPPERS_get_mpf
+#define TOPPERS_pget_mpf
+#define TOPPERS_tget_mpf
+#define TOPPERS_rel_mpf
+#define TOPPERS_ini_mpf
+#define TOPPERS_ref_mpf
+
+/* time_manage.c */
+#define TOPPERS_get_tim
+#define TOPPERS_get_utm
+
+/* cyclic.c */
+#define TOPPERS_cycini
+#define TOPPERS_sta_cyc
+#define TOPPERS_stp_cyc
+#define TOPPERS_ref_cyc
+#define TOPPERS_cyccal
+
+/* alarm.c */
+#define TOPPERS_almini
+#define TOPPERS_sta_alm
+#define TOPPERS_ista_alm
+#define TOPPERS_stp_alm
+#define TOPPERS_istp_alm
+#define TOPPERS_ref_alm
+#define TOPPERS_almcal
+
+/* sys_manage.c */
+#define TOPPERS_rot_rdq
+#define TOPPERS_irot_rdq
+#define TOPPERS_get_tid
+#define TOPPERS_iget_tid
+#define TOPPERS_loc_cpu
+#define TOPPERS_iloc_cpu
+#define TOPPERS_unl_cpu
+#define TOPPERS_iunl_cpu
+#define TOPPERS_dis_dsp
+#define TOPPERS_ena_dsp
+#define TOPPERS_sns_ctx
+#define TOPPERS_sns_loc
+#define TOPPERS_sns_dsp
+#define TOPPERS_sns_dpn
+#define TOPPERS_sns_ker
+
+/* interrupt.c */
+#define TOPPERS_intini
+#define TOPPERS_dis_int
+#define TOPPERS_ena_int
+#define TOPPERS_chg_ipm
+#define TOPPERS_get_ipm
+
+/* exception.c */
+#define TOPPERS_excini
+#define TOPPERS_xsns_dpn
+#define TOPPERS_xsns_xpn
+
+#endif /* TOPPERS_ALLFUNC_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: check.h 1139 2008-06-19 07:03:34Z ertl-hiro $
+ */
+
+/*
+ * エラーチェック用マクロ
+ */
+
+#ifndef TOPPERS_CHECK_H
+#define TOPPERS_CHECK_H
+
+/*
+ * 優先度の範囲の判定
+ */
+#define VALID_TPRI(tpri) (TMIN_TPRI <= (tpri) && (tpri) <= TMAX_TPRI)
+
+#ifndef VALID_INTPRI_CHGIPM
+#define VALID_INTPRI_CHGIPM(intpri) \
+ (TMIN_INTPRI <= (intpri) && (intpri) <= TIPM_ENAALL)
+#endif /* VALID_INTPRI_CHGIPM */
+
+/*
+ * タスク優先度のチェック(E_PAR)
+ */
+#define CHECK_TPRI(tpri) { \
+ if (!VALID_TPRI(tpri)) { \
+ ercd = E_PAR; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_TPRI_INI(tpri) { \
+ if (!(VALID_TPRI(tpri) || (tpri) == TPRI_INI)) { \
+ ercd = E_PAR; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_TPRI_SELF(tpri) { \
+ if (!(VALID_TPRI(tpri) || (tpri) == TPRI_SELF)) { \
+ ercd = E_PAR; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * タイムアウト指定値のチェック(E_PAR)
+ */
+#define CHECK_TMOUT(tmout) { \
+ if (!(TMO_FEVR <= (tmout))) { \
+ ercd = E_PAR; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * 割込み優先度のチェック(E_PAR)
+ */
+#define CHECK_INTPRI_CHGIPM(inttpri) { \
+ if (!VALID_INTPRI_CHGIPM(intpri)) { \
+ ercd = E_PAR; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * 割込み番号のチェック(E_PAR)
+ */
+#define CHECK_INTNO_DISINT(intno) { \
+ if (!VALID_INTNO_DISINT(intno)) { \
+ ercd = E_PAR; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * その他のパラメータエラーのチェック(E_PAR)
+ */
+#define CHECK_PAR(exp) { \
+ if (!(exp)) { \
+ ercd = E_PAR; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * オブジェクトIDの範囲の判定
+ */
+#define VALID_TSKID(tskid) (TMIN_TSKID <= (tskid) && (tskid) <= tmax_tskid)
+#define VALID_SEMID(semid) (TMIN_SEMID <= (semid) && (semid) <= tmax_semid)
+#define VALID_FLGID(flgid) (TMIN_FLGID <= (flgid) && (flgid) <= tmax_flgid)
+#define VALID_DTQID(dtqid) (TMIN_DTQID <= (dtqid) && (dtqid) <= tmax_dtqid)
+#define VALID_PDQID(pdqid) (TMIN_PDQID <= (pdqid) && (pdqid) <= tmax_pdqid)
+#define VALID_MBXID(mbxid) (TMIN_MBXID <= (mbxid) && (mbxid) <= tmax_mbxid)
+#define VALID_MTXID(mtxid) (TMIN_MTXID <= (mtxid) && (mtxid) <= tmax_mtxid)
+#define VALID_MPFID(mpfid) (TMIN_MPFID <= (mpfid) && (mpfid) <= tmax_mpfid)
+#define VALID_CYCID(cycid) (TMIN_CYCID <= (cycid) && (cycid) <= tmax_cycid)
+#define VALID_ALMID(almid) (TMIN_ALMID <= (almid) && (almid) <= tmax_almid)
+
+/*
+ * オブジェクトIDのチェック(E_ID)
+ */
+#define CHECK_TSKID(tskid) { \
+ if (!VALID_TSKID(tskid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_TSKID_SELF(tskid) { \
+ if (!(VALID_TSKID(tskid) || (tskid) == TSK_SELF)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_SEMID(semid) { \
+ if (!VALID_SEMID(semid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_FLGID(flgid) { \
+ if (!VALID_FLGID(flgid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_DTQID(dtqid) { \
+ if (!VALID_DTQID(dtqid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_PDQID(pdqid) { \
+ if (!VALID_PDQID(pdqid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_MBXID(mbxid) { \
+ if (!VALID_MBXID(mbxid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_MTXID(mtxid) { \
+ if (!VALID_MTXID(mtxid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_MPFID(mpfid) { \
+ if (!VALID_MPFID(mpfid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_CYCID(cycid) { \
+ if (!VALID_CYCID(cycid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_ALMID(almid) { \
+ if (!VALID_ALMID(almid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * 呼出しコンテキストのチェック(E_CTX)
+ */
+#define CHECK_TSKCTX() { \
+ if (sense_context()) { \
+ ercd = E_CTX; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_INTCTX() { \
+ if (!sense_context()) { \
+ ercd = E_CTX; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * 呼出しコンテキストとCPUロック状態のチェック(E_CTX)
+ */
+#define CHECK_TSKCTX_UNL() { \
+ if (sense_context() || t_sense_lock()) { \
+ ercd = E_CTX; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_INTCTX_UNL() { \
+ if (!sense_context() || i_sense_lock()) { \
+ ercd = E_CTX; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * ディスパッチ保留状態でないかのチェック(E_CTX)
+ */
+#define CHECK_DISPATCH() { \
+ if (sense_context() || t_sense_lock() || !dspflg) { \
+ ercd = E_CTX; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * その他のコンテキストエラーのチェック(E_CTX)
+ */
+#define CHECK_CTX(exp) { \
+ if (!(exp)) { \
+ ercd = E_CTX; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * 自タスクを指定していないかのチェック(E_ILUSE)
+ */
+#define CHECK_NONSELF(p_tcb) { \
+ if ((p_tcb) == p_runtsk) { \
+ ercd = E_ILUSE; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * その他の不正使用エラーのチェック(E_ILUSE)
+ */
+#define CHECK_ILUSE(exp) { \
+ if (!(exp)) { \
+ ercd = E_ILUSE; \
+ goto error_exit; \
+ } \
+}
+
+#endif /* TOPPERS_CHECK_H */
--- /dev/null
+$ ======================================================================
+$
+$ TOPPERS/ASP Kernel
+$ Toyohashi Open Platform for Embedded Real-Time Systems/
+$ Advanced Standard Profile Kernel
+$
+$ Copyright (C) 2007 by TAKAGI Nobuhisa
+$ Copyright (C) 2007-2010 by Embedded and Real-Time Systems Laboratory
+$ Graduate School of Information Science, Nagoya Univ., JAPAN
+$
+$ 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+$ ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+$ 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+$ (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+$ 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+$ スコード中に含まれていること.
+$ (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+$ 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+$ 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+$ の無保証規定を掲載すること.
+$ (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+$ 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+$ と.
+$ (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+$ 作権表示,この利用条件および下記の無保証規定を掲載すること.
+$ (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+$ 報告すること.
+$ (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+$ 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+$ また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+$ 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+$ 免責すること.
+$
+$ 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+$ よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+$ に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+$ アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+$ の責任を負わない.
+$
+$ $Id: kernel.tf 1845 2010-07-11 13:02:57Z ertl-hiro $
+$
+$ =====================================================================
+
+$ =====================================================================
+$ kernel_cfg.hの生成
+$ =====================================================================
+
+$FILE "kernel_cfg.h"$
+/* kernel_cfg.h */$NL$
+#ifndef TOPPERS_KERNEL_CFG_H$NL$
+#define TOPPERS_KERNEL_CFG_H$NL$
+$NL$
+#define TNUM_TSKID $LENGTH(TSK.ID_LIST)$$NL$
+#define TNUM_SEMID $LENGTH(SEM.ID_LIST)$$NL$
+#define TNUM_FLGID $LENGTH(FLG.ID_LIST)$$NL$
+#define TNUM_DTQID $LENGTH(DTQ.ID_LIST)$$NL$
+#define TNUM_PDQID $LENGTH(PDQ.ID_LIST)$$NL$
+#define TNUM_MBXID $LENGTH(MBX.ID_LIST)$$NL$
+#define TNUM_MTXID $LENGTH(MTX.ID_LIST)$$NL$
+#define TNUM_MPFID $LENGTH(MPF.ID_LIST)$$NL$
+#define TNUM_CYCID $LENGTH(CYC.ID_LIST)$$NL$
+#define TNUM_ALMID $LENGTH(ALM.ID_LIST)$$NL$
+$NL$
+$FOREACH id TSK.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id SEM.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id FLG.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id DTQ.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id PDQ.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id MBX.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id MTX.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id MPF.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id CYC.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id ALM.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$NL$
+#endif /* TOPPERS_KERNEL_CFG_H */$NL$
+
+$ =====================================================================
+$ kernel_cfg.cの生成
+$ =====================================================================
+
+$FILE "kernel_cfg.c"$
+/* kernel_cfg.c */$NL$
+#include "kernel/kernel_int.h"$NL$
+#include "kernel_cfg.h"$NL$
+$NL$
+#ifndef TOPPERS_EMPTY_LABEL$NL$
+#define TOPPERS_EMPTY_LABEL(x,y) x y[0]$NL$
+#endif$NL$
+$NL$
+#if TKERNEL_PRID != 0x07u$NL$
+#error The kernel does not match this configuration file.$NL$
+#endif$NL$
+$NL$
+
+$
+$ インクルードディレクティブ(#include)
+$
+/*$NL$
+$SPC$* Include Directives (#include)$NL$
+$SPC$*/$NL$
+$NL$
+$INCLUDES$
+$NL$
+
+$
+$ オブジェクトのID番号を保持する変数
+$
+$IF USE_EXTERNAL_ID$
+ /*$NL$
+ $SPC$* Variables for Object ID$NL$
+ $SPC$*/$NL$
+ $NL$
+ $FOREACH id TSK.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id SEM.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id FLG.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id DTQ.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id PDQ.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id MBX.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id MTX.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id MPF.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id CYC.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id ALM.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+$END$
+
+$
+$ トレースログマクロのデフォルト定義
+$
+/*$NL$
+$SPC$* Default Definitions of Trace Log Macros$NL$
+$SPC$*/$NL$
+$NL$
+#ifndef LOG_ISR_ENTER$NL$
+#define LOG_ISR_ENTER(intno)$NL$
+#endif /* LOG_ISR_ENTER */$NL$
+$NL$
+#ifndef LOG_ISR_LEAVE$NL$
+#define LOG_ISR_LEAVE(intno)$NL$
+#endif /* LOG_ISR_LEAVE */$NL$
+$NL$
+
+$
+$ タスク
+$
+/*$NL$
+$SPC$* Task Management Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ タスクが1個以上存在することのチェック
+$IF !LENGTH(TSK.ID_LIST)$
+ $ERROR$$FORMAT("no task is registered")$$END$
+$END$
+
+$ タスクID番号の最大値
+const ID _kernel_tmax_tskid = (TMIN_TSKID + TNUM_TSKID - 1);$NL$
+$NL$
+
+$ エラーチェック
+$FOREACH tskid TSK.ID_LIST$
+$ // tskatrが([TA_ACT])でない場合(E_RSATR)
+ $IF (TSK.TSKATR[tskid] & ~(TA_ACT|ALT(TARGET_TSKATR,0))) != 0$
+ $ERROR TSK.TEXT_LINE[tskid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "tskatr", TSK.TSKATR[tskid], tskid, "CRE_TSK")$$END$
+ $END$
+
+$ // (TMIN_TPRI <= itskpri && itskpri <= TMAX_TPRI)でない場合(E_PAR)
+ $IF !(TMIN_TPRI <= TSK.ITSKPRI[tskid] && TSK.ITSKPRI[tskid] <= TMAX_TPRI)$
+ $ERROR TSK.TEXT_LINE[tskid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "itskpri", TSK.ITSKPRI[tskid], tskid, "CRE_TSK")$$END$
+ $END$
+
+$ // texatrが(TA_NULL)でない場合(E_RSATR)
+ $IF LENGTH(TSK.TEXATR[tskid]) && TSK.TEXATR[tskid] != 0$
+ $ERROR DEF_TEX.TEXT_LINE[tskid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "texatr", TSK.TEXATR[tskid], tskid, "DEF_TEX")$$END$
+ $END$
+$END$
+
+$ スタック領域の生成とそれに関するエラーチェック
+$FOREACH tskid TSK.ID_LIST$
+$ // stkszが0か,ターゲット定義の最小値(TARGET_MIN_STKSZ)よりも小さい場合(E_PAR)
+ $IF TSK.STKSZ[tskid] == 0 || (LENGTH(TARGET_MIN_STKSZ) &&
+ TSK.STKSZ[tskid] < TARGET_MIN_STKSZ)$
+ $ERROR TSK.TEXT_LINE[tskid]$E_PAR: $FORMAT(_("%1% `%2%\' of `%3%\' in %4% is too small"), "stksz", TSK.STKSZ[tskid], tskid, "CRE_TSK")$$END$
+ $END$
+$ // stkszがスタック領域のサイズとして正しくない場合(E_PAR)
+ $IF !EQ(TSK.STK[tskid], "NULL") && LENGTH(CHECK_STKSZ_ALIGN)
+ && (TSK.STKSZ[tskid] & (CHECK_STKSZ_ALIGN - 1))$
+ $ERROR TSK.TEXT_LINE[tskid]$E_PAR: $FORMAT(_("%1% `%2%\' of `%3%\' in %4% is not aligned"), "stksz", TSK.STKSZ[tskid], tskid, "CRE_TSK")$$END$
+ $END$
+
+ $IF EQ(TSK.STK[tskid],"NULL")$
+ static STK_T _kernel_stack_$tskid$[COUNT_STK_T($TSK.STKSZ[tskid]$)];$NL$
+ $TSK.TINIB_STKSZ[tskid] = FORMAT("ROUND_STK_T(%1%)", TSK.STKSZ[tskid])$
+ $TSK.TINIB_STK[tskid] = CONCAT("_kernel_stack_", tskid)$
+ $ELSE$
+ $TSK.TINIB_STKSZ[tskid] = TSK.STKSZ[tskid]$
+ $TSK.TINIB_STK[tskid] = TSK.STK[tskid]$
+ $END$
+$END$
+$NL$
+
+$ タスク初期化ブロックの生成(タスクは1個以上存在する)
+const TINIB _kernel_tinib_table[TNUM_TSKID] = {$NL$
+$JOINEACH tskid TSK.ID_LIST ",\n"$
+$ // タスク属性,拡張情報,起動番地,起動時優先度
+ $TAB${
+ $SPC$($TSK.TSKATR[tskid]$), (intptr_t)($TSK.EXINF[tskid]$),
+ $SPC$($TSK.TASK[tskid]$), INT_PRIORITY($TSK.ITSKPRI[tskid]$),
+
+$ // タスク初期化コンテキストブロック,スタック領域
+ $IF ALT(USE_TSKINICTXB,0)$
+ $GENERATE_TSKINICTXB(tskid)$
+ $ELSE$
+ $SPC$$TSK.TINIB_STKSZ[tskid]$, $TSK.TINIB_STK[tskid]$,
+ $END$
+
+$ // タスク例外処理ルーチンの属性と起動番地
+ $SPC$($ALT(TSK.TEXATR[tskid],"TA_NULL")$), ($ALT(TSK.TEXRTN[tskid],"NULL")$) }
+$END$$NL$
+};$NL$
+$NL$
+
+$ タスクコントロールブロックの生成
+TCB _kernel_tcb_table[TNUM_TSKID];$NL$
+$NL$
+
+$ タスク生成順序テーブルの生成
+const ID _kernel_torder_table[TNUM_TSKID] = {$NL$
+$TAB$$JOINEACH tskid TSK.ORDER_LIST ", "$$tskid$$END$$NL$
+};$NL$
+$NL$
+
+$
+$ セマフォ
+$
+/*$NL$
+$SPC$* Semaphore Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ セマフォID番号の最大値
+const ID _kernel_tmax_semid = (TMIN_SEMID + TNUM_SEMID - 1);$NL$
+$NL$
+
+$ セマフォ初期化ブロックの生成
+$IF LENGTH(SEM.ID_LIST)$
+ const SEMINIB _kernel_seminib_table[TNUM_SEMID] = {$NL$
+ $JOINEACH semid SEM.ID_LIST ",\n"$
+$ // sematrが([TA_TPRI])でない場合(E_RSATR)
+ $IF (SEM.SEMATR[semid] & ~TA_TPRI) != 0$
+ $ERROR SEM.TEXT_LINE[semid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "sematr", SEM.SEMATR[semid], semid, "CRE_SEM")$$END$
+ $END$
+
+$ // (0 <= isemcnt && isemcnt <= maxsem)でない場合(E_PAR)
+ $IF !(0 <= SEM.ISEMCNT[semid] && SEM.ISEMCNT[semid] <= SEM.MAXSEM[semid])$
+ $ERROR SEM.TEXT_LINE[semid]$E_PAR: $FORMAT(_("too large %1% `%2%\' of `%3%\' in %4%"), "isemcnt", SEM.ISEMCNT[semid], semid, "CRE_SEM")$$END$
+ $END$
+
+$ // (1 <= maxsem && maxsem <= TMAX_MAXSEM)でない場合(E_PAR)
+ $IF !(1 <= SEM.MAXSEM[semid] && SEM.MAXSEM[semid] <= TMAX_MAXSEM)$
+ $ERROR SEM.TEXT_LINE[semid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "maxsem", SEM.MAXSEM[semid], semid, "CRE_SEM")$$END$
+ $END$
+
+$ // セマフォ初期化ブロック
+ $TAB${ ($SEM.SEMATR[semid]$), ($SEM.ISEMCNT[semid]$), ($SEM.MAXSEM[semid]$) }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // セマフォコントロールブロック
+ SEMCB _kernel_semcb_table[TNUM_SEMID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const SEMINIB, _kernel_seminib_table);$NL$
+ TOPPERS_EMPTY_LABEL(SEMCB, _kernel_semcb_table);$NL$
+$END$
+$NL$
+
+$
+$ イベントフラグ
+$
+/*$NL$
+$SPC$* Eventflag Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ イベントフラグID番号の最大値
+const ID _kernel_tmax_flgid = (TMIN_FLGID + TNUM_FLGID - 1);$NL$
+$NL$
+
+$ イベントフラグ初期化ブロックの生成
+$IF LENGTH(FLG.ID_LIST)$
+ const FLGINIB _kernel_flginib_table[TNUM_FLGID] = {$NL$
+ $JOINEACH flgid FLG.ID_LIST ",\n"$
+$ // flgatrが([TA_TPRI]|[TA_WMUL]|[TA_CLR])でない場合(E_RSATR)
+ $IF (FLG.FLGATR[flgid] & ~(TA_TPRI|TA_WMUL|TA_CLR)) != 0$
+ $ERROR FLG.TEXT_LINE[flgid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "flgatr", FLG.FLGATR[flgid], flgid, "CRE_FLG")$$END$
+ $END$
+
+$ // イベントフラグ初期化ブロック
+ $TAB${ ($FLG.FLGATR[flgid]$), ($FLG.IFLGPTN[flgid]$) }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // イベントフラグコントロールブロック
+ FLGCB _kernel_flgcb_table[TNUM_FLGID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const FLGINIB, _kernel_flginib_table);$NL$
+ TOPPERS_EMPTY_LABEL(FLGCB, _kernel_flgcb_table);$NL$
+$END$
+$NL$
+
+$
+$ データキュー
+$
+/*$NL$
+$SPC$* Dataqueue Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ データキューID番号の最大値
+const ID _kernel_tmax_dtqid = (TMIN_DTQID + TNUM_DTQID - 1);$NL$
+$NL$
+
+$IF LENGTH(DTQ.ID_LIST)$
+ $FOREACH dtqid DTQ.ID_LIST$
+$ // dtqatrが([TA_TPRI])でない場合(E_RSATR)
+ $IF (DTQ.DTQATR[dtqid] & ~TA_TPRI) != 0$
+ $ERROR DTQ.TEXT_LINE[dtqid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "dtqatr", DTQ.DTQATR[dtqid], dtqid, "CRE_DTQ")$$END$
+ $END$
+
+$ // dtqmbがNULLでない場合(E_NOSPT)
+ $IF !EQ(DTQ.DTQMB[dtqid], "NULL")$
+ $ERROR DTQ.TEXT_LINE[dtqid]$E_NOSPT: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "dtqmb", DTQ.DTQMB[dtqid], dtqid, "CRE_DTQ")$$END$
+ $END$
+
+$ // データキュー領域
+ $IF DTQ.DTQCNT[dtqid]$
+ static intptr_t _kernel_dtqmb_$dtqid$[$DTQ.DTQCNT[dtqid]$];$NL$
+ $END$
+ $END$
+
+$ // データキュー初期化ブロックの生成
+ const DTQINIB _kernel_dtqinib_table[TNUM_DTQID] = {$NL$
+ $JOINEACH dtqid DTQ.ID_LIST ",\n"$
+ $TAB${ ($DTQ.DTQATR[dtqid]$), ($DTQ.DTQCNT[dtqid]$), $IF DTQ.DTQCNT[dtqid]$(_kernel_dtqmb_$dtqid$)$ELSE$NULL$END$ }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // データキューコントロールブロック
+ DTQCB _kernel_dtqcb_table[TNUM_DTQID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const DTQINIB, _kernel_dtqinib_table);$NL$
+ TOPPERS_EMPTY_LABEL(DTQCB, _kernel_dtqcb_table);$NL$
+$END$
+$NL$
+
+$
+$ 優先度データキュー
+$
+/*$NL$
+$SPC$* Priority Dataqueue Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 優先度データキューID番号の最大値
+const ID _kernel_tmax_pdqid = (TMIN_PDQID + TNUM_PDQID - 1);$NL$
+$NL$
+
+$IF LENGTH(PDQ.ID_LIST)$
+ $FOREACH pdqid PDQ.ID_LIST$
+$ // pdqatrが([TA_TPRI])でない場合(E_RSATR)
+ $IF (PDQ.PDQATR[pdqid] & ~TA_TPRI) != 0$
+ $ERROR PDQ.TEXT_LINE[pdqid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "pdqatr", PDQ.PDQATR[pdqid], pdqid, "CRE_PDQ")$$END$
+ $END$
+
+$ // (TMIN_DPRI <= maxdpri && maxdpri <= TMAX_DPRI)でない場合(E_PAR)
+ $IF !(TMIN_DPRI <= PDQ.MAXDPRI[pdqid] && PDQ.MAXDPRI[pdqid] <= TMAX_DPRI)$
+ $ERROR PDQ.TEXT_LINE[pdqid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "maxdpri", PDQ.MAXDPRI[pdqid], pdqid, "CRE_PDQ")$$END$
+ $END$
+
+$ // pdqmbがNULLでない場合(E_NOSPT)
+ $IF !EQ(PDQ.PDQMB[pdqid], "NULL")$
+ $ERROR PDQ.TEXT_LINE[pdqid]$E_NOSPT: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "pdqmb", PDQ.PDQMB[pdqid], pdqid, "CRE_PDQ")$$END$
+ $END$
+
+$ // 優先度データキュー領域
+ $IF PDQ.PDQCNT[pdqid]$
+ static PDQMB _kernel_pdqmb_$pdqid$[$PDQ.PDQCNT[pdqid]$];$NL$
+ $END$
+ $END$
+
+$ // 優先度データキュー初期化ブロックの生成
+ const PDQINIB _kernel_pdqinib_table[TNUM_PDQID] = {$NL$
+ $JOINEACH pdqid PDQ.ID_LIST ",\n"$
+ $TAB${ ($PDQ.PDQATR[pdqid]$), ($PDQ.PDQCNT[pdqid]$), ($PDQ.MAXDPRI[pdqid]$), $IF PDQ.PDQCNT[pdqid]$(_kernel_pdqmb_$pdqid$)$ELSE$NULL$END$ }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // 優先度データキューコントロールブロック
+ PDQCB _kernel_pdqcb_table[TNUM_PDQID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const PDQINIB, _kernel_pdqinib_table);$NL$
+ TOPPERS_EMPTY_LABEL(PDQCB, _kernel_pdqcb_table);$NL$
+$END$
+$NL$
+
+$
+$ メールボックス
+$
+/*$NL$
+$SPC$* Mailbox Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ メールボックスID番号の最大値
+const ID _kernel_tmax_mbxid = (TMIN_MBXID + TNUM_MBXID - 1);$NL$
+$NL$
+
+$ メールボックス初期化ブロックの生成
+$IF LENGTH(MBX.ID_LIST)$
+ const MBXINIB _kernel_mbxinib_table[TNUM_MBXID] = {$NL$
+ $JOINEACH mbxid MBX.ID_LIST ",\n"$
+$ // mbxatrが([TA_TPRI]|[TA_MPRI])でない場合(E_RSATR)
+ $IF (MBX.MBXATR[mbxid] & ~(TA_TPRI|TA_MPRI)) != 0$
+ $ERROR MBX.TEXT_LINE[mbxid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mbxatr", MBX.MBXATR[mbxid], mbxid, "CRE_MBX")$$END$
+ $END$
+
+$ // (TMIN_MPRI <= maxmpri && maxmpri <= TMAX_MPRI)でない場合(E_PAR)
+ $IF !(TMIN_MPRI <= MBX.MAXMPRI[mbxid] && MBX.MAXMPRI[mbxid] <= TMAX_MPRI)$
+ $ERROR MBX.TEXT_LINE[mbxid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "maxmpri", MBX.MAXMPRI[mbxid], mbxid, "CRE_MBX")$$END$
+ $END$
+
+$ // mprihdがNULLでない場合(E_NOSPT)
+ $IF !EQ(MBX.MPRIHD[mbxid], "NULL")$
+ $ERROR MBX.TEXT_LINE[mbxid]$E_NOSPT: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mprihd", MBX.MPRIHD[mbxid], mbxid, "CRE_MBX")$$END$
+ $END$
+
+$ // メールボックス初期化ブロック
+ $TAB${ ($MBX.MBXATR[mbxid]$), ($MBX.MAXMPRI[mbxid]$) }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // メールボックスコントロールブロック
+ MBXCB _kernel_mbxcb_table[TNUM_MBXID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const MBXINIB, _kernel_mbxinib_table);$NL$
+ TOPPERS_EMPTY_LABEL(MBXCB, _kernel_mbxcb_table);$NL$
+$END$
+$NL$
+
+$
+$ ミューテックス
+$
+/*$NL$
+$SPC$* Mutex Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ ミューテックスID番号の最大値
+const ID _kernel_tmax_mtxid = (TMIN_MTXID + TNUM_MTXID - 1);$NL$
+$NL$
+
+$ ミューテックス初期化ブロックの生成
+$IF LENGTH(MTX.ID_LIST)$
+ const MTXINIB _kernel_mtxinib_table[TNUM_MTXID] = {$NL$
+ $JOINEACH mtxid MTX.ID_LIST ",\n"$
+$ // mtxatrが([TA_TPRI|TA_CEILING])でない場合(E_RSATR)
+ $IF !(MTX.MTXATR[mtxid] == 0 || MTX.MTXATR[mtxid] == TA_TPRI || MTX.MTXATR[mtxid] == TA_CEILING)$
+ $ERROR MTX.TEXT_LINE[mtxid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mtxatr", MTX.MTXATR[mtxid], mtxid, "CRE_MTX")$$END$
+ $END$
+
+$ // ceilpriが未指定の場合は0と見なす
+ $IF !LENGTH(MTX.CEILPRI[mtxid])$
+ $MTX.CEILPRI[mtxid] = 0$
+ $END$
+$ // (TMIN_TPRI <= ceilpri && ceilpri <= TMAX_TPRI)でない場合(E_PAR)
+ $IF MTX.MTXATR[mtxid] == TA_CEILING && (MTX.CEILPRI[mtxid] < TMIN_TPRI || TMAX_TPRI < MTX.CEILPRI[mtxid])$
+ $ERROR MTX.TEXT_LINE[mtxid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "ceilpri", MTX.CEILPRI[mtxid], mtxid, "CRE_MTX")$$END$
+ $END$
+
+$ // ミューテックス初期化ブロック
+ $TAB${ ($MTX.MTXATR[mtxid]$), INT_PRIORITY($MTX.CEILPRI[mtxid]$) }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // ミューテックスコントロールブロック
+ MTXCB _kernel_mtxcb_table[TNUM_MTXID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const MTXINIB, _kernel_mtxinib_table);$NL$
+ TOPPERS_EMPTY_LABEL(MTXCB, _kernel_mtxcb_table);$NL$
+$END$
+$NL$
+
+$
+$ 固定長メモリプール
+$
+/*$NL$
+$SPC$* Fixed-sized Memorypool Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 固定長メモリプールID番号の最大値
+const ID _kernel_tmax_mpfid = (TMIN_MPFID + TNUM_MPFID - 1);$NL$
+$NL$
+
+$IF LENGTH(MPF.ID_LIST)$
+ $FOREACH mpfid MPF.ID_LIST$
+$ // mpfatrが([TA_TPRI])でない場合(E_RSATR)
+ $IF (MPF.MPFATR[mpfid] & ~TA_TPRI) != 0$
+ $ERROR MPF.TEXT_LINE[mpfid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mpfatr", MPF.MPFATR[mpfid], mpfid, "CRE_MPF")$$END$
+ $END$
+
+$ // blkcntが0の場合(E_PAR)
+ $IF MPF.BLKCNT[mpfid] == 0$
+ $ERROR MPF.TEXT_LINE[mpfid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "blkcnt", MPF.BLKCNT[mpfid], mpfid, "CRE_MPF")$$END$
+ $END$
+
+$ // blkszが0の場合(E_PAR)
+ $IF MPF.BLKSZ[mpfid] == 0$
+ $ERROR MPF.TEXT_LINE[mpfid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "blksz", MPF.BLKSZ[mpfid], mpfid, "CRE_MPF")$$END$
+ $END$
+
+$ // 固定長メモリプール領域
+ $IF EQ(MPF.MPF[mpfid], "NULL")$
+ static MPF_T _kernel_mpf_$mpfid$[($MPF.BLKCNT[mpfid]$) * COUNT_MPF_T($MPF.BLKSZ[mpfid]$)];$NL$
+ $END$
+
+$ // mpfmbがNULLでない場合(E_NOSPT)
+ $IF !EQ(MPF.MPFMB[mpfid], "NULL")$
+ $ERROR MPF.TEXT_LINE[mpfid]$E_NOSPT: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mpfmb", MPF.MPFMB[mpfid], mpfid, "CRE_MPF")$$END$
+ $END$
+
+$ // 固定長メモリプール管理領域
+ static MPFMB _kernel_mpfmb_$mpfid$[$MPF.BLKCNT[mpfid]$];$NL$
+ $END$
+
+$ // 固定長メモリプール初期化ブロックの生成
+ const MPFINIB _kernel_mpfinib_table[TNUM_MPFID] = {$NL$
+ $JOINEACH mpfid MPF.ID_LIST ",\n"$
+ $TAB${ ($MPF.MPFATR[mpfid]$), ($MPF.BLKCNT[mpfid]$), ROUND_MPF_T($MPF.BLKSZ[mpfid]$), $IF EQ(MPF.MPF[mpfid],"NULL")$(_kernel_mpf_$mpfid$)$ELSE$($MPF.MPF[mpfid]$)$END$, (_kernel_mpfmb_$mpfid$) }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // 固定長メモリプールコントロールブロック
+ MPFCB _kernel_mpfcb_table[TNUM_MPFID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const MPFINIB, _kernel_mpfinib_table);$NL$
+ TOPPERS_EMPTY_LABEL(MPFCB, _kernel_mpfcb_table);$NL$
+$END$
+$NL$
+
+$
+$ 周期ハンドラ
+$
+/*$NL$
+$SPC$* Cyclic Handler Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 周期ハンドラID番号の最大値
+const ID _kernel_tmax_cycid = (TMIN_CYCID + TNUM_CYCID - 1);$NL$
+$NL$
+
+$ 周期ハンドラ初期化テーブルの生成
+$IF LENGTH(CYC.ID_LIST)$
+ const CYCINIB _kernel_cycinib_table[TNUM_CYCID] = {$NL$
+ $JOINEACH cycid CYC.ID_LIST ",\n"$
+$ // cycatrが([TA_STA])でない場合(E_RSATR)
+ $IF (CYC.CYCATR[cycid] & ~TA_STA) != 0$
+ $ERROR CYC.TEXT_LINE[cycid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "cycatr", CYC.CYCATR[cycid], cycid, "CRE_CYC")$$END$
+ $END$
+
+$ // (0 < cyctim && cyctim <= TMAX_RELTIM)でない場合(E_PAR)
+ $IF !(0 < CYC.CYCTIM[cycid] && CYC.CYCTIM[cycid] <= TMAX_RELTIM)$
+ $ERROR CYC.TEXT_LINE[cycid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "cyctim", CYC.CYCTIM[cycid], cycid, "CRE_CYC")$$END$
+ $END$
+
+$ // (0 <= cycphs && cycphs <= TMAX_RELTIM)でない場合(E_PAR)
+ $IF !(0 <= CYC.CYCPHS[cycid] && CYC.CYCPHS[cycid] <= TMAX_RELTIM)$
+ $ERROR CYC.TEXT_LINE[cycid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "cycphs", CYC.CYCPHS[cycid], cycid, "CRE_CYC")$$END$
+ $END$
+
+$ // 警告:cycatrにTA_STAが設定されていて,(cycphs == 0)の場合
+ $IF (CYC.CYCATR[cycid] & TA_STA) != 0 && CYC.CYCPHS[cycid] == 0$
+ $WARNING CYC.TEXT_LINE[cycid]$$FORMAT(_("%1% is not recommended when %2% is set to %3% in %4%"), "cycphs==0", "TA_STA", "cycatr", "CRE_CYC")$$END$
+ $END$
+
+$ // 周期ハンドラ初期化ブロック
+ $TAB${ ($CYC.CYCATR[cycid]$), (intptr_t)($CYC.EXINF[cycid]$), ($CYC.CYCHDR[cycid]$), ($CYC.CYCTIM[cycid]$), ($CYC.CYCPHS[cycid]$) }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // 周期ハンドラコントロールブロック
+ CYCCB _kernel_cyccb_table[TNUM_CYCID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const CYCINIB, _kernel_cycinib_table);$NL$
+ TOPPERS_EMPTY_LABEL(CYCCB, _kernel_cyccb_table);$NL$
+$END$
+$NL$
+
+$
+$ アラームハンドラ
+$
+/*$NL$
+$SPC$* Alarm Handler Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ アラームハンドラID番号の最大値
+const ID _kernel_tmax_almid = (TMIN_ALMID + TNUM_ALMID - 1);$NL$
+$NL$
+
+$ アラームハンドラ初期化ブロックの生成
+$IF LENGTH(ALM.ID_LIST)$
+ const ALMINIB _kernel_alminib_table[TNUM_ALMID] = {$NL$
+ $JOINEACH almid ALM.ID_LIST ",\n"$
+$ // almatrが(TA_NULL)でない場合(E_RSATR)
+ $IF ALM.ALMATR[almid] != 0$
+ $ERROR ALM.TEXT_LINE[almid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "almatr", ALM.ALMATR[almid], almid, "CRE_ALM")$$END$
+ $END$
+
+$ // アラームハンドラ初期化ブロック
+ $TAB${ ($ALM.ALMATR[almid]$), (intptr_t)($ALM.EXINF[almid]$), ($ALM.ALMHDR[almid]$) }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // アラームハンドラコントロールブロック
+ ALMCB _kernel_almcb_table[TNUM_ALMID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const ALMINIB, _kernel_alminib_table);$NL$
+ TOPPERS_EMPTY_LABEL(ALMCB, _kernel_almcb_table);$NL$
+$END$
+$NL$
+
+$
+$ 割込み管理機能
+$
+/*$NL$
+$SPC$* Interrupt Management Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 割込み番号と割込みハンドラ番号の変換テーブルの作成
+$IF LENGTH(INTNO_ATTISR_VALID) != LENGTH(INHNO_ATTISR_VALID)$
+ $ERROR$length of `INTNO_ATTISR_VALID' is different from length of `INHNO_ATTISR_VALID'$END$
+$END$
+$i = 0$
+$FOREACH intno INTNO_ATTISR_VALID$
+ $inhno = AT(INHNO_ATTISR_VALID, i)$
+ $INHNO[intno] = inhno$
+ $INTNO[inhno] = intno$
+ $i = i + 1$
+$END$
+
+$ 割込み要求ラインに関するエラーチェック
+$i = 0$
+$FOREACH intno INT.ORDER_LIST$
+$ // intnoがCFG_INTに対する割込み番号として正しくない場合(E_PAR)
+ $IF !LENGTH(FIND(INTNO_CFGINT_VALID, INT.INTNO[intno]))$
+ $ERROR INT.TEXT_LINE[intno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "intno", INT.INTNO[intno], "CFG_INT")$$END$
+ $END$
+
+$ // intnoがCFG_INTによって設定済みの場合(E_OBJ)
+ $j = 0$
+ $FOREACH intno2 INT.ORDER_LIST$
+ $IF INT.INTNO[intno] == INT.INTNO[intno2] && j < i$
+ $ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' in %3% is duplicated"), "intno", INT.INTNO[intno], "CFG_INT")$$END$
+ $END$
+ $j = j + 1$
+ $END$
+
+$ // intatrが([TA_ENAINT]|[TA_EDGE])でない場合(E_RSATR)
+ $IF (INT.INTATR[intno] & ~(TA_ENAINT|TA_EDGE|ALT(TARGET_INTATR,0))) != 0$
+ $ERROR INT.TEXT_LINE[intno]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "intatr", INT.INTATR[intno], "intno", INT.INTNO[intno], "CFG_INT")$$END$
+ $END$
+
+$ // intpriがCFG_INTに対する割込み優先度として正しくない場合(E_PAR)
+ $IF !LENGTH(FIND(INTPRI_CFGINT_VALID, INT.INTPRI[intno]))$
+ $ERROR INT.TEXT_LINE[intno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "intpri", INT.INTPRI[intno], "CFG_INT")$$END$
+ $END$
+
+$ // カーネル管理に固定されているintnoに対して,intpriにTMIN_INTPRI
+$ // よりも小さい値が指定された場合(E_OBJ)
+ $IF LENGTH(FIND(INTNO_FIX_KERNEL, intno))$
+ $IF INT.INTPRI[intno] < TMIN_INTPRI$
+ $ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' must not have higher priority than %3%"), "intno", INT.INTNO[intno], "TMIN_INTPRI")$$END$
+ $END$
+ $END$
+
+$ // カーネル管理外に固定されているintnoに対して,intpriにTMIN_INTPRI
+$ // よりも小さい値が指定されなかった場合(E_OBJ)
+ $IF LENGTH(FIND(INTNO_FIX_NONKERNEL, intno))$
+ $IF INT.INTPRI[intno] >= TMIN_INTPRI$
+ $ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' must have higher priority than %3%"), "intno", INT.INTNO[intno], "TMIN_INTPRI")$$END$
+ $END$
+ $END$
+ $i = i + 1$
+$END$
+
+$ 割込みハンドラに関するエラーチェック
+$i = 0$
+$FOREACH inhno INH.ORDER_LIST$
+$ // inhnoがDEF_INHに対する割込みハンドラ番号として正しくない場合(E_PAR)
+ $IF !LENGTH(FIND(INHNO_DEFINH_VALID, INH.INHNO[inhno]))$
+ $ERROR INH.TEXT_LINE[inhno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "inhno", INH.INHNO[inhno], "DEF_INH")$$END$
+ $END$
+
+$ // inhnoがDEF_INHによって設定済みの場合(E_OBJ)
+ $j = 0$
+ $FOREACH inhno2 INH.ORDER_LIST$
+ $IF INH.INHNO[inhno] == INH.INHNO[inhno2] && j < i$
+ $ERROR INH.TEXT_LINE[inhno]$E_OBJ: $FORMAT(_("%1% `%2%\' in %3% is duplicated"), "inhno", INH.INHNO[inhno], "DEF_INH")$$END$
+ $END$
+ $j = j + 1$
+ $END$
+
+$ // inhatrが(TA_NULL)でない場合(E_RSATR)
+ $IF (INH.INHATR[inhno] & ~ALT(TARGET_INHATR,0)) != 0$
+ $ERROR INH.TEXT_LINE[inhno]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "inhatr", INH.INHATR[inhno], "inhno", INH.INHNO[inhno], "DEF_INH")$$END$
+ $END$
+
+$ // カーネル管理に固定されているinhnoに対して,inhatrにTA_NONKERNEL
+$ // が指定されている場合(E_RSATR)
+ $IF LENGTH(FIND(INHNO_FIX_KERNEL, inhno))$
+ $IF (INH.INHATR[inhno] & TA_NONKERNEL) != 0$
+ $ERROR INH.TEXT_LINE[inhno]$E_RSATR: $FORMAT(_("%1% `%2%\' must not be non-kernel interrupt"), "inhno", INH.INHNO[inhno])$$END$
+ $END$
+ $END$
+
+$ // カーネル管理外に固定されているinhnoに対して,inhatrにTA_NONKERNEL
+$ // が指定されていない場合(E_RSATR)
+ $IF LENGTH(FIND(INHNO_FIX_NONKERNEL, inhno))$
+ $IF (INH.INHATR[inhno] & TA_NONKERNEL) == 0$
+ $ERROR INH.TEXT_LINE[inhno]$E_RSATR: $FORMAT(_("%1% `%2%\' must be non-kernel interrupt"), "inhno", INH.INHNO[inhno])$$END$
+ $END$
+ $END$
+
+ $IF LENGTH(INTNO[INH.INHNO[inhno]])$
+ $intno = INTNO[INH.INHNO[inhno]]$
+ $IF LENGTH(FIND(INTNO_CFGINT_VALID, intno))$
+$ // inhnoに対応するintnoに対するCFG_INTがない場合(E_OBJ)
+ $IF !LENGTH(INT.INTNO[intno])$
+ $ERROR INH.TEXT_LINE[inhno]$E_OBJ: $FORMAT(_("%1% `%2%\' corresponding to %3% `%4%\' is not configured with %5%"), "intno", INT.INTNO[intno], "inhno", INH.INHNO[inhno], "CFG_INT")$$END$
+ $ELSE$
+ $IF (INH.INHATR[inhno] & TA_NONKERNEL) == 0$
+$ // inhatrにTA_NONKERNELが指定されておらず,inhnoに対応
+$ // するintnoに対してCFG_INTで設定された割込み優先度が
+$ // TMIN_INTPRIよりも小さい場合(E_OBJ)
+ $IF INT.INTPRI[intno] < TMIN_INTPRI$
+ $ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' configured for %3% `%4%\' is higher than %5%"), "intpri", INT.INTPRI[intno], "inhno", INH.INHNO[inhno], "TMIN_INTPRI")$$END$
+ $END$
+ $ELSE$
+$ // inhatrにTA_NONKERNELが指定されており,inhnoに対応
+$ // するintnoに対してCFG_INTで設定された割込み優先度が
+$ // TMIN_INTPRI以上である場合(E_OBJ)
+ $IF INT.INTPRI[intno] >= TMIN_INTPRI$
+ $ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' configured for %3% `%4%\' is lower than or equal to %5%"), "intpri", INT.INTPRI[intno], "inhno", INH.INHNO[inhno], "TMIN_INTPRI")$$END$
+ $END$
+ $END$
+ $END$
+ $END$
+ $END$
+ $i = i + 1$
+$END$
+
+$ 割込みサービスルーチン(ISR)に関するエラーチェックと割込みハンドラの生成
+$FOREACH order ISR.ORDER_LIST$
+$ // isratrが(TA_NULL)でない場合(E_RSATR)
+ $IF (ISR.ISRATR[order] & ~ALT(TARGET_ISRATR,0)) != 0$
+ $ERROR ISR.TEXT_LINE[order]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "isratr", ISR.ISRATR[order], "isr", ISR.ISR[order], "ATT_ISR")$$END$
+ $END$
+
+$ // intnoがATT_ISRに対する割込み番号として正しくない場合(E_PAR)
+ $IF !LENGTH(FIND(INTNO_ATTISR_VALID, ISR.INTNO[order]))$
+ $ERROR ISR.TEXT_LINE[order]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "intno", ISR.INTNO[order], "ATT_ISR")$$END$
+ $END$
+
+$ // (TMIN_ISRPRI <= isrpri && isrpri <= TMAX_ISRPRI)でない場合(E_PAR)
+ $IF !(TMIN_ISRPRI <= ISR.ISRPRI[order] && ISR.ISRPRI[order] <= TMAX_ISRPRI)$
+ $ERROR ISR.TEXT_LINE[order]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "isrpri", ISR.ISRPRI[order], "ATT_ISR")$$END$
+ $END$
+$END$
+
+$FOREACH intno INTNO_ATTISR_VALID$
+ $inhno = INHNO[intno]$
+
+$ // 割込み番号intnoに対して登録されたISRのリストの作成
+ $isr_order_list = {}$
+ $FOREACH order ISR.ORDER_LIST$
+ $IF ISR.INTNO[order] == intno$
+ $isr_order_list = APPEND(isr_order_list, order)$
+ $order_for_error = order$
+ $END$
+ $END$
+
+$ // 割込み番号intnoに対して登録されたISRが存在する場合
+ $IF LENGTH(isr_order_list) > 0$
+$ // intnoに対応するinhnoに対してDEF_INHがある場合(E_OBJ)
+ $IF LENGTH(INH.INHNO[inhno])$
+ $ERROR ISR.TEXT_LINE[order_for_error]$E_OBJ: $FORMAT(_("%1% `%2%\' in %3% is duplicated with %4% `%5%\'"), "intno", ISR.INTNO[order_for_error], "ATT_ISR", "inhno", INH.INHNO[inhno])$$END$
+ $END$
+
+$ // intnoに対するCFG_INTがない場合(E_OBJ)
+ $IF !LENGTH(INT.INTNO[intno])$
+ $ERROR ISR.TEXT_LINE[order_for_error]$E_OBJ: $FORMAT(_("%1% `%2%\' is not configured with %3%"), "intno", ISR.INTNO[order_for_error], "CFG_INT")$$END$
+ $ELSE$
+$ // intnoに対してCFG_INTで設定された割込み優先度がTMIN_INTPRI
+$ // よりも小さい場合(E_OBJ)
+ $IF INT.INTPRI[intno] < TMIN_INTPRI$
+ $ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' configured for %3% `%4%\' is higher than %5%"), "intpri", INT.INTPRI[intno], "intno", ISR.INTNO[order_for_error], "TMIN_INTPRI")$$END$
+ $END$
+ $END$
+
+$ // DEF_INH(inhno, { TA_NULL, _kernel_inthdr_<intno> } );
+ $INH.INHNO[inhno] = inhno$
+ $INH.INHATR[inhno] = VALUE("TA_NULL", 0)$
+ $INH.INTHDR[inhno] = CONCAT("_kernel_inthdr_", intno)$
+ $INH.ORDER_LIST = APPEND(INH.ORDER_LIST, inhno)$
+
+$ // ISR用の割込みハンドラ
+ void$NL$
+ _kernel_inthdr_$intno$(void)$NL$
+ {$NL$
+ $IF LENGTH(isr_order_list) > 1$
+ $TAB$PRI saved_ipm;$NL$
+ $NL$
+ $TAB$i_begin_int($intno$);$NL$
+ $TAB$saved_ipm = i_get_ipm();$NL$
+ $ELSE$
+ $TAB$i_begin_int($intno$);$NL$
+ $END$
+$ // ISRを優先度順に呼び出す
+ $JOINEACH order SORT(isr_order_list, "ISR.ISRPRI") "\tif (i_sense_lock()) {\n\t\ti_unlock_cpu();\n\t}\n\ti_set_ipm(saved_ipm);\n"$
+ $TAB$LOG_ISR_ENTER($intno$);$NL$
+ $TAB$((ISR)($ISR.ISR[order]$))((intptr_t)($ISR.EXINF[order]$));$NL$
+ $TAB$LOG_ISR_LEAVE($intno$);$NL$
+ $END$
+ $TAB$i_end_int($intno$);$NL$
+ }$NL$
+ $END$
+$END$
+$NL$
+
+$
+$ 割込み管理機能のための標準的な初期化情報の生成
+$
+$ 割込みハンドラの初期化に必要な情報
+$IF !ALT(OMIT_INITIALIZE_INTERRUPT,0) || ALT(USE_INHINIB_TABLE,0)$
+
+$ 割込みハンドラ数
+#define TNUM_INHNO $LENGTH(INH.ORDER_LIST)$$NL$
+const uint_t _kernel_tnum_inhno = TNUM_INHNO;$NL$
+$NL$
+$FOREACH inhno INH.ORDER_LIST$
+ $IF (INH.INHATR[inhno] & TA_NONKERNEL) == 0$
+ INTHDR_ENTRY($INH.INHNO[inhno]$, $+INH.INHNO[inhno]$, $INH.INTHDR[inhno]$)$NL$
+ $END$
+$END$
+$NL$
+
+$ 割込みハンドラ初期化テーブル
+$IF LENGTH(INH.ORDER_LIST)$
+ const INHINIB _kernel_inhinib_table[TNUM_INHNO] = {$NL$
+ $JOINEACH inhno INH.ORDER_LIST ",\n"$
+ $IF (INH.INHATR[inhno] & TA_NONKERNEL) == 0$
+ $TAB${ ($INH.INHNO[inhno]$), ($INH.INHATR[inhno]$), (FP)(INT_ENTRY($INH.INHNO[inhno]$, $INH.INTHDR[inhno]$)) }
+ $ELSE$
+ $TAB${ ($INH.INHNO[inhno]$), ($INH.INHATR[inhno]$), (FP)($INH.INTHDR[inhno]$) }
+ $END$
+ $END$$NL$
+ };$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const INHINIB, _kernel_inhinib_table);$NL$
+$END$
+$NL$
+$END$
+
+$ 割込み要求ラインの初期化に必要な情報
+$IF !ALT(OMIT_INITIALIZE_INTERRUPT,0) || ALT(USE_INHINTB_TABLE,0)$
+
+$ 割込み要求ライン数
+#define TNUM_INTNO $LENGTH(INT.ORDER_LIST)$$NL$
+const uint_t _kernel_tnum_intno = TNUM_INTNO;$NL$
+$NL$
+
+$ 割込み要求ライン初期化テーブル
+$IF LENGTH(INT.ORDER_LIST)$
+ const INTINIB _kernel_intinib_table[TNUM_INTNO] = {$NL$
+ $JOINEACH intno INT.ORDER_LIST ",\n"$
+ $TAB${ ($INT.INTNO[intno]$), ($INT.INTATR[intno]$), ($INT.INTPRI[intno]$) }
+ $END$$NL$
+ };$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const INTINIB, _kernel_intinib_table);$NL$
+$END$
+$NL$
+$END$
+
+$
+$ CPU例外管理機能
+$
+/*$NL$
+$SPC$* CPU Exception Management Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ CPU例外ハンドラに関するエラーチェック
+$i = 0$
+$FOREACH excno EXC.ORDER_LIST$
+$ // excnoがDEF_EXCに対するCPU例外ハンドラ番号として正しくない場合(E_PAR)
+ $IF !LENGTH(FIND(EXCNO_DEFEXC_VALID, EXC.EXCNO[excno]))$
+ $ERROR EXC.TEXT_LINE[excno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "excno", EXC.EXCNO[excno], "DEF_EXC")$$END$
+ $END$
+
+$ // excnoがDEF_EXCによって設定済みの場合(E_OBJ)
+ $j = 0$
+ $FOREACH excno2 EXC.ORDER_LIST$
+ $IF EXC.EXCNO[excno] == EXC.EXCNO[excno2] && j < i$
+ $ERROR EXC.TEXT_LINE[excno]$E_OBJ: $FORMAT(_("%1% `%2%\' in %3% is duplicated"), "excno", EXC.EXCNO[excno], "DEF_EXC")$$END$
+ $END$
+ $j = j + 1$
+ $END$
+
+$ // excatrが(TA_NULL)でない場合(E_RSATR)
+ $IF (EXC.EXCATR[excno] & ~ALT(TARGET_EXCATR,0)) != 0$
+ $ERROR EXC.TEXT_LINE[excno]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "excatr", EXC.EXCATR[excno], "excno", EXC.EXCNO[excno], "DEF_EXC")$$END$
+ $END$
+ $i = i + 1$
+$END$
+
+$ CPU例外ハンドラのための標準的な初期化情報の生成
+$IF !ALT(OMIT_INITIALIZE_EXCEPTION,0)$
+
+$ CPU例外ハンドラ数
+#define TNUM_EXCNO $LENGTH(EXC.ORDER_LIST)$$NL$
+const uint_t _kernel_tnum_excno = TNUM_EXCNO;$NL$
+$NL$
+$FOREACH excno EXC.ORDER_LIST$
+ EXCHDR_ENTRY($EXC.EXCNO[excno]$, $+EXC.EXCNO[excno]$, $EXC.EXCHDR[excno]$)$NL$
+$END$
+$NL$
+
+$ CPU例外ハンドラ初期化テーブル
+$IF LENGTH(EXC.ORDER_LIST)$
+ const EXCINIB _kernel_excinib_table[TNUM_EXCNO] = {$NL$
+ $JOINEACH excno EXC.ORDER_LIST ",\n"$
+ $TAB${ ($EXC.EXCNO[excno]$), ($EXC.EXCATR[excno]$), (FP)(EXC_ENTRY($EXC.EXCNO[excno]$, $EXC.EXCHDR[excno]$)) }
+ $END$$NL$
+ };$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const EXCINIB, _kernel_excinib_table);$NL$
+$END$
+$NL$
+$END$
+
+$
+$ 非タスクコンテキスト用のスタック領域
+$
+/*$NL$
+$SPC$* Stack Area for Non-task Context$NL$
+$SPC$*/$NL$
+$NL$
+
+$IF !LENGTH(ICS.ORDER_LIST)$
+$ // DEF_ICSがない場合のデフォルト値の設定
+ #ifdef DEFAULT_ISTK$NL$
+ $NL$
+ #define TOPPERS_ISTKSZ DEFAULT_ISTKSZ$NL$
+ #define TOPPERS_ISTK DEFAULT_ISTK$NL$
+ $NL$
+ #else /* DEAULT_ISTK */$NL$
+ $NL$
+ static STK_T _kernel_istack[COUNT_STK_T(DEFAULT_ISTKSZ)];$NL$
+ #define TOPPERS_ISTKSZ ROUND_STK_T(DEFAULT_ISTKSZ)$NL$
+ #define TOPPERS_ISTK _kernel_istack$NL$
+ $NL$
+ #endif /* DEAULT_ISTK */$NL$
+$ELSE$
+
+$ // 静的API「DEF_ICS」が複数ある(E_OBJ)
+ $IF LENGTH(ICS.ORDER_LIST) > 1$
+ $ERROR$E_OBJ: $FORMAT(_("too many %1%"), "DEF_ICS")$$END$
+ $END$
+
+$ // istkszがスタック領域のサイズとして正しくない場合(E_PAR)
+ $IF !EQ(ICS.ISTK[1], "NULL") && LENGTH(CHECK_STKSZ_ALIGN)
+ && (ICS.ISTKSZ[1] & (CHECK_STKSZ_ALIGN - 1))$
+ $ERROR ICS.TEXT_LINE[1]$E_PAR: $FORMAT(_("%1% `%2%\' in %3% is not aligned"), "istksz", ICS.ISTKSZ[1], "DEF_ICS")$$END$
+ $END$
+
+ $IF EQ(ICS.ISTK[1], "NULL")$
+$ // スタック領域の自動割付け
+ static STK_T _kernel_istack[COUNT_STK_T($ICS.ISTKSZ[1]$)];$NL$
+ #define TOPPERS_ISTKSZ ROUND_STK_T($ICS.ISTKSZ[1]$)$NL$
+ #define TOPPERS_ISTK _kernel_istack$NL$
+ $ELSE$
+ #define TOPPERS_ISTKSZ ($ICS.ISTKSZ[1]$)$NL$
+ #define TOPPERS_ISTK ($ICS.ISTK[1]$)$NL$
+ $END$
+$END$
+$NL$
+
+$ 非タスクコンテキスト用のスタック領域
+const SIZE _kernel_istksz = TOPPERS_ISTKSZ;$NL$
+STK_T *const _kernel_istk = TOPPERS_ISTK;$NL$
+$NL$
+#ifdef TOPPERS_ISTKPT$NL$
+STK_T *const _kernel_istkpt = TOPPERS_ISTKPT(TOPPERS_ISTK, TOPPERS_ISTKSZ);$NL$
+#endif /* TOPPERS_ISTKPT */$NL$
+$NL$
+
+$
+$ タイムイベント管理
+$
+/*$NL$
+$SPC$* Time Event Management$NL$
+$SPC$*/$NL$
+$NL$
+TMEVTN _kernel_tmevt_heap[TNUM_TSKID + TNUM_CYCID + TNUM_ALMID];$NL$
+$NL$
+
+$
+$ 各モジュールの初期化関数
+$
+/*$NL$
+$SPC$* Module Initialization Function$NL$
+$SPC$*/$NL$
+$NL$
+void$NL$
+_kernel_initialize_object(void)$NL$
+{$NL$
+$TAB$_kernel_initialize_task();$NL$
+$IF LENGTH(SEM.ID_LIST)$ _kernel_initialize_semaphore();$NL$$END$
+$IF LENGTH(FLG.ID_LIST)$ _kernel_initialize_eventflag();$NL$$END$
+$IF LENGTH(DTQ.ID_LIST)$ _kernel_initialize_dataqueue();$NL$$END$
+$IF LENGTH(PDQ.ID_LIST)$ _kernel_initialize_pridataq();$NL$$END$
+$IF LENGTH(MBX.ID_LIST)$ _kernel_initialize_mailbox();$NL$$END$
+$IF LENGTH(MTX.ID_LIST)$ _kernel_initialize_mutex();$NL$$END$
+$IF LENGTH(MPF.ID_LIST)$ _kernel_initialize_mempfix();$NL$$END$
+$IF LENGTH(CYC.ID_LIST)$ _kernel_initialize_cyclic();$NL$$END$
+$IF LENGTH(ALM.ID_LIST)$ _kernel_initialize_alarm();$NL$$END$
+$TAB$_kernel_initialize_interrupt();$NL$
+$TAB$_kernel_initialize_exception();$NL$
+}$NL$
+$NL$
+
+$
+$ 初期化ルーチンの実行関数
+$
+/*$NL$
+$SPC$* Initialization Routine$NL$
+$SPC$*/$NL$
+$NL$
+void$NL$
+_kernel_call_inirtn(void)$NL$
+{$NL$
+$FOREACH order INI.ORDER_LIST$
+$ // iniatrが(TA_NULL)でない場合(E_RSATR)
+ $IF INI.INIATR[order] != 0$
+ $ERROR INI.TEXT_LINE[order]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "iniatr", INI.INIATR[order], "inirtn", INI.INIRTN[order], "ATT_INI")$$END$
+ $END$
+ $TAB$((INIRTN)($INI.INIRTN[order]$))((intptr_t)($INI.EXINF[order]$));$NL$
+$END$
+}$NL$
+$NL$
+
+$
+$ 終了処理ルーチンの実行関数
+$
+/*$NL$
+$SPC$* Termination Routine$NL$
+$SPC$*/$NL$
+$NL$
+void$NL$
+_kernel_call_terrtn(void)$NL$
+{$NL$
+$FOREACH rorder TER.RORDER_LIST$
+$ // teratrが(TA_NULL)でない場合(E_RSATR)
+ $IF TER.TERATR[rorder] != 0$
+ $ERROR TER.TEXT_LINE[rorder]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "teratr", TER.TERATR[rorder], "terrtn", TER.TERRTN[rorder], "ATT_TER")$$END$
+ $END$
+ $TAB$((TERRTN)($TER.TERRTN[rorder]$))((intptr_t)($TER.EXINF[rorder]$));$NL$
+$END$
+}$NL$
+$NL$
--- /dev/null
+tsk,CRE_TSK,#tskid { .tskatr &exinf &task +itskpri .stksz &stk },,
+tsk,DEF_TEX,%tskid { .texatr &texrtn },0,1,
+sem,CRE_SEM,#semid { .sematr .isemcnt .maxsem },,
+flg,CRE_FLG,#flgid { .flgatr .iflgptn },,
+dtq,CRE_DTQ,#dtqid { .dtqatr .dtqcnt &dtqmb },,
+pdq,CRE_PDQ,#pdqid { .pdqatr .pdqcnt +maxdpri &pdqmb },,
+mbx,CRE_MBX,#mbxid { .mbxatr +maxmpri &mprihd },,
+mtx,CRE_MTX,#mtxid { .mtxatr +ceilpri? },,
+mpf,CRE_MPF,#mpfid { .mpfatr .blkcnt .blksz &mpf &mpfmb },,
+cyc,CRE_CYC,#cycid { .cycatr &exinf &cychdr .cyctim .cycphs },,
+alm,CRE_ALM,#almid { .almatr &exinf &almhdr },,
+int,CFG_INT,.intno { .intatr +intpri },,
+isr,ATT_ISR,{ .isratr &exinf .intno &isr +isrpri },-1,
+inh,DEF_INH,.inhno { .inhatr &inthdr },,
+ics,DEF_ICS,{ .istksz &istk },-1,
+exc,DEF_EXC,.excno { .excatr &exchdr },,
+ini,ATT_INI,{ .iniatr &exinf &inirtn },-1,
+ter,ATT_TER,{ .teratr &exinf &terrtn },-1,
--- /dev/null
+TA_NULL,TA_NULL
+TA_ACT,TA_ACT
+TA_TPRI,TA_TPRI
+TA_MPRI,TA_MPRI
+TA_WMUL,TA_WMUL
+TA_CLR,TA_CLR
+TA_CEILING,TA_CEILING
+TA_STA,TA_STA
+TA_NONKERNEL,TA_NONKERNEL
+TA_ENAINT,TA_ENAINT
+TA_EDGE,TA_EDGE
+TMIN_TPRI,TMIN_TPRI,signed
+TMAX_TPRI,TMAX_TPRI,signed
+TMIN_DPRI,TMIN_DPRI,signed
+TMAX_DPRI,TMAX_DPRI,signed
+TMIN_MPRI,TMIN_MPRI,signed
+TMAX_MPRI,TMAX_MPRI,signed
+TMIN_ISRPRI,TMIN_ISRPRI,signed
+TMAX_ISRPRI,TMAX_ISRPRI,signed
+TMAX_MAXSEM,TMAX_MAXSEM
+TMAX_RELTIM,TMAX_RELTIM
+TMIN_INTPRI,TMIN_INTPRI,signed
+OMIT_INITIALIZE_INTERRUPT,#defined(OMIT_INITIALIZE_INTERRUPT)
+OMIT_INITIALIZE_EXCEPTION,#defined(OMIT_INITIALIZE_EXCEPTION)
+USE_TSKINICTXB,#defined(USE_TSKINICTXB)
+sizeof_ID,sizeof(ID)
+sizeof_uint_t,sizeof(uint_t)
+sizeof_SIZE,sizeof(SIZE)
+sizeof_ATR,sizeof(ATR)
+sizeof_PRI,sizeof(PRI)
+sizeof_void_ptr,sizeof(void*)
+sizeof_VP,sizeof(void*)
+sizeof_intptr_t,sizeof(intptr_t)
+sizeof_FP,sizeof(FP)
+sizeof_TINIB,sizeof(TINIB)
+offsetof_TINIB_tskatr,"offsetof(TINIB,tskatr)"
+offsetof_TINIB_exinf,"offsetof(TINIB,exinf)"
+offsetof_TINIB_task,"offsetof(TINIB,task)"
+offsetof_TINIB_ipriority,"offsetof(TINIB,ipriority)"
+offsetof_TINIB_stksz,#!defined(USE_TSKINICTXB),,"offsetof(TINIB,stksz)"
+offsetof_TINIB_stk,#!defined(USE_TSKINICTXB),,"offsetof(TINIB,stk)"
+offsetof_TINIB_texatr,"offsetof(TINIB,texatr)"
+offsetof_TINIB_texrtn,"offsetof(TINIB,texrtn)"
+sizeof_SEMINIB,sizeof(SEMINIB)
+offsetof_SEMINIB_sematr,"offsetof(SEMINIB,sematr)"
+offsetof_SEMINIB_isemcnt,"offsetof(SEMINIB,isemcnt)"
+offsetof_SEMINIB_maxsem,"offsetof(SEMINIB,maxsem)"
+sizeof_FLGPTN,sizeof(FLGPTN)
+sizeof_FLGINIB,sizeof(FLGINIB)
+offsetof_FLGINIB_flgatr,"offsetof(FLGINIB,flgatr)"
+offsetof_FLGINIB_iflgptn,"offsetof(FLGINIB,iflgptn)"
+sizeof_DTQINIB,sizeof(DTQINIB)
+offsetof_DTQINIB_dtqatr,"offsetof(DTQINIB,dtqatr)"
+offsetof_DTQINIB_dtqcnt,"offsetof(DTQINIB,dtqcnt)"
+offsetof_DTQINIB_p_dtqmb,"offsetof(DTQINIB,p_dtqmb)"
+sizeof_PDQINIB,sizeof(PDQINIB)
+offsetof_PDQINIB_pdqatr,"offsetof(PDQINIB,pdqatr)"
+offsetof_PDQINIB_pdqcnt,"offsetof(PDQINIB,pdqcnt)"
+offsetof_PDQINIB_maxdpri,"offsetof(PDQINIB,maxdpri)"
+offsetof_PDQINIB_p_pdqmb,"offsetof(PDQINIB,p_pdqmb)"
+sizeof_MBXINIB,sizeof(MBXINIB)
+offsetof_MBXINIB_mbxatr,"offsetof(MBXINIB,mbxatr)"
+offsetof_MBXINIB_maxmpri,"offsetof(MBXINIB,maxmpri)"
+sizeof_MPFINIB,sizeof(MPFINIB)
+offsetof_MPFINIB_mpfatr,"offsetof(MPFINIB,mpfatr)"
+offsetof_MPFINIB_blkcnt,"offsetof(MPFINIB,blkcnt)"
+offsetof_MPFINIB_blksz,"offsetof(MPFINIB,blksz)"
+offsetof_MPFINIB_mpf,"offsetof(MPFINIB,mpf)"
+offsetof_MPFINIB_p_mpfmb,"offsetof(MPFINIB,p_mpfmb)"
+sizeof_CYCINIB,sizeof(CYCINIB)
+offsetof_CYCINIB_cycatr,"offsetof(CYCINIB,cycatr)"
+offsetof_CYCINIB_exinf,"offsetof(CYCINIB,exinf)"
+offsetof_CYCINIB_cychdr,"offsetof(CYCINIB,cychdr)"
+offsetof_CYCINIB_cyctim,"offsetof(CYCINIB,cyctim)"
+offsetof_CYCINIB_cycphs,"offsetof(CYCINIB,cycphs)"
+sizeof_ALMINIB,sizeof(ALMINIB)
+offsetof_ALMINIB_almatr,"offsetof(ALMINIB,almatr)"
+offsetof_ALMINIB_exinf,"offsetof(ALMINIB,exinf)"
+offsetof_ALMINIB_almhdr,"offsetof(ALMINIB,almhdr)"
+sizeof_INHNO,sizeof(INHNO)
+sizeof_INTNO,sizeof(INTNO)
+sizeof_EXCNO,sizeof(EXCNO)
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: kernel_impl.h 1713 2010-01-27 13:23:29Z ertl-hiro $
+ */
+
+/*
+ * TOPPERS/ASPカーネル内部向け標準ヘッダファイル
+ *
+ * このヘッダファイルは,カーネルを構成するプログラムのソースファイル
+ * で必ずインクルードするべき標準ヘッダファイルである.
+ *
+ * アセンブリ言語のソースファイルからこのファイルをインクルードする時
+ * は,TOPPERS_MACRO_ONLYを定義しておく.これにより,マクロ定義以外を
+ * 除くようになっている.
+ */
+
+#ifndef TOPPERS_KERNEL_IMPL_H
+#define TOPPERS_KERNEL_IMPL_H
+
+/*
+ * カーネルの内部識別名のリネーム
+ */
+#include "kernel_rename.h"
+
+/*
+ * アプリケーションと共通のヘッダファイル
+ */
+#include <kernel.h>
+
+/*
+ * システムログ機能のための定義
+ */
+#include <t_syslog.h>
+
+/*
+ * 型キャストを行うマクロの定義
+ */
+#ifndef CAST
+#define CAST(type, val) ((type)(val))
+#endif /* CAST */
+
+/*
+ * ターゲット依存情報の定義
+ */
+#include "target_config.h"
+
+/*
+ * すべての関数をコンパイルするための定義
+ */
+#ifdef ALLFUNC
+#include "allfunc.h"
+#endif /* ALLFUNC */
+
+/*
+ * ビットフィールドでの符号無し整数型
+ *
+ * 8ビット以下の幅のビットフィールドで,符号無し整数値を保持したい場合
+ * に用いるべきデータ型.ANSI Cでは,ビットフィールドのデータ型には
+ * intとunsigned intしか許されないため,デフォルトの定義はunsigned
+ * intとしているが,ターゲットおよびツール依存で,unsigned charまたは
+ * unsigned shortに定義した方が効率が良い場合がある.
+ */
+#ifndef BIT_FIELD_UINT
+#define BIT_FIELD_UINT unsigned int
+#endif /* BIT_FIELD_UINT */
+
+/*
+ * ビットフィールドでのブール型
+ *
+ * 1ビット幅のビットフィールドで,ブール値を保持したい場合に用いるべき
+ * データ型.デフォルトではBIT_FIELD_UINTと同一に定義しているが,ブー
+ * ル値を保持することを明示するために別の名称としている.
+ */
+#ifndef BIT_FIELD_BOOL
+#define BIT_FIELD_BOOL BIT_FIELD_UINT
+#endif /* BIT_FIELD_BOOL */
+
+/*
+ * オブジェクトIDの最小値の定義
+ */
+#define TMIN_TSKID 1 /* タスクIDの最小値 */
+#define TMIN_SEMID 1 /* セマフォIDの最小値 */
+#define TMIN_FLGID 1 /* フラグIDの最小値 */
+#define TMIN_DTQID 1 /* データキューIDの最小値 */
+#define TMIN_PDQID 1 /* 優先度データキューIDの最小値 */
+#define TMIN_MBXID 1 /* メールボックスIDの最小値 */
+#define TMIN_MTXID 1 /* ミューテックスIDの最小値 */
+#define TMIN_MPFID 1 /* 固定長メモリプールIDの最小値 */
+#define TMIN_CYCID 1 /* 周期ハンドラIDの最小値 */
+#define TMIN_ALMID 1 /* アラームハンドラIDの最小値 */
+
+/*
+ * 優先度の段階数の定義
+ */
+#define TNUM_TPRI (TMAX_TPRI - TMIN_TPRI + 1)
+#define TNUM_MPRI (TMAX_MPRI - TMIN_MPRI + 1)
+#define TNUM_INTPRI (TMAX_INTPRI - TMIN_INTPRI + 1)
+
+/*
+ * ヘッダファイルを持たないモジュールの関数・変数の宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ * 各モジュールの初期化(kernel_cfg.c)
+ */
+extern void initialize_object(void);
+
+/*
+ * 初期化ルーチンの実行(kernel_cfg.c)
+ */
+extern void call_inirtn(void);
+
+/*
+ * 終了処理ルーチンの実行(kernel_cfg.c)
+ */
+extern void call_terrtn(void);
+
+/*
+ * 非タスクコンテキスト用のスタック領域(kernel_cfg.c)
+ */
+extern const SIZE istksz; /* スタック領域のサイズ(丸めた値) */
+extern STK_T *const istk; /* スタック領域の先頭番地 */
+#ifdef TOPPERS_ISTKPT
+extern STK_T *const istkpt; /* スタックポインタの初期値 */
+#endif /* TOPPERS_ISTKPT */
+
+/*
+ * カーネル動作状態フラグ(startup.c)
+ */
+extern bool_t kerflg;
+
+/*
+ * カーネルの起動(startup.c)
+ */
+extern void sta_ker(void);
+
+/*
+ * カーネルの終了処理(startup.c)
+ */
+extern void exit_kernel(void);
+
+#endif /* TOPPERS_MACRO_ONLY */
+#endif /* TOPPERS_KERNEL_IMPL_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: kernel_int.h 525 2007-09-11 18:01:00Z hiro $
+ */
+
+/*
+ * kernel_cfg.c(およびcfg1_out.c)用ヘッダファイル
+ */
+
+#ifndef TOPPERS_KERNEL_INT_H
+#define TOPPERS_KERNEL_INT_H
+
+/*
+ * カーネル標準ヘッダファイル
+ */
+#include "kernel_impl.h"
+
+/*
+ * カーネルの各ヘッダファイル
+ */
+#include "task.h"
+#include "semaphore.h"
+#include "eventflag.h"
+#include "dataqueue.h"
+#include "pridataq.h"
+#include "mailbox.h"
+#include "mempfix.h"
+#include "mutex.h"
+#include "cyclic.h"
+#include "alarm.h"
+#include "interrupt.h"
+#include "exception.h"
+#include "time_event.h"
+
+/*
+ * リネームしたシンボルを元に戻すためのヘッダファイル
+ */
+#include "kernel_unrename.h"
+
+#endif /* TOPPERS_KERNEL_INT_H */
--- /dev/null
+# startup.c
+kerflg
+exit_kernel
+
+# task.c
+p_runtsk
+p_schedtsk
+reqflg
+disdsp
+dspflg
+ready_queue
+ready_primap
+initialize_task
+search_schedtsk
+make_runnable
+make_non_runnable
+make_dormant
+make_active
+change_priority
+rotate_ready_queue
+call_texrtn
+calltex
+
+# wait.c
+make_wait_tmout
+wait_complete
+wait_tmout
+wait_tmout_ok
+wait_release
+wobj_make_wait
+wobj_make_wait_tmout
+init_wait_queue
+
+# time_event.c
+current_time
+min_time
+next_time
+next_subtime
+last_index
+initialize_tmevt
+tmevt_up
+tmevt_down
+tmevtb_insert
+tmevtb_delete
+tmevt_lefttim
+signal_time
+
+# semaphore.c
+initialize_semaphore
+
+# eventflag.c
+initialize_eventflag
+check_flg_cond
+
+# dataqueue.c
+initialize_dataqueue
+enqueue_data
+force_enqueue_data
+dequeue_data
+send_data
+force_send_data
+receive_data
+
+# pridataq.c
+initialize_pridataq
+enqueue_pridata
+dequeue_pridata
+send_pridata
+receive_pridata
+
+# mailbox.c
+initialize_mailbox
+
+# mempfix.c
+initialize_mempfix
+get_mpf_block
+
+# mutex.c
+mtxhook_check_ceilpri
+mtxhook_scan_ceilmtx
+mtxhook_release_all
+initialize_mutex
+mutex_check_ceilpri
+mutex_scan_ceilmtx
+mutex_calc_priority
+mutex_release
+mutex_release_all
+
+# cyclic.c
+initialize_cyclic
+call_cychdr
+
+# alarm.c
+initialize_alarm
+call_almhdr
+
+# interrupt.c
+initialize_interrupt
+
+# exception.c
+initialize_exception
+
+# kernel_cfg.c
+initialize_object
+call_inirtn
+call_terrtn
+tmax_tskid
+tinib_table
+torder_table
+tcb_table
+tmax_semid
+seminib_table
+semcb_table
+tmax_flgid
+flginib_table
+flgcb_table
+tmax_dtqid
+dtqcb_table
+dtqinib_table
+tmax_pdqid
+pdqcb_table
+pdqinib_table
+tmax_mbxid
+mbxcb_table
+mbxinib_table
+tmax_mtxid
+mtxcb_table
+mtxinib_table
+tmax_mpfid
+mpfinib_table
+mpfcb_table
+tmax_cycid
+cycinib_table
+cyccb_table
+tmax_almid
+alminib_table
+almcb_table
+tnum_inhno
+inhinib_table
+tnum_intno
+intinib_table
+tnum_excno
+excinib_table
+tmevt_heap
+istksz
+istk
+istkpt
+
+INCLUDE "target"
--- /dev/null
+/* This file is generated from kernel_rename.def by genrename. */
+
+#ifndef TOPPERS_KERNEL_RENAME_H
+#define TOPPERS_KERNEL_RENAME_H
+
+/*
+ * startup.c
+ */
+#define kerflg _kernel_kerflg
+#define exit_kernel _kernel_exit_kernel
+
+/*
+ * task.c
+ */
+#define p_runtsk _kernel_p_runtsk
+#define p_schedtsk _kernel_p_schedtsk
+#define reqflg _kernel_reqflg
+#define disdsp _kernel_disdsp
+#define dspflg _kernel_dspflg
+#define ready_queue _kernel_ready_queue
+#define ready_primap _kernel_ready_primap
+#define initialize_task _kernel_initialize_task
+#define search_schedtsk _kernel_search_schedtsk
+#define make_runnable _kernel_make_runnable
+#define make_non_runnable _kernel_make_non_runnable
+#define make_dormant _kernel_make_dormant
+#define make_active _kernel_make_active
+#define change_priority _kernel_change_priority
+#define rotate_ready_queue _kernel_rotate_ready_queue
+#define call_texrtn _kernel_call_texrtn
+#define calltex _kernel_calltex
+
+/*
+ * wait.c
+ */
+#define make_wait_tmout _kernel_make_wait_tmout
+#define wait_complete _kernel_wait_complete
+#define wait_tmout _kernel_wait_tmout
+#define wait_tmout_ok _kernel_wait_tmout_ok
+#define wait_release _kernel_wait_release
+#define wobj_make_wait _kernel_wobj_make_wait
+#define wobj_make_wait_tmout _kernel_wobj_make_wait_tmout
+#define init_wait_queue _kernel_init_wait_queue
+
+/*
+ * time_event.c
+ */
+#define current_time _kernel_current_time
+#define min_time _kernel_min_time
+#define next_time _kernel_next_time
+#define next_subtime _kernel_next_subtime
+#define last_index _kernel_last_index
+#define initialize_tmevt _kernel_initialize_tmevt
+#define tmevt_up _kernel_tmevt_up
+#define tmevt_down _kernel_tmevt_down
+#define tmevtb_insert _kernel_tmevtb_insert
+#define tmevtb_delete _kernel_tmevtb_delete
+#define tmevt_lefttim _kernel_tmevt_lefttim
+#define signal_time _kernel_signal_time
+
+/*
+ * semaphore.c
+ */
+#define initialize_semaphore _kernel_initialize_semaphore
+
+/*
+ * eventflag.c
+ */
+#define initialize_eventflag _kernel_initialize_eventflag
+#define check_flg_cond _kernel_check_flg_cond
+
+/*
+ * dataqueue.c
+ */
+#define initialize_dataqueue _kernel_initialize_dataqueue
+#define enqueue_data _kernel_enqueue_data
+#define force_enqueue_data _kernel_force_enqueue_data
+#define dequeue_data _kernel_dequeue_data
+#define send_data _kernel_send_data
+#define force_send_data _kernel_force_send_data
+#define receive_data _kernel_receive_data
+
+/*
+ * pridataq.c
+ */
+#define initialize_pridataq _kernel_initialize_pridataq
+#define enqueue_pridata _kernel_enqueue_pridata
+#define dequeue_pridata _kernel_dequeue_pridata
+#define send_pridata _kernel_send_pridata
+#define receive_pridata _kernel_receive_pridata
+
+/*
+ * mailbox.c
+ */
+#define initialize_mailbox _kernel_initialize_mailbox
+
+/*
+ * mempfix.c
+ */
+#define initialize_mempfix _kernel_initialize_mempfix
+#define get_mpf_block _kernel_get_mpf_block
+
+/*
+ * mutex.c
+ */
+#define mtxhook_check_ceilpri _kernel_mtxhook_check_ceilpri
+#define mtxhook_scan_ceilmtx _kernel_mtxhook_scan_ceilmtx
+#define mtxhook_release_all _kernel_mtxhook_release_all
+#define initialize_mutex _kernel_initialize_mutex
+#define mutex_check_ceilpri _kernel_mutex_check_ceilpri
+#define mutex_scan_ceilmtx _kernel_mutex_scan_ceilmtx
+#define mutex_calc_priority _kernel_mutex_calc_priority
+#define mutex_release _kernel_mutex_release
+#define mutex_release_all _kernel_mutex_release_all
+
+/*
+ * cyclic.c
+ */
+#define initialize_cyclic _kernel_initialize_cyclic
+#define call_cychdr _kernel_call_cychdr
+
+/*
+ * alarm.c
+ */
+#define initialize_alarm _kernel_initialize_alarm
+#define call_almhdr _kernel_call_almhdr
+
+/*
+ * interrupt.c
+ */
+#define initialize_interrupt _kernel_initialize_interrupt
+
+/*
+ * exception.c
+ */
+#define initialize_exception _kernel_initialize_exception
+
+/*
+ * kernel_cfg.c
+ */
+#define initialize_object _kernel_initialize_object
+#define call_inirtn _kernel_call_inirtn
+#define call_terrtn _kernel_call_terrtn
+#define tmax_tskid _kernel_tmax_tskid
+#define tinib_table _kernel_tinib_table
+#define torder_table _kernel_torder_table
+#define tcb_table _kernel_tcb_table
+#define tmax_semid _kernel_tmax_semid
+#define seminib_table _kernel_seminib_table
+#define semcb_table _kernel_semcb_table
+#define tmax_flgid _kernel_tmax_flgid
+#define flginib_table _kernel_flginib_table
+#define flgcb_table _kernel_flgcb_table
+#define tmax_dtqid _kernel_tmax_dtqid
+#define dtqcb_table _kernel_dtqcb_table
+#define dtqinib_table _kernel_dtqinib_table
+#define tmax_pdqid _kernel_tmax_pdqid
+#define pdqcb_table _kernel_pdqcb_table
+#define pdqinib_table _kernel_pdqinib_table
+#define tmax_mbxid _kernel_tmax_mbxid
+#define mbxcb_table _kernel_mbxcb_table
+#define mbxinib_table _kernel_mbxinib_table
+#define tmax_mtxid _kernel_tmax_mtxid
+#define mtxcb_table _kernel_mtxcb_table
+#define mtxinib_table _kernel_mtxinib_table
+#define tmax_mpfid _kernel_tmax_mpfid
+#define mpfinib_table _kernel_mpfinib_table
+#define mpfcb_table _kernel_mpfcb_table
+#define tmax_cycid _kernel_tmax_cycid
+#define cycinib_table _kernel_cycinib_table
+#define cyccb_table _kernel_cyccb_table
+#define tmax_almid _kernel_tmax_almid
+#define alminib_table _kernel_alminib_table
+#define almcb_table _kernel_almcb_table
+#define tnum_inhno _kernel_tnum_inhno
+#define inhinib_table _kernel_inhinib_table
+#define tnum_intno _kernel_tnum_intno
+#define intinib_table _kernel_intinib_table
+#define tnum_excno _kernel_tnum_excno
+#define excinib_table _kernel_excinib_table
+#define tmevt_heap _kernel_tmevt_heap
+#define istksz _kernel_istksz
+#define istk _kernel_istk
+#define istkpt _kernel_istkpt
+
+
+#ifdef TOPPERS_LABEL_ASM
+
+/*
+ * startup.c
+ */
+#define _kerflg __kernel_kerflg
+#define _exit_kernel __kernel_exit_kernel
+
+/*
+ * task.c
+ */
+#define _p_runtsk __kernel_p_runtsk
+#define _p_schedtsk __kernel_p_schedtsk
+#define _reqflg __kernel_reqflg
+#define _disdsp __kernel_disdsp
+#define _dspflg __kernel_dspflg
+#define _ready_queue __kernel_ready_queue
+#define _ready_primap __kernel_ready_primap
+#define _initialize_task __kernel_initialize_task
+#define _search_schedtsk __kernel_search_schedtsk
+#define _make_runnable __kernel_make_runnable
+#define _make_non_runnable __kernel_make_non_runnable
+#define _make_dormant __kernel_make_dormant
+#define _make_active __kernel_make_active
+#define _change_priority __kernel_change_priority
+#define _rotate_ready_queue __kernel_rotate_ready_queue
+#define _call_texrtn __kernel_call_texrtn
+#define _calltex __kernel_calltex
+
+/*
+ * wait.c
+ */
+#define _make_wait_tmout __kernel_make_wait_tmout
+#define _wait_complete __kernel_wait_complete
+#define _wait_tmout __kernel_wait_tmout
+#define _wait_tmout_ok __kernel_wait_tmout_ok
+#define _wait_release __kernel_wait_release
+#define _wobj_make_wait __kernel_wobj_make_wait
+#define _wobj_make_wait_tmout __kernel_wobj_make_wait_tmout
+#define _init_wait_queue __kernel_init_wait_queue
+
+/*
+ * time_event.c
+ */
+#define _current_time __kernel_current_time
+#define _min_time __kernel_min_time
+#define _next_time __kernel_next_time
+#define _next_subtime __kernel_next_subtime
+#define _last_index __kernel_last_index
+#define _initialize_tmevt __kernel_initialize_tmevt
+#define _tmevt_up __kernel_tmevt_up
+#define _tmevt_down __kernel_tmevt_down
+#define _tmevtb_insert __kernel_tmevtb_insert
+#define _tmevtb_delete __kernel_tmevtb_delete
+#define _tmevt_lefttim __kernel_tmevt_lefttim
+#define _signal_time __kernel_signal_time
+
+/*
+ * semaphore.c
+ */
+#define _initialize_semaphore __kernel_initialize_semaphore
+
+/*
+ * eventflag.c
+ */
+#define _initialize_eventflag __kernel_initialize_eventflag
+#define _check_flg_cond __kernel_check_flg_cond
+
+/*
+ * dataqueue.c
+ */
+#define _initialize_dataqueue __kernel_initialize_dataqueue
+#define _enqueue_data __kernel_enqueue_data
+#define _force_enqueue_data __kernel_force_enqueue_data
+#define _dequeue_data __kernel_dequeue_data
+#define _send_data __kernel_send_data
+#define _force_send_data __kernel_force_send_data
+#define _receive_data __kernel_receive_data
+
+/*
+ * pridataq.c
+ */
+#define _initialize_pridataq __kernel_initialize_pridataq
+#define _enqueue_pridata __kernel_enqueue_pridata
+#define _dequeue_pridata __kernel_dequeue_pridata
+#define _send_pridata __kernel_send_pridata
+#define _receive_pridata __kernel_receive_pridata
+
+/*
+ * mailbox.c
+ */
+#define _initialize_mailbox __kernel_initialize_mailbox
+
+/*
+ * mempfix.c
+ */
+#define _initialize_mempfix __kernel_initialize_mempfix
+#define _get_mpf_block __kernel_get_mpf_block
+
+/*
+ * mutex.c
+ */
+#define _mtxhook_check_ceilpri __kernel_mtxhook_check_ceilpri
+#define _mtxhook_scan_ceilmtx __kernel_mtxhook_scan_ceilmtx
+#define _mtxhook_release_all __kernel_mtxhook_release_all
+#define _initialize_mutex __kernel_initialize_mutex
+#define _mutex_check_ceilpri __kernel_mutex_check_ceilpri
+#define _mutex_scan_ceilmtx __kernel_mutex_scan_ceilmtx
+#define _mutex_calc_priority __kernel_mutex_calc_priority
+#define _mutex_release __kernel_mutex_release
+#define _mutex_release_all __kernel_mutex_release_all
+
+/*
+ * cyclic.c
+ */
+#define _initialize_cyclic __kernel_initialize_cyclic
+#define _call_cychdr __kernel_call_cychdr
+
+/*
+ * alarm.c
+ */
+#define _initialize_alarm __kernel_initialize_alarm
+#define _call_almhdr __kernel_call_almhdr
+
+/*
+ * interrupt.c
+ */
+#define _initialize_interrupt __kernel_initialize_interrupt
+
+/*
+ * exception.c
+ */
+#define _initialize_exception __kernel_initialize_exception
+
+/*
+ * kernel_cfg.c
+ */
+#define _initialize_object __kernel_initialize_object
+#define _call_inirtn __kernel_call_inirtn
+#define _call_terrtn __kernel_call_terrtn
+#define _tmax_tskid __kernel_tmax_tskid
+#define _tinib_table __kernel_tinib_table
+#define _torder_table __kernel_torder_table
+#define _tcb_table __kernel_tcb_table
+#define _tmax_semid __kernel_tmax_semid
+#define _seminib_table __kernel_seminib_table
+#define _semcb_table __kernel_semcb_table
+#define _tmax_flgid __kernel_tmax_flgid
+#define _flginib_table __kernel_flginib_table
+#define _flgcb_table __kernel_flgcb_table
+#define _tmax_dtqid __kernel_tmax_dtqid
+#define _dtqcb_table __kernel_dtqcb_table
+#define _dtqinib_table __kernel_dtqinib_table
+#define _tmax_pdqid __kernel_tmax_pdqid
+#define _pdqcb_table __kernel_pdqcb_table
+#define _pdqinib_table __kernel_pdqinib_table
+#define _tmax_mbxid __kernel_tmax_mbxid
+#define _mbxcb_table __kernel_mbxcb_table
+#define _mbxinib_table __kernel_mbxinib_table
+#define _tmax_mtxid __kernel_tmax_mtxid
+#define _mtxcb_table __kernel_mtxcb_table
+#define _mtxinib_table __kernel_mtxinib_table
+#define _tmax_mpfid __kernel_tmax_mpfid
+#define _mpfinib_table __kernel_mpfinib_table
+#define _mpfcb_table __kernel_mpfcb_table
+#define _tmax_cycid __kernel_tmax_cycid
+#define _cycinib_table __kernel_cycinib_table
+#define _cyccb_table __kernel_cyccb_table
+#define _tmax_almid __kernel_tmax_almid
+#define _alminib_table __kernel_alminib_table
+#define _almcb_table __kernel_almcb_table
+#define _tnum_inhno __kernel_tnum_inhno
+#define _inhinib_table __kernel_inhinib_table
+#define _tnum_intno __kernel_tnum_intno
+#define _intinib_table __kernel_intinib_table
+#define _tnum_excno __kernel_tnum_excno
+#define _excinib_table __kernel_excinib_table
+#define _tmevt_heap __kernel_tmevt_heap
+#define _istksz __kernel_istksz
+#define _istk __kernel_istk
+#define _istkpt __kernel_istkpt
+
+
+#endif /* TOPPERS_LABEL_ASM */
+
+#include "target_rename.h"
+
+#endif /* TOPPERS_KERNEL_RENAME_H */
--- /dev/null
+/* This file is generated from kernel_rename.def by genrename. */
+
+/* This file is included only when kernel_rename.h has been included. */
+#ifdef TOPPERS_KERNEL_RENAME_H
+#undef TOPPERS_KERNEL_RENAME_H
+
+/*
+ * startup.c
+ */
+#undef kerflg
+#undef exit_kernel
+
+/*
+ * task.c
+ */
+#undef p_runtsk
+#undef p_schedtsk
+#undef reqflg
+#undef disdsp
+#undef dspflg
+#undef ready_queue
+#undef ready_primap
+#undef initialize_task
+#undef search_schedtsk
+#undef make_runnable
+#undef make_non_runnable
+#undef make_dormant
+#undef make_active
+#undef change_priority
+#undef rotate_ready_queue
+#undef call_texrtn
+#undef calltex
+
+/*
+ * wait.c
+ */
+#undef make_wait_tmout
+#undef wait_complete
+#undef wait_tmout
+#undef wait_tmout_ok
+#undef wait_release
+#undef wobj_make_wait
+#undef wobj_make_wait_tmout
+#undef init_wait_queue
+
+/*
+ * time_event.c
+ */
+#undef current_time
+#undef min_time
+#undef next_time
+#undef next_subtime
+#undef last_index
+#undef initialize_tmevt
+#undef tmevt_up
+#undef tmevt_down
+#undef tmevtb_insert
+#undef tmevtb_delete
+#undef tmevt_lefttim
+#undef signal_time
+
+/*
+ * semaphore.c
+ */
+#undef initialize_semaphore
+
+/*
+ * eventflag.c
+ */
+#undef initialize_eventflag
+#undef check_flg_cond
+
+/*
+ * dataqueue.c
+ */
+#undef initialize_dataqueue
+#undef enqueue_data
+#undef force_enqueue_data
+#undef dequeue_data
+#undef send_data
+#undef force_send_data
+#undef receive_data
+
+/*
+ * pridataq.c
+ */
+#undef initialize_pridataq
+#undef enqueue_pridata
+#undef dequeue_pridata
+#undef send_pridata
+#undef receive_pridata
+
+/*
+ * mailbox.c
+ */
+#undef initialize_mailbox
+
+/*
+ * mempfix.c
+ */
+#undef initialize_mempfix
+#undef get_mpf_block
+
+/*
+ * mutex.c
+ */
+#undef mtxhook_check_ceilpri
+#undef mtxhook_scan_ceilmtx
+#undef mtxhook_release_all
+#undef initialize_mutex
+#undef mutex_check_ceilpri
+#undef mutex_scan_ceilmtx
+#undef mutex_calc_priority
+#undef mutex_release
+#undef mutex_release_all
+
+/*
+ * cyclic.c
+ */
+#undef initialize_cyclic
+#undef call_cychdr
+
+/*
+ * alarm.c
+ */
+#undef initialize_alarm
+#undef call_almhdr
+
+/*
+ * interrupt.c
+ */
+#undef initialize_interrupt
+
+/*
+ * exception.c
+ */
+#undef initialize_exception
+
+/*
+ * kernel_cfg.c
+ */
+#undef initialize_object
+#undef call_inirtn
+#undef call_terrtn
+#undef tmax_tskid
+#undef tinib_table
+#undef torder_table
+#undef tcb_table
+#undef tmax_semid
+#undef seminib_table
+#undef semcb_table
+#undef tmax_flgid
+#undef flginib_table
+#undef flgcb_table
+#undef tmax_dtqid
+#undef dtqcb_table
+#undef dtqinib_table
+#undef tmax_pdqid
+#undef pdqcb_table
+#undef pdqinib_table
+#undef tmax_mbxid
+#undef mbxcb_table
+#undef mbxinib_table
+#undef tmax_mtxid
+#undef mtxcb_table
+#undef mtxinib_table
+#undef tmax_mpfid
+#undef mpfinib_table
+#undef mpfcb_table
+#undef tmax_cycid
+#undef cycinib_table
+#undef cyccb_table
+#undef tmax_almid
+#undef alminib_table
+#undef almcb_table
+#undef tnum_inhno
+#undef inhinib_table
+#undef tnum_intno
+#undef intinib_table
+#undef tnum_excno
+#undef excinib_table
+#undef tmevt_heap
+#undef istksz
+#undef istk
+#undef istkpt
+
+
+#ifdef TOPPERS_LABEL_ASM
+
+/*
+ * startup.c
+ */
+#undef _kerflg
+#undef _exit_kernel
+
+/*
+ * task.c
+ */
+#undef _p_runtsk
+#undef _p_schedtsk
+#undef _reqflg
+#undef _disdsp
+#undef _dspflg
+#undef _ready_queue
+#undef _ready_primap
+#undef _initialize_task
+#undef _search_schedtsk
+#undef _make_runnable
+#undef _make_non_runnable
+#undef _make_dormant
+#undef _make_active
+#undef _change_priority
+#undef _rotate_ready_queue
+#undef _call_texrtn
+#undef _calltex
+
+/*
+ * wait.c
+ */
+#undef _make_wait_tmout
+#undef _wait_complete
+#undef _wait_tmout
+#undef _wait_tmout_ok
+#undef _wait_release
+#undef _wobj_make_wait
+#undef _wobj_make_wait_tmout
+#undef _init_wait_queue
+
+/*
+ * time_event.c
+ */
+#undef _current_time
+#undef _min_time
+#undef _next_time
+#undef _next_subtime
+#undef _last_index
+#undef _initialize_tmevt
+#undef _tmevt_up
+#undef _tmevt_down
+#undef _tmevtb_insert
+#undef _tmevtb_delete
+#undef _tmevt_lefttim
+#undef _signal_time
+
+/*
+ * semaphore.c
+ */
+#undef _initialize_semaphore
+
+/*
+ * eventflag.c
+ */
+#undef _initialize_eventflag
+#undef _check_flg_cond
+
+/*
+ * dataqueue.c
+ */
+#undef _initialize_dataqueue
+#undef _enqueue_data
+#undef _force_enqueue_data
+#undef _dequeue_data
+#undef _send_data
+#undef _force_send_data
+#undef _receive_data
+
+/*
+ * pridataq.c
+ */
+#undef _initialize_pridataq
+#undef _enqueue_pridata
+#undef _dequeue_pridata
+#undef _send_pridata
+#undef _receive_pridata
+
+/*
+ * mailbox.c
+ */
+#undef _initialize_mailbox
+
+/*
+ * mempfix.c
+ */
+#undef _initialize_mempfix
+#undef _get_mpf_block
+
+/*
+ * mutex.c
+ */
+#undef _mtxhook_check_ceilpri
+#undef _mtxhook_scan_ceilmtx
+#undef _mtxhook_release_all
+#undef _initialize_mutex
+#undef _mutex_check_ceilpri
+#undef _mutex_scan_ceilmtx
+#undef _mutex_calc_priority
+#undef _mutex_release
+#undef _mutex_release_all
+
+/*
+ * cyclic.c
+ */
+#undef _initialize_cyclic
+#undef _call_cychdr
+
+/*
+ * alarm.c
+ */
+#undef _initialize_alarm
+#undef _call_almhdr
+
+/*
+ * interrupt.c
+ */
+#undef _initialize_interrupt
+
+/*
+ * exception.c
+ */
+#undef _initialize_exception
+
+/*
+ * kernel_cfg.c
+ */
+#undef _initialize_object
+#undef _call_inirtn
+#undef _call_terrtn
+#undef _tmax_tskid
+#undef _tinib_table
+#undef _torder_table
+#undef _tcb_table
+#undef _tmax_semid
+#undef _seminib_table
+#undef _semcb_table
+#undef _tmax_flgid
+#undef _flginib_table
+#undef _flgcb_table
+#undef _tmax_dtqid
+#undef _dtqcb_table
+#undef _dtqinib_table
+#undef _tmax_pdqid
+#undef _pdqcb_table
+#undef _pdqinib_table
+#undef _tmax_mbxid
+#undef _mbxcb_table
+#undef _mbxinib_table
+#undef _tmax_mtxid
+#undef _mtxcb_table
+#undef _mtxinib_table
+#undef _tmax_mpfid
+#undef _mpfinib_table
+#undef _mpfcb_table
+#undef _tmax_cycid
+#undef _cycinib_table
+#undef _cyccb_table
+#undef _tmax_almid
+#undef _alminib_table
+#undef _almcb_table
+#undef _tnum_inhno
+#undef _inhinib_table
+#undef _tnum_intno
+#undef _intinib_table
+#undef _tnum_excno
+#undef _excinib_table
+#undef _tmevt_heap
+#undef _istksz
+#undef _istk
+#undef _istkpt
+
+
+#endif /* TOPPERS_LABEL_ASM */
+
+#include "target_unrename.h"
+
+#endif /* TOPPERS_KERNEL_RENAME_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2005-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: mutex.c 1694 2010-01-01 15:59:09Z ertl-hiro $
+ */
+
+/*
+ * ミューテックス機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "mutex.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_LOC_MTX_ENTER
+#define LOG_LOC_MTX_ENTER(mtxid)
+#endif /* LOG_LOC_MTX_ENTER */
+
+#ifndef LOG_LOC_MTX_LEAVE
+#define LOG_LOC_MTX_LEAVE(ercd)
+#endif /* LOG_LOC_MTX_LEAVE */
+
+#ifndef LOG_PLOC_MTX_ENTER
+#define LOG_PLOC_MTX_ENTER(mtxid)
+#endif /* LOG_PLOC_MTX_ENTER */
+
+#ifndef LOG_PLOC_MTX_LEAVE
+#define LOG_PLOC_MTX_LEAVE(ercd)
+#endif /* LOG_PLOC_MTX_LEAVE */
+
+#ifndef LOG_TLOC_MTX_ENTER
+#define LOG_TLOC_MTX_ENTER(mtxid, tmout)
+#endif /* LOG_TLOC_MTX_ENTER */
+
+#ifndef LOG_TLOC_MTX_LEAVE
+#define LOG_TLOC_MTX_LEAVE(ercd)
+#endif /* LOG_TLOC_MTX_LEAVE */
+
+#ifndef LOG_UNL_MTX_ENTER
+#define LOG_UNL_MTX_ENTER(mtxid)
+#endif /* LOG_UNL_MTX_ENTER */
+
+#ifndef LOG_UNL_MTX_LEAVE
+#define LOG_UNL_MTX_LEAVE(ercd)
+#endif /* LOG_UNL_MTX_LEAVE */
+
+#ifndef LOG_INI_MTX_ENTER
+#define LOG_INI_MTX_ENTER(mtxid)
+#endif /* LOG_INI_MTX_ENTER */
+
+#ifndef LOG_INI_MTX_LEAVE
+#define LOG_INI_MTX_LEAVE(ercd)
+#endif /* LOG_INI_MTX_LEAVE */
+
+#ifndef LOG_REF_MTX_ENTER
+#define LOG_REF_MTX_ENTER(mtxid, pk_rmtx)
+#endif /* LOG_REF_MTX_ENTER */
+
+#ifndef LOG_REF_MTX_LEAVE
+#define LOG_REF_MTX_LEAVE(ercd, pk_rmtx)
+#endif /* LOG_REF_MTX_LEAVE */
+
+/*
+ * ミューテックスの数
+ */
+#define tnum_mtx ((uint_t)(tmax_mtxid - TMIN_MTXID + 1))
+
+/*
+ * ミューテックスIDからミューテックス管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_MTX(mtxid) ((uint_t)((mtxid) - TMIN_MTXID))
+#define get_mtxcb(mtxid) (&(mtxcb_table[INDEX_MTX(mtxid)]))
+
+/*
+ * ミューテックス管理ブロック中のmutex_queueへのポインタから,ミューテッ
+ * クス管理ブロックへのポインタを取り出すためのマクロ
+ */
+#define MTXCB_QUEUE(p_queue) \
+ ((MTXCB *)(((char *) p_queue) - offsetof(MTXCB, mutex_queue)))
+
+/*
+ * ミューテックスのプロトコルを判断するマクロ
+ */
+#define MTXPROTO_MASK 0x03U
+#define MTXPROTO(p_mtxcb) ((p_mtxcb)->p_mtxinib->mtxatr & MTXPROTO_MASK)
+#define MTX_CEILING(p_mtxcb) (MTXPROTO(p_mtxcb) == TA_CEILING)
+
+/*
+ * フックルーチン呼出し用の変数
+ */
+#ifdef TOPPERS_mtxhook
+
+bool_t (*mtxhook_check_ceilpri)(TCB *p_tcb, uint_t bpriority) = NULL;
+bool_t (*mtxhook_scan_ceilmtx)(TCB *p_tcb) = NULL;
+bool_t (*mtxhook_release_all)(TCB *p_tcb) = NULL;
+
+#endif /* TOPPERS_mtxhook */
+
+/*
+ * ミューテックス機能の初期化
+ */
+#ifdef TOPPERS_mtxini
+
+void
+initialize_mutex(void)
+{
+ uint_t i;
+ MTXCB *p_mtxcb;
+
+ mtxhook_check_ceilpri = mutex_check_ceilpri;
+ mtxhook_scan_ceilmtx = mutex_scan_ceilmtx;
+ mtxhook_release_all = mutex_release_all;
+
+ for (p_mtxcb = mtxcb_table, i = 0; i < tnum_mtx; p_mtxcb++, i++) {
+ queue_initialize(&(p_mtxcb->wait_queue));
+ p_mtxcb->p_mtxinib = &(mtxinib_table[i]);
+ p_mtxcb->p_loctsk = NULL;
+ }
+}
+
+#endif /* TOPPERS_mtxini */
+
+/*
+ * 上限優先度違反のチェック
+ */
+#ifdef TOPPERS_mtxchk
+
+bool_t
+mutex_check_ceilpri(TCB *p_tcb, uint_t bpriority)
+{
+ QUEUE *p_queue;
+ MTXCB *p_mtxcb;
+
+ /*
+ * タスクがロックしている優先度上限ミューテックスの中で,上限優先
+ * 度がbpriorityよりも低いものがあれば,falseを返す.
+ */
+ p_queue = p_tcb->mutex_queue.p_next;
+ while (p_queue != &(p_tcb->mutex_queue)) {
+ p_mtxcb = MTXCB_QUEUE(p_queue);
+ if (MTX_CEILING(p_mtxcb) && bpriority < p_mtxcb->p_mtxinib->ceilpri) {
+ return(false);
+ }
+ p_queue = p_queue->p_next;
+ }
+
+ /*
+ * タスクが優先度上限ミューテックスのロックを待っている場合に,そ
+ * の上限優先度がbpriorityよりも低くければ,falseを返す.
+ */
+ if (TSTAT_WAIT_MTX(p_tcb->tstat)) {
+ p_mtxcb = ((WINFO_MTX *)(p_tcb->p_winfo))->p_mtxcb;
+ if (MTX_CEILING(p_mtxcb) && bpriority < p_mtxcb->p_mtxinib->ceilpri) {
+ return(false);
+ }
+ }
+
+ /*
+ * いずれの条件にも当てはまらなければtrueを返す.
+ */
+ return(true);
+}
+
+#endif /* TOPPERS_mtxchk */
+
+/*
+ * 優先度上限ミューテックスをロックしているかのチェック
+ */
+#ifdef TOPPERS_mtxscan
+
+bool_t
+mutex_scan_ceilmtx(TCB *p_tcb)
+{
+ QUEUE *p_queue;
+ MTXCB *p_mtxcb;
+
+ p_queue = p_tcb->mutex_queue.p_next;
+ while (p_queue != &(p_tcb->mutex_queue)) {
+ p_mtxcb = MTXCB_QUEUE(p_queue);
+ if (MTX_CEILING(p_mtxcb)) {
+ return(true);
+ }
+ p_queue = p_queue->p_next;
+ }
+ return(false);
+}
+
+#endif /* TOPPERS_mtxscan */
+
+/*
+ * タスクの現在優先度の計算
+ */
+#ifdef TOPPERS_mtxcalc
+
+uint_t
+mutex_calc_priority(TCB *p_tcb)
+{
+ uint_t priority;
+ QUEUE *p_queue;
+ MTXCB *p_mtxcb;
+
+ priority = p_tcb->bpriority;
+ p_queue = p_tcb->mutex_queue.p_next;
+ while (p_queue != &(p_tcb->mutex_queue)) {
+ p_mtxcb = MTXCB_QUEUE(p_queue);
+ if (MTX_CEILING(p_mtxcb) && p_mtxcb->p_mtxinib->ceilpri < priority) {
+ priority = p_mtxcb->p_mtxinib->ceilpri;
+ }
+ p_queue = p_queue->p_next;
+ }
+ return(priority);
+}
+
+#endif /* TOPPERS_mtxcalc */
+
+/*
+ * 要素優先度が上がる(または増える)場合の現在優先度変更処理
+ */
+Inline bool_t
+mutex_raise_priority(TCB *p_tcb, uint_t newpri)
+{
+ if (newpri < p_tcb->priority) {
+ return(change_priority(p_tcb, newpri, true));
+ }
+ return(false);
+}
+
+/*
+ * 要素優先度が下がる(または減る)場合の現在優先度変更処理
+ */
+Inline bool_t
+mutex_drop_priority(TCB *p_tcb, uint_t oldpri)
+{
+ uint_t newpri;
+
+ if (oldpri == p_tcb->priority) {
+ newpri = mutex_calc_priority(p_tcb);
+ if (newpri != p_tcb->priority) {
+ return(change_priority(p_tcb, newpri, true));
+ }
+ }
+ return(false);
+}
+
+/*
+ * ミューテックスをロックした場合の処理
+ */
+Inline bool_t
+mutex_acquire(TCB *p_loctsk, MTXCB *p_mtxcb)
+{
+ p_mtxcb->p_loctsk = p_loctsk;
+ queue_insert_prev(&(p_loctsk->mutex_queue), &(p_mtxcb->mutex_queue));
+ if (MTX_CEILING(p_mtxcb)) {
+ return(mutex_raise_priority(p_loctsk, p_mtxcb->p_mtxinib->ceilpri));
+ }
+ return(false);
+}
+
+/*
+ * ミューテックスのロック解除
+ */
+#ifdef TOPPERS_mtxrel
+
+bool_t
+mutex_release(MTXCB *p_mtxcb)
+{
+ TCB *p_tcb;
+
+ if (queue_empty(&(p_mtxcb->wait_queue))) {
+ p_mtxcb->p_loctsk = NULL;
+ return(false);
+ }
+ else {
+ /*
+ * ミューテックス待ちキューの先頭タスク(p_tcb)に,ミューテッ
+ * クスをロックさせる.
+ */
+ p_tcb = (TCB *) queue_delete_next(&(p_mtxcb->wait_queue));
+ wait_dequeue_tmevtb(p_tcb);
+ p_tcb->p_winfo->wercd = E_OK;
+
+ p_mtxcb->p_loctsk = p_tcb;
+ queue_insert_prev(&(p_tcb->mutex_queue), &(p_mtxcb->mutex_queue));
+ if (MTX_CEILING(p_mtxcb)) {
+ if (p_mtxcb->p_mtxinib->ceilpri < p_tcb->priority) {
+ p_tcb->priority = p_mtxcb->p_mtxinib->ceilpri;
+ }
+ }
+ return(make_non_wait(p_tcb));
+ }
+}
+
+#endif /* TOPPERS_mtxrel */
+
+/*
+ * タスクがロックしているすべてのミューテックスのロック解除
+ */
+#ifdef TOPPERS_mtxrela
+
+bool_t
+mutex_release_all(TCB *p_tcb)
+{
+ MTXCB *p_mtxcb;
+ bool_t dspreq = false;
+
+ while (!queue_empty(&(p_tcb->mutex_queue))) {
+ p_mtxcb = MTXCB_QUEUE(p_tcb->mutex_queue.p_next);
+ queue_delete(&(p_mtxcb->mutex_queue));
+ if (mutex_release(p_mtxcb)) {
+ dspreq = true;
+ }
+ }
+ return(dspreq);
+}
+
+#endif /* TOPPERS_mtxrela */
+
+/*
+ * ミューテックスのロック
+ */
+#ifdef TOPPERS_loc_mtx
+
+ER
+loc_mtx(ID mtxid)
+{
+ MTXCB *p_mtxcb;
+ WINFO_MTX winfo_mtx;
+ ER ercd;
+
+ LOG_LOC_MTX_ENTER(mtxid);
+ CHECK_DISPATCH();
+ CHECK_MTXID(mtxid);
+ p_mtxcb = get_mtxcb(mtxid);
+
+ t_lock_cpu();
+ if (MTX_CEILING(p_mtxcb)
+ && p_runtsk->bpriority < p_mtxcb->p_mtxinib->ceilpri) {
+ ercd = E_ILUSE;
+ }
+ else if (p_mtxcb->p_loctsk == NULL) {
+ (void) mutex_acquire(p_runtsk, p_mtxcb);
+ /*
+ * 優先度上限ミューテックスをロックした場合,p_runtskの優先度
+ * が上がる可能性があるが,ディスパッチが必要になることはない.
+ */
+ assert(!(p_runtsk != p_schedtsk && dspflg));
+ ercd = E_OK;
+ }
+ else if (p_mtxcb->p_loctsk == p_runtsk) {
+ ercd = E_ILUSE;
+ }
+ else {
+ p_runtsk->tstat = (TS_WAITING | TS_WAIT_MTX);
+ wobj_make_wait((WOBJCB *) p_mtxcb, (WINFO_WOBJ *) &winfo_mtx);
+ dispatch();
+ ercd = winfo_mtx.winfo.wercd;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_LOC_MTX_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_loc_mtx */
+
+/*
+ * ミューテックスのロック(ポーリング)
+ */
+#ifdef TOPPERS_ploc_mtx
+
+ER
+ploc_mtx(ID mtxid)
+{
+ MTXCB *p_mtxcb;
+ ER ercd;
+
+ LOG_PLOC_MTX_ENTER(mtxid);
+ CHECK_TSKCTX_UNL();
+ CHECK_MTXID(mtxid);
+ p_mtxcb = get_mtxcb(mtxid);
+
+ t_lock_cpu();
+ if (MTX_CEILING(p_mtxcb)
+ && p_runtsk->bpriority < p_mtxcb->p_mtxinib->ceilpri) {
+ ercd = E_ILUSE;
+ }
+ else if (p_mtxcb->p_loctsk == NULL) {
+ (void) mutex_acquire(p_runtsk, p_mtxcb);
+ /*
+ * 優先度上限ミューテックスをロックした場合,p_runtskの優先度
+ * が上がる可能性があるが,ディスパッチが必要になることはない.
+ */
+ assert(!(p_runtsk != p_schedtsk && dspflg));
+ ercd = E_OK;
+ }
+ else if (p_mtxcb->p_loctsk == p_runtsk) {
+ ercd = E_ILUSE;
+ }
+ else {
+ ercd = E_TMOUT;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_PLOC_MTX_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ploc_mtx */
+
+/*
+ * ミューテックスのロック(タイムアウトあり)
+ */
+#ifdef TOPPERS_tloc_mtx
+
+ER
+tloc_mtx(ID mtxid, TMO tmout)
+{
+ MTXCB *p_mtxcb;
+ WINFO_MTX winfo_mtx;
+ TMEVTB tmevtb;
+ ER ercd;
+
+ LOG_TLOC_MTX_ENTER(mtxid, tmout);
+ CHECK_DISPATCH();
+ CHECK_MTXID(mtxid);
+ CHECK_TMOUT(tmout);
+ p_mtxcb = get_mtxcb(mtxid);
+
+ t_lock_cpu();
+ if (MTX_CEILING(p_mtxcb)
+ && p_runtsk->bpriority < p_mtxcb->p_mtxinib->ceilpri) {
+ ercd = E_ILUSE;
+ }
+ else if (p_mtxcb->p_loctsk == NULL) {
+ (void) mutex_acquire(p_runtsk, p_mtxcb);
+ /*
+ * 優先度上限ミューテックスをロックした場合,p_runtskの優先度
+ * が上がる可能性があるが,ディスパッチが必要になることはない.
+ */
+ assert(!(p_runtsk != p_schedtsk && dspflg));
+ ercd = E_OK;
+ }
+ else if (p_mtxcb->p_loctsk == p_runtsk) {
+ ercd = E_ILUSE;
+ }
+ else if (tmout == TMO_POL) {
+ ercd = E_TMOUT;
+ }
+ else {
+ p_runtsk->tstat = (TS_WAITING | TS_WAIT_MTX);
+ wobj_make_wait_tmout((WOBJCB *) p_mtxcb, (WINFO_WOBJ *) &winfo_mtx,
+ &tmevtb, tmout);
+ dispatch();
+ ercd = winfo_mtx.winfo.wercd;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_TLOC_MTX_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_tloc_mtx */
+
+/*
+ * ミューテックスのロック解除
+ */
+#ifdef TOPPERS_unl_mtx
+
+ER
+unl_mtx(ID mtxid)
+{
+ MTXCB *p_mtxcb;
+ bool_t dspreq = false;
+ ER ercd;
+
+ LOG_UNL_MTX_ENTER(mtxid);
+ CHECK_TSKCTX_UNL();
+ CHECK_MTXID(mtxid);
+ p_mtxcb = get_mtxcb(mtxid);
+
+ t_lock_cpu();
+ if (p_mtxcb->p_loctsk != p_runtsk) {
+ ercd = E_ILUSE;
+ }
+ else {
+ queue_delete(&(p_mtxcb->mutex_queue));
+ if (MTX_CEILING(p_mtxcb)) {
+ if (mutex_drop_priority(p_runtsk, p_mtxcb->p_mtxinib->ceilpri)) {
+ dspreq = true;
+ }
+ }
+ if (mutex_release(p_mtxcb)) {
+ dspreq = true;
+ }
+ if (dspreq) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_UNL_MTX_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_unl_mtx */
+
+/*
+ * ミューテックスの初期化
+ */
+#ifdef TOPPERS_ini_mtx
+
+ER
+ini_mtx(ID mtxid)
+{
+ MTXCB *p_mtxcb;
+ TCB *p_loctsk;
+ bool_t dspreq;
+ ER ercd;
+
+ LOG_INI_MTX_ENTER(mtxid);
+ CHECK_TSKCTX_UNL();
+ CHECK_MTXID(mtxid);
+ p_mtxcb = get_mtxcb(mtxid);
+
+ t_lock_cpu();
+ dspreq = init_wait_queue(&(p_mtxcb->wait_queue));
+ p_loctsk = p_mtxcb->p_loctsk;
+ if (p_loctsk != NULL) {
+ queue_delete(&(p_mtxcb->mutex_queue));
+ p_mtxcb->p_loctsk = NULL;
+ if (MTX_CEILING(p_mtxcb)) {
+ if (mutex_drop_priority(p_loctsk, p_mtxcb->p_mtxinib->ceilpri)) {
+ dspreq = true;
+ }
+ }
+ }
+ if (dspreq) {
+ dispatch();
+ }
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_INI_MTX_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ini_mtx */
+
+/*
+ * ミューテックスの状態参照
+ */
+#ifdef TOPPERS_ref_mtx
+
+ER
+ref_mtx(ID mtxid, T_RMTX *pk_rmtx)
+{
+ MTXCB *p_mtxcb;
+ ER ercd;
+
+ LOG_REF_MTX_ENTER(mtxid, pk_rmtx);
+ CHECK_TSKCTX_UNL();
+ CHECK_MTXID(mtxid);
+ p_mtxcb = get_mtxcb(mtxid);
+
+ t_lock_cpu();
+ pk_rmtx->htskid = (p_mtxcb->p_loctsk != NULL) ? TSKID(p_mtxcb->p_loctsk)
+ : TSK_NONE;
+ pk_rmtx->wtskid = wait_tskid(&(p_mtxcb->wait_queue));
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_REF_MTX_LEAVE(ercd, pk_rmtx);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ref_mtx */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2005-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: mutex.h 1694 2010-01-01 15:59:09Z ertl-hiro $
+ */
+
+/*
+ * ミューテックス機能
+ */
+
+#ifndef TOPPERS_MUTEX_H
+#define TOPPERS_MUTEX_H
+
+#include <queue.h>
+
+/*
+ * ミューテックス初期化ブロック
+ *
+ * この構造体は,同期・通信オブジェクトの初期化ブロックの共通部分
+ * (WOBJINIB)を拡張(オブジェクト指向言語の継承に相当)したもので,
+ * 最初のフィールドが共通になっている.
+ */
+typedef struct mutex_initialization_block {
+ ATR mtxatr; /* ミューテックス属性 */
+ uint_t ceilpri; /* ミューテックスの上限優先度(内部表現)*/
+} MTXINIB;
+
+/*
+ * ミューテックス管理ブロック
+ *
+ * この構造体は,同期・通信オブジェクトの管理ブロックの共通部分(WOBJCB)
+ * を拡張(オブジェクト指向言語の継承に相当)したもので,最初の2つの
+ * フィールドが共通になっている.
+ */
+typedef struct mutex_control_block {
+ QUEUE wait_queue; /* ミューテックス待ちキュー */
+ const MTXINIB *p_mtxinib; /* 初期化ブロックへのポインタ */
+ TCB *p_loctsk; /* ミューテックスをロックしているタスク */
+ QUEUE mutex_queue; /* ロックしているミューテックスのキュー */
+} MTXCB;
+
+/*
+ * ミューテックス待ち情報ブロックの定義
+ *
+ * この構造体は,同期・通信オブジェクトの待ち情報ブロックの共通部分
+ * (WINFO_WOBJ)を拡張(オブジェクト指向言語の継承に相当)したもので,
+ * すべてのフィールドが共通になっている.
+ */
+typedef struct mutex_waiting_information {
+ WINFO winfo; /* 標準の待ち情報ブロック */
+ MTXCB *p_mtxcb; /* 待っているミューテックスの管理ブロック */
+} WINFO_MTX;
+
+/*
+ * ミューテックスIDの最大値(kernel_cfg.c)
+ */
+extern const ID tmax_mtxid;
+
+/*
+ * ミューテックス初期化ブロックのエリア(kernel_cfg.c)
+ */
+extern const MTXINIB mtxinib_table[];
+
+/*
+ * ミューテックス管理ブロックのエリア(kernel_cfg.c)
+ */
+extern MTXCB mtxcb_table[];
+
+/*
+ * ミューテックス管理ブロックからミューテックスIDを取り出すためのマクロ
+ */
+#define MTXID(p_mtxcb) ((ID)(((p_mtxcb) - mtxcb_table) + TMIN_MTXID))
+
+/*
+ * ミューテックス機能の初期化
+ */
+extern void initialize_mutex(void);
+
+/*
+ * 上限優先度違反のチェック
+ *
+ * chg_priの中で上限優先度違反のチェックを行うために用いる関数であり,
+ * p_tcbで指定されるタスクがロックしている優先度上限ミューテックスと,
+ * ロックを待っている優先度上限ミューテックスの中で,上限優先度が
+ * bpriorityよりも低いものがあればfalseを,そうでなければtrueを返す.
+ */
+extern bool_t (*mtxhook_check_ceilpri)(TCB *p_tcb, uint_t bpriority);
+extern bool_t mutex_check_ceilpri(TCB *p_tcb, uint_t bpriority);
+
+/*
+ * 優先度上限ミューテックスをロックしているかのチェック
+ *
+ * p_tcbで指定されるタスクが優先度上限ミューテックスをロックしていれば
+ * true,そうでなければfalseを返す.
+ */
+extern bool_t (*mtxhook_scan_ceilmtx)(TCB *p_tcb);
+extern bool_t mutex_scan_ceilmtx(TCB *p_tcb);
+
+/*
+ * タスクの現在優先度の計算
+ *
+ * p_tcbで指定されるタスクの現在優先度(に設定すべき値)を計算する.
+ */
+extern uint_t mutex_calc_priority(TCB *p_tcb);
+
+/*
+ * ミューテックスのロック解除
+ *
+ * p_mtxcbで指定されるミューテックスをロック解除する.ロック解除した
+ * ミューテックスに,ロック待ち状態のタスクがある場合には,そのタスク
+ * にミューテックスをロックさせる.
+ */
+extern bool_t mutex_release(MTXCB *p_mtxcb);
+
+/*
+ * タスクがロックしているすべてのミューテックスのロック解除
+ *
+ * p_tcbで指定されるタスクに,それがロックしているすべてのミューテック
+ * スをロック解除させる.ロック解除したミューテックスに,ロック待ち状
+ * 態のタスクがある場合には,そのタスクにミューテックスをロックさせる.
+ *
+ * この関数は,タスクの終了時に使われるものであるため,p_tcbで指定され
+ * るタスクの優先度を変更する処理は行わない.この関数の中でタスクの優
+ * 先度が変化し,実行すべきタスクが変わることがある.そのため,この関
+ * 数から戻った後に,ディスパッチが必要か判別して,必要な場合にはディ
+ * スパッチを行わなければならない.
+ */
+extern bool_t (*mtxhook_release_all)(TCB *p_tcb);
+extern bool_t mutex_release_all(TCB *p_tcb);
+
+#endif /* TOPPERS_MUTEX_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: sys_manage.c 762 2008-03-07 23:51:41Z hiro $
+ */
+
+/*
+ * システム状態管理機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_ROT_RDQ_ENTER
+#define LOG_ROT_RDQ_ENTER(tskpri)
+#endif /* LOG_ROT_RDQ_ENTER */
+
+#ifndef LOG_ROT_RDQ_LEAVE
+#define LOG_ROT_RDQ_LEAVE(ercd)
+#endif /* LOG_ROT_RDQ_LEAVE */
+
+#ifndef LOG_IROT_RDQ_ENTER
+#define LOG_IROT_RDQ_ENTER(tskpri)
+#endif /* LOG_IROT_RDQ_ENTER */
+
+#ifndef LOG_IROT_RDQ_LEAVE
+#define LOG_IROT_RDQ_LEAVE(ercd)
+#endif /* LOG_IROT_RDQ_LEAVE */
+
+#ifndef LOG_GET_TID_ENTER
+#define LOG_GET_TID_ENTER(p_tskid)
+#endif /* LOG_GET_TID_ENTER */
+
+#ifndef LOG_GET_TID_LEAVE
+#define LOG_GET_TID_LEAVE(ercd, tskid)
+#endif /* LOG_GET_TID_LEAVE */
+
+#ifndef LOG_IGET_TID_ENTER
+#define LOG_IGET_TID_ENTER(p_tskid)
+#endif /* LOG_IGET_TID_ENTER */
+
+#ifndef LOG_IGET_TID_LEAVE
+#define LOG_IGET_TID_LEAVE(ercd, tskid)
+#endif /* LOG_IGET_TID_LEAVE */
+
+#ifndef LOG_LOC_CPU_ENTER
+#define LOG_LOC_CPU_ENTER()
+#endif /* LOG_LOC_CPU_ENTER */
+
+#ifndef LOG_LOC_CPU_LEAVE
+#define LOG_LOC_CPU_LEAVE(ercd)
+#endif /* LOG_LOC_CPU_LEAVE */
+
+#ifndef LOG_ILOC_CPU_ENTER
+#define LOG_ILOC_CPU_ENTER()
+#endif /* LOG_ILOC_CPU_ENTER */
+
+#ifndef LOG_ILOC_CPU_LEAVE
+#define LOG_ILOC_CPU_LEAVE(ercd)
+#endif /* LOG_ILOC_CPU_LEAVE */
+
+#ifndef LOG_UNL_CPU_ENTER
+#define LOG_UNL_CPU_ENTER()
+#endif /* LOG_UNL_CPU_ENTER */
+
+#ifndef LOG_UNL_CPU_LEAVE
+#define LOG_UNL_CPU_LEAVE(ercd)
+#endif /* LOG_UNL_CPU_LEAVE */
+
+#ifndef LOG_IUNL_CPU_ENTER
+#define LOG_IUNL_CPU_ENTER()
+#endif /* LOG_IUNL_CPU_ENTER */
+
+#ifndef LOG_IUNL_CPU_LEAVE
+#define LOG_IUNL_CPU_LEAVE(ercd)
+#endif /* LOG_IUNL_CPU_LEAVE */
+
+#ifndef LOG_DIS_DSP_ENTER
+#define LOG_DIS_DSP_ENTER()
+#endif /* LOG_DIS_DSP_ENTER */
+
+#ifndef LOG_DIS_DSP_LEAVE
+#define LOG_DIS_DSP_LEAVE(ercd)
+#endif /* LOG_DIS_DSP_LEAVE */
+
+#ifndef LOG_ENA_DSP_ENTER
+#define LOG_ENA_DSP_ENTER()
+#endif /* LOG_ENA_DSP_ENTER */
+
+#ifndef LOG_ENA_DSP_LEAVE
+#define LOG_ENA_DSP_LEAVE(ercd)
+#endif /* LOG_ENA_DSP_LEAVE */
+
+#ifndef LOG_SNS_CTX_ENTER
+#define LOG_SNS_CTX_ENTER()
+#endif /* LOG_SNS_CTX_ENTER */
+
+#ifndef LOG_SNS_CTX_LEAVE
+#define LOG_SNS_CTX_LEAVE(state)
+#endif /* LOG_SNS_CTX_LEAVE */
+
+#ifndef LOG_SNS_LOC_ENTER
+#define LOG_SNS_LOC_ENTER()
+#endif /* LOG_SNS_LOC_ENTER */
+
+#ifndef LOG_SNS_LOC_LEAVE
+#define LOG_SNS_LOC_LEAVE(state)
+#endif /* LOG_SNS_LOC_LEAVE */
+
+#ifndef LOG_SNS_DSP_ENTER
+#define LOG_SNS_DSP_ENTER()
+#endif /* LOG_SNS_DSP_ENTER */
+
+#ifndef LOG_SNS_DSP_LEAVE
+#define LOG_SNS_DSP_LEAVE(state)
+#endif /* LOG_SNS_DSP_LEAVE */
+
+#ifndef LOG_SNS_DPN_ENTER
+#define LOG_SNS_DPN_ENTER()
+#endif /* LOG_SNS_DPN_ENTER */
+
+#ifndef LOG_SNS_DPN_LEAVE
+#define LOG_SNS_DPN_LEAVE(state)
+#endif /* LOG_SNS_DPN_LEAVE */
+
+#ifndef LOG_SNS_KER_ENTER
+#define LOG_SNS_KER_ENTER()
+#endif /* LOG_SNS_KER_ENTER */
+
+#ifndef LOG_SNS_KER_LEAVE
+#define LOG_SNS_KER_LEAVE(state)
+#endif /* LOG_SNS_KER_LEAVE */
+
+/*
+ * タスクの優先順位の回転
+ */
+#ifdef TOPPERS_rot_rdq
+
+ER
+rot_rdq(PRI tskpri)
+{
+ uint_t pri;
+ ER ercd;
+
+ LOG_ROT_RDQ_ENTER(tskpri);
+ CHECK_TSKCTX_UNL();
+ CHECK_TPRI_SELF(tskpri);
+
+ t_lock_cpu();
+ pri = (tskpri == TPRI_SELF) ? p_runtsk->bpriority : INT_PRIORITY(tskpri);
+ if (rotate_ready_queue(pri)) {
+ dispatch();
+ }
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_ROT_RDQ_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_rot_rdq */
+
+/*
+ * タスクの優先順位の回転(非タスクコンテキスト用)
+ */
+#ifdef TOPPERS_irot_rdq
+
+ER
+irot_rdq(PRI tskpri)
+{
+ ER ercd;
+
+ LOG_IROT_RDQ_ENTER(tskpri);
+ CHECK_INTCTX_UNL();
+ CHECK_TPRI(tskpri);
+
+ i_lock_cpu();
+ if (rotate_ready_queue(INT_PRIORITY(tskpri))) {
+ reqflg = true;
+ }
+ ercd = E_OK;
+ i_unlock_cpu();
+
+ error_exit:
+ LOG_IROT_RDQ_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_irot_rdq */
+
+/*
+ * 実行状態のタスクIDの参照
+ */
+#ifdef TOPPERS_get_tid
+
+ER
+get_tid(ID *p_tskid)
+{
+ ER ercd;
+
+ LOG_GET_TID_ENTER(p_tskid);
+ CHECK_TSKCTX_UNL();
+
+ t_lock_cpu();
+ *p_tskid = TSKID(p_runtsk);
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_GET_TID_LEAVE(ercd, *p_tskid);
+ return(ercd);
+}
+
+#endif /* TOPPERS_get_tid */
+
+/*
+ * 実行状態のタスクIDの参照(非タスクコンテキスト用)
+ */
+#ifdef TOPPERS_iget_tid
+
+ER
+iget_tid(ID *p_tskid)
+{
+ ER ercd;
+
+ LOG_IGET_TID_ENTER(p_tskid);
+ CHECK_INTCTX_UNL();
+
+ i_lock_cpu();
+ *p_tskid = (p_runtsk == NULL) ? TSK_NONE : TSKID(p_runtsk);
+ ercd = E_OK;
+ i_unlock_cpu();
+
+ error_exit:
+ LOG_IGET_TID_LEAVE(ercd, *p_tskid);
+ return(ercd);
+}
+
+#endif /* TOPPERS_iget_tid */
+
+/*
+ * CPUロック状態への移行
+ */
+#ifdef TOPPERS_loc_cpu
+
+ER
+loc_cpu(void)
+{
+ ER ercd;
+
+ LOG_LOC_CPU_ENTER();
+ CHECK_TSKCTX();
+
+ if (!t_sense_lock()) {
+ t_lock_cpu();
+ }
+ ercd = E_OK;
+
+ error_exit:
+ LOG_LOC_CPU_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_loc_cpu */
+
+/*
+ * CPUロック状態への移行(非タスクコンテキスト用)
+ */
+#ifdef TOPPERS_iloc_cpu
+
+ER
+iloc_cpu(void)
+{
+ ER ercd;
+
+ LOG_ILOC_CPU_ENTER();
+ CHECK_INTCTX();
+
+ if (!i_sense_lock()) {
+ i_lock_cpu();
+ }
+ ercd = E_OK;
+
+ error_exit:
+ LOG_ILOC_CPU_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_iloc_cpu */
+
+/*
+ * CPUロック状態の解除
+ *
+ * CPUロック中は,ディスパッチが必要となるサービスコールを呼び出すこ
+ * とはできないため,CPUロック状態の解除時にディスパッチャを起動する
+ * 必要はない.
+ */
+#ifdef TOPPERS_unl_cpu
+
+ER
+unl_cpu(void)
+{
+ ER ercd;
+
+ LOG_UNL_CPU_ENTER();
+ CHECK_TSKCTX();
+
+ if (t_sense_lock()) {
+ t_unlock_cpu();
+ }
+ ercd = E_OK;
+
+ error_exit:
+ LOG_UNL_CPU_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_unl_cpu */
+
+/*
+ * CPUロック状態の解除(非タスクコンテキスト用)
+ *
+ * CPUロック中は,ディスパッチが必要となるサービスコールを呼び出すこ
+ * とはできないため,CPUロック状態の解除時にディスパッチャの起動を要
+ * 求する必要はない.
+ */
+#ifdef TOPPERS_iunl_cpu
+
+ER
+iunl_cpu(void)
+{
+ ER ercd;
+
+ LOG_IUNL_CPU_ENTER();
+ CHECK_INTCTX();
+
+ if (i_sense_lock()) {
+ i_unlock_cpu();
+ }
+ ercd = E_OK;
+
+ error_exit:
+ LOG_IUNL_CPU_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_iunl_cpu */
+
+/*
+ * ディスパッチの禁止
+ */
+#ifdef TOPPERS_dis_dsp
+
+ER
+dis_dsp(void)
+{
+ ER ercd;
+
+ LOG_DIS_DSP_ENTER();
+ CHECK_TSKCTX_UNL();
+
+ t_lock_cpu();
+ disdsp = true;
+ dspflg = false;
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_DIS_DSP_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_dis_dsp */
+
+/*
+ * ディスパッチの許可
+ */
+#ifdef TOPPERS_ena_dsp
+
+ER
+ena_dsp(void)
+{
+ ER ercd;
+
+ LOG_ENA_DSP_ENTER();
+ CHECK_TSKCTX_UNL();
+
+ t_lock_cpu();
+ disdsp = false;
+ if (t_get_ipm() == TIPM_ENAALL) {
+ dspflg = true;
+ if (p_runtsk != p_schedtsk) {
+ dispatch();
+ }
+ }
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_ENA_DSP_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ena_dsp */
+
+/*
+ * コンテキストの参照
+ */
+#ifdef TOPPERS_sns_ctx
+
+bool_t
+sns_ctx(void)
+{
+ bool_t state;
+
+ LOG_SNS_CTX_ENTER();
+ state = sense_context() ? true : false;
+ LOG_SNS_CTX_LEAVE(state);
+ return(state);
+}
+
+#endif /* TOPPERS_sns_ctx */
+
+/*
+ * CPUロック状態の参照
+ */
+#ifdef TOPPERS_sns_loc
+
+bool_t
+sns_loc(void)
+{
+ bool_t state;
+
+ LOG_SNS_LOC_ENTER();
+ state = x_sense_lock() ? true : false;
+ LOG_SNS_LOC_LEAVE(state);
+ return(state);
+}
+
+#endif /* TOPPERS_sns_loc */
+
+/*
+ * ディスパッチ禁止状態の参照
+ */
+#ifdef TOPPERS_sns_dsp
+
+bool_t
+sns_dsp(void)
+{
+ bool_t state;
+
+ LOG_SNS_DSP_ENTER();
+ state = disdsp;
+ LOG_SNS_DSP_LEAVE(state);
+ return(state);
+}
+
+#endif /* TOPPERS_sns_dsp */
+
+/*
+ * ディスパッチ保留状態の参照
+ */
+#ifdef TOPPERS_sns_dpn
+
+bool_t
+sns_dpn(void)
+{
+ bool_t state;
+
+ LOG_SNS_DPN_ENTER();
+ state = (sense_context() || t_sense_lock() || !dspflg) ? true : false;
+ LOG_SNS_DPN_LEAVE(state);
+ return(state);
+}
+
+#endif /* TOPPERS_sns_dpn */
+
+/*
+ * カーネル非動作状態の参照
+ */
+#ifdef TOPPERS_sns_ker
+
+bool_t
+sns_ker(void)
+{
+ bool_t state;
+
+ LOG_SNS_KER_ENTER();
+ state = kerflg ? false : true;
+ LOG_SNS_KER_LEAVE(state);
+ return(state);
+}
+
+#endif /* TOPPERS_sns_ker */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * $Id: task.c 1812 2010-06-27 13:07:15Z ertl-hiro $
+ */
+
+/*
+ * タスク管理モジュール
+ */
+
+#include "kernel_impl.h"
+#include "wait.h"
+#include "task.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_TEX_ENTER
+#define LOG_TEX_ENTER(p_tcb, texptn)
+#endif /* LOG_TEX_ENTER */
+
+#ifndef LOG_TEX_LEAVE
+#define LOG_TEX_LEAVE(p_tcb)
+#endif /* LOG_TEX_LEAVE */
+
+#ifdef TOPPERS_tskini
+
+/*
+ * 実行状態のタスク
+ */
+TCB *p_runtsk;
+
+/*
+ * 最高優先順位のタスク
+ */
+TCB *p_schedtsk;
+
+/*
+ * タスクディスパッチ/タスク例外処理ルーチン起動要求フラグ
+ */
+bool_t reqflg;
+
+/*
+ * ディスパッチ禁止状態
+ */
+bool_t disdsp;
+
+/*
+ * タスクディスパッチ可能状態
+ */
+bool_t dspflg;
+
+/*
+ * レディキュー
+ */
+QUEUE ready_queue[TNUM_TPRI];
+
+/*
+ * レディキューサーチのためのビットマップ
+ */
+uint16_t ready_primap;
+
+/*
+ * タスク管理モジュールの初期化
+ */
+void
+initialize_task(void)
+{
+ uint_t i, j;
+ TCB *p_tcb;
+
+ p_runtsk = p_schedtsk = NULL;
+ reqflg = false;
+ disdsp = false;
+ dspflg = true;
+
+ for (i = 0; i < TNUM_TPRI; i++) {
+ queue_initialize(&(ready_queue[i]));
+ }
+ ready_primap = 0U;
+
+ for (i = 0; i < tnum_tsk; i++) {
+ j = INDEX_TSK(torder_table[i]);
+ p_tcb = &(tcb_table[j]);
+ p_tcb->p_tinib = &(tinib_table[j]);
+ p_tcb->actque = false;
+ make_dormant(p_tcb);
+ queue_initialize(&(p_tcb->mutex_queue));
+ if ((p_tcb->p_tinib->tskatr & TA_ACT) != 0U) {
+ make_active(p_tcb);
+ }
+ }
+}
+
+#endif /* TOPPERS_tskini */
+
+/*
+ * ビットマップサーチ関数
+ *
+ * bitmap内の1のビットの内,最も下位(右)のものをサーチし,そのビッ
+ * ト番号を返す.ビット番号は,最下位ビットを0とする.bitmapに0を指定
+ * してはならない.この関数では,bitmapが16ビットであることを仮定し,
+ * uint16_t型としている.
+ *
+ * ビットサーチ命令を持つプロセッサでは,ビットサーチ命令を使うように
+ * 書き直した方が効率が良い場合がある.このような場合には,ターゲット
+ * 依存部でビットサーチ命令を使ったbitmap_searchを定義し,
+ * OMIT_BITMAP_SEARCHをマクロ定義すればよい.また,ビットサーチ命令の
+ * サーチ方向が逆などの理由で優先度とビットとの対応を変更したい場合に
+ * は,PRIMAP_BITをマクロ定義すればよい.
+ *
+ * また,標準ライブラリにffsがあるなら,次のように定義して標準ライブ
+ * ラリを使った方が効率が良い可能性もある.
+ * #define bitmap_search(bitmap) (ffs(bitmap) - 1)
+ */
+#ifndef PRIMAP_BIT
+#define PRIMAP_BIT(pri) (1U << (pri))
+#endif /* PRIMAP_BIT */
+
+#ifndef OMIT_BITMAP_SEARCH
+
+static const unsigned char bitmap_search_table[] = { 0, 1, 0, 2, 0, 1, 0,
+ 3, 0, 1, 0, 2, 0, 1, 0 };
+
+Inline uint_t
+bitmap_search(uint16_t bitmap)
+{
+ uint_t n = 0U;
+
+ assert(bitmap != 0U);
+ if ((bitmap & 0x00ffU) == 0U) {
+ bitmap >>= 8;
+ n += 8;
+ }
+ if ((bitmap & 0x0fU) == 0U) {
+ bitmap >>= 4;
+ n += 4;
+ }
+ return(n + bitmap_search_table[(bitmap & 0x0fU) - 1]);
+}
+
+#endif /* OMIT_BITMAP_SEARCH */
+
+/*
+ * 優先度ビットマップが空かのチェック
+ */
+Inline bool_t
+primap_empty(void)
+{
+ return(ready_primap == 0U);
+}
+
+/*
+ * 優先度ビットマップのサーチ
+ */
+Inline uint_t
+primap_search(void)
+{
+ return(bitmap_search(ready_primap));
+}
+
+/*
+ * 優先度ビットマップのセット
+ */
+Inline void
+primap_set(uint_t pri)
+{
+ ready_primap |= PRIMAP_BIT(pri);
+}
+
+/*
+ * 優先度ビットマップのクリア
+ */
+Inline void
+primap_clear(uint_t pri)
+{
+ ready_primap &= ~PRIMAP_BIT(pri);
+}
+
+/*
+ * 最高優先順位タスクのサーチ
+ */
+#ifdef TOPPERS_tsksched
+
+TCB *
+search_schedtsk(void)
+{
+ uint_t schedpri;
+
+ schedpri = primap_search();
+ return((TCB *)(ready_queue[schedpri].p_next));
+}
+
+#endif /* TOPPERS_tsksched */
+
+/*
+ * 実行できる状態への遷移
+ *
+ * 最高優先順位のタスクを更新するのは,実行できるタスクがなかった場合
+ * と,p_tcbの優先度が最高優先順位のタスクの優先度よりも高い場合であ
+ * る.
+ */
+#ifdef TOPPERS_tskrun
+
+bool_t
+make_runnable(TCB *p_tcb)
+{
+ uint_t pri = p_tcb->priority;
+
+ queue_insert_prev(&(ready_queue[pri]), &(p_tcb->task_queue));
+ primap_set(pri);
+
+ if (p_schedtsk == (TCB *) NULL || pri < p_schedtsk->priority) {
+ p_schedtsk = p_tcb;
+ return(dspflg);
+ }
+ return(false);
+}
+
+#endif /* TOPPERS_tskrun */
+
+/*
+ * 実行できる状態から他の状態への遷移
+ *
+ * 最高優先順位のタスクを更新するのは,p_tcbが最高優先順位のタスクで
+ * あった場合である.p_tcbと同じ優先度のタスクが他にある場合は,p_tcb
+ * の次のタスクが最高優先順位になる.そうでない場合は,レディキューを
+ * サーチする必要がある.
+ */
+#ifdef TOPPERS_tsknrun
+
+bool_t
+make_non_runnable(TCB *p_tcb)
+{
+ uint_t pri = p_tcb->priority;
+ QUEUE *p_queue = &(ready_queue[pri]);
+
+ queue_delete(&(p_tcb->task_queue));
+ if (queue_empty(p_queue)) {
+ primap_clear(pri);
+ if (p_schedtsk == p_tcb) {
+ p_schedtsk = primap_empty() ? (TCB *) NULL : search_schedtsk();
+ return(dspflg);
+ }
+ }
+ else {
+ if (p_schedtsk == p_tcb) {
+ p_schedtsk = (TCB *)(p_queue->p_next);
+ return(dspflg);
+ }
+ }
+ return(false);
+}
+
+#endif /* TOPPERS_tsknrun */
+
+/*
+ * 休止状態への遷移
+ */
+#ifdef TOPPERS_tskdmt
+
+void
+make_dormant(TCB *p_tcb)
+{
+ p_tcb->tstat = TS_DORMANT;
+ p_tcb->bpriority = p_tcb->priority = p_tcb->p_tinib->ipriority;
+ p_tcb->wupque = false;
+ p_tcb->enatex = false;
+ p_tcb->texptn = 0U;
+ LOG_TSKSTAT(p_tcb);
+}
+
+#endif /* TOPPERS_tskdmt */
+
+/*
+ * 休止状態から実行できる状態への遷移
+ */
+#ifdef TOPPERS_tskact
+
+bool_t
+make_active(TCB *p_tcb)
+{
+ activate_context(p_tcb);
+ p_tcb->tstat = TS_RUNNABLE;
+ LOG_TSKSTAT(p_tcb);
+ return(make_runnable(p_tcb));
+}
+
+#endif /* TOPPERS_tskact */
+
+/*
+ * タスクの優先度の変更
+ *
+ * タスクが実行できる状態の場合には,レディキューの中での位置を変更す
+ * る.オブジェクトの待ちキューの中で待ち状態になっている場合には,待
+ * ちキューの中での位置を変更する.
+ *
+ * 最高優先順位のタスクを更新するのは,(1) p_tcbが最高優先順位のタス
+ * クであって,その優先度を下げた場合,(2) p_tcbが最高優先順位のタス
+ * クではなく,変更後の優先度が最高優先順位のタスクの優先度よりも高い
+ * 場合である.(1)の場合には,レディキューをサーチする必要がある.
+ */
+#ifdef TOPPERS_tskpri
+
+bool_t
+change_priority(TCB *p_tcb, uint_t newpri, bool_t mtxmode)
+{
+ uint_t oldpri;
+
+ oldpri = p_tcb->priority;
+ p_tcb->priority = newpri;
+
+ if (TSTAT_RUNNABLE(p_tcb->tstat)) {
+ /*
+ * タスクが実行できる状態の場合
+ */
+ queue_delete(&(p_tcb->task_queue));
+ if (queue_empty(&(ready_queue[oldpri]))) {
+ primap_clear(oldpri);
+ }
+ if (mtxmode) {
+ queue_insert_next(&(ready_queue[newpri]), &(p_tcb->task_queue));
+ }
+ else {
+ queue_insert_prev(&(ready_queue[newpri]), &(p_tcb->task_queue));
+ }
+ primap_set(newpri);
+
+ if (p_schedtsk == p_tcb) {
+ if (newpri >= oldpri) {
+ p_schedtsk = search_schedtsk();
+ return(p_schedtsk != p_tcb && dspflg);
+ }
+ }
+ else {
+ if (mtxmode ? newpri <= p_schedtsk->priority
+ : newpri < p_schedtsk->priority) {
+ p_schedtsk = p_tcb;
+ return(dspflg);
+ }
+ }
+ }
+ else {
+ if (TSTAT_WAIT_WOBJCB(p_tcb->tstat)) {
+ /*
+ * タスクが,同期・通信オブジェクトの管理ブロックの共通部
+ * 分(WOBJCB)の待ちキューにつながれている場合
+ */
+ wobj_change_priority(((WINFO_WOBJ *)(p_tcb->p_winfo))->p_wobjcb,
+ p_tcb);
+ }
+ }
+ return(false);
+}
+
+#endif /* TOPPERS_tskpri */
+
+/*
+ * レディキューの回転
+ *
+ * 最高優先順位のタスクを更新するのは,最高優先順位のタスクがタスクキ
+ * ューの末尾に移動した場合である.
+ */
+#ifdef TOPPERS_tskrot
+
+bool_t
+rotate_ready_queue(uint_t pri)
+{
+ QUEUE *p_queue = &(ready_queue[pri]);
+ QUEUE *p_entry;
+
+ if (!queue_empty(p_queue) && p_queue->p_next->p_next != p_queue) {
+ p_entry = queue_delete_next(p_queue);
+ queue_insert_prev(p_queue, p_entry);
+ if (p_schedtsk == (TCB *) p_entry) {
+ p_schedtsk = (TCB *)(p_queue->p_next);
+ return(dspflg);
+ }
+ }
+ return(false);
+}
+
+#endif /* TOPPERS_tskrot */
+
+/*
+ * タスク例外処理ルーチンの呼出し
+ *
+ * ASPカーネルでは,タスク例外処理ルーチン内でCPUロック状態に遷移し,
+ * 元の状態に戻さずにリターンした場合,カーネルが元の状態に戻す.
+ */
+#ifdef TOPPERS_tsktex
+
+void
+call_texrtn(void)
+{
+ TEXPTN texptn;
+ PRI saved_ipm;
+ bool_t saved_disdsp, saved_dspflg;
+
+ saved_ipm = t_get_ipm();
+ saved_disdsp = disdsp;
+ saved_dspflg = dspflg;
+ p_runtsk->enatex = false;
+ do {
+ texptn = p_runtsk->texptn;
+ p_runtsk->texptn = 0U;
+
+ t_unlock_cpu();
+ LOG_TEX_ENTER(p_runtsk, texptn);
+ (*((TEXRTN)(p_runtsk->p_tinib->texrtn)))(texptn,
+ p_runtsk->p_tinib->exinf);
+ LOG_TEX_LEAVE(p_runtsk);
+ if (!t_sense_lock()) {
+ t_lock_cpu();
+ }
+ t_set_ipm(saved_ipm);
+ disdsp = saved_disdsp;
+ dspflg = saved_dspflg;
+ /*
+ * ここでp_runtsk->enatexをfalseにするのは,タスク例外処理ルー
+ * チンから,タスク例外処理許可状態のままリターンした場合の対
+ * 策である.
+ */
+ p_runtsk->enatex = false;
+ if (p_runtsk != p_schedtsk && dspflg) {
+ /*
+ * ここでdispatchを呼び出す処理は,相互再帰呼出しになって
+ * いるが,dispatchを呼ぶ前にp_runtsk->enatexをflaseにして
+ * おけば支障がない.その理由については,「TOPPERS/ASP カー
+ * ネル 設計メモ」を参照のこと.
+ */
+ dispatch();
+ }
+ } while (p_runtsk->texptn != 0U);
+ p_runtsk->enatex = true;
+}
+
+/*
+ * タスク例外処理ルーチンの起動
+ */
+#ifndef OMIT_CALLTEX
+
+void
+calltex(void)
+{
+ if (p_runtsk->enatex && p_runtsk->texptn != 0U) {
+ call_texrtn();
+ }
+}
+
+#endif /* OMIT_CALLTEX */
+#endif /* TOPPERS_tsktex */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * $Id: task.h 1863 2010-07-25 12:23:05Z ertl-hiro $
+ */
+
+/*
+ * タスク管理モジュール
+ */
+
+#ifndef TOPPERS_TASK_H
+#define TOPPERS_TASK_H
+
+#include <queue.h>
+#include "time_event.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_TSKSTAT
+#define LOG_TSKSTAT(p_tcb)
+#endif /* LOG_TSKSTAT */
+
+/*
+ * タスク優先度の内部表現・外部表現変換マクロ
+ */
+#define INT_PRIORITY(x) ((uint_t)((x) - TMIN_TPRI))
+#define EXT_TSKPRI(x) ((PRI)(x) + TMIN_TPRI)
+
+/*
+ * タスク状態の内部表現
+ *
+ * TCB中のタスク状態では,実行状態(RUNNING)と実行可能状態(READY)
+ * は区別しない.両状態を総称して,実行できる状態(RUNNABLE)と呼ぶ.
+ * 二重待ち状態は,(TS_WAITING | TS_SUSPENDED)で表す.TS_WAIT_???は待
+ * ち要因を表し,待ち状態(二重待ち状態を含む)の場合にのみ設定する.
+ */
+#define TS_DORMANT 0x00U /* 休止状態 */
+#define TS_RUNNABLE 0x01U /* 実行できる状態 */
+#define TS_WAITING 0x02U /* 待ち状態 */
+#define TS_SUSPENDED 0x04U /* 強制待ち状態 */
+
+#define TS_WAIT_DLY (0x00U << 3) /* 時間経過待ち */
+#define TS_WAIT_SLP (0x01U << 3) /* 起床待ち */
+#define TS_WAIT_RDTQ (0x02U << 3) /* データキューからの受信待ち */
+#define TS_WAIT_RPDQ (0x03U << 3) /* 優先度データキューからの受信待ち */
+#define TS_WAIT_SEM (0x04U << 3) /* セマフォ資源の獲得待ち */
+#define TS_WAIT_FLG (0x05U << 3) /* イベントフラグ待ち */
+#define TS_WAIT_SDTQ (0x06U << 3) /* データキューへの送信待ち */
+#define TS_WAIT_SPDQ (0x07U << 3) /* 優先度データキューへの送信待ち */
+#define TS_WAIT_MBX (0x08U << 3) /* メールボックスからの受信待ち */
+#define TS_WAIT_MPF (0x09U << 3) /* 固定長メモリブロックの獲得待ち */
+#define TS_WAIT_MTX (0x0aU << 3) /* ミューテックスのロック待ち */
+
+/*
+ * タスク状態判別マクロ
+ *
+ * TSTAT_DORMANTはタスクが休止状態であるかどうかを,TSTAT_RUNNABLEは
+ * タスクが実行できる状態であるかどうかを判別する.TSTAT_WAITINGは待
+ * ち状態と二重待ち状態のいずれかであるかどうかを,TSTAT_SUSPENDEDは
+ * 強制待ち状態と二重待ち状態のいずれかであるかどうかを判別する.
+ */
+#define TSTAT_DORMANT(tstat) ((tstat) == TS_DORMANT)
+#define TSTAT_RUNNABLE(tstat) (((tstat) & TS_RUNNABLE) != 0U)
+#define TSTAT_WAITING(tstat) (((tstat) & TS_WAITING) != 0U)
+#define TSTAT_SUSPENDED(tstat) (((tstat) & TS_SUSPENDED) != 0U)
+
+/*
+ * タスク待ち要因判別マクロ
+ *
+ * TSTAT_WAIT_SLPはタスクが起床待ちであるかどうかを,TSTAT_WAIT_WOBJ
+ * はタスクが同期・通信オブジェクトに対する待ちであるか(言い換えると,
+ * 同期通信オブジェクトの待ちキューにつながれているか)どうかを判別す
+ * る.また,TSTAT_WAIT_WOBJCBはタスクが同期・通信オブジェクトの管理
+ * ブロックの共通部分(WOBJCB)の待ちキューにつながれているかどうかを
+ * 判別する.
+ *
+ * TSTAT_WAIT_SLPは,任意のタスク状態の中から,タスクが起床待ちである
+ * ことを判別できる.すなわち,TSTAT_WAITINGにより待ち状態であることを
+ * 判別せずに,TSTAT_SLPだけを用いて起床待ち状態であることを判別できる.
+ * これを効率的に実現するために,TS_WAIT_SLPの値を,(0x00U << 3)ではな
+ * く(0x01U << 3)としている.そのため,タスクが時間経過待ち状態である
+ * ことを判別するためのTSTAT_WAIT_DLYを,TSTAT_WAIT_SLPと同様の方法で
+ * 実現することはできない.
+ */
+#define TS_WAIT_MASK (0x0fU << 3) /* 待ち要因の取出しマスク */
+
+#define TSTAT_WAIT_SLP(tstat) (((tstat) & TS_WAIT_MASK) == TS_WAIT_SLP)
+#define TSTAT_WAIT_WOBJ(tstat) (((tstat) & TS_WAIT_MASK) >= TS_WAIT_RDTQ)
+#define TSTAT_WAIT_WOBJCB(tstat) (((tstat) & TS_WAIT_MASK) >= TS_WAIT_SEM)
+#define TSTAT_WAIT_MTX(tstat) (((tstat) & TS_WAIT_MASK) == TS_WAIT_MTX)
+
+/*
+ * 待ち情報ブロック(WINFO)の定義
+ *
+ * タスクが待ち状態の間は,TCBおよびそのp_winfoで指されるWINFOを次の
+ * ように設定しなければならない.
+ *
+ * (a) TCBのタスク状態を待ち状態(TS_WAITING)にする.その際に,待ち
+ * 要因(TS_WAIT_???)も設定する.
+ *
+ * (b) タイムアウトを監視するために,タイムイベントブロックを登録する.
+ * 登録するタイムイベントブロックは,待ちに入るサービスコール処理関数
+ * のローカル変数として確保し,それへのポインタをWINFOのp_tmevtbに記
+ * 憶する.タイムアウトの監視が必要ない場合(永久待ちの場合)には,
+ * p_tmevtbをNULLにする.
+ *
+ * 同期・通信オブジェクトに対する待ち状態の場合には,標準のWINFOに
+ * p_wobjcbフィールドを追加した構造体(WINFO_WOBJ,wait.hで定義)を使
+ * う.また,以下の(c)〜(e)の設定を行う必要がある.同期・通信オブジェ
+ * クトに関係しない待ち(起床待ち,時間経過待ち)の場合には,(c)〜(e)
+ * は必要ない.
+ *
+ * (c) TCBを待ち対象の同期・通信オブジェクトの待ちキューにつなぐ.待
+ * ちキューにつなぐために,task_queueを使う.
+ *
+ * (d) 待ち対象の同期・通信オブジェクトの管理ブロックへのポインタを,
+ * WINFO_WOBJのp_wobjcbに記憶する.
+ *
+ * (e) 待ち対象の同期・通信オブジェクトに依存して記憶することが必要な
+ * 情報がある場合には,WINFO_WOBJに必要な情報のためのフィールドを追加
+ * した構造体を定義し,WINFO_WOBJの代わりに用いる.
+ *
+ * 待ち状態を解除する際には,待ち解除したタスクに対する返値をWINFOの
+ * wercdに設定する.wercdが必要なのは待ち解除以降であるのに対して,
+ * p_tmevtbは待ち解除後は必要ないため,メモリ節約のために共用体を使っ
+ * ている.そのため,wercdへエラーコードを設定するのは,タイムイベント
+ * ブロックを登録解除した後にしなければならない.
+ */
+typedef union waiting_information {
+ ER wercd; /* 待ち解除時のエラーコード */
+ TMEVTB *p_tmevtb; /* 待ち状態用のタイムイベントブロック */
+} WINFO;
+
+/*
+ * タスク初期化ブロック
+ *
+ * タスクに関する情報を,値が変わらないためにROMに置ける部分(タスク
+ * 初期化ブロック)と,値が変化するためにRAMに置かなければならない部
+ * 分(タスク管理ブロック,TCB)に分離し,TCB内に対応するタスク初期化
+ * ブロックを指すポインタを入れる.タスク初期化ブロック内に対応する
+ * TCBを指すポインタを入れる方法の方が,RAMの節約の観点からは望ましい
+ * が,実行効率が悪くなるために採用していない.他のオブジェクトについ
+ * ても同様に扱う.
+ *
+ * タスク初期化ブロックには,DEF_TEXで定義されるタスク例外処理ルーチ
+ * ンに関する情報も含む.
+ */
+typedef struct task_initialization_block {
+ ATR tskatr; /* タスク属性 */
+ intptr_t exinf; /* タスクの拡張情報 */
+ TASK task; /* タスクの起動番地 */
+ uint_t ipriority; /* タスクの起動時優先度(内部表現) */
+
+#ifdef USE_TSKINICTXB
+ TSKINICTXB tskinictxb; /* タスク初期化コンテキストブロック */
+#else /* USE_TSKINICTXB */
+ SIZE stksz; /* スタック領域のサイズ(丸めた値) */
+ void *stk; /* スタック領域の先頭番地 */
+#endif /* USE_TSKINICTXB */
+
+ ATR texatr; /* タスク例外処理ルーチン属性 */
+ TEXRTN texrtn; /* タスク例外処理ルーチンの起動番地 */
+} TINIB;
+
+/*
+ * TCB中のフィールドのビット幅の定義
+ *
+ * プロセッサによっては,TCB中のフィールドのビット幅でメモリ使用量と
+ * 性能がトレードオフになるため,ターゲット依存にフィールドのビット幅
+ * を変更することを許している.
+ */
+#ifndef TBIT_TCB_PRIORITY
+#define TBIT_TCB_PRIORITY 8 /* priorityフィールドのビット幅 */
+#endif /* TBIT_TCB_PRIORITY */
+
+/*
+ * タスク管理ブロック(TCB)
+ *
+ * ASPカーネルでは,タスクの起動要求キューイング数の最大値(TMAX_ACTCNT)
+ * と起床要求キューイング数の最大値(TMAX_WUPCNT)は1に固定されている
+ * ため,キューイングされているかどうかの真偽値で表現することができる.
+ * また,強制待ち要求ネスト数の最大値(TMAX_SUSCNT)が1に固定されてい
+ * るので,強制待ち要求ネスト数(suscnt)は必要ない.
+ *
+ * TCBのいくつかのフィールドは,特定のタスク状態でのみ有効な値を保持し,
+ * それ以外の場合は値が保証されない(よって,参照してはならない).各
+ * フィールドが有効な値を保持する条件は次の通り.
+ *
+ * ・初期化後は常に有効:
+ * p_tinib,tstat,actque
+ * ・休止状態以外で有効(休止状態では初期値になっている):
+ * bpriority,priority,wupque,enatex,texptn,mutex_queue
+ * ・待ち状態(二重待ち状態を含む)で有効:
+ * p_winfo
+ * ・実行できる状態と同期・通信オブジェクトに対する待ち状態で有効:
+ * task_queue
+ * ・実行可能状態,待ち状態,強制待ち状態,二重待ち状態で有効:
+ * tskctxb
+ */
+typedef struct task_control_block {
+ QUEUE task_queue; /* タスクキュー */
+ const TINIB *p_tinib; /* 初期化ブロックへのポインタ */
+
+#ifdef UINT8_MAX
+ uint8_t tstat; /* タスク状態(内部表現)*/
+#else /* UINT8_MAX */
+ BIT_FIELD_UINT tstat : 8; /* タスク状態(内部表現)*/
+#endif /* UINT8_MAX */
+ BIT_FIELD_UINT bpriority : TBIT_TCB_PRIORITY;
+ /* ベース優先度(内部表現)*/
+#if defined(UINT8_MAX) && (TBIT_TCB_PRIORITY == 8)
+ uint8_t priority; /* 現在の優先度(内部表現)*/
+#else /* defined(UINT8_MAX) && (TBIT_TCB_PRIORITY == 8) */
+ BIT_FIELD_UINT priority : TBIT_TCB_PRIORITY;
+ /* 現在の優先度(内部表現)*/
+#endif /* defined(UINT8_MAX) && (TBIT_TCB_PRIORITY == 8) */
+ BIT_FIELD_BOOL actque : 1; /* 起動要求キューイング */
+ BIT_FIELD_BOOL wupque : 1; /* 起床要求キューイング */
+ BIT_FIELD_BOOL enatex : 1; /* タスク例外処理許可状態 */
+
+ TEXPTN texptn; /* 保留例外要因 */
+ WINFO *p_winfo; /* 待ち情報ブロックへのポインタ */
+ QUEUE mutex_queue; /* ロックしているミューテックスのキュー */
+ TSKCTXB tskctxb; /* タスクコンテキストブロック */
+} TCB;
+
+/*
+ * 実行状態のタスク
+ *
+ * 実行状態のタスク(=プロセッサがコンテキストを持っているタスク)の
+ * TCBを指すポインタ.実行状態のタスクがない場合はNULLにする.
+ *
+ * サービスコールの処理中で,自タスク(サービスコールを呼び出したタス
+ * ク)に関する情報を参照する場合はp_runtskを使う.p_runtskを書き換え
+ * るのは,ディスパッチャ(と初期化処理)のみである.
+ */
+extern TCB *p_runtsk;
+
+/*
+ * 最高優先順位のタスク
+ *
+ * 実行できるタスクの中で最高優先順位のタスクのTCBを指すポインタ.実
+ * 行できるタスクがない場合はNULLにする.
+ *
+ * ディスパッチ禁止状態など,ディスパッチが保留されている間はp_runtsk
+ * と一致しているとは限らない.
+ */
+extern TCB *p_schedtsk;
+
+/*
+ * ディスパッチ/タスク例外処理ルーチン起動要求フラグ
+ *
+ * 割込みハンドラ/CPU例外ハンドラの出口処理に,ディスパッチまたは
+ * タスク例外処理ルーチンの起動を要求することを示すフラグ.
+ */
+extern bool_t reqflg;
+
+/*
+ * ディスパッチ禁止状態
+ *
+ * ディスパッチ禁止状態であることを示すフラグ.
+ */
+extern bool_t disdsp;
+
+/*
+ * タスクディスパッチ可能状態
+ *
+ * 割込み優先度マスク全解除状態であり,ディスパッチ許可状態である(ディ
+ * スパッチ禁止状態でない)ことを示すフラグ.
+ */
+extern bool_t dspflg;
+
+/*
+ * レディキュー
+ *
+ * レディキューは,実行できる状態のタスクを管理するためのキューである.
+ * 実行状態のタスクも管理しているため,レディ(実行可能)キューという
+ * 名称は正確ではないが,レディキューという名称が定着しているため,こ
+ * の名称で呼ぶことにする.
+ *
+ * レディキューは,優先度ごとのタスクキューで構成されている.タスクの
+ * TCBは,該当する優先度のキューに登録される.
+ */
+extern QUEUE ready_queue[TNUM_TPRI];
+
+/*
+ * レディキューサーチのためのビットマップ
+ *
+ * レディキューのサーチを効率よく行うために,優先度ごとのタスクキュー
+ * にタスクが入っているかどうかを示すビットマップを用意している.ビッ
+ * トマップを使うことで,メモリアクセスの回数を減らすことができるが,
+ * ビット操作命令が充実していないプロセッサで,優先度の段階数が少ない
+ * 場合には,ビットマップ操作のオーバーヘッドのために,逆に効率が落ち
+ * る可能性もある.
+ *
+ * 優先度が16段階であることを仮定しているため,uint16_t型としている.
+ */
+extern uint16_t ready_primap;
+
+/*
+ * タスクIDの最大値(kernel_cfg.c)
+ */
+extern const ID tmax_tskid;
+
+/*
+ * タスク初期化ブロックのエリア(kernel_cfg.c)
+ */
+extern const TINIB tinib_table[];
+
+/*
+ * タスク生成順序テーブル(kernel_cfg.c)
+ */
+extern const ID torder_table[];
+
+/*
+ * TCBのエリア(kernel_cfg.c)
+ */
+extern TCB tcb_table[];
+
+/*
+ * タスクの数
+ */
+#define tnum_tsk ((uint_t)(tmax_tskid - TMIN_TSKID + 1))
+
+/*
+ * タスクIDからTCBを取り出すためのマクロ
+ */
+#define INDEX_TSK(tskid) ((uint_t)((tskid) - TMIN_TSKID))
+#define get_tcb(tskid) (&(tcb_table[INDEX_TSK(tskid)]))
+#define get_tcb_self(tskid) ((tskid) == TSK_SELF ? p_runtsk : get_tcb(tskid))
+
+/*
+ * TCBからタスクIDを取り出すためのマクロ
+ */
+#define TSKID(p_tcb) ((ID)(((p_tcb) - tcb_table) + TMIN_TSKID))
+
+/*
+ * タスク管理モジュールの初期化
+ */
+extern void initialize_task(void);
+
+/*
+ * 最高優先順位タスクのサーチ
+ *
+ * レディキュー中の最高優先順位のタスクをサーチし,そのTCBへのポインタ
+ * を返す.レディキューが空の場合には,この関数を呼び出してはならない.
+ */
+extern TCB *search_schedtsk(void);
+
+/*
+ * 実行できる状態への遷移
+ *
+ * p_tcbで指定されるタスクをレディキューに挿入する.レディキューに挿入
+ * したタスクの優先度が,最高優先順位のタスクの優先度よりも高い場合は,
+ * 最高優先順位のタスクを更新し,ディスパッチ許可状態であればtrueを返
+ * す.そうでない場合はfalseを返す.
+ */
+extern bool_t make_runnable(TCB *p_tcb);
+
+/*
+ * 実行できる状態から他の状態への遷移
+ *
+ * p_tcbで指定されるタスクをレディキューから削除する.p_tcbで指定した
+ * タスクが最高優先順位のタスクであった場合には,最高優先順位のタスク
+ * を設定しなおし,ディスパッチ許可状態であればtrueを返す.そうでない
+ * 場合はfalseを返す.タスクの状態は更新しない.
+ */
+extern bool_t make_non_runnable(TCB *p_tcb);
+
+/*
+ * 休止状態への遷移
+ *
+ * p_tcbで指定されるタスクの状態を休止状態とする.また,タスクの起動
+ * 時に初期化すべき変数の初期化と,タスク起動のためのコンテキストを設
+ * 定する.
+ */
+extern void make_dormant(TCB *p_tcb);
+
+/*
+ * 休止状態から実行できる状態への遷移
+ *
+ * p_tcbで指定されるタスクの状態を休止状態から実行できる状態とする.
+ * 実行できる状態に遷移したタスクへのディスパッチが必要な場合はtrue,
+ * そうでない場合はfalseを返す.
+ */
+extern bool_t make_active(TCB *p_tcb);
+
+/*
+ * タスクの優先度の変更
+ *
+ * p_tcbで指定されるタスクの優先度をnewpri(内部表現)に変更する.また,
+ * 必要な場合には最高優先順位のタスクを更新し,ディスパッチ許可状態で
+ * あればtrueを返す.そうでない場合はfalseを返す.
+ *
+ * p_tcbで指定されるタスクの優先順位は,mtxmodeがfalseの時は同じ優先度
+ * のタスクの中で最低,mtxmodeがtrueの時は同じ優先度のタスクの中で最高
+ * とする.
+ */
+extern bool_t change_priority(TCB *p_tcb, uint_t newpri, bool_t mtxmode);
+
+/*
+ * レディキューの回転
+ *
+ * レディキュー中の,priで指定される優先度のタスクキューを回転させる.
+ * また,必要な場合には最高優先順位のタスクを変更し,ディスパッチが保
+ * 留されていなければtrueを返す.そうでない場合はfalseを返す.
+ */
+extern bool_t rotate_ready_queue(uint_t pri);
+
+/*
+ * タスク例外処理ルーチンの呼出し
+ *
+ * タスク例外処理ルーチンを呼び出す.呼び出す前に,実行状態のタスクの
+ * 保留例外要因をクリアし,タスク例外処理禁止状態にし,CPUロックを解
+ * 除する.
+ *
+ * タスク例外処理ルーチンから戻ると,まずCPUロック状態に戻し,その間
+ * に保留例外要因が0でなくなっていれば,再びタスク例外処理ルーチンを
+ * 呼び出す.保留例外要因が0の場合には,例外処理許可状態にして関数か
+ * らリターンする.
+ *
+ * この関数は,実行状態のタスクが,タスク例外処理許可状態(enatexが
+ * true)で,保留例外要因が0でない(texptnが0でない)場合に呼び出すこ
+ * とを想定している.この関数は,CPUロック状態で呼び出さなければなら
+ * ない.
+ */
+extern void call_texrtn(void);
+
+/*
+ * タスク例外処理ルーチンの起動
+ *
+ * 実行状態のタスクがタスク例外処理ルーチンの起動条件を満たしていれば,
+ * タスク例外処理ルーチンを呼び出す.CPU例外処理ルーチンを呼び出す時
+ * は,一時的にCPUロックを解除する.
+ *
+ * この関数は,ディスパッチャや割込みハンドラ/CPU例外ハンドラの出口
+ * 処理から呼び出されることを想定している.この関数は,CPUロック状態
+ * で呼び出さなければならない.
+ *
+ * 実行効率を上げるために,この関数をターゲット依存部で記述してもよい.
+ * その場合には,OMIT_CALLTEXをマクロ定義する.
+ */
+extern void calltex(void);
+
+#endif /* TOPPERS_TASK_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: task_manage.c 1694 2010-01-01 15:59:09Z ertl-hiro $
+ */
+
+/*
+ * タスク管理機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "mutex.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_ACT_TSK_ENTER
+#define LOG_ACT_TSK_ENTER(tskid)
+#endif /* LOG_ACT_TSK_ENTER */
+
+#ifndef LOG_ACT_TSK_LEAVE
+#define LOG_ACT_TSK_LEAVE(ercd)
+#endif /* LOG_ACT_TSK_LEAVE */
+
+#ifndef LOG_IACT_TSK_ENTER
+#define LOG_IACT_TSK_ENTER(tskid)
+#endif /* LOG_IACT_TSK_ENTER */
+
+#ifndef LOG_IACT_TSK_LEAVE
+#define LOG_IACT_TSK_LEAVE(ercd)
+#endif /* LOG_IACT_TSK_LEAVE */
+
+#ifndef LOG_CAN_ACT_ENTER
+#define LOG_CAN_ACT_ENTER(tskid)
+#endif /* LOG_CAN_ACT_ENTER */
+
+#ifndef LOG_CAN_ACT_LEAVE
+#define LOG_CAN_ACT_LEAVE(ercd)
+#endif /* LOG_CAN_ACT_LEAVE */
+
+#ifndef LOG_EXT_TSK_ENTER
+#define LOG_EXT_TSK_ENTER()
+#endif /* LOG_EXT_TSK_ENTER */
+
+#ifndef LOG_EXT_TSK_LEAVE
+#define LOG_EXT_TSK_LEAVE(ercd)
+#endif /* LOG_EXT_TSK_LEAVE */
+
+#ifndef LOG_TER_TSK_ENTER
+#define LOG_TER_TSK_ENTER(tskid)
+#endif /* LOG_TER_TSK_ENTER */
+
+#ifndef LOG_TER_TSK_LEAVE
+#define LOG_TER_TSK_LEAVE(ercd)
+#endif /* LOG_TER_TSK_LEAVE */
+
+#ifndef LOG_CHG_PRI_ENTER
+#define LOG_CHG_PRI_ENTER(tskid, tskpri)
+#endif /* LOG_CHG_PRI_ENTER */
+
+#ifndef LOG_CHG_PRI_LEAVE
+#define LOG_CHG_PRI_LEAVE(ercd)
+#endif /* LOG_CHG_PRI_LEAVE */
+
+#ifndef LOG_GET_PRI_ENTER
+#define LOG_GET_PRI_ENTER(tskid, p_tskpri)
+#endif /* LOG_GET_PRI_ENTER */
+
+#ifndef LOG_GET_PRI_LEAVE
+#define LOG_GET_PRI_LEAVE(ercd, tskpri)
+#endif /* LOG_GET_PRI_LEAVE */
+
+#ifndef LOG_GET_INF_ENTER
+#define LOG_GET_INF_ENTER(p_exinf)
+#endif /* LOG_GET_INF_ENTER */
+
+#ifndef LOG_GET_INF_LEAVE
+#define LOG_GET_INF_LEAVE(ercd, exinf)
+#endif /* LOG_GET_INF_LEAVE */
+
+/*
+ * タスクの起動
+ */
+#ifdef TOPPERS_act_tsk
+
+ER
+act_tsk(ID tskid)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_ACT_TSK_ENTER(tskid);
+ CHECK_TSKCTX_UNL();
+ CHECK_TSKID_SELF(tskid);
+ p_tcb = get_tcb_self(tskid);
+
+ t_lock_cpu();
+ if (TSTAT_DORMANT(p_tcb->tstat)) {
+ if (make_active(p_tcb)) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ else if (!(p_tcb->actque)) {
+ p_tcb->actque = true;
+ ercd = E_OK;
+ }
+ else {
+ ercd = E_QOVR;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_ACT_TSK_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_act_tsk */
+
+/*
+ * タスクの起動(非タスクコンテキスト用)
+ */
+#ifdef TOPPERS_iact_tsk
+
+ER
+iact_tsk(ID tskid)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_IACT_TSK_ENTER(tskid);
+ CHECK_INTCTX_UNL();
+ CHECK_TSKID(tskid);
+ p_tcb = get_tcb(tskid);
+
+ i_lock_cpu();
+ if (TSTAT_DORMANT(p_tcb->tstat)) {
+ if (make_active(p_tcb)) {
+ reqflg = true;
+ }
+ ercd = E_OK;
+ }
+ else if (!(p_tcb->actque)) {
+ p_tcb->actque = true;
+ ercd = E_OK;
+ }
+ else {
+ ercd = E_QOVR;
+ }
+ i_unlock_cpu();
+
+ error_exit:
+ LOG_IACT_TSK_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_iact_tsk */
+
+/*
+ * タスク起動要求のキャンセル
+ */
+#ifdef TOPPERS_can_act
+
+ER_UINT
+can_act(ID tskid)
+{
+ TCB *p_tcb;
+ ER_UINT ercd;
+
+ LOG_CAN_ACT_ENTER(tskid);
+ CHECK_TSKCTX_UNL();
+ CHECK_TSKID_SELF(tskid);
+ p_tcb = get_tcb_self(tskid);
+
+ t_lock_cpu();
+ ercd = p_tcb->actque ? 1 : 0;
+ p_tcb->actque = false;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_CAN_ACT_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_can_act */
+
+/*
+ * 自タスクの終了
+ */
+#ifdef TOPPERS_ext_tsk
+
+ER
+ext_tsk(void)
+{
+ ER ercd;
+
+ LOG_EXT_TSK_ENTER();
+ CHECK_TSKCTX();
+
+ if (t_sense_lock()) {
+ /*
+ * CPUロック状態でext_tskが呼ばれた場合は,CPUロックを解除し
+ * てからタスクを終了する.実装上は,サービスコール内でのCPU
+ * ロックを省略すればよいだけ.
+ */
+ }
+ else {
+ t_lock_cpu();
+ }
+ if (disdsp) {
+ /*
+ * ディスパッチ禁止状態でext_tskが呼ばれた場合は,ディスパッ
+ * チ許可状態にしてからタスクを終了する.
+ */
+ disdsp = false;
+ }
+ if (t_get_ipm() != TIPM_ENAALL) {
+ /*
+ * 割込み優先度マスク(IPM)がTIPM_ENAALL以外の状態でext_tsk
+ * が呼ばれた場合は,IPMをTIPM_ENAALLにしてからタスクを終了す
+ * る.
+ */
+ t_set_ipm(TIPM_ENAALL);
+ }
+ dspflg = true;
+
+ (void) make_non_runnable(p_runtsk);
+ if (!queue_empty(&(p_runtsk->mutex_queue))) {
+ (void) (*mtxhook_release_all)(p_runtsk);
+ }
+ make_dormant(p_runtsk);
+ if (p_runtsk->actque) {
+ p_runtsk->actque = false;
+ (void) make_active(p_runtsk);
+ }
+ exit_and_dispatch();
+ return(E_SYS);
+
+ error_exit:
+ LOG_EXT_TSK_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ext_tsk */
+
+/*
+ * タスクの強制終了
+ */
+#ifdef TOPPERS_ter_tsk
+
+ER
+ter_tsk(ID tskid)
+{
+ TCB *p_tcb;
+ bool_t dspreq = false;
+ ER ercd;
+
+ LOG_TER_TSK_ENTER(tskid);
+ CHECK_TSKCTX_UNL();
+ CHECK_TSKID(tskid);
+ p_tcb = get_tcb(tskid);
+ CHECK_NONSELF(p_tcb);
+
+ t_lock_cpu();
+ if (TSTAT_DORMANT(p_tcb->tstat)) {
+ ercd = E_OBJ;
+ }
+ else {
+ if (TSTAT_RUNNABLE(p_tcb->tstat)) {
+ /*
+ * p_tcbは自タスクでないため,(シングルプロセッサでは)実
+ * 行状態でなく,make_non_runnable(p_tcb)でタスクディスパッ
+ * チが必要になることはない.
+ */
+ (void) make_non_runnable(p_tcb);
+ }
+ else if (TSTAT_WAITING(p_tcb->tstat)) {
+ wait_dequeue_wobj(p_tcb);
+ wait_dequeue_tmevtb(p_tcb);
+ }
+ if (!queue_empty(&(p_tcb->mutex_queue))) {
+ if ((*mtxhook_release_all)(p_tcb)) {
+ dspreq = true;
+ }
+ }
+ make_dormant(p_tcb);
+ if (p_tcb->actque) {
+ p_tcb->actque = false;
+ if (make_active(p_tcb)) {
+ dspreq = true;
+ }
+ }
+ if (dspreq) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_TER_TSK_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ter_tsk */
+
+/*
+ * タスク優先度の変更
+ */
+#ifdef TOPPERS_chg_pri
+
+ER
+chg_pri(ID tskid, PRI tskpri)
+{
+ TCB *p_tcb;
+ uint_t newbpri;
+ ER ercd;
+
+ LOG_CHG_PRI_ENTER(tskid, tskpri);
+ CHECK_TSKCTX_UNL();
+ CHECK_TSKID_SELF(tskid);
+ CHECK_TPRI_INI(tskpri);
+ p_tcb = get_tcb_self(tskid);
+ newbpri = (tskpri == TPRI_INI) ? p_tcb->p_tinib->ipriority
+ : INT_PRIORITY(tskpri);
+
+ t_lock_cpu();
+ if (TSTAT_DORMANT(p_tcb->tstat)) {
+ ercd = E_OBJ;
+ }
+ else if ((!queue_empty(&(p_tcb->mutex_queue))
+ || TSTAT_WAIT_MTX(p_tcb->tstat))
+ && !((*mtxhook_check_ceilpri)(p_tcb, newbpri))) {
+ ercd = E_ILUSE;
+ }
+ else {
+ p_tcb->bpriority = newbpri;
+ if (queue_empty(&(p_tcb->mutex_queue))
+ || !((*mtxhook_scan_ceilmtx)(p_tcb))) {
+ if (change_priority(p_tcb, newbpri, false)) {
+ dispatch();
+ }
+ }
+ ercd = E_OK;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_CHG_PRI_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_chg_pri */
+
+/*
+ * タスク優先度の参照
+ */
+#ifdef TOPPERS_get_pri
+
+ER
+get_pri(ID tskid, PRI *p_tskpri)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_GET_PRI_ENTER(tskid, p_tskpri);
+ CHECK_TSKCTX_UNL();
+ CHECK_TSKID_SELF(tskid);
+ p_tcb = get_tcb_self(tskid);
+
+ t_lock_cpu();
+ if (TSTAT_DORMANT(p_tcb->tstat)) {
+ ercd = E_OBJ;
+ }
+ else {
+ *p_tskpri = EXT_TSKPRI(p_tcb->priority);
+ ercd = E_OK;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_GET_PRI_LEAVE(ercd, *p_tskpri);
+ return(ercd);
+}
+
+#endif /* TOPPERS_get_pri */
+
+/*
+ * 自タスクの拡張情報の参照
+ */
+#ifdef TOPPERS_get_inf
+
+ER
+get_inf(intptr_t *p_exinf)
+{
+ ER ercd;
+
+ LOG_GET_INF_ENTER(p_exinf);
+ CHECK_TSKCTX_UNL();
+
+ t_lock_cpu();
+ *p_exinf = p_runtsk->p_tinib->exinf;
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_GET_INF_LEAVE(ercd, *p_exinf);
+ return(ercd);
+}
+
+#endif /* TOPPERS_get_inf */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: task_refer.c 1016 2008-05-10 08:42:16Z ertl-hiro $
+ */
+
+/*
+ * タスクの状態参照機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "semaphore.h"
+#include "eventflag.h"
+#include "dataqueue.h"
+#include "pridataq.h"
+#include "mailbox.h"
+#include "mempfix.h"
+#include "time_event.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_REF_TSK_ENTER
+#define LOG_REF_TSK_ENTER(tskid, pk_rtsk)
+#endif /* LOG_REF_TSK_ENTER */
+
+#ifndef LOG_REF_TSK_LEAVE
+#define LOG_REF_TSK_LEAVE(ercd, pk_rtsk)
+#endif /* LOG_REF_TSK_LEAVE */
+
+/*
+ * タスクの状態参照
+ */
+#ifdef TOPPERS_ref_tsk
+
+ER
+ref_tsk(ID tskid, T_RTSK *pk_rtsk)
+{
+ TCB *p_tcb;
+ uint_t tstat;
+ ER ercd;
+
+ LOG_REF_TSK_ENTER(tskid, pk_rtsk);
+ CHECK_TSKCTX_UNL();
+ CHECK_TSKID_SELF(tskid);
+ p_tcb = get_tcb_self(tskid);
+
+ t_lock_cpu();
+ tstat = p_tcb->tstat;
+ if (TSTAT_DORMANT(tstat)) {
+ /*
+ * 対象タスクが休止状態の場合
+ */
+ pk_rtsk->tskstat = TTS_DMT;
+ }
+ else {
+ /*
+ * タスク状態の取出し
+ */
+ if (TSTAT_SUSPENDED(tstat)) {
+ if (TSTAT_WAITING(tstat)) {
+ pk_rtsk->tskstat = TTS_WAS;
+ }
+ else {
+ pk_rtsk->tskstat = TTS_SUS;
+ }
+ }
+ else if (TSTAT_WAITING(tstat)) {
+ pk_rtsk->tskstat = TTS_WAI;
+ }
+ else if (p_tcb == p_runtsk) {
+ pk_rtsk->tskstat = TTS_RUN;
+ }
+ else {
+ pk_rtsk->tskstat = TTS_RDY;
+ }
+
+ /*
+ * 現在優先度とベース優先度の取出し
+ */
+ pk_rtsk->tskpri = EXT_TSKPRI(p_tcb->priority);
+ pk_rtsk->tskbpri = EXT_TSKPRI(p_tcb->bpriority);
+
+ if (TSTAT_WAITING(tstat)) {
+ /*
+ * 待ち要因と待ち対象のオブジェクトのIDの取出し
+ */
+ switch (tstat & TS_WAIT_MASK) {
+ case TS_WAIT_SLP:
+ pk_rtsk->tskwait = TTW_SLP;
+ break;
+ case TS_WAIT_DLY:
+ pk_rtsk->tskwait = TTW_DLY;
+ break;
+ case TS_WAIT_SEM:
+ pk_rtsk->tskwait = TTW_SEM;
+ pk_rtsk->wobjid = SEMID(((WINFO_SEM *)(p_tcb->p_winfo))
+ ->p_semcb);
+ break;
+ case TS_WAIT_FLG:
+ pk_rtsk->tskwait = TTW_FLG;
+ pk_rtsk->wobjid = FLGID(((WINFO_FLG *)(p_tcb->p_winfo))
+ ->p_flgcb);
+ break;
+ case TS_WAIT_SDTQ:
+ pk_rtsk->tskwait = TTW_SDTQ;
+ pk_rtsk->wobjid = DTQID(((WINFO_DTQ *)(p_tcb->p_winfo))
+ ->p_dtqcb);
+ break;
+ case TS_WAIT_RDTQ:
+ pk_rtsk->tskwait = TTW_RDTQ;
+ pk_rtsk->wobjid = DTQID(((WINFO_DTQ *)(p_tcb->p_winfo))
+ ->p_dtqcb);
+ break;
+ case TS_WAIT_SPDQ:
+ pk_rtsk->tskwait = TTW_SPDQ;
+ pk_rtsk->wobjid = PDQID(((WINFO_PDQ *)(p_tcb->p_winfo))
+ ->p_pdqcb);
+ break;
+ case TS_WAIT_RPDQ:
+ pk_rtsk->tskwait = TTW_RPDQ;
+ pk_rtsk->wobjid = PDQID(((WINFO_PDQ *)(p_tcb->p_winfo))
+ ->p_pdqcb);
+ break;
+ case TS_WAIT_MBX:
+ pk_rtsk->tskwait = TTW_MBX;
+ pk_rtsk->wobjid = MBXID(((WINFO_MBX *)(p_tcb->p_winfo))
+ ->p_mbxcb);
+ break;
+ case TS_WAIT_MPF:
+ pk_rtsk->tskwait = TTW_MPF;
+ pk_rtsk->wobjid = MPFID(((WINFO_MPF *)(p_tcb->p_winfo))
+ ->p_mpfcb);
+ break;
+ }
+
+ /*
+ * タイムアウトするまでの時間の取出し
+ */
+ if (p_tcb->p_winfo->p_tmevtb != NULL) {
+ pk_rtsk->lefttmo
+ = (TMO) tmevt_lefttim(p_tcb->p_winfo->p_tmevtb);
+ }
+ else {
+ pk_rtsk->lefttmo = TMO_FEVR;
+ }
+ }
+
+ /*
+ * 起床要求キューイング数の取出し
+ */
+ pk_rtsk->wupcnt = p_tcb->wupque ? 1U : 0U;
+ }
+
+ /*
+ * 起動要求キューイング数の取出し
+ */
+ pk_rtsk->actcnt = p_tcb->actque ? 1U : 0U;
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_REF_TSK_LEAVE(ercd, pk_rtsk);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ref_tsk */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: bit_kernel.c 1544 2009-05-08 07:53:48Z ertl-hiro $
+ */
+
+/*
+ * カーネルの整合性検査
+ */
+
+#include "kernel/kernel_impl.h"
+#include "kernel/task.h"
+#include "kernel/wait.h"
+#include "kernel/semaphore.h"
+#include "kernel/eventflag.h"
+#include "kernel/dataqueue.h"
+#include "kernel/pridataq.h"
+#include "kernel/mailbox.h"
+#include "kernel/mutex.h"
+#include "kernel/mempfix.h"
+#include "kernel/time_event.h"
+
+/*
+ * エラーコードの定義
+ */
+#define E_SYS_LINENO ERCD(E_SYS, -(__LINE__))
+
+/*
+ * 管理ブロックのアドレスの正当性のチェック
+ */
+#define VALID_TCB(p_tcb) \
+ ((((char *) p_tcb) - ((char *) tcb_table)) % sizeof(TCB) == 0 \
+ && TMIN_TSKID <= TSKID(p_tcb) && TSKID(p_tcb) <= tmax_tskid)
+
+#define VALID_SEMCB(p_semcb) \
+ ((((char *) p_semcb) - ((char *) semcb_table)) % sizeof(SEMCB) == 0 \
+ && TMIN_SEMID <= SEMID(p_semcb) && SEMID(p_semcb) <= tmax_semid)
+
+#define VALID_FLGCB(p_flgcb) \
+ ((((char *) p_flgcb) - ((char *) flgcb_table)) % sizeof(FLGCB) == 0 \
+ && TMIN_FLGID <= FLGID(p_flgcb) && FLGID(p_flgcb) <= tmax_flgid)
+
+#define VALID_DTQCB(p_dtqcb) \
+ ((((char *) p_dtqcb) - ((char *) dtqcb_table)) % sizeof(DTQCB) == 0 \
+ && TMIN_DTQID <= DTQID(p_dtqcb) && DTQID(p_dtqcb) <= tmax_dtqid)
+
+#define VALID_PDQCB(p_pdqcb) \
+ ((((char *) p_pdqcb) - ((char *) pdqcb_table)) % sizeof(PDQCB) == 0 \
+ && TMIN_PDQID <= PDQID(p_pdqcb) && PDQID(p_pdqcb) <= tmax_pdqid)
+
+#define VALID_MBXCB(p_mbxcb) \
+ ((((char *) p_mbxcb) - ((char *) mbxcb_table)) % sizeof(MBXCB) == 0 \
+ && TMIN_MBXID <= MBXID(p_mbxcb) && MBXID(p_mbxcb) <= tmax_mbxid)
+
+#define VALID_MTXCB(p_mtxcb) \
+ ((((char *) p_mtxcb) - ((char *) mtxcb_table)) % sizeof(MTXCB) == 0 \
+ && TMIN_MTXID <= MTXID(p_mtxcb) && MTXID(p_mtxcb) <= tmax_mtxid)
+
+#define VALID_MPFCB(p_mpfcb) \
+ ((((char *) p_mpfcb) - ((char *) mpfcb_table)) % sizeof(MPFCB) == 0 \
+ && TMIN_MPFID <= MPFID(p_mpfcb) && MPFID(p_mpfcb) <= tmax_mpfid)
+
+/*
+ * キューのチェックのための関数
+ *
+ * p_queueにp_entryが含まれているかを調べる.含まれていればtrue,含ま
+ * れていない場合にはfalseを返す.ダブルリンクの不整合の場合にも,
+ * falseを返す.
+ */
+static bool_t
+in_queue(QUEUE *p_queue, QUEUE *p_entry)
+{
+ QUEUE *p_current, *p_next;
+
+ p_current = p_queue->p_next;
+ if (p_current->p_prev != p_queue) {
+ return(false); /* ダブルリンクの不整合 */
+ }
+ while (p_current != p_queue) {
+ if (p_current == p_entry) {
+ return(true); /* p_entryが含まれていた */
+ }
+
+ /*
+ * キューの次の要素に進む
+ */
+ p_next = p_current->p_next;
+ if (p_next->p_prev != p_current) {
+ return(false); /* ダブルリンクの不整合 */
+ }
+ p_current = p_next;
+ }
+ return(false);
+}
+
+/*
+ * スタック上を指しているかの検査
+ */
+static bool_t
+on_stack(void *addr, const TINIB *p_tinib)
+{
+ if (p_tinib->stk <= addr
+ && addr < (void *)((char *)(p_tinib->stk) + p_tinib->stksz)) {
+ return(true);
+ }
+ return(false);
+}
+
+/*
+ * タスク毎の整合性検査
+ */
+static ER
+bit_task(ID tskid)
+{
+ TCB *p_tcb;
+ const TINIB *p_tinib;
+ uint_t tstat, tstat_wait, priority;
+ TMEVTB *p_tmevtb;
+ SEMCB *p_semcb;
+ FLGCB *p_flgcb;
+ DTQCB *p_dtqcb;
+ PDQCB *p_pdqcb;
+ MBXCB *p_mbxcb;
+ MTXCB *p_mtxcb;
+ MPFCB *p_mpfcb;
+
+ if (!(TMIN_TSKID <= (tskid) && (tskid) <= tmax_tskid)) {
+ return(E_ID);
+ }
+ p_tcb = get_tcb(tskid);
+ p_tinib = p_tcb->p_tinib;
+ tstat = p_tcb->tstat;
+ tstat_wait = (tstat & TS_WAIT_MASK);
+ priority = p_tcb->priority;
+
+ /*
+ * 初期化ブロックへのポインタの検査
+ */
+ if (p_tinib != &(tinib_table[INDEX_TSK(tskid)])) {
+ return(E_SYS_LINENO);
+ }
+
+ /*
+ * tstatの検査
+ */
+ switch (tstat & (TS_RUNNABLE | TS_WAITING | TS_SUSPENDED)) {
+ case TS_DORMANT:
+ if (tstat != TS_DORMANT) {
+ return(E_SYS_LINENO);
+ }
+ break;
+ case TS_RUNNABLE:
+ if (tstat != TS_RUNNABLE) {
+ return(E_SYS_LINENO);
+ }
+ break;
+ case TS_WAITING:
+ case (TS_WAITING | TS_SUSPENDED):
+ if (!(TS_WAIT_DLY <= tstat_wait && tstat_wait <= TS_WAIT_MTX)) {
+ return(E_SYS_LINENO);
+ }
+ if ((tstat & ~(TS_WAIT_MASK | TS_RUNNABLE | TS_WAITING | TS_SUSPENDED))
+ != 0U) {
+ return(E_SYS_LINENO);
+ }
+ break;
+ case TS_SUSPENDED:
+ if (tstat != TS_SUSPENDED) {
+ return(E_SYS_LINENO);
+ }
+ break;
+ default:
+ return(E_SYS_LINENO);
+ }
+
+ /*
+ * actqueの検査
+ */
+ if (TSTAT_DORMANT(tstat) && p_tcb->actque) {
+ return(E_SYS_LINENO);
+ }
+
+ /*
+ * タスク優先度の検査
+ */
+ if (priority >= TNUM_TPRI) {
+ return(E_SYS_LINENO);
+ }
+
+ /*
+ * texptnの検査
+ */
+ if (p_tcb->p_tinib->texrtn == NULL && p_tcb->texptn != 0U) {
+ return(E_SYS_LINENO);
+ }
+
+ /*
+ * 休止状態におけるチェック
+ */
+ if (TSTAT_DORMANT(tstat)) {
+ if (!(priority == p_tinib->ipriority)
+ && (p_tcb->wupque == false)
+ && (p_tcb->enatex == false)
+ && (p_tcb->texptn == 0U)) {
+ return(E_SYS_LINENO);
+ }
+ }
+
+ /*
+ * 実行できる状態におけるチェック
+ */
+ if (TSTAT_RUNNABLE(tstat)) {
+ if (!in_queue(&ready_queue[priority], &(p_tcb->task_queue))) {
+ return(E_SYS_LINENO);
+ }
+ }
+
+ /*
+ * 待ち状態におけるチェック
+ */
+ if (TSTAT_WAITING(tstat)) {
+ if (!on_stack(p_tcb->p_winfo, p_tinib)) {
+ return(E_SYS_LINENO);
+ }
+ p_tmevtb = p_tcb->p_winfo->p_tmevtb;
+ if (p_tmevtb != NULL) {
+ if (!on_stack(p_tmevtb, p_tinib)) {
+ return(E_SYS_LINENO);
+ }
+ /*
+ * (*p_tmevtb)の検査(未完成)
+ */
+ }
+
+ switch (tstat & TS_WAIT_MASK) {
+ case TS_WAIT_SLP:
+ if (p_tcb->wupque == true) {
+ return(E_SYS_LINENO);
+ }
+ break;
+
+ case TS_WAIT_DLY:
+ if (p_tmevtb == NULL) {
+ return(E_SYS_LINENO);
+ }
+ break;
+
+ case TS_WAIT_SEM:
+ p_semcb = ((WINFO_SEM *)(p_tcb->p_winfo))->p_semcb;
+ if (!VALID_SEMCB(p_semcb)) {
+ return(E_SYS_LINENO);
+ }
+ if (!in_queue(&(p_semcb->wait_queue), &(p_tcb->task_queue))) {
+ return(E_SYS_LINENO);
+ }
+ break;
+
+ case TS_WAIT_FLG:
+ p_flgcb = ((WINFO_FLG *)(p_tcb->p_winfo))->p_flgcb;
+ if (!VALID_FLGCB(p_flgcb)) {
+ return(E_SYS_LINENO);
+ }
+ if (!in_queue(&(p_flgcb->wait_queue), &(p_tcb->task_queue))) {
+ return(E_SYS_LINENO);
+ }
+ break;
+
+ case TS_WAIT_SDTQ:
+ p_dtqcb = ((WINFO_DTQ *)(p_tcb->p_winfo))->p_dtqcb;
+ if (!VALID_DTQCB(p_dtqcb)) {
+ return(E_SYS_LINENO);
+ }
+ if (!in_queue(&(p_dtqcb->swait_queue), &(p_tcb->task_queue))) {
+ return(E_SYS_LINENO);
+ }
+ break;
+
+ case TS_WAIT_RDTQ:
+ p_dtqcb = ((WINFO_DTQ *)(p_tcb->p_winfo))->p_dtqcb;
+ if (!VALID_DTQCB(p_dtqcb)) {
+ return(E_SYS_LINENO);
+ }
+ if (!in_queue(&(p_dtqcb->rwait_queue), &(p_tcb->task_queue))) {
+ return(E_SYS_LINENO);
+ }
+ break;
+
+ case TS_WAIT_SPDQ:
+ p_pdqcb = ((WINFO_PDQ *)(p_tcb->p_winfo))->p_pdqcb;
+ if (!VALID_PDQCB(p_pdqcb)) {
+ return(E_SYS_LINENO);
+ }
+ if (!in_queue(&(p_pdqcb->swait_queue), &(p_tcb->task_queue))) {
+ return(E_SYS_LINENO);
+ }
+ break;
+
+ case TS_WAIT_RPDQ:
+ p_pdqcb = ((WINFO_PDQ *)(p_tcb->p_winfo))->p_pdqcb;
+ if (!VALID_PDQCB(p_pdqcb)) {
+ return(E_SYS_LINENO);
+ }
+ if (!in_queue(&(p_pdqcb->rwait_queue), &(p_tcb->task_queue))) {
+ return(E_SYS_LINENO);
+ }
+ break;
+
+ case TS_WAIT_MBX:
+ p_mbxcb = ((WINFO_MBX *)(p_tcb->p_winfo))->p_mbxcb;
+ if (!VALID_MBXCB(p_mbxcb)) {
+ return(E_SYS_LINENO);
+ }
+ if (!in_queue(&(p_mbxcb->wait_queue), &(p_tcb->task_queue))) {
+ return(E_SYS_LINENO);
+ }
+ break;
+
+ case TS_WAIT_MTX:
+ p_mtxcb = ((WINFO_MTX *)(p_tcb->p_winfo))->p_mtxcb;
+ if (!VALID_MTXCB(p_mtxcb)) {
+ return(E_SYS_LINENO);
+ }
+ if (!in_queue(&(p_mtxcb->wait_queue), &(p_tcb->task_queue))) {
+ return(E_SYS_LINENO);
+ }
+ break;
+
+ case TS_WAIT_MPF:
+ p_mpfcb = ((WINFO_MPF *)(p_tcb->p_winfo))->p_mpfcb;
+ if (!VALID_MPFCB(p_mpfcb)) {
+ return(E_SYS_LINENO);
+ }
+ if (!in_queue(&(p_mpfcb->wait_queue), &(p_tcb->task_queue))) {
+ return(E_SYS_LINENO);
+ }
+ break;
+ }
+ }
+
+ /*
+ * tskctxbの検査
+ */
+ if (!TSTAT_DORMANT(tstat) && p_tcb != p_runtsk) {
+ /*
+ * ターゲット依存の検査
+ */
+#if 0
+ if (bit_tskctxb(&(p_tcb->tskctxb))) {
+ return(E_SYS_LINENO);
+ }
+#endif
+ }
+ return(E_OK);
+}
+
+/*
+ * セマフォ毎の整合性検査
+ */
+#define INDEX_SEM(semid) ((uint_t)((semid) - TMIN_SEMID))
+#define get_semcb(semid) (&(semcb_table[INDEX_SEM(semid)]))
+
+static ER
+bit_semaphore(ID semid)
+{
+ SEMCB *p_semcb;
+ const SEMINIB *p_seminib;
+ uint_t semcnt;
+ QUEUE *p_queue;
+ TCB *p_tcb;
+
+ if (!(TMIN_SEMID <= (semid) && (semid) <= tmax_semid)) {
+ return(E_ID);
+ }
+ p_semcb = get_semcb(semid);
+ p_seminib = p_semcb->p_seminib;
+ semcnt = p_semcb->semcnt;
+
+ /*
+ * 初期化ブロックへのポインタの検査
+ */
+ if (p_seminib != &(seminib_table[INDEX_SEM(semid)])) {
+ return(E_SYS_LINENO);
+ }
+
+ /*
+ * semcntの検査
+ */
+ if (semcnt > p_seminib->maxsem) {
+ return(E_SYS_LINENO);
+ }
+
+ /*
+ * wait_queueの検査
+ */
+ if (semcnt == 0) {
+ p_queue = p_semcb->wait_queue.p_next;
+ while (p_queue != &(p_semcb->wait_queue)) {
+ p_tcb = (TCB *) p_queue;
+ p_queue = p_queue->p_next;
+ if (!VALID_TCB(p_tcb)) {
+ return(E_SYS_LINENO);
+ }
+ if (p_tcb->tstat != (TS_WAITING | TS_WAIT_SEM)) {
+ return(E_SYS_LINENO);
+ }
+ if (p_semcb != ((WINFO_SEM *)(p_tcb->p_winfo))->p_semcb) {
+ return(E_SYS_LINENO);
+ }
+ }
+ }
+ else {
+ if (!queue_empty(&(p_semcb->wait_queue))) {
+ return(E_SYS_LINENO);
+ }
+ }
+ return(E_OK);
+}
+
+/*
+ * 整合性検査ルーチン本体
+ */
+ER
+bit_kernel(void)
+{
+ ID tskid;
+ ID semid;
+ ER ercd;
+
+ /*
+ * タスク毎の検査
+ */
+ for (tskid = TMIN_TSKID; tskid <= tmax_tskid; tskid++) {
+ ercd = bit_task(tskid);
+ if (ercd != E_OK) {
+ return(ercd);
+ }
+ }
+
+ /*
+ * セマフォ毎の検査
+ */
+ for (semid = TMIN_SEMID; semid <= tmax_semid; semid++) {
+ ercd = bit_semaphore(semid);
+ if (ercd != E_OK) {
+ return(ercd);
+ }
+ }
+
+ return(E_OK);
+}
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * High Reliable system Profile Kernel
+ *
+ * Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: bit_mutex.c 762 2008-03-07 23:51:41Z hiro $
+ */
+
+/*
+ * ミューテックス機能の整合性検査
+ */
+
+#include "kernel/kernel_impl.h"
+#include "kernel/task.h"
+#include "kernel/mutex.h"
+
+/*
+ * ミューテックスIDからミューテックス管理ブロックを取り出すためのマク
+ * ロ(mutex.cより)
+ */
+#define INDEX_MTX(mtxid) ((uint_t)((mtxid) - TMIN_MTXID))
+#define get_mtxcb(mtxid) (&(mtxcb_table[INDEX_MTX(mtxid)]))
+
+/*
+ * ミューテックス管理ブロック中のmutex_queueへのポインタから,ミューテッ
+ * クス管理ブロックへのポインタを取り出すためのマクロ(mutex.cより)
+ */
+#define MTXCB_QUEUE(p_queue) \
+ ((MTXCB *)(((char *) p_queue) - offsetof(MTXCB, mutex_queue)))
+
+/*
+ * ミューテックスのプロトコルを判断するマクロ(mutex.cより)
+ */
+#define MTXPROTO_MASK 0x03U
+#define MTXPROTO(p_mtxcb) ((p_mtxcb)->p_mtxinib->mtxatr & MTXPROTO_MASK)
+#define MTX_CEILING(p_mtxcb) (MTXPROTO(p_mtxcb) == TA_CEILING)
+
+/*
+ * エラーコードの定義
+ */
+#define E_SYS_LINENO ERCD(E_SYS, -(__LINE__))
+
+/*
+ * 管理ブロックのアドレスの正当性のチェック
+ */
+#define VALID_TCB(p_tcb) \
+ ((((char *) p_tcb) - ((char *) tcb_table)) % sizeof(TCB) == 0 \
+ && TMIN_TSKID <= TSKID(p_tcb) && TSKID(p_tcb) <= tmax_tskid)
+
+#define VALID_MTXCB(p_mtxcb) \
+ ((((char *) p_mtxcb) - ((char *) mtxcb_table)) % sizeof(MTXCB) == 0 \
+ && TMIN_MTXID <= MTXID(p_mtxcb) && MTXID(p_mtxcb) <= tmax_mtxid)
+
+/*
+ * キューのチェックのための関数
+ *
+ * p_queueにp_entryが含まれているかを調べる.含まれていればtrue,含ま
+ * れていない場合にはfalseを返す.ダブルリンクの不整合の場合にも,
+ * falseを返す.
+ */
+static bool_t
+in_queue(QUEUE *p_queue, QUEUE *p_entry)
+{
+ QUEUE *p_current, *p_next;
+
+ p_current = p_queue->p_next;
+ if (p_current->p_prev != p_queue) {
+ return(false); /* ダブルリンクの不整合 */
+ }
+ while (p_current != p_queue) {
+ if (p_current == p_entry) {
+ return(true); /* p_entryが含まれていた */
+ }
+
+ /*
+ * キューの次の要素に進む
+ */
+ p_next = p_current->p_next;
+ if (p_next->p_prev != p_current) {
+ return(false); /* ダブルリンクの不整合 */
+ }
+ p_current = p_next;
+ }
+ return(false);
+}
+
+/*
+ * タスク毎の検査
+ */
+static ER
+bit_mutex_task(ID tskid)
+{
+ TCB *p_tcb;
+ MTXCB *p_mtxcb;
+ QUEUE *p_queue, *p_next;
+ uint_t priority;
+
+ if (!(TMIN_TSKID <= (tskid) && (tskid) <= tmax_tskid)) {
+ return(E_ID);
+ }
+ p_tcb = get_tcb(tskid);
+ priority = p_tcb->bpriority;
+
+ /*
+ * タスクがロックしているミューテックスのキューの検査
+ */
+ p_queue = p_tcb->mutex_queue.p_next;
+ if (p_queue->p_prev != &(p_tcb->mutex_queue)) {
+ return(E_SYS_LINENO);
+ }
+ while (p_queue != &(p_tcb->mutex_queue)) {
+ p_mtxcb = MTXCB_QUEUE(p_queue);
+ if (!VALID_MTXCB(p_mtxcb)) {
+ return(E_SYS_LINENO);
+ }
+
+ /*
+ * ミューテックスをロックしているタスクのチェック
+ */
+ if (p_mtxcb->p_loctsk != p_tcb) {
+ return(E_SYS_LINENO);
+ }
+
+ /*
+ * 現在優先度の計算
+ */
+ if (MTXPROTO(p_mtxcb)) {
+ if (p_mtxcb->p_mtxinib->ceilpri < priority) {
+ priority = p_mtxcb->p_mtxinib->ceilpri;
+ }
+ }
+
+ /*
+ * キューの次の要素に進む
+ */
+ p_next = p_queue->p_next;
+ if (p_next->p_prev != p_queue) {
+ return(E_SYS_LINENO);
+ }
+ p_queue = p_next;
+ }
+
+ /*
+ * 現在優先度の検査
+ */
+ if (p_tcb->priority != p_tcb->priority) {
+ return(E_SYS_LINENO);
+ }
+
+ /*
+ * タスクが待っているミューテックスに関する検査
+ */
+ if (TSTAT_WAIT_MTX(p_tcb->tstat)) {
+ p_mtxcb = ((WINFO_MTX *)(p_tcb->p_winfo))->p_mtxcb;
+ if (!VALID_MTXCB(p_mtxcb)) {
+ return(E_SYS_LINENO);
+ }
+ if (!in_queue(&(p_mtxcb->wait_queue), &(p_tcb->task_queue))) {
+ return(E_SYS_LINENO);
+ }
+ }
+ return(E_OK);
+}
+
+/*
+ * ミューテックス毎の検査
+ */
+static ER
+bit_mutex_mutex(ID mtxid)
+{
+ MTXCB *p_mtxcb;
+ TCB *p_tcb;
+ QUEUE *p_queue, *p_next;
+ uint_t priority;
+
+ if (!(TMIN_MTXID <= (mtxid) && (mtxid) <= tmax_mtxid)) {
+ return(E_ID);
+ }
+ p_mtxcb = get_mtxcb(mtxid);
+
+ /*
+ * 初期化ブロックへのポインタの検査
+ */
+ if (p_mtxcb->p_mtxinib != &(mtxinib_table[INDEX_MTX(mtxid)])) {
+ return(E_SYS_LINENO);
+ }
+
+ /*
+ * ミューテックス待ちキューの検査
+ */
+ p_queue = p_mtxcb->wait_queue.p_next;
+ if (p_queue->p_prev != &(p_mtxcb->wait_queue)) {
+ return(E_SYS_LINENO);
+ }
+ priority = TMIN_TPRI;
+ while (p_queue != &(p_mtxcb->wait_queue)) {
+ p_tcb = (TCB *) p_queue;
+ if (!VALID_TCB(p_tcb)) {
+ return(E_SYS_LINENO);
+ }
+
+ /*
+ * キューがタスク優先度順になっているかの検査
+ */
+ if (MTXPROTO(p_mtxcb) != TA_NULL) {
+ if (p_tcb->priority < priority) {
+ return(E_SYS_LINENO);
+ }
+ }
+ priority = p_tcb->priority;
+
+ /*
+ * タスク状態の検査
+ *
+ * ミューテックス待ち状態のタスクの検査は,タスク毎の検査で行っ
+ * ているため,ここでは行わない.
+ */
+ if (!TSTAT_WAIT_MTX(p_tcb->tstat)) {
+ return(E_SYS_LINENO);
+ }
+
+ /*
+ * 優先度上限の検査
+ */
+ if (MTXPROTO(p_mtxcb) == TA_CEILING) {
+ if (p_tcb->bpriority < p_mtxcb->p_mtxinib->ceilpri) {
+ return(E_SYS_LINENO);
+ }
+ }
+
+ /*
+ * キューの次の要素に進む
+ */
+ p_next = p_queue->p_next;
+ if (p_next->p_prev != p_queue) {
+ return(E_SYS_LINENO);
+ }
+ p_queue = p_next;
+ }
+
+ /*
+ * ミューテックスをロックしているタスクの検査
+ */
+ p_tcb = p_mtxcb->p_loctsk;
+ if (p_tcb == NULL) {
+ /*
+ * ミューテックスがロックされていない時
+ */
+ if (!queue_empty(&(p_mtxcb->wait_queue))) {
+ return(E_SYS_LINENO);
+ }
+ }
+ else {
+ /*
+ * ミューテックスがロックされている時
+ *
+ * ミューテックスをロックしているタスクの検査は,タスク毎の検
+ * 査で行っているため,ここでは行わない.
+ */
+ if (!VALID_TCB(p_tcb)) {
+ return(E_SYS_LINENO);
+ }
+ if (!in_queue(&(p_tcb->mutex_queue), &(p_mtxcb->mutex_queue))) {
+ return(E_SYS_LINENO);
+ }
+
+ /*
+ * 優先度上限の検査
+ */
+ if (MTXPROTO(p_mtxcb) == TA_CEILING) {
+ if (p_tcb->bpriority < p_mtxcb->p_mtxinib->ceilpri) {
+ return(E_SYS_LINENO);
+ }
+ }
+ }
+ return(E_OK);
+}
+
+/*
+ * 整合性検査ルーチン本体
+ */
+ER
+bit_mutex(void)
+{
+ ID tskid, mtxid;
+ ER ercd;
+
+ /*
+ * タスク毎の検査
+ */
+ for (tskid = TMIN_TSKID; tskid <= tmax_tskid; tskid++) {
+ ercd = bit_mutex_task(tskid);
+ if (ercd != E_OK) {
+ return(ercd);
+ }
+ }
+
+ /*
+ * ミューテックス毎の検査
+ */
+ for (mtxid = TMIN_MTXID; mtxid <= tmax_mtxid; mtxid++) {
+ ercd = bit_mutex_mutex(mtxid);
+ if (ercd != E_OK) {
+ return(ercd);
+ }
+ }
+ return(E_OK);
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_mutex.h 495 2007-08-20 02:39:10Z hiro $
+ */
+
+/*
+ * ミューテックスのテスト(1)〜(3)
+ */
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 優先度の定義
+ */
+#define HIGH_PRIORITY 9 /* 高優先度 */
+#define MID_PRIORITY 10 /* 中優先度 */
+#define LOW_PRIORITY 11 /* 低優先度 */
+
+/*
+ * ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define STACK_SIZE 4096 /* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void task1(intptr_t exinf);
+extern void task2(intptr_t exinf);
+extern void task3(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007,2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_mutex1.c 1696 2010-01-01 16:01:25Z ertl-hiro $
+ */
+
+/*
+ * ミューテックスのテスト(1)
+ *
+ * 【テストの目的】
+ *
+ * FIFO順ミューテックスを,ロックする処理とロック解除する処理を一通り
+ * テストする.
+ *
+ * 【テスト項目】
+ *
+ * (A) ミューテックスのロック処理(loc_mtx)
+ * (A-1) ロックされていない場合には,すぐにロックできること
+ * (A-2) 多重にロックしようとすると,E_ILUSEエラーになること
+ * (A-3) ロックされている場合には,FIFO順で待ち状態になること
+ * (B) ミューテックスのロック解除処理(unl_mtx)
+ * (B-1) 他タスクがロックしているミューテックスを解放しようとすると
+ * E_ILUSEエラーになること
+ * (B-2) 待ちタスクがないと,単にロック解除すること
+ * (B-3) 待ちタスクにロックを渡すこと
+ * (B-4) 待ちタスクにロックを渡して,ディスパッチが起こること
+ * (C) ミューテックスのロック処理(ploc_mtx)
+ * (C-1) ロックされている場合には,すぐにE_TMOUTエラーになること
+ * (D) ミューテックスのロック処理(tloc_mtx)
+ * (D-1) ロックされている場合には,タイムアウト付きの待ち状態にな
+ * ること
+ * (E) おまけ
+ * (E-1) タスクを終了すると,ミューテックスをロック解除すること
+ *
+ * 【使用リソース】
+ *
+ * TASK1: 低優先度タスク,メインタスク,最初から起動
+ * TASK2: 中優先度タスク
+ * TASK3: 高優先度タスク
+ * MTX1: ミューテックス(TA_NULL属性)
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(優先度:低)==
+ * call(set_bit_func(bit_mutex))
+ * 1: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TSK_NONE)
+ * assert(rmtx.wtskid == TSK_NONE)
+ * loc_mtx(MTX1) ... (A-1)
+ * 2: loc_mtx(MTX1) -> E_ILUSE ... (A-2)
+ * 3: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TASK1)
+ * assert(rmtx.wtskid == TSK_NONE)
+ * act_tsk(TASK2)
+ * == TASK2(優先度:中)==
+ * 4: ploc_mtx(MTX1) -> E_TMOUT ... (C-1)
+ * loc_mtx(MTX1) ... (A-3)
+ * == TASK1(続き)==
+ * 5: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TASK1)
+ * assert(rmtx.wtskid == TASK2)
+ * act_tsk(TASK3)
+ * == TASK3(優先度:高)==
+ * 6: unl_mtx(MTX1) -> E_ILUSE ... (B-1)
+ * 7: loc_mtx(MTX1) ... (A-3)
+ * == TASK1(続き)==
+ * 8: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TASK1)
+ * assert(rmtx.wtskid == TASK2)
+ * dis_dsp()
+ * unl_mtx(MTX1) ... (B-3)
+ * 9: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TASK2)
+ * assert(rmtx.wtskid == TASK3)
+ * ena_dsp()
+ * == TASK2(続き)==
+ * 10: unl_mtx(MTX1) ... (B-4)
+ * == TASK3(続き)==
+ * 11: ext_tsk() -> noreturn ... (E-1)
+ * == TASK2(続き)==
+ * 12: loc_mtx(MTX1)
+ * 13: slp_tsk()
+ * == TASK1(続き)==
+ * 14: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TASK2)
+ * assert(rmtx.wtskid == TSK_NONE)
+ * tloc_mtx(MTX1, 10) -> E_TMOUT ... (D-1)
+ * 15: wup_tsk(TASK2)
+ * == TASK2(続き)==
+ * 16: unl_mtx(MTX1) ... (B-2)
+ * 17: ext_tsk() -> noreturn
+ * == TASK1(続き)==
+ * 18: END
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include "syssvc/logtask.h"
+#include "kernel_cfg.h"
+#include "test_lib.h"
+#include "test_mutex.h"
+
+extern ER bit_mutex(void);
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+ T_RMTX rmtx;
+
+ set_bit_func(bit_mutex);
+
+ check_point(1);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TSK_NONE);
+ check_assert(rmtx.wtskid == TSK_NONE);
+
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(2);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_ILUSE);
+
+ check_point(3);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TASK1);
+ check_assert(rmtx.wtskid == TSK_NONE);
+
+ ercd = act_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(5);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TASK1);
+ check_assert(rmtx.wtskid == TASK2);
+
+ ercd = act_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ check_point(8);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TASK1);
+ check_assert(rmtx.wtskid == TASK2);
+
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+
+ ercd = unl_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(9);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TASK2);
+ check_assert(rmtx.wtskid == TASK3);
+
+ ercd = ena_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(14);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TASK2);
+ check_assert(rmtx.wtskid == TSK_NONE);
+
+ ercd = tloc_mtx(MTX1, 10);
+ check_ercd(ercd, E_TMOUT);
+
+ check_point(15);
+ ercd = wup_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_finish(18);
+
+ check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(4);
+ ercd = ploc_mtx(MTX1);
+ check_ercd(ercd, E_TMOUT);
+
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(10);
+ ercd = unl_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(12);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(13);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(16);
+ ercd = unl_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(17);
+ ercd = ext_tsk();
+
+ check_point(0);
+}
+
+void
+task3(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(6);
+ ercd = unl_mtx(MTX1);
+ check_ercd(ercd, E_ILUSE);
+
+ check_point(7);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(11);
+ ercd = ext_tsk();
+
+ check_point(0);
+}
--- /dev/null
+/*
+ * @(#) $Id: test_mutex1.cfg 1696 2010-01-01 16:01:25Z ertl-hiro $
+ */
+
+/*
+ * ミューテックスのテスト(1)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+INCLUDE("syssvc/logtask.cfg");
+
+#include "test_mutex.h"
+
+CRE_TSK(TASK1, { TA_ACT, 1, task1, LOW_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task2, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK3, { TA_NULL, 3, task3, HIGH_PRIORITY, STACK_SIZE, NULL });
+CRE_MTX(MTX1, { TA_NULL });
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007,2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_mutex2.c 1696 2010-01-01 16:01:25Z ertl-hiro $
+ */
+
+/*
+ * ミューテックスのテスト(2)
+ *
+ * 【テストの目的】
+ *
+ * 優先度順ミューテックスを,ロックする処理とロック解除する処理を一通
+ * りテストする.
+ *
+ * 【テスト項目】
+ *
+ * (A) ミューテックスのロック処理(loc_mtx)
+ * (A-1) ロックされていない場合には,すぐにロックできること
+ * (A-2) 多重にロックしようとすると,E_ILUSEエラーになること
+ * (A-3) ロックされている場合には,優先度順で待ち状態になること
+ * (B) ミューテックスのロック解除処理(unl_mtx)
+ * (B-1) 他タスクがロックしているミューテックスを解放しようとすると
+ * E_ILUSEエラーになること
+ * (B-2) 待ちタスクがないと,単にロック解除すること
+ * (B-3) 待ちタスクにロックを渡すこと
+ * (B-4) 待ちタスクにロックを渡して,ディスパッチが起こること
+ * (C) ミューテックスのロック処理(ploc_mtx)
+ * (C-1) ロックされている場合には,すぐにE_TMOUTエラーになること
+ * (D) ミューテックスのロック処理(tloc_mtx)
+ * (D-1) ロックされている場合には,タイムアウト付きの待ち状態にな
+ * ること
+ * (E) おまけ
+ * (E-1) タスクを終了すると,ミューテックスをロック解除すること
+ *
+ * 【使用リソース】
+ *
+ * TASK1: 低優先度タスク,メインタスク,最初から起動
+ * TASK2: 中優先度タスク
+ * TASK3: 高優先度タスク
+ * MTX1: ミューテックス(TA_TPRI属性)
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(優先度:低)==
+ * call(set_bit_func(bit_mutex))
+ * 1: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TSK_NONE)
+ * assert(rmtx.wtskid == TSK_NONE)
+ * loc_mtx(MTX1) ... (A-1)
+ * 2: loc_mtx(MTX1) -> E_ILUSE ... (A-2)
+ * 3: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TASK1)
+ * assert(rmtx.wtskid == TSK_NONE)
+ * act_tsk(TASK2)
+ * == TASK2(優先度:中)==
+ * 4: ploc_mtx(MTX1) -> E_TMOUT ... (C-1)
+ * loc_mtx(MTX1) ... (A-3)
+ * == TASK1(続き)==
+ * 5: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TASK1)
+ * assert(rmtx.wtskid == TASK2)
+ * act_tsk(TASK3)
+ * == TASK3(優先度:高)==
+ * 6: unl_mtx(MTX1) -> E_ILUSE ... (B-1)
+ * 7: loc_mtx(MTX1) ... (A-3)
+ * == TASK1(続き)==
+ * 8: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TASK1)
+ * assert(rmtx.wtskid == TASK3)
+ * dis_dsp()
+ * unl_mtx(MTX1) ... (B-3)
+ * 9: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TASK3)
+ * assert(rmtx.wtskid == TASK2)
+ * ena_dsp()
+ * == TASK3(続き)==
+ * 10: ext_tsk() -> noreturn ... (E-1)
+ * == TASK2(続き)==
+ * 11: unl_mtx(MTX1) ... (B-4)
+ * 12: loc_mtx(MTX1)
+ * 13: slp_tsk()
+ * == TASK1(続き)==
+ * 14: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TASK2)
+ * assert(rmtx.wtskid == TSK_NONE)
+ * tloc_mtx(MTX1, 10) -> E_TMOUT ... (D-1)
+ * 15: wup_tsk(TASK2)
+ * == TASK2(続き)==
+ * 16: unl_mtx(MTX1) ... (B-2)
+ * 17: ext_tsk() -> noreturn
+ * == TASK1(続き)==
+ * 18: END
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include "syssvc/logtask.h"
+#include "kernel_cfg.h"
+#include "test_lib.h"
+#include "test_mutex.h"
+
+extern ER bit_mutex(void);
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+ T_RMTX rmtx;
+
+ set_bit_func(bit_mutex);
+
+ check_point(1);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TSK_NONE);
+ check_assert(rmtx.wtskid == TSK_NONE);
+
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(2);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_ILUSE);
+
+ check_point(3);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TASK1);
+ check_assert(rmtx.wtskid == TSK_NONE);
+
+ ercd = act_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(5);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TASK1);
+ check_assert(rmtx.wtskid == TASK2);
+
+ ercd = act_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ check_point(8);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TASK1);
+ check_assert(rmtx.wtskid == TASK3);
+
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+
+ ercd = unl_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(9);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TASK3);
+ check_assert(rmtx.wtskid == TASK2);
+
+ ercd = ena_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(14);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TASK2);
+ check_assert(rmtx.wtskid == TSK_NONE);
+
+ ercd = tloc_mtx(MTX1, 10);
+ check_ercd(ercd, E_TMOUT);
+
+ check_point(15);
+ ercd = wup_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_finish(18);
+
+ check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(4);
+ ercd = ploc_mtx(MTX1);
+ check_ercd(ercd, E_TMOUT);
+
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(11);
+ ercd = unl_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(12);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(13);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(16);
+ ercd = unl_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(17);
+ ercd = ext_tsk();
+
+ check_point(0);
+}
+
+void
+task3(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(6);
+ ercd = unl_mtx(MTX1);
+ check_ercd(ercd, E_ILUSE);
+
+ check_point(7);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(10);
+ ercd = ext_tsk();
+
+ check_point(0);
+}
--- /dev/null
+/*
+ * @(#) $Id: test_mutex2.cfg 1696 2010-01-01 16:01:25Z ertl-hiro $
+ */
+
+/*
+ * ミューテックスのテスト(2)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+INCLUDE("syssvc/logtask.cfg");
+
+#include "test_mutex.h"
+
+CRE_TSK(TASK1, { TA_ACT, 1, task1, LOW_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task2, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK3, { TA_NULL, 3, task3, HIGH_PRIORITY, STACK_SIZE, NULL });
+CRE_MTX(MTX1, { TA_TPRI });
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007,2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_mutex3.c 1696 2010-01-01 16:01:25Z ertl-hiro $
+ */
+
+/*
+ * ミューテックスのテスト(3)
+ *
+ * 【テストの目的】
+ *
+ * 優先度上限ミューテックスを,ロックする処理とロック解除する処理を一
+ * 通りテストする.ref_tskによるベース優先度と現在優先度の参照処理のテ
+ * ストも兼ねている.
+ *
+ * 【テスト項目】
+ *
+ * (A) ミューテックスのロック処理(loc_mtx)
+ * (A-1) ロックされていない場合には,すぐにロックできること
+ * (A-2) 多重にロックしようとすると,E_ILUSEエラーになること
+ * (A-3) ロックされている場合には,優先度順で待ち状態になること
+ * (B) ミューテックスのロック解除処理(unl_mtx)
+ * (B-1) 他タスクがロックしているミューテックスを解放しようとすると
+ * E_ILUSEエラーになること
+ * (B-2) 待ちタスクがないと,単にロック解除すること
+ * (B-3) 待ちタスクにロックを渡すこと
+ * (B-4) 待ちタスクにロックを渡して,ディスパッチが起こること
+ * (C) ミューテックスのロック処理(ploc_mtx)
+ * (C-1) ロックされている場合には,すぐにE_TMOUTエラーになること
+ * (D) ミューテックスのロック処理(tloc_mtx)
+ * (D-1) ロックされている場合には,タイムアウト付きの待ち状態にな
+ * ること
+ * (E) おまけ
+ * (E-1) タスクを終了すると,ミューテックスをロック解除すること
+ *
+ * 【使用リソース】
+ *
+ * TASK1: 低優先度タスク,メインタスク,最初から起動
+ * TASK2: 中優先度タスク
+ * TASK3: 高優先度タスク
+ * MTX1: ミューテックス(TA_CEILING属性,上限は高優先度)
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(優先度:低)==
+ * call(set_bit_func(bit_mutex))
+ * 1: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TSK_NONE)
+ * assert(rmtx.wtskid == TSK_NONE)
+ * loc_mtx(MTX1) ... (A-1)
+ * 2: ref_tsk(TASK1, &rtsk)
+ * assert(rtsk.tskpri == HIGH_PRIORITY)
+ * assert(rtsk.tskbpri == LOW_PRIORITY)
+ * loc_mtx(MTX1) -> E_ILUSE ... (A-2)
+ * 3: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TASK1)
+ * assert(rmtx.wtskid == TSK_NONE)
+ * act_tsk(TASK2)
+ * 4: tslp_tsk(10) -> E_TMOUT
+ * == TASK2(優先度:中)==
+ * 5: ploc_mtx(MTX1) -> E_TMOUT ... (C-1)
+ * loc_mtx(MTX1) ... (A-3)
+ * == TASK1(続き)==
+ * 6: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TASK1)
+ * assert(rmtx.wtskid == TASK2)
+ * act_tsk(TASK3)
+ * 7: tslp_tsk(10) -> E_TMOUT
+ * == TASK3(優先度:高)==
+ * 8: unl_mtx(MTX1) -> E_ILUSE ... (B-1)
+ * 9: loc_mtx(MTX1) ... (A-3)
+ * == TASK1(続き)==
+ * 10: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TASK1)
+ * assert(rmtx.wtskid == TASK3)
+ * dis_dsp()
+ * unl_mtx(MTX1) ... (B-3)
+ * 11: ref_tsk(TASK1, &rtsk)
+ * assert(rtsk.tskpri == LOW_PRIORITY)
+ * assert(rtsk.tskbpri == LOW_PRIORITY)
+ * ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TASK3)
+ * assert(rmtx.wtskid == TASK2)
+ * ena_dsp()
+ * == TASK3(続き)==
+ * 12: ext_tsk() -> noreturn ... (E-1)
+ * == TASK2(続き)==
+ * 13: ref_tsk(TASK2, &rtsk)
+ * assert(rtsk.tskpri == HIGH_PRIORITY)
+ * assert(rtsk.tskbpri == MID_PRIORITY)
+ * unl_mtx(MTX1) ... (B-4)
+ * 14: loc_mtx(MTX1)
+ * 15: slp_tsk()
+ * == TASK1(続き)==
+ * 16: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TASK2)
+ * assert(rmtx.wtskid == TSK_NONE)
+ * tloc_mtx(MTX1, 10) -> E_TMOUT ... (D-1)
+ * 17: wup_tsk(TASK2)
+ * == TASK2(続き)==
+ * 18: unl_mtx(MTX1) ... (B-2)
+ * 19: ext_tsk() -> noreturn
+ * == TASK1(続き)==
+ * 20: END
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include "syssvc/logtask.h"
+#include "kernel_cfg.h"
+#include "test_lib.h"
+#include "test_mutex.h"
+
+extern ER bit_mutex(void);
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+ T_RTSK rtsk;
+ T_RMTX rmtx;
+
+ set_bit_func(bit_mutex);
+
+ check_point(1);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TSK_NONE);
+ check_assert(rmtx.wtskid == TSK_NONE);
+
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(2);
+ ercd = ref_tsk(TASK1, &rtsk);
+ check_ercd(ercd, E_OK);
+ check_assert(rtsk.tskpri == HIGH_PRIORITY);
+ check_assert(rtsk.tskbpri == LOW_PRIORITY);
+
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_ILUSE);
+
+ check_point(3);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TASK1);
+ check_assert(rmtx.wtskid == TSK_NONE);
+
+ ercd = act_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(4);
+ ercd = tslp_tsk(10);
+ check_ercd(ercd, E_TMOUT);
+
+ check_point(6);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TASK1);
+ check_assert(rmtx.wtskid == TASK2);
+
+ ercd = act_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ check_point(7);
+ ercd = tslp_tsk(10);
+ check_ercd(ercd, E_TMOUT);
+
+ check_point(10);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TASK1);
+ check_assert(rmtx.wtskid == TASK3);
+
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+
+ ercd = unl_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(11);
+ ercd = ref_tsk(TASK1, &rtsk);
+ check_ercd(ercd, E_OK);
+ check_assert(rtsk.tskpri == LOW_PRIORITY);
+ check_assert(rtsk.tskbpri == LOW_PRIORITY);
+
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TASK3);
+ check_assert(rmtx.wtskid == TASK2);
+
+ ercd = ena_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(16);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TASK2);
+ check_assert(rmtx.wtskid == TSK_NONE);
+
+ ercd = tloc_mtx(MTX1, 10);
+ check_ercd(ercd, E_TMOUT);
+
+ check_point(17);
+ ercd = wup_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_finish(20);
+
+ check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+ ER ercd;
+ T_RTSK rtsk;
+
+ check_point(5);
+ ercd = ploc_mtx(MTX1);
+ check_ercd(ercd, E_TMOUT);
+
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(13);
+ ercd = ref_tsk(TASK2, &rtsk);
+ check_ercd(ercd, E_OK);
+ check_assert(rtsk.tskpri == HIGH_PRIORITY);
+ check_assert(rtsk.tskbpri == MID_PRIORITY);
+
+ ercd = unl_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(14);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(15);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(18);
+ ercd = unl_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(19);
+ ercd = ext_tsk();
+
+ check_point(0);
+}
+
+void
+task3(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(8);
+ ercd = unl_mtx(MTX1);
+ check_ercd(ercd, E_ILUSE);
+
+ check_point(9);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(12);
+ ercd = ext_tsk();
+
+ check_point(0);
+}
--- /dev/null
+/*
+ * @(#) $Id: test_mutex3.cfg 733 2008-01-24 08:28:59Z hiro $
+ */
+
+/*
+ * ミューテックスのテスト(3)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+INCLUDE("syssvc/logtask.cfg");
+
+#include "test_mutex.h"
+
+CRE_TSK(TASK1, { TA_ACT, 1, task1, LOW_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task2, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK3, { TA_NULL, 3, task3, HIGH_PRIORITY, STACK_SIZE, NULL });
+CRE_MTX(MTX1, { TA_CEILING, HIGH_PRIORITY });
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_mutex4.c 1696 2010-01-01 16:01:25Z ertl-hiro $
+ */
+
+/*
+ * ミューテックスのテスト(4)
+ *
+ * 【テストの目的】
+ *
+ * 優先度上限ミューテックスに対して,loc_mtxとunl_mtxに伴う優先度の変
+ * 更処理を網羅的にテストする.ただし,change_priorityと
+ * mutex_calc_priorityの内容には踏み込まない.
+ *
+ * 【テスト項目】
+ *
+ * (A) ミューテックスのロック処理(loc_mtx)に伴う優先度変更
+ * (A-1) ロックしたミューテックスの優先度上限が自タスクの現在優先
+ * 度よりも高い場合に,自タスクの優先度がその優先度上限まで
+ * 上がること.また,同じ優先度内での優先順位が最高になるこ
+ * と
+ * (A-2) ロックしたミューテックスの優先度上限が自タスクの現在優先
+ * 度と同じ場合に,自タスクの優先度が変わらないこと.また,
+ * 同じ優先度内での優先順位が変わらないこと
+ * (A-3) ロックしたミューテックスの優先度上限が自タスクの現在優先
+ * 度よりも低い場合に,自タスクの優先度が変わらないこと.ま
+ * た,同じ優先度内での優先順位が変わらないこと
+ * (B) ミューテックスのロック解除処理(unl_mtx)に伴うロック解除した
+ * タスクの優先度変更
+ * (B-1) ロック解除したミューテックスの上限優先度が自タスクの現在
+ * 優先度と同じで,ミューテックスのロック解除で優先度が下が
+ * るべき場合に,自タスクの優先度が適切に下げられること.ま
+ * た,同じ優先度内での優先順位が最高になること
+ * (B-2) ロック解除したミューテックスの上限優先度が自タスクの現在
+ * 優先度と同じで,ミューテックスのロック解除で優先度が変わ
+ * るべきでない場合に,自タスクの優先度が変わらないこと.ま
+ * た,同じ優先度内での優先順位が変わらないこと
+ * (B-3) ロック解除したミューテックスの上限優先度が自タスクの現在
+ * 優先度よりも低い場合に,自タスクの優先度が変わらないこと.
+ * また,同じ優先度内での優先順位が変わらないこと
+ * (C) ミューテックスのロック解除処理(unl_mtx)に伴いミューテックスを
+ * ロックしたタスクの優先度変更
+ * (C-1) ミューテックスの優先度上限が新たにミューテックスをロック
+ * したタスクの現在優先度よりも高い場合に,当該タスクの優先
+ * 度がその優先度上限まで上がること.また,同じ優先度内での
+ * 優先順位が最低になること
+ * (C-2) ミューテックスの優先度上限が新たにミューテックスをロック
+ * したタスクの現在優先度と同じ場合に,当該タスクの優先度が
+ * 変わらないこと.また,同じ優先度内での優先順位が最低にな
+ * ること
+ * (C-3) ミューテックスの優先度上限が新たにミューテックスをロック
+ * したタスクの現在優先度よりも低い場合に,当該タスクの優先
+ * 度が変わらないこと.また,同じ優先度内での優先順位が最低
+ * になること
+ * (D) ミューテックスのロック処理(loc_mtx)のE_ILUSEエラー
+ * (D-1) 自タスクのベース優先度が,ロックしようとしたミューテック
+ * スの上限優先度よりも高い時,E_ILUSEエラーになること
+ * (D-2) 自タスクのベース優先度が,ロックしようとしたミューテック
+ * スの上限優先度と同じかそれより低ければ,自タスクの現在優
+ * 先度がそれより高くても,E_ILUSEエラーにならないこと
+ *
+ * 【テスト項目の実現方法】
+ *
+ * (A-1)
+ * 中優先度タスク(TASK1)に,高優先度上限ミューテックス(MTX2)を
+ * ロックさせ,高優先度になることを確認する.また,実行可能状態の
+ * 高優先度タスク(TASK4)よりも,優先順位が高くなることを確認する.
+ * ディスパッチ禁止状態で実施する.
+ * (A-2)
+ * 中優先度タスク(TASK1)に,中優先度上限ミューテックス(MTX1)を
+ * ロックさせ,優先度が変わらないことを確認する.また,実行可能状
+ * 態の中優先度タスクを2つ(TASK2,TASK3)を用意しておき,優先順位
+ * が変わらないことを確認する.ディスパッチ禁止状態で実施する.
+ * (A-3)
+ * 中優先度タスク(TASK1)が高優先度上限ミューテックス(MTX2)をロッ
+ * クして高優先度になっている状態で,中優先度上限ミューテックス
+ * (MTX1)をロックさせ,優先度が変わらないことを確認する.また,
+ * 実行可能状態の高優先度タスクを2つ(TASK4,TASK5)を用意しておき,
+ * 優先順位が変わらないことを確認する.ディスパッチ禁止状態で実施
+ * する.
+ * (B-1)
+ * 中優先度タスク(TASK1)に高優先度上限ミューテックス(MTX2)のみ
+ * をロックさせている状態で,それをロック解除させ,中優先度になる
+ * ことを確認する.また,実行可能状態の中優先度タスク(TASK2)より
+ * も,優先順位が高くなることを確認する.
+ * (B-2)
+ * 中優先度タスク(TASK1)に中優先度上限ミューテックス(MTX1)のみ
+ * をロックさせている状態で,それをロック解除させ,優先度が変わら
+ * ないことを確認する.また,実行可能状態の中優先度タスクを2つ
+ * (TASK2,TASK3)を用意しておき,優先順位が変わらないことを確認
+ * する.ディスパッチ禁止状態で実施する.
+ * (B-3)
+ * 中優先度タスク(TASK1)に高優先度上限ミューテックス(MTX2)と中
+ * 優先度上限ミューテックス(MTX1)をロックさせている状態で,中優
+ * 先度上限ミューテックス(MTX1)をロック解除させ,優先度が変わら
+ * ないことを確認する.また,実行可能状態の高優先度タスクを2つ
+ * (TASK4,TASK5)を用意しておき,優先順位が変わらないことを確認
+ * する.ディスパッチ禁止状態で実施する.
+ * (C-1)
+ * 中優先度タスク(TASK1)に高優先度上限ミューテックスを2つ(MTX2,
+ * MTX3)ロックさせ,別の中優先度タスク(TASK2)がMTX2を待っている
+ * 状態で,TASK1にMTX2をロック解除させ,TASK2の優先度が高優先度に
+ * なることを確認する.また,TASK2の優先順位が,TASK1よりも低くな
+ * ることを確認する.
+ * (C-2)
+ * 中優先度タスク(TASK2)に中優先度上限ミューテックス(MTX1)をロッ
+ * クさせ,別の中優先度タスク(TASK1)がMTX1を待っている状態で,
+ * TASK2にMTX1をロック解除させ,TASK1の優先度が中優先度のまま変化
+ * しないことを確認する.また,実行可能状態の中優先度タスクをもう
+ * 1つ(TASK3)用意しておき,TASK1の優先順位がTASK3よりも低くなる
+ * ことを確認する.
+ * (C-3)
+ * 中優先度タスク(TASK1)に中優先度上限ミューテックス(MTX1)と高
+ * 優先度上限ミューテックス(MTX3)をロックさせ,別の中優先度タス
+ * ク(TASK2)が別の高優先度上限ミューテックス(MTX2)をロックして
+ * MTX1を待っている状態で,TASK1にMTX1をロック解除させ,TASK2の優
+ * 先度が高優先度のまま変化しないことを確認する.また,TASK2の優先
+ * 順位が,TASK1よりも低くなることを確認する.
+ * (D-1)
+ * 高優先度タスク(TASK4)に,中優先度上限ミューテックス(MTX1)を
+ * ロックさせ,E_ILUSEエラーになることを確認する.
+ * (D-2)
+ * 中優先度タスク(TASK1)が高優先度上限ミューテックス(MTX2)をロッ
+ * クして高優先度になっている状態で,中優先度上限ミューテックス
+ * (MTX1)をロックさせ,E_ILUSEエラーになるないことを確認する.
+ *
+ * 【使用リソース】
+ *
+ * TASK1: 中優先度タスク,メインタスク,最初から起動
+ * TASK2: 中優先度タスク
+ * TASK3: 中優先度タスク
+ * TASK4: 高優先度タスク
+ * TASK5: 高優先度タスク
+ * MTX1: ミューテックス(TA_CEILING属性,上限は中優先度)
+ * MTX2: ミューテックス(TA_CEILING属性,上限は高優先度)
+ * MTX3: ミューテックス(TA_CEILING属性,上限は高優先度)
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(優先度:中)==
+ * call(set_bit_func(bit_mutex))
+ * 1: dis_dsp()
+ * 2: act_tsk(TASK2)
+ * act_tsk(TASK4)
+ * // 高:TASK4,中:TASK1→TASK2
+ * 3: ploc_mtx(MTX2) ... (A-1)
+ * // 高:TASK1→TASK4,中:TASK2,MTX2:TASK1
+ * get_pri(TSK_SELF, &tskpri)
+ * assert(tskpri == HIGH_PRIORITY)
+ * 4: ena_dsp()
+ * 5: unl_mtx(MTX2) ... (B-1)
+ * // 高:TASK4,中:TASK1→TASK2
+ * == TASK4(優先度:高)==
+ * 6: loc_mtx(MTX1) -> E_ILUSE ... (D-1)
+ * 7: slp_tsk()
+ * // 中:TASK1→TASK2
+ * == TASK1(続き)==
+ * 8: get_pri(TSK_SELF, &tskpri)
+ * assert(tskpri == MID_PRIORITY)
+ *
+ * 9: dis_dsp()
+ * 10: rot_rdq(MID_PRIORITY)
+ * // 中:TASK2→TASK1
+ * 11: act_tsk(TASK3)
+ * // 中:TASK2→TASK1→TASK3
+ * 12: ploc_mtx(MTX1) ... (A-2)
+ * // 中:TASK2→TASK1→TASK3,MTX1:TASK1
+ * get_pri(TSK_SELF, &tskpri)
+ * assert(tskpri == MID_PRIORITY)
+ * 13: ena_dsp()
+ * == TASK2(優先度:中)==
+ * 14: slp_tsk()
+ * // 中:TASK1→TASK3,MTX1:TASK1
+ * == TASK1(続き)==
+ * 15: slp_tsk()
+ * // 中:TASK3,MTX1:TASK1
+ * == TASK3(優先度:中)==
+ * 16: wup_tsk(TASK1)
+ * // 中:TASK3→TASK1,MTX1:TASK1
+ * 17: slp_tsk()
+ * // 中:TASK1,MTX1:TASK1
+ *
+ * == TASK1(続き)==
+ * 18: wup_tsk(TASK2)
+ * // 中:TASK1→TASK2,MTX1:TASK1
+ * 19: dis_dsp()
+ * 20: rot_rdq(MID_PRIORITY)
+ * // 中:TASK2→TASK1,MTX1:TASK1
+ * 21: wup_tsk(TASK3)
+ * // 中:TASK2→TASK1→TASK3,MTX1:TASK1
+ * 22: unl_mtx(MTX1) ... (B-2)
+ * // 中:TASK2→TASK1→TASK3
+ * get_pri(TSK_SELF, &tskpri)
+ * assert(tskpri == MID_PRIORITY)
+ * 23: ena_dsp()
+ * == TASK2(優先度:中)==
+ * 24: slp_tsk()
+ * // 中:TASK1→TASK3
+ * == TASK1(続き)==
+ * 25: slp_tsk()
+ * // 中:TASK3
+ * == TASK3(優先度:中)==
+ * 26: wup_tsk(TASK1)
+ * // 中:TASK3→TASK1
+ * 27: slp_tsk()
+ * // 中:TASK1
+ *
+ * == TASK1(続き)==
+ * 28: dis_dsp()
+ * 29: wup_tsk(TASK4)
+ * // 高:TASK4,中:TASK1
+ * 30: ploc_mtx(MTX2)
+ * // 高:TASK1→TASK4,MTX2:TASK1
+ * 31: rot_rdq(HIGH_PRIORITY)
+ * // 高:TASK4→TASK1,MTX2:TASK1
+ * 32: act_tsk(TASK5)
+ * // 高:TASK4→TASK1→TASK5,MTX2:TASK1
+ * 33: ploc_mtx(MTX1) ... (A-3)(D-2)
+ * // 高:TASK4→TASK1→TASK5,MTX2:TASK1,MTX1:TASK1
+ * get_pri(TSK_SELF, &tskpri)
+ * assert(tskpri == HIGH_PRIORITY)
+ * 34: ena_dsp()
+ * == TASK4(続き)==
+ * 35: slp_tsk()
+ * // 高:TASK1→TASK5,MTX2:TASK1,MTX1:TASK1
+ * == TASK1(続き)==
+ * 36: slp_tsk()
+ * // 高:TASK5,MTX2:TASK1,MTX1:TASK1
+ * == TASK5(優先度:高)==
+ * 37: wup_tsk(TASK1)
+ * // 高:TASK5→TASK1,MTX2:TASK1,MTX1:TASK1
+ * 38: slp_tsk()
+ * // 高:TASK1,MTX2:TASK1,MTX1:TASK1
+ *
+ * == TASK1(続き)==
+ * 39: dis_dsp()
+ * 40: wup_tsk(TASK4)
+ * // 高:TASK1→TASK4,MTX2:TASK1,MTX1:TASK1
+ * 41: rot_rdq(HIGH_PRIORITY)
+ * // 高:TASK4→TASK1,MTX2:TASK1,MTX1:TASK1
+ * 42: wup_tsk(TASK5)
+ * // 高:TASK4→TASK1→TASK5,MTX2:TASK1,MTX1:TASK1
+ * 43: unl_mtx(MTX1) ... (B-3)
+ * // 高:TASK4→TASK1→TASK5,MTX2:TASK1
+ * get_pri(TSK_SELF, &tskpri)
+ * assert(tskpri == HIGH_PRIORITY)
+ * 44: ena_dsp()
+ * == TASK4(続き)==
+ * 45: slp_tsk()
+ * // 高:TASK1→TASK5,MTX2:TASK1
+ * == TASK1(続き)==
+ * 46: slp_tsk()
+ * // 高:TASK5,MTX2:TASK1
+ * == TASK5(続き)==
+ * 47: wup_tsk(TASK1)
+ * // 高:TASK5→TASK1,MTX2:TASK1
+ * 48: slp_tsk()
+ * // 高:TASK1,MTX2:TASK1
+ *
+ * == TASK1(続き)==
+ * 49: wup_tsk(TASK2)
+ * wup_tsk(TASK3)
+ * slp_tsk()
+ * // 中:TASK2→TASK3,MTX2:TASK1
+ * == TASK2(続き)==
+ * 50: loc_mtx(MTX2)
+ * // 中:TASK3,MTX2:TASK1→TASK2
+ * == TASK3(続き)==
+ * 51: wup_tsk(TASK1)
+ * // 高:TASK1,中:TASK3,MTX2:TASK1→TASK2
+ * == TASK1(続き)==
+ * 52: loc_mtx(MTX3)
+ * // 高:TASK1,中:TASK3,MTX2:TASK1→TASK2,MTX3:TASK1
+ * 53: unl_mtx(MTX2) ... (C-1)
+ * // 高:TASK1→TASK2,中:TASK3,MTX2:TASK2,MTX3:TASK1
+ * get_pri(TASK2, &tskpri)
+ * assert(tskpri == HIGH_PRIORITY)
+ * 54: loc_mtx(MTX1)
+ * // 高:TASK1→TASK2,中:TASK3,MTX1:TASK1,MTX2:TASK2,MTX3:TASK1
+ * 55: slp_tsk()
+ * // 高:TASK2,中:TASK3,MTX1:TASK1,MTX2:TASK2,MTX3:TASK1
+ *
+ * == TASK2(続き)==
+ * 56: wup_tsk(TASK1)
+ * // 高:TASK2→TASK1,中:TASK3,MTX1:TASK1,MTX2:TASK2,MTX3:TASK1
+ * 57: loc_mtx(MTX1)
+ * // 高:TASK1,中:TASK3,MTX1:TASK1→TASK2,MTX2:TASK2,MTX3:TASK1
+ * == TASK1(続き)==
+ * 58: unl_mtx(MTX1) ... (C-3)
+ * // 高:TASK1→TASK2,中:TASK3,MTX1:TASK2,MTX2:TASK2,MTX3:TASK1
+ * get_pri(TASK2, &tskpri)
+ * assert(tskpri == HIGH_PRIORITY)
+ * 59: unl_mtx(MTX3)
+ * // 高:TASK2,中:TASK1→TASK3,MTX1:TASK2,MTX2:TASK2
+ * == TASK2(続き)==
+ * 60: unl_mtx(MTX2)
+ * // 中:TASK2→TASK1→TASK3,MTX1:TASK2
+ *
+ * 61: rot_rdq(MID_PRIORITY)
+ * // 中:TASK1→TASK3→TASK2,MTX1:TASK2
+ * == TASK1(続き)==
+ * 62: loc_mtx(MTX1)
+ * // 中:TASK3→TASK2,MTX1:TASK2→TASK1
+ * == TASK3(続き)==
+ * 63: rot_rdq(MID_PRIORITY)
+ * // 中:TASK2→TASK3,MTX1:TASK2→TASK1
+ * == TASK2(続き)==
+ * 64: unl_mtx(MTX1) ... (C-2)
+ * // 中:TASK2→TASK3→TASK1,MTX1:TASK1
+ * get_pri(TASK1, &tskpri)
+ * assert(tskpri == MID_PRIORITY)
+ * == TASK2(続き)==
+ * 65: ext_tsk() -> noreturn
+ * // 中:TASK3→TASK1,MTX1:TASK1
+ * == TASK3(続き)==
+ * 66: ext_tsk() -> noreturn
+ * // 中:TASK1,MTX1:TASK1
+ * == TASK1(続き)==
+ * 67: END
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include "syssvc/logtask.h"
+#include "kernel_cfg.h"
+#include "test_lib.h"
+#include "test_mutex4.h"
+
+extern ER bit_mutex(void);
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+ PRI tskpri;
+
+ set_bit_func(bit_mutex);
+
+ check_point(1);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(2);
+ ercd = act_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ ercd = act_tsk(TASK4);
+ check_ercd(ercd, E_OK);
+
+ check_point(3);
+ ercd = ploc_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ ercd = get_pri(TSK_SELF, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == HIGH_PRIORITY);
+
+ check_point(4);
+ ercd = ena_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(5);
+ ercd = unl_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(8);
+ ercd = get_pri(TSK_SELF, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == MID_PRIORITY);
+
+ check_point(9);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(10);
+ ercd = rot_rdq(MID_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ check_point(11);
+ ercd = act_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ check_point(12);
+ ercd = ploc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ ercd = get_pri(TSK_SELF, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == MID_PRIORITY);
+
+ check_point(13);
+ ercd = ena_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(15);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(18);
+ ercd = wup_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(19);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(20);
+ ercd = rot_rdq(MID_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ check_point(21);
+ ercd = wup_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ check_point(22);
+ ercd = unl_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ ercd = get_pri(TSK_SELF, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == MID_PRIORITY);
+
+ check_point(23);
+ ercd = ena_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(25);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(28);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(29);
+ ercd = wup_tsk(TASK4);
+ check_ercd(ercd, E_OK);
+
+ check_point(30);
+ ercd = ploc_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(31);
+ ercd = rot_rdq(HIGH_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ check_point(32);
+ ercd = act_tsk(TASK5);
+ check_ercd(ercd, E_OK);
+
+ check_point(33);
+ ercd = ploc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ ercd = get_pri(TSK_SELF, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == HIGH_PRIORITY);
+
+ check_point(34);
+ ercd = ena_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(36);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(39);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(40);
+ ercd = wup_tsk(TASK4);
+ check_ercd(ercd, E_OK);
+
+ check_point(41);
+ ercd = rot_rdq(HIGH_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ check_point(42);
+ ercd = wup_tsk(TASK5);
+ check_ercd(ercd, E_OK);
+
+ check_point(43);
+ ercd = unl_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ ercd = get_pri(TSK_SELF, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == HIGH_PRIORITY);
+
+ check_point(44);
+ ercd = ena_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(46);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(49);
+ ercd = wup_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ ercd = wup_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(52);
+ ercd = loc_mtx(MTX3);
+ check_ercd(ercd, E_OK);
+
+ check_point(53);
+ ercd = unl_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ ercd = get_pri(TASK2, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == HIGH_PRIORITY);
+
+ check_point(54);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(55);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(58);
+ ercd = unl_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ ercd = get_pri(TASK2, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == HIGH_PRIORITY);
+
+ check_point(59);
+ ercd = unl_mtx(MTX3);
+ check_ercd(ercd, E_OK);
+
+ check_point(62);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_finish(67);
+
+ check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+ ER ercd;
+ PRI tskpri;
+
+ check_point(14);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(24);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(50);
+ ercd = loc_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(56);
+ ercd = wup_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(57);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(60);
+ ercd = unl_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(61);
+ ercd = rot_rdq(MID_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ check_point(64);
+ ercd = unl_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ ercd = get_pri(TASK1, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == MID_PRIORITY);
+
+ check_point(65);
+ ercd = ext_tsk();
+
+ check_point(0);
+}
+
+void
+task3(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(16);
+ ercd = wup_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(17);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(26);
+ ercd = wup_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(27);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(51);
+ ercd = wup_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(63);
+ ercd = rot_rdq(MID_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ check_point(66);
+ ercd = ext_tsk();
+
+ check_point(0);
+}
+
+void
+task4(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(6);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_ILUSE);
+
+ check_point(7);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(35);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(45);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(0);
+}
+
+void
+task5(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(37);
+ ercd = wup_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(38);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(47);
+ ercd = wup_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(48);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(0);
+}
--- /dev/null
+/*
+ * @(#) $Id: test_mutex4.cfg 1565 2009-05-24 14:34:47Z ertl-hiro $
+ */
+
+/*
+ * ミューテックスのテスト(4)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+INCLUDE("syssvc/logtask.cfg");
+
+#include "test_mutex4.h"
+
+CRE_TSK(TASK1, { TA_ACT, 1, task1, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task2, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK3, { TA_NULL, 3, task3, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK4, { TA_NULL, 4, task4, HIGH_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK5, { TA_NULL, 5, task5, HIGH_PRIORITY, STACK_SIZE, NULL });
+CRE_MTX(MTX1, { TA_CEILING, MID_PRIORITY });
+CRE_MTX(MTX2, { TA_CEILING, HIGH_PRIORITY });
+CRE_MTX(MTX3, { TA_CEILING, HIGH_PRIORITY });
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_mutex4.h 1696 2010-01-01 16:01:25Z ertl-hiro $
+ */
+
+/*
+ * ミューテックスのテスト(4)
+ */
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 優先度の定義
+ */
+#define HIGH_PRIORITY 9 /* 高優先度 */
+#define MID_PRIORITY 10 /* 中優先度 */
+#define LOW_PRIORITY 11 /* 低優先度 */
+
+/*
+ * ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define STACK_SIZE 4096 /* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void task1(intptr_t exinf);
+extern void task2(intptr_t exinf);
+extern void task3(intptr_t exinf);
+extern void task4(intptr_t exinf);
+extern void task5(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_mutex5.c 1696 2010-01-01 16:01:25Z ertl-hiro $
+ */
+
+/*
+ * ミューテックスのテスト(5)
+ *
+ * 【テストの目的】
+ *
+ * 優先度上限ミューテックスに対して,ミューテックスの再初期化処理を網
+ * 羅的にテストする.ただし,change_priorityとmutex_calc_priorityの内
+ * 容には踏み込まない.
+ *
+ * 【テスト項目】
+ *
+ * (A) ミューテックスの初期化(ini_mtx)に伴うミューテックスをロックし
+ * ていたタスク(実行できる状態)の優先度変更
+ * (A-1) 初期化したミューテックスの上限優先度が,ミューテックスを
+ * ロックしていたタスク(実行できる状態)の現在優先度と同じ
+ * で,ミューテックスのロック解除で優先度が下がるべき場合に,
+ * 当該タスクの優先度が適切に下げられること.また,同じ優先
+ * 度内での優先順位が最高になること
+ * (A-2) 初期化したミューテックスの上限優先度が,ミューテックスを
+ * ロックしていたタスク(実行できる状態)の現在優先度と同じ
+ * で,ミューテックスのロック解除で優先度が変わるべきでない
+ * 場合に,当該タスクの優先度が変わらないこと.また,同じ優
+ * 先度内での優先順位が変わらないこと
+ * (A-3) 初期化したミューテックスの上限優先度が,ミューテックスを
+ * ロックしていたタスク(実行できる状態)の現在優先度よりも
+ * 低い場合に,当該タスクの優先度が変わらないこと.また,同
+ * じ優先度内での優先順位が変わらないこと
+ * (A-4) (A-1)の結果,タスクディスパッチが起こること.
+ * (B) ミューテックスの初期化(ini_mtx)に伴うミューテックスをロックし
+ * ていたタスク(待ち状態)の優先度変更
+ * (B-1) 初期化したミューテックスの上限優先度が,ミューテックスを
+ * ロックしていたタスク(待ち状態)の現在優先度と同じで,
+ * ミューテックスのロック解除で優先度が下がるべき場合に,当
+ * 該タスクの優先度が適切に下げられること.また,同じ優先度
+ * 内での順序が最後になること
+ * (B-2) 初期化したミューテックスの上限優先度が,ミューテックスを
+ * ロックしていたタスク(待ち状態)の現在優先度と同じで,
+ * ミューテックスのロック解除で優先度が変わるべきでない場合
+ * に,当該タスクの優先度が変わらないこと.また,同じ優先度
+ * 内での順序が変わらないこと
+ * (B-3) 初期化したミューテックスの上限優先度が,ミューテックスを
+ * ロックしていたタスク(待ち状態)の現在優先度よりも低い場
+ * 合に,当該タスクの優先度が変わらないこと.また,同じ優先
+ * 度内での順序が変わらないこと
+ * (C) ミューテックスの初期化(ini_mtx)に伴うミューテックスを待ってい
+ * たタスクの状態変化
+ * (C-1) ミューテックスを待っていたタスクが待ち解除されること.
+ * (C-2) (C-1)の結果,タスクディスパッチが起こること.
+ *
+ * 【テスト項目の実現方法】
+ *
+ * (A-1)
+ * 低優先度タスク(TASK1)が,中優先度上限ミューテックス(MTX1)を
+ * ロックした状態で,高優先度タスク(TASK5)からMTX1を再初期化し,
+ * TASK1の優先度が低優先度に下がることを確認する.また,実行可能状
+ * 態の低優先度タスク(TASK2)よりも,優先順位が高くなることを確認
+ * する.
+ * (A-2)
+ * 低優先度タスク(TASK1)が,中優先度上限ミューテックスを2つ
+ * (MTX1,MTX2)をロックした状態で,高優先度タスク(TASK5)から
+ * MTX1を再初期化し,TASK1の優先度が変化しないことを確認する.また,
+ * 実行可能状態の中優先度タスクを2つ(TASK3,TASK4)を用意しておき,
+ * 優先順位が変わらないことを確認する.
+ * (A-3)
+ * 低優先度タスク(TASK1)が,中優先度上限ミューテックス(MTX2)と
+ * 低優先度上限ミューテックス(MTX3)をロックした状態で,高優先度
+ * タスク(TASK5)からMTX3を再初期化し,TASK1の優先度が変化しない
+ * ことを確認する.また,実行可能状態の中優先度タスクを2つ(TASK3,
+ * TASK4)を用意しておき,優先順位が変わらないことを確認する.
+ * (A-4)
+ * 低優先度タスク(TASK1)が,中優先度上限ミューテックス(MTX2)を
+ * ロックした状態で,TASK1からMTX2を再初期化し,TASK1の優先度が低
+ * 優先度に下がり,実行可能状態の中優先度タスク(TASK4)に切り換わ
+ * ることを確認する.また,実行可能状態の低優先度タスク(TASK2)よ
+ * りも,優先順位が高くなることを確認する.
+ * (B-1)
+ * 低優先度タスク(TASK1)が,中優先度上限ミューテックス(MTX1)を
+ * ロックした状態で,別のミューテックス(MTX4)待ち状態とし,高優
+ * 先度タスク(TASK5)からMTX1を再初期化し,TASK1の優先度が低優先
+ * 度に下がることを確認する.また,MTX4待ち状態の低優先度タスク
+ * (TASK2)よりも,待ち行列中での順序が後になることを確認する.
+ * (B-2)
+ * 低優先度タスク(TASK1)が,中優先度上限ミューテックスを2つ
+ * (MTX1,MTX2)をロックした状態で,別のミューテックス(MTX4)待
+ * ち状態とし,高優先度タスク(TASK5)からMTX1を再初期化し,TASK1
+ * の優先度が変化しないことを確認する.また,MTX4待ち状態の中優先
+ * 度タスクを2つ(TASK3,TASK4)を用意しておき,待ち行列中での順序
+ * が変わらないことを確認する.
+ * (B-3)
+ * 低優先度タスク(TASK1)が,中優先度上限ミューテックス(MTX2)と
+ * 低優先度上限ミューテックス(MTX3)をロックした状態で,別のミュー
+ * テックス(MTX4)待ち状態とし,高優先度タスク(TASK5)からMTX3を
+ * 再初期化し,TASK1の優先度が変化しないことを確認する.また,
+ * MTX4待ち状態の中優先度タスクを2つ(TASK3,TASK4)を用意しておき,
+ * 待ち行列中での順序が変わらないことを確認する.
+ * (C-1)
+ * 低優先度タスク(TASK1)が中優先度上限ミューテックス(MTX1)をロッ
+ * クし,中優先度タスク(TASK3)がMTX1を待っている状態で,高優先度
+ * タスク(TASK5)からMTX1を再初期化し,TASK3が待ち解除されること
+ * を確認する.また,実行可能状態の中優先度タスク(TASK4)よりも,
+ * TASK3の方が優先順位が低くなることを確認する.
+ * (C-2)
+ * 低優先度タスク(TASK1)が中優先度上限ミューテックス(MTX1)をロッ
+ * クし,中優先度タスク(TASK3)がMTX1を待ち,TASK1を起床待ち状態
+ * とした状態で,別の低優先度タスク(TASK2)からMTX1を再初期化し,
+ * TASK3が待ち解除され,TASK3に切り換わることを確認する.
+ *
+ * 【使用リソース】
+ *
+ * TASK1: 低優先度タスク,メインタスク,最初から起動
+ * TASK2: 低優先度タスク
+ * TASK3: 中優先度タスク
+ * TASK4: 中優先度タスク
+ * TASK5: 高優先度タスク
+ * MTX1: ミューテックス(TA_CEILING属性,上限は中優先度)
+ * MTX2: ミューテックス(TA_CEILING属性,上限は中優先度)
+ * MTX3: ミューテックス(TA_CEILING属性,上限は低優先度)
+ * MTX4: ミューテックス(TA_CEILING属性,上限は高優先度)
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(優先度:低)==
+ * call(set_bit_func(bit_mutex))
+ * 1: loc_mtx(MTX1)
+ * 2: act_tsk(TASK2)
+ * 3: act_tsk(TASK5)
+ * // 高:TASK5,中:TASK1,低:TASK2,MTX1:TASK1
+ * == TASK5(優先度:高)==
+ * 4: ini_mtx(MTX1) ... (A-1)
+ * // 高:TASK5,低:TASK1→TASK2
+ * get_pri(TASK1, &tskpri)
+ * assert(tskpri == LOW_PRIORITY)
+ * 5: slp_tsk()
+ * // 低:TASK1→TASK2
+ *
+ * == TASK1(続き)==
+ * 6: sus_tsk(TASK2)
+ * 7: loc_mtx(MTX1)
+ * loc_mtx(MTX2)
+ * 8: act_tsk(TASK3)
+ * // 中:TASK1→TASK3,MTX1:TASK1,MTX2:TASK1
+ * 9: dis_dsp()
+ * 10: rot_rdq(MID_PRIORITY)
+ * // 中:TASK3→TASK1,MTX1:TASK1,MTX2:TASK1
+ * 11: act_tsk(TASK4)
+ * // 中:TASK3→TASK1→TASK4,MTX1:TASK1,MTX2:TASK1
+ * 12: wup_tsk(TASK5)
+ * // 高:TASK5,中:TASK3→TASK1→TASK4,MTX1:TASK1,MTX2:TASK1
+ * 13: ena_dsp()
+ * == TASK5(続き)==
+ * 14: ini_mtx(MTX1) ... (A-2)
+ * // 高:TASK5,中:TASK3→TASK1→TASK4,MTX2:TASK1
+ * get_pri(TASK1, &tskpri)
+ * assert(tskpri == MID_PRIORITY)
+ * 15: slp_tsk()
+ * // 中:TASK3→TASK1→TASK4,MTX2:TASK1
+ * == TASK3(優先度:中)==
+ * 16: slp_tsk()
+ * // 中:TASK1→TASK4,MTX2:TASK1
+ * == TASK1(続き)==
+ * 17: slp_tsk()
+ * // 中:TASK4,MTX2:TASK1
+ * == TASK4(優先度:中)==
+ * 18: wup_tsk(TASK1)
+ * // 中:TASK4→TASK1,MTX2:TASK1
+ * 19: slp_tsk()
+ * // 中:TASK1,MTX2:TASK1
+ *
+ * == TASK1(続き)==
+ * 20: loc_mtx(MTX3)
+ * // 中:TASK1,MTX2:TASK1,MTX3:TASK1
+ * 21: wup_tsk(TASK3)
+ * // 中:TASK1→TASK3,MTX2:TASK1,MTX3:TASK1
+ * 22: dis_dsp()
+ * 23: rot_rdq(MID_PRIORITY)
+ * // 中:TASK3→TASK1,MTX2:TASK1,MTX3:TASK1
+ * 24: wup_tsk(TASK4)
+ * // 中:TASK3→TASK1→TASK4,MTX2:TASK1,MTX3:TASK1
+ * 25: wup_tsk(TASK5)
+ * // 高:TASK5,中:TASK3→TASK1→TASK4,MTX2:TASK1,MTX3:TASK1
+ * 26: ena_dsp()
+ * == TASK5(続き)==
+ * 27: ini_mtx(MTX3) ... (A-3)
+ * // 高:TASK5,中:TASK3→TASK1→TASK4,MTX2:TASK1
+ * get_pri(TASK1, &tskpri)
+ * assert(tskpri == MID_PRIORITY)
+ * 28: slp_tsk()
+ * // 中:TASK3→TASK1→TASK4,MTX2:TASK1
+ * == TASK3(続き)==
+ * 29: slp_tsk()
+ * // 中:TASK1→TASK4,MTX2:TASK1
+ *
+ * == TASK1(続き)==
+ * 30: slp_tsk()
+ * // 中:TASK4,MTX2:TASK1
+ * == TASK4(続き)==
+ * 31: wup_tsk(TASK1)
+ * // 中:TASK4→TASK1,MTX2:TASK1
+ * 32: rot_rdq(MID_PRIORITY)
+ * // 中:TASK1→TASK4,MTX2:TASK1
+ * == TASK1(続き)==
+ * 33: rsm_tsk(TASK2)
+ * // 中:TASK1→TASK4,低:TASK2,MTX2:TASK1
+ * 34: ini_mtx(MTX2) ... (A-4)
+ * // 中:TASK4,低:TASK1→TASK2
+ * == TASK4(続き)==
+ * 35: get_pri(TASK1, &tskpri)
+ * assert(tskpri == LOW_PRIORITY)
+ * 36: slp_tsk()
+ * // 低:TASK1→TASK2
+ *
+ * == TASK1(続き)==
+ * 37: wup_tsk(TASK5)
+ * == TASK5(続き)==
+ * 38: loc_mtx(MTX4)
+ * 39: tslp_tsk(10) -> E_TMOUT
+ * // 低:TASK1→TASK2,MTX4:TASK5
+ * == TASK1(続き)==
+ * 40: loc_mtx(MTX1)
+ * // 中:TASK1,低:TASK2,MTX1:TASK1,MTX4:TASK5
+ * 41: loc_mtx(MTX4)
+ * // 低:TASK2,MTX1:TASK1,MTX4:TASK5→TASK1
+ * == TASK2(優先度:低)==
+ * 42: loc_mtx(MTX4)
+ * // MTX1:TASK1,MTX4:TASK5→TASK1→TASK2
+ * // タイムアウト待ち
+ * // 高:TASK5,MTX1:TASK1,MTX4:TASK5→TASK1→TASK2
+ * == TASK5(続き)==
+ * 43: ini_mtx(MTX1) ... (B-1)
+ * // 高:TASK5,MTX4:TASK5→TASK2→TASK1
+ * get_pri(TASK1, &tskpri)
+ * assert(tskpri == LOW_PRIORITY)
+ * 44: unl_mtx(MTX4)
+ * // 高:TASK5→TASK2,MTX4:TASK2→TASK1
+ * 45: slp_tsk()
+ * // 高:TASK2,MTX4:TASK2→TASK1
+ * == TASK2(続き)==
+ * 46: unl_mtx(MTX4)
+ * // 高:TASK1,低:TASK2,MTX4:TASK1
+ * == TASK1(続き)==
+ * 47: unl_mtx(MTX4)
+ * // 低:TASK1→TASK2
+ *
+ * 48: wup_tsk(TASK5)
+ * == TASK5(続き)==
+ * 49: loc_mtx(MTX4)
+ * 50: slp_tsk()
+ * // 低:TASK1→TASK2,MTX4:TASK5
+ * == TASK1(続き)==
+ * 51: wup_tsk(TASK3)
+ * // 中:TASK3,低:TASK1→TASK2,MTX4:TASK5
+ * == TASK3(続き)==
+ * 52: loc_mtx(MTX4)
+ * // 低:TASK1→TASK2,MTX4:TASK5→TASK3
+ * == TASK1(続き)==
+ * 53: loc_mtx(MTX1)
+ * loc_mtx(MTX2)
+ * // 中:TASK1,低:TASK2,MTX1:TASK1,MTX2:TASK1,MTX4:TASK5→TASK3
+ * 54: loc_mtx(MTX4)
+ * // 低:TASK2,MTX1:TASK1,MTX2:TASK1,MTX4:TASK5→TASK3→TASK1
+ * == TASK2(続き)==
+ * 55: wup_tsk(TASK4)
+ * == TASK4(続き)==
+ * 56: loc_mtx(MTX4)
+ * // 低:TASK2,MTX1:TASK1,MTX2:TASK1,
+ * // MTX4:TASK5→TASK3→TASK1→TASK4
+ * == TASK2(続き)==
+ * 57: wup_tsk(TASK5)
+ * // 高:TASK5,低:TASK2,MTX1:TASK1,MTX2:TASK1,
+ * // MTX4:TASK5→TASK3→TASK1→TASK4
+ * == TASK5(続き)==
+ * 58: ini_mtx(MTX1) ... (B-2)
+ * // 高:TASK5,低:TASK2,MTX2:TASK1,MTX4:TASK5→TASK3→TASK1→TASK4
+ * get_pri(TASK1, &tskpri)
+ * assert(tskpri == MID_PRIORITY)
+ * 59: unl_mtx(MTX4)
+ * // 高:TASK5→TASK3,低:TASK2,MTX2:TASK1,MTX4:TASK3→TASK1→TASK4
+ * 60: slp_tsk()
+ * // 高:TASK3,低:TASK2,MTX2:TASK1,MTX4:TASK3→TASK1→TASK4
+ * == TASK3(続き)==
+ * 61: unl_mtx(MTX4)
+ * // 高:TASK1,中:TASK3,低:TASK2,MTX2:TASK1,MTX4:TASK1→TASK4
+ * == TASK1(続き)==
+ * 62: unl_mtx(MTX4)
+ * // 高:TASK4,中:TASK1→TASK3,低:TASK2,MTX2:TASK1,MTX4:TASK4
+ * == TASK4(続き)==
+ * 63: unl_mtx(MTX4)
+ * // 中:TASK4→TASK1→TASK3,低:TASK2,MTX2:TASK1
+ * 64: slp_tsk()
+ * // 中:TASK1→TASK3,低:TASK2,MTX2:TASK1
+ * == TASK1(続き)==
+ * 65: slp_tsk()
+ * // 中:TASK3,低:TASK2,MTX2:TASK1
+ * == TASK3(続き)==
+ * 66: slp_tsk()
+ * // 低:TASK2,MTX2:TASK1
+ *
+ * == TASK2(続き)==
+ * 67: wup_tsk(TASK5)
+ * == TASK5(続き)==
+ * 68: loc_mtx(MTX4)
+ * 69: slp_tsk()
+ * // 低:TASK2,MTX4:TASK5
+ * == TASK2(続き)==
+ * 70: wup_tsk(TASK3)
+ * == TASK3(続き)==
+ * 71: loc_mtx(MTX4)
+ * // 低:TASK2,MTX4:TASK5→TASK3
+ * == TASK2(続き)==
+ * 72: wup_tsk(TASK1)
+ * // 中:TASK1,低:TASK2,MTX4:TASK5
+ * == TASK1(続き)==
+ * 73: loc_mtx(MTX3)
+ * // 中:TASK1,低:TASK2,MTX2:TASK1,MTX3:TASK1,MTX4:TASK5→TASK3
+ * 74: loc_mtx(MTX4)
+ * // 低:TASK2,MTX2:TASK1,MTX3:TASK1,MTX4:TASK5→TASK3→TASK1
+ * == TASK2(続き)==
+ * 75: wup_tsk(TASK4)
+ * == TASK4(続き)==
+ * 76: loc_mtx(MTX4)
+ * // 低:TASK2,MTX2:TASK1,MTX3:TASK1,
+ * // MTX4:TASK5→TASK3→TASK1→TASK4
+ * == TASK2(続き)==
+ * 77: wup_tsk(TASK5)
+ * // 高:TASK5,低:TASK2,MTX2:TASK1,MTX3:TASK1,
+ * // MTX4:TASK5→TASK3→TASK1→TASK4
+ * == TASK5(続き)==
+ * 78: ini_mtx(MTX3) ... (B-3)
+ * // 高:TASK5,低:TASK2,MTX2:TASK1,MTX4:TASK5→TASK3→TASK1→TASK4
+ * get_pri(TASK1, &tskpri)
+ * assert(tskpri == MID_PRIORITY)
+ * 79: unl_mtx(MTX4)
+ * // 高:TASK5→TASK3,低:TASK2,MTX2:TASK1,MTX4:TASK3→TASK1→TASK4
+ * 80: slp_tsk()
+ * // 高:TASK3,低:TASK2,MTX2:TASK1,MTX4:TASK3→TASK1→TASK4
+ * == TASK3(続き)==
+ * 81: unl_mtx(MTX4)
+ * // 高:TASK1,中:TASK3,低:TASK2,MTX2:TASK1,MTX4:TASK1→TASK4
+ * == TASK1(続き)==
+ * 82: unl_mtx(MTX4)
+ * // 高:TASK4,中:TASK1→TASK3,低:TASK2,MTX2:TASK1,MTX4:TASK4
+ * == TASK4(続き)==
+ * 83: unl_mtx(MTX4)
+ * // 中:TASK4→TASK1→TASK3,低:TASK2,MTX2:TASK1
+ * 84: slp_tsk()
+ * // 中:TASK1→TASK3,低:TASK2,MTX2:TASK1
+ * == TASK1(続き)==
+ * 85: unl_mtx(MTX2)
+ * // 中:TASK3,低:TASK1→TASK2
+ * == TASK3(続き)==
+ * 86: slp_tsk()
+ * // 低:TASK1→TASK2
+ *
+ * == TASK1(続き)==
+ * 87: sus_tsk(TASK2)
+ * // 低:TASK1
+ * 88: loc_mtx(MTX1)
+ * // 中:TASK1,MTX1:TASK1
+ * 89: wup_tsk(TASK3)
+ * // 中:TASK1→TASK3,MTX1:TASK1
+ * 90: rot_rdq(MID_PRIORITY)
+ * // 中:TASK3→TASK1,MTX1:TASK1
+ * == TASK3(続き)==
+ * 91: loc_mtx(MTX1) -> E_DLT
+ * // 中:TASK1,MTX1:TASK1→TASK3
+ * == TASK1(続き)==
+ * 92: wup_tsk(TASK5)
+ * // 高:TASK5,中:TASK1,MTX1:TASK1→TASK3
+ * == TASK5(続き)==
+ * 93: wup_tsk(TASK4)
+ * // 高:TASK5,中:TASK1→TASK4,MTX1:TASK1→TASK3
+ * 94: ini_mtx(MTX1) ... (C-1)
+ * // 高:TASK5,中:TASK4→TASK3,低:TASK1
+ * 95: ext_tsk() -> noreturn
+ * // 中:TASK4→TASK3,低:TASK1
+ * == TASK4(続き)==
+ * 96: ext_tsk() -> noreturn
+ * // 中:TASK3,低:TASK1
+ * == TASK3(続き)==
+ * 97: slp_tsk()
+ * // 低:TASK1
+ *
+ * == TASK1(続き)==
+ * 98: loc_mtx(MTX1)
+ * // 中:TASK1,MTX1:TASK1
+ * 99: wup_tsk(TASK3)
+ * // 中:TASK1→TASK3,MTX1:TASK1
+ * 100: rot_rdq(MID_PRIORITY)
+ * // 中:TASK3→TASK1,MTX1:TASK1
+ * == TASK3(続き)==
+ * 101: loc_mtx(MTX1) -> E_DLT
+ * // 中:TASK1,MTX1:TASK1→TASK3
+ * == TASK1(続き)==
+ * 102: rsm_tsk(TASK2)
+ * // 中:TASK1,低:TASK2,MTX1:TASK1→TASK3
+ * 103: slp_tsk()
+ * // 低:TASK2,MTX1:TASK1→TASK3
+ * == TASK2(続き)==
+ * 104: ini_mtx(MTX1) ... (C-2)
+ * // 中:TASK3,低:TASK2
+ * == TASK3(続き)==
+ * 105: ext_tsk() -> noreturn
+ * // 低:TASK2
+ * == TASK2(続き)==
+ * 106: ter_tsk(TASK1)
+ * 107: END
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include "syssvc/logtask.h"
+#include "kernel_cfg.h"
+#include "test_lib.h"
+#include "test_mutex5.h"
+
+extern ER bit_mutex(void);
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+
+ set_bit_func(bit_mutex);
+
+ check_point(1);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(2);
+ ercd = act_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(3);
+ ercd = act_tsk(TASK5);
+ check_ercd(ercd, E_OK);
+
+ check_point(6);
+ ercd = sus_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(7);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ ercd = loc_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(8);
+ ercd = act_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ check_point(9);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(10);
+ ercd = rot_rdq(MID_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ check_point(11);
+ ercd = act_tsk(TASK4);
+ check_ercd(ercd, E_OK);
+
+ check_point(12);
+ ercd = wup_tsk(TASK5);
+ check_ercd(ercd, E_OK);
+
+ check_point(13);
+ ercd = ena_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(17);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(20);
+ ercd = loc_mtx(MTX3);
+ check_ercd(ercd, E_OK);
+
+ check_point(21);
+ ercd = wup_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ check_point(22);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(23);
+ ercd = rot_rdq(MID_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ check_point(24);
+ ercd = wup_tsk(TASK4);
+ check_ercd(ercd, E_OK);
+
+ check_point(25);
+ ercd = wup_tsk(TASK5);
+ check_ercd(ercd, E_OK);
+
+ check_point(26);
+ ercd = ena_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(30);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(33);
+ ercd = rsm_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(34);
+ ercd = ini_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(37);
+ ercd = wup_tsk(TASK5);
+ check_ercd(ercd, E_OK);
+
+ check_point(40);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(41);
+ ercd = loc_mtx(MTX4);
+ check_ercd(ercd, E_OK);
+
+ check_point(47);
+ ercd = unl_mtx(MTX4);
+ check_ercd(ercd, E_OK);
+
+ check_point(48);
+ ercd = wup_tsk(TASK5);
+ check_ercd(ercd, E_OK);
+
+ check_point(51);
+ ercd = wup_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ check_point(53);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ ercd = loc_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(54);
+ ercd = loc_mtx(MTX4);
+ check_ercd(ercd, E_OK);
+
+ check_point(62);
+ ercd = unl_mtx(MTX4);
+ check_ercd(ercd, E_OK);
+
+ check_point(65);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(73);
+ ercd = loc_mtx(MTX3);
+ check_ercd(ercd, E_OK);
+
+ check_point(74);
+ ercd = loc_mtx(MTX4);
+ check_ercd(ercd, E_OK);
+
+ check_point(82);
+ ercd = unl_mtx(MTX4);
+ check_ercd(ercd, E_OK);
+
+ check_point(85);
+ ercd = unl_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(87);
+ ercd = sus_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(88);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(89);
+ ercd = wup_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ check_point(90);
+ ercd = rot_rdq(MID_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ check_point(92);
+ ercd = wup_tsk(TASK5);
+ check_ercd(ercd, E_OK);
+
+ check_point(98);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(99);
+ ercd = wup_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ check_point(100);
+ ercd = rot_rdq(MID_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ check_point(102);
+ ercd = rsm_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(103);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(42);
+ ercd = loc_mtx(MTX4);
+ check_ercd(ercd, E_OK);
+
+ check_point(46);
+ ercd = unl_mtx(MTX4);
+ check_ercd(ercd, E_OK);
+
+ check_point(55);
+ ercd = wup_tsk(TASK4);
+ check_ercd(ercd, E_OK);
+
+ check_point(57);
+ ercd = wup_tsk(TASK5);
+ check_ercd(ercd, E_OK);
+
+ check_point(67);
+ ercd = wup_tsk(TASK5);
+ check_ercd(ercd, E_OK);
+
+ check_point(70);
+ ercd = wup_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ check_point(72);
+ ercd = wup_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(75);
+ ercd = wup_tsk(TASK4);
+ check_ercd(ercd, E_OK);
+
+ check_point(77);
+ ercd = wup_tsk(TASK5);
+ check_ercd(ercd, E_OK);
+
+ check_point(104);
+ ercd = ini_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(106);
+ ercd = ter_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_finish(107);
+
+ check_point(0);
+}
+
+void
+task3(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(16);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(29);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(52);
+ ercd = loc_mtx(MTX4);
+ check_ercd(ercd, E_OK);
+
+ check_point(61);
+ ercd = unl_mtx(MTX4);
+ check_ercd(ercd, E_OK);
+
+ check_point(66);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(71);
+ ercd = loc_mtx(MTX4);
+ check_ercd(ercd, E_OK);
+
+ check_point(81);
+ ercd = unl_mtx(MTX4);
+ check_ercd(ercd, E_OK);
+
+ check_point(86);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(91);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_DLT);
+
+ check_point(97);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(101);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_DLT);
+
+ check_point(105);
+ ercd = ext_tsk();
+
+ check_point(0);
+}
+
+void
+task4(intptr_t exinf)
+{
+ ER ercd;
+ PRI tskpri;
+
+ check_point(18);
+ ercd = wup_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(19);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(31);
+ ercd = wup_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(32);
+ ercd = rot_rdq(MID_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ check_point(35);
+ ercd = get_pri(TASK1, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == LOW_PRIORITY);
+
+ check_point(36);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(56);
+ ercd = loc_mtx(MTX4);
+ check_ercd(ercd, E_OK);
+
+ check_point(63);
+ ercd = unl_mtx(MTX4);
+ check_ercd(ercd, E_OK);
+
+ check_point(64);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(76);
+ ercd = loc_mtx(MTX4);
+ check_ercd(ercd, E_OK);
+
+ check_point(83);
+ ercd = unl_mtx(MTX4);
+ check_ercd(ercd, E_OK);
+
+ check_point(84);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(96);
+ ercd = ext_tsk();
+
+ check_point(0);
+}
+
+void
+task5(intptr_t exinf)
+{
+ ER ercd;
+ PRI tskpri;
+
+ check_point(4);
+ ercd = ini_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ ercd = get_pri(TASK1, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == LOW_PRIORITY);
+
+ check_point(5);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(14);
+ ercd = ini_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ ercd = get_pri(TASK1, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == MID_PRIORITY);
+
+ check_point(15);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(27);
+ ercd = ini_mtx(MTX3);
+ check_ercd(ercd, E_OK);
+
+ ercd = get_pri(TASK1, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == MID_PRIORITY);
+
+ check_point(28);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(38);
+ ercd = loc_mtx(MTX4);
+ check_ercd(ercd, E_OK);
+
+ check_point(39);
+ ercd = tslp_tsk(10);
+ check_ercd(ercd, E_TMOUT);
+
+ check_point(43);
+ ercd = ini_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ ercd = get_pri(TASK1, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == LOW_PRIORITY);
+
+ check_point(44);
+ ercd = unl_mtx(MTX4);
+ check_ercd(ercd, E_OK);
+
+ check_point(45);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(49);
+ ercd = loc_mtx(MTX4);
+ check_ercd(ercd, E_OK);
+
+ check_point(50);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(58);
+ ercd = ini_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ ercd = get_pri(TASK1, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == MID_PRIORITY);
+
+ check_point(59);
+ ercd = unl_mtx(MTX4);
+ check_ercd(ercd, E_OK);
+
+ check_point(60);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(68);
+ ercd = loc_mtx(MTX4);
+ check_ercd(ercd, E_OK);
+
+ check_point(69);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(78);
+ ercd = ini_mtx(MTX3);
+ check_ercd(ercd, E_OK);
+
+ ercd = get_pri(TASK1, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == MID_PRIORITY);
+
+ check_point(79);
+ ercd = unl_mtx(MTX4);
+ check_ercd(ercd, E_OK);
+
+ check_point(80);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(93);
+ ercd = wup_tsk(TASK4);
+ check_ercd(ercd, E_OK);
+
+ check_point(94);
+ ercd = ini_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(95);
+ ercd = ext_tsk();
+
+ check_point(0);
+}
--- /dev/null
+/*
+ * @(#) $Id: test_mutex5.cfg 1696 2010-01-01 16:01:25Z ertl-hiro $
+ */
+
+/*
+ * ミューテックスのテスト(5)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+INCLUDE("syssvc/logtask.cfg");
+
+#include "test_mutex5.h"
+
+CRE_TSK(TASK1, { TA_ACT, 1, task1, LOW_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task2, LOW_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK3, { TA_NULL, 3, task3, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK4, { TA_NULL, 4, task4, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK5, { TA_NULL, 5, task5, HIGH_PRIORITY, STACK_SIZE, NULL });
+CRE_MTX(MTX1, { TA_CEILING, MID_PRIORITY });
+CRE_MTX(MTX2, { TA_CEILING, MID_PRIORITY });
+CRE_MTX(MTX3, { TA_CEILING, LOW_PRIORITY });
+CRE_MTX(MTX4, { TA_CEILING, HIGH_PRIORITY });
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_mutex5.h 1696 2010-01-01 16:01:25Z ertl-hiro $
+ */
+
+/*
+ * ミューテックスのテスト(5)
+ */
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 優先度の定義
+ */
+#define HIGH_PRIORITY 9 /* 高優先度 */
+#define MID_PRIORITY 10 /* 中優先度 */
+#define LOW_PRIORITY 11 /* 低優先度 */
+
+/*
+ * ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define STACK_SIZE 4096 /* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void task1(intptr_t exinf);
+extern void task2(intptr_t exinf);
+extern void task3(intptr_t exinf);
+extern void task4(intptr_t exinf);
+extern void task5(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_mutex6.c 1696 2010-01-01 16:01:25Z ertl-hiro $
+ */
+
+/*
+ * ミューテックスのテスト(6)
+ *
+ * 【テストの目的】
+ *
+ * 優先度上限ミューテックスに対して,タスクの終了時,タスクの優先順位
+ * の回転時のミューテックス関連の処理を網羅的にテストする.
+ *
+ * 【テスト項目】
+ *
+ * (A) タスクの終了時(ext_tsk)
+ * (A-1) ロックしていたミューテックス(1つ)がロック解除されること.
+ * (A-2) ロックしていたミューテックス(1つ)がロック解除され,ロッ
+ * クを待っていたタスクがそれをロックし,優先度が変化し,待
+ * ち解除されること.
+ * (A-3) ロックしていたミューテックス(複数)がすべてロック解除さ
+ * れること.
+ * (A-4) ロックしていたミューテックス(複数)がロック解除され,ロッ
+ * クを待っていたタスク(複数)がそれをロックし,優先度が変
+ * 化し,待ち解除されること.その時に,後でミューテックスを
+ * ロックしたタスク(先にロックしていたミューテックスを待っ
+ * ていたタスク)の方が,優先順位が高くなること.
+ * (B) タスクの優先順位の回転(rot_rdq)
+ * (B-1) TPRI_SELFを指定した時に,タスクのベース優先度の優先順位が
+ * 回転すること.
+ * (B-2) TPRI_SELFを指定した時に,タスクの現在優先度の優先順位が回
+ * 転しないこと.
+ *
+ * 【テスト項目の実現方法】
+ *
+ * (A-1)
+ * 低優先度タスク(TASK2)にミューテックス(MTX1)をロックさせ,
+ * ext_tskすると,ロックが解除されることを確認する.
+ * (A-2)
+ * 低優先度タスク(TASK2)に高優先度上限ミューテックス(MTX1)をロッ
+ * クさせ,別の低優先度タスク(TASK3)にMTX1を待たせた状態で,
+ * TASK2 がext_tskすると,TASK3が高優先度になって待ち解除されるこ
+ * とを確認する.
+ * (A-3)
+ * 低優先度タスク(TASK2)にミューテックスを2つ(MTX1,MTX2)ロッ
+ * クさせ,ext_tskすると,両方のロックが解除されることを確認する.
+ * (A-4)
+ * 低優先度タスク(TASK2)に高優先度上限ミューテックス2つ(MTX1,
+ * MTX2)をこの順でロックさせ,別の低優先度タスク2つ(TASK3,
+ * TASK4)にそれぞれのロックを待たせた状態で,TASK2をext_tskすると,
+ * TASK3とTASK4が高優先度になって待ち解除されることを確認する.ま
+ * た,先にロックしていたミューテックス(MTX1)を待っていたタスク
+ * (TASK3)が,TASK4よりも優先順位が高くなることを確認する.
+ * (B-1)
+ * 低優先度タスクが3つ(TASK2,TASK3,TASK4)が実行できる状態の時
+ * に,1つの低優先度タスク(TASK2)に高優先度上限ミューテックスを
+ * ロックさせ,rot_rdq(TPRI_SELF)すると,残りの2つの低優先度タスク
+ * の優先順位が回転することを確認する.
+ * (B-2)
+ * 上と同じ状況で,高優先度タスクの優先順位が回転しないことを確認
+ * する.
+ *
+ * 【使用リソース】
+ *
+ * TASK1: 低優先度タスク,メインタスク,最初から起動
+ * TASK2: 低優先度タスク
+ * TASK3: 低優先度タスク
+ * TASK4: 低優先度タスク
+ * MTX1: ミューテックス(TA_CEILING属性,上限は高優先度)
+ * MTX2: ミューテックス(TA_CEILING属性,上限は高優先度)
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(優先度:低)==
+ * call(set_bit_func(bit_mutex))
+ * 1: act_tsk(TASK2)
+ * 2: rot_rdq(TPRI_SELF)
+ * // 低:TASK2→TASK1
+ * == TASK2-1(優先度:低)1回め ==
+ * 3: loc_mtx(MTX1)
+ * // 高:TASK2,低:TASK1,MTX1:TASK2
+ * 4: ext_tsk() -> noreturn ... (A-1)
+ * // 低:TASK1
+ * == TASK1(続き)==
+ * 5: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TSK_NONE)
+ * assert(rmtx.wtskid == TSK_NONE)
+ *
+ * 6: act_tsk(TASK2)
+ * act_tsk(TASK3)
+ * 7: rot_rdq(TPRI_SELF)
+ * // 低:TASK2→TASK3→TASK1
+ * == TASK2-2(優先度:低)2回め ==
+ * 8: loc_mtx(MTX1)
+ * // 高:TASK2,低:TASK3→TASK1,MTX1:TASK2
+ * 9: slp_tsk()
+ * // 低:TASK3→TASK1,MTX1:TASK2
+ * == TASK3(優先度:低)==
+ * 10: loc_mtx(MTX1)
+ * // 低:TASK1,MTX1:TASK2→TASK3
+ * == TASK1(続き)==
+ * 11: wup_tsk(TASK2)
+ * // 高:TASK2,低:TASK1,MTX1:TASK2→TASK3
+ * == TASK2-2(続き)==
+ * 12: ext_tsk() -> noreturn ... (A-2)
+ * // 高:TASK3,低:TASK1,MTX1:TASK3
+ * == TASK3(続き)==
+ * 13: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TASK3)
+ * assert(rmtx.wtskid == TSK_NONE)
+ * get_pri(TPRI_SELF, &tskpri)
+ * assert(tskpri == HIGH_PRIORITY)
+ * unl_mtx(MTX1)
+ * slp_tsk()
+ * // 低:TASK1
+ *
+ * == TASK1(続き)==
+ * 14: act_tsk(TASK2)
+ * 15: rot_rdq(TPRI_SELF)
+ * // 低:TASK2→TASK1
+ * == TASK2-3(優先度:低)3回め ==
+ * 16: loc_mtx(MTX1)
+ * loc_mtx(MTX2)
+ * // 高:TASK2,低:TASK1,MTX1:TASK2,MTX2:TASK2
+ * 17: ext_tsk() -> noreturn ... (A-3)
+ * // 低:TASK1
+ * == TASK1(続き)==
+ * 18: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TSK_NONE)
+ * assert(rmtx.wtskid == TSK_NONE)
+ * ref_mtx(MTX2, &rmtx)
+ * assert(rmtx.htskid == TSK_NONE)
+ * assert(rmtx.wtskid == TSK_NONE)
+ *
+ * 19: act_tsk(TASK2)
+ * wup_tsk(TASK3)
+ * act_tsk(TASK4)
+ * 20: rot_rdq(TPRI_SELF)
+ * // 低:TASK2→TASK3→TASK4→TASK1
+ * == TASK2-4(優先度:低)4回め ==
+ * 21: loc_mtx(MTX1)
+ * loc_mtx(MTX2)
+ * // 高:TASK2,低:TASK3→TASK4→TASK1,MTX1:TASK2,MTX2:TASK2
+ * 22: chg_pri(TASK1, HIGH_PRIORITY)
+ * // 高:TASK2→TASK1,低:TASK3→TASK4,MTX1:TASK2,MTX2:TASK2
+ * 23: rot_rdq(TPRI_SELF) ... (B-1)(B-2)
+ * // 高:TASK2→TASK1,低:TASK4→TASK3,MTX1:TASK2,MTX2:TASK2
+ * 24: slp_tsk()
+ * // 高:TASK1,低:TASK4→TASK3,MTX1:TASK2,MTX2:TASK2
+ * == TASK1(続き)==
+ * 25: chg_pri(TSK_SELF, TPRI_INI)
+ * // 低:TASK4→TASK3→TASK1,MTX1:TASK2,MTX2:TASK2
+ * == TASK4(優先度:低)==
+ * 26: loc_mtx(MTX2)
+ * // 低:TASK3→TASK1,MTX1:TASK2,MTX2:TASK2→TASK4
+ * == TASK3(続き)==
+ * 27: loc_mtx(MTX1)
+ * // 低:TASK1,MTX1:TASK2→TASK3,MTX2:TASK2→TASK4
+ * == TASK1(続き)==
+ * 28: wup_tsk(TASK2)
+ * // 高:TASK2,低:TASK1,MTX1:TASK2→TASK3,MTX2:TASK2→TASK4
+ * == TASK2-4(続き)==
+ * 29: ext_tsk() -> noreturn ... (A-4)
+ * // 高:TASK3→TASK4,低:TASK1,MTX1:TASK3,MTX2:TASK4
+ * == TASK3(続き)==
+ * 30: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TASK3)
+ * assert(rmtx.wtskid == TSK_NONE)
+ * ref_mtx(MTX2, &rmtx)
+ * assert(rmtx.htskid == TASK4)
+ * assert(rmtx.wtskid == TSK_NONE)
+ * get_pri(TPRI_SELF, &tskpri)
+ * assert(tskpri == HIGH_PRIORITY)
+ * ext_tsk() -> noreturn
+ * // 高:TASK4,低:TASK1,MTX2:TASK4
+ * == TASK4(続き)==
+ * 31: get_pri(TPRI_SELF, &tskpri)
+ * assert(tskpri == HIGH_PRIORITY)
+ * ext_tsk() -> noreturn
+ * // 低:TASK1
+ * == TASK1(続き)==
+ * 32: END
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include "syssvc/logtask.h"
+#include "kernel_cfg.h"
+#include "test_lib.h"
+#include "test_mutex6.h"
+
+extern ER bit_mutex(void);
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+ T_RMTX rmtx;
+
+ set_bit_func(bit_mutex);
+
+ check_point(1);
+ ercd = act_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(2);
+ ercd = rot_rdq(TPRI_SELF);
+ check_ercd(ercd, E_OK);
+
+ check_point(5);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TSK_NONE);
+ check_assert(rmtx.wtskid == TSK_NONE);
+
+ check_point(6);
+ ercd = act_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ ercd = act_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ check_point(7);
+ ercd = rot_rdq(TPRI_SELF);
+ check_ercd(ercd, E_OK);
+
+ check_point(11);
+ ercd = wup_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(14);
+ ercd = act_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(15);
+ ercd = rot_rdq(TPRI_SELF);
+ check_ercd(ercd, E_OK);
+
+ check_point(18);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TSK_NONE);
+ check_assert(rmtx.wtskid == TSK_NONE);
+
+ ercd = ref_mtx(MTX2, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TSK_NONE);
+ check_assert(rmtx.wtskid == TSK_NONE);
+
+ check_point(19);
+ ercd = act_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ ercd = wup_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ ercd = act_tsk(TASK4);
+ check_ercd(ercd, E_OK);
+
+ check_point(20);
+ ercd = rot_rdq(TPRI_SELF);
+ check_ercd(ercd, E_OK);
+
+ check_point(25);
+ ercd = chg_pri(TSK_SELF, TPRI_INI);
+ check_ercd(ercd, E_OK);
+
+ check_point(28);
+ ercd = wup_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_finish(32);
+
+ check_point(0);
+}
+
+static uint_t task2_count = 0;
+
+void
+task2(intptr_t exinf)
+{
+ ER ercd;
+
+ switch (++task2_count) {
+ case 1:
+ check_point(3);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(4);
+ ercd = ext_tsk();
+
+ check_point(0);
+
+ case 2:
+ check_point(8);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(9);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(12);
+ ercd = ext_tsk();
+
+ check_point(0);
+
+ case 3:
+ check_point(16);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ ercd = loc_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(17);
+ ercd = ext_tsk();
+
+ check_point(0);
+
+ case 4:
+ check_point(21);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ ercd = loc_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(22);
+ ercd = chg_pri(TASK1, HIGH_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ check_point(23);
+ ercd = rot_rdq(TPRI_SELF);
+ check_ercd(ercd, E_OK);
+
+ check_point(24);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(29);
+ ercd = ext_tsk();
+
+ check_point(0);
+ }
+ check_point(0);
+}
+
+void
+task3(intptr_t exinf)
+{
+ ER ercd;
+ PRI tskpri;
+ T_RMTX rmtx;
+
+ check_point(10);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(13);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TASK3);
+ check_assert(rmtx.wtskid == TSK_NONE);
+
+ ercd = get_pri(TPRI_SELF, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == HIGH_PRIORITY);
+
+ ercd = unl_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(27);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(30);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TASK3);
+ check_assert(rmtx.wtskid == TSK_NONE);
+
+ ercd = ref_mtx(MTX2, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TASK4);
+ check_assert(rmtx.wtskid == TSK_NONE);
+
+ ercd = get_pri(TPRI_SELF, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == HIGH_PRIORITY);
+
+ ercd = ext_tsk();
+
+ check_point(0);
+}
+
+void
+task4(intptr_t exinf)
+{
+ ER ercd;
+ PRI tskpri;
+
+ check_point(26);
+ ercd = loc_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(31);
+ ercd = get_pri(TPRI_SELF, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == HIGH_PRIORITY);
+
+ ercd = ext_tsk();
+
+ check_point(0);
+}
--- /dev/null
+/*
+ * @(#) $Id: test_mutex6.cfg 733 2008-01-24 08:28:59Z hiro $
+ */
+
+/*
+ * ミューテックスのテスト(6)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+INCLUDE("syssvc/logtask.cfg");
+
+#include "test_mutex6.h"
+
+CRE_TSK(TASK1, { TA_ACT, 1, task1, LOW_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task2, LOW_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK3, { TA_NULL, 3, task3, LOW_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK4, { TA_NULL, 4, task4, LOW_PRIORITY, STACK_SIZE, NULL });
+CRE_MTX(MTX1, { TA_CEILING, HIGH_PRIORITY });
+CRE_MTX(MTX2, { TA_CEILING, HIGH_PRIORITY });
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_mutex6.h 519 2007-08-28 02:08:04Z hiro $
+ */
+
+/*
+ * ミューテックスのテスト(6)
+ */
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 優先度の定義
+ */
+#define HIGH_PRIORITY 9 /* 高優先度 */
+#define MID_PRIORITY 10 /* 中優先度 */
+#define LOW_PRIORITY 11 /* 低優先度 */
+
+/*
+ * ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define STACK_SIZE 4096 /* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void task1(intptr_t exinf);
+extern void task2(intptr_t exinf);
+extern void task3(intptr_t exinf);
+extern void task4(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2008-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_mutex7.c 1696 2010-01-01 16:01:25Z ertl-hiro $
+ */
+
+/*
+ * ミューテックスのテスト(7)
+ *
+ * 【テストの目的】
+ *
+ * 優先度上限ミューテックスに対して,タスクの強制終了時のミューテック
+ * ス関連の処理を網羅的にテストする.
+ *
+ * 【テスト項目】
+ *
+ * (A) タスクの強制終了時(ter_tsk)
+ * (A-1) ロックしていたミューテックス(1つ)がロック解除されること.
+ * (A-2) ロックしていたミューテックス(1つ)がロック解除され,ロッ
+ * クを待っていたタスクがそれをロックし,優先度が変化し,待
+ * ち解除されること.
+ * (A-3) (A-2)の結果,タスクディスパッチが起こること.
+ * (A-4) ロックしていたミューテックス(複数)がすべてロック解除さ
+ * れること.
+ * (A-5) ロックしていたミューテックス(複数)がロック解除され,ロッ
+ * クを待っていたタスク(複数)がそれをロックし,優先度が変
+ * 化し,待ち解除されること.その時に,後でミューテックスを
+ * ロックしたタスク(先にロックしていたミューテックスを待っ
+ * ていたタスク)の方が,優先順位が高くなること.
+ * (A-6) (A-5)の結果,タスクディスパッチが起こること.
+ *
+ * 【テスト項目の実現方法】
+ *
+ * (A-1)
+ * 低優先度タスク(TASK2)にミューテックス(MTX1)をロックさせ,別
+ * のタスク(TASK1)からTASK2をter_tskすると,ロックが解除されるこ
+ * とを確認する.
+ * (A-2)
+ * 低優先度タスク(TASK2)に中優先度上限ミューテックス(MTX1)をロッ
+ * クさせ,別の低優先度タスク(TASK3)にMTX1を待たせた状態で,高優
+ * 先度タスク(TASK1)からTASK2をter_tskすると,TASK3が中優先度に
+ * なって待ち解除されることを確認する.
+ * (A-3)
+ * 低優先度タスク(TASK2)に中優先度上限ミューテックス(MTX1)をロッ
+ * クさせ,別の低優先度タスク(TASK3)にMTX1を待たせた状態で,別の
+ * 低優先度タスク(TASK1)からTASK2をter_tskすると,TASK3が中優先
+ * 度になって待ち解除され,TASK3に切り換わることを確認する.
+ * (A-4)
+ * 低優先度タスク(TASK2)にミューテックスを2つ(MTX1,MTX2)ロッ
+ * クさせ,別のタスク(TASK1)からTASK2をter_tskすると,両方のロッ
+ * クが解除されることを確認する.
+ * (A-5)
+ * 低優先度タスク(TASK2)に高優先度上限ミューテックス2つ(MTX1,
+ * MTX2)をこの順でロックさせ,別の低優先度タスク2つ(TASK3,
+ * TASK4)にそれぞれのロックを待たせた状態で,高優先度タスク
+ * (TASK1)からTASK2をter_tskすると,TASK3とTASK4が中優先度になっ
+ * て待ち解除されることを確認する.また,先にロックしていたミュー
+ * テックス(MTX1)を待っていたタスク(TASK3)が,TASK4よりも優先
+ * 順位が高くなることを確認する.
+ * (A-6)
+ * 低優先度タスク(TASK2)に高優先度上限ミューテックス2つ(MTX1,
+ * MTX2)をこの順でロックさせ,別の低優先度タスク2つ(TASK3,
+ * TASK4)にそれぞれのロックを待たせた状態で,別の低優先度タスク
+ * (TASK1)からTASK2 をter_tskすると,TASK3とTASK4が中優先度になっ
+ * て待ち解除され,TASK3に切り換わることを確認する.
+ *
+ * 【使用リソース】
+ *
+ * TASK1: 高優先度タスク,メインタスク,最初から起動
+ * TASK2: 低優先度タスク
+ * TASK3: 低優先度タスク
+ * TASK4: 低優先度タスク
+ * MTX1: ミューテックス(TA_CEILING属性,上限は中優先度)
+ * MTX2: ミューテックス(TA_CEILING属性,上限は中優先度)
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(優先度:高)==
+ * call(set_bit_func(bit_mutex))
+ * 1: act_tsk(TASK2)
+ * 2: slp_tsk()
+ * == TASK2-1(優先度:低)==
+ * 3: loc_mtx(MTX1)
+ * 4: wup_tsk(TASK1)
+ * == TASK1(続き)==
+ * 5: ter_tsk(TASK2) ... (A-1)
+ * 6: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TSK_NONE)
+ * assert(rmtx.wtskid == TSK_NONE)
+ *
+ * 7: act_tsk(TASK2)
+ * act_tsk(TASK3)
+ * 8: slp_tsk()
+ * == TASK2-2(優先度:低)==
+ * 9: loc_mtx(MTX1)
+ * 10: tslp_tsk(10) -> E_TMOUT
+ * == TASK3-1(優先度:低)==
+ * 11: loc_mtx(MTX1)
+ * == TASK2-2(続き)==
+ * 12: wup_tsk(TASK1)
+ * == TASK1(続き)==
+ * 13: ter_tsk(TASK2) ... (A-2)
+ * 14: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TASK3)
+ * assert(rmtx.wtskid == TSK_NONE)
+ * get_pri(TASK3, &tskpri)
+ * assert(tskpri == MID_PRIORITY)
+ * 15: ter_tsk(TASK3)
+ *
+ * 16: act_tsk(TASK2)
+ * act_tsk(TASK3)
+ * 17: chg_pri(TSK_SELF, LOW_PRIORITY)
+ * == TASK2-3(優先度:低)==
+ * 18: loc_mtx(MTX1)
+ * 19: slp_tsk()
+ * == TASK3-2(優先度:低)==
+ * 20: loc_mtx(MTX1)
+ * == TASK1(続き)==
+ * 21: ter_tsk(TASK2) ... (A-3)
+ * == TASK3-2(続き)==
+ * 22: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TASK3)
+ * assert(rmtx.wtskid == TSK_NONE)
+ * get_pri(TASK3, &tskpri)
+ * assert(tskpri == MID_PRIORITY)
+ * 23: ext_tsk() -> noreturn
+ * == TASK1(続き)==
+ * 24: chg_pri(TSK_SELF, HIGH_PRIORITY)
+ *
+ * 25: act_tsk(TASK2)
+ * 26: slp_tsk()
+ * == TASK2-4(優先度:低)==
+ * 27: loc_mtx(MTX1)
+ * loc_mtx(MTX2)
+ * 28: wup_tsk(TASK1)
+ * == TASK1(続き)==
+ * 29: ter_tsk(TASK2) ... (A-4)
+ * 30: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TSK_NONE)
+ * assert(rmtx.wtskid == TSK_NONE)
+ * ref_mtx(MTX2, &rmtx)
+ * assert(rmtx.htskid == TSK_NONE)
+ * assert(rmtx.wtskid == TSK_NONE)
+ * 31: MISSING
+ *
+ * 32: act_tsk(TASK2)
+ * act_tsk(TASK3)
+ * act_tsk(TASK4)
+ * 33: slp_tsk()
+ * == TASK2-5(優先度:低)==
+ * 34: loc_mtx(MTX1)
+ * loc_mtx(MTX2)
+ * 35: tslp_tsk(10) -> E_TMOUT
+ * == TASK3-3(優先度:低)==
+ * 36: loc_mtx(MTX1)
+ * == TASK4-1(優先度:低)==
+ * 37: loc_mtx(MTX2)
+ * == TASK2-5(続き)==
+ * 38: wup_tsk(TASK1)
+ * == TASK1(続き)==
+ * 39: ter_tsk(TASK2) ... (A-5)
+ * 40: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TASK3)
+ * assert(rmtx.wtskid == TSK_NONE)
+ * ref_mtx(MTX2, &rmtx)
+ * assert(rmtx.htskid == TASK4)
+ * assert(rmtx.wtskid == TSK_NONE)
+ * get_pri(TASK3, &tskpri)
+ * assert(tskpri == MID_PRIORITY)
+ * get_pri(TASK4, &tskpri)
+ * assert(tskpri == MID_PRIORITY)
+ * 41: chg_pri(TSK_SELF, LOW_PRIORITY)
+ * == TASK3-3(続き)==
+ * 42: ext_tsk() -> noreturn
+ * == TASK4-1(続き)==
+ * 43: ext_tsk() -> noreturn
+ * == TASK1(続き)==
+ * 44: act_tsk(TASK2)
+ * act_tsk(TASK3)
+ * act_tsk(TASK4)
+ * 45: chg_pri(TSK_SELF, LOW_PRIORITY)
+ * == TASK2-6(優先度:低)==
+ * 46: loc_mtx(MTX1)
+ * loc_mtx(MTX2)
+ * 47: slp_tsk()
+ * == TASK3-4(優先度:低)==
+ * 48: loc_mtx(MTX1)
+ * == TASK4-2(優先度:低)==
+ * 49: loc_mtx(MTX2)
+ * == TASK1(続き)==
+ * 50: ter_tsk(TASK2) ... (A-6)
+ * == TASK3-4(続き)==
+ * 51: ref_mtx(MTX1, &rmtx)
+ * assert(rmtx.htskid == TASK3)
+ * assert(rmtx.wtskid == TSK_NONE)
+ * ref_mtx(MTX2, &rmtx)
+ * assert(rmtx.htskid == TASK4)
+ * assert(rmtx.wtskid == TSK_NONE)
+ * get_pri(TASK3, &tskpri)
+ * assert(tskpri == MID_PRIORITY)
+ * get_pri(TASK4, &tskpri)
+ * assert(tskpri == MID_PRIORITY)
+ * 52: ext_tsk() -> noreturn
+ * == TASK4-2(続き)==
+ * 53: ext_tsk() -> noreturn
+ * == TASK1(続き)==
+ * 54: END
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include "syssvc/logtask.h"
+#include "kernel_cfg.h"
+#include "test_lib.h"
+#include "test_mutex7.h"
+
+extern ER bit_mutex(void);
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+ PRI tskpri;
+ T_RMTX rmtx;
+
+ set_bit_func(bit_mutex);
+
+ check_point(1);
+ ercd = act_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(2);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(5);
+ ercd = ter_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(6);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TSK_NONE);
+ check_assert(rmtx.wtskid == TSK_NONE);
+
+ check_point(7);
+ ercd = act_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ ercd = act_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ check_point(8);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(13);
+ ercd = ter_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(14);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TASK3);
+ check_assert(rmtx.wtskid == TSK_NONE);
+
+ ercd = get_pri(TASK3, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == MID_PRIORITY);
+
+ check_point(15);
+ ercd = ter_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ check_point(16);
+ ercd = act_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ ercd = act_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ check_point(17);
+ ercd = chg_pri(TSK_SELF, LOW_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ check_point(21);
+ ercd = ter_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(24);
+ ercd = chg_pri(TSK_SELF, HIGH_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ check_point(25);
+ ercd = act_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(26);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(29);
+ ercd = ter_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(30);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TSK_NONE);
+ check_assert(rmtx.wtskid == TSK_NONE);
+
+ ercd = ref_mtx(MTX2, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TSK_NONE);
+ check_assert(rmtx.wtskid == TSK_NONE);
+
+ check_point(31);
+
+ check_point(32);
+ ercd = act_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ ercd = act_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ ercd = act_tsk(TASK4);
+ check_ercd(ercd, E_OK);
+
+ check_point(33);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(39);
+ ercd = ter_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(40);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TASK3);
+ check_assert(rmtx.wtskid == TSK_NONE);
+
+ ercd = ref_mtx(MTX2, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TASK4);
+ check_assert(rmtx.wtskid == TSK_NONE);
+
+ ercd = get_pri(TASK3, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == MID_PRIORITY);
+
+ ercd = get_pri(TASK4, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == MID_PRIORITY);
+
+ check_point(41);
+ ercd = chg_pri(TSK_SELF, LOW_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ check_point(44);
+ ercd = act_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ ercd = act_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ ercd = act_tsk(TASK4);
+ check_ercd(ercd, E_OK);
+
+ check_point(45);
+ ercd = chg_pri(TSK_SELF, LOW_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ check_point(50);
+ ercd = ter_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_finish(54);
+
+ check_point(0);
+}
+
+static uint_t task2_count = 0;
+
+void
+task2(intptr_t exinf)
+{
+ ER ercd;
+
+ switch (++task2_count) {
+ case 1:
+ check_point(3);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(4);
+ ercd = wup_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(0);
+
+ case 2:
+ check_point(9);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(10);
+ ercd = tslp_tsk(10);
+ check_ercd(ercd, E_TMOUT);
+
+ check_point(12);
+ ercd = wup_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(0);
+
+ case 3:
+ check_point(18);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(19);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(0);
+
+ case 4:
+ check_point(27);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ ercd = loc_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(28);
+ ercd = wup_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(0);
+
+ case 5:
+ check_point(34);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ ercd = loc_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(35);
+ ercd = tslp_tsk(10);
+ check_ercd(ercd, E_TMOUT);
+
+ check_point(38);
+ ercd = wup_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(0);
+
+ case 6:
+ check_point(46);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ ercd = loc_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(47);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(0);
+ }
+ check_point(0);
+}
+
+static uint_t task3_count = 0;
+
+void
+task3(intptr_t exinf)
+{
+ ER ercd;
+ PRI tskpri;
+ T_RMTX rmtx;
+
+ switch (++task3_count) {
+ case 1:
+ check_point(11);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(0);
+
+ case 2:
+ check_point(20);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(22);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TASK3);
+ check_assert(rmtx.wtskid == TSK_NONE);
+
+ ercd = get_pri(TASK3, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == MID_PRIORITY);
+
+ check_point(23);
+ ercd = ext_tsk();
+
+ check_point(0);
+
+ case 3:
+ check_point(36);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(42);
+ ercd = ext_tsk();
+
+ check_point(0);
+
+ case 4:
+ check_point(48);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(51);
+ ercd = ref_mtx(MTX1, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TASK3);
+ check_assert(rmtx.wtskid == TSK_NONE);
+
+ ercd = ref_mtx(MTX2, &rmtx);
+ check_ercd(ercd, E_OK);
+ check_assert(rmtx.htskid == TASK4);
+ check_assert(rmtx.wtskid == TSK_NONE);
+
+ ercd = get_pri(TASK3, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == MID_PRIORITY);
+
+ ercd = get_pri(TASK4, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == MID_PRIORITY);
+
+ check_point(52);
+ ercd = ext_tsk();
+
+ check_point(0);
+ }
+ check_point(0);
+}
+
+static uint_t task4_count = 0;
+
+void
+task4(intptr_t exinf)
+{
+ ER ercd;
+
+ switch (++task4_count) {
+ case 1:
+ check_point(37);
+ ercd = loc_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(43);
+ ercd = ext_tsk();
+
+ check_point(0);
+
+ case 2:
+ check_point(49);
+ ercd = loc_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(53);
+ ercd = ext_tsk();
+
+ check_point(0);
+ }
+ check_point(0);
+}
--- /dev/null
+/*
+ * @(#) $Id: test_mutex7.cfg 1566 2009-05-24 14:35:24Z ertl-hiro $
+ */
+
+/*
+ * ミューテックスのテスト(7)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+INCLUDE("syssvc/logtask.cfg");
+
+#include "test_mutex7.h"
+
+CRE_TSK(TASK1, { TA_ACT, 1, task1, HIGH_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task2, LOW_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK3, { TA_NULL, 3, task3, LOW_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK4, { TA_NULL, 4, task4, LOW_PRIORITY, STACK_SIZE, NULL });
+CRE_MTX(MTX1, { TA_CEILING, MID_PRIORITY });
+CRE_MTX(MTX2, { TA_CEILING, MID_PRIORITY });
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_mutex7.h 1566 2009-05-24 14:35:24Z ertl-hiro $
+ */
+
+/*
+ * ミューテックスのテスト(7)
+ */
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 優先度の定義
+ */
+#define HIGH_PRIORITY 9 /* 高優先度 */
+#define MID_PRIORITY 10 /* 中優先度 */
+#define LOW_PRIORITY 11 /* 低優先度 */
+
+/*
+ * ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define STACK_SIZE 4096 /* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void task1(intptr_t exinf);
+extern void task2(intptr_t exinf);
+extern void task3(intptr_t exinf);
+extern void task4(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_mutex8.c 1696 2010-01-01 16:01:25Z ertl-hiro $
+ */
+
+/*
+ * ミューテックスのテスト(8)
+ *
+ * 【テストの目的】
+ *
+ * 優先度上限ミューテックスに対して,chg_priに伴うミューテックス関連の
+ * 優先度変更処理を網羅的にテストする.ただし,change_priorityと
+ * mutex_calc_priorityの内容には踏み込まない.
+ *
+ * 【テスト項目】
+ *
+ * (A) タスクのベース優先度の変更処理(chg_pri)
+ * (A-1) 対象タスクが実行できる状態で,ミューテックスをロックして
+ * いない場合に,同じ優先度内での優先順位が最低になること
+ * (A-2) 対象タスクが実行できる状態で,優先度上限ミューテックス以
+ * 外のミューテックスのみをロックしている場合に,同じ優先度
+ * 内での優先順位が最低になること
+ * (A-3) 対象タスクが実行できる状態で,優先度上限ミューテックスを
+ * ロックしている場合に,同じ優先度内での優先順位が変わらな
+ * いこと
+ * (A-4) 対象タスクが待ち状態で,優先度順の待ち行列につながれてお
+ * り,ミューテックスをロックしていない場合に,優先度が正し
+ * く変更され,同じ優先度内での順序が最後になること
+ * (A-5) 対象タスクが待ち状態で,優先度順の待ち行列につながれてお
+ * り,優先度上限ミューテックス以外のミューテックスのみをロッ
+ * クしている場合に,優先度が正しく変更され,同じ優先度内で
+ * の順序が最後になること
+ * (A-6) 対象タスクが待ち状態で,優先度順の待ち行列につながれてお
+ * り,優先度上限ミューテックスをロックしている場合に,同じ
+ * 優先度内での順序が変わらないこと
+ * (B) タスクのベース優先度の変更処理(chg_pri)のE_ILUSEエラー
+ * (B-1) 対象タスクがロックしているミューテックスの上限優先度より
+ * も,ベース優先度を高くしようとした時,E_ILUSEエラーになる
+ * こと
+ * (B-2) 対象タスクが優先度上限ミューテックスをロックしていても,
+ * ロックしているミューテックスの上限優先度よりも,ベース優
+ * 先度を高くしようとしない場合には,E_ILUSEエラーにならない
+ * こと
+ * (B-3) 対象タスクがロックを待っているミューテックスの上限優先度
+ * よりも,ベース優先度を高くしようとした時,E_ILUSEエラーに
+ * なること
+ * (B-4) 対象タスクが優先度上限ミューテックス待ちであっても,ロッ
+ * クを待っているミューテックスの上限優先度よりも,ベース優
+ * 先度を高くしようとしない場合には,E_ILUSEエラーにならない
+ * こと
+ *
+ * 【テスト項目の実現方法】
+ *
+ * (A-1)
+ * 中優先度タスク(TASK1)が実行可能状態の時に,高優先度タスク
+ * (TASK5)からTASK1を低優先度にchg_priすると,実行可能状態の他の
+ * 低優先度タスク(TASK4)よりも,優先順位が低くなることを確認する.
+ * (A-2)
+ * 中優先度タスク(TASK1)が優先度順ミューテックス(MTX3)をロック
+ * し,実行可能状態の時に,高優先度タスク(TASK5)からTASK1を低優
+ * 先度にchg_priすると,実行可能状態の他の低優先度タスク(TASK4)
+ * よりも,優先順位が低くなることを確認する.
+ * (A-3)
+ * 中優先度タスク(TASK1)が中優先度上限ミューテックス(MTX1)をロッ
+ * クし,実行可能状態の時に,高優先度タスク(TASK5)からTASK1を低
+ * 優先度にchg_priすると,TASK1の優先度が変化しないことを確認する.
+ * また,実行可能状態の中優先度タスクを2つ(TASK2,TASK3)を用意し
+ * ておき,優先順位が変わらないことを確認する.
+ * (A-4)
+ * 中優先度タスク(TASK1)が高優先度上限ミューテックス(MTX2)を待っ
+ * ている時に,高優先度タスク(TASK5)からTASK1を低優先度に
+ * chg_priすると,MTX2を待っている他の低優先度タスク(TASK4)より
+ * も,待ち行列中での順序が後になることを確認する.
+ * (A-5)
+ * 中優先度タスク(TASK1)が優先度順ミューテックス(MTX3)をロック
+ * し,高優先度上限ミューテックス(MTX2)を待っている時に,高優先度タ
+ * スク(TASK5)からTASK1を低優先度にchg_priすると,MTX2を待ってい
+ * る他の低優先度タスク(TASK4)よりも,待ち行列中での順序が変わら
+ * ないことを確認する.
+ * (A-6)
+ * 中優先度タスク(TASK1)が中優先度上限ミューテックス(MTX1)をロッ
+ * クし,高優先度上限ミューテックス(MTX2)を待っている時に,高優
+ * 先度タスク(TASK5)からTASK1を低優先度にchg_priすると,TASK1の
+ * 優先度が変化しないことを確認する.また,MTX2を待っている中優先
+ * 度タスクを2つ(TASK2,TASK3)を用意しておき,待ち行列中での順序
+ * が変わらないことを確認する.
+ * (B-1)
+ * 中優先度タスク(TASK1)が中優先度上限ミューテックス(MTX1)をロッ
+ * クし,実行可能状態の時に,高優先度タスク(TASK5)からTASK1を高
+ * 優先度にchg_priすると,E_ILUSEエラーになることを確認する.
+ * (B-2)
+ * (A-3)のテスト項目で,chg_priがE_ILUSEエラーにならないことで確認
+ * できている.
+ * (B-3)
+ * 中優先度タスク(TASK2)が中優先度上限ミューテックス(MTX1)のロッ
+ * クを待っている時に,高優先度タスク(TASK5)からTASK2を高優先度
+ * にchg_priすると,E_ILUSEエラーになることを確認する.
+ * (B-4)
+ * (A-6)のテスト項目で,chg_priがE_ILUSEエラーにならないことで確認
+ * できている.
+ *
+ * 【使用リソース】
+ *
+ * TASK1: 中優先度タスク,メインタスク,最初から起動
+ * TASK2: 中優先度タスク
+ * TASK3: 中優先度タスク
+ * TASK4: 低優先度タスク
+ * TASK5: 高優先度タスク
+ * MTX1: ミューテックス(TA_CEILING属性,上限は中優先度)
+ * MTX2: ミューテックス(TA_CEILING属性,上限は高優先度)
+ * MTX3: ミューテックス(TA_TPRI属性)
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(優先度:中)==
+ * call(set_bit_func(bit_mutex))
+ * 1: act_tsk(TASK4)
+ * 2: act_tsk(TASK5)
+ * // 高:TASK5,中:TASK1,低:TASK4
+ * == TASK5(優先度:高)==
+ * 3: chg_pri(TASK1, LOW_PRIORITY) ... (A-1)
+ * // 高:TASK5,低:TASK4→TASK1
+ * 4: slp_tsk()
+ * == TASK4(優先度:低)==
+ * 5: slp_tsk()
+ * == TASK1(続き)==
+ * 6: chg_pri(TSK_SELF, TPRI_INI)
+ *
+ * 7: loc_mtx(MTX3)
+ * 8: wup_tsk(TASK4)
+ * 9: wup_tsk(TASK5)
+ * // 高:TASK5,中:TASK1,低:TASK4,MTX3:TASK1
+ * == TASK5(続き)==
+ * 10: chg_pri(TASK1, LOW_PRIORITY) ... (A-2)
+ * // 高:TASK5,低:TASK4→TASK1,MTX3:TASK1
+ * 11: slp_tsk()
+ * == TASK4(続き)==
+ * 12: slp_tsk()
+ * == TASK1(続き)==
+ * 13: unl_mtx(MTX3)
+ * chg_pri(TSK_SELF, TPRI_INI)
+ *
+ * 14: loc_mtx(MTX1)
+ * 15: act_tsk(TASK2)
+ * 16: dis_dsp()
+ * 17: rot_rdq(MID_PRIORITY)
+ * 18: act_tsk(TASK3)
+ * // 中:TASK2→TASK1→TASK3,MTX1:TASK1
+ * 19: wup_tsk(TASK5)
+ * // 高:TASK5,中:TASK2→TASK1→TASK3,MTX1:TASK1
+ * 20: ena_dsp()
+ * == TASK5(続き)==
+ * 21: chg_pri(TASK1, LOW_PRIORITY) ... (A-3)(B-2)
+ * // 高:TASK5,中:TASK2→TASK1→TASK3,MTX1:TASK1
+ * get_pri(TASK1, &tskpri)
+ * assert(tskpri == MID_PRIORITY)
+ * 22: slp_tsk()
+ * // 中:TASK2→TASK1→TASK3,MTX1:TASK1
+ * == TASK2(続き)==
+ * 23: slp_tsk()
+ * // 中:TASK1→TASK3,MTX1:TASK1
+ * == TASK1(続き)==
+ * 24: unl_mtx(MTX1)
+ * // 中:TASK3,低:TASK1
+ * == TASK3(続き)==
+ * 25: slp_tsk()
+ * == TASK1(続き)==
+ * 26: chg_pri(TSK_SELF, TPRI_INI)
+ *
+ * 27: wup_tsk(TASK5)
+ * == TASK5(続き)==
+ * 28: loc_mtx(MTX2)
+ * 29: tslp_tsk(10) -> E_TMOUT
+ * == TASK1(続き)==
+ * 30: wup_tsk(TASK4)
+ * 31: loc_mtx(MTX2)
+ * == TASK4(続き)==
+ * 32: loc_mtx(MTX2)
+ * // MTX2:TASK5→TASK1→TASK4
+ * // タイムアウト待ち
+ * // 高:TASK5,MTX2:TASK5→TASK1→TASK4
+ * == TASK5(続き)==
+ * 33: chg_pri(TASK1, LOW_PRIORITY) ... (A-4)
+ * // 高:TASK5,MTX2:TASK5→TASK4→TASK1
+ * 34: unl_mtx(MTX2)
+ * // 高:TASK5→TASK4,MTX2:TASK4→TASK1
+ * 35: slp_tsk()
+ * // 高:TASK4,MTX2:TASK4→TASK1
+ * == TASK4(続き)==
+ * 36: unl_mtx(MTX2)
+ * // 高:TASK1,低:TASK4,MTX2:TASK1
+ * == TASK1(続き)==
+ * 37: unl_mtx(MTX2)
+ * // 低:TASK1→TASK4
+ * 38: chg_pri(TSK_SELF, TPRI_INI)
+ *
+ * 39: loc_mtx(MTX3)
+ * 40: wup_tsk(TASK5)
+ * // 高:TASK5,中:TASK1,低:TASK4,MTX3:TASK1
+ * == TASK5(続き)==
+ * 41: loc_mtx(MTX2)
+ * 42: tslp_tsk(10) -> E_TMOUT
+ * == TASK1(続き)==
+ * 43: loc_mtx(MTX2)
+ * == TASK4(続き)==
+ * 44: loc_mtx(MTX2)
+ * // MTX2:TASK5→TASK1→TASK4,MTX3:TASK1
+ * // タイムアウト待ち
+ * // 高:TASK5,MTX2:TASK5→TASK1→TASK4,MTX3:TASK1
+ * == TASK5(続き)==
+ * 45: chg_pri(TASK1, LOW_PRIORITY) ... (A-5)
+ * // 高:TASK5,MTX2:TASK5→TASK4→TASK1,MTX3:TASK1
+ * 46: unl_mtx(MTX2)
+ * // 高:TASK5→TASK4,MTX2:TASK4→TASK1,MTX3:TASK1
+ * 47: slp_tsk()
+ * // 高:TASK4,MTX2:TASK4→TASK1,MTX3:TASK1
+ * == TASK4(続き)==
+ * 48: unl_mtx(MTX2)
+ * // 高:TASK1,低:TASK4,MTX2:TASK1,MTX3:TASK1
+ * == TASK1(続き)==
+ * 49: unl_mtx(MTX2)
+ * // 低:TASK1→TASK4,MTX3:TASK1
+ * 50: unl_mtx(MTX3)
+ * // 低:TASK1→TASK4
+ * 51: ter_tsk(TASK4)
+ * 52: chg_pri(TSK_SELF, TPRI_INI)
+ *
+ * 53: loc_mtx(MTX1)
+ * 54: wup_tsk(TASK5)
+ * // 高:TASK5,中:TASK1,MTX1:TASK1
+ * == TASK5(続き)==
+ * 55: loc_mtx(MTX2)
+ * 56: tslp_tsk(10) -> E_TMOUT
+ * // 中:TASK1,MTX1:TASK1,MTX2:TASK5
+ * == TASK1(続き)==
+ * 57: wup_tsk(TASK2)
+ * 58: rot_rdq(MID_PRIORITY)
+ * == TASK2(続き)==
+ * 59: loc_mtx(MTX2)
+ * // 中:TASK1,MTX1:TASK1,MTX2:TASK5→TASK2
+ * == TASK1(続き)==
+ * 60: wup_tsk(TASK3)
+ * 61: loc_mtx(MTX2)
+ * // 中:TASK3,MTX1:TASK1,MTX2:TASK5→TASK2→TASK1
+ * == TASK3(続き)==
+ * 62: loc_mtx(MTX2)
+ * // MTX1:TASK1,MTX2:TASK5→TASK2→TASK1→TASK3
+ * // タイムアウト待ち
+ * // 高:TASK5,MTX1:TASK1,MTX2:TASK5→TASK2→TASK1→TASK3
+ * == TASK5(続き)==
+ * 63: chg_pri(TASK1, LOW_PRIORITY) ... (A-6)(B-4)
+ * // 高:TASK5,MTX1:TASK1,MTX2:TASK5→TASK2→TASK1→TASK3
+ * get_pri(TASK1, &tskpri)
+ * assert(tskpri == MID_PRIORITY)
+ * 64: unl_mtx(MTX2)
+ * // 高:TASK5→TASK2,MTX1:TASK1,MTX2:TASK2→TASK1→TASK3
+ * 65: slp_tsk()
+ * // 高:TASK2,MTX1:TASK1,MTX2:TASK2→TASK1→TASK3
+ * == TASK2(続き)==
+ * 66: unl_mtx(MTX2)
+ * // 高:TASK1,中:TASK2,MTX1:TASK1,MTX2:TASK1→TASK3
+ * == TASK1(続き)==
+ * 67: unl_mtx(MTX2)
+ * // 高:TASK3,中:TASK1→TASK2,MTX1:TASK1,MTX2:TASK3
+ * == TASK3(続き)==
+ * 68: unl_mtx(MTX2)
+ * // 中:TASK3→TASK1→TASK2,MTX1:TASK1
+ * 69: ext_tsk() -> noreturn
+ * // 中:TASK1→TASK2,MTX1:TASK1
+ * == TASK1(続き)==
+ * 70: chg_pri(TSK_SELF, TPRI_INI)
+ * // 中:TASK1→TASK2,MTX1:TASK1
+ *
+ * 71: rot_rdq(MID_PRIORITY)
+ * // 中:TASK2→TASK1,MTX1:TASK1
+ * == TASK2(続き)==
+ * 72: loc_mtx(MTX1)
+ * // 中:TASK1,MTX1:TASK1→TASK2
+ * == TASK1(続き)==
+ * 73: wup_tsk(TASK5)
+ * // 高:TASK5,中:TASK1,MTX1:TASK1→TASK2
+ * == TASK5(続き)==
+ * 74: chg_pri(TASK1, HIGH_PRIORITY) -> E_ILUSE ... (B-1)
+ * 75: chg_pri(TASK2, HIGH_PRIORITY) -> E_ILUSE ... (B-3)
+ * 76: ext_tsk() -> noreturn
+ * // 中:TASK1,MTX1:TASK1→TASK2
+ * == TASK1(続き)==
+ * 77: unl_mtx(MTX1)
+ * // 中:TASK1→TASK2,MTX1:TASK2
+ * 78: ext_tsk() -> noreturn
+ * == TASK2(続き)==
+ * 79: unl_mtx(MTX1)
+ * 80: END
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include "syssvc/logtask.h"
+#include "kernel_cfg.h"
+#include "test_lib.h"
+#include "test_mutex8.h"
+
+extern ER bit_mutex(void);
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+
+ set_bit_func(bit_mutex);
+
+ check_point(1);
+ ercd = act_tsk(TASK4);
+ check_ercd(ercd, E_OK);
+
+ check_point(2);
+ ercd = act_tsk(TASK5);
+ check_ercd(ercd, E_OK);
+
+ check_point(6);
+ ercd = chg_pri(TSK_SELF, TPRI_INI);
+ check_ercd(ercd, E_OK);
+
+ check_point(7);
+ ercd = loc_mtx(MTX3);
+ check_ercd(ercd, E_OK);
+
+ check_point(8);
+ ercd = wup_tsk(TASK4);
+ check_ercd(ercd, E_OK);
+
+ check_point(9);
+ ercd = wup_tsk(TASK5);
+ check_ercd(ercd, E_OK);
+
+ check_point(13);
+ ercd = unl_mtx(MTX3);
+ check_ercd(ercd, E_OK);
+
+ ercd = chg_pri(TSK_SELF, TPRI_INI);
+ check_ercd(ercd, E_OK);
+
+ check_point(14);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(15);
+ ercd = act_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(16);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(17);
+ ercd = rot_rdq(MID_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ check_point(18);
+ ercd = act_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ check_point(19);
+ ercd = wup_tsk(TASK5);
+ check_ercd(ercd, E_OK);
+
+ check_point(20);
+ ercd = ena_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(24);
+ ercd = unl_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(26);
+ ercd = chg_pri(TSK_SELF, TPRI_INI);
+ check_ercd(ercd, E_OK);
+
+ check_point(27);
+ ercd = wup_tsk(TASK5);
+ check_ercd(ercd, E_OK);
+
+ check_point(30);
+ ercd = wup_tsk(TASK4);
+ check_ercd(ercd, E_OK);
+
+ check_point(31);
+ ercd = loc_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(37);
+ ercd = unl_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(38);
+ ercd = chg_pri(TSK_SELF, TPRI_INI);
+ check_ercd(ercd, E_OK);
+
+ check_point(39);
+ ercd = loc_mtx(MTX3);
+ check_ercd(ercd, E_OK);
+
+ check_point(40);
+ ercd = wup_tsk(TASK5);
+ check_ercd(ercd, E_OK);
+
+ check_point(43);
+ ercd = loc_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(49);
+ ercd = unl_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(50);
+ ercd = unl_mtx(MTX3);
+ check_ercd(ercd, E_OK);
+
+ check_point(51);
+ ercd = ter_tsk(TASK4);
+ check_ercd(ercd, E_OK);
+
+ check_point(52);
+ ercd = chg_pri(TSK_SELF, TPRI_INI);
+ check_ercd(ercd, E_OK);
+
+ check_point(53);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(54);
+ ercd = wup_tsk(TASK5);
+ check_ercd(ercd, E_OK);
+
+ check_point(57);
+ ercd = wup_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(58);
+ ercd = rot_rdq(MID_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ check_point(60);
+ ercd = wup_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ check_point(61);
+ ercd = loc_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(67);
+ ercd = unl_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(70);
+ ercd = chg_pri(TSK_SELF, TPRI_INI);
+ check_ercd(ercd, E_OK);
+
+ check_point(71);
+ ercd = rot_rdq(MID_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ check_point(73);
+ ercd = wup_tsk(TASK5);
+ check_ercd(ercd, E_OK);
+
+ check_point(77);
+ ercd = unl_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(78);
+ ercd = ext_tsk();
+
+ check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(23);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(59);
+ ercd = loc_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(66);
+ ercd = unl_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(72);
+ ercd = loc_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_point(79);
+ ercd = unl_mtx(MTX1);
+ check_ercd(ercd, E_OK);
+
+ check_finish(80);
+
+ check_point(0);
+}
+
+void
+task3(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(25);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(62);
+ ercd = loc_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(68);
+ ercd = unl_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(69);
+ ercd = ext_tsk();
+
+ check_point(0);
+}
+
+void
+task4(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(5);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(12);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(32);
+ ercd = loc_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(36);
+ ercd = unl_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(44);
+ ercd = loc_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(48);
+ ercd = unl_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(0);
+}
+
+void
+task5(intptr_t exinf)
+{
+ ER ercd;
+ PRI tskpri;
+
+ check_point(3);
+ ercd = chg_pri(TASK1, LOW_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ check_point(4);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(10);
+ ercd = chg_pri(TASK1, LOW_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ check_point(11);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(21);
+ ercd = chg_pri(TASK1, LOW_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ ercd = get_pri(TASK1, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == MID_PRIORITY);
+
+ check_point(22);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(28);
+ ercd = loc_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(29);
+ ercd = tslp_tsk(10);
+ check_ercd(ercd, E_TMOUT);
+
+ check_point(33);
+ ercd = chg_pri(TASK1, LOW_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ check_point(34);
+ ercd = unl_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(35);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(41);
+ ercd = loc_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(42);
+ ercd = tslp_tsk(10);
+ check_ercd(ercd, E_TMOUT);
+
+ check_point(45);
+ ercd = chg_pri(TASK1, LOW_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ check_point(46);
+ ercd = unl_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(47);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(55);
+ ercd = loc_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(56);
+ ercd = tslp_tsk(10);
+ check_ercd(ercd, E_TMOUT);
+
+ check_point(63);
+ ercd = chg_pri(TASK1, LOW_PRIORITY);
+ check_ercd(ercd, E_OK);
+
+ ercd = get_pri(TASK1, &tskpri);
+ check_ercd(ercd, E_OK);
+ check_assert(tskpri == MID_PRIORITY);
+
+ check_point(64);
+ ercd = unl_mtx(MTX2);
+ check_ercd(ercd, E_OK);
+
+ check_point(65);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(74);
+ ercd = chg_pri(TASK1, HIGH_PRIORITY);
+ check_ercd(ercd, E_ILUSE);
+
+ check_point(75);
+ ercd = chg_pri(TASK2, HIGH_PRIORITY);
+ check_ercd(ercd, E_ILUSE);
+
+ check_point(76);
+ ercd = ext_tsk();
+
+ check_point(0);
+}
--- /dev/null
+/*
+ * @(#) $Id: test_mutex8.cfg 1696 2010-01-01 16:01:25Z ertl-hiro $
+ */
+
+/*
+ * ミューテックスのテスト(8)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+INCLUDE("syssvc/logtask.cfg");
+
+#include "test_mutex8.h"
+
+CRE_TSK(TASK1, { TA_ACT, 1, task1, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task2, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK3, { TA_NULL, 3, task3, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK4, { TA_NULL, 4, task4, LOW_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK5, { TA_NULL, 5, task5, HIGH_PRIORITY, STACK_SIZE, NULL });
+CRE_MTX(MTX1, { TA_CEILING, MID_PRIORITY });
+CRE_MTX(MTX2, { TA_CEILING, HIGH_PRIORITY });
+CRE_MTX(MTX3, { TA_TPRI });
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_mutex8.h 1696 2010-01-01 16:01:25Z ertl-hiro $
+ */
+
+/*
+ * ミューテックスのテスト(8)
+ */
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 優先度の定義
+ */
+#define HIGH_PRIORITY 9 /* 高優先度 */
+#define MID_PRIORITY 10 /* 中優先度 */
+#define LOW_PRIORITY 11 /* 低優先度 */
+
+/*
+ * ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define STACK_SIZE 4096 /* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void task1(intptr_t exinf);
+extern void task2(intptr_t exinf);
+extern void task3(intptr_t exinf);
+extern void task4(intptr_t exinf);
+extern void task5(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: kernel.h 1862 2010-07-25 11:49:51Z ertl-hiro $
+ */
+
+/*
+ * TOPPERS/ASPカーネル 標準ヘッダファイル
+ *
+ * TOPPERS/ASPカーネルがサポートするサービスコールの宣言と,必要なデー
+ * タ型,定数,マクロの定義を含むヘッダファイル.
+ *
+ * アセンブリ言語のソースファイルからこのファイルをインクルードする時
+ * は,TOPPERS_MACRO_ONLYを定義しておく.これにより,マクロ定義以外を
+ * 除くようになっている.
+ *
+ * このファイルをインクルードする前にインクルードしておくべきファイル
+ * はない.
+ */
+
+#ifndef TOPPERS_KERNEL_H
+#define TOPPERS_KERNEL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * TOPPERS共通のデータ型・定数・マクロ
+ */
+#include <t_stddef.h>
+
+/*
+ * ターゲット依存部
+ */
+#include "target_kernel.h"
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ * データ型の定義
+ */
+
+/*
+ * ビットパターンやオブジェクト番号の型定義
+ */
+typedef uint_t TEXPTN; /* タスク例外要因のビットパターン */
+typedef uint_t FLGPTN; /* イベントフラグのビットパターン */
+typedef ulong_t OVRTIM; /* プロセッサ時間 */
+typedef uint_t INTNO; /* 割込み番号 */
+typedef uint_t INHNO; /* 割込みハンドラ番号 */
+typedef uint_t EXCNO; /* CPU例外ハンドラ番号 */
+
+/*
+ * 処理単位の型定義
+ */
+typedef void (*TASK)(intptr_t exinf);
+typedef void (*TEXRTN)(TEXPTN texptn, intptr_t exinf);
+typedef void (*CYCHDR)(intptr_t exinf);
+typedef void (*ALMHDR)(intptr_t exinf);
+typedef void (*OVRHDR)(ID tskid, intptr_t exinf);
+typedef void (*ISR)(intptr_t exinf);
+typedef void (*INTHDR)(void);
+typedef void (*EXCHDR)(void *p_excinf);
+typedef void (*INIRTN)(intptr_t exinf);
+typedef void (*TERRTN)(intptr_t exinf);
+
+/*
+ * メモリ領域確保のための型定義
+ */
+#ifndef TOPPERS_STK_T
+#define TOPPERS_STK_T intptr_t
+#endif /* TOPPERS_STK_T */
+typedef TOPPERS_STK_T STK_T; /* スタック領域を確保するための型 */
+
+#ifndef TOPPERS_MPF_T
+#define TOPPERS_MPF_T intptr_t
+#endif /* TOPPERS_MPF_T */
+typedef TOPPERS_MPF_T MPF_T; /* 固定長メモリプール領域を確保するための型 */
+
+/*
+ * メッセージヘッダの型定義
+ */
+typedef struct t_msg { /* メールボックスのメッセージヘッダ */
+ struct t_msg *pk_next;
+} T_MSG;
+
+typedef struct t_msg_pri { /* 優先度付きメッセージヘッダ */
+ T_MSG msgque; /* メッセージヘッダ */
+ PRI msgpri; /* メッセージ優先度 */
+} T_MSG_PRI;
+
+/*
+ * パケット形式の定義
+ */
+typedef struct t_rtsk {
+ STAT tskstat; /* タスク状態 */
+ PRI tskpri; /* タスクの現在優先度 */
+ PRI tskbpri; /* タスクのベース優先度 */
+ STAT tskwait; /* 待ち要因 */
+ ID wobjid; /* 待ち対象のオブジェクトのID */
+ TMO lefttmo; /* タイムアウトするまでの時間 */
+ uint_t actcnt; /* 起動要求キューイング数 */
+ uint_t wupcnt; /* 起床要求キューイング数 */
+} T_RTSK;
+
+typedef struct t_rtex {
+ STAT texstat; /* タスク例外処理の状態 */
+ TEXPTN pndptn; /* 保留例外要因 */
+} T_RTEX;
+
+typedef struct t_rsem {
+ ID wtskid; /* セマフォの待ち行列の先頭のタスクのID番号 */
+ uint_t semcnt; /* セマフォの現在の資源数 */
+} T_RSEM;
+
+typedef struct t_rflg {
+ ID wtskid; /* イベントフラグの待ち行列の先頭のタスクのID番号 */
+ FLGPTN flgptn; /* イベントフラグの現在のビットパターン */
+} T_RFLG;
+
+typedef struct t_rdtq {
+ ID stskid; /* データキューの送信待ち行列の先頭のタスクのID番号 */
+ ID rtskid; /* データキューの受信待ち行列の先頭のタスクのID番号 */
+ uint_t sdtqcnt; /* データキュー管理領域に格納されているデータの数 */
+} T_RDTQ;
+
+typedef struct t_rpdq {
+ ID stskid; /* 優先度データキューの送信待ち行列の先頭のタスク
+ のID番号 */
+ ID rtskid; /* 優先度データキューの受信待ち行列の先頭のタスク
+ のID番号 */
+ uint_t spdqcnt; /* 優先度データキュー管理領域に格納されているデー
+ タの数 */
+} T_RPDQ;
+
+typedef struct t_rmbx {
+ ID wtskid; /* メールボックスの待ち行列の先頭のタスクのID番号 */
+ T_MSG *pk_msg; /* メッセージキューの先頭につながれたメッセージ
+ の先頭番地 */
+} T_RMBX;
+
+typedef struct t_rmpf {
+ ID wtskid; /* 固定長メモリプールの待ち行列の先頭のタスクの
+ ID番号 */
+ uint_t fblkcnt; /* 固定長メモリプール領域の空きメモリ領域に割り
+ 付けることができる固定長メモリブロックの数 */
+} T_RMPF;
+
+typedef struct t_rcyc {
+ STAT cycstat; /* 周期ハンドラの動作状態 */
+ RELTIM lefttim; /* 次に周期ハンドラを起動する時刻までの相対時間 */
+} T_RCYC;
+
+typedef struct t_ralm {
+ STAT almstat; /* アラームハンドラの動作状態 */
+ RELTIM lefttim; /* アラームハンドラを起動する時刻までの相対時間 */
+} T_RALM;
+
+typedef struct t_rovr {
+ STAT ovrstat; /* オーバランハンドラの動作状態 */
+ OVRTIM leftotm; /* 残りプロセッサ時間 */
+} T_ROVR;
+
+/*
+ * サービスコールの宣言
+ */
+
+/*
+ * タスク管理機能
+ */
+extern ER act_tsk(ID tskid) throw();
+extern ER iact_tsk(ID tskid) throw();
+extern ER_UINT can_act(ID tskid) throw();
+extern ER ext_tsk(void) throw();
+extern ER ter_tsk(ID tskid) throw();
+extern ER chg_pri(ID tskid, PRI tskpri) throw();
+extern ER get_pri(ID tskid, PRI *p_tskpri) throw();
+extern ER get_inf(intptr_t *p_exinf) throw();
+extern ER ref_tsk(ID tskid, T_RTSK *pk_rtsk) throw();
+
+/*
+ * タスク付属同期機能
+ */
+extern ER slp_tsk(void) throw();
+extern ER tslp_tsk(TMO tmout) throw();
+extern ER wup_tsk(ID tskid) throw();
+extern ER iwup_tsk(ID tskid) throw();
+extern ER_UINT can_wup(ID tskid) throw();
+extern ER rel_wai(ID tskid) throw();
+extern ER irel_wai(ID tskid) throw();
+extern ER sus_tsk(ID tskid) throw();
+extern ER rsm_tsk(ID tskid) throw();
+extern ER dly_tsk(RELTIM dlytim) throw();
+
+/*
+ * タスク例外処理機能
+ */
+extern ER ras_tex(ID tskid, TEXPTN rasptn) throw();
+extern ER iras_tex(ID tskid, TEXPTN rasptn) throw();
+extern ER dis_tex(void) throw();
+extern ER ena_tex(void) throw();
+extern bool_t sns_tex(void) throw();
+extern ER ref_tex(ID tskid, T_RTEX *pk_rtex) throw();
+
+/*
+ * 同期・通信機能
+ */
+extern ER sig_sem(ID semid) throw();
+extern ER isig_sem(ID semid) throw();
+extern ER wai_sem(ID semid) throw();
+extern ER pol_sem(ID semid) throw();
+extern ER twai_sem(ID semid, TMO tmout) throw();
+extern ER ini_sem(ID semid) throw();
+extern ER ref_sem(ID semid, T_RSEM *pk_rsem) throw();
+
+extern ER set_flg(ID flgid, FLGPTN setptn) throw();
+extern ER iset_flg(ID flgid, FLGPTN setptn) throw();
+extern ER clr_flg(ID flgid, FLGPTN clrptn) throw();
+extern ER wai_flg(ID flgid, FLGPTN waiptn,
+ MODE wfmode, FLGPTN *p_flgptn) throw();
+extern ER pol_flg(ID flgid, FLGPTN waiptn,
+ MODE wfmode, FLGPTN *p_flgptn) throw();
+extern ER twai_flg(ID flgid, FLGPTN waiptn,
+ MODE wfmode, FLGPTN *p_flgptn, TMO tmout) throw();
+extern ER ini_flg(ID flgid) throw();
+extern ER ref_flg(ID flgid, T_RFLG *pk_rflg) throw();
+
+extern ER snd_dtq(ID dtqid, intptr_t data) throw();
+extern ER psnd_dtq(ID dtqid, intptr_t data) throw();
+extern ER ipsnd_dtq(ID dtqid, intptr_t data) throw();
+extern ER tsnd_dtq(ID dtqid, intptr_t data, TMO tmout) throw();
+extern ER fsnd_dtq(ID dtqid, intptr_t data) throw();
+extern ER ifsnd_dtq(ID dtqid, intptr_t data) throw();
+extern ER rcv_dtq(ID dtqid, intptr_t *p_data) throw();
+extern ER prcv_dtq(ID dtqid, intptr_t *p_data) throw();
+extern ER trcv_dtq(ID dtqid, intptr_t *p_data, TMO tmout) throw();
+extern ER ini_dtq(ID dtqid) throw();
+extern ER ref_dtq(ID dtqid, T_RDTQ *pk_rdtq) throw();
+
+extern ER snd_pdq(ID pdqid, intptr_t data, PRI datapri) throw();
+extern ER psnd_pdq(ID pdqid, intptr_t data, PRI datapri) throw();
+extern ER ipsnd_pdq(ID pdqid, intptr_t data, PRI datapri) throw();
+extern ER tsnd_pdq(ID pdqid, intptr_t data,
+ PRI datapri, TMO tmout) throw();
+extern ER rcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri) throw();
+extern ER prcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri) throw();
+extern ER trcv_pdq(ID pdqid, intptr_t *p_data,
+ PRI *p_datapri, TMO tmout) throw();
+extern ER ini_pdq(ID pdqid) throw();
+extern ER ref_pdq(ID pdqid, T_RPDQ *pk_rpdq) throw();
+
+extern ER snd_mbx(ID mbxid, T_MSG *pk_msg) throw();
+extern ER rcv_mbx(ID mbxid, T_MSG **ppk_msg) throw();
+extern ER prcv_mbx(ID mbxid, T_MSG **ppk_msg) throw();
+extern ER trcv_mbx(ID mbxid, T_MSG **ppk_msg, TMO tmout) throw();
+extern ER ini_mbx(ID mbxid) throw();
+extern ER ref_mbx(ID mbxid, T_RMBX *pk_rmbx) throw();
+
+/*
+ * メモリプール管理機能
+ */
+extern ER get_mpf(ID mpfid, void **p_blk) throw();
+extern ER pget_mpf(ID mpfid, void **p_blk) throw();
+extern ER tget_mpf(ID mpfid, void **p_blk, TMO tmout) throw();
+extern ER rel_mpf(ID mpfid, void *blk) throw();
+extern ER ini_mpf(ID mpfid) throw();
+extern ER ref_mpf(ID mpfid, T_RMPF *pk_rmpf) throw();
+
+/*
+ * 時間管理機能
+ */
+extern ER get_tim(SYSTIM *p_systim) throw();
+extern ER get_utm(SYSUTM *p_sysutm) throw();
+
+extern ER sta_cyc(ID cycid) throw();
+extern ER stp_cyc(ID cycid) throw();
+extern ER ref_cyc(ID cycid, T_RCYC *pk_rcyc) throw();
+
+extern ER sta_alm(ID almid, RELTIM almtim) throw();
+extern ER ista_alm(ID almid, RELTIM almtim) throw();
+extern ER stp_alm(ID almid) throw();
+extern ER istp_alm(ID almid) throw();
+extern ER ref_alm(ID almid, T_RALM *pk_ralm) throw();
+
+extern ER sta_ovr(ID tskid, OVRTIM ovrtim) throw();
+extern ER ista_ovr(ID tskid, OVRTIM ovrtim) throw();
+extern ER stp_ovr(ID tskid) throw();
+extern ER istp_ovr(ID tskid) throw();
+extern ER ref_ovr(ID tskid, T_ROVR *pk_rovr) throw();
+
+/*
+ * システム状態管理機能
+ */
+extern ER rot_rdq(PRI tskpri) throw();
+extern ER irot_rdq(PRI tskpri) throw();
+extern ER get_tid(ID *p_tskid) throw();
+extern ER iget_tid(ID *p_tskid) throw();
+extern ER loc_cpu(void) throw();
+extern ER iloc_cpu(void) throw();
+extern ER unl_cpu(void) throw();
+extern ER iunl_cpu(void) throw();
+extern ER dis_dsp(void) throw();
+extern ER ena_dsp(void) throw();
+extern bool_t sns_ctx(void) throw();
+extern bool_t sns_loc(void) throw();
+extern bool_t sns_dsp(void) throw();
+extern bool_t sns_dpn(void) throw();
+extern bool_t sns_ker(void) throw();
+extern ER ext_ker(void) throw();
+
+/*
+ * 割込み管理機能
+ */
+extern ER dis_int(INTNO intno) throw();
+extern ER ena_int(INTNO intno) throw();
+extern ER chg_ipm(PRI intpri) throw();
+extern ER get_ipm(PRI *p_intpri) throw();
+
+/*
+ * CPU例外管理機能
+ */
+extern bool_t xsns_dpn(void *p_excinf) throw();
+extern bool_t xsns_xpn(void *p_excinf) throw();
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ * オブジェクト属性の定義
+ */
+#define TA_ACT UINT_C(0x02) /* タスクを起動された状態で生成 */
+
+#define TA_TPRI UINT_C(0x01) /* タスクの待ち行列を優先度順に */
+#define TA_MPRI UINT_C(0x02) /* メッセージキューを優先度順に */
+
+#define TA_WMUL UINT_C(0x02) /* 複数の待ちタスク */
+#define TA_CLR UINT_C(0x04) /* イベントフラグのクリア指定 */
+
+#define TA_STA UINT_C(0x02) /* 周期ハンドラを動作状態で生成 */
+
+#define TA_NONKERNEL UINT_C(0x02) /* カーネル管理外の割込み */
+
+#define TA_ENAINT UINT_C(0x01) /* 割込み要求禁止フラグをクリア */
+#define TA_EDGE UINT_C(0x02) /* エッジトリガ */
+
+/*
+ * サービスコールの動作モードの定義
+ */
+#define TWF_ORW UINT_C(0x01) /* イベントフラグのOR待ち */
+#define TWF_ANDW UINT_C(0x02) /* イベントフラグのAND待ち */
+
+/*
+ * オブジェクトの状態の定義
+ */
+#define TTS_RUN UINT_C(0x01) /* 実行状態 */
+#define TTS_RDY UINT_C(0x02) /* 実行可能状態 */
+#define TTS_WAI UINT_C(0x04) /* 待ち状態 */
+#define TTS_SUS UINT_C(0x08) /* 強制待ち状態 */
+#define TTS_WAS UINT_C(0x0c) /* 二重待ち状態 */
+#define TTS_DMT UINT_C(0x10) /* 休止状態 */
+
+#define TTW_SLP UINT_C(0x0001) /* 起床待ち */
+#define TTW_DLY UINT_C(0x0002) /* 時間経過待ち */
+#define TTW_SEM UINT_C(0x0004) /* セマフォの資源獲得待ち */
+#define TTW_FLG UINT_C(0x0008) /* イベントフラグ待ち */
+#define TTW_SDTQ UINT_C(0x0010) /* データキューへの送信待ち */
+#define TTW_RDTQ UINT_C(0x0020) /* データキューからの受信待ち */
+#define TTW_SPDQ UINT_C(0x0100) /* 優先度データキューへの送信待ち */
+#define TTW_RPDQ UINT_C(0x0200) /* 優先度データキューからの受信待ち */
+#define TTW_MBX UINT_C(0x0040) /* メールボックスからの受信待ち */
+#define TTW_MPF UINT_C(0x2000) /* 固定長メモリブロックの獲得待ち */
+
+#define TTEX_ENA UINT_C(0x01) /* タスク例外処理許可状態 */
+#define TTEX_DIS UINT_C(0x02) /* タスク例外処理禁止状態 */
+
+#define TCYC_STP UINT_C(0x01) /* 周期ハンドラが動作していない */
+#define TCYC_STA UINT_C(0x02) /* 周期ハンドラが動作している */
+
+#define TALM_STP UINT_C(0x01) /* アラームハンドラが動作していない */
+#define TALM_STA UINT_C(0x02) /* アラームハンドラが動作している */
+
+#define TOVR_STP UINT_C(0x01) /* オーバランハンドラが動作していない*/
+#define TOVR_STA UINT_C(0x02) /* オーバランハンドラが動作している */
+
+/*
+ * その他の定数の定義
+ */
+#define TSK_SELF 0 /* 自タスク指定 */
+#define TSK_NONE 0 /* 該当するタスクがない */
+
+#define TPRI_SELF 0 /* 自タスクのベース優先度 */
+#define TPRI_INI 0 /* タスクの起動時優先度 */
+
+#define TIPM_ENAALL 0 /* 割込み優先度マスク全解除 */
+
+/*
+ * 構成定数とマクロ
+ */
+
+/*
+ * サポートする機能
+ */
+#ifdef TOPPERS_TARGET_SUPPORT_DIS_INT
+#define TOPPERS_SUPPORT_DIS_INT /* dis_intがサポートされている */
+#endif /* TOPPERS_TARGET_SUPPORT_DIS_INT */
+
+#ifdef TOPPERS_TARGET_SUPPORT_ENA_INT
+#define TOPPERS_SUPPORT_ENA_INT /* ena_intがサポートされている */
+#endif /* TOPPERS_TARGET_SUPPORT_ENA_INT */
+
+#ifdef TOPPERS_TARGET_SUPPORT_GET_UTM
+#define TOPPERS_SUPPORT_GET_UTM /* get_utmがサポートされている */
+#endif /* TOPPERS_TARGET_SUPPORT_GET_UTM */
+
+#ifdef TOPPERS_TARGET_SUPPORT_OVRHDR
+#define TOPPERS_SUPPORT_OVRHDR /* オーバランハンドラ機能拡張 */
+#endif /* TOPPERS_TARGET_SUPPORT_OVRHDR */
+
+/*
+ * 優先度の範囲
+ */
+#define TMIN_TPRI 1 /* タスク優先度の最小値(最高値)*/
+#define TMAX_TPRI 16 /* タスク優先度の最大値(最低値)*/
+#define TMIN_DPRI 1 /* データ優先度の最小値(最高値)*/
+#define TMAX_DPRI 16 /* データ優先度の最大値(最低値)*/
+#define TMIN_MPRI 1 /* メッセージ優先度の最小値(最高値)*/
+#define TMAX_MPRI 16 /* メッセージ優先度の最大値(最低値)*/
+#define TMIN_ISRPRI 1 /* 割込みサービスルーチン優先度の最小値 */
+#define TMAX_ISRPRI 16 /* 割込みサービスルーチン優先度の最大値 */
+
+/*
+ * バージョン情報
+ */
+#define TKERNEL_MAKER UINT_C(0x0118) /* カーネルのメーカーコード */
+#define TKERNEL_PRID UINT_C(0x0007) /* カーネルの識別番号 */
+#define TKERNEL_SPVER UINT_C(0xf512) /* カーネル仕様のバージョン番号 */
+#define TKERNEL_PRVER UINT_C(0x1060) /* カーネルのバージョン番号 */
+
+/*
+ * キューイング回数の最大値
+ */
+#define TMAX_ACTCNT UINT_C(1) /* 起動要求キューイング数の最大値 */
+#define TMAX_WUPCNT UINT_C(1) /* 起床要求キューイング数の最大値 */
+
+/*
+ * ビットパターンのビット数
+ */
+#ifndef TBIT_TEXPTN /* タスク例外要因のビット数 */
+#define TBIT_TEXPTN (sizeof(TEXPTN) * CHAR_BIT)
+#endif /* TBIT_TEXPTN */
+
+#ifndef TBIT_FLGPTN /* イベントフラグのビット数 */
+#define TBIT_FLGPTN (sizeof(FLGPTN) * CHAR_BIT)
+#endif /* TBIT_FLGPTN */
+
+/*
+ * プロセッサ時間(OVRTIM)の最大値
+ */
+#ifndef TMAX_OVRTIM
+#define TMAX_OVRTIM ULONG_MAX
+#endif /* TMAX_OVRTIM */
+
+/*
+ * メモリ領域確保のためのマクロ
+ *
+ * 以下のTOPPERS_COUNT_SZとTOPPERS_ROUND_SZの定義は,unitが2の巾乗であ
+ * ることを仮定している.
+ */
+#ifndef TOPPERS_COUNT_SZ
+#define TOPPERS_COUNT_SZ(sz, unit) (((sz) + (unit) - 1) / (unit))
+#endif /* TOPPERS_COUNT_SZ */
+#ifndef TOPPERS_ROUND_SZ
+#define TOPPERS_ROUND_SZ(sz, unit) (((sz) + (unit) - 1) & ~((unit) - 1))
+#endif /* TOPPERS_ROUND_SZ */
+
+#define COUNT_STK_T(sz) TOPPERS_COUNT_SZ(sz, sizeof(STK_T))
+#define ROUND_STK_T(sz) TOPPERS_ROUND_SZ(sz, sizeof(STK_T))
+
+#define COUNT_MPF_T(blksz) TOPPERS_COUNT_SZ(blksz, sizeof(MPF_T))
+#define ROUND_MPF_T(blksz) TOPPERS_ROUND_SZ(blksz, sizeof(MPF_T))
+
+/*
+ * その他の構成定数
+ */
+#define TMAX_MAXSEM UINT_MAX /* セマフォの最大資源数の最大値 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_KERNEL_H */
--- /dev/null
+#
+# TOPPERS/ASP Kernel
+# Toyohashi Open Platform for Embedded Real-Time Systems/
+# Advanced Standard Profile Kernel
+#
+# Copyright (C) 2003 by Embedded and Real-Time Systems Laboratory
+# Toyohashi Univ. of Technology, JAPAN
+# Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+# Graduate School of Information Science, Nagoya Univ., JAPAN
+#
+# 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+# スコード中に含まれていること.
+# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+# の無保証規定を掲載すること.
+# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+# と.
+# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+# 作権表示,この利用条件および下記の無保証規定を掲載すること.
+# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+# 報告すること.
+# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+# 免責すること.
+#
+# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+# の責任を負わない.
+#
+# @(#) $Id: Makefile.kernel 1717 2010-01-31 11:41:03Z ertl-hiro $
+#
+
+#
+# カーネルのファイル構成の定義
+#
+
+#
+# 1つのソースファイルから複数のオブジェクトファイルを生成するように作
+# 成されたソースファイルのリスト
+#
+KERNEL_FCSRCS = startup.c task.c wait.c time_event.c \
+ task_manage.c task_refer.c task_sync.c task_except.c \
+ semaphore.c eventflag.c dataqueue.c pridataq.c mailbox.c \
+ mempfix.c time_manage.c cyclic.c alarm.c overrun.c \
+ sys_manage.c interrupt.c exception.c
+
+#
+# 各ソースファイルから生成されるオブジェクトファイルのリスト
+#
+startup = sta_ker.o ext_ker.o
+
+task = tskini.o tsksched.o tskrun.o tsknrun.o \
+ tskdmt.o tskact.o tskpri.o tskrot.o tsktex.o
+
+wait = waimake.o waicmp.o waitmo.o waitmook.o \
+ wairel.o wobjwai.o wobjwaitmo.o iniwque.o
+
+time_event = tmeini.o tmeup.o tmedown.o tmeins.o tmedel.o tmeltim.o sigtim.o
+
+task_manage = act_tsk.o iact_tsk.o can_act.o ext_tsk.o ter_tsk.o \
+ chg_pri.o get_pri.o get_inf.o
+
+task_refer = ref_tsk.o
+
+task_sync = slp_tsk.o tslp_tsk.o wup_tsk.o iwup_tsk.o can_wup.o \
+ rel_wai.o irel_wai.o sus_tsk.o rsm_tsk.o dly_tsk.o
+
+task_except = ras_tex.o iras_tex.o dis_tex.o ena_tex.o sns_tex.o ref_tex.o
+
+semaphore = semini.o sig_sem.o isig_sem.o \
+ wai_sem.o pol_sem.o twai_sem.o ini_sem.o ref_sem.o
+
+eventflag = flgini.o flgcnd.o set_flg.o iset_flg.o clr_flg.o \
+ wai_flg.o pol_flg.o twai_flg.o ini_flg.o ref_flg.o
+
+dataqueue = dtqini.o dtqenq.o dtqfenq.o dtqdeq.o dtqsnd.o dtqfsnd.o dtqrcv.o \
+ snd_dtq.o psnd_dtq.o ipsnd_dtq.o tsnd_dtq.o fsnd_dtq.o ifsnd_dtq.o \
+ rcv_dtq.o prcv_dtq.o trcv_dtq.o ini_dtq.o ref_dtq.o
+
+pridataq = pdqini.o pdqenq.o pdqdeq.o pdqsnd.o pdqrcv.o \
+ snd_pdq.o psnd_pdq.o ipsnd_pdq.o tsnd_pdq.o \
+ rcv_pdq.o prcv_pdq.o trcv_pdq.o ini_pdq.o ref_pdq.o
+
+mailbox = mbxini.o snd_mbx.o rcv_mbx.o prcv_mbx.o trcv_mbx.o \
+ ini_mbx.o ref_mbx.o
+
+mempfix = mpfini.o mpfget.o get_mpf.o pget_mpf.o tget_mpf.o \
+ rel_mpf.o ini_mpf.o ref_mpf.o
+
+time_manage = get_tim.o get_utm.o
+
+cyclic = cycini.o sta_cyc.o stp_cyc.o ref_cyc.o cyccal.o
+
+alarm = almini.o sta_alm.o ista_alm.o stp_alm.o istp_alm.o ref_alm.o almcal.o
+
+overrun = ovrini.o ovrsta.o ovrstp.o sta_ovr.o ista_ovr.o \
+ stp_ovr.o istp_ovr.o ref_ovr.o ovrcal.o
+
+sys_manage = rot_rdq.o irot_rdq.o get_tid.o iget_tid.o \
+ loc_cpu.o iloc_cpu.o unl_cpu.o iunl_cpu.o dis_dsp.o ena_dsp.o \
+ sns_ctx.o sns_loc.o sns_dsp.o sns_dpn.o sns_ker.o
+
+interrupt = intini.o dis_int.o ena_int.o chg_ipm.o get_ipm.o
+
+exception = excini.o xsns_dpn.o xsns_xpn.o
+
+#
+# 生成されるオブジェクトファイルの依存関係の定義
+#
+$(startup) $(startup:.o=.s) $(startup:.o=.d): startup.c
+$(task) $(task:.o=.s) $(task:.o=.d): task.c
+$(wait) $(wait:.o=.s) $(wait:.o=.d): wait.c
+$(time_event) $(time_event:.o=.s) $(time_event:.o=.d): time_event.c
+$(task_manage) $(task_manage:.o=.s) $(task_manage:.o=.d): task_manage.c
+$(task_refer) $(task_refer:.o=.s) $(task_refer:.o=.d): task_refer.c
+$(task_sync) $(task_sync:.o=.s) $(task_sync:.o=.d): task_sync.c
+$(task_except) $(task_except:.o=.s) $(task_except:.o=.d): task_except.c
+$(semaphore) $(semaphore:.o=.s) $(semaphore:.o=.d): semaphore.c
+$(eventflag) $(eventflag:.o=.s) $(eventflag:.o=.d): eventflag.c
+$(dataqueue) $(dataqueue:.o=.s) $(dataqueue:.o=.d): dataqueue.c
+$(pridataq) $(pridataq:.o=.s) $(pridataq:.o=.d): pridataq.c
+$(mailbox) $(mailbox:.o=.s) $(mailbox:.o=.d): mailbox.c
+$(mempfix) $(mempfix:.o=.s) $(mempfix:.o=.d): mempfix.c
+$(time_manage) $(time_manage:.o=.s) $(time_manage:.o=.d): time_manage.c
+$(cyclic) $(cyclic:.o=.s) $(cyclic:.o=.d): cyclic.c
+$(alarm) $(alarm:.o=.s) $(alarm:.o=.d): alarm.c
+$(overrun) $(overrun:.o=.s) $(overrun:.o=.d): overrun.c
+$(sys_manage) $(sys_manage:.o=.s) $(sys_manage:.o=.d): sys_manage.c
+$(interrupt) $(interrupt:.o=.s) $(interrupt:.o=.d): interrupt.c
+$(exception) $(exception:.o=.s) $(exception:.o=.d): exception.c
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: allfunc.h 1717 2010-01-31 11:41:03Z ertl-hiro $
+ */
+
+/*
+ * すべての関数をコンパイルするための定義
+ */
+
+#ifndef TOPPERS_ALLFUNC_H
+#define TOPPERS_ALLFUNC_H
+
+/* startup.c */
+#define TOPPERS_sta_ker
+#define TOPPERS_ext_ker
+
+/* task.c */
+#define TOPPERS_tskini
+#define TOPPERS_tsksched
+#define TOPPERS_tskrun
+#define TOPPERS_tsknrun
+#define TOPPERS_tskdmt
+#define TOPPERS_tskact
+#define TOPPERS_tskpri
+#define TOPPERS_tskrot
+#define TOPPERS_tsktex
+
+/* wait.c */
+#define TOPPERS_waimake
+#define TOPPERS_waicmp
+#define TOPPERS_waitmo
+#define TOPPERS_waitmook
+#define TOPPERS_wairel
+#define TOPPERS_wobjwai
+#define TOPPERS_wobjwaitmo
+#define TOPPERS_iniwque
+
+/* time_event.c */
+#define TOPPERS_tmeini
+#define TOPPERS_tmeup
+#define TOPPERS_tmedown
+#define TOPPERS_tmeins
+#define TOPPERS_tmedel
+#define TOPPERS_tmeltim
+#define TOPPERS_sigtim
+
+/* task_manage.c */
+#define TOPPERS_act_tsk
+#define TOPPERS_iact_tsk
+#define TOPPERS_can_act
+#define TOPPERS_ext_tsk
+#define TOPPERS_ter_tsk
+#define TOPPERS_chg_pri
+#define TOPPERS_get_pri
+#define TOPPERS_get_inf
+
+/* task_refer.c */
+#define TOPPERS_ref_tsk
+
+/* task_sync.c */
+#define TOPPERS_slp_tsk
+#define TOPPERS_tslp_tsk
+#define TOPPERS_wup_tsk
+#define TOPPERS_iwup_tsk
+#define TOPPERS_can_wup
+#define TOPPERS_rel_wai
+#define TOPPERS_irel_wai
+#define TOPPERS_sus_tsk
+#define TOPPERS_rsm_tsk
+#define TOPPERS_dly_tsk
+
+/* task_except.c */
+#define TOPPERS_ras_tex
+#define TOPPERS_iras_tex
+#define TOPPERS_dis_tex
+#define TOPPERS_ena_tex
+#define TOPPERS_sns_tex
+#define TOPPERS_ref_tex
+
+/* semaphore.c */
+#define TOPPERS_semini
+#define TOPPERS_sig_sem
+#define TOPPERS_isig_sem
+#define TOPPERS_wai_sem
+#define TOPPERS_pol_sem
+#define TOPPERS_twai_sem
+#define TOPPERS_ini_sem
+#define TOPPERS_ref_sem
+
+/* eventflag.c */
+#define TOPPERS_flgini
+#define TOPPERS_flgcnd
+#define TOPPERS_set_flg
+#define TOPPERS_iset_flg
+#define TOPPERS_clr_flg
+#define TOPPERS_wai_flg
+#define TOPPERS_pol_flg
+#define TOPPERS_twai_flg
+#define TOPPERS_ini_flg
+#define TOPPERS_ref_flg
+
+/* dataqueue.c */
+#define TOPPERS_dtqini
+#define TOPPERS_dtqenq
+#define TOPPERS_dtqfenq
+#define TOPPERS_dtqdeq
+#define TOPPERS_dtqsnd
+#define TOPPERS_dtqfsnd
+#define TOPPERS_dtqrcv
+#define TOPPERS_snd_dtq
+#define TOPPERS_psnd_dtq
+#define TOPPERS_ipsnd_dtq
+#define TOPPERS_tsnd_dtq
+#define TOPPERS_fsnd_dtq
+#define TOPPERS_ifsnd_dtq
+#define TOPPERS_rcv_dtq
+#define TOPPERS_prcv_dtq
+#define TOPPERS_trcv_dtq
+#define TOPPERS_ini_dtq
+#define TOPPERS_ref_dtq
+
+/* pridataq.c */
+#define TOPPERS_pdqini
+#define TOPPERS_pdqenq
+#define TOPPERS_pdqdeq
+#define TOPPERS_pdqsnd
+#define TOPPERS_pdqrcv
+#define TOPPERS_snd_pdq
+#define TOPPERS_psnd_pdq
+#define TOPPERS_ipsnd_pdq
+#define TOPPERS_tsnd_pdq
+#define TOPPERS_rcv_pdq
+#define TOPPERS_prcv_pdq
+#define TOPPERS_trcv_pdq
+#define TOPPERS_ini_pdq
+#define TOPPERS_ref_pdq
+
+/* mailbox.c */
+#define TOPPERS_mbxini
+#define TOPPERS_snd_mbx
+#define TOPPERS_rcv_mbx
+#define TOPPERS_prcv_mbx
+#define TOPPERS_trcv_mbx
+#define TOPPERS_ini_mbx
+#define TOPPERS_ref_mbx
+
+/* mempfix.c */
+#define TOPPERS_mpfini
+#define TOPPERS_mpfget
+#define TOPPERS_get_mpf
+#define TOPPERS_pget_mpf
+#define TOPPERS_tget_mpf
+#define TOPPERS_rel_mpf
+#define TOPPERS_ini_mpf
+#define TOPPERS_ref_mpf
+
+/* time_manage.c */
+#define TOPPERS_get_tim
+#define TOPPERS_get_utm
+
+/* cyclic.c */
+#define TOPPERS_cycini
+#define TOPPERS_sta_cyc
+#define TOPPERS_stp_cyc
+#define TOPPERS_ref_cyc
+#define TOPPERS_cyccal
+
+/* alarm.c */
+#define TOPPERS_almini
+#define TOPPERS_sta_alm
+#define TOPPERS_ista_alm
+#define TOPPERS_stp_alm
+#define TOPPERS_istp_alm
+#define TOPPERS_ref_alm
+#define TOPPERS_almcal
+
+/* overrun.c */
+#define TOPPERS_ovrini
+#define TOPPERS_ovrsta
+#define TOPPERS_ovrstp
+#define TOPPERS_sta_ovr
+#define TOPPERS_ista_ovr
+#define TOPPERS_stp_ovr
+#define TOPPERS_istp_ovr
+#define TOPPERS_ref_ovr
+#define TOPPERS_ovrcal
+
+/* sys_manage.c */
+#define TOPPERS_rot_rdq
+#define TOPPERS_irot_rdq
+#define TOPPERS_get_tid
+#define TOPPERS_iget_tid
+#define TOPPERS_loc_cpu
+#define TOPPERS_iloc_cpu
+#define TOPPERS_unl_cpu
+#define TOPPERS_iunl_cpu
+#define TOPPERS_dis_dsp
+#define TOPPERS_ena_dsp
+#define TOPPERS_sns_ctx
+#define TOPPERS_sns_loc
+#define TOPPERS_sns_dsp
+#define TOPPERS_sns_dpn
+#define TOPPERS_sns_ker
+
+/* interrupt.c */
+#define TOPPERS_intini
+#define TOPPERS_dis_int
+#define TOPPERS_ena_int
+#define TOPPERS_chg_ipm
+#define TOPPERS_get_ipm
+
+/* exception.c */
+#define TOPPERS_excini
+#define TOPPERS_xsns_dpn
+#define TOPPERS_xsns_xpn
+
+#endif /* TOPPERS_ALLFUNC_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: check.h 1717 2010-01-31 11:41:03Z ertl-hiro $
+ */
+
+/*
+ * エラーチェック用マクロ
+ */
+
+#ifndef TOPPERS_CHECK_H
+#define TOPPERS_CHECK_H
+
+/*
+ * 優先度の範囲の判定
+ */
+#define VALID_TPRI(tpri) (TMIN_TPRI <= (tpri) && (tpri) <= TMAX_TPRI)
+
+#ifndef VALID_INTPRI_CHGIPM
+#define VALID_INTPRI_CHGIPM(intpri) \
+ (TMIN_INTPRI <= (intpri) && (intpri) <= TIPM_ENAALL)
+#endif /* VALID_INTPRI_CHGIPM */
+
+/*
+ * タスク優先度のチェック(E_PAR)
+ */
+#define CHECK_TPRI(tpri) { \
+ if (!VALID_TPRI(tpri)) { \
+ ercd = E_PAR; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_TPRI_INI(tpri) { \
+ if (!(VALID_TPRI(tpri) || (tpri) == TPRI_INI)) { \
+ ercd = E_PAR; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_TPRI_SELF(tpri) { \
+ if (!(VALID_TPRI(tpri) || (tpri) == TPRI_SELF)) { \
+ ercd = E_PAR; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * タイムアウト指定値のチェック(E_PAR)
+ */
+#define CHECK_TMOUT(tmout) { \
+ if (!(TMO_FEVR <= (tmout))) { \
+ ercd = E_PAR; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * 割込み優先度のチェック(E_PAR)
+ */
+#define CHECK_INTPRI_CHGIPM(inttpri) { \
+ if (!VALID_INTPRI_CHGIPM(intpri)) { \
+ ercd = E_PAR; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * 割込み番号のチェック(E_PAR)
+ */
+#define CHECK_INTNO_DISINT(intno) { \
+ if (!VALID_INTNO_DISINT(intno)) { \
+ ercd = E_PAR; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * その他のパラメータエラーのチェック(E_PAR)
+ */
+#define CHECK_PAR(exp) { \
+ if (!(exp)) { \
+ ercd = E_PAR; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * オブジェクトIDの範囲の判定
+ */
+#define VALID_TSKID(tskid) (TMIN_TSKID <= (tskid) && (tskid) <= tmax_tskid)
+#define VALID_SEMID(semid) (TMIN_SEMID <= (semid) && (semid) <= tmax_semid)
+#define VALID_FLGID(flgid) (TMIN_FLGID <= (flgid) && (flgid) <= tmax_flgid)
+#define VALID_DTQID(dtqid) (TMIN_DTQID <= (dtqid) && (dtqid) <= tmax_dtqid)
+#define VALID_PDQID(pdqid) (TMIN_PDQID <= (pdqid) && (pdqid) <= tmax_pdqid)
+#define VALID_MBXID(mbxid) (TMIN_MBXID <= (mbxid) && (mbxid) <= tmax_mbxid)
+#define VALID_MPFID(mpfid) (TMIN_MPFID <= (mpfid) && (mpfid) <= tmax_mpfid)
+#define VALID_CYCID(cycid) (TMIN_CYCID <= (cycid) && (cycid) <= tmax_cycid)
+#define VALID_ALMID(almid) (TMIN_ALMID <= (almid) && (almid) <= tmax_almid)
+
+/*
+ * オブジェクトIDのチェック(E_ID)
+ */
+#define CHECK_TSKID(tskid) { \
+ if (!VALID_TSKID(tskid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_TSKID_SELF(tskid) { \
+ if (!(VALID_TSKID(tskid) || (tskid) == TSK_SELF)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_SEMID(semid) { \
+ if (!VALID_SEMID(semid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_FLGID(flgid) { \
+ if (!VALID_FLGID(flgid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_DTQID(dtqid) { \
+ if (!VALID_DTQID(dtqid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_PDQID(pdqid) { \
+ if (!VALID_PDQID(pdqid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_MBXID(mbxid) { \
+ if (!VALID_MBXID(mbxid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_MPFID(mpfid) { \
+ if (!VALID_MPFID(mpfid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_CYCID(cycid) { \
+ if (!VALID_CYCID(cycid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_ALMID(almid) { \
+ if (!VALID_ALMID(almid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * 呼出しコンテキストのチェック(E_CTX)
+ */
+#define CHECK_TSKCTX() { \
+ if (sense_context()) { \
+ ercd = E_CTX; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_INTCTX() { \
+ if (!sense_context()) { \
+ ercd = E_CTX; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * 呼出しコンテキストとCPUロック状態のチェック(E_CTX)
+ */
+#define CHECK_TSKCTX_UNL() { \
+ if (sense_context() || t_sense_lock()) { \
+ ercd = E_CTX; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_INTCTX_UNL() { \
+ if (!sense_context() || i_sense_lock()) { \
+ ercd = E_CTX; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * ディスパッチ保留状態でないかのチェック(E_CTX)
+ */
+#define CHECK_DISPATCH() { \
+ if (sense_context() || t_sense_lock() || !dspflg) { \
+ ercd = E_CTX; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * その他のコンテキストエラーのチェック(E_CTX)
+ */
+#define CHECK_CTX(exp) { \
+ if (!(exp)) { \
+ ercd = E_CTX; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * 自タスクを指定していないかのチェック(E_ILUSE)
+ */
+#define CHECK_NONSELF(p_tcb) { \
+ if ((p_tcb) == p_runtsk) { \
+ ercd = E_ILUSE; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * その他の不正使用エラーのチェック(E_ILUSE)
+ */
+#define CHECK_ILUSE(exp) { \
+ if (!(exp)) { \
+ ercd = E_ILUSE; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * 静的なオブジェクト状態エラーのチェック(E_OBJ)
+ */
+#define CHECK_OBJ(exp) { \
+ if (!(exp)) { \
+ ercd = E_OBJ; \
+ goto error_exit; \
+ } \
+}
+
+#endif /* TOPPERS_CHECK_H */
--- /dev/null
+$ ======================================================================
+$
+$ TOPPERS/ASP Kernel
+$ Toyohashi Open Platform for Embedded Real-Time Systems/
+$ Advanced Standard Profile Kernel
+$
+$ Copyright (C) 2007 by TAKAGI Nobuhisa
+$ Copyright (C) 2007-2010 by Embedded and Real-Time Systems Laboratory
+$ Graduate School of Information Science, Nagoya Univ., JAPAN
+$
+$ 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+$ ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+$ 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+$ (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+$ 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+$ スコード中に含まれていること.
+$ (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+$ 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+$ 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+$ の無保証規定を掲載すること.
+$ (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+$ 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+$ と.
+$ (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+$ 作権表示,この利用条件および下記の無保証規定を掲載すること.
+$ (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+$ 報告すること.
+$ (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+$ 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+$ また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+$ 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+$ 免責すること.
+$
+$ 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+$ よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+$ に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+$ アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+$ の責任を負わない.
+$
+$ $Id: kernel.tf 1845 2010-07-11 13:02:57Z ertl-hiro $
+$
+$ =====================================================================
+
+$ =====================================================================
+$ kernel_cfg.hの生成
+$ =====================================================================
+
+$FILE "kernel_cfg.h"$
+/* kernel_cfg.h */$NL$
+#ifndef TOPPERS_KERNEL_CFG_H$NL$
+#define TOPPERS_KERNEL_CFG_H$NL$
+$NL$
+#define TNUM_TSKID $LENGTH(TSK.ID_LIST)$$NL$
+#define TNUM_SEMID $LENGTH(SEM.ID_LIST)$$NL$
+#define TNUM_FLGID $LENGTH(FLG.ID_LIST)$$NL$
+#define TNUM_DTQID $LENGTH(DTQ.ID_LIST)$$NL$
+#define TNUM_PDQID $LENGTH(PDQ.ID_LIST)$$NL$
+#define TNUM_MBXID $LENGTH(MBX.ID_LIST)$$NL$
+#define TNUM_MPFID $LENGTH(MPF.ID_LIST)$$NL$
+#define TNUM_CYCID $LENGTH(CYC.ID_LIST)$$NL$
+#define TNUM_ALMID $LENGTH(ALM.ID_LIST)$$NL$
+$NL$
+$FOREACH id TSK.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id SEM.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id FLG.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id DTQ.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id PDQ.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id MBX.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id MPF.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id CYC.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id ALM.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$NL$
+#endif /* TOPPERS_KERNEL_CFG_H */$NL$
+
+$ =====================================================================
+$ kernel_cfg.cの生成
+$ =====================================================================
+
+$FILE "kernel_cfg.c"$
+/* kernel_cfg.c */$NL$
+#include "kernel/kernel_int.h"$NL$
+#include "kernel_cfg.h"$NL$
+$NL$
+#ifndef TOPPERS_EMPTY_LABEL$NL$
+#define TOPPERS_EMPTY_LABEL(x,y) x y[0]$NL$
+#endif$NL$
+$NL$
+#if TKERNEL_PRID != 0x07u$NL$
+#error The kernel does not match this configuration file.$NL$
+#endif$NL$
+$NL$
+
+$
+$ インクルードディレクティブ(#include)
+$
+/*$NL$
+$SPC$* Include Directives (#include)$NL$
+$SPC$*/$NL$
+$NL$
+$INCLUDES$
+$NL$
+
+$
+$ オブジェクトのID番号を保持する変数
+$
+$IF USE_EXTERNAL_ID$
+ /*$NL$
+ $SPC$* Variables for Object ID$NL$
+ $SPC$*/$NL$
+ $NL$
+ $FOREACH id TSK.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id SEM.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id FLG.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id DTQ.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id PDQ.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id MBX.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id MPF.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id CYC.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id ALM.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+$END$
+
+$
+$ トレースログマクロのデフォルト定義
+$
+/*$NL$
+$SPC$* Default Definitions of Trace Log Macros$NL$
+$SPC$*/$NL$
+$NL$
+#ifndef LOG_ISR_ENTER$NL$
+#define LOG_ISR_ENTER(intno)$NL$
+#endif /* LOG_ISR_ENTER */$NL$
+$NL$
+#ifndef LOG_ISR_LEAVE$NL$
+#define LOG_ISR_LEAVE(intno)$NL$
+#endif /* LOG_ISR_LEAVE */$NL$
+$NL$
+
+$
+$ タスク
+$
+/*$NL$
+$SPC$* Task Management Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ タスクが1個以上存在することのチェック
+$IF !LENGTH(TSK.ID_LIST)$
+ $ERROR$$FORMAT("no task is registered")$$END$
+$END$
+
+$ タスクID番号の最大値
+const ID _kernel_tmax_tskid = (TMIN_TSKID + TNUM_TSKID - 1);$NL$
+$NL$
+
+$ エラーチェック
+$FOREACH tskid TSK.ID_LIST$
+$ // tskatrが([TA_ACT])でない場合(E_RSATR)
+ $IF (TSK.TSKATR[tskid] & ~(TA_ACT|ALT(TARGET_TSKATR,0))) != 0$
+ $ERROR TSK.TEXT_LINE[tskid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "tskatr", TSK.TSKATR[tskid], tskid, "CRE_TSK")$$END$
+ $END$
+
+$ // (TMIN_TPRI <= itskpri && itskpri <= TMAX_TPRI)でない場合(E_PAR)
+ $IF !(TMIN_TPRI <= TSK.ITSKPRI[tskid] && TSK.ITSKPRI[tskid] <= TMAX_TPRI)$
+ $ERROR TSK.TEXT_LINE[tskid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "itskpri", TSK.ITSKPRI[tskid], tskid, "CRE_TSK")$$END$
+ $END$
+
+$ // texatrが(TA_NULL)でない場合(E_RSATR)
+ $IF LENGTH(TSK.TEXATR[tskid]) && TSK.TEXATR[tskid] != 0$
+ $ERROR DEF_TEX.TEXT_LINE[tskid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "texatr", TSK.TEXATR[tskid], tskid, "DEF_TEX")$$END$
+ $END$
+$END$
+
+$ スタック領域の生成とそれに関するエラーチェック
+$FOREACH tskid TSK.ID_LIST$
+$ // stkszが0か,ターゲット定義の最小値(TARGET_MIN_STKSZ)よりも小さい場合(E_PAR)
+ $IF TSK.STKSZ[tskid] == 0 || (LENGTH(TARGET_MIN_STKSZ) &&
+ TSK.STKSZ[tskid] < TARGET_MIN_STKSZ)$
+ $ERROR TSK.TEXT_LINE[tskid]$E_PAR: $FORMAT(_("%1% `%2%\' of `%3%\' in %4% is too small"), "stksz", TSK.STKSZ[tskid], tskid, "CRE_TSK")$$END$
+ $END$
+$ // stkszがスタック領域のサイズとして正しくない場合(E_PAR)
+ $IF !EQ(TSK.STK[tskid], "NULL") && LENGTH(CHECK_STKSZ_ALIGN)
+ && (TSK.STKSZ[tskid] & (CHECK_STKSZ_ALIGN - 1))$
+ $ERROR TSK.TEXT_LINE[tskid]$E_PAR: $FORMAT(_("%1% `%2%\' of `%3%\' in %4% is not aligned"), "stksz", TSK.STKSZ[tskid], tskid, "CRE_TSK")$$END$
+ $END$
+
+ $IF EQ(TSK.STK[tskid],"NULL")$
+ static STK_T _kernel_stack_$tskid$[COUNT_STK_T($TSK.STKSZ[tskid]$)];$NL$
+ $TSK.TINIB_STKSZ[tskid] = FORMAT("ROUND_STK_T(%1%)", TSK.STKSZ[tskid])$
+ $TSK.TINIB_STK[tskid] = CONCAT("_kernel_stack_", tskid)$
+ $ELSE$
+ $TSK.TINIB_STKSZ[tskid] = TSK.STKSZ[tskid]$
+ $TSK.TINIB_STK[tskid] = TSK.STK[tskid]$
+ $END$
+$END$
+$NL$
+
+$ タスク初期化ブロックの生成(タスクは1個以上存在する)
+const TINIB _kernel_tinib_table[TNUM_TSKID] = {$NL$
+$JOINEACH tskid TSK.ID_LIST ",\n"$
+$ // タスク属性,拡張情報,起動番地,起動時優先度
+ $TAB${
+ $SPC$($TSK.TSKATR[tskid]$), (intptr_t)($TSK.EXINF[tskid]$),
+ $SPC$($TSK.TASK[tskid]$), INT_PRIORITY($TSK.ITSKPRI[tskid]$),
+
+$ // タスク初期化コンテキストブロック,スタック領域
+ $IF ALT(USE_TSKINICTXB,0)$
+ $GENERATE_TSKINICTXB(tskid)$
+ $ELSE$
+ $SPC$$TSK.TINIB_STKSZ[tskid]$, $TSK.TINIB_STK[tskid]$,
+ $END$
+
+$ // タスク例外処理ルーチンの属性と起動番地
+ $SPC$($ALT(TSK.TEXATR[tskid],"TA_NULL")$), ($ALT(TSK.TEXRTN[tskid],"NULL")$) }
+$END$$NL$
+};$NL$
+$NL$
+
+$ タスクコントロールブロックの生成
+TCB _kernel_tcb_table[TNUM_TSKID];$NL$
+$NL$
+
+$ タスク生成順序テーブルの生成
+const ID _kernel_torder_table[TNUM_TSKID] = {$NL$
+$TAB$$JOINEACH tskid TSK.ORDER_LIST ", "$$tskid$$END$$NL$
+};$NL$
+$NL$
+
+$
+$ セマフォ
+$
+/*$NL$
+$SPC$* Semaphore Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ セマフォID番号の最大値
+const ID _kernel_tmax_semid = (TMIN_SEMID + TNUM_SEMID - 1);$NL$
+$NL$
+
+$ セマフォ初期化ブロックの生成
+$IF LENGTH(SEM.ID_LIST)$
+ const SEMINIB _kernel_seminib_table[TNUM_SEMID] = {$NL$
+ $JOINEACH semid SEM.ID_LIST ",\n"$
+$ // sematrが([TA_TPRI])でない場合(E_RSATR)
+ $IF (SEM.SEMATR[semid] & ~TA_TPRI) != 0$
+ $ERROR SEM.TEXT_LINE[semid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "sematr", SEM.SEMATR[semid], semid, "CRE_SEM")$$END$
+ $END$
+
+$ // (0 <= isemcnt && isemcnt <= maxsem)でない場合(E_PAR)
+ $IF !(0 <= SEM.ISEMCNT[semid] && SEM.ISEMCNT[semid] <= SEM.MAXSEM[semid])$
+ $ERROR SEM.TEXT_LINE[semid]$E_PAR: $FORMAT(_("too large %1% `%2%\' of `%3%\' in %4%"), "isemcnt", SEM.ISEMCNT[semid], semid, "CRE_SEM")$$END$
+ $END$
+
+$ // (1 <= maxsem && maxsem <= TMAX_MAXSEM)でない場合(E_PAR)
+ $IF !(1 <= SEM.MAXSEM[semid] && SEM.MAXSEM[semid] <= TMAX_MAXSEM)$
+ $ERROR SEM.TEXT_LINE[semid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "maxsem", SEM.MAXSEM[semid], semid, "CRE_SEM")$$END$
+ $END$
+
+$ // セマフォ初期化ブロック
+ $TAB${ ($SEM.SEMATR[semid]$), ($SEM.ISEMCNT[semid]$), ($SEM.MAXSEM[semid]$) }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // セマフォコントロールブロック
+ SEMCB _kernel_semcb_table[TNUM_SEMID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const SEMINIB, _kernel_seminib_table);$NL$
+ TOPPERS_EMPTY_LABEL(SEMCB, _kernel_semcb_table);$NL$
+$END$
+$NL$
+
+$
+$ イベントフラグ
+$
+/*$NL$
+$SPC$* Eventflag Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ イベントフラグID番号の最大値
+const ID _kernel_tmax_flgid = (TMIN_FLGID + TNUM_FLGID - 1);$NL$
+$NL$
+
+$ イベントフラグ初期化ブロックの生成
+$IF LENGTH(FLG.ID_LIST)$
+ const FLGINIB _kernel_flginib_table[TNUM_FLGID] = {$NL$
+ $JOINEACH flgid FLG.ID_LIST ",\n"$
+$ // flgatrが([TA_TPRI]|[TA_WMUL]|[TA_CLR])でない場合(E_RSATR)
+ $IF (FLG.FLGATR[flgid] & ~(TA_TPRI|TA_WMUL|TA_CLR)) != 0$
+ $ERROR FLG.TEXT_LINE[flgid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "flgatr", FLG.FLGATR[flgid], flgid, "CRE_FLG")$$END$
+ $END$
+
+$ // イベントフラグ初期化ブロック
+ $TAB${ ($FLG.FLGATR[flgid]$), ($FLG.IFLGPTN[flgid]$) }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // イベントフラグコントロールブロック
+ FLGCB _kernel_flgcb_table[TNUM_FLGID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const FLGINIB, _kernel_flginib_table);$NL$
+ TOPPERS_EMPTY_LABEL(FLGCB, _kernel_flgcb_table);$NL$
+$END$
+$NL$
+
+$
+$ データキュー
+$
+/*$NL$
+$SPC$* Dataqueue Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ データキューID番号の最大値
+const ID _kernel_tmax_dtqid = (TMIN_DTQID + TNUM_DTQID - 1);$NL$
+$NL$
+
+$IF LENGTH(DTQ.ID_LIST)$
+ $FOREACH dtqid DTQ.ID_LIST$
+$ // dtqatrが([TA_TPRI])でない場合(E_RSATR)
+ $IF (DTQ.DTQATR[dtqid] & ~TA_TPRI) != 0$
+ $ERROR DTQ.TEXT_LINE[dtqid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "dtqatr", DTQ.DTQATR[dtqid], dtqid, "CRE_DTQ")$$END$
+ $END$
+
+$ // dtqmbがNULLでない場合(E_NOSPT)
+ $IF !EQ(DTQ.DTQMB[dtqid], "NULL")$
+ $ERROR DTQ.TEXT_LINE[dtqid]$E_NOSPT: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "dtqmb", DTQ.DTQMB[dtqid], dtqid, "CRE_DTQ")$$END$
+ $END$
+
+$ // データキュー領域
+ $IF DTQ.DTQCNT[dtqid]$
+ static intptr_t _kernel_dtqmb_$dtqid$[$DTQ.DTQCNT[dtqid]$];$NL$
+ $END$
+ $END$
+
+$ // データキュー初期化ブロックの生成
+ const DTQINIB _kernel_dtqinib_table[TNUM_DTQID] = {$NL$
+ $JOINEACH dtqid DTQ.ID_LIST ",\n"$
+ $TAB${ ($DTQ.DTQATR[dtqid]$), ($DTQ.DTQCNT[dtqid]$), $IF DTQ.DTQCNT[dtqid]$(_kernel_dtqmb_$dtqid$)$ELSE$NULL$END$ }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // データキューコントロールブロック
+ DTQCB _kernel_dtqcb_table[TNUM_DTQID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const DTQINIB, _kernel_dtqinib_table);$NL$
+ TOPPERS_EMPTY_LABEL(DTQCB, _kernel_dtqcb_table);$NL$
+$END$
+$NL$
+
+$
+$ 優先度データキュー
+$
+/*$NL$
+$SPC$* Priority Dataqueue Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 優先度データキューID番号の最大値
+const ID _kernel_tmax_pdqid = (TMIN_PDQID + TNUM_PDQID - 1);$NL$
+$NL$
+
+$IF LENGTH(PDQ.ID_LIST)$
+ $FOREACH pdqid PDQ.ID_LIST$
+$ // pdqatrが([TA_TPRI])でない場合(E_RSATR)
+ $IF (PDQ.PDQATR[pdqid] & ~TA_TPRI) != 0$
+ $ERROR PDQ.TEXT_LINE[pdqid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "pdqatr", PDQ.PDQATR[pdqid], pdqid, "CRE_PDQ")$$END$
+ $END$
+
+$ // (TMIN_DPRI <= maxdpri && maxdpri <= TMAX_DPRI)でない場合(E_PAR)
+ $IF !(TMIN_DPRI <= PDQ.MAXDPRI[pdqid] && PDQ.MAXDPRI[pdqid] <= TMAX_DPRI)$
+ $ERROR PDQ.TEXT_LINE[pdqid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "maxdpri", PDQ.MAXDPRI[pdqid], pdqid, "CRE_PDQ")$$END$
+ $END$
+
+$ // pdqmbがNULLでない場合(E_NOSPT)
+ $IF !EQ(PDQ.PDQMB[pdqid], "NULL")$
+ $ERROR PDQ.TEXT_LINE[pdqid]$E_NOSPT: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "pdqmb", PDQ.PDQMB[pdqid], pdqid, "CRE_PDQ")$$END$
+ $END$
+
+$ // 優先度データキュー領域
+ $IF PDQ.PDQCNT[pdqid]$
+ static PDQMB _kernel_pdqmb_$pdqid$[$PDQ.PDQCNT[pdqid]$];$NL$
+ $END$
+ $END$
+
+$ // 優先度データキュー初期化ブロックの生成
+ const PDQINIB _kernel_pdqinib_table[TNUM_PDQID] = {$NL$
+ $JOINEACH pdqid PDQ.ID_LIST ",\n"$
+ $TAB${ ($PDQ.PDQATR[pdqid]$), ($PDQ.PDQCNT[pdqid]$), ($PDQ.MAXDPRI[pdqid]$), $IF PDQ.PDQCNT[pdqid]$(_kernel_pdqmb_$pdqid$)$ELSE$NULL$END$ }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // 優先度データキューコントロールブロック
+ PDQCB _kernel_pdqcb_table[TNUM_PDQID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const PDQINIB, _kernel_pdqinib_table);$NL$
+ TOPPERS_EMPTY_LABEL(PDQCB, _kernel_pdqcb_table);$NL$
+$END$
+$NL$
+
+$
+$ メールボックス
+$
+/*$NL$
+$SPC$* Mailbox Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ メールボックスID番号の最大値
+const ID _kernel_tmax_mbxid = (TMIN_MBXID + TNUM_MBXID - 1);$NL$
+$NL$
+
+$ メールボックス初期化ブロックの生成
+$IF LENGTH(MBX.ID_LIST)$
+ const MBXINIB _kernel_mbxinib_table[TNUM_MBXID] = {$NL$
+ $JOINEACH mbxid MBX.ID_LIST ",\n"$
+$ // mbxatrが([TA_TPRI]|[TA_MPRI])でない場合(E_RSATR)
+ $IF (MBX.MBXATR[mbxid] & ~(TA_TPRI|TA_MPRI)) != 0$
+ $ERROR MBX.TEXT_LINE[mbxid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mbxatr", MBX.MBXATR[mbxid], mbxid, "CRE_MBX")$$END$
+ $END$
+
+$ // (TMIN_MPRI <= maxmpri && maxmpri <= TMAX_MPRI)でない場合(E_PAR)
+ $IF !(TMIN_MPRI <= MBX.MAXMPRI[mbxid] && MBX.MAXMPRI[mbxid] <= TMAX_MPRI)$
+ $ERROR MBX.TEXT_LINE[mbxid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "maxmpri", MBX.MAXMPRI[mbxid], mbxid, "CRE_MBX")$$END$
+ $END$
+
+$ // mprihdがNULLでない場合(E_NOSPT)
+ $IF !EQ(MBX.MPRIHD[mbxid], "NULL")$
+ $ERROR MBX.TEXT_LINE[mbxid]$E_NOSPT: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mprihd", MBX.MPRIHD[mbxid], mbxid, "CRE_MBX")$$END$
+ $END$
+
+$ // メールボックス初期化ブロック
+ $TAB${ ($MBX.MBXATR[mbxid]$), ($MBX.MAXMPRI[mbxid]$) }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // メールボックスコントロールブロック
+ MBXCB _kernel_mbxcb_table[TNUM_MBXID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const MBXINIB, _kernel_mbxinib_table);$NL$
+ TOPPERS_EMPTY_LABEL(MBXCB, _kernel_mbxcb_table);$NL$
+$END$
+$NL$
+
+$
+$ 固定長メモリプール
+$
+/*$NL$
+$SPC$* Fixed-sized Memorypool Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 固定長メモリプールID番号の最大値
+const ID _kernel_tmax_mpfid = (TMIN_MPFID + TNUM_MPFID - 1);$NL$
+$NL$
+
+$IF LENGTH(MPF.ID_LIST)$
+ $FOREACH mpfid MPF.ID_LIST$
+$ // mpfatrが([TA_TPRI])でない場合(E_RSATR)
+ $IF (MPF.MPFATR[mpfid] & ~TA_TPRI) != 0$
+ $ERROR MPF.TEXT_LINE[mpfid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mpfatr", MPF.MPFATR[mpfid], mpfid, "CRE_MPF")$$END$
+ $END$
+
+$ // blkcntが0の場合(E_PAR)
+ $IF MPF.BLKCNT[mpfid] == 0$
+ $ERROR MPF.TEXT_LINE[mpfid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "blkcnt", MPF.BLKCNT[mpfid], mpfid, "CRE_MPF")$$END$
+ $END$
+
+$ // blkszが0の場合(E_PAR)
+ $IF MPF.BLKSZ[mpfid] == 0$
+ $ERROR MPF.TEXT_LINE[mpfid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "blksz", MPF.BLKSZ[mpfid], mpfid, "CRE_MPF")$$END$
+ $END$
+
+$ // 固定長メモリプール領域
+ $IF EQ(MPF.MPF[mpfid], "NULL")$
+ static MPF_T _kernel_mpf_$mpfid$[($MPF.BLKCNT[mpfid]$) * COUNT_MPF_T($MPF.BLKSZ[mpfid]$)];$NL$
+ $END$
+
+$ // mpfmbがNULLでない場合(E_NOSPT)
+ $IF !EQ(MPF.MPFMB[mpfid], "NULL")$
+ $ERROR MPF.TEXT_LINE[mpfid]$E_NOSPT: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mpfmb", MPF.MPFMB[mpfid], mpfid, "CRE_MPF")$$END$
+ $END$
+
+$ // 固定長メモリプール管理領域
+ static MPFMB _kernel_mpfmb_$mpfid$[$MPF.BLKCNT[mpfid]$];$NL$
+ $END$
+
+$ // 固定長メモリプール初期化ブロックの生成
+ const MPFINIB _kernel_mpfinib_table[TNUM_MPFID] = {$NL$
+ $JOINEACH mpfid MPF.ID_LIST ",\n"$
+ $TAB${ ($MPF.MPFATR[mpfid]$), ($MPF.BLKCNT[mpfid]$), ROUND_MPF_T($MPF.BLKSZ[mpfid]$), $IF EQ(MPF.MPF[mpfid],"NULL")$(_kernel_mpf_$mpfid$)$ELSE$($MPF.MPF[mpfid]$)$END$, (_kernel_mpfmb_$mpfid$) }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // 固定長メモリプールコントロールブロック
+ MPFCB _kernel_mpfcb_table[TNUM_MPFID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const MPFINIB, _kernel_mpfinib_table);$NL$
+ TOPPERS_EMPTY_LABEL(MPFCB, _kernel_mpfcb_table);$NL$
+$END$
+$NL$
+
+$
+$ 周期ハンドラ
+$
+/*$NL$
+$SPC$* Cyclic Handler Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 周期ハンドラID番号の最大値
+const ID _kernel_tmax_cycid = (TMIN_CYCID + TNUM_CYCID - 1);$NL$
+$NL$
+
+$ 周期ハンドラ初期化テーブルの生成
+$IF LENGTH(CYC.ID_LIST)$
+ const CYCINIB _kernel_cycinib_table[TNUM_CYCID] = {$NL$
+ $JOINEACH cycid CYC.ID_LIST ",\n"$
+$ // cycatrが([TA_STA])でない場合(E_RSATR)
+ $IF (CYC.CYCATR[cycid] & ~TA_STA) != 0$
+ $ERROR CYC.TEXT_LINE[cycid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "cycatr", CYC.CYCATR[cycid], cycid, "CRE_CYC")$$END$
+ $END$
+
+$ // (0 < cyctim && cyctim <= TMAX_RELTIM)でない場合(E_PAR)
+ $IF !(0 < CYC.CYCTIM[cycid] && CYC.CYCTIM[cycid] <= TMAX_RELTIM)$
+ $ERROR CYC.TEXT_LINE[cycid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "cyctim", CYC.CYCTIM[cycid], cycid, "CRE_CYC")$$END$
+ $END$
+
+$ // (0 <= cycphs && cycphs <= TMAX_RELTIM)でない場合(E_PAR)
+ $IF !(0 <= CYC.CYCPHS[cycid] && CYC.CYCPHS[cycid] <= TMAX_RELTIM)$
+ $ERROR CYC.TEXT_LINE[cycid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "cycphs", CYC.CYCPHS[cycid], cycid, "CRE_CYC")$$END$
+ $END$
+
+$ // 警告:cycatrにTA_STAが設定されていて,(cycphs == 0)の場合
+ $IF (CYC.CYCATR[cycid] & TA_STA) != 0 && CYC.CYCPHS[cycid] == 0$
+ $WARNING CYC.TEXT_LINE[cycid]$$FORMAT(_("%1% is not recommended when %2% is set to %3% in %4%"), "cycphs==0", "TA_STA", "cycatr", "CRE_CYC")$$END$
+ $END$
+
+$ // 周期ハンドラ初期化ブロック
+ $TAB${ ($CYC.CYCATR[cycid]$), (intptr_t)($CYC.EXINF[cycid]$), ($CYC.CYCHDR[cycid]$), ($CYC.CYCTIM[cycid]$), ($CYC.CYCPHS[cycid]$) }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // 周期ハンドラコントロールブロック
+ CYCCB _kernel_cyccb_table[TNUM_CYCID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const CYCINIB, _kernel_cycinib_table);$NL$
+ TOPPERS_EMPTY_LABEL(CYCCB, _kernel_cyccb_table);$NL$
+$END$
+$NL$
+
+$
+$ アラームハンドラ
+$
+/*$NL$
+$SPC$* Alarm Handler Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ アラームハンドラID番号の最大値
+const ID _kernel_tmax_almid = (TMIN_ALMID + TNUM_ALMID - 1);$NL$
+$NL$
+
+$ アラームハンドラ初期化ブロックの生成
+$IF LENGTH(ALM.ID_LIST)$
+ const ALMINIB _kernel_alminib_table[TNUM_ALMID] = {$NL$
+ $JOINEACH almid ALM.ID_LIST ",\n"$
+$ // almatrが(TA_NULL)でない場合(E_RSATR)
+ $IF ALM.ALMATR[almid] != 0$
+ $ERROR ALM.TEXT_LINE[almid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "almatr", ALM.ALMATR[almid], almid, "CRE_ALM")$$END$
+ $END$
+
+$ // アラームハンドラ初期化ブロック
+ $TAB${ ($ALM.ALMATR[almid]$), (intptr_t)($ALM.EXINF[almid]$), ($ALM.ALMHDR[almid]$) }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // アラームハンドラコントロールブロック
+ ALMCB _kernel_almcb_table[TNUM_ALMID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const ALMINIB, _kernel_alminib_table);$NL$
+ TOPPERS_EMPTY_LABEL(ALMCB, _kernel_almcb_table);$NL$
+$END$
+$NL$
+
+$
+$ オーバランハンドラ
+$
+/*$NL$
+$SPC$* Overrun Handler Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ // 静的API「DEF_OVR」が複数ある(E_OBJ)
+$IF LENGTH(OVR.ORDER_LIST) > 1$
+ $ERROR$E_OBJ: $FORMAT(_("too many %1%"), "DEF_OVR")$$END$
+$END$
+
+$ オーバランハンドラ初期化ブロックの生成
+#ifdef TOPPERS_SUPPORT_OVRHDR$NL$$NL$
+const OVRINIB _kernel_ovrinib = {$NL$
+$IF LENGTH(OVR.ORDER_LIST)$
+ $TAB$($OVR.OVRATR[1]$), ($OVR.OVRHDR[1]$)$NL$
+$ELSE$
+ $TAB$TA_NULL, NULL$NL$
+$END$
+};$NL$$NL$
+#endif /* TOPPERS_SUPPORT_OVRHDR */$NL$
+$NL$
+
+$
+$ 割込み管理機能
+$
+/*$NL$
+$SPC$* Interrupt Management Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 割込み番号と割込みハンドラ番号の変換テーブルの作成
+$IF LENGTH(INTNO_ATTISR_VALID) != LENGTH(INHNO_ATTISR_VALID)$
+ $ERROR$length of `INTNO_ATTISR_VALID' is different from length of `INHNO_ATTISR_VALID'$END$
+$END$
+$i = 0$
+$FOREACH intno INTNO_ATTISR_VALID$
+ $inhno = AT(INHNO_ATTISR_VALID, i)$
+ $INHNO[intno] = inhno$
+ $INTNO[inhno] = intno$
+ $i = i + 1$
+$END$
+
+$ 割込み要求ラインに関するエラーチェック
+$i = 0$
+$FOREACH intno INT.ORDER_LIST$
+$ // intnoがCFG_INTに対する割込み番号として正しくない場合(E_PAR)
+ $IF !LENGTH(FIND(INTNO_CFGINT_VALID, INT.INTNO[intno]))$
+ $ERROR INT.TEXT_LINE[intno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "intno", INT.INTNO[intno], "CFG_INT")$$END$
+ $END$
+
+$ // intnoがCFG_INTによって設定済みの場合(E_OBJ)
+ $j = 0$
+ $FOREACH intno2 INT.ORDER_LIST$
+ $IF INT.INTNO[intno] == INT.INTNO[intno2] && j < i$
+ $ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' in %3% is duplicated"), "intno", INT.INTNO[intno], "CFG_INT")$$END$
+ $END$
+ $j = j + 1$
+ $END$
+
+$ // intatrが([TA_ENAINT]|[TA_EDGE])でない場合(E_RSATR)
+ $IF (INT.INTATR[intno] & ~(TA_ENAINT|TA_EDGE|ALT(TARGET_INTATR,0))) != 0$
+ $ERROR INT.TEXT_LINE[intno]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "intatr", INT.INTATR[intno], "intno", INT.INTNO[intno], "CFG_INT")$$END$
+ $END$
+
+$ // intpriがCFG_INTに対する割込み優先度として正しくない場合(E_PAR)
+ $IF !LENGTH(FIND(INTPRI_CFGINT_VALID, INT.INTPRI[intno]))$
+ $ERROR INT.TEXT_LINE[intno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "intpri", INT.INTPRI[intno], "CFG_INT")$$END$
+ $END$
+
+$ // カーネル管理に固定されているintnoに対して,intpriにTMIN_INTPRI
+$ // よりも小さい値が指定された場合(E_OBJ)
+ $IF LENGTH(FIND(INTNO_FIX_KERNEL, intno))$
+ $IF INT.INTPRI[intno] < TMIN_INTPRI$
+ $ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' must not have higher priority than %3%"), "intno", INT.INTNO[intno], "TMIN_INTPRI")$$END$
+ $END$
+ $END$
+
+$ // カーネル管理外に固定されているintnoに対して,intpriにTMIN_INTPRI
+$ // よりも小さい値が指定されなかった場合(E_OBJ)
+ $IF LENGTH(FIND(INTNO_FIX_NONKERNEL, intno))$
+ $IF INT.INTPRI[intno] >= TMIN_INTPRI$
+ $ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' must have higher priority than %3%"), "intno", INT.INTNO[intno], "TMIN_INTPRI")$$END$
+ $END$
+ $END$
+ $i = i + 1$
+$END$
+
+$ 割込みハンドラに関するエラーチェック
+$i = 0$
+$FOREACH inhno INH.ORDER_LIST$
+$ // inhnoがDEF_INHに対する割込みハンドラ番号として正しくない場合(E_PAR)
+ $IF !LENGTH(FIND(INHNO_DEFINH_VALID, INH.INHNO[inhno]))$
+ $ERROR INH.TEXT_LINE[inhno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "inhno", INH.INHNO[inhno], "DEF_INH")$$END$
+ $END$
+
+$ // inhnoがDEF_INHによって設定済みの場合(E_OBJ)
+ $j = 0$
+ $FOREACH inhno2 INH.ORDER_LIST$
+ $IF INH.INHNO[inhno] == INH.INHNO[inhno2] && j < i$
+ $ERROR INH.TEXT_LINE[inhno]$E_OBJ: $FORMAT(_("%1% `%2%\' in %3% is duplicated"), "inhno", INH.INHNO[inhno], "DEF_INH")$$END$
+ $END$
+ $j = j + 1$
+ $END$
+
+$ // inhatrが(TA_NULL)でない場合(E_RSATR)
+ $IF (INH.INHATR[inhno] & ~ALT(TARGET_INHATR,0)) != 0$
+ $ERROR INH.TEXT_LINE[inhno]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "inhatr", INH.INHATR[inhno], "inhno", INH.INHNO[inhno], "DEF_INH")$$END$
+ $END$
+
+$ // カーネル管理に固定されているinhnoに対して,inhatrにTA_NONKERNEL
+$ // が指定されている場合(E_RSATR)
+ $IF LENGTH(FIND(INHNO_FIX_KERNEL, inhno))$
+ $IF (INH.INHATR[inhno] & TA_NONKERNEL) != 0$
+ $ERROR INH.TEXT_LINE[inhno]$E_RSATR: $FORMAT(_("%1% `%2%\' must not be non-kernel interrupt"), "inhno", INH.INHNO[inhno])$$END$
+ $END$
+ $END$
+
+$ // カーネル管理外に固定されているinhnoに対して,inhatrにTA_NONKERNEL
+$ // が指定されていない場合(E_RSATR)
+ $IF LENGTH(FIND(INHNO_FIX_NONKERNEL, inhno))$
+ $IF (INH.INHATR[inhno] & TA_NONKERNEL) == 0$
+ $ERROR INH.TEXT_LINE[inhno]$E_RSATR: $FORMAT(_("%1% `%2%\' must be non-kernel interrupt"), "inhno", INH.INHNO[inhno])$$END$
+ $END$
+ $END$
+
+ $IF LENGTH(INTNO[INH.INHNO[inhno]])$
+ $intno = INTNO[INH.INHNO[inhno]]$
+ $IF LENGTH(FIND(INTNO_CFGINT_VALID, intno))$
+$ // inhnoに対応するintnoに対するCFG_INTがない場合(E_OBJ)
+ $IF !LENGTH(INT.INTNO[intno])$
+ $ERROR INH.TEXT_LINE[inhno]$E_OBJ: $FORMAT(_("%1% `%2%\' corresponding to %3% `%4%\' is not configured with %5%"), "intno", INT.INTNO[intno], "inhno", INH.INHNO[inhno], "CFG_INT")$$END$
+ $ELSE$
+ $IF (INH.INHATR[inhno] & TA_NONKERNEL) == 0$
+$ // inhatrにTA_NONKERNELが指定されておらず,inhnoに対応
+$ // するintnoに対してCFG_INTで設定された割込み優先度が
+$ // TMIN_INTPRIよりも小さい場合(E_OBJ)
+ $IF INT.INTPRI[intno] < TMIN_INTPRI$
+ $ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' configured for %3% `%4%\' is higher than %5%"), "intpri", INT.INTPRI[intno], "inhno", INH.INHNO[inhno], "TMIN_INTPRI")$$END$
+ $END$
+ $ELSE$
+$ // inhatrにTA_NONKERNELが指定されており,inhnoに対応
+$ // するintnoに対してCFG_INTで設定された割込み優先度が
+$ // TMIN_INTPRI以上である場合(E_OBJ)
+ $IF INT.INTPRI[intno] >= TMIN_INTPRI$
+ $ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' configured for %3% `%4%\' is lower than or equal to %5%"), "intpri", INT.INTPRI[intno], "inhno", INH.INHNO[inhno], "TMIN_INTPRI")$$END$
+ $END$
+ $END$
+ $END$
+ $END$
+ $END$
+ $i = i + 1$
+$END$
+
+$ 割込みサービスルーチン(ISR)に関するエラーチェックと割込みハンドラの生成
+$FOREACH order ISR.ORDER_LIST$
+$ // isratrが(TA_NULL)でない場合(E_RSATR)
+ $IF (ISR.ISRATR[order] & ~ALT(TARGET_ISRATR,0)) != 0$
+ $ERROR ISR.TEXT_LINE[order]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "isratr", ISR.ISRATR[order], "isr", ISR.ISR[order], "ATT_ISR")$$END$
+ $END$
+
+$ // intnoがATT_ISRに対する割込み番号として正しくない場合(E_PAR)
+ $IF !LENGTH(FIND(INTNO_ATTISR_VALID, ISR.INTNO[order]))$
+ $ERROR ISR.TEXT_LINE[order]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "intno", ISR.INTNO[order], "ATT_ISR")$$END$
+ $END$
+
+$ // (TMIN_ISRPRI <= isrpri && isrpri <= TMAX_ISRPRI)でない場合(E_PAR)
+ $IF !(TMIN_ISRPRI <= ISR.ISRPRI[order] && ISR.ISRPRI[order] <= TMAX_ISRPRI)$
+ $ERROR ISR.TEXT_LINE[order]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "isrpri", ISR.ISRPRI[order], "ATT_ISR")$$END$
+ $END$
+$END$
+
+$FOREACH intno INTNO_ATTISR_VALID$
+ $inhno = INHNO[intno]$
+
+$ // 割込み番号intnoに対して登録されたISRのリストの作成
+ $isr_order_list = {}$
+ $FOREACH order ISR.ORDER_LIST$
+ $IF ISR.INTNO[order] == intno$
+ $isr_order_list = APPEND(isr_order_list, order)$
+ $order_for_error = order$
+ $END$
+ $END$
+
+$ // 割込み番号intnoに対して登録されたISRが存在する場合
+ $IF LENGTH(isr_order_list) > 0$
+$ // intnoに対応するinhnoに対してDEF_INHがある場合(E_OBJ)
+ $IF LENGTH(INH.INHNO[inhno])$
+ $ERROR ISR.TEXT_LINE[order_for_error]$E_OBJ: $FORMAT(_("%1% `%2%\' in %3% is duplicated with %4% `%5%\'"), "intno", ISR.INTNO[order_for_error], "ATT_ISR", "inhno", INH.INHNO[inhno])$$END$
+ $END$
+
+$ // intnoに対するCFG_INTがない場合(E_OBJ)
+ $IF !LENGTH(INT.INTNO[intno])$
+ $ERROR ISR.TEXT_LINE[order_for_error]$E_OBJ: $FORMAT(_("%1% `%2%\' is not configured with %3%"), "intno", ISR.INTNO[order_for_error], "CFG_INT")$$END$
+ $ELSE$
+$ // intnoに対してCFG_INTで設定された割込み優先度がTMIN_INTPRI
+$ // よりも小さい場合(E_OBJ)
+ $IF INT.INTPRI[intno] < TMIN_INTPRI$
+ $ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' configured for %3% `%4%\' is higher than %5%"), "intpri", INT.INTPRI[intno], "intno", ISR.INTNO[order_for_error], "TMIN_INTPRI")$$END$
+ $END$
+ $END$
+
+$ // DEF_INH(inhno, { TA_NULL, _kernel_inthdr_<intno> } );
+ $INH.INHNO[inhno] = inhno$
+ $INH.INHATR[inhno] = VALUE("TA_NULL", 0)$
+ $INH.INTHDR[inhno] = CONCAT("_kernel_inthdr_", intno)$
+ $INH.ORDER_LIST = APPEND(INH.ORDER_LIST, inhno)$
+
+$ // ISR用の割込みハンドラ
+ void$NL$
+ _kernel_inthdr_$intno$(void)$NL$
+ {$NL$
+ $IF LENGTH(isr_order_list) > 1$
+ $TAB$PRI saved_ipm;$NL$
+ $NL$
+ $TAB$i_begin_int($intno$);$NL$
+ $TAB$saved_ipm = i_get_ipm();$NL$
+ $ELSE$
+ $TAB$i_begin_int($intno$);$NL$
+ $END$
+$ // ISRを優先度順に呼び出す
+ $JOINEACH order SORT(isr_order_list, "ISR.ISRPRI") "\tif (i_sense_lock()) {\n\t\ti_unlock_cpu();\n\t}\n\ti_set_ipm(saved_ipm);\n"$
+ $TAB$LOG_ISR_ENTER($intno$);$NL$
+ $TAB$((ISR)($ISR.ISR[order]$))((intptr_t)($ISR.EXINF[order]$));$NL$
+ $TAB$LOG_ISR_LEAVE($intno$);$NL$
+ $END$
+ $TAB$i_end_int($intno$);$NL$
+ }$NL$
+ $END$
+$END$
+$NL$
+
+$
+$ 割込み管理機能のための標準的な初期化情報の生成
+$
+$ 割込みハンドラの初期化に必要な情報
+$IF !ALT(OMIT_INITIALIZE_INTERRUPT,0) || ALT(USE_INHINIB_TABLE,0)$
+
+$ 割込みハンドラ数
+#define TNUM_INHNO $LENGTH(INH.ORDER_LIST)$$NL$
+const uint_t _kernel_tnum_inhno = TNUM_INHNO;$NL$
+$NL$
+$FOREACH inhno INH.ORDER_LIST$
+ $IF (INH.INHATR[inhno] & TA_NONKERNEL) == 0$
+ INTHDR_ENTRY($INH.INHNO[inhno]$, $+INH.INHNO[inhno]$, $INH.INTHDR[inhno]$)$NL$
+ $END$
+$END$
+$NL$
+
+$ 割込みハンドラ初期化テーブル
+$IF LENGTH(INH.ORDER_LIST)$
+ const INHINIB _kernel_inhinib_table[TNUM_INHNO] = {$NL$
+ $JOINEACH inhno INH.ORDER_LIST ",\n"$
+ $IF (INH.INHATR[inhno] & TA_NONKERNEL) == 0$
+ $TAB${ ($INH.INHNO[inhno]$), ($INH.INHATR[inhno]$), (FP)(INT_ENTRY($INH.INHNO[inhno]$, $INH.INTHDR[inhno]$)) }
+ $ELSE$
+ $TAB${ ($INH.INHNO[inhno]$), ($INH.INHATR[inhno]$), (FP)($INH.INTHDR[inhno]$) }
+ $END$
+ $END$$NL$
+ };$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const INHINIB, _kernel_inhinib_table);$NL$
+$END$
+$NL$
+$END$
+
+$ 割込み要求ラインの初期化に必要な情報
+$IF !ALT(OMIT_INITIALIZE_INTERRUPT,0) || ALT(USE_INHINTB_TABLE,0)$
+
+$ 割込み要求ライン数
+#define TNUM_INTNO $LENGTH(INT.ORDER_LIST)$$NL$
+const uint_t _kernel_tnum_intno = TNUM_INTNO;$NL$
+$NL$
+
+$ 割込み要求ライン初期化テーブル
+$IF LENGTH(INT.ORDER_LIST)$
+ const INTINIB _kernel_intinib_table[TNUM_INTNO] = {$NL$
+ $JOINEACH intno INT.ORDER_LIST ",\n"$
+ $TAB${ ($INT.INTNO[intno]$), ($INT.INTATR[intno]$), ($INT.INTPRI[intno]$) }
+ $END$$NL$
+ };$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const INTINIB, _kernel_intinib_table);$NL$
+$END$
+$NL$
+$END$
+
+$
+$ CPU例外管理機能
+$
+/*$NL$
+$SPC$* CPU Exception Management Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ CPU例外ハンドラに関するエラーチェック
+$i = 0$
+$FOREACH excno EXC.ORDER_LIST$
+$ // excnoがDEF_EXCに対するCPU例外ハンドラ番号として正しくない場合(E_PAR)
+ $IF !LENGTH(FIND(EXCNO_DEFEXC_VALID, EXC.EXCNO[excno]))$
+ $ERROR EXC.TEXT_LINE[excno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "excno", EXC.EXCNO[excno], "DEF_EXC")$$END$
+ $END$
+
+$ // excnoがDEF_EXCによって設定済みの場合(E_OBJ)
+ $j = 0$
+ $FOREACH excno2 EXC.ORDER_LIST$
+ $IF EXC.EXCNO[excno] == EXC.EXCNO[excno2] && j < i$
+ $ERROR EXC.TEXT_LINE[excno]$E_OBJ: $FORMAT(_("%1% `%2%\' in %3% is duplicated"), "excno", EXC.EXCNO[excno], "DEF_EXC")$$END$
+ $END$
+ $j = j + 1$
+ $END$
+
+$ // excatrが(TA_NULL)でない場合(E_RSATR)
+ $IF (EXC.EXCATR[excno] & ~ALT(TARGET_EXCATR,0)) != 0$
+ $ERROR EXC.TEXT_LINE[excno]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "excatr", EXC.EXCATR[excno], "excno", EXC.EXCNO[excno], "DEF_EXC")$$END$
+ $END$
+ $i = i + 1$
+$END$
+
+$ CPU例外ハンドラのための標準的な初期化情報の生成
+$IF !ALT(OMIT_INITIALIZE_EXCEPTION,0)$
+
+$ CPU例外ハンドラ数
+#define TNUM_EXCNO $LENGTH(EXC.ORDER_LIST)$$NL$
+const uint_t _kernel_tnum_excno = TNUM_EXCNO;$NL$
+$NL$
+$FOREACH excno EXC.ORDER_LIST$
+ EXCHDR_ENTRY($EXC.EXCNO[excno]$, $+EXC.EXCNO[excno]$, $EXC.EXCHDR[excno]$)$NL$
+$END$
+$NL$
+
+$ CPU例外ハンドラ初期化テーブル
+$IF LENGTH(EXC.ORDER_LIST)$
+ const EXCINIB _kernel_excinib_table[TNUM_EXCNO] = {$NL$
+ $JOINEACH excno EXC.ORDER_LIST ",\n"$
+ $TAB${ ($EXC.EXCNO[excno]$), ($EXC.EXCATR[excno]$), (FP)(EXC_ENTRY($EXC.EXCNO[excno]$, $EXC.EXCHDR[excno]$)) }
+ $END$$NL$
+ };$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const EXCINIB, _kernel_excinib_table);$NL$
+$END$
+$NL$
+$END$
+
+$
+$ 非タスクコンテキスト用のスタック領域
+$
+/*$NL$
+$SPC$* Stack Area for Non-task Context$NL$
+$SPC$*/$NL$
+$NL$
+
+$IF !LENGTH(ICS.ORDER_LIST)$
+$ // DEF_ICSがない場合のデフォルト値の設定
+ #ifdef DEFAULT_ISTK$NL$
+ $NL$
+ #define TOPPERS_ISTKSZ DEFAULT_ISTKSZ$NL$
+ #define TOPPERS_ISTK DEFAULT_ISTK$NL$
+ $NL$
+ #else /* DEAULT_ISTK */$NL$
+ $NL$
+ static STK_T _kernel_istack[COUNT_STK_T(DEFAULT_ISTKSZ)];$NL$
+ #define TOPPERS_ISTKSZ ROUND_STK_T(DEFAULT_ISTKSZ)$NL$
+ #define TOPPERS_ISTK _kernel_istack$NL$
+ $NL$
+ #endif /* DEAULT_ISTK */$NL$
+$ELSE$
+
+$ // 静的API「DEF_ICS」が複数ある(E_OBJ)
+ $IF LENGTH(ICS.ORDER_LIST) > 1$
+ $ERROR$E_OBJ: $FORMAT(_("too many %1%"), "DEF_ICS")$$END$
+ $END$
+
+$ // istkszがスタック領域のサイズとして正しくない場合(E_PAR)
+ $IF !EQ(ICS.ISTK[1], "NULL") && LENGTH(CHECK_STKSZ_ALIGN)
+ && (ICS.ISTKSZ[1] & (CHECK_STKSZ_ALIGN - 1))$
+ $ERROR ICS.TEXT_LINE[1]$E_PAR: $FORMAT(_("%1% `%2%\' in %3% is not aligned"), "istksz", ICS.ISTKSZ[1], "DEF_ICS")$$END$
+ $END$
+
+ $IF EQ(ICS.ISTK[1], "NULL")$
+$ // スタック領域の自動割付け
+ static STK_T _kernel_istack[COUNT_STK_T($ICS.ISTKSZ[1]$)];$NL$
+ #define TOPPERS_ISTKSZ ROUND_STK_T($ICS.ISTKSZ[1]$)$NL$
+ #define TOPPERS_ISTK _kernel_istack$NL$
+ $ELSE$
+ #define TOPPERS_ISTKSZ ($ICS.ISTKSZ[1]$)$NL$
+ #define TOPPERS_ISTK ($ICS.ISTK[1]$)$NL$
+ $END$
+$END$
+$NL$
+
+$ 非タスクコンテキスト用のスタック領域
+const SIZE _kernel_istksz = TOPPERS_ISTKSZ;$NL$
+STK_T *const _kernel_istk = TOPPERS_ISTK;$NL$
+$NL$
+#ifdef TOPPERS_ISTKPT$NL$
+STK_T *const _kernel_istkpt = TOPPERS_ISTKPT(TOPPERS_ISTK, TOPPERS_ISTKSZ);$NL$
+#endif /* TOPPERS_ISTKPT */$NL$
+$NL$
+
+$
+$ タイムイベント管理
+$
+/*$NL$
+$SPC$* Time Event Management$NL$
+$SPC$*/$NL$
+$NL$
+TMEVTN _kernel_tmevt_heap[TNUM_TSKID + TNUM_CYCID + TNUM_ALMID];$NL$
+$NL$
+
+$
+$ 各モジュールの初期化関数
+$
+/*$NL$
+$SPC$* Module Initialization Function$NL$
+$SPC$*/$NL$
+$NL$
+void$NL$
+_kernel_initialize_object(void)$NL$
+{$NL$
+$TAB$_kernel_initialize_task();$NL$
+$IF LENGTH(SEM.ID_LIST)$ _kernel_initialize_semaphore();$NL$$END$
+$IF LENGTH(FLG.ID_LIST)$ _kernel_initialize_eventflag();$NL$$END$
+$IF LENGTH(DTQ.ID_LIST)$ _kernel_initialize_dataqueue();$NL$$END$
+$IF LENGTH(PDQ.ID_LIST)$ _kernel_initialize_pridataq();$NL$$END$
+$IF LENGTH(MBX.ID_LIST)$ _kernel_initialize_mailbox();$NL$$END$
+$IF LENGTH(MPF.ID_LIST)$ _kernel_initialize_mempfix();$NL$$END$
+$IF LENGTH(CYC.ID_LIST)$ _kernel_initialize_cyclic();$NL$$END$
+$IF LENGTH(ALM.ID_LIST)$ _kernel_initialize_alarm();$NL$$END$
+$TAB$_kernel_initialize_overrun();$NL$
+$TAB$_kernel_initialize_interrupt();$NL$
+$TAB$_kernel_initialize_exception();$NL$
+}$NL$
+$NL$
+
+$
+$ 初期化ルーチンの実行関数
+$
+/*$NL$
+$SPC$* Initialization Routine$NL$
+$SPC$*/$NL$
+$NL$
+void$NL$
+_kernel_call_inirtn(void)$NL$
+{$NL$
+$FOREACH order INI.ORDER_LIST$
+$ // iniatrが(TA_NULL)でない場合(E_RSATR)
+ $IF INI.INIATR[order] != 0$
+ $ERROR INI.TEXT_LINE[order]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "iniatr", INI.INIATR[order], "inirtn", INI.INIRTN[order], "ATT_INI")$$END$
+ $END$
+ $TAB$((INIRTN)($INI.INIRTN[order]$))((intptr_t)($INI.EXINF[order]$));$NL$
+$END$
+}$NL$
+$NL$
+
+$
+$ 終了処理ルーチンの実行関数
+$
+/*$NL$
+$SPC$* Termination Routine$NL$
+$SPC$*/$NL$
+$NL$
+void$NL$
+_kernel_call_terrtn(void)$NL$
+{$NL$
+$FOREACH rorder TER.RORDER_LIST$
+$ // teratrが(TA_NULL)でない場合(E_RSATR)
+ $IF TER.TERATR[rorder] != 0$
+ $ERROR TER.TEXT_LINE[rorder]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "teratr", TER.TERATR[rorder], "terrtn", TER.TERRTN[rorder], "ATT_TER")$$END$
+ $END$
+ $TAB$((TERRTN)($TER.TERRTN[rorder]$))((intptr_t)($TER.EXINF[rorder]$));$NL$
+$END$
+}$NL$
+$NL$
--- /dev/null
+tsk,CRE_TSK,#tskid { .tskatr &exinf &task +itskpri .stksz &stk },,
+tsk,DEF_TEX,%tskid { .texatr &texrtn },0,1,
+sem,CRE_SEM,#semid { .sematr .isemcnt .maxsem },,
+flg,CRE_FLG,#flgid { .flgatr .iflgptn },,
+dtq,CRE_DTQ,#dtqid { .dtqatr .dtqcnt &dtqmb },,
+pdq,CRE_PDQ,#pdqid { .pdqatr .pdqcnt +maxdpri &pdqmb },,
+mbx,CRE_MBX,#mbxid { .mbxatr +maxmpri &mprihd },,
+mpf,CRE_MPF,#mpfid { .mpfatr .blkcnt .blksz &mpf &mpfmb },,
+cyc,CRE_CYC,#cycid { .cycatr &exinf &cychdr .cyctim .cycphs },,
+alm,CRE_ALM,#almid { .almatr &exinf &almhdr },,
+ovr,DEF_OVR,{ .ovratr &ovrhdr },-1,
+int,CFG_INT,.intno { .intatr +intpri },,
+isr,ATT_ISR,{ .isratr &exinf .intno &isr +isrpri },-1,
+inh,DEF_INH,.inhno { .inhatr &inthdr },,
+ics,DEF_ICS,{ .istksz &istk },-1,
+exc,DEF_EXC,.excno { .excatr &exchdr },,
+ini,ATT_INI,{ .iniatr &exinf &inirtn },-1,
+ter,ATT_TER,{ .teratr &exinf &terrtn },-1,
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: kernel_int.h 1717 2010-01-31 11:41:03Z ertl-hiro $
+ */
+
+/*
+ * kernel_cfg.c(およびcfg1_out.c)用ヘッダファイル
+ */
+
+#ifndef TOPPERS_KERNEL_INT_H
+#define TOPPERS_KERNEL_INT_H
+
+/*
+ * カーネル標準ヘッダファイル
+ */
+#include "kernel_impl.h"
+
+/*
+ * カーネルの各ヘッダファイル
+ */
+#include "task.h"
+#include "semaphore.h"
+#include "eventflag.h"
+#include "dataqueue.h"
+#include "pridataq.h"
+#include "mailbox.h"
+#include "mempfix.h"
+#include "cyclic.h"
+#include "alarm.h"
+#include "overrun.h"
+#include "interrupt.h"
+#include "exception.h"
+#include "time_event.h"
+
+/*
+ * リネームしたシンボルを元に戻すためのヘッダファイル
+ */
+#include "kernel_unrename.h"
+
+#endif /* TOPPERS_KERNEL_INT_H */
--- /dev/null
+# startup.c
+kerflg
+exit_kernel
+
+# task.c
+p_runtsk
+p_schedtsk
+reqflg
+disdsp
+dspflg
+ready_queue
+ready_primap
+initialize_task
+search_schedtsk
+make_runnable
+make_non_runnable
+make_dormant
+make_active
+change_priority
+rotate_ready_queue
+call_texrtn
+calltex
+
+# wait.c
+make_wait_tmout
+wait_complete
+wait_tmout
+wait_tmout_ok
+wait_release
+wobj_make_wait
+wobj_make_wait_tmout
+init_wait_queue
+
+# time_event.c
+current_time
+min_time
+next_time
+next_subtime
+last_index
+initialize_tmevt
+tmevt_up
+tmevt_down
+tmevtb_insert
+tmevtb_delete
+tmevt_lefttim
+signal_time
+
+# semaphore.c
+initialize_semaphore
+
+# eventflag.c
+initialize_eventflag
+check_flg_cond
+
+# dataqueue.c
+initialize_dataqueue
+enqueue_data
+force_enqueue_data
+dequeue_data
+send_data
+force_send_data
+receive_data
+
+# pridataq.c
+initialize_pridataq
+enqueue_pridata
+dequeue_pridata
+send_pridata
+receive_pridata
+
+# mailbox.c
+initialize_mailbox
+
+# mempfix.c
+initialize_mempfix
+get_mpf_block
+
+# cyclic.c
+initialize_cyclic
+call_cychdr
+
+# alarm.c
+initialize_alarm
+call_almhdr
+
+# overrun.c
+initialize_overrun
+ovrtimer_start
+ovrtimer_stop
+call_ovrhdr
+
+# interrupt.c
+initialize_interrupt
+
+# exception.c
+initialize_exception
+
+# kernel_cfg.c
+initialize_object
+call_inirtn
+call_terrtn
+tmax_tskid
+tinib_table
+torder_table
+tcb_table
+tmax_semid
+seminib_table
+semcb_table
+tmax_flgid
+flginib_table
+flgcb_table
+tmax_dtqid
+dtqcb_table
+dtqinib_table
+tmax_pdqid
+pdqcb_table
+pdqinib_table
+tmax_mbxid
+mbxcb_table
+mbxinib_table
+tmax_mpfid
+mpfinib_table
+mpfcb_table
+tmax_cycid
+cycinib_table
+cyccb_table
+tmax_almid
+alminib_table
+almcb_table
+ovrinib
+tnum_inhno
+inhinib_table
+tnum_intno
+intinib_table
+tnum_excno
+excinib_table
+tmevt_heap
+istksz
+istk
+istkpt
+
+INCLUDE "target"
--- /dev/null
+/* This file is generated from kernel_rename.def by genrename. */
+
+#ifndef TOPPERS_KERNEL_RENAME_H
+#define TOPPERS_KERNEL_RENAME_H
+
+/*
+ * startup.c
+ */
+#define kerflg _kernel_kerflg
+#define exit_kernel _kernel_exit_kernel
+
+/*
+ * task.c
+ */
+#define p_runtsk _kernel_p_runtsk
+#define p_schedtsk _kernel_p_schedtsk
+#define reqflg _kernel_reqflg
+#define disdsp _kernel_disdsp
+#define dspflg _kernel_dspflg
+#define ready_queue _kernel_ready_queue
+#define ready_primap _kernel_ready_primap
+#define initialize_task _kernel_initialize_task
+#define search_schedtsk _kernel_search_schedtsk
+#define make_runnable _kernel_make_runnable
+#define make_non_runnable _kernel_make_non_runnable
+#define make_dormant _kernel_make_dormant
+#define make_active _kernel_make_active
+#define change_priority _kernel_change_priority
+#define rotate_ready_queue _kernel_rotate_ready_queue
+#define call_texrtn _kernel_call_texrtn
+#define calltex _kernel_calltex
+
+/*
+ * wait.c
+ */
+#define make_wait_tmout _kernel_make_wait_tmout
+#define wait_complete _kernel_wait_complete
+#define wait_tmout _kernel_wait_tmout
+#define wait_tmout_ok _kernel_wait_tmout_ok
+#define wait_release _kernel_wait_release
+#define wobj_make_wait _kernel_wobj_make_wait
+#define wobj_make_wait_tmout _kernel_wobj_make_wait_tmout
+#define init_wait_queue _kernel_init_wait_queue
+
+/*
+ * time_event.c
+ */
+#define current_time _kernel_current_time
+#define min_time _kernel_min_time
+#define next_time _kernel_next_time
+#define next_subtime _kernel_next_subtime
+#define last_index _kernel_last_index
+#define initialize_tmevt _kernel_initialize_tmevt
+#define tmevt_up _kernel_tmevt_up
+#define tmevt_down _kernel_tmevt_down
+#define tmevtb_insert _kernel_tmevtb_insert
+#define tmevtb_delete _kernel_tmevtb_delete
+#define tmevt_lefttim _kernel_tmevt_lefttim
+#define signal_time _kernel_signal_time
+
+/*
+ * semaphore.c
+ */
+#define initialize_semaphore _kernel_initialize_semaphore
+
+/*
+ * eventflag.c
+ */
+#define initialize_eventflag _kernel_initialize_eventflag
+#define check_flg_cond _kernel_check_flg_cond
+
+/*
+ * dataqueue.c
+ */
+#define initialize_dataqueue _kernel_initialize_dataqueue
+#define enqueue_data _kernel_enqueue_data
+#define force_enqueue_data _kernel_force_enqueue_data
+#define dequeue_data _kernel_dequeue_data
+#define send_data _kernel_send_data
+#define force_send_data _kernel_force_send_data
+#define receive_data _kernel_receive_data
+
+/*
+ * pridataq.c
+ */
+#define initialize_pridataq _kernel_initialize_pridataq
+#define enqueue_pridata _kernel_enqueue_pridata
+#define dequeue_pridata _kernel_dequeue_pridata
+#define send_pridata _kernel_send_pridata
+#define receive_pridata _kernel_receive_pridata
+
+/*
+ * mailbox.c
+ */
+#define initialize_mailbox _kernel_initialize_mailbox
+
+/*
+ * mempfix.c
+ */
+#define initialize_mempfix _kernel_initialize_mempfix
+#define get_mpf_block _kernel_get_mpf_block
+
+/*
+ * cyclic.c
+ */
+#define initialize_cyclic _kernel_initialize_cyclic
+#define call_cychdr _kernel_call_cychdr
+
+/*
+ * alarm.c
+ */
+#define initialize_alarm _kernel_initialize_alarm
+#define call_almhdr _kernel_call_almhdr
+
+/*
+ * overrun.c
+ */
+#define initialize_overrun _kernel_initialize_overrun
+#define ovrtimer_start _kernel_ovrtimer_start
+#define ovrtimer_stop _kernel_ovrtimer_stop
+#define call_ovrhdr _kernel_call_ovrhdr
+
+/*
+ * interrupt.c
+ */
+#define initialize_interrupt _kernel_initialize_interrupt
+
+/*
+ * exception.c
+ */
+#define initialize_exception _kernel_initialize_exception
+
+/*
+ * kernel_cfg.c
+ */
+#define initialize_object _kernel_initialize_object
+#define call_inirtn _kernel_call_inirtn
+#define call_terrtn _kernel_call_terrtn
+#define tmax_tskid _kernel_tmax_tskid
+#define tinib_table _kernel_tinib_table
+#define torder_table _kernel_torder_table
+#define tcb_table _kernel_tcb_table
+#define tmax_semid _kernel_tmax_semid
+#define seminib_table _kernel_seminib_table
+#define semcb_table _kernel_semcb_table
+#define tmax_flgid _kernel_tmax_flgid
+#define flginib_table _kernel_flginib_table
+#define flgcb_table _kernel_flgcb_table
+#define tmax_dtqid _kernel_tmax_dtqid
+#define dtqcb_table _kernel_dtqcb_table
+#define dtqinib_table _kernel_dtqinib_table
+#define tmax_pdqid _kernel_tmax_pdqid
+#define pdqcb_table _kernel_pdqcb_table
+#define pdqinib_table _kernel_pdqinib_table
+#define tmax_mbxid _kernel_tmax_mbxid
+#define mbxcb_table _kernel_mbxcb_table
+#define mbxinib_table _kernel_mbxinib_table
+#define tmax_mpfid _kernel_tmax_mpfid
+#define mpfinib_table _kernel_mpfinib_table
+#define mpfcb_table _kernel_mpfcb_table
+#define tmax_cycid _kernel_tmax_cycid
+#define cycinib_table _kernel_cycinib_table
+#define cyccb_table _kernel_cyccb_table
+#define tmax_almid _kernel_tmax_almid
+#define alminib_table _kernel_alminib_table
+#define almcb_table _kernel_almcb_table
+#define ovrinib _kernel_ovrinib
+#define tnum_inhno _kernel_tnum_inhno
+#define inhinib_table _kernel_inhinib_table
+#define tnum_intno _kernel_tnum_intno
+#define intinib_table _kernel_intinib_table
+#define tnum_excno _kernel_tnum_excno
+#define excinib_table _kernel_excinib_table
+#define tmevt_heap _kernel_tmevt_heap
+#define istksz _kernel_istksz
+#define istk _kernel_istk
+#define istkpt _kernel_istkpt
+
+
+#ifdef TOPPERS_LABEL_ASM
+
+/*
+ * startup.c
+ */
+#define _kerflg __kernel_kerflg
+#define _exit_kernel __kernel_exit_kernel
+
+/*
+ * task.c
+ */
+#define _p_runtsk __kernel_p_runtsk
+#define _p_schedtsk __kernel_p_schedtsk
+#define _reqflg __kernel_reqflg
+#define _disdsp __kernel_disdsp
+#define _dspflg __kernel_dspflg
+#define _ready_queue __kernel_ready_queue
+#define _ready_primap __kernel_ready_primap
+#define _initialize_task __kernel_initialize_task
+#define _search_schedtsk __kernel_search_schedtsk
+#define _make_runnable __kernel_make_runnable
+#define _make_non_runnable __kernel_make_non_runnable
+#define _make_dormant __kernel_make_dormant
+#define _make_active __kernel_make_active
+#define _change_priority __kernel_change_priority
+#define _rotate_ready_queue __kernel_rotate_ready_queue
+#define _call_texrtn __kernel_call_texrtn
+#define _calltex __kernel_calltex
+
+/*
+ * wait.c
+ */
+#define _make_wait_tmout __kernel_make_wait_tmout
+#define _wait_complete __kernel_wait_complete
+#define _wait_tmout __kernel_wait_tmout
+#define _wait_tmout_ok __kernel_wait_tmout_ok
+#define _wait_release __kernel_wait_release
+#define _wobj_make_wait __kernel_wobj_make_wait
+#define _wobj_make_wait_tmout __kernel_wobj_make_wait_tmout
+#define _init_wait_queue __kernel_init_wait_queue
+
+/*
+ * time_event.c
+ */
+#define _current_time __kernel_current_time
+#define _min_time __kernel_min_time
+#define _next_time __kernel_next_time
+#define _next_subtime __kernel_next_subtime
+#define _last_index __kernel_last_index
+#define _initialize_tmevt __kernel_initialize_tmevt
+#define _tmevt_up __kernel_tmevt_up
+#define _tmevt_down __kernel_tmevt_down
+#define _tmevtb_insert __kernel_tmevtb_insert
+#define _tmevtb_delete __kernel_tmevtb_delete
+#define _tmevt_lefttim __kernel_tmevt_lefttim
+#define _signal_time __kernel_signal_time
+
+/*
+ * semaphore.c
+ */
+#define _initialize_semaphore __kernel_initialize_semaphore
+
+/*
+ * eventflag.c
+ */
+#define _initialize_eventflag __kernel_initialize_eventflag
+#define _check_flg_cond __kernel_check_flg_cond
+
+/*
+ * dataqueue.c
+ */
+#define _initialize_dataqueue __kernel_initialize_dataqueue
+#define _enqueue_data __kernel_enqueue_data
+#define _force_enqueue_data __kernel_force_enqueue_data
+#define _dequeue_data __kernel_dequeue_data
+#define _send_data __kernel_send_data
+#define _force_send_data __kernel_force_send_data
+#define _receive_data __kernel_receive_data
+
+/*
+ * pridataq.c
+ */
+#define _initialize_pridataq __kernel_initialize_pridataq
+#define _enqueue_pridata __kernel_enqueue_pridata
+#define _dequeue_pridata __kernel_dequeue_pridata
+#define _send_pridata __kernel_send_pridata
+#define _receive_pridata __kernel_receive_pridata
+
+/*
+ * mailbox.c
+ */
+#define _initialize_mailbox __kernel_initialize_mailbox
+
+/*
+ * mempfix.c
+ */
+#define _initialize_mempfix __kernel_initialize_mempfix
+#define _get_mpf_block __kernel_get_mpf_block
+
+/*
+ * cyclic.c
+ */
+#define _initialize_cyclic __kernel_initialize_cyclic
+#define _call_cychdr __kernel_call_cychdr
+
+/*
+ * alarm.c
+ */
+#define _initialize_alarm __kernel_initialize_alarm
+#define _call_almhdr __kernel_call_almhdr
+
+/*
+ * overrun.c
+ */
+#define _initialize_overrun __kernel_initialize_overrun
+#define _ovrtimer_start __kernel_ovrtimer_start
+#define _ovrtimer_stop __kernel_ovrtimer_stop
+#define _call_ovrhdr __kernel_call_ovrhdr
+
+/*
+ * interrupt.c
+ */
+#define _initialize_interrupt __kernel_initialize_interrupt
+
+/*
+ * exception.c
+ */
+#define _initialize_exception __kernel_initialize_exception
+
+/*
+ * kernel_cfg.c
+ */
+#define _initialize_object __kernel_initialize_object
+#define _call_inirtn __kernel_call_inirtn
+#define _call_terrtn __kernel_call_terrtn
+#define _tmax_tskid __kernel_tmax_tskid
+#define _tinib_table __kernel_tinib_table
+#define _torder_table __kernel_torder_table
+#define _tcb_table __kernel_tcb_table
+#define _tmax_semid __kernel_tmax_semid
+#define _seminib_table __kernel_seminib_table
+#define _semcb_table __kernel_semcb_table
+#define _tmax_flgid __kernel_tmax_flgid
+#define _flginib_table __kernel_flginib_table
+#define _flgcb_table __kernel_flgcb_table
+#define _tmax_dtqid __kernel_tmax_dtqid
+#define _dtqcb_table __kernel_dtqcb_table
+#define _dtqinib_table __kernel_dtqinib_table
+#define _tmax_pdqid __kernel_tmax_pdqid
+#define _pdqcb_table __kernel_pdqcb_table
+#define _pdqinib_table __kernel_pdqinib_table
+#define _tmax_mbxid __kernel_tmax_mbxid
+#define _mbxcb_table __kernel_mbxcb_table
+#define _mbxinib_table __kernel_mbxinib_table
+#define _tmax_mpfid __kernel_tmax_mpfid
+#define _mpfinib_table __kernel_mpfinib_table
+#define _mpfcb_table __kernel_mpfcb_table
+#define _tmax_cycid __kernel_tmax_cycid
+#define _cycinib_table __kernel_cycinib_table
+#define _cyccb_table __kernel_cyccb_table
+#define _tmax_almid __kernel_tmax_almid
+#define _alminib_table __kernel_alminib_table
+#define _almcb_table __kernel_almcb_table
+#define _ovrinib __kernel_ovrinib
+#define _tnum_inhno __kernel_tnum_inhno
+#define _inhinib_table __kernel_inhinib_table
+#define _tnum_intno __kernel_tnum_intno
+#define _intinib_table __kernel_intinib_table
+#define _tnum_excno __kernel_tnum_excno
+#define _excinib_table __kernel_excinib_table
+#define _tmevt_heap __kernel_tmevt_heap
+#define _istksz __kernel_istksz
+#define _istk __kernel_istk
+#define _istkpt __kernel_istkpt
+
+
+#endif /* TOPPERS_LABEL_ASM */
+
+#include "target_rename.h"
+
+#endif /* TOPPERS_KERNEL_RENAME_H */
--- /dev/null
+/* This file is generated from kernel_rename.def by genrename. */
+
+/* This file is included only when kernel_rename.h has been included. */
+#ifdef TOPPERS_KERNEL_RENAME_H
+#undef TOPPERS_KERNEL_RENAME_H
+
+/*
+ * startup.c
+ */
+#undef kerflg
+#undef exit_kernel
+
+/*
+ * task.c
+ */
+#undef p_runtsk
+#undef p_schedtsk
+#undef reqflg
+#undef disdsp
+#undef dspflg
+#undef ready_queue
+#undef ready_primap
+#undef initialize_task
+#undef search_schedtsk
+#undef make_runnable
+#undef make_non_runnable
+#undef make_dormant
+#undef make_active
+#undef change_priority
+#undef rotate_ready_queue
+#undef call_texrtn
+#undef calltex
+
+/*
+ * wait.c
+ */
+#undef make_wait_tmout
+#undef wait_complete
+#undef wait_tmout
+#undef wait_tmout_ok
+#undef wait_release
+#undef wobj_make_wait
+#undef wobj_make_wait_tmout
+#undef init_wait_queue
+
+/*
+ * time_event.c
+ */
+#undef current_time
+#undef min_time
+#undef next_time
+#undef next_subtime
+#undef last_index
+#undef initialize_tmevt
+#undef tmevt_up
+#undef tmevt_down
+#undef tmevtb_insert
+#undef tmevtb_delete
+#undef tmevt_lefttim
+#undef signal_time
+
+/*
+ * semaphore.c
+ */
+#undef initialize_semaphore
+
+/*
+ * eventflag.c
+ */
+#undef initialize_eventflag
+#undef check_flg_cond
+
+/*
+ * dataqueue.c
+ */
+#undef initialize_dataqueue
+#undef enqueue_data
+#undef force_enqueue_data
+#undef dequeue_data
+#undef send_data
+#undef force_send_data
+#undef receive_data
+
+/*
+ * pridataq.c
+ */
+#undef initialize_pridataq
+#undef enqueue_pridata
+#undef dequeue_pridata
+#undef send_pridata
+#undef receive_pridata
+
+/*
+ * mailbox.c
+ */
+#undef initialize_mailbox
+
+/*
+ * mempfix.c
+ */
+#undef initialize_mempfix
+#undef get_mpf_block
+
+/*
+ * cyclic.c
+ */
+#undef initialize_cyclic
+#undef call_cychdr
+
+/*
+ * alarm.c
+ */
+#undef initialize_alarm
+#undef call_almhdr
+
+/*
+ * overrun.c
+ */
+#undef initialize_overrun
+#undef ovrtimer_start
+#undef ovrtimer_stop
+#undef call_ovrhdr
+
+/*
+ * interrupt.c
+ */
+#undef initialize_interrupt
+
+/*
+ * exception.c
+ */
+#undef initialize_exception
+
+/*
+ * kernel_cfg.c
+ */
+#undef initialize_object
+#undef call_inirtn
+#undef call_terrtn
+#undef tmax_tskid
+#undef tinib_table
+#undef torder_table
+#undef tcb_table
+#undef tmax_semid
+#undef seminib_table
+#undef semcb_table
+#undef tmax_flgid
+#undef flginib_table
+#undef flgcb_table
+#undef tmax_dtqid
+#undef dtqcb_table
+#undef dtqinib_table
+#undef tmax_pdqid
+#undef pdqcb_table
+#undef pdqinib_table
+#undef tmax_mbxid
+#undef mbxcb_table
+#undef mbxinib_table
+#undef tmax_mpfid
+#undef mpfinib_table
+#undef mpfcb_table
+#undef tmax_cycid
+#undef cycinib_table
+#undef cyccb_table
+#undef tmax_almid
+#undef alminib_table
+#undef almcb_table
+#undef ovrinib
+#undef tnum_inhno
+#undef inhinib_table
+#undef tnum_intno
+#undef intinib_table
+#undef tnum_excno
+#undef excinib_table
+#undef tmevt_heap
+#undef istksz
+#undef istk
+#undef istkpt
+
+
+#ifdef TOPPERS_LABEL_ASM
+
+/*
+ * startup.c
+ */
+#undef _kerflg
+#undef _exit_kernel
+
+/*
+ * task.c
+ */
+#undef _p_runtsk
+#undef _p_schedtsk
+#undef _reqflg
+#undef _disdsp
+#undef _dspflg
+#undef _ready_queue
+#undef _ready_primap
+#undef _initialize_task
+#undef _search_schedtsk
+#undef _make_runnable
+#undef _make_non_runnable
+#undef _make_dormant
+#undef _make_active
+#undef _change_priority
+#undef _rotate_ready_queue
+#undef _call_texrtn
+#undef _calltex
+
+/*
+ * wait.c
+ */
+#undef _make_wait_tmout
+#undef _wait_complete
+#undef _wait_tmout
+#undef _wait_tmout_ok
+#undef _wait_release
+#undef _wobj_make_wait
+#undef _wobj_make_wait_tmout
+#undef _init_wait_queue
+
+/*
+ * time_event.c
+ */
+#undef _current_time
+#undef _min_time
+#undef _next_time
+#undef _next_subtime
+#undef _last_index
+#undef _initialize_tmevt
+#undef _tmevt_up
+#undef _tmevt_down
+#undef _tmevtb_insert
+#undef _tmevtb_delete
+#undef _tmevt_lefttim
+#undef _signal_time
+
+/*
+ * semaphore.c
+ */
+#undef _initialize_semaphore
+
+/*
+ * eventflag.c
+ */
+#undef _initialize_eventflag
+#undef _check_flg_cond
+
+/*
+ * dataqueue.c
+ */
+#undef _initialize_dataqueue
+#undef _enqueue_data
+#undef _force_enqueue_data
+#undef _dequeue_data
+#undef _send_data
+#undef _force_send_data
+#undef _receive_data
+
+/*
+ * pridataq.c
+ */
+#undef _initialize_pridataq
+#undef _enqueue_pridata
+#undef _dequeue_pridata
+#undef _send_pridata
+#undef _receive_pridata
+
+/*
+ * mailbox.c
+ */
+#undef _initialize_mailbox
+
+/*
+ * mempfix.c
+ */
+#undef _initialize_mempfix
+#undef _get_mpf_block
+
+/*
+ * cyclic.c
+ */
+#undef _initialize_cyclic
+#undef _call_cychdr
+
+/*
+ * alarm.c
+ */
+#undef _initialize_alarm
+#undef _call_almhdr
+
+/*
+ * overrun.c
+ */
+#undef _initialize_overrun
+#undef _ovrtimer_start
+#undef _ovrtimer_stop
+#undef _call_ovrhdr
+
+/*
+ * interrupt.c
+ */
+#undef _initialize_interrupt
+
+/*
+ * exception.c
+ */
+#undef _initialize_exception
+
+/*
+ * kernel_cfg.c
+ */
+#undef _initialize_object
+#undef _call_inirtn
+#undef _call_terrtn
+#undef _tmax_tskid
+#undef _tinib_table
+#undef _torder_table
+#undef _tcb_table
+#undef _tmax_semid
+#undef _seminib_table
+#undef _semcb_table
+#undef _tmax_flgid
+#undef _flginib_table
+#undef _flgcb_table
+#undef _tmax_dtqid
+#undef _dtqcb_table
+#undef _dtqinib_table
+#undef _tmax_pdqid
+#undef _pdqcb_table
+#undef _pdqinib_table
+#undef _tmax_mbxid
+#undef _mbxcb_table
+#undef _mbxinib_table
+#undef _tmax_mpfid
+#undef _mpfinib_table
+#undef _mpfcb_table
+#undef _tmax_cycid
+#undef _cycinib_table
+#undef _cyccb_table
+#undef _tmax_almid
+#undef _alminib_table
+#undef _almcb_table
+#undef _ovrinib
+#undef _tnum_inhno
+#undef _inhinib_table
+#undef _tnum_intno
+#undef _intinib_table
+#undef _tnum_excno
+#undef _excinib_table
+#undef _tmevt_heap
+#undef _istksz
+#undef _istk
+#undef _istkpt
+
+
+#endif /* TOPPERS_LABEL_ASM */
+
+#include "target_unrename.h"
+
+#endif /* TOPPERS_KERNEL_RENAME_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: overrun.c 1723 2010-01-31 13:05:57Z ertl-hiro $
+ */
+
+/*
+ * オーバランハンドラ機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "overrun.h"
+
+#ifdef TOPPERS_SUPPORT_OVRHDR
+#include "target_timer.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_OVR_ENTER
+#define LOG_OVR_ENTER(p_runtsk)
+#endif /* LOG_OVR_ENTER */
+
+#ifndef LOG_OVR_LEAVE
+#define LOG_OVR_LEAVE(p_runtsk)
+#endif /* LOG_OVR_LEAVE */
+
+#ifndef LOG_STA_OVR_ENTER
+#define LOG_STA_OVR_ENTER(tskid, ovrtim)
+#endif /* LOG_STA_OVR_ENTER */
+
+#ifndef LOG_STA_OVR_LEAVE
+#define LOG_STA_OVR_LEAVE(ercd)
+#endif /* LOG_STA_OVR_LEAVE */
+
+#ifndef LOG_ISTA_OVR_ENTER
+#define LOG_ISTA_OVR_ENTER(tskid, ovrtim)
+#endif /* LOG_ISTA_OVR_ENTER */
+
+#ifndef LOG_ISTA_OVR_LEAVE
+#define LOG_ISTA_OVR_LEAVE(ercd)
+#endif /* LOG_ISTA_OVR_LEAVE */
+
+#ifndef LOG_ISTP_OVR_ENTER
+#define LOG_ISTP_OVR_ENTER(tskid)
+#endif /* LOG_ISTP_OVR_ENTER */
+
+#ifndef LOG_ISTP_OVR_LEAVE
+#define LOG_ISTP_OVR_LEAVE(ercd)
+#endif /* LOG_ISTP_OVR_LEAVE */
+
+#ifndef LOG_STP_OVR_ENTER
+#define LOG_STP_OVR_ENTER(tskid)
+#endif /* LOG_STP_OVR_ENTER */
+
+#ifndef LOG_STP_OVR_LEAVE
+#define LOG_STP_OVR_LEAVE(ercd)
+#endif /* LOG_STP_OVR_LEAVE */
+
+#ifndef LOG_REF_OVR_ENTER
+#define LOG_REF_OVR_ENTER(tskid, pk_rovr)
+#endif /* LOG_REF_OVR_ENTER */
+
+#ifndef LOG_REF_OVR_LEAVE
+#define LOG_REF_OVR_LEAVE(ercd, pk_rovr)
+#endif /* LOG_REF_OVR_LEAVE */
+
+#ifdef TOPPERS_ovrini
+
+/*
+ * オーバランタイマが動作中かを示すフラグ
+ */
+bool_t ovrtimer_flag;
+
+/*
+ * オーバランハンドラ機能の初期化
+ */
+void
+initialize_overrun(void)
+{
+ ovrtimer_flag = false;
+}
+
+#endif /* TOPPERS_ovrini */
+
+/*
+ * オーバランハンドラ用タイマの動作開始
+ */
+#ifdef TOPPERS_ovrsta
+#ifndef OMIT_OVRTIMER_START
+
+void
+ovrtimer_start(void)
+{
+ if (p_runtsk->leftotm > 0U) {
+ target_ovrtimer_start(p_runtsk->leftotm);
+ ovrtimer_flag = true;
+ }
+}
+
+#endif /* OMIT_OVRTIMER_START */
+#endif /* TOPPERS_ovrsta */
+
+/*
+ * オーバランハンドラ用タイマの停止
+ */
+#ifdef TOPPERS_ovrstp
+#ifndef OMIT_OVRTIMER_STOP
+
+void
+ovrtimer_stop(void)
+{
+ if (ovrtimer_flag) {
+ assert(p_runtsk->leftotm > 0U);
+ p_runtsk->leftotm = target_ovrtimer_stop();
+ ovrtimer_flag = false;
+ }
+}
+
+#endif /* OMIT_OVRTIMER_STOP */
+#endif /* TOPPERS_ovrstp */
+
+/*
+ * オーバランハンドラの動作開始
+ */
+#ifdef TOPPERS_sta_ovr
+
+ER
+sta_ovr(ID tskid, OVRTIM ovrtim)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_STA_OVR_ENTER(tskid, ovrtim);
+ CHECK_TSKCTX_UNL();
+ CHECK_OBJ(ovrinib.ovrhdr != NULL);
+ CHECK_TSKID_SELF(tskid);
+ CHECK_PAR(0U < ovrtim && ovrtim <= TMAX_OVRTIM);
+ p_tcb = get_tcb_self(tskid);
+
+ t_lock_cpu();
+ if (p_tcb == p_runtsk) {
+ if (p_tcb->leftotm > 0U) {
+ (void) target_ovrtimer_stop();
+ }
+ target_ovrtimer_start(ovrtim);
+ ovrtimer_flag = true;
+ }
+ p_tcb->leftotm = ovrtim;
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_STA_OVR_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_sta_ovr */
+
+/*
+ * オーバランハンドラの動作開始(非タスクコンテキスト用)
+ */
+#ifdef TOPPERS_ista_ovr
+
+ER
+ista_ovr(ID tskid, OVRTIM ovrtim)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_ISTA_OVR_ENTER(tskid, ovrtim);
+ CHECK_INTCTX_UNL();
+ CHECK_OBJ(ovrinib.ovrhdr != NULL);
+ CHECK_TSKID(tskid);
+ CHECK_PAR(0U < ovrtim && ovrtim <= TMAX_OVRTIM);
+ p_tcb = get_tcb(tskid);
+
+ i_lock_cpu();
+ p_tcb->leftotm = ovrtim;
+ ercd = E_OK;
+ i_unlock_cpu();
+
+ error_exit:
+ LOG_ISTA_OVR_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ista_ovr */
+
+/*
+ * オーバランハンドラの動作停止
+ */
+#ifdef TOPPERS_stp_ovr
+
+ER
+stp_ovr(ID tskid)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_STP_OVR_ENTER(tskid);
+ CHECK_TSKCTX_UNL();
+ CHECK_OBJ(ovrinib.ovrhdr != NULL);
+ CHECK_TSKID_SELF(tskid);
+ p_tcb = get_tcb_self(tskid);
+
+ t_lock_cpu();
+ if (p_tcb->leftotm > 0U) {
+ if (p_tcb == p_runtsk) {
+ (void) target_ovrtimer_stop();
+ ovrtimer_flag = false;
+ }
+ p_tcb->leftotm = 0U;
+ }
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_STP_OVR_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_stp_ovr */
+
+/*
+ * オーバランハンドラの動作停止(非タスクコンテキスト用)
+ */
+#ifdef TOPPERS_istp_ovr
+
+ER
+istp_ovr(ID tskid)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_ISTP_OVR_ENTER(tskid);
+ CHECK_INTCTX_UNL();
+ CHECK_OBJ(ovrinib.ovrhdr != NULL);
+ CHECK_TSKID(tskid);
+ p_tcb = get_tcb(tskid);
+
+ i_lock_cpu();
+ p_tcb->leftotm = 0U;
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_ISTP_OVR_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_istp_ovr */
+
+/*
+ * オーバランハンドラの状態参照
+ */
+#ifdef TOPPERS_ref_ovr
+
+ER
+ref_ovr(ID tskid, T_ROVR *pk_rovr)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_REF_OVR_ENTER(tskid, pk_rovr);
+ CHECK_TSKCTX_UNL();
+ CHECK_OBJ(ovrinib.ovrhdr != NULL);
+ CHECK_TSKID_SELF(tskid);
+ p_tcb = get_tcb_self(tskid);
+
+ t_lock_cpu();
+ if (p_tcb->leftotm > 0U) {
+ pk_rovr->ovrstat = TOVR_STA;
+ if (p_tcb == p_runtsk) {
+ pk_rovr->leftotm = target_ovrtimer_get_current();
+ }
+ else {
+ pk_rovr->leftotm = p_tcb->leftotm;
+ }
+ }
+ else {
+ pk_rovr->ovrstat = TOVR_STP;
+ }
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_REF_OVR_LEAVE(ercd, pk_rovr);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ref_ovr */
+
+/*
+ * オーバランハンドラ起動ルーチン
+ */
+#ifdef TOPPERS_ovrcal
+
+void
+call_ovrhdr(void)
+{
+ PRI saved_ipm;
+
+ assert(sense_context());
+ assert(!i_sense_lock());
+ assert(ovrinib.ovrhdr != NULL);
+
+ p_runtsk->leftotm = 0U;
+ saved_ipm = i_get_ipm();
+
+ LOG_OVR_ENTER(p_runtsk);
+ (*((OVRHDR)(ovrinib.ovrhdr)))(TSKID(p_runtsk), p_runtsk->p_tinib->exinf);
+ LOG_OVR_LEAVE(p_runtsk);
+
+ if (i_sense_lock()) {
+ i_unlock_cpu();
+ }
+ i_set_ipm(saved_ipm);
+}
+
+#endif /* TOPPERS_ovrcal */
+#endif /* TOPPERS_SUPPORT_OVRHDR */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: overrun.h 1717 2010-01-31 11:41:03Z ertl-hiro $
+ */
+
+/*
+ * オーバランハンドラ機能
+ */
+
+#ifndef TOPPERS_OVERRUN_H
+#define TOPPERS_OVERRUN_H
+
+#ifdef TOPPERS_SUPPORT_OVRHDR
+#include "target_timer.h"
+
+/*
+ * オーバランハンドラ初期化ブロック
+ */
+typedef struct overrun_handler_initialization_block {
+ ATR ovratr; /* オーバランハンドラ属性 */
+ OVRHDR ovrhdr; /* オーバランハンドラの起動番地 */
+} OVRINIB;
+
+/*
+ * オーバランハンドラ初期化ブロックのエリア(kernel_cfg.c)
+ */
+extern const OVRINIB ovrinib;
+
+/*
+ * オーバランタイマが動作中かを示すフラグ
+ */
+extern bool_t ovrtimer_flag;
+
+/*
+ * オーバランハンドラ機能の初期化
+ */
+extern void initialize_overrun(void);
+
+/*
+ * オーバランハンドラ用タイマの動作開始
+ */
+extern void ovrtimer_start(void);
+
+/*
+ * オーバランハンドラ用タイマの停止
+ */
+#ifndef OMIT_OVRTIMER_STOP
+
+extern void ovrtimer_stop(void);
+
+#else /* OMIT_OVRTIMER_STOP */
+
+Inline void
+ovrtimer_stop(void)
+{
+ if (p_runtsk->leftotm > 0U) {
+ p_runtsk->leftotm = target_ovrtimer_stop();
+ ovrtimer_flag = false;
+ }
+}
+
+#endif /* OMIT_OVRTIMER_STOP */
+
+/*
+ * オーバランハンドラ起動ルーチン
+ */
+extern void call_ovrhdr(void);
+
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+#endif /* TOPPERS_OVERRUN_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * $Id: task.c 1812 2010-06-27 13:07:15Z ertl-hiro $
+ */
+
+/*
+ * タスク管理モジュール
+ */
+
+#include "kernel_impl.h"
+#include "wait.h"
+#include "task.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_TEX_ENTER
+#define LOG_TEX_ENTER(p_tcb, texptn)
+#endif /* LOG_TEX_ENTER */
+
+#ifndef LOG_TEX_LEAVE
+#define LOG_TEX_LEAVE(p_tcb)
+#endif /* LOG_TEX_LEAVE */
+
+#ifdef TOPPERS_tskini
+
+/*
+ * 実行状態のタスク
+ */
+TCB *p_runtsk;
+
+/*
+ * 最高優先順位のタスク
+ */
+TCB *p_schedtsk;
+
+/*
+ * タスクディスパッチ/タスク例外処理ルーチン起動要求フラグ
+ */
+bool_t reqflg;
+
+/*
+ * ディスパッチ禁止状態
+ */
+bool_t disdsp;
+
+/*
+ * タスクディスパッチ可能状態
+ */
+bool_t dspflg;
+
+/*
+ * レディキュー
+ */
+QUEUE ready_queue[TNUM_TPRI];
+
+/*
+ * レディキューサーチのためのビットマップ
+ */
+uint16_t ready_primap;
+
+/*
+ * タスク管理モジュールの初期化
+ */
+void
+initialize_task(void)
+{
+ uint_t i, j;
+ TCB *p_tcb;
+
+ p_runtsk = p_schedtsk = NULL;
+ reqflg = false;
+ disdsp = false;
+ dspflg = true;
+
+ for (i = 0; i < TNUM_TPRI; i++) {
+ queue_initialize(&(ready_queue[i]));
+ }
+ ready_primap = 0U;
+
+ for (i = 0; i < tnum_tsk; i++) {
+ j = INDEX_TSK(torder_table[i]);
+ p_tcb = &(tcb_table[j]);
+ p_tcb->p_tinib = &(tinib_table[j]);
+ p_tcb->actque = false;
+ make_dormant(p_tcb);
+ if ((p_tcb->p_tinib->tskatr & TA_ACT) != 0U) {
+ make_active(p_tcb);
+ }
+ }
+}
+
+#endif /* TOPPERS_tskini */
+
+/*
+ * ビットマップサーチ関数
+ *
+ * bitmap内の1のビットの内,最も下位(右)のものをサーチし,そのビッ
+ * ト番号を返す.ビット番号は,最下位ビットを0とする.bitmapに0を指定
+ * してはならない.この関数では,bitmapが16ビットであることを仮定し,
+ * uint16_t型としている.
+ *
+ * ビットサーチ命令を持つプロセッサでは,ビットサーチ命令を使うように
+ * 書き直した方が効率が良い場合がある.このような場合には,ターゲット
+ * 依存部でビットサーチ命令を使ったbitmap_searchを定義し,
+ * OMIT_BITMAP_SEARCHをマクロ定義すればよい.また,ビットサーチ命令の
+ * サーチ方向が逆などの理由で優先度とビットとの対応を変更したい場合に
+ * は,PRIMAP_BITをマクロ定義すればよい.
+ *
+ * また,標準ライブラリにffsがあるなら,次のように定義して標準ライブ
+ * ラリを使った方が効率が良い可能性もある.
+ * #define bitmap_search(bitmap) (ffs(bitmap) - 1)
+ */
+#ifndef PRIMAP_BIT
+#define PRIMAP_BIT(pri) (1U << (pri))
+#endif /* PRIMAP_BIT */
+
+#ifndef OMIT_BITMAP_SEARCH
+
+static const unsigned char bitmap_search_table[] = { 0, 1, 0, 2, 0, 1, 0,
+ 3, 0, 1, 0, 2, 0, 1, 0 };
+
+Inline uint_t
+bitmap_search(uint16_t bitmap)
+{
+ uint_t n = 0U;
+
+ assert(bitmap != 0U);
+ if ((bitmap & 0x00ffU) == 0U) {
+ bitmap >>= 8;
+ n += 8;
+ }
+ if ((bitmap & 0x0fU) == 0U) {
+ bitmap >>= 4;
+ n += 4;
+ }
+ return(n + bitmap_search_table[(bitmap & 0x0fU) - 1]);
+}
+
+#endif /* OMIT_BITMAP_SEARCH */
+
+/*
+ * 優先度ビットマップが空かのチェック
+ */
+Inline bool_t
+primap_empty(void)
+{
+ return(ready_primap == 0U);
+}
+
+/*
+ * 優先度ビットマップのサーチ
+ */
+Inline uint_t
+primap_search(void)
+{
+ return(bitmap_search(ready_primap));
+}
+
+/*
+ * 優先度ビットマップのセット
+ */
+Inline void
+primap_set(uint_t pri)
+{
+ ready_primap |= PRIMAP_BIT(pri);
+}
+
+/*
+ * 優先度ビットマップのクリア
+ */
+Inline void
+primap_clear(uint_t pri)
+{
+ ready_primap &= ~PRIMAP_BIT(pri);
+}
+
+/*
+ * 最高優先順位タスクのサーチ
+ */
+#ifdef TOPPERS_tsksched
+
+TCB *
+search_schedtsk(void)
+{
+ uint_t schedpri;
+
+ schedpri = primap_search();
+ return((TCB *)(ready_queue[schedpri].p_next));
+}
+
+#endif /* TOPPERS_tsksched */
+
+/*
+ * 実行できる状態への遷移
+ *
+ * 最高優先順位のタスクを更新するのは,実行できるタスクがなかった場合
+ * と,p_tcbの優先度が最高優先順位のタスクの優先度よりも高い場合であ
+ * る.
+ */
+#ifdef TOPPERS_tskrun
+
+bool_t
+make_runnable(TCB *p_tcb)
+{
+ uint_t pri = p_tcb->priority;
+
+ queue_insert_prev(&(ready_queue[pri]), &(p_tcb->task_queue));
+ primap_set(pri);
+
+ if (p_schedtsk == (TCB *) NULL || pri < p_schedtsk->priority) {
+ p_schedtsk = p_tcb;
+ return(dspflg);
+ }
+ return(false);
+}
+
+#endif /* TOPPERS_tskrun */
+
+/*
+ * 実行できる状態から他の状態への遷移
+ *
+ * 最高優先順位のタスクを更新するのは,p_tcbが最高優先順位のタスクで
+ * あった場合である.p_tcbと同じ優先度のタスクが他にある場合は,p_tcb
+ * の次のタスクが最高優先順位になる.そうでない場合は,レディキューを
+ * サーチする必要がある.
+ */
+#ifdef TOPPERS_tsknrun
+
+bool_t
+make_non_runnable(TCB *p_tcb)
+{
+ uint_t pri = p_tcb->priority;
+ QUEUE *p_queue = &(ready_queue[pri]);
+
+ queue_delete(&(p_tcb->task_queue));
+ if (queue_empty(p_queue)) {
+ primap_clear(pri);
+ if (p_schedtsk == p_tcb) {
+ p_schedtsk = primap_empty() ? (TCB *) NULL : search_schedtsk();
+ return(dspflg);
+ }
+ }
+ else {
+ if (p_schedtsk == p_tcb) {
+ p_schedtsk = (TCB *)(p_queue->p_next);
+ return(dspflg);
+ }
+ }
+ return(false);
+}
+
+#endif /* TOPPERS_tsknrun */
+
+/*
+ * 休止状態への遷移
+ */
+#ifdef TOPPERS_tskdmt
+
+void
+make_dormant(TCB *p_tcb)
+{
+ p_tcb->tstat = TS_DORMANT;
+ p_tcb->priority = p_tcb->p_tinib->ipriority;
+ p_tcb->wupque = false;
+ p_tcb->enatex = false;
+ p_tcb->texptn = 0U;
+ p_tcb->leftotm = 0U;
+ LOG_TSKSTAT(p_tcb);
+}
+
+#endif /* TOPPERS_tskdmt */
+
+/*
+ * 休止状態から実行できる状態への遷移
+ */
+#ifdef TOPPERS_tskact
+
+bool_t
+make_active(TCB *p_tcb)
+{
+ activate_context(p_tcb);
+ p_tcb->tstat = TS_RUNNABLE;
+ LOG_TSKSTAT(p_tcb);
+ return(make_runnable(p_tcb));
+}
+
+#endif /* TOPPERS_tskact */
+
+/*
+ * タスクの優先度の変更
+ *
+ * タスクが実行できる状態の場合には,レディキューの中での位置を変更す
+ * る.オブジェクトの待ちキューの中で待ち状態になっている場合には,待
+ * ちキューの中での位置を変更する.
+ *
+ * 最高優先順位のタスクを更新するのは,(1) p_tcbが最高優先順位のタス
+ * クであって,その優先度を下げた場合,(2) p_tcbが最高優先順位のタス
+ * クではなく,変更後の優先度が最高優先順位のタスクの優先度よりも高い
+ * 場合である.(1)の場合には,レディキューをサーチする必要がある.
+ */
+#ifdef TOPPERS_tskpri
+
+bool_t
+change_priority(TCB *p_tcb, uint_t newpri)
+{
+ uint_t oldpri;
+
+ oldpri = p_tcb->priority;
+ p_tcb->priority = newpri;
+
+ if (TSTAT_RUNNABLE(p_tcb->tstat)) {
+ /*
+ * タスクが実行できる状態の場合
+ */
+ queue_delete(&(p_tcb->task_queue));
+ if (queue_empty(&(ready_queue[oldpri]))) {
+ primap_clear(oldpri);
+ }
+ queue_insert_prev(&(ready_queue[newpri]), &(p_tcb->task_queue));
+ primap_set(newpri);
+
+ if (p_schedtsk == p_tcb) {
+ if (newpri >= oldpri) {
+ p_schedtsk = search_schedtsk();
+ return(p_schedtsk != p_tcb && dspflg);
+ }
+ }
+ else {
+ if (newpri < p_schedtsk->priority) {
+ p_schedtsk = p_tcb;
+ return(dspflg);
+ }
+ }
+ }
+ else {
+ if (TSTAT_WAIT_WOBJCB(p_tcb->tstat)) {
+ /*
+ * タスクが,同期・通信オブジェクトの管理ブロックの共通部
+ * 分(WOBJCB)の待ちキューにつながれている場合
+ */
+ wobj_change_priority(((WINFO_WOBJ *)(p_tcb->p_winfo))->p_wobjcb,
+ p_tcb);
+ }
+ }
+ return(false);
+}
+
+#endif /* TOPPERS_tskpri */
+
+/*
+ * レディキューの回転
+ *
+ * 最高優先順位のタスクを更新するのは,最高優先順位のタスクがタスクキ
+ * ューの末尾に移動した場合である.
+ */
+#ifdef TOPPERS_tskrot
+
+bool_t
+rotate_ready_queue(uint_t pri)
+{
+ QUEUE *p_queue = &(ready_queue[pri]);
+ QUEUE *p_entry;
+
+ if (!queue_empty(p_queue) && p_queue->p_next->p_next != p_queue) {
+ p_entry = queue_delete_next(p_queue);
+ queue_insert_prev(p_queue, p_entry);
+ if (p_schedtsk == (TCB *) p_entry) {
+ p_schedtsk = (TCB *)(p_queue->p_next);
+ return(dspflg);
+ }
+ }
+ return(false);
+}
+
+#endif /* TOPPERS_tskrot */
+
+/*
+ * タスク例外処理ルーチンの呼出し
+ *
+ * ASPカーネルでは,タスク例外処理ルーチン内でCPUロック状態に遷移し,
+ * 元の状態に戻さずにリターンした場合,カーネルが元の状態に戻す.
+ */
+#ifdef TOPPERS_tsktex
+
+void
+call_texrtn(void)
+{
+ TEXPTN texptn;
+ PRI saved_ipm;
+ bool_t saved_disdsp, saved_dspflg;
+
+ saved_ipm = t_get_ipm();
+ saved_disdsp = disdsp;
+ saved_dspflg = dspflg;
+ p_runtsk->enatex = false;
+ do {
+ texptn = p_runtsk->texptn;
+ p_runtsk->texptn = 0U;
+
+ t_unlock_cpu();
+ LOG_TEX_ENTER(p_runtsk, texptn);
+ (*((TEXRTN)(p_runtsk->p_tinib->texrtn)))(texptn,
+ p_runtsk->p_tinib->exinf);
+ LOG_TEX_LEAVE(p_runtsk);
+ if (!t_sense_lock()) {
+ t_lock_cpu();
+ }
+ t_set_ipm(saved_ipm);
+ disdsp = saved_disdsp;
+ dspflg = saved_dspflg;
+ /*
+ * ここでp_runtsk->enatexをfalseにするのは,タスク例外処理ルー
+ * チンから,タスク例外処理許可状態のままリターンした場合の対
+ * 策である.
+ */
+ p_runtsk->enatex = false;
+ if (p_runtsk != p_schedtsk && dspflg) {
+ /*
+ * ここでdispatchを呼び出す処理は,相互再帰呼出しになって
+ * いるが,dispatchを呼ぶ前にp_runtsk->enatexをflaseにして
+ * おけば支障がない.その理由については,「TOPPERS/ASP カー
+ * ネル 設計メモ」を参照のこと.
+ */
+ dispatch();
+ }
+ } while (p_runtsk->texptn != 0U);
+ p_runtsk->enatex = true;
+}
+
+/*
+ * タスク例外処理ルーチンの起動
+ */
+#ifndef OMIT_CALLTEX
+
+void
+calltex(void)
+{
+ if (p_runtsk->enatex && p_runtsk->texptn != 0U) {
+ call_texrtn();
+ }
+}
+
+#endif /* OMIT_CALLTEX */
+#endif /* TOPPERS_tsktex */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: task.h 1863 2010-07-25 12:23:05Z ertl-hiro $
+ */
+
+/*
+ * タスク管理モジュール
+ */
+
+#ifndef TOPPERS_TASK_H
+#define TOPPERS_TASK_H
+
+#include <queue.h>
+#include "time_event.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_TSKSTAT
+#define LOG_TSKSTAT(p_tcb)
+#endif /* LOG_TSKSTAT */
+
+/*
+ * タスク優先度の内部表現・外部表現変換マクロ
+ */
+#define INT_PRIORITY(x) ((uint_t)((x) - TMIN_TPRI))
+#define EXT_TSKPRI(x) ((PRI)(x) + TMIN_TPRI)
+
+/*
+ * タスク状態の内部表現
+ *
+ * TCB中のタスク状態では,実行状態(RUNNING)と実行可能状態(READY)
+ * は区別しない.両状態を総称して,実行できる状態(RUNNABLE)と呼ぶ.
+ * 二重待ち状態は,(TS_WAITING | TS_SUSPENDED)で表す.TS_WAIT_???は待
+ * ち要因を表し,待ち状態(二重待ち状態を含む)の場合にのみ設定する.
+ */
+#define TS_DORMANT 0x00U /* 休止状態 */
+#define TS_RUNNABLE 0x01U /* 実行できる状態 */
+#define TS_WAITING 0x02U /* 待ち状態 */
+#define TS_SUSPENDED 0x04U /* 強制待ち状態 */
+
+#define TS_WAIT_DLY (0x00U << 3) /* 時間経過待ち */
+#define TS_WAIT_SLP (0x01U << 3) /* 起床待ち */
+#define TS_WAIT_RDTQ (0x02U << 3) /* データキューからの受信待ち */
+#define TS_WAIT_RPDQ (0x03U << 3) /* 優先度データキューからの受信待ち */
+#define TS_WAIT_SEM (0x04U << 3) /* セマフォ資源の獲得待ち */
+#define TS_WAIT_FLG (0x05U << 3) /* イベントフラグ待ち */
+#define TS_WAIT_SDTQ (0x06U << 3) /* データキューへの送信待ち */
+#define TS_WAIT_SPDQ (0x07U << 3) /* 優先度データキューへの送信待ち */
+#define TS_WAIT_MBX (0x08U << 3) /* メールボックスからの受信待ち */
+#define TS_WAIT_MPF (0x09U << 3) /* 固定長メモリブロックの獲得待ち */
+
+/*
+ * タスク状態判別マクロ
+ *
+ * TSTAT_DORMANTはタスクが休止状態であるかどうかを,TSTAT_RUNNABLEは
+ * タスクが実行できる状態であるかどうかを判別する.TSTAT_WAITINGは待
+ * ち状態と二重待ち状態のいずれかであるかどうかを,TSTAT_SUSPENDEDは
+ * 強制待ち状態と二重待ち状態のいずれかであるかどうかを判別する.
+ */
+#define TSTAT_DORMANT(tstat) ((tstat) == TS_DORMANT)
+#define TSTAT_RUNNABLE(tstat) (((tstat) & TS_RUNNABLE) != 0U)
+#define TSTAT_WAITING(tstat) (((tstat) & TS_WAITING) != 0U)
+#define TSTAT_SUSPENDED(tstat) (((tstat) & TS_SUSPENDED) != 0U)
+
+/*
+ * タスク待ち要因判別マクロ
+ *
+ * TSTAT_WAIT_SLPはタスクが起床待ちであるかどうかを,TSTAT_WAIT_WOBJ
+ * はタスクが同期・通信オブジェクトに対する待ちであるか(言い換えると,
+ * 同期通信オブジェクトの待ちキューにつながれているか)どうかを判別す
+ * る.また,TSTAT_WAIT_WOBJCBはタスクが同期・通信オブジェクトの管理
+ * ブロックの共通部分(WOBJCB)の待ちキューにつながれているかどうかを
+ * 判別する.
+ *
+ * TSTAT_WAIT_SLPは,任意のタスク状態の中から,タスクが起床待ちである
+ * ことを判別できる.すなわち,TSTAT_WAITINGにより待ち状態であることを
+ * 判別せずに,TSTAT_SLPだけを用いて起床待ち状態であることを判別できる.
+ * これを効率的に実現するために,TS_WAIT_SLPの値を,(0x00U << 3)ではな
+ * く(0x01U << 3)としている.そのため,タスクが時間経過待ち状態である
+ * ことを判別するためのTSTAT_WAIT_DLYを,TSTAT_WAIT_SLPと同様の方法で
+ * 実現することはできない.
+ */
+#define TS_WAIT_MASK (0x0fU << 3) /* 待ち要因の取出しマスク */
+
+#define TSTAT_WAIT_SLP(tstat) (((tstat) & TS_WAIT_MASK) == TS_WAIT_SLP)
+#define TSTAT_WAIT_WOBJ(tstat) (((tstat) & TS_WAIT_MASK) >= TS_WAIT_RDTQ)
+#define TSTAT_WAIT_WOBJCB(tstat) (((tstat) & TS_WAIT_MASK) >= TS_WAIT_SEM)
+
+/*
+ * 待ち情報ブロック(WINFO)の定義
+ *
+ * タスクが待ち状態の間は,TCBおよびそのp_winfoで指されるWINFOを次の
+ * ように設定しなければならない.
+ *
+ * (a) TCBのタスク状態を待ち状態(TS_WAITING)にする.その際に,待ち
+ * 要因(TS_WAIT_???)も設定する.
+ *
+ * (b) タイムアウトを監視するために,タイムイベントブロックを登録する.
+ * 登録するタイムイベントブロックは,待ちに入るサービスコール処理関数
+ * のローカル変数として確保し,それへのポインタをWINFOのp_tmevtbに記
+ * 憶する.タイムアウトの監視が必要ない場合(永久待ちの場合)には,
+ * p_tmevtbをNULLにする.
+ *
+ * 同期・通信オブジェクトに対する待ち状態の場合には,標準のWINFOに
+ * p_wobjcbフィールドを追加した構造体(WINFO_WOBJ,wait.hで定義)を使
+ * う.また,以下の(c)〜(e)の設定を行う必要がある.同期・通信オブジェ
+ * クトに関係しない待ち(起床待ち,時間経過待ち)の場合には,(c)〜(e)
+ * は必要ない.
+ *
+ * (c) TCBを待ち対象の同期・通信オブジェクトの待ちキューにつなぐ.待
+ * ちキューにつなぐために,task_queueを使う.
+ *
+ * (d) 待ち対象の同期・通信オブジェクトの管理ブロックへのポインタを,
+ * WINFO_WOBJのp_wobjcbに記憶する.
+ *
+ * (e) 待ち対象の同期・通信オブジェクトに依存して記憶することが必要な
+ * 情報がある場合には,WINFO_WOBJに必要な情報のためのフィールドを追加
+ * した構造体を定義し,WINFO_WOBJの代わりに用いる.
+ *
+ * 待ち状態を解除する際には,待ち解除したタスクに対する返値をWINFOの
+ * wercdに設定する.wercdが必要なのは待ち解除以降であるのに対して,
+ * p_tmevtbは待ち解除後は必要ないため,メモリ節約のために共用体を使っ
+ * ている.そのため,wercdへエラーコードを設定するのは,タイムイベント
+ * ブロックを登録解除した後にしなければならない.
+ */
+typedef union waiting_information {
+ ER wercd; /* 待ち解除時のエラーコード */
+ TMEVTB *p_tmevtb; /* 待ち状態用のタイムイベントブロック */
+} WINFO;
+
+/*
+ * タスク初期化ブロック
+ *
+ * タスクに関する情報を,値が変わらないためにROMに置ける部分(タスク
+ * 初期化ブロック)と,値が変化するためにRAMに置かなければならない部
+ * 分(タスク管理ブロック,TCB)に分離し,TCB内に対応するタスク初期化
+ * ブロックを指すポインタを入れる.タスク初期化ブロック内に対応する
+ * TCBを指すポインタを入れる方法の方が,RAMの節約の観点からは望ましい
+ * が,実行効率が悪くなるために採用していない.他のオブジェクトについ
+ * ても同様に扱う.
+ *
+ * タスク初期化ブロックには,DEF_TEXで定義されるタスク例外処理ルーチ
+ * ンに関する情報も含む.
+ */
+typedef struct task_initialization_block {
+ ATR tskatr; /* タスク属性 */
+ intptr_t exinf; /* タスクの拡張情報 */
+ TASK task; /* タスクの起動番地 */
+ uint_t ipriority; /* タスクの起動時優先度(内部表現) */
+
+#ifdef USE_TSKINICTXB
+ TSKINICTXB tskinictxb; /* タスク初期化コンテキストブロック */
+#else /* USE_TSKINICTXB */
+ SIZE stksz; /* スタック領域のサイズ(丸めた値) */
+ void *stk; /* スタック領域の先頭番地 */
+#endif /* USE_TSKINICTXB */
+
+ ATR texatr; /* タスク例外処理ルーチン属性 */
+ TEXRTN texrtn; /* タスク例外処理ルーチンの起動番地 */
+} TINIB;
+
+/*
+ * TCB中のフィールドのビット幅の定義
+ *
+ * プロセッサによっては,TCB中のフィールドのビット幅でメモリ使用量と
+ * 性能がトレードオフになるため,ターゲット依存にフィールドのビット幅
+ * を変更することを許している.
+ */
+#ifndef TBIT_TCB_PRIORITY
+#define TBIT_TCB_PRIORITY 8 /* priorityフィールドのビット幅 */
+#endif /* TBIT_TCB_PRIORITY */
+
+/*
+ * タスク管理ブロック(TCB)
+ *
+ * ASPカーネルでは,タスクの起動要求キューイング数の最大値(TMAX_ACTCNT)
+ * と起床要求キューイング数の最大値(TMAX_WUPCNT)は1に固定されている
+ * ため,キューイングされているかどうかの真偽値で表現することができる.
+ * また,強制待ち要求ネスト数の最大値(TMAX_SUSCNT)が1に固定されてい
+ * るので,強制待ち要求ネスト数(suscnt)は必要ない.
+ *
+ * TCBのいくつかのフィールドは,特定のタスク状態でのみ有効な値を保持し,
+ * それ以外の場合は値が保証されない(よって,参照してはならない).各
+ * フィールドが有効な値を保持する条件は次の通り.
+ *
+ * ・初期化後は常に有効:
+ * p_tinib,tstat,actque
+ * ・休止状態以外で有効(休止状態では初期値になっている):
+ * priority,wupque,enatex,texptn,leftotm
+ * ・待ち状態(二重待ち状態を含む)で有効:
+ * p_winfo
+ * ・実行できる状態と同期・通信オブジェクトに対する待ち状態で有効:
+ * task_queue
+ * ・実行可能状態,待ち状態,強制待ち状態,二重待ち状態で有効:
+ * tskctxb
+ */
+typedef struct task_control_block {
+ QUEUE task_queue; /* タスクキュー */
+ const TINIB *p_tinib; /* 初期化ブロックへのポインタ */
+
+#ifdef UINT8_MAX
+ uint8_t tstat; /* タスク状態(内部表現)*/
+#else /* UINT8_MAX */
+ BIT_FIELD_UINT tstat : 8; /* タスク状態(内部表現)*/
+#endif /* UINT8_MAX */
+#if defined(UINT8_MAX) && (TBIT_TCB_PRIORITY == 8)
+ uint8_t priority; /* 現在の優先度(内部表現)*/
+#else /* defined(UINT8_MAX) && (TBIT_TCB_PRIORITY == 8) */
+ BIT_FIELD_UINT priority : TBIT_TCB_PRIORITY;
+ /* 現在の優先度(内部表現)*/
+#endif /* defined(UINT8_MAX) && (TBIT_TCB_PRIORITY == 8) */
+ BIT_FIELD_BOOL actque : 1; /* 起動要求キューイング */
+ BIT_FIELD_BOOL wupque : 1; /* 起床要求キューイング */
+ BIT_FIELD_BOOL enatex : 1; /* タスク例外処理許可状態 */
+
+ TEXPTN texptn; /* 保留例外要因 */
+ WINFO *p_winfo; /* 待ち情報ブロックへのポインタ */
+ OVRTIM leftotm; /* 残りプロセッサ時間 */
+ TSKCTXB tskctxb; /* タスクコンテキストブロック */
+} TCB;
+
+/*
+ * 実行状態のタスク
+ *
+ * 実行状態のタスク(=プロセッサがコンテキストを持っているタスク)の
+ * TCBを指すポインタ.実行状態のタスクがない場合はNULLにする.
+ *
+ * サービスコールの処理中で,自タスク(サービスコールを呼び出したタス
+ * ク)に関する情報を参照する場合はp_runtskを使う.p_runtskを書き換え
+ * るのは,ディスパッチャ(と初期化処理)のみである.
+ */
+extern TCB *p_runtsk;
+
+/*
+ * 最高優先順位のタスク
+ *
+ * 実行できるタスクの中で最高優先順位のタスクのTCBを指すポインタ.実
+ * 行できるタスクがない場合はNULLにする.
+ *
+ * ディスパッチ禁止状態など,ディスパッチが保留されている間はp_runtsk
+ * と一致しているとは限らない.
+ */
+extern TCB *p_schedtsk;
+
+/*
+ * ディスパッチ/タスク例外処理ルーチン起動要求フラグ
+ *
+ * 割込みハンドラ/CPU例外ハンドラの出口処理に,ディスパッチまたは
+ * タスク例外処理ルーチンの起動を要求することを示すフラグ.
+ */
+extern bool_t reqflg;
+
+/*
+ * ディスパッチ禁止状態
+ *
+ * ディスパッチ禁止状態であることを示すフラグ.
+ */
+extern bool_t disdsp;
+
+/*
+ * タスクディスパッチ可能状態
+ *
+ * 割込み優先度マスク全解除状態であり,ディスパッチ許可状態である(ディ
+ * スパッチ禁止状態でない)ことを示すフラグ.
+ */
+extern bool_t dspflg;
+
+/*
+ * レディキュー
+ *
+ * レディキューは,実行できる状態のタスクを管理するためのキューである.
+ * 実行状態のタスクも管理しているため,レディ(実行可能)キューという
+ * 名称は正確ではないが,レディキューという名称が定着しているため,こ
+ * の名称で呼ぶことにする.
+ *
+ * レディキューは,優先度ごとのタスクキューで構成されている.タスクの
+ * TCBは,該当する優先度のキューに登録される.
+ */
+extern QUEUE ready_queue[TNUM_TPRI];
+
+/*
+ * レディキューサーチのためのビットマップ
+ *
+ * レディキューのサーチを効率よく行うために,優先度ごとのタスクキュー
+ * にタスクが入っているかどうかを示すビットマップを用意している.ビッ
+ * トマップを使うことで,メモリアクセスの回数を減らすことができるが,
+ * ビット操作命令が充実していないプロセッサで,優先度の段階数が少ない
+ * 場合には,ビットマップ操作のオーバーヘッドのために,逆に効率が落ち
+ * る可能性もある.
+ *
+ * 優先度が16段階であることを仮定しているため,uint16_t型としている.
+ */
+extern uint16_t ready_primap;
+
+/*
+ * タスクIDの最大値(kernel_cfg.c)
+ */
+extern const ID tmax_tskid;
+
+/*
+ * タスク初期化ブロックのエリア(kernel_cfg.c)
+ */
+extern const TINIB tinib_table[];
+
+/*
+ * タスク生成順序テーブル(kernel_cfg.c)
+ */
+extern const ID torder_table[];
+
+/*
+ * TCBのエリア(kernel_cfg.c)
+ */
+extern TCB tcb_table[];
+
+/*
+ * タスクの数
+ */
+#define tnum_tsk ((uint_t)(tmax_tskid - TMIN_TSKID + 1))
+
+/*
+ * タスクIDからTCBを取り出すためのマクロ
+ */
+#define INDEX_TSK(tskid) ((uint_t)((tskid) - TMIN_TSKID))
+#define get_tcb(tskid) (&(tcb_table[INDEX_TSK(tskid)]))
+#define get_tcb_self(tskid) ((tskid) == TSK_SELF ? p_runtsk : get_tcb(tskid))
+
+/*
+ * TCBからタスクIDを取り出すためのマクロ
+ */
+#define TSKID(p_tcb) ((ID)(((p_tcb) - tcb_table) + TMIN_TSKID))
+
+/*
+ * タスク管理モジュールの初期化
+ */
+extern void initialize_task(void);
+
+/*
+ * 最高優先順位タスクのサーチ
+ *
+ * レディキュー中の最高優先順位のタスクをサーチし,そのTCBへのポインタ
+ * を返す.レディキューが空の場合には,この関数を呼び出してはならない.
+ */
+extern TCB *search_schedtsk(void);
+
+/*
+ * 実行できる状態への遷移
+ *
+ * p_tcbで指定されるタスクをレディキューに挿入する.レディキューに挿入
+ * したタスクの優先度が,最高優先順位のタスクの優先度よりも高い場合は,
+ * 最高優先順位のタスクを更新し,ディスパッチ許可状態であればtrueを返
+ * す.そうでない場合はfalseを返す.
+ */
+extern bool_t make_runnable(TCB *p_tcb);
+
+/*
+ * 実行できる状態から他の状態への遷移
+ *
+ * p_tcbで指定されるタスクをレディキューから削除する.p_tcbで指定した
+ * タスクが最高優先順位のタスクであった場合には,最高優先順位のタスク
+ * を設定しなおし,ディスパッチ許可状態であればtrueを返す.そうでない
+ * 場合はfalseを返す.タスクの状態は更新しない.
+ */
+extern bool_t make_non_runnable(TCB *p_tcb);
+
+/*
+ * 休止状態への遷移
+ *
+ * p_tcbで指定されるタスクの状態を休止状態とする.また,タスクの起動
+ * 時に初期化すべき変数の初期化と,タスク起動のためのコンテキストを設
+ * 定する.
+ */
+extern void make_dormant(TCB *p_tcb);
+
+/*
+ * 休止状態から実行できる状態への遷移
+ *
+ * p_tcbで指定されるタスクの状態を休止状態から実行できる状態とする.
+ * 実行できる状態に遷移したタスクへのディスパッチが必要な場合はtrue,
+ * そうでない場合はfalseを返す.
+ */
+extern bool_t make_active(TCB *p_tcb);
+
+/*
+ * タスクの優先度の変更
+ *
+ * p_tcbで指定されるタスクの優先度をnewpri(内部表現)に変更する.また,
+ * 必要な場合には最高優先順位のタスクを更新し,ディスパッチ許可状態で
+ * あればtrueを返す.そうでない場合はfalseを返す.
+ */
+extern bool_t change_priority(TCB *p_tcb, uint_t newpri);
+
+/*
+ * レディキューの回転
+ *
+ * レディキュー中の,priで指定される優先度のタスクキューを回転させる.
+ * また,必要な場合には最高優先順位のタスクを変更し,ディスパッチが保
+ * 留されていなければtrueを返す.そうでない場合はfalseを返す.
+ */
+extern bool_t rotate_ready_queue(uint_t pri);
+
+/*
+ * タスク例外処理ルーチンの呼出し
+ *
+ * タスク例外処理ルーチンを呼び出す.呼び出す前に,実行状態のタスクの
+ * 保留例外要因をクリアし,タスク例外処理禁止状態にし,CPUロックを解
+ * 除する.
+ *
+ * タスク例外処理ルーチンから戻ると,まずCPUロック状態に戻し,その間
+ * に保留例外要因が0でなくなっていれば,再びタスク例外処理ルーチンを
+ * 呼び出す.保留例外要因が0の場合には,例外処理許可状態にして関数か
+ * らリターンする.
+ *
+ * この関数は,実行状態のタスクが,タスク例外処理許可状態(enatexが
+ * true)で,保留例外要因が0でない(texptnが0でない)場合に呼び出すこ
+ * とを想定している.この関数は,CPUロック状態で呼び出さなければなら
+ * ない.
+ */
+extern void call_texrtn(void);
+
+/*
+ * タスク例外処理ルーチンの起動
+ *
+ * 実行状態のタスクがタスク例外処理ルーチンの起動条件を満たしていれば,
+ * タスク例外処理ルーチンを呼び出す.CPU例外処理ルーチンを呼び出す時
+ * は,一時的にCPUロックを解除する.
+ *
+ * この関数は,ディスパッチャや割込みハンドラ/CPU例外ハンドラの出口
+ * 処理から呼び出されることを想定している.この関数は,CPUロック状態
+ * で呼び出さなければならない.
+ *
+ * 実行効率を上げるために,この関数をターゲット依存部で記述してもよい.
+ * その場合には,OMIT_CALLTEXをマクロ定義する.
+ */
+extern void calltex(void);
+
+#endif /* TOPPERS_TASK_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: task_manage.c 1717 2010-01-31 11:41:03Z ertl-hiro $
+ */
+
+/*
+ * タスク管理機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "overrun.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_ACT_TSK_ENTER
+#define LOG_ACT_TSK_ENTER(tskid)
+#endif /* LOG_ACT_TSK_ENTER */
+
+#ifndef LOG_ACT_TSK_LEAVE
+#define LOG_ACT_TSK_LEAVE(ercd)
+#endif /* LOG_ACT_TSK_LEAVE */
+
+#ifndef LOG_IACT_TSK_ENTER
+#define LOG_IACT_TSK_ENTER(tskid)
+#endif /* LOG_IACT_TSK_ENTER */
+
+#ifndef LOG_IACT_TSK_LEAVE
+#define LOG_IACT_TSK_LEAVE(ercd)
+#endif /* LOG_IACT_TSK_LEAVE */
+
+#ifndef LOG_CAN_ACT_ENTER
+#define LOG_CAN_ACT_ENTER(tskid)
+#endif /* LOG_CAN_ACT_ENTER */
+
+#ifndef LOG_CAN_ACT_LEAVE
+#define LOG_CAN_ACT_LEAVE(ercd)
+#endif /* LOG_CAN_ACT_LEAVE */
+
+#ifndef LOG_EXT_TSK_ENTER
+#define LOG_EXT_TSK_ENTER()
+#endif /* LOG_EXT_TSK_ENTER */
+
+#ifndef LOG_EXT_TSK_LEAVE
+#define LOG_EXT_TSK_LEAVE(ercd)
+#endif /* LOG_EXT_TSK_LEAVE */
+
+#ifndef LOG_TER_TSK_ENTER
+#define LOG_TER_TSK_ENTER(tskid)
+#endif /* LOG_TER_TSK_ENTER */
+
+#ifndef LOG_TER_TSK_LEAVE
+#define LOG_TER_TSK_LEAVE(ercd)
+#endif /* LOG_TER_TSK_LEAVE */
+
+#ifndef LOG_CHG_PRI_ENTER
+#define LOG_CHG_PRI_ENTER(tskid, tskpri)
+#endif /* LOG_CHG_PRI_ENTER */
+
+#ifndef LOG_CHG_PRI_LEAVE
+#define LOG_CHG_PRI_LEAVE(ercd)
+#endif /* LOG_CHG_PRI_LEAVE */
+
+#ifndef LOG_GET_PRI_ENTER
+#define LOG_GET_PRI_ENTER(tskid, p_tskpri)
+#endif /* LOG_GET_PRI_ENTER */
+
+#ifndef LOG_GET_PRI_LEAVE
+#define LOG_GET_PRI_LEAVE(ercd, tskpri)
+#endif /* LOG_GET_PRI_LEAVE */
+
+#ifndef LOG_GET_INF_ENTER
+#define LOG_GET_INF_ENTER(p_exinf)
+#endif /* LOG_GET_INF_ENTER */
+
+#ifndef LOG_GET_INF_LEAVE
+#define LOG_GET_INF_LEAVE(ercd, exinf)
+#endif /* LOG_GET_INF_LEAVE */
+
+/*
+ * タスクの起動
+ */
+#ifdef TOPPERS_act_tsk
+
+ER
+act_tsk(ID tskid)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_ACT_TSK_ENTER(tskid);
+ CHECK_TSKCTX_UNL();
+ CHECK_TSKID_SELF(tskid);
+ p_tcb = get_tcb_self(tskid);
+
+ t_lock_cpu();
+ if (TSTAT_DORMANT(p_tcb->tstat)) {
+ if (make_active(p_tcb)) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ else if (!(p_tcb->actque)) {
+ p_tcb->actque = true;
+ ercd = E_OK;
+ }
+ else {
+ ercd = E_QOVR;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_ACT_TSK_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_act_tsk */
+
+/*
+ * タスクの起動(非タスクコンテキスト用)
+ */
+#ifdef TOPPERS_iact_tsk
+
+ER
+iact_tsk(ID tskid)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_IACT_TSK_ENTER(tskid);
+ CHECK_INTCTX_UNL();
+ CHECK_TSKID(tskid);
+ p_tcb = get_tcb(tskid);
+
+ i_lock_cpu();
+ if (TSTAT_DORMANT(p_tcb->tstat)) {
+ if (make_active(p_tcb)) {
+ reqflg = true;
+ }
+ ercd = E_OK;
+ }
+ else if (!(p_tcb->actque)) {
+ p_tcb->actque = true;
+ ercd = E_OK;
+ }
+ else {
+ ercd = E_QOVR;
+ }
+ i_unlock_cpu();
+
+ error_exit:
+ LOG_IACT_TSK_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_iact_tsk */
+
+/*
+ * タスク起動要求のキャンセル
+ */
+#ifdef TOPPERS_can_act
+
+ER_UINT
+can_act(ID tskid)
+{
+ TCB *p_tcb;
+ ER_UINT ercd;
+
+ LOG_CAN_ACT_ENTER(tskid);
+ CHECK_TSKCTX_UNL();
+ CHECK_TSKID_SELF(tskid);
+ p_tcb = get_tcb_self(tskid);
+
+ t_lock_cpu();
+ ercd = p_tcb->actque ? 1 : 0;
+ p_tcb->actque = false;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_CAN_ACT_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_can_act */
+
+/*
+ * 自タスクの終了
+ */
+#ifdef TOPPERS_ext_tsk
+
+ER
+ext_tsk(void)
+{
+ ER ercd;
+
+ LOG_EXT_TSK_ENTER();
+ CHECK_TSKCTX();
+
+ if (t_sense_lock()) {
+ /*
+ * CPUロック状態でext_tskが呼ばれた場合は,CPUロックを解除し
+ * てからタスクを終了する.実装上は,サービスコール内でのCPU
+ * ロックを省略すればよいだけ.
+ */
+ }
+ else {
+ t_lock_cpu();
+ }
+ if (disdsp) {
+ /*
+ * ディスパッチ禁止状態でext_tskが呼ばれた場合は,ディスパッ
+ * チ許可状態にしてからタスクを終了する.
+ */
+ disdsp = false;
+ }
+ if (t_get_ipm() != TIPM_ENAALL) {
+ /*
+ * 割込み優先度マスク(IPM)がTIPM_ENAALL以外の状態でext_tsk
+ * が呼ばれた場合は,IPMをTIPM_ENAALLにしてからタスクを終了す
+ * る.
+ */
+ t_set_ipm(TIPM_ENAALL);
+ }
+ dspflg = true;
+
+ (void) make_non_runnable(p_runtsk);
+#ifdef TOPPERS_SUPPORT_OVRHDR
+ ovrtimer_stop();
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+ make_dormant(p_runtsk);
+ if (p_runtsk->actque) {
+ p_runtsk->actque = false;
+ (void) make_active(p_runtsk);
+ }
+ exit_and_dispatch();
+ return(E_SYS);
+
+ error_exit:
+ LOG_EXT_TSK_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ext_tsk */
+
+/*
+ * タスクの強制終了
+ */
+#ifdef TOPPERS_ter_tsk
+
+ER
+ter_tsk(ID tskid)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_TER_TSK_ENTER(tskid);
+ CHECK_TSKCTX_UNL();
+ CHECK_TSKID(tskid);
+ p_tcb = get_tcb(tskid);
+ CHECK_NONSELF(p_tcb);
+
+ t_lock_cpu();
+ if (TSTAT_DORMANT(p_tcb->tstat)) {
+ ercd = E_OBJ;
+ }
+ else {
+ if (TSTAT_RUNNABLE(p_tcb->tstat)) {
+ /*
+ * p_tcbは自タスクでないため,(シングルプロセッサでは)実
+ * 行状態でなく,make_non_runnable(p_tcb)でタスクディスパッ
+ * チが必要になることはない.
+ */
+ (void) make_non_runnable(p_tcb);
+ }
+ else if (TSTAT_WAITING(p_tcb->tstat)) {
+ wait_dequeue_wobj(p_tcb);
+ wait_dequeue_tmevtb(p_tcb);
+ }
+ make_dormant(p_tcb);
+ if (p_tcb->actque) {
+ p_tcb->actque = false;
+ if (make_active(p_tcb)) {
+ dispatch();
+ }
+ }
+ ercd = E_OK;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_TER_TSK_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ter_tsk */
+
+/*
+ * タスク優先度の変更
+ */
+#ifdef TOPPERS_chg_pri
+
+ER
+chg_pri(ID tskid, PRI tskpri)
+{
+ TCB *p_tcb;
+ uint_t newpri;
+ ER ercd;
+
+ LOG_CHG_PRI_ENTER(tskid, tskpri);
+ CHECK_TSKCTX_UNL();
+ CHECK_TSKID_SELF(tskid);
+ CHECK_TPRI_INI(tskpri);
+ p_tcb = get_tcb_self(tskid);
+ newpri = (tskpri == TPRI_INI) ? p_tcb->p_tinib->ipriority
+ : INT_PRIORITY(tskpri);
+
+ t_lock_cpu();
+ if (TSTAT_DORMANT(p_tcb->tstat)) {
+ ercd = E_OBJ;
+ }
+ else {
+ if (change_priority(p_tcb, newpri)) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_CHG_PRI_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_chg_pri */
+
+/*
+ * タスク優先度の参照
+ */
+#ifdef TOPPERS_get_pri
+
+ER
+get_pri(ID tskid, PRI *p_tskpri)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_GET_PRI_ENTER(tskid, p_tskpri);
+ CHECK_TSKCTX_UNL();
+ CHECK_TSKID_SELF(tskid);
+ p_tcb = get_tcb_self(tskid);
+
+ t_lock_cpu();
+ if (TSTAT_DORMANT(p_tcb->tstat)) {
+ ercd = E_OBJ;
+ }
+ else {
+ *p_tskpri = EXT_TSKPRI(p_tcb->priority);
+ ercd = E_OK;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_GET_PRI_LEAVE(ercd, *p_tskpri);
+ return(ercd);
+}
+
+#endif /* TOPPERS_get_pri */
+
+/*
+ * 自タスクの拡張情報の参照
+ */
+#ifdef TOPPERS_get_inf
+
+ER
+get_inf(intptr_t *p_exinf)
+{
+ ER ercd;
+
+ LOG_GET_INF_ENTER(p_exinf);
+ CHECK_TSKCTX_UNL();
+
+ t_lock_cpu();
+ *p_exinf = p_runtsk->p_tinib->exinf;
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_GET_INF_LEAVE(ercd, *p_exinf);
+ return(ercd);
+}
+
+#endif /* TOPPERS_get_inf */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: sample1.c 1812 2010-06-27 13:07:15Z ertl-hiro $
+ */
+
+/*
+ * サンプルプログラム(1)の本体
+ *
+ * ASPカーネルの基本的な動作を確認するためのサンプルプログラム.
+ *
+ * プログラムの概要:
+ *
+ * ユーザインタフェースを受け持つメインタスク(タスクID: MAIN_TASK,優
+ * 先度: MAIN_PRIORITY)と,3つの並列実行されるタスク(タスクID:
+ * TASK1〜TASK3,初期優先度: MID_PRIORITY)で構成される.また,起動周
+ * 期が2秒の周期ハンドラ(周期ハンドラID: CYCHDR1)を用いる.
+ *
+ * 並列実行されるタスクは,task_loop回空ループを実行する度に,タスクが
+ * 実行中であることをあらわすメッセージを表示する.
+ *
+ * 周期ハンドラは,三つの優先度(HIGH_PRIORITY,MID_PRIORITY,
+ * LOW_PRIORITY)のレディキューを回転させる.プログラムの起動直後は,
+ * 周期ハンドラは停止状態になっている.
+ *
+ * メインタスクは,シリアルI/Oポートからの文字入力を行い(文字入力を
+ * 待っている間は,並列実行されるタスクが実行されている),入力された
+ * 文字に対応した処理を実行する.入力された文字と処理の関係は次の通り.
+ * Control-Cまたは'Q'が入力されると,プログラムを終了する.
+ *
+ * '1' : 対象タスクをTASK1に切り換える(初期設定).
+ * '2' : 対象タスクをTASK2に切り換える.
+ * '3' : 対象タスクをTASK3に切り換える.
+ * 'a' : 対象タスクをact_tskにより起動する.
+ * 'A' : 対象タスクに対する起動要求をcan_actによりキャンセルする.
+ * 'e' : 対象タスクにext_tskを呼び出させ,終了させる.
+ * 't' : 対象タスクをter_tskにより強制終了する.
+ * '>' : 対象タスクの優先度をHIGH_PRIORITYにする.
+ * '=' : 対象タスクの優先度をMID_PRIORITYにする.
+ * '<' : 対象タスクの優先度をLOW_PRIORITYにする.
+ * 'G' : 対象タスクの優先度をget_priで読み出す.
+ * 's' : 対象タスクにslp_tskを呼び出させ,起床待ちにさせる.
+ * 'S' : 対象タスクにtslp_tsk(10秒)を呼び出させ,起床待ちにさせる.
+ * 'w' : 対象タスクをwup_tskにより起床する.
+ * 'W' : 対象タスクに対する起床要求をcan_wupによりキャンセルする.
+ * 'l' : 対象タスクをrel_waiにより強制的に待ち解除にする.
+ * 'u' : 対象タスクをsus_tskにより強制待ち状態にする.
+ * 'm' : 対象タスクの強制待ち状態をrsm_tskにより解除する.
+ * 'd' : 対象タスクにdly_tsk(10秒)を呼び出させ,時間経過待ちにさせる.
+ * 'x' : 対象タスクに例外パターン0x0001の例外処理を要求する.
+ * 'X' : 対象タスクに例外パターン0x0002の例外処理を要求する.
+ * 'y' : 対象タスクにdis_texを呼び出させ,タスク例外を禁止する.
+ * 'Y' : 対象タスクにena_texを呼び出させ,タスク例外を許可する.
+ * 'r' : 3つの優先度(HIGH_PRIORITY,MID_PRIORITY,LOW_PRIORITY)のレ
+ * ディキューを回転させる.
+ * 'c' : 周期ハンドラを動作開始させる.
+ * 'C' : 周期ハンドラを動作停止させる.
+ * 'b' : アラームハンドラを5秒後に起動するよう動作開始させる.
+ * 'B' : アラームハンドラを動作停止させる.
+ * 'z' : 対象タスクにCPU例外を発生させる(タスクを終了させる).
+ * 'Z' : 対象タスクにCPUロック状態でCPU例外を発生させる(プログラムを
+ * 終了する).
+ * 'V' : get_utmで性能評価用システム時刻を2回読む.
+ * 'o' : 対象タスクに対してオーバランハンドラを動作開始させる
+ * 'O' : 対象タスクに対してオーバランハンドラを動作停止させる
+ * 'v' : 発行したシステムコールを表示する(デフォルト).
+ * 'q' : 発行したシステムコールを表示しない.
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "kernel_cfg.h"
+#include "sample1.h"
+
+/*
+ * サービスコールのエラーのログ出力
+ */
+Inline void
+svc_perror(const char *file, int_t line, const char *expr, ER ercd)
+{
+ if (ercd < 0) {
+ t_perror(LOG_ERROR, file, line, expr, ercd);
+ }
+}
+
+#define SVC_PERROR(expr) svc_perror(__FILE__, __LINE__, #expr, (expr))
+
+/*
+ * 並行実行されるタスクへのメッセージ領域
+ */
+char_t message[3];
+
+/*
+ * ループ回数
+ */
+ulong_t task_loop; /* タスク内でのループ回数 */
+ulong_t tex_loop; /* 例外処理ルーチン内でのループ回数 */
+
+/*
+ * 並行実行されるタスク
+ */
+void task(intptr_t exinf)
+{
+ volatile ulong_t i;
+ int_t n = 0;
+ int_t tskno = (int_t) exinf;
+ const char *graph[] = { "| ", " + ", " *" };
+ char_t c;
+ T_ROVR pk_rovr;
+
+ SVC_PERROR(ena_tex());
+ while (1) {
+#ifdef TOPPERS_SUPPORT_OVRHDR
+ SVC_PERROR(ref_ovr(TSK_SELF, &pk_rovr));
+ if ((pk_rovr.ovrstat & TOVR_STA) != 0) {
+ syslog(LOG_NOTICE, "task%d is running (%03d). %s [%ld]",
+ tskno, ++n, graph[tskno-1], pk_rovr.leftotm);
+ }
+ else {
+ syslog(LOG_NOTICE, "task%d is running (%03d). %s",
+ tskno, ++n, graph[tskno-1]);
+ }
+#else /* TOPPERS_SUPPORT_OVRHDR */
+ syslog(LOG_NOTICE, "task%d is running (%03d). %s",
+ tskno, ++n, graph[tskno-1]);
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+ for (i = 0; i < task_loop; i++);
+ c = message[tskno-1];
+ message[tskno-1] = 0;
+ switch (c) {
+ case 'e':
+ syslog(LOG_INFO, "#%d#ext_tsk()", tskno);
+ SVC_PERROR(ext_tsk());
+ assert(0);
+ case 's':
+ syslog(LOG_INFO, "#%d#slp_tsk()", tskno);
+ SVC_PERROR(slp_tsk());
+ break;
+ case 'S':
+ syslog(LOG_INFO, "#%d#tslp_tsk(10000)", tskno);
+ SVC_PERROR(tslp_tsk(10000));
+ break;
+ case 'd':
+ syslog(LOG_INFO, "#%d#dly_tsk(10000)", tskno);
+ SVC_PERROR(dly_tsk(10000));
+ break;
+ case 'y':
+ syslog(LOG_INFO, "#%d#dis_tex()", tskno);
+ SVC_PERROR(dis_tex());
+ break;
+ case 'Y':
+ syslog(LOG_INFO, "#%d#ena_tex()", tskno);
+ SVC_PERROR(ena_tex());
+ break;
+#ifdef CPUEXC1
+ case 'z':
+ syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno);
+ RAISE_CPU_EXCEPTION;
+ break;
+ case 'Z':
+ SVC_PERROR(loc_cpu());
+ syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno);
+ RAISE_CPU_EXCEPTION;
+ SVC_PERROR(unl_cpu());
+ break;
+#endif /* CPUEXC1 */
+ default:
+ break;
+ }
+ }
+}
+
+/*
+ * 並行して実行されるタスク用のタスク例外処理ルーチン
+ */
+void tex_routine(TEXPTN texptn, intptr_t exinf)
+{
+ volatile ulong_t i;
+ int_t tskno = (int_t) exinf;
+
+ syslog(LOG_NOTICE, "task%d receives exception 0x%04x.", tskno, texptn);
+ for (i = 0; i < tex_loop; i++);
+
+ if ((texptn & 0x8000U) != 0U) {
+ syslog(LOG_INFO, "#%d#ext_tsk()", tskno);
+ SVC_PERROR(ext_tsk());
+ assert(0);
+ }
+}
+
+/*
+ * CPU例外ハンドラ
+ */
+#ifdef CPUEXC1
+
+void
+cpuexc_handler(void *p_excinf)
+{
+ ID tskid;
+
+ syslog(LOG_NOTICE, "CPU exception handler (p_excinf = %08p).", p_excinf);
+ if (sns_ctx() != true) {
+ syslog(LOG_WARNING,
+ "sns_ctx() is not true in CPU exception handler.");
+ }
+ if (sns_dpn() != true) {
+ syslog(LOG_WARNING,
+ "sns_dpn() is not true in CPU exception handler.");
+ }
+ syslog(LOG_INFO, "sns_loc = %d sns_dsp = %d sns_tex = %d",
+ sns_loc(), sns_dsp(), sns_tex());
+ syslog(LOG_INFO, "xsns_dpn = %d xsns_xpn = %d",
+ xsns_dpn(p_excinf), xsns_xpn(p_excinf));
+
+ if (xsns_xpn(p_excinf)) {
+ syslog(LOG_NOTICE, "Sample program ends with exception.");
+ SVC_PERROR(ext_ker());
+ assert(0);
+ }
+
+ SVC_PERROR(iget_tid(&tskid));
+ SVC_PERROR(iras_tex(tskid, 0x8000U));
+}
+
+#endif /* CPUEXC1 */
+
+/*
+ * 周期ハンドラ
+ *
+ * HIGH_PRIORITY,MID_PRIORITY,LOW_PRIORITY の各優先度のレディキュー
+ * を回転させる.
+ */
+void cyclic_handler(intptr_t exinf)
+{
+ SVC_PERROR(irot_rdq(HIGH_PRIORITY));
+ SVC_PERROR(irot_rdq(MID_PRIORITY));
+ SVC_PERROR(irot_rdq(LOW_PRIORITY));
+}
+
+/*
+ * アラームハンドラ
+ *
+ * HIGH_PRIORITY,MID_PRIORITY,LOW_PRIORITY の各優先度のレディキュー
+ * を回転させる.
+ */
+void alarm_handler(intptr_t exinf)
+{
+ SVC_PERROR(irot_rdq(HIGH_PRIORITY));
+ SVC_PERROR(irot_rdq(MID_PRIORITY));
+ SVC_PERROR(irot_rdq(LOW_PRIORITY));
+}
+
+/*
+ * オーバランハンドラ
+ */
+#ifdef TOPPERS_SUPPORT_OVRHDR
+
+void
+overrun_handler(ID tskid, intptr_t exinf)
+{
+ int_t tskno = (int_t) exinf;
+
+ syslog(LOG_NOTICE, "Overrun handler for task%d.", tskno);
+ syslog(LOG_INFO, "#iras_tex(%d, 0x0004U)", tskno);
+ SVC_PERROR(iras_tex(tskid, 0x0004U));
+}
+
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+
+/*
+ * メインタスク
+ */
+void main_task(intptr_t exinf)
+{
+ char_t c;
+ ID tskid = TASK1;
+ int_t tskno = 1;
+ ER_UINT ercd;
+ PRI tskpri;
+#ifndef TASK_LOOP
+ volatile ulong_t i;
+ SYSTIM stime1, stime2;
+#endif /* TASK_LOOP */
+#ifdef TOPPERS_SUPPORT_GET_UTM
+ SYSUTM utime1, utime2;
+#endif /* TOPPERS_SUPPORT_GET_UTM */
+
+ SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG)));
+ syslog(LOG_NOTICE, "Sample program starts (exinf = %d).", (int_t) exinf);
+
+ /*
+ * シリアルポートの初期化
+ *
+ * システムログタスクと同じシリアルポートを使う場合など,シリアル
+ * ポートがオープン済みの場合にはここでE_OBJエラーになるが,支障は
+ * ない.
+ */
+ ercd = serial_opn_por(TASK_PORTID);
+ if (ercd < 0 && MERCD(ercd) != E_OBJ) {
+ syslog(LOG_ERROR, "%s (%d) reported by `serial_opn_por'.",
+ itron_strerror(ercd), SERCD(ercd));
+ }
+ SVC_PERROR(serial_ctl_por(TASK_PORTID,
+ (IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV)));
+
+ /*
+ * ループ回数の設定
+ *
+ * TASK_LOOPがマクロ定義されている場合,測定せずに,TASK_LOOPに定
+ * 義された値を,タスク内でのループ回数とする.
+ *
+ * MEASURE_TWICEがマクロ定義されている場合,1回目の測定結果を捨て
+ * て,2回目の測定結果を使う.1回目の測定は長めの時間が出るため.
+ */
+#ifdef TASK_LOOP
+ task_loop = TASK_LOOP;
+#else /* TASK_LOOP */
+
+#ifdef MEASURE_TWICE
+ task_loop = LOOP_REF;
+ SVC_PERROR(get_tim(&stime1));
+ for (i = 0; i < task_loop; i++);
+ SVC_PERROR(get_tim(&stime2));
+#endif /* MEASURE_TWICE */
+
+ task_loop = LOOP_REF;
+ SVC_PERROR(get_tim(&stime1));
+ for (i = 0; i < task_loop; i++);
+ SVC_PERROR(get_tim(&stime2));
+ task_loop = LOOP_REF * 400UL / (stime2 - stime1);
+
+#endif /* TASK_LOOP */
+ tex_loop = task_loop / 5;
+
+ /*
+ * タスクの起動
+ */
+ SVC_PERROR(act_tsk(TASK1));
+ SVC_PERROR(act_tsk(TASK2));
+ SVC_PERROR(act_tsk(TASK3));
+
+ /*
+ * メインループ
+ */
+ do {
+ SVC_PERROR(serial_rea_dat(TASK_PORTID, &c, 1));
+ switch (c) {
+ case 'e':
+ case 's':
+ case 'S':
+ case 'd':
+ case 'y':
+ case 'Y':
+ case 'z':
+ case 'Z':
+ message[tskno-1] = c;
+ break;
+ case '1':
+ tskno = 1;
+ tskid = TASK1;
+ break;
+ case '2':
+ tskno = 2;
+ tskid = TASK2;
+ break;
+ case '3':
+ tskno = 3;
+ tskid = TASK3;
+ break;
+ case 'a':
+ syslog(LOG_INFO, "#act_tsk(%d)", tskno);
+ SVC_PERROR(act_tsk(tskid));
+ break;
+ case 'A':
+ syslog(LOG_INFO, "#can_act(%d)", tskno);
+ SVC_PERROR(ercd = can_act(tskid));
+ if (ercd >= 0) {
+ syslog(LOG_NOTICE, "can_act(%d) returns %d", tskno, ercd);
+ }
+ break;
+ case 't':
+ syslog(LOG_INFO, "#ter_tsk(%d)", tskno);
+ SVC_PERROR(ter_tsk(tskid));
+ break;
+ case '>':
+ syslog(LOG_INFO, "#chg_pri(%d, HIGH_PRIORITY)", tskno);
+ SVC_PERROR(chg_pri(tskid, HIGH_PRIORITY));
+ break;
+ case '=':
+ syslog(LOG_INFO, "#chg_pri(%d, MID_PRIORITY)", tskno);
+ SVC_PERROR(chg_pri(tskid, MID_PRIORITY));
+ break;
+ case '<':
+ syslog(LOG_INFO, "#chg_pri(%d, LOW_PRIORITY)", tskno);
+ SVC_PERROR(chg_pri(tskid, LOW_PRIORITY));
+ break;
+ case 'G':
+ syslog(LOG_INFO, "#get_pri(%d, &tskpri)", tskno);
+ SVC_PERROR(ercd = get_pri(tskid, &tskpri));
+ if (ercd >= 0) {
+ syslog(LOG_NOTICE, "priority of task %d is %d", tskno, tskpri);
+ }
+ break;
+ case 'w':
+ syslog(LOG_INFO, "#wup_tsk(%d)", tskno);
+ SVC_PERROR(wup_tsk(tskid));
+ break;
+ case 'W':
+ syslog(LOG_INFO, "#can_wup(%d)", tskno);
+ SVC_PERROR(ercd = can_wup(tskid));
+ if (ercd >= 0) {
+ syslog(LOG_NOTICE, "can_wup(%d) returns %d", tskno, ercd);
+ }
+ break;
+ case 'l':
+ syslog(LOG_INFO, "#rel_wai(%d)", tskno);
+ SVC_PERROR(rel_wai(tskid));
+ break;
+ case 'u':
+ syslog(LOG_INFO, "#sus_tsk(%d)", tskno);
+ SVC_PERROR(sus_tsk(tskid));
+ break;
+ case 'm':
+ syslog(LOG_INFO, "#rsm_tsk(%d)", tskno);
+ SVC_PERROR(rsm_tsk(tskid));
+ break;
+ case 'x':
+ syslog(LOG_INFO, "#ras_tex(%d, 0x0001U)", tskno);
+ SVC_PERROR(ras_tex(tskid, 0x0001U));
+ break;
+ case 'X':
+ syslog(LOG_INFO, "#ras_tex(%d, 0x0002U)", tskno);
+ SVC_PERROR(ras_tex(tskid, 0x0002U));
+ break;
+ case 'r':
+ syslog(LOG_INFO, "#rot_rdq(three priorities)");
+ SVC_PERROR(rot_rdq(HIGH_PRIORITY));
+ SVC_PERROR(rot_rdq(MID_PRIORITY));
+ SVC_PERROR(rot_rdq(LOW_PRIORITY));
+ break;
+ case 'c':
+ syslog(LOG_INFO, "#sta_cyc(1)");
+ SVC_PERROR(sta_cyc(CYCHDR1));
+ break;
+ case 'C':
+ syslog(LOG_INFO, "#stp_cyc(1)");
+ SVC_PERROR(stp_cyc(CYCHDR1));
+ break;
+ case 'b':
+ syslog(LOG_INFO, "#sta_alm(1, 5000)");
+ SVC_PERROR(sta_alm(ALMHDR1, 5000));
+ break;
+ case 'B':
+ syslog(LOG_INFO, "#stp_alm(1)");
+ SVC_PERROR(stp_alm(ALMHDR1));
+ break;
+
+ case 'V':
+#ifdef TOPPERS_SUPPORT_GET_UTM
+ SVC_PERROR(get_utm(&utime1));
+ SVC_PERROR(get_utm(&utime2));
+ syslog(LOG_NOTICE, "utime1 = %ld, utime2 = %ld",
+ (ulong_t) utime1, (ulong_t) utime2);
+#else /* TOPPERS_SUPPORT_GET_UTM */
+ syslog(LOG_NOTICE, "get_utm is not supported.");
+#endif /* TOPPERS_SUPPORT_GET_UTM */
+ break;
+
+ case 'o':
+#ifdef TOPPERS_SUPPORT_OVRHDR
+ syslog(LOG_INFO, "#sta_ovr(%d, 2000000)", tskno);
+ SVC_PERROR(sta_ovr(tskid, 2000000));
+#else /* TOPPERS_SUPPORT_OVRHDR */
+ syslog(LOG_NOTICE, "sta_ovr is not supported.");
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+ break;
+ case 'O':
+#ifdef TOPPERS_SUPPORT_OVRHDR
+ syslog(LOG_INFO, "#stp_ovr(%d)", tskno);
+ SVC_PERROR(stp_ovr(tskid));
+#else /* TOPPERS_SUPPORT_OVRHDR */
+ syslog(LOG_NOTICE, "stp_ovr is not supported.");
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+ break;
+
+ case 'v':
+ SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_INFO),
+ LOG_UPTO(LOG_EMERG)));
+ break;
+ case 'q':
+ SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_NOTICE),
+ LOG_UPTO(LOG_EMERG)));
+ break;
+
+#ifdef BIT_KERNEL
+ case ' ':
+ SVC_PERROR(loc_cpu());
+ {
+ extern ER bit_kernel(void);
+
+ SVC_PERROR(ercd = bit_kernel());
+ if (ercd >= 0) {
+ syslog(LOG_NOTICE, "bit_kernel passed.");
+ }
+ }
+ SVC_PERROR(unl_cpu());
+ break;
+#endif /* BIT_KERNEL */
+
+ default:
+ break;
+ }
+ } while (c != '\003' && c != 'Q');
+
+ syslog(LOG_NOTICE, "Sample program ends.");
+ SVC_PERROR(ext_ker());
+ assert(0);
+}
--- /dev/null
+/*
+ * @(#) $Id: sample1.cfg 1717 2010-01-31 11:41:03Z ertl-hiro $
+ */
+
+/*
+ * サンプルプログラム(1)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+INCLUDE("syssvc/logtask.cfg");
+
+#include "sample1.h"
+CRE_TSK(TASK1, { TA_NULL, 1, task, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK3, { TA_NULL, 3, task, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(MAIN_TASK, { TA_ACT, 0, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
+DEF_TEX(TASK1, { TA_NULL, tex_routine });
+DEF_TEX(TASK2, { TA_NULL, tex_routine });
+DEF_TEX(TASK3, { TA_NULL, tex_routine });
+CRE_CYC(CYCHDR1, { TA_NULL, 0, cyclic_handler, 2000, 0 });
+CRE_ALM(ALMHDR1, { TA_NULL, 0, alarm_handler });
+DEF_OVR({ TA_NULL, overrun_handler });
+#ifdef CPUEXC1
+DEF_EXC(CPUEXC1, { TA_NULL, cpuexc_handler });
+#endif /* CPUEXC1 */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: sample1.h 1717 2010-01-31 11:41:03Z ertl-hiro $
+ */
+
+/*
+ * サンプルプログラム(1)のヘッダファイル
+ */
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 各タスクの優先度の定義
+ */
+
+#define MAIN_PRIORITY 5 /* メインタスクの優先度 */
+ /* HIGH_PRIORITYより高くすること */
+
+#define HIGH_PRIORITY 9 /* 並列に実行されるタスクの優先度 */
+#define MID_PRIORITY 10
+#define LOW_PRIORITY 11
+
+/*
+ * ターゲットに依存する可能性のある定数の定義
+ */
+
+#ifndef TASK_PORTID
+#define TASK_PORTID 1 /* 文字入力するシリアルポートID */
+#endif /* TASK_PORTID */
+
+#ifndef STACK_SIZE
+#define STACK_SIZE 4096 /* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+#ifndef LOOP_REF
+#define LOOP_REF ULONG_C(1000000) /* 速度計測用のループ回数 */
+#endif /* LOOP_REF */
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void task(intptr_t exinf);
+extern void main_task(intptr_t exinf);
+extern void tex_routine(TEXPTN texptn, intptr_t exinf);
+#ifdef CPUEXC1
+extern void cpuexc_handler(void *p_excinf);
+#endif /* CPUEXC1 */
+extern void cyclic_handler(intptr_t exinf);
+extern void alarm_handler(intptr_t exinf);
+#ifdef TOPPERS_SUPPORT_OVRHDR
+extern void overrun_handler(ID tskid, intptr_t exinf);
+#endif /* TOPPERS_SUPPORT_OVRHDR */
+
+#endif /* TOPPERS_MACRO_ONLY */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: kernel.h 1862 2010-07-25 11:49:51Z ertl-hiro $
+ */
+
+/*
+ * TOPPERS/ASPカーネル 標準ヘッダファイル
+ *
+ * TOPPERS/ASPカーネルがサポートするサービスコールの宣言と,必要なデー
+ * タ型,定数,マクロの定義を含むヘッダファイル.
+ *
+ * アセンブリ言語のソースファイルからこのファイルをインクルードする時
+ * は,TOPPERS_MACRO_ONLYを定義しておく.これにより,マクロ定義以外を
+ * 除くようになっている.
+ *
+ * このファイルをインクルードする前にインクルードしておくべきファイル
+ * はない.
+ */
+
+#ifndef TOPPERS_KERNEL_H
+#define TOPPERS_KERNEL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * TOPPERS共通のデータ型・定数・マクロ
+ */
+#include <t_stddef.h>
+
+/*
+ * ターゲット依存部
+ */
+#include "target_kernel.h"
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ * データ型の定義
+ */
+
+/*
+ * ビットパターンやオブジェクト番号の型定義
+ */
+typedef uint_t TEXPTN; /* タスク例外要因のビットパターン */
+typedef uint_t FLGPTN; /* イベントフラグのビットパターン */
+typedef uint_t INTNO; /* 割込み番号 */
+typedef uint_t INHNO; /* 割込みハンドラ番号 */
+typedef uint_t EXCNO; /* CPU例外ハンドラ番号 */
+
+/*
+ * 処理単位の型定義
+ */
+typedef void (*TASK)(intptr_t exinf);
+typedef void (*TEXRTN)(TEXPTN texptn, intptr_t exinf);
+typedef void (*CYCHDR)(intptr_t exinf);
+typedef void (*ALMHDR)(intptr_t exinf);
+typedef void (*ISR)(intptr_t exinf);
+typedef void (*INTHDR)(void);
+typedef void (*EXCHDR)(void *p_excinf);
+typedef void (*INIRTN)(intptr_t exinf);
+typedef void (*TERRTN)(intptr_t exinf);
+
+/*
+ * メモリ領域確保のための型定義
+ */
+#ifndef TOPPERS_STK_T
+#define TOPPERS_STK_T intptr_t
+#endif /* TOPPERS_STK_T */
+typedef TOPPERS_STK_T STK_T; /* スタック領域を確保するための型 */
+
+#ifndef TOPPERS_MPF_T
+#define TOPPERS_MPF_T intptr_t
+#endif /* TOPPERS_MPF_T */
+typedef TOPPERS_MPF_T MPF_T; /* 固定長メモリプール領域を確保するための型 */
+
+/*
+ * メッセージヘッダの型定義
+ */
+typedef struct t_msg { /* メールボックスのメッセージヘッダ */
+ struct t_msg *pk_next;
+} T_MSG;
+
+typedef struct t_msg_pri { /* 優先度付きメッセージヘッダ */
+ T_MSG msgque; /* メッセージヘッダ */
+ PRI msgpri; /* メッセージ優先度 */
+} T_MSG_PRI;
+
+/*
+ * パケット形式の定義
+ */
+typedef struct t_rtsk {
+ STAT tskstat; /* タスク状態 */
+ PRI tskpri; /* タスクの現在優先度 */
+ PRI tskbpri; /* タスクのベース優先度 */
+ STAT tskwait; /* 待ち要因 */
+ ID wobjid; /* 待ち対象のオブジェクトのID */
+ TMO lefttmo; /* タイムアウトするまでの時間 */
+ uint_t actcnt; /* 起動要求キューイング数 */
+ uint_t wupcnt; /* 起床要求キューイング数 */
+} T_RTSK;
+
+typedef struct t_rtex {
+ STAT texstat; /* タスク例外処理の状態 */
+ TEXPTN pndptn; /* 保留例外要因 */
+} T_RTEX;
+
+typedef struct t_rsem {
+ ID wtskid; /* セマフォの待ち行列の先頭のタスクのID番号 */
+ uint_t semcnt; /* セマフォの現在の資源数 */
+} T_RSEM;
+
+typedef struct t_rflg {
+ ID wtskid; /* イベントフラグの待ち行列の先頭のタスクのID番号 */
+ FLGPTN flgptn; /* イベントフラグの現在のビットパターン */
+} T_RFLG;
+
+typedef struct t_rdtq {
+ ID stskid; /* データキューの送信待ち行列の先頭のタスクのID番号 */
+ ID rtskid; /* データキューの受信待ち行列の先頭のタスクのID番号 */
+ uint_t sdtqcnt; /* データキュー管理領域に格納されているデータの数 */
+} T_RDTQ;
+
+typedef struct t_rpdq {
+ ID stskid; /* 優先度データキューの送信待ち行列の先頭のタスク
+ のID番号 */
+ ID rtskid; /* 優先度データキューの受信待ち行列の先頭のタスク
+ のID番号 */
+ uint_t spdqcnt; /* 優先度データキュー管理領域に格納されているデー
+ タの数 */
+} T_RPDQ;
+
+typedef struct t_rmbx {
+ ID wtskid; /* メールボックスの待ち行列の先頭のタスクのID番号 */
+ T_MSG *pk_msg; /* メッセージキューの先頭につながれたメッセージ
+ の先頭番地 */
+} T_RMBX;
+
+typedef struct t_rmpf {
+ ID wtskid; /* 固定長メモリプールの待ち行列の先頭のタスクの
+ ID番号 */
+ uint_t fblkcnt; /* 固定長メモリプール領域の空きメモリ領域に割り
+ 付けることができる固定長メモリブロックの数 */
+} T_RMPF;
+
+typedef struct t_rcyc {
+ STAT cycstat; /* 周期ハンドラの動作状態 */
+ RELTIM lefttim; /* 次に周期ハンドラを起動する時刻までの相対時間 */
+} T_RCYC;
+
+typedef struct t_ralm {
+ STAT almstat; /* アラームハンドラの動作状態 */
+ RELTIM lefttim; /* アラームハンドラを起動する時刻までの相対時間 */
+} T_RALM;
+
+/*
+ * サービスコールの宣言
+ */
+
+/*
+ * タスク管理機能
+ */
+extern ER act_tsk(ID tskid) throw();
+extern ER iact_tsk(ID tskid) throw();
+extern ER_UINT can_act(ID tskid) throw();
+extern ER ext_tsk(void) throw();
+extern ER ter_tsk(ID tskid) throw();
+extern ER chg_pri(ID tskid, PRI tskpri) throw();
+extern ER get_pri(ID tskid, PRI *p_tskpri) throw();
+extern ER get_inf(intptr_t *p_exinf) throw();
+extern ER ref_tsk(ID tskid, T_RTSK *pk_rtsk) throw();
+
+/*
+ * タスク付属同期機能
+ */
+extern ER slp_tsk(void) throw();
+extern ER tslp_tsk(TMO tmout) throw();
+extern ER wup_tsk(ID tskid) throw();
+extern ER iwup_tsk(ID tskid) throw();
+extern ER_UINT can_wup(ID tskid) throw();
+extern ER rel_wai(ID tskid) throw();
+extern ER irel_wai(ID tskid) throw();
+extern ER sus_tsk(ID tskid) throw();
+extern ER rsm_tsk(ID tskid) throw();
+extern ER dly_tsk(RELTIM dlytim) throw();
+
+/*
+ * タスク例外処理機能
+ */
+extern ER ras_tex(ID tskid, TEXPTN rasptn) throw();
+extern ER iras_tex(ID tskid, TEXPTN rasptn) throw();
+extern ER dis_tex(void) throw();
+extern ER ena_tex(void) throw();
+extern bool_t sns_tex(void) throw();
+extern ER ref_tex(ID tskid, T_RTEX *pk_rtex) throw();
+
+/*
+ * 同期・通信機能
+ */
+extern ER sig_sem(ID semid) throw();
+extern ER isig_sem(ID semid) throw();
+extern ER wai_sem(ID semid) throw();
+extern ER pol_sem(ID semid) throw();
+extern ER twai_sem(ID semid, TMO tmout) throw();
+extern ER ini_sem(ID semid) throw();
+extern ER ref_sem(ID semid, T_RSEM *pk_rsem) throw();
+
+extern ER set_flg(ID flgid, FLGPTN setptn) throw();
+extern ER iset_flg(ID flgid, FLGPTN setptn) throw();
+extern ER clr_flg(ID flgid, FLGPTN clrptn) throw();
+extern ER wai_flg(ID flgid, FLGPTN waiptn,
+ MODE wfmode, FLGPTN *p_flgptn) throw();
+extern ER pol_flg(ID flgid, FLGPTN waiptn,
+ MODE wfmode, FLGPTN *p_flgptn) throw();
+extern ER twai_flg(ID flgid, FLGPTN waiptn,
+ MODE wfmode, FLGPTN *p_flgptn, TMO tmout) throw();
+extern ER ini_flg(ID flgid) throw();
+extern ER ref_flg(ID flgid, T_RFLG *pk_rflg) throw();
+
+extern ER snd_dtq(ID dtqid, intptr_t data) throw();
+extern ER psnd_dtq(ID dtqid, intptr_t data) throw();
+extern ER ipsnd_dtq(ID dtqid, intptr_t data) throw();
+extern ER tsnd_dtq(ID dtqid, intptr_t data, TMO tmout) throw();
+extern ER fsnd_dtq(ID dtqid, intptr_t data) throw();
+extern ER ifsnd_dtq(ID dtqid, intptr_t data) throw();
+extern ER rcv_dtq(ID dtqid, intptr_t *p_data) throw();
+extern ER prcv_dtq(ID dtqid, intptr_t *p_data) throw();
+extern ER trcv_dtq(ID dtqid, intptr_t *p_data, TMO tmout) throw();
+extern ER ini_dtq(ID dtqid) throw();
+extern ER ref_dtq(ID dtqid, T_RDTQ *pk_rdtq) throw();
+
+extern ER snd_pdq(ID pdqid, intptr_t data, PRI datapri) throw();
+extern ER psnd_pdq(ID pdqid, intptr_t data, PRI datapri) throw();
+extern ER ipsnd_pdq(ID pdqid, intptr_t data, PRI datapri) throw();
+extern ER tsnd_pdq(ID pdqid, intptr_t data,
+ PRI datapri, TMO tmout) throw();
+extern ER rcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri) throw();
+extern ER prcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri) throw();
+extern ER trcv_pdq(ID pdqid, intptr_t *p_data,
+ PRI *p_datapri, TMO tmout) throw();
+extern ER ini_pdq(ID pdqid) throw();
+extern ER ref_pdq(ID pdqid, T_RPDQ *pk_rpdq) throw();
+
+extern ER snd_mbx(ID mbxid, T_MSG *pk_msg) throw();
+extern ER rcv_mbx(ID mbxid, T_MSG **ppk_msg) throw();
+extern ER prcv_mbx(ID mbxid, T_MSG **ppk_msg) throw();
+extern ER trcv_mbx(ID mbxid, T_MSG **ppk_msg, TMO tmout) throw();
+extern ER ini_mbx(ID mbxid) throw();
+extern ER ref_mbx(ID mbxid, T_RMBX *pk_rmbx) throw();
+
+/*
+ * メモリプール管理機能
+ */
+extern ER get_mpf(ID mpfid, void **p_blk) throw();
+extern ER pget_mpf(ID mpfid, void **p_blk) throw();
+extern ER tget_mpf(ID mpfid, void **p_blk, TMO tmout) throw();
+extern ER rel_mpf(ID mpfid, void *blk) throw();
+extern ER ini_mpf(ID mpfid) throw();
+extern ER ref_mpf(ID mpfid, T_RMPF *pk_rmpf) throw();
+
+/*
+ * 時間管理機能
+ */
+extern ER get_tim(SYSTIM *p_systim) throw();
+extern ER get_utm(SYSUTM *p_sysutm) throw();
+
+extern ER sta_cyc(ID cycid) throw();
+extern ER stp_cyc(ID cycid) throw();
+extern ER ref_cyc(ID cycid, T_RCYC *pk_rcyc) throw();
+
+extern ER sta_alm(ID almid, RELTIM almtim) throw();
+extern ER ista_alm(ID almid, RELTIM almtim) throw();
+extern ER stp_alm(ID almid) throw();
+extern ER istp_alm(ID almid) throw();
+extern ER ref_alm(ID almid, T_RALM *pk_ralm) throw();
+
+/*
+ * システム状態管理機能
+ */
+extern ER rot_rdq(PRI tskpri) throw();
+extern ER irot_rdq(PRI tskpri) throw();
+extern ER get_tid(ID *p_tskid) throw();
+extern ER iget_tid(ID *p_tskid) throw();
+extern ER loc_cpu(void) throw();
+extern ER iloc_cpu(void) throw();
+extern ER unl_cpu(void) throw();
+extern ER iunl_cpu(void) throw();
+extern ER dis_dsp(void) throw();
+extern ER ena_dsp(void) throw();
+extern bool_t sns_ctx(void) throw();
+extern bool_t sns_loc(void) throw();
+extern bool_t sns_dsp(void) throw();
+extern bool_t sns_dpn(void) throw();
+extern bool_t sns_ker(void) throw();
+extern ER ext_ker(void) throw();
+
+/*
+ * 割込み管理機能
+ */
+extern ER dis_int(INTNO intno) throw();
+extern ER ena_int(INTNO intno) throw();
+extern ER chg_ipm(PRI intpri) throw();
+extern ER get_ipm(PRI *p_intpri) throw();
+
+/*
+ * CPU例外管理機能
+ */
+extern bool_t xsns_dpn(void *p_excinf) throw();
+extern bool_t xsns_xpn(void *p_excinf) throw();
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ * オブジェクト属性の定義
+ */
+#define TA_ACT UINT_C(0x02) /* タスクを起動された状態で生成 */
+
+#define TA_TPRI UINT_C(0x01) /* タスクの待ち行列を優先度順に */
+#define TA_MPRI UINT_C(0x02) /* メッセージキューを優先度順に */
+
+#define TA_WMUL UINT_C(0x02) /* 複数の待ちタスク */
+#define TA_CLR UINT_C(0x04) /* イベントフラグのクリア指定 */
+
+#define TA_STA UINT_C(0x02) /* 周期ハンドラを動作状態で生成 */
+
+#define TA_NONKERNEL UINT_C(0x02) /* カーネル管理外の割込み */
+
+#define TA_ENAINT UINT_C(0x01) /* 割込み要求禁止フラグをクリア */
+#define TA_EDGE UINT_C(0x02) /* エッジトリガ */
+
+/*
+ * サービスコールの動作モードの定義
+ */
+#define TWF_ORW UINT_C(0x01) /* イベントフラグのOR待ち */
+#define TWF_ANDW UINT_C(0x02) /* イベントフラグのAND待ち */
+
+/*
+ * オブジェクトの状態の定義
+ */
+#define TTS_RUN UINT_C(0x01) /* 実行状態 */
+#define TTS_RDY UINT_C(0x02) /* 実行可能状態 */
+#define TTS_WAI UINT_C(0x04) /* 待ち状態 */
+#define TTS_SUS UINT_C(0x08) /* 強制待ち状態 */
+#define TTS_WAS UINT_C(0x0c) /* 二重待ち状態 */
+#define TTS_DMT UINT_C(0x10) /* 休止状態 */
+
+#define TTW_SLP UINT_C(0x0001) /* 起床待ち */
+#define TTW_DLY UINT_C(0x0002) /* 時間経過待ち */
+#define TTW_SEM UINT_C(0x0004) /* セマフォの資源獲得待ち */
+#define TTW_FLG UINT_C(0x0008) /* イベントフラグ待ち */
+#define TTW_SDTQ UINT_C(0x0010) /* データキューへの送信待ち */
+#define TTW_RDTQ UINT_C(0x0020) /* データキューからの受信待ち */
+#define TTW_SPDQ UINT_C(0x0100) /* 優先度データキューへの送信待ち */
+#define TTW_RPDQ UINT_C(0x0200) /* 優先度データキューからの受信待ち */
+#define TTW_MBX UINT_C(0x0040) /* メールボックスからの受信待ち */
+#define TTW_MPF UINT_C(0x2000) /* 固定長メモリブロックの獲得待ち */
+
+#define TTEX_ENA UINT_C(0x01) /* タスク例外処理許可状態 */
+#define TTEX_DIS UINT_C(0x02) /* タスク例外処理禁止状態 */
+
+#define TCYC_STP UINT_C(0x01) /* 周期ハンドラが動作していない */
+#define TCYC_STA UINT_C(0x02) /* 周期ハンドラが動作している */
+
+#define TALM_STP UINT_C(0x01) /* アラームハンドラが動作していない */
+#define TALM_STA UINT_C(0x02) /* アラームハンドラが動作している */
+
+/*
+ * その他の定数の定義
+ */
+#define TSK_SELF 0 /* 自タスク指定 */
+#define TSK_NONE 0 /* 該当するタスクがない */
+
+#define TPRI_SELF 0 /* 自タスクのベース優先度 */
+#define TPRI_INI 0 /* タスクの起動時優先度 */
+
+#define TIPM_ENAALL 0 /* 割込み優先度マスク全解除 */
+
+/*
+ * 構成定数とマクロ
+ */
+
+/*
+ * サポートする機能
+ */
+#ifdef TOPPERS_TARGET_SUPPORT_DIS_INT
+#define TOPPERS_SUPPORT_DIS_INT /* dis_intがサポートされている */
+#endif /* TOPPERS_TARGET_SUPPORT_DIS_INT */
+
+#ifdef TOPPERS_TARGET_SUPPORT_ENA_INT
+#define TOPPERS_SUPPORT_ENA_INT /* ena_intがサポートされている */
+#endif /* TOPPERS_TARGET_SUPPORT_ENA_INT */
+
+#ifdef TOPPERS_TARGET_SUPPORT_GET_UTM
+#define TOPPERS_SUPPORT_GET_UTM /* get_utmがサポートされている */
+#endif /* TOPPERS_TARGET_SUPPORT_GET_UTM */
+
+#define TOPPERS_SUPPORT_PRI_LEVEL /* タスク優先度の範囲の拡張 */
+
+/*
+ * 優先度の範囲
+ */
+#define TMIN_TPRI 1 /* タスク優先度の最小値(最高値)*/
+#define TMAX_TPRI 256 /* タスク優先度の最大値(最低値)*/
+#define TMIN_DPRI 1 /* データ優先度の最小値(最高値)*/
+#define TMAX_DPRI 256 /* データ優先度の最大値(最低値)*/
+#define TMIN_MPRI 1 /* メッセージ優先度の最小値(最高値)*/
+#define TMAX_MPRI 256 /* メッセージ優先度の最大値(最低値)*/
+#define TMIN_ISRPRI 1 /* 割込みサービスルーチン優先度の最小値 */
+#define TMAX_ISRPRI 256 /* 割込みサービスルーチン優先度の最大値 */
+
+/*
+ * バージョン情報
+ */
+#define TKERNEL_MAKER UINT_C(0x0118) /* カーネルのメーカーコード */
+#define TKERNEL_PRID UINT_C(0x0007) /* カーネルの識別番号 */
+#define TKERNEL_SPVER UINT_C(0xf512) /* カーネル仕様のバージョン番号 */
+#define TKERNEL_PRVER UINT_C(0x1060) /* カーネルのバージョン番号 */
+
+/*
+ * キューイング回数の最大値
+ */
+#define TMAX_ACTCNT UINT_C(1) /* 起動要求キューイング数の最大値 */
+#define TMAX_WUPCNT UINT_C(1) /* 起床要求キューイング数の最大値 */
+
+/*
+ * ビットパターンのビット数
+ */
+#ifndef TBIT_TEXPTN /* タスク例外要因のビット数 */
+#define TBIT_TEXPTN (sizeof(TEXPTN) * CHAR_BIT)
+#endif /* TBIT_TEXPTN */
+
+#ifndef TBIT_FLGPTN /* イベントフラグのビット数 */
+#define TBIT_FLGPTN (sizeof(FLGPTN) * CHAR_BIT)
+#endif /* TBIT_FLGPTN */
+
+/*
+ * メモリ領域確保のためのマクロ
+ *
+ * 以下のTOPPERS_COUNT_SZとTOPPERS_ROUND_SZの定義は,unitが2の巾乗であ
+ * ることを仮定している.
+ */
+#ifndef TOPPERS_COUNT_SZ
+#define TOPPERS_COUNT_SZ(sz, unit) (((sz) + (unit) - 1) / (unit))
+#endif /* TOPPERS_COUNT_SZ */
+#ifndef TOPPERS_ROUND_SZ
+#define TOPPERS_ROUND_SZ(sz, unit) (((sz) + (unit) - 1) & ~((unit) - 1))
+#endif /* TOPPERS_ROUND_SZ */
+
+#define COUNT_STK_T(sz) TOPPERS_COUNT_SZ(sz, sizeof(STK_T))
+#define ROUND_STK_T(sz) TOPPERS_ROUND_SZ(sz, sizeof(STK_T))
+
+#define COUNT_MPF_T(blksz) TOPPERS_COUNT_SZ(blksz, sizeof(MPF_T))
+#define ROUND_MPF_T(blksz) TOPPERS_ROUND_SZ(blksz, sizeof(MPF_T))
+
+/*
+ * その他の構成定数
+ */
+#define TMAX_MAXSEM UINT_MAX /* セマフォの最大資源数の最大値 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_KERNEL_H */
--- /dev/null
+# startup.c
+kerflg
+exit_kernel
+
+# task.c
+p_runtsk
+p_schedtsk
+reqflg
+disdsp
+dspflg
+ready_queue
+ready_primap
+ready_primap1
+ready_primap2
+initialize_task
+search_schedtsk
+make_runnable
+make_non_runnable
+make_dormant
+make_active
+change_priority
+rotate_ready_queue
+call_texrtn
+calltex
+
+# wait.c
+make_wait_tmout
+wait_complete
+wait_tmout
+wait_tmout_ok
+wait_release
+wobj_make_wait
+wobj_make_wait_tmout
+init_wait_queue
+
+# time_event.c
+current_time
+min_time
+next_time
+next_subtime
+last_index
+initialize_tmevt
+tmevt_up
+tmevt_down
+tmevtb_insert
+tmevtb_delete
+tmevt_lefttim
+signal_time
+
+# semaphore.c
+initialize_semaphore
+
+# eventflag.c
+initialize_eventflag
+check_flg_cond
+
+# dataqueue.c
+initialize_dataqueue
+enqueue_data
+force_enqueue_data
+dequeue_data
+send_data
+force_send_data
+receive_data
+
+# pridataq.c
+initialize_pridataq
+enqueue_pridata
+dequeue_pridata
+send_pridata
+receive_pridata
+
+# mailbox.c
+initialize_mailbox
+
+# mempfix.c
+initialize_mempfix
+get_mpf_block
+
+# cyclic.c
+initialize_cyclic
+call_cychdr
+
+# alarm.c
+initialize_alarm
+call_almhdr
+
+# interrupt.c
+initialize_interrupt
+
+# exception.c
+initialize_exception
+
+# kernel_cfg.c
+initialize_object
+call_inirtn
+call_terrtn
+tmax_tskid
+tinib_table
+torder_table
+tcb_table
+tmax_semid
+seminib_table
+semcb_table
+tmax_flgid
+flginib_table
+flgcb_table
+tmax_dtqid
+dtqcb_table
+dtqinib_table
+tmax_pdqid
+pdqcb_table
+pdqinib_table
+tmax_mbxid
+mbxcb_table
+mbxinib_table
+tmax_mpfid
+mpfinib_table
+mpfcb_table
+tmax_cycid
+cycinib_table
+cyccb_table
+tmax_almid
+alminib_table
+almcb_table
+tnum_inhno
+inhinib_table
+tnum_intno
+intinib_table
+tnum_excno
+excinib_table
+tmevt_heap
+istksz
+istk
+istkpt
+
+INCLUDE "target"
--- /dev/null
+/* This file is generated from kernel_rename.def by genrename. */
+
+#ifndef TOPPERS_KERNEL_RENAME_H
+#define TOPPERS_KERNEL_RENAME_H
+
+/*
+ * startup.c
+ */
+#define kerflg _kernel_kerflg
+#define exit_kernel _kernel_exit_kernel
+
+/*
+ * task.c
+ */
+#define p_runtsk _kernel_p_runtsk
+#define p_schedtsk _kernel_p_schedtsk
+#define reqflg _kernel_reqflg
+#define disdsp _kernel_disdsp
+#define dspflg _kernel_dspflg
+#define ready_queue _kernel_ready_queue
+#define ready_primap _kernel_ready_primap
+#define ready_primap1 _kernel_ready_primap1
+#define ready_primap2 _kernel_ready_primap2
+#define initialize_task _kernel_initialize_task
+#define search_schedtsk _kernel_search_schedtsk
+#define make_runnable _kernel_make_runnable
+#define make_non_runnable _kernel_make_non_runnable
+#define make_dormant _kernel_make_dormant
+#define make_active _kernel_make_active
+#define change_priority _kernel_change_priority
+#define rotate_ready_queue _kernel_rotate_ready_queue
+#define call_texrtn _kernel_call_texrtn
+#define calltex _kernel_calltex
+
+/*
+ * wait.c
+ */
+#define make_wait_tmout _kernel_make_wait_tmout
+#define wait_complete _kernel_wait_complete
+#define wait_tmout _kernel_wait_tmout
+#define wait_tmout_ok _kernel_wait_tmout_ok
+#define wait_release _kernel_wait_release
+#define wobj_make_wait _kernel_wobj_make_wait
+#define wobj_make_wait_tmout _kernel_wobj_make_wait_tmout
+#define init_wait_queue _kernel_init_wait_queue
+
+/*
+ * time_event.c
+ */
+#define current_time _kernel_current_time
+#define min_time _kernel_min_time
+#define next_time _kernel_next_time
+#define next_subtime _kernel_next_subtime
+#define last_index _kernel_last_index
+#define initialize_tmevt _kernel_initialize_tmevt
+#define tmevt_up _kernel_tmevt_up
+#define tmevt_down _kernel_tmevt_down
+#define tmevtb_insert _kernel_tmevtb_insert
+#define tmevtb_delete _kernel_tmevtb_delete
+#define tmevt_lefttim _kernel_tmevt_lefttim
+#define signal_time _kernel_signal_time
+
+/*
+ * semaphore.c
+ */
+#define initialize_semaphore _kernel_initialize_semaphore
+
+/*
+ * eventflag.c
+ */
+#define initialize_eventflag _kernel_initialize_eventflag
+#define check_flg_cond _kernel_check_flg_cond
+
+/*
+ * dataqueue.c
+ */
+#define initialize_dataqueue _kernel_initialize_dataqueue
+#define enqueue_data _kernel_enqueue_data
+#define force_enqueue_data _kernel_force_enqueue_data
+#define dequeue_data _kernel_dequeue_data
+#define send_data _kernel_send_data
+#define force_send_data _kernel_force_send_data
+#define receive_data _kernel_receive_data
+
+/*
+ * pridataq.c
+ */
+#define initialize_pridataq _kernel_initialize_pridataq
+#define enqueue_pridata _kernel_enqueue_pridata
+#define dequeue_pridata _kernel_dequeue_pridata
+#define send_pridata _kernel_send_pridata
+#define receive_pridata _kernel_receive_pridata
+
+/*
+ * mailbox.c
+ */
+#define initialize_mailbox _kernel_initialize_mailbox
+
+/*
+ * mempfix.c
+ */
+#define initialize_mempfix _kernel_initialize_mempfix
+#define get_mpf_block _kernel_get_mpf_block
+
+/*
+ * cyclic.c
+ */
+#define initialize_cyclic _kernel_initialize_cyclic
+#define call_cychdr _kernel_call_cychdr
+
+/*
+ * alarm.c
+ */
+#define initialize_alarm _kernel_initialize_alarm
+#define call_almhdr _kernel_call_almhdr
+
+/*
+ * interrupt.c
+ */
+#define initialize_interrupt _kernel_initialize_interrupt
+
+/*
+ * exception.c
+ */
+#define initialize_exception _kernel_initialize_exception
+
+/*
+ * kernel_cfg.c
+ */
+#define initialize_object _kernel_initialize_object
+#define call_inirtn _kernel_call_inirtn
+#define call_terrtn _kernel_call_terrtn
+#define tmax_tskid _kernel_tmax_tskid
+#define tinib_table _kernel_tinib_table
+#define torder_table _kernel_torder_table
+#define tcb_table _kernel_tcb_table
+#define tmax_semid _kernel_tmax_semid
+#define seminib_table _kernel_seminib_table
+#define semcb_table _kernel_semcb_table
+#define tmax_flgid _kernel_tmax_flgid
+#define flginib_table _kernel_flginib_table
+#define flgcb_table _kernel_flgcb_table
+#define tmax_dtqid _kernel_tmax_dtqid
+#define dtqcb_table _kernel_dtqcb_table
+#define dtqinib_table _kernel_dtqinib_table
+#define tmax_pdqid _kernel_tmax_pdqid
+#define pdqcb_table _kernel_pdqcb_table
+#define pdqinib_table _kernel_pdqinib_table
+#define tmax_mbxid _kernel_tmax_mbxid
+#define mbxcb_table _kernel_mbxcb_table
+#define mbxinib_table _kernel_mbxinib_table
+#define tmax_mpfid _kernel_tmax_mpfid
+#define mpfinib_table _kernel_mpfinib_table
+#define mpfcb_table _kernel_mpfcb_table
+#define tmax_cycid _kernel_tmax_cycid
+#define cycinib_table _kernel_cycinib_table
+#define cyccb_table _kernel_cyccb_table
+#define tmax_almid _kernel_tmax_almid
+#define alminib_table _kernel_alminib_table
+#define almcb_table _kernel_almcb_table
+#define tnum_inhno _kernel_tnum_inhno
+#define inhinib_table _kernel_inhinib_table
+#define tnum_intno _kernel_tnum_intno
+#define intinib_table _kernel_intinib_table
+#define tnum_excno _kernel_tnum_excno
+#define excinib_table _kernel_excinib_table
+#define tmevt_heap _kernel_tmevt_heap
+#define istksz _kernel_istksz
+#define istk _kernel_istk
+#define istkpt _kernel_istkpt
+
+
+#ifdef TOPPERS_LABEL_ASM
+
+/*
+ * startup.c
+ */
+#define _kerflg __kernel_kerflg
+#define _exit_kernel __kernel_exit_kernel
+
+/*
+ * task.c
+ */
+#define _p_runtsk __kernel_p_runtsk
+#define _p_schedtsk __kernel_p_schedtsk
+#define _reqflg __kernel_reqflg
+#define _disdsp __kernel_disdsp
+#define _dspflg __kernel_dspflg
+#define _ready_queue __kernel_ready_queue
+#define _ready_primap __kernel_ready_primap
+#define _ready_primap1 __kernel_ready_primap1
+#define _ready_primap2 __kernel_ready_primap2
+#define _initialize_task __kernel_initialize_task
+#define _search_schedtsk __kernel_search_schedtsk
+#define _make_runnable __kernel_make_runnable
+#define _make_non_runnable __kernel_make_non_runnable
+#define _make_dormant __kernel_make_dormant
+#define _make_active __kernel_make_active
+#define _change_priority __kernel_change_priority
+#define _rotate_ready_queue __kernel_rotate_ready_queue
+#define _call_texrtn __kernel_call_texrtn
+#define _calltex __kernel_calltex
+
+/*
+ * wait.c
+ */
+#define _make_wait_tmout __kernel_make_wait_tmout
+#define _wait_complete __kernel_wait_complete
+#define _wait_tmout __kernel_wait_tmout
+#define _wait_tmout_ok __kernel_wait_tmout_ok
+#define _wait_release __kernel_wait_release
+#define _wobj_make_wait __kernel_wobj_make_wait
+#define _wobj_make_wait_tmout __kernel_wobj_make_wait_tmout
+#define _init_wait_queue __kernel_init_wait_queue
+
+/*
+ * time_event.c
+ */
+#define _current_time __kernel_current_time
+#define _min_time __kernel_min_time
+#define _next_time __kernel_next_time
+#define _next_subtime __kernel_next_subtime
+#define _last_index __kernel_last_index
+#define _initialize_tmevt __kernel_initialize_tmevt
+#define _tmevt_up __kernel_tmevt_up
+#define _tmevt_down __kernel_tmevt_down
+#define _tmevtb_insert __kernel_tmevtb_insert
+#define _tmevtb_delete __kernel_tmevtb_delete
+#define _tmevt_lefttim __kernel_tmevt_lefttim
+#define _signal_time __kernel_signal_time
+
+/*
+ * semaphore.c
+ */
+#define _initialize_semaphore __kernel_initialize_semaphore
+
+/*
+ * eventflag.c
+ */
+#define _initialize_eventflag __kernel_initialize_eventflag
+#define _check_flg_cond __kernel_check_flg_cond
+
+/*
+ * dataqueue.c
+ */
+#define _initialize_dataqueue __kernel_initialize_dataqueue
+#define _enqueue_data __kernel_enqueue_data
+#define _force_enqueue_data __kernel_force_enqueue_data
+#define _dequeue_data __kernel_dequeue_data
+#define _send_data __kernel_send_data
+#define _force_send_data __kernel_force_send_data
+#define _receive_data __kernel_receive_data
+
+/*
+ * pridataq.c
+ */
+#define _initialize_pridataq __kernel_initialize_pridataq
+#define _enqueue_pridata __kernel_enqueue_pridata
+#define _dequeue_pridata __kernel_dequeue_pridata
+#define _send_pridata __kernel_send_pridata
+#define _receive_pridata __kernel_receive_pridata
+
+/*
+ * mailbox.c
+ */
+#define _initialize_mailbox __kernel_initialize_mailbox
+
+/*
+ * mempfix.c
+ */
+#define _initialize_mempfix __kernel_initialize_mempfix
+#define _get_mpf_block __kernel_get_mpf_block
+
+/*
+ * cyclic.c
+ */
+#define _initialize_cyclic __kernel_initialize_cyclic
+#define _call_cychdr __kernel_call_cychdr
+
+/*
+ * alarm.c
+ */
+#define _initialize_alarm __kernel_initialize_alarm
+#define _call_almhdr __kernel_call_almhdr
+
+/*
+ * interrupt.c
+ */
+#define _initialize_interrupt __kernel_initialize_interrupt
+
+/*
+ * exception.c
+ */
+#define _initialize_exception __kernel_initialize_exception
+
+/*
+ * kernel_cfg.c
+ */
+#define _initialize_object __kernel_initialize_object
+#define _call_inirtn __kernel_call_inirtn
+#define _call_terrtn __kernel_call_terrtn
+#define _tmax_tskid __kernel_tmax_tskid
+#define _tinib_table __kernel_tinib_table
+#define _torder_table __kernel_torder_table
+#define _tcb_table __kernel_tcb_table
+#define _tmax_semid __kernel_tmax_semid
+#define _seminib_table __kernel_seminib_table
+#define _semcb_table __kernel_semcb_table
+#define _tmax_flgid __kernel_tmax_flgid
+#define _flginib_table __kernel_flginib_table
+#define _flgcb_table __kernel_flgcb_table
+#define _tmax_dtqid __kernel_tmax_dtqid
+#define _dtqcb_table __kernel_dtqcb_table
+#define _dtqinib_table __kernel_dtqinib_table
+#define _tmax_pdqid __kernel_tmax_pdqid
+#define _pdqcb_table __kernel_pdqcb_table
+#define _pdqinib_table __kernel_pdqinib_table
+#define _tmax_mbxid __kernel_tmax_mbxid
+#define _mbxcb_table __kernel_mbxcb_table
+#define _mbxinib_table __kernel_mbxinib_table
+#define _tmax_mpfid __kernel_tmax_mpfid
+#define _mpfinib_table __kernel_mpfinib_table
+#define _mpfcb_table __kernel_mpfcb_table
+#define _tmax_cycid __kernel_tmax_cycid
+#define _cycinib_table __kernel_cycinib_table
+#define _cyccb_table __kernel_cyccb_table
+#define _tmax_almid __kernel_tmax_almid
+#define _alminib_table __kernel_alminib_table
+#define _almcb_table __kernel_almcb_table
+#define _tnum_inhno __kernel_tnum_inhno
+#define _inhinib_table __kernel_inhinib_table
+#define _tnum_intno __kernel_tnum_intno
+#define _intinib_table __kernel_intinib_table
+#define _tnum_excno __kernel_tnum_excno
+#define _excinib_table __kernel_excinib_table
+#define _tmevt_heap __kernel_tmevt_heap
+#define _istksz __kernel_istksz
+#define _istk __kernel_istk
+#define _istkpt __kernel_istkpt
+
+
+#endif /* TOPPERS_LABEL_ASM */
+
+#include "target_rename.h"
+
+#endif /* TOPPERS_KERNEL_RENAME_H */
--- /dev/null
+/* This file is generated from kernel_rename.def by genrename. */
+
+/* This file is included only when kernel_rename.h has been included. */
+#ifdef TOPPERS_KERNEL_RENAME_H
+#undef TOPPERS_KERNEL_RENAME_H
+
+/*
+ * startup.c
+ */
+#undef kerflg
+#undef exit_kernel
+
+/*
+ * task.c
+ */
+#undef p_runtsk
+#undef p_schedtsk
+#undef reqflg
+#undef disdsp
+#undef dspflg
+#undef ready_queue
+#undef ready_primap
+#undef ready_primap1
+#undef ready_primap2
+#undef initialize_task
+#undef search_schedtsk
+#undef make_runnable
+#undef make_non_runnable
+#undef make_dormant
+#undef make_active
+#undef change_priority
+#undef rotate_ready_queue
+#undef call_texrtn
+#undef calltex
+
+/*
+ * wait.c
+ */
+#undef make_wait_tmout
+#undef wait_complete
+#undef wait_tmout
+#undef wait_tmout_ok
+#undef wait_release
+#undef wobj_make_wait
+#undef wobj_make_wait_tmout
+#undef init_wait_queue
+
+/*
+ * time_event.c
+ */
+#undef current_time
+#undef min_time
+#undef next_time
+#undef next_subtime
+#undef last_index
+#undef initialize_tmevt
+#undef tmevt_up
+#undef tmevt_down
+#undef tmevtb_insert
+#undef tmevtb_delete
+#undef tmevt_lefttim
+#undef signal_time
+
+/*
+ * semaphore.c
+ */
+#undef initialize_semaphore
+
+/*
+ * eventflag.c
+ */
+#undef initialize_eventflag
+#undef check_flg_cond
+
+/*
+ * dataqueue.c
+ */
+#undef initialize_dataqueue
+#undef enqueue_data
+#undef force_enqueue_data
+#undef dequeue_data
+#undef send_data
+#undef force_send_data
+#undef receive_data
+
+/*
+ * pridataq.c
+ */
+#undef initialize_pridataq
+#undef enqueue_pridata
+#undef dequeue_pridata
+#undef send_pridata
+#undef receive_pridata
+
+/*
+ * mailbox.c
+ */
+#undef initialize_mailbox
+
+/*
+ * mempfix.c
+ */
+#undef initialize_mempfix
+#undef get_mpf_block
+
+/*
+ * cyclic.c
+ */
+#undef initialize_cyclic
+#undef call_cychdr
+
+/*
+ * alarm.c
+ */
+#undef initialize_alarm
+#undef call_almhdr
+
+/*
+ * interrupt.c
+ */
+#undef initialize_interrupt
+
+/*
+ * exception.c
+ */
+#undef initialize_exception
+
+/*
+ * kernel_cfg.c
+ */
+#undef initialize_object
+#undef call_inirtn
+#undef call_terrtn
+#undef tmax_tskid
+#undef tinib_table
+#undef torder_table
+#undef tcb_table
+#undef tmax_semid
+#undef seminib_table
+#undef semcb_table
+#undef tmax_flgid
+#undef flginib_table
+#undef flgcb_table
+#undef tmax_dtqid
+#undef dtqcb_table
+#undef dtqinib_table
+#undef tmax_pdqid
+#undef pdqcb_table
+#undef pdqinib_table
+#undef tmax_mbxid
+#undef mbxcb_table
+#undef mbxinib_table
+#undef tmax_mpfid
+#undef mpfinib_table
+#undef mpfcb_table
+#undef tmax_cycid
+#undef cycinib_table
+#undef cyccb_table
+#undef tmax_almid
+#undef alminib_table
+#undef almcb_table
+#undef tnum_inhno
+#undef inhinib_table
+#undef tnum_intno
+#undef intinib_table
+#undef tnum_excno
+#undef excinib_table
+#undef tmevt_heap
+#undef istksz
+#undef istk
+#undef istkpt
+
+
+#ifdef TOPPERS_LABEL_ASM
+
+/*
+ * startup.c
+ */
+#undef _kerflg
+#undef _exit_kernel
+
+/*
+ * task.c
+ */
+#undef _p_runtsk
+#undef _p_schedtsk
+#undef _reqflg
+#undef _disdsp
+#undef _dspflg
+#undef _ready_queue
+#undef _ready_primap
+#undef _ready_primap1
+#undef _ready_primap2
+#undef _initialize_task
+#undef _search_schedtsk
+#undef _make_runnable
+#undef _make_non_runnable
+#undef _make_dormant
+#undef _make_active
+#undef _change_priority
+#undef _rotate_ready_queue
+#undef _call_texrtn
+#undef _calltex
+
+/*
+ * wait.c
+ */
+#undef _make_wait_tmout
+#undef _wait_complete
+#undef _wait_tmout
+#undef _wait_tmout_ok
+#undef _wait_release
+#undef _wobj_make_wait
+#undef _wobj_make_wait_tmout
+#undef _init_wait_queue
+
+/*
+ * time_event.c
+ */
+#undef _current_time
+#undef _min_time
+#undef _next_time
+#undef _next_subtime
+#undef _last_index
+#undef _initialize_tmevt
+#undef _tmevt_up
+#undef _tmevt_down
+#undef _tmevtb_insert
+#undef _tmevtb_delete
+#undef _tmevt_lefttim
+#undef _signal_time
+
+/*
+ * semaphore.c
+ */
+#undef _initialize_semaphore
+
+/*
+ * eventflag.c
+ */
+#undef _initialize_eventflag
+#undef _check_flg_cond
+
+/*
+ * dataqueue.c
+ */
+#undef _initialize_dataqueue
+#undef _enqueue_data
+#undef _force_enqueue_data
+#undef _dequeue_data
+#undef _send_data
+#undef _force_send_data
+#undef _receive_data
+
+/*
+ * pridataq.c
+ */
+#undef _initialize_pridataq
+#undef _enqueue_pridata
+#undef _dequeue_pridata
+#undef _send_pridata
+#undef _receive_pridata
+
+/*
+ * mailbox.c
+ */
+#undef _initialize_mailbox
+
+/*
+ * mempfix.c
+ */
+#undef _initialize_mempfix
+#undef _get_mpf_block
+
+/*
+ * cyclic.c
+ */
+#undef _initialize_cyclic
+#undef _call_cychdr
+
+/*
+ * alarm.c
+ */
+#undef _initialize_alarm
+#undef _call_almhdr
+
+/*
+ * interrupt.c
+ */
+#undef _initialize_interrupt
+
+/*
+ * exception.c
+ */
+#undef _initialize_exception
+
+/*
+ * kernel_cfg.c
+ */
+#undef _initialize_object
+#undef _call_inirtn
+#undef _call_terrtn
+#undef _tmax_tskid
+#undef _tinib_table
+#undef _torder_table
+#undef _tcb_table
+#undef _tmax_semid
+#undef _seminib_table
+#undef _semcb_table
+#undef _tmax_flgid
+#undef _flginib_table
+#undef _flgcb_table
+#undef _tmax_dtqid
+#undef _dtqcb_table
+#undef _dtqinib_table
+#undef _tmax_pdqid
+#undef _pdqcb_table
+#undef _pdqinib_table
+#undef _tmax_mbxid
+#undef _mbxcb_table
+#undef _mbxinib_table
+#undef _tmax_mpfid
+#undef _mpfinib_table
+#undef _mpfcb_table
+#undef _tmax_cycid
+#undef _cycinib_table
+#undef _cyccb_table
+#undef _tmax_almid
+#undef _alminib_table
+#undef _almcb_table
+#undef _tnum_inhno
+#undef _inhinib_table
+#undef _tnum_intno
+#undef _intinib_table
+#undef _tnum_excno
+#undef _excinib_table
+#undef _tmevt_heap
+#undef _istksz
+#undef _istk
+#undef _istkpt
+
+
+#endif /* TOPPERS_LABEL_ASM */
+
+#include "target_unrename.h"
+
+#endif /* TOPPERS_KERNEL_RENAME_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * $Id: task.c 1812 2010-06-27 13:07:15Z ertl-hiro $
+ */
+
+/*
+ * タスク管理モジュール
+ */
+
+#include "kernel_impl.h"
+#include "wait.h"
+#include "task.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_TEX_ENTER
+#define LOG_TEX_ENTER(p_tcb, texptn)
+#endif /* LOG_TEX_ENTER */
+
+#ifndef LOG_TEX_LEAVE
+#define LOG_TEX_LEAVE(p_tcb)
+#endif /* LOG_TEX_LEAVE */
+
+#ifdef TOPPERS_tskini
+
+/*
+ * 実行状態のタスク
+ */
+TCB *p_runtsk;
+
+/*
+ * 最高優先順位のタスク
+ */
+TCB *p_schedtsk;
+
+/*
+ * タスクディスパッチ/タスク例外処理ルーチン起動要求フラグ
+ */
+bool_t reqflg;
+
+/*
+ * ディスパッチ禁止状態
+ */
+bool_t disdsp;
+
+/*
+ * タスクディスパッチ可能状態
+ */
+bool_t dspflg;
+
+/*
+ * レディキュー
+ */
+QUEUE ready_queue[TNUM_TPRI];
+
+/*
+ * レディキューサーチのためのビットマップ
+ */
+#ifdef PRIMAP_LEVEL_1
+uint16_t ready_primap;
+#else /* PRIMAP_LEVEL_1 */
+uint16_t ready_primap1;
+uint16_t ready_primap2[TNUM_PRIMAP2];
+#endif /* PRIMAP_LEVEL_1 */
+
+/*
+ * タスク管理モジュールの初期化
+ */
+void
+initialize_task(void)
+{
+ uint_t i, j;
+ TCB *p_tcb;
+
+ p_runtsk = p_schedtsk = NULL;
+ reqflg = false;
+ disdsp = false;
+ dspflg = true;
+
+ for (i = 0; i < TNUM_TPRI; i++) {
+ queue_initialize(&(ready_queue[i]));
+ }
+#ifdef PRIMAP_LEVEL_1
+ ready_primap = 0U;
+#else /* PRIMAP_LEVEL_1 */
+ ready_primap1 = 0U;
+ for (i = 0; i < TNUM_PRIMAP2; i++) {
+ ready_primap2[i] = 0U;
+ }
+#endif /* PRIMAP_LEVEL_1 */
+
+ for (i = 0; i < tnum_tsk; i++) {
+ j = INDEX_TSK(torder_table[i]);
+ p_tcb = &(tcb_table[j]);
+ p_tcb->p_tinib = &(tinib_table[j]);
+ p_tcb->actque = false;
+ make_dormant(p_tcb);
+ if ((p_tcb->p_tinib->tskatr & TA_ACT) != 0U) {
+ make_active(p_tcb);
+ }
+ }
+}
+
+#endif /* TOPPERS_tskini */
+
+/*
+ * ビットマップサーチ関数
+ *
+ * bitmap内の1のビットの内,最も下位(右)のものをサーチし,そのビッ
+ * ト番号を返す.ビット番号は,最下位ビットを0とする.bitmapに0を指定
+ * してはならない.この関数では,bitmapが16ビットであることを仮定し,
+ * uint16_t型としている.
+ *
+ * ビットサーチ命令を持つプロセッサでは,ビットサーチ命令を使うように
+ * 書き直した方が効率が良い場合がある.このような場合には,ターゲット
+ * 依存部でビットサーチ命令を使ったbitmap_searchを定義し,
+ * OMIT_BITMAP_SEARCHをマクロ定義すればよい.また,ビットサーチ命令の
+ * サーチ方向が逆などの理由で優先度とビットとの対応を変更したい場合に
+ * は,PRIMAP_BITをマクロ定義すればよい.
+ *
+ * また,標準ライブラリにffsがあるなら,次のように定義して標準ライブ
+ * ラリを使った方が効率が良い可能性もある.
+ * #define bitmap_search(bitmap) (ffs(bitmap) - 1)
+ */
+#ifndef PRIMAP_BIT
+#define PRIMAP_BIT(pri) (1U << (pri))
+#endif /* PRIMAP_BIT */
+
+#ifndef OMIT_BITMAP_SEARCH
+
+static const unsigned char bitmap_search_table[] = { 0, 1, 0, 2, 0, 1, 0,
+ 3, 0, 1, 0, 2, 0, 1, 0 };
+
+Inline uint_t
+bitmap_search(uint16_t bitmap)
+{
+ uint_t n = 0U;
+
+ assert(bitmap != 0U);
+ if ((bitmap & 0x00ffU) == 0U) {
+ bitmap >>= 8;
+ n += 8;
+ }
+ if ((bitmap & 0x0fU) == 0U) {
+ bitmap >>= 4;
+ n += 4;
+ }
+ return(n + bitmap_search_table[(bitmap & 0x0fU) - 1]);
+}
+
+#endif /* OMIT_BITMAP_SEARCH */
+
+/*
+ * 優先度ビットマップが空かのチェック
+ */
+Inline bool_t
+primap_empty(void)
+{
+#ifdef PRIMAP_LEVEL_1
+ return(ready_primap == 0U);
+#else /* PRIMAP_LEVEL_1 */
+ return(ready_primap1 == 0U);
+#endif /* PRIMAP_LEVEL_1 */
+}
+
+/*
+ * 優先度ビットマップのサーチ
+ */
+Inline uint_t
+primap_search(void)
+{
+#ifdef PRIMAP_LEVEL_1
+ return(bitmap_search(ready_primap));
+#else /* PRIMAP_LEVEL_1 */
+ uint_t i;
+
+ i = bitmap_search(ready_primap1);
+ return(i * TBIT_PRIMAP + bitmap_search(ready_primap2[i]));
+#endif /* PRIMAP_LEVEL_1 */
+}
+
+/*
+ * 優先度ビットマップのセット
+ */
+Inline void
+primap_set(uint_t pri)
+{
+#ifdef PRIMAP_LEVEL_1
+ ready_primap |= PRIMAP_BIT(pri);
+#else /* PRIMAP_LEVEL_1 */
+ ready_primap2[pri / TBIT_PRIMAP] |= PRIMAP_BIT(pri % TBIT_PRIMAP);
+ ready_primap1 |= PRIMAP_BIT(pri / TBIT_PRIMAP);
+#endif /* PRIMAP_LEVEL_1 */
+}
+
+/*
+ * 優先度ビットマップのクリア
+ */
+Inline void
+primap_clear(uint_t pri)
+{
+#ifdef PRIMAP_LEVEL_1
+ ready_primap &= ~PRIMAP_BIT(pri);
+#else /* PRIMAP_LEVEL_1 */
+ if ((ready_primap2[pri / TBIT_PRIMAP] &= ~PRIMAP_BIT(pri % TBIT_PRIMAP))
+ == 0U) {
+ ready_primap1 &= ~PRIMAP_BIT(pri / TBIT_PRIMAP);
+ }
+#endif /* PRIMAP_LEVEL_1 */
+}
+
+/*
+ * 最高優先順位タスクのサーチ
+ */
+#ifdef TOPPERS_tsksched
+
+TCB *
+search_schedtsk(void)
+{
+ uint_t schedpri;
+
+ schedpri = primap_search();
+ return((TCB *)(ready_queue[schedpri].p_next));
+}
+
+#endif /* TOPPERS_tsksched */
+
+/*
+ * 実行できる状態への遷移
+ *
+ * 最高優先順位のタスクを更新するのは,実行できるタスクがなかった場合
+ * と,p_tcbの優先度が最高優先順位のタスクの優先度よりも高い場合であ
+ * る.
+ */
+#ifdef TOPPERS_tskrun
+
+bool_t
+make_runnable(TCB *p_tcb)
+{
+ uint_t pri = p_tcb->priority;
+
+ queue_insert_prev(&(ready_queue[pri]), &(p_tcb->task_queue));
+ primap_set(pri);
+
+ if (p_schedtsk == (TCB *) NULL || pri < p_schedtsk->priority) {
+ p_schedtsk = p_tcb;
+ return(dspflg);
+ }
+ return(false);
+}
+
+#endif /* TOPPERS_tskrun */
+
+/*
+ * 実行できる状態から他の状態への遷移
+ *
+ * 最高優先順位のタスクを更新するのは,p_tcbが最高優先順位のタスクで
+ * あった場合である.p_tcbと同じ優先度のタスクが他にある場合は,p_tcb
+ * の次のタスクが最高優先順位になる.そうでない場合は,レディキューを
+ * サーチする必要がある.
+ */
+#ifdef TOPPERS_tsknrun
+
+bool_t
+make_non_runnable(TCB *p_tcb)
+{
+ uint_t pri = p_tcb->priority;
+ QUEUE *p_queue = &(ready_queue[pri]);
+
+ queue_delete(&(p_tcb->task_queue));
+ if (queue_empty(p_queue)) {
+ primap_clear(pri);
+ if (p_schedtsk == p_tcb) {
+ p_schedtsk = primap_empty() ? (TCB *) NULL : search_schedtsk();
+ return(dspflg);
+ }
+ }
+ else {
+ if (p_schedtsk == p_tcb) {
+ p_schedtsk = (TCB *)(p_queue->p_next);
+ return(dspflg);
+ }
+ }
+ return(false);
+}
+
+#endif /* TOPPERS_tsknrun */
+
+/*
+ * 休止状態への遷移
+ */
+#ifdef TOPPERS_tskdmt
+
+void
+make_dormant(TCB *p_tcb)
+{
+ p_tcb->tstat = TS_DORMANT;
+ p_tcb->priority = p_tcb->p_tinib->ipriority;
+ p_tcb->wupque = false;
+ p_tcb->enatex = false;
+ p_tcb->texptn = 0U;
+ LOG_TSKSTAT(p_tcb);
+}
+
+#endif /* TOPPERS_tskdmt */
+
+/*
+ * 休止状態から実行できる状態への遷移
+ */
+#ifdef TOPPERS_tskact
+
+bool_t
+make_active(TCB *p_tcb)
+{
+ activate_context(p_tcb);
+ p_tcb->tstat = TS_RUNNABLE;
+ LOG_TSKSTAT(p_tcb);
+ return(make_runnable(p_tcb));
+}
+
+#endif /* TOPPERS_tskact */
+
+/*
+ * タスクの優先度の変更
+ *
+ * タスクが実行できる状態の場合には,レディキューの中での位置を変更す
+ * る.オブジェクトの待ちキューの中で待ち状態になっている場合には,待
+ * ちキューの中での位置を変更する.
+ *
+ * 最高優先順位のタスクを更新するのは,(1) p_tcbが最高優先順位のタス
+ * クであって,その優先度を下げた場合,(2) p_tcbが最高優先順位のタス
+ * クではなく,変更後の優先度が最高優先順位のタスクの優先度よりも高い
+ * 場合である.(1)の場合には,レディキューをサーチする必要がある.
+ */
+#ifdef TOPPERS_tskpri
+
+bool_t
+change_priority(TCB *p_tcb, uint_t newpri)
+{
+ uint_t oldpri;
+
+ oldpri = p_tcb->priority;
+ p_tcb->priority = newpri;
+
+ if (TSTAT_RUNNABLE(p_tcb->tstat)) {
+ /*
+ * タスクが実行できる状態の場合
+ */
+ queue_delete(&(p_tcb->task_queue));
+ if (queue_empty(&(ready_queue[oldpri]))) {
+ primap_clear(oldpri);
+ }
+ queue_insert_prev(&(ready_queue[newpri]), &(p_tcb->task_queue));
+ primap_set(newpri);
+
+ if (p_schedtsk == p_tcb) {
+ if (newpri >= oldpri) {
+ p_schedtsk = search_schedtsk();
+ return(p_schedtsk != p_tcb && dspflg);
+ }
+ }
+ else {
+ if (newpri < p_schedtsk->priority) {
+ p_schedtsk = p_tcb;
+ return(dspflg);
+ }
+ }
+ }
+ else {
+ if (TSTAT_WAIT_WOBJCB(p_tcb->tstat)) {
+ /*
+ * タスクが,同期・通信オブジェクトの管理ブロックの共通部
+ * 分(WOBJCB)の待ちキューにつながれている場合
+ */
+ wobj_change_priority(((WINFO_WOBJ *)(p_tcb->p_winfo))->p_wobjcb,
+ p_tcb);
+ }
+ }
+ return(false);
+}
+
+#endif /* TOPPERS_tskpri */
+
+/*
+ * レディキューの回転
+ *
+ * 最高優先順位のタスクを更新するのは,最高優先順位のタスクがタスクキ
+ * ューの末尾に移動した場合である.
+ */
+#ifdef TOPPERS_tskrot
+
+bool_t
+rotate_ready_queue(uint_t pri)
+{
+ QUEUE *p_queue = &(ready_queue[pri]);
+ QUEUE *p_entry;
+
+ if (!queue_empty(p_queue) && p_queue->p_next->p_next != p_queue) {
+ p_entry = queue_delete_next(p_queue);
+ queue_insert_prev(p_queue, p_entry);
+ if (p_schedtsk == (TCB *) p_entry) {
+ p_schedtsk = (TCB *)(p_queue->p_next);
+ return(dspflg);
+ }
+ }
+ return(false);
+}
+
+#endif /* TOPPERS_tskrot */
+
+/*
+ * タスク例外処理ルーチンの呼出し
+ *
+ * ASPカーネルでは,タスク例外処理ルーチン内でCPUロック状態に遷移し,
+ * 元の状態に戻さずにリターンした場合,カーネルが元の状態に戻す.
+ */
+#ifdef TOPPERS_tsktex
+
+void
+call_texrtn(void)
+{
+ TEXPTN texptn;
+ PRI saved_ipm;
+ bool_t saved_disdsp, saved_dspflg;
+
+ saved_ipm = t_get_ipm();
+ saved_disdsp = disdsp;
+ saved_dspflg = dspflg;
+ p_runtsk->enatex = false;
+ do {
+ texptn = p_runtsk->texptn;
+ p_runtsk->texptn = 0U;
+
+ t_unlock_cpu();
+ LOG_TEX_ENTER(p_runtsk, texptn);
+ (*((TEXRTN)(p_runtsk->p_tinib->texrtn)))(texptn,
+ p_runtsk->p_tinib->exinf);
+ LOG_TEX_LEAVE(p_runtsk);
+ if (!t_sense_lock()) {
+ t_lock_cpu();
+ }
+ t_set_ipm(saved_ipm);
+ disdsp = saved_disdsp;
+ dspflg = saved_dspflg;
+ /*
+ * ここでp_runtsk->enatexをfalseにするのは,タスク例外処理ルー
+ * チンから,タスク例外処理許可状態のままリターンした場合の対
+ * 策である.
+ */
+ p_runtsk->enatex = false;
+ if (p_runtsk != p_schedtsk && dspflg) {
+ /*
+ * ここでdispatchを呼び出す処理は,相互再帰呼出しになって
+ * いるが,dispatchを呼ぶ前にp_runtsk->enatexをflaseにして
+ * おけば支障がない.その理由については,「TOPPERS/ASP カー
+ * ネル 設計メモ」を参照のこと.
+ */
+ dispatch();
+ }
+ } while (p_runtsk->texptn != 0U);
+ p_runtsk->enatex = true;
+}
+
+/*
+ * タスク例外処理ルーチンの起動
+ */
+#ifndef OMIT_CALLTEX
+
+void
+calltex(void)
+{
+ if (p_runtsk->enatex && p_runtsk->texptn != 0U) {
+ call_texrtn();
+ }
+}
+
+#endif /* OMIT_CALLTEX */
+#endif /* TOPPERS_tsktex */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * $Id: task.h 1863 2010-07-25 12:23:05Z ertl-hiro $
+ */
+
+/*
+ * タスク管理モジュール
+ */
+
+#ifndef TOPPERS_TASK_H
+#define TOPPERS_TASK_H
+
+#include <queue.h>
+#include "time_event.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_TSKSTAT
+#define LOG_TSKSTAT(p_tcb)
+#endif /* LOG_TSKSTAT */
+
+/*
+ * タスク優先度の内部表現・外部表現変換マクロ
+ */
+#define INT_PRIORITY(x) ((uint_t)((x) - TMIN_TPRI))
+#define EXT_TSKPRI(x) ((PRI)(x) + TMIN_TPRI)
+
+/*
+ * タスク状態の内部表現
+ *
+ * TCB中のタスク状態では,実行状態(RUNNING)と実行可能状態(READY)
+ * は区別しない.両状態を総称して,実行できる状態(RUNNABLE)と呼ぶ.
+ * 二重待ち状態は,(TS_WAITING | TS_SUSPENDED)で表す.TS_WAIT_???は待
+ * ち要因を表し,待ち状態(二重待ち状態を含む)の場合にのみ設定する.
+ */
+#define TS_DORMANT 0x00U /* 休止状態 */
+#define TS_RUNNABLE 0x01U /* 実行できる状態 */
+#define TS_WAITING 0x02U /* 待ち状態 */
+#define TS_SUSPENDED 0x04U /* 強制待ち状態 */
+
+#define TS_WAIT_DLY (0x00U << 3) /* 時間経過待ち */
+#define TS_WAIT_SLP (0x01U << 3) /* 起床待ち */
+#define TS_WAIT_RDTQ (0x02U << 3) /* データキューからの受信待ち */
+#define TS_WAIT_RPDQ (0x03U << 3) /* 優先度データキューからの受信待ち */
+#define TS_WAIT_SEM (0x04U << 3) /* セマフォ資源の獲得待ち */
+#define TS_WAIT_FLG (0x05U << 3) /* イベントフラグ待ち */
+#define TS_WAIT_SDTQ (0x06U << 3) /* データキューへの送信待ち */
+#define TS_WAIT_SPDQ (0x07U << 3) /* 優先度データキューへの送信待ち */
+#define TS_WAIT_MBX (0x08U << 3) /* メールボックスからの受信待ち */
+#define TS_WAIT_MPF (0x09U << 3) /* 固定長メモリブロックの獲得待ち */
+
+/*
+ * タスク状態判別マクロ
+ *
+ * TSTAT_DORMANTはタスクが休止状態であるかどうかを,TSTAT_RUNNABLEは
+ * タスクが実行できる状態であるかどうかを判別する.TSTAT_WAITINGは待
+ * ち状態と二重待ち状態のいずれかであるかどうかを,TSTAT_SUSPENDEDは
+ * 強制待ち状態と二重待ち状態のいずれかであるかどうかを判別する.
+ */
+#define TSTAT_DORMANT(tstat) ((tstat) == TS_DORMANT)
+#define TSTAT_RUNNABLE(tstat) (((tstat) & TS_RUNNABLE) != 0U)
+#define TSTAT_WAITING(tstat) (((tstat) & TS_WAITING) != 0U)
+#define TSTAT_SUSPENDED(tstat) (((tstat) & TS_SUSPENDED) != 0U)
+
+/*
+ * タスク待ち要因判別マクロ
+ *
+ * TSTAT_WAIT_SLPはタスクが起床待ちであるかどうかを,TSTAT_WAIT_WOBJ
+ * はタスクが同期・通信オブジェクトに対する待ちであるか(言い換えると,
+ * 同期通信オブジェクトの待ちキューにつながれているか)どうかを判別す
+ * る.また,TSTAT_WAIT_WOBJCBはタスクが同期・通信オブジェクトの管理
+ * ブロックの共通部分(WOBJCB)の待ちキューにつながれているかどうかを
+ * 判別する.
+ *
+ * TSTAT_WAIT_SLPは,任意のタスク状態の中から,タスクが起床待ちである
+ * ことを判別できる.すなわち,TSTAT_WAITINGにより待ち状態であることを
+ * 判別せずに,TSTAT_SLPだけを用いて起床待ち状態であることを判別できる.
+ * これを効率的に実現するために,TS_WAIT_SLPの値を,(0x00U << 3)ではな
+ * く(0x01U << 3)としている.そのため,タスクが時間経過待ち状態である
+ * ことを判別するためのTSTAT_WAIT_DLYを,TSTAT_WAIT_SLPと同様の方法で
+ * 実現することはできない.
+ */
+#define TS_WAIT_MASK (0x0fU << 3) /* 待ち要因の取出しマスク */
+
+#define TSTAT_WAIT_SLP(tstat) (((tstat) & TS_WAIT_MASK) == TS_WAIT_SLP)
+#define TSTAT_WAIT_WOBJ(tstat) (((tstat) & TS_WAIT_MASK) >= TS_WAIT_RDTQ)
+#define TSTAT_WAIT_WOBJCB(tstat) (((tstat) & TS_WAIT_MASK) >= TS_WAIT_SEM)
+
+/*
+ * 待ち情報ブロック(WINFO)の定義
+ *
+ * タスクが待ち状態の間は,TCBおよびそのp_winfoで指されるWINFOを次の
+ * ように設定しなければならない.
+ *
+ * (a) TCBのタスク状態を待ち状態(TS_WAITING)にする.その際に,待ち
+ * 要因(TS_WAIT_???)も設定する.
+ *
+ * (b) タイムアウトを監視するために,タイムイベントブロックを登録する.
+ * 登録するタイムイベントブロックは,待ちに入るサービスコール処理関数
+ * のローカル変数として確保し,それへのポインタをWINFOのp_tmevtbに記
+ * 憶する.タイムアウトの監視が必要ない場合(永久待ちの場合)には,
+ * p_tmevtbをNULLにする.
+ *
+ * 同期・通信オブジェクトに対する待ち状態の場合には,標準のWINFOに
+ * p_wobjcbフィールドを追加した構造体(WINFO_WOBJ,wait.hで定義)を使
+ * う.また,以下の(c)〜(e)の設定を行う必要がある.同期・通信オブジェ
+ * クトに関係しない待ち(起床待ち,時間経過待ち)の場合には,(c)〜(e)
+ * は必要ない.
+ *
+ * (c) TCBを待ち対象の同期・通信オブジェクトの待ちキューにつなぐ.待
+ * ちキューにつなぐために,task_queueを使う.
+ *
+ * (d) 待ち対象の同期・通信オブジェクトの管理ブロックへのポインタを,
+ * WINFO_WOBJのp_wobjcbに記憶する.
+ *
+ * (e) 待ち対象の同期・通信オブジェクトに依存して記憶することが必要な
+ * 情報がある場合には,WINFO_WOBJに必要な情報のためのフィールドを追加
+ * した構造体を定義し,WINFO_WOBJの代わりに用いる.
+ *
+ * 待ち状態を解除する際には,待ち解除したタスクに対する返値をWINFOの
+ * wercdに設定する.wercdが必要なのは待ち解除以降であるのに対して,
+ * p_tmevtbは待ち解除後は必要ないため,メモリ節約のために共用体を使っ
+ * ている.そのため,wercdへエラーコードを設定するのは,タイムイベント
+ * ブロックを登録解除した後にしなければならない.
+ */
+typedef union waiting_information {
+ ER wercd; /* 待ち解除時のエラーコード */
+ TMEVTB *p_tmevtb; /* 待ち状態用のタイムイベントブロック */
+} WINFO;
+
+/*
+ * タスク初期化ブロック
+ *
+ * タスクに関する情報を,値が変わらないためにROMに置ける部分(タスク
+ * 初期化ブロック)と,値が変化するためにRAMに置かなければならない部
+ * 分(タスク管理ブロック,TCB)に分離し,TCB内に対応するタスク初期化
+ * ブロックを指すポインタを入れる.タスク初期化ブロック内に対応する
+ * TCBを指すポインタを入れる方法の方が,RAMの節約の観点からは望ましい
+ * が,実行効率が悪くなるために採用していない.他のオブジェクトについ
+ * ても同様に扱う.
+ *
+ * タスク初期化ブロックには,DEF_TEXで定義されるタスク例外処理ルーチ
+ * ンに関する情報も含む.
+ */
+typedef struct task_initialization_block {
+ ATR tskatr; /* タスク属性 */
+ intptr_t exinf; /* タスクの拡張情報 */
+ TASK task; /* タスクの起動番地 */
+ uint_t ipriority; /* タスクの起動時優先度(内部表現) */
+
+#ifdef USE_TSKINICTXB
+ TSKINICTXB tskinictxb; /* タスク初期化コンテキストブロック */
+#else /* USE_TSKINICTXB */
+ SIZE stksz; /* スタック領域のサイズ(丸めた値) */
+ void *stk; /* スタック領域の先頭番地 */
+#endif /* USE_TSKINICTXB */
+
+ ATR texatr; /* タスク例外処理ルーチン属性 */
+ TEXRTN texrtn; /* タスク例外処理ルーチンの起動番地 */
+} TINIB;
+
+/*
+ * TCB中のフィールドのビット幅の定義
+ *
+ * プロセッサによっては,TCB中のフィールドのビット幅でメモリ使用量と
+ * 性能がトレードオフになるため,ターゲット依存にフィールドのビット幅
+ * を変更することを許している.
+ */
+#ifndef TBIT_TCB_PRIORITY
+#define TBIT_TCB_PRIORITY 8 /* priorityフィールドのビット幅 */
+#endif /* TBIT_TCB_PRIORITY */
+
+/*
+ * タスク管理ブロック(TCB)
+ *
+ * ASPカーネルでは,タスクの起動要求キューイング数の最大値(TMAX_ACTCNT)
+ * と起床要求キューイング数の最大値(TMAX_WUPCNT)は1に固定されている
+ * ため,キューイングされているかどうかの真偽値で表現することができる.
+ * また,強制待ち要求ネスト数の最大値(TMAX_SUSCNT)が1に固定されてい
+ * るので,強制待ち要求ネスト数(suscnt)は必要ない.
+ *
+ * TCBのいくつかのフィールドは,特定のタスク状態でのみ有効な値を保持し,
+ * それ以外の場合は値が保証されない(よって,参照してはならない).各
+ * フィールドが有効な値を保持する条件は次の通り.
+ *
+ * ・初期化後は常に有効:
+ * p_tinib,tstat,actque
+ * ・休止状態以外で有効(休止状態では初期値になっている):
+ * priority,wupque,enatex,texptn
+ * ・待ち状態(二重待ち状態を含む)で有効:
+ * p_winfo
+ * ・実行できる状態と同期・通信オブジェクトに対する待ち状態で有効:
+ * task_queue
+ * ・実行可能状態,待ち状態,強制待ち状態,二重待ち状態で有効:
+ * tskctxb
+ */
+typedef struct task_control_block {
+ QUEUE task_queue; /* タスクキュー */
+ const TINIB *p_tinib; /* 初期化ブロックへのポインタ */
+
+#ifdef UINT8_MAX
+ uint8_t tstat; /* タスク状態(内部表現)*/
+#else /* UINT8_MAX */
+ BIT_FIELD_UINT tstat : 8; /* タスク状態(内部表現)*/
+#endif /* UINT8_MAX */
+#if defined(UINT8_MAX) && (TBIT_TCB_PRIORITY == 8)
+ uint8_t priority; /* 現在の優先度(内部表現)*/
+#else /* defined(UINT8_MAX) && (TBIT_TCB_PRIORITY == 8) */
+ BIT_FIELD_UINT priority : TBIT_TCB_PRIORITY;
+ /* 現在の優先度(内部表現)*/
+#endif /* defined(UINT8_MAX) && (TBIT_TCB_PRIORITY == 8) */
+ BIT_FIELD_BOOL actque : 1; /* 起動要求キューイング */
+ BIT_FIELD_BOOL wupque : 1; /* 起床要求キューイング */
+ BIT_FIELD_BOOL enatex : 1; /* タスク例外処理許可状態 */
+
+ TEXPTN texptn; /* 保留例外要因 */
+ WINFO *p_winfo; /* 待ち情報ブロックへのポインタ */
+ TSKCTXB tskctxb; /* タスクコンテキストブロック */
+} TCB;
+
+/*
+ * 実行状態のタスク
+ *
+ * 実行状態のタスク(=プロセッサがコンテキストを持っているタスク)の
+ * TCBを指すポインタ.実行状態のタスクがない場合はNULLにする.
+ *
+ * サービスコールの処理中で,自タスク(サービスコールを呼び出したタス
+ * ク)に関する情報を参照する場合はp_runtskを使う.p_runtskを書き換え
+ * るのは,ディスパッチャ(と初期化処理)のみである.
+ */
+extern TCB *p_runtsk;
+
+/*
+ * 最高優先順位のタスク
+ *
+ * 実行できるタスクの中で最高優先順位のタスクのTCBを指すポインタ.実
+ * 行できるタスクがない場合はNULLにする.
+ *
+ * ディスパッチ禁止状態など,ディスパッチが保留されている間はp_runtsk
+ * と一致しているとは限らない.
+ */
+extern TCB *p_schedtsk;
+
+/*
+ * ディスパッチ/タスク例外処理ルーチン起動要求フラグ
+ *
+ * 割込みハンドラ/CPU例外ハンドラの出口処理に,ディスパッチまたは
+ * タスク例外処理ルーチンの起動を要求することを示すフラグ.
+ */
+extern bool_t reqflg;
+
+/*
+ * ディスパッチ禁止状態
+ *
+ * ディスパッチ禁止状態であることを示すフラグ.
+ */
+extern bool_t disdsp;
+
+/*
+ * タスクディスパッチ可能状態
+ *
+ * 割込み優先度マスク全解除状態であり,ディスパッチ許可状態である(ディ
+ * スパッチ禁止状態でない)ことを示すフラグ.
+ */
+extern bool_t dspflg;
+
+/*
+ * レディキュー
+ *
+ * レディキューは,実行できる状態のタスクを管理するためのキューである.
+ * 実行状態のタスクも管理しているため,レディ(実行可能)キューという
+ * 名称は正確ではないが,レディキューという名称が定着しているため,こ
+ * の名称で呼ぶことにする.
+ *
+ * レディキューは,優先度ごとのタスクキューで構成されている.タスクの
+ * TCBは,該当する優先度のキューに登録される.
+ */
+extern QUEUE ready_queue[TNUM_TPRI];
+
+/*
+ * レディキューサーチのためのビットマップ
+ *
+ * レディキューのサーチを効率よく行うために,優先度ごとのタスクキュー
+ * にタスクが入っているかどうかを示すビットマップを用意している.ビッ
+ * トマップを使うことで,メモリアクセスの回数を減らすことができるが,
+ * ビット操作命令が充実していないプロセッサで,優先度の段階数が少ない
+ * 場合には,ビットマップ操作のオーバーヘッドのために,逆に効率が落ち
+ * る可能性もある.
+ *
+ * 優先度の段階数により,ビットマップを1段階にするか2段階にするかを決
+ * 定する.2段階で足りない場合には対応していない.
+ */
+#define TBIT_PRIMAP 16 /* ビットマップ1つあたりの段階数 */
+
+#if TNUM_TPRI <= TBIT_PRIMAP
+#define PRIMAP_LEVEL_1 /* ビットマップを1段階に */
+#elif TNUM_TPRI <= TBIT_PRIMAP * TBIT_PRIMAP
+#define PRIMAP_LEVEL_2 /* ビットマップを2段階に */
+#define TNUM_PRIMAP2 ((TNUM_TPRI + TBIT_PRIMAP - 1) / TBIT_PRIMAP)
+#else
+#error too many task priority levels.
+#endif
+
+#ifdef PRIMAP_LEVEL_1
+extern uint16_t ready_primap; /* 優先度ビットマップ */
+#else /* PRIMAP_LEVEL_1 */
+extern uint16_t ready_primap1; /* 1段目の優先度ビットマップ */
+extern uint16_t ready_primap2[TNUM_PRIMAP2]; /* 2段目の優先度ビットマップ */
+#endif /* PRIMAP_LEVEL_1 */
+
+/*
+ * タスクIDの最大値(kernel_cfg.c)
+ */
+extern const ID tmax_tskid;
+
+/*
+ * タスク初期化ブロックのエリア(kernel_cfg.c)
+ */
+extern const TINIB tinib_table[];
+
+/*
+ * タスク生成順序テーブル(kernel_cfg.c)
+ */
+extern const ID torder_table[];
+
+/*
+ * TCBのエリア(kernel_cfg.c)
+ */
+extern TCB tcb_table[];
+
+/*
+ * タスクの数
+ */
+#define tnum_tsk ((uint_t)(tmax_tskid - TMIN_TSKID + 1))
+
+/*
+ * タスクIDからTCBを取り出すためのマクロ
+ */
+#define INDEX_TSK(tskid) ((uint_t)((tskid) - TMIN_TSKID))
+#define get_tcb(tskid) (&(tcb_table[INDEX_TSK(tskid)]))
+#define get_tcb_self(tskid) ((tskid) == TSK_SELF ? p_runtsk : get_tcb(tskid))
+
+/*
+ * TCBからタスクIDを取り出すためのマクロ
+ */
+#define TSKID(p_tcb) ((ID)(((p_tcb) - tcb_table) + TMIN_TSKID))
+
+/*
+ * タスク管理モジュールの初期化
+ */
+extern void initialize_task(void);
+
+/*
+ * 最高優先順位タスクのサーチ
+ *
+ * レディキュー中の最高優先順位のタスクをサーチし,そのTCBへのポインタ
+ * を返す.レディキューが空の場合には,この関数を呼び出してはならない.
+ */
+extern TCB *search_schedtsk(void);
+
+/*
+ * 実行できる状態への遷移
+ *
+ * p_tcbで指定されるタスクをレディキューに挿入する.レディキューに挿入
+ * したタスクの優先度が,最高優先順位のタスクの優先度よりも高い場合は,
+ * 最高優先順位のタスクを更新し,ディスパッチ許可状態であればtrueを返
+ * す.そうでない場合はfalseを返す.
+ */
+extern bool_t make_runnable(TCB *p_tcb);
+
+/*
+ * 実行できる状態から他の状態への遷移
+ *
+ * p_tcbで指定されるタスクをレディキューから削除する.p_tcbで指定した
+ * タスクが最高優先順位のタスクであった場合には,最高優先順位のタスク
+ * を設定しなおし,ディスパッチ許可状態であればtrueを返す.そうでない
+ * 場合はfalseを返す.タスクの状態は更新しない.
+ */
+extern bool_t make_non_runnable(TCB *p_tcb);
+
+/*
+ * 休止状態への遷移
+ *
+ * p_tcbで指定されるタスクの状態を休止状態とする.また,タスクの起動
+ * 時に初期化すべき変数の初期化と,タスク起動のためのコンテキストを設
+ * 定する.
+ */
+extern void make_dormant(TCB *p_tcb);
+
+/*
+ * 休止状態から実行できる状態への遷移
+ *
+ * p_tcbで指定されるタスクの状態を休止状態から実行できる状態とする.
+ * 実行できる状態に遷移したタスクへのディスパッチが必要な場合はtrue,
+ * そうでない場合はfalseを返す.
+ */
+extern bool_t make_active(TCB *p_tcb);
+
+/*
+ * タスクの優先度の変更
+ *
+ * p_tcbで指定されるタスクの優先度をnewpri(内部表現)に変更する.また,
+ * 必要な場合には最高優先順位のタスクを更新し,ディスパッチ許可状態で
+ * あればtrueを返す.そうでない場合はfalseを返す.
+ */
+extern bool_t change_priority(TCB *p_tcb, uint_t newpri);
+
+/*
+ * レディキューの回転
+ *
+ * レディキュー中の,priで指定される優先度のタスクキューを回転させる.
+ * また,必要な場合には最高優先順位のタスクを変更し,ディスパッチが保
+ * 留されていなければtrueを返す.そうでない場合はfalseを返す.
+ */
+extern bool_t rotate_ready_queue(uint_t pri);
+
+/*
+ * タスク例外処理ルーチンの呼出し
+ *
+ * タスク例外処理ルーチンを呼び出す.呼び出す前に,実行状態のタスクの
+ * 保留例外要因をクリアし,タスク例外処理禁止状態にし,CPUロックを解
+ * 除する.
+ *
+ * タスク例外処理ルーチンから戻ると,まずCPUロック状態に戻し,その間
+ * に保留例外要因が0でなくなっていれば,再びタスク例外処理ルーチンを
+ * 呼び出す.保留例外要因が0の場合には,例外処理許可状態にして関数か
+ * らリターンする.
+ *
+ * この関数は,実行状態のタスクが,タスク例外処理許可状態(enatexが
+ * true)で,保留例外要因が0でない(texptnが0でない)場合に呼び出すこ
+ * とを想定している.この関数は,CPUロック状態で呼び出さなければなら
+ * ない.
+ */
+extern void call_texrtn(void);
+
+/*
+ * タスク例外処理ルーチンの起動
+ *
+ * 実行状態のタスクがタスク例外処理ルーチンの起動条件を満たしていれば,
+ * タスク例外処理ルーチンを呼び出す.CPU例外処理ルーチンを呼び出す時
+ * は,一時的にCPUロックを解除する.
+ *
+ * この関数は,ディスパッチャや割込みハンドラ/CPU例外ハンドラの出口
+ * 処理から呼び出されることを想定している.この関数は,CPUロック状態
+ * で呼び出さなければならない.
+ *
+ * 実行効率を上げるために,この関数をターゲット依存部で記述してもよい.
+ * その場合には,OMIT_CALLTEXをマクロ定義する.
+ */
+extern void calltex(void);
+
+#endif /* TOPPERS_TASK_H */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_task1.h 496 2007-08-20 02:53:40Z hiro $
+ */
+
+/*
+ * タスク管理モジュールのテスト(1)
+ */
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 優先度の定義
+ */
+#define HIGH_PRIORITY 18 /* 高優先度 */
+#define MID_PRIORITY 137 /* 中優先度 */
+#define LOW_PRIORITY 255 /* 低優先度 */
+
+/*
+ * ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define STACK_SIZE 4096 /* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void task1(intptr_t exinf);
+extern void task2(intptr_t exinf);
+extern void task3(intptr_t exinf);
+extern void task4(intptr_t exinf);
+extern void task5(intptr_t exinf);
+extern void task6(intptr_t exinf);
+extern void alarm1_handler(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2006-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: histogram.h 1876 2010-07-29 16:27:57Z ertl-hiro $
+ */
+
+/*
+ * 実行時間分布集計モジュール
+ */
+
+#ifndef TOPPERS_HISTOGRAM_H
+#define TOPPERS_HISTOGRAM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * 実行時間分布計測の初期化
+ */
+extern void init_hist(ID histid, uint_t maxval, uint_t *hist);
+
+/*
+ * 実行時間計測の開始
+ */
+extern void begin_measure(ID histid);
+
+/*
+ * 実行時間計測の終了
+ */
+extern void end_measure(ID histid);
+
+/*
+ * 実行時間分布計測の表示
+ */
+extern void print_hist(ID histid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_HISTOGRAM_H */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * $Id: itron.h 1762 2010-02-18 02:24:39Z ertl-hiro $
+ */
+
+/*
+ * ITRON仕様共通規定のデータ型・定数・マクロ
+ *
+ * このヘッダファイルは,ITRON仕様共通規定のデータ型・定数・マクロの中
+ * で,TOPPERS共通ヘッダファイルに含まれないものの定義を含む.ITRON仕
+ * 様との互換性を必要とするアプリケーションがインクルードすることを想
+ * 定している.
+ *
+ * アセンブリ言語のソースファイルからこのファイルをインクルードする時
+ * は,TOPPERS_MACRO_ONLYを定義しておく.これにより,マクロ定義以外を
+ * 除くようになっている.
+ */
+
+#ifndef TOPPERS_ITRON_H
+#define TOPPERS_ITRON_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * TOPPERS共通ヘッダファイル
+ */
+#include "t_stddef.h"
+
+/*
+ * ITRON仕様共通データ型
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+#ifdef INT8_MAX
+typedef int8_t B; /* 符号付き8ビット整数 */
+#endif /* INT8_MAX */
+
+#ifdef UINT8_MAX
+typedef uint8_t UB; /* 符号無し8ビット整数 */
+typedef uint8_t VB; /* 型が定まらない8ビットの値 */
+#endif /* UINT8_MAX */
+
+typedef int16_t H; /* 符号付き16ビット整数 */
+typedef uint16_t UH; /* 符号無し16ビット整数 */
+typedef uint16_t VH; /* 型が定まらない16ビットの値 */
+
+typedef int32_t W; /* 符号付き32ビット整数 */
+typedef uint32_t UW; /* 符号無し32ビット整数 */
+typedef uint32_t VW; /* 型が定まらない32ビットの値 */
+
+#ifdef INT64_MAX
+typedef int64_t D; /* 符号付き64ビット整数 */
+#endif /* INT64_MAX */
+
+#ifdef UINT64_MAX
+typedef uint64_t UD; /* 符号無し64ビット整数 */
+typedef uint64_t VD; /* 型が定まらない64ビットの値 */
+#endif /* UINT64_MAX */
+
+typedef void *VP; /* 型が定まらないものへのポインタ */
+
+typedef int_t INT; /* 自然なサイズの符号付き整数 */
+typedef uint_t UINT; /* 自然なサイズの符号無し整数 */
+
+typedef bool_t BOOL; /* 真偽値 */
+
+typedef intptr_t VP_INT; /* ポインタまたは符号付き整数 */
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ * ITRON仕様共通定数
+ */
+#define TRUE true /* 真 */
+#define FALSE false /* 偽 */
+
+/*
+ * オブジェクト属性の定義
+ */
+#define TA_HLNG UINT_C(0x00) /* 高級言語用インタフェース */
+#define TA_TFIFO UINT_C(0x00) /* タスクの待ち行列をFIFO順に */
+#define TA_MFIFO UINT_C(0x00) /* メッセージキューをFIFO順に */
+#define TA_WSGL UINT_C(0x00) /* 待ちタスクは1つのみ */
+
+/*
+ * ネスト回数の最大値
+ */
+#define TMAX_SUSCNT UINT_C(1) /* 強制待ち要求ネスト数の最大値 */
+
+/*
+ * 強制待ち状態からの強制再開
+ */
+#define frsm_tsk(tskid) rsm_tsk(tskid)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_ITRON_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: kernel.h 1862 2010-07-25 11:49:51Z ertl-hiro $
+ */
+
+/*
+ * TOPPERS/ASPカーネル 標準ヘッダファイル
+ *
+ * TOPPERS/ASPカーネルがサポートするサービスコールの宣言と,必要なデー
+ * タ型,定数,マクロの定義を含むヘッダファイル.
+ *
+ * アセンブリ言語のソースファイルからこのファイルをインクルードする時
+ * は,TOPPERS_MACRO_ONLYを定義しておく.これにより,マクロ定義以外を
+ * 除くようになっている.
+ *
+ * このファイルをインクルードする前にインクルードしておくべきファイル
+ * はない.
+ */
+
+#ifndef TOPPERS_KERNEL_H
+#define TOPPERS_KERNEL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * TOPPERS共通のデータ型・定数・マクロ
+ */
+#include <t_stddef.h>
+
+/*
+ * ターゲット依存部
+ */
+#include "target_kernel.h"
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ * データ型の定義
+ */
+
+/*
+ * ビットパターンやオブジェクト番号の型定義
+ */
+typedef uint_t TEXPTN; /* タスク例外要因のビットパターン */
+typedef uint_t FLGPTN; /* イベントフラグのビットパターン */
+typedef uint_t INTNO; /* 割込み番号 */
+typedef uint_t INHNO; /* 割込みハンドラ番号 */
+typedef uint_t EXCNO; /* CPU例外ハンドラ番号 */
+
+/*
+ * 処理単位の型定義
+ */
+typedef void (*TASK)(intptr_t exinf);
+typedef void (*TEXRTN)(TEXPTN texptn, intptr_t exinf);
+typedef void (*CYCHDR)(intptr_t exinf);
+typedef void (*ALMHDR)(intptr_t exinf);
+typedef void (*ISR)(intptr_t exinf);
+typedef void (*INTHDR)(void);
+typedef void (*EXCHDR)(void *p_excinf);
+typedef void (*INIRTN)(intptr_t exinf);
+typedef void (*TERRTN)(intptr_t exinf);
+
+/*
+ * メモリ領域確保のための型定義
+ */
+#ifndef TOPPERS_STK_T
+#define TOPPERS_STK_T intptr_t
+#endif /* TOPPERS_STK_T */
+typedef TOPPERS_STK_T STK_T; /* スタック領域を確保するための型 */
+
+#ifndef TOPPERS_MPF_T
+#define TOPPERS_MPF_T intptr_t
+#endif /* TOPPERS_MPF_T */
+typedef TOPPERS_MPF_T MPF_T; /* 固定長メモリプール領域を確保するための型 */
+
+/*
+ * メッセージヘッダの型定義
+ */
+typedef struct t_msg { /* メールボックスのメッセージヘッダ */
+ struct t_msg *pk_next;
+} T_MSG;
+
+typedef struct t_msg_pri { /* 優先度付きメッセージヘッダ */
+ T_MSG msgque; /* メッセージヘッダ */
+ PRI msgpri; /* メッセージ優先度 */
+} T_MSG_PRI;
+
+/*
+ * パケット形式の定義
+ */
+typedef struct t_rtsk {
+ STAT tskstat; /* タスク状態 */
+ PRI tskpri; /* タスクの現在優先度 */
+ PRI tskbpri; /* タスクのベース優先度 */
+ STAT tskwait; /* 待ち要因 */
+ ID wobjid; /* 待ち対象のオブジェクトのID */
+ TMO lefttmo; /* タイムアウトするまでの時間 */
+ uint_t actcnt; /* 起動要求キューイング数 */
+ uint_t wupcnt; /* 起床要求キューイング数 */
+} T_RTSK;
+
+typedef struct t_itsk {
+ PRI tsk_pri_curr; /* 現在のプライオリティ */
+ PRI tsk_pri_base; /* ベースプライオリティ */
+ SIZE stk_used; /* タスクスタック使用量 */
+ SIZE stk_total; /* タスクスタック総量 */
+ void *stk_head; /* タスクスタック先頭アドレス */
+ void *stk_tail; /* タスクスタック最終アドレス */
+} T_ITSK;
+
+typedef struct t_rtex {
+ STAT texstat; /* タスク例外処理の状態 */
+ TEXPTN pndptn; /* 保留例外要因 */
+} T_RTEX;
+
+typedef struct t_rsem {
+ ID wtskid; /* セマフォの待ち行列の先頭のタスクのID番号 */
+ uint_t semcnt; /* セマフォの現在の資源数 */
+} T_RSEM;
+
+typedef struct t_rflg {
+ ID wtskid; /* イベントフラグの待ち行列の先頭のタスクのID番号 */
+ FLGPTN flgptn; /* イベントフラグの現在のビットパターン */
+} T_RFLG;
+
+typedef struct t_rdtq {
+ ID stskid; /* データキューの送信待ち行列の先頭のタスクのID番号 */
+ ID rtskid; /* データキューの受信待ち行列の先頭のタスクのID番号 */
+ uint_t sdtqcnt; /* データキュー管理領域に格納されているデータの数 */
+} T_RDTQ;
+
+typedef struct t_rpdq {
+ ID stskid; /* 優先度データキューの送信待ち行列の先頭のタスク
+ のID番号 */
+ ID rtskid; /* 優先度データキューの受信待ち行列の先頭のタスク
+ のID番号 */
+ uint_t spdqcnt; /* 優先度データキュー管理領域に格納されているデー
+ タの数 */
+} T_RPDQ;
+
+typedef struct t_rmbx {
+ ID wtskid; /* メールボックスの待ち行列の先頭のタスクのID番号 */
+ T_MSG *pk_msg; /* メッセージキューの先頭につながれたメッセージ
+ の先頭番地 */
+} T_RMBX;
+
+typedef struct t_rmpf {
+ ID wtskid; /* 固定長メモリプールの待ち行列の先頭のタスクの
+ ID番号 */
+ uint_t fblkcnt; /* 固定長メモリプール領域の空きメモリ領域に割り
+ 付けることができる固定長メモリブロックの数 */
+} T_RMPF;
+
+typedef struct t_rcyc {
+ STAT cycstat; /* 周期ハンドラの動作状態 */
+ RELTIM lefttim; /* 次に周期ハンドラを起動する時刻までの相対時間 */
+} T_RCYC;
+
+typedef struct t_ralm {
+ STAT almstat; /* アラームハンドラの動作状態 */
+ RELTIM lefttim; /* アラームハンドラを起動する時刻までの相対時間 */
+} T_RALM;
+
+/*
+ * サービスコールの宣言
+ */
+
+/*
+ * タスク管理機能
+ */
+extern ER act_tsk(ID tskid) throw();
+extern ER iact_tsk(ID tskid) throw();
+extern ER_UINT can_act(ID tskid) throw();
+extern ER ext_tsk(void) throw();
+extern ER ter_tsk(ID tskid) throw();
+extern ER chg_pri(ID tskid, PRI tskpri) throw();
+extern ER get_pri(ID tskid, PRI *p_tskpri) throw();
+extern ER get_inf(intptr_t *p_exinf) throw();
+extern ER ref_tsk(ID tskid, T_RTSK *pk_rtsk) throw();
+extern ER inf_tsk(ID tskid, T_ITSK *pk_itsk) throw();
+
+/*
+ * タスク付属同期機能
+ */
+extern ER slp_tsk(void) throw();
+extern ER tslp_tsk(TMO tmout) throw();
+extern ER wup_tsk(ID tskid) throw();
+extern ER iwup_tsk(ID tskid) throw();
+extern ER_UINT can_wup(ID tskid) throw();
+extern ER rel_wai(ID tskid) throw();
+extern ER irel_wai(ID tskid) throw();
+extern ER sus_tsk(ID tskid) throw();
+extern ER rsm_tsk(ID tskid) throw();
+extern ER dly_tsk(RELTIM dlytim) throw();
+
+/*
+ * タスク例外処理機能
+ */
+extern ER ras_tex(ID tskid, TEXPTN rasptn) throw();
+extern ER iras_tex(ID tskid, TEXPTN rasptn) throw();
+extern ER dis_tex(void) throw();
+extern ER ena_tex(void) throw();
+extern bool_t sns_tex(void) throw();
+extern ER ref_tex(ID tskid, T_RTEX *pk_rtex) throw();
+
+/*
+ * 同期・通信機能
+ */
+extern ER sig_sem(ID semid) throw();
+extern ER isig_sem(ID semid) throw();
+extern ER wai_sem(ID semid) throw();
+extern ER pol_sem(ID semid) throw();
+extern ER twai_sem(ID semid, TMO tmout) throw();
+extern ER ini_sem(ID semid) throw();
+extern ER ref_sem(ID semid, T_RSEM *pk_rsem) throw();
+
+extern ER set_flg(ID flgid, FLGPTN setptn) throw();
+extern ER iset_flg(ID flgid, FLGPTN setptn) throw();
+extern ER clr_flg(ID flgid, FLGPTN clrptn) throw();
+extern ER wai_flg(ID flgid, FLGPTN waiptn,
+ MODE wfmode, FLGPTN *p_flgptn) throw();
+extern ER pol_flg(ID flgid, FLGPTN waiptn,
+ MODE wfmode, FLGPTN *p_flgptn) throw();
+extern ER twai_flg(ID flgid, FLGPTN waiptn,
+ MODE wfmode, FLGPTN *p_flgptn, TMO tmout) throw();
+extern ER ini_flg(ID flgid) throw();
+extern ER ref_flg(ID flgid, T_RFLG *pk_rflg) throw();
+
+extern ER snd_dtq(ID dtqid, intptr_t data) throw();
+extern ER psnd_dtq(ID dtqid, intptr_t data) throw();
+extern ER ipsnd_dtq(ID dtqid, intptr_t data) throw();
+extern ER tsnd_dtq(ID dtqid, intptr_t data, TMO tmout) throw();
+extern ER fsnd_dtq(ID dtqid, intptr_t data) throw();
+extern ER ifsnd_dtq(ID dtqid, intptr_t data) throw();
+extern ER rcv_dtq(ID dtqid, intptr_t *p_data) throw();
+extern ER prcv_dtq(ID dtqid, intptr_t *p_data) throw();
+extern ER trcv_dtq(ID dtqid, intptr_t *p_data, TMO tmout) throw();
+extern ER ini_dtq(ID dtqid) throw();
+extern ER ref_dtq(ID dtqid, T_RDTQ *pk_rdtq) throw();
+
+extern ER snd_pdq(ID pdqid, intptr_t data, PRI datapri) throw();
+extern ER psnd_pdq(ID pdqid, intptr_t data, PRI datapri) throw();
+extern ER ipsnd_pdq(ID pdqid, intptr_t data, PRI datapri) throw();
+extern ER tsnd_pdq(ID pdqid, intptr_t data,
+ PRI datapri, TMO tmout) throw();
+extern ER rcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri) throw();
+extern ER prcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri) throw();
+extern ER trcv_pdq(ID pdqid, intptr_t *p_data,
+ PRI *p_datapri, TMO tmout) throw();
+extern ER ini_pdq(ID pdqid) throw();
+extern ER ref_pdq(ID pdqid, T_RPDQ *pk_rpdq) throw();
+
+extern ER snd_mbx(ID mbxid, T_MSG *pk_msg) throw();
+extern ER rcv_mbx(ID mbxid, T_MSG **ppk_msg) throw();
+extern ER prcv_mbx(ID mbxid, T_MSG **ppk_msg) throw();
+extern ER trcv_mbx(ID mbxid, T_MSG **ppk_msg, TMO tmout) throw();
+extern ER ini_mbx(ID mbxid) throw();
+extern ER ref_mbx(ID mbxid, T_RMBX *pk_rmbx) throw();
+
+/*
+ * メモリプール管理機能
+ */
+extern ER get_mpf(ID mpfid, void **p_blk) throw();
+extern ER pget_mpf(ID mpfid, void **p_blk) throw();
+extern ER tget_mpf(ID mpfid, void **p_blk, TMO tmout) throw();
+extern ER rel_mpf(ID mpfid, void *blk) throw();
+extern ER ini_mpf(ID mpfid) throw();
+extern ER ref_mpf(ID mpfid, T_RMPF *pk_rmpf) throw();
+
+/*
+ * 時間管理機能
+ */
+extern ER get_tim(SYSTIM *p_systim) throw();
+extern ER get_utm(SYSUTM *p_sysutm) throw();
+
+extern ER sta_cyc(ID cycid) throw();
+extern ER stp_cyc(ID cycid) throw();
+extern ER ref_cyc(ID cycid, T_RCYC *pk_rcyc) throw();
+
+extern ER sta_alm(ID almid, RELTIM almtim) throw();
+extern ER ista_alm(ID almid, RELTIM almtim) throw();
+extern ER stp_alm(ID almid) throw();
+extern ER istp_alm(ID almid) throw();
+extern ER ref_alm(ID almid, T_RALM *pk_ralm) throw();
+
+/*
+ * システム状態管理機能
+ */
+extern ER rot_rdq(PRI tskpri) throw();
+extern ER irot_rdq(PRI tskpri) throw();
+extern ER get_tid(ID *p_tskid) throw();
+extern ER iget_tid(ID *p_tskid) throw();
+extern ER loc_cpu(void) throw();
+extern ER iloc_cpu(void) throw();
+extern ER unl_cpu(void) throw();
+extern ER iunl_cpu(void) throw();
+extern ER dis_dsp(void) throw();
+extern ER ena_dsp(void) throw();
+extern bool_t sns_ctx(void) throw();
+extern bool_t sns_loc(void) throw();
+extern bool_t sns_dsp(void) throw();
+extern bool_t sns_dpn(void) throw();
+extern bool_t sns_ker(void) throw();
+extern ER ext_ker(void) throw();
+
+/*
+ * 割込み管理機能
+ */
+extern ER dis_int(INTNO intno) throw();
+extern ER ena_int(INTNO intno) throw();
+extern ER chg_ipm(PRI intpri) throw();
+extern ER get_ipm(PRI *p_intpri) throw();
+
+/*
+ * CPU例外管理機能
+ */
+extern bool_t xsns_dpn(void *p_excinf) throw();
+extern bool_t xsns_xpn(void *p_excinf) throw();
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ * オブジェクト属性の定義
+ */
+#define TA_ACT UINT_C(0x02) /* タスクを起動された状態で生成 */
+
+#define TA_TPRI UINT_C(0x01) /* タスクの待ち行列を優先度順に */
+#define TA_MPRI UINT_C(0x02) /* メッセージキューを優先度順に */
+
+#define TA_WMUL UINT_C(0x02) /* 複数の待ちタスク */
+#define TA_CLR UINT_C(0x04) /* イベントフラグのクリア指定 */
+
+#define TA_STA UINT_C(0x02) /* 周期ハンドラを動作状態で生成 */
+
+#define TA_NONKERNEL UINT_C(0x02) /* カーネル管理外の割込み */
+
+#define TA_ENAINT UINT_C(0x01) /* 割込み要求禁止フラグをクリア */
+#define TA_EDGE UINT_C(0x02) /* エッジトリガ */
+
+/*
+ * サービスコールの動作モードの定義
+ */
+#define TWF_ORW UINT_C(0x01) /* イベントフラグのOR待ち */
+#define TWF_ANDW UINT_C(0x02) /* イベントフラグのAND待ち */
+
+/*
+ * オブジェクトの状態の定義
+ */
+#define TTS_RUN UINT_C(0x01) /* 実行状態 */
+#define TTS_RDY UINT_C(0x02) /* 実行可能状態 */
+#define TTS_WAI UINT_C(0x04) /* 待ち状態 */
+#define TTS_SUS UINT_C(0x08) /* 強制待ち状態 */
+#define TTS_WAS UINT_C(0x0c) /* 二重待ち状態 */
+#define TTS_DMT UINT_C(0x10) /* 休止状態 */
+
+#define TTW_SLP UINT_C(0x0001) /* 起床待ち */
+#define TTW_DLY UINT_C(0x0002) /* 時間経過待ち */
+#define TTW_SEM UINT_C(0x0004) /* セマフォの資源獲得待ち */
+#define TTW_FLG UINT_C(0x0008) /* イベントフラグ待ち */
+#define TTW_SDTQ UINT_C(0x0010) /* データキューへの送信待ち */
+#define TTW_RDTQ UINT_C(0x0020) /* データキューからの受信待ち */
+#define TTW_SPDQ UINT_C(0x0100) /* 優先度データキューへの送信待ち */
+#define TTW_RPDQ UINT_C(0x0200) /* 優先度データキューからの受信待ち */
+#define TTW_MBX UINT_C(0x0040) /* メールボックスからの受信待ち */
+#define TTW_MPF UINT_C(0x2000) /* 固定長メモリブロックの獲得待ち */
+
+#define TTEX_ENA UINT_C(0x01) /* タスク例外処理許可状態 */
+#define TTEX_DIS UINT_C(0x02) /* タスク例外処理禁止状態 */
+
+#define TCYC_STP UINT_C(0x01) /* 周期ハンドラが動作していない */
+#define TCYC_STA UINT_C(0x02) /* 周期ハンドラが動作している */
+
+#define TALM_STP UINT_C(0x01) /* アラームハンドラが動作していない */
+#define TALM_STA UINT_C(0x02) /* アラームハンドラが動作している */
+
+/*
+ * その他の定数の定義
+ */
+#define TSK_SELF 0 /* 自タスク指定 */
+#define TSK_NONE 0 /* 該当するタスクがない */
+
+#define TPRI_SELF 0 /* 自タスクのベース優先度 */
+#define TPRI_INI 0 /* タスクの起動時優先度 */
+
+#define TIPM_ENAALL 0 /* 割込み優先度マスク全解除 */
+
+/*
+ * 構成定数とマクロ
+ */
+
+/*
+ * サポートする機能
+ */
+#ifdef TOPPERS_TARGET_SUPPORT_DIS_INT
+#define TOPPERS_SUPPORT_DIS_INT /* dis_intがサポートされている */
+#endif /* TOPPERS_TARGET_SUPPORT_DIS_INT */
+
+#ifdef TOPPERS_TARGET_SUPPORT_ENA_INT
+#define TOPPERS_SUPPORT_ENA_INT /* ena_intがサポートされている */
+#endif /* TOPPERS_TARGET_SUPPORT_ENA_INT */
+
+#ifdef TOPPERS_TARGET_SUPPORT_GET_UTM
+#define TOPPERS_SUPPORT_GET_UTM /* get_utmがサポートされている */
+#endif /* TOPPERS_TARGET_SUPPORT_GET_UTM */
+
+/*
+ * 優先度の範囲
+ */
+#define TMIN_TPRI 1 /* タスク優先度の最小値(最高値)*/
+#define TMAX_TPRI 16 /* タスク優先度の最大値(最低値)*/
+#define TMIN_DPRI 1 /* データ優先度の最小値(最高値)*/
+#define TMAX_DPRI 16 /* データ優先度の最大値(最低値)*/
+#define TMIN_MPRI 1 /* メッセージ優先度の最小値(最高値)*/
+#define TMAX_MPRI 16 /* メッセージ優先度の最大値(最低値)*/
+#define TMIN_ISRPRI 1 /* 割込みサービスルーチン優先度の最小値 */
+#define TMAX_ISRPRI 16 /* 割込みサービスルーチン優先度の最大値 */
+
+/*
+ * バージョン情報
+ */
+#define TKERNEL_MAKER UINT_C(0x0118) /* カーネルのメーカーコード */
+#define TKERNEL_PRID UINT_C(0x0007) /* カーネルの識別番号 */
+#define TKERNEL_SPVER UINT_C(0xf512) /* カーネル仕様のバージョン番号 */
+#define TKERNEL_PRVER UINT_C(0x1060) /* カーネルのバージョン番号 */
+
+/*
+ * キューイング回数の最大値
+ */
+#define TMAX_ACTCNT UINT_C(1) /* 起動要求キューイング数の最大値 */
+#define TMAX_WUPCNT UINT_C(1) /* 起床要求キューイング数の最大値 */
+
+/*
+ * ビットパターンのビット数
+ */
+#ifndef TBIT_TEXPTN /* タスク例外要因のビット数 */
+#define TBIT_TEXPTN (sizeof(TEXPTN) * CHAR_BIT)
+#endif /* TBIT_TEXPTN */
+
+#ifndef TBIT_FLGPTN /* イベントフラグのビット数 */
+#define TBIT_FLGPTN (sizeof(FLGPTN) * CHAR_BIT)
+#endif /* TBIT_FLGPTN */
+
+/*
+ * メモリ領域確保のためのマクロ
+ *
+ * 以下のTOPPERS_COUNT_SZとTOPPERS_ROUND_SZの定義は,unitが2の巾乗であ
+ * ることを仮定している.
+ */
+#ifndef TOPPERS_COUNT_SZ
+#define TOPPERS_COUNT_SZ(sz, unit) (((sz) + (unit) - 1) / (unit))
+#endif /* TOPPERS_COUNT_SZ */
+#ifndef TOPPERS_ROUND_SZ
+#define TOPPERS_ROUND_SZ(sz, unit) (((sz) + (unit) - 1) & ~((unit) - 1))
+#endif /* TOPPERS_ROUND_SZ */
+
+#define COUNT_STK_T(sz) TOPPERS_COUNT_SZ(sz, sizeof(STK_T))
+#define ROUND_STK_T(sz) TOPPERS_ROUND_SZ(sz, sizeof(STK_T))
+
+#define COUNT_MPF_T(blksz) TOPPERS_COUNT_SZ(blksz, sizeof(MPF_T))
+#define ROUND_MPF_T(blksz) TOPPERS_ROUND_SZ(blksz, sizeof(MPF_T))
+
+/*
+ * その他の構成定数
+ */
+#define TMAX_MAXSEM UINT_MAX /* セマフォの最大資源数の最大値 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_KERNEL_H */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: log_output.h 1176 2008-07-01 10:24:46Z ertl-hiro $
+ */
+
+/*
+ * システムログのフォーマット出力
+ */
+
+#ifndef TOPPERS_LOG_OUTPUT_H
+#define TOPPERS_LOG_OUTPUT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <t_syslog.h>
+
+/*
+ * 文字列整形出力
+ *
+ * formatで指定されるフォーマット記述とp_argsで指定される引数列から作
+ * 成したメッセージを,1文字出力関数putcを用いて出力する.
+ */
+extern void syslog_printf(const char *format, const intptr_t *p_args,
+ void (*putc)(char_t)) throw();
+
+/*
+ * ログ情報の出力
+ *
+ * p_syslogで指定されるログ情報を文字列に整形し,1文字出力関数putcを用
+ * いて出力する.
+ */
+extern void syslog_print(const SYSLOG *p_syslog, void (*putc)(char_t)) throw();
+
+/*
+ * ログ情報喪失メッセージ文字列
+ *
+ * lost個のログ情報が失われた旨のメッセージを,1文字出力関数putcを用い
+ * て出力する.
+ */
+extern void syslog_lostmsg(uint_t lost, void (*putc)(char_t)) throw();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_LOG_OUTPUT_H */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2000 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2006-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: queue.h 1549 2009-05-10 15:21:52Z ertl-hiro $
+ */
+
+/*
+ * キュー操作ライブラリ
+ *
+ * このキュー操作ライブラリでは,キューヘッダを含むリング構造のダブル
+ * リンクキューを扱う.具体的には,キューヘッダの次エントリはキューの
+ * 先頭のエントリ,前エントリはキューの末尾のエントリとする.また,キ
+ * ューの先頭のエントリの前エントリと,キューの末尾のエントリの次エン
+ * トリは,キューヘッダとする.空のキューは,次エントリ,前エントリと
+ * も自分自身を指すキューヘッダであらわす.
+ */
+
+#ifndef TOPPERS_QUEUE_H
+#define TOPPERS_QUEUE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * キューのデータ構造の定義
+ */
+typedef struct queue {
+ struct queue *p_next; /* 次エントリへのポインタ */
+ struct queue *p_prev; /* 前エントリへのポインタ */
+} QUEUE;
+
+/*
+ * キューの初期化
+ *
+ * p_queueにはキューヘッダを指定する.
+ */
+Inline void
+queue_initialize(QUEUE *p_queue)
+{
+ p_queue->p_prev = p_queue->p_next = p_queue;
+}
+
+/*
+ * キューの前エントリへの挿入
+ *
+ * p_queueの前にp_entryを挿入する.p_queueにキューヘッダを指定した場
+ * 合には,キューの末尾にp_entryを挿入することになる.
+ */
+Inline void
+queue_insert_prev(QUEUE *p_queue, QUEUE *p_entry)
+{
+ p_entry->p_prev = p_queue->p_prev;
+ p_entry->p_next = p_queue;
+ p_queue->p_prev->p_next = p_entry;
+ p_queue->p_prev = p_entry;
+}
+
+/*
+ * キューの次エントリへの挿入
+ *
+ * p_queueの次にp_entryを挿入する.p_queueにキューヘッダを指定した場
+ * 合には,キューの先頭にp_entryを挿入することになる.
+ */
+Inline void
+queue_insert_next(QUEUE *p_queue, QUEUE *p_entry)
+{
+ p_entry->p_prev = p_queue;
+ p_entry->p_next = p_queue->p_next;
+ p_queue->p_next->p_prev = p_entry;
+ p_queue->p_next = p_entry;
+}
+
+/*
+ * エントリの削除
+ *
+ * p_entryをキューから削除する.
+ */
+Inline void
+queue_delete(QUEUE *p_entry)
+{
+ p_entry->p_prev->p_next = p_entry->p_next;
+ p_entry->p_next->p_prev = p_entry->p_prev;
+}
+
+/*
+ * キューの次エントリの取出し
+ *
+ * p_queueの次エントリをキューから削除し,削除したエントリを返す.
+ * p_queueにキューヘッダを指定した場合には,キューの先頭のエントリを
+ * 取り出すことになる.p_queueに空のキューを指定して呼び出してはなら
+ * ない.
+ */
+Inline QUEUE *
+queue_delete_next(QUEUE *p_queue)
+{
+ QUEUE *p_entry;
+
+ assert(p_queue->p_next != p_queue);
+ p_entry = p_queue->p_next;
+ p_queue->p_next = p_entry->p_next;
+ p_entry->p_next->p_prev = p_queue;
+ return(p_entry);
+}
+
+/*
+ * キューが空かどうかのチェック
+ *
+ * p_queueにはキューヘッダを指定する.
+ */
+Inline bool_t
+queue_empty(QUEUE *p_queue)
+{
+ if (p_queue->p_next == p_queue) {
+ assert(p_queue->p_prev == p_queue);
+ return(true);
+ }
+ return(false);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_QUEUE_H */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: sil.h 1844 2010-07-11 12:59:26Z ertl-hiro $
+ */
+
+/*
+ * システムインタフェースレイヤ
+ *
+ * システムインタフェースレイヤのサービスコールの定義・宣言とマクロな
+ * どの定義を含むヘッダファイル.
+ *
+ * アセンブリ言語のソースファイルからこのファイルをインクルードする時
+ * は,TOPPERS_MACRO_ONLYを定義しておくことで,マクロ定義以外の記述を
+ * 除くことができる.
+ *
+ * このファイルをインクルードする前にインクルードしておくべきファイル
+ * はない.
+ */
+
+#ifndef TOPPERS_SIL_H
+#define TOPPERS_SIL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * TOPPERS共通のデータ型・定数・マクロ
+ */
+#include <t_stddef.h>
+
+/*
+ * ターゲット依存部
+ */
+#include "target_sil.h"
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ * 全割込みロック状態の制御
+ *
+ * SIL_PRE_LOC,SIL_LOC_INT(),SIL_UNL_INT()は,ターゲット依存部で用
+ * 意する.デフォルトの定義は用意していない.
+ */
+
+/*
+ * 微少時間待ち
+ */
+extern void sil_dly_nse(ulong_t dlytim) throw();
+
+/*
+ * エンディアンの反転
+ */
+#ifndef TOPPERS_SIL_REV_ENDIAN_UINT16
+#define TOPPERS_SIL_REV_ENDIAN_UINT16(data) \
+ ((((data) & 0xff) << 8) | (((data) >> 8) & 0xff))
+#endif /* TOPPERS_SIL_REV_ENDIAN_UINT16 */
+
+#ifndef TOPPERS_SIL_REV_ENDIAN_UINT32
+#define TOPPERS_SIL_REV_ENDIAN_UINT32(data) \
+ ((((data) & 0xff) << 24) | (((data) & 0xff00) << 8) \
+ | (((data) >> 8) & 0xff00) | (((data) >> 24) & 0xff))
+#endif /* TOPPERS_SIL_REV_ENDIAN_UINT32 */
+
+/*
+ * メモリ空間アクセス関数
+ */
+#ifndef TOPPERS_OMIT_SIL_ACCESS
+
+/*
+ * 8ビット単位の読出し/書込み
+ */
+#ifdef UINT8_MAX
+
+Inline uint8_t
+sil_reb_mem(void *mem)
+{
+ uint8_t data;
+
+ data = *((volatile uint8_t *) mem);
+ return(data);
+}
+
+Inline void
+sil_wrb_mem(void *mem, uint8_t data)
+{
+ *((volatile uint8_t *) mem) = data;
+}
+
+#endif /* UINT8_MAX */
+
+/*
+ * 16ビット単位の読出し/書込み
+ */
+
+Inline uint16_t
+sil_reh_mem(void *mem)
+{
+ uint16_t data;
+
+ data = *((volatile uint16_t *) mem);
+ return(data);
+}
+
+Inline void
+sil_wrh_mem(void *mem, uint16_t data)
+{
+ *((volatile uint16_t *) mem) = data;
+}
+
+#ifdef SIL_ENDIAN_BIG /* ビッグエンディアンプロセッサ */
+
+#define sil_reh_bem(mem) sil_reh_mem(mem)
+#define sil_wrh_bem(mem, data) sil_wrh_mem(mem, data)
+
+#ifndef TOPPERS_OMIT_SIL_REH_LEM
+
+Inline uint16_t
+sil_reh_lem(void *mem)
+{
+ uint16_t data;
+
+ data = *((volatile uint16_t *) mem);
+ return(TOPPERS_SIL_REV_ENDIAN_UINT16(data));
+}
+
+#endif /* TOPPERS_OMIT_SIL_REH_LEM */
+#ifndef TOPPERS_OMIT_SIL_WRH_LEM
+
+Inline void
+sil_wrh_lem(void *mem, uint16_t data)
+{
+ *((volatile uint16_t *) mem) = TOPPERS_SIL_REV_ENDIAN_UINT16(data);
+}
+
+#endif /* TOPPERS_OMIT_SIL_WRH_LEM */
+#else /* SIL_ENDIAN_BIG */
+#ifdef SIL_ENDIAN_LITTLE /* リトルエンディアンプロセッサ */
+
+#define sil_reh_lem(mem) sil_reh_mem(mem)
+#define sil_wrh_lem(mem, data) sil_wrh_mem(mem, data)
+
+#ifndef TOPPERS_OMIT_SIL_REH_BEM
+
+Inline uint16_t
+sil_reh_bem(void *mem)
+{
+ uint16_t data;
+
+ data = *((volatile uint16_t *) mem);
+ return(TOPPERS_SIL_REV_ENDIAN_UINT16(data));
+}
+
+#endif /* TOPPERS_OMIT_SIL_REH_BEM */
+#ifndef TOPPERS_OMIT_SIL_WRH_BEM
+
+Inline void
+sil_wrh_bem(void *mem, uint16_t data)
+{
+ *((volatile uint16_t *) mem) = TOPPERS_SIL_REV_ENDIAN_UINT16(data);
+}
+
+#endif /* TOPPERS_OMIT_SIL_WRH_BEM */
+#else /* SIL_ENDIAN_LITTLE */
+
+#error Neither SIL_ENDIAN_BIG nor SIL_ENDIAN_LITTLE is defined.
+
+#endif /* SIL_ENDIAN_LITTLE */
+#endif /* SIL_ENDIAN_BIG */
+
+/*
+ * 32ビット単位の読出し/書込み
+ */
+
+Inline uint32_t
+sil_rew_mem(void *mem)
+{
+ uint32_t data;
+
+ data = *((volatile uint32_t *) mem);
+ return(data);
+}
+
+Inline void
+sil_wrw_mem(void *mem, uint32_t data)
+{
+ *((volatile uint32_t *) mem) = data;
+}
+
+#ifdef SIL_ENDIAN_BIG /* ビッグエンディアンプロセッサ */
+
+#define sil_rew_bem(mem) sil_rew_mem(mem)
+#define sil_wrw_bem(mem, data) sil_wrw_mem(mem, data)
+
+#ifndef TOPPERS_OMIT_SIL_REW_LEM
+
+Inline uint32_t
+sil_rew_lem(void *mem)
+{
+ uint32_t data;
+
+ data = *((volatile uint32_t *) mem);
+ return(TOPPERS_SIL_REV_ENDIAN_UINT32(data));
+}
+
+#endif /* TOPPERS_OMIT_SIL_REW_LEM */
+#ifndef TOPPERS_OMIT_SIL_WRW_LEM
+
+Inline void
+sil_wrw_lem(void *mem, uint32_t data)
+{
+ *((volatile uint32_t *) mem) = TOPPERS_SIL_REV_ENDIAN_UINT32(data);
+}
+
+#endif /* TOPPERS_OMIT_SIL_WRW_LEM */
+#else /* SIL_ENDIAN_BIG */ /* リトルエンディアンプロセッサ */
+
+#define sil_rew_lem(mem) sil_rew_mem(mem)
+#define sil_wrw_lem(mem, data) sil_wrw_mem(mem, data)
+
+#ifndef TOPPERS_OMIT_SIL_REW_BEM
+
+Inline uint32_t
+sil_rew_bem(void *mem)
+{
+ uint32_t data;
+
+ data = *((volatile uint32_t *) mem);
+ return(TOPPERS_SIL_REV_ENDIAN_UINT32(data));
+}
+
+#endif /* TOPPERS_OMIT_SIL_REW_BEM */
+#ifndef TOPPERS_OMIT_SIL_WRW_BEM
+
+Inline void
+sil_wrw_bem(void *mem, uint32_t data)
+{
+ *((volatile uint32_t *) mem) = TOPPERS_SIL_REV_ENDIAN_UINT32(data);
+}
+
+#endif /* TOPPERS_OMIT_SIL_WRW_BEM */
+#endif /* SIL_ENDIAN_BIG */
+#endif /* TOPPERS_OMIT_SIL_ACCESS */
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_SIL_H */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: t_stddef.h 1513 2009-04-22 07:35:20Z ertl-hiro $
+ */
+
+/*
+ * TOPPERS共通ヘッダファイル
+ *
+ * TOPPERS関連のすべてのソースファイルでインクルードすべきヘッダファイ
+ * ル.各種のカーネルやソフトウェア部品で共通に用いることを想定してい
+ * る.TOPPERSの各種のカーネルやソフトウェア部品で共通に用いるデータ型,
+ * 定数,マクロの定義などを含む.
+ *
+ * アセンブリ言語のソースファイルからこのファイルをインクルードする時
+ * は,TOPPERS_MACRO_ONLYを定義しておく.これにより,マクロ定義以外を
+ * 除くようになっている.
+ *
+ * このファイルをインクルードする前にインクルードしておくべきファイル
+ * はない.
+ */
+
+#ifndef TOPPERS_T_STDDEF_H
+#define TOPPERS_T_STDDEF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * ターゲット依存部
+ */
+#include "target_stddef.h"
+
+/*
+ * C言語/EC++でthrow()に対処するための定義
+ */
+#if !defined(__cplusplus) || defined(__embedded_cplusplus)
+#define throw()
+#endif
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ * ターゲット依存のデータ型のマクロのデフォルト定義
+ */
+#ifndef TOPPERS_bool
+#define TOPPERS_bool int /* ブール型 */
+#endif /* TOPPERS_bool */
+
+#ifndef TOPPERS_size
+#define TOPPERS_size uintptr_t /* サイズ型 */
+#endif /* TOPPERS_size */
+
+#ifndef TOPPERS_fp
+struct TOPPERS_dummy_t { int TOPPERS_dummy_field; };
+typedef void (*TOPPERS_fp_t)(struct TOPPERS_dummy_t);
+#define TOPPERS_fp TOPPERS_fp_t /* プログラムの起動番地 */
+#endif /* TOPPERS_fp */
+
+/*
+ * 共通データ型
+ */
+typedef TOPPERS_bool bool_t; /* 真偽値 */
+typedef unsigned char char_t; /* 符号無しの文字型 */
+
+typedef signed int int_t; /* 自然なサイズの符号付き整数 */
+typedef unsigned int uint_t; /* 自然なサイズの符号無し整数 */
+
+typedef signed long long_t; /* 長めのサイズの符号付き整数 */
+typedef unsigned long ulong_t; /* 長めのサイズの符号無し整数 */
+
+typedef int_t FN; /* 機能コード */
+typedef int_t ER; /* エラーコード */
+typedef int_t ID; /* オブジェクトのID番号 */
+typedef uint_t ATR; /* オブジェクトの属性 */
+typedef uint_t STAT; /* オブジェクトの状態 */
+typedef uint_t MODE; /* サービスコールの動作モード */
+typedef int_t PRI; /* 優先度 */
+typedef TOPPERS_size SIZE; /* メモリ領域のサイズ */
+
+typedef int_t TMO; /* タイムアウト指定 */
+typedef uint_t RELTIM; /* 相対時間 */
+typedef ulong_t SYSTIM; /* システム時刻 */
+typedef ulong_t SYSUTM; /* 性能評価用システム時刻 */
+
+typedef TOPPERS_fp FP; /* プログラムの起動番地 */
+
+typedef int_t ER_BOOL; /* エラーコードまたは真偽値 */
+typedef int_t ER_ID; /* エラーコードまたはID番号 */
+typedef int_t ER_UINT; /* エラーコードまたは符号無し整数 */
+
+typedef uint32_t ACPTN; /* アクセス許可パターン */
+typedef struct acvct { /* アクセス許可ベクタ */
+ ACPTN acptn1; /* 通常操作1のアクセス許可パターン */
+ ACPTN acptn2; /* 通常操作2のアクセス許可パターン */
+ ACPTN acptn3; /* 管理操作のアクセス許可パターン */
+ ACPTN acptn4; /* 参照操作のアクセス許可パターン */
+} ACVCT;
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ * 整数定数を作るマクロ
+ */
+#ifndef UINT_C
+#define UINT_C(val) (val ## U) /* uint_t型の定数を作るマクロ */
+#endif /* UINT_C */
+
+#ifndef ULONG_C
+#define ULONG_C(val) (val ## UL) /* ulong_t型の定数を作るマクロ */
+#endif /* ULONG_C */
+
+/*
+ * 一般定数
+ */
+#ifndef NULL
+#define NULL 0 /* 無効ポインタ */
+#endif /* NULL */
+
+#ifndef true
+#define true 1 /* 真 */
+#endif /* true */
+
+#ifndef false
+#define false 0 /* 偽 */
+#endif /* false */
+
+#define E_OK 0 /* 正常終了 */
+
+/*
+ * メインエラーコード
+ */
+#define E_SYS (-5) /* システムエラー */
+#define E_NOSPT (-9) /* 未サポート機能 */
+#define E_RSFN (-10) /* 予約機能コード */
+#define E_RSATR (-11) /* 予約属性 */
+#define E_PAR (-17) /* パラメータエラー */
+#define E_ID (-18) /* 不正ID番号 */
+#define E_CTX (-25) /* コンテキストエラー */
+#define E_MACV (-26) /* メモリアクセス違反 */
+#define E_OACV (-27) /* オブジェクトアクセス違反 */
+#define E_ILUSE (-28) /* サービスコール不正使用 */
+#define E_NOMEM (-33) /* メモリ不足 */
+#define E_NOID (-34) /* ID番号不足 */
+#define E_NORES (-35) /* 資源不足 */
+#define E_OBJ (-41) /* オブジェクト状態エラー */
+#define E_NOEXS (-42) /* オブジェクト未生成 */
+#define E_QOVR (-43) /* キューイングオーバーフロー */
+#define E_RLWAI (-49) /* 待ち状態の強制解除 */
+#define E_TMOUT (-50) /* ポーリング失敗またはタイムアウト */
+#define E_DLT (-51) /* 待ちオブジェクトの削除 */
+#define E_CLS (-52) /* 待ちオブジェクトの状態変化 */
+#define E_WBLK (-57) /* ノンブロッキング受付け */
+#define E_BOVR (-58) /* バッファオーバーフロー */
+
+/*
+ * オブジェクト属性
+ */
+#define TA_NULL UINT_C(0) /* オブジェクト属性を指定しない */
+
+/*
+ * タイムアウト指定
+ */
+#define TMO_POL 0 /* ポーリング */
+#define TMO_FEVR (-1) /* 永久待ち */
+#define TMO_NBLK (-2) /* ノンブロッキング */
+
+/*
+ * アクセス許可パターン
+ */
+#define TACP_KERNEL (0U) /* カーネルドメインだけにアクセスを許可 */
+#define TACP_SHARED (~0U) /* すべてのドメインからアクセスを許可 */
+
+/*
+ * 型に関する情報を取り出すためのマクロ
+ */
+#ifndef offsetof
+#define offsetof(structure, field) ((uintptr_t) &(((structure *) 0)->field))
+#endif /* offsetof */
+
+#ifndef alignof
+#define alignof(type) offsetof(struct { char field1; type field2; }, field2)
+#endif /* alignof */
+
+#ifndef ALIGN_TYPE /* アラインメントのチェック */
+#define ALIGN_TYPE(addr, type) \
+ ((((uintptr_t)(addr)) & (alignof(type) - 1)) == 0U)
+#endif /* ALIGN_TYPE */
+
+/*
+ * assertマクロ
+ */
+#undef assert
+#ifndef NDEBUG
+#define assert(exp) ((void)((exp) ? 0 : (TOPPERS_assert_fail(#exp, \
+ __FILE__, __LINE__), TOPPERS_assert_abort(), 0)))
+#else /* NDEBUG */
+#define assert(exp) ((void) 0)
+#endif /* NDEBUG */
+
+#ifdef __cplusplus
+}
+#endif
+
+/*
+ * エラーコード生成・分解マクロ
+ *
+ * 以下のマクロ定義は,符号付き整数が2の補数で表現されており,右シフト
+ * 演算子(>>)が算術シフトされることを仮定している.そうでない開発環
+ * 境では,target_stddef.hでこれらの定義を上書きしなければならない.
+ *
+ * MERCDマクロの定義は,メインエラーコードが負であることを仮定している.
+ * そうでない場合,2つの定義が一致しなくなる.
+ */
+#ifndef ERCD
+#define ERCD(mercd, sercd) \
+ ((ER)((((uint_t) sercd) << 8) | (((uint_t) mercd) & 0xffU)))
+#endif /* ERCD */
+
+#ifndef MERCD
+#ifdef INT8_MAX
+#define MERCD(ercd) ((ER)((int8_t)(ercd)))
+#else /* INT8_MAX */
+#define MERCD(ercd) ((ER)(((uint_t) ercd) | ~0xffU))
+#endif /* INT8_MAX */
+#endif /* MERCD */
+
+#ifndef SERCD
+#define SERCD(ercd) ((ER)((ercd) >> 8))
+#endif /* SERCD */
+
+/*
+ * アクセス許可パターン生成マクロ
+ */
+#define TACP(domid) (1U << ((domid) - 1)) /* domidだけにアクセスを許可 */
+
+/*
+ * 相対時間(RELTIM)に指定できる最大値
+ */
+#if UINT_MAX < LONG_MAX
+#define TMAX_RELTIM ((RELTIM) UINT_MAX)
+#else /* UINT_MAX < LONG_MAX */
+#define TMAX_RELTIM ((RELTIM) LONG_MAX)
+#endif /* UINT_MAX < LONG_MAX */
+
+#endif /* TOPPERS_T_STDDEF_H */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2006 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: t_stdlib.h 264 2007-07-12 08:23:10Z hiro $
+ */
+
+/*
+ * 基本的なライブラリ関数
+ */
+
+#ifndef TOPPERS_T_STDLIB_H
+#define TOPPERS_T_STDLIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * エラーメッセージ文字列を返す関数
+ *
+ * ercdで指定されたエラーコードのメインエラーコードの名称(E_PAR,
+ * E_OBJなど)の文字列を返す関数.
+ */
+extern const char *itron_strerror(ER ercd) throw();
+
+/*
+ * エラーメッセージのログ出力
+ *
+ * サービスコールがエラーを返した場合に,そのファイル名,行番号,メイ
+ * ンエラーコード等を表示するための関数.
+ */
+extern void t_perror(uint_t prio, const char *file, int_t line,
+ const char *expr, ER ercd) throw();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_T_STDLIB_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: t_syslog.h 1176 2008-07-01 10:24:46Z ertl-hiro $
+ */
+
+/*
+ * システムログ出力を行うための定義
+ *
+ * システムログサービスは,システムのログ情報を出力するためのサービス
+ * である.カーネルからのログ情報の出力にも用いるため,内部で待ち状態
+ * にはいることはない.
+ *
+ * ログ情報は,カーネル内のログバッファに書き込むか,低レベルの文字出
+ * 力関数を用いて出力する.どちらを使うかは,拡張サービスコールで切り
+ * 換えることができる.
+ *
+ * ログバッファ領域がオーバフローした場合には,古いログ情報を消して上
+ * 書きする.
+ *
+ * アセンブリ言語のソースファイルからこのファイルをインクルードする時
+ * は,TOPPERS_MACRO_ONLYを定義しておくことで,マクロ定義以外の記述を
+ * 除くことができる.
+ *
+ * このファイルをインクルードする前に,t_stddef.hをインクルードしてお
+ * くことが必要である.
+ */
+
+#ifndef TOPPERS_T_SYSLOG_H
+#define TOPPERS_T_SYSLOG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * ログ情報の種別の定義
+ */
+#define LOG_TYPE_COMMENT UINT_C(0x01) /* コメント */
+#define LOG_TYPE_ASSERT UINT_C(0x02) /* アサーションの失敗 */
+
+#define LOG_TYPE_INH UINT_C(0x11) /* 割込みハンドラ */
+#define LOG_TYPE_ISR UINT_C(0x12) /* 割込みサービスルーチン */
+#define LOG_TYPE_CYC UINT_C(0x13) /* 周期ハンドラ */
+#define LOG_TYPE_ALM UINT_C(0x14) /* アラームハンドラ */
+#define LOG_TYPE_OVR UINT_C(0x15) /* オーバランハンドラ */
+#define LOG_TYPE_EXC UINT_C(0x16) /* CPU例外ハンドラ */
+#define LOG_TYPE_TEX UINT_C(0x17) /* タスク例外処理ルーチン */
+#define LOG_TYPE_TSKSTAT UINT_C(0x18) /* タスク状態変化 */
+#define LOG_TYPE_DSP UINT_C(0x19) /* ディスパッチャ */
+#define LOG_TYPE_SVC UINT_C(0x1a) /* サービスコール */
+
+#define LOG_ENTER UINT_C(0x00) /* 入口/開始 */
+#define LOG_LEAVE UINT_C(0x80) /* 出口/終了 */
+
+/*
+ * ログ情報の重要度の定義
+ */
+#define LOG_EMERG UINT_C(0) /* シャットダウンに値するエラー */
+#define LOG_ALERT UINT_C(1)
+#define LOG_CRIT UINT_C(2)
+#define LOG_ERROR UINT_C(3) /* システムエラー */
+#define LOG_WARNING UINT_C(4) /* 警告メッセージ */
+#define LOG_NOTICE UINT_C(5)
+#define LOG_INFO UINT_C(6)
+#define LOG_DEBUG UINT_C(7) /* デバッグ用メッセージ */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ * ログ情報のデータ構造
+ */
+
+#define TMAX_LOGINFO 6
+
+typedef struct {
+ uint_t logtype; /* ログ情報の種別 */
+ SYSTIM logtim; /* ログ時刻 */
+ intptr_t loginfo[TMAX_LOGINFO]; /* その他のログ情報 */
+} SYSLOG;
+
+/*
+ * ログ情報の重要度のビットマップを作るためのマクロ
+ */
+#define LOG_MASK(prio) (1U << (prio))
+#define LOG_UPTO(prio) ((1U << ((prio) + 1)) - 1)
+
+/*
+ * パケット形式の定義
+ */
+typedef struct t_syslog_rlog {
+ uint_t count; /* ログバッファ中のログの数 */
+ uint_t lost; /* 失われたログの数 */
+ uint_t logmask; /* ログバッファに記録すべき重要度 */
+ uint_t lowmask; /* 低レベル出力すべき重要度 */
+} T_SYSLOG_RLOG;
+
+#ifndef TOPPERS_OMIT_SYSLOG
+
+/*
+ * ログ情報を出力するためのライブラリ関数
+ */
+
+extern ER syslog_wri_log(uint_t prio, const SYSLOG *p_syslog) throw();
+
+Inline void
+_syslog_0(uint_t prio, uint_t type)
+{
+ SYSLOG syslog;
+
+ syslog.logtype = type;
+ (void) syslog_wri_log(prio, &syslog);
+}
+
+Inline void
+_syslog_1(uint_t prio, uint_t type, intptr_t arg1)
+{
+ SYSLOG syslog;
+
+ syslog.logtype = type;
+ syslog.loginfo[0] = arg1;
+ (void) syslog_wri_log(prio, &syslog);
+}
+
+Inline void
+_syslog_2(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2)
+{
+ SYSLOG syslog;
+
+ syslog.logtype = type;
+ syslog.loginfo[0] = arg1;
+ syslog.loginfo[1] = arg2;
+ (void) syslog_wri_log(prio, &syslog);
+}
+
+Inline void
+_syslog_3(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2,
+ intptr_t arg3)
+{
+ SYSLOG syslog;
+
+ syslog.logtype = type;
+ syslog.loginfo[0] = arg1;
+ syslog.loginfo[1] = arg2;
+ syslog.loginfo[2] = arg3;
+ (void) syslog_wri_log(prio, &syslog);
+}
+
+Inline void
+_syslog_4(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2,
+ intptr_t arg3, intptr_t arg4)
+{
+ SYSLOG syslog;
+
+ syslog.logtype = type;
+ syslog.loginfo[0] = arg1;
+ syslog.loginfo[1] = arg2;
+ syslog.loginfo[2] = arg3;
+ syslog.loginfo[3] = arg4;
+ (void) syslog_wri_log(prio, &syslog);
+}
+
+Inline void
+_syslog_5(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2,
+ intptr_t arg3, intptr_t arg4, intptr_t arg5)
+{
+ SYSLOG syslog;
+
+ syslog.logtype = type;
+ syslog.loginfo[0] = arg1;
+ syslog.loginfo[1] = arg2;
+ syslog.loginfo[2] = arg3;
+ syslog.loginfo[3] = arg4;
+ syslog.loginfo[4] = arg5;
+ (void) syslog_wri_log(prio, &syslog);
+}
+
+Inline void
+_syslog_6(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2,
+ intptr_t arg3, intptr_t arg4, intptr_t arg5, intptr_t arg6)
+{
+ SYSLOG syslog;
+
+ syslog.logtype = type;
+ syslog.loginfo[0] = arg1;
+ syslog.loginfo[1] = arg2;
+ syslog.loginfo[2] = arg3;
+ syslog.loginfo[3] = arg4;
+ syslog.loginfo[4] = arg5;
+ syslog.loginfo[5] = arg6;
+ (void) syslog_wri_log(prio, &syslog);
+}
+
+/*
+ * ログ情報(コメント)を出力するためのライブラリ関数(vasyslog.c)
+ */
+extern void syslog(uint_t prio, const char *format, ...) throw();
+
+#else /* TOPPERS_OMIT_SYSLOG */
+
+/*
+ * システムログ出力を抑止する場合
+ */
+
+Inline void
+_syslog_0(uint_t prio, uint_t type)
+{
+}
+
+Inline void
+_syslog_1(uint_t prio, uint_t type, intptr_t arg1)
+{
+}
+
+Inline void
+_syslog_2(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2)
+{
+}
+
+Inline void
+_syslog_3(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2,
+ intptr_t arg3)
+{
+}
+
+Inline void
+_syslog_4(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2,
+ intptr_t arg3, intptr_t arg4)
+{
+}
+
+Inline void
+_syslog_5(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2,
+ intptr_t arg3, intptr_t arg4, intptr_t arg5)
+{
+}
+
+Inline void
+_syslog_6(uint_t prio, uint_t type, intptr_t arg1, intptr_t arg2,
+ intptr_t arg3, intptr_t arg4, intptr_t arg5, intptr_t arg6)
+{
+}
+
+Inline void
+syslog(uint_t prio, const char *format, ...)
+{
+}
+
+#endif /* TOPPERS_OMIT_SYSLOG */
+
+/*
+ * ログ情報(コメント)を出力するためのマクロ
+ *
+ * formatおよび後続の引数から作成したメッセージを,重大度prioでログ情
+ * 報として出力するためのマクロ.arg1〜argnはintptr_t型にキャストする
+ * ため,intptr_t型に型変換できる任意の型でよい.
+ */
+
+#define syslog_0(prio, format) \
+ _syslog_1(prio, LOG_TYPE_COMMENT, (intptr_t) format)
+
+#define syslog_1(prio, format, arg1) \
+ _syslog_2(prio, LOG_TYPE_COMMENT, (intptr_t) format, \
+ (intptr_t)(arg1))
+
+#define syslog_2(prio, format, arg1, arg2) \
+ _syslog_3(prio, LOG_TYPE_COMMENT, (intptr_t) format, \
+ (intptr_t)(arg1), (intptr_t)(arg2))
+
+#define syslog_3(prio, format, arg1, arg2, arg3) \
+ _syslog_4(prio, LOG_TYPE_COMMENT, (intptr_t) format, \
+ (intptr_t)(arg1), (intptr_t)(arg2), (intptr_t)(arg3))
+
+#define syslog_4(prio, format, arg1, arg2, arg3, arg4) \
+ _syslog_5(prio, LOG_TYPE_COMMENT, (intptr_t) format, \
+ (intptr_t)(arg1), (intptr_t)(arg2), (intptr_t)(arg3), \
+ (intptr_t)(arg4))
+
+#define syslog_5(prio, format, arg1, arg2, arg3, arg4, arg5) \
+ _syslog_6(prio, LOG_TYPE_COMMENT, (intptr_t) format, \
+ (intptr_t)(arg1), (intptr_t)(arg2), (intptr_t)(arg3), \
+ (intptr_t)(arg4), (intptr_t)(arg5))
+
+/*
+ * ログ情報(アサーションの失敗)を出力するためのマクロ
+ */
+#ifndef TOPPERS_assert_fail
+#define TOPPERS_assert_fail(exp, file, line) \
+ _syslog_3(LOG_EMERG, LOG_TYPE_ASSERT, (intptr_t)(file), \
+ (intptr_t)(line), (intptr_t)(exp))
+#endif /* TOPPERS_assert_fail */
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_T_SYSLOG_H */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2005-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_lib.h 1652 2009-10-10 18:01:05Z ertl-hiro $
+ */
+
+/*
+ * テストプログラム用ライブラリ
+ */
+
+#include <t_stddef.h>
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 自己診断関数の型
+ */
+typedef ER (*BIT_FUNC)(void);
+
+/*
+ * 自己診断関数の設定
+ */
+extern void set_bit_func(BIT_FUNC bit_func);
+
+/*
+ * システムログの出力処理
+ */
+extern void syslog_flush(void);
+
+/*
+ * テストプログラムの終了
+ */
+extern void test_finish(void);
+
+/*
+ * チェックポイント
+ */
+extern void check_point(uint_t count);
+
+/*
+ * 完了チェックポイント
+ */
+extern void check_finish(uint_t count);
+
+/*
+ * 条件チェック
+ */
+extern void _check_assert(const char *expr, const char *file, int_t line);
+#define check_assert(exp) \
+ ((void)(!(exp) ? (_check_assert(#exp, __FILE__, __LINE__), 0) : 0))
+
+/*
+ * エラーコードチェック
+ */
+extern void _check_ercd(ER ercd, const char *file, int_t line);
+#define check_ercd(ercd, expected_ercd) \
+ ((void)((ercd) != (expected_ercd) ? \
+ (_check_ercd(ercd, __FILE__, __LINE__), 0) : 0))
+
+/*
+ * システム状態のチェック
+ */
+Inline void
+check_state(bool_t ctx, bool_t loc, PRI ipm, bool_t dsp,
+ bool_t dpn, bool_t tex)
+{
+ PRI intpri;
+ ER ercd;
+
+ check_assert(sns_ctx() == ctx);
+ check_assert(sns_loc() == loc);
+ if (!loc) {
+ /*
+ * IPMのチェックは,CPUロック解除状態の場合にのみ行う.
+ */
+ ercd = get_ipm(&intpri);
+ check_ercd(ercd, E_OK);
+ check_assert(intpri == ipm);
+ }
+ check_assert(sns_dsp() == dsp);
+ check_assert(sns_dpn() == dpn);
+ check_assert(sns_tex() == tex);
+}
+
+/*
+ * システム状態のチェック(非タスクコンテキスト用)
+ */
+Inline void
+check_state_i(bool_t ctx, bool_t loc, bool_t dsp, bool_t dpn, bool_t tex)
+{
+ check_assert(sns_ctx() == ctx);
+ check_assert(sns_loc() == loc);
+ check_assert(sns_dsp() == dsp);
+ check_assert(sns_dpn() == dpn);
+ check_assert(sns_tex() == tex);
+}
--- /dev/null
+#
+# TOPPERS/ASP Kernel
+# Toyohashi Open Platform for Embedded Real-Time Systems/
+# Advanced Standard Profile Kernel
+#
+# Copyright (C) 2003 by Embedded and Real-Time Systems Laboratory
+# Toyohashi Univ. of Technology, JAPAN
+# Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
+# Graduate School of Information Science, Nagoya Univ., JAPAN
+#
+# 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+# スコード中に含まれていること.
+# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+# の無保証規定を掲載すること.
+# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+# と.
+# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+# 作権表示,この利用条件および下記の無保証規定を掲載すること.
+# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+# 報告すること.
+# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+# 免責すること.
+#
+# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+# の責任を負わない.
+#
+# @(#) $Id: Makefile.kernel 877 2008-04-11 10:36:50Z hiro $
+#
+
+#
+# カーネルのファイル構成の定義
+#
+
+#
+# 1つのソースファイルから複数のオブジェクトファイルを生成するように作
+# 成されたソースファイルのリスト
+#
+KERNEL_FCSRCS = startup.c task.c wait.c time_event.c \
+ task_manage.c task_refer.c task_sync.c task_except.c \
+ semaphore.c eventflag.c dataqueue.c pridataq.c mailbox.c \
+ mempfix.c time_manage.c cyclic.c alarm.c \
+ sys_manage.c interrupt.c exception.c \
+ task_info.c
+
+#
+# 各ソースファイルから生成されるオブジェクトファイルのリスト
+#
+startup = sta_ker.o ext_ker.o
+
+task = tskini.o tsksched.o tskrun.o tsknrun.o \
+ tskdmt.o tskact.o tskpri.o tskrot.o tsktex.o
+
+wait = waimake.o waicmp.o waitmo.o waitmook.o \
+ wairel.o wobjwai.o wobjwaitmo.o iniwque.o
+
+time_event = tmeini.o tmeup.o tmedown.o tmeins.o tmedel.o tmeltim.o sigtim.o
+
+task_manage = act_tsk.o iact_tsk.o can_act.o ext_tsk.o ter_tsk.o \
+ chg_pri.o get_pri.o get_inf.o
+
+task_refer = ref_tsk.o
+
+task_info = inf_tsk.o
+
+task_sync = slp_tsk.o tslp_tsk.o wup_tsk.o iwup_tsk.o can_wup.o \
+ rel_wai.o irel_wai.o sus_tsk.o rsm_tsk.o dly_tsk.o
+
+task_except = ras_tex.o iras_tex.o dis_tex.o ena_tex.o sns_tex.o ref_tex.o
+
+semaphore = semini.o sig_sem.o isig_sem.o \
+ wai_sem.o pol_sem.o twai_sem.o ini_sem.o ref_sem.o
+
+eventflag = flgini.o flgcnd.o set_flg.o iset_flg.o clr_flg.o \
+ wai_flg.o pol_flg.o twai_flg.o ini_flg.o ref_flg.o
+
+dataqueue = dtqini.o dtqenq.o dtqfenq.o dtqdeq.o dtqsnd.o dtqfsnd.o dtqrcv.o \
+ snd_dtq.o psnd_dtq.o ipsnd_dtq.o tsnd_dtq.o fsnd_dtq.o ifsnd_dtq.o \
+ rcv_dtq.o prcv_dtq.o trcv_dtq.o ini_dtq.o ref_dtq.o
+
+pridataq = pdqini.o pdqenq.o pdqdeq.o pdqsnd.o pdqrcv.o \
+ snd_pdq.o psnd_pdq.o ipsnd_pdq.o tsnd_pdq.o \
+ rcv_pdq.o prcv_pdq.o trcv_pdq.o ini_pdq.o ref_pdq.o
+
+mailbox = mbxini.o snd_mbx.o rcv_mbx.o prcv_mbx.o trcv_mbx.o \
+ ini_mbx.o ref_mbx.o
+
+mempfix = mpfini.o mpfget.o get_mpf.o pget_mpf.o tget_mpf.o \
+ rel_mpf.o ini_mpf.o ref_mpf.o
+
+time_manage = get_tim.o get_utm.o
+
+cyclic = cycini.o sta_cyc.o stp_cyc.o ref_cyc.o cyccal.o
+
+alarm = almini.o sta_alm.o ista_alm.o stp_alm.o istp_alm.o ref_alm.o almcal.o
+
+sys_manage = rot_rdq.o irot_rdq.o get_tid.o iget_tid.o \
+ loc_cpu.o iloc_cpu.o unl_cpu.o iunl_cpu.o dis_dsp.o ena_dsp.o \
+ sns_ctx.o sns_loc.o sns_dsp.o sns_dpn.o sns_ker.o
+
+interrupt = intini.o dis_int.o ena_int.o chg_ipm.o get_ipm.o
+
+exception = excini.o xsns_dpn.o xsns_xpn.o
+
+#
+# 生成されるオブジェクトファイルの依存関係の定義
+#
+$(startup) $(startup:.o=.s) $(startup:.o=.d): startup.c
+$(task) $(task:.o=.s) $(task:.o=.d): task.c
+$(wait) $(wait:.o=.s) $(wait:.o=.d): wait.c
+$(time_event) $(time_event:.o=.s) $(time_event:.o=.d): time_event.c
+$(task_manage) $(task_manage:.o=.s) $(task_manage:.o=.d): task_manage.c
+$(task_refer) $(task_refer:.o=.s) $(task_refer:.o=.d): task_refer.c
+$(task_info) $(task_info:.o=.s) $(task_info:.o=.d): task_info.c
+$(task_sync) $(task_sync:.o=.s) $(task_sync:.o=.d): task_sync.c
+$(task_except) $(task_except:.o=.s) $(task_except:.o=.d): task_except.c
+$(semaphore) $(semaphore:.o=.s) $(semaphore:.o=.d): semaphore.c
+$(eventflag) $(eventflag:.o=.s) $(eventflag:.o=.d): eventflag.c
+$(dataqueue) $(dataqueue:.o=.s) $(dataqueue:.o=.d): dataqueue.c
+$(pridataq) $(pridataq:.o=.s) $(pridataq:.o=.d): pridataq.c
+$(mailbox) $(mailbox:.o=.s) $(mailbox:.o=.d): mailbox.c
+$(mempfix) $(mempfix:.o=.s) $(mempfix:.o=.d): mempfix.c
+$(time_manage) $(time_manage:.o=.s) $(time_manage:.o=.d): time_manage.c
+$(cyclic) $(cyclic:.o=.s) $(cyclic:.o=.d): cyclic.c
+$(alarm) $(alarm:.o=.s) $(alarm:.o=.d): alarm.c
+$(sys_manage) $(sys_manage:.o=.s) $(sys_manage:.o=.d): sys_manage.c
+$(interrupt) $(interrupt:.o=.s) $(interrupt:.o=.d): interrupt.c
+$(exception) $(exception:.o=.s) $(exception:.o=.d): exception.c
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: alarm.c 748 2008-03-07 17:18:06Z hiro $
+ */
+
+/*
+ * アラームハンドラ機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "alarm.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_ALM_ENTER
+#define LOG_ALM_ENTER(p_almcb)
+#endif /* LOG_ALM_ENTER */
+
+#ifndef LOG_ALM_LEAVE
+#define LOG_ALM_LEAVE(p_almcb)
+#endif /* LOG_ALM_LEAVE */
+
+#ifndef LOG_STA_ALM_ENTER
+#define LOG_STA_ALM_ENTER(almid, almtim)
+#endif /* LOG_STA_ALM_ENTER */
+
+#ifndef LOG_STA_ALM_LEAVE
+#define LOG_STA_ALM_LEAVE(ercd)
+#endif /* LOG_STA_ALM_LEAVE */
+
+#ifndef LOG_ISTA_ALM_ENTER
+#define LOG_ISTA_ALM_ENTER(almid, almtim)
+#endif /* LOG_ISTA_ALM_ENTER */
+
+#ifndef LOG_ISTA_ALM_LEAVE
+#define LOG_ISTA_ALM_LEAVE(ercd)
+#endif /* LOG_ISTA_ALM_LEAVE */
+
+#ifndef LOG_STP_ALM_ENTER
+#define LOG_STP_ALM_ENTER(almid)
+#endif /* LOG_STP_ALM_ENTER */
+
+#ifndef LOG_STP_ALM_LEAVE
+#define LOG_STP_ALM_LEAVE(ercd)
+#endif /* LOG_STP_ALM_LEAVE */
+
+#ifndef LOG_ISTP_ALM_ENTER
+#define LOG_ISTP_ALM_ENTER(almid)
+#endif /* LOG_ISTP_ALM_ENTER */
+
+#ifndef LOG_ISTP_ALM_LEAVE
+#define LOG_ISTP_ALM_LEAVE(ercd)
+#endif /* LOG_ISTP_ALM_LEAVE */
+
+#ifndef LOG_REF_ALM_ENTER
+#define LOG_REF_ALM_ENTER(almid, pk_ralm)
+#endif /* LOG_REF_ALM_ENTER */
+
+#ifndef LOG_REF_ALM_LEAVE
+#define LOG_REF_ALM_LEAVE(ercd, pk_ralm)
+#endif /* LOG_REF_ALM_LEAVE */
+
+/*
+ * アラームハンドラの数
+ */
+#define tnum_alm ((uint_t)(tmax_almid - TMIN_ALMID + 1))
+
+/*
+ * アラームハンドラIDからアラームハンドラ管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_ALM(almid) ((uint_t)((almid) - TMIN_ALMID))
+#define get_almcb(almid) (&(almcb_table[INDEX_ALM(almid)]))
+
+/*
+ * アラームハンドラ機能の初期化
+ */
+#ifdef TOPPERS_almini
+
+void
+initialize_alarm(void)
+{
+ uint_t i;
+ ALMCB *p_almcb;
+
+ for (p_almcb = almcb_table, i = 0; i < tnum_alm; p_almcb++, i++) {
+ p_almcb->p_alminib = &(alminib_table[i]);
+ p_almcb->almsta = false;
+ }
+}
+
+#endif /* TOPPERS_almini */
+
+/*
+ * アラームハンドラの動作開始
+ */
+#ifdef TOPPERS_sta_alm
+
+ER
+sta_alm(ID almid, RELTIM almtim)
+{
+ ALMCB *p_almcb;
+ ER ercd;
+
+ LOG_STA_ALM_ENTER(almid, almtim);
+ CHECK_TSKCTX_UNL();
+ CHECK_ALMID(almid);
+ CHECK_PAR(almtim <= TMAX_RELTIM);
+ p_almcb = get_almcb(almid);
+
+ t_lock_cpu();
+ if (p_almcb->almsta) {
+ tmevtb_dequeue(&(p_almcb->tmevtb));
+ }
+ else {
+ p_almcb->almsta = true;
+ }
+ tmevtb_enqueue(&(p_almcb->tmevtb), almtim,
+ (CBACK) call_almhdr, (void *) p_almcb);
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_STA_ALM_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_sta_alm */
+
+/*
+ * アラームハンドラの動作開始(非タスクコンテキスト用)
+ */
+#ifdef TOPPERS_ista_alm
+
+ER
+ista_alm(ID almid, RELTIM almtim)
+{
+ ALMCB *p_almcb;
+ ER ercd;
+
+ LOG_ISTA_ALM_ENTER(almid, almtim);
+ CHECK_INTCTX_UNL();
+ CHECK_ALMID(almid);
+ CHECK_PAR(almtim <= TMAX_RELTIM);
+ p_almcb = get_almcb(almid);
+
+ i_lock_cpu();
+ if (p_almcb->almsta) {
+ tmevtb_dequeue(&(p_almcb->tmevtb));
+ }
+ else {
+ p_almcb->almsta = true;
+ }
+ tmevtb_enqueue(&(p_almcb->tmevtb), almtim,
+ (CBACK) call_almhdr, (void *) p_almcb);
+ ercd = E_OK;
+ i_unlock_cpu();
+
+ error_exit:
+ LOG_ISTA_ALM_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ista_alm */
+
+/*
+ * アラームハンドラの動作停止
+ */
+#ifdef TOPPERS_stp_alm
+
+ER
+stp_alm(ID almid)
+{
+ ALMCB *p_almcb;
+ ER ercd;
+
+ LOG_STP_ALM_ENTER(almid);
+ CHECK_TSKCTX_UNL();
+ CHECK_ALMID(almid);
+ p_almcb = get_almcb(almid);
+
+ t_lock_cpu();
+ if (p_almcb->almsta) {
+ p_almcb->almsta = false;
+ tmevtb_dequeue(&(p_almcb->tmevtb));
+ }
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_STP_ALM_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_stp_alm */
+
+/*
+ * アラームハンドラの動作停止(非タスクコンテキスト用)
+ */
+#ifdef TOPPERS_istp_alm
+
+ER
+istp_alm(ID almid)
+{
+ ALMCB *p_almcb;
+ ER ercd;
+
+ LOG_ISTP_ALM_ENTER(almid);
+ CHECK_INTCTX_UNL();
+ CHECK_ALMID(almid);
+ p_almcb = get_almcb(almid);
+
+ i_lock_cpu();
+ if (p_almcb->almsta) {
+ p_almcb->almsta = false;
+ tmevtb_dequeue(&(p_almcb->tmevtb));
+ }
+ ercd = E_OK;
+ i_unlock_cpu();
+
+ error_exit:
+ LOG_ISTP_ALM_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_istp_alm */
+
+/*
+ * アラームハンドラの状態参照
+ */
+#ifdef TOPPERS_ref_alm
+
+ER
+ref_alm(ID almid, T_RALM *pk_ralm)
+{
+ ALMCB *p_almcb;
+ ER ercd;
+
+ LOG_REF_ALM_ENTER(almid, pk_ralm);
+ CHECK_TSKCTX_UNL();
+ CHECK_ALMID(almid);
+ p_almcb = get_almcb(almid);
+
+ t_lock_cpu();
+ if (p_almcb->almsta) {
+ pk_ralm->almstat = TALM_STA;
+ pk_ralm->lefttim = tmevt_lefttim(&(p_almcb->tmevtb));
+ }
+ else {
+ pk_ralm->almstat = TALM_STP;
+ }
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_REF_ALM_LEAVE(ercd, pk_ralm);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ref_alm */
+
+/*
+ * アラームハンドラ起動ルーチン
+ */
+#ifdef TOPPERS_almcal
+
+void
+call_almhdr(ALMCB *p_almcb)
+{
+ PRI saved_ipm;
+
+ /*
+ * アラームハンドラを停止状態にする.
+ */
+ p_almcb->almsta = false;
+
+ /*
+ * アラームハンドラを,CPUロック解除状態で呼び出す.
+ */
+ saved_ipm = i_get_ipm();
+ i_unlock_cpu();
+
+ LOG_ALM_ENTER(p_almcb);
+ (*((ALMHDR)(p_almcb->p_alminib->almhdr)))(p_almcb->p_alminib->exinf);
+ LOG_ALM_LEAVE(p_almcb);
+
+ if (!i_sense_lock()) {
+ i_lock_cpu();
+ }
+ i_set_ipm(saved_ipm);
+}
+
+#endif /* TOPPERS_almcal */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005,2006 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: alarm.h 748 2008-03-07 17:18:06Z hiro $
+ */
+
+/*
+ * アラームハンドラ機能
+ */
+
+#ifndef TOPPERS_ALARM_H
+#define TOPPERS_ALARM_H
+
+#include "time_event.h"
+
+/*
+ * アラームハンドラ初期化ブロック
+ */
+typedef struct alarm_handler_initialization_block {
+ ATR almatr; /* アラームハンドラ属性 */
+ intptr_t exinf; /* アラームハンドラの拡張情報 */
+ ALMHDR almhdr; /* アラームハンドラの起動番地 */
+} ALMINIB;
+
+/*
+ * アラームハンドラ管理ブロック
+ */
+typedef struct alarm_handler_control_block {
+ const ALMINIB *p_alminib; /* 初期化ブロックへのポインタ */
+ bool_t almsta; /* アラームハンドラの動作状態 */
+ TMEVTB tmevtb; /* タイムイベントブロック */
+} ALMCB;
+
+/*
+ * アラームハンドラIDの最大値(kernel_cfg.c)
+ */
+extern const ID tmax_almid;
+
+/*
+ * アラームハンドラ初期化ブロックのエリア(kernel_cfg.c)
+ */
+extern const ALMINIB alminib_table[];
+
+/*
+ * アラームハンドラ管理ブロックのエリア(kernel_cfg.c)
+ */
+extern ALMCB almcb_table[];
+
+/*
+ * アラームハンドラ機能の初期化
+ */
+extern void initialize_alarm(void);
+
+/*
+ * アラームハンドラ起動ルーチン
+ */
+extern void call_almhdr(ALMCB *p_almcb);
+
+#endif /* TOPPERS_ALARM_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: allfunc.h 879 2008-04-11 10:38:16Z hiro $
+ */
+
+/*
+ * すべての関数をコンパイルするための定義
+ */
+
+#ifndef TOPPERS_ALLFUNC_H
+#define TOPPERS_ALLFUNC_H
+
+/* startup.c */
+#define TOPPERS_sta_ker
+#define TOPPERS_ext_ker
+
+/* task.c */
+#define TOPPERS_tskini
+#define TOPPERS_tsksched
+#define TOPPERS_tskrun
+#define TOPPERS_tsknrun
+#define TOPPERS_tskdmt
+#define TOPPERS_tskact
+#define TOPPERS_tskpri
+#define TOPPERS_tskrot
+#define TOPPERS_tsktex
+
+/* wait.c */
+#define TOPPERS_waimake
+#define TOPPERS_waicmp
+#define TOPPERS_waitmo
+#define TOPPERS_waitmook
+#define TOPPERS_wairel
+#define TOPPERS_wobjwai
+#define TOPPERS_wobjwaitmo
+#define TOPPERS_iniwque
+
+/* time_event.c */
+#define TOPPERS_tmeini
+#define TOPPERS_tmeup
+#define TOPPERS_tmedown
+#define TOPPERS_tmeins
+#define TOPPERS_tmedel
+#define TOPPERS_tmeltim
+#define TOPPERS_sigtim
+
+/* task_manage.c */
+#define TOPPERS_act_tsk
+#define TOPPERS_iact_tsk
+#define TOPPERS_can_act
+#define TOPPERS_ext_tsk
+#define TOPPERS_ter_tsk
+#define TOPPERS_chg_pri
+#define TOPPERS_get_pri
+#define TOPPERS_get_inf
+
+/* task_refer.c */
+#define TOPPERS_ref_tsk
+
+/* task_info.c */
+#define TOPPERS_inf_tsk
+
+/* task_sync.c */
+#define TOPPERS_slp_tsk
+#define TOPPERS_tslp_tsk
+#define TOPPERS_wup_tsk
+#define TOPPERS_iwup_tsk
+#define TOPPERS_can_wup
+#define TOPPERS_rel_wai
+#define TOPPERS_irel_wai
+#define TOPPERS_sus_tsk
+#define TOPPERS_rsm_tsk
+#define TOPPERS_dly_tsk
+
+/* task_except.c */
+#define TOPPERS_ras_tex
+#define TOPPERS_iras_tex
+#define TOPPERS_dis_tex
+#define TOPPERS_ena_tex
+#define TOPPERS_sns_tex
+#define TOPPERS_ref_tex
+
+/* semaphore.c */
+#define TOPPERS_semini
+#define TOPPERS_sig_sem
+#define TOPPERS_isig_sem
+#define TOPPERS_wai_sem
+#define TOPPERS_pol_sem
+#define TOPPERS_twai_sem
+#define TOPPERS_ini_sem
+#define TOPPERS_ref_sem
+
+/* eventflag.c */
+#define TOPPERS_flgini
+#define TOPPERS_flgcnd
+#define TOPPERS_set_flg
+#define TOPPERS_iset_flg
+#define TOPPERS_clr_flg
+#define TOPPERS_wai_flg
+#define TOPPERS_pol_flg
+#define TOPPERS_twai_flg
+#define TOPPERS_ini_flg
+#define TOPPERS_ref_flg
+
+/* dataqueue.c */
+#define TOPPERS_dtqini
+#define TOPPERS_dtqenq
+#define TOPPERS_dtqfenq
+#define TOPPERS_dtqdeq
+#define TOPPERS_dtqsnd
+#define TOPPERS_dtqfsnd
+#define TOPPERS_dtqrcv
+#define TOPPERS_snd_dtq
+#define TOPPERS_psnd_dtq
+#define TOPPERS_ipsnd_dtq
+#define TOPPERS_tsnd_dtq
+#define TOPPERS_fsnd_dtq
+#define TOPPERS_ifsnd_dtq
+#define TOPPERS_rcv_dtq
+#define TOPPERS_prcv_dtq
+#define TOPPERS_trcv_dtq
+#define TOPPERS_ini_dtq
+#define TOPPERS_ref_dtq
+
+/* pridataq.c */
+#define TOPPERS_pdqini
+#define TOPPERS_pdqenq
+#define TOPPERS_pdqdeq
+#define TOPPERS_pdqsnd
+#define TOPPERS_pdqrcv
+#define TOPPERS_snd_pdq
+#define TOPPERS_psnd_pdq
+#define TOPPERS_ipsnd_pdq
+#define TOPPERS_tsnd_pdq
+#define TOPPERS_rcv_pdq
+#define TOPPERS_prcv_pdq
+#define TOPPERS_trcv_pdq
+#define TOPPERS_ini_pdq
+#define TOPPERS_ref_pdq
+
+/* mailbox.c */
+#define TOPPERS_mbxini
+#define TOPPERS_snd_mbx
+#define TOPPERS_rcv_mbx
+#define TOPPERS_prcv_mbx
+#define TOPPERS_trcv_mbx
+#define TOPPERS_ini_mbx
+#define TOPPERS_ref_mbx
+
+/* mempfix.c */
+#define TOPPERS_mpfini
+#define TOPPERS_mpfget
+#define TOPPERS_get_mpf
+#define TOPPERS_pget_mpf
+#define TOPPERS_tget_mpf
+#define TOPPERS_rel_mpf
+#define TOPPERS_ini_mpf
+#define TOPPERS_ref_mpf
+
+/* time_manage.c */
+#define TOPPERS_get_tim
+#define TOPPERS_get_utm
+
+/* cyclic.c */
+#define TOPPERS_cycini
+#define TOPPERS_sta_cyc
+#define TOPPERS_stp_cyc
+#define TOPPERS_ref_cyc
+#define TOPPERS_cyccal
+
+/* alarm.c */
+#define TOPPERS_almini
+#define TOPPERS_sta_alm
+#define TOPPERS_ista_alm
+#define TOPPERS_stp_alm
+#define TOPPERS_istp_alm
+#define TOPPERS_ref_alm
+#define TOPPERS_almcal
+
+/* sys_manage.c */
+#define TOPPERS_rot_rdq
+#define TOPPERS_irot_rdq
+#define TOPPERS_get_tid
+#define TOPPERS_iget_tid
+#define TOPPERS_loc_cpu
+#define TOPPERS_iloc_cpu
+#define TOPPERS_unl_cpu
+#define TOPPERS_iunl_cpu
+#define TOPPERS_dis_dsp
+#define TOPPERS_ena_dsp
+#define TOPPERS_sns_ctx
+#define TOPPERS_sns_loc
+#define TOPPERS_sns_dsp
+#define TOPPERS_sns_dpn
+#define TOPPERS_sns_ker
+
+/* interrupt.c */
+#define TOPPERS_intini
+#define TOPPERS_dis_int
+#define TOPPERS_ena_int
+#define TOPPERS_chg_ipm
+#define TOPPERS_get_ipm
+
+/* exception.c */
+#define TOPPERS_excini
+#define TOPPERS_xsns_dpn
+#define TOPPERS_xsns_xpn
+
+#endif /* TOPPERS_ALLFUNC_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: check.h 1139 2008-06-19 07:03:34Z ertl-hiro $
+ */
+
+/*
+ * エラーチェック用マクロ
+ */
+
+#ifndef TOPPERS_CHECK_H
+#define TOPPERS_CHECK_H
+
+/*
+ * 優先度の範囲の判定
+ */
+#define VALID_TPRI(tpri) (TMIN_TPRI <= (tpri) && (tpri) <= TMAX_TPRI)
+
+#ifndef VALID_INTPRI_CHGIPM
+#define VALID_INTPRI_CHGIPM(intpri) \
+ (TMIN_INTPRI <= (intpri) && (intpri) <= TIPM_ENAALL)
+#endif /* VALID_INTPRI_CHGIPM */
+
+/*
+ * タスク優先度のチェック(E_PAR)
+ */
+#define CHECK_TPRI(tpri) { \
+ if (!VALID_TPRI(tpri)) { \
+ ercd = E_PAR; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_TPRI_INI(tpri) { \
+ if (!(VALID_TPRI(tpri) || (tpri) == TPRI_INI)) { \
+ ercd = E_PAR; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_TPRI_SELF(tpri) { \
+ if (!(VALID_TPRI(tpri) || (tpri) == TPRI_SELF)) { \
+ ercd = E_PAR; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * タイムアウト指定値のチェック(E_PAR)
+ */
+#define CHECK_TMOUT(tmout) { \
+ if (!(TMO_FEVR <= (tmout))) { \
+ ercd = E_PAR; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * 割込み優先度のチェック(E_PAR)
+ */
+#define CHECK_INTPRI_CHGIPM(inttpri) { \
+ if (!VALID_INTPRI_CHGIPM(intpri)) { \
+ ercd = E_PAR; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * 割込み番号のチェック(E_PAR)
+ */
+#define CHECK_INTNO_DISINT(intno) { \
+ if (!VALID_INTNO_DISINT(intno)) { \
+ ercd = E_PAR; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * その他のパラメータエラーのチェック(E_PAR)
+ */
+#define CHECK_PAR(exp) { \
+ if (!(exp)) { \
+ ercd = E_PAR; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * オブジェクトIDの範囲の判定
+ */
+#define VALID_TSKID(tskid) (TMIN_TSKID <= (tskid) && (tskid) <= tmax_tskid)
+#define VALID_SEMID(semid) (TMIN_SEMID <= (semid) && (semid) <= tmax_semid)
+#define VALID_FLGID(flgid) (TMIN_FLGID <= (flgid) && (flgid) <= tmax_flgid)
+#define VALID_DTQID(dtqid) (TMIN_DTQID <= (dtqid) && (dtqid) <= tmax_dtqid)
+#define VALID_PDQID(pdqid) (TMIN_PDQID <= (pdqid) && (pdqid) <= tmax_pdqid)
+#define VALID_MBXID(mbxid) (TMIN_MBXID <= (mbxid) && (mbxid) <= tmax_mbxid)
+#define VALID_MPFID(mpfid) (TMIN_MPFID <= (mpfid) && (mpfid) <= tmax_mpfid)
+#define VALID_CYCID(cycid) (TMIN_CYCID <= (cycid) && (cycid) <= tmax_cycid)
+#define VALID_ALMID(almid) (TMIN_ALMID <= (almid) && (almid) <= tmax_almid)
+
+/*
+ * オブジェクトIDのチェック(E_ID)
+ */
+#define CHECK_TSKID(tskid) { \
+ if (!VALID_TSKID(tskid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_TSKID_SELF(tskid) { \
+ if (!(VALID_TSKID(tskid) || (tskid) == TSK_SELF)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_SEMID(semid) { \
+ if (!VALID_SEMID(semid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_FLGID(flgid) { \
+ if (!VALID_FLGID(flgid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_DTQID(dtqid) { \
+ if (!VALID_DTQID(dtqid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_PDQID(pdqid) { \
+ if (!VALID_PDQID(pdqid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_MBXID(mbxid) { \
+ if (!VALID_MBXID(mbxid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_MPFID(mpfid) { \
+ if (!VALID_MPFID(mpfid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_CYCID(cycid) { \
+ if (!VALID_CYCID(cycid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_ALMID(almid) { \
+ if (!VALID_ALMID(almid)) { \
+ ercd = E_ID; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * 呼出しコンテキストのチェック(E_CTX)
+ */
+#define CHECK_TSKCTX() { \
+ if (sense_context()) { \
+ ercd = E_CTX; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_INTCTX() { \
+ if (!sense_context()) { \
+ ercd = E_CTX; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * 呼出しコンテキストとCPUロック状態のチェック(E_CTX)
+ */
+#define CHECK_TSKCTX_UNL() { \
+ if (sense_context() || t_sense_lock()) { \
+ ercd = E_CTX; \
+ goto error_exit; \
+ } \
+}
+
+#define CHECK_INTCTX_UNL() { \
+ if (!sense_context() || i_sense_lock()) { \
+ ercd = E_CTX; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * ディスパッチ保留状態でないかのチェック(E_CTX)
+ */
+#define CHECK_DISPATCH() { \
+ if (sense_context() || t_sense_lock() || !dspflg) { \
+ ercd = E_CTX; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * その他のコンテキストエラーのチェック(E_CTX)
+ */
+#define CHECK_CTX(exp) { \
+ if (!(exp)) { \
+ ercd = E_CTX; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * 自タスクを指定していないかのチェック(E_ILUSE)
+ */
+#define CHECK_NONSELF(p_tcb) { \
+ if ((p_tcb) == p_runtsk) { \
+ ercd = E_ILUSE; \
+ goto error_exit; \
+ } \
+}
+
+/*
+ * その他の不正使用エラーのチェック(E_ILUSE)
+ */
+#define CHECK_ILUSE(exp) { \
+ if (!(exp)) { \
+ ercd = E_ILUSE; \
+ goto error_exit; \
+ } \
+}
+
+#endif /* TOPPERS_CHECK_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: cyclic.c 1358 2008-09-21 09:16:57Z ertl-hiro $
+ */
+
+/*
+ * 周期ハンドラ機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "cyclic.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_CYC_ENTER
+#define LOG_CYC_ENTER(p_cyccb)
+#endif /* LOG_CYC_ENTER */
+
+#ifndef LOG_CYC_LEAVE
+#define LOG_CYC_LEAVE(p_cyccb)
+#endif /* LOG_CYC_LEAVE */
+
+#ifndef LOG_STA_CYC_ENTER
+#define LOG_STA_CYC_ENTER(cycid)
+#endif /* LOG_STA_CYC_ENTER */
+
+#ifndef LOG_STA_CYC_LEAVE
+#define LOG_STA_CYC_LEAVE(ercd)
+#endif /* LOG_STA_CYC_LEAVE */
+
+#ifndef LOG_STP_CYC_ENTER
+#define LOG_STP_CYC_ENTER(cycid)
+#endif /* LOG_STP_CYC_ENTER */
+
+#ifndef LOG_STP_CYC_LEAVE
+#define LOG_STP_CYC_LEAVE(ercd)
+#endif /* LOG_STP_CYC_LEAVE */
+
+#ifndef LOG_REF_CYC_ENTER
+#define LOG_REF_CYC_ENTER(cycid, pk_rcyc)
+#endif /* LOG_REF_CYC_ENTER */
+
+#ifndef LOG_REF_CYC_LEAVE
+#define LOG_REF_CYC_LEAVE(ercd, pk_rcyc)
+#endif /* LOG_REF_CYC_LEAVE */
+
+/*
+ * 周期ハンドラの数
+ */
+#define tnum_cyc ((uint_t)(tmax_cycid - TMIN_CYCID + 1))
+
+/*
+ * 周期ハンドラIDから周期ハンドラ管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_CYC(cycid) ((uint_t)((cycid) - TMIN_CYCID))
+#define get_cyccb(cycid) (&(cyccb_table[INDEX_CYC(cycid)]))
+
+/*
+ * 周期ハンドラ起動のためのタイムイベントブロックの登録
+ */
+Inline void
+tmevtb_enqueue_cyc(CYCCB *p_cyccb, EVTTIM evttim)
+{
+ tmevtb_enqueue_evttim(&(p_cyccb->tmevtb), evttim,
+ (CBACK) call_cychdr, (void *) p_cyccb);
+ p_cyccb->evttim = evttim;
+}
+
+/*
+ * 周期ハンドラ機能の初期化
+ */
+#ifdef TOPPERS_cycini
+
+void
+initialize_cyclic(void)
+{
+ uint_t i;
+ CYCCB *p_cyccb;
+
+ for (p_cyccb = cyccb_table, i = 0; i < tnum_cyc; p_cyccb++, i++) {
+ p_cyccb->p_cycinib = &(cycinib_table[i]);
+ if ((p_cyccb->p_cycinib->cycatr & TA_STA) != 0U) {
+ p_cyccb->cycsta = true;
+ tmevtb_enqueue_cyc(p_cyccb, (EVTTIM)(p_cyccb->p_cycinib->cycphs));
+ }
+ else {
+ p_cyccb->cycsta = false;
+ }
+ }
+}
+
+#endif /* TOPPERS_cycini */
+
+/*
+ * 周期ハンドラの動作開始
+ */
+#ifdef TOPPERS_sta_cyc
+
+ER
+sta_cyc(ID cycid)
+{
+ CYCCB *p_cyccb;
+ ER ercd;
+
+ LOG_STA_CYC_ENTER(cycid);
+ CHECK_TSKCTX_UNL();
+ CHECK_CYCID(cycid);
+ p_cyccb = get_cyccb(cycid);
+
+ t_lock_cpu();
+ if (p_cyccb->cycsta) {
+ tmevtb_dequeue(&(p_cyccb->tmevtb));
+ }
+ else {
+ p_cyccb->cycsta = true;
+ }
+ tmevtb_enqueue_cyc(p_cyccb, base_time + p_cyccb->p_cycinib->cycphs);
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_STA_CYC_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_sta_cyc */
+
+/*
+ * 周期ハンドラの動作停止
+ */
+#ifdef TOPPERS_stp_cyc
+
+ER
+stp_cyc(ID cycid)
+{
+ CYCCB *p_cyccb;
+ ER ercd;
+
+ LOG_STP_CYC_ENTER(cycid);
+ CHECK_TSKCTX_UNL();
+ CHECK_CYCID(cycid);
+ p_cyccb = get_cyccb(cycid);
+
+ t_lock_cpu();
+ if (p_cyccb->cycsta) {
+ p_cyccb->cycsta = false;
+ tmevtb_dequeue(&(p_cyccb->tmevtb));
+ }
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_STP_CYC_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_stp_cyc */
+
+/*
+ * 周期ハンドラの状態参照
+ */
+#ifdef TOPPERS_ref_cyc
+
+ER
+ref_cyc(ID cycid, T_RCYC *pk_rcyc)
+{
+ CYCCB *p_cyccb;
+ ER ercd;
+
+ LOG_REF_CYC_ENTER(cycid, pk_rcyc);
+ CHECK_TSKCTX_UNL();
+ CHECK_CYCID(cycid);
+ p_cyccb = get_cyccb(cycid);
+
+ t_lock_cpu();
+ if (p_cyccb->cycsta) {
+ pk_rcyc->cycstat = TCYC_STA;
+ pk_rcyc->lefttim = tmevt_lefttim(&(p_cyccb->tmevtb));
+ }
+ else {
+ pk_rcyc->cycstat = TCYC_STP;
+ }
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_REF_CYC_LEAVE(ercd, pk_rcyc);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ref_cyc */
+
+/*
+ * 周期ハンドラ起動ルーチン
+ */
+#ifdef TOPPERS_cyccal
+
+void
+call_cychdr(CYCCB *p_cyccb)
+{
+ PRI saved_ipm;
+
+ /*
+ * 次回の起動のためのタイムイベントブロックを登録する.
+ *
+ * 同じタイムティックで周期ハンドラを再度起動すべき場合には,この
+ * 関数からsignal_timeに戻った後に,再度この関数が呼ばれることにな
+ * る.
+ */
+ tmevtb_enqueue_cyc(p_cyccb, p_cyccb->evttim + p_cyccb->p_cycinib->cyctim);
+
+ /*
+ * 周期ハンドラを,CPUロック解除状態で呼び出す.
+ */
+ saved_ipm = i_get_ipm();
+ i_unlock_cpu();
+
+ LOG_CYC_ENTER(p_cyccb);
+ (*((CYCHDR)(p_cyccb->p_cycinib->cychdr)))(p_cyccb->p_cycinib->exinf);
+ LOG_CYC_LEAVE(p_cyccb);
+
+ if (!i_sense_lock()) {
+ i_lock_cpu();
+ }
+ i_set_ipm(saved_ipm);
+}
+
+#endif /* TOPPERS_cyccal */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005,2006 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: cyclic.h 748 2008-03-07 17:18:06Z hiro $
+ */
+
+/*
+ * 周期ハンドラ機能
+ */
+
+#ifndef TOPPERS_CYCLIC_H
+#define TOPPERS_CYCLIC_H
+
+#include "time_event.h"
+
+/*
+ * 周期ハンドラ初期化ブロック
+ */
+typedef struct cyclic_handler_initialization_block {
+ ATR cycatr; /* 周期ハンドラ属性 */
+ intptr_t exinf; /* 周期ハンドラの拡張情報 */
+ CYCHDR cychdr; /* 周期ハンドラの起動番地 */
+ RELTIM cyctim; /* 周期ハンドラの起動周期 */
+ RELTIM cycphs; /* 周期ハンドラの起動位相 */
+} CYCINIB;
+
+/*
+ * 周期ハンドラ管理ブロック
+ */
+typedef struct cyclic_handler_control_block {
+ const CYCINIB *p_cycinib; /* 初期化ブロックへのポインタ */
+ bool_t cycsta; /* 周期ハンドラの動作状態 */
+ EVTTIM evttim; /* 次に周期ハンドラを起動する時刻 */
+ TMEVTB tmevtb; /* タイムイベントブロック */
+} CYCCB;
+
+/*
+ * 周期ハンドラIDの最大値(kernel_cfg.c)
+ */
+extern const ID tmax_cycid;
+
+/*
+ * 周期ハンドラ初期化ブロックのエリア(kernel_cfg.c)
+ */
+extern const CYCINIB cycinib_table[];
+
+/*
+ * 周期ハンドラ管理ブロックのエリア(kernel_cfg.c)
+ */
+extern CYCCB cyccb_table[];
+
+/*
+ * 周期ハンドラ機能の初期化
+ */
+extern void initialize_cyclic(void);
+
+/*
+ * 周期ハンドラ起動ルーチン
+ */
+extern void call_cychdr(CYCCB *p_cyccb);
+
+#endif /* TOPPERS_CYCLIC_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: dataqueue.c 1774 2010-03-19 12:45:46Z ertl-hiro $
+ */
+
+/*
+ * データキュー機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "dataqueue.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_SND_DTQ_ENTER
+#define LOG_SND_DTQ_ENTER(dtqid, data)
+#endif /* LOG_SND_DTQ_ENTER */
+
+#ifndef LOG_SND_DTQ_LEAVE
+#define LOG_SND_DTQ_LEAVE(ercd)
+#endif /* LOG_SND_DTQ_LEAVE */
+
+#ifndef LOG_PSND_DTQ_ENTER
+#define LOG_PSND_DTQ_ENTER(dtqid, data)
+#endif /* LOG_PSND_DTQ_ENTER */
+
+#ifndef LOG_PSND_DTQ_LEAVE
+#define LOG_PSND_DTQ_LEAVE(ercd)
+#endif /* LOG_PSND_DTQ_LEAVE */
+
+#ifndef LOG_IPSND_DTQ_ENTER
+#define LOG_IPSND_DTQ_ENTER(dtqid, data)
+#endif /* LOG_IPSND_DTQ_ENTER */
+
+#ifndef LOG_IPSND_DTQ_LEAVE
+#define LOG_IPSND_DTQ_LEAVE(ercd)
+#endif /* LOG_IPSND_DTQ_LEAVE */
+
+#ifndef LOG_TSND_DTQ_ENTER
+#define LOG_TSND_DTQ_ENTER(dtqid, data, tmout)
+#endif /* LOG_TSND_DTQ_ENTER */
+
+#ifndef LOG_TSND_DTQ_LEAVE
+#define LOG_TSND_DTQ_LEAVE(ercd)
+#endif /* LOG_TSND_DTQ_LEAVE */
+
+#ifndef LOG_FSND_DTQ_ENTER
+#define LOG_FSND_DTQ_ENTER(dtqid, data)
+#endif /* LOG_FSND_DTQ_ENTER */
+
+#ifndef LOG_FSND_DTQ_LEAVE
+#define LOG_FSND_DTQ_LEAVE(ercd)
+#endif /* LOG_FSND_DTQ_LEAVE */
+
+#ifndef LOG_IFSND_DTQ_ENTER
+#define LOG_IFSND_DTQ_ENTER(dtqid, data)
+#endif /* LOG_IFSND_DTQ_ENTER */
+
+#ifndef LOG_IFSND_DTQ_LEAVE
+#define LOG_IFSND_DTQ_LEAVE(ercd)
+#endif /* LOG_IFSND_DTQ_LEAVE */
+
+#ifndef LOG_RCV_DTQ_ENTER
+#define LOG_RCV_DTQ_ENTER(dtqid, p_data)
+#endif /* LOG_RCV_DTQ_ENTER */
+
+#ifndef LOG_RCV_DTQ_LEAVE
+#define LOG_RCV_DTQ_LEAVE(ercd, data)
+#endif /* LOG_RCV_DTQ_LEAVE */
+
+#ifndef LOG_PRCV_DTQ_ENTER
+#define LOG_PRCV_DTQ_ENTER(dtqid, p_data)
+#endif /* LOG_PRCV_DTQ_ENTER */
+
+#ifndef LOG_PRCV_DTQ_LEAVE
+#define LOG_PRCV_DTQ_LEAVE(ercd, data)
+#endif /* LOG_PRCV_DTQ_LEAVE */
+
+#ifndef LOG_TRCV_DTQ_ENTER
+#define LOG_TRCV_DTQ_ENTER(dtqid, p_data, tmout)
+#endif /* LOG_TRCV_DTQ_ENTER */
+
+#ifndef LOG_TRCV_DTQ_LEAVE
+#define LOG_TRCV_DTQ_LEAVE(ercd, data)
+#endif /* LOG_TRCV_DTQ_LEAVE */
+
+#ifndef LOG_INI_DTQ_ENTER
+#define LOG_INI_DTQ_ENTER(dtqid)
+#endif /* LOG_INI_DTQ_ENTER */
+
+#ifndef LOG_INI_DTQ_LEAVE
+#define LOG_INI_DTQ_LEAVE(ercd)
+#endif /* LOG_INI_DTQ_LEAVE */
+
+#ifndef LOG_REF_DTQ_ENTER
+#define LOG_REF_DTQ_ENTER(dtqid, pk_rdtq)
+#endif /* LOG_REF_DTQ_ENTER */
+
+#ifndef LOG_REF_DTQ_LEAVE
+#define LOG_REF_DTQ_LEAVE(ercd, pk_rdtq)
+#endif /* LOG_REF_DTQ_LEAVE */
+
+/*
+ * データキューの数
+ */
+#define tnum_dtq ((uint_t)(tmax_dtqid - TMIN_DTQID + 1))
+
+/*
+ * データキューIDからデータキュー管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_DTQ(dtqid) ((uint_t)((dtqid) - TMIN_DTQID))
+#define get_dtqcb(dtqid) (&(dtqcb_table[INDEX_DTQ(dtqid)]))
+
+/*
+ * データキュー機能の初期化
+ */
+#ifdef TOPPERS_dtqini
+
+void
+initialize_dataqueue(void)
+{
+ uint_t i;
+ DTQCB *p_dtqcb;
+
+ for (p_dtqcb = dtqcb_table, i = 0; i < tnum_dtq; p_dtqcb++, i++) {
+ queue_initialize(&(p_dtqcb->swait_queue));
+ p_dtqcb->p_dtqinib = &(dtqinib_table[i]);
+ queue_initialize(&(p_dtqcb->rwait_queue));
+ p_dtqcb->count = 0U;
+ p_dtqcb->head = 0U;
+ p_dtqcb->tail = 0U;
+ }
+}
+
+#endif /* TOPPERS_dtqini */
+
+/*
+ * データキュー管理領域へのデータの格納
+ */
+#ifdef TOPPERS_dtqenq
+
+void
+enqueue_data(DTQCB *p_dtqcb, intptr_t data)
+{
+ *(p_dtqcb->p_dtqinib->p_dtqmb + p_dtqcb->tail) = data;
+ p_dtqcb->count++;
+ p_dtqcb->tail++;
+ if (p_dtqcb->tail >= p_dtqcb->p_dtqinib->dtqcnt) {
+ p_dtqcb->tail = 0U;
+ }
+}
+
+#endif /* TOPPERS_dtqenq */
+
+/*
+ * データキュー管理領域へのデータの強制格納
+ */
+#ifdef TOPPERS_dtqfenq
+
+void
+force_enqueue_data(DTQCB *p_dtqcb, intptr_t data)
+{
+ *(p_dtqcb->p_dtqinib->p_dtqmb + p_dtqcb->tail) = data;
+ p_dtqcb->tail++;
+ if (p_dtqcb->tail >= p_dtqcb->p_dtqinib->dtqcnt) {
+ p_dtqcb->tail = 0U;
+ }
+ if (p_dtqcb->count < p_dtqcb->p_dtqinib->dtqcnt) {
+ p_dtqcb->count++;
+ }
+ else {
+ p_dtqcb->head = p_dtqcb->tail;
+ }
+}
+
+#endif /* TOPPERS_dtqfenq */
+
+/*
+ * データキュー管理領域からのデータの取出し
+ */
+#ifdef TOPPERS_dtqdeq
+
+void
+dequeue_data(DTQCB *p_dtqcb, intptr_t *p_data)
+{
+ *p_data = *(p_dtqcb->p_dtqinib->p_dtqmb + p_dtqcb->head);
+ p_dtqcb->count--;
+ p_dtqcb->head++;
+ if (p_dtqcb->head >= p_dtqcb->p_dtqinib->dtqcnt) {
+ p_dtqcb->head = 0U;
+ }
+}
+
+#endif /* TOPPERS_dtqdeq */
+
+/*
+ * データキューへのデータ送信
+ */
+#ifdef TOPPERS_dtqsnd
+
+bool_t
+send_data(DTQCB *p_dtqcb, intptr_t data, bool_t *p_reqdsp)
+{
+ TCB *p_tcb;
+
+ if (!queue_empty(&(p_dtqcb->rwait_queue))) {
+ p_tcb = (TCB *) queue_delete_next(&(p_dtqcb->rwait_queue));
+ ((WINFO_DTQ *)(p_tcb->p_winfo))->data = data;
+ *p_reqdsp = wait_complete(p_tcb);
+ return(true);
+ }
+ else if (p_dtqcb->count < p_dtqcb->p_dtqinib->dtqcnt) {
+ enqueue_data(p_dtqcb, data);
+ *p_reqdsp = false;
+ return(true);
+ }
+ else {
+ return(false);
+ }
+}
+
+#endif /* TOPPERS_dtqsnd */
+
+/*
+ * データキューへのデータ強制送信
+ */
+#ifdef TOPPERS_dtqfsnd
+
+bool_t
+force_send_data(DTQCB *p_dtqcb, intptr_t data)
+{
+ TCB *p_tcb;
+
+ if (!queue_empty(&(p_dtqcb->rwait_queue))) {
+ p_tcb = (TCB *) queue_delete_next(&(p_dtqcb->rwait_queue));
+ ((WINFO_DTQ *)(p_tcb->p_winfo))->data = data;
+ return(wait_complete(p_tcb));
+ }
+ else {
+ force_enqueue_data(p_dtqcb, data);
+ return(false);
+ }
+}
+
+#endif /* TOPPERS_dtqfsnd */
+
+/*
+ * 送信待ちキューの先頭タスクからのデータ受信
+ */
+#ifdef TOPPERS_dtqrcv
+
+bool_t
+receive_data(DTQCB *p_dtqcb, intptr_t *p_data, bool_t *p_reqdsp)
+{
+ TCB *p_tcb;
+ intptr_t data;
+
+ if (p_dtqcb->count > 0U) {
+ dequeue_data(p_dtqcb, p_data);
+ if (!queue_empty(&(p_dtqcb->swait_queue))) {
+ p_tcb = (TCB *) queue_delete_next(&(p_dtqcb->swait_queue));
+ data = ((WINFO_DTQ *)(p_tcb->p_winfo))->data;
+ enqueue_data(p_dtqcb, data);
+ *p_reqdsp = wait_complete(p_tcb);
+ }
+ else {
+ *p_reqdsp = false;
+ }
+ return(true);
+ }
+ else if (!queue_empty(&(p_dtqcb->swait_queue))) {
+ p_tcb = (TCB *) queue_delete_next(&(p_dtqcb->swait_queue));
+ *p_data = ((WINFO_DTQ *)(p_tcb->p_winfo))->data;
+ *p_reqdsp = wait_complete(p_tcb);
+ return(true);
+ }
+ else {
+ return(false);
+ }
+}
+
+#endif /* TOPPERS_dtqrcv */
+
+/*
+ * データキューへの送信
+ */
+#ifdef TOPPERS_snd_dtq
+
+ER
+snd_dtq(ID dtqid, intptr_t data)
+{
+ DTQCB *p_dtqcb;
+ WINFO_DTQ winfo_dtq;
+ bool_t reqdsp;
+ ER ercd;
+
+ LOG_SND_DTQ_ENTER(dtqid, data);
+ CHECK_DISPATCH();
+ CHECK_DTQID(dtqid);
+ p_dtqcb = get_dtqcb(dtqid);
+
+ t_lock_cpu();
+ if (send_data(p_dtqcb, data, &reqdsp)) {
+ if (reqdsp) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ else {
+ winfo_dtq.data = data;
+ p_runtsk->tstat = (TS_WAITING | TS_WAIT_SDTQ);
+ wobj_make_wait((WOBJCB *) p_dtqcb, (WINFO_WOBJ *) &winfo_dtq);
+ dispatch();
+ ercd = winfo_dtq.winfo.wercd;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_SND_DTQ_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_snd_dtq */
+
+/*
+ * データキューへの送信(ポーリング)
+ */
+#ifdef TOPPERS_psnd_dtq
+
+ER
+psnd_dtq(ID dtqid, intptr_t data)
+{
+ DTQCB *p_dtqcb;
+ bool_t reqdsp;
+ ER ercd;
+
+ LOG_PSND_DTQ_ENTER(dtqid, data);
+ CHECK_TSKCTX_UNL();
+ CHECK_DTQID(dtqid);
+ p_dtqcb = get_dtqcb(dtqid);
+
+ t_lock_cpu();
+ if (send_data(p_dtqcb, data, &reqdsp)) {
+ if (reqdsp) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ else {
+ ercd = E_TMOUT;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_PSND_DTQ_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_psnd_dtq */
+
+/*
+ * データキューへの送信(ポーリング,非タスクコンテキスト用)
+ */
+#ifdef TOPPERS_ipsnd_dtq
+
+ER
+ipsnd_dtq(ID dtqid, intptr_t data)
+{
+ DTQCB *p_dtqcb;
+ bool_t reqdsp;
+ ER ercd;
+
+ LOG_IPSND_DTQ_ENTER(dtqid, data);
+ CHECK_INTCTX_UNL();
+ CHECK_DTQID(dtqid);
+ p_dtqcb = get_dtqcb(dtqid);
+
+ i_lock_cpu();
+ if (send_data(p_dtqcb, data, &reqdsp)) {
+ if (reqdsp) {
+ reqflg = true;
+ }
+ ercd = E_OK;
+ }
+ else {
+ ercd = E_TMOUT;
+ }
+ i_unlock_cpu();
+
+ error_exit:
+ LOG_IPSND_DTQ_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ipsnd_dtq */
+
+/*
+ * データキューへの送信(タイムアウトあり)
+ */
+#ifdef TOPPERS_tsnd_dtq
+
+ER
+tsnd_dtq(ID dtqid, intptr_t data, TMO tmout)
+{
+ DTQCB *p_dtqcb;
+ WINFO_DTQ winfo_dtq;
+ TMEVTB tmevtb;
+ bool_t reqdsp;
+ ER ercd;
+
+ LOG_TSND_DTQ_ENTER(dtqid, data, tmout);
+ CHECK_DISPATCH();
+ CHECK_DTQID(dtqid);
+ CHECK_TMOUT(tmout);
+ p_dtqcb = get_dtqcb(dtqid);
+
+ t_lock_cpu();
+ if (send_data(p_dtqcb, data, &reqdsp)) {
+ if (reqdsp) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ else if (tmout == TMO_POL) {
+ ercd = E_TMOUT;
+ }
+ else {
+ winfo_dtq.data = data;
+ p_runtsk->tstat = (TS_WAITING | TS_WAIT_SDTQ);
+ wobj_make_wait_tmout((WOBJCB *) p_dtqcb, (WINFO_WOBJ *) &winfo_dtq,
+ &tmevtb, tmout);
+ dispatch();
+ ercd = winfo_dtq.winfo.wercd;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_TSND_DTQ_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_tsnd_dtq */
+
+/*
+ * データキューへの強制送信
+ */
+#ifdef TOPPERS_fsnd_dtq
+
+ER
+fsnd_dtq(ID dtqid, intptr_t data)
+{
+ DTQCB *p_dtqcb;
+ ER ercd;
+
+ LOG_FSND_DTQ_ENTER(dtqid, data);
+ CHECK_TSKCTX_UNL();
+ CHECK_DTQID(dtqid);
+ p_dtqcb = get_dtqcb(dtqid);
+ CHECK_ILUSE(p_dtqcb->p_dtqinib->dtqcnt > 0U);
+
+ t_lock_cpu();
+ if (force_send_data(p_dtqcb, data)) {
+ dispatch();
+ }
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_FSND_DTQ_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_fsnd_dtq */
+
+/*
+ * データキューへの強制送信(非タスクコンテキスト用)
+ */
+#ifdef TOPPERS_ifsnd_dtq
+
+ER
+ifsnd_dtq(ID dtqid, intptr_t data)
+{
+ DTQCB *p_dtqcb;
+ ER ercd;
+
+ LOG_IFSND_DTQ_ENTER(dtqid, data);
+ CHECK_INTCTX_UNL();
+ CHECK_DTQID(dtqid);
+ p_dtqcb = get_dtqcb(dtqid);
+ CHECK_ILUSE(p_dtqcb->p_dtqinib->dtqcnt > 0U);
+
+ i_lock_cpu();
+ if (force_send_data(p_dtqcb, data)) {
+ reqflg = true;
+ }
+ ercd = E_OK;
+ i_unlock_cpu();
+
+ error_exit:
+ LOG_IFSND_DTQ_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ifsnd_dtq */
+
+/*
+ * データキューからの受信
+ */
+#ifdef TOPPERS_rcv_dtq
+
+ER
+rcv_dtq(ID dtqid, intptr_t *p_data)
+{
+ DTQCB *p_dtqcb;
+ WINFO_DTQ winfo_dtq;
+ bool_t reqdsp;
+ ER ercd;
+
+ LOG_RCV_DTQ_ENTER(dtqid, p_data);
+ CHECK_DISPATCH();
+ CHECK_DTQID(dtqid);
+ p_dtqcb = get_dtqcb(dtqid);
+
+ t_lock_cpu();
+ if (receive_data(p_dtqcb, p_data, &reqdsp)) {
+ if (reqdsp) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ else {
+ p_runtsk->tstat = (TS_WAITING | TS_WAIT_RDTQ);
+ make_wait(&(winfo_dtq.winfo));
+ queue_insert_prev(&(p_dtqcb->rwait_queue), &(p_runtsk->task_queue));
+ winfo_dtq.p_dtqcb = p_dtqcb;
+ LOG_TSKSTAT(p_runtsk);
+ dispatch();
+ ercd = winfo_dtq.winfo.wercd;
+ if (ercd == E_OK) {
+ *p_data = winfo_dtq.data;
+ }
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_RCV_DTQ_LEAVE(ercd, *p_data);
+ return(ercd);
+}
+
+#endif /* TOPPERS_rcv_dtq */
+
+/*
+ * データキューからの受信(ポーリング)
+ */
+#ifdef TOPPERS_prcv_dtq
+
+ER
+prcv_dtq(ID dtqid, intptr_t *p_data)
+{
+ DTQCB *p_dtqcb;
+ bool_t reqdsp;
+ ER ercd;
+
+ LOG_PRCV_DTQ_ENTER(dtqid, p_data);
+ CHECK_TSKCTX_UNL();
+ CHECK_DTQID(dtqid);
+ p_dtqcb = get_dtqcb(dtqid);
+
+ t_lock_cpu();
+ if (receive_data(p_dtqcb, p_data, &reqdsp)) {
+ if (reqdsp) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ else {
+ ercd = E_TMOUT;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_PRCV_DTQ_LEAVE(ercd, *p_data);
+ return(ercd);
+}
+
+#endif /* TOPPERS_prcv_dtq */
+
+/*
+ * データキューからの受信(タイムアウトあり)
+ */
+#ifdef TOPPERS_trcv_dtq
+
+ER
+trcv_dtq(ID dtqid, intptr_t *p_data, TMO tmout)
+{
+ DTQCB *p_dtqcb;
+ WINFO_DTQ winfo_dtq;
+ TMEVTB tmevtb;
+ bool_t reqdsp;
+ ER ercd;
+
+ LOG_TRCV_DTQ_ENTER(dtqid, p_data, tmout);
+ CHECK_DISPATCH();
+ CHECK_DTQID(dtqid);
+ CHECK_TMOUT(tmout);
+ p_dtqcb = get_dtqcb(dtqid);
+
+ t_lock_cpu();
+ if (receive_data(p_dtqcb, p_data, &reqdsp)) {
+ if (reqdsp) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ else if (tmout == TMO_POL) {
+ ercd = E_TMOUT;
+ }
+ else {
+ p_runtsk->tstat = (TS_WAITING | TS_WAIT_RDTQ);
+ make_wait_tmout(&(winfo_dtq.winfo), &tmevtb, tmout);
+ queue_insert_prev(&(p_dtqcb->rwait_queue), &(p_runtsk->task_queue));
+ winfo_dtq.p_dtqcb = p_dtqcb;
+ LOG_TSKSTAT(p_runtsk);
+ dispatch();
+ ercd = winfo_dtq.winfo.wercd;
+ if (ercd == E_OK) {
+ *p_data = winfo_dtq.data;
+ }
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_TRCV_DTQ_LEAVE(ercd, *p_data);
+ return(ercd);
+}
+
+#endif /* TOPPERS_trcv_dtq */
+
+/*
+ * データキューの再初期化
+ */
+#ifdef TOPPERS_ini_dtq
+
+ER
+ini_dtq(ID dtqid)
+{
+ DTQCB *p_dtqcb;
+ bool_t dspreq;
+ ER ercd;
+
+ LOG_INI_DTQ_ENTER(dtqid);
+ CHECK_TSKCTX_UNL();
+ CHECK_DTQID(dtqid);
+ p_dtqcb = get_dtqcb(dtqid);
+
+ t_lock_cpu();
+ dspreq = init_wait_queue(&(p_dtqcb->swait_queue));
+ if (init_wait_queue(&(p_dtqcb->rwait_queue))) {
+ dspreq = true;
+ };
+ p_dtqcb->count = 0U;
+ p_dtqcb->head = 0U;
+ p_dtqcb->tail = 0U;
+ if (dspreq) {
+ dispatch();
+ }
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_INI_DTQ_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ini_dtq */
+
+/*
+ * データキューの状態参照
+ */
+#ifdef TOPPERS_ref_dtq
+
+ER
+ref_dtq(ID dtqid, T_RDTQ *pk_rdtq)
+{
+ DTQCB *p_dtqcb;
+ ER ercd;
+
+ LOG_REF_DTQ_ENTER(dtqid, pk_rdtq);
+ CHECK_TSKCTX_UNL();
+ CHECK_DTQID(dtqid);
+ p_dtqcb = get_dtqcb(dtqid);
+
+ t_lock_cpu();
+ pk_rdtq->stskid = wait_tskid(&(p_dtqcb->swait_queue));
+ pk_rdtq->rtskid = wait_tskid(&(p_dtqcb->rwait_queue));
+ pk_rdtq->sdtqcnt = p_dtqcb->count;
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_REF_DTQ_LEAVE(ercd, pk_rdtq);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ref_dtq */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: dataqueue.h 748 2008-03-07 17:18:06Z hiro $
+ */
+
+/*
+ * データキュー機能
+ */
+
+#ifndef TOPPERS_DATAQUEUE_H
+#define TOPPERS_DATAQUEUE_H
+
+#include <queue.h>
+
+/*
+ * データキュー初期化ブロック
+ *
+ * この構造体は,同期・通信オブジェクトの初期化ブロックの共通部分
+ * (WOBJINIB)を拡張(オブジェクト指向言語の継承に相当)したもので,
+ * 最初のフィールドが共通になっている.
+ */
+typedef struct dataqueue_initialization_block {
+ ATR dtqatr; /* データキュー属性 */
+ uint_t dtqcnt; /* データキューの容量 */
+ intptr_t *p_dtqmb; /* データキュー管理領域の先頭番地 */
+} DTQINIB;
+
+/*
+ * データキュー管理ブロック
+ *
+ * この構造体は,同期・通信オブジェクトの管理ブロックの共通部分(WOBJCB)
+ * を拡張(オブジェクト指向言語の継承に相当)したもので,最初の2つの
+ * フィールドが共通になっている.
+ */
+typedef struct dataqueue_control_block {
+ QUEUE swait_queue; /* データキュー送信待ちキュー */
+ const DTQINIB *p_dtqinib; /* 初期化ブロックへのポインタ */
+ QUEUE rwait_queue; /* データキュー受信待ちキュー */
+ uint_t count; /* データキュー中のデータの数 */
+ uint_t head; /* 最初のデータの格納場所 */
+ uint_t tail; /* 最後のデータの格納場所の次 */
+} DTQCB;
+
+/*
+ * データキュー待ち情報ブロックの定義
+ *
+ * この構造体は,同期・通信オブジェクトの待ち情報ブロックの共通部分
+ * (WINFO_WOBJ)を拡張(オブジェクト指向言語の継承に相当)したもので,
+ * 最初の2つのフィールドが共通になっている.
+ * データキューへの送信待ちとデータキューからの受信待ちで,同じ待ち情
+ * 報ブロックを使う.
+ */
+typedef struct dataqueue_waiting_information {
+ WINFO winfo; /* 標準の待ち情報ブロック */
+ DTQCB *p_dtqcb; /* 待っているデータキューの管理ブロック */
+ intptr_t data; /* 送受信データ */
+} WINFO_DTQ;
+
+/*
+ * データキューIDの最大値(kernel_cfg.c)
+ */
+extern const ID tmax_dtqid;
+
+/*
+ * データキュー初期化ブロックのエリア(kernel_cfg.c)
+ */
+extern const DTQINIB dtqinib_table[];
+
+/*
+ * データキュー管理ブロックのエリア(kernel_cfg.c)
+ */
+extern DTQCB dtqcb_table[];
+
+/*
+ * データキュー管理ブロックからデータキューIDを取り出すためのマクロ
+ */
+#define DTQID(p_dtqcb) ((ID)(((p_dtqcb) - dtqcb_table) + TMIN_DTQID))
+
+/*
+ * データキュー機能の初期化
+ */
+extern void initialize_dataqueue(void);
+
+/*
+ * データキュー管理領域へのデータの格納
+ */
+extern void enqueue_data(DTQCB *p_dtqcb, intptr_t data);
+
+/*
+ * データキュー管理領域へのデータの強制格納
+ */
+extern void force_enqueue_data(DTQCB *p_dtqcb, intptr_t data);
+
+/*
+ * データキュー管理領域からのデータの取出し
+ */
+extern void dequeue_data(DTQCB *p_dtqcb, intptr_t *p_data);
+
+/*
+ * データキューへのデータ送信
+ */
+extern bool_t send_data(DTQCB *p_dtqcb, intptr_t data, bool_t *p_reqdsp);
+
+/*
+ * データキューへのデータ強制送信
+ */
+extern bool_t force_send_data(DTQCB *p_dtqcb, intptr_t data);
+
+/*
+ * データキューからのデータ受信
+ */
+extern bool_t receive_data(DTQCB *p_dtqcb, intptr_t *p_data,
+ bool_t *p_reqdsp);
+
+#endif /* TOPPERS_DATAQUEUE_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: eventflag.c 748 2008-03-07 17:18:06Z hiro $
+ */
+
+/*
+ * イベントフラグ機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "eventflag.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_SET_FLG_ENTER
+#define LOG_SET_FLG_ENTER(flgid, setptn)
+#endif /* LOG_SET_FLG_ENTER */
+
+#ifndef LOG_SET_FLG_LEAVE
+#define LOG_SET_FLG_LEAVE(ercd)
+#endif /* LOG_SET_FLG_LEAVE */
+
+#ifndef LOG_ISET_FLG_ENTER
+#define LOG_ISET_FLG_ENTER(flgid, setptn)
+#endif /* LOG_ISET_FLG_ENTER */
+
+#ifndef LOG_ISET_FLG_LEAVE
+#define LOG_ISET_FLG_LEAVE(ercd)
+#endif /* LOG_ISET_FLG_LEAVE */
+
+#ifndef LOG_CLR_FLG_ENTER
+#define LOG_CLR_FLG_ENTER(flgid, clrptn)
+#endif /* LOG_CLR_FLG_ENTER */
+
+#ifndef LOG_CLR_FLG_LEAVE
+#define LOG_CLR_FLG_LEAVE(ercd)
+#endif /* LOG_CLR_FLG_LEAVE */
+
+#ifndef LOG_WAI_FLG_ENTER
+#define LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn)
+#endif /* LOG_WAI_FLG_ENTER */
+
+#ifndef LOG_WAI_FLG_LEAVE
+#define LOG_WAI_FLG_LEAVE(ercd, flgptn)
+#endif /* LOG_WAI_FLG_LEAVE */
+
+#ifndef LOG_POL_FLG_ENTER
+#define LOG_POL_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn)
+#endif /* LOG_POL_FLG_ENTER */
+
+#ifndef LOG_POL_FLG_LEAVE
+#define LOG_POL_FLG_LEAVE(ercd, flgptn)
+#endif /* LOG_POL_FLG_LEAVE */
+
+#ifndef LOG_TWAI_FLG_ENTER
+#define LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout)
+#endif /* LOG_TWAI_FLG_ENTER */
+
+#ifndef LOG_TWAI_FLG_LEAVE
+#define LOG_TWAI_FLG_LEAVE(ercd, flgptn)
+#endif /* LOG_TWAI_FLG_LEAVE */
+
+#ifndef LOG_INI_FLG_ENTER
+#define LOG_INI_FLG_ENTER(flgid)
+#endif /* LOG_INI_FLG_ENTER */
+
+#ifndef LOG_INI_FLG_LEAVE
+#define LOG_INI_FLG_LEAVE(ercd)
+#endif /* LOG_INI_FLG_LEAVE */
+
+#ifndef LOG_REF_FLG_ENTER
+#define LOG_REF_FLG_ENTER(flgid, pk_rflg)
+#endif /* LOG_REF_FLG_ENTER */
+
+#ifndef LOG_REF_FLG_LEAVE
+#define LOG_REF_FLG_LEAVE(ercd, pk_rflg)
+#endif /* LOG_REF_FLG_LEAVE */
+
+/*
+ * イベントフラグの数
+ */
+#define tnum_flg ((uint_t)(tmax_flgid - TMIN_FLGID + 1))
+
+/*
+ * イベントフラグIDからイベントフラグ管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_FLG(flgid) ((uint_t)((flgid) - TMIN_FLGID))
+#define get_flgcb(flgid) (&(flgcb_table[INDEX_FLG(flgid)]))
+
+/*
+ * イベントフラグ機能の初期化
+ */
+#ifdef TOPPERS_flgini
+
+void
+initialize_eventflag(void)
+{
+ uint_t i;
+ FLGCB *p_flgcb;
+
+ for (p_flgcb = flgcb_table, i = 0; i < tnum_flg; p_flgcb++, i++) {
+ queue_initialize(&(p_flgcb->wait_queue));
+ p_flgcb->p_flginib = &(flginib_table[i]);
+ p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
+ }
+}
+
+#endif /* TOPPERS_flgini */
+
+/*
+ * イベントフラグ待ち解除条件のチェック
+ */
+#ifdef TOPPERS_flgcnd
+
+bool_t
+check_flg_cond(FLGCB *p_flgcb, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
+{
+ if ((wfmode & TWF_ORW) != 0U ? (p_flgcb->flgptn & waiptn) != 0U
+ : (p_flgcb->flgptn & waiptn) == waiptn) {
+ *p_flgptn = p_flgcb->flgptn;
+ if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
+ p_flgcb->flgptn = 0U;
+ }
+ return(true);
+ }
+ return(false);
+}
+
+#endif /* TOPPERS_flgcnd */
+
+/*
+ * イベントフラグのセット
+ */
+#ifdef TOPPERS_set_flg
+
+ER
+set_flg(ID flgid, FLGPTN setptn)
+{
+ FLGCB *p_flgcb;
+ QUEUE *p_queue;
+ TCB *p_tcb;
+ WINFO_FLG *p_winfo_flg;
+ bool_t dspreq = false;
+ ER ercd;
+
+ LOG_SET_FLG_ENTER(flgid, setptn);
+ CHECK_TSKCTX_UNL();
+ CHECK_FLGID(flgid);
+ p_flgcb = get_flgcb(flgid);
+
+ t_lock_cpu();
+ p_flgcb->flgptn |= setptn;
+ p_queue = p_flgcb->wait_queue.p_next;
+ while (p_queue != &(p_flgcb->wait_queue)) {
+ p_tcb = (TCB *) p_queue;
+ p_queue = p_queue->p_next;
+ p_winfo_flg = (WINFO_FLG *)(p_tcb->p_winfo);
+ if (check_flg_cond(p_flgcb, p_winfo_flg->waiptn,
+ p_winfo_flg->wfmode, &(p_winfo_flg->flgptn))) {
+ queue_delete(&(p_tcb->task_queue));
+ if (wait_complete(p_tcb)) {
+ dspreq = true;
+ }
+ if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
+ break;
+ }
+ }
+ }
+ if (dspreq) {
+ dispatch();
+ }
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_SET_FLG_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_set_flg */
+
+/*
+ * イベントフラグのセット(非タスクコンテキスト用)
+ */
+#ifdef TOPPERS_iset_flg
+
+ER
+iset_flg(ID flgid, FLGPTN setptn)
+{
+ FLGCB *p_flgcb;
+ QUEUE *p_queue;
+ TCB *p_tcb;
+ WINFO_FLG *p_winfo_flg;
+ ER ercd;
+
+ LOG_ISET_FLG_ENTER(flgid, setptn);
+ CHECK_INTCTX_UNL();
+ CHECK_FLGID(flgid);
+ p_flgcb = get_flgcb(flgid);
+
+ i_lock_cpu();
+ p_flgcb->flgptn |= setptn;
+ p_queue = p_flgcb->wait_queue.p_next;
+ while (p_queue != &(p_flgcb->wait_queue)) {
+ p_tcb = (TCB *) p_queue;
+ p_queue = p_queue->p_next;
+ p_winfo_flg = (WINFO_FLG *)(p_tcb->p_winfo);
+ if (check_flg_cond(p_flgcb, p_winfo_flg->waiptn,
+ p_winfo_flg->wfmode, &(p_winfo_flg->flgptn))) {
+ queue_delete(&(p_tcb->task_queue));
+ if (wait_complete(p_tcb)) {
+ reqflg = true;
+ }
+ if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
+ break;
+ }
+ }
+ }
+ ercd = E_OK;
+ i_unlock_cpu();
+
+ error_exit:
+ LOG_ISET_FLG_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_iset_flg */
+
+/*
+ * イベントフラグのクリア
+ */
+#ifdef TOPPERS_clr_flg
+
+ER
+clr_flg(ID flgid, FLGPTN clrptn)
+{
+ FLGCB *p_flgcb;
+ ER ercd;
+
+ LOG_CLR_FLG_ENTER(flgid, clrptn);
+ CHECK_TSKCTX_UNL();
+ CHECK_FLGID(flgid);
+ p_flgcb = get_flgcb(flgid);
+
+ t_lock_cpu();
+ p_flgcb->flgptn &= clrptn;
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_CLR_FLG_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_clr_flg */
+
+/*
+ * イベントフラグ待ち
+ */
+#ifdef TOPPERS_wai_flg
+
+ER
+wai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
+{
+ FLGCB *p_flgcb;
+ WINFO_FLG winfo_flg;
+ ER ercd;
+
+ LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn);
+ CHECK_DISPATCH();
+ CHECK_FLGID(flgid);
+ CHECK_PAR(waiptn != 0U);
+ CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
+ p_flgcb = get_flgcb(flgid);
+
+ t_lock_cpu();
+ if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
+ && !queue_empty(&(p_flgcb->wait_queue))) {
+ ercd = E_ILUSE;
+ }
+ else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
+ ercd = E_OK;
+ }
+ else {
+ winfo_flg.waiptn = waiptn;
+ winfo_flg.wfmode = wfmode;
+ p_runtsk->tstat = (TS_WAITING | TS_WAIT_FLG);
+ wobj_make_wait((WOBJCB *) p_flgcb, (WINFO_WOBJ *) &winfo_flg);
+ dispatch();
+ ercd = winfo_flg.winfo.wercd;
+ if (ercd == E_OK) {
+ *p_flgptn = winfo_flg.flgptn;
+ }
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_WAI_FLG_LEAVE(ercd, *p_flgptn);
+ return(ercd);
+}
+
+#endif /* TOPPERS_wai_flg */
+
+/*
+ * イベントフラグ待ち(ポーリング)
+ */
+#ifdef TOPPERS_pol_flg
+
+ER
+pol_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
+{
+ FLGCB *p_flgcb;
+ ER ercd;
+
+ LOG_POL_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn);
+ CHECK_TSKCTX_UNL();
+ CHECK_FLGID(flgid);
+ CHECK_PAR(waiptn != 0U);
+ CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
+ p_flgcb = get_flgcb(flgid);
+
+ t_lock_cpu();
+ if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
+ && !queue_empty(&(p_flgcb->wait_queue))) {
+ ercd = E_ILUSE;
+ }
+ else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
+ ercd = E_OK;
+ }
+ else {
+ ercd = E_TMOUT;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_POL_FLG_LEAVE(ercd, *p_flgptn);
+ return(ercd);
+}
+
+#endif /* TOPPERS_pol_flg */
+
+/*
+ * イベントフラグ待ち(タイムアウトあり)
+ */
+#ifdef TOPPERS_twai_flg
+
+ER
+twai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn, TMO tmout)
+{
+ FLGCB *p_flgcb;
+ WINFO_FLG winfo_flg;
+ TMEVTB tmevtb;
+ ER ercd;
+
+ LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout);
+ CHECK_DISPATCH();
+ CHECK_FLGID(flgid);
+ CHECK_PAR(waiptn != 0U);
+ CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
+ CHECK_TMOUT(tmout);
+ p_flgcb = get_flgcb(flgid);
+
+ t_lock_cpu();
+ if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
+ && !queue_empty(&(p_flgcb->wait_queue))) {
+ ercd = E_ILUSE;
+ }
+ else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
+ ercd = E_OK;
+ }
+ else if (tmout == TMO_POL) {
+ ercd = E_TMOUT;
+ }
+ else {
+ winfo_flg.waiptn = waiptn;
+ winfo_flg.wfmode = wfmode;
+ p_runtsk->tstat = (TS_WAITING | TS_WAIT_FLG);
+ wobj_make_wait_tmout((WOBJCB *) p_flgcb, (WINFO_WOBJ *) &winfo_flg,
+ &tmevtb, tmout);
+ dispatch();
+ ercd = winfo_flg.winfo.wercd;
+ if (ercd == E_OK) {
+ *p_flgptn = winfo_flg.flgptn;
+ }
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_TWAI_FLG_LEAVE(ercd, *p_flgptn);
+ return(ercd);
+}
+
+#endif /* TOPPERS_twai_flg */
+
+/*
+ * イベントフラグの再初期化
+ */
+#ifdef TOPPERS_ini_flg
+
+ER
+ini_flg(ID flgid)
+{
+ FLGCB *p_flgcb;
+ bool_t dspreq;
+ ER ercd;
+
+ LOG_INI_FLG_ENTER(flgid);
+ CHECK_TSKCTX_UNL();
+ CHECK_FLGID(flgid);
+ p_flgcb = get_flgcb(flgid);
+
+ t_lock_cpu();
+ dspreq = init_wait_queue(&(p_flgcb->wait_queue));
+ p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
+ if (dspreq) {
+ dispatch();
+ }
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_INI_FLG_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ini_flg */
+
+/*
+ * イベントフラグの状態参照
+ */
+#ifdef TOPPERS_ref_flg
+
+ER
+ref_flg(ID flgid, T_RFLG *pk_rflg)
+{
+ FLGCB *p_flgcb;
+ ER ercd;
+
+ LOG_REF_FLG_ENTER(flgid, pk_rflg);
+ CHECK_TSKCTX_UNL();
+ CHECK_FLGID(flgid);
+ p_flgcb = get_flgcb(flgid);
+
+ t_lock_cpu();
+ pk_rflg->wtskid = wait_tskid(&(p_flgcb->wait_queue));
+ pk_rflg->flgptn = p_flgcb->flgptn;
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_REF_FLG_LEAVE(ercd, pk_rflg);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ref_flg */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: eventflag.h 748 2008-03-07 17:18:06Z hiro $
+ */
+
+/*
+ * イベントフラグ機能
+ */
+
+#ifndef TOPPERS_EVENTFLAG_H
+#define TOPPERS_EVENTFLAG_H
+
+#include <queue.h>
+
+/*
+ * イベントフラグ初期化ブロック
+ *
+ * この構造体は,同期・通信オブジェクトの初期化ブロックの共通部分
+ * (WOBJINIB)を拡張(オブジェクト指向言語の継承に相当)したもので,
+ * 最初のフィールドが共通になっている.
+ */
+typedef struct eventflag_initialization_block {
+ ATR flgatr; /* イベントフラグ属性 */
+ FLGPTN iflgptn; /* イベントフラグのビットパターンの初期値 */
+} FLGINIB;
+
+/*
+ * イベントフラグ管理ブロック
+ *
+ * この構造体は,同期・通信オブジェクトの管理ブロックの共通部分(WOBJCB)
+ * を拡張(オブジェクト指向言語の継承に相当)したもので,最初の2つの
+ * フィールドが共通になっている.
+ */
+typedef struct eventflag_control_block {
+ QUEUE wait_queue; /* イベントフラグ待ちキュー */
+ const FLGINIB *p_flginib; /* 初期化ブロックへのポインタ */
+ FLGPTN flgptn; /* イベントフラグ現在パターン */
+} FLGCB;
+
+/*
+ * イベントフラグ待ち情報ブロックの定義
+ *
+ * この構造体は,同期・通信オブジェクトの待ち情報ブロックの共通部分
+ * (WINFO_WOBJ)を拡張(オブジェクト指向言語の継承に相当)したもので,
+ * 最初の2つのフィールドが共通になっている.
+ *
+ * flgptnは,waiptnおよびwfmodeと同時に使うことはないため,共用体を使
+ * えばメモリを節約することが可能である.
+ */
+typedef struct eventflag_waiting_information {
+ WINFO winfo; /* 標準の待ち情報ブロック */
+ FLGCB *p_flgcb; /* 待っているイベントフラグの管理ブロック */
+ FLGPTN waiptn; /* 待ちパターン */
+ MODE wfmode; /* 待ちモード */
+ FLGPTN flgptn; /* 待ち解除時のパターン */
+} WINFO_FLG;
+
+/*
+ * イベントフラグIDの最大値(kernel_cfg.c)
+ */
+extern const ID tmax_flgid;
+
+/*
+ * イベントフラグ初期化ブロックのエリア(kernel_cfg.c)
+ */
+extern const FLGINIB flginib_table[];
+
+/*
+ * イベントフラグ管理ブロックのエリア(kernel_cfg.c)
+ */
+extern FLGCB flgcb_table[];
+
+/*
+ * イベントフラグ管理ブロックからイベントフラグIDを取り出すためのマクロ
+ */
+#define FLGID(p_flgcb) ((ID)(((p_flgcb) - flgcb_table) + TMIN_FLGID))
+
+/*
+ * イベントフラグ機能の初期化
+ */
+extern void initialize_eventflag(void);
+
+/*
+ * イベントフラグ待ち解除条件のチェック
+ */
+extern bool_t check_flg_cond(FLGCB *p_flgcb, FLGPTN waiptn,
+ MODE wfmode, FLGPTN *p_flgptn);
+
+#endif /* TOPPERS_EVENTFLAG_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: exception.c 1653 2009-10-10 18:04:15Z ertl-hiro $
+ */
+
+/*
+ * CPU例外管理機能
+ */
+
+#include "kernel_impl.h"
+#include "task.h"
+#include "exception.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_XSNS_DPN_ENTER
+#define LOG_XSNS_DPN_ENTER(p_excinf)
+#endif /* LOG_XSNS_DPN_ENTER */
+
+#ifndef LOG_XSNS_DPN_LEAVE
+#define LOG_XSNS_DPN_LEAVE(state)
+#endif /* LOG_XSNS_DPN_LEAVE */
+
+#ifndef LOG_XSNS_XPN_ENTER
+#define LOG_XSNS_XPN_ENTER(p_excinf)
+#endif /* LOG_XSNS_XPN_ENTER */
+
+#ifndef LOG_XSNS_XPN_LEAVE
+#define LOG_XSNS_XPN_LEAVE(state)
+#endif /* LOG_XSNS_XPN_LEAVE */
+
+/*
+ * CPU例外ハンドラ管理機能の初期化
+ */
+#ifdef TOPPERS_excini
+#ifndef OMIT_INITIALIZE_EXCEPTION
+
+void
+initialize_exception(void)
+{
+ uint_t i;
+ const EXCINIB *p_excinib;
+
+ for (p_excinib = excinib_table, i = 0; i < tnum_excno; p_excinib++, i++) {
+ x_define_exc(p_excinib->excno, p_excinib->exc_entry);
+ }
+}
+
+#endif /* OMIT_INITIALIZE_EXCEPTION */
+#endif /* TOPPERS_excini */
+
+/*
+ * CPU例外の発生したコンテキストの参照
+ */
+
+/*
+ * CPU例外発生時のディスパッチ保留状態の参照
+ *
+ * CPU例外ハンドラ中でdisdspが変化することはないため,CPU例外が発生し
+ * た時のdisdspを保存しておく必要はない.
+ */
+#ifdef TOPPERS_xsns_dpn
+
+bool_t
+xsns_dpn(void *p_excinf)
+{
+ bool_t state;
+
+ LOG_XSNS_DPN_ENTER(p_excinf);
+ state = (exc_sense_intmask(p_excinf) && !disdsp) ? false : true;
+ LOG_XSNS_DPN_LEAVE(state);
+ return(state);
+}
+
+#endif /* TOPPERS_xsns_dpn */
+
+/*
+ * CPU例外発生時のタスク例外処理保留状態の参照
+ *
+ * CPU例外ハンドラ中でp_runtskとp_runtsk->enatexが変化することはない
+ * ため,CPU例外が発生した時のp_runtsk->enatexを保存しておく必要はな
+ * い.
+ */
+#ifdef TOPPERS_xsns_xpn
+
+bool_t
+xsns_xpn(void *p_excinf)
+{
+ bool_t state;
+
+ LOG_XSNS_XPN_ENTER(p_excinf);
+ state = (exc_sense_unlock(p_excinf) && p_runtsk->enatex) ? false : true;
+ LOG_XSNS_XPN_LEAVE(state);
+ return(state);
+}
+
+#endif /* TOPPERS_xsns_xpn */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: exception.h 648 2007-12-15 09:35:35Z hiro $
+ */
+
+/*
+ * CPU例外管理機能
+ */
+
+#ifndef TOPPERS_EXCEPTION_H
+#define TOPPERS_EXCEPTION_H
+
+#ifndef OMIT_INITIALIZE_EXCEPTION
+
+/*
+ * CPU例外ハンドラ初期化ブロック
+ */
+typedef struct cpu_exception_handler_initialization_block {
+ EXCNO excno; /* CPU例外ハンドラ番号 */
+ ATR excatr; /* CPU例外ハンドラ属性 */
+ FP exc_entry; /* CPU例外ハンドラの出入口処理の番地 */
+} EXCINIB;
+
+/*
+ * CPU例外ハンドラ番号の数(kernel_cfg.c)
+ */
+extern const uint_t tnum_excno;
+
+/*
+ * CPU例外ハンドラ初期化ブロックのエリア(kernel_cfg.c)
+ */
+extern const EXCINIB excinib_table[];
+
+#endif /* OMIT_INITIALIZE_EXCEPTION */
+
+/*
+ * CPU例外ハンドラ管理機能の初期化
+ */
+extern void initialize_exception(void);
+
+#endif /* TOPPERS_EXCEPTION_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: interrupt.c 1646 2009-10-01 05:19:30Z ertl-hiro $
+ */
+
+/*
+ * 割込み管理機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "interrupt.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_DIS_INT_ENTER
+#define LOG_DIS_INT_ENTER(intno)
+#endif /* LOG_DIS_INT_ENTER */
+
+#ifndef LOG_DIS_INT_LEAVE
+#define LOG_DIS_INT_LEAVE(ercd)
+#endif /* LOG_DIS_INT_LEAVE */
+
+#ifndef LOG_ENA_INT_ENTER
+#define LOG_ENA_INT_ENTER(intno)
+#endif /* LOG_ENA_INT_ENTER */
+
+#ifndef LOG_ENA_INT_LEAVE
+#define LOG_ENA_INT_LEAVE(ercd)
+#endif /* LOG_ENA_INT_LEAVE */
+
+#ifndef LOG_CHG_IPM_ENTER
+#define LOG_CHG_IPM_ENTER(intpri)
+#endif /* LOG_CHG_IPM_ENTER */
+
+#ifndef LOG_CHG_IPM_LEAVE
+#define LOG_CHG_IPM_LEAVE(ercd)
+#endif /* LOG_CHG_IPM_LEAVE */
+
+#ifndef LOG_GET_IPM_ENTER
+#define LOG_GET_IPM_ENTER(p_intpri)
+#endif /* LOG_GET_IPM_ENTER */
+
+#ifndef LOG_GET_IPM_LEAVE
+#define LOG_GET_IPM_LEAVE(ercd, intpri)
+#endif /* LOG_GET_IPM_LEAVE */
+
+/*
+ * 割込み管理機能の初期化
+ */
+#ifdef TOPPERS_intini
+#ifndef OMIT_INITIALIZE_INTERRUPT
+
+void
+initialize_interrupt(void)
+{
+ uint_t i;
+ const INHINIB *p_inhinib;
+ const INTINIB *p_intinib;
+
+ for (p_inhinib = inhinib_table, i = 0; i < tnum_inhno; p_inhinib++, i++) {
+ x_define_inh(p_inhinib->inhno, p_inhinib->int_entry);
+ }
+ for (p_intinib = intinib_table, i = 0; i < tnum_intno; p_intinib++, i++) {
+ x_config_int(p_intinib->intno, p_intinib->intatr, p_intinib->intpri);
+ }
+}
+
+#endif /* OMIT_INITIALIZE_INTERRUPT */
+#endif /* TOPPERS_intini */
+
+/*
+ * 割込みの禁止
+ */
+#ifdef TOPPERS_dis_int
+#ifdef TOPPERS_SUPPORT_DIS_INT
+
+ER
+dis_int(INTNO intno)
+{
+ bool_t locked;
+ ER ercd;
+
+ LOG_DIS_INT_ENTER(intno);
+ CHECK_TSKCTX();
+ CHECK_INTNO_DISINT(intno);
+
+ locked = t_sense_lock();
+ if (!locked) {
+ t_lock_cpu();
+ }
+ if (t_disable_int(intno)) {
+ ercd = E_OK;
+ }
+ else {
+ ercd = E_OBJ;
+ }
+ if (!locked) {
+ t_unlock_cpu();
+ }
+
+ error_exit:
+ LOG_DIS_INT_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_SUPPORT_DIS_INT */
+#endif /* TOPPERS_dis_int */
+
+/*
+ * 割込みの許可
+ */
+#ifdef TOPPERS_ena_int
+#ifdef TOPPERS_SUPPORT_ENA_INT
+
+ER
+ena_int(INTNO intno)
+{
+ bool_t locked;
+ ER ercd;
+
+ LOG_ENA_INT_ENTER(intno);
+ CHECK_TSKCTX();
+ CHECK_INTNO_DISINT(intno);
+
+ locked = t_sense_lock();
+ if (!locked) {
+ t_lock_cpu();
+ }
+ if (t_enable_int(intno)) {
+ ercd = E_OK;
+ }
+ else {
+ ercd = E_OBJ;
+ }
+ if (!locked) {
+ t_unlock_cpu();
+ }
+
+ error_exit:
+ LOG_ENA_INT_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_SUPPORT_ENA_INT */
+#endif /* TOPPERS_ena_int */
+
+/*
+ * 割込み優先度マスクの変更
+ */
+#ifdef TOPPERS_chg_ipm
+
+ER
+chg_ipm(PRI intpri)
+{
+ ER ercd;
+
+ LOG_CHG_IPM_ENTER(intpri);
+ CHECK_TSKCTX_UNL();
+ CHECK_INTPRI_CHGIPM(intpri);
+
+ t_lock_cpu();
+ t_set_ipm(intpri);
+ if (intpri != TIPM_ENAALL) {
+ dspflg = false;
+ }
+ else if (!disdsp) {
+ dspflg = true;
+ if (p_runtsk != p_schedtsk) {
+ dispatch();
+ }
+ }
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_CHG_IPM_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_chg_ipm */
+
+/*
+ * 割込み優先度マスクの参照
+ */
+#ifdef TOPPERS_get_ipm
+
+ER
+get_ipm(PRI *p_intpri)
+{
+ ER ercd;
+
+ LOG_GET_IPM_ENTER(p_intpri);
+ CHECK_TSKCTX_UNL();
+
+ t_lock_cpu();
+ *p_intpri = t_get_ipm();
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_GET_IPM_LEAVE(ercd, *p_intpri);
+ return(ercd);
+}
+
+#endif /* TOPPERS_get_ipm */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: interrupt.h 648 2007-12-15 09:35:35Z hiro $
+ */
+
+/*
+ * 割込み管理機能
+ */
+
+#ifndef TOPPERS_INTERRUPT_H
+#define TOPPERS_INTERRUPT_H
+
+#ifndef OMIT_INITIALIZE_INTERRUPT
+
+/*
+ * 割込みハンドラ初期化ブロック
+ */
+typedef struct interrupt_handler_initialization_block {
+ INHNO inhno; /* 割込みハンドラ番号 */
+ ATR inhatr; /* 割込みハンドラ属性 */
+ FP int_entry; /* 割込みハンドラの出入口処理の番地 */
+} INHINIB;
+
+/*
+ * 割込み要求ライン初期化ブロック
+ */
+typedef struct interrupt_request_initialization_block {
+ INTNO intno; /* 割込み番号 */
+ ATR intatr; /* 割込み属性 */
+ PRI intpri; /* 割込み優先度 */
+} INTINIB;
+
+/*
+ * 割込みハンドラ番号の数(kernel_cfg.c)
+ */
+extern const uint_t tnum_inhno;
+
+/*
+ * 割込みハンドラ初期化ブロックのエリア(kernel_cfg.c)
+ */
+extern const INHINIB inhinib_table[];
+
+/*
+ * 割込み要求ラインの数(kernel_cfg.c)
+ */
+extern const uint_t tnum_intno;
+
+/*
+ * 割込み要求ライン初期化ブロックのエリア(kernel_cfg.c)
+ */
+extern const INTINIB intinib_table[];
+
+#endif /* OMIT_INITIALIZE_INTERRUPT */
+
+/*
+ * 割込み管理機能の初期化
+ */
+extern void initialize_interrupt(void);
+
+#endif /* TOPPERS_INTERRUPT_H */
--- /dev/null
+$ ======================================================================
+$
+$ TOPPERS/ASP Kernel
+$ Toyohashi Open Platform for Embedded Real-Time Systems/
+$ Advanced Standard Profile Kernel
+$
+$ Copyright (C) 2007 by TAKAGI Nobuhisa
+$ Copyright (C) 2007-2010 by Embedded and Real-Time Systems Laboratory
+$ Graduate School of Information Science, Nagoya Univ., JAPAN
+$
+$ 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+$ ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+$ 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+$ (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+$ 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+$ スコード中に含まれていること.
+$ (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+$ 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+$ 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+$ の無保証規定を掲載すること.
+$ (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+$ 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+$ と.
+$ (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+$ 作権表示,この利用条件および下記の無保証規定を掲載すること.
+$ (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+$ 報告すること.
+$ (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+$ 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+$ また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+$ 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+$ 免責すること.
+$
+$ 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+$ よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+$ に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+$ アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+$ の責任を負わない.
+$
+$ $Id: kernel.tf 1845 2010-07-11 13:02:57Z ertl-hiro $
+$
+$ =====================================================================
+
+$ =====================================================================
+$ kernel_cfg.hの生成
+$ =====================================================================
+
+$FILE "kernel_cfg.h"$
+/* kernel_cfg.h */$NL$
+#ifndef TOPPERS_KERNEL_CFG_H$NL$
+#define TOPPERS_KERNEL_CFG_H$NL$
+$NL$
+#define TNUM_TSKID $LENGTH(TSK.ID_LIST)$$NL$
+#define TNUM_SEMID $LENGTH(SEM.ID_LIST)$$NL$
+#define TNUM_FLGID $LENGTH(FLG.ID_LIST)$$NL$
+#define TNUM_DTQID $LENGTH(DTQ.ID_LIST)$$NL$
+#define TNUM_PDQID $LENGTH(PDQ.ID_LIST)$$NL$
+#define TNUM_MBXID $LENGTH(MBX.ID_LIST)$$NL$
+#define TNUM_MPFID $LENGTH(MPF.ID_LIST)$$NL$
+#define TNUM_CYCID $LENGTH(CYC.ID_LIST)$$NL$
+#define TNUM_ALMID $LENGTH(ALM.ID_LIST)$$NL$
+$NL$
+$FOREACH id TSK.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id SEM.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id FLG.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id DTQ.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id PDQ.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id MBX.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id MPF.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id CYC.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$FOREACH id ALM.ID_LIST$
+ #define $id$ $+id$$NL$
+$END$
+$NL$
+#endif /* TOPPERS_KERNEL_CFG_H */$NL$
+
+$ =====================================================================
+$ kernel_cfg.cの生成
+$ =====================================================================
+
+$FILE "kernel_cfg.c"$
+/* kernel_cfg.c */$NL$
+#include "kernel/kernel_int.h"$NL$
+#include "kernel_cfg.h"$NL$
+$NL$
+#ifndef TOPPERS_EMPTY_LABEL$NL$
+#define TOPPERS_EMPTY_LABEL(x,y) x y[0]$NL$
+#endif$NL$
+$NL$
+#if TKERNEL_PRID != 0x07u$NL$
+#error The kernel does not match this configuration file.$NL$
+#endif$NL$
+$NL$
+
+$
+$ インクルードディレクティブ(#include)
+$
+/*$NL$
+$SPC$* Include Directives (#include)$NL$
+$SPC$*/$NL$
+$NL$
+$INCLUDES$
+$NL$
+
+$
+$ オブジェクトのID番号を保持する変数
+$
+$IF USE_EXTERNAL_ID$
+ /*$NL$
+ $SPC$* Variables for Object ID$NL$
+ $SPC$*/$NL$
+ $NL$
+ $FOREACH id TSK.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id SEM.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id FLG.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id DTQ.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id PDQ.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id MBX.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id MPF.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id CYC.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+ $FOREACH id ALM.ID_LIST$
+ const ID $id$_id$SPC$=$SPC$$+id$;$NL$
+ $END$
+$END$
+
+$
+$ トレースログマクロのデフォルト定義
+$
+/*$NL$
+$SPC$* Default Definitions of Trace Log Macros$NL$
+$SPC$*/$NL$
+$NL$
+#ifndef LOG_ISR_ENTER$NL$
+#define LOG_ISR_ENTER(intno)$NL$
+#endif /* LOG_ISR_ENTER */$NL$
+$NL$
+#ifndef LOG_ISR_LEAVE$NL$
+#define LOG_ISR_LEAVE(intno)$NL$
+#endif /* LOG_ISR_LEAVE */$NL$
+$NL$
+
+$
+$ タスク
+$
+/*$NL$
+$SPC$* Task Management Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ タスクが1個以上存在することのチェック
+$IF !LENGTH(TSK.ID_LIST)$
+ $ERROR$$FORMAT("no task is registered")$$END$
+$END$
+
+$ タスクID番号の最大値
+const ID _kernel_tmax_tskid = (TMIN_TSKID + TNUM_TSKID - 1);$NL$
+$NL$
+
+$ エラーチェック
+$FOREACH tskid TSK.ID_LIST$
+$ // tskatrが([TA_ACT])でない場合(E_RSATR)
+ $IF (TSK.TSKATR[tskid] & ~(TA_ACT|ALT(TARGET_TSKATR,0))) != 0$
+ $ERROR TSK.TEXT_LINE[tskid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "tskatr", TSK.TSKATR[tskid], tskid, "CRE_TSK")$$END$
+ $END$
+
+$ // (TMIN_TPRI <= itskpri && itskpri <= TMAX_TPRI)でない場合(E_PAR)
+ $IF !(TMIN_TPRI <= TSK.ITSKPRI[tskid] && TSK.ITSKPRI[tskid] <= TMAX_TPRI)$
+ $ERROR TSK.TEXT_LINE[tskid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "itskpri", TSK.ITSKPRI[tskid], tskid, "CRE_TSK")$$END$
+ $END$
+
+$ // texatrが(TA_NULL)でない場合(E_RSATR)
+ $IF LENGTH(TSK.TEXATR[tskid]) && TSK.TEXATR[tskid] != 0$
+ $ERROR DEF_TEX.TEXT_LINE[tskid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "texatr", TSK.TEXATR[tskid], tskid, "DEF_TEX")$$END$
+ $END$
+$END$
+
+$ スタック領域の生成とそれに関するエラーチェック
+$FOREACH tskid TSK.ID_LIST$
+$ // stkszが0か,ターゲット定義の最小値(TARGET_MIN_STKSZ)よりも小さい場合(E_PAR)
+ $IF TSK.STKSZ[tskid] == 0 || (LENGTH(TARGET_MIN_STKSZ) &&
+ TSK.STKSZ[tskid] < TARGET_MIN_STKSZ)$
+ $ERROR TSK.TEXT_LINE[tskid]$E_PAR: $FORMAT(_("%1% `%2%\' of `%3%\' in %4% is too small"), "stksz", TSK.STKSZ[tskid], tskid, "CRE_TSK")$$END$
+ $END$
+$ // stkszがスタック領域のサイズとして正しくない場合(E_PAR)
+ $IF !EQ(TSK.STK[tskid], "NULL") && LENGTH(CHECK_STKSZ_ALIGN)
+ && (TSK.STKSZ[tskid] & (CHECK_STKSZ_ALIGN - 1))$
+ $ERROR TSK.TEXT_LINE[tskid]$E_PAR: $FORMAT(_("%1% `%2%\' of `%3%\' in %4% is not aligned"), "stksz", TSK.STKSZ[tskid], tskid, "CRE_TSK")$$END$
+ $END$
+
+ $IF EQ(TSK.STK[tskid],"NULL")$
+ static STK_T _kernel_stack_$tskid$[COUNT_STK_T($TSK.STKSZ[tskid]$)];$NL$
+ $TSK.TINIB_STKSZ[tskid] = FORMAT("ROUND_STK_T(%1%)", TSK.STKSZ[tskid])$
+ $TSK.TINIB_STK[tskid] = CONCAT("_kernel_stack_", tskid)$
+ $ELSE$
+ $TSK.TINIB_STKSZ[tskid] = TSK.STKSZ[tskid]$
+ $TSK.TINIB_STK[tskid] = TSK.STK[tskid]$
+ $END$
+$END$
+$NL$
+
+$ タスク初期化ブロックの生成(タスクは1個以上存在する)
+const TINIB _kernel_tinib_table[TNUM_TSKID] = {$NL$
+$JOINEACH tskid TSK.ID_LIST ",\n"$
+$ // タスク属性,拡張情報,起動番地,起動時優先度
+ $TAB${
+ $SPC$($TSK.TSKATR[tskid]$), (intptr_t)($TSK.EXINF[tskid]$),
+ $SPC$($TSK.TASK[tskid]$), INT_PRIORITY($TSK.ITSKPRI[tskid]$),
+
+$ // タスク初期化コンテキストブロック,スタック領域
+ $IF ALT(USE_TSKINICTXB,0)$
+ $GENERATE_TSKINICTXB(tskid)$
+ $ELSE$
+ $SPC$$TSK.TINIB_STKSZ[tskid]$, $TSK.TINIB_STK[tskid]$,
+ $END$
+
+$ // タスク例外処理ルーチンの属性と起動番地
+ $SPC$($ALT(TSK.TEXATR[tskid],"TA_NULL")$), ($ALT(TSK.TEXRTN[tskid],"NULL")$) }
+$END$$NL$
+};$NL$
+$NL$
+
+$ タスクコントロールブロックの生成
+TCB _kernel_tcb_table[TNUM_TSKID];$NL$
+$NL$
+
+$ タスク生成順序テーブルの生成
+const ID _kernel_torder_table[TNUM_TSKID] = {$NL$
+$TAB$$JOINEACH tskid TSK.ORDER_LIST ", "$$tskid$$END$$NL$
+};$NL$
+$NL$
+
+$
+$ セマフォ
+$
+/*$NL$
+$SPC$* Semaphore Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ セマフォID番号の最大値
+const ID _kernel_tmax_semid = (TMIN_SEMID + TNUM_SEMID - 1);$NL$
+$NL$
+
+$ セマフォ初期化ブロックの生成
+$IF LENGTH(SEM.ID_LIST)$
+ const SEMINIB _kernel_seminib_table[TNUM_SEMID] = {$NL$
+ $JOINEACH semid SEM.ID_LIST ",\n"$
+$ // sematrが([TA_TPRI])でない場合(E_RSATR)
+ $IF (SEM.SEMATR[semid] & ~TA_TPRI) != 0$
+ $ERROR SEM.TEXT_LINE[semid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "sematr", SEM.SEMATR[semid], semid, "CRE_SEM")$$END$
+ $END$
+
+$ // (0 <= isemcnt && isemcnt <= maxsem)でない場合(E_PAR)
+ $IF !(0 <= SEM.ISEMCNT[semid] && SEM.ISEMCNT[semid] <= SEM.MAXSEM[semid])$
+ $ERROR SEM.TEXT_LINE[semid]$E_PAR: $FORMAT(_("too large %1% `%2%\' of `%3%\' in %4%"), "isemcnt", SEM.ISEMCNT[semid], semid, "CRE_SEM")$$END$
+ $END$
+
+$ // (1 <= maxsem && maxsem <= TMAX_MAXSEM)でない場合(E_PAR)
+ $IF !(1 <= SEM.MAXSEM[semid] && SEM.MAXSEM[semid] <= TMAX_MAXSEM)$
+ $ERROR SEM.TEXT_LINE[semid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "maxsem", SEM.MAXSEM[semid], semid, "CRE_SEM")$$END$
+ $END$
+
+$ // セマフォ初期化ブロック
+ $TAB${ ($SEM.SEMATR[semid]$), ($SEM.ISEMCNT[semid]$), ($SEM.MAXSEM[semid]$) }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // セマフォコントロールブロック
+ SEMCB _kernel_semcb_table[TNUM_SEMID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const SEMINIB, _kernel_seminib_table);$NL$
+ TOPPERS_EMPTY_LABEL(SEMCB, _kernel_semcb_table);$NL$
+$END$
+$NL$
+
+$
+$ イベントフラグ
+$
+/*$NL$
+$SPC$* Eventflag Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ イベントフラグID番号の最大値
+const ID _kernel_tmax_flgid = (TMIN_FLGID + TNUM_FLGID - 1);$NL$
+$NL$
+
+$ イベントフラグ初期化ブロックの生成
+$IF LENGTH(FLG.ID_LIST)$
+ const FLGINIB _kernel_flginib_table[TNUM_FLGID] = {$NL$
+ $JOINEACH flgid FLG.ID_LIST ",\n"$
+$ // flgatrが([TA_TPRI]|[TA_WMUL]|[TA_CLR])でない場合(E_RSATR)
+ $IF (FLG.FLGATR[flgid] & ~(TA_TPRI|TA_WMUL|TA_CLR)) != 0$
+ $ERROR FLG.TEXT_LINE[flgid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "flgatr", FLG.FLGATR[flgid], flgid, "CRE_FLG")$$END$
+ $END$
+
+$ // イベントフラグ初期化ブロック
+ $TAB${ ($FLG.FLGATR[flgid]$), ($FLG.IFLGPTN[flgid]$) }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // イベントフラグコントロールブロック
+ FLGCB _kernel_flgcb_table[TNUM_FLGID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const FLGINIB, _kernel_flginib_table);$NL$
+ TOPPERS_EMPTY_LABEL(FLGCB, _kernel_flgcb_table);$NL$
+$END$
+$NL$
+
+$
+$ データキュー
+$
+/*$NL$
+$SPC$* Dataqueue Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ データキューID番号の最大値
+const ID _kernel_tmax_dtqid = (TMIN_DTQID + TNUM_DTQID - 1);$NL$
+$NL$
+
+$IF LENGTH(DTQ.ID_LIST)$
+ $FOREACH dtqid DTQ.ID_LIST$
+$ // dtqatrが([TA_TPRI])でない場合(E_RSATR)
+ $IF (DTQ.DTQATR[dtqid] & ~TA_TPRI) != 0$
+ $ERROR DTQ.TEXT_LINE[dtqid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "dtqatr", DTQ.DTQATR[dtqid], dtqid, "CRE_DTQ")$$END$
+ $END$
+
+$ // dtqmbがNULLでない場合(E_NOSPT)
+ $IF !EQ(DTQ.DTQMB[dtqid], "NULL")$
+ $ERROR DTQ.TEXT_LINE[dtqid]$E_NOSPT: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "dtqmb", DTQ.DTQMB[dtqid], dtqid, "CRE_DTQ")$$END$
+ $END$
+
+$ // データキュー領域
+ $IF DTQ.DTQCNT[dtqid]$
+ static intptr_t _kernel_dtqmb_$dtqid$[$DTQ.DTQCNT[dtqid]$];$NL$
+ $END$
+ $END$
+
+$ // データキュー初期化ブロックの生成
+ const DTQINIB _kernel_dtqinib_table[TNUM_DTQID] = {$NL$
+ $JOINEACH dtqid DTQ.ID_LIST ",\n"$
+ $TAB${ ($DTQ.DTQATR[dtqid]$), ($DTQ.DTQCNT[dtqid]$), $IF DTQ.DTQCNT[dtqid]$(_kernel_dtqmb_$dtqid$)$ELSE$NULL$END$ }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // データキューコントロールブロック
+ DTQCB _kernel_dtqcb_table[TNUM_DTQID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const DTQINIB, _kernel_dtqinib_table);$NL$
+ TOPPERS_EMPTY_LABEL(DTQCB, _kernel_dtqcb_table);$NL$
+$END$
+$NL$
+
+$
+$ 優先度データキュー
+$
+/*$NL$
+$SPC$* Priority Dataqueue Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 優先度データキューID番号の最大値
+const ID _kernel_tmax_pdqid = (TMIN_PDQID + TNUM_PDQID - 1);$NL$
+$NL$
+
+$IF LENGTH(PDQ.ID_LIST)$
+ $FOREACH pdqid PDQ.ID_LIST$
+$ // pdqatrが([TA_TPRI])でない場合(E_RSATR)
+ $IF (PDQ.PDQATR[pdqid] & ~TA_TPRI) != 0$
+ $ERROR PDQ.TEXT_LINE[pdqid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "pdqatr", PDQ.PDQATR[pdqid], pdqid, "CRE_PDQ")$$END$
+ $END$
+
+$ // (TMIN_DPRI <= maxdpri && maxdpri <= TMAX_DPRI)でない場合(E_PAR)
+ $IF !(TMIN_DPRI <= PDQ.MAXDPRI[pdqid] && PDQ.MAXDPRI[pdqid] <= TMAX_DPRI)$
+ $ERROR PDQ.TEXT_LINE[pdqid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "maxdpri", PDQ.MAXDPRI[pdqid], pdqid, "CRE_PDQ")$$END$
+ $END$
+
+$ // pdqmbがNULLでない場合(E_NOSPT)
+ $IF !EQ(PDQ.PDQMB[pdqid], "NULL")$
+ $ERROR PDQ.TEXT_LINE[pdqid]$E_NOSPT: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "pdqmb", PDQ.PDQMB[pdqid], pdqid, "CRE_PDQ")$$END$
+ $END$
+
+$ // 優先度データキュー領域
+ $IF PDQ.PDQCNT[pdqid]$
+ static PDQMB _kernel_pdqmb_$pdqid$[$PDQ.PDQCNT[pdqid]$];$NL$
+ $END$
+ $END$
+
+$ // 優先度データキュー初期化ブロックの生成
+ const PDQINIB _kernel_pdqinib_table[TNUM_PDQID] = {$NL$
+ $JOINEACH pdqid PDQ.ID_LIST ",\n"$
+ $TAB${ ($PDQ.PDQATR[pdqid]$), ($PDQ.PDQCNT[pdqid]$), ($PDQ.MAXDPRI[pdqid]$), $IF PDQ.PDQCNT[pdqid]$(_kernel_pdqmb_$pdqid$)$ELSE$NULL$END$ }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // 優先度データキューコントロールブロック
+ PDQCB _kernel_pdqcb_table[TNUM_PDQID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const PDQINIB, _kernel_pdqinib_table);$NL$
+ TOPPERS_EMPTY_LABEL(PDQCB, _kernel_pdqcb_table);$NL$
+$END$
+$NL$
+
+$
+$ メールボックス
+$
+/*$NL$
+$SPC$* Mailbox Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ メールボックスID番号の最大値
+const ID _kernel_tmax_mbxid = (TMIN_MBXID + TNUM_MBXID - 1);$NL$
+$NL$
+
+$ メールボックス初期化ブロックの生成
+$IF LENGTH(MBX.ID_LIST)$
+ const MBXINIB _kernel_mbxinib_table[TNUM_MBXID] = {$NL$
+ $JOINEACH mbxid MBX.ID_LIST ",\n"$
+$ // mbxatrが([TA_TPRI]|[TA_MPRI])でない場合(E_RSATR)
+ $IF (MBX.MBXATR[mbxid] & ~(TA_TPRI|TA_MPRI)) != 0$
+ $ERROR MBX.TEXT_LINE[mbxid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mbxatr", MBX.MBXATR[mbxid], mbxid, "CRE_MBX")$$END$
+ $END$
+
+$ // (TMIN_MPRI <= maxmpri && maxmpri <= TMAX_MPRI)でない場合(E_PAR)
+ $IF !(TMIN_MPRI <= MBX.MAXMPRI[mbxid] && MBX.MAXMPRI[mbxid] <= TMAX_MPRI)$
+ $ERROR MBX.TEXT_LINE[mbxid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "maxmpri", MBX.MAXMPRI[mbxid], mbxid, "CRE_MBX")$$END$
+ $END$
+
+$ // mprihdがNULLでない場合(E_NOSPT)
+ $IF !EQ(MBX.MPRIHD[mbxid], "NULL")$
+ $ERROR MBX.TEXT_LINE[mbxid]$E_NOSPT: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mprihd", MBX.MPRIHD[mbxid], mbxid, "CRE_MBX")$$END$
+ $END$
+
+$ // メールボックス初期化ブロック
+ $TAB${ ($MBX.MBXATR[mbxid]$), ($MBX.MAXMPRI[mbxid]$) }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // メールボックスコントロールブロック
+ MBXCB _kernel_mbxcb_table[TNUM_MBXID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const MBXINIB, _kernel_mbxinib_table);$NL$
+ TOPPERS_EMPTY_LABEL(MBXCB, _kernel_mbxcb_table);$NL$
+$END$
+$NL$
+
+$
+$ 固定長メモリプール
+$
+/*$NL$
+$SPC$* Fixed-sized Memorypool Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 固定長メモリプールID番号の最大値
+const ID _kernel_tmax_mpfid = (TMIN_MPFID + TNUM_MPFID - 1);$NL$
+$NL$
+
+$IF LENGTH(MPF.ID_LIST)$
+ $FOREACH mpfid MPF.ID_LIST$
+$ // mpfatrが([TA_TPRI])でない場合(E_RSATR)
+ $IF (MPF.MPFATR[mpfid] & ~TA_TPRI) != 0$
+ $ERROR MPF.TEXT_LINE[mpfid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mpfatr", MPF.MPFATR[mpfid], mpfid, "CRE_MPF")$$END$
+ $END$
+
+$ // blkcntが0の場合(E_PAR)
+ $IF MPF.BLKCNT[mpfid] == 0$
+ $ERROR MPF.TEXT_LINE[mpfid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "blkcnt", MPF.BLKCNT[mpfid], mpfid, "CRE_MPF")$$END$
+ $END$
+
+$ // blkszが0の場合(E_PAR)
+ $IF MPF.BLKSZ[mpfid] == 0$
+ $ERROR MPF.TEXT_LINE[mpfid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "blksz", MPF.BLKSZ[mpfid], mpfid, "CRE_MPF")$$END$
+ $END$
+
+$ // 固定長メモリプール領域
+ $IF EQ(MPF.MPF[mpfid], "NULL")$
+ static MPF_T _kernel_mpf_$mpfid$[($MPF.BLKCNT[mpfid]$) * COUNT_MPF_T($MPF.BLKSZ[mpfid]$)];$NL$
+ $END$
+
+$ // mpfmbがNULLでない場合(E_NOSPT)
+ $IF !EQ(MPF.MPFMB[mpfid], "NULL")$
+ $ERROR MPF.TEXT_LINE[mpfid]$E_NOSPT: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "mpfmb", MPF.MPFMB[mpfid], mpfid, "CRE_MPF")$$END$
+ $END$
+
+$ // 固定長メモリプール管理領域
+ static MPFMB _kernel_mpfmb_$mpfid$[$MPF.BLKCNT[mpfid]$];$NL$
+ $END$
+
+$ // 固定長メモリプール初期化ブロックの生成
+ const MPFINIB _kernel_mpfinib_table[TNUM_MPFID] = {$NL$
+ $JOINEACH mpfid MPF.ID_LIST ",\n"$
+ $TAB${ ($MPF.MPFATR[mpfid]$), ($MPF.BLKCNT[mpfid]$), ROUND_MPF_T($MPF.BLKSZ[mpfid]$), $IF EQ(MPF.MPF[mpfid],"NULL")$(_kernel_mpf_$mpfid$)$ELSE$($MPF.MPF[mpfid]$)$END$, (_kernel_mpfmb_$mpfid$) }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // 固定長メモリプールコントロールブロック
+ MPFCB _kernel_mpfcb_table[TNUM_MPFID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const MPFINIB, _kernel_mpfinib_table);$NL$
+ TOPPERS_EMPTY_LABEL(MPFCB, _kernel_mpfcb_table);$NL$
+$END$
+$NL$
+
+$
+$ 周期ハンドラ
+$
+/*$NL$
+$SPC$* Cyclic Handler Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 周期ハンドラID番号の最大値
+const ID _kernel_tmax_cycid = (TMIN_CYCID + TNUM_CYCID - 1);$NL$
+$NL$
+
+$ 周期ハンドラ初期化テーブルの生成
+$IF LENGTH(CYC.ID_LIST)$
+ const CYCINIB _kernel_cycinib_table[TNUM_CYCID] = {$NL$
+ $JOINEACH cycid CYC.ID_LIST ",\n"$
+$ // cycatrが([TA_STA])でない場合(E_RSATR)
+ $IF (CYC.CYCATR[cycid] & ~TA_STA) != 0$
+ $ERROR CYC.TEXT_LINE[cycid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "cycatr", CYC.CYCATR[cycid], cycid, "CRE_CYC")$$END$
+ $END$
+
+$ // (0 < cyctim && cyctim <= TMAX_RELTIM)でない場合(E_PAR)
+ $IF !(0 < CYC.CYCTIM[cycid] && CYC.CYCTIM[cycid] <= TMAX_RELTIM)$
+ $ERROR CYC.TEXT_LINE[cycid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "cyctim", CYC.CYCTIM[cycid], cycid, "CRE_CYC")$$END$
+ $END$
+
+$ // (0 <= cycphs && cycphs <= TMAX_RELTIM)でない場合(E_PAR)
+ $IF !(0 <= CYC.CYCPHS[cycid] && CYC.CYCPHS[cycid] <= TMAX_RELTIM)$
+ $ERROR CYC.TEXT_LINE[cycid]$E_PAR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "cycphs", CYC.CYCPHS[cycid], cycid, "CRE_CYC")$$END$
+ $END$
+
+$ // 警告:cycatrにTA_STAが設定されていて,(cycphs == 0)の場合
+ $IF (CYC.CYCATR[cycid] & TA_STA) != 0 && CYC.CYCPHS[cycid] == 0$
+ $WARNING CYC.TEXT_LINE[cycid]$$FORMAT(_("%1% is not recommended when %2% is set to %3% in %4%"), "cycphs==0", "TA_STA", "cycatr", "CRE_CYC")$$END$
+ $END$
+
+$ // 周期ハンドラ初期化ブロック
+ $TAB${ ($CYC.CYCATR[cycid]$), (intptr_t)($CYC.EXINF[cycid]$), ($CYC.CYCHDR[cycid]$), ($CYC.CYCTIM[cycid]$), ($CYC.CYCPHS[cycid]$) }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // 周期ハンドラコントロールブロック
+ CYCCB _kernel_cyccb_table[TNUM_CYCID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const CYCINIB, _kernel_cycinib_table);$NL$
+ TOPPERS_EMPTY_LABEL(CYCCB, _kernel_cyccb_table);$NL$
+$END$
+$NL$
+
+$
+$ アラームハンドラ
+$
+/*$NL$
+$SPC$* Alarm Handler Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ アラームハンドラID番号の最大値
+const ID _kernel_tmax_almid = (TMIN_ALMID + TNUM_ALMID - 1);$NL$
+$NL$
+
+$ アラームハンドラ初期化ブロックの生成
+$IF LENGTH(ALM.ID_LIST)$
+ const ALMINIB _kernel_alminib_table[TNUM_ALMID] = {$NL$
+ $JOINEACH almid ALM.ID_LIST ",\n"$
+$ // almatrが(TA_NULL)でない場合(E_RSATR)
+ $IF ALM.ALMATR[almid] != 0$
+ $ERROR ALM.TEXT_LINE[almid]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of `%3%\' in %4%"), "almatr", ALM.ALMATR[almid], almid, "CRE_ALM")$$END$
+ $END$
+
+$ // アラームハンドラ初期化ブロック
+ $TAB${ ($ALM.ALMATR[almid]$), (intptr_t)($ALM.EXINF[almid]$), ($ALM.ALMHDR[almid]$) }
+ $END$$NL$
+ };$NL$
+ $NL$
+
+$ // アラームハンドラコントロールブロック
+ ALMCB _kernel_almcb_table[TNUM_ALMID];$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const ALMINIB, _kernel_alminib_table);$NL$
+ TOPPERS_EMPTY_LABEL(ALMCB, _kernel_almcb_table);$NL$
+$END$
+$NL$
+
+$
+$ 割込み管理機能
+$
+/*$NL$
+$SPC$* Interrupt Management Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ 割込み番号と割込みハンドラ番号の変換テーブルの作成
+$IF LENGTH(INTNO_ATTISR_VALID) != LENGTH(INHNO_ATTISR_VALID)$
+ $ERROR$length of `INTNO_ATTISR_VALID' is different from length of `INHNO_ATTISR_VALID'$END$
+$END$
+$i = 0$
+$FOREACH intno INTNO_ATTISR_VALID$
+ $inhno = AT(INHNO_ATTISR_VALID, i)$
+ $INHNO[intno] = inhno$
+ $INTNO[inhno] = intno$
+ $i = i + 1$
+$END$
+
+$ 割込み要求ラインに関するエラーチェック
+$i = 0$
+$FOREACH intno INT.ORDER_LIST$
+$ // intnoがCFG_INTに対する割込み番号として正しくない場合(E_PAR)
+ $IF !LENGTH(FIND(INTNO_CFGINT_VALID, INT.INTNO[intno]))$
+ $ERROR INT.TEXT_LINE[intno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "intno", INT.INTNO[intno], "CFG_INT")$$END$
+ $END$
+
+$ // intnoがCFG_INTによって設定済みの場合(E_OBJ)
+ $j = 0$
+ $FOREACH intno2 INT.ORDER_LIST$
+ $IF INT.INTNO[intno] == INT.INTNO[intno2] && j < i$
+ $ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' in %3% is duplicated"), "intno", INT.INTNO[intno], "CFG_INT")$$END$
+ $END$
+ $j = j + 1$
+ $END$
+
+$ // intatrが([TA_ENAINT]|[TA_EDGE])でない場合(E_RSATR)
+ $IF (INT.INTATR[intno] & ~(TA_ENAINT|TA_EDGE|ALT(TARGET_INTATR,0))) != 0$
+ $ERROR INT.TEXT_LINE[intno]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "intatr", INT.INTATR[intno], "intno", INT.INTNO[intno], "CFG_INT")$$END$
+ $END$
+
+$ // intpriがCFG_INTに対する割込み優先度として正しくない場合(E_PAR)
+ $IF !LENGTH(FIND(INTPRI_CFGINT_VALID, INT.INTPRI[intno]))$
+ $ERROR INT.TEXT_LINE[intno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "intpri", INT.INTPRI[intno], "CFG_INT")$$END$
+ $END$
+
+$ // カーネル管理に固定されているintnoに対して,intpriにTMIN_INTPRI
+$ // よりも小さい値が指定された場合(E_OBJ)
+ $IF LENGTH(FIND(INTNO_FIX_KERNEL, intno))$
+ $IF INT.INTPRI[intno] < TMIN_INTPRI$
+ $ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' must not have higher priority than %3%"), "intno", INT.INTNO[intno], "TMIN_INTPRI")$$END$
+ $END$
+ $END$
+
+$ // カーネル管理外に固定されているintnoに対して,intpriにTMIN_INTPRI
+$ // よりも小さい値が指定されなかった場合(E_OBJ)
+ $IF LENGTH(FIND(INTNO_FIX_NONKERNEL, intno))$
+ $IF INT.INTPRI[intno] >= TMIN_INTPRI$
+ $ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' must have higher priority than %3%"), "intno", INT.INTNO[intno], "TMIN_INTPRI")$$END$
+ $END$
+ $END$
+ $i = i + 1$
+$END$
+
+$ 割込みハンドラに関するエラーチェック
+$i = 0$
+$FOREACH inhno INH.ORDER_LIST$
+$ // inhnoがDEF_INHに対する割込みハンドラ番号として正しくない場合(E_PAR)
+ $IF !LENGTH(FIND(INHNO_DEFINH_VALID, INH.INHNO[inhno]))$
+ $ERROR INH.TEXT_LINE[inhno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "inhno", INH.INHNO[inhno], "DEF_INH")$$END$
+ $END$
+
+$ // inhnoがDEF_INHによって設定済みの場合(E_OBJ)
+ $j = 0$
+ $FOREACH inhno2 INH.ORDER_LIST$
+ $IF INH.INHNO[inhno] == INH.INHNO[inhno2] && j < i$
+ $ERROR INH.TEXT_LINE[inhno]$E_OBJ: $FORMAT(_("%1% `%2%\' in %3% is duplicated"), "inhno", INH.INHNO[inhno], "DEF_INH")$$END$
+ $END$
+ $j = j + 1$
+ $END$
+
+$ // inhatrが(TA_NULL)でない場合(E_RSATR)
+ $IF (INH.INHATR[inhno] & ~ALT(TARGET_INHATR,0)) != 0$
+ $ERROR INH.TEXT_LINE[inhno]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "inhatr", INH.INHATR[inhno], "inhno", INH.INHNO[inhno], "DEF_INH")$$END$
+ $END$
+
+$ // カーネル管理に固定されているinhnoに対して,inhatrにTA_NONKERNEL
+$ // が指定されている場合(E_RSATR)
+ $IF LENGTH(FIND(INHNO_FIX_KERNEL, inhno))$
+ $IF (INH.INHATR[inhno] & TA_NONKERNEL) != 0$
+ $ERROR INH.TEXT_LINE[inhno]$E_RSATR: $FORMAT(_("%1% `%2%\' must not be non-kernel interrupt"), "inhno", INH.INHNO[inhno])$$END$
+ $END$
+ $END$
+
+$ // カーネル管理外に固定されているinhnoに対して,inhatrにTA_NONKERNEL
+$ // が指定されていない場合(E_RSATR)
+ $IF LENGTH(FIND(INHNO_FIX_NONKERNEL, inhno))$
+ $IF (INH.INHATR[inhno] & TA_NONKERNEL) == 0$
+ $ERROR INH.TEXT_LINE[inhno]$E_RSATR: $FORMAT(_("%1% `%2%\' must be non-kernel interrupt"), "inhno", INH.INHNO[inhno])$$END$
+ $END$
+ $END$
+
+ $IF LENGTH(INTNO[INH.INHNO[inhno]])$
+ $intno = INTNO[INH.INHNO[inhno]]$
+ $IF LENGTH(FIND(INTNO_CFGINT_VALID, intno))$
+$ // inhnoに対応するintnoに対するCFG_INTがない場合(E_OBJ)
+ $IF !LENGTH(INT.INTNO[intno])$
+ $ERROR INH.TEXT_LINE[inhno]$E_OBJ: $FORMAT(_("%1% `%2%\' corresponding to %3% `%4%\' is not configured with %5%"), "intno", INT.INTNO[intno], "inhno", INH.INHNO[inhno], "CFG_INT")$$END$
+ $ELSE$
+ $IF (INH.INHATR[inhno] & TA_NONKERNEL) == 0$
+$ // inhatrにTA_NONKERNELが指定されておらず,inhnoに対応
+$ // するintnoに対してCFG_INTで設定された割込み優先度が
+$ // TMIN_INTPRIよりも小さい場合(E_OBJ)
+ $IF INT.INTPRI[intno] < TMIN_INTPRI$
+ $ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' configured for %3% `%4%\' is higher than %5%"), "intpri", INT.INTPRI[intno], "inhno", INH.INHNO[inhno], "TMIN_INTPRI")$$END$
+ $END$
+ $ELSE$
+$ // inhatrにTA_NONKERNELが指定されており,inhnoに対応
+$ // するintnoに対してCFG_INTで設定された割込み優先度が
+$ // TMIN_INTPRI以上である場合(E_OBJ)
+ $IF INT.INTPRI[intno] >= TMIN_INTPRI$
+ $ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' configured for %3% `%4%\' is lower than or equal to %5%"), "intpri", INT.INTPRI[intno], "inhno", INH.INHNO[inhno], "TMIN_INTPRI")$$END$
+ $END$
+ $END$
+ $END$
+ $END$
+ $END$
+ $i = i + 1$
+$END$
+
+$ 割込みサービスルーチン(ISR)に関するエラーチェックと割込みハンドラの生成
+$FOREACH order ISR.ORDER_LIST$
+$ // isratrが(TA_NULL)でない場合(E_RSATR)
+ $IF (ISR.ISRATR[order] & ~ALT(TARGET_ISRATR,0)) != 0$
+ $ERROR ISR.TEXT_LINE[order]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "isratr", ISR.ISRATR[order], "isr", ISR.ISR[order], "ATT_ISR")$$END$
+ $END$
+
+$ // intnoがATT_ISRに対する割込み番号として正しくない場合(E_PAR)
+ $IF !LENGTH(FIND(INTNO_ATTISR_VALID, ISR.INTNO[order]))$
+ $ERROR ISR.TEXT_LINE[order]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "intno", ISR.INTNO[order], "ATT_ISR")$$END$
+ $END$
+
+$ // (TMIN_ISRPRI <= isrpri && isrpri <= TMAX_ISRPRI)でない場合(E_PAR)
+ $IF !(TMIN_ISRPRI <= ISR.ISRPRI[order] && ISR.ISRPRI[order] <= TMAX_ISRPRI)$
+ $ERROR ISR.TEXT_LINE[order]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "isrpri", ISR.ISRPRI[order], "ATT_ISR")$$END$
+ $END$
+$END$
+
+$FOREACH intno INTNO_ATTISR_VALID$
+ $inhno = INHNO[intno]$
+
+$ // 割込み番号intnoに対して登録されたISRのリストの作成
+ $isr_order_list = {}$
+ $FOREACH order ISR.ORDER_LIST$
+ $IF ISR.INTNO[order] == intno$
+ $isr_order_list = APPEND(isr_order_list, order)$
+ $order_for_error = order$
+ $END$
+ $END$
+
+$ // 割込み番号intnoに対して登録されたISRが存在する場合
+ $IF LENGTH(isr_order_list) > 0$
+$ // intnoに対応するinhnoに対してDEF_INHがある場合(E_OBJ)
+ $IF LENGTH(INH.INHNO[inhno])$
+ $ERROR ISR.TEXT_LINE[order_for_error]$E_OBJ: $FORMAT(_("%1% `%2%\' in %3% is duplicated with %4% `%5%\'"), "intno", ISR.INTNO[order_for_error], "ATT_ISR", "inhno", INH.INHNO[inhno])$$END$
+ $END$
+
+$ // intnoに対するCFG_INTがない場合(E_OBJ)
+ $IF !LENGTH(INT.INTNO[intno])$
+ $ERROR ISR.TEXT_LINE[order_for_error]$E_OBJ: $FORMAT(_("%1% `%2%\' is not configured with %3%"), "intno", ISR.INTNO[order_for_error], "CFG_INT")$$END$
+ $ELSE$
+$ // intnoに対してCFG_INTで設定された割込み優先度がTMIN_INTPRI
+$ // よりも小さい場合(E_OBJ)
+ $IF INT.INTPRI[intno] < TMIN_INTPRI$
+ $ERROR INT.TEXT_LINE[intno]$E_OBJ: $FORMAT(_("%1% `%2%\' configured for %3% `%4%\' is higher than %5%"), "intpri", INT.INTPRI[intno], "intno", ISR.INTNO[order_for_error], "TMIN_INTPRI")$$END$
+ $END$
+ $END$
+
+$ // DEF_INH(inhno, { TA_NULL, _kernel_inthdr_<intno> } );
+ $INH.INHNO[inhno] = inhno$
+ $INH.INHATR[inhno] = VALUE("TA_NULL", 0)$
+ $INH.INTHDR[inhno] = CONCAT("_kernel_inthdr_", intno)$
+ $INH.ORDER_LIST = APPEND(INH.ORDER_LIST, inhno)$
+
+$ // ISR用の割込みハンドラ
+ void$NL$
+ _kernel_inthdr_$intno$(void)$NL$
+ {$NL$
+ $IF LENGTH(isr_order_list) > 1$
+ $TAB$PRI saved_ipm;$NL$
+ $NL$
+ $TAB$i_begin_int($intno$);$NL$
+ $TAB$saved_ipm = i_get_ipm();$NL$
+ $ELSE$
+ $TAB$i_begin_int($intno$);$NL$
+ $END$
+$ // ISRを優先度順に呼び出す
+ $JOINEACH order SORT(isr_order_list, "ISR.ISRPRI") "\tif (i_sense_lock()) {\n\t\ti_unlock_cpu();\n\t}\n\ti_set_ipm(saved_ipm);\n"$
+ $TAB$LOG_ISR_ENTER($intno$);$NL$
+ $TAB$((ISR)($ISR.ISR[order]$))((intptr_t)($ISR.EXINF[order]$));$NL$
+ $TAB$LOG_ISR_LEAVE($intno$);$NL$
+ $END$
+ $TAB$i_end_int($intno$);$NL$
+ }$NL$
+ $END$
+$END$
+$NL$
+
+$
+$ 割込み管理機能のための標準的な初期化情報の生成
+$
+$ 割込みハンドラの初期化に必要な情報
+$IF !ALT(OMIT_INITIALIZE_INTERRUPT,0) || ALT(USE_INHINIB_TABLE,0)$
+
+$ 割込みハンドラ数
+#define TNUM_INHNO $LENGTH(INH.ORDER_LIST)$$NL$
+const uint_t _kernel_tnum_inhno = TNUM_INHNO;$NL$
+$NL$
+$FOREACH inhno INH.ORDER_LIST$
+ $IF (INH.INHATR[inhno] & TA_NONKERNEL) == 0$
+ INTHDR_ENTRY($INH.INHNO[inhno]$, $+INH.INHNO[inhno]$, $INH.INTHDR[inhno]$)$NL$
+ $END$
+$END$
+$NL$
+
+$ 割込みハンドラ初期化テーブル
+$IF LENGTH(INH.ORDER_LIST)$
+ const INHINIB _kernel_inhinib_table[TNUM_INHNO] = {$NL$
+ $JOINEACH inhno INH.ORDER_LIST ",\n"$
+ $IF (INH.INHATR[inhno] & TA_NONKERNEL) == 0$
+ $TAB${ ($INH.INHNO[inhno]$), ($INH.INHATR[inhno]$), (FP)(INT_ENTRY($INH.INHNO[inhno]$, $INH.INTHDR[inhno]$)) }
+ $ELSE$
+ $TAB${ ($INH.INHNO[inhno]$), ($INH.INHATR[inhno]$), (FP)($INH.INTHDR[inhno]$) }
+ $END$
+ $END$$NL$
+ };$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const INHINIB, _kernel_inhinib_table);$NL$
+$END$
+$NL$
+$END$
+
+$ 割込み要求ラインの初期化に必要な情報
+$IF !ALT(OMIT_INITIALIZE_INTERRUPT,0) || ALT(USE_INHINTB_TABLE,0)$
+
+$ 割込み要求ライン数
+#define TNUM_INTNO $LENGTH(INT.ORDER_LIST)$$NL$
+const uint_t _kernel_tnum_intno = TNUM_INTNO;$NL$
+$NL$
+
+$ 割込み要求ライン初期化テーブル
+$IF LENGTH(INT.ORDER_LIST)$
+ const INTINIB _kernel_intinib_table[TNUM_INTNO] = {$NL$
+ $JOINEACH intno INT.ORDER_LIST ",\n"$
+ $TAB${ ($INT.INTNO[intno]$), ($INT.INTATR[intno]$), ($INT.INTPRI[intno]$) }
+ $END$$NL$
+ };$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const INTINIB, _kernel_intinib_table);$NL$
+$END$
+$NL$
+$END$
+
+$
+$ CPU例外管理機能
+$
+/*$NL$
+$SPC$* CPU Exception Management Functions$NL$
+$SPC$*/$NL$
+$NL$
+
+$ CPU例外ハンドラに関するエラーチェック
+$i = 0$
+$FOREACH excno EXC.ORDER_LIST$
+$ // excnoがDEF_EXCに対するCPU例外ハンドラ番号として正しくない場合(E_PAR)
+ $IF !LENGTH(FIND(EXCNO_DEFEXC_VALID, EXC.EXCNO[excno]))$
+ $ERROR EXC.TEXT_LINE[excno]$E_PAR: $FORMAT(_("illegal %1% `%2%\' in %3%"), "excno", EXC.EXCNO[excno], "DEF_EXC")$$END$
+ $END$
+
+$ // excnoがDEF_EXCによって設定済みの場合(E_OBJ)
+ $j = 0$
+ $FOREACH excno2 EXC.ORDER_LIST$
+ $IF EXC.EXCNO[excno] == EXC.EXCNO[excno2] && j < i$
+ $ERROR EXC.TEXT_LINE[excno]$E_OBJ: $FORMAT(_("%1% `%2%\' in %3% is duplicated"), "excno", EXC.EXCNO[excno], "DEF_EXC")$$END$
+ $END$
+ $j = j + 1$
+ $END$
+
+$ // excatrが(TA_NULL)でない場合(E_RSATR)
+ $IF (EXC.EXCATR[excno] & ~ALT(TARGET_EXCATR,0)) != 0$
+ $ERROR EXC.TEXT_LINE[excno]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "excatr", EXC.EXCATR[excno], "excno", EXC.EXCNO[excno], "DEF_EXC")$$END$
+ $END$
+ $i = i + 1$
+$END$
+
+$ CPU例外ハンドラのための標準的な初期化情報の生成
+$IF !ALT(OMIT_INITIALIZE_EXCEPTION,0)$
+
+$ CPU例外ハンドラ数
+#define TNUM_EXCNO $LENGTH(EXC.ORDER_LIST)$$NL$
+const uint_t _kernel_tnum_excno = TNUM_EXCNO;$NL$
+$NL$
+$FOREACH excno EXC.ORDER_LIST$
+ EXCHDR_ENTRY($EXC.EXCNO[excno]$, $+EXC.EXCNO[excno]$, $EXC.EXCHDR[excno]$)$NL$
+$END$
+$NL$
+
+$ CPU例外ハンドラ初期化テーブル
+$IF LENGTH(EXC.ORDER_LIST)$
+ const EXCINIB _kernel_excinib_table[TNUM_EXCNO] = {$NL$
+ $JOINEACH excno EXC.ORDER_LIST ",\n"$
+ $TAB${ ($EXC.EXCNO[excno]$), ($EXC.EXCATR[excno]$), (FP)(EXC_ENTRY($EXC.EXCNO[excno]$, $EXC.EXCHDR[excno]$)) }
+ $END$$NL$
+ };$NL$
+$ELSE$
+ TOPPERS_EMPTY_LABEL(const EXCINIB, _kernel_excinib_table);$NL$
+$END$
+$NL$
+$END$
+
+$
+$ 非タスクコンテキスト用のスタック領域
+$
+/*$NL$
+$SPC$* Stack Area for Non-task Context$NL$
+$SPC$*/$NL$
+$NL$
+
+$IF !LENGTH(ICS.ORDER_LIST)$
+$ // DEF_ICSがない場合のデフォルト値の設定
+ #ifdef DEFAULT_ISTK$NL$
+ $NL$
+ #define TOPPERS_ISTKSZ DEFAULT_ISTKSZ$NL$
+ #define TOPPERS_ISTK DEFAULT_ISTK$NL$
+ $NL$
+ #else /* DEAULT_ISTK */$NL$
+ $NL$
+ static STK_T _kernel_istack[COUNT_STK_T(DEFAULT_ISTKSZ)];$NL$
+ #define TOPPERS_ISTKSZ ROUND_STK_T(DEFAULT_ISTKSZ)$NL$
+ #define TOPPERS_ISTK _kernel_istack$NL$
+ $NL$
+ #endif /* DEAULT_ISTK */$NL$
+$ELSE$
+
+$ // 静的API「DEF_ICS」が複数ある(E_OBJ)
+ $IF LENGTH(ICS.ORDER_LIST) > 1$
+ $ERROR$E_OBJ: $FORMAT(_("too many %1%"), "DEF_ICS")$$END$
+ $END$
+
+$ // istkszがスタック領域のサイズとして正しくない場合(E_PAR)
+ $IF !EQ(ICS.ISTK[1], "NULL") && LENGTH(CHECK_STKSZ_ALIGN)
+ && (ICS.ISTKSZ[1] & (CHECK_STKSZ_ALIGN - 1))$
+ $ERROR ICS.TEXT_LINE[1]$E_PAR: $FORMAT(_("%1% `%2%\' in %3% is not aligned"), "istksz", ICS.ISTKSZ[1], "DEF_ICS")$$END$
+ $END$
+
+ $IF EQ(ICS.ISTK[1], "NULL")$
+$ // スタック領域の自動割付け
+ static STK_T _kernel_istack[COUNT_STK_T($ICS.ISTKSZ[1]$)];$NL$
+ #define TOPPERS_ISTKSZ ROUND_STK_T($ICS.ISTKSZ[1]$)$NL$
+ #define TOPPERS_ISTK _kernel_istack$NL$
+ $ELSE$
+ #define TOPPERS_ISTKSZ ($ICS.ISTKSZ[1]$)$NL$
+ #define TOPPERS_ISTK ($ICS.ISTK[1]$)$NL$
+ $END$
+$END$
+$NL$
+
+$ 非タスクコンテキスト用のスタック領域
+const SIZE _kernel_istksz = TOPPERS_ISTKSZ;$NL$
+STK_T *const _kernel_istk = TOPPERS_ISTK;$NL$
+$NL$
+#ifdef TOPPERS_ISTKPT$NL$
+STK_T *const _kernel_istkpt = TOPPERS_ISTKPT(TOPPERS_ISTK, TOPPERS_ISTKSZ);$NL$
+#endif /* TOPPERS_ISTKPT */$NL$
+$NL$
+
+$
+$ タイムイベント管理
+$
+/*$NL$
+$SPC$* Time Event Management$NL$
+$SPC$*/$NL$
+$NL$
+TMEVTN _kernel_tmevt_heap[TNUM_TSKID + TNUM_CYCID + TNUM_ALMID];$NL$
+$NL$
+
+$
+$ 各モジュールの初期化関数
+$
+/*$NL$
+$SPC$* Module Initialization Function$NL$
+$SPC$*/$NL$
+$NL$
+void$NL$
+_kernel_initialize_object(void)$NL$
+{$NL$
+$TAB$_kernel_initialize_task();$NL$
+$IF LENGTH(SEM.ID_LIST)$ _kernel_initialize_semaphore();$NL$$END$
+$IF LENGTH(FLG.ID_LIST)$ _kernel_initialize_eventflag();$NL$$END$
+$IF LENGTH(DTQ.ID_LIST)$ _kernel_initialize_dataqueue();$NL$$END$
+$IF LENGTH(PDQ.ID_LIST)$ _kernel_initialize_pridataq();$NL$$END$
+$IF LENGTH(MBX.ID_LIST)$ _kernel_initialize_mailbox();$NL$$END$
+$IF LENGTH(MPF.ID_LIST)$ _kernel_initialize_mempfix();$NL$$END$
+$IF LENGTH(CYC.ID_LIST)$ _kernel_initialize_cyclic();$NL$$END$
+$IF LENGTH(ALM.ID_LIST)$ _kernel_initialize_alarm();$NL$$END$
+$TAB$_kernel_initialize_interrupt();$NL$
+$TAB$_kernel_initialize_exception();$NL$
+}$NL$
+$NL$
+
+$
+$ 初期化ルーチンの実行関数
+$
+/*$NL$
+$SPC$* Initialization Routine$NL$
+$SPC$*/$NL$
+$NL$
+void$NL$
+_kernel_call_inirtn(void)$NL$
+{$NL$
+$FOREACH order INI.ORDER_LIST$
+$ // iniatrが(TA_NULL)でない場合(E_RSATR)
+ $IF INI.INIATR[order] != 0$
+ $ERROR INI.TEXT_LINE[order]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "iniatr", INI.INIATR[order], "inirtn", INI.INIRTN[order], "ATT_INI")$$END$
+ $END$
+ $TAB$((INIRTN)($INI.INIRTN[order]$))((intptr_t)($INI.EXINF[order]$));$NL$
+$END$
+}$NL$
+$NL$
+
+$
+$ 終了処理ルーチンの実行関数
+$
+/*$NL$
+$SPC$* Termination Routine$NL$
+$SPC$*/$NL$
+$NL$
+void$NL$
+_kernel_call_terrtn(void)$NL$
+{$NL$
+$FOREACH rorder TER.RORDER_LIST$
+$ // teratrが(TA_NULL)でない場合(E_RSATR)
+ $IF TER.TERATR[rorder] != 0$
+ $ERROR TER.TEXT_LINE[rorder]$E_RSATR: $FORMAT(_("illegal %1% `%2%\' of %3% `%4%\' in %5%"), "teratr", TER.TERATR[rorder], "terrtn", TER.TERRTN[rorder], "ATT_TER")$$END$
+ $END$
+ $TAB$((TERRTN)($TER.TERRTN[rorder]$))((intptr_t)($TER.EXINF[rorder]$));$NL$
+$END$
+}$NL$
+$NL$
+
+$ =====================================================================
+$ TraceLogVisualizerを使用するためのインクルード
+$ =====================================================================
+$INCLUDE"arch/logtrace/tlv.tf"$
+
--- /dev/null
+tsk,CRE_TSK,#tskid { .tskatr &exinf &task +itskpri .stksz &stk },,
+tsk,DEF_TEX,%tskid { .texatr &texrtn },0,1,
+sem,CRE_SEM,#semid { .sematr .isemcnt .maxsem },,
+flg,CRE_FLG,#flgid { .flgatr .iflgptn },,
+dtq,CRE_DTQ,#dtqid { .dtqatr .dtqcnt &dtqmb },,
+pdq,CRE_PDQ,#pdqid { .pdqatr .pdqcnt +maxdpri &pdqmb },,
+mbx,CRE_MBX,#mbxid { .mbxatr +maxmpri &mprihd },,
+mpf,CRE_MPF,#mpfid { .mpfatr .blkcnt .blksz &mpf &mpfmb },,
+cyc,CRE_CYC,#cycid { .cycatr &exinf &cychdr .cyctim .cycphs },,
+alm,CRE_ALM,#almid { .almatr &exinf &almhdr },,
+int,CFG_INT,.intno { .intatr +intpri },,
+isr,ATT_ISR,{ .isratr &exinf .intno &isr +isrpri },-1,
+inh,DEF_INH,.inhno { .inhatr &inthdr },,
+ics,DEF_ICS,{ .istksz &istk },-1,
+exc,DEF_EXC,.excno { .excatr &exchdr },,
+ini,ATT_INI,{ .iniatr &exinf &inirtn },-1,
+ter,ATT_TER,{ .teratr &exinf &terrtn },-1,
--- /dev/null
+$ ======================================================================
+$
+$ TOPPERS/ASP Kernel
+$ Toyohashi Open Platform for Embedded Real-Time Systems/
+$ Advanced Standard Profile Kernel
+$
+$ Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
+$ Graduate School of Information Science, Nagoya Univ., JAPAN
+$
+$ 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+$ ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+$ 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+$ (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+$ 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+$ スコード中に含まれていること.
+$ (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+$ 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+$ 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+$ の無保証規定を掲載すること.
+$ (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+$ 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+$ と.
+$ (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+$ 作権表示,この利用条件および下記の無保証規定を掲載すること.
+$ (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+$ 報告すること.
+$ (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+$ 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+$ また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+$ 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+$ 免責すること.
+$
+$ 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+$ よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+$ に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+$ アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+$ の責任を負わない.
+$
+$ @(#) $Id: kernel_check.tf 1755 2010-02-14 02:37:36Z ertl-hiro $
+$
+$ =====================================================================
+
+$
+$ 関数の先頭番地のチェック
+$
+$IF LENGTH(CHECK_FUNC_ALIGN) || LENGTH(CHECK_FUNC_NONNULL)$
+$ // タスクとタスク例外処理ルーチンの先頭番地のチェック
+ $tinib = SYMBOL("_kernel_tinib_table")$
+ $FOREACH tskid TSK.ID_LIST$
+ $task = PEEK(tinib + offsetof_TINIB_task, sizeof_FP)$
+ $IF LENGTH(CHECK_FUNC_ALIGN) && (task & (CHECK_FUNC_ALIGN - 1))$
+ $ERROR TSK.TEXT_LINE[tskid]$E_PAR:
+ $FORMAT(_("%1% `%2%\' of `%3%\' in %4% is not aligned"),
+ "task", TSK.TASK[tskid], tskid, "CRE_TSK")$$END$
+ $END$
+ $IF LENGTH(CHECK_FUNC_NONNULL) && (task == 0)$
+ $ERROR TSK.TEXT_LINE[tskid]$E_PAR:
+ $FORMAT(_("%1% `%2%\' of `%3%\' in %4% is null"),
+ "task", TSK.TASK[tskid], tskid, "CRE_TSK")$$END$
+ $END$
+ $texrtn = PEEK(tinib + offsetof_TINIB_texrtn, sizeof_FP)$
+ $IF LENGTH(CHECK_FUNC_ALIGN) && (texrtn & (CHECK_FUNC_ALIGN - 1))$
+ $ERROR DEF_TEX.TEXT_LINE[tskid]$E_PAR:
+ $FORMAT(_("%1% `%2%\' of `%3%\' in %4% is not aligned"),
+ "texrtn", TSK.TEXRTN[tskid], tskid, "DEF_TEX")$$END$
+ $END$
+ $tinib = tinib + sizeof_TINIB$
+ $END$
+
+$ // 周期ハンドラの先頭番地のチェック
+ $cycinib = SYMBOL("_kernel_cycinib_table")$
+ $FOREACH cycid CYC.ID_LIST$
+ $cychdr = PEEK(cycinib + offsetof_CYCINIB_cychdr, 4)$
+ $IF LENGTH(CHECK_FUNC_ALIGN) && (cychdr & (CHECK_FUNC_ALIGN - 1))$
+ $ERROR CYC.TEXT_LINE[cycid]$E_PAR:
+ $FORMAT(_("%1% `%2%\' of `%3%\' in %4% is not aligned"),
+ "cychdr", CYC.CYCHDR[cycid], cycid, "CRE_CYC")$$END$
+ $END$
+ $IF LENGTH(CHECK_FUNC_NONNULL) && (cychdr == 0)$
+ $ERROR CYC.TEXT_LINE[cycid]$E_PAR:
+ $FORMAT(_("%1% `%2%\' of `%3%\' in %4% is null"),
+ "cychdr", CYC.CYCHDR[cycid], cycid, "CRE_CYC")$$END$
+ $END$
+ $cycinib = cycinib + sizeof_CYCINIB$
+ $END$
+
+$ // アラームハンドラの先頭番地のチェック
+ $alminib = SYMBOL("_kernel_alminib_table")$
+ $FOREACH almid ALM.ID_LIST$
+ $almhdr = PEEK(alminib + offsetof_ALMINIB_almhdr, 4)$
+ $IF LENGTH(CHECK_FUNC_ALIGN) && (almhdr & (CHECK_FUNC_ALIGN - 1))$
+ $ERROR ALM.TEXT_LINE[almid]$E_PAR:
+ $FORMAT(_("%1% `%2%\' of `%3%\' in %4% is not aligned"),
+ "almhdr", ALM.ALMHDR[almid], almid, "CRE_ALM")$$END$
+ $END$
+ $IF LENGTH(CHECK_FUNC_NONNULL) && (almhdr == 0)$
+ $ERROR ALM.TEXT_LINE[almid]$E_PAR:
+ $FORMAT(_("%1% `%2%\' of `%3%\' in %4% is null"),
+ "almhdr", ALM.ALMHDR[almid], almid, "CRE_ALM")$$END$
+ $END$
+ $alminib = alminib + sizeof_ALMINIB$
+ $END$
+$END$
+
+$
+$ スタック領域の先頭番地のチェック
+$
+$IF LENGTH(CHECK_STACK_ALIGN) || LENGTH(CHECK_STACK_NONNULL)$
+$ // タスクのスタック領域の先頭番地のチェック
+ $IF !ALT(USE_TSKINICTXB,0)$
+ $tinib = SYMBOL("_kernel_tinib_table")$
+ $FOREACH tskid TSK.ID_LIST$
+ $stk = PEEK(tinib + offsetof_TINIB_stk, sizeof_void_ptr)$
+ $IF LENGTH(CHECK_STACK_ALIGN) && (stk & (CHECK_STACK_ALIGN - 1))$
+ $ERROR TSK.TEXT_LINE[tskid]$E_PAR:
+ $FORMAT(_("%1% `%2%\' of `%3%\' in %4% is not aligned"),
+ "stk", TSK.STK[tskid], tskid, "CRE_TSK")$$END$
+ $END$
+ $IF LENGTH(CHECK_STACK_NONNULL) && (stk == 0)$
+ $ERROR TSK.TEXT_LINE[tskid]$E_PAR:
+ $FORMAT(_("%1% `%2%\' of `%3%\' in %4% is null"),
+ "stk", TSK.STK[tskid], tskid, "CRE_TSK")$$END$
+ $END$
+ $tinib = tinib + sizeof_TINIB$
+ $END$
+ $END$
+
+$ // 非タスクコンテキスト用のスタック領域の先頭番地のチェック
+ $istk = PEEK(SYMBOL("_kernel_istk"), sizeof_void_ptr)$
+ $IF LENGTH(CHECK_STACK_ALIGN) && (istk & (CHECK_STACK_ALIGN - 1))$
+ $ERROR ICE.TEXT_LINE[1]$E_PAR:
+ $FORMAT(_("%1% `%2%\' in %3% is not aligned"),
+ "istk", ICS.ISTK[1], "DEF_ICS")$$END$
+ $END$
+ $IF LENGTH(CHECK_STACK_NONNULL) && (istk == 0)$
+ $ERROR ICE.TEXT_LINE[1]$E_PAR:
+ $FORMAT(_("%1% `%2%\' in %3% is null"),
+ "istk", ICS.ISTK[1], "DEF_ICS")$$END$
+ $END$
+$END$
+
+$
+$ 固定長メモリプール領域の先頭番地のチェック
+$
+$IF LENGTH(CHECK_MPF_ALIGN) || LENGTH(CHECK_MPF_NONNULL)$
+$ // 固定長メモリプール領域の先頭番地のチェック
+ $mpfinib = SYMBOL("_kernel_mpfinib_table")$
+ $FOREACH mpfid MPF.ID_LIST$
+ $mpf = PEEK(mpfinib + offsetof_MPFINIB_mpf, sizeof_void_ptr)$
+ $IF LENGTH(CHECK_MPF_ALIGN) && (mpf & (CHECK_MPF_ALIGN - 1))$
+ $ERROR MPF.TEXT_LINE[mpfid]$E_PAR:
+ $FORMAT(_("%1% `%2%\' of `%3%\' in %4% is not aligned"),
+ "mpf", MPF.MPF[mpfid], mpfid, "CRE_MPF")$$END$
+ $END$
+ $IF LENGTH(CHECK_MPF_NONNULL) && (mpf == 0)$
+ $ERROR MPF.TEXT_LINE[mpfid]$E_PAR:
+ $FORMAT(_("%1% `%2%\' of `%3%\' in %4% is null"),
+ "mpf", MPF.MPF[mpfid], mpfid, "CRE_MPF")$$END$
+ $END$
+ $mpfinib = mpfinib + sizeof_MPFINIB$
+ $END$
+$END$
--- /dev/null
+TA_NULL,TA_NULL
+TA_ACT,TA_ACT
+TA_TPRI,TA_TPRI
+TA_MPRI,TA_MPRI
+TA_WMUL,TA_WMUL
+TA_CLR,TA_CLR
+TA_STA,TA_STA
+TA_NONKERNEL,TA_NONKERNEL
+TA_ENAINT,TA_ENAINT
+TA_EDGE,TA_EDGE
+TMIN_TPRI,TMIN_TPRI,signed
+TMAX_TPRI,TMAX_TPRI,signed
+TMIN_DPRI,TMIN_DPRI,signed
+TMAX_DPRI,TMAX_DPRI,signed
+TMIN_MPRI,TMIN_MPRI,signed
+TMAX_MPRI,TMAX_MPRI,signed
+TMIN_ISRPRI,TMIN_ISRPRI,signed
+TMAX_ISRPRI,TMAX_ISRPRI,signed
+TMAX_MAXSEM,TMAX_MAXSEM
+TMAX_RELTIM,TMAX_RELTIM
+TMIN_INTPRI,TMIN_INTPRI,signed
+OMIT_INITIALIZE_INTERRUPT,#defined(OMIT_INITIALIZE_INTERRUPT)
+OMIT_INITIALIZE_EXCEPTION,#defined(OMIT_INITIALIZE_EXCEPTION)
+USE_TSKINICTXB,#defined(USE_TSKINICTXB)
+sizeof_ID,sizeof(ID)
+sizeof_uint_t,sizeof(uint_t)
+sizeof_SIZE,sizeof(SIZE)
+sizeof_ATR,sizeof(ATR)
+sizeof_PRI,sizeof(PRI)
+sizeof_void_ptr,sizeof(void*)
+sizeof_VP,sizeof(void*)
+sizeof_intptr_t,sizeof(intptr_t)
+sizeof_FP,sizeof(FP)
+sizeof_TINIB,sizeof(TINIB)
+offsetof_TINIB_tskatr,"offsetof(TINIB,tskatr)"
+offsetof_TINIB_exinf,"offsetof(TINIB,exinf)"
+offsetof_TINIB_task,"offsetof(TINIB,task)"
+offsetof_TINIB_ipriority,"offsetof(TINIB,ipriority)"
+offsetof_TINIB_stksz,#!defined(USE_TSKINICTXB),,"offsetof(TINIB,stksz)"
+offsetof_TINIB_stk,#!defined(USE_TSKINICTXB),,"offsetof(TINIB,stk)"
+offsetof_TINIB_texatr,"offsetof(TINIB,texatr)"
+offsetof_TINIB_texrtn,"offsetof(TINIB,texrtn)"
+sizeof_SEMINIB,sizeof(SEMINIB)
+offsetof_SEMINIB_sematr,"offsetof(SEMINIB,sematr)"
+offsetof_SEMINIB_isemcnt,"offsetof(SEMINIB,isemcnt)"
+offsetof_SEMINIB_maxsem,"offsetof(SEMINIB,maxsem)"
+sizeof_FLGPTN,sizeof(FLGPTN)
+sizeof_FLGINIB,sizeof(FLGINIB)
+offsetof_FLGINIB_flgatr,"offsetof(FLGINIB,flgatr)"
+offsetof_FLGINIB_iflgptn,"offsetof(FLGINIB,iflgptn)"
+sizeof_DTQINIB,sizeof(DTQINIB)
+offsetof_DTQINIB_dtqatr,"offsetof(DTQINIB,dtqatr)"
+offsetof_DTQINIB_dtqcnt,"offsetof(DTQINIB,dtqcnt)"
+offsetof_DTQINIB_p_dtqmb,"offsetof(DTQINIB,p_dtqmb)"
+sizeof_PDQINIB,sizeof(PDQINIB)
+offsetof_PDQINIB_pdqatr,"offsetof(PDQINIB,pdqatr)"
+offsetof_PDQINIB_pdqcnt,"offsetof(PDQINIB,pdqcnt)"
+offsetof_PDQINIB_maxdpri,"offsetof(PDQINIB,maxdpri)"
+offsetof_PDQINIB_p_pdqmb,"offsetof(PDQINIB,p_pdqmb)"
+sizeof_MBXINIB,sizeof(MBXINIB)
+offsetof_MBXINIB_mbxatr,"offsetof(MBXINIB,mbxatr)"
+offsetof_MBXINIB_maxmpri,"offsetof(MBXINIB,maxmpri)"
+sizeof_MPFINIB,sizeof(MPFINIB)
+offsetof_MPFINIB_mpfatr,"offsetof(MPFINIB,mpfatr)"
+offsetof_MPFINIB_blkcnt,"offsetof(MPFINIB,blkcnt)"
+offsetof_MPFINIB_blksz,"offsetof(MPFINIB,blksz)"
+offsetof_MPFINIB_mpf,"offsetof(MPFINIB,mpf)"
+offsetof_MPFINIB_p_mpfmb,"offsetof(MPFINIB,p_mpfmb)"
+sizeof_CYCINIB,sizeof(CYCINIB)
+offsetof_CYCINIB_cycatr,"offsetof(CYCINIB,cycatr)"
+offsetof_CYCINIB_exinf,"offsetof(CYCINIB,exinf)"
+offsetof_CYCINIB_cychdr,"offsetof(CYCINIB,cychdr)"
+offsetof_CYCINIB_cyctim,"offsetof(CYCINIB,cyctim)"
+offsetof_CYCINIB_cycphs,"offsetof(CYCINIB,cycphs)"
+sizeof_ALMINIB,sizeof(ALMINIB)
+offsetof_ALMINIB_almatr,"offsetof(ALMINIB,almatr)"
+offsetof_ALMINIB_exinf,"offsetof(ALMINIB,exinf)"
+offsetof_ALMINIB_almhdr,"offsetof(ALMINIB,almhdr)"
+sizeof_INHNO,sizeof(INHNO)
+sizeof_INTNO,sizeof(INTNO)
+sizeof_EXCNO,sizeof(EXCNO)
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: kernel_impl.h 1713 2010-01-27 13:23:29Z ertl-hiro $
+ */
+
+/*
+ * TOPPERS/ASPカーネル内部向け標準ヘッダファイル
+ *
+ * このヘッダファイルは,カーネルを構成するプログラムのソースファイル
+ * で必ずインクルードするべき標準ヘッダファイルである.
+ *
+ * アセンブリ言語のソースファイルからこのファイルをインクルードする時
+ * は,TOPPERS_MACRO_ONLYを定義しておく.これにより,マクロ定義以外を
+ * 除くようになっている.
+ */
+
+#ifndef TOPPERS_KERNEL_IMPL_H
+#define TOPPERS_KERNEL_IMPL_H
+
+/*
+ * カーネルの内部識別名のリネーム
+ */
+#include "kernel_rename.h"
+
+/*
+ * アプリケーションと共通のヘッダファイル
+ */
+#include <kernel.h>
+
+/*
+ * システムログ機能のための定義
+ */
+#include <t_syslog.h>
+
+/*
+ * 型キャストを行うマクロの定義
+ */
+#ifndef CAST
+#define CAST(type, val) ((type)(val))
+#endif /* CAST */
+
+/*
+ * ターゲット依存情報の定義
+ */
+#include "target_config.h"
+
+/*
+ * すべての関数をコンパイルするための定義
+ */
+#ifdef ALLFUNC
+#include "allfunc.h"
+#endif /* ALLFUNC */
+
+/*
+ * ビットフィールドでの符号無し整数型
+ *
+ * 8ビット以下の幅のビットフィールドで,符号無し整数値を保持したい場合
+ * に用いるべきデータ型.ANSI Cでは,ビットフィールドのデータ型には
+ * intとunsigned intしか許されないため,デフォルトの定義はunsigned
+ * intとしているが,ターゲットおよびツール依存で,unsigned charまたは
+ * unsigned shortに定義した方が効率が良い場合がある.
+ */
+#ifndef BIT_FIELD_UINT
+#define BIT_FIELD_UINT unsigned int
+#endif /* BIT_FIELD_UINT */
+
+/*
+ * ビットフィールドでのブール型
+ *
+ * 1ビット幅のビットフィールドで,ブール値を保持したい場合に用いるべき
+ * データ型.デフォルトではBIT_FIELD_UINTと同一に定義しているが,ブー
+ * ル値を保持することを明示するために別の名称としている.
+ */
+#ifndef BIT_FIELD_BOOL
+#define BIT_FIELD_BOOL BIT_FIELD_UINT
+#endif /* BIT_FIELD_BOOL */
+
+/*
+ * オブジェクトIDの最小値の定義
+ */
+#define TMIN_TSKID 1 /* タスクIDの最小値 */
+#define TMIN_SEMID 1 /* セマフォIDの最小値 */
+#define TMIN_FLGID 1 /* フラグIDの最小値 */
+#define TMIN_DTQID 1 /* データキューIDの最小値 */
+#define TMIN_PDQID 1 /* 優先度データキューIDの最小値 */
+#define TMIN_MBXID 1 /* メールボックスIDの最小値 */
+#define TMIN_MPFID 1 /* 固定長メモリプールIDの最小値 */
+#define TMIN_CYCID 1 /* 周期ハンドラIDの最小値 */
+#define TMIN_ALMID 1 /* アラームハンドラIDの最小値 */
+
+/*
+ * 優先度の段階数の定義
+ */
+#define TNUM_TPRI (TMAX_TPRI - TMIN_TPRI + 1)
+#define TNUM_MPRI (TMAX_MPRI - TMIN_MPRI + 1)
+#define TNUM_INTPRI (TMAX_INTPRI - TMIN_INTPRI + 1)
+
+/*
+ * ヘッダファイルを持たないモジュールの関数・変数の宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ * 各モジュールの初期化(kernel_cfg.c)
+ */
+extern void initialize_object(void);
+
+/*
+ * 初期化ルーチンの実行(kernel_cfg.c)
+ */
+extern void call_inirtn(void);
+
+/*
+ * 終了処理ルーチンの実行(kernel_cfg.c)
+ */
+extern void call_terrtn(void);
+
+/*
+ * 非タスクコンテキスト用のスタック領域(kernel_cfg.c)
+ */
+extern const SIZE istksz; /* スタック領域のサイズ(丸めた値) */
+extern STK_T *const istk; /* スタック領域の先頭番地 */
+#ifdef TOPPERS_ISTKPT
+extern STK_T *const istkpt; /* スタックポインタの初期値 */
+#endif /* TOPPERS_ISTKPT */
+
+/*
+ * カーネル動作状態フラグ(startup.c)
+ */
+extern bool_t kerflg;
+
+/*
+ * カーネルの起動(startup.c)
+ */
+extern void sta_ker(void);
+
+/*
+ * カーネルの終了処理(startup.c)
+ */
+extern void exit_kernel(void);
+
+#endif /* TOPPERS_MACRO_ONLY */
+#endif /* TOPPERS_KERNEL_IMPL_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: kernel_int.h 508 2007-08-22 23:08:54Z hiro $
+ */
+
+/*
+ * kernel_cfg.c(およびcfg1_out.c)用ヘッダファイル
+ */
+
+#ifndef TOPPERS_KERNEL_INT_H
+#define TOPPERS_KERNEL_INT_H
+
+/*
+ * カーネル標準ヘッダファイル
+ */
+#include "kernel_impl.h"
+
+/*
+ * カーネルの各ヘッダファイル
+ */
+#include "task.h"
+#include "semaphore.h"
+#include "eventflag.h"
+#include "dataqueue.h"
+#include "pridataq.h"
+#include "mailbox.h"
+#include "mempfix.h"
+#include "cyclic.h"
+#include "alarm.h"
+#include "interrupt.h"
+#include "exception.h"
+#include "time_event.h"
+
+/*
+ * リネームしたシンボルを元に戻すためのヘッダファイル
+ */
+#include "kernel_unrename.h"
+
+#endif /* TOPPERS_KERNEL_INT_H */
--- /dev/null
+# startup.c
+kerflg
+exit_kernel
+
+# task.c
+p_runtsk
+p_schedtsk
+reqflg
+disdsp
+dspflg
+ready_queue
+ready_primap
+initialize_task
+search_schedtsk
+make_runnable
+make_non_runnable
+make_dormant
+make_active
+change_priority
+rotate_ready_queue
+call_texrtn
+calltex
+
+# wait.c
+make_wait_tmout
+wait_complete
+wait_tmout
+wait_tmout_ok
+wait_release
+wobj_make_wait
+wobj_make_wait_tmout
+init_wait_queue
+
+# time_event.c
+current_time
+min_time
+next_time
+next_subtime
+last_index
+initialize_tmevt
+tmevt_up
+tmevt_down
+tmevtb_insert
+tmevtb_delete
+tmevt_lefttim
+signal_time
+
+# semaphore.c
+initialize_semaphore
+
+# eventflag.c
+initialize_eventflag
+check_flg_cond
+
+# dataqueue.c
+initialize_dataqueue
+enqueue_data
+force_enqueue_data
+dequeue_data
+send_data
+force_send_data
+receive_data
+
+# pridataq.c
+initialize_pridataq
+enqueue_pridata
+dequeue_pridata
+send_pridata
+receive_pridata
+
+# mailbox.c
+initialize_mailbox
+
+# mempfix.c
+initialize_mempfix
+get_mpf_block
+
+# cyclic.c
+initialize_cyclic
+call_cychdr
+
+# alarm.c
+initialize_alarm
+call_almhdr
+
+# interrupt.c
+initialize_interrupt
+
+# exception.c
+initialize_exception
+
+# kernel_cfg.c
+initialize_object
+call_inirtn
+call_terrtn
+tmax_tskid
+tinib_table
+torder_table
+tcb_table
+tmax_semid
+seminib_table
+semcb_table
+tmax_flgid
+flginib_table
+flgcb_table
+tmax_dtqid
+dtqcb_table
+dtqinib_table
+tmax_pdqid
+pdqcb_table
+pdqinib_table
+tmax_mbxid
+mbxcb_table
+mbxinib_table
+tmax_mpfid
+mpfinib_table
+mpfcb_table
+tmax_cycid
+cycinib_table
+cyccb_table
+tmax_almid
+alminib_table
+almcb_table
+tnum_inhno
+inhinib_table
+tnum_intno
+intinib_table
+tnum_excno
+excinib_table
+tmevt_heap
+istksz
+istk
+istkpt
+
+INCLUDE "target"
--- /dev/null
+/* This file is generated from kernel_rename.def by genrename. */
+
+#ifndef TOPPERS_KERNEL_RENAME_H
+#define TOPPERS_KERNEL_RENAME_H
+
+/*
+ * startup.c
+ */
+#define kerflg _kernel_kerflg
+#define exit_kernel _kernel_exit_kernel
+
+/*
+ * task.c
+ */
+#define p_runtsk _kernel_p_runtsk
+#define p_schedtsk _kernel_p_schedtsk
+#define reqflg _kernel_reqflg
+#define disdsp _kernel_disdsp
+#define dspflg _kernel_dspflg
+#define ready_queue _kernel_ready_queue
+#define ready_primap _kernel_ready_primap
+#define initialize_task _kernel_initialize_task
+#define search_schedtsk _kernel_search_schedtsk
+#define make_runnable _kernel_make_runnable
+#define make_non_runnable _kernel_make_non_runnable
+#define make_dormant _kernel_make_dormant
+#define make_active _kernel_make_active
+#define change_priority _kernel_change_priority
+#define rotate_ready_queue _kernel_rotate_ready_queue
+#define call_texrtn _kernel_call_texrtn
+#define calltex _kernel_calltex
+
+/*
+ * wait.c
+ */
+#define make_wait_tmout _kernel_make_wait_tmout
+#define wait_complete _kernel_wait_complete
+#define wait_tmout _kernel_wait_tmout
+#define wait_tmout_ok _kernel_wait_tmout_ok
+#define wait_release _kernel_wait_release
+#define wobj_make_wait _kernel_wobj_make_wait
+#define wobj_make_wait_tmout _kernel_wobj_make_wait_tmout
+#define init_wait_queue _kernel_init_wait_queue
+
+/*
+ * time_event.c
+ */
+#define current_time _kernel_current_time
+#define min_time _kernel_min_time
+#define next_time _kernel_next_time
+#define next_subtime _kernel_next_subtime
+#define last_index _kernel_last_index
+#define initialize_tmevt _kernel_initialize_tmevt
+#define tmevt_up _kernel_tmevt_up
+#define tmevt_down _kernel_tmevt_down
+#define tmevtb_insert _kernel_tmevtb_insert
+#define tmevtb_delete _kernel_tmevtb_delete
+#define tmevt_lefttim _kernel_tmevt_lefttim
+#define signal_time _kernel_signal_time
+
+/*
+ * semaphore.c
+ */
+#define initialize_semaphore _kernel_initialize_semaphore
+
+/*
+ * eventflag.c
+ */
+#define initialize_eventflag _kernel_initialize_eventflag
+#define check_flg_cond _kernel_check_flg_cond
+
+/*
+ * dataqueue.c
+ */
+#define initialize_dataqueue _kernel_initialize_dataqueue
+#define enqueue_data _kernel_enqueue_data
+#define force_enqueue_data _kernel_force_enqueue_data
+#define dequeue_data _kernel_dequeue_data
+#define send_data _kernel_send_data
+#define force_send_data _kernel_force_send_data
+#define receive_data _kernel_receive_data
+
+/*
+ * pridataq.c
+ */
+#define initialize_pridataq _kernel_initialize_pridataq
+#define enqueue_pridata _kernel_enqueue_pridata
+#define dequeue_pridata _kernel_dequeue_pridata
+#define send_pridata _kernel_send_pridata
+#define receive_pridata _kernel_receive_pridata
+
+/*
+ * mailbox.c
+ */
+#define initialize_mailbox _kernel_initialize_mailbox
+
+/*
+ * mempfix.c
+ */
+#define initialize_mempfix _kernel_initialize_mempfix
+#define get_mpf_block _kernel_get_mpf_block
+
+/*
+ * cyclic.c
+ */
+#define initialize_cyclic _kernel_initialize_cyclic
+#define call_cychdr _kernel_call_cychdr
+
+/*
+ * alarm.c
+ */
+#define initialize_alarm _kernel_initialize_alarm
+#define call_almhdr _kernel_call_almhdr
+
+/*
+ * interrupt.c
+ */
+#define initialize_interrupt _kernel_initialize_interrupt
+
+/*
+ * exception.c
+ */
+#define initialize_exception _kernel_initialize_exception
+
+/*
+ * kernel_cfg.c
+ */
+#define initialize_object _kernel_initialize_object
+#define call_inirtn _kernel_call_inirtn
+#define call_terrtn _kernel_call_terrtn
+#define tmax_tskid _kernel_tmax_tskid
+#define tinib_table _kernel_tinib_table
+#define torder_table _kernel_torder_table
+#define tcb_table _kernel_tcb_table
+#define tmax_semid _kernel_tmax_semid
+#define seminib_table _kernel_seminib_table
+#define semcb_table _kernel_semcb_table
+#define tmax_flgid _kernel_tmax_flgid
+#define flginib_table _kernel_flginib_table
+#define flgcb_table _kernel_flgcb_table
+#define tmax_dtqid _kernel_tmax_dtqid
+#define dtqcb_table _kernel_dtqcb_table
+#define dtqinib_table _kernel_dtqinib_table
+#define tmax_pdqid _kernel_tmax_pdqid
+#define pdqcb_table _kernel_pdqcb_table
+#define pdqinib_table _kernel_pdqinib_table
+#define tmax_mbxid _kernel_tmax_mbxid
+#define mbxcb_table _kernel_mbxcb_table
+#define mbxinib_table _kernel_mbxinib_table
+#define tmax_mpfid _kernel_tmax_mpfid
+#define mpfinib_table _kernel_mpfinib_table
+#define mpfcb_table _kernel_mpfcb_table
+#define tmax_cycid _kernel_tmax_cycid
+#define cycinib_table _kernel_cycinib_table
+#define cyccb_table _kernel_cyccb_table
+#define tmax_almid _kernel_tmax_almid
+#define alminib_table _kernel_alminib_table
+#define almcb_table _kernel_almcb_table
+#define tnum_inhno _kernel_tnum_inhno
+#define inhinib_table _kernel_inhinib_table
+#define tnum_intno _kernel_tnum_intno
+#define intinib_table _kernel_intinib_table
+#define tnum_excno _kernel_tnum_excno
+#define excinib_table _kernel_excinib_table
+#define tmevt_heap _kernel_tmevt_heap
+#define istksz _kernel_istksz
+#define istk _kernel_istk
+#define istkpt _kernel_istkpt
+
+
+#ifdef TOPPERS_LABEL_ASM
+
+/*
+ * startup.c
+ */
+#define _kerflg __kernel_kerflg
+#define _exit_kernel __kernel_exit_kernel
+
+/*
+ * task.c
+ */
+#define _p_runtsk __kernel_p_runtsk
+#define _p_schedtsk __kernel_p_schedtsk
+#define _reqflg __kernel_reqflg
+#define _disdsp __kernel_disdsp
+#define _dspflg __kernel_dspflg
+#define _ready_queue __kernel_ready_queue
+#define _ready_primap __kernel_ready_primap
+#define _initialize_task __kernel_initialize_task
+#define _search_schedtsk __kernel_search_schedtsk
+#define _make_runnable __kernel_make_runnable
+#define _make_non_runnable __kernel_make_non_runnable
+#define _make_dormant __kernel_make_dormant
+#define _make_active __kernel_make_active
+#define _change_priority __kernel_change_priority
+#define _rotate_ready_queue __kernel_rotate_ready_queue
+#define _call_texrtn __kernel_call_texrtn
+#define _calltex __kernel_calltex
+
+/*
+ * wait.c
+ */
+#define _make_wait_tmout __kernel_make_wait_tmout
+#define _wait_complete __kernel_wait_complete
+#define _wait_tmout __kernel_wait_tmout
+#define _wait_tmout_ok __kernel_wait_tmout_ok
+#define _wait_release __kernel_wait_release
+#define _wobj_make_wait __kernel_wobj_make_wait
+#define _wobj_make_wait_tmout __kernel_wobj_make_wait_tmout
+#define _init_wait_queue __kernel_init_wait_queue
+
+/*
+ * time_event.c
+ */
+#define _current_time __kernel_current_time
+#define _min_time __kernel_min_time
+#define _next_time __kernel_next_time
+#define _next_subtime __kernel_next_subtime
+#define _last_index __kernel_last_index
+#define _initialize_tmevt __kernel_initialize_tmevt
+#define _tmevt_up __kernel_tmevt_up
+#define _tmevt_down __kernel_tmevt_down
+#define _tmevtb_insert __kernel_tmevtb_insert
+#define _tmevtb_delete __kernel_tmevtb_delete
+#define _tmevt_lefttim __kernel_tmevt_lefttim
+#define _signal_time __kernel_signal_time
+
+/*
+ * semaphore.c
+ */
+#define _initialize_semaphore __kernel_initialize_semaphore
+
+/*
+ * eventflag.c
+ */
+#define _initialize_eventflag __kernel_initialize_eventflag
+#define _check_flg_cond __kernel_check_flg_cond
+
+/*
+ * dataqueue.c
+ */
+#define _initialize_dataqueue __kernel_initialize_dataqueue
+#define _enqueue_data __kernel_enqueue_data
+#define _force_enqueue_data __kernel_force_enqueue_data
+#define _dequeue_data __kernel_dequeue_data
+#define _send_data __kernel_send_data
+#define _force_send_data __kernel_force_send_data
+#define _receive_data __kernel_receive_data
+
+/*
+ * pridataq.c
+ */
+#define _initialize_pridataq __kernel_initialize_pridataq
+#define _enqueue_pridata __kernel_enqueue_pridata
+#define _dequeue_pridata __kernel_dequeue_pridata
+#define _send_pridata __kernel_send_pridata
+#define _receive_pridata __kernel_receive_pridata
+
+/*
+ * mailbox.c
+ */
+#define _initialize_mailbox __kernel_initialize_mailbox
+
+/*
+ * mempfix.c
+ */
+#define _initialize_mempfix __kernel_initialize_mempfix
+#define _get_mpf_block __kernel_get_mpf_block
+
+/*
+ * cyclic.c
+ */
+#define _initialize_cyclic __kernel_initialize_cyclic
+#define _call_cychdr __kernel_call_cychdr
+
+/*
+ * alarm.c
+ */
+#define _initialize_alarm __kernel_initialize_alarm
+#define _call_almhdr __kernel_call_almhdr
+
+/*
+ * interrupt.c
+ */
+#define _initialize_interrupt __kernel_initialize_interrupt
+
+/*
+ * exception.c
+ */
+#define _initialize_exception __kernel_initialize_exception
+
+/*
+ * kernel_cfg.c
+ */
+#define _initialize_object __kernel_initialize_object
+#define _call_inirtn __kernel_call_inirtn
+#define _call_terrtn __kernel_call_terrtn
+#define _tmax_tskid __kernel_tmax_tskid
+#define _tinib_table __kernel_tinib_table
+#define _torder_table __kernel_torder_table
+#define _tcb_table __kernel_tcb_table
+#define _tmax_semid __kernel_tmax_semid
+#define _seminib_table __kernel_seminib_table
+#define _semcb_table __kernel_semcb_table
+#define _tmax_flgid __kernel_tmax_flgid
+#define _flginib_table __kernel_flginib_table
+#define _flgcb_table __kernel_flgcb_table
+#define _tmax_dtqid __kernel_tmax_dtqid
+#define _dtqcb_table __kernel_dtqcb_table
+#define _dtqinib_table __kernel_dtqinib_table
+#define _tmax_pdqid __kernel_tmax_pdqid
+#define _pdqcb_table __kernel_pdqcb_table
+#define _pdqinib_table __kernel_pdqinib_table
+#define _tmax_mbxid __kernel_tmax_mbxid
+#define _mbxcb_table __kernel_mbxcb_table
+#define _mbxinib_table __kernel_mbxinib_table
+#define _tmax_mpfid __kernel_tmax_mpfid
+#define _mpfinib_table __kernel_mpfinib_table
+#define _mpfcb_table __kernel_mpfcb_table
+#define _tmax_cycid __kernel_tmax_cycid
+#define _cycinib_table __kernel_cycinib_table
+#define _cyccb_table __kernel_cyccb_table
+#define _tmax_almid __kernel_tmax_almid
+#define _alminib_table __kernel_alminib_table
+#define _almcb_table __kernel_almcb_table
+#define _tnum_inhno __kernel_tnum_inhno
+#define _inhinib_table __kernel_inhinib_table
+#define _tnum_intno __kernel_tnum_intno
+#define _intinib_table __kernel_intinib_table
+#define _tnum_excno __kernel_tnum_excno
+#define _excinib_table __kernel_excinib_table
+#define _tmevt_heap __kernel_tmevt_heap
+#define _istksz __kernel_istksz
+#define _istk __kernel_istk
+#define _istkpt __kernel_istkpt
+
+
+#endif /* TOPPERS_LABEL_ASM */
+
+#include "target_rename.h"
+
+#endif /* TOPPERS_KERNEL_RENAME_H */
--- /dev/null
+/* This file is generated from kernel_rename.def by genrename. */
+
+/* This file is included only when kernel_rename.h has been included. */
+#ifdef TOPPERS_KERNEL_RENAME_H
+#undef TOPPERS_KERNEL_RENAME_H
+
+/*
+ * startup.c
+ */
+#undef kerflg
+#undef exit_kernel
+
+/*
+ * task.c
+ */
+#undef p_runtsk
+#undef p_schedtsk
+#undef reqflg
+#undef disdsp
+#undef dspflg
+#undef ready_queue
+#undef ready_primap
+#undef initialize_task
+#undef search_schedtsk
+#undef make_runnable
+#undef make_non_runnable
+#undef make_dormant
+#undef make_active
+#undef change_priority
+#undef rotate_ready_queue
+#undef call_texrtn
+#undef calltex
+
+/*
+ * wait.c
+ */
+#undef make_wait_tmout
+#undef wait_complete
+#undef wait_tmout
+#undef wait_tmout_ok
+#undef wait_release
+#undef wobj_make_wait
+#undef wobj_make_wait_tmout
+#undef init_wait_queue
+
+/*
+ * time_event.c
+ */
+#undef current_time
+#undef min_time
+#undef next_time
+#undef next_subtime
+#undef last_index
+#undef initialize_tmevt
+#undef tmevt_up
+#undef tmevt_down
+#undef tmevtb_insert
+#undef tmevtb_delete
+#undef tmevt_lefttim
+#undef signal_time
+
+/*
+ * semaphore.c
+ */
+#undef initialize_semaphore
+
+/*
+ * eventflag.c
+ */
+#undef initialize_eventflag
+#undef check_flg_cond
+
+/*
+ * dataqueue.c
+ */
+#undef initialize_dataqueue
+#undef enqueue_data
+#undef force_enqueue_data
+#undef dequeue_data
+#undef send_data
+#undef force_send_data
+#undef receive_data
+
+/*
+ * pridataq.c
+ */
+#undef initialize_pridataq
+#undef enqueue_pridata
+#undef dequeue_pridata
+#undef send_pridata
+#undef receive_pridata
+
+/*
+ * mailbox.c
+ */
+#undef initialize_mailbox
+
+/*
+ * mempfix.c
+ */
+#undef initialize_mempfix
+#undef get_mpf_block
+
+/*
+ * cyclic.c
+ */
+#undef initialize_cyclic
+#undef call_cychdr
+
+/*
+ * alarm.c
+ */
+#undef initialize_alarm
+#undef call_almhdr
+
+/*
+ * interrupt.c
+ */
+#undef initialize_interrupt
+
+/*
+ * exception.c
+ */
+#undef initialize_exception
+
+/*
+ * kernel_cfg.c
+ */
+#undef initialize_object
+#undef call_inirtn
+#undef call_terrtn
+#undef tmax_tskid
+#undef tinib_table
+#undef torder_table
+#undef tcb_table
+#undef tmax_semid
+#undef seminib_table
+#undef semcb_table
+#undef tmax_flgid
+#undef flginib_table
+#undef flgcb_table
+#undef tmax_dtqid
+#undef dtqcb_table
+#undef dtqinib_table
+#undef tmax_pdqid
+#undef pdqcb_table
+#undef pdqinib_table
+#undef tmax_mbxid
+#undef mbxcb_table
+#undef mbxinib_table
+#undef tmax_mpfid
+#undef mpfinib_table
+#undef mpfcb_table
+#undef tmax_cycid
+#undef cycinib_table
+#undef cyccb_table
+#undef tmax_almid
+#undef alminib_table
+#undef almcb_table
+#undef tnum_inhno
+#undef inhinib_table
+#undef tnum_intno
+#undef intinib_table
+#undef tnum_excno
+#undef excinib_table
+#undef tmevt_heap
+#undef istksz
+#undef istk
+#undef istkpt
+
+
+#ifdef TOPPERS_LABEL_ASM
+
+/*
+ * startup.c
+ */
+#undef _kerflg
+#undef _exit_kernel
+
+/*
+ * task.c
+ */
+#undef _p_runtsk
+#undef _p_schedtsk
+#undef _reqflg
+#undef _disdsp
+#undef _dspflg
+#undef _ready_queue
+#undef _ready_primap
+#undef _initialize_task
+#undef _search_schedtsk
+#undef _make_runnable
+#undef _make_non_runnable
+#undef _make_dormant
+#undef _make_active
+#undef _change_priority
+#undef _rotate_ready_queue
+#undef _call_texrtn
+#undef _calltex
+
+/*
+ * wait.c
+ */
+#undef _make_wait_tmout
+#undef _wait_complete
+#undef _wait_tmout
+#undef _wait_tmout_ok
+#undef _wait_release
+#undef _wobj_make_wait
+#undef _wobj_make_wait_tmout
+#undef _init_wait_queue
+
+/*
+ * time_event.c
+ */
+#undef _current_time
+#undef _min_time
+#undef _next_time
+#undef _next_subtime
+#undef _last_index
+#undef _initialize_tmevt
+#undef _tmevt_up
+#undef _tmevt_down
+#undef _tmevtb_insert
+#undef _tmevtb_delete
+#undef _tmevt_lefttim
+#undef _signal_time
+
+/*
+ * semaphore.c
+ */
+#undef _initialize_semaphore
+
+/*
+ * eventflag.c
+ */
+#undef _initialize_eventflag
+#undef _check_flg_cond
+
+/*
+ * dataqueue.c
+ */
+#undef _initialize_dataqueue
+#undef _enqueue_data
+#undef _force_enqueue_data
+#undef _dequeue_data
+#undef _send_data
+#undef _force_send_data
+#undef _receive_data
+
+/*
+ * pridataq.c
+ */
+#undef _initialize_pridataq
+#undef _enqueue_pridata
+#undef _dequeue_pridata
+#undef _send_pridata
+#undef _receive_pridata
+
+/*
+ * mailbox.c
+ */
+#undef _initialize_mailbox
+
+/*
+ * mempfix.c
+ */
+#undef _initialize_mempfix
+#undef _get_mpf_block
+
+/*
+ * cyclic.c
+ */
+#undef _initialize_cyclic
+#undef _call_cychdr
+
+/*
+ * alarm.c
+ */
+#undef _initialize_alarm
+#undef _call_almhdr
+
+/*
+ * interrupt.c
+ */
+#undef _initialize_interrupt
+
+/*
+ * exception.c
+ */
+#undef _initialize_exception
+
+/*
+ * kernel_cfg.c
+ */
+#undef _initialize_object
+#undef _call_inirtn
+#undef _call_terrtn
+#undef _tmax_tskid
+#undef _tinib_table
+#undef _torder_table
+#undef _tcb_table
+#undef _tmax_semid
+#undef _seminib_table
+#undef _semcb_table
+#undef _tmax_flgid
+#undef _flginib_table
+#undef _flgcb_table
+#undef _tmax_dtqid
+#undef _dtqcb_table
+#undef _dtqinib_table
+#undef _tmax_pdqid
+#undef _pdqcb_table
+#undef _pdqinib_table
+#undef _tmax_mbxid
+#undef _mbxcb_table
+#undef _mbxinib_table
+#undef _tmax_mpfid
+#undef _mpfinib_table
+#undef _mpfcb_table
+#undef _tmax_cycid
+#undef _cycinib_table
+#undef _cyccb_table
+#undef _tmax_almid
+#undef _alminib_table
+#undef _almcb_table
+#undef _tnum_inhno
+#undef _inhinib_table
+#undef _tnum_intno
+#undef _intinib_table
+#undef _tnum_excno
+#undef _excinib_table
+#undef _tmevt_heap
+#undef _istksz
+#undef _istk
+#undef _istkpt
+
+
+#endif /* TOPPERS_LABEL_ASM */
+
+#include "target_unrename.h"
+
+#endif /* TOPPERS_KERNEL_RENAME_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: mailbox.c 748 2008-03-07 17:18:06Z hiro $
+ */
+
+/*
+ * メールボックス機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "mailbox.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_SND_MBX_ENTER
+#define LOG_SND_MBX_ENTER(mbxid, pk_msg)
+#endif /* LOG_SND_MBX_ENTER */
+
+#ifndef LOG_SND_MBX_LEAVE
+#define LOG_SND_MBX_LEAVE(ercd)
+#endif /* LOG_SND_MBX_LEAVE */
+
+#ifndef LOG_RCV_MBX_ENTER
+#define LOG_RCV_MBX_ENTER(mbxid, ppk_msg)
+#endif /* LOG_RCV_MBX_ENTER */
+
+#ifndef LOG_RCV_MBX_LEAVE
+#define LOG_RCV_MBX_LEAVE(ercd, pk_msg)
+#endif /* LOG_RCV_MBX_LEAVE */
+
+#ifndef LOG_PRCV_MBX_ENTER
+#define LOG_PRCV_MBX_ENTER(mbxid, ppk_msg)
+#endif /* LOG_PRCV_MBX_ENTER */
+
+#ifndef LOG_PRCV_MBX_LEAVE
+#define LOG_PRCV_MBX_LEAVE(ercd, pk_msg)
+#endif /* LOG_PRCV_MBX_LEAVE */
+
+#ifndef LOG_TRCV_MBX_ENTER
+#define LOG_TRCV_MBX_ENTER(mbxid, ppk_msg, tmout)
+#endif /* LOG_TRCV_MBX_ENTER */
+
+#ifndef LOG_TRCV_MBX_LEAVE
+#define LOG_TRCV_MBX_LEAVE(ercd, pk_msg)
+#endif /* LOG_TRCV_MBX_LEAVE */
+
+#ifndef LOG_INI_MBX_ENTER
+#define LOG_INI_MBX_ENTER(mbxid)
+#endif /* LOG_INI_MBX_ENTER */
+
+#ifndef LOG_INI_MBX_LEAVE
+#define LOG_INI_MBX_LEAVE(ercd)
+#endif /* LOG_INI_MBX_LEAVE */
+
+#ifndef LOG_REF_MBX_ENTER
+#define LOG_REF_MBX_ENTER(mbxid, pk_rmbx)
+#endif /* LOG_REF_MBX_ENTER */
+
+#ifndef LOG_REF_MBX_LEAVE
+#define LOG_REF_MBX_LEAVE(ercd, pk_rmbx)
+#endif /* LOG_REF_MBX_LEAVE */
+
+/*
+ * メールボックスの数
+ */
+#define tnum_mbx ((uint_t)(tmax_mbxid - TMIN_MBXID + 1))
+
+/*
+ * メールボックスIDからメールボックス管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_MBX(mbxid) ((uint_t)((mbxid) - TMIN_MBXID))
+#define get_mbxcb(mbxid) (&(mbxcb_table[INDEX_MBX(mbxid)]))
+
+/*
+ * メールボックス機能の初期化
+ */
+#ifdef TOPPERS_mbxini
+
+void
+initialize_mailbox(void)
+{
+ uint_t i;
+ MBXCB *p_mbxcb;
+
+ for (p_mbxcb = mbxcb_table, i = 0; i < tnum_mbx; p_mbxcb++, i++) {
+ queue_initialize(&(p_mbxcb->wait_queue));
+ p_mbxcb->p_mbxinib = &(mbxinib_table[i]);
+ p_mbxcb->pk_head = NULL;
+ }
+}
+
+#endif /* TOPPERS_mbxini */
+
+/*
+ * メッセージ優先度の取出し
+ */
+#define MSGPRI(pk_msg) (((T_MSG_PRI *) pk_msg)->msgpri)
+
+/*
+ * 優先度順メッセージキューへの挿入
+ */
+Inline void
+enqueue_msg_pri(T_MSG **ppk_prevmsg_next, T_MSG *pk_msg)
+{
+ T_MSG *pk_nextmsg;
+
+ while ((pk_nextmsg = *ppk_prevmsg_next) != NULL) {
+ if (MSGPRI(pk_nextmsg) > MSGPRI(pk_msg)) {
+ break;
+ }
+ ppk_prevmsg_next = &(pk_nextmsg->pk_next);
+ }
+ pk_msg->pk_next = pk_nextmsg;
+ *ppk_prevmsg_next = pk_msg;
+}
+
+/*
+ * メールボックスへの送信
+ */
+#ifdef TOPPERS_snd_mbx
+
+ER
+snd_mbx(ID mbxid, T_MSG *pk_msg)
+{
+ MBXCB *p_mbxcb;
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_SND_MBX_ENTER(mbxid, pk_msg);
+ CHECK_TSKCTX_UNL();
+ CHECK_MBXID(mbxid);
+ p_mbxcb = get_mbxcb(mbxid);
+ CHECK_PAR((p_mbxcb->p_mbxinib->mbxatr & TA_MPRI) == 0U
+ || (TMIN_MPRI <= MSGPRI(pk_msg)
+ && MSGPRI(pk_msg) <= p_mbxcb->p_mbxinib->maxmpri));
+
+ t_lock_cpu();
+ if (!queue_empty(&(p_mbxcb->wait_queue))) {
+ p_tcb = (TCB *) queue_delete_next(&(p_mbxcb->wait_queue));
+ ((WINFO_MBX *)(p_tcb->p_winfo))->pk_msg = pk_msg;
+ if (wait_complete(p_tcb)) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ else if ((p_mbxcb->p_mbxinib->mbxatr & TA_MPRI) != 0U) {
+ enqueue_msg_pri(&(p_mbxcb->pk_head), pk_msg);
+ ercd = E_OK;
+ }
+ else {
+ pk_msg->pk_next = NULL;
+ if (p_mbxcb->pk_head != NULL) {
+ p_mbxcb->pk_last->pk_next = pk_msg;
+ }
+ else {
+ p_mbxcb->pk_head = pk_msg;
+ }
+ p_mbxcb->pk_last = pk_msg;
+ ercd = E_OK;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_SND_MBX_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_snd_mbx */
+
+/*
+ * メールボックスからの受信
+ */
+#ifdef TOPPERS_rcv_mbx
+
+ER
+rcv_mbx(ID mbxid, T_MSG **ppk_msg)
+{
+ MBXCB *p_mbxcb;
+ WINFO_MBX winfo_mbx;
+ ER ercd;
+
+ LOG_RCV_MBX_ENTER(mbxid, ppk_msg);
+ CHECK_DISPATCH();
+ CHECK_MBXID(mbxid);
+ p_mbxcb = get_mbxcb(mbxid);
+
+ t_lock_cpu();
+ if (p_mbxcb->pk_head != NULL) {
+ *ppk_msg = p_mbxcb->pk_head;
+ p_mbxcb->pk_head = (*ppk_msg)->pk_next;
+ ercd = E_OK;
+ }
+ else {
+ p_runtsk->tstat = (TS_WAITING | TS_WAIT_MBX);
+ wobj_make_wait((WOBJCB *) p_mbxcb, (WINFO_WOBJ *) &winfo_mbx);
+ dispatch();
+ ercd = winfo_mbx.winfo.wercd;
+ if (ercd == E_OK) {
+ *ppk_msg = winfo_mbx.pk_msg;
+ }
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_RCV_MBX_LEAVE(ercd, *ppk_msg);
+ return(ercd);
+}
+
+#endif /* TOPPERS_rcv_mbx */
+
+/*
+ * メールボックスからの受信(ポーリング)
+ */
+#ifdef TOPPERS_prcv_mbx
+
+ER
+prcv_mbx(ID mbxid, T_MSG **ppk_msg)
+{
+ MBXCB *p_mbxcb;
+ ER ercd;
+
+ LOG_PRCV_MBX_ENTER(mbxid, ppk_msg);
+ CHECK_TSKCTX_UNL();
+ CHECK_MBXID(mbxid);
+ p_mbxcb = get_mbxcb(mbxid);
+
+ t_lock_cpu();
+ if (p_mbxcb->pk_head != NULL) {
+ *ppk_msg = p_mbxcb->pk_head;
+ p_mbxcb->pk_head = (*ppk_msg)->pk_next;
+ ercd = E_OK;
+ }
+ else {
+ ercd = E_TMOUT;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_PRCV_MBX_LEAVE(ercd, *ppk_msg);
+ return(ercd);
+}
+
+#endif /* TOPPERS_prcv_mbx */
+
+/*
+ * メールボックスからの受信(タイムアウトあり)
+ */
+#ifdef TOPPERS_trcv_mbx
+
+ER
+trcv_mbx(ID mbxid, T_MSG **ppk_msg, TMO tmout)
+{
+ MBXCB *p_mbxcb;
+ WINFO_MBX winfo_mbx;
+ TMEVTB tmevtb;
+ ER ercd;
+
+ LOG_TRCV_MBX_ENTER(mbxid, ppk_msg, tmout);
+ CHECK_DISPATCH();
+ CHECK_MBXID(mbxid);
+ CHECK_TMOUT(tmout);
+ p_mbxcb = get_mbxcb(mbxid);
+
+ t_lock_cpu();
+ if (p_mbxcb->pk_head != NULL) {
+ *ppk_msg = p_mbxcb->pk_head;
+ p_mbxcb->pk_head = (*ppk_msg)->pk_next;
+ ercd = E_OK;
+ }
+ else if (tmout == TMO_POL) {
+ ercd = E_TMOUT;
+ }
+ else {
+ p_runtsk->tstat = (TS_WAITING | TS_WAIT_MBX);
+ wobj_make_wait_tmout((WOBJCB *) p_mbxcb, (WINFO_WOBJ *) &winfo_mbx,
+ &tmevtb, tmout);
+ dispatch();
+ ercd = winfo_mbx.winfo.wercd;
+ if (ercd == E_OK) {
+ *ppk_msg = winfo_mbx.pk_msg;
+ }
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_TRCV_MBX_LEAVE(ercd, *ppk_msg);
+ return(ercd);
+}
+
+#endif /* TOPPERS_trcv_mbx */
+
+/*
+ * メールボックスの再初期化
+ */
+#ifdef TOPPERS_ini_mbx
+
+ER
+ini_mbx(ID mbxid)
+{
+ MBXCB *p_mbxcb;
+ bool_t dspreq;
+ ER ercd;
+
+ LOG_INI_MBX_ENTER(mbxid);
+ CHECK_TSKCTX_UNL();
+ CHECK_MBXID(mbxid);
+ p_mbxcb = get_mbxcb(mbxid);
+
+ t_lock_cpu();
+ dspreq = init_wait_queue(&(p_mbxcb->wait_queue));
+ p_mbxcb->pk_head = NULL;
+ if (dspreq) {
+ dispatch();
+ }
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_INI_MBX_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ini_mbx */
+
+/*
+ * メールボックスの状態参照
+ */
+#ifdef TOPPERS_ref_mbx
+
+ER
+ref_mbx(ID mbxid, T_RMBX *pk_rmbx)
+{
+ MBXCB *p_mbxcb;
+ ER ercd;
+
+ LOG_REF_MBX_ENTER(mbxid, pk_rmbx);
+ CHECK_TSKCTX_UNL();
+ CHECK_MBXID(mbxid);
+ p_mbxcb = get_mbxcb(mbxid);
+
+ t_lock_cpu();
+ pk_rmbx->wtskid = wait_tskid(&(p_mbxcb->wait_queue));
+ pk_rmbx->pk_msg = p_mbxcb->pk_head;
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_REF_MBX_LEAVE(ercd, pk_rmbx);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ref_mbx */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005,2006 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: mailbox.h 264 2007-07-12 08:23:10Z hiro $
+ */
+
+/*
+ * メールボックス機能
+ */
+
+#ifndef TOPPERS_MAILBOX_H
+#define TOPPERS_MAILBOX_H
+
+#include <queue.h>
+
+/*
+ * メールボックス初期化ブロック
+ *
+ * この構造体は,同期・通信オブジェクトの初期化ブロックの共通部分
+ * (WOBJINIB)を拡張(オブジェクト指向言語の継承に相当)したもので,
+ * 最初のフィールドが共通になっている.
+ */
+typedef struct mailbox_initialization_block {
+ ATR mbxatr; /* メールボックス属性 */
+ PRI maxmpri; /* メッセージ優先度の最大値 */
+} MBXINIB;
+
+/*
+ * メールボックス管理ブロック
+ *
+ * この構造体は,同期・通信オブジェクトの管理ブロックの共通部分(WOBJCB)
+ * を拡張(オブジェクト指向言語の継承に相当)したもので,最初の2つの
+ * フィールドが共通になっている.
+ *
+ * メッセージキューがメッセージの優先度順の場合には,pk_lastは使わな
+ * い.また,メッセージキューが空の場合(pk_headがNULLの場合)にも,
+ * pk_lastは無効である.
+ */
+typedef struct mailbox_control_block {
+ QUEUE wait_queue; /* メールボックス待ちキュー */
+ const MBXINIB *p_mbxinib; /* 初期化ブロックへのポインタ */
+ T_MSG *pk_head; /* 先頭のメッセージ */
+ T_MSG *pk_last; /* 末尾のメッセージ */
+} MBXCB;
+
+/*
+ * メールボックス待ち情報ブロックの定義
+ *
+ * この構造体は,同期・通信オブジェクトの待ち情報ブロックの共通部分
+ * (WINFO_WOBJ)を拡張(オブジェクト指向言語の継承に相当)したもので,
+ * 最初の2つのフィールドが共通になっている.
+ */
+typedef struct mailbox_waiting_information {
+ WINFO winfo; /* 標準の待ち情報ブロック */
+ MBXCB *p_mbxcb; /* 待っているメールボックスの管理ブロック */
+ T_MSG *pk_msg; /* 受信したメッセージ */
+} WINFO_MBX;
+
+/*
+ * メールボックスIDの最大値(kernel_cfg.c)
+ */
+extern const ID tmax_mbxid;
+
+/*
+ * メールボックス初期化ブロックのエリア(kernel_cfg.c)
+ */
+extern const MBXINIB mbxinib_table[];
+
+/*
+ * メールボックス管理ブロックのエリア(kernel_cfg.c)
+ */
+extern MBXCB mbxcb_table[];
+
+/*
+ * メールボックス管理ブロックからメールボックスIDを取り出すためのマクロ
+ */
+#define MBXID(p_mbxcb) ((ID)(((p_mbxcb) - mbxcb_table) + TMIN_MBXID))
+
+/*
+ * メールボックス機能の初期化
+ */
+extern void initialize_mailbox(void);
+
+#endif /* TOPPERS_MAILBOX_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: mempfix.c 748 2008-03-07 17:18:06Z hiro $
+ */
+
+/*
+ * 固定長メモリプール機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "mempfix.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_GET_MPF_ENTER
+#define LOG_GET_MPF_ENTER(mpfid, p_blk)
+#endif /* LOG_GET_MPF_ENTER */
+
+#ifndef LOG_GET_MPF_LEAVE
+#define LOG_GET_MPF_LEAVE(ercd, blk)
+#endif /* LOG_GET_MPF_LEAVE */
+
+#ifndef LOG_PGET_MPF_ENTER
+#define LOG_PGET_MPF_ENTER(mpfid, p_blk)
+#endif /* LOG_PGET_MPF_ENTER */
+
+#ifndef LOG_PGET_MPF_LEAVE
+#define LOG_PGET_MPF_LEAVE(ercd, blk)
+#endif /* LOG_PGET_MPF_LEAVE */
+
+#ifndef LOG_TGET_MPF_ENTER
+#define LOG_TGET_MPF_ENTER(mpfid, p_blk, tmout)
+#endif /* LOG_TGET_MPF_ENTER */
+
+#ifndef LOG_TGET_MPF_LEAVE
+#define LOG_TGET_MPF_LEAVE(ercd, blk)
+#endif /* LOG_TGET_MPF_LEAVE */
+
+#ifndef LOG_REL_MPF_ENTER
+#define LOG_REL_MPF_ENTER(mpfid, blk)
+#endif /* LOG_REL_MPF_ENTER */
+
+#ifndef LOG_REL_MPF_LEAVE
+#define LOG_REL_MPF_LEAVE(ercd)
+#endif /* LOG_REL_MPF_LEAVE */
+
+#ifndef LOG_INI_MPF_ENTER
+#define LOG_INI_MPF_ENTER(mpfid)
+#endif /* LOG_INI_MPF_ENTER */
+
+#ifndef LOG_INI_MPF_LEAVE
+#define LOG_INI_MPF_LEAVE(ercd)
+#endif /* LOG_INI_MPF_LEAVE */
+
+#ifndef LOG_REF_MPF_ENTER
+#define LOG_REF_MPF_ENTER(mpfid, pk_rmpf)
+#endif /* LOG_REF_MPF_ENTER */
+
+#ifndef LOG_REF_MPF_LEAVE
+#define LOG_REF_MPF_LEAVE(ercd, pk_rmpf)
+#endif /* LOG_REF_MPF_LEAVE */
+
+/*
+ * 固定長メモリプールの数
+ */
+#define tnum_mpf ((uint_t)(tmax_mpfid - TMIN_MPFID + 1))
+
+/*
+ * 固定長メモリプールIDから固定長メモリプール管理ブロックを取り出すた
+ * めのマクロ
+ */
+#define INDEX_MPF(mpfid) ((uint_t)((mpfid) - TMIN_MPFID))
+#define get_mpfcb(mpfid) (&(mpfcb_table[INDEX_MPF(mpfid)]))
+
+/*
+ * 特殊なインデックス値の定義
+ */
+#define INDEX_NULL (~0U) /* 空きブロックリストの最後 */
+#define INDEX_ALLOC (~1U) /* 割当て済みのブロック */
+
+/*
+ * 固定長メモリプール機能の初期化
+ */
+#ifdef TOPPERS_mpfini
+
+void
+initialize_mempfix(void)
+{
+ uint_t i;
+ MPFCB *p_mpfcb;
+
+ for (p_mpfcb = mpfcb_table, i = 0; i < tnum_mpf; p_mpfcb++, i++) {
+ queue_initialize(&(p_mpfcb->wait_queue));
+ p_mpfcb->p_mpfinib = &(mpfinib_table[i]);
+ p_mpfcb->fblkcnt = p_mpfcb->p_mpfinib->blkcnt;
+ p_mpfcb->unused = 0U;
+ p_mpfcb->freelist = INDEX_NULL;
+ }
+}
+
+#endif /* TOPPERS_mpfini */
+
+/*
+ * 固定長メモリプールからブロックを獲得
+ */
+#ifdef TOPPERS_mpfget
+
+void
+get_mpf_block(MPFCB *p_mpfcb, void **p_blk)
+{
+ uint_t blkidx;
+
+ if (p_mpfcb->freelist != INDEX_NULL) {
+ blkidx = p_mpfcb->freelist;
+ p_mpfcb->freelist = (p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next;
+ }
+ else {
+ blkidx = p_mpfcb->unused;
+ p_mpfcb->unused++;
+ }
+ *p_blk = (void *)((char *)(p_mpfcb->p_mpfinib->mpf)
+ + p_mpfcb->p_mpfinib->blksz * blkidx);
+ p_mpfcb->fblkcnt--;
+ (p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next = INDEX_ALLOC;
+}
+
+#endif /* TOPPERS_mpfget */
+
+/*
+ * 固定長メモリブロックの獲得
+ */
+#ifdef TOPPERS_get_mpf
+
+ER
+get_mpf(ID mpfid, void **p_blk)
+{
+ MPFCB *p_mpfcb;
+ WINFO_MPF winfo_mpf;
+ ER ercd;
+
+ LOG_GET_MPF_ENTER(mpfid, p_blk);
+ CHECK_DISPATCH();
+ CHECK_MPFID(mpfid);
+ p_mpfcb = get_mpfcb(mpfid);
+
+ t_lock_cpu();
+ if (p_mpfcb->fblkcnt > 0) {
+ get_mpf_block(p_mpfcb, p_blk);
+ ercd = E_OK;
+ }
+ else {
+ p_runtsk->tstat = (TS_WAITING | TS_WAIT_MPF);
+ wobj_make_wait((WOBJCB *) p_mpfcb, (WINFO_WOBJ *) &winfo_mpf);
+ dispatch();
+ ercd = winfo_mpf.winfo.wercd;
+ if (ercd == E_OK) {
+ *p_blk = winfo_mpf.blk;
+ }
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_GET_MPF_LEAVE(ercd, *p_blk);
+ return(ercd);
+}
+
+#endif /* TOPPERS_get_mpf */
+
+/*
+ * 固定長メモリブロックの獲得(ポーリング)
+ */
+#ifdef TOPPERS_pget_mpf
+
+ER
+pget_mpf(ID mpfid, void **p_blk)
+{
+ MPFCB *p_mpfcb;
+ ER ercd;
+
+ LOG_PGET_MPF_ENTER(mpfid, p_blk);
+ CHECK_TSKCTX_UNL();
+ CHECK_MPFID(mpfid);
+ p_mpfcb = get_mpfcb(mpfid);
+
+ t_lock_cpu();
+ if (p_mpfcb->fblkcnt > 0) {
+ get_mpf_block(p_mpfcb, p_blk);
+ ercd = E_OK;
+ }
+ else {
+ ercd = E_TMOUT;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_PGET_MPF_LEAVE(ercd, *p_blk);
+ return(ercd);
+}
+
+#endif /* TOPPERS_pget_mpf */
+
+/*
+ * 固定長メモリブロックの獲得(タイムアウトあり)
+ */
+#ifdef TOPPERS_tget_mpf
+
+ER
+tget_mpf(ID mpfid, void **p_blk, TMO tmout)
+{
+ MPFCB *p_mpfcb;
+ WINFO_MPF winfo_mpf;
+ TMEVTB tmevtb;
+ ER ercd;
+
+ LOG_TGET_MPF_ENTER(mpfid, p_blk, tmout);
+ CHECK_DISPATCH();
+ CHECK_MPFID(mpfid);
+ CHECK_TMOUT(tmout);
+ p_mpfcb = get_mpfcb(mpfid);
+
+ t_lock_cpu();
+ if (p_mpfcb->fblkcnt > 0) {
+ get_mpf_block(p_mpfcb, p_blk);
+ ercd = E_OK;
+ }
+ else if (tmout == TMO_POL) {
+ ercd = E_TMOUT;
+ }
+ else {
+ p_runtsk->tstat = (TS_WAITING | TS_WAIT_MPF);
+ wobj_make_wait_tmout((WOBJCB *) p_mpfcb, (WINFO_WOBJ *) &winfo_mpf,
+ &tmevtb, tmout);
+ dispatch();
+ ercd = winfo_mpf.winfo.wercd;
+ if (ercd == E_OK) {
+ *p_blk = winfo_mpf.blk;
+ }
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_TGET_MPF_LEAVE(ercd, *p_blk);
+ return(ercd);
+}
+
+#endif /* TOPPERS_tget_mpf */
+
+/*
+ * 固定長メモリブロックの返却
+ */
+#ifdef TOPPERS_rel_mpf
+
+ER
+rel_mpf(ID mpfid, void *blk)
+{
+ MPFCB *p_mpfcb;
+ SIZE blkoffset;
+ uint_t blkidx;
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_REL_MPF_ENTER(mpfid, blk);
+ CHECK_TSKCTX_UNL();
+ CHECK_MPFID(mpfid);
+ p_mpfcb = get_mpfcb(mpfid);
+ CHECK_PAR(p_mpfcb->p_mpfinib->mpf <= blk);
+ blkoffset = ((char *) blk) - (char *)(p_mpfcb->p_mpfinib->mpf);
+ CHECK_PAR(blkoffset % p_mpfcb->p_mpfinib->blksz == 0U);
+ CHECK_PAR(blkoffset / p_mpfcb->p_mpfinib->blksz < p_mpfcb->unused);
+ blkidx = (uint_t)(blkoffset / p_mpfcb->p_mpfinib->blksz);
+ CHECK_PAR((p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next == INDEX_ALLOC);
+
+ t_lock_cpu();
+ if (!queue_empty(&(p_mpfcb->wait_queue))) {
+ p_tcb = (TCB *) queue_delete_next(&(p_mpfcb->wait_queue));
+ ((WINFO_MPF *)(p_tcb->p_winfo))->blk = blk;
+ if (wait_complete(p_tcb)) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ else {
+ p_mpfcb->fblkcnt++;
+ (p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next = p_mpfcb->freelist;
+ p_mpfcb->freelist = blkidx;
+ ercd = E_OK;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_REL_MPF_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_rel_mpf */
+
+/*
+ * 固定長メモリプールの再初期化
+ */
+#ifdef TOPPERS_ini_mpf
+
+ER
+ini_mpf(ID mpfid)
+{
+ MPFCB *p_mpfcb;
+ bool_t dspreq;
+ ER ercd;
+
+ LOG_INI_MPF_ENTER(mpfid);
+ CHECK_TSKCTX_UNL();
+ CHECK_MPFID(mpfid);
+ p_mpfcb = get_mpfcb(mpfid);
+
+ t_lock_cpu();
+ dspreq = init_wait_queue(&(p_mpfcb->wait_queue));
+ p_mpfcb->fblkcnt = p_mpfcb->p_mpfinib->blkcnt;
+ p_mpfcb->unused = 0U;
+ p_mpfcb->freelist = INDEX_NULL;
+ if (dspreq) {
+ dispatch();
+ }
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_INI_MPF_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ini_mpf */
+
+/*
+ * 固定長メモリプールの状態参照
+ */
+#ifdef TOPPERS_ref_mpf
+
+ER
+ref_mpf(ID mpfid, T_RMPF *pk_rmpf)
+{
+ MPFCB *p_mpfcb;
+ ER ercd;
+
+ LOG_REF_MPF_ENTER(mpfid, pk_rmpf);
+ CHECK_TSKCTX_UNL();
+ CHECK_MPFID(mpfid);
+ p_mpfcb = get_mpfcb(mpfid);
+
+ t_lock_cpu();
+ pk_rmpf->wtskid = wait_tskid(&(p_mpfcb->wait_queue));
+ pk_rmpf->fblkcnt = p_mpfcb->fblkcnt;
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_REF_MPF_LEAVE(ercd, pk_rmpf);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ref_mpf */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005,2006 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: mempfix.h 264 2007-07-12 08:23:10Z hiro $
+ */
+
+/*
+ * 固定長メモリプール機能
+ */
+
+#ifndef TOPPERS_MEMPFIX_H
+#define TOPPERS_MEMPFIX_H
+
+#include <queue.h>
+
+/*
+ * 固定長メモリブロック管理ブロック
+ *
+ * nextフィールドには,メモリブロックが割当て済みの場合はINDEX_ALLOCを,
+ * 未割当ての場合は次の未割当てブロックのインデックス番号を格納する.
+ * 最後の未割当てブロックの場合には,INDEX_NULLを格納する.
+ */
+typedef struct fixed_memoryblock_management_block {
+ uint_t next; /* 次の未割当てブロック */
+} MPFMB;
+
+/*
+ * 固定長メモリプール初期化ブロック
+ *
+ * この構造体は,同期・通信オブジェクトの初期化ブロックの共通部分
+ * (WOBJINIB)を拡張(オブジェクト指向言語の継承に相当)したもので,
+ * 最初のフィールドが共通になっている.
+ */
+typedef struct fixed_memorypool_initialization_block {
+ ATR mpfatr; /* 固定長メモリプール属性 */
+ uint_t blkcnt; /* メモリブロック数 */
+ uint_t blksz; /* メモリブロックのサイズ(丸めた値) */
+ void *mpf; /* 固定長メモリプール領域の先頭番地 */
+ MPFMB *p_mpfmb; /* 固定長メモリプール管理領域の先頭番地 */
+} MPFINIB;
+
+/*
+ * 固定長メモリプール管理ブロック
+ *
+ * この構造体は,同期・通信オブジェクトの管理ブロックの共通部分(WOBJCB)
+ * を拡張(オブジェクト指向言語の継承に相当)したもので,最初の2つの
+ * フィールドが共通になっている.
+ */
+typedef struct fixed_memorypool_control_block {
+ QUEUE wait_queue; /* 固定長メモリプール待ちキュー */
+ const MPFINIB *p_mpfinib; /* 初期化ブロックへのポインタ */
+ uint_t fblkcnt; /* 未割当てブロック数 */
+ uint_t unused; /* 未使用ブロックの先頭 */
+ uint_t freelist; /* 未割当てブロックのリスト */
+} MPFCB;
+
+/*
+ * 固定長メモリプール待ち情報ブロックの定義
+ *
+ * この構造体は,同期・通信オブジェクトの待ち情報ブロックの共通部分
+ * (WINFO_WOBJ)を拡張(オブジェクト指向言語の継承に相当)したもので,
+ * 最初の2つのフィールドが共通になっている.
+ */
+typedef struct fixed_memorypool_waiting_information {
+ WINFO winfo; /* 標準の待ち情報ブロック */
+ MPFCB *p_mpfcb; /* 待っている固定長メモリプールの管理ブロック*/
+ void *blk; /* 獲得したメモリブロック */
+} WINFO_MPF;
+
+/*
+ * 固定長メモリプールIDの最大値(kernel_cfg.c)
+ */
+extern const ID tmax_mpfid;
+
+/*
+ * 固定長メモリプール初期化ブロックのエリア(kernel_cfg.c)
+ */
+extern const MPFINIB mpfinib_table[];
+
+/*
+ * 固定長メモリプール管理ブロックのエリア(kernel_cfg.c)
+ */
+extern MPFCB mpfcb_table[];
+
+/*
+ * 固定長メモリプール管理ブロックから固定長メモリプールIDを取り出すた
+ * めのマクロ
+ */
+#define MPFID(p_mpfcb) ((ID)(((p_mpfcb) - mpfcb_table) + TMIN_MPFID))
+
+/*
+ * 固定長メモリプール機能の初期化
+ */
+extern void initialize_mempfix(void);
+
+/*
+ * 固定長メモリプールからブロックを獲得
+ */
+extern void get_mpf_block(MPFCB *p_mpfcb, void **p_blk);
+
+#endif /* TOPPERS_MEMPFIX_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: pridataq.c 1774 2010-03-19 12:45:46Z ertl-hiro $
+ */
+
+/*
+ * 優先度データキュー機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "pridataq.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_SND_PDQ_ENTER
+#define LOG_SND_PDQ_ENTER(pdqid, data, datapri)
+#endif /* LOG_SND_PDQ_ENTER */
+
+#ifndef LOG_SND_PDQ_LEAVE
+#define LOG_SND_PDQ_LEAVE(ercd)
+#endif /* LOG_SND_PDQ_LEAVE */
+
+#ifndef LOG_PSND_PDQ_ENTER
+#define LOG_PSND_PDQ_ENTER(pdqid, data, datapri)
+#endif /* LOG_PSND_PDQ_ENTER */
+
+#ifndef LOG_PSND_PDQ_LEAVE
+#define LOG_PSND_PDQ_LEAVE(ercd)
+#endif /* LOG_PSND_PDQ_LEAVE */
+
+#ifndef LOG_IPSND_PDQ_ENTER
+#define LOG_IPSND_PDQ_ENTER(pdqid, data, datapri)
+#endif /* LOG_IPSND_PDQ_ENTER */
+
+#ifndef LOG_IPSND_PDQ_LEAVE
+#define LOG_IPSND_PDQ_LEAVE(ercd)
+#endif /* LOG_IPSND_PDQ_LEAVE */
+
+#ifndef LOG_TSND_PDQ_ENTER
+#define LOG_TSND_PDQ_ENTER(pdqid, data, datapri, tmout)
+#endif /* LOG_TSND_PDQ_ENTER */
+
+#ifndef LOG_TSND_PDQ_LEAVE
+#define LOG_TSND_PDQ_LEAVE(ercd)
+#endif /* LOG_TSND_PDQ_LEAVE */
+
+#ifndef LOG_RCV_PDQ_ENTER
+#define LOG_RCV_PDQ_ENTER(pdqid, p_data, p_datapri)
+#endif /* LOG_RCV_PDQ_ENTER */
+
+#ifndef LOG_RCV_PDQ_LEAVE
+#define LOG_RCV_PDQ_LEAVE(ercd, data, datapri)
+#endif /* LOG_RCV_PDQ_LEAVE */
+
+#ifndef LOG_PRCV_PDQ_ENTER
+#define LOG_PRCV_PDQ_ENTER(pdqid, p_data, p_datapri)
+#endif /* LOG_PRCV_PDQ_ENTER */
+
+#ifndef LOG_PRCV_PDQ_LEAVE
+#define LOG_PRCV_PDQ_LEAVE(ercd, data, datapri)
+#endif /* LOG_PRCV_PDQ_LEAVE */
+
+#ifndef LOG_TRCV_PDQ_ENTER
+#define LOG_TRCV_PDQ_ENTER(pdqid, p_data, p_datapri, tmout)
+#endif /* LOG_TRCV_PDQ_ENTER */
+
+#ifndef LOG_TRCV_PDQ_LEAVE
+#define LOG_TRCV_PDQ_LEAVE(ercd, data, datapri)
+#endif /* LOG_TRCV_PDQ_LEAVE */
+
+#ifndef LOG_INI_PDQ_ENTER
+#define LOG_INI_PDQ_ENTER(pdqid)
+#endif /* LOG_INI_PDQ_ENTER */
+
+#ifndef LOG_INI_PDQ_LEAVE
+#define LOG_INI_PDQ_LEAVE(ercd)
+#endif /* LOG_INI_PDQ_LEAVE */
+
+#ifndef LOG_REF_PDQ_ENTER
+#define LOG_REF_PDQ_ENTER(pdqid, pk_rpdq)
+#endif /* LOG_REF_PDQ_ENTER */
+
+#ifndef LOG_REF_PDQ_LEAVE
+#define LOG_REF_PDQ_LEAVE(ercd, pk_rpdq)
+#endif /* LOG_REF_PDQ_LEAVE */
+
+/*
+ * 優先度データキューの数
+ */
+#define tnum_pdq ((uint_t)(tmax_pdqid - TMIN_PDQID + 1))
+
+/*
+ * 優先度データキューIDから優先度データキュー管理ブロックを取り出すた
+ * めのマクロ
+ */
+#define INDEX_PDQ(pdqid) ((uint_t)((pdqid) - TMIN_PDQID))
+#define get_pdqcb(pdqid) (&(pdqcb_table[INDEX_PDQ(pdqid)]))
+
+/*
+ * 優先度データキュー機能の初期化
+ */
+#ifdef TOPPERS_pdqini
+
+void
+initialize_pridataq(void)
+{
+ uint_t i;
+ PDQCB *p_pdqcb;
+
+ for (p_pdqcb = pdqcb_table, i = 0; i < tnum_pdq; p_pdqcb++, i++) {
+ queue_initialize(&(p_pdqcb->swait_queue));
+ p_pdqcb->p_pdqinib = &(pdqinib_table[i]);
+ queue_initialize(&(p_pdqcb->rwait_queue));
+ p_pdqcb->count = 0U;
+ p_pdqcb->p_head = NULL;
+ p_pdqcb->unused = 0U;
+ p_pdqcb->p_freelist = NULL;
+ }
+}
+
+#endif /* TOPPERS_pdqini */
+
+/*
+ * 優先度データキュー管理領域へのデータの格納
+ */
+#ifdef TOPPERS_pdqenq
+
+void
+enqueue_pridata(PDQCB *p_pdqcb, intptr_t data, PRI datapri)
+{
+ PDQMB *p_pdqmb;
+ PDQMB **pp_prev_next, *p_next;
+
+ if (p_pdqcb->p_freelist != NULL) {
+ p_pdqmb = p_pdqcb->p_freelist;
+ p_pdqcb->p_freelist = p_pdqmb->p_next;
+ }
+ else {
+ p_pdqmb = p_pdqcb->p_pdqinib->p_pdqmb + p_pdqcb->unused;
+ p_pdqcb->unused++;
+ }
+
+ p_pdqmb->data = data;
+ p_pdqmb->datapri = datapri;
+
+ pp_prev_next = &(p_pdqcb->p_head);
+ while ((p_next = *pp_prev_next) != NULL) {
+ if (p_next->datapri > datapri) {
+ break;
+ }
+ pp_prev_next = &(p_next->p_next);
+ }
+ p_pdqmb->p_next = p_next;
+ *pp_prev_next = p_pdqmb;
+ p_pdqcb->count++;
+}
+
+#endif /* TOPPERS_pdqenq */
+
+/*
+ * 優先度データキュー管理領域からのデータの取出し
+ */
+#ifdef TOPPERS_pdqdeq
+
+void
+dequeue_pridata(PDQCB *p_pdqcb, intptr_t *p_data, PRI *p_datapri)
+{
+ PDQMB *p_pdqmb;
+
+ p_pdqmb = p_pdqcb->p_head;
+ p_pdqcb->p_head = p_pdqmb->p_next;
+ p_pdqcb->count--;
+
+ *p_data = p_pdqmb->data;
+ *p_datapri = p_pdqmb->datapri;
+
+ p_pdqmb->p_next = p_pdqcb->p_freelist;
+ p_pdqcb->p_freelist = p_pdqmb;
+}
+
+#endif /* TOPPERS_pdqdeq */
+
+/*
+ * 優先度データキューへのデータ送信
+ */
+#ifdef TOPPERS_pdqsnd
+
+bool_t
+send_pridata(PDQCB *p_pdqcb, intptr_t data, PRI datapri, bool_t *p_reqdsp)
+{
+ TCB *p_tcb;
+
+ if (!queue_empty(&(p_pdqcb->rwait_queue))) {
+ p_tcb = (TCB *) queue_delete_next(&(p_pdqcb->rwait_queue));
+ ((WINFO_PDQ *)(p_tcb->p_winfo))->data = data;
+ ((WINFO_PDQ *)(p_tcb->p_winfo))->datapri = datapri;
+ *p_reqdsp = wait_complete(p_tcb);
+ return(true);
+ }
+ else if (p_pdqcb->count < p_pdqcb->p_pdqinib->pdqcnt) {
+ enqueue_pridata(p_pdqcb, data, datapri);
+ *p_reqdsp = false;
+ return(true);
+ }
+ else {
+ return(false);
+ }
+}
+
+#endif /* TOPPERS_pdqsnd */
+
+/*
+ * 優先度データキューからのデータ受信
+ */
+#ifdef TOPPERS_pdqrcv
+
+bool_t
+receive_pridata(PDQCB *p_pdqcb, intptr_t *p_data,
+ PRI *p_datapri, bool_t *p_reqdsp)
+{
+ TCB *p_tcb;
+ intptr_t data;
+ PRI datapri;
+
+ if (p_pdqcb->count > 0U) {
+ dequeue_pridata(p_pdqcb, p_data, p_datapri);
+ if (!queue_empty(&(p_pdqcb->swait_queue))) {
+ p_tcb = (TCB *) queue_delete_next(&(p_pdqcb->swait_queue));
+ data = ((WINFO_PDQ *)(p_tcb->p_winfo))->data;
+ datapri = ((WINFO_PDQ *)(p_tcb->p_winfo))->datapri;
+ enqueue_pridata(p_pdqcb, data, datapri);
+ *p_reqdsp = wait_complete(p_tcb);
+ }
+ else {
+ *p_reqdsp = false;
+ }
+ return(true);
+ }
+ else if (!queue_empty(&(p_pdqcb->swait_queue))) {
+ p_tcb = (TCB *) queue_delete_next(&(p_pdqcb->swait_queue));
+ *p_data = ((WINFO_PDQ *)(p_tcb->p_winfo))->data;
+ *p_datapri = ((WINFO_PDQ *)(p_tcb->p_winfo))->datapri;
+ *p_reqdsp = wait_complete(p_tcb);
+ return(true);
+ }
+ else {
+ return(false);
+ }
+}
+
+#endif /* TOPPERS_pdqrcv */
+
+/*
+ * 優先度データキューへの送信
+ */
+#ifdef TOPPERS_snd_pdq
+
+ER
+snd_pdq(ID pdqid, intptr_t data, PRI datapri)
+{
+ PDQCB *p_pdqcb;
+ WINFO_PDQ winfo_pdq;
+ bool_t reqdsp;
+ ER ercd;
+
+ LOG_SND_PDQ_ENTER(pdqid, data, datapri);
+ CHECK_DISPATCH();
+ CHECK_PDQID(pdqid);
+ p_pdqcb = get_pdqcb(pdqid);
+ CHECK_PAR(TMIN_DPRI <= datapri && datapri <= p_pdqcb->p_pdqinib->maxdpri);
+
+ t_lock_cpu();
+ if (send_pridata(p_pdqcb, data, datapri, &reqdsp)) {
+ if (reqdsp) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ else {
+ winfo_pdq.data = data;
+ winfo_pdq.datapri = datapri;
+ p_runtsk->tstat = (TS_WAITING | TS_WAIT_SPDQ);
+ wobj_make_wait((WOBJCB *) p_pdqcb, (WINFO_WOBJ *) &winfo_pdq);
+ dispatch();
+ ercd = winfo_pdq.winfo.wercd;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_SND_PDQ_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_snd_pdq */
+
+/*
+ * 優先度データキューへの送信(ポーリング)
+ */
+#ifdef TOPPERS_psnd_pdq
+
+ER
+psnd_pdq(ID pdqid, intptr_t data, PRI datapri)
+{
+ PDQCB *p_pdqcb;
+ bool_t reqdsp;
+ ER ercd;
+
+ LOG_PSND_PDQ_ENTER(pdqid, data, datapri);
+ CHECK_TSKCTX_UNL();
+ CHECK_PDQID(pdqid);
+ p_pdqcb = get_pdqcb(pdqid);
+ CHECK_PAR(TMIN_DPRI <= datapri && datapri <= p_pdqcb->p_pdqinib->maxdpri);
+
+ t_lock_cpu();
+ if (send_pridata(p_pdqcb, data, datapri, &reqdsp)) {
+ if (reqdsp) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ else {
+ ercd = E_TMOUT;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_PSND_PDQ_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_psnd_pdq */
+
+/*
+ * 優先度データキューへの送信(ポーリング,非タスクコンテキスト用)
+ */
+#ifdef TOPPERS_ipsnd_pdq
+
+ER
+ipsnd_pdq(ID pdqid, intptr_t data, PRI datapri)
+{
+ PDQCB *p_pdqcb;
+ bool_t reqdsp;
+ ER ercd;
+
+ LOG_IPSND_PDQ_ENTER(pdqid, data, datapri);
+ CHECK_INTCTX_UNL();
+ CHECK_PDQID(pdqid);
+ p_pdqcb = get_pdqcb(pdqid);
+ CHECK_PAR(TMIN_DPRI <= datapri && datapri <= p_pdqcb->p_pdqinib->maxdpri);
+
+ i_lock_cpu();
+ if (send_pridata(p_pdqcb, data, datapri, &reqdsp)) {
+ if (reqdsp) {
+ reqflg = true;
+ }
+ ercd = E_OK;
+ }
+ else {
+ ercd = E_TMOUT;
+ }
+ i_unlock_cpu();
+
+ error_exit:
+ LOG_IPSND_PDQ_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ipsnd_pdq */
+
+/*
+ * 優先度データキューへの送信(タイムアウトあり)
+ */
+#ifdef TOPPERS_tsnd_pdq
+
+ER
+tsnd_pdq(ID pdqid, intptr_t data, PRI datapri, TMO tmout)
+{
+ PDQCB *p_pdqcb;
+ WINFO_PDQ winfo_pdq;
+ TMEVTB tmevtb;
+ bool_t reqdsp;
+ ER ercd;
+
+ LOG_TSND_PDQ_ENTER(pdqid, data, datapri, tmout);
+ CHECK_DISPATCH();
+ CHECK_PDQID(pdqid);
+ CHECK_TMOUT(tmout);
+ p_pdqcb = get_pdqcb(pdqid);
+ CHECK_PAR(TMIN_DPRI <= datapri && datapri <= p_pdqcb->p_pdqinib->maxdpri);
+
+ t_lock_cpu();
+ if (send_pridata(p_pdqcb, data, datapri, &reqdsp)) {
+ if (reqdsp) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ else if (tmout == TMO_POL) {
+ ercd = E_TMOUT;
+ }
+ else {
+ winfo_pdq.data = data;
+ winfo_pdq.datapri = datapri;
+ p_runtsk->tstat = (TS_WAITING | TS_WAIT_SPDQ);
+ wobj_make_wait_tmout((WOBJCB *) p_pdqcb, (WINFO_WOBJ *) &winfo_pdq,
+ &tmevtb, tmout);
+ dispatch();
+ ercd = winfo_pdq.winfo.wercd;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_TSND_PDQ_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_tsnd_pdq */
+
+/*
+ * 優先度データキューからの受信
+ */
+#ifdef TOPPERS_rcv_pdq
+
+ER
+rcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri)
+{
+ PDQCB *p_pdqcb;
+ WINFO_PDQ winfo_pdq;
+ bool_t reqdsp;
+ ER ercd;
+
+ LOG_RCV_PDQ_ENTER(pdqid, p_data, p_datapri);
+ CHECK_DISPATCH();
+ CHECK_PDQID(pdqid);
+ p_pdqcb = get_pdqcb(pdqid);
+
+ t_lock_cpu();
+ if (receive_pridata(p_pdqcb, p_data, p_datapri, &reqdsp)) {
+ if (reqdsp) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ else {
+ p_runtsk->tstat = (TS_WAITING | TS_WAIT_RPDQ);
+ make_wait(&(winfo_pdq.winfo));
+ queue_insert_prev(&(p_pdqcb->rwait_queue), &(p_runtsk->task_queue));
+ winfo_pdq.p_pdqcb = p_pdqcb;
+ LOG_TSKSTAT(p_runtsk);
+ dispatch();
+ ercd = winfo_pdq.winfo.wercd;
+ if (ercd == E_OK) {
+ *p_data = winfo_pdq.data;
+ *p_datapri = winfo_pdq.datapri;
+ }
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_RCV_PDQ_LEAVE(ercd, *p_data, *p_datapri);
+ return(ercd);
+}
+
+#endif /* TOPPERS_rcv_pdq */
+
+/*
+ * 優先度データキューからの受信(ポーリング)
+ */
+#ifdef TOPPERS_prcv_pdq
+
+ER
+prcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri)
+{
+ PDQCB *p_pdqcb;
+ bool_t reqdsp;
+ ER ercd;
+
+ LOG_PRCV_PDQ_ENTER(pdqid, p_data, p_datapri);
+ CHECK_TSKCTX_UNL();
+ CHECK_PDQID(pdqid);
+ p_pdqcb = get_pdqcb(pdqid);
+
+ t_lock_cpu();
+ if (receive_pridata(p_pdqcb, p_data, p_datapri, &reqdsp)) {
+ if (reqdsp) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ else {
+ ercd = E_TMOUT;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_PRCV_PDQ_LEAVE(ercd, *p_data, *p_datapri);
+ return(ercd);
+}
+
+#endif /* TOPPERS_prcv_pdq */
+
+/*
+ * 優先度データキューからの受信(タイムアウトあり)
+ */
+#ifdef TOPPERS_trcv_pdq
+
+ER
+trcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri, TMO tmout)
+{
+ PDQCB *p_pdqcb;
+ WINFO_PDQ winfo_pdq;
+ TMEVTB tmevtb;
+ bool_t reqdsp;
+ ER ercd;
+
+ LOG_TRCV_PDQ_ENTER(pdqid, p_data, p_datapri, tmout);
+ CHECK_DISPATCH();
+ CHECK_PDQID(pdqid);
+ CHECK_TMOUT(tmout);
+ p_pdqcb = get_pdqcb(pdqid);
+
+ t_lock_cpu();
+ if (receive_pridata(p_pdqcb, p_data, p_datapri, &reqdsp)) {
+ if (reqdsp) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ else if (tmout == TMO_POL) {
+ ercd = E_TMOUT;
+ }
+ else {
+ p_runtsk->tstat = (TS_WAITING | TS_WAIT_RPDQ);
+ make_wait_tmout(&(winfo_pdq.winfo), &tmevtb, tmout);
+ queue_insert_prev(&(p_pdqcb->rwait_queue), &(p_runtsk->task_queue));
+ winfo_pdq.p_pdqcb = p_pdqcb;
+ LOG_TSKSTAT(p_runtsk);
+ dispatch();
+ ercd = winfo_pdq.winfo.wercd;
+ if (ercd == E_OK) {
+ *p_data = winfo_pdq.data;
+ *p_datapri = winfo_pdq.datapri;
+ }
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_TRCV_PDQ_LEAVE(ercd, *p_data, *p_datapri);
+ return(ercd);
+}
+
+#endif /* TOPPERS_trcv_pdq */
+
+/*
+ * 優先度データキューの再初期化
+ */
+#ifdef TOPPERS_ini_pdq
+
+ER
+ini_pdq(ID pdqid)
+{
+ PDQCB *p_pdqcb;
+ bool_t dspreq;
+ ER ercd;
+
+ LOG_INI_PDQ_ENTER(pdqid);
+ CHECK_TSKCTX_UNL();
+ CHECK_PDQID(pdqid);
+ p_pdqcb = get_pdqcb(pdqid);
+
+ t_lock_cpu();
+ dspreq = init_wait_queue(&(p_pdqcb->swait_queue));
+ if (init_wait_queue(&(p_pdqcb->rwait_queue))) {
+ dspreq = true;
+ }
+ p_pdqcb->count = 0U;
+ p_pdqcb->p_head = NULL;
+ p_pdqcb->unused = 0U;
+ p_pdqcb->p_freelist = NULL;
+ if (dspreq) {
+ dispatch();
+ }
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_INI_PDQ_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ini_pdq */
+
+/*
+ * 優先度データキューの状態参照
+ */
+#ifdef TOPPERS_ref_pdq
+
+ER
+ref_pdq(ID pdqid, T_RPDQ *pk_rpdq)
+{
+ PDQCB *p_pdqcb;
+ ER ercd;
+
+ LOG_REF_PDQ_ENTER(pdqid, pk_rpdq);
+ CHECK_TSKCTX_UNL();
+ CHECK_PDQID(pdqid);
+ p_pdqcb = get_pdqcb(pdqid);
+
+ t_lock_cpu();
+ pk_rpdq->stskid = wait_tskid(&(p_pdqcb->swait_queue));
+ pk_rpdq->rtskid = wait_tskid(&(p_pdqcb->rwait_queue));
+ pk_rpdq->spdqcnt = p_pdqcb->count;
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_REF_PDQ_LEAVE(ercd, pk_rpdq);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ref_pdq */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: pridataq.h 748 2008-03-07 17:18:06Z hiro $
+ */
+
+/*
+ * 優先度データキュー機能
+ */
+
+#ifndef TOPPERS_PRIDATAQ_H
+#define TOPPERS_PRIDATAQ_H
+
+#include <queue.h>
+
+/*
+ * 優先度データ管理ブロック
+ */
+typedef struct pridata_management_block PDQMB;
+
+struct pridata_management_block {
+ PDQMB *p_next; /* 次のデータ */
+ intptr_t data; /* データ本体 */
+ PRI datapri; /* データ優先度 */
+};
+
+/*
+ * 優先度データキュー初期化ブロック
+ *
+ * この構造体は,同期・通信オブジェクトの初期化ブロックの共通部分
+ * (WOBJINIB)を拡張(オブジェクト指向言語の継承に相当)したもので,
+ * 最初のフィールドが共通になっている.
+ */
+typedef struct pridataq_initialization_block {
+ ATR pdqatr; /* 優先度データキュー属性 */
+ uint_t pdqcnt; /* 優先度データキューの容量 */
+ PRI maxdpri; /* データ優先度の最大値 */
+ PDQMB *p_pdqmb; /* 優先度データキュー管理領域の先頭番地 */
+} PDQINIB;
+
+/*
+ * 優先度データキュー管理ブロック
+ *
+ * この構造体は,同期・通信オブジェクトの管理ブロックの共通部分(WOBJCB)
+ * を拡張(オブジェクト指向言語の継承に相当)したもので,最初の2つの
+ * フィールドが共通になっている.
+ */
+typedef struct pridataq_control_block {
+ QUEUE swait_queue; /* 優先度データキュー送信待ちキュー */
+ const PDQINIB *p_pdqinib; /* 初期化ブロックへのポインタ */
+ QUEUE rwait_queue; /* 優先度データキュー受信待ちキュー */
+ uint_t count; /* 優先度データキュー中のデータの数 */
+ PDQMB *p_head; /* 最初のデータ */
+ uint_t unused; /* 未使用データ管理ブロックの先頭 */
+ PDQMB *p_freelist; /* 未割当てデータ管理ブロックのリスト */
+} PDQCB;
+
+/*
+ * 優先度データキュー待ち情報ブロックの定義
+ *
+ * この構造体は,同期・通信オブジェクトの待ち情報ブロックの共通部分
+ * (WINFO_WOBJ)を拡張(オブジェクト指向言語の継承に相当)したもので,
+ * 最初の2つのフィールドが共通になっている.
+ * 優先度データキューへの送信待ちと優先度データキューからの受信待ちで,
+ * 同じ待ち情報ブロックを使う.
+ */
+typedef struct pridataq_waiting_information {
+ WINFO winfo; /* 標準の待ち情報ブロック */
+ PDQCB *p_pdqcb; /* 待っている優先度データキューの管理ブロック*/
+ intptr_t data; /* 送受信データ */
+ PRI datapri; /* データ優先度 */
+} WINFO_PDQ;
+
+/*
+ * 優先度データキューIDの最大値(kernel_cfg.c)
+ */
+extern const ID tmax_pdqid;
+
+/*
+ * 優先度データキュー初期化ブロックのエリア(kernel_cfg.c)
+ */
+extern const PDQINIB pdqinib_table[];
+
+/*
+ * 優先度データキュー管理ブロックのエリア(kernel_cfg.c)
+ */
+extern PDQCB pdqcb_table[];
+
+/*
+ * 優先度データキュー管理ブロックから優先度データキューIDを取り出すた
+ * めのマクロ
+ */
+#define PDQID(p_pdqcb) ((ID)(((p_pdqcb) - pdqcb_table) + TMIN_PDQID))
+
+/*
+ * 優先度データキュー機能の初期化
+ */
+extern void initialize_pridataq(void);
+
+/*
+ * 優先度データキュー管理領域へのデータの格納
+ */
+extern void enqueue_pridata(PDQCB *p_pdqcb, intptr_t data, PRI datapri);
+
+/*
+ * 優先度データキュー管理領域からのデータの取出し
+ */
+extern void dequeue_pridata(PDQCB *p_pdqcb, intptr_t *p_data, PRI *p_datapri);
+
+/*
+ * 優先度データキューへのデータ送信
+ */
+extern bool_t send_pridata(PDQCB *p_pdqcb, intptr_t data,
+ PRI datapri, bool_t *p_reqdsp);
+
+/*
+ * 優先度データキューからのデータ受信
+ */
+extern bool_t receive_pridata(PDQCB *p_pdqcb, intptr_t *p_data,
+ PRI *p_datapri, bool_t *p_reqdsp);
+
+#endif /* TOPPERS_PRIDATAQ_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: semaphore.c 748 2008-03-07 17:18:06Z hiro $
+ */
+
+/*
+ * セマフォ機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "semaphore.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_SIG_SEM_ENTER
+#define LOG_SIG_SEM_ENTER(semid)
+#endif /* LOG_SIG_SEM_ENTER */
+
+#ifndef LOG_SIG_SEM_LEAVE
+#define LOG_SIG_SEM_LEAVE(ercd)
+#endif /* LOG_SIG_SEM_LEAVE */
+
+#ifndef LOG_ISIG_SEM_ENTER
+#define LOG_ISIG_SEM_ENTER(semid)
+#endif /* LOG_ISIG_SEM_ENTER */
+
+#ifndef LOG_ISIG_SEM_LEAVE
+#define LOG_ISIG_SEM_LEAVE(ercd)
+#endif /* LOG_ISIG_SEM_LEAVE */
+
+#ifndef LOG_WAI_SEM_ENTER
+#define LOG_WAI_SEM_ENTER(semid)
+#endif /* LOG_WAI_SEM_ENTER */
+
+#ifndef LOG_WAI_SEM_LEAVE
+#define LOG_WAI_SEM_LEAVE(ercd)
+#endif /* LOG_WAI_SEM_LEAVE */
+
+#ifndef LOG_POL_SEM_ENTER
+#define LOG_POL_SEM_ENTER(semid)
+#endif /* LOG_POL_SEM_ENTER */
+
+#ifndef LOG_POL_SEM_LEAVE
+#define LOG_POL_SEM_LEAVE(ercd)
+#endif /* LOG_POL_SEM_LEAVE */
+
+#ifndef LOG_TWAI_SEM_ENTER
+#define LOG_TWAI_SEM_ENTER(semid, tmout)
+#endif /* LOG_TWAI_SEM_ENTER */
+
+#ifndef LOG_TWAI_SEM_LEAVE
+#define LOG_TWAI_SEM_LEAVE(ercd)
+#endif /* LOG_TWAI_SEM_LEAVE */
+
+#ifndef LOG_INI_SEM_ENTER
+#define LOG_INI_SEM_ENTER(semid)
+#endif /* LOG_INI_SEM_ENTER */
+
+#ifndef LOG_INI_SEM_LEAVE
+#define LOG_INI_SEM_LEAVE(ercd)
+#endif /* LOG_INI_SEM_LEAVE */
+
+#ifndef LOG_REF_SEM_ENTER
+#define LOG_REF_SEM_ENTER(semid, pk_rsem)
+#endif /* LOG_REF_SEM_ENTER */
+
+#ifndef LOG_REF_SEM_LEAVE
+#define LOG_REF_SEM_LEAVE(ercd, pk_rsem)
+#endif /* LOG_REF_SEM_LEAVE */
+
+/*
+ * セマフォの数
+ */
+#define tnum_sem ((uint_t)(tmax_semid - TMIN_SEMID + 1))
+
+/*
+ * セマフォIDからセマフォ管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_SEM(semid) ((uint_t)((semid) - TMIN_SEMID))
+#define get_semcb(semid) (&(semcb_table[INDEX_SEM(semid)]))
+
+/*
+ * セマフォ機能の初期化
+ */
+#ifdef TOPPERS_semini
+
+void
+initialize_semaphore(void)
+{
+ uint_t i;
+ SEMCB *p_semcb;
+
+ for (p_semcb = semcb_table, i = 0; i < tnum_sem; p_semcb++, i++) {
+ queue_initialize(&(p_semcb->wait_queue));
+ p_semcb->p_seminib = &(seminib_table[i]);
+ p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
+ }
+}
+
+#endif /* TOPPERS_semini */
+
+/*
+ * セマフォ資源の返却
+ */
+#ifdef TOPPERS_sig_sem
+
+ER
+sig_sem(ID semid)
+{
+ SEMCB *p_semcb;
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_SIG_SEM_ENTER(semid);
+ CHECK_TSKCTX_UNL();
+ CHECK_SEMID(semid);
+ p_semcb = get_semcb(semid);
+
+ t_lock_cpu();
+ if (!queue_empty(&(p_semcb->wait_queue))) {
+ p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
+ if (wait_complete(p_tcb)) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
+ p_semcb->semcnt += 1;
+ ercd = E_OK;
+ }
+ else {
+ ercd = E_QOVR;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_SIG_SEM_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_sig_sem */
+
+/*
+ * セマフォ資源の返却(非タスクコンテキスト用)
+ */
+#ifdef TOPPERS_isig_sem
+
+ER
+isig_sem(ID semid)
+{
+ SEMCB *p_semcb;
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_ISIG_SEM_ENTER(semid);
+ CHECK_INTCTX_UNL();
+ CHECK_SEMID(semid);
+ p_semcb = get_semcb(semid);
+
+ i_lock_cpu();
+ if (!queue_empty(&(p_semcb->wait_queue))) {
+ p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
+ if (wait_complete(p_tcb)) {
+ reqflg = true;
+ }
+ ercd = E_OK;
+ }
+ else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
+ p_semcb->semcnt += 1;
+ ercd = E_OK;
+ }
+ else {
+ ercd = E_QOVR;
+ }
+ i_unlock_cpu();
+
+ error_exit:
+ LOG_ISIG_SEM_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_isig_sem */
+
+/*
+ * セマフォ資源の獲得
+ */
+#ifdef TOPPERS_wai_sem
+
+ER
+wai_sem(ID semid)
+{
+ SEMCB *p_semcb;
+ WINFO_SEM winfo_sem;
+ ER ercd;
+
+ LOG_WAI_SEM_ENTER(semid);
+ CHECK_DISPATCH();
+ CHECK_SEMID(semid);
+ p_semcb = get_semcb(semid);
+
+ t_lock_cpu();
+ if (p_semcb->semcnt >= 1) {
+ p_semcb->semcnt -= 1;
+ ercd = E_OK;
+ }
+ else {
+ p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM);
+ wobj_make_wait((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem);
+ dispatch();
+ ercd = winfo_sem.winfo.wercd;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_WAI_SEM_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_wai_sem */
+
+/*
+ * セマフォ資源の獲得(ポーリング)
+ */
+#ifdef TOPPERS_pol_sem
+
+ER
+pol_sem(ID semid)
+{
+ SEMCB *p_semcb;
+ ER ercd;
+
+ LOG_POL_SEM_ENTER(semid);
+ CHECK_TSKCTX_UNL();
+ CHECK_SEMID(semid);
+ p_semcb = get_semcb(semid);
+
+ t_lock_cpu();
+ if (p_semcb->semcnt >= 1) {
+ p_semcb->semcnt -= 1;
+ ercd = E_OK;
+ }
+ else {
+ ercd = E_TMOUT;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_POL_SEM_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_pol_sem */
+
+/*
+ * セマフォ資源の獲得(タイムアウトあり)
+ */
+#ifdef TOPPERS_twai_sem
+
+ER
+twai_sem(ID semid, TMO tmout)
+{
+ SEMCB *p_semcb;
+ WINFO_SEM winfo_sem;
+ TMEVTB tmevtb;
+ ER ercd;
+
+ LOG_TWAI_SEM_ENTER(semid, tmout);
+ CHECK_DISPATCH();
+ CHECK_SEMID(semid);
+ CHECK_TMOUT(tmout);
+ p_semcb = get_semcb(semid);
+
+ t_lock_cpu();
+ if (p_semcb->semcnt >= 1) {
+ p_semcb->semcnt -= 1;
+ ercd = E_OK;
+ }
+ else if (tmout == TMO_POL) {
+ ercd = E_TMOUT;
+ }
+ else {
+ p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM);
+ wobj_make_wait_tmout((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem,
+ &tmevtb, tmout);
+ dispatch();
+ ercd = winfo_sem.winfo.wercd;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_TWAI_SEM_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_twai_sem */
+
+/*
+ * セマフォの再初期化
+ */
+#ifdef TOPPERS_ini_sem
+
+ER
+ini_sem(ID semid)
+{
+ SEMCB *p_semcb;
+ bool_t dspreq;
+ ER ercd;
+
+ LOG_INI_SEM_ENTER(semid);
+ CHECK_TSKCTX_UNL();
+ CHECK_SEMID(semid);
+ p_semcb = get_semcb(semid);
+
+ t_lock_cpu();
+ dspreq = init_wait_queue(&(p_semcb->wait_queue));
+ p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
+ if (dspreq) {
+ dispatch();
+ }
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_INI_SEM_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ini_sem */
+
+/*
+ * セマフォの状態参照
+ */
+#ifdef TOPPERS_ref_sem
+
+ER
+ref_sem(ID semid, T_RSEM *pk_rsem)
+{
+ SEMCB *p_semcb;
+ ER ercd;
+
+ LOG_REF_SEM_ENTER(semid, pk_rsem);
+ CHECK_TSKCTX_UNL();
+ CHECK_SEMID(semid);
+ p_semcb = get_semcb(semid);
+
+ t_lock_cpu();
+ pk_rsem->wtskid = wait_tskid(&(p_semcb->wait_queue));
+ pk_rsem->semcnt = p_semcb->semcnt;
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_REF_SEM_LEAVE(ercd, pk_rsem);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ref_sem */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005,2006 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: semaphore.h 264 2007-07-12 08:23:10Z hiro $
+ */
+
+/*
+ * セマフォ機能
+ */
+
+#ifndef TOPPERS_SEMAPHORE_H
+#define TOPPERS_SEMAPHORE_H
+
+#include <queue.h>
+
+/*
+ * セマフォ初期化ブロック
+ *
+ * この構造体は,同期・通信オブジェクトの初期化ブロックの共通部分
+ * (WOBJINIB)を拡張(オブジェクト指向言語の継承に相当)したもので,
+ * 最初のフィールドが共通になっている.
+ */
+typedef struct semaphore_initialization_block {
+ ATR sematr; /* セマフォ属性 */
+ uint_t isemcnt; /* セマフォの資源数の初期値 */
+ uint_t maxsem; /* セマフォの最大資源数 */
+} SEMINIB;
+
+/*
+ * セマフォ管理ブロック
+ *
+ * この構造体は,同期・通信オブジェクトの管理ブロックの共通部分(WOBJCB)
+ * を拡張(オブジェクト指向言語の継承に相当)したもので,最初の2つの
+ * フィールドが共通になっている.
+ */
+typedef struct semaphore_control_block {
+ QUEUE wait_queue; /* セマフォ待ちキュー */
+ const SEMINIB *p_seminib; /* 初期化ブロックへのポインタ */
+ uint_t semcnt; /* セマフォ現在カウント値 */
+} SEMCB;
+
+/*
+ * セマフォ待ち情報ブロックの定義
+ *
+ * この構造体は,同期・通信オブジェクトの待ち情報ブロックの共通部分
+ * (WINFO_WOBJ)を拡張(オブジェクト指向言語の継承に相当)したもので,
+ * すべてのフィールドが共通になっている.
+ */
+typedef struct semaphore_waiting_information {
+ WINFO winfo; /* 標準の待ち情報ブロック */
+ SEMCB *p_semcb; /* 待っているセマフォの管理ブロック */
+} WINFO_SEM;
+
+/*
+ * セマフォIDの最大値(kernel_cfg.c)
+ */
+extern const ID tmax_semid;
+
+/*
+ * セマフォ初期化ブロックのエリア(kernel_cfg.c)
+ */
+extern const SEMINIB seminib_table[];
+
+/*
+ * セマフォ管理ブロックのエリア(kernel_cfg.c)
+ */
+extern SEMCB semcb_table[];
+
+/*
+ * セマフォ管理ブロックからセマフォIDを取り出すためのマクロ
+ */
+#define SEMID(p_semcb) ((ID)(((p_semcb) - semcb_table) + TMIN_SEMID))
+
+/*
+ * セマフォ機能の初期化
+ */
+extern void initialize_semaphore(void);
+
+#endif /* TOPPERS_SEMAPHORE_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: startup.c 1430 2009-01-14 17:37:56Z ertl-hiro $
+ */
+
+/*
+ * カーネルの初期化と終了処理
+ */
+
+#include "kernel_impl.h"
+#include "time_event.h"
+#include <sil.h>
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_KER_ENTER
+#define LOG_KER_ENTER()
+#endif /* LOG_KER_ENTER */
+
+#ifndef LOG_KER_LEAVE
+#define LOG_KER_LEAVE()
+#endif /* LOG_KER_LEAVE */
+
+#ifndef LOG_EXT_KER_ENTER
+#define LOG_EXT_KER_ENTER()
+#endif /* LOG_EXT_KER_ENTER */
+
+#ifndef LOG_EXT_KER_LEAVE
+#define LOG_EXT_KER_LEAVE(ercd)
+#endif /* LOG_EXT_KER_LEAVE */
+
+#ifdef TOPPERS_sta_ker
+
+/*
+ * カーネル動作状態フラグ
+ *
+ * スタートアップルーチンで,false(=0)に初期化されることを期待して
+ * いる.
+ */
+bool_t kerflg = false;
+
+/*
+ * カーネルの起動
+ */
+void
+sta_ker(void)
+{
+ /*
+ * ターゲット依存の初期化
+ */
+ target_initialize();
+
+ /*
+ * 各モジュールの初期化
+ *
+ * タイムイベント管理モジュールは他のモジュールより先に初期化
+ * する必要がある.
+ */
+ initialize_tmevt();
+ initialize_object();
+
+ /*
+ * 初期化ルーチンの実行
+ */
+ call_inirtn();
+
+ /*
+ * カーネル動作の開始
+ */
+ kerflg = true;
+ LOG_KER_ENTER();
+ start_dispatch();
+ assert(0);
+}
+
+#endif /* TOPPERS_sta_ker */
+
+/*
+ * カーネルの終了
+ */
+#ifdef TOPPERS_ext_ker
+
+ER
+ext_ker(void)
+{
+ SIL_PRE_LOC;
+
+ LOG_EXT_KER_ENTER();
+
+ /*
+ * 割込みロック状態に移行
+ */
+ SIL_LOC_INT();
+
+ /*
+ * カーネル動作の終了
+ */
+ LOG_KER_LEAVE();
+ kerflg = false;
+
+ /*
+ * カーネルの終了処理の呼出し
+ *
+ * 非タスクコンテキストに切り換えて,exit_kernelを呼び出す.
+ */
+ call_exit_kernel();
+ assert(0);
+}
+
+/*
+ * カーネルの終了処理
+ */
+void
+exit_kernel(void)
+{
+ /*
+ * 終了処理ルーチンの実行
+ */
+ call_terrtn();
+
+ /*
+ * ターゲット依存の終了処理
+ */
+ target_exit();
+ assert(0);
+}
+
+#endif /* TOPPERS_ext_ker */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: sys_manage.c 748 2008-03-07 17:18:06Z hiro $
+ */
+
+/*
+ * システム状態管理機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_ROT_RDQ_ENTER
+#define LOG_ROT_RDQ_ENTER(tskpri)
+#endif /* LOG_ROT_RDQ_ENTER */
+
+#ifndef LOG_ROT_RDQ_LEAVE
+#define LOG_ROT_RDQ_LEAVE(ercd)
+#endif /* LOG_ROT_RDQ_LEAVE */
+
+#ifndef LOG_IROT_RDQ_ENTER
+#define LOG_IROT_RDQ_ENTER(tskpri)
+#endif /* LOG_IROT_RDQ_ENTER */
+
+#ifndef LOG_IROT_RDQ_LEAVE
+#define LOG_IROT_RDQ_LEAVE(ercd)
+#endif /* LOG_IROT_RDQ_LEAVE */
+
+#ifndef LOG_GET_TID_ENTER
+#define LOG_GET_TID_ENTER(p_tskid)
+#endif /* LOG_GET_TID_ENTER */
+
+#ifndef LOG_GET_TID_LEAVE
+#define LOG_GET_TID_LEAVE(ercd, tskid)
+#endif /* LOG_GET_TID_LEAVE */
+
+#ifndef LOG_IGET_TID_ENTER
+#define LOG_IGET_TID_ENTER(p_tskid)
+#endif /* LOG_IGET_TID_ENTER */
+
+#ifndef LOG_IGET_TID_LEAVE
+#define LOG_IGET_TID_LEAVE(ercd, tskid)
+#endif /* LOG_IGET_TID_LEAVE */
+
+#ifndef LOG_LOC_CPU_ENTER
+#define LOG_LOC_CPU_ENTER()
+#endif /* LOG_LOC_CPU_ENTER */
+
+#ifndef LOG_LOC_CPU_LEAVE
+#define LOG_LOC_CPU_LEAVE(ercd)
+#endif /* LOG_LOC_CPU_LEAVE */
+
+#ifndef LOG_ILOC_CPU_ENTER
+#define LOG_ILOC_CPU_ENTER()
+#endif /* LOG_ILOC_CPU_ENTER */
+
+#ifndef LOG_ILOC_CPU_LEAVE
+#define LOG_ILOC_CPU_LEAVE(ercd)
+#endif /* LOG_ILOC_CPU_LEAVE */
+
+#ifndef LOG_UNL_CPU_ENTER
+#define LOG_UNL_CPU_ENTER()
+#endif /* LOG_UNL_CPU_ENTER */
+
+#ifndef LOG_UNL_CPU_LEAVE
+#define LOG_UNL_CPU_LEAVE(ercd)
+#endif /* LOG_UNL_CPU_LEAVE */
+
+#ifndef LOG_IUNL_CPU_ENTER
+#define LOG_IUNL_CPU_ENTER()
+#endif /* LOG_IUNL_CPU_ENTER */
+
+#ifndef LOG_IUNL_CPU_LEAVE
+#define LOG_IUNL_CPU_LEAVE(ercd)
+#endif /* LOG_IUNL_CPU_LEAVE */
+
+#ifndef LOG_DIS_DSP_ENTER
+#define LOG_DIS_DSP_ENTER()
+#endif /* LOG_DIS_DSP_ENTER */
+
+#ifndef LOG_DIS_DSP_LEAVE
+#define LOG_DIS_DSP_LEAVE(ercd)
+#endif /* LOG_DIS_DSP_LEAVE */
+
+#ifndef LOG_ENA_DSP_ENTER
+#define LOG_ENA_DSP_ENTER()
+#endif /* LOG_ENA_DSP_ENTER */
+
+#ifndef LOG_ENA_DSP_LEAVE
+#define LOG_ENA_DSP_LEAVE(ercd)
+#endif /* LOG_ENA_DSP_LEAVE */
+
+#ifndef LOG_SNS_CTX_ENTER
+#define LOG_SNS_CTX_ENTER()
+#endif /* LOG_SNS_CTX_ENTER */
+
+#ifndef LOG_SNS_CTX_LEAVE
+#define LOG_SNS_CTX_LEAVE(state)
+#endif /* LOG_SNS_CTX_LEAVE */
+
+#ifndef LOG_SNS_LOC_ENTER
+#define LOG_SNS_LOC_ENTER()
+#endif /* LOG_SNS_LOC_ENTER */
+
+#ifndef LOG_SNS_LOC_LEAVE
+#define LOG_SNS_LOC_LEAVE(state)
+#endif /* LOG_SNS_LOC_LEAVE */
+
+#ifndef LOG_SNS_DSP_ENTER
+#define LOG_SNS_DSP_ENTER()
+#endif /* LOG_SNS_DSP_ENTER */
+
+#ifndef LOG_SNS_DSP_LEAVE
+#define LOG_SNS_DSP_LEAVE(state)
+#endif /* LOG_SNS_DSP_LEAVE */
+
+#ifndef LOG_SNS_DPN_ENTER
+#define LOG_SNS_DPN_ENTER()
+#endif /* LOG_SNS_DPN_ENTER */
+
+#ifndef LOG_SNS_DPN_LEAVE
+#define LOG_SNS_DPN_LEAVE(state)
+#endif /* LOG_SNS_DPN_LEAVE */
+
+#ifndef LOG_SNS_KER_ENTER
+#define LOG_SNS_KER_ENTER()
+#endif /* LOG_SNS_KER_ENTER */
+
+#ifndef LOG_SNS_KER_LEAVE
+#define LOG_SNS_KER_LEAVE(state)
+#endif /* LOG_SNS_KER_LEAVE */
+
+/*
+ * タスクの優先順位の回転
+ */
+#ifdef TOPPERS_rot_rdq
+
+ER
+rot_rdq(PRI tskpri)
+{
+ uint_t pri;
+ ER ercd;
+
+ LOG_ROT_RDQ_ENTER(tskpri);
+ CHECK_TSKCTX_UNL();
+ CHECK_TPRI_SELF(tskpri);
+
+ t_lock_cpu();
+ pri = (tskpri == TPRI_SELF) ? p_runtsk->priority : INT_PRIORITY(tskpri);
+ if (rotate_ready_queue(pri)) {
+ dispatch();
+ }
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_ROT_RDQ_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_rot_rdq */
+
+/*
+ * タスクの優先順位の回転(非タスクコンテキスト用)
+ */
+#ifdef TOPPERS_irot_rdq
+
+ER
+irot_rdq(PRI tskpri)
+{
+ ER ercd;
+
+ LOG_IROT_RDQ_ENTER(tskpri);
+ CHECK_INTCTX_UNL();
+ CHECK_TPRI(tskpri);
+
+ i_lock_cpu();
+ if (rotate_ready_queue(INT_PRIORITY(tskpri))) {
+ reqflg = true;
+ }
+ ercd = E_OK;
+ i_unlock_cpu();
+
+ error_exit:
+ LOG_IROT_RDQ_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_irot_rdq */
+
+/*
+ * 実行状態のタスクIDの参照
+ */
+#ifdef TOPPERS_get_tid
+
+ER
+get_tid(ID *p_tskid)
+{
+ ER ercd;
+
+ LOG_GET_TID_ENTER(p_tskid);
+ CHECK_TSKCTX_UNL();
+
+ t_lock_cpu();
+ *p_tskid = TSKID(p_runtsk);
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_GET_TID_LEAVE(ercd, *p_tskid);
+ return(ercd);
+}
+
+#endif /* TOPPERS_get_tid */
+
+/*
+ * 実行状態のタスクIDの参照(非タスクコンテキスト用)
+ */
+#ifdef TOPPERS_iget_tid
+
+ER
+iget_tid(ID *p_tskid)
+{
+ ER ercd;
+
+ LOG_IGET_TID_ENTER(p_tskid);
+ CHECK_INTCTX_UNL();
+
+ i_lock_cpu();
+ *p_tskid = (p_runtsk == NULL) ? TSK_NONE : TSKID(p_runtsk);
+ ercd = E_OK;
+ i_unlock_cpu();
+
+ error_exit:
+ LOG_IGET_TID_LEAVE(ercd, *p_tskid);
+ return(ercd);
+}
+
+#endif /* TOPPERS_iget_tid */
+
+/*
+ * CPUロック状態への移行
+ */
+#ifdef TOPPERS_loc_cpu
+
+ER
+loc_cpu(void)
+{
+ ER ercd;
+
+ LOG_LOC_CPU_ENTER();
+ CHECK_TSKCTX();
+
+ if (!t_sense_lock()) {
+ t_lock_cpu();
+ }
+ ercd = E_OK;
+
+ error_exit:
+ LOG_LOC_CPU_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_loc_cpu */
+
+/*
+ * CPUロック状態への移行(非タスクコンテキスト用)
+ */
+#ifdef TOPPERS_iloc_cpu
+
+ER
+iloc_cpu(void)
+{
+ ER ercd;
+
+ LOG_ILOC_CPU_ENTER();
+ CHECK_INTCTX();
+
+ if (!i_sense_lock()) {
+ i_lock_cpu();
+ }
+ ercd = E_OK;
+
+ error_exit:
+ LOG_ILOC_CPU_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_iloc_cpu */
+
+/*
+ * CPUロック状態の解除
+ *
+ * CPUロック中は,ディスパッチが必要となるサービスコールを呼び出すこ
+ * とはできないため,CPUロック状態の解除時にディスパッチャを起動する
+ * 必要はない.
+ */
+#ifdef TOPPERS_unl_cpu
+
+ER
+unl_cpu(void)
+{
+ ER ercd;
+
+ LOG_UNL_CPU_ENTER();
+ CHECK_TSKCTX();
+
+ if (t_sense_lock()) {
+ t_unlock_cpu();
+ }
+ ercd = E_OK;
+
+ error_exit:
+ LOG_UNL_CPU_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_unl_cpu */
+
+/*
+ * CPUロック状態の解除(非タスクコンテキスト用)
+ *
+ * CPUロック中は,ディスパッチが必要となるサービスコールを呼び出すこ
+ * とはできないため,CPUロック状態の解除時にディスパッチャの起動を要
+ * 求する必要はない.
+ */
+#ifdef TOPPERS_iunl_cpu
+
+ER
+iunl_cpu(void)
+{
+ ER ercd;
+
+ LOG_IUNL_CPU_ENTER();
+ CHECK_INTCTX();
+
+ if (i_sense_lock()) {
+ i_unlock_cpu();
+ }
+ ercd = E_OK;
+
+ error_exit:
+ LOG_IUNL_CPU_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_iunl_cpu */
+
+/*
+ * ディスパッチの禁止
+ */
+#ifdef TOPPERS_dis_dsp
+
+ER
+dis_dsp(void)
+{
+ ER ercd;
+
+ LOG_DIS_DSP_ENTER();
+ CHECK_TSKCTX_UNL();
+
+ t_lock_cpu();
+ disdsp = true;
+ dspflg = false;
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_DIS_DSP_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_dis_dsp */
+
+/*
+ * ディスパッチの許可
+ */
+#ifdef TOPPERS_ena_dsp
+
+ER
+ena_dsp(void)
+{
+ ER ercd;
+
+ LOG_ENA_DSP_ENTER();
+ CHECK_TSKCTX_UNL();
+
+ t_lock_cpu();
+ disdsp = false;
+ if (t_get_ipm() == TIPM_ENAALL) {
+ dspflg = true;
+ if (p_runtsk != p_schedtsk) {
+ dispatch();
+ }
+ }
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_ENA_DSP_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ena_dsp */
+
+/*
+ * コンテキストの参照
+ */
+#ifdef TOPPERS_sns_ctx
+
+bool_t
+sns_ctx(void)
+{
+ bool_t state;
+
+ LOG_SNS_CTX_ENTER();
+ state = sense_context() ? true : false;
+ LOG_SNS_CTX_LEAVE(state);
+ return(state);
+}
+
+#endif /* TOPPERS_sns_ctx */
+
+/*
+ * CPUロック状態の参照
+ */
+#ifdef TOPPERS_sns_loc
+
+bool_t
+sns_loc(void)
+{
+ bool_t state;
+
+ LOG_SNS_LOC_ENTER();
+ state = x_sense_lock() ? true : false;
+ LOG_SNS_LOC_LEAVE(state);
+ return(state);
+}
+
+#endif /* TOPPERS_sns_loc */
+
+/*
+ * ディスパッチ禁止状態の参照
+ */
+#ifdef TOPPERS_sns_dsp
+
+bool_t
+sns_dsp(void)
+{
+ bool_t state;
+
+ LOG_SNS_DSP_ENTER();
+ state = disdsp;
+ LOG_SNS_DSP_LEAVE(state);
+ return(state);
+}
+
+#endif /* TOPPERS_sns_dsp */
+
+/*
+ * ディスパッチ保留状態の参照
+ */
+#ifdef TOPPERS_sns_dpn
+
+bool_t
+sns_dpn(void)
+{
+ bool_t state;
+
+ LOG_SNS_DPN_ENTER();
+ state = (sense_context() || t_sense_lock() || !dspflg) ? true : false;
+ LOG_SNS_DPN_LEAVE(state);
+ return(state);
+}
+
+#endif /* TOPPERS_sns_dpn */
+
+/*
+ * カーネル非動作状態の参照
+ */
+#ifdef TOPPERS_sns_ker
+
+bool_t
+sns_ker(void)
+{
+ bool_t state;
+
+ LOG_SNS_KER_ENTER();
+ state = kerflg ? false : true;
+ LOG_SNS_KER_LEAVE(state);
+ return(state);
+}
+
+#endif /* TOPPERS_sns_ker */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * $Id: task.c 1874 2010-07-29 14:23:02Z ertl-hiro $
+ */
+
+/*
+ * タスク管理モジュール
+ */
+
+#include "kernel_impl.h"
+#include "wait.h"
+#include "task.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_TEX_ENTER
+#define LOG_TEX_ENTER(p_tcb, texptn)
+#endif /* LOG_TEX_ENTER */
+
+#ifndef LOG_TEX_LEAVE
+#define LOG_TEX_LEAVE(p_tcb)
+#endif /* LOG_TEX_LEAVE */
+
+#ifdef TOPPERS_tskini
+
+/*
+ * 実行状態のタスク
+ */
+TCB *p_runtsk;
+
+/*
+ * 最高優先順位のタスク
+ */
+TCB *p_schedtsk;
+
+/*
+ * タスクディスパッチ/タスク例外処理ルーチン起動要求フラグ
+ */
+bool_t reqflg;
+
+/*
+ * ディスパッチ禁止状態
+ */
+bool_t disdsp;
+
+/*
+ * タスクディスパッチ可能状態
+ */
+bool_t dspflg;
+
+/*
+ * レディキュー
+ */
+QUEUE ready_queue[TNUM_TPRI];
+
+/*
+ * レディキューサーチのためのビットマップ
+ */
+uint16_t ready_primap;
+
+/*
+ * タスク管理モジュールの初期化
+ */
+void
+initialize_task(void)
+{
+ uint_t i, j;
+ TCB *p_tcb;
+
+ p_runtsk = p_schedtsk = NULL;
+ reqflg = false;
+ disdsp = false;
+ dspflg = true;
+
+ for (i = 0; i < TNUM_TPRI; i++) {
+ queue_initialize(&(ready_queue[i]));
+ }
+ ready_primap = 0U;
+
+ for (i = 0; i < tnum_tsk; i++) {
+ j = INDEX_TSK(torder_table[i]);
+ p_tcb = &(tcb_table[j]);
+ p_tcb->p_tinib = &(tinib_table[j]);
+ p_tcb->actque = false;
+ make_dormant(p_tcb);
+ if ((p_tcb->p_tinib->tskatr & TA_ACT) != 0U) {
+ make_active(p_tcb);
+ }
+ }
+}
+
+#endif /* TOPPERS_tskini */
+
+/*
+ * ビットマップサーチ関数
+ *
+ * bitmap内の1のビットの内,最も下位(右)のものをサーチし,そのビッ
+ * ト番号を返す.ビット番号は,最下位ビットを0とする.bitmapに0を指定
+ * してはならない.この関数では,bitmapが16ビットであることを仮定し,
+ * uint16_t型としている.
+ *
+ * ビットサーチ命令を持つプロセッサでは,ビットサーチ命令を使うように
+ * 書き直した方が効率が良い場合がある.このような場合には,ターゲット
+ * 依存部でビットサーチ命令を使ったbitmap_searchを定義し,
+ * OMIT_BITMAP_SEARCHをマクロ定義すればよい.また,ビットサーチ命令の
+ * サーチ方向が逆などの理由で優先度とビットとの対応を変更したい場合に
+ * は,PRIMAP_BITをマクロ定義すればよい.
+ *
+ * また,ライブラリにffsがあるなら,次のように定義してライブラリ関数を
+ * 使った方が効率が良い可能性もある.
+ * #define bitmap_search(bitmap) (ffs(bitmap) - 1)
+ */
+#ifndef PRIMAP_BIT
+#define PRIMAP_BIT(pri) (1U << (pri))
+#endif /* PRIMAP_BIT */
+
+#ifndef OMIT_BITMAP_SEARCH
+
+static const unsigned char bitmap_search_table[] = { 0, 1, 0, 2, 0, 1, 0,
+ 3, 0, 1, 0, 2, 0, 1, 0 };
+
+Inline uint_t
+bitmap_search(uint16_t bitmap)
+{
+ uint_t n = 0U;
+
+ assert(bitmap != 0U);
+ if ((bitmap & 0x00ffU) == 0U) {
+ bitmap >>= 8;
+ n += 8;
+ }
+ if ((bitmap & 0x0fU) == 0U) {
+ bitmap >>= 4;
+ n += 4;
+ }
+ return(n + bitmap_search_table[(bitmap & 0x0fU) - 1]);
+}
+
+#endif /* OMIT_BITMAP_SEARCH */
+
+/*
+ * 優先度ビットマップが空かのチェック
+ */
+Inline bool_t
+primap_empty(void)
+{
+ return(ready_primap == 0U);
+}
+
+/*
+ * 優先度ビットマップのサーチ
+ */
+Inline uint_t
+primap_search(void)
+{
+ return(bitmap_search(ready_primap));
+}
+
+/*
+ * 優先度ビットマップのセット
+ */
+Inline void
+primap_set(uint_t pri)
+{
+ ready_primap |= PRIMAP_BIT(pri);
+}
+
+/*
+ * 優先度ビットマップのクリア
+ */
+Inline void
+primap_clear(uint_t pri)
+{
+ ready_primap &= ~PRIMAP_BIT(pri);
+}
+
+/*
+ * 最高優先順位タスクのサーチ
+ */
+#ifdef TOPPERS_tsksched
+
+TCB *
+search_schedtsk(void)
+{
+ uint_t schedpri;
+
+ schedpri = primap_search();
+ return((TCB *)(ready_queue[schedpri].p_next));
+}
+
+#endif /* TOPPERS_tsksched */
+
+/*
+ * 実行できる状態への遷移
+ *
+ * 最高優先順位のタスクを更新するのは,実行できるタスクがなかった場合
+ * と,p_tcbの優先度が最高優先順位のタスクの優先度よりも高い場合であ
+ * る.
+ */
+#ifdef TOPPERS_tskrun
+
+bool_t
+make_runnable(TCB *p_tcb)
+{
+ uint_t pri = p_tcb->priority;
+
+ queue_insert_prev(&(ready_queue[pri]), &(p_tcb->task_queue));
+ primap_set(pri);
+
+ if (p_schedtsk == (TCB *) NULL || pri < p_schedtsk->priority) {
+ p_schedtsk = p_tcb;
+ return(dspflg);
+ }
+ return(false);
+}
+
+#endif /* TOPPERS_tskrun */
+
+/*
+ * 実行できる状態から他の状態への遷移
+ *
+ * 最高優先順位のタスクを更新するのは,p_tcbが最高優先順位のタスクで
+ * あった場合である.p_tcbと同じ優先度のタスクが他にある場合は,p_tcb
+ * の次のタスクが最高優先順位になる.そうでない場合は,レディキューを
+ * サーチする必要がある.
+ */
+#ifdef TOPPERS_tsknrun
+
+bool_t
+make_non_runnable(TCB *p_tcb)
+{
+ uint_t pri = p_tcb->priority;
+ QUEUE *p_queue = &(ready_queue[pri]);
+
+ queue_delete(&(p_tcb->task_queue));
+ if (queue_empty(p_queue)) {
+ primap_clear(pri);
+ if (p_schedtsk == p_tcb) {
+ p_schedtsk = primap_empty() ? (TCB *) NULL : search_schedtsk();
+ return(dspflg);
+ }
+ }
+ else {
+ if (p_schedtsk == p_tcb) {
+ p_schedtsk = (TCB *)(p_queue->p_next);
+ return(dspflg);
+ }
+ }
+ return(false);
+}
+
+#endif /* TOPPERS_tsknrun */
+
+/*
+ * 休止状態への遷移
+ */
+#ifdef TOPPERS_tskdmt
+
+void
+make_dormant(TCB *p_tcb)
+{
+ p_tcb->tstat = TS_DORMANT;
+ p_tcb->priority = p_tcb->p_tinib->ipriority;
+ p_tcb->wupque = false;
+ p_tcb->enatex = false;
+ p_tcb->texptn = 0U;
+ LOG_TSKSTAT(p_tcb);
+}
+
+#endif /* TOPPERS_tskdmt */
+
+/*
+ * 休止状態から実行できる状態への遷移
+ */
+#ifdef TOPPERS_tskact
+
+bool_t
+make_active(TCB *p_tcb)
+{
+ activate_context(p_tcb);
+ p_tcb->tstat = TS_RUNNABLE;
+ LOG_TSKSTAT(p_tcb);
+ return(make_runnable(p_tcb));
+}
+
+#endif /* TOPPERS_tskact */
+
+/*
+ * タスクの優先度の変更
+ *
+ * タスクが実行できる状態の場合には,レディキューの中での位置を変更す
+ * る.オブジェクトの待ちキューの中で待ち状態になっている場合には,待
+ * ちキューの中での位置を変更する.
+ *
+ * 最高優先順位のタスクを更新するのは,(1) p_tcbが最高優先順位のタス
+ * クであって,その優先度を下げた場合,(2) p_tcbが最高優先順位のタス
+ * クではなく,変更後の優先度が最高優先順位のタスクの優先度よりも高い
+ * 場合である.(1)の場合には,レディキューをサーチする必要がある.
+ */
+#ifdef TOPPERS_tskpri
+
+bool_t
+change_priority(TCB *p_tcb, uint_t newpri)
+{
+ uint_t oldpri;
+
+ oldpri = p_tcb->priority;
+ p_tcb->priority = newpri;
+
+ if (TSTAT_RUNNABLE(p_tcb->tstat)) {
+ /*
+ * タスクが実行できる状態の場合
+ */
+ queue_delete(&(p_tcb->task_queue));
+ if (queue_empty(&(ready_queue[oldpri]))) {
+ primap_clear(oldpri);
+ }
+ queue_insert_prev(&(ready_queue[newpri]), &(p_tcb->task_queue));
+ primap_set(newpri);
+
+ if (p_schedtsk == p_tcb) {
+ if (newpri >= oldpri) {
+ p_schedtsk = search_schedtsk();
+ return(p_schedtsk != p_tcb && dspflg);
+ }
+ }
+ else {
+ if (newpri < p_schedtsk->priority) {
+ p_schedtsk = p_tcb;
+ return(dspflg);
+ }
+ }
+ }
+ else {
+ if (TSTAT_WAIT_WOBJCB(p_tcb->tstat)) {
+ /*
+ * タスクが,同期・通信オブジェクトの管理ブロックの共通部
+ * 分(WOBJCB)の待ちキューにつながれている場合
+ */
+ wobj_change_priority(((WINFO_WOBJ *)(p_tcb->p_winfo))->p_wobjcb,
+ p_tcb);
+ }
+ }
+ return(false);
+}
+
+#endif /* TOPPERS_tskpri */
+
+/*
+ * レディキューの回転
+ *
+ * 最高優先順位のタスクを更新するのは,最高優先順位のタスクがタスクキ
+ * ューの末尾に移動した場合である.
+ */
+#ifdef TOPPERS_tskrot
+
+bool_t
+rotate_ready_queue(uint_t pri)
+{
+ QUEUE *p_queue = &(ready_queue[pri]);
+ QUEUE *p_entry;
+
+ if (!queue_empty(p_queue) && p_queue->p_next->p_next != p_queue) {
+ p_entry = queue_delete_next(p_queue);
+ queue_insert_prev(p_queue, p_entry);
+ if (p_schedtsk == (TCB *) p_entry) {
+ p_schedtsk = (TCB *)(p_queue->p_next);
+ return(dspflg);
+ }
+ }
+ return(false);
+}
+
+#endif /* TOPPERS_tskrot */
+
+/*
+ * タスク例外処理ルーチンの呼出し
+ *
+ * ASPカーネルでは,タスク例外処理ルーチン内でCPUロック状態に遷移し,
+ * 元の状態に戻さずにリターンした場合,カーネルが元の状態に戻す.
+ */
+#ifdef TOPPERS_tsktex
+
+void
+call_texrtn(void)
+{
+ TEXPTN texptn;
+ PRI saved_ipm;
+ bool_t saved_disdsp, saved_dspflg;
+
+ saved_ipm = t_get_ipm();
+ saved_disdsp = disdsp;
+ saved_dspflg = dspflg;
+ p_runtsk->enatex = false;
+ do {
+ texptn = p_runtsk->texptn;
+ p_runtsk->texptn = 0U;
+
+ t_unlock_cpu();
+ LOG_TEX_ENTER(p_runtsk, texptn);
+ (*((TEXRTN)(p_runtsk->p_tinib->texrtn)))(texptn,
+ p_runtsk->p_tinib->exinf);
+ LOG_TEX_LEAVE(p_runtsk);
+ if (!t_sense_lock()) {
+ t_lock_cpu();
+ }
+ t_set_ipm(saved_ipm);
+ disdsp = saved_disdsp;
+ dspflg = saved_dspflg;
+ /*
+ * ここでp_runtsk->enatexをfalseにするのは,タスク例外処理ルー
+ * チンから,タスク例外処理許可状態のままリターンした場合の対
+ * 策である.
+ */
+ p_runtsk->enatex = false;
+ if (p_runtsk != p_schedtsk && dspflg) {
+ /*
+ * ここでdispatchを呼び出す処理は,相互再帰呼出しになって
+ * いるが,dispatchを呼ぶ前にp_runtsk->enatexをflaseにして
+ * おけば支障がない.その理由については,「TOPPERS/ASP カー
+ * ネル 設計メモ」を参照のこと.
+ */
+ dispatch();
+ }
+ } while (p_runtsk->texptn != 0U);
+ p_runtsk->enatex = true;
+}
+
+/*
+ * タスク例外処理ルーチンの起動
+ */
+#ifndef OMIT_CALLTEX
+
+void
+calltex(void)
+{
+ if (p_runtsk->enatex && p_runtsk->texptn != 0U) {
+ call_texrtn();
+ }
+}
+
+#endif /* OMIT_CALLTEX */
+#endif /* TOPPERS_tsktex */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * $Id: task.h 1839 2010-07-10 17:27:27Z ertl-hiro $
+ */
+
+/*
+ * タスク管理モジュール
+ */
+
+#ifndef TOPPERS_TASK_H
+#define TOPPERS_TASK_H
+
+#include <queue.h>
+#include "time_event.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_TSKSTAT
+#define LOG_TSKSTAT(p_tcb)
+#endif /* LOG_TSKSTAT */
+
+/*
+ * タスク優先度の内部表現・外部表現変換マクロ
+ */
+#define INT_PRIORITY(x) ((uint_t)((x) - TMIN_TPRI))
+#define EXT_TSKPRI(x) ((PRI)(x) + TMIN_TPRI)
+
+/*
+ * タスク状態の内部表現
+ *
+ * TCB中のタスク状態では,実行状態(RUNNING)と実行可能状態(READY)
+ * は区別しない.両状態を総称して,実行できる状態(RUNNABLE)と呼ぶ.
+ * 二重待ち状態は,(TS_WAITING | TS_SUSPENDED)で表す.TS_WAIT_???は待
+ * ち要因を表し,待ち状態(二重待ち状態を含む)の場合にのみ設定する.
+ */
+#define TS_DORMANT 0x00U /* 休止状態 */
+#define TS_RUNNABLE 0x01U /* 実行できる状態 */
+#define TS_WAITING 0x02U /* 待ち状態 */
+#define TS_SUSPENDED 0x04U /* 強制待ち状態 */
+
+#define TS_WAIT_DLY (0x00U << 3) /* 時間経過待ち */
+#define TS_WAIT_SLP (0x01U << 3) /* 起床待ち */
+#define TS_WAIT_RDTQ (0x02U << 3) /* データキューからの受信待ち */
+#define TS_WAIT_RPDQ (0x03U << 3) /* 優先度データキューからの受信待ち */
+#define TS_WAIT_SEM (0x04U << 3) /* セマフォ資源の獲得待ち */
+#define TS_WAIT_FLG (0x05U << 3) /* イベントフラグ待ち */
+#define TS_WAIT_SDTQ (0x06U << 3) /* データキューへの送信待ち */
+#define TS_WAIT_SPDQ (0x07U << 3) /* 優先度データキューへの送信待ち */
+#define TS_WAIT_MBX (0x08U << 3) /* メールボックスからの受信待ち */
+#define TS_WAIT_MPF (0x09U << 3) /* 固定長メモリブロックの獲得待ち */
+
+/*
+ * タスク状態判別マクロ
+ *
+ * TSTAT_DORMANTはタスクが休止状態であるかどうかを,TSTAT_RUNNABLEは
+ * タスクが実行できる状態であるかどうかを判別する.TSTAT_WAITINGは待
+ * ち状態と二重待ち状態のいずれかであるかどうかを,TSTAT_SUSPENDEDは
+ * 強制待ち状態と二重待ち状態のいずれかであるかどうかを判別する.
+ */
+#define TSTAT_DORMANT(tstat) ((tstat) == TS_DORMANT)
+#define TSTAT_RUNNABLE(tstat) (((tstat) & TS_RUNNABLE) != 0U)
+#define TSTAT_WAITING(tstat) (((tstat) & TS_WAITING) != 0U)
+#define TSTAT_SUSPENDED(tstat) (((tstat) & TS_SUSPENDED) != 0U)
+
+/*
+ * タスク待ち要因判別マクロ
+ *
+ * TSTAT_WAIT_SLPはタスクが起床待ちであるかどうかを,TSTAT_WAIT_WOBJ
+ * はタスクが同期・通信オブジェクトに対する待ちであるか(言い換えると,
+ * 同期通信オブジェクトの待ちキューにつながれているか)どうかを判別す
+ * る.また,TSTAT_WAIT_WOBJCBはタスクが同期・通信オブジェクトの管理
+ * ブロックの共通部分(WOBJCB)の待ちキューにつながれているかどうかを
+ * 判別する.
+ *
+ * TSTAT_WAIT_SLPは,任意のタスク状態の中から,タスクが起床待ちである
+ * ことを判別できる.すなわち,TSTAT_WAITINGにより待ち状態であることを
+ * 判別せずに,TSTAT_SLPだけを用いて起床待ち状態であることを判別できる.
+ * これを効率的に実現するために,TS_WAIT_SLPの値を,(0x00U << 3)ではな
+ * く(0x01U << 3)としている.そのため,タスクが時間経過待ち状態である
+ * ことを判別するためのTSTAT_WAIT_DLYを,TSTAT_WAIT_SLPと同様の方法で
+ * 実現することはできない.
+ */
+#define TS_WAIT_MASK (0x0fU << 3) /* 待ち要因の取出しマスク */
+
+#define TSTAT_WAIT_SLP(tstat) (((tstat) & TS_WAIT_MASK) == TS_WAIT_SLP)
+#define TSTAT_WAIT_WOBJ(tstat) (((tstat) & TS_WAIT_MASK) >= TS_WAIT_RDTQ)
+#define TSTAT_WAIT_WOBJCB(tstat) (((tstat) & TS_WAIT_MASK) >= TS_WAIT_SEM)
+
+/*
+ * 待ち情報ブロック(WINFO)の定義
+ *
+ * タスクが待ち状態の間は,TCBおよびそのp_winfoで指されるWINFOを次の
+ * ように設定しなければならない.
+ *
+ * (a) TCBのタスク状態を待ち状態(TS_WAITING)にする.その際に,待ち
+ * 要因(TS_WAIT_???)も設定する.
+ *
+ * (b) タイムアウトを監視するために,タイムイベントブロックを登録する.
+ * 登録するタイムイベントブロックは,待ちに入るサービスコール処理関数
+ * のローカル変数として確保し,それへのポインタをWINFOのp_tmevtbに記
+ * 憶する.タイムアウトの監視が必要ない場合(永久待ちの場合)には,
+ * p_tmevtbをNULLにする.
+ *
+ * 同期・通信オブジェクトに対する待ち状態の場合には,標準のWINFOに
+ * p_wobjcbフィールドを追加した構造体(WINFO_WOBJ,wait.hで定義)を使
+ * う.また,以下の(c)〜(e)の設定を行う必要がある.同期・通信オブジェ
+ * クトに関係しない待ち(起床待ち,時間経過待ち)の場合には,(c)〜(e)
+ * は必要ない.
+ *
+ * (c) TCBを待ち対象の同期・通信オブジェクトの待ちキューにつなぐ.待
+ * ちキューにつなぐために,task_queueを使う.
+ *
+ * (d) 待ち対象の同期・通信オブジェクトの管理ブロックへのポインタを,
+ * WINFO_WOBJのp_wobjcbに記憶する.
+ *
+ * (e) 待ち対象の同期・通信オブジェクトに依存して記憶することが必要な
+ * 情報がある場合には,WINFO_WOBJに必要な情報のためのフィールドを追加
+ * した構造体を定義し,WINFO_WOBJの代わりに用いる.
+ *
+ * 待ち状態を解除する際には,待ち解除したタスクに対する返値をWINFOの
+ * wercdに設定する.wercdが必要なのは待ち解除以降であるのに対して,
+ * p_tmevtbは待ち解除後は必要ないため,メモリ節約のために共用体を使っ
+ * ている.そのため,wercdへエラーコードを設定するのは,タイムイベント
+ * ブロックを登録解除した後にしなければならない.
+ */
+typedef union waiting_information {
+ ER wercd; /* 待ち解除時のエラーコード */
+ TMEVTB *p_tmevtb; /* 待ち状態用のタイムイベントブロック */
+} WINFO;
+
+/*
+ * タスク初期化ブロック
+ *
+ * タスクに関する情報を,値が変わらないためにROMに置ける部分(タスク
+ * 初期化ブロック)と,値が変化するためにRAMに置かなければならない部
+ * 分(タスク管理ブロック,TCB)に分離し,TCB内に対応するタスク初期化
+ * ブロックを指すポインタを入れる.タスク初期化ブロック内に対応する
+ * TCBを指すポインタを入れる方法の方が,RAMの節約の観点からは望ましい
+ * が,実行効率が悪くなるために採用していない.他のオブジェクトについ
+ * ても同様に扱う.
+ *
+ * タスク初期化ブロックには,DEF_TEXで定義されるタスク例外処理ルーチ
+ * ンに関する情報も含む.
+ */
+typedef struct task_initialization_block {
+ ATR tskatr; /* タスク属性 */
+ intptr_t exinf; /* タスクの拡張情報 */
+ TASK task; /* タスクの起動番地 */
+ uint_t ipriority; /* タスクの起動時優先度(内部表現) */
+
+#ifdef USE_TSKINICTXB
+ TSKINICTXB tskinictxb; /* タスク初期化コンテキストブロック */
+#else /* USE_TSKINICTXB */
+ SIZE stksz; /* スタック領域のサイズ(丸めた値) */
+ void *stk; /* スタック領域の先頭番地 */
+#endif /* USE_TSKINICTXB */
+
+ ATR texatr; /* タスク例外処理ルーチン属性 */
+ TEXRTN texrtn; /* タスク例外処理ルーチンの起動番地 */
+} TINIB;
+
+/*
+ * TCB中のフィールドのビット幅の定義
+ *
+ * プロセッサによっては,TCB中のフィールドのビット幅でメモリ使用量と
+ * 性能がトレードオフになるため,ターゲット依存にフィールドのビット幅
+ * を変更することを許している.
+ */
+#ifndef TBIT_TCB_PRIORITY
+#define TBIT_TCB_PRIORITY 8 /* priorityフィールドのビット幅 */
+#endif /* TBIT_TCB_PRIORITY */
+
+/*
+ * タスク管理ブロック(TCB)
+ *
+ * ASPカーネルでは,タスクの起動要求キューイング数の最大値(TMAX_ACTCNT)
+ * と起床要求キューイング数の最大値(TMAX_WUPCNT)は1に固定されている
+ * ため,キューイングされているかどうかの真偽値で表現することができる.
+ * また,強制待ち要求ネスト数の最大値(TMAX_SUSCNT)が1に固定されてい
+ * るので,強制待ち要求ネスト数(suscnt)は必要ない.
+ *
+ * TCBのいくつかのフィールドは,特定のタスク状態でのみ有効な値を保持し,
+ * それ以外の場合は値が保証されない(よって,参照してはならない).各
+ * フィールドが有効な値を保持する条件は次の通り.
+ *
+ * ・初期化後は常に有効:
+ * p_tinib,tstat,actque
+ * ・休止状態以外で有効(休止状態では初期値になっている):
+ * priority,wupque,enatex,texptn
+ * ・待ち状態(二重待ち状態を含む)で有効:
+ * p_winfo
+ * ・実行できる状態と同期・通信オブジェクトに対する待ち状態で有効:
+ * task_queue
+ * ・実行可能状態,待ち状態,強制待ち状態,二重待ち状態で有効:
+ * tskctxb
+ */
+typedef struct task_control_block {
+ QUEUE task_queue; /* タスクキュー */
+ const TINIB *p_tinib; /* 初期化ブロックへのポインタ */
+
+#ifdef UINT8_MAX
+ uint8_t tstat; /* タスク状態(内部表現)*/
+#else /* UINT8_MAX */
+ BIT_FIELD_UINT tstat : 8; /* タスク状態(内部表現)*/
+#endif /* UINT8_MAX */
+#if defined(UINT8_MAX) && (TBIT_TCB_PRIORITY == 8)
+ uint8_t priority; /* 現在の優先度(内部表現)*/
+#else /* defined(UINT8_MAX) && (TBIT_TCB_PRIORITY == 8) */
+ BIT_FIELD_UINT priority : TBIT_TCB_PRIORITY;
+ /* 現在の優先度(内部表現)*/
+#endif /* defined(UINT8_MAX) && (TBIT_TCB_PRIORITY == 8) */
+ BIT_FIELD_BOOL actque : 1; /* 起動要求キューイング */
+ BIT_FIELD_BOOL wupque : 1; /* 起床要求キューイング */
+ BIT_FIELD_BOOL enatex : 1; /* タスク例外処理許可状態 */
+
+ TEXPTN texptn; /* 保留例外要因 */
+ WINFO *p_winfo; /* 待ち情報ブロックへのポインタ */
+ TSKCTXB tskctxb; /* タスクコンテキストブロック */
+} TCB;
+
+/*
+ * 実行状態のタスク
+ *
+ * 実行状態のタスク(=プロセッサがコンテキストを持っているタスク)の
+ * TCBを指すポインタ.実行状態のタスクがない場合はNULLにする.
+ *
+ * サービスコールの処理中で,自タスク(サービスコールを呼び出したタス
+ * ク)に関する情報を参照する場合はp_runtskを使う.p_runtskを書き換え
+ * るのは,ディスパッチャ(と初期化処理)のみである.
+ */
+extern TCB *p_runtsk;
+
+/*
+ * 最高優先順位のタスク
+ *
+ * 実行できるタスクの中で最高優先順位のタスクのTCBを指すポインタ.実
+ * 行できるタスクがない場合はNULLにする.
+ *
+ * ディスパッチ禁止状態など,ディスパッチが保留されている間はp_runtsk
+ * と一致しているとは限らない.
+ */
+extern TCB *p_schedtsk;
+
+/*
+ * ディスパッチ/タスク例外処理ルーチン起動要求フラグ
+ *
+ * 割込みハンドラ/CPU例外ハンドラの出口処理に,ディスパッチまたは
+ * タスク例外処理ルーチンの起動を要求することを示すフラグ.
+ */
+extern bool_t reqflg;
+
+/*
+ * ディスパッチ禁止状態
+ *
+ * ディスパッチ禁止状態であることを示すフラグ.
+ */
+extern bool_t disdsp;
+
+/*
+ * タスクディスパッチ可能状態
+ *
+ * 割込み優先度マスク全解除状態であり,ディスパッチ許可状態である(ディ
+ * スパッチ禁止状態でない)ことを示すフラグ.
+ */
+extern bool_t dspflg;
+
+/*
+ * レディキュー
+ *
+ * レディキューは,実行できる状態のタスクを管理するためのキューである.
+ * 実行状態のタスクも管理しているため,レディ(実行可能)キューという
+ * 名称は正確ではないが,レディキューという名称が定着しているため,こ
+ * の名称で呼ぶことにする.
+ *
+ * レディキューは,優先度ごとのタスクキューで構成されている.タスクの
+ * TCBは,該当する優先度のキューに登録される.
+ */
+extern QUEUE ready_queue[TNUM_TPRI];
+
+/*
+ * レディキューサーチのためのビットマップ
+ *
+ * レディキューのサーチを効率よく行うために,優先度ごとのタスクキュー
+ * にタスクが入っているかどうかを示すビットマップを用意している.ビッ
+ * トマップを使うことで,メモリアクセスの回数を減らすことができるが,
+ * ビット操作命令が充実していないプロセッサで,優先度の段階数が少ない
+ * 場合には,ビットマップ操作のオーバーヘッドのために,逆に効率が落ち
+ * る可能性もある.
+ *
+ * 優先度が16段階であることを仮定しているため,uint16_t型としている.
+ */
+extern uint16_t ready_primap;
+
+/*
+ * タスクIDの最大値(kernel_cfg.c)
+ */
+extern const ID tmax_tskid;
+
+/*
+ * タスク初期化ブロックのエリア(kernel_cfg.c)
+ */
+extern const TINIB tinib_table[];
+
+/*
+ * タスク生成順序テーブル(kernel_cfg.c)
+ */
+extern const ID torder_table[];
+
+/*
+ * TCBのエリア(kernel_cfg.c)
+ */
+extern TCB tcb_table[];
+
+/*
+ * タスクの数
+ */
+#define tnum_tsk ((uint_t)(tmax_tskid - TMIN_TSKID + 1))
+
+/*
+ * タスクIDからTCBを取り出すためのマクロ
+ */
+#define INDEX_TSK(tskid) ((uint_t)((tskid) - TMIN_TSKID))
+#define get_tcb(tskid) (&(tcb_table[INDEX_TSK(tskid)]))
+#define get_tcb_self(tskid) ((tskid) == TSK_SELF ? p_runtsk : get_tcb(tskid))
+
+/*
+ * TCBからタスクIDを取り出すためのマクロ
+ */
+#define TSKID(p_tcb) ((ID)(((p_tcb) - tcb_table) + TMIN_TSKID))
+
+/*
+ * タスク管理モジュールの初期化
+ */
+extern void initialize_task(void);
+
+/*
+ * 最高優先順位タスクのサーチ
+ *
+ * レディキュー中の最高優先順位のタスクをサーチし,そのTCBへのポインタ
+ * を返す.レディキューが空の場合には,この関数を呼び出してはならない.
+ */
+extern TCB *search_schedtsk(void);
+
+/*
+ * 実行できる状態への遷移
+ *
+ * p_tcbで指定されるタスクをレディキューに挿入する.レディキューに挿入
+ * したタスクの優先度が,最高優先順位のタスクの優先度よりも高い場合は,
+ * 最高優先順位のタスクを更新し,ディスパッチ許可状態であればtrueを返
+ * す.そうでない場合はfalseを返す.
+ */
+extern bool_t make_runnable(TCB *p_tcb);
+
+/*
+ * 実行できる状態から他の状態への遷移
+ *
+ * p_tcbで指定されるタスクをレディキューから削除する.p_tcbで指定した
+ * タスクが最高優先順位のタスクであった場合には,最高優先順位のタスク
+ * を設定しなおし,ディスパッチ許可状態であればtrueを返す.そうでない
+ * 場合はfalseを返す.タスクの状態は更新しない.
+ */
+extern bool_t make_non_runnable(TCB *p_tcb);
+
+/*
+ * 休止状態への遷移
+ *
+ * p_tcbで指定されるタスクの状態を休止状態とする.また,タスクの起動
+ * 時に初期化すべき変数の初期化と,タスク起動のためのコンテキストを設
+ * 定する.
+ */
+extern void make_dormant(TCB *p_tcb);
+
+/*
+ * 休止状態から実行できる状態への遷移
+ *
+ * p_tcbで指定されるタスクの状態を休止状態から実行できる状態とする.
+ * 実行できる状態に遷移したタスクへのディスパッチが必要な場合はtrue,
+ * そうでない場合はfalseを返す.
+ */
+extern bool_t make_active(TCB *p_tcb);
+
+/*
+ * タスクの優先度の変更
+ *
+ * p_tcbで指定されるタスクの優先度をnewpri(内部表現)に変更する.また,
+ * 必要な場合には最高優先順位のタスクを更新し,ディスパッチ許可状態で
+ * あればtrueを返す.そうでない場合はfalseを返す.
+ */
+extern bool_t change_priority(TCB *p_tcb, uint_t newpri);
+
+/*
+ * レディキューの回転
+ *
+ * レディキュー中の,priで指定される優先度のタスクキューを回転させる.
+ * また,必要な場合には最高優先順位のタスクを変更し,ディスパッチが保
+ * 留されていなければtrueを返す.そうでない場合はfalseを返す.
+ */
+extern bool_t rotate_ready_queue(uint_t pri);
+
+/*
+ * タスク例外処理ルーチンの呼出し
+ *
+ * タスク例外処理ルーチンを呼び出す.呼び出す前に,実行状態のタスクの
+ * 保留例外要因をクリアし,タスク例外処理禁止状態にし,CPUロックを解
+ * 除する.
+ *
+ * タスク例外処理ルーチンから戻ると,まずCPUロック状態に戻し,その間
+ * に保留例外要因が0でなくなっていれば,再びタスク例外処理ルーチンを
+ * 呼び出す.保留例外要因が0の場合には,例外処理許可状態にして関数か
+ * らリターンする.
+ *
+ * この関数は,実行状態のタスクが,タスク例外処理許可状態(enatexが
+ * true)で,保留例外要因が0でない(texptnが0でない)場合に呼び出すこ
+ * とを想定している.この関数は,CPUロック状態で呼び出さなければなら
+ * ない.
+ */
+extern void call_texrtn(void);
+
+/*
+ * タスク例外処理ルーチンの起動
+ *
+ * 実行状態のタスクがタスク例外処理ルーチンの起動条件を満たしていれば,
+ * タスク例外処理ルーチンを呼び出す.CPU例外処理ルーチンを呼び出す時
+ * は,一時的にCPUロックを解除する.
+ *
+ * この関数は,ディスパッチャや割込みハンドラ/CPU例外ハンドラの出口
+ * 処理から呼び出されることを想定している.この関数は,CPUロック状態
+ * で呼び出さなければならない.
+ *
+ * 実行効率を上げるために,この関数をターゲット依存部で記述してもよい.
+ * その場合には,OMIT_CALLTEXをマクロ定義する.
+ */
+extern void calltex(void);
+
+#endif /* TOPPERS_TASK_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: task_except.c 748 2008-03-07 17:18:06Z hiro $
+ */
+
+/*
+ * タスク例外処理機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_RAS_TEX_ENTER
+#define LOG_RAS_TEX_ENTER(tskid, rasptn)
+#endif /* LOG_RAS_TEX_ENTER */
+
+#ifndef LOG_RAS_TEX_LEAVE
+#define LOG_RAS_TEX_LEAVE(ercd)
+#endif /* LOG_RAS_TEX_LEAVE */
+
+#ifndef LOG_IRAS_TEX_ENTER
+#define LOG_IRAS_TEX_ENTER(tskid, rasptn)
+#endif /* LOG_IRAS_TEX_ENTER */
+
+#ifndef LOG_IRAS_TEX_LEAVE
+#define LOG_IRAS_TEX_LEAVE(ercd)
+#endif /* LOG_IRAS_TEX_LEAVE */
+
+#ifndef LOG_DIS_TEX_ENTER
+#define LOG_DIS_TEX_ENTER()
+#endif /* LOG_DIS_TEX_ENTER */
+
+#ifndef LOG_DIS_TEX_LEAVE
+#define LOG_DIS_TEX_LEAVE(ercd)
+#endif /* LOG_DIS_TEX_LEAVE */
+
+#ifndef LOG_ENA_TEX_ENTER
+#define LOG_ENA_TEX_ENTER()
+#endif /* LOG_ENA_TEX_ENTER */
+
+#ifndef LOG_ENA_TEX_LEAVE
+#define LOG_ENA_TEX_LEAVE(ercd)
+#endif /* LOG_ENA_TEX_LEAVE */
+
+#ifndef LOG_SNS_TEX_ENTER
+#define LOG_SNS_TEX_ENTER()
+#endif /* LOG_SNS_TEX_ENTER */
+
+#ifndef LOG_SNS_TEX_LEAVE
+#define LOG_SNS_TEX_LEAVE(state)
+#endif /* LOG_SNS_TEX_LEAVE */
+
+#ifndef LOG_REF_TEX_ENTER
+#define LOG_REF_TEX_ENTER(tskid, pk_rtex)
+#endif /* LOG_REF_TEX_ENTER */
+
+#ifndef LOG_REF_TEX_LEAVE
+#define LOG_REF_TEX_LEAVE(ercd, pk_rtex)
+#endif /* LOG_REF_TEX_LEAVE */
+
+/*
+ * タスク例外処理の要求
+ */
+#ifdef TOPPERS_ras_tex
+
+ER
+ras_tex(ID tskid, TEXPTN rasptn)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_RAS_TEX_ENTER(tskid, rasptn);
+ CHECK_TSKCTX_UNL();
+ CHECK_TSKID_SELF(tskid);
+ CHECK_PAR(rasptn != 0U);
+ p_tcb = get_tcb_self(tskid);
+
+ t_lock_cpu();
+ if (TSTAT_DORMANT(p_tcb->tstat) || p_tcb->p_tinib->texrtn == NULL) {
+ ercd = E_OBJ;
+ }
+ else {
+ p_tcb->texptn |= rasptn;
+ if (p_tcb == p_runtsk && p_runtsk->enatex) {
+ call_texrtn();
+ }
+ ercd = E_OK;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_RAS_TEX_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ras_tex */
+
+/*
+ * タスク例外処理の要求(非タスクコンテキスト用)
+ */
+#ifdef TOPPERS_iras_tex
+
+ER
+iras_tex(ID tskid, TEXPTN rasptn)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_IRAS_TEX_ENTER(tskid, rasptn);
+ CHECK_INTCTX_UNL();
+ CHECK_TSKID(tskid);
+ CHECK_PAR(rasptn != 0U);
+ p_tcb = get_tcb(tskid);
+
+ i_lock_cpu();
+ if (TSTAT_DORMANT(p_tcb->tstat) || p_tcb->p_tinib->texrtn == NULL) {
+ ercd = E_OBJ;
+ }
+ else {
+ p_tcb->texptn |= rasptn;
+ if (p_tcb == p_runtsk && p_runtsk->enatex) {
+ reqflg = true;
+ }
+ ercd = E_OK;
+ }
+ i_unlock_cpu();
+
+ error_exit:
+ LOG_IRAS_TEX_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_iras_tex */
+
+/*
+ * タスク例外処理の禁止
+ */
+#ifdef TOPPERS_dis_tex
+
+ER
+dis_tex(void)
+{
+ ER ercd;
+
+ LOG_DIS_TEX_ENTER();
+ CHECK_TSKCTX_UNL();
+
+ t_lock_cpu();
+ if (p_runtsk->p_tinib->texrtn == NULL) {
+ ercd = E_OBJ;
+ }
+ else {
+ p_runtsk->enatex = false;
+ ercd = E_OK;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_DIS_TEX_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_dis_tex */
+
+/*
+ * タスク例外処理の許可
+ */
+#ifdef TOPPERS_ena_tex
+
+ER
+ena_tex(void)
+{
+ ER ercd;
+
+ LOG_ENA_TEX_ENTER();
+ CHECK_TSKCTX_UNL();
+
+ t_lock_cpu();
+ if (p_runtsk->p_tinib->texrtn == NULL) {
+ ercd = E_OBJ;
+ }
+ else {
+ p_runtsk->enatex = true;
+ if (p_runtsk->texptn != 0U) {
+ call_texrtn();
+ }
+ ercd = E_OK;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_ENA_TEX_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ena_tex */
+
+/*
+ * タスク例外処理禁止状態の参照
+ */
+#ifdef TOPPERS_sns_tex
+
+bool_t
+sns_tex(void)
+{
+ bool_t state;
+
+ LOG_SNS_TEX_ENTER();
+ state = (p_runtsk != NULL && p_runtsk->enatex) ? false : true;
+ LOG_SNS_TEX_LEAVE(state);
+ return(state);
+}
+
+#endif /* TOPPERS_sns_tex */
+
+/*
+ * タスク例外処理の状態参照
+ */
+#ifdef TOPPERS_ref_tex
+
+ER
+ref_tex(ID tskid, T_RTEX *pk_rtex)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_REF_TEX_ENTER(tskid, pk_rtex);
+ CHECK_TSKCTX_UNL();
+ CHECK_TSKID_SELF(tskid);
+ p_tcb = get_tcb_self(tskid);
+
+ t_lock_cpu();
+ if (TSTAT_DORMANT(p_tcb->tstat) || p_tcb->p_tinib->texrtn == NULL) {
+ ercd = E_OBJ;
+ }
+ else {
+ pk_rtex->texstat = (p_tcb->enatex) ? TTEX_ENA : TTEX_DIS;
+ pk_rtex->pndptn = p_tcb->texptn;
+ ercd = E_OK;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_REF_TEX_LEAVE(ercd, pk_rtex);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ref_tex */
--- /dev/null
+/*
+ * タスクの情報取得機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "semaphore.h"
+#include "eventflag.h"
+#include "dataqueue.h"
+#include "pridataq.h"
+#include "mailbox.h"
+#include "mempfix.h"
+#include "time_event.h"
+
+/*
+ * タスクの情報取得機能
+ */
+#ifdef TOPPERS_inf_tsk
+
+ER
+inf_tsk(ID tskid, T_ITSK *pk_itsk)
+{
+ TCB *p_tcb;
+ ER ercd = E_OK;
+ uint_t tstat;
+
+ p_tcb = get_tcb(tskid);
+ t_lock_cpu();
+ tstat = p_tcb->tstat;
+ if (TSTAT_DORMANT(tstat)) {
+ pk_itsk->stk_used = 0;
+ } else {
+ pk_itsk->stk_used = p_tcb->p_tinib->stksz
+ - (p_tcb->tskctxb.sp - p_tcb->p_tinib->stk);
+ }
+ pk_itsk->stk_total = p_tcb->p_tinib->stksz;
+ pk_itsk->tsk_pri_curr = EXT_TSKPRI(p_tcb->priority);
+ pk_itsk->tsk_pri_base = EXT_TSKPRI(p_tcb->priority);
+ pk_itsk->stk_head = p_tcb->p_tinib->stk;
+ pk_itsk->stk_tail = p_tcb->p_tinib->stk + p_tcb->p_tinib->stksz - 1;
+ t_unlock_cpu();
+
+ return ercd;
+}
+
+#endif /* TOPPERS_inf_tsk */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: task_manage.c 1595 2009-06-26 01:59:29Z ertl-hiro $
+ */
+
+/*
+ * タスク管理機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_ACT_TSK_ENTER
+#define LOG_ACT_TSK_ENTER(tskid)
+#endif /* LOG_ACT_TSK_ENTER */
+
+#ifndef LOG_ACT_TSK_LEAVE
+#define LOG_ACT_TSK_LEAVE(ercd)
+#endif /* LOG_ACT_TSK_LEAVE */
+
+#ifndef LOG_IACT_TSK_ENTER
+#define LOG_IACT_TSK_ENTER(tskid)
+#endif /* LOG_IACT_TSK_ENTER */
+
+#ifndef LOG_IACT_TSK_LEAVE
+#define LOG_IACT_TSK_LEAVE(ercd)
+#endif /* LOG_IACT_TSK_LEAVE */
+
+#ifndef LOG_CAN_ACT_ENTER
+#define LOG_CAN_ACT_ENTER(tskid)
+#endif /* LOG_CAN_ACT_ENTER */
+
+#ifndef LOG_CAN_ACT_LEAVE
+#define LOG_CAN_ACT_LEAVE(ercd)
+#endif /* LOG_CAN_ACT_LEAVE */
+
+#ifndef LOG_EXT_TSK_ENTER
+#define LOG_EXT_TSK_ENTER()
+#endif /* LOG_EXT_TSK_ENTER */
+
+#ifndef LOG_EXT_TSK_LEAVE
+#define LOG_EXT_TSK_LEAVE(ercd)
+#endif /* LOG_EXT_TSK_LEAVE */
+
+#ifndef LOG_TER_TSK_ENTER
+#define LOG_TER_TSK_ENTER(tskid)
+#endif /* LOG_TER_TSK_ENTER */
+
+#ifndef LOG_TER_TSK_LEAVE
+#define LOG_TER_TSK_LEAVE(ercd)
+#endif /* LOG_TER_TSK_LEAVE */
+
+#ifndef LOG_CHG_PRI_ENTER
+#define LOG_CHG_PRI_ENTER(tskid, tskpri)
+#endif /* LOG_CHG_PRI_ENTER */
+
+#ifndef LOG_CHG_PRI_LEAVE
+#define LOG_CHG_PRI_LEAVE(ercd)
+#endif /* LOG_CHG_PRI_LEAVE */
+
+#ifndef LOG_GET_PRI_ENTER
+#define LOG_GET_PRI_ENTER(tskid, p_tskpri)
+#endif /* LOG_GET_PRI_ENTER */
+
+#ifndef LOG_GET_PRI_LEAVE
+#define LOG_GET_PRI_LEAVE(ercd, tskpri)
+#endif /* LOG_GET_PRI_LEAVE */
+
+#ifndef LOG_GET_INF_ENTER
+#define LOG_GET_INF_ENTER(p_exinf)
+#endif /* LOG_GET_INF_ENTER */
+
+#ifndef LOG_GET_INF_LEAVE
+#define LOG_GET_INF_LEAVE(ercd, exinf)
+#endif /* LOG_GET_INF_LEAVE */
+
+/*
+ * タスクの起動
+ */
+#ifdef TOPPERS_act_tsk
+
+ER
+act_tsk(ID tskid)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_ACT_TSK_ENTER(tskid);
+ CHECK_TSKCTX_UNL();
+ CHECK_TSKID_SELF(tskid);
+ p_tcb = get_tcb_self(tskid);
+
+ t_lock_cpu();
+ if (TSTAT_DORMANT(p_tcb->tstat)) {
+ if (make_active(p_tcb)) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ else if (!(p_tcb->actque)) {
+ p_tcb->actque = true;
+ ercd = E_OK;
+ }
+ else {
+ ercd = E_QOVR;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_ACT_TSK_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_act_tsk */
+
+/*
+ * タスクの起動(非タスクコンテキスト用)
+ */
+#ifdef TOPPERS_iact_tsk
+
+ER
+iact_tsk(ID tskid)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_IACT_TSK_ENTER(tskid);
+ CHECK_INTCTX_UNL();
+ CHECK_TSKID(tskid);
+ p_tcb = get_tcb(tskid);
+
+ i_lock_cpu();
+ if (TSTAT_DORMANT(p_tcb->tstat)) {
+ if (make_active(p_tcb)) {
+ reqflg = true;
+ }
+ ercd = E_OK;
+ }
+ else if (!(p_tcb->actque)) {
+ p_tcb->actque = true;
+ ercd = E_OK;
+ }
+ else {
+ ercd = E_QOVR;
+ }
+ i_unlock_cpu();
+
+ error_exit:
+ LOG_IACT_TSK_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_iact_tsk */
+
+/*
+ * タスク起動要求のキャンセル
+ */
+#ifdef TOPPERS_can_act
+
+ER_UINT
+can_act(ID tskid)
+{
+ TCB *p_tcb;
+ ER_UINT ercd;
+
+ LOG_CAN_ACT_ENTER(tskid);
+ CHECK_TSKCTX_UNL();
+ CHECK_TSKID_SELF(tskid);
+ p_tcb = get_tcb_self(tskid);
+
+ t_lock_cpu();
+ ercd = p_tcb->actque ? 1 : 0;
+ p_tcb->actque = false;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_CAN_ACT_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_can_act */
+
+/*
+ * 自タスクの終了
+ */
+#ifdef TOPPERS_ext_tsk
+
+ER
+ext_tsk(void)
+{
+ ER ercd;
+
+ LOG_EXT_TSK_ENTER();
+ CHECK_TSKCTX();
+
+ if (t_sense_lock()) {
+ /*
+ * CPUロック状態でext_tskが呼ばれた場合は,CPUロックを解除し
+ * てからタスクを終了する.実装上は,サービスコール内でのCPU
+ * ロックを省略すればよいだけ.
+ */
+ }
+ else {
+ t_lock_cpu();
+ }
+ if (disdsp) {
+ /*
+ * ディスパッチ禁止状態でext_tskが呼ばれた場合は,ディスパッ
+ * チ許可状態にしてからタスクを終了する.
+ */
+ disdsp = false;
+ }
+ if (t_get_ipm() != TIPM_ENAALL) {
+ /*
+ * 割込み優先度マスク(IPM)がTIPM_ENAALL以外の状態でext_tsk
+ * が呼ばれた場合は,IPMをTIPM_ENAALLにしてからタスクを終了す
+ * る.
+ */
+ t_set_ipm(TIPM_ENAALL);
+ }
+ dspflg = true;
+
+ (void) make_non_runnable(p_runtsk);
+ make_dormant(p_runtsk);
+ if (p_runtsk->actque) {
+ p_runtsk->actque = false;
+ (void) make_active(p_runtsk);
+ }
+ exit_and_dispatch();
+ return(E_SYS);
+
+ error_exit:
+ LOG_EXT_TSK_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ext_tsk */
+
+/*
+ * タスクの強制終了
+ */
+#ifdef TOPPERS_ter_tsk
+
+ER
+ter_tsk(ID tskid)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_TER_TSK_ENTER(tskid);
+ CHECK_TSKCTX_UNL();
+ CHECK_TSKID(tskid);
+ p_tcb = get_tcb(tskid);
+ CHECK_NONSELF(p_tcb);
+
+ t_lock_cpu();
+ if (TSTAT_DORMANT(p_tcb->tstat)) {
+ ercd = E_OBJ;
+ }
+ else {
+ if (TSTAT_RUNNABLE(p_tcb->tstat)) {
+ /*
+ * p_tcbは自タスクでないため,(シングルプロセッサでは)実
+ * 行状態でなく,make_non_runnable(p_tcb)でタスクディスパッ
+ * チが必要になることはない.
+ */
+ (void) make_non_runnable(p_tcb);
+ }
+ else if (TSTAT_WAITING(p_tcb->tstat)) {
+ wait_dequeue_wobj(p_tcb);
+ wait_dequeue_tmevtb(p_tcb);
+ }
+ make_dormant(p_tcb);
+ if (p_tcb->actque) {
+ p_tcb->actque = false;
+ if (make_active(p_tcb)) {
+ dispatch();
+ }
+ }
+ ercd = E_OK;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_TER_TSK_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ter_tsk */
+
+/*
+ * タスク優先度の変更
+ */
+#ifdef TOPPERS_chg_pri
+
+ER
+chg_pri(ID tskid, PRI tskpri)
+{
+ TCB *p_tcb;
+ uint_t newpri;
+ ER ercd;
+
+ LOG_CHG_PRI_ENTER(tskid, tskpri);
+ CHECK_TSKCTX_UNL();
+ CHECK_TSKID_SELF(tskid);
+ CHECK_TPRI_INI(tskpri);
+ p_tcb = get_tcb_self(tskid);
+ newpri = (tskpri == TPRI_INI) ? p_tcb->p_tinib->ipriority
+ : INT_PRIORITY(tskpri);
+
+ t_lock_cpu();
+ if (TSTAT_DORMANT(p_tcb->tstat)) {
+ ercd = E_OBJ;
+ }
+ else {
+ if (change_priority(p_tcb, newpri)) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_CHG_PRI_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_chg_pri */
+
+/*
+ * タスク優先度の参照
+ */
+#ifdef TOPPERS_get_pri
+
+ER
+get_pri(ID tskid, PRI *p_tskpri)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_GET_PRI_ENTER(tskid, p_tskpri);
+ CHECK_TSKCTX_UNL();
+ CHECK_TSKID_SELF(tskid);
+ p_tcb = get_tcb_self(tskid);
+
+ t_lock_cpu();
+ if (TSTAT_DORMANT(p_tcb->tstat)) {
+ ercd = E_OBJ;
+ }
+ else {
+ *p_tskpri = EXT_TSKPRI(p_tcb->priority);
+ ercd = E_OK;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_GET_PRI_LEAVE(ercd, *p_tskpri);
+ return(ercd);
+}
+
+#endif /* TOPPERS_get_pri */
+
+/*
+ * 自タスクの拡張情報の参照
+ */
+#ifdef TOPPERS_get_inf
+
+ER
+get_inf(intptr_t *p_exinf)
+{
+ ER ercd;
+
+ LOG_GET_INF_ENTER(p_exinf);
+ CHECK_TSKCTX_UNL();
+
+ t_lock_cpu();
+ *p_exinf = p_runtsk->p_tinib->exinf;
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_GET_INF_LEAVE(ercd, *p_exinf);
+ return(ercd);
+}
+
+#endif /* TOPPERS_get_inf */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: task_refer.c 1016 2008-05-10 08:42:16Z ertl-hiro $
+ */
+
+/*
+ * タスクの状態参照機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+#include "semaphore.h"
+#include "eventflag.h"
+#include "dataqueue.h"
+#include "pridataq.h"
+#include "mailbox.h"
+#include "mempfix.h"
+#include "time_event.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_REF_TSK_ENTER
+#define LOG_REF_TSK_ENTER(tskid, pk_rtsk)
+#endif /* LOG_REF_TSK_ENTER */
+
+#ifndef LOG_REF_TSK_LEAVE
+#define LOG_REF_TSK_LEAVE(ercd, pk_rtsk)
+#endif /* LOG_REF_TSK_LEAVE */
+
+/*
+ * タスクの状態参照
+ */
+#ifdef TOPPERS_ref_tsk
+
+ER
+ref_tsk(ID tskid, T_RTSK *pk_rtsk)
+{
+ TCB *p_tcb;
+ uint_t tstat;
+ ER ercd;
+
+ LOG_REF_TSK_ENTER(tskid, pk_rtsk);
+ CHECK_TSKCTX_UNL();
+ CHECK_TSKID_SELF(tskid);
+ p_tcb = get_tcb_self(tskid);
+
+ t_lock_cpu();
+ tstat = p_tcb->tstat;
+ if (TSTAT_DORMANT(tstat)) {
+ /*
+ * 対象タスクが休止状態の場合
+ */
+ pk_rtsk->tskstat = TTS_DMT;
+ }
+ else {
+ /*
+ * タスク状態の取出し
+ */
+ if (TSTAT_SUSPENDED(tstat)) {
+ if (TSTAT_WAITING(tstat)) {
+ pk_rtsk->tskstat = TTS_WAS;
+ }
+ else {
+ pk_rtsk->tskstat = TTS_SUS;
+ }
+ }
+ else if (TSTAT_WAITING(tstat)) {
+ pk_rtsk->tskstat = TTS_WAI;
+ }
+ else if (p_tcb == p_runtsk) {
+ pk_rtsk->tskstat = TTS_RUN;
+ }
+ else {
+ pk_rtsk->tskstat = TTS_RDY;
+ }
+
+ /*
+ * 現在優先度とベース優先度の取出し
+ */
+ pk_rtsk->tskpri = EXT_TSKPRI(p_tcb->priority);
+ pk_rtsk->tskbpri = EXT_TSKPRI(p_tcb->priority);
+
+ if (TSTAT_WAITING(tstat)) {
+ /*
+ * 待ち要因と待ち対象のオブジェクトのIDの取出し
+ */
+ switch (tstat & TS_WAIT_MASK) {
+ case TS_WAIT_SLP:
+ pk_rtsk->tskwait = TTW_SLP;
+ break;
+ case TS_WAIT_DLY:
+ pk_rtsk->tskwait = TTW_DLY;
+ break;
+ case TS_WAIT_SEM:
+ pk_rtsk->tskwait = TTW_SEM;
+ pk_rtsk->wobjid = SEMID(((WINFO_SEM *)(p_tcb->p_winfo))
+ ->p_semcb);
+ break;
+ case TS_WAIT_FLG:
+ pk_rtsk->tskwait = TTW_FLG;
+ pk_rtsk->wobjid = FLGID(((WINFO_FLG *)(p_tcb->p_winfo))
+ ->p_flgcb);
+ break;
+ case TS_WAIT_SDTQ:
+ pk_rtsk->tskwait = TTW_SDTQ;
+ pk_rtsk->wobjid = DTQID(((WINFO_DTQ *)(p_tcb->p_winfo))
+ ->p_dtqcb);
+ break;
+ case TS_WAIT_RDTQ:
+ pk_rtsk->tskwait = TTW_RDTQ;
+ pk_rtsk->wobjid = DTQID(((WINFO_DTQ *)(p_tcb->p_winfo))
+ ->p_dtqcb);
+ break;
+ case TS_WAIT_SPDQ:
+ pk_rtsk->tskwait = TTW_SPDQ;
+ pk_rtsk->wobjid = PDQID(((WINFO_PDQ *)(p_tcb->p_winfo))
+ ->p_pdqcb);
+ break;
+ case TS_WAIT_RPDQ:
+ pk_rtsk->tskwait = TTW_RPDQ;
+ pk_rtsk->wobjid = PDQID(((WINFO_PDQ *)(p_tcb->p_winfo))
+ ->p_pdqcb);
+ break;
+ case TS_WAIT_MBX:
+ pk_rtsk->tskwait = TTW_MBX;
+ pk_rtsk->wobjid = MBXID(((WINFO_MBX *)(p_tcb->p_winfo))
+ ->p_mbxcb);
+ break;
+ case TS_WAIT_MPF:
+ pk_rtsk->tskwait = TTW_MPF;
+ pk_rtsk->wobjid = MPFID(((WINFO_MPF *)(p_tcb->p_winfo))
+ ->p_mpfcb);
+ break;
+ }
+
+ /*
+ * タイムアウトするまでの時間の取出し
+ */
+ if (p_tcb->p_winfo->p_tmevtb != NULL) {
+ pk_rtsk->lefttmo
+ = (TMO) tmevt_lefttim(p_tcb->p_winfo->p_tmevtb);
+ }
+ else {
+ pk_rtsk->lefttmo = TMO_FEVR;
+ }
+ }
+
+ /*
+ * 起床要求キューイング数の取出し
+ */
+ pk_rtsk->wupcnt = p_tcb->wupque ? 1U : 0U;
+ }
+
+ /*
+ * 起動要求キューイング数の取出し
+ */
+ pk_rtsk->actcnt = p_tcb->actque ? 1U : 0U;
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_REF_TSK_LEAVE(ercd, pk_rtsk);
+ return(ercd);
+}
+
+#endif /* TOPPERS_ref_tsk */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: task_sync.c 1453 2009-02-18 09:09:34Z ertl-hiro $
+ */
+
+/*
+ * タスク付属同期機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "task.h"
+#include "wait.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_SLP_TSK_ENTER
+#define LOG_SLP_TSK_ENTER()
+#endif /* LOG_SLP_TSK_ENTER */
+
+#ifndef LOG_SLP_TSK_LEAVE
+#define LOG_SLP_TSK_LEAVE(ercd)
+#endif /* LOG_SLP_TSK_LEAVE */
+
+#ifndef LOG_TSLP_TSK_ENTER
+#define LOG_TSLP_TSK_ENTER(tmout)
+#endif /* LOG_TSLP_TSK_ENTER */
+
+#ifndef LOG_TSLP_TSK_LEAVE
+#define LOG_TSLP_TSK_LEAVE(ercd)
+#endif /* LOG_TSLP_TSK_LEAVE */
+
+#ifndef LOG_WUP_TSK_ENTER
+#define LOG_WUP_TSK_ENTER(tskid)
+#endif /* LOG_WUP_TSK_ENTER */
+
+#ifndef LOG_WUP_TSK_LEAVE
+#define LOG_WUP_TSK_LEAVE(ercd)
+#endif /* LOG_WUP_TSK_LEAVE */
+
+#ifndef LOG_IWUP_TSK_ENTER
+#define LOG_IWUP_TSK_ENTER(tskid)
+#endif /* LOG_IWUP_TSK_ENTER */
+
+#ifndef LOG_IWUP_TSK_LEAVE
+#define LOG_IWUP_TSK_LEAVE(ercd)
+#endif /* LOG_IWUP_TSK_LEAVE */
+
+#ifndef LOG_CAN_WUP_ENTER
+#define LOG_CAN_WUP_ENTER(tskid)
+#endif /* LOG_CAN_WUP_ENTER */
+
+#ifndef LOG_CAN_WUP_LEAVE
+#define LOG_CAN_WUP_LEAVE(ercd)
+#endif /* LOG_CAN_WUP_LEAVE */
+
+#ifndef LOG_REL_WAI_ENTER
+#define LOG_REL_WAI_ENTER(tskid)
+#endif /* LOG_REL_WAI_ENTER */
+
+#ifndef LOG_REL_WAI_LEAVE
+#define LOG_REL_WAI_LEAVE(ercd)
+#endif /* LOG_REL_WAI_LEAVE */
+
+#ifndef LOG_IREL_WAI_ENTER
+#define LOG_IREL_WAI_ENTER(tskid)
+#endif /* LOG_IREL_WAI_ENTER */
+
+#ifndef LOG_IREL_WAI_LEAVE
+#define LOG_IREL_WAI_LEAVE(ercd)
+#endif /* LOG_IREL_WAI_LEAVE */
+
+#ifndef LOG_SUS_TSK_ENTER
+#define LOG_SUS_TSK_ENTER(tskid)
+#endif /* LOG_SUS_TSK_ENTER */
+
+#ifndef LOG_SUS_TSK_LEAVE
+#define LOG_SUS_TSK_LEAVE(ercd)
+#endif /* LOG_SUS_TSK_LEAVE */
+
+#ifndef LOG_RSM_TSK_ENTER
+#define LOG_RSM_TSK_ENTER(tskid)
+#endif /* LOG_RSM_TSK_ENTER */
+
+#ifndef LOG_RSM_TSK_LEAVE
+#define LOG_RSM_TSK_LEAVE(ercd)
+#endif /* LOG_RSM_TSK_LEAVE */
+
+#ifndef LOG_DLY_TSK_ENTER
+#define LOG_DLY_TSK_ENTER(dlytim)
+#endif /* LOG_DLY_TSK_ENTER */
+
+#ifndef LOG_DLY_TSK_LEAVE
+#define LOG_DLY_TSK_LEAVE(ercd)
+#endif /* LOG_DLY_TSK_LEAVE */
+
+/*
+ * 起床待ち
+ */
+#ifdef TOPPERS_slp_tsk
+
+ER
+slp_tsk(void)
+{
+ WINFO winfo;
+ ER ercd;
+
+ LOG_SLP_TSK_ENTER();
+ CHECK_DISPATCH();
+
+ t_lock_cpu();
+ if (p_runtsk->wupque) {
+ p_runtsk->wupque = false;
+ ercd = E_OK;
+ }
+ else {
+ p_runtsk->tstat = (TS_WAITING | TS_WAIT_SLP);
+ make_wait(&winfo);
+ LOG_TSKSTAT(p_runtsk);
+ dispatch();
+ ercd = winfo.wercd;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_SLP_TSK_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_slp_tsk */
+
+/*
+ * 起床待ち(タイムアウトあり)
+ */
+#ifdef TOPPERS_tslp_tsk
+
+ER
+tslp_tsk(TMO tmout)
+{
+ WINFO winfo;
+ TMEVTB tmevtb;
+ ER ercd;
+
+ LOG_TSLP_TSK_ENTER(tmout);
+ CHECK_DISPATCH();
+ CHECK_TMOUT(tmout);
+
+ t_lock_cpu();
+ if (p_runtsk->wupque) {
+ p_runtsk->wupque = false;
+ ercd = E_OK;
+ }
+ else if (tmout == TMO_POL) {
+ ercd = E_TMOUT;
+ }
+ else {
+ p_runtsk->tstat = (TS_WAITING | TS_WAIT_SLP);
+ make_wait_tmout(&winfo, &tmevtb, tmout);
+ LOG_TSKSTAT(p_runtsk);
+ dispatch();
+ ercd = winfo.wercd;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_TSLP_TSK_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_tslp_tsk */
+
+/*
+ * タスクの起床
+ */
+#ifdef TOPPERS_wup_tsk
+
+ER
+wup_tsk(ID tskid)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_WUP_TSK_ENTER(tskid);
+ CHECK_TSKCTX_UNL();
+ CHECK_TSKID_SELF(tskid);
+ p_tcb = get_tcb_self(tskid);
+
+ t_lock_cpu();
+ if (TSTAT_DORMANT(p_tcb->tstat)) {
+ ercd = E_OBJ;
+ }
+ else if (TSTAT_WAIT_SLP(p_tcb->tstat)) {
+ if (wait_complete(p_tcb)) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ else if (!(p_tcb->wupque)) {
+ p_tcb->wupque = true;
+ ercd = E_OK;
+ }
+ else {
+ ercd = E_QOVR;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_WUP_TSK_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_wup_tsk */
+
+/*
+ * タスクの起床(非タスクコンテキスト用)
+ */
+#ifdef TOPPERS_iwup_tsk
+
+ER
+iwup_tsk(ID tskid)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_IWUP_TSK_ENTER(tskid);
+ CHECK_INTCTX_UNL();
+ CHECK_TSKID(tskid);
+ p_tcb = get_tcb(tskid);
+
+ i_lock_cpu();
+ if (TSTAT_DORMANT(p_tcb->tstat)) {
+ ercd = E_OBJ;
+ }
+ else if (TSTAT_WAIT_SLP(p_tcb->tstat)) {
+ if (wait_complete(p_tcb)) {
+ reqflg = true;
+ }
+ ercd = E_OK;
+ }
+ else if (!(p_tcb->wupque)) {
+ p_tcb->wupque = true;
+ ercd = E_OK;
+ }
+ else {
+ ercd = E_QOVR;
+ }
+ i_unlock_cpu();
+
+ error_exit:
+ LOG_IWUP_TSK_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_iwup_tsk */
+
+/*
+ * タスク起床要求のキャンセル
+ */
+#ifdef TOPPERS_can_wup
+
+ER_UINT
+can_wup(ID tskid)
+{
+ TCB *p_tcb;
+ ER_UINT ercd;
+
+ LOG_CAN_WUP_ENTER(tskid);
+ CHECK_TSKCTX_UNL();
+ CHECK_TSKID_SELF(tskid);
+ p_tcb = get_tcb_self(tskid);
+
+ t_lock_cpu();
+ if (TSTAT_DORMANT(p_tcb->tstat)) {
+ ercd = E_OBJ;
+ }
+ else {
+ ercd = p_tcb->wupque ? 1 : 0;
+ p_tcb->wupque = false;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_CAN_WUP_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_can_wup */
+
+/*
+ * 待ち状態の強制解除
+ */
+#ifdef TOPPERS_rel_wai
+
+ER
+rel_wai(ID tskid)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_REL_WAI_ENTER(tskid);
+ CHECK_TSKCTX_UNL();
+ CHECK_TSKID(tskid);
+ p_tcb = get_tcb(tskid);
+
+ t_lock_cpu();
+ if (!TSTAT_WAITING(p_tcb->tstat)) {
+ ercd = E_OBJ;
+ }
+ else {
+ if (wait_release(p_tcb)) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_REL_WAI_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_rel_wai */
+
+/*
+ * 待ち状態の強制解除(非タスクコンテキスト用)
+ */
+#ifdef TOPPERS_irel_wai
+
+ER
+irel_wai(ID tskid)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_IREL_WAI_ENTER(tskid);
+ CHECK_INTCTX_UNL();
+ CHECK_TSKID(tskid);
+ p_tcb = get_tcb(tskid);
+
+ i_lock_cpu();
+ if (!TSTAT_WAITING(p_tcb->tstat)) {
+ ercd = E_OBJ;
+ }
+ else {
+ if (wait_release(p_tcb)) {
+ reqflg = true;
+ }
+ ercd = E_OK;
+ }
+ i_unlock_cpu();
+
+ error_exit:
+ LOG_IREL_WAI_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_irel_wai */
+
+/*
+ * 強制待ち状態への移行
+ */
+#ifdef TOPPERS_sus_tsk
+
+ER
+sus_tsk(ID tskid)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_SUS_TSK_ENTER(tskid);
+ CHECK_TSKCTX_UNL();
+ CHECK_TSKID_SELF(tskid);
+ p_tcb = get_tcb_self(tskid);
+
+ t_lock_cpu();
+ if (p_tcb == p_runtsk && !dspflg) {
+ ercd = E_CTX;
+ }
+ else if (TSTAT_DORMANT(p_tcb->tstat)) {
+ ercd = E_OBJ;
+ }
+ else if (TSTAT_RUNNABLE(p_tcb->tstat)) {
+ /*
+ * 実行できる状態から強制待ち状態への遷移
+ */
+ p_tcb->tstat = TS_SUSPENDED;
+ LOG_TSKSTAT(p_tcb);
+ if (make_non_runnable(p_tcb)) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ else if (TSTAT_SUSPENDED(p_tcb->tstat)) {
+ ercd = E_QOVR;
+ }
+ else {
+ /*
+ * 待ち状態から二重待ち状態への遷移
+ */
+ p_tcb->tstat |= TS_SUSPENDED;
+ LOG_TSKSTAT(p_tcb);
+ ercd = E_OK;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_SUS_TSK_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_sus_tsk */
+
+/*
+ * 強制待ち状態からの再開
+ */
+#ifdef TOPPERS_rsm_tsk
+
+ER
+rsm_tsk(ID tskid)
+{
+ TCB *p_tcb;
+ ER ercd;
+
+ LOG_RSM_TSK_ENTER(tskid);
+ CHECK_TSKCTX_UNL();
+ CHECK_TSKID(tskid);
+ p_tcb = get_tcb(tskid);
+
+ t_lock_cpu();
+ if (!TSTAT_SUSPENDED(p_tcb->tstat)) {
+ ercd = E_OBJ;
+ }
+ else if (!TSTAT_WAITING(p_tcb->tstat)) {
+ /*
+ * 強制待ち状態から実行できる状態への遷移
+ */
+ p_tcb->tstat = TS_RUNNABLE;
+ LOG_TSKSTAT(p_tcb);
+ if (make_runnable(p_tcb)) {
+ dispatch();
+ }
+ ercd = E_OK;
+ }
+ else {
+ /*
+ * 二重待ち状態から待ち状態への遷移
+ */
+ p_tcb->tstat &= ~TS_SUSPENDED;
+ LOG_TSKSTAT(p_tcb);
+ ercd = E_OK;
+ }
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_RSM_TSK_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_rsm_tsk */
+
+/*
+ * 自タスクの遅延
+ */
+#ifdef TOPPERS_dly_tsk
+
+ER
+dly_tsk(RELTIM dlytim)
+{
+ WINFO winfo;
+ TMEVTB tmevtb;
+ ER ercd;
+
+ LOG_DLY_TSK_ENTER(dlytim);
+ CHECK_DISPATCH();
+ CHECK_PAR(dlytim <= TMAX_RELTIM);
+
+ t_lock_cpu();
+ p_runtsk->tstat = (TS_WAITING | TS_WAIT_DLY);
+ (void) make_non_runnable(p_runtsk);
+ p_runtsk->p_winfo = &winfo;
+ winfo.p_tmevtb = &tmevtb;
+ tmevtb_enqueue(&tmevtb, dlytim, (CBACK) wait_tmout_ok, (void *) p_runtsk);
+ LOG_TSKSTAT(p_runtsk);
+ dispatch();
+ ercd = winfo.wercd;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_DLY_TSK_LEAVE(ercd);
+ return(ercd);
+}
+
+#endif /* TOPPERS_dly_tsk */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * $Id: time_event.c 1747 2010-02-11 18:24:19Z ertl-hiro $
+ */
+
+/*
+ * タイムイベント管理モジュール
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "time_event.h"
+
+/*
+ * タイムイベントヒープ操作マクロ
+ */
+#define PARENT(index) ((index) >> 1) /* 親ノードを求める */
+#define LCHILD(index) ((index) << 1) /* 左の子ノードを求める */
+#define TMEVT_NODE(index) (tmevt_heap[(index) - 1])
+
+/*
+ * イベント発生時刻比較マクロ
+ *
+ * イベント発生時刻は,min_timeからの相対値で比較する.すなわち,
+ * min_timeを最小値(最も近い時刻),mit_time-1が最大値(最も遠い時刻)
+ * とみなして比較する.
+ */
+#define EVTTIM_LT(t1, t2) (((t1) - min_time) < ((t2) - min_time))
+#define EVTTIM_LE(t1, t2) (((t1) - min_time) <= ((t2) - min_time))
+
+#ifdef TOPPERS_tmeini
+
+/*
+ * 現在のシステム時刻(単位: 1ミリ秒)
+ *
+ * 厳密には,前のタイムティックのシステム時刻.
+ */
+EVTTIM current_time;
+
+/*
+ * タイムイベントヒープ中で有効な最小のシステム時刻(単位: 1ミリ秒)
+ */
+EVTTIM min_time;
+
+/*
+ * 次のタイムティックのシステム時刻(単位: 1ミリ秒)
+ */
+EVTTIM next_time;
+
+/*
+ * システム時刻積算用変数(単位: 1/TIC_DENOミリ秒)
+ */
+#if TIC_DENO != 1U
+uint_t next_subtime;
+#endif /* TIC_DENO != 1U */
+
+/*
+ * タイムイベントヒープの最後の使用領域のインデックス
+ */
+uint_t last_index;
+
+/*
+ * タイマモジュールの初期化
+ */
+void
+initialize_tmevt(void)
+{
+ current_time = min_time = 0U;
+ next_time = current_time + TIC_NUME / TIC_DENO;
+#if TIC_DENO != 1U
+ next_subtime = TIC_NUME % TIC_DENO;
+#endif /* TIC_DENO != 1U */
+ last_index = 0U;
+}
+
+#endif /* TOPPERS_tmeini */
+
+/*
+ * タイムイベントの挿入位置を上向きに探索
+ *
+ * 時刻timeに発生するタイムイベントを挿入するノードを空けるために,
+ * ヒープの上に向かって空ノードを移動させる.移動前の空ノードの位置を
+ * indexに渡すと,移動後の空ノードの位置(すなわち挿入位置)を返す.
+ */
+#ifdef TOPPERS_tmeup
+
+uint_t
+tmevt_up(uint_t index, EVTTIM time)
+{
+ uint_t parent;
+
+ while (index > 1) {
+ /*
+ * 親ノードのイベント発生時刻の方が早い(または同じ)ならば,
+ * indexが挿入位置なのでループを抜ける.
+ */
+ parent = PARENT(index);
+ if (EVTTIM_LE(TMEVT_NODE(parent).time, time)) {
+ break;
+ }
+
+ /*
+ * 親ノードをindexの位置に移動させる.
+ */
+ TMEVT_NODE(index) = TMEVT_NODE(parent);
+ TMEVT_NODE(index).p_tmevtb->index = index;
+
+ /*
+ * indexを親ノードの位置に更新.
+ */
+ index = parent;
+ }
+ return(index);
+}
+
+#endif /* TOPPERS_tmeup */
+
+/*
+ * タイムイベントの挿入位置を下向きに探索
+ *
+ * 時刻timeに発生するタイムイベントを挿入するノードを空けるために,
+ * ヒープの下に向かって空ノードを移動させる.移動前の空ノードの位置を
+ * indexに渡すと,移動後の空ノードの位置(すなわち挿入位置)を返す.
+ */
+#ifdef TOPPERS_tmedown
+
+uint_t
+tmevt_down(uint_t index, EVTTIM time)
+{
+ uint_t child;
+
+ while ((child = LCHILD(index)) <= last_index) {
+ /*
+ * 左右の子ノードのイベント発生時刻を比較し,早い方の子ノード
+ * の位置をchildに設定する.以下の子ノードは,ここで選ばれた方
+ * の子ノードのこと.
+ */
+ if (child + 1 <= last_index
+ && EVTTIM_LT(TMEVT_NODE(child + 1).time,
+ TMEVT_NODE(child).time)) {
+ child = child + 1;
+ }
+
+ /*
+ * 子ノードのイベント発生時刻の方が遅い(または同じ)ならば,
+ * indexが挿入位置なのでループを抜ける.
+ */
+ if (EVTTIM_LE(time, TMEVT_NODE(child).time)) {
+ break;
+ }
+
+ /*
+ * 子ノードをindexの位置に移動させる.
+ */
+ TMEVT_NODE(index) = TMEVT_NODE(child);
+ TMEVT_NODE(index).p_tmevtb->index = index;
+
+ /*
+ * indexを子ノードの位置に更新.
+ */
+ index = child;
+ }
+ return(index);
+}
+
+#endif /* TOPPERS_tmedown */
+
+/*
+ * タイムイベントヒープへの登録
+ *
+ * p_tmevtbで指定したタイムイベントブロックを,timeで指定した時間が経
+ * 過後にイベントが発生するように,タイムイベントヒープに登録する.
+ */
+#ifdef TOPPERS_tmeins
+
+void
+tmevtb_insert(TMEVTB *p_tmevtb, EVTTIM time)
+{
+ uint_t index;
+
+ /*
+ * last_indexをインクリメントし,そこから上に挿入位置を探す.
+ */
+ index = tmevt_up(++last_index, time);
+
+ /*
+ * タイムイベントをindexの位置に挿入する.
+ */
+ TMEVT_NODE(index).time = time;
+ TMEVT_NODE(index).p_tmevtb = p_tmevtb;
+ p_tmevtb->index = index;
+}
+
+#endif /* TOPPERS_tmeins */
+
+/*
+ * タイムイベントヒープからの削除
+ */
+#ifdef TOPPERS_tmedel
+
+void
+tmevtb_delete(TMEVTB *p_tmevtb)
+{
+ uint_t index = p_tmevtb->index;
+ uint_t parent;
+ EVTTIM event_time = TMEVT_NODE(last_index).time;
+
+ /*
+ * 削除によりタイムイベントヒープが空になる場合は何もしない.
+ */
+ if (--last_index == 0) {
+ return;
+ }
+
+ /*
+ * 削除したノードの位置に最後のノード(last_index+1の位置のノード)
+ * を挿入し,それを適切な位置へ移動させる.実際には,最後のノード
+ * を実際に挿入するのではなく,削除したノードの位置が空ノードにな
+ * るので,最後のノードを挿入すべき位置へ向けて空ノードを移動させ
+ * る.
+ * 最後のノードのイベント発生時刻が,削除したノードの親ノードのイ
+ * ベント発生時刻より前の場合には,上に向かって挿入位置を探す.そ
+ * うでない場合には,下に向かって探す.
+ */
+ if (index > 1 && EVTTIM_LT(event_time,
+ TMEVT_NODE(parent = PARENT(index)).time)) {
+ /*
+ * 親ノードをindexの位置に移動させる.
+ */
+ TMEVT_NODE(index) = TMEVT_NODE(parent);
+ TMEVT_NODE(index).p_tmevtb->index = index;
+
+ /*
+ * 削除したノードの親ノードから上に向かって挿入位置を探す.
+ */
+ index = tmevt_up(parent, event_time);
+ }
+ else {
+ /*
+ * 削除したノードから下に向かって挿入位置を探す.
+ */
+ index = tmevt_down(index, event_time);
+ }
+
+ /*
+ * 最後のノードをindexの位置に挿入する.
+ */
+ TMEVT_NODE(index) = TMEVT_NODE(last_index + 1);
+ TMEVT_NODE(index).p_tmevtb->index = index;
+}
+
+#endif /* TOPPERS_tmedel */
+
+/*
+ * タイムイベントヒープの先頭のノードの削除
+ */
+Inline void
+tmevtb_delete_top(void)
+{
+ uint_t index;
+ EVTTIM event_time = TMEVT_NODE(last_index).time;
+
+ /*
+ * 削除によりタイムイベントヒープが空になる場合は何もしない.
+ */
+ if (--last_index == 0) {
+ return;
+ }
+
+ /*
+ * ルートノードに最後のノード(last_index + 1 の位置のノード)を
+ * 挿入し,それを適切な位置へ移動させる.実際には,最後のノードを
+ * 実際に挿入するのではなく,ルートノードが空ノードになるので,最
+ * 後のノードを挿入すべき位置へ向けて空ノードを移動させる.
+ */
+ index = tmevt_down(1, event_time);
+
+ /*
+ * 最後のノードをindexの位置に挿入する.
+ */
+ TMEVT_NODE(index) = TMEVT_NODE(last_index + 1);
+ TMEVT_NODE(index).p_tmevtb->index = index;
+}
+
+/*
+ * タイムイベントまでの残り時間の計算
+ */
+#ifdef TOPPERS_tmeltim
+
+RELTIM
+tmevt_lefttim(TMEVTB *p_tmevtb)
+{
+ EVTTIM time;
+
+ time = TMEVT_NODE(p_tmevtb->index).time;
+ if (EVTTIM_LE(time, next_time)) {
+ /*
+ * 次のタイムティックで処理される場合には0を返す.
+ */
+ return(0U);
+ }
+ else {
+ return((RELTIM)(time - base_time));
+ }
+}
+
+#endif /* TOPPERS_tmeltim */
+
+/*
+ * タイムティックの供給
+ */
+#ifdef TOPPERS_sigtim
+
+void
+signal_time(void)
+{
+ TMEVTB *p_tmevtb;
+
+ assert(sense_context());
+ assert(!i_sense_lock());
+
+ i_lock_cpu();
+
+ /*
+ * current_timeを更新する.
+ */
+ current_time = next_time;
+
+ /*
+ * next_time,next_subtimeを更新する.
+ */
+#if TIC_DENO == 1U
+ next_time = current_time + TIC_NUME;
+#else /* TIC_DENO == 1U */
+ next_subtime += TIC_NUME % TIC_DENO;
+ next_time = current_time + TIC_NUME / TIC_DENO;
+ if (next_subtime >= TIC_DENO) {
+ next_subtime -= TIC_DENO;
+ next_time += 1U;
+ }
+#endif /* TIC_DENO == 1U */
+
+ /*
+ * current_timeよりイベント発生時刻の早い(または同じ)タイムイベ
+ * ントを,タイムイベントヒープから削除し,コールバック関数を呼び
+ * 出す.
+ */
+ while (last_index > 0 && EVTTIM_LE(TMEVT_NODE(1).time, current_time)) {
+ p_tmevtb = TMEVT_NODE(1).p_tmevtb;
+ tmevtb_delete_top();
+ (*(p_tmevtb->callback))(p_tmevtb->arg);
+ }
+
+ /*
+ * min_timeを更新する.
+ */
+ min_time = current_time;
+
+ i_unlock_cpu();
+}
+
+#endif /* TOPPERS_sigtim */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * $Id: time_event.h 1774 2010-03-19 12:45:46Z ertl-hiro $
+ */
+
+/*
+ * タイムイベント管理モジュール
+ */
+
+#ifndef TOPPERS_TIME_EVENT_H
+#define TOPPERS_TIME_EVENT_H
+
+/*
+ * イベント発生時刻のデータ型の定義
+ *
+ * EVTTIMは,RELTIMとして指定できる範囲よりも広い範囲を表現できる必要
+ * がある.μITRON4.0仕様のスタンダードプロファイルでは,RELTIMが16ビッ
+ * ト以上でなければならないため,EVTTIMは17ビット以上であることが必要
+ * である.そのため,16ビットになる場合があるuint_tではなく,ulong_tに
+ * 定義している.
+ */
+typedef ulong_t EVTTIM;
+
+/*
+ * タイムイベントブロックのデータ型の定義
+ */
+typedef void (*CBACK)(void *); /* コールバック関数の型 */
+
+typedef struct time_event_block {
+ uint_t index; /* タイムイベントヒープ中での位置 */
+ CBACK callback; /* コールバック関数 */
+ void *arg; /* コールバック関数へ渡す引数 */
+} TMEVTB;
+
+/*
+ * タイムイベントヒープ中のノードのデータ型の定義
+ */
+typedef struct time_event_node {
+ EVTTIM time; /* イベント発生時刻 */
+ TMEVTB *p_tmevtb; /* 対応するタイムイベントブロック */
+} TMEVTN;
+
+/*
+ * タイムイベントヒープ(kernel_cfg.c)
+ */
+extern TMEVTN tmevt_heap[];
+
+/*
+ * 現在のシステム時刻(単位: 1ミリ秒)
+ *
+ * システム起動時に0に初期化され,以降,タイムティックが供給される度に
+ * 単調に増加する.
+ */
+extern EVTTIM current_time;
+
+/*
+ * タイムイベントヒープ中で有効な最小のシステム時刻(単位: 1ミリ秒)
+ */
+extern EVTTIM min_time;
+
+/*
+ * 次のタイムティックのシステム時刻(単位: 1ミリ秒)
+ */
+extern EVTTIM next_time;
+
+/*
+ * システム時刻積算用変数(単位: 1/TIC_DENOミリ秒)
+ *
+ * 次のタイムティックのシステム時刻の下位桁を示す(上位桁はnext_time).
+ * TIC_DENOが1の時は,下位桁は常に0であるため,この変数は必要ない.
+ */
+#if TIC_DENO != 1U
+extern uint_t next_subtime;
+#endif /* TIC_DENO != 1U */
+
+/*
+ * 相対時間の基準時刻(単位: 1ミリ秒)
+ *
+ * 次のタイムティックのシステム時刻を切り上げた時刻.TIC_DENOが1の時
+ * は,next_timeに一致する.
+ */
+#if TIC_DENO == 1U
+#define base_time (next_time)
+#else /* TIC_DENO == 1U */
+#define base_time (next_time + (next_subtime > 0U ? 1U : 0U))
+#endif /* TIC_DENO == 1U */
+
+/*
+ * タイムイベントヒープの最後の使用領域のインデックス
+ *
+ * タイムイベントヒープに登録されているタイムイベントの数に一致する.
+ */
+extern uint_t last_index;
+
+/*
+ * タイムイベント管理モジュールの初期化
+ */
+extern void initialize_tmevt(void);
+
+/*
+ * タイムイベントの挿入位置の探索
+ */
+extern uint_t tmevt_up(uint_t index, EVTTIM time);
+extern uint_t tmevt_down(uint_t index, EVTTIM time);
+
+/*
+ * タイムイベントヒープへの登録と削除
+ */
+extern void tmevtb_insert(TMEVTB *p_tmevtb, EVTTIM time);
+extern void tmevtb_delete(TMEVTB *p_tmevtb);
+
+/*
+ * タイムイベントブロックの登録(相対時間指定)
+ *
+ * timeで指定した相対時間が経過した後に,argを引数としてcallbackが呼
+ * び出されるように,p_tmevtbで指定したタイムイベントブロックを登録す
+ * る.
+ *
+ */
+Inline void
+tmevtb_enqueue(TMEVTB *p_tmevtb, RELTIM time, CBACK callback, void *arg)
+{
+ assert(time <= TMAX_RELTIM);
+
+ p_tmevtb->callback = callback;
+ p_tmevtb->arg = arg;
+ tmevtb_insert(p_tmevtb, base_time + time);
+}
+
+/*
+ * タイムイベントブロックの登録(イベント発生時刻指定)
+ *
+ * timeで指定したイベント発生時刻に,argを引数としてcallbackが呼び出
+ * されるように,p_tmevtbで指定したタイムイベントブロックを登録する.
+ */
+Inline void
+tmevtb_enqueue_evttim(TMEVTB *p_tmevtb, EVTTIM time, CBACK callback, void *arg)
+{
+ p_tmevtb->callback = callback;
+ p_tmevtb->arg = arg;
+ tmevtb_insert(p_tmevtb, time);
+}
+
+/*
+ * タイムイベントブロックの登録解除
+ */
+Inline void
+tmevtb_dequeue(TMEVTB *p_tmevtb)
+{
+ tmevtb_delete(p_tmevtb);
+}
+
+/*
+ * タイムイベントまでの残り時間の計算
+ */
+extern RELTIM tmevt_lefttim(TMEVTB *p_tmevtb);
+
+/*
+ * タイムティックの供給
+ */
+extern void signal_time(void);
+
+#endif /* TOPPERS_TIME_EVENT_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * $Id: time_manage.c 1747 2010-02-11 18:24:19Z ertl-hiro $
+ */
+
+/*
+ * システム時刻管理機能
+ */
+
+#include "kernel_impl.h"
+#include "check.h"
+#include "time_event.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_GET_TIM_ENTER
+#define LOG_GET_TIM_ENTER(p_systim)
+#endif /* LOG_GET_TIM_ENTER */
+
+#ifndef LOG_GET_TIM_LEAVE
+#define LOG_GET_TIM_LEAVE(ercd, systim)
+#endif /* LOG_GET_TIM_LEAVE */
+
+#ifndef LOG_GET_UTM_ENTER
+#define LOG_GET_UTM_ENTER(p_sysutm)
+#endif /* LOG_GET_UTM_ENTER */
+
+#ifndef LOG_GET_UTM_LEAVE
+#define LOG_GET_UTM_LEAVE(ercd, sysutm)
+#endif /* LOG_GET_UTM_LEAVE */
+
+/*
+ * システム時刻の参照
+ */
+#ifdef TOPPERS_get_tim
+
+ER
+get_tim(SYSTIM *p_systim)
+{
+ ER ercd;
+
+ LOG_GET_TIM_ENTER(p_systim);
+ CHECK_TSKCTX_UNL();
+
+ t_lock_cpu();
+ *p_systim = current_time;
+ ercd = E_OK;
+ t_unlock_cpu();
+
+ error_exit:
+ LOG_GET_TIM_LEAVE(ercd, *p_systim);
+ return(ercd);
+}
+
+#endif /* TOPPERS_get_tim */
+
+/*
+ * 性能評価用システム時刻の参照
+ */
+#ifdef TOPPERS_get_utm
+#ifdef TOPPERS_SUPPORT_GET_UTM
+#ifndef OMIT_GET_UTM
+#include "target_timer.h"
+
+ER
+get_utm(SYSUTM *p_sysutm)
+{
+ SYSUTM utime;
+ SYSTIM time;
+#if TIC_DENO != 1
+ uint_t subtime;
+#endif /* TIC_DENO != 1 */
+ CLOCK clock1, clock2;
+ bool_t ireq;
+ SIL_PRE_LOC;
+
+ LOG_GET_UTM_ENTER(p_sysutm);
+
+ SIL_LOC_INT();
+ time = next_time;
+#if TIC_DENO != 1
+ subtime = next_subtime;
+#endif /* TIC_DENO != 1 */
+ clock1 = target_timer_get_current();
+ ireq = target_timer_probe_int();
+ clock2 = target_timer_get_current();
+ SIL_UNL_INT();
+
+ utime = ((SYSUTM) time) * 1000U;
+#if TIC_DENO != 1
+ utime += subtime * 1000U / TIC_DENO;
+#endif /* TIC_DENO != 1 */
+
+ if (!ireq || clock1 > clock2) {
+ utime -= TIC_NUME * 1000U / TIC_DENO;
+ }
+ utime += TO_USEC(clock1);
+ *p_sysutm = utime;
+
+ LOG_GET_UTM_LEAVE(E_OK, *p_sysutm);
+ return(E_OK);
+}
+
+#endif /* OMIT_GET_UTM */
+#endif /* TOPPERS_SUPPORT_GET_UTM */
+#endif /* TOPPERS_get_utm */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: wait.c 1841 2010-07-10 17:37:34Z ertl-hiro $
+ */
+
+/*
+ * 待ち状態管理モジュール
+ */
+
+#include "kernel_impl.h"
+#include "wait.h"
+
+/*
+ * 待ち状態への遷移(タイムアウト指定)
+ */
+#ifdef TOPPERS_waimake
+
+void
+make_wait_tmout(WINFO *p_winfo, TMEVTB *p_tmevtb, TMO tmout)
+{
+ (void) make_non_runnable(p_runtsk);
+ p_runtsk->p_winfo = p_winfo;
+ if (tmout > 0) {
+ p_winfo->p_tmevtb = p_tmevtb;
+ tmevtb_enqueue(p_tmevtb, (RELTIM) tmout,
+ (CBACK) wait_tmout, (void *) p_runtsk);
+ }
+ else {
+ assert(tmout == TMO_FEVR);
+ p_winfo->p_tmevtb = NULL;
+ }
+}
+
+#endif /* TOPPERS_waimake */
+
+/*
+ * 待ち解除
+ */
+#ifdef TOPPERS_waicmp
+
+bool_t
+wait_complete(TCB *p_tcb)
+{
+ wait_dequeue_tmevtb(p_tcb);
+ p_tcb->p_winfo->wercd = E_OK;
+ return(make_non_wait(p_tcb));
+}
+
+#endif /* TOPPERS_waicmp */
+
+/*
+ * タイムアウトに伴う待ち解除
+ */
+#ifdef TOPPERS_waitmo
+
+void
+wait_tmout(TCB *p_tcb)
+{
+ wait_dequeue_wobj(p_tcb);
+ p_tcb->p_winfo->wercd = E_TMOUT;
+ if (make_non_wait(p_tcb)) {
+ reqflg = true;
+ }
+
+ /*
+ * ここで優先度の高い割込みを受け付ける.
+ */
+ i_unlock_cpu();
+ i_lock_cpu();
+}
+
+#endif /* TOPPERS_waitmo */
+#ifdef TOPPERS_waitmook
+
+void
+wait_tmout_ok(TCB *p_tcb)
+{
+ p_tcb->p_winfo->wercd = E_OK;
+ if (make_non_wait(p_tcb)) {
+ reqflg = true;
+ }
+
+ /*
+ * ここで優先度の高い割込みを受け付ける.
+ */
+ i_unlock_cpu();
+ i_lock_cpu();
+}
+
+#endif /* TOPPERS_waitmook */
+
+/*
+ * 待ち状態の強制解除
+ */
+#ifdef TOPPERS_wairel
+
+bool_t
+wait_release(TCB *p_tcb)
+{
+ wait_dequeue_wobj(p_tcb);
+ wait_dequeue_tmevtb(p_tcb);
+ p_tcb->p_winfo->wercd = E_RLWAI;
+ return(make_non_wait(p_tcb));
+}
+
+#endif /* TOPPERS_wairel */
+
+/*
+ * 実行中のタスクの同期・通信オブジェクトの待ちキューへの挿入
+ *
+ * 実行中のタスクを,同期・通信オブジェクトの待ちキューへ挿入する.オ
+ * ブジェクトの属性に応じて,FIFO順またはタスク優先度順で挿入する.
+ */
+Inline void
+wobj_queue_insert(WOBJCB *p_wobjcb)
+{
+ if ((p_wobjcb->p_wobjinib->wobjatr & TA_TPRI) != 0U) {
+ queue_insert_tpri(&(p_wobjcb->wait_queue), p_runtsk);
+ }
+ else {
+ queue_insert_prev(&(p_wobjcb->wait_queue), &(p_runtsk->task_queue));
+ }
+}
+
+/*
+ * 同期・通信オブジェクトに対する待ち状態への遷移
+ */
+#ifdef TOPPERS_wobjwai
+
+void
+wobj_make_wait(WOBJCB *p_wobjcb, WINFO_WOBJ *p_winfo_wobj)
+{
+ make_wait(&(p_winfo_wobj->winfo));
+ wobj_queue_insert(p_wobjcb);
+ p_winfo_wobj->p_wobjcb = p_wobjcb;
+ LOG_TSKSTAT(p_runtsk);
+}
+
+#endif /* TOPPERS_wobjwai */
+#ifdef TOPPERS_wobjwaitmo
+
+void
+wobj_make_wait_tmout(WOBJCB *p_wobjcb, WINFO_WOBJ *p_winfo_wobj,
+ TMEVTB *p_tmevtb, TMO tmout)
+{
+ make_wait_tmout(&(p_winfo_wobj->winfo), p_tmevtb, tmout);
+ wobj_queue_insert(p_wobjcb);
+ p_winfo_wobj->p_wobjcb = p_wobjcb;
+ LOG_TSKSTAT(p_runtsk);
+}
+
+#endif /* TOPPERS_wobjwaitmo */
+
+/*
+ * 待ちキューの初期化
+ */
+#ifdef TOPPERS_iniwque
+
+bool_t
+init_wait_queue(QUEUE *p_wait_queue)
+{
+ TCB *p_tcb;
+ bool_t dspreq = false;
+
+ while (!queue_empty(p_wait_queue)) {
+ p_tcb = (TCB *) queue_delete_next(p_wait_queue);
+ wait_dequeue_tmevtb(p_tcb);
+ p_tcb->p_winfo->wercd = E_DLT;
+ if (make_non_wait(p_tcb)) {
+ dspreq = true;
+ };
+ }
+ return(dspreq);
+}
+
+#endif /* TOPPERS_iniwque */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: wait.h 1841 2010-07-10 17:37:34Z ertl-hiro $
+ */
+
+/*
+ * 待ち状態管理モジュール
+ */
+
+#ifndef TOPPERS_WAIT_H
+#define TOPPERS_WAIT_H
+
+#include "task.h"
+#include "time_event.h"
+
+/*
+ * タスクの優先度順の待ちキューへの挿入
+ *
+ * p_tcbで指定されるタスクを,タスク優先度順のキューp_queueに挿入する.
+ * キューの中に同じ優先度のタスクがある場合には,その最後に挿入する.
+ */
+Inline void
+queue_insert_tpri(QUEUE *p_queue, TCB *p_tcb)
+{
+ QUEUE *p_entry;
+ uint_t priority = p_tcb->priority;
+
+ for (p_entry = p_queue->p_next; p_entry != p_queue;
+ p_entry = p_entry->p_next) {
+ if (priority < ((TCB *) p_entry)->priority) {
+ break;
+ }
+ }
+ queue_insert_prev(p_entry, &(p_tcb->task_queue));
+}
+
+/*
+ * 待ち状態への遷移
+ *
+ * 実行中のタスクを待ち状態に遷移させる.具体的には,実行中のタスクを
+ * レディキューから削除し,TCBのp_winfoフィールド,WINFOのp_tmevtbフィー
+ * ルドを設定する.
+ */
+Inline void
+make_wait(WINFO *p_winfo)
+{
+ (void) make_non_runnable(p_runtsk);
+ p_runtsk->p_winfo = p_winfo;
+ p_winfo->p_tmevtb = NULL;
+}
+
+/*
+ * 待ち状態への遷移(タイムアウト指定)
+ *
+ * 実行中のタスクを,タイムアウト指定付きで待ち状態に遷移させる.具体
+ * 的には,実行中のタスクをレディキューから削除し,TCBのp_winfoフィー
+ * ルド,WINFOのp_tmevtbフィールドを設定する.また,タイムイベントブ
+ * ロックを登録する.
+ */
+extern void make_wait_tmout(WINFO *p_winfo, TMEVTB *p_tmevtb, TMO tmout);
+
+/*
+ * 待ち解除のためのタスク状態の更新
+ *
+ * p_tcbで指定されるタスクを,待ち解除するようタスク状態を更新する.
+ * 待ち解除するタスクが実行できる状態になる場合は,レディキューにつな
+ * ぐ.また,ディスパッチが必要な場合にはtrueを返す.
+ */
+Inline bool_t
+make_non_wait(TCB *p_tcb)
+{
+ assert(TSTAT_WAITING(p_tcb->tstat));
+
+ if (!TSTAT_SUSPENDED(p_tcb->tstat)) {
+ /*
+ * 待ち状態から実行できる状態への遷移
+ */
+ p_tcb->tstat = TS_RUNNABLE;
+ LOG_TSKSTAT(p_tcb);
+ return(make_runnable(p_tcb));
+ }
+ else {
+ /*
+ * 二重待ち状態から強制待ち状態への遷移
+ */
+ p_tcb->tstat = TS_SUSPENDED;
+ LOG_TSKSTAT(p_tcb);
+ return(false);
+ }
+}
+
+/*
+ * オブジェクト待ちキューからの削除
+ *
+ * p_tcbで指定されるタスクが,同期・通信オブジェクトの待ちキューにつ
+ * ながれていれば,待ちキューから削除する.
+ */
+Inline void
+wait_dequeue_wobj(TCB *p_tcb)
+{
+ if (TSTAT_WAIT_WOBJ(p_tcb->tstat)) {
+ queue_delete(&(p_tcb->task_queue));
+ }
+}
+
+/*
+ * 時間待ちのためのタイムイベントブロックの登録解除
+ *
+ * p_tcbで指定されるタスクに対して,時間待ちのためのタイムイベントブ
+ * ロックが登録されていれば,それを登録解除する.
+ */
+Inline void
+wait_dequeue_tmevtb(TCB *p_tcb)
+{
+ if (p_tcb->p_winfo->p_tmevtb != NULL) {
+ tmevtb_dequeue(p_tcb->p_winfo->p_tmevtb);
+ }
+}
+
+/*
+ * 待ち解除
+ *
+ * p_tcbで指定されるタスクの待ち状態を解除する.具体的には,タイムイ
+ * ベントブロックが登録されていれば,それを登録解除する.また,タスク
+ * 状態を更新し,待ち解除したタスクからの返値をE_OKとする.待ちキュー
+ * からの削除は行わない.待ち解除したタスクへのディスパッチが必要な場
+ * 合にはtrueを返す.
+ */
+extern bool_t wait_complete(TCB *p_tcb);
+
+/*
+ * タイムアウトに伴う待ち解除
+ *
+ * p_tcbで指定されるタスクが,待ちキューにつながれていれば待ちキュー
+ * から削除し,タスク状態を更新する.また,待ち解除したタスクからの返
+ * 値を,wait_tmoutではE_TMOUT,wait_tmout_okではE_OKとする.待ち解除
+ * したタスクへのディスパッチが必要な時は,reqflgをtrueにする.
+ *
+ * wait_tmout_okは,dly_tskで使うためのもので,待ちキューから削除する
+ * 処理を行わない.
+ *
+ * いずれの関数も,タイムイベントのコールバック関数として用いるための
+ * もので,割込みハンドラから呼び出されることを想定している.
+ */
+extern void wait_tmout(TCB *p_tcb);
+extern void wait_tmout_ok(TCB *p_tcb);
+
+/*
+ * 待ち状態の強制解除
+ *
+ * p_tcbで指定されるタスクの待ち状態を強制的に解除する.具体的には,
+ * タスクが待ちキューにつながれていれば待ちキューから削除し,タイムイ
+ * ベントブロックが登録されていればそれを登録解除する.また,タスクの
+ * 状態を更新し,待ち解除したタスクからの返値をE_RLWAIとする.また,
+ * 待ち解除したタスクへのディスパッチが必要な場合にはtrueを返す.
+ */
+extern bool_t wait_release(TCB *p_tcb);
+
+/*
+ * 待ちキューの先頭のタスクID
+ *
+ * p_wait_queueで指定した待ちキューの先頭のタスクIDを返す.待ちキュー
+ * が空の場合には,TSK_NONEを返す.
+ */
+Inline ID
+wait_tskid(QUEUE *p_wait_queue)
+{
+ if (!queue_empty(p_wait_queue)) {
+ return(TSKID((TCB *) p_wait_queue->p_next));
+ }
+ else {
+ return(TSK_NONE);
+ }
+}
+
+/*
+ * 同期・通信オブジェクトの管理ブロックの共通部分操作ルーチン
+ *
+ * 同期・通信オブジェクトの初期化ブロックと管理ブロックの先頭部分は共
+ * 通になっている.以下は,その共通部分を扱うための型およびルーチン群
+ * である.
+ *
+ * 複数の待ちキューを持つ同期・通信オブジェクトの場合,先頭以外の待ち
+ * キューを操作する場合には,これらのルーチンは使えない.また,オブジェ
+ * クト属性のTA_TPRIビットを参照するので,このビットを他の目的に使って
+ * いる場合も,これらのルーチンは使えない.
+ */
+
+/*
+ * 同期・通信オブジェクトの初期化ブロックの共通部分
+ */
+typedef struct wait_object_initialization_block {
+ ATR wobjatr; /* オブジェクト属性 */
+} WOBJINIB;
+
+/*
+ * 同期・通信オブジェクトの管理ブロックの共通部分
+ */
+typedef struct wait_object_control_block {
+ QUEUE wait_queue; /* 待ちキュー */
+ const WOBJINIB *p_wobjinib; /* 初期化ブロックへのポインタ */
+} WOBJCB;
+
+/*
+ * 同期・通信オブジェクトの待ち情報ブロックの共通部分
+ *
+ * この構造体は,待ち情報ブロック(WINFO)を拡張(オブジェクト指向言
+ * 語の継承に相当)したものであるが,WINFOが共用体で定義されているた
+ * めに,1つのフィールドとして含めている.
+ */
+typedef struct wait_object_waiting_information {
+ WINFO winfo; /* 標準の待ち情報ブロック */
+ WOBJCB *p_wobjcb; /* 待ちオブジェクトの管理ブロック */
+} WINFO_WOBJ;
+
+/*
+ * 同期・通信オブジェクトに対する待ち状態への遷移
+ *
+ * 実行中のタスクを待ち状態に遷移させ,同期・通信オブジェクトの待ちキュー
+ * につなぐ.また,待ち情報ブロック(WINFO)のp_wobjcbを設定する.
+ * wobj_make_wait_tmoutは,タイムイベントブロックの登録も行う.
+ */
+extern void wobj_make_wait(WOBJCB *p_wobjcb, WINFO_WOBJ *p_winfo);
+extern void wobj_make_wait_tmout(WOBJCB *p_wobjcb, WINFO_WOBJ *p_winfo,
+ TMEVTB *p_tmevtb, TMO tmout);
+
+/*
+ * タスク優先度変更時の処理
+ *
+ * 同期・通信オブジェクトに対する待ち状態にあるタスクの優先度が変更さ
+ * れた場合に,待ちキューの中でのタスクの位置を修正する.
+ */
+Inline void
+wobj_change_priority(WOBJCB *p_wobjcb, TCB *p_tcb)
+{
+ if ((p_wobjcb->p_wobjinib->wobjatr & TA_TPRI) != 0U) {
+ queue_delete(&(p_tcb->task_queue));
+ queue_insert_tpri(&(p_wobjcb->wait_queue), p_tcb);
+ }
+}
+
+/*
+ * 待ちキューの初期化
+ *
+ * 待ちキューにつながれているタスクをすべて待ち解除する.待ち解除した
+ * タスクからの返値は,E_DLTとする.待ち解除したタスクへのディスパッチ
+ * が必要な場合はtrue,そうでない場合はfalseを返す.
+ */
+extern bool_t init_wait_queue(QUEUE *p_wait_queue);
+
+#endif /* TOPPERS_WAIT_H */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2006-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: histogram.c 1574 2009-05-31 13:57:37Z ertl-hiro $
+ */
+
+/*
+ * 実行時間分布集計モジュール
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <test_lib.h>
+#include <histogram.h>
+#include "target_test.h"
+
+/*
+ * 実行時間分布計測の数
+ */
+#ifndef TNUM_HIST
+#define TNUM_HIST 10
+#endif /* TNUM_HIST */
+
+/*
+ * ターゲット依存部で設定変更するためのマクロ
+ */
+#ifndef HISTTIM /* 実行時間計測用の時刻のデータ型 */
+#define HISTTIM SYSUTM
+#endif /* HISTTIM */
+
+#ifndef HIST_GET_TIM /* 実行時間計測用の現在時刻の取得 */
+#ifndef TOPPERS_SUPPORT_GET_UTM
+#error get_utm is not supported.
+#endif /* TOPPERS_SUPPORT_GET_UTM */
+#define HIST_GET_TIM(p_time) ((void) get_utm(p_time))
+#endif /* HIST_GET_TIM */
+
+#ifndef HIST_CONV_TIM /* 時刻の差から実行時間への変換 */
+#define HIST_CONV_TIM(time) ((uint_t)(time))
+#endif /* HIST_CONV_TIM */
+
+#ifndef HIST_BM_HOOK /* 実行時間計測直前に行うべき処理 */
+#define HIST_BM_HOOK() ((void) 0)
+#endif
+
+/*
+ * 実行時間分布計測管理ブロック
+ */
+typedef struct histogram_control_block {
+ HISTTIM begin_time; /* 計測開始時刻 */
+ uint_t maxval; /* 分布を記録する最大時間 */
+ uint_t *histarea; /* 分布を記録するメモリ領域 */
+ uint_t over; /* 最大時間を超えた度数 */
+ uint_t under; /* 時間の逆転が疑われる度数 */
+} HISTCB;
+
+/*
+ * 実行時間分布計測管理ブロックのエリア
+ */
+HISTCB histcb_table[TNUM_HIST];
+
+/*
+ * 実行時間分布計測IDの最小値と最大値
+ */
+#define TMIN_HISTID 1
+#define TMAX_HISTID (TMIN_HISTID + TNUM_HIST - 1)
+
+/*
+ * 実行時間分布計測の初期化
+ */
+void
+init_hist(ID histid, uint_t maxval, uint_t histarea[])
+{
+ HISTCB *p_histcb;
+ uint_t i;
+
+ assert(TMIN_HISTID <= histid && histid <= TMAX_HISTID);
+ p_histcb = &(histcb_table[histid - TMIN_HISTID]);
+
+ for (i = 0; i <= maxval; i++) {
+ histarea[i] = 0U;
+ }
+ p_histcb->maxval = maxval;
+ p_histcb->histarea = histarea;
+ p_histcb->over = 0U;
+ p_histcb->under = 0U;
+}
+
+/*
+ * 実行時間計測の開始
+ */
+void
+begin_measure(ID histid)
+{
+ HISTCB *p_histcb;
+
+ assert(TMIN_HISTID <= histid && histid <= TMAX_HISTID);
+ p_histcb = &(histcb_table[histid - TMIN_HISTID]);
+
+ HIST_BM_HOOK();
+ HIST_GET_TIM(&(p_histcb->begin_time));
+}
+
+/*
+ * 実行時間計測の終了
+ */
+void
+end_measure(ID histid)
+{
+ HISTCB *p_histcb;
+ HISTTIM end_time;
+ uint_t val;
+
+ HIST_GET_TIM(&end_time);
+
+ assert(TMIN_HISTID <= histid && histid <= TMAX_HISTID);
+ p_histcb = &(histcb_table[histid - TMIN_HISTID]);
+
+ val = HIST_CONV_TIM(end_time - p_histcb->begin_time);
+ if (val <= p_histcb->maxval) {
+ p_histcb->histarea[val]++;
+ }
+ else if (val <= ((uint_t) INT_MAX)) {
+ p_histcb->over++;
+ }
+ else {
+ p_histcb->under++;
+ }
+}
+
+/*
+ * 実行時間分布計測の表示
+ */
+void
+print_hist(ID histid)
+{
+ HISTCB *p_histcb;
+ uint_t i;
+
+ assert(TMIN_HISTID <= histid && histid <= TMAX_HISTID);
+ p_histcb = &(histcb_table[histid - TMIN_HISTID]);
+
+ for (i = 0; i <= p_histcb->maxval; i++) {
+ if (p_histcb->histarea[i] > 0) {
+ syslog_2(LOG_NOTICE, "%d : %d", i, p_histcb->histarea[i]);
+ syslog_flush();
+ }
+ }
+ if (p_histcb->over > 0) {
+ syslog_2(LOG_NOTICE, "> %d : %d", p_histcb->maxval, p_histcb->over);
+ }
+ if (p_histcb->under > 0) {
+ syslog_1(LOG_NOTICE, "> INT_MAX : %d", p_histcb->under);
+ }
+ syslog_flush();
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: log_output.c 1176 2008-07-01 10:24:46Z ertl-hiro $
+ */
+
+/*
+ * システムログのフォーマット出力
+ */
+
+#include <t_stddef.h>
+#include <t_syslog.h>
+
+/*
+ * 数値を文字列に変換
+ */
+#define CONVERT_BUFLEN ((sizeof(uintptr_t) * CHAR_BIT + 2) / 3)
+ /* uintptr_t型の数値の最大文字数 */
+static void
+convert(uintptr_t val, uint_t radix, const char *radchar,
+ uint_t width, bool_t minus, bool_t padzero, void (*putc)(char_t))
+{
+ char buf[CONVERT_BUFLEN];
+ uint_t i, j;
+
+ i = 0U;
+ do {
+ buf[i++] = radchar[val % radix];
+ val /= radix;
+ } while (i < CONVERT_BUFLEN && val != 0);
+
+ if (minus && width > 0) {
+ width -= 1;
+ }
+ if (minus && padzero) {
+ (*putc)('-');
+ }
+ for (j = i; j < width; j++) {
+ (*putc)((char_t)(padzero ? '0' : ' '));
+ }
+ if (minus && !padzero) {
+ (*putc)('-');
+ }
+ while (i > 0U) {
+ (*putc)(buf[--i]);
+ }
+}
+
+/*
+ * 文字列整形出力
+ */
+static const char raddec[] = "0123456789";
+static const char radhex[] = "0123456789abcdef";
+static const char radHEX[] = "0123456789ABCDEF";
+
+void
+syslog_printf(const char *format, const intptr_t *p_args, void (*putc)(char_t))
+{
+ char c;
+ uint_t width;
+ bool_t padzero;
+ intptr_t val;
+ const char *str;
+
+ while ((c = *format++) != '\0') {
+ if (c != '%') {
+ (*putc)(c);
+ continue;
+ }
+
+ width = 0U;
+ padzero = false;
+ if ((c = *format++) == '0') {
+ padzero = true;
+ c = *format++;
+ }
+ while ('0' <= c && c <= '9') {
+ width = width * 10U + c - '0';
+ c = *format++;
+ }
+ if (c == 'l') {
+ c = *format++;
+ }
+ switch (c) {
+ case 'd':
+ val = (intptr_t)(*p_args++);
+ if (val >= 0) {
+ convert((uintptr_t) val, 10U, raddec,
+ width, false, padzero, putc);
+ }
+ else {
+ convert((uintptr_t)(-val), 10U, raddec,
+ width, true, padzero, putc);
+ }
+ break;
+ case 'u':
+ val = (intptr_t)(*p_args++);
+ convert((uintptr_t) val, 10U, raddec, width, false, padzero, putc);
+ break;
+ case 'x':
+ case 'p':
+ val = (intptr_t)(*p_args++);
+ convert((uintptr_t) val, 16U, radhex, width, false, padzero, putc);
+ break;
+ case 'X':
+ val = (intptr_t)(*p_args++);
+ convert((uintptr_t) val, 16U, radHEX, width, false, padzero, putc);
+ break;
+ case 'c':
+ (*putc)((char_t)(intptr_t)(*p_args++));
+ break;
+ case 's':
+ str = (const char *)(*p_args++);
+ while ((c = *str++) != '\0') {
+ (*putc)(c);
+ }
+ break;
+ case '%':
+ (*putc)('%');
+ break;
+ case '\0':
+ format--;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+/*
+ * ログ情報の出力
+ */
+void
+syslog_print(const SYSLOG *p_syslog, void (*putc)(char_t))
+{
+ switch (p_syslog->logtype) {
+ case LOG_TYPE_COMMENT:
+ syslog_printf((const char *)(p_syslog->loginfo[0]),
+ &(p_syslog->loginfo[1]), putc);
+ break;
+ case LOG_TYPE_ASSERT:
+ syslog_printf("%s:%u: Assertion `%s' failed.",
+ &(p_syslog->loginfo[0]), putc);
+ break;
+ }
+}
+
+/*
+ * ログ情報喪失メッセージの出力
+ */
+void
+syslog_lostmsg(uint_t lost, void (*putc)(char_t))
+{
+ intptr_t lostinfo[1];
+
+ lostinfo[0] = (intptr_t) lost;
+ syslog_printf("%d messages are lost.", lostinfo, putc);
+ (*putc)('\n');
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: strerror.c 1732 2010-02-03 03:15:52Z ertl-hiro $
+ */
+
+/*
+ * エラーメッセージ文字列を返す関数
+ */
+
+#include <t_stddef.h>
+#include <t_stdlib.h>
+
+const char *
+itron_strerror(ER ercd)
+{
+ switch (MERCD(ercd)) {
+ case E_OK:
+ return("E_OK");
+
+ case E_SYS:
+ return("E_SYS");
+ case E_NOSPT:
+ return("E_NOSPT");
+ case E_RSFN:
+ return("E_RSFN");
+ case E_RSATR:
+ return("E_RSATR");
+
+ case E_PAR:
+ return("E_PAR");
+ case E_ID:
+ return("E_ID");
+
+ case E_CTX:
+ return("E_CTX");
+ case E_MACV:
+ return("E_MACV");
+ case E_OACV:
+ return("E_OACV");
+ case E_ILUSE:
+ return("E_ILUSE");
+
+ case E_NOMEM:
+ return("E_NOMEM");
+ case E_NOID:
+ return("E_NOID");
+ case E_NORES:
+ return("E_NORES");
+
+ case E_OBJ:
+ return("E_OBJ");
+ case E_NOEXS:
+ return("E_NOEXS");
+ case E_QOVR:
+ return("E_QOVR");
+
+ case E_RLWAI:
+ return("E_RLWAI");
+ case E_TMOUT:
+ return("E_TMOUT");
+ case E_DLT:
+ return("E_DLT");
+ case E_CLS:
+ return("E_CLS");
+
+ case E_WBLK:
+ return("E_WBLK");
+ case E_BOVR:
+ return("E_BOVR");
+
+ default:
+ return("unknown error");
+ }
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2006 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: t_perror.c 264 2007-07-12 08:23:10Z hiro $
+ */
+
+/*
+ * エラーメッセージの出力
+ */
+
+#include <t_stddef.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+
+void
+t_perror(uint_t prio, const char *file, int_t line, const char *expr, ER ercd)
+{
+ syslog_5(prio, "%s (%d) reported by `%s' in line %d of `%s'.",
+ itron_strerror(ercd), SERCD(ercd), expr, line, file);
+
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2005-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_lib.c 1573 2009-05-31 13:47:28Z ertl-hiro $
+ */
+
+/*
+ * テストプログラム用ライブラリ
+ */
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <log_output.h>
+#include "syssvc/syslog.h"
+#include "target_syssvc.h"
+#include "test_lib.h"
+
+/*
+ * チェックポイント
+ */
+static uint_t check_count = 0u;
+
+/*
+ * 自己診断関数
+ */
+static BIT_FUNC check_bit_func = NULL;
+
+/*
+ * 自己診断関数の設定
+ */
+void
+set_bit_func(BIT_FUNC bit_func)
+{
+ check_bit_func = bit_func;
+}
+
+/*
+ * システムログの出力処理
+ */
+void
+syslog_flush(void)
+{
+ SYSLOG syslog;
+ ER_UINT rercd;
+
+ /*
+ * ログバッファに記録されたログ情報を,低レベル出力機能を用いて出
+ * 力する.
+ */
+ while ((rercd = syslog_rea_log(&syslog)) >= 0) {
+ if (rercd > 0) {
+ syslog_lostmsg((uint_t) rercd, target_fput_log);
+ }
+ if (syslog.logtype >= LOG_TYPE_COMMENT) {
+ syslog_print(&syslog, target_fput_log);
+ target_fput_log('\n');
+ }
+ }
+}
+
+/*
+ * テストプログラムの終了
+ */
+void
+test_finish(void)
+{
+ SIL_PRE_LOC;
+
+ SIL_LOC_INT();
+ syslog_flush();
+ ext_ker();
+}
+
+/*
+ * チェックポイント
+ */
+void
+check_point(uint_t count)
+{
+ bool_t errorflag = false;
+ ER rercd;
+ SIL_PRE_LOC;
+
+ /*
+ * 割込みロック状態に
+ */
+ SIL_LOC_INT();
+
+ /*
+ * シーケンスチェック
+ */
+ if (++check_count == count) {
+ syslog_1(LOG_NOTICE, "Check point %d passed.", count);
+ }
+ else {
+ syslog_1(LOG_ERROR, "## Unexpected check point %d.", count);
+ errorflag = true;
+ }
+
+ /*
+ * カーネルの内部状態の検査
+ */
+ if (check_bit_func != NULL) {
+ rercd = (*check_bit_func)();
+ if (rercd < 0) {
+ syslog_2(LOG_ERROR, "## Internal inconsistency detected (%s, %d).",
+ itron_strerror(rercd), SERCD(rercd));
+ errorflag = true;
+ }
+ }
+
+ /*
+ * エラーが検出された場合は,テストプログラムを終了する.
+ */
+ if (errorflag) {
+ test_finish();
+ }
+
+ /*
+ * 割込みロック状態を解除
+ */
+ SIL_UNL_INT();
+}
+
+/*
+ * 完了チェックポイント
+ */
+void
+check_finish(uint_t count)
+{
+ check_point(count);
+ syslog_0(LOG_NOTICE, "All check points passed.");
+ test_finish();
+}
+
+/*
+ * 条件チェックのエラー処理
+ */
+void
+_check_assert(const char *expr, const char *file, int_t line)
+{
+ syslog_3(LOG_ERROR, "## Assertion `%s' failed at %s:%u.",
+ expr, file, line);
+ test_finish();
+}
+
+/*
+ * エラーコードチェックのエラー処理
+ */
+void
+_check_ercd(ER ercd, const char *file, int_t line)
+{
+ syslog_3(LOG_ERROR, "## Unexpected error %s detected at %s:%u.",
+ itron_strerror(ercd), file, line);
+ test_finish();
+}
--- /dev/null
+/**\r
+ * @file : lpc17xx_adc.c\r
+ * @brief : Contains all functions support for ADC firmware library on LPC17xx\r
+ * @version : 1.0\r
+ * @date : 3. April. 2009\r
+ * @author : NgaDinh\r
+ **************************************************************************\r
+ * Software that is described herein is for illustrative purposes only\r
+ * which provides customers with programming information regarding the\r
+ * products. This software is supplied "AS IS" without any warranties.\r
+ * NXP Semiconductors assumes no responsibility or liability for the\r
+ * use of the software, conveys no license or title under any patent,\r
+ * copyright, or mask work right to the product. NXP Semiconductors\r
+ * reserves the right to make changes in the software without\r
+ * notification. NXP Semiconductors also make no representation or\r
+ * warranty that such application will be suitable for the specified\r
+ * use without further testing or modification.\r
+ **********************************************************************/\r
+\r
+/* Peripheral group ----------------------------------------------------------- */\r
+/** @addtogroup ADC\r
+ * @{\r
+ */\r
+\r
+/* Includes ------------------------------------------------------------------- */\r
+#include "lpc17xx_adc.h"\r
+#include "lpc17xx_clkpwr.h"\r
+\r
+/* If this source file built with example, the LPC17xx FW library configuration\r
+ * file in each example directory ("lpc17xx_libcfg.h") must be included,\r
+ * otherwise the default FW library configuration file must be included instead\r
+ */\r
+#ifdef __BUILD_WITH_EXAMPLE__\r
+#include "lpc17xx_libcfg.h"\r
+#else\r
+#include "lpc17xx_libcfg_default.h"\r
+#endif /* __BUILD_WITH_EXAMPLE__ */\r
+\r
+\r
+#ifdef _ADC\r
+\r
+/* Public Functions ----------------------------------------------------------- */\r
+/** @addtogroup ADC_Public_Functions\r
+ * @{\r
+ */\r
+\r
+/*********************************************************************//**\r
+ * @brief Initial for ADC\r
+ * - Set bit PCADC\r
+ * - Set clock for ADC\r
+ * - Set Clock Frequency\r
+ *\r
+ * @param[in] ADCx pointer to LPC_ADC_TypeDef\r
+ * @param[in] ConvFreq Clock frequency\r
+ * @return None\r
+ **********************************************************************/\r
+void ADC_Init(LPC_ADC_TypeDef *ADCx, uint32_t ConvFreq)\r
+\r
+{\r
+ uint32_t temp, tmp;\r
+\r
+ CHECK_PARAM(PARAM_ADCx(ADCx));\r
+ CHECK_PARAM(PARAM_ADC_FREQUENCY(ConvFreq));\r
+\r
+ // Turn on power and clock\r
+ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCAD, ENABLE);\r
+ // Set clock divider for ADC to 4 from CCLK as default\r
+ // CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_ADC,CLKPWR_PCLKSEL_CCLK_DIV_4);\r
+\r
+ ADCx->ADCR = 0;\r
+\r
+ //Enable PDN bit\r
+ tmp = ADC_CR_PDN;\r
+ // Set clock frequency\r
+ temp = CLKPWR_GetPCLK(CLKPWR_PCLKSEL_ADC) ;\r
+ temp = (temp /ConvFreq) - 1;\r
+ tmp |= ADC_CR_CLKDIV(temp);\r
+\r
+ ADCx->ADCR = tmp;\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+* @brief Close ADC\r
+* @param[in] ADCx pointer to ADC\r
+* @return None\r
+**********************************************************************/\r
+void ADC_DeInit(LPC_ADC_TypeDef *ADCx)\r
+{\r
+ CHECK_PARAM(PARAM_ADCx(ADCx));\r
+\r
+ // Clear PDN bit\r
+ ADCx->ADCR &= ~ADC_CR_PDN;\r
+ // Turn on power and clock\r
+ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCAD, DISABLE);\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+* @brief Get Result conversion from A/D data register\r
+* @param[in] channel number which want to read back the result\r
+* @return Result of conversion\r
+*********************************************************************/\r
+uint32_t ADC_GetData(uint32_t channel)\r
+{\r
+ uint32_t adc_value;\r
+\r
+ CHECK_PARAM(PARAM_ADC_CHANNEL_SELECTION(channel));\r
+\r
+ adc_value = *(uint32_t *)((&LPC_ADC->ADDR0) + channel);\r
+ return ADC_GDR_RESULT(adc_value);\r
+}\r
+\r
+/*********************************************************************//**\r
+* @brief Set start mode for ADC\r
+* @param[in] ADCx pointer to LPC_ADC_TypeDef\r
+* @param[in] start_mode Start mode choose one of modes in\r
+* 'ADC_START_OPT' enumeration type definition\r
+* @return None\r
+*********************************************************************/\r
+void ADC_StartCmd(LPC_ADC_TypeDef *ADCx, uint8_t start_mode)\r
+{\r
+ CHECK_PARAM(PARAM_ADCx(ADCx));\r
+ CHECK_PARAM(PARAM_ADC_START_OPT(start_mode));\r
+\r
+ ADCx->ADCR &= ~ADC_CR_START_MASK;\r
+ ADCx->ADCR |=ADC_CR_START_MODE_SEL((uint32_t)start_mode);\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+* @brief ADC Burst mode setting\r
+*\r
+* @param[in] ADCx pointer to ADC\r
+* @param[in] NewState\r
+* - 1: Set Burst mode\r
+* - 0: reset Burst mode\r
+* @return None\r
+**********************************************************************/\r
+void ADC_BurstCmd(LPC_ADC_TypeDef *ADCx, FunctionalState NewState)\r
+{\r
+ CHECK_PARAM(PARAM_ADCx(ADCx));\r
+\r
+ ADCx->ADCR &= ~ADC_CR_BURST;\r
+ if (NewState){\r
+ ADCx->ADCR |= ADC_CR_BURST;\r
+ }\r
+\r
+}\r
+\r
+/*********************************************************************//**\r
+* @brief Set AD conversion in power mode\r
+*\r
+* @param[in] ADCx pointer to ADC\r
+* @param[in] NewState\r
+* - 1: AD converter is optional\r
+* - 0: AD Converter is in power down mode\r
+* @return None\r
+**********************************************************************/\r
+void ADC_PowerdownCmd(LPC_ADC_TypeDef *ADCx, FunctionalState NewState)\r
+{\r
+ CHECK_PARAM(PARAM_ADCx(ADCx));\r
+\r
+ ADCx->ADCR &= ~ADC_CR_PDN;\r
+ if (NewState){\r
+ ADCx->ADCR |= ADC_CR_PDN;\r
+ }\r
+}\r
+\r
+/*********************************************************************//**\r
+* @brief Set Edge start configuration\r
+*\r
+* @param[in] ADCx pointer to ADC\r
+* @param[in] EdgeOption is ADC_START_ON_RISING and ADC_START_ON_FALLING\r
+* 0:ADC_START_ON_RISING\r
+* 1:ADC_START_ON_FALLING\r
+*\r
+* @return None\r
+**********************************************************************/\r
+void ADC_EdgeStartConfig(LPC_ADC_TypeDef *ADCx, uint8_t EdgeOption)\r
+{\r
+ CHECK_PARAM(PARAM_ADCx(ADCx));\r
+ CHECK_PARAM(PARAM_ADC_START_ON_EDGE_OPT(EdgeOption));\r
+\r
+ ADCx->ADCR &= ~ADC_CR_EDGE;\r
+ if (EdgeOption){\r
+ ADCx->ADCR |= ADC_CR_EDGE;\r
+ }\r
+}\r
+\r
+/*********************************************************************//**\r
+* @brief ADC interrupt configuration\r
+* @param[in] ADCx pointer to ADC\r
+* @param[in] IntType\r
+* @param[in] NewState:\r
+* - SET : enable ADC interrupt\r
+* - RESET: disable ADC interrupt\r
+*\r
+* @return None\r
+**********************************************************************/\r
+void ADC_IntConfig (LPC_ADC_TypeDef *ADCx, ADC_TYPE_INT_OPT IntType, FunctionalState NewState)\r
+{\r
+ CHECK_PARAM(PARAM_ADCx(ADCx));\r
+ CHECK_PARAM(PARAM_ADC_TYPE_INT_OPT(IntType));\r
+\r
+ ADCx->ADINTEN &= ~ADC_INTEN_CH(IntType);\r
+ if (NewState){\r
+ ADCx->ADINTEN |= ADC_INTEN_CH(IntType);\r
+ }\r
+}\r
+\r
+/*********************************************************************//**\r
+* @brief Enable/Disable ADC channel number\r
+* @param[in] ADCx pointer to ADC\r
+* @param[in] Channel channel number\r
+* @param[in] NewState Enable or Disable\r
+*\r
+* @return None\r
+**********************************************************************/\r
+void ADC_ChannelCmd (LPC_ADC_TypeDef *ADCx, uint8_t Channel, FunctionalState NewState)\r
+{\r
+ CHECK_PARAM(PARAM_ADCx(ADCx));\r
+ CHECK_PARAM(PARAM_ADC_CHANNEL_SELECTION(Channel));\r
+\r
+ if (NewState == ENABLE) {\r
+ ADCx->ADCR |= ADC_CR_CH_SEL(Channel);\r
+ } else {\r
+ ADCx->ADCR &= ~ADC_CR_CH_SEL(Channel);\r
+ }\r
+}\r
+\r
+/*********************************************************************//**\r
+* @brief Get ADC result\r
+* @param[in] ADCx pointer to ADC\r
+* @param[in] channel channel number\r
+* @return Data conversion\r
+**********************************************************************/\r
+uint16_t ADC_ChannelGetData(LPC_ADC_TypeDef *ADCx, uint8_t channel)\r
+{\r
+ uint32_t adc_value;\r
+\r
+ CHECK_PARAM(PARAM_ADCx(ADCx));\r
+ CHECK_PARAM(PARAM_ADC_CHANNEL_SELECTION(channel));\r
+\r
+ adc_value = *(uint32_t *) ((&ADCx->ADDR0) + channel);\r
+ return ADC_DR_RESULT(adc_value);\r
+}\r
+\r
+/*********************************************************************//**\r
+* @brief Get ADC Chanel status from ADC data register\r
+* @param[in] ADCx pointer to ADC\r
+* @param[in] channel channel number\r
+* @param[in] StatusType\r
+* 0:Burst status\r
+* 1:Done status\r
+* @return SET / RESET\r
+**********************************************************************/\r
+FlagStatus ADC_ChannelGetStatus(LPC_ADC_TypeDef *ADCx, uint8_t channel, uint32_t StatusType)\r
+{\r
+ uint32_t temp;\r
+\r
+ CHECK_PARAM(PARAM_ADCx(ADCx));\r
+ CHECK_PARAM(PARAM_ADC_CHANNEL_SELECTION(channel));\r
+ CHECK_PARAM(PARAM_ADC_DATA_STATUS(StatusType));\r
+\r
+ temp = *(uint32_t *) ((&ADCx->ADDR0) + channel);\r
+ if (StatusType) {\r
+ temp &= ADC_DR_DONE_FLAG;\r
+ }else{\r
+ temp &= ADC_DR_OVERRUN_FLAG;\r
+ }\r
+ if (temp) {\r
+ return SET;\r
+ } else {\r
+ return RESET;\r
+ }\r
+\r
+}\r
+\r
+/*********************************************************************//**\r
+* @brief Get ADC Data from AD Global register\r
+* @param[in] ADCx pointer to ADC\r
+* @param[in] channel channel number\r
+* @return Result of conversion\r
+**********************************************************************/\r
+uint16_t ADC_GlobalGetData(LPC_ADC_TypeDef *ADCx, uint8_t channel)\r
+{\r
+ CHECK_PARAM(PARAM_ADCx(ADCx));\r
+ CHECK_PARAM(PARAM_ADC_CHANNEL_SELECTION(channel));\r
+\r
+ //ADCx->ADGDR &= ~ADC_GDR_CH_MASK;\r
+ //ADCx->ADGDR |= ADC_GDR_CH(channel);\r
+ return (uint16_t)(ADC_GDR_RESULT(ADCx->ADGDR));\r
+}\r
+\r
+/*********************************************************************//**\r
+* @brief Get ADC Chanel status from AD global data register\r
+* @param[in] ADCx pointer to ADC\r
+* @param[in] StatusType\r
+* 0:Burst status\r
+* 1:Done status\r
+* @return SET / RESET\r
+**********************************************************************/\r
+FlagStatus ADC_GlobalGetStatus(LPC_ADC_TypeDef *ADCx, uint32_t StatusType)\r
+{\r
+ uint32_t temp;\r
+\r
+ CHECK_PARAM(PARAM_ADCx(ADCx));\r
+ CHECK_PARAM(PARAM_ADC_DATA_STATUS(StatusType));\r
+\r
+ temp = ADCx->ADGDR;\r
+ if (StatusType){\r
+ temp &= ADC_DR_DONE_FLAG;\r
+ }else{\r
+ temp &= ADC_DR_OVERRUN_FLAG;\r
+ }\r
+ if (temp){\r
+ return SET;\r
+ }else{\r
+ return RESET;\r
+ }\r
+}\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#endif /* _ADC */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* --------------------------------- End Of File ------------------------------ */\r
+\r
--- /dev/null
+/***********************************************************************//**\r
+ * @file : lpc17xx_adc.h\r
+ * @brief : Contains all macro definitions and function prototypes\r
+ * support for ADC firmware library on LPC17xx\r
+ * @version : 1.0\r
+ * @date : 3. April. 2009\r
+ * @author : NgaDinh\r
+ **************************************************************************\r
+ * Software that is described herein is for illustrative purposes only\r
+ * which provides customers with programming information regarding the\r
+ * products. This software is supplied "AS IS" without any warranties.\r
+ * NXP Semiconductors assumes no responsibility or liability for the\r
+ * use of the software, conveys no license or title under any patent,\r
+ * copyright, or mask work right to the product. NXP Semiconductors\r
+ * reserves the right to make changes in the software without\r
+ * notification. NXP Semiconductors also make no representation or\r
+ * warranty that such application will be suitable for the specified\r
+ * use without further testing or modification.\r
+ **************************************************************************/\r
+\r
+/* Peripheral group ----------------------------------------------------------- */\r
+/** @defgroup ADC\r
+ * @ingroup LPC1700CMSIS_FwLib_Drivers\r
+ * @{\r
+ */\r
+\r
+#ifndef LPC17XX_ADC_H_\r
+#define LPC17XX_ADC_H_\r
+\r
+/* Includes ------------------------------------------------------------------- */\r
+#include "LPC17xx.h"\r
+#include "lpc_types.h"\r
+\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif\r
+\r
+\r
+/* Private Macros ------------------------------------------------------------- */\r
+/** @defgroup ADC_Private_Macros ADC_Private_Macros\r
+ * @{\r
+ */\r
+\r
+\r
+/** @defgroup group3 ADC_REGISTER_BIT_DEFINITIONS\r
+ * @{\r
+ */\r
+\r
+/*********************************************************************//**\r
+ * Macro defines for ADC control register\r
+ **********************************************************************/\r
+/** Selects which of the AD0.0:7 pins is (are) to be sampled and converted */\r
+#define ADC_CR_CH_SEL(n) ((1UL << n))\r
+/** The APB clock (PCLK) is divided by (this value plus one)\r
+* to produce the clock for the A/D */\r
+#define ADC_CR_CLKDIV(n) ((n<<8))\r
+/** Repeated conversions A/D enable bit */\r
+#define ADC_CR_BURST ((1UL<<16))\r
+/** ADC convert in power down mode */\r
+#define ADC_CR_PDN ((1UL<<21))\r
+/** Start mask bits */\r
+#define ADC_CR_START_MASK ((7UL<<24))\r
+/** Select Start Mode */\r
+#define ADC_CR_START_MODE_SEL(SEL) ((SEL<<24))\r
+/** Start conversion now */\r
+#define ADC_CR_START_NOW ((1UL<<24))\r
+/** Start conversion when the edge selected by bit 27 occurs on P2.10/EINT0 */\r
+#define ADC_CR_START_EINT0 ((2UL<<24))\r
+/** Start conversion when the edge selected by bit 27 occurs on P1.27/CAP0.1 */\r
+#define ADC_CR_START_CAP01 ((3UL<<24))\r
+/** Start conversion when the edge selected by bit 27 occurs on MAT0.1 */\r
+#define ADC_CR_START_MAT01 ((4UL<<24))\r
+/** Start conversion when the edge selected by bit 27 occurs on MAT0.3 */\r
+#define ADC_CR_START_MAT03 ((5UL<<24))\r
+/** Start conversion when the edge selected by bit 27 occurs on MAT1.0 */\r
+#define ADC_CR_START_MAT10 ((6UL<<24))\r
+/** Start conversion when the edge selected by bit 27 occurs on MAT1.1 */\r
+#define ADC_CR_START_MAT11 ((7UL<<24))\r
+/** Start conversion on a falling edge on the selected CAP/MAT signal */\r
+#define ADC_CR_EDGE ((1UL<<27))\r
+\r
+/*********************************************************************//**\r
+ * Macro defines for ADC Global Data register\r
+ **********************************************************************/\r
+/** When DONE is 1, this field contains result value of ADC conversion */\r
+#define ADC_GDR_RESULT(n) (((n>>4)&0xFFF))\r
+/** These bits contain the channel from which the LS bits were converted */\r
+#define ADC_GDR_CH(n) (((n>>24)&0x7))\r
+/** This bit is 1 in burst mode if the results of one or\r
+ * more conversions was (were) lost */\r
+#define ADC_GDR_OVERRUN_FLAG ((1UL<<30))\r
+/** This bit is set to 1 when an A/D conversion completes */\r
+#define ADC_GDR_DONE_FLAG ((1UL<<31))\r
+\r
+/** This bits is used to mask for Channel */\r
+#define ADC_GDR_CH_MASK ((7UL<<24))\r
+/*********************************************************************//**\r
+ * Macro defines for ADC Interrupt register\r
+ **********************************************************************/\r
+/** These bits allow control over which A/D channels generate\r
+ * interrupts for conversion completion */\r
+#define ADC_INTEN_CH(n) ((1UL<<n))\r
+/** When 1, enables the global DONE flag in ADDR to generate an interrupt */\r
+#define ADC_INTEN_GLOBAL ((1UL<<8))\r
+\r
+/*********************************************************************//**\r
+ * Macro defines for ADC Data register\r
+ **********************************************************************/\r
+/** When DONE is 1, this field contains result value of ADC conversion */\r
+#define ADC_DR_RESULT(n) (((n>>4)&0xFFF))\r
+/** These bits mirror the OVERRRUN status flags that appear in the\r
+ * result register for each A/D channel */\r
+#define ADC_DR_OVERRUN_FLAG ((1UL<<30))\r
+/** This bit is set to 1 when an A/D conversion completes. It is cleared\r
+ * when this register is read */\r
+#define ADC_DR_DONE_FLAG ((1UL<<31))\r
+\r
+/*********************************************************************//**\r
+ * Macro defines for ADC Status register\r
+**********************************************************************/\r
+/** These bits mirror the DONE status flags that appear in the result\r
+ * register for each A/D channel */\r
+#define ADC_STAT_CH_DONE_FLAG(n) ((n&0xFF))\r
+/** These bits mirror the OVERRRUN status flags that appear in the\r
+ * result register for each A/D channel */\r
+#define ADC_STAT_CH_OVERRUN_FLAG(n) (((n>>8)&0xFF))\r
+/** This bit is the A/D interrupt flag */\r
+#define ADC_STAT_INT_FLAG ((1UL<<16))\r
+\r
+/*********************************************************************//**\r
+ * Macro defines for ADC Trim register\r
+**********************************************************************/\r
+/** Offset trim bits for ADC operation */\r
+#define ADC_ADCOFFS(n) (((n&0xF)<<4))\r
+/** Written to boot code*/\r
+#define ADC_TRIM(n) (((n&0xF)<<8))\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Types --------------------------------------------------------------- */\r
+/** @defgroup ADC_Public_Types\r
+ * @{\r
+ */\r
+\r
+/*********************************************************************//**\r
+ * @brief ADC enumeration\r
+ **********************************************************************/\r
+/** @brief Channel Selection */\r
+typedef enum\r
+{\r
+ ADC_CHANNEL_0 = 0, /*!< Channel 0 */\r
+ ADC_CHANNEL_1, /*!< Channel 1 */\r
+ ADC_CHANNEL_2, /*!< Channel 2 */\r
+ ADC_CHANNEL_3, /*!< Channel 3 */\r
+ ADC_CHANNEL_4, /*!< Channel 4 */\r
+ ADC_CHANNEL_5, /*!< Channel 5 */\r
+ ADC_CHANNEL_6, /*!< Channel 6 */\r
+ ADC_CHANNEL_7 /*!< Channel 7 */\r
+}ADC_CHANNEL_SELECTION;\r
+\r
+\r
+\r
+/** @brief Type of start option */\r
+\r
+/** @brief Type of start option */\r
+\r
+typedef enum\r
+{\r
+ ADC_START_CONTINUOUS =0, /*!< Continuous mode */\r
+ ADC_START_NOW, /*!< Start conversion now */\r
+ ADC_START_ON_EINT0, /*!< Start conversion when the edge selected\r
+ * by bit 27 occurs on P2.10/EINT0 */\r
+ ADC_START_ON_CAP01, /*!< Start conversion when the edge selected\r
+ * by bit 27 occurs on P1.27/CAP0.1 */\r
+ ADC_START_ON_MAT01, /*!< Start conversion when the edge selected\r
+ * by bit 27 occurs on MAT0.1 */\r
+ ADC_START_ON_MAT03, /*!< Start conversion when the edge selected\r
+ * by bit 27 occurs on MAT0.3 */\r
+ ADC_START_ON_MAT10, /*!< Start conversion when the edge selected\r
+ * by bit 27 occurs on MAT1.0 */\r
+ ADC_START_ON_MAT11 /*!< Start conversion when the edge selected\r
+ * by bit 27 occurs on MAT1.1 */\r
+} ADC_START_OPT;\r
+\r
+\r
+/** @brief Type of edge when start conversion on the selected CAP/MAT signal */\r
+\r
+typedef enum\r
+{\r
+ ADC_START_ON_RISING = 0, /*!< Start conversion on a rising edge\r
+ *on the selected CAP/MAT signal */\r
+ ADC_START_ON_FALLING /*!< Start conversion on a falling edge\r
+ *on the selected CAP/MAT signal */\r
+} ADC_START_ON_EDGE_OPT;\r
+\r
+/** @brief* ADC type interrupt enum */\r
+typedef enum\r
+{\r
+ ADC_ADINTEN0 = 0, /*!< Interrupt channel 0 */\r
+ ADC_ADINTEN1, /*!< Interrupt channel 1 */\r
+ ADC_ADINTEN2, /*!< Interrupt channel 2 */\r
+ ADC_ADINTEN3, /*!< Interrupt channel 3 */\r
+ ADC_ADINTEN4, /*!< Interrupt channel 4 */\r
+ ADC_ADINTEN5, /*!< Interrupt channel 5 */\r
+ ADC_ADINTEN6, /*!< Interrupt channel 6 */\r
+ ADC_ADINTEN7, /*!< Interrupt channel 7 */\r
+ ADC_ADGINTEN /*!< Individual channel/global flag done generate an interrupt */\r
+}ADC_TYPE_INT_OPT;\r
+\r
+/** Macro to determine if it is valid interrupt type */\r
+#define PARAM_ADC_TYPE_INT_OPT(OPT) ((OPT == ADC_ADINTEN0)||(OPT == ADC_ADINTEN1)\\r
+||(OPT == ADC_ADINTEN2)||(OPT == ADC_ADINTEN3)\\r
+||(OPT == ADC_ADINTEN4)||(OPT == ADC_ADINTEN5)\\r
+||(OPT == ADC_ADINTEN6)||(OPT == ADC_ADINTEN7)\\r
+||(OPT == ADC_ADGINTEN))\r
+\r
+\r
+/** @brief ADC Data status */\r
+typedef enum\r
+{\r
+ ADC_DATA_BURST = 0, /*Burst bit*/\r
+ ADC_DATA_DONE /*Done bit*/\r
+}ADC_DATA_STATUS;\r
+\r
+\r
+#define PARAM_ADC_START_ON_EDGE_OPT(OPT) ((OPT == ADC_START_ON_RISING)||(OPT == ADC_START_ON_FALLING))\r
+\r
+#define PARAM_ADC_DATA_STATUS(OPT) ((OPT== ADC_DATA_BURST)||(OPT== ADC_DATA_DONE))\r
+\r
+#define PARAM_ADC_FREQUENCY(FRE) (FRE <= 13000000 )\r
+\r
+#define PARAM_ADC_CHANNEL_SELECTION(SEL) ((SEL == ADC_CHANNEL_0)||(ADC_CHANNEL_1)\\r
+||(SEL == ADC_CHANNEL_2)|(ADC_CHANNEL_3)\\r
+||(SEL == ADC_CHANNEL_4)||(ADC_CHANNEL_5)\\r
+||(SEL == ADC_CHANNEL_6)||(ADC_CHANNEL_7))\r
+\r
+#define PARAM_ADC_START_OPT(OPT) ((OPT == ADC_START_CONTINUOUS)||(OPT == ADC_START_NOW)\\r
+||(OPT == ADC_START_ON_EINT0)||(OPT == ADC_START_ON_CAP01)\\r
+||(OPT == ADC_START_ON_MAT01)||(OPT == ADC_START_ON_MAT03)\\r
+||(OPT == ADC_START_ON_MAT10)||(OPT == ADC_START_ON_MAT11))\r
+\r
+#define PARAM_ADC_TYPE_INT_OPT(OPT) ((OPT == ADC_ADINTEN0)||(OPT == ADC_ADINTEN1)\\r
+||(OPT == ADC_ADINTEN2)||(OPT == ADC_ADINTEN3)\\r
+||(OPT == ADC_ADINTEN4)||(OPT == ADC_ADINTEN5)\\r
+||(OPT == ADC_ADINTEN6)||(OPT == ADC_ADINTEN7)\\r
+||(OPT == ADC_ADGINTEN))\r
+\r
+#define PARAM_ADCx(n) (((uint32_t *)n)==((uint32_t *)LPC_ADC))\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+\r
+/* Public Functions ----------------------------------------------------------- */\r
+/** @defgroup ADC_Public_Functions\r
+ * @{\r
+ */\r
+\r
+void ADC_Init(LPC_ADC_TypeDef *ADCx, uint32_t ConvFreq);\r
+void ADC_DeInit(LPC_ADC_TypeDef *ADCx);\r
+void ADC_BurstCmd(LPC_ADC_TypeDef *ADCx, FunctionalState NewState);\r
+void ADC_PowerdownCmd(LPC_ADC_TypeDef *ADCx, FunctionalState NewState);\r
+void ADC_StartCmd(LPC_ADC_TypeDef *ADCx, uint8_t start_mode);\r
+void ADC_EdgeStartConfig(LPC_ADC_TypeDef *ADCx, uint8_t EdgeOption);\r
+void ADC_IntConfig (LPC_ADC_TypeDef *ADCx, ADC_TYPE_INT_OPT IntType, FunctionalState NewState);\r
+void ADC_ChannelCmd (LPC_ADC_TypeDef *ADCx, uint8_t Channel, FunctionalState NewState);\r
+uint16_t ADC_ChannelGetData(LPC_ADC_TypeDef *ADCx, uint8_t channel);\r
+FlagStatus ADC_ChannelGetStatus(LPC_ADC_TypeDef *ADCx, uint8_t channel, uint32_t StatusType);\r
+uint16_t ADC_GlobalGetData(LPC_ADC_TypeDef *ADCx, uint8_t channel);\r
+FlagStatus ADC_GlobalGetStatus(LPC_ADC_TypeDef *ADCx, uint32_t StatusType);\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+\r
+#endif /* LPC17XX_ADC_H_ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* --------------------------------- End Of File ------------------------------ */\r
--- /dev/null
+/**\r
+ * @file : lpc17xx_clkpwr.c\r
+ * @brief : Contains all functions support for Clock and Power Control\r
+ * firmware library on LPC17xx\r
+ * @version : 1.0\r
+ * @date : 18. Mar. 2009\r
+ * @author : HieuNguyen\r
+ **************************************************************************\r
+ * Software that is described herein is for illustrative purposes only\r
+ * which provides customers with programming information regarding the\r
+ * products. This software is supplied "AS IS" without any warranties.\r
+ * NXP Semiconductors assumes no responsibility or liability for the\r
+ * use of the software, conveys no license or title under any patent,\r
+ * copyright, or mask work right to the product. NXP Semiconductors\r
+ * reserves the right to make changes in the software without\r
+ * notification. NXP Semiconductors also make no representation or\r
+ * warranty that such application will be suitable for the specified\r
+ * use without further testing or modification.\r
+ **********************************************************************/\r
+\r
+/* Peripheral group ----------------------------------------------------------- */\r
+/** @addtogroup CLKPWR\r
+ * @{\r
+ */\r
+\r
+/* Includes ------------------------------------------------------------------- */\r
+#include "lpc17xx_clkpwr.h"\r
+\r
+\r
+/* Public Functions ----------------------------------------------------------- */\r
+/** @addtogroup CLKPWR_Public_Functions\r
+ * @{\r
+ */\r
+\r
+/*********************************************************************//**\r
+ * @brief Set value of each Peripheral Clock Selection\r
+ * @param[in] ClkType Peripheral Clock Selection of each type,\r
+ * should be one of the following:\r
+ * - CLKPWR_PCLKSEL_WDT : WDT\r
+ - CLKPWR_PCLKSEL_TIMER0 : Timer 0\r
+ - CLKPWR_PCLKSEL_TIMER1 : Timer 1\r
+ - CLKPWR_PCLKSEL_UART0 : UART 0\r
+ - CLKPWR_PCLKSEL_UART1 : UART 1\r
+ - CLKPWR_PCLKSEL_PWM1 : PWM 1\r
+ - CLKPWR_PCLKSEL_I2C0 : I2C 0\r
+ - CLKPWR_PCLKSEL_SPI : SPI\r
+ - CLKPWR_PCLKSEL_SSP1 : SSP 1\r
+ - CLKPWR_PCLKSEL_DAC : DAC\r
+ - CLKPWR_PCLKSEL_ADC : ADC\r
+ - CLKPWR_PCLKSEL_CAN1 : CAN 1\r
+ - CLKPWR_PCLKSEL_CAN2 : CAN 2\r
+ - CLKPWR_PCLKSEL_ACF : ACF\r
+ - CLKPWR_PCLKSEL_QEI : QEI\r
+ - CLKPWR_PCLKSEL_PCB : PCB\r
+ - CLKPWR_PCLKSEL_I2C1 : I2C 1\r
+ - CLKPWR_PCLKSEL_SSP0 : SSP 0\r
+ - CLKPWR_PCLKSEL_TIMER2 : Timer 2\r
+ - CLKPWR_PCLKSEL_TIMER3 : Timer 3\r
+ - CLKPWR_PCLKSEL_UART2 : UART 2\r
+ - CLKPWR_PCLKSEL_UART3 : UART 3\r
+ - CLKPWR_PCLKSEL_I2C2 : I2C 2\r
+ - CLKPWR_PCLKSEL_I2S : I2S\r
+ - CLKPWR_PCLKSEL_RIT : RIT\r
+ - CLKPWR_PCLKSEL_SYSCON : SYSCON\r
+ - CLKPWR_PCLKSEL_MC : MC\r
+\r
+ * @param[in] DivVal Value of divider, should be:\r
+ * - CLKPWR_PCLKSEL_CCLK_DIV_4 : PCLK_peripheral = CCLK/4\r
+ * - CLKPWR_PCLKSEL_CCLK_DIV_1 : PCLK_peripheral = CCLK/1\r
+ * - CLKPWR_PCLKSEL_CCLK_DIV_2 : PCLK_peripheral = CCLK/2\r
+ *\r
+ * @return none\r
+ **********************************************************************/\r
+void CLKPWR_SetPCLKDiv (uint32_t ClkType, uint32_t DivVal)\r
+{\r
+ uint32_t bitpos;\r
+\r
+ bitpos = (ClkType < 32) ? (ClkType) : (ClkType - 32);\r
+\r
+ /* PCLKSEL0 selected */\r
+ if (ClkType < 32)\r
+ {\r
+ /* Clear two bit at bit position */\r
+ LPC_SC->PCLKSEL0 &= (~(CLKPWR_PCLKSEL_BITMASK(bitpos)));\r
+\r
+ /* Set two selected bit */\r
+ LPC_SC->PCLKSEL0 |= (CLKPWR_PCLKSEL_SET(bitpos, DivVal));\r
+ }\r
+ /* PCLKSEL1 selected */\r
+ else\r
+ {\r
+ /* Clear two bit at bit position */\r
+ LPC_SC->PCLKSEL1 &= ~(CLKPWR_PCLKSEL_BITMASK(bitpos));\r
+\r
+ /* Set two selected bit */\r
+ LPC_SC->PCLKSEL1 |= (CLKPWR_PCLKSEL_SET(bitpos, DivVal));\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Get current value of each Peripheral Clock Selection\r
+ * @param[in] ClkType Peripheral Clock Selection of each type,\r
+ * should be one of the following:\r
+ * - CLKPWR_PCLKSEL_WDT : WDT\r
+ - CLKPWR_PCLKSEL_TIMER0 : Timer 0\r
+ - CLKPWR_PCLKSEL_TIMER1 : Timer 1\r
+ - CLKPWR_PCLKSEL_UART0 : UART 0\r
+ - CLKPWR_PCLKSEL_UART1 : UART 1\r
+ - CLKPWR_PCLKSEL_PWM1 : PWM 1\r
+ - CLKPWR_PCLKSEL_I2C0 : I2C 0\r
+ - CLKPWR_PCLKSEL_SPI : SPI\r
+ - CLKPWR_PCLKSEL_SSP1 : SSP 1\r
+ - CLKPWR_PCLKSEL_DAC : DAC\r
+ - CLKPWR_PCLKSEL_ADC : ADC\r
+ - CLKPWR_PCLKSEL_CAN1 : CAN 1\r
+ - CLKPWR_PCLKSEL_CAN2 : CAN 2\r
+ - CLKPWR_PCLKSEL_ACF : ACF\r
+ - CLKPWR_PCLKSEL_QEI : QEI\r
+ - CLKPWR_PCLKSEL_PCB : PCB\r
+ - CLKPWR_PCLKSEL_I2C1 : I2C 1\r
+ - CLKPWR_PCLKSEL_SSP0 : SSP 0\r
+ - CLKPWR_PCLKSEL_TIMER2 : Timer 2\r
+ - CLKPWR_PCLKSEL_TIMER3 : Timer 3\r
+ - CLKPWR_PCLKSEL_UART2 : UART 2\r
+ - CLKPWR_PCLKSEL_UART3 : UART 3\r
+ - CLKPWR_PCLKSEL_I2C2 : I2C 2\r
+ - CLKPWR_PCLKSEL_I2S : I2S\r
+ - CLKPWR_PCLKSEL_RIT : RIT\r
+ - CLKPWR_PCLKSEL_SYSCON : SYSCON\r
+ - CLKPWR_PCLKSEL_MC : MC\r
+\r
+ * @return Value of Selected Peripheral Clock Selection\r
+ **********************************************************************/\r
+uint32_t CLKPWR_GetPCLKSEL (uint32_t ClkType)\r
+{\r
+ uint32_t bitpos, retval;\r
+\r
+ if (ClkType < 32)\r
+ {\r
+ bitpos = ClkType;\r
+ retval = LPC_SC->PCLKSEL0;\r
+ }\r
+ else\r
+ {\r
+ bitpos = ClkType - 32;\r
+ retval = LPC_SC->PCLKSEL1;\r
+ }\r
+\r
+ retval = CLKPWR_PCLKSEL_GET(bitpos, retval);\r
+ return retval;\r
+}\r
+\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Get current value of each Peripheral Clock\r
+ * @param[in] ClkType Peripheral Clock Selection of each type,\r
+ * should be one of the following:\r
+ * - CLKPWR_PCLKSEL_WDT : WDT\r
+ - CLKPWR_PCLKSEL_TIMER0 : Timer 0\r
+ - CLKPWR_PCLKSEL_TIMER1 : Timer 1\r
+ - CLKPWR_PCLKSEL_UART0 : UART 0\r
+ - CLKPWR_PCLKSEL_UART1 : UART 1\r
+ - CLKPWR_PCLKSEL_PWM1 : PWM 1\r
+ - CLKPWR_PCLKSEL_I2C0 : I2C 0\r
+ - CLKPWR_PCLKSEL_SPI : SPI\r
+ - CLKPWR_PCLKSEL_SSP1 : SSP 1\r
+ - CLKPWR_PCLKSEL_DAC : DAC\r
+ - CLKPWR_PCLKSEL_ADC : ADC\r
+ - CLKPWR_PCLKSEL_CAN1 : CAN 1\r
+ - CLKPWR_PCLKSEL_CAN2 : CAN 2\r
+ - CLKPWR_PCLKSEL_ACF : ACF\r
+ - CLKPWR_PCLKSEL_QEI : QEI\r
+ - CLKPWR_PCLKSEL_PCB : PCB\r
+ - CLKPWR_PCLKSEL_I2C1 : I2C 1\r
+ - CLKPWR_PCLKSEL_SSP0 : SSP 0\r
+ - CLKPWR_PCLKSEL_TIMER2 : Timer 2\r
+ - CLKPWR_PCLKSEL_TIMER3 : Timer 3\r
+ - CLKPWR_PCLKSEL_UART2 : UART 2\r
+ - CLKPWR_PCLKSEL_UART3 : UART 3\r
+ - CLKPWR_PCLKSEL_I2C2 : I2C 2\r
+ - CLKPWR_PCLKSEL_I2S : I2S\r
+ - CLKPWR_PCLKSEL_RIT : RIT\r
+ - CLKPWR_PCLKSEL_SYSCON : SYSCON\r
+ - CLKPWR_PCLKSEL_MC : MC\r
+\r
+ * @return Value of Selected Peripheral Clock\r
+ **********************************************************************/\r
+uint32_t CLKPWR_GetPCLK (uint32_t ClkType)\r
+{\r
+ uint32_t retval, div;\r
+\r
+ retval = SystemCoreClock;\r
+ div = CLKPWR_GetPCLKSEL(ClkType);\r
+\r
+ switch (div)\r
+ {\r
+ case 0:\r
+ div = 4;\r
+ break;\r
+\r
+ case 1:\r
+ div = 1;\r
+ break;\r
+\r
+ case 2:\r
+ div = 2;\r
+ break;\r
+\r
+ case 3:\r
+ div = 8;\r
+ break;\r
+ }\r
+ retval /= div;\r
+\r
+ return retval;\r
+}\r
+\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Configure power supply for each peripheral according to NewState\r
+ * @param[in] PPType Type of peripheral used to enable power,\r
+ * should be one of the following:\r
+ * - CLKPWR_PCONP_PCTIM0 : Timer 0\r
+ - CLKPWR_PCONP_PCTIM1 : Timer 1\r
+ - CLKPWR_PCONP_PCUART0 : UART 0\r
+ - CLKPWR_PCONP_PCUART1 : UART 1\r
+ - CLKPWR_PCONP_PCPWM1 : PWM 1\r
+ - CLKPWR_PCONP_PCI2C0 : I2C 0\r
+ - CLKPWR_PCONP_PCSPI : SPI\r
+ - CLKPWR_PCONP_PCRTC : RTC\r
+ - CLKPWR_PCONP_PCSSP1 : SSP 1\r
+ - CLKPWR_PCONP_PCAD : ADC\r
+ - CLKPWR_PCONP_PCAN1 : CAN 1\r
+ - CLKPWR_PCONP_PCAN2 : CAN 2\r
+ - CLKPWR_PCONP_PCGPIO : GPIO\r
+ - CLKPWR_PCONP_PCRIT : RIT\r
+ - CLKPWR_PCONP_PCMC : MC\r
+ - CLKPWR_PCONP_PCQEI : QEI\r
+ - CLKPWR_PCONP_PCI2C1 : I2C 1\r
+ - CLKPWR_PCONP_PCSSP0 : SSP 0\r
+ - CLKPWR_PCONP_PCTIM2 : Timer 2\r
+ - CLKPWR_PCONP_PCTIM3 : Timer 3\r
+ - CLKPWR_PCONP_PCUART2 : UART 2\r
+ - CLKPWR_PCONP_PCUART3 : UART 3\r
+ - CLKPWR_PCONP_PCI2C2 : I2C 2\r
+ - CLKPWR_PCONP_PCI2S : I2S\r
+ - CLKPWR_PCONP_PCGPDMA : GPDMA\r
+ - CLKPWR_PCONP_PCENET : Ethernet\r
+ - CLKPWR_PCONP_PCUSB : USB\r
+ *\r
+ * @param[in] NewState New state of Peripheral Power, should be:\r
+ * - ENABLE : Enable power for this peripheral\r
+ * - DISABLE : Disable power for this peripheral\r
+ *\r
+ * @return none\r
+ **********************************************************************/\r
+void CLKPWR_ConfigPPWR (uint32_t PPType, FunctionalState NewState)\r
+{\r
+ if (NewState == ENABLE)\r
+ {\r
+ LPC_SC->PCONP |= PPType & CLKPWR_PCONP_BITMASK;\r
+ }\r
+ else if (NewState == DISABLE)\r
+ {\r
+ LPC_SC->PCONP &= (~PPType) & CLKPWR_PCONP_BITMASK;\r
+ }\r
+}\r
+\r
+\r
+/**\r
+ * @brief Enter Sleep mode with co-operated instruction by the Cortex-M3.\r
+ * @param[in] None\r
+ * @return None\r
+ */\r
+void CLKPWR_Sleep(void)\r
+{\r
+ LPC_SC->PCON = 0x00;\r
+ /* Sleep Mode*/\r
+ __WFI();\r
+}\r
+\r
+\r
+/**\r
+ * @brief Enter Deep Sleep mode with co-operated instruction by the Cortex-M3.\r
+ * @param[in] None\r
+ * @return None\r
+ */\r
+void CLKPWR_DeepSleep(void)\r
+{\r
+ /* Deep-Sleep Mode, set SLEEPDEEP bit */\r
+ SCB->SCR = 0x4;\r
+ LPC_SC->PCON = 0x00;\r
+ /* Sleep Mode*/\r
+ __WFI();\r
+}\r
+\r
+\r
+/**\r
+ * @brief Enter Power Down mode with co-operated instruction by the Cortex-M3.\r
+ * @param[in] None\r
+ * @return None\r
+ */\r
+void CLKPWR_PowerDown(void)\r
+{\r
+ /* Deep-Sleep Mode, set SLEEPDEEP bit */\r
+ SCB->SCR = 0x4;\r
+ LPC_SC->PCON = 0x01;\r
+ /* Sleep Mode*/\r
+ __WFI();\r
+}\r
+\r
+\r
+/**\r
+ * @brief Enter Deep Power Down mode with co-operated instruction by the Cortex-M3.\r
+ * @param[in] None\r
+ * @return None\r
+ */\r
+void CLKPWR_DeepPowerDown(void)\r
+{\r
+ /* Deep-Sleep Mode, set SLEEPDEEP bit */\r
+ SCB->SCR = 0x4;\r
+ LPC_SC->PCON = 0x03;\r
+ /* Sleep Mode*/\r
+ __WFI();\r
+}\r
+\r
+\r
+/**\r
+ * @brief Configure Brown-Out function in\r
+ */\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* --------------------------------- End Of File ------------------------------ */\r
--- /dev/null
+/***********************************************************************//**\r
+ * @file : lpc17xx_clkpwr.h\r
+ * @brief : Contains all macro definitions and function prototypes\r
+ * support for Clock and Power Control firmware library on LPC17xx\r
+ * @version : 1.0\r
+ * @date : 18. Mar. 2009\r
+ * @author : HieuNguyen\r
+ **************************************************************************\r
+ * Software that is described herein is for illustrative purposes only\r
+ * which provides customers with programming information regarding the\r
+ * products. This software is supplied "AS IS" without any warranties.\r
+ * NXP Semiconductors assumes no responsibility or liability for the\r
+ * use of the software, conveys no license or title under any patent,\r
+ * copyright, or mask work right to the product. NXP Semiconductors\r
+ * reserves the right to make changes in the software without\r
+ * notification. NXP Semiconductors also make no representation or\r
+ * warranty that such application will be suitable for the specified\r
+ * use without further testing or modification.\r
+ **************************************************************************/\r
+\r
+/* Peripheral group ----------------------------------------------------------- */\r
+/** @defgroup CLKPWR\r
+ * @ingroup LPC1700CMSIS_FwLib_Drivers\r
+ * @{\r
+ */\r
+\r
+#ifndef LPC17XX_CLKPWR_H_\r
+#define LPC17XX_CLKPWR_H_\r
+\r
+/* Includes ------------------------------------------------------------------- */\r
+#include "lpc17xx.h"\r
+#include "lpc_types.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif\r
+\r
+\r
+/* Private Macros ------------------------------------------------------------- */\r
+/** @defgroup CLKPWR_Private_Macros\r
+ * @{\r
+ */\r
+\r
+/** @defgroup CLKPPWR_REGISTER_BIT_DEFINITIONS\r
+ * @{\r
+ */\r
+\r
+/* Clock source selection multiplexer definition */\r
+/** Internal RC oscillator */\r
+#define CLKPWR_CLKSRCSEL_CLKSRC_IRC ((uint32_t)(0x00))\r
+/** Main oscillator */\r
+#define CLKPWR_CLKSRCSEL_CLKSRC_MAINOSC ((uint32_t)(0x01))\r
+/** RTC oscillator */\r
+#define CLKPWR_CLKSRCSEL_CLKSRC_RTC ((uint32_t)(0x02))\r
+/** Clock source selection bit mask */\r
+#define CLKPWR_CLKSRCSEL_BITMASK ((uint32_t)(0x03))\r
+\r
+\r
+/* Clock Output Configuration register definition */\r
+/** Selects the CPU clock as the CLKOUT source */\r
+#define CLKPWR_CLKOUTCFG_CLKOUTSEL_CPU ((uint32_t)(0x00))\r
+/** Selects the main oscillator as the CLKOUT source */\r
+#define CLKPWR_CLKOUTCFG_CLKOUTSEL_MAINOSC ((uint32_t)(0x01))\r
+/** Selects the Internal RC oscillator as the CLKOUT source */\r
+#define CLKPWR_CLKOUTCFG_CLKOUTSEL_RC ((uint32_t)(0x02))\r
+/** Selects the USB clock as the CLKOUT source */\r
+#define CLKPWR_CLKOUTCFG_CLKOUTSEL_USB ((uint32_t)(0x03))\r
+/** Selects the RTC oscillator as the CLKOUT source */\r
+#define CLKPWR_CLKOUTCFG_CLKOUTSEL_RTC ((uint32_t)(0x04))\r
+/** Integer value to divide the output clock by, minus one */\r
+#define CLKPWR_CLKOUTCFG_CLKOUTDIV(n) ((uint32_t)((n&0x0F)<<4))\r
+/** CLKOUT enable control */\r
+#define CLKPWR_CLKOUTCFG_CLKOUT_EN ((uint32_t)(1<<8))\r
+/** CLKOUT activity indication */\r
+#define CLKPWR_CLKOUTCFG_CLKOUT_ACT ((uint32_t)(1<<9))\r
+/** Clock source selection bit mask */\r
+#define CLKPWR_CLKOUTCFG_BITMASK ((uint32_t)(0x3FF))\r
+\r
+\r
+/* PLL 0 control definition */\r
+/** PLL 0 control enable */\r
+#define CLKPWR_PLL0CON_ENABLE ((uint32_t)(0x01))\r
+/** PLL 0 control connect */\r
+#define CLKPWR_PLL0CON_CONNECT ((uint32_t)(0x02))\r
+/** PLL 0 control bit mask */\r
+#define CLKPWR_PLL0CON_BITMASK ((uint32_t)(0x03))\r
+\r
+\r
+/* PLL 0 Configuration register definition */\r
+/** PLL 0 Configuration MSEL field */\r
+#define CLKPWR_PLL0CFG_MSEL(n) ((uint32_t)(n&0x7FFF))\r
+/** PLL 0 Configuration NSEL field */\r
+#define CLKPWR_PLL0CFG_NSEL(n) ((uint32_t)((n<<16)&0xFF0000))\r
+/** PLL 0 Configuration bit mask */\r
+#define CLKPWR_PLL0CFG_BITMASK ((uint32_t)(0xFF7FFF))\r
+\r
+\r
+/* PLL 0 status definition */\r
+/** PLL 0 MSEL value */\r
+#define CLKPWR_PLL0STAT_MSEL(n) ((uint32_t)(n&0x7FFF))\r
+/** PLL NSEL get value */\r
+#define CLKPWR_PLL0STAT_NSEL(n) ((uint32_t)((n>>16)&0xFF))\r
+/** PLL status enable bit */\r
+#define CLKPWR_PLL0STAT_PLLE ((uint32_t)(1<<24))\r
+/** PLL status Connect bit */\r
+#define CLKPWR_PLL0STAT_PLLC ((uint32_t)(1<<25))\r
+/** PLL status lock */\r
+#define CLKPWR_PLL0STAT_PLOCK ((uint32_t)(1<<26))\r
+\r
+\r
+/* PLL0 Feed register definition */\r
+/** PLL0 Feed bit mask */\r
+#define CLKPWR_PLL0FEED_BITMASK ((uint32_t)0xFF)\r
+\r
+\r
+/* USB PLL control definition */\r
+/** USB PLL control enable */\r
+#define CLKPWR_PLL1CON_ENABLE ((uint32_t)(0x01))\r
+/** USB PLL control connect */\r
+#define CLKPWR_PLL1CON_CONNECT ((uint32_t)(0x02))\r
+/** USB PLL control bit mask */\r
+#define CLKPWR_PLL1CON_BITMASK ((uint32_t)(0x03))\r
+\r
+\r
+/* USB PLL configuration definition */\r
+/** USB PLL MSEL set value */\r
+#define CLKPWR_PLL1CFG_MSEL(n) ((uint32_t)(n&0x1F))\r
+/** USB PLL PSEL set value */\r
+#define CLKPWR_PLL1CFG_PSEL(n) ((uint32_t)((n&0x03)<<5))\r
+/** USB PLL configuration bit mask */\r
+#define CLKPWR_PLL1CFG_BITMASK ((uint32_t)(0x7F))\r
+\r
+\r
+/* USB PLL status definition */\r
+/** USB PLL MSEL get value */\r
+#define CLKPWR_PLL1STAT_MSEL(n) ((uint32_t)(n&0x1F))\r
+/** USB PLL PSEL get value */\r
+#define CLKPWR_PLL1STAT_PSEL(n) ((uint32_t)((n>>5)&0x03))\r
+/** USB PLL status enable bit */\r
+#define CLKPWR_PLL1STAT_PLLE ((uint32_t)(1<<8))\r
+/** USB PLL status Connect bit */\r
+#define CLKPWR_PLL1STAT_PLLC ((uint32_t)(1<<9))\r
+/** USB PLL status lock */\r
+#define CLKPWR_PLL1STAT_PLOCK ((uint32_t)(1<<10))\r
+\r
+\r
+/* PLL1 Feed register definition */\r
+/** PLL1 Feed bit mask */\r
+#define CLKPWR_PLL1FEED_BITMASK ((uint32_t)0xFF)\r
+\r
+\r
+/* CPU Clock Configuration register definition */\r
+/** CPU Clock configuration bit mask */\r
+#define CLKPWR_CCLKCFG_BITMASK ((uint32_t)(0xFF))\r
+\r
+/* USB Clock Configuration register definition */\r
+/** USB Clock Configuration bit mask */\r
+#define CLKPWR_USBCLKCFG_BITMASK ((uint32_t)(0x0F))\r
+\r
+/* IRC Trim register definition */\r
+/** IRC Trim bit mask */\r
+#define CLKPWR_IRCTRIM_BITMASK ((uint32_t)(0x0F))\r
+\r
+\r
+/* Peripheral clock divider bit position definition */\r
+/** Peripheral Clock Selection 0 mask bit */\r
+#define CLKPWR_PCLKSEL0_BITMASK ((uint32_t)(0xFFF3F3FF))\r
+/** Peripheral Clock Selection 1 mask bit */\r
+#define CLKPWR_PCLKSEL1_BITMASK ((uint32_t)(0xFCF3F0F3))\r
+\r
+\r
+/** Macro to set peripheral clock of each type\r
+ * p: position of two bits that hold divider of peripheral clock\r
+ * n: value of divider of peripheral clock to be set */\r
+#define CLKPWR_PCLKSEL_SET(p,n) _SBF(p,n)\r
+/** Macro to mask peripheral clock of each type */\r
+#define CLKPWR_PCLKSEL_BITMASK(p) _SBF(p,0x03)\r
+/** Macro to get peripheral clock of each type */\r
+#define CLKPWR_PCLKSEL_GET(p, n) ((uint32_t)((n>>p)&0x03))\r
+\r
+\r
+/* Power Mode Control register definition */\r
+/** Power mode control bit 0 */\r
+#define CLKPWR_PCON_PM0 ((uint32_t)(1<<0))\r
+/** Power mode control bit 1 */\r
+#define CLKPWR_PCON_PM1 ((uint32_t)(1<<1))\r
+/** Brown-Out Reduced Power Mode */\r
+#define CLKPWR_PCON_BODPDM ((uint32_t)(1<<2))\r
+/** Brown-Out Global Disable */\r
+#define CLKPWR_PCON_BOGD ((uint32_t)(1<<3))\r
+/** Brown Out Reset Disable */\r
+#define CLKPWR_PCON_BORD ((uint32_t)(1<<4))\r
+/** Sleep Mode entry flag */\r
+#define CLKPWR_PCON_SMFLAG ((uint32_t)(1<<8))\r
+/** Deep Sleep entry flag */\r
+#define CLKPWR_PCON_DSFLAG ((uint32_t)(1<<9))\r
+/** Power-down entry flag */\r
+#define CLKPWR_PCON_PDFLAG ((uint32_t)(1<<10))\r
+/** Deep Power-down entry flag */\r
+#define CLKPWR_PCON_DPDFLAG ((uint32_t)(1<<11))\r
+\r
+\r
+/** Power Control for Peripherals bit mask */\r
+#define CLKPWR_PCONP_BITMASK 0xEFEFF7DE\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Macros -------------------------------------------------------------- */\r
+/** @defgroup CLKPWR_Public_Macros\r
+ * @{\r
+ */\r
+\r
+/**********************************************************************\r
+ * Peripheral Clock Selection Definitions\r
+ **********************************************************************/\r
+/** Peripheral clock divider bit position for WDT */\r
+#define CLKPWR_PCLKSEL_WDT ((uint32_t)(0))\r
+/** Peripheral clock divider bit position for TIMER0 */\r
+#define CLKPWR_PCLKSEL_TIMER0 ((uint32_t)(2))\r
+/** Peripheral clock divider bit position for TIMER1 */\r
+#define CLKPWR_PCLKSEL_TIMER1 ((uint32_t)(4))\r
+/** Peripheral clock divider bit position for UART0 */\r
+#define CLKPWR_PCLKSEL_UART0 ((uint32_t)(6))\r
+/** Peripheral clock divider bit position for UART1 */\r
+#define CLKPWR_PCLKSEL_UART1 ((uint32_t)(8))\r
+/** Peripheral clock divider bit position for PWM1 */\r
+#define CLKPWR_PCLKSEL_PWM1 ((uint32_t)(12))\r
+/** Peripheral clock divider bit position for I2C0 */\r
+#define CLKPWR_PCLKSEL_I2C0 ((uint32_t)(14))\r
+/** Peripheral clock divider bit position for SPI */\r
+#define CLKPWR_PCLKSEL_SPI ((uint32_t)(16))\r
+/** Peripheral clock divider bit position for SSP1 */\r
+#define CLKPWR_PCLKSEL_SSP1 ((uint32_t)(20))\r
+/** Peripheral clock divider bit position for DAC */\r
+#define CLKPWR_PCLKSEL_DAC ((uint32_t)(22))\r
+/** Peripheral clock divider bit position for ADC */\r
+#define CLKPWR_PCLKSEL_ADC ((uint32_t)(24))\r
+/** Peripheral clock divider bit position for CAN1 */\r
+#define CLKPWR_PCLKSEL_CAN1 ((uint32_t)(26))\r
+/** Peripheral clock divider bit position for CAN2 */\r
+#define CLKPWR_PCLKSEL_CAN2 ((uint32_t)(28))\r
+/** Peripheral clock divider bit position for ACF */\r
+#define CLKPWR_PCLKSEL_ACF ((uint32_t)(30))\r
+/** Peripheral clock divider bit position for QEI */\r
+#define CLKPWR_PCLKSEL_QEI ((uint32_t)(32))\r
+/** Peripheral clock divider bit position for PCB */\r
+#define CLKPWR_PCLKSEL_PCB ((uint32_t)(36))\r
+/** Peripheral clock divider bit position for I2C1 */\r
+#define CLKPWR_PCLKSEL_I2C1 ((uint32_t)(38))\r
+/** Peripheral clock divider bit position for SSP0 */\r
+#define CLKPWR_PCLKSEL_SSP0 ((uint32_t)(42))\r
+/** Peripheral clock divider bit position for TIMER2 */\r
+#define CLKPWR_PCLKSEL_TIMER2 ((uint32_t)(44))\r
+/** Peripheral clock divider bit position for TIMER3 */\r
+#define CLKPWR_PCLKSEL_TIMER3 ((uint32_t)(46))\r
+/** Peripheral clock divider bit position for UART2 */\r
+#define CLKPWR_PCLKSEL_UART2 ((uint32_t)(48))\r
+/** Peripheral clock divider bit position for UART3 */\r
+#define CLKPWR_PCLKSEL_UART3 ((uint32_t)(50))\r
+/** Peripheral clock divider bit position for I2C2 */\r
+#define CLKPWR_PCLKSEL_I2C2 ((uint32_t)(52))\r
+/** Peripheral clock divider bit position for I2S */\r
+#define CLKPWR_PCLKSEL_I2S ((uint32_t)(54))\r
+/** Peripheral clock divider bit position for RIT */\r
+#define CLKPWR_PCLKSEL_RIT ((uint32_t)(58))\r
+/** Peripheral clock divider bit position for SYSCON */\r
+#define CLKPWR_PCLKSEL_SYSCON ((uint32_t)(60))\r
+/** Peripheral clock divider bit position for MC */\r
+#define CLKPWR_PCLKSEL_MC ((uint32_t)(62))\r
+\r
+/** Macro for Peripheral Clock Selection register bit values\r
+ * Note: When CCLK_DIV_8, Peripheral\92s clock is selected to\r
+ * PCLK_xyz = CCLK/8 except for CAN1, CAN2, and CAN filtering\r
+ * when \9211\92selects PCLK_xyz = CCLK/6 */\r
+/* Peripheral clock divider is set to 4 from CCLK */\r
+#define CLKPWR_PCLKSEL_CCLK_DIV_4 ((uint32_t)(0))\r
+/** Peripheral clock divider is the same with CCLK */\r
+#define CLKPWR_PCLKSEL_CCLK_DIV_1 ((uint32_t)(1))\r
+/** Peripheral clock divider is set to 2 from CCLK */\r
+#define CLKPWR_PCLKSEL_CCLK_DIV_2 ((uint32_t)(2))\r
+\r
+\r
+/********************************************************************\r
+* Power Control for Peripherals Definitions\r
+**********************************************************************/\r
+/** Timer/Counter 0 power/clock control bit */\r
+#define CLKPWR_PCONP_PCTIM0 ((uint32_t)(1<<1))\r
+/* Timer/Counter 1 power/clock control bit */\r
+#define CLKPWR_PCONP_PCTIM1 ((uint32_t)(1<<2))\r
+/** UART0 power/clock control bit */\r
+#define CLKPWR_PCONP_PCUART0 ((uint32_t)(1<<3))\r
+/** UART1 power/clock control bit */\r
+#define CLKPWR_PCONP_PCUART1 ((uint32_t)(1<<4))\r
+/** PWM1 power/clock control bit */\r
+#define CLKPWR_PCONP_PCPWM1 ((uint32_t)(1<<6))\r
+/** The I2C0 interface power/clock control bit */\r
+#define CLKPWR_PCONP_PCI2C0 ((uint32_t)(1<<7))\r
+/** The SPI interface power/clock control bit */\r
+#define CLKPWR_PCONP_PCSPI ((uint32_t)(1<<8))\r
+/** The RTC power/clock control bit */\r
+#define CLKPWR_PCONP_PCRTC ((uint32_t)(1<<9))\r
+/** The SSP1 interface power/clock control bit */\r
+#define CLKPWR_PCONP_PCSSP1 ((uint32_t)(1<<10))\r
+/** A/D converter 0 (ADC0) power/clock control bit */\r
+#define CLKPWR_PCONP_PCAD ((uint32_t)(1<<12))\r
+/** CAN Controller 1 power/clock control bit */\r
+#define CLKPWR_PCONP_PCAN1 ((uint32_t)(1<<13))\r
+/** CAN Controller 2 power/clock control bit */\r
+#define CLKPWR_PCONP_PCAN2 ((uint32_t)(1<<14))\r
+/** GPIO power/clock control bit */\r
+#define CLKPWR_PCONP_PCGPIO ((uint32_t)(1<<15))\r
+/** Repetitive Interrupt Timer power/clock control bit */\r
+#define CLKPWR_PCONP_PCRIT ((uint32_t)(1<<16))\r
+/** Motor Control PWM */\r
+#define CLKPWR_PCONP_PCMC ((uint32_t)(1<<17))\r
+/** Quadrature Encoder Interface power/clock control bit */\r
+#define CLKPWR_PCONP_PCQEI ((uint32_t)(1<<18))\r
+/** The I2C1 interface power/clock control bit */\r
+#define CLKPWR_PCONP_PCI2C1 ((uint32_t)(1<<19))\r
+/** The SSP0 interface power/clock control bit */\r
+#define CLKPWR_PCONP_PCSSP0 ((uint32_t)(1<<21))\r
+/** Timer 2 power/clock control bit */\r
+#define CLKPWR_PCONP_PCTIM2 ((uint32_t)(1<<22))\r
+/** Timer 3 power/clock control bit */\r
+#define CLKPWR_PCONP_PCTIM3 ((uint32_t)(1<<23))\r
+/** UART 2 power/clock control bit */\r
+#define CLKPWR_PCONP_PCUART2 ((uint32_t)(1<<24))\r
+/** UART 3 power/clock control bit */\r
+#define CLKPWR_PCONP_PCUART3 ((uint32_t)(1<<25))\r
+/** I2C interface 2 power/clock control bit */\r
+#define CLKPWR_PCONP_PCI2C2 ((uint32_t)(1<<26))\r
+/** I2S interface power/clock control bit*/\r
+#define CLKPWR_PCONP_PCI2S ((uint32_t)(1<<27))\r
+/** GP DMA function power/clock control bit*/\r
+#define CLKPWR_PCONP_PCGPDMA ((uint32_t)(1<<29))\r
+/** Ethernet block power/clock control bit*/\r
+#define CLKPWR_PCONP_PCENET ((uint32_t)(1<<30))\r
+/** USB interface power/clock control bit*/\r
+#define CLKPWR_PCONP_PCUSB ((uint32_t)(1<<31))\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Functions ----------------------------------------------------------- */\r
+/** @defgroup CLKPWR_Public_Functions\r
+ * @{\r
+ */\r
+\r
+void CLKPWR_SetPCLKDiv (uint32_t ClkType, uint32_t DivVal);\r
+uint32_t CLKPWR_GetPCLKSEL (uint32_t ClkType);\r
+uint32_t CLKPWR_GetPCLK (uint32_t ClkType);\r
+void CLKPWR_ConfigPPWR (uint32_t PPType, FunctionalState NewState);\r
+void CLKPWR_Sleep(void);\r
+void CLKPWR_DeepSleep(void);\r
+void CLKPWR_PowerDown(void);\r
+void CLKPWR_DeepPowerDown(void);\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* LPC17XX_CLKPWR_H_ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* --------------------------------- End Of File ------------------------------ */\r
--- /dev/null
+/***********************************************************************//**\r
+ * @file : lpc17xx_libcfg.h\r
+ * @purpose : Library configuration file\r
+ * @version : 1.0\r
+ * @date : 26. Mar. 2009\r
+ * @author : HieuNguyen\r
+ **************************************************************************\r
+ * Software that is described herein is for illustrative purposes only\r
+ * which provides customers with programming information regarding the\r
+ * products. This software is supplied "AS IS" without any warranties.\r
+ * NXP Semiconductors assumes no responsibility or liability for the\r
+ * use of the software, conveys no license or title under any patent,\r
+ * copyright, or mask work right to the product. NXP Semiconductors\r
+ * reserves the right to make changes in the software without\r
+ * notification. NXP Semiconductors also make no representation or\r
+ * warranty that such application will be suitable for the specified\r
+ * use without further testing or modification.\r
+ **************************************************************************/\r
+\r
+#ifndef LPC17XX_LIBCFG_H_\r
+#define LPC17XX_LIBCFG_H_\r
+\r
+#include "lpc_types.h"\r
+\r
+\r
+/************************** DEBUG MODE DEFINITIONS *********************************/\r
+/* Un-comment the line below to compile the library in DEBUG mode, this will expanse\r
+ the "CHECK_PARAM" macro in the FW library code */\r
+\r
+#define DEBUG 1\r
+\r
+/******************* PERIPHERAL FW LIBRARY CONFIGURATION DEFINITIONS ***********************/\r
+\r
+/* Comment the line below to disable the specific peripheral inclusion */\r
+\r
+/* UART ------------------------------- */\r
+#define _UART 1\r
+#define _UART0 1\r
+//#define _UART1 1\r
+//#define _UART2 1\r
+//#define _UART3 1\r
+\r
+\r
+/* SPI ------------------------------- */\r
+//#define _SPI\r
+\r
+\r
+/* I2C ------------------------------- */\r
+#define _I2C 1\r
+#define _I2C0 1\r
+#define _I2C1 1\r
+#define _I2C2 1\r
+\r
+\r
+/************************** GLOBAL/PUBLIC MACRO DEFINITIONS *********************************/\r
+\r
+#ifdef DEBUG\r
+/*******************************************************************************\r
+* @brief The CHECK_PARAM macro is used for function's parameters check.\r
+* It is used only if the library is compiled in DEBUG mode.\r
+* @param[in] expr - If expr is false, it calls check_failed() function\r
+* which reports the name of the source file and the source\r
+* line number of the call that failed.\r
+* - If expr is true, it returns no value.\r
+* @return None\r
+*******************************************************************************/\r
+#define CHECK_PARAM(expr) ((expr) ? (void)0 : check_failed((uint8_t *)__FILE__, __LINE__))\r
+#else\r
+#define CHECK_PARAM(expr)\r
+#endif /* DEBUG */\r
+\r
+\r
+\r
+/************************** GLOBAL/PUBLIC FUNCTION DECLARATION *********************************/\r
+\r
+#ifdef DEBUG\r
+void check_failed(uint8_t *file, uint32_t line);\r
+#endif\r
+\r
+\r
+#endif /* LPC17XX_LIBCFG_H_ */\r
--- /dev/null
+/***********************************************************************//**\r
+ * @file : lpc17xx_libcfg_default.c\r
+ * @brief : Library configuration source file (default),\r
+ * used to build library without examples.\r
+ * @version : 1.0\r
+ * @date : 26. Mar. 2009\r
+ * @author : HieuNguyen\r
+ **************************************************************************\r
+ * Software that is described herein is for illustrative purposes only\r
+ * which provides customers with programming information regarding the\r
+ * products. This software is supplied "AS IS" without any warranties.\r
+ * NXP Semiconductors assumes no responsibility or liability for the\r
+ * use of the software, conveys no license or title under any patent,\r
+ * copyright, or mask work right to the product. NXP Semiconductors\r
+ * reserves the right to make changes in the software without\r
+ * notification. NXP Semiconductors also make no representation or\r
+ * warranty that such application will be suitable for the specified\r
+ * use without further testing or modification.\r
+ **************************************************************************/\r
+\r
+/* Library group ----------------------------------------------------------- */\r
+/** @addtogroup LIBCFG_DEFAULT\r
+ * @{\r
+ */\r
+\r
+/* Includes ------------------------------------------------------------------- */\r
+#include "lpc17xx_libcfg_default.h"\r
+\r
+/* Public Functions ----------------------------------------------------------- */\r
+/** @addtogroup LIBCFG_DEFAULT_Public_Functions\r
+ * @{\r
+ */\r
+\r
+#ifndef __BUILD_WITH_EXAMPLE__\r
+\r
+#ifdef DEBUG\r
+/*******************************************************************************\r
+* @brief Reports the name of the source file and the source line number\r
+* where the CHECK_PARAM error has occurred.\r
+* @param[in] file Pointer to the source file name\r
+* @param[in] line assert_param error line source number\r
+* @return None\r
+*******************************************************************************/\r
+void check_failed(uint8_t *file, uint32_t line)\r
+{\r
+ /* User can add his own implementation to report the file name and line number,\r
+ ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */\r
+\r
+ /* Infinite loop */\r
+ while(1);\r
+}\r
+#endif /* DEBUG */\r
+\r
+#endif /* __BUILD_WITH_EXAMPLE__ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* --------------------------------- End Of File ------------------------------ */\r
--- /dev/null
+/***********************************************************************//**\r
+ * @file : lpc17xx_libcfg_default.h\r
+ * @brief : Default Library configuration header file\r
+ * @version : 1.0\r
+ * @date : 26. Mar. 2009\r
+ * @author : HieuNguyen\r
+ **************************************************************************\r
+ * Software that is described herein is for illustrative purposes only\r
+ * which provides customers with programming information regarding the\r
+ * products. This software is supplied "AS IS" without any warranties.\r
+ * NXP Semiconductors assumes no responsibility or liability for the\r
+ * use of the software, conveys no license or title under any patent,\r
+ * copyright, or mask work right to the product. NXP Semiconductors\r
+ * reserves the right to make changes in the software without\r
+ * notification. NXP Semiconductors also make no representation or\r
+ * warranty that such application will be suitable for the specified\r
+ * use without further testing or modification.\r
+ **************************************************************************/\r
+\r
+/* Library Configuration group ----------------------------------------------------------- */\r
+/** @defgroup LIBCFG_DEFAULT\r
+ * @ingroup LPC1700CMSIS_FwLib_Drivers\r
+ * @{\r
+ */\r
+\r
+#ifndef LPC17XX_LIBCFG_DEFAULT_H_\r
+#define LPC17XX_LIBCFG_DEFAULT_H_\r
+\r
+/* Includes ------------------------------------------------------------------- */\r
+#include "lpc_types.h"\r
+\r
+\r
+/* Public Macros -------------------------------------------------------------- */\r
+/** @defgroup LIBCFG_DEFAULT_Public_Macros\r
+ * @{\r
+ */\r
+\r
+/************************** DEBUG MODE DEFINITIONS *********************************/\r
+/* Un-comment the line below to compile the library in DEBUG mode, this will expanse\r
+ the "CHECK_PARAM" macro in the FW library code */\r
+\r
+#define DEBUG 1\r
+\r
+\r
+/******************* PERIPHERAL FW LIBRARY CONFIGURATION DEFINITIONS ***********************/\r
+\r
+/* Comment the line below to disable the specific peripheral inclusion */\r
+\r
+/* GPIO ------------------------------- */\r
+#define _GPIO 1\r
+\r
+/* UART ------------------------------- */\r
+#define _UART 1\r
+#define _UART0 1\r
+#define _UART1 1\r
+#define _UART2 1\r
+#define _UART3 1\r
+\r
+/* SPI ------------------------------- */\r
+#define _SPI 1\r
+\r
+/* SSP ------------------------------- */\r
+#define _SSP 1\r
+#define _SSP0 1\r
+#define _SSP1 1\r
+\r
+\r
+/* I2C ------------------------------- */\r
+#define _I2C 1\r
+#define _I2C0 1\r
+#define _I2C1 1\r
+#define _I2C2 1\r
+\r
+/* TIMER ------------------------------- */\r
+#define _TIM 1\r
+\r
+/* WDT ------------------------------- */\r
+#define _WDT 1\r
+\r
+\r
+/* GPDMA ------------------------------- */\r
+#define _GPDMA 1\r
+\r
+\r
+/* DAC ------------------------------- */\r
+#define _DAC 1\r
+\r
+/* DAC ------------------------------- */\r
+#define _ADC 1\r
+\r
+\r
+/* PWM ------------------------------- */\r
+#define _PWM 1\r
+#define _PWM1 1\r
+\r
+/* RTC ------------------------------- */\r
+#define _RTC 1\r
+\r
+/* I2S ------------------------------- */\r
+#define _I2S 1\r
+\r
+/* USB device ------------------------------- */\r
+#define _USBDEV 1\r
+#define _USB_DMA 1\r
+\r
+/* QEI ------------------------------- */\r
+#define _QEI 1\r
+\r
+/* MCPWM ------------------------------- */\r
+#define _MCPWM 1\r
+\r
+/* CAN--------------------------------*/\r
+#define _CAN 1\r
+\r
+/* RIT ------------------------------- */\r
+#define _RIT 1\r
+\r
+/* EMAC ------------------------------ */\r
+#define _EMAC 1\r
+\r
+\r
+/************************** GLOBAL/PUBLIC MACRO DEFINITIONS *********************************/\r
+\r
+#ifdef DEBUG\r
+/*******************************************************************************\r
+* @brief The CHECK_PARAM macro is used for function's parameters check.\r
+* It is used only if the library is compiled in DEBUG mode.\r
+* @param[in] expr - If expr is false, it calls check_failed() function\r
+* which reports the name of the source file and the source\r
+* line number of the call that failed.\r
+* - If expr is true, it returns no value.\r
+* @return None\r
+*******************************************************************************/\r
+#define CHECK_PARAM(expr) ((expr) ? (void)0 : check_failed((uint8_t *)__FILE__, __LINE__))\r
+#else\r
+#define CHECK_PARAM(expr)\r
+#endif /* DEBUG */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Functions ----------------------------------------------------------- */\r
+/** @defgroup LIBCFG_DEFAULT_Public_Functions\r
+ * @{\r
+ */\r
+\r
+#ifdef DEBUG\r
+void check_failed(uint8_t *file, uint32_t line);\r
+#endif\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#endif /* LPC17XX_LIBCFG_DEFAULT_H_ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* --------------------------------- End Of File ------------------------------ */\r
--- /dev/null
+/**\r
+ * @file : lpc17xx_pinsel.c\r
+ * @brief : Contains all functions support for Pin connect block firmware\r
+ * library on LPC17xx\r
+ * @version : 1.0\r
+ * @date : 25. Feb. 2009\r
+ * @author : HoanTran\r
+ **************************************************************************\r
+ * Software that is described herein is for illustrative purposes only\r
+ * which provides customers with programming information regarding the\r
+ * products. This software is supplied "AS IS" without any warranties.\r
+ * NXP Semiconductors assumes no responsibility or liability for the\r
+ * use of the software, conveys no license or title under any patent,\r
+ * copyright, or mask work right to the product. NXP Semiconductors\r
+ * reserves the right to make changes in the software without\r
+ * notification. NXP Semiconductors also make no representation or\r
+ * warranty that such application will be suitable for the specified\r
+ * use without further testing or modification.\r
+ **********************************************************************/\r
+\r
+/* Peripheral group ----------------------------------------------------------- */\r
+/** @addtogroup PINSEL\r
+ * @{\r
+ */\r
+\r
+/* Includes ------------------------------------------------------------------- */\r
+#include "lpc17xx_pinsel.h"\r
+\r
+\r
+/* Public Functions ----------------------------------------------------------- */\r
+/** @addtogroup PINSEL_Public_Functions\r
+ * @{\r
+ */\r
+\r
+/*********************************************************************//**\r
+ * @brief Setup the pin selection function\r
+ * @param[in] portnum PORT number,\r
+ * should be one of the following:\r
+ * - PINSEL_PORT_0 : Port 0\r
+ * - PINSEL_PORT_1 : Port 1\r
+ * - PINSEL_PORT_2 : Port 2\r
+ * - PINSEL_PORT_3 : Port 3\r
+ *\r
+ * @param[in] pinnum Pin number,\r
+ * should be one of the following:\r
+ - PINSEL_PIN_0 : Pin 0\r
+ - PINSEL_PIN_1 : Pin 1\r
+ - PINSEL_PIN_2 : Pin 2\r
+ - PINSEL_PIN_3 : Pin 3\r
+ - PINSEL_PIN_4 : Pin 4\r
+ - PINSEL_PIN_5 : Pin 5\r
+ - PINSEL_PIN_6 : Pin 6\r
+ - PINSEL_PIN_7 : Pin 7\r
+ - PINSEL_PIN_8 : Pin 8\r
+ - PINSEL_PIN_9 : Pin 9\r
+ - PINSEL_PIN_10 : Pin 10\r
+ - PINSEL_PIN_11 : Pin 11\r
+ - PINSEL_PIN_12 : Pin 12\r
+ - PINSEL_PIN_13 : Pin 13\r
+ - PINSEL_PIN_14 : Pin 14\r
+ - PINSEL_PIN_15 : Pin 15\r
+ - PINSEL_PIN_16 : Pin 16\r
+ - PINSEL_PIN_17 : Pin 17\r
+ - PINSEL_PIN_18 : Pin 18\r
+ - PINSEL_PIN_19 : Pin 19\r
+ - PINSEL_PIN_20 : Pin 20\r
+ - PINSEL_PIN_21 : Pin 21\r
+ - PINSEL_PIN_22 : Pin 22\r
+ - PINSEL_PIN_23 : Pin 23\r
+ - PINSEL_PIN_24 : Pin 24\r
+ - PINSEL_PIN_25 : Pin 25\r
+ - PINSEL_PIN_26 : Pin 26\r
+ - PINSEL_PIN_27 : Pin 27\r
+ - PINSEL_PIN_28 : Pin 28\r
+ - PINSEL_PIN_29 : Pin 29\r
+ - PINSEL_PIN_30 : Pin 30\r
+ - PINSEL_PIN_31 : Pin 31\r
+\r
+ * @param[in] funcnum Function number,\r
+ * should be one of the following:\r
+ * - PINSEL_FUNC_0 : default function\r
+ * - PINSEL_FUNC_1 : first alternate function\r
+ * - PINSEL_FUNC_2 : second alternate function\r
+ * - PINSEL_FUNC_3 : third alternate function\r
+ *\r
+ * @return None\r
+ **********************************************************************/\r
+void PINSEL_SetPinFunc ( uint8_t portnum, uint8_t pinnum, uint8_t funcnum)\r
+{\r
+ uint32_t pinnum_t = pinnum;\r
+ uint32_t pinselreg_idx = 2 * portnum;\r
+ uint32_t *pPinCon = (uint32_t *)&LPC_PINCON->PINSEL0;\r
+\r
+ if (pinnum_t >= 16) {\r
+ pinnum_t -= 16;\r
+ pinselreg_idx++;\r
+ }\r
+ *(uint32_t *)(pPinCon + pinselreg_idx) &= ~(0x03UL << (pinnum_t * 2));\r
+ *(uint32_t *)(pPinCon + pinselreg_idx) |= ((uint32_t)funcnum) << (pinnum_t * 2);\r
+}\r
+\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Configure trace function\r
+ * @param[in] NewState State of the Trace function configuration,\r
+ * should be one of the following:\r
+ * - ENABLE : Enable Trace Function\r
+ * - DISABLE : Disable Trace Function\r
+ *\r
+ * @return None\r
+ **********************************************************************/\r
+void PINSEL_ConfigTraceFunc(FunctionalState NewState)\r
+{\r
+ if (NewState == ENABLE) {\r
+ LPC_PINCON->PINSEL10 |= (0x01UL << 3);\r
+ } else if (NewState == DISABLE) {\r
+ LPC_PINCON->PINSEL10 &= ~(0x01UL << 3);\r
+ }\r
+}\r
+\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Setup resistor mode for each pin\r
+ * @param[in] portnum PORT number,\r
+ * should be one of the following:\r
+ * - PINSEL_PORT_0 : Port 0\r
+ * - PINSEL_PORT_1 : Port 1\r
+ * - PINSEL_PORT_2 : Port 2\r
+ * - PINSEL_PORT_3 : Port 3\r
+ * @param[in] pinnum Pin number,\r
+ * should be one of the following:\r
+ - PINSEL_PIN_0 : Pin 0\r
+ - PINSEL_PIN_1 : Pin 1\r
+ - PINSEL_PIN_2 : Pin 2\r
+ - PINSEL_PIN_3 : Pin 3\r
+ - PINSEL_PIN_4 : Pin 4\r
+ - PINSEL_PIN_5 : Pin 5\r
+ - PINSEL_PIN_6 : Pin 6\r
+ - PINSEL_PIN_7 : Pin 7\r
+ - PINSEL_PIN_8 : Pin 8\r
+ - PINSEL_PIN_9 : Pin 9\r
+ - PINSEL_PIN_10 : Pin 10\r
+ - PINSEL_PIN_11 : Pin 11\r
+ - PINSEL_PIN_12 : Pin 12\r
+ - PINSEL_PIN_13 : Pin 13\r
+ - PINSEL_PIN_14 : Pin 14\r
+ - PINSEL_PIN_15 : Pin 15\r
+ - PINSEL_PIN_16 : Pin 16\r
+ - PINSEL_PIN_17 : Pin 17\r
+ - PINSEL_PIN_18 : Pin 18\r
+ - PINSEL_PIN_19 : Pin 19\r
+ - PINSEL_PIN_20 : Pin 20\r
+ - PINSEL_PIN_21 : Pin 21\r
+ - PINSEL_PIN_22 : Pin 22\r
+ - PINSEL_PIN_23 : Pin 23\r
+ - PINSEL_PIN_24 : Pin 24\r
+ - PINSEL_PIN_25 : Pin 25\r
+ - PINSEL_PIN_26 : Pin 26\r
+ - PINSEL_PIN_27 : Pin 27\r
+ - PINSEL_PIN_28 : Pin 28\r
+ - PINSEL_PIN_29 : Pin 29\r
+ - PINSEL_PIN_30 : Pin 30\r
+ - PINSEL_PIN_31 : Pin 31\r
+\r
+ * @param[in] modenum: Mode number,\r
+ * should be one of the following:\r
+ - PINSEL_PINMODE_PULLUP : Internal pull-up resistor\r
+ - PINSEL_PINMODE_TRISTATE : Tri-state\r
+ - PINSEL_PINMODE_PULLDOWN : Internal pull-down resistor\r
+\r
+ * @return None\r
+ **********************************************************************/\r
+void PINSEL_SetResistorMode ( uint8_t portnum, uint8_t pinnum, uint8_t modenum)\r
+{\r
+ uint32_t pinnum_t = pinnum;\r
+ uint32_t pinmodereg_idx = 2 * portnum;\r
+ uint32_t *pPinCon = (uint32_t *)&LPC_PINCON->PINMODE0;\r
+\r
+ if (pinnum_t >= 16) {\r
+ pinnum_t -= 16;\r
+ pinmodereg_idx++ ;\r
+ }\r
+\r
+ *(uint32_t *)(pPinCon + pinmodereg_idx) &= ~(0x03UL << (pinnum_t * 2));\r
+ *(uint32_t *)(pPinCon + pinmodereg_idx) |= ((uint32_t)modenum) << (pinnum_t * 2);\r
+}\r
+\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Setup Open drain mode for each pin\r
+ * @param[in] portnum PORT number,\r
+ * should be one of the following:\r
+ * - PINSEL_PORT_0 : Port 0\r
+ * - PINSEL_PORT_1 : Port 1\r
+ * - PINSEL_PORT_2 : Port 2\r
+ * - PINSEL_PORT_3 : Port 3\r
+ *\r
+ * @param[in] pinnum Pin number,\r
+ * should be one of the following:\r
+ - PINSEL_PIN_0 : Pin 0\r
+ - PINSEL_PIN_1 : Pin 1\r
+ - PINSEL_PIN_2 : Pin 2\r
+ - PINSEL_PIN_3 : Pin 3\r
+ - PINSEL_PIN_4 : Pin 4\r
+ - PINSEL_PIN_5 : Pin 5\r
+ - PINSEL_PIN_6 : Pin 6\r
+ - PINSEL_PIN_7 : Pin 7\r
+ - PINSEL_PIN_8 : Pin 8\r
+ - PINSEL_PIN_9 : Pin 9\r
+ - PINSEL_PIN_10 : Pin 10\r
+ - PINSEL_PIN_11 : Pin 11\r
+ - PINSEL_PIN_12 : Pin 12\r
+ - PINSEL_PIN_13 : Pin 13\r
+ - PINSEL_PIN_14 : Pin 14\r
+ - PINSEL_PIN_15 : Pin 15\r
+ - PINSEL_PIN_16 : Pin 16\r
+ - PINSEL_PIN_17 : Pin 17\r
+ - PINSEL_PIN_18 : Pin 18\r
+ - PINSEL_PIN_19 : Pin 19\r
+ - PINSEL_PIN_20 : Pin 20\r
+ - PINSEL_PIN_21 : Pin 21\r
+ - PINSEL_PIN_22 : Pin 22\r
+ - PINSEL_PIN_23 : Pin 23\r
+ - PINSEL_PIN_24 : Pin 24\r
+ - PINSEL_PIN_25 : Pin 25\r
+ - PINSEL_PIN_26 : Pin 26\r
+ - PINSEL_PIN_27 : Pin 27\r
+ - PINSEL_PIN_28 : Pin 28\r
+ - PINSEL_PIN_29 : Pin 29\r
+ - PINSEL_PIN_30 : Pin 30\r
+ - PINSEL_PIN_31 : Pin 31\r
+\r
+ * @param[in] modenum Open drain mode number,\r
+ * should be one of the following:\r
+ * - PINSEL_PINMODE_NORMAL : Pin is in the normal (not open drain) mode\r
+ * - PINSEL_PINMODE_OPENDRAIN : Pin is in the open drain mode\r
+ *\r
+ * @return None\r
+ **********************************************************************/\r
+void PINSEL_SetOpenDrainMode( uint8_t portnum, uint8_t pinnum, uint8_t modenum)\r
+{\r
+ uint32_t *pPinCon = (uint32_t *)&LPC_PINCON->PINMODE_OD0;\r
+\r
+ if (modenum == PINSEL_PINMODE_OPENDRAIN){\r
+ *(uint32_t *)(pPinCon + portnum) |= (0x01UL << pinnum);\r
+ } else {\r
+ *(uint32_t *)(pPinCon + portnum) &= ~(0x01UL << pinnum);\r
+ }\r
+}\r
+\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Setup I2C0 pins\r
+ * @param[in] i2cPinMode I2C pin mode,\r
+ * should be one of the following:\r
+ * - PINSEL_I2C_Normal_Mode : The standard drive mode\r
+ * - PINSEL_I2C_Fast_Mode : Fast Mode Plus drive mode\r
+ *\r
+ * @param[in] filterSlewRateEnable should be:\r
+ * - ENABLE: Enable filter and slew rate.\r
+ * - DISABLE: Disable filter and slew rate.\r
+ *\r
+ * @return None\r
+ **********************************************************************/\r
+void PINSEL_SetI2C0Pins(uint8_t i2cPinMode, FunctionalState filterSlewRateEnable)\r
+{\r
+ uint32_t regVal;\r
+\r
+ if (i2cPinMode == PINSEL_I2C_Fast_Mode){\r
+ regVal = PINSEL_I2CPADCFG_SCLDRV0 | PINSEL_I2CPADCFG_SDADRV0;\r
+ }\r
+\r
+ if (filterSlewRateEnable == DISABLE){\r
+ regVal = PINSEL_I2CPADCFG_SCLI2C0 | PINSEL_I2CPADCFG_SDAI2C0;\r
+ }\r
+ LPC_PINCON->I2CPADCFG = regVal;\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Configure Pin corresponding to specified parameters passed\r
+ * in the PinCfg\r
+ * @param[in] PinCfg Pointer to a PINSEL_CFG_Type structure\r
+ * that contains the configuration information for the\r
+ * specified pin.\r
+ * @return None\r
+ **********************************************************************/\r
+void PINSEL_ConfigPin(PINSEL_CFG_Type *PinCfg)\r
+{\r
+ PINSEL_SetPinFunc(PinCfg->Portnum, PinCfg->Pinnum, PinCfg->Funcnum);\r
+ PINSEL_SetResistorMode(PinCfg->Portnum, PinCfg->Pinnum, PinCfg->Pinmode);\r
+ PINSEL_SetOpenDrainMode(PinCfg->Portnum, PinCfg->Pinnum, PinCfg->OpenDrain);\r
+}\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* --------------------------------- End Of File ------------------------------ */\r
--- /dev/null
+/***********************************************************************//**\r
+ * @file : lpc17xx_pinsel.h\r
+ * @brief : Contains all macro definitions and function prototypes\r
+ * support for Pin connect block firmware library on LPC17xx\r
+ * @version : 1.0\r
+ * @date : 25. Feb. 2009\r
+ * @author : HoanTran\r
+ **************************************************************************\r
+ * Software that is described herein is for illustrative purposes only\r
+ * which provides customers with programming information regarding the\r
+ * products. This software is supplied "AS IS" without any warranties.\r
+ * NXP Semiconductors assumes no responsibility or liability for the\r
+ * use of the software, conveys no license or title under any patent,\r
+ * copyright, or mask work right to the product. NXP Semiconductors\r
+ * reserves the right to make changes in the software without\r
+ * notification. NXP Semiconductors also make no representation or\r
+ * warranty that such application will be suitable for the specified\r
+ * use without further testing or modification.\r
+ **************************************************************************/\r
+\r
+/* Peripheral group ----------------------------------------------------------- */\r
+/** @defgroup PINSEL\r
+ * @ingroup LPC1700CMSIS_FwLib_Drivers\r
+ * @{\r
+ */\r
+\r
+#ifndef LPC17XX_PINSEL_H_\r
+#define LPC17XX_PINSEL_H_\r
+\r
+/* Includes ------------------------------------------------------------------- */\r
+#include "lpc17xx.h"\r
+#include "lpc_types.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif\r
+\r
+\r
+/* Private Macros ------------------------------------------------------------- */\r
+/** @defgroup PINSEL_Private_Macros\r
+ * @{\r
+ */\r
+\r
+/** @defgroup PINSEL_REGISTER_BIT_DEFINITIONS\r
+ * @{\r
+ */\r
+\r
+/* Pin selection define */\r
+/* I2C Pin Configuration register bit description */\r
+#define PINSEL_I2CPADCFG_SDADRV0 _BIT(0) /**< Drive mode control for the SDA0 pin, P0.27 */\r
+#define PINSEL_I2CPADCFG_SDAI2C0 _BIT(1) /**< I2C mode control for the SDA0 pin, P0.27 */\r
+#define PINSEL_I2CPADCFG_SCLDRV0 _BIT(2) /**< Drive mode control for the SCL0 pin, P0.28 */\r
+#define PINSEL_I2CPADCFG_SCLI2C0 _BIT(3) /**< I2C mode control for the SCL0 pin, P0.28 */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Macros -------------------------------------------------------------- */\r
+/** @defgroup PINSEL_Public_Macros\r
+ * @{\r
+ */\r
+\r
+/*********************************************************************//**\r
+ *!< Macros define for PORT Selection\r
+ ***********************************************************************/\r
+#define PINSEL_PORT_0 ((0)) /**< PORT 0*/\r
+#define PINSEL_PORT_1 ((1)) /**< PORT 1*/\r
+#define PINSEL_PORT_2 ((2)) /**< PORT 2*/\r
+#define PINSEL_PORT_3 ((3)) /**< PORT 3*/\r
+#define PINSEL_PORT_4 ((4)) /**< PORT 4*/\r
+\r
+\r
+/***********************************************************************\r
+ * Macros define for Pin Function selection\r
+ **********************************************************************/\r
+#define PINSEL_FUNC_0 ((0)) /**< default function*/\r
+#define PINSEL_FUNC_1 ((1)) /**< first alternate function*/\r
+#define PINSEL_FUNC_2 ((2)) /**< second alternate function*/\r
+#define PINSEL_FUNC_3 ((3)) /**< third or reserved alternate function*/\r
+\r
+\r
+\r
+/***********************************************************************\r
+ * Macros define for Pin Number of Port\r
+ **********************************************************************/\r
+#define PINSEL_PIN_0 ((0)) /**< Pin 0 */\r
+#define PINSEL_PIN_1 ((1)) /**< Pin 1 */\r
+#define PINSEL_PIN_2 ((2)) /**< Pin 2 */\r
+#define PINSEL_PIN_3 ((3)) /**< Pin 3 */\r
+#define PINSEL_PIN_4 ((4)) /**< Pin 4 */\r
+#define PINSEL_PIN_5 ((5)) /**< Pin 5 */\r
+#define PINSEL_PIN_6 ((6)) /**< Pin 6 */\r
+#define PINSEL_PIN_7 ((7)) /**< Pin 7 */\r
+#define PINSEL_PIN_8 ((8)) /**< Pin 8 */\r
+#define PINSEL_PIN_9 ((9)) /**< Pin 9 */\r
+#define PINSEL_PIN_10 ((10)) /**< Pin 10 */\r
+#define PINSEL_PIN_11 ((11)) /**< Pin 11 */\r
+#define PINSEL_PIN_12 ((12)) /**< Pin 12 */\r
+#define PINSEL_PIN_13 ((13)) /**< Pin 13 */\r
+#define PINSEL_PIN_14 ((14)) /**< Pin 14 */\r
+#define PINSEL_PIN_15 ((15)) /**< Pin 15 */\r
+#define PINSEL_PIN_16 ((16)) /**< Pin 16 */\r
+#define PINSEL_PIN_17 ((17)) /**< Pin 17 */\r
+#define PINSEL_PIN_18 ((18)) /**< Pin 18 */\r
+#define PINSEL_PIN_19 ((19)) /**< Pin 19 */\r
+#define PINSEL_PIN_20 ((20)) /**< Pin 20 */\r
+#define PINSEL_PIN_21 ((21)) /**< Pin 21 */\r
+#define PINSEL_PIN_22 ((22)) /**< Pin 22 */\r
+#define PINSEL_PIN_23 ((23)) /**< Pin 23 */\r
+#define PINSEL_PIN_24 ((24)) /**< Pin 24 */\r
+#define PINSEL_PIN_25 ((25)) /**< Pin 25 */\r
+#define PINSEL_PIN_26 ((26)) /**< Pin 26 */\r
+#define PINSEL_PIN_27 ((27)) /**< Pin 27 */\r
+#define PINSEL_PIN_28 ((28)) /**< Pin 28 */\r
+#define PINSEL_PIN_29 ((29)) /**< Pin 29 */\r
+#define PINSEL_PIN_30 ((30)) /**< Pin 30 */\r
+#define PINSEL_PIN_31 ((31)) /**< Pin 31 */\r
+\r
+\r
+/***********************************************************************\r
+ * Macros define for Pin mode\r
+ **********************************************************************/\r
+#define PINSEL_PINMODE_PULLUP ((0)) /**< Internal pull-up resistor*/\r
+#define PINSEL_PINMODE_TRISTATE ((2)) /**< Tri-state */\r
+#define PINSEL_PINMODE_PULLDOWN ((3)) /**< Internal pull-down resistor */\r
+\r
+\r
+/***********************************************************************\r
+ * Macros define for Pin mode (normal/open drain)\r
+ **********************************************************************/\r
+#define PINSEL_PINMODE_NORMAL ((0)) /**< Pin is in the normal (not open drain) mode.*/\r
+#define PINSEL_PINMODE_OPENDRAIN ((1)) /**< Pin is in the open drain mode */\r
+\r
+\r
+/***********************************************************************\r
+ * Macros define for I2C mode\r
+ ***********************************************************************/\r
+#define PINSEL_I2C_Normal_Mode ((0)) /**< The standard drive mode */\r
+#define PINSEL_I2C_Fast_Mode ((1)) /**< Fast Mode Plus drive mode */\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Types --------------------------------------------------------------- */\r
+/** @defgroup PINSEL_Public_Types\r
+ * @{\r
+ */\r
+\r
+/** @brief Pin configuration structure */\r
+typedef struct\r
+{\r
+ uint8_t Portnum; /**< Port Number, should be PINSEL_PORT_x,\r
+ where x should be in range from 0 to 4 */\r
+ uint8_t Pinnum; /**< Pin Number, should be PINSEL_PIN_x,\r
+ where x should be in range from 0 to 31 */\r
+ uint8_t Funcnum; /**< Function Number, should be PINSEL_FUNC_x,\r
+ where x should be in range from 0 to 3 */\r
+ uint8_t Pinmode; /**< Pin Mode, should be:\r
+ - PINSEL_PINMODE_PULLUP: Internal pull-up resistor\r
+ - PINSEL_PINMODE_TRISTATE: Tri-state\r
+ - PINSEL_PINMODE_PULLDOWN: Internal pull-down resistor */\r
+ uint8_t OpenDrain; /**< OpenDrain mode, should be:\r
+ - PINSEL_PINMODE_NORMAL: Pin is in the normal (not open drain) mode\r
+ - PINSEL_PINMODE_OPENDRAIN: Pin is in the open drain mode */\r
+} PINSEL_CFG_Type;\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Functions ----------------------------------------------------------- */\r
+/** @defgroup PINSEL_Public_Functions\r
+ * @{\r
+ */\r
+\r
+void PINSEL_SetPinFunc ( uint8_t portnum, uint8_t pinnum, uint8_t funcnum);\r
+void PINSEL_ConfigTraceFunc (FunctionalState NewState);\r
+void PINSEL_SetResistorMode ( uint8_t portnum, uint8_t pinnum, uint8_t modenum);\r
+void PINSEL_SetOpenDrainMode( uint8_t portnum, uint8_t pinnum, uint8_t modenum);\r
+void PINSEL_SetI2C0Pins(uint8_t i2cPinMode, FunctionalState filterSlewRateEnable);\r
+void PINSEL_ConfigPin(PINSEL_CFG_Type *PinCfg);\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* LPC17XX_PINSEL_H_ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* --------------------------------- End Of File ------------------------------ */\r
+\r
--- /dev/null
+/***********************************************************************//**\r
+ * @file : lpc_types.h\r
+ * @brief :\r
+ * Contains the NXP ABL typedefs for C standard types.\r
+ * It is intended to be used in ISO C conforming development\r
+ * environments and checks for this insofar as it is possible\r
+ * to do so.\r
+ * @version : 1.0\r
+ * @date : 27 Jul. 2008\r
+ * @author : wellsk\r
+ **************************************************************************\r
+ * Software that is described herein is for illustrative purposes only\r
+ * which provides customers with programming information regarding the\r
+ * products. This software is supplied "AS IS" without any warranties.\r
+ * NXP Semiconductors assumes no responsibility or liability for the\r
+ * use of the software, conveys no license or title under any patent,\r
+ * copyright, or mask work right to the product. NXP Semiconductors\r
+ * reserves the right to make changes in the software without\r
+ * notification. NXP Semiconductors also make no representation or\r
+ * warranty that such application will be suitable for the specified\r
+ * use without further testing or modification.\r
+ **************************************************************************/\r
+\r
+/* Type group ----------------------------------------------------------- */\r
+/** @defgroup LPC_Types\r
+ * @ingroup LPC1700CMSIS_FwLib_Drivers\r
+ * @{\r
+ */\r
+\r
+#ifndef LPC_TYPES_H\r
+#define LPC_TYPES_H\r
+\r
+/* Includes ------------------------------------------------------------------- */\r
+#include <stdint.h>\r
+\r
+\r
+/* Public Types --------------------------------------------------------------- */\r
+/** @defgroup LPC_Types_Public_Types\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief Boolean Type definition\r
+ */\r
+typedef enum {FALSE = 0, TRUE = !FALSE} Bool;\r
+\r
+/**\r
+ * @brief Flag Status and Interrupt Flag Status type definition\r
+ */\r
+typedef enum {RESET = 0, SET = !RESET} FlagStatus, IntStatus, SetState;\r
+#define PARAM_SETSTATE(State) ((State==RESET) || (State==SET))\r
+\r
+/**\r
+ * @brief Functional State Definition\r
+ */\r
+typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;\r
+#define PARAM_FUNCTIONALSTATE(State) ((State==DISABLE) || (State==ENABLE))\r
+\r
+/**\r
+ * @ Status type definition\r
+ */\r
+typedef enum {ERROR = 0, SUCCESS = !ERROR} Status;\r
+\r
+\r
+/**\r
+ * Read/Write transfer type mode (Block or non-block)\r
+ */\r
+typedef enum\r
+{\r
+ NONE_BLOCKING = 0, /**< None Blocking type */\r
+ BLOCKING, /**< Blocking type */\r
+} TRANSFER_BLOCK_Type;\r
+\r
+\r
+/** Pointer to Function returning Void (any number of parameters) */\r
+typedef void (*PFV)();\r
+\r
+/** Pointer to Function returning int32_t (any number of parameters) */\r
+typedef int32_t(*PFI)();\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Macros -------------------------------------------------------------- */\r
+/** @defgroup LPC_Types_Public_Macros\r
+ * @{\r
+ */\r
+\r
+/* _BIT(n) sets the bit at position "n"\r
+ * _BIT(n) is intended to be used in "OR" and "AND" expressions:\r
+ * e.g., "(_BIT(3) | _BIT(7))".\r
+ */\r
+#undef _BIT\r
+/* Set bit macro */\r
+#define _BIT(n) (1<<n)\r
+\r
+/* _SBF(f,v) sets the bit field starting at position "f" to value "v".\r
+ * _SBF(f,v) is intended to be used in "OR" and "AND" expressions:\r
+ * e.g., "((_SBF(5,7) | _SBF(12,0xF)) & 0xFFFF)"\r
+ */\r
+#undef _SBF\r
+/* Set bit field macro */\r
+#define _SBF(f,v) (v<<f)\r
+\r
+/* _BITMASK constructs a symbol with 'field_width' least significant\r
+ * bits set.\r
+ * e.g., _BITMASK(5) constructs '0x1F', _BITMASK(16) == 0xFFFF\r
+ * The symbol is intended to be used to limit the bit field width\r
+ * thusly:\r
+ * <a_register> = (any_expression) & _BITMASK(x), where 0 < x <= 32.\r
+ * If "any_expression" results in a value that is larger than can be\r
+ * contained in 'x' bits, the bits above 'x - 1' are masked off. When\r
+ * used with the _SBF example above, the example would be written:\r
+ * a_reg = ((_SBF(5,7) | _SBF(12,0xF)) & _BITMASK(16))\r
+ * This ensures that the value written to a_reg is no wider than\r
+ * 16 bits, and makes the code easier to read and understand.\r
+ */\r
+#undef _BITMASK\r
+/* Bitmask creation macro */\r
+#define _BITMASK(field_width) ( _BIT(field_width) - 1)\r
+\r
+/* NULL pointer */\r
+#ifndef NULL\r
+#define NULL ((void*) 0)\r
+#endif\r
+\r
+/* Number of elements in an array */\r
+#define NELEMENTS(array) (sizeof (array) / sizeof (array[0]))\r
+\r
+/* Static data/function define */\r
+#define STATIC static\r
+/* External data/function define */\r
+#define EXTERN extern\r
+\r
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))\r
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Old Type Definition compatibility ------------------------------------------ */\r
+/** @addtogroup LPC_Types_Public_Types\r
+ * @{\r
+ */\r
+\r
+/** SMA type for character type */\r
+typedef char CHAR;\r
+\r
+/** SMA type for 8 bit unsigned value */\r
+typedef uint8_t UNS_8;\r
+\r
+/** SMA type for 8 bit signed value */\r
+typedef int8_t INT_8;\r
+\r
+/** SMA type for 16 bit unsigned value */\r
+typedef uint16_t UNS_16;\r
+\r
+/** SMA type for 16 bit signed value */\r
+typedef int16_t INT_16;\r
+\r
+/** SMA type for 32 bit unsigned value */\r
+typedef uint32_t UNS_32;\r
+\r
+/** SMA type for 32 bit signed value */\r
+typedef int32_t INT_32;\r
+\r
+/** SMA type for 64 bit signed value */\r
+typedef int64_t INT_64;\r
+\r
+/** SMA type for 64 bit unsigned value */\r
+typedef uint64_t UNS_64;\r
+\r
+/** 32 bit boolean type */\r
+typedef Bool BOOL_32;\r
+\r
+/** 16 bit boolean type */\r
+typedef Bool BOOL_16;\r
+\r
+/** 8 bit boolean type */\r
+typedef Bool BOOL_8;\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+#endif /* LPC_TYPES_H */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* --------------------------------- End Of File ------------------------------ */\r
--- /dev/null
+/**\r
+ * @file : lpc17xx_gpio.c\r
+ * @brief : Contains all functions support for GPIO firmware library on LPC17xx\r
+ * @version : 1.0\r
+ * @date : 11. Jun. 2009\r
+ * @author : HieuNguyen\r
+ **************************************************************************\r
+ * Software that is described herein is for illustrative purposes only\r
+ * which provides customers with programming information regarding the\r
+ * products. This software is supplied "AS IS" without any warranties.\r
+ * NXP Semiconductors assumes no responsibility or liability for the\r
+ * use of the software, conveys no license or title under any patent,\r
+ * copyright, or mask work right to the product. NXP Semiconductors\r
+ * reserves the right to make changes in the software without\r
+ * notification. NXP Semiconductors also make no representation or\r
+ * warranty that such application will be suitable for the specified\r
+ * use without further testing or modification.\r
+ **********************************************************************/\r
+\r
+/* Peripheral group ----------------------------------------------------------- */\r
+/** @addtogroup GPIO\r
+ * @{\r
+ */\r
+\r
+/* Includes ------------------------------------------------------------------- */\r
+#include "lpc17xx_gpio.h"\r
+\r
+/* If this source file built with example, the LPC17xx FW library configuration\r
+ * file in each example directory ("lpc17xx_libcfg.h") must be included,\r
+ * otherwise the default FW library configuration file must be included instead\r
+ */\r
+#ifdef __BUILD_WITH_EXAMPLE__\r
+#include "lpc17xx_libcfg.h"\r
+#else\r
+#include "lpc17xx_libcfg_default.h"\r
+#endif /* __BUILD_WITH_EXAMPLE__ */\r
+\r
+\r
+#ifdef _GPIO\r
+\r
+/* Private Functions ---------------------------------------------------------- */\r
+/** @addtogroup GPIO_Private_Functions\r
+ * @{\r
+ */\r
+/*********************************************************************//**\r
+ * @brief Get pointer to GPIO peripheral due to GPIO port\r
+ * @param[in] portNum Port Number value, should be in range from 0 to 4.\r
+ * @return Pointer to GPIO peripheral\r
+ **********************************************************************/\r
+static LPC_GPIO_TypeDef *GPIO_GetPointer(uint8_t portNum)\r
+{\r
+ LPC_GPIO_TypeDef *pGPIO = NULL;\r
+\r
+ switch (portNum) {\r
+ case 0:\r
+ pGPIO = LPC_GPIO0;\r
+ break;\r
+ case 1:\r
+ pGPIO = LPC_GPIO1;\r
+ break;\r
+ case 2:\r
+ pGPIO = LPC_GPIO2;\r
+ break;\r
+ case 3:\r
+ pGPIO = LPC_GPIO3;\r
+ break;\r
+ case 4:\r
+ pGPIO = LPC_GPIO4;\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return pGPIO;\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief Get pointer to FIO peripheral in halfword accessible style\r
+ * due to FIO port\r
+ * @param[in] portNum Port Number value, should be in range from 0 to 4.\r
+ * @return Pointer to FIO peripheral\r
+ **********************************************************************/\r
+static GPIO_HalfWord_TypeDef *FIO_HalfWordGetPointer(uint8_t portNum)\r
+{\r
+ GPIO_HalfWord_TypeDef *pFIO = NULL;\r
+\r
+ switch (portNum) {\r
+ case 0:\r
+ pFIO = GPIO0_HalfWord;\r
+ break;\r
+ case 1:\r
+ pFIO = GPIO1_HalfWord;\r
+ break;\r
+ case 2:\r
+ pFIO = GPIO2_HalfWord;\r
+ break;\r
+ case 3:\r
+ pFIO = GPIO3_HalfWord;\r
+ break;\r
+ case 4:\r
+ pFIO = GPIO4_HalfWord;\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return pFIO;\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief Get pointer to FIO peripheral in byte accessible style\r
+ * due to FIO port\r
+ * @param[in] portNum Port Number value, should be in range from 0 to 4.\r
+ * @return Pointer to FIO peripheral\r
+ **********************************************************************/\r
+static GPIO_Byte_TypeDef *FIO_ByteGetPointer(uint8_t portNum)\r
+{\r
+ GPIO_Byte_TypeDef *pFIO = NULL;\r
+\r
+ switch (portNum) {\r
+ case 0:\r
+ pFIO = GPIO0_Byte;\r
+ break;\r
+ case 1:\r
+ pFIO = GPIO1_Byte;\r
+ break;\r
+ case 2:\r
+ pFIO = GPIO2_Byte;\r
+ break;\r
+ case 3:\r
+ pFIO = GPIO3_Byte;\r
+ break;\r
+ case 4:\r
+ pFIO = GPIO4_Byte;\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return pFIO;\r
+}\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Functions ----------------------------------------------------------- */\r
+/** @addtogroup GPIO_Public_Functions\r
+ * @{\r
+ */\r
+\r
+\r
+/* GPIO ------------------------------------------------------------------------------ */\r
+\r
+/*********************************************************************//**\r
+ * @brief Set Direction for GPIO port.\r
+ * @param[in] portNum Port Number value, should be in range from 0 to 4\r
+ * @param[in] bitValue Value that contains all bits to set direction,\r
+ * in range from 0 to 0xFFFFFFFF.\r
+ * example: value 0x5 to set direction for bit 0 and bit 1.\r
+ * @param[in] dir Direction value, should be:\r
+ * - 0: Input.\r
+ * - 1: Output.\r
+ * @return None\r
+ *\r
+ * Note: All remaining bits that are not activated in bitValue (value '0')\r
+ * will not be effected by this function.\r
+ **********************************************************************/\r
+void GPIO_SetDir(uint8_t portNum, uint32_t bitValue, uint8_t dir)\r
+{\r
+ LPC_GPIO_TypeDef *pGPIO = GPIO_GetPointer(portNum);\r
+\r
+ if (pGPIO != NULL) {\r
+ // Enable Output\r
+ if (dir) {\r
+ pGPIO->FIODIR |= bitValue;\r
+ }\r
+ // Enable Input\r
+ else {\r
+ pGPIO->FIODIR &= ~bitValue;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Set Value for bits that have output direction on GPIO port.\r
+ * @param[in] portNum Port number value, should be in range from 0 to 4\r
+ * @param[in] bitValue Value that contains all bits on GPIO to set,\r
+ * in range from 0 to 0xFFFFFFFF.\r
+ * example: value 0x5 to set bit 0 and bit 1.\r
+ * @return None\r
+ *\r
+ * Note:\r
+ * - For all bits that has been set as input direction, this function will\r
+ * not effect.\r
+ * - For all remaining bits that are not activated in bitValue (value '0')\r
+ * will not be effected by this function.\r
+ **********************************************************************/\r
+void GPIO_SetValue(uint8_t portNum, uint32_t bitValue)\r
+{\r
+ LPC_GPIO_TypeDef *pGPIO = GPIO_GetPointer(portNum);\r
+\r
+ if (pGPIO != NULL) {\r
+ pGPIO->FIOSET = bitValue;\r
+ }\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief Clear Value for bits that have output direction on GPIO port.\r
+ * @param[in] portNum Port number value, should be in range from 0 to 4\r
+ * @param[in] bitValue Value that contains all bits on GPIO to clear,\r
+ * in range from 0 to 0xFFFFFFFF.\r
+ * example: value 0x5 to clear bit 0 and bit 1.\r
+ * @return None\r
+ *\r
+ * Note:\r
+ * - For all bits that has been set as input direction, this function will\r
+ * not effect.\r
+ * - For all remaining bits that are not activated in bitValue (value '0')\r
+ * will not be effected by this function.\r
+ **********************************************************************/\r
+void GPIO_ClearValue(uint8_t portNum, uint32_t bitValue)\r
+{\r
+ LPC_GPIO_TypeDef *pGPIO = GPIO_GetPointer(portNum);\r
+\r
+ if (pGPIO != NULL) {\r
+ pGPIO->FIOCLR = bitValue;\r
+ }\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief Read Current state on port pin that have input direction of GPIO\r
+ * @param[in] portNum Port number to read value, in range from 0 to 4\r
+ * @return Current value of GPIO port.\r
+ *\r
+ * Note: Return value contain state of each port pin (bit) on that GPIO regardless\r
+ * its direction is input or output.\r
+ **********************************************************************/\r
+uint32_t GPIO_ReadValue(uint8_t portNum)\r
+{\r
+ LPC_GPIO_TypeDef *pGPIO = GPIO_GetPointer(portNum);\r
+\r
+ if (pGPIO != NULL) {\r
+ return pGPIO->FIOPIN;\r
+ }\r
+\r
+ return (0);\r
+}\r
+\r
+/* FIO word accessible ----------------------------------------------------------------- */\r
+/* Stub function for FIO (word-accessible) style */\r
+\r
+/**\r
+ * @brief The same with GPIO_SetDir()\r
+ */\r
+void FIO_SetDir(uint8_t portNum, uint32_t bitValue, uint8_t dir)\r
+{\r
+ GPIO_SetDir(portNum, bitValue, dir);\r
+}\r
+\r
+/**\r
+ * @brief The same with GPIO_SetValue()\r
+ */\r
+void FIO_SetValue(uint8_t portNum, uint32_t bitValue)\r
+{\r
+ GPIO_SetValue(portNum, bitValue);\r
+}\r
+\r
+/**\r
+ * @brief The same with GPIO_ClearValue()\r
+ */\r
+void FIO_ClearValue(uint8_t portNum, uint32_t bitValue)\r
+{\r
+ GPIO_ClearValue(portNum, bitValue);\r
+}\r
+\r
+/**\r
+ * @brief The same with GPIO_ReadValue()\r
+ */\r
+uint32_t FIO_ReadValue(uint8_t portNum)\r
+{\r
+ return (GPIO_ReadValue(portNum));\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Set mask value for bits in FIO port\r
+ * @param[in] portNum Port number, in range from 0 to 4\r
+ * @param[in] bitValue Value that contains all bits in to set,\r
+ * in range from 0 to 0xFFFFFFFF.\r
+ * @param[in] maskValue Mask value contains state value for each bit:\r
+ * - 0: not mask.\r
+ * - 1: mask.\r
+ * @return None\r
+ *\r
+ * Note:\r
+ * - All remaining bits that are not activated in bitValue (value '0')\r
+ * will not be effected by this function.\r
+ * - After executing this function, in mask register, value '0' on each bit\r
+ * enables an access to the corresponding physical pin via a read or write access,\r
+ * while value '1' on bit (masked) that corresponding pin will not be changed\r
+ * with write access and if read, will not be reflected in the updated pin.\r
+ **********************************************************************/\r
+void FIO_SetMask(uint8_t portNum, uint32_t bitValue, uint8_t maskValue)\r
+{\r
+ LPC_GPIO_TypeDef *pFIO = GPIO_GetPointer(portNum);\r
+ if(pFIO != NULL) {\r
+ // Mask\r
+ if (maskValue){\r
+ pFIO->FIOMASK |= bitValue;\r
+ }\r
+ // Un-mask\r
+ else {\r
+ pFIO->FIOMASK &= ~bitValue;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+/* FIO halfword accessible ------------------------------------------------------------- */\r
+\r
+/*********************************************************************//**\r
+ * @brief Set direction for FIO port in halfword accessible style\r
+ * @param[in] portNum Port number, in range from 0 to 4\r
+ * @param[in] halfwordNum HalfWord part number, should be 0 (lower) or 1(upper)\r
+ * @param[in] bitValue Value that contains all bits in to set direction,\r
+ * in range from 0 to 0xFFFF.\r
+ * @param[in] dir Direction value, should be:\r
+ * - 0: Input.\r
+ * - 1: Output.\r
+ * @return None\r
+ *\r
+ * Note: All remaining bits that are not activated in bitValue (value '0')\r
+ * will not be effected by this function.\r
+ **********************************************************************/\r
+void FIO_HalfWordSetDir(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue, uint8_t dir)\r
+{\r
+ GPIO_HalfWord_TypeDef *pFIO = FIO_HalfWordGetPointer(portNum);\r
+ if(pFIO != NULL) {\r
+ // Output direction\r
+ if (dir) {\r
+ // Upper\r
+ if(halfwordNum) {\r
+ pFIO->FIODIRU |= bitValue;\r
+ }\r
+ // lower\r
+ else {\r
+ pFIO->FIODIRL |= bitValue;\r
+ }\r
+ }\r
+ // Input direction\r
+ else {\r
+ // Upper\r
+ if(halfwordNum) {\r
+ pFIO->FIODIRU &= ~bitValue;\r
+ }\r
+ // lower\r
+ else {\r
+ pFIO->FIODIRL &= ~bitValue;\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Set mask value for bits in FIO port in halfword accessible style\r
+ * @param[in] portNum Port number, in range from 0 to 4\r
+ * @param[in] halfwordNum HalfWord part number, should be 0 (lower) or 1(upper)\r
+ * @param[in] bitValue Value that contains all bits in to set,\r
+ * in range from 0 to 0xFFFF.\r
+ * @param[in] maskValue Mask value contains state value for each bit:\r
+ * - 0: not mask.\r
+ * - 1: mask.\r
+ * @return None\r
+ *\r
+ * Note:\r
+ * - All remaining bits that are not activated in bitValue (value '0')\r
+ * will not be effected by this function.\r
+ * - After executing this function, in mask register, value '0' on each bit\r
+ * enables an access to the corresponding physical pin via a read or write access,\r
+ * while value '1' on bit (masked) that corresponding pin will not be changed\r
+ * with write access and if read, will not be reflected in the updated pin.\r
+ **********************************************************************/\r
+void FIO_HalfWordSetMask(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue, uint8_t maskValue)\r
+{\r
+ GPIO_HalfWord_TypeDef *pFIO = FIO_HalfWordGetPointer(portNum);\r
+ if(pFIO != NULL) {\r
+ // Mask\r
+ if (maskValue){\r
+ // Upper\r
+ if(halfwordNum) {\r
+ pFIO->FIOMASKU |= bitValue;\r
+ }\r
+ // lower\r
+ else {\r
+ pFIO->FIOMASKL |= bitValue;\r
+ }\r
+ }\r
+ // Un-mask\r
+ else {\r
+ // Upper\r
+ if(halfwordNum) {\r
+ pFIO->FIOMASKU &= ~bitValue;\r
+ }\r
+ // lower\r
+ else {\r
+ pFIO->FIOMASKL &= ~bitValue;\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Set bits for FIO port in halfword accessible style\r
+ * @param[in] portNum Port number, in range from 0 to 4\r
+ * @param[in] halfwordNum HalfWord part number, should be 0 (lower) or 1(upper)\r
+ * @param[in] bitValue Value that contains all bits in to set,\r
+ * in range from 0 to 0xFFFF.\r
+ * @return None\r
+ *\r
+ * Note:\r
+ * - For all bits that has been set as input direction, this function will\r
+ * not effect.\r
+ * - For all remaining bits that are not activated in bitValue (value '0')\r
+ * will not be effected by this function.\r
+ **********************************************************************/\r
+void FIO_HalfWordSetValue(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue)\r
+{\r
+ GPIO_HalfWord_TypeDef *pFIO = FIO_HalfWordGetPointer(portNum);\r
+ if(pFIO != NULL) {\r
+ // Upper\r
+ if(halfwordNum) {\r
+ pFIO->FIOSETU = bitValue;\r
+ }\r
+ // lower\r
+ else {\r
+ pFIO->FIOSETL = bitValue;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Clear bits for FIO port in halfword accessible style\r
+ * @param[in] portNum Port number, in range from 0 to 4\r
+ * @param[in] halfwordNum HalfWord part number, should be 0 (lower) or 1(upper)\r
+ * @param[in] bitValue Value that contains all bits in to clear,\r
+ * in range from 0 to 0xFFFF.\r
+ * @return None\r
+ *\r
+ * Note:\r
+ * - For all bits that has been set as input direction, this function will\r
+ * not effect.\r
+ * - For all remaining bits that are not activated in bitValue (value '0')\r
+ * will not be effected by this function.\r
+ **********************************************************************/\r
+void FIO_HalfWordClearValue(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue)\r
+{\r
+ GPIO_HalfWord_TypeDef *pFIO = FIO_HalfWordGetPointer(portNum);\r
+ if(pFIO != NULL) {\r
+ // Upper\r
+ if(halfwordNum) {\r
+ pFIO->FIOCLRU = bitValue;\r
+ }\r
+ // lower\r
+ else {\r
+ pFIO->FIOCLRL = bitValue;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Read Current state on port pin that have input direction of GPIO\r
+ * in halfword accessible style.\r
+ * @param[in] portNum Port number, in range from 0 to 4\r
+ * @param[in] halfwordNum HalfWord part number, should be 0 (lower) or 1(upper)\r
+ * @return Current value of FIO port pin of specified halfword.\r
+ * Note: Return value contain state of each port pin (bit) on that FIO regardless\r
+ * its direction is input or output.\r
+ **********************************************************************/\r
+uint16_t FIO_HalfWordReadValue(uint8_t portNum, uint8_t halfwordNum)\r
+{\r
+ GPIO_HalfWord_TypeDef *pFIO = FIO_HalfWordGetPointer(portNum);\r
+ if(pFIO != NULL) {\r
+ // Upper\r
+ if(halfwordNum) {\r
+ return (pFIO->FIOPINU);\r
+ }\r
+ // lower\r
+ else {\r
+ return (pFIO->FIOPINL);\r
+ }\r
+ }\r
+ return (0);\r
+}\r
+\r
+\r
+/* FIO Byte accessible ------------------------------------------------------------ */\r
+\r
+/*********************************************************************//**\r
+ * @brief Set direction for FIO port in byte accessible style\r
+ * @param[in] portNum Port number, in range from 0 to 4\r
+ * @param[in] byteNum Byte part number, should be in range from 0 to 3\r
+ * @param[in] bitValue Value that contains all bits in to set direction,\r
+ * in range from 0 to 0xFF.\r
+ * @param[in] dir Direction value, should be:\r
+ * - 0: Input.\r
+ * - 1: Output.\r
+ * @return None\r
+ *\r
+ * Note: All remaining bits that are not activated in bitValue (value '0')\r
+ * will not be effected by this function.\r
+ **********************************************************************/\r
+void FIO_ByteSetDir(uint8_t portNum, uint8_t byteNum, uint8_t bitValue, uint8_t dir)\r
+{\r
+ GPIO_Byte_TypeDef *pFIO = FIO_ByteGetPointer(portNum);\r
+ if(pFIO != NULL) {\r
+ // Output direction\r
+ if (dir) {\r
+ if ((byteNum >= 0) && (byteNum <= 3)) {\r
+ pFIO->FIODIR[byteNum] |= bitValue;\r
+ }\r
+ }\r
+ // Input direction\r
+ else {\r
+ if ((byteNum >= 0) && (byteNum <= 3)) {\r
+ pFIO->FIODIR[byteNum] &= ~bitValue;\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief Set mask value for bits in FIO port in byte accessible style\r
+ * @param[in] portNum Port number, in range from 0 to 4\r
+ * @param[in] byteNum Byte part number, should be in range from 0 to 3\r
+ * @param[in] bitValue Value that contains all bits in to set mask,\r
+ * in range from 0 to 0xFF.\r
+ * @param[in] maskValue Mask value contains state value for each bit:\r
+ * - 0: not mask.\r
+ * - 1: mask.\r
+ * @return None\r
+ *\r
+ * Note:\r
+ * - All remaining bits that are not activated in bitValue (value '0')\r
+ * will not be effected by this function.\r
+ * - After executing this function, in mask register, value '0' on each bit\r
+ * enables an access to the corresponding physical pin via a read or write access,\r
+ * while value '1' on bit (masked) that corresponding pin will not be changed\r
+ * with write access and if read, will not be reflected in the updated pin.\r
+ **********************************************************************/\r
+void FIO_ByteSetMask(uint8_t portNum, uint8_t byteNum, uint8_t bitValue, uint8_t maskValue)\r
+{\r
+ GPIO_Byte_TypeDef *pFIO = FIO_ByteGetPointer(portNum);\r
+ if(pFIO != NULL) {\r
+ // Mask\r
+ if (maskValue) {\r
+ if ((byteNum >= 0) && (byteNum <= 3)) {\r
+ pFIO->FIOMASK[byteNum] |= bitValue;\r
+ }\r
+ }\r
+ // Un-mask\r
+ else {\r
+ if ((byteNum >= 0) && (byteNum <= 3)) {\r
+ pFIO->FIOMASK[byteNum] &= ~bitValue;\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Set bits for FIO port in byte accessible style\r
+ * @param[in] portNum Port number, in range from 0 to 4\r
+ * @param[in] byteNum Byte part number, should be in range from 0 to 3\r
+ * @param[in] bitValue Value that contains all bits in to set,\r
+ * in range from 0 to 0xFF.\r
+ * @return None\r
+ *\r
+ * Note:\r
+ * - For all bits that has been set as input direction, this function will\r
+ * not effect.\r
+ * - For all remaining bits that are not activated in bitValue (value '0')\r
+ * will not be effected by this function.\r
+ **********************************************************************/\r
+void FIO_ByteSetValue(uint8_t portNum, uint8_t byteNum, uint8_t bitValue)\r
+{\r
+ GPIO_Byte_TypeDef *pFIO = FIO_ByteGetPointer(portNum);\r
+ if (pFIO != NULL) {\r
+ if ((byteNum >= 0) && (byteNum <= 3)){\r
+ pFIO->FIOSET[byteNum] = bitValue;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Clear bits for FIO port in byte accessible style\r
+ * @param[in] portNum Port number, in range from 0 to 4\r
+ * @param[in] byteNum Byte part number, should be in range from 0 to 3\r
+ * @param[in] bitValue Value that contains all bits in to clear,\r
+ * in range from 0 to 0xFF.\r
+ * @return None\r
+ *\r
+ * Note:\r
+ * - For all bits that has been set as input direction, this function will\r
+ * not effect.\r
+ * - For all remaining bits that are not activated in bitValue (value '0')\r
+ * will not be effected by this function.\r
+ **********************************************************************/\r
+void FIO_ByteClearValue(uint8_t portNum, uint8_t byteNum, uint8_t bitValue)\r
+{\r
+ GPIO_Byte_TypeDef *pFIO = FIO_ByteGetPointer(portNum);\r
+ if (pFIO != NULL) {\r
+ if ((byteNum >= 0) && (byteNum <= 3)){\r
+ pFIO->FIOCLR[byteNum] = bitValue;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Read Current state on port pin that have input direction of GPIO\r
+ * in byte accessible style.\r
+ * @param[in] portNum Port number, in range from 0 to 4\r
+ * @param[in] byteNum Byte part number, should be in range from 0 to 3\r
+ * @return Current value of FIO port pin of specified byte part.\r
+ * Note: Return value contain state of each port pin (bit) on that FIO regardless\r
+ * its direction is input or output.\r
+ **********************************************************************/\r
+uint8_t FIO_ByteReadValue(uint8_t portNum, uint8_t byteNum)\r
+{\r
+ GPIO_Byte_TypeDef *pFIO = FIO_ByteGetPointer(portNum);\r
+ if (pFIO != NULL) {\r
+ if ((byteNum >= 0) && (byteNum <= 3)){\r
+ return (pFIO->FIOPIN[byteNum]);\r
+ }\r
+ }\r
+ return (0);\r
+}\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#endif /* _GPIO */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* --------------------------------- End Of File ------------------------------ */\r
--- /dev/null
+/***********************************************************************//**\r
+ * @file : lpc17xx_gpio.h\r
+ * @brief : Contains all macro definitions and function prototypes\r
+ * support for GPIO firmware library on LPC17xx\r
+ * @version : 1.0\r
+ * @date : 23. Apr. 2009\r
+ * @author : HieuNguyen\r
+ **************************************************************************\r
+ * Software that is described herein is for illustrative purposes only\r
+ * which provides customers with programming information regarding the\r
+ * products. This software is supplied "AS IS" without any warranties.\r
+ * NXP Semiconductors assumes no responsibility or liability for the\r
+ * use of the software, conveys no license or title under any patent,\r
+ * copyright, or mask work right to the product. NXP Semiconductors\r
+ * reserves the right to make changes in the software without\r
+ * notification. NXP Semiconductors also make no representation or\r
+ * warranty that such application will be suitable for the specified\r
+ * use without further testing or modification.\r
+ **************************************************************************/\r
+\r
+/* Peripheral group ----------------------------------------------------------- */\r
+/** @defgroup GPIO\r
+ * @ingroup LPC1700CMSIS_FwLib_Drivers\r
+ * @{\r
+ */\r
+\r
+#ifndef LPC17XX_GPIO_H_\r
+#define LPC17XX_GPIO_H_\r
+\r
+/* Includes ------------------------------------------------------------------- */\r
+#include "LPC17xx.h"\r
+#include "lpc_types.h"\r
+\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif\r
+\r
+\r
+/* Public Types --------------------------------------------------------------- */\r
+/** @defgroup GPIO_Public_Types\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief Fast GPIO port byte type definition\r
+ */\r
+typedef struct {\r
+ __IO uint8_t FIODIR[4]; /**< FIO direction register in byte-align */\r
+ uint32_t RESERVED0[3]; /**< Reserved */\r
+ __IO uint8_t FIOMASK[4]; /**< FIO mask register in byte-align */\r
+ __IO uint8_t FIOPIN[4]; /**< FIO pin register in byte align */\r
+ __IO uint8_t FIOSET[4]; /**< FIO set register in byte-align */\r
+ __O uint8_t FIOCLR[4]; /**< FIO clear register in byte-align */\r
+} GPIO_Byte_TypeDef;\r
+\r
+\r
+/**\r
+ * @brief Fast GPIO port half-word type definition\r
+ */\r
+typedef struct {\r
+ __IO uint16_t FIODIRL; /**< FIO direction register lower halfword part */\r
+ __IO uint16_t FIODIRU; /**< FIO direction register upper halfword part */\r
+ uint32_t RESERVED0[3]; /**< Reserved */\r
+ __IO uint16_t FIOMASKL; /**< FIO mask register lower halfword part */\r
+ __IO uint16_t FIOMASKU; /**< FIO mask register upper halfword part */\r
+ __IO uint16_t FIOPINL; /**< FIO pin register lower halfword part */\r
+ __IO uint16_t FIOPINU; /**< FIO pin register upper halfword part */\r
+ __IO uint16_t FIOSETL; /**< FIO set register lower halfword part */\r
+ __IO uint16_t FIOSETU; /**< FIO set register upper halfword part */\r
+ __O uint16_t FIOCLRL; /**< FIO clear register lower halfword part */\r
+ __O uint16_t FIOCLRU; /**< FIO clear register upper halfword part */\r
+} GPIO_HalfWord_TypeDef;\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Macros -------------------------------------------------------------- */\r
+/** @defgroup GPIO_Public_Macros\r
+ * @{\r
+ */\r
+\r
+/** Fast GPIO port 0 byte accessible definition */\r
+#define GPIO0_Byte ((GPIO_Byte_TypeDef *)(LPC_GPIO0_BASE))\r
+/** Fast GPIO port 1 byte accessible definition */\r
+#define GPIO1_Byte ((GPIO_Byte_TypeDef *)(LPC_GPIO1_BASE))\r
+/** Fast GPIO port 2 byte accessible definition */\r
+#define GPIO2_Byte ((GPIO_Byte_TypeDef *)(LPC_GPIO2_BASE))\r
+/** Fast GPIO port 3 byte accessible definition */\r
+#define GPIO3_Byte ((GPIO_Byte_TypeDef *)(LPC_GPIO3_BASE))\r
+/** Fast GPIO port 4 byte accessible definition */\r
+#define GPIO4_Byte ((GPIO_Byte_TypeDef *)(LPC_GPIO4_BASE))\r
+\r
+\r
+\r
+/** Fast GPIO port 0 half-word accessible definition */\r
+#define GPIO0_HalfWord ((GPIO_HalfWord_TypeDef *)(LPC_GPIO0_BASE))\r
+/** Fast GPIO port 1 half-word accessible definition */\r
+#define GPIO1_HalfWord ((GPIO_HalfWord_TypeDef *)(LPC_GPIO1_BASE))\r
+/** Fast GPIO port 2 half-word accessible definition */\r
+#define GPIO2_HalfWord ((GPIO_HalfWord_TypeDef *)(LPC_GPIO2_BASE))\r
+/** Fast GPIO port 3 half-word accessible definition */\r
+#define GPIO3_HalfWord ((GPIO_HalfWord_TypeDef *)(LPC_GPIO3_BASE))\r
+/** Fast GPIO port 4 half-word accessible definition */\r
+#define GPIO4_HalfWord ((GPIO_HalfWord_TypeDef *)(LPC_GPIO4_BASE))\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Functions ----------------------------------------------------------- */\r
+/** @defgroup GPIO_Public_Functions\r
+ * @{\r
+ */\r
+\r
+/* GPIO style ------------------------------- */\r
+void GPIO_SetDir(uint8_t portNum, uint32_t bitValue, uint8_t dir);\r
+void GPIO_SetValue(uint8_t portNum, uint32_t bitValue);\r
+void GPIO_ClearValue(uint8_t portNum, uint32_t bitValue);\r
+uint32_t GPIO_ReadValue(uint8_t portNum);\r
+\r
+/* FIO (word-accessible) style ------------------------------- */\r
+void FIO_SetDir(uint8_t portNum, uint32_t bitValue, uint8_t dir);\r
+void FIO_SetValue(uint8_t portNum, uint32_t bitValue);\r
+void FIO_ClearValue(uint8_t portNum, uint32_t bitValue);\r
+uint32_t FIO_ReadValue(uint8_t portNum);\r
+void FIO_SetMask(uint8_t portNum, uint32_t bitValue, uint8_t maskValue);\r
+\r
+/* FIO (halfword-accessible) style ------------------------------- */\r
+void FIO_HalfWordSetDir(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue, uint8_t dir);\r
+void FIO_HalfWordSetMask(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue, uint8_t maskValue);\r
+void FIO_HalfWordSetValue(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue);\r
+void FIO_HalfWordClearValue(uint8_t portNum, uint8_t halfwordNum, uint16_t bitValue);\r
+uint16_t FIO_HalfWordReadValue(uint8_t portNum, uint8_t halfwordNum);\r
+\r
+/* FIO (byte-accessible) style ------------------------------- */\r
+void FIO_ByteSetDir(uint8_t portNum, uint8_t byteNum, uint8_t bitValue, uint8_t dir);\r
+void FIO_ByteSetMask(uint8_t portNum, uint8_t byteNum, uint8_t bitValue, uint8_t maskValue);\r
+void FIO_ByteSetValue(uint8_t portNum, uint8_t byteNum, uint8_t bitValue);\r
+void FIO_ByteClearValue(uint8_t portNum, uint8_t byteNum, uint8_t bitValue);\r
+uint8_t FIO_ByteReadValue(uint8_t portNum, uint8_t byteNum);\r
+\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* LPC17XX_GPIO_H_ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* --------------------------------- End Of File ------------------------------ */\r
--- /dev/null
+/**\r
+ * @file : lpc17xx_i2c.c\r
+ * @brief : Contains all functions support for I2C firmware library on LPC17xx\r
+ * @version : 1.0\r
+ * @date : 9. April. 2009\r
+ * @author : HieuNguyen\r
+ **************************************************************************\r
+ * Software that is described herein is for illustrative purposes only\r
+ * which provides customers with programming information regarding the\r
+ * products. This software is supplied "AS IS" without any warranties.\r
+ * NXP Semiconductors assumes no responsibility or liability for the\r
+ * use of the software, conveys no license or title under any patent,\r
+ * copyright, or mask work right to the product. NXP Semiconductors\r
+ * reserves the right to make changes in the software without\r
+ * notification. NXP Semiconductors also make no representation or\r
+ * warranty that such application will be suitable for the specified\r
+ * use without further testing or modification.\r
+ **********************************************************************/\r
+\r
+/* Peripheral group ----------------------------------------------------------- */\r
+/** @addtogroup I2C\r
+ * @{\r
+ */\r
+\r
+/* Includes ------------------------------------------------------------------- */\r
+#include "lpc17xx_i2c.h"\r
+#include "lpc17xx_clkpwr.h"\r
+#include "lpc17xx_pinsel.h"\r
+\r
+\r
+/* If this source file built with example, the LPC17xx FW library configuration\r
+ * file in each example directory ("lpc17xx_libcfg.h") must be included,\r
+ * otherwise the default FW library configuration file must be included instead\r
+ */\r
+#ifdef __BUILD_WITH_EXAMPLE__\r
+#include "lpc17xx_libcfg.h"\r
+#else\r
+#include "lpc17xx_libcfg_default.h"\r
+#endif /* __BUILD_WITH_EXAMPLE__ */\r
+\r
+\r
+#ifdef _I2C\r
+\r
+\r
+/* Private Types -------------------------------------------------------------- */\r
+/** @defgroup I2C_Private_Types\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief I2C device configuration structure type\r
+ */\r
+typedef struct\r
+{\r
+ uint32_t txrx_setup; /* Transmission setup */\r
+ int32_t dir; /* Current direction phase, 0 - write, 1 - read */\r
+ void (*inthandler)(LPC_I2C_TypeDef *I2Cx); /* Transmission interrupt handler */\r
+} I2C_CFG_T;\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* Private Variables ---------------------------------------------------------- */\r
+/**\r
+ * @brief II2C driver data for I2C0, I2C1 and I2C2\r
+ */\r
+static I2C_CFG_T i2cdat[3];\r
+\r
+\r
+\r
+/* Private Functions ---------------------------------------------------------- */\r
+/** @defgroup I2C_Private_Functions\r
+ * @{\r
+ */\r
+\r
+/* Generate a start condition on I2C bus (in master mode only) */\r
+static uint32_t I2C_Start (LPC_I2C_TypeDef *I2Cx);\r
+\r
+/* Generate a stop condition on I2C bus (in master mode only) */\r
+static void I2C_Stop (LPC_I2C_TypeDef *I2Cx);\r
+\r
+/* I2C send byte subroutine */\r
+static uint32_t I2C_SendByte (LPC_I2C_TypeDef *I2Cx, uint8_t databyte);\r
+\r
+/* I2C get byte subroutine */\r
+static uint32_t I2C_GetByte (LPC_I2C_TypeDef *I2Cx, uint8_t *retdat, Bool ack);\r
+\r
+/* I2C interrupt master handler */\r
+void I2C_MasterHandler (LPC_I2C_TypeDef *I2Cx);\r
+\r
+/* I2C interrupt master handler */\r
+void I2C_SlaveHandler (LPC_I2C_TypeDef *I2Cx);\r
+\r
+/* Enable interrupt for I2C device */\r
+void I2C_IntCmd (LPC_I2C_TypeDef *I2Cx, Bool NewState);\r
+\r
+/*--------------------------------------------------------------------------------*/\r
+\r
+/**\r
+ * @brief Convert from I2C peripheral to number\r
+ */\r
+static int32_t I2C_getNum(LPC_I2C_TypeDef *I2Cx){\r
+ if (I2Cx == LPC_I2C0) {\r
+ return (0);\r
+ } else if (I2Cx == LPC_I2C1) {\r
+ return (1);\r
+ } else if (I2Cx == LPC_I2C2) {\r
+ return (2);\r
+ }\r
+ return (-1);\r
+}\r
+\r
+/***********************************************************************\r
+ * Function: I2C_Start\r
+ * Purpose: Generate a start condition on I2C bus (in master mode only)\r
+ * Parameters:\r
+ * i2cdev: Pointer to I2C register\r
+ * blocking: blocking or none blocking mode\r
+ * Returns: value of I2C status register after generate a start condition\r
+ **********************************************************************/\r
+static uint32_t I2C_Start (LPC_I2C_TypeDef *I2Cx)\r
+{\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+ I2Cx->I2CONSET = I2C_I2CONSET_STA;\r
+\r
+ // Wait for complete\r
+ while (!(I2Cx->I2CONSET & I2C_I2CONSET_SI));\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_STAC;\r
+ return (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK);\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ * Function: I2C_Stop\r
+ * Purpose: Generate a stop condition on I2C bus (in master mode only)\r
+ * Parameters:\r
+ * I2Cx: Pointer to I2C register\r
+ * Returns: None\r
+ **********************************************************************/\r
+static void I2C_Stop (LPC_I2C_TypeDef *I2Cx)\r
+{\r
+\r
+ /* Make sure start bit is not active */\r
+ if (I2Cx->I2CONSET & I2C_I2CONSET_STA)\r
+ {\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_STAC;\r
+ }\r
+ I2Cx->I2CONSET = I2C_I2CONSET_STO;\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ * Function: I2C_SendByte\r
+ * Purpose: Send a byte\r
+ * Parameters:\r
+ * I2Cx: Pointer to I2C register\r
+ * Returns: value of I2C status register after sending\r
+ **********************************************************************/\r
+static uint32_t I2C_SendByte (LPC_I2C_TypeDef *I2Cx, uint8_t databyte)\r
+{\r
+ /* Make sure start bit is not active */\r
+ if (I2Cx->I2CONSET & I2C_I2CONSET_STA)\r
+ {\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_STAC;\r
+ }\r
+ I2Cx->I2DAT = databyte & I2C_I2DAT_BITMASK;\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+\r
+ while (!(I2Cx->I2CONSET & I2C_I2CONSET_SI));\r
+ return (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK);\r
+}\r
+\r
+\r
+/***********************************************************************\r
+ * Function: I2C_GetByte\r
+ * Purpose: Get a byte\r
+ * Parameters:\r
+ * I2Cx: Pointer to I2C register\r
+ * Returns: value of I2C status register after receiving\r
+ **********************************************************************/\r
+static uint32_t I2C_GetByte (LPC_I2C_TypeDef *I2Cx, uint8_t *retdat, Bool ack)\r
+{\r
+ if (ack == TRUE)\r
+ {\r
+ I2Cx->I2CONSET = I2C_I2CONSET_AA;\r
+ }\r
+ else\r
+ {\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_AAC;\r
+ }\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+\r
+ while (!(I2Cx->I2CONSET & I2C_I2CONSET_SI));\r
+ *retdat = (uint8_t) (I2Cx->I2DAT & I2C_I2DAT_BITMASK);\r
+ return (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK);\r
+}\r
+\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Enable/Disable interrupt for I2C peripheral\r
+ * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2\r
+ * @param[in] NewState New State of I2C peripheral interrupt in NVIC core\r
+ * should be:\r
+ * - ENABLE: enable interrupt for this I2C peripheral\r
+ * - DISABLE: disable interrupt for this I2C peripheral\r
+ * @return None\r
+ **********************************************************************/\r
+void I2C_IntCmd (LPC_I2C_TypeDef *I2Cx, Bool NewState)\r
+{\r
+ if (NewState)\r
+ {\r
+ if(I2Cx == LPC_I2C0)\r
+ {\r
+ NVIC_EnableIRQ(I2C0_IRQn);\r
+ }\r
+ else if (I2Cx == LPC_I2C1)\r
+ {\r
+ NVIC_EnableIRQ(I2C1_IRQn);\r
+ }\r
+ else if (I2Cx == LPC_I2C2)\r
+ {\r
+ NVIC_EnableIRQ(I2C2_IRQn);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if(I2Cx == LPC_I2C0)\r
+ {\r
+ NVIC_DisableIRQ(I2C0_IRQn);\r
+ }\r
+ else if (I2Cx == LPC_I2C1)\r
+ {\r
+ NVIC_DisableIRQ(I2C1_IRQn);\r
+ }\r
+ else if (I2Cx == LPC_I2C2)\r
+ {\r
+ NVIC_DisableIRQ(I2C2_IRQn);\r
+ }\r
+ }\r
+ return;\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief General Master Interrupt handler for I2C peripheral\r
+ * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2\r
+ * @return None\r
+ **********************************************************************/\r
+void I2C_MasterHandler (LPC_I2C_TypeDef *I2Cx)\r
+{\r
+ int32_t tmp;\r
+ uint8_t returnCode;\r
+ I2C_M_SETUP_Type *txrx_setup;\r
+\r
+ tmp = I2C_getNum(I2Cx);\r
+ txrx_setup = (I2C_M_SETUP_Type *) i2cdat[tmp].txrx_setup;\r
+\r
+ returnCode = (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK);\r
+ // Save current status\r
+ txrx_setup->status = returnCode;\r
+ // there's no relevant information\r
+ if (returnCode == I2C_I2STAT_NO_INF){\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+ return;\r
+ }\r
+\r
+ /* ----------------------------- TRANSMIT PHASE --------------------------*/\r
+ if (i2cdat[tmp].dir == 0){\r
+ switch (returnCode)\r
+ {\r
+ /* A start/repeat start condition has been transmitted -------------------*/\r
+ case I2C_I2STAT_M_TX_START:\r
+ case I2C_I2STAT_M_TX_RESTART:\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_STAC;\r
+ /*\r
+ * If there's any transmit data, then start to\r
+ * send SLA+W right now, otherwise check whether if there's\r
+ * any receive data for next state.\r
+ */\r
+ if ((txrx_setup->tx_data != NULL) && (txrx_setup->tx_length != 0)){\r
+ I2Cx->I2DAT = (txrx_setup->sl_addr7bit << 1);\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+ } else {\r
+ goto next_stage;\r
+ }\r
+ break;\r
+\r
+ /* SLA+W has been transmitted, ACK has been received ----------------------*/\r
+ case I2C_I2STAT_M_TX_SLAW_ACK:\r
+ /* Data has been transmitted, ACK has been received */\r
+ case I2C_I2STAT_M_TX_DAT_ACK:\r
+ /* Send more data */\r
+ if ((txrx_setup->tx_count < txrx_setup->tx_length) \\r
+ && (txrx_setup->tx_data != NULL)){\r
+ I2Cx->I2DAT = *(uint8_t *)(txrx_setup->tx_data + txrx_setup->tx_count);\r
+ txrx_setup->tx_count++;\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+ }\r
+ // no more data, switch to next stage\r
+ else {\r
+next_stage:\r
+ // change direction\r
+ i2cdat[tmp].dir = 1;\r
+ // Check if any data to receive\r
+ if ((txrx_setup->rx_length != 0) && (txrx_setup->rx_data != NULL)){\r
+ // check whether if we need to issue an repeat start\r
+ if ((txrx_setup->tx_length != 0) && (txrx_setup->tx_data != NULL)){\r
+ // Send out an repeat start command\r
+ I2Cx->I2CONSET = I2C_I2CONSET_STA;\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC;\r
+ }\r
+ // Don't need issue an repeat start, just goto send SLA+R\r
+ else {\r
+ goto send_slar;\r
+ }\r
+ }\r
+ // no more data send, the go to end stage now\r
+ else {\r
+ // success, goto end stage\r
+ txrx_setup->status |= I2C_SETUP_STATUS_DONE;\r
+ goto end_stage;\r
+ }\r
+ }\r
+ break;\r
+\r
+ /* SLA+W has been transmitted, NACK has been received ----------------------*/\r
+ case I2C_I2STAT_M_TX_SLAW_NACK:\r
+ /* Data has been transmitted, NACK has been received -----------------------*/\r
+ case I2C_I2STAT_M_TX_DAT_NACK:\r
+ // update status\r
+ txrx_setup->status |= I2C_SETUP_STATUS_NOACKF;\r
+ goto retry;\r
+ break;\r
+ /* Arbitration lost in SLA+R/W or Data bytes -------------------------------*/\r
+ case I2C_I2STAT_M_TX_ARB_LOST:\r
+ // update status\r
+ txrx_setup->status |= I2C_SETUP_STATUS_ARBF;\r
+ default:\r
+ goto retry;\r
+ break;\r
+ }\r
+ }\r
+\r
+ /* ----------------------------- RECEIVE PHASE --------------------------*/\r
+ else if (i2cdat[tmp].dir == 1){\r
+ switch (returnCode){\r
+ /* A start/repeat start condition has been transmitted ---------------------*/\r
+ case I2C_I2STAT_M_RX_START:\r
+ case I2C_I2STAT_M_RX_RESTART:\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_STAC;\r
+ /*\r
+ * If there's any receive data, then start to\r
+ * send SLA+R right now, otherwise check whether if there's\r
+ * any receive data for end of state.\r
+ */\r
+ if ((txrx_setup->rx_data != NULL) && (txrx_setup->rx_length != 0)){\r
+send_slar:\r
+ I2Cx->I2DAT = (txrx_setup->sl_addr7bit << 1) | 0x01;\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+ } else {\r
+ // Success, goto end stage\r
+ txrx_setup->status |= I2C_SETUP_STATUS_DONE;\r
+ goto end_stage;\r
+ }\r
+ break;\r
+\r
+ /* SLA+R has been transmitted, ACK has been received -----------------*/\r
+ case I2C_I2STAT_M_RX_SLAR_ACK:\r
+ if (txrx_setup->rx_count < (txrx_setup->rx_length - 1)) {\r
+ /*Data will be received, ACK will be return*/\r
+ I2Cx->I2CONSET = I2C_I2CONSET_AA;\r
+ }\r
+ else {\r
+ /*Last data will be received, NACK will be return*/\r
+ I2Cx->I2CONCLR = I2C_I2CONSET_AA;\r
+ }\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+ break;\r
+\r
+ /* Data has been received, ACK has been returned ----------------------*/\r
+ case I2C_I2STAT_M_RX_DAT_ACK:\r
+ // Note save data and increase counter first, then check later\r
+ /* Save data */\r
+ if ((txrx_setup->rx_data != NULL) && (txrx_setup->rx_count < txrx_setup->rx_length)){\r
+ *(uint8_t *)(txrx_setup->rx_data + txrx_setup->rx_count) = (I2Cx->I2DAT & I2C_I2DAT_BITMASK);\r
+ txrx_setup->rx_count++;\r
+ }\r
+ if (txrx_setup->rx_count < (txrx_setup->rx_length - 1)) {\r
+ /*Data will be received, ACK will be return*/\r
+ I2Cx->I2CONSET = I2C_I2CONSET_AA;\r
+ }\r
+ else {\r
+ /*Last data will be received, NACK will be return*/\r
+ I2Cx->I2CONCLR = I2C_I2CONSET_AA;\r
+ }\r
+\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+ break;\r
+\r
+ /* Data has been received, NACK has been return -------------------------*/\r
+ case I2C_I2STAT_M_RX_DAT_NACK:\r
+ /* Save the last data */\r
+ if ((txrx_setup->rx_data != NULL) && (txrx_setup->rx_count < txrx_setup->rx_length)){\r
+ *(uint8_t *)(txrx_setup->rx_data + txrx_setup->rx_count) = (I2Cx->I2DAT & I2C_I2DAT_BITMASK);\r
+ txrx_setup->rx_count++;\r
+ }\r
+ // success, go to end stage\r
+ txrx_setup->status |= I2C_SETUP_STATUS_DONE;\r
+ goto end_stage;\r
+ break;\r
+\r
+ /* SLA+R has been transmitted, NACK has been received ------------------*/\r
+ case I2C_I2STAT_M_RX_SLAR_NACK:\r
+ // update status\r
+ txrx_setup->status |= I2C_SETUP_STATUS_NOACKF;\r
+ goto retry;\r
+ break;\r
+\r
+ /* Arbitration lost ----------------------------------------------------*/\r
+ case I2C_I2STAT_M_RX_ARB_LOST:\r
+ // update status\r
+ txrx_setup->status |= I2C_SETUP_STATUS_ARBF;\r
+ default:\r
+retry:\r
+ // check if retransmission is available\r
+ if (txrx_setup->retransmissions_count < txrx_setup->retransmissions_max){\r
+ // Clear tx count\r
+ txrx_setup->tx_count = 0;\r
+ I2Cx->I2CONSET = I2C_I2CONSET_STA;\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC;\r
+ txrx_setup->retransmissions_count++;\r
+ }\r
+ // End of stage\r
+ else {\r
+end_stage:\r
+ // Disable interrupt\r
+ I2C_IntCmd(I2Cx, 0);\r
+ // Send stop\r
+ I2C_Stop(I2Cx);\r
+ // Call callback if installed\r
+ if (txrx_setup->callback != NULL){\r
+ txrx_setup->callback();\r
+ }\r
+ }\r
+ break;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief General Slave Interrupt handler for I2C peripheral\r
+ * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2\r
+ * @return None\r
+ **********************************************************************/\r
+void I2C_SlaveHandler (LPC_I2C_TypeDef *I2Cx)\r
+{\r
+ int32_t tmp;\r
+ uint8_t returnCode;\r
+ I2C_S_SETUP_Type *txrx_setup;\r
+ uint32_t timeout;\r
+\r
+ tmp = I2C_getNum(I2Cx);\r
+ txrx_setup = (I2C_S_SETUP_Type *) i2cdat[tmp].txrx_setup;\r
+\r
+ returnCode = (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK);\r
+ // Save current status\r
+ txrx_setup->status = returnCode;\r
+ // there's no relevant information\r
+ if (returnCode == I2C_I2STAT_NO_INF){\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+ return;\r
+ }\r
+\r
+\r
+ switch (returnCode)\r
+ {\r
+\r
+ /* No status information */\r
+ case I2C_I2STAT_NO_INF:\r
+ I2Cx->I2CONSET = I2C_I2CONSET_AA;\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+ break;\r
+\r
+ /* Reading phase -------------------------------------------------------- */\r
+ /* Own SLA+R has been received, ACK has been returned */\r
+ case I2C_I2STAT_S_RX_SLAW_ACK:\r
+ /* General call address has been received, ACK has been returned */\r
+ case I2C_I2STAT_S_RX_GENCALL_ACK:\r
+ I2Cx->I2CONSET = I2C_I2CONSET_AA;\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+ break;\r
+\r
+ /* Previously addressed with own SLA;\r
+ * DATA byte has been received;\r
+ * ACK has been returned */\r
+ case I2C_I2STAT_S_RX_PRE_SLA_DAT_ACK:\r
+ /* DATA has been received, ACK hasn been return */\r
+ case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_ACK:\r
+ /*\r
+ * All data bytes that over-flow the specified receive\r
+ * data length, just ignore them.\r
+ */\r
+ if ((txrx_setup->rx_count < txrx_setup->rx_length) \\r
+ && (txrx_setup->rx_data != NULL)){\r
+ *(uint8_t *)(txrx_setup->rx_data + txrx_setup->rx_count) = (uint8_t)I2Cx->I2DAT;\r
+ txrx_setup->rx_count++;\r
+ }\r
+ I2Cx->I2CONSET = I2C_I2CONSET_AA;\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+ break;\r
+\r
+ /* Previously addressed with own SLA;\r
+ * DATA byte has been received;\r
+ * NOT ACK has been returned */\r
+ case I2C_I2STAT_S_RX_PRE_SLA_DAT_NACK:\r
+ /* DATA has been received, NOT ACK has been returned */\r
+ case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_NACK:\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+ break;\r
+\r
+ /*\r
+ * Note that: Return code only let us know a stop condition mixed\r
+ * with a repeat start condition in the same code value.\r
+ * So we should provide a time-out. In case this is really a stop\r
+ * condition, this will return back after time out condition. Otherwise,\r
+ * next session that is slave receive data will be completed.\r
+ */\r
+\r
+ /* A Stop or a repeat start condition */\r
+ case I2C_I2STAT_S_RX_STA_STO_SLVREC_SLVTRX:\r
+ // Temporally lock the interrupt for timeout condition\r
+ I2C_IntCmd(I2Cx, 0);\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+ // enable time out\r
+ timeout = I2C_SLAVE_TIME_OUT;\r
+ while(1){\r
+ if (I2Cx->I2CONSET & I2C_I2CONSET_SI){\r
+ // re-Enable interrupt\r
+ I2C_IntCmd(I2Cx, 1);\r
+ break;\r
+ } else {\r
+ timeout--;\r
+ if (timeout == 0){\r
+ // timeout occur, it's really a stop condition\r
+ txrx_setup->status |= I2C_SETUP_STATUS_DONE;\r
+ goto s_int_end;\r
+ }\r
+ }\r
+ }\r
+ break;\r
+\r
+ /* Writing phase -------------------------------------------------------- */\r
+ /* Own SLA+R has been received, ACK has been returned */\r
+ case I2C_I2STAT_S_TX_SLAR_ACK:\r
+ /* Data has been transmitted, ACK has been received */\r
+ case I2C_I2STAT_S_TX_DAT_ACK:\r
+ /*\r
+ * All data bytes that over-flow the specified receive\r
+ * data length, just ignore them.\r
+ */\r
+ if ((txrx_setup->tx_count < txrx_setup->tx_length) \\r
+ && (txrx_setup->tx_data != NULL)){\r
+ I2Cx->I2DAT = *(uint8_t *) (txrx_setup->tx_data + txrx_setup->tx_count);\r
+ txrx_setup->tx_count++;\r
+ }\r
+ I2Cx->I2CONSET = I2C_I2CONSET_AA;\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+ break;\r
+\r
+ /* Data has been transmitted, NACK has been received,\r
+ * that means there's no more data to send, exit now */\r
+ /*\r
+ * Note: Don't wait for stop event since in slave transmit mode,\r
+ * since there no proof lets us know when a stop signal has been received\r
+ * on slave side.\r
+ */\r
+ case I2C_I2STAT_S_TX_DAT_NACK:\r
+ I2Cx->I2CONSET = I2C_I2CONSET_AA;\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+ txrx_setup->status |= I2C_SETUP_STATUS_DONE;\r
+ goto s_int_end;\r
+ break;\r
+\r
+ // Other status must be captured\r
+ default:\r
+s_int_end:\r
+ // Disable interrupt\r
+ I2C_IntCmd(I2Cx, 0);\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_AAC | I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC;\r
+ // Call callback if installed\r
+ if (txrx_setup->callback != NULL){\r
+ txrx_setup->callback();\r
+ }\r
+ break;\r
+ }\r
+}\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Functions ----------------------------------------------------------- */\r
+/** @addtogroup I2C_Public_Functions\r
+ * @{\r
+ */\r
+\r
+/*********************************************************************//**\r
+ * @brief Setup clock rate for I2C peripheral\r
+ * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2\r
+ * @param[in] target_clock : clock of SSP (Hz)\r
+ * @return None\r
+ ***********************************************************************/\r
+void I2C_SetClock (LPC_I2C_TypeDef *I2Cx, uint32_t target_clock)\r
+{\r
+ uint32_t temp;\r
+\r
+ CHECK_PARAM(PARAM_I2Cx(I2Cx));\r
+\r
+ // Get PCLK of I2C controller\r
+ if (I2Cx == LPC_I2C0)\r
+ {\r
+ temp = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_I2C0) / target_clock;\r
+ }\r
+ else if (I2Cx == LPC_I2C1)\r
+ {\r
+ temp = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_I2C1) / target_clock;\r
+ }\r
+ else if (I2Cx == LPC_I2C2)\r
+ {\r
+ temp = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_I2C1) / target_clock;\r
+ }\r
+\r
+ /* Set the I2C clock value to register */\r
+ I2Cx->I2SCLH = (uint32_t)(temp / 2);\r
+ I2Cx->I2SCLL = (uint32_t)(temp - I2Cx->I2SCLH);\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief De-initializes the I2C peripheral registers to their\r
+* default reset values.\r
+ * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2\r
+ * @return None\r
+ **********************************************************************/\r
+void I2C_DeInit(LPC_I2C_TypeDef* I2Cx)\r
+{\r
+ CHECK_PARAM(PARAM_I2Cx(I2Cx));\r
+\r
+ /* Disable I2C control */\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_I2ENC;\r
+\r
+ if (I2Cx==LPC_I2C0)\r
+ {\r
+ /* Disable power for I2C0 module */\r
+ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C0, DISABLE);\r
+ }\r
+ else if (I2Cx==LPC_I2C1)\r
+ {\r
+ /* Disable power for I2C1 module */\r
+ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C1, DISABLE);\r
+ }\r
+ else if (I2Cx==LPC_I2C2)\r
+ {\r
+ /* Disable power for I2C2 module */\r
+ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C2, DISABLE);\r
+ }\r
+}\r
+\r
+\r
+/********************************************************************//**\r
+ * @brief Initializes the I2Cx peripheral with specified parameter.\r
+ * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2\r
+ * @param[in] clockrate Target clock rate value to initialized I2C\r
+ * peripheral\r
+ * @return None\r
+ *********************************************************************/\r
+void I2C_Init(LPC_I2C_TypeDef *I2Cx, uint32_t clockrate)\r
+{\r
+ CHECK_PARAM(PARAM_I2Cx(I2Cx));\r
+\r
+ if (I2Cx==LPC_I2C0)\r
+ {\r
+ /* Set up clock and power for I2C0 module */\r
+ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C0, ENABLE);\r
+ /* As default, peripheral clock for I2C0 module\r
+ * is set to FCCLK / 2 */\r
+ CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_I2C0, CLKPWR_PCLKSEL_CCLK_DIV_2);\r
+ }\r
+ else if (I2Cx==LPC_I2C1)\r
+ {\r
+ /* Set up clock and power for I2C1 module */\r
+ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C1, ENABLE);\r
+ /* As default, peripheral clock for I2C1 module\r
+ * is set to FCCLK / 2 */\r
+ CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_I2C1, CLKPWR_PCLKSEL_CCLK_DIV_2);\r
+ }\r
+ else if (I2Cx==LPC_I2C2)\r
+ {\r
+ /* Set up clock and power for I2C2 module */\r
+ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCI2C2, ENABLE);\r
+ /* As default, peripheral clock for I2C2 module\r
+ * is set to FCCLK / 2 */\r
+ CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_I2C2, CLKPWR_PCLKSEL_CCLK_DIV_2);\r
+ }\r
+ else {\r
+ // Up-Support this device\r
+ return;\r
+ }\r
+\r
+ /* Set clock rate */\r
+ I2C_SetClock(I2Cx, clockrate);\r
+ /* Set I2C operation to default */\r
+ I2Cx->I2CONCLR = (I2C_I2CONCLR_AAC | I2C_I2CONCLR_STAC | I2C_I2CONCLR_I2ENC);\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Enable or disable I2C peripheral's operation\r
+ * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2\r
+ * @param[in] NewState New State of I2Cx peripheral's operation\r
+ * @return none\r
+ **********************************************************************/\r
+void I2C_Cmd(LPC_I2C_TypeDef* I2Cx, FunctionalState NewState)\r
+{\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));\r
+ CHECK_PARAM(PARAM_I2Cx(I2Cx));\r
+\r
+ if (NewState == ENABLE)\r
+ {\r
+ I2Cx->I2CONSET = I2C_I2CONSET_I2EN;\r
+ }\r
+ else\r
+ {\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_I2ENC;\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Transmit and Receive data in master mode\r
+ * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2\r
+ * @param[in] TransferCfg Pointer to a I2C_M_SETUP_Type structure that\r
+ * contains specified information about the\r
+ * configuration for master transfer.\r
+ * @param[in] Opt a I2C_TRANSFER_OPT_Type type that selected for\r
+ * interrupt or polling mode.\r
+ * @return SUCCESS or ERROR\r
+ *\r
+ * Note:\r
+ * - In case of using I2C to transmit data only, either transmit length set to 0\r
+ * or transmit data pointer set to NULL.\r
+ * - In case of using I2C to receive data only, either receive length set to 0\r
+ * or receive data pointer set to NULL.\r
+ * - In case of using I2C to transmit followed by receive data, transmit length,\r
+ * transmit data pointer, receive length and receive data pointer should be set\r
+ * corresponding.\r
+ **********************************************************************/\r
+Status I2C_MasterTransferData(LPC_I2C_TypeDef *I2Cx, I2C_M_SETUP_Type *TransferCfg, \\r
+ I2C_TRANSFER_OPT_Type Opt)\r
+{\r
+ uint8_t *txdat;\r
+ uint8_t *rxdat;\r
+ uint32_t CodeStatus;\r
+ uint8_t tmp;\r
+\r
+ // reset all default state\r
+ txdat = (uint8_t *) TransferCfg->tx_data;\r
+ rxdat = (uint8_t *) TransferCfg->rx_data;\r
+ // Reset I2C setup value to default state\r
+ TransferCfg->tx_count = 0;\r
+ TransferCfg->rx_count = 0;\r
+ TransferCfg->status = 0;\r
+\r
+ if (Opt == I2C_TRANSFER_POLLING){\r
+\r
+ /* First Start condition -------------------------------------------------------------- */\r
+ TransferCfg->retransmissions_count = 0;\r
+retry:\r
+ // reset all default state\r
+ txdat = (uint8_t *) TransferCfg->tx_data;\r
+ rxdat = (uint8_t *) TransferCfg->rx_data;\r
+ // Reset I2C setup value to default state\r
+ TransferCfg->tx_count = 0;\r
+ TransferCfg->rx_count = 0;\r
+ CodeStatus = 0;\r
+\r
+ // Start command\r
+ CodeStatus = I2C_Start(I2Cx);\r
+ if ((CodeStatus != I2C_I2STAT_M_TX_START) \\r
+ && (CodeStatus != I2C_I2STAT_M_TX_RESTART)){\r
+ TransferCfg->retransmissions_count++;\r
+ if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){\r
+ // save status\r
+ TransferCfg->status = CodeStatus;\r
+ goto error;\r
+ } else {\r
+ goto retry;\r
+ }\r
+ }\r
+\r
+ /* In case of sending data first --------------------------------------------------- */\r
+ if ((TransferCfg->tx_length != 0) && (TransferCfg->tx_data != NULL)){\r
+\r
+ /* Send slave address + WR direction bit = 0 ----------------------------------- */\r
+ CodeStatus = I2C_SendByte(I2Cx, (TransferCfg->sl_addr7bit << 1));\r
+ if (CodeStatus != I2C_I2STAT_M_TX_SLAW_ACK){\r
+ TransferCfg->retransmissions_count++;\r
+ if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){\r
+ // save status\r
+ TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF;\r
+ goto error;\r
+ } else {\r
+ goto retry;\r
+ }\r
+ }\r
+\r
+ /* Send a number of data bytes ---------------------------------------- */\r
+ while (TransferCfg->tx_count < TransferCfg->tx_length)\r
+ {\r
+ CodeStatus = I2C_SendByte(I2Cx, *txdat);\r
+ if (CodeStatus != I2C_I2STAT_M_TX_DAT_ACK){\r
+ TransferCfg->retransmissions_count++;\r
+ if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){\r
+ // save status\r
+ TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF;\r
+ goto error;\r
+ } else {\r
+ goto retry;\r
+ }\r
+ }\r
+\r
+ txdat++;\r
+ TransferCfg->tx_count++;\r
+ }\r
+ }\r
+\r
+ /* Second Start condition (Repeat Start) ------------------------------------------- */\r
+ if ((TransferCfg->tx_length != 0) && (TransferCfg->tx_data != NULL) \\r
+ && (TransferCfg->rx_length != 0) && (TransferCfg->rx_data != NULL)){\r
+\r
+ CodeStatus = I2C_Start(I2Cx);\r
+ if ((CodeStatus != I2C_I2STAT_M_RX_START) \\r
+ && (CodeStatus != I2C_I2STAT_M_RX_RESTART)){\r
+ TransferCfg->retransmissions_count++;\r
+ if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){\r
+ // Update status\r
+ TransferCfg->status = CodeStatus;\r
+ goto error;\r
+ } else {\r
+ goto retry;\r
+ }\r
+ }\r
+ }\r
+\r
+ /* Then, start reading after sending data -------------------------------------- */\r
+ if ((TransferCfg->rx_length != 0) && (TransferCfg->rx_data != NULL)){\r
+ /* Send slave address + RD direction bit = 1 ----------------------------------- */\r
+\r
+ CodeStatus = I2C_SendByte(I2Cx, ((TransferCfg->sl_addr7bit << 1) | 0x01));\r
+ if (CodeStatus != I2C_I2STAT_M_RX_SLAR_ACK){\r
+ TransferCfg->retransmissions_count++;\r
+ if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){\r
+ // update status\r
+ TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF;\r
+ goto error;\r
+ } else {\r
+ goto retry;\r
+ }\r
+ }\r
+\r
+ /* Receive a number of data bytes ------------------------------------------------- */\r
+ while (TransferCfg->rx_count < TransferCfg->rx_length){\r
+\r
+ /*\r
+ * Note that: if data length is only one, the master should not\r
+ * issue an ACK signal on bus after reading to avoid of next data frame\r
+ * on slave side\r
+ */\r
+ if (TransferCfg->rx_count < (TransferCfg->rx_length - 1)){\r
+ // Issue an ACK signal for next data frame\r
+ CodeStatus = I2C_GetByte(I2Cx, &tmp, 1);\r
+ if (CodeStatus != I2C_I2STAT_M_RX_DAT_ACK){\r
+ TransferCfg->retransmissions_count++;\r
+ if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){\r
+ // update status\r
+ TransferCfg->status = CodeStatus;\r
+ goto error;\r
+ } else {\r
+ goto retry;\r
+ }\r
+ }\r
+ } else {\r
+ // Do not issue an ACK signal\r
+ CodeStatus = I2C_GetByte(I2Cx, &tmp, 0);\r
+ if (CodeStatus != I2C_I2STAT_M_RX_DAT_NACK){\r
+ TransferCfg->retransmissions_count++;\r
+ if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){\r
+ // update status\r
+ TransferCfg->status = CodeStatus;\r
+ goto error;\r
+ } else {\r
+ goto retry;\r
+ }\r
+ }\r
+ }\r
+ *rxdat++ = tmp;\r
+ TransferCfg->rx_count++;\r
+ }\r
+ }\r
+\r
+ /* Send STOP condition ------------------------------------------------- */\r
+ I2C_Stop(I2Cx);\r
+ return SUCCESS;\r
+\r
+error:\r
+ // Send stop condition\r
+ I2C_Stop(I2Cx);\r
+ return ERROR;\r
+ }\r
+\r
+ else if (Opt == I2C_TRANSFER_INTERRUPT){\r
+ // Setup tx_rx data, callback and interrupt handler\r
+ tmp = I2C_getNum(I2Cx);\r
+ i2cdat[tmp].txrx_setup = (uint32_t) TransferCfg;\r
+ i2cdat[tmp].inthandler = I2C_MasterHandler;\r
+ // Set direction phase, write first\r
+ i2cdat[tmp].dir = 0;\r
+\r
+ /* First Start condition -------------------------------------------------------------- */\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+ I2Cx->I2CONSET = I2C_I2CONSET_STA;\r
+ I2C_IntCmd(I2Cx, 1);\r
+\r
+ return (SUCCESS);\r
+ }\r
+\r
+ return ERROR;\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief Receive and Transmit data in slave mode\r
+ * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2\r
+ * @param[in] TransferCfg Pointer to a I2C_S_SETUP_Type structure that\r
+ * contains specified information about the\r
+ * configuration for master transfer.\r
+ * @param[in] Opt I2C_TRANSFER_OPT_Type type that selected for\r
+ * interrupt or polling mode.\r
+ * @return SUCCESS or ERROR\r
+ *\r
+ * Note:\r
+ * The mode of slave's operation depends on the command sent from master on\r
+ * the I2C bus. If the master send a SLA+W command, this sub-routine will\r
+ * use receive data length and receive data pointer. If the master send a SLA+R\r
+ * command, this sub-routine will use transmit data length and transmit data\r
+ * pointer.\r
+ * If the master issue an repeat start command or a stop command, the slave will\r
+ * enable an time out condition, during time out condition, if there's no activity\r
+ * on I2C bus, the slave will exit, otherwise (i.e. the master send a SLA+R/W),\r
+ * the slave then switch to relevant operation mode. The time out should be used\r
+ * because the return status code can not show difference from stop and repeat\r
+ * start command in slave operation.\r
+ * In case of the expected data length from master is greater than data length\r
+ * that slave can support:\r
+ * - In case of reading operation (from master): slave will return I2C_I2DAT_IDLE_CHAR\r
+ * value.\r
+ * - In case of writing operation (from master): slave will ignore remain data from master.\r
+ **********************************************************************/\r
+Status I2C_SlaveTransferData(LPC_I2C_TypeDef *I2Cx, I2C_S_SETUP_Type *TransferCfg, \\r
+ I2C_TRANSFER_OPT_Type Opt)\r
+{\r
+ uint8_t *txdat;\r
+ uint8_t *rxdat;\r
+ uint32_t CodeStatus;\r
+ uint32_t timeout;\r
+ int32_t time_en;\r
+ int32_t tmp;\r
+\r
+ // reset all default state\r
+ txdat = (uint8_t *) TransferCfg->tx_data;\r
+ rxdat = (uint8_t *) TransferCfg->rx_data;\r
+ // Reset I2C setup value to default state\r
+ TransferCfg->tx_count = 0;\r
+ TransferCfg->rx_count = 0;\r
+ TransferCfg->status = 0;\r
+\r
+\r
+ // Polling option\r
+ if (Opt == I2C_TRANSFER_POLLING){\r
+\r
+ /* Set AA bit to ACK command on I2C bus */\r
+ I2Cx->I2CONSET = I2C_I2CONSET_AA;\r
+ /* Clear SI bit to be ready ... */\r
+ I2Cx->I2CONCLR = (I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC);\r
+\r
+ time_en = 0;\r
+ timeout = 0;\r
+\r
+ while (1)\r
+ {\r
+ /* Check SI flag ready */\r
+ if (I2Cx->I2CONSET & I2C_I2CONSET_SI)\r
+ {\r
+ time_en = 0;\r
+\r
+ switch (CodeStatus = (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK))\r
+ {\r
+\r
+ /* No status information */\r
+ case I2C_I2STAT_NO_INF:\r
+ I2Cx->I2CONSET = I2C_I2CONSET_AA;\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+ break;\r
+\r
+ /* Reading phase -------------------------------------------------------- */\r
+ /* Own SLA+R has been received, ACK has been returned */\r
+ case I2C_I2STAT_S_RX_SLAW_ACK:\r
+ /* General call address has been received, ACK has been returned */\r
+ case I2C_I2STAT_S_RX_GENCALL_ACK:\r
+ I2Cx->I2CONSET = I2C_I2CONSET_AA;\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+ break;\r
+\r
+ /* Previously addressed with own SLA;\r
+ * DATA byte has been received;\r
+ * ACK has been returned */\r
+ case I2C_I2STAT_S_RX_PRE_SLA_DAT_ACK:\r
+ /* DATA has been received, ACK hasn been return */\r
+ case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_ACK:\r
+ /*\r
+ * All data bytes that over-flow the specified receive\r
+ * data length, just ignore them.\r
+ */\r
+ if ((TransferCfg->rx_count < TransferCfg->rx_length) \\r
+ && (TransferCfg->rx_data != NULL)){\r
+ *rxdat++ = (uint8_t)I2Cx->I2DAT;\r
+ TransferCfg->rx_count++;\r
+ }\r
+ I2Cx->I2CONSET = I2C_I2CONSET_AA;\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+ break;\r
+\r
+ /* Previously addressed with own SLA;\r
+ * DATA byte has been received;\r
+ * NOT ACK has been returned */\r
+ case I2C_I2STAT_S_RX_PRE_SLA_DAT_NACK:\r
+ /* DATA has been received, NOT ACK has been returned */\r
+ case I2C_I2STAT_S_RX_PRE_GENCALL_DAT_NACK:\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+ break;\r
+\r
+ /*\r
+ * Note that: Return code only let us know a stop condition mixed\r
+ * with a repeat start condition in the same code value.\r
+ * So we should provide a time-out. In case this is really a stop\r
+ * condition, this will return back after time out condition. Otherwise,\r
+ * next session that is slave receive data will be completed.\r
+ */\r
+\r
+ /* A Stop or a repeat start condition */\r
+ case I2C_I2STAT_S_RX_STA_STO_SLVREC_SLVTRX:\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+ // enable time out\r
+ time_en = 1;\r
+ timeout = 0;\r
+ break;\r
+\r
+ /* Writing phase -------------------------------------------------------- */\r
+ /* Own SLA+R has been received, ACK has been returned */\r
+ case I2C_I2STAT_S_TX_SLAR_ACK:\r
+ /* Data has been transmitted, ACK has been received */\r
+ case I2C_I2STAT_S_TX_DAT_ACK:\r
+ /*\r
+ * All data bytes that over-flow the specified receive\r
+ * data length, just ignore them.\r
+ */\r
+ if ((TransferCfg->tx_count < TransferCfg->tx_length) \\r
+ && (TransferCfg->tx_data != NULL)){\r
+ I2Cx->I2DAT = *txdat++;\r
+ TransferCfg->tx_count++;\r
+ }\r
+ I2Cx->I2CONSET = I2C_I2CONSET_AA;\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+ break;\r
+\r
+ /* Data has been transmitted, NACK has been received,\r
+ * that means there's no more data to send, exit now */\r
+ /*\r
+ * Note: Don't wait for stop event since in slave transmit mode,\r
+ * since there no proof lets us know when a stop signal has been received\r
+ * on slave side.\r
+ */\r
+ case I2C_I2STAT_S_TX_DAT_NACK:\r
+ I2Cx->I2CONSET = I2C_I2CONSET_AA;\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+ // enable time out\r
+ time_en = 1;\r
+ timeout = 0;\r
+ break;\r
+\r
+ // Other status must be captured\r
+ default:\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;\r
+ goto s_error;\r
+ break;\r
+ }\r
+ } else if (time_en){\r
+ if (timeout++ > I2C_SLAVE_TIME_OUT){\r
+ // it's really a stop condition, goto end stage\r
+ goto s_end_stage;\r
+ }\r
+ }\r
+ }\r
+\r
+s_end_stage:\r
+ /* Clear AA bit to disable ACK on I2C bus */\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_AAC;\r
+ // Check if there's no error during operation\r
+ // Update status\r
+ TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_DONE;\r
+ return SUCCESS;\r
+\r
+s_error:\r
+ /* Clear AA bit to disable ACK on I2C bus */\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_AAC;\r
+ // Update status\r
+ TransferCfg->status = CodeStatus;\r
+ return ERROR;\r
+ }\r
+\r
+ else if (Opt == I2C_TRANSFER_INTERRUPT){\r
+ // Setup tx_rx data, callback and interrupt handler\r
+ tmp = I2C_getNum(I2Cx);\r
+ i2cdat[tmp].txrx_setup = (uint32_t) TransferCfg;\r
+ i2cdat[tmp].inthandler = I2C_SlaveHandler;\r
+ // Set direction phase, read first\r
+ i2cdat[tmp].dir = 1;\r
+\r
+ // Enable AA\r
+ I2Cx->I2CONSET = I2C_I2CONSET_AA;\r
+ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC | I2C_I2CONCLR_STAC;\r
+ I2C_IntCmd(I2Cx, 1);\r
+\r
+ return (SUCCESS);\r
+ }\r
+\r
+ return ERROR;\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief Set Own slave address in I2C peripheral corresponding to\r
+ * parameter specified in OwnSlaveAddrConfigStruct.\r
+ * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2\r
+ * @param[in] OwnSlaveAddrConfigStruct Pointer to a I2C_OWNSLAVEADDR_CFG_Type\r
+ * structure that contains the configuration information for the\r
+* specified I2C slave address.\r
+ * @return None\r
+ **********************************************************************/\r
+void I2C_SetOwnSlaveAddr(LPC_I2C_TypeDef *I2Cx, I2C_OWNSLAVEADDR_CFG_Type *OwnSlaveAddrConfigStruct)\r
+{\r
+ uint32_t tmp;\r
+ CHECK_PARAM(PARAM_I2Cx(I2Cx));\r
+ CHECK_PARAM(PARAM_I2C_SLAVEADDR_CH(OwnSlaveAddrConfigStruct->SlaveAddrChannel));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(OwnSlaveAddrConfigStruct->GeneralCallState));\r
+\r
+ tmp = (((uint32_t)(OwnSlaveAddrConfigStruct->SlaveAddr_7bit << 1)) \\r
+ | ((OwnSlaveAddrConfigStruct->GeneralCallState == ENABLE) ? 0x01 : 0x00))& I2C_I2ADR_BITMASK;\r
+ switch (OwnSlaveAddrConfigStruct->SlaveAddrChannel)\r
+ {\r
+ case 0:\r
+ I2Cx->I2ADR0 = tmp;\r
+ I2Cx->I2MASK0 = I2C_I2MASK_MASK((uint32_t) \\r
+ (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue));\r
+ break;\r
+ case 1:\r
+ I2Cx->I2ADR1 = tmp;\r
+ I2Cx->I2MASK1 = I2C_I2MASK_MASK((uint32_t) \\r
+ (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue));\r
+ break;\r
+ case 2:\r
+ I2Cx->I2ADR2 = tmp;\r
+ I2Cx->I2MASK2 = I2C_I2MASK_MASK((uint32_t) \\r
+ (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue));\r
+ break;\r
+ case 3:\r
+ I2Cx->I2ADR3 = tmp;\r
+ I2Cx->I2MASK3 = I2C_I2MASK_MASK((uint32_t) \\r
+ (OwnSlaveAddrConfigStruct->SlaveAddrMaskValue));\r
+ break;\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Configures functionality in I2C monitor mode\r
+ * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2\r
+ * @param[in] MonitorCfgType Monitor Configuration type, should be:\r
+ * - I2C_MONITOR_CFG_SCL_OUTPUT: I2C module can 'stretch'\r
+ * the clock line (hold it low) until it has had time to\r
+ * respond to an I2C interrupt.\r
+ * - I2C_MONITOR_CFG_MATCHALL: When this bit is set to '1'\r
+ * and the I2C is in monitor mode, an interrupt will be\r
+ * generated on ANY address received.\r
+ * @param[in] NewState New State of this function, should be:\r
+ * - ENABLE: Enable this function.\r
+ * - DISABLE: Disable this function.\r
+ * @return None\r
+ **********************************************************************/\r
+void I2C_MonitorModeConfig(LPC_I2C_TypeDef *I2Cx, uint32_t MonitorCfgType, FunctionalState NewState)\r
+{\r
+ CHECK_PARAM(PARAM_I2Cx(I2Cx));\r
+ CHECK_PARAM(PARAM_I2C_MONITOR_CFG(MonitorCfgType));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));\r
+\r
+ if (NewState == ENABLE)\r
+ {\r
+ I2Cx->MMCTRL |= MonitorCfgType;\r
+ }\r
+ else\r
+ {\r
+ I2Cx->MMCTRL &= (~MonitorCfgType) & I2C_I2MMCTRL_BITMASK;\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Enable/Disable I2C monitor mode\r
+ * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2\r
+ * @param[in] NewState New State of this function, should be:\r
+ * - ENABLE: Enable monitor mode.\r
+ * - DISABLE: Disable monitor mode.\r
+ * @return None\r
+ **********************************************************************/\r
+void I2C_MonitorModeCmd(LPC_I2C_TypeDef *I2Cx, FunctionalState NewState)\r
+{\r
+ CHECK_PARAM(PARAM_I2Cx(I2Cx));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));\r
+\r
+ if (NewState == ENABLE)\r
+ {\r
+ I2Cx->MMCTRL |= I2C_I2MMCTRL_MM_ENA;\r
+ }\r
+ else\r
+ {\r
+ I2Cx->MMCTRL &= (~I2C_I2MMCTRL_MM_ENA) & I2C_I2MMCTRL_BITMASK;\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Get data from I2C data buffer in monitor mode.\r
+ * @param[in] I2Cx I2C peripheral selected, should be I2C0, I2C1 or I2C2\r
+ * @return None\r
+ * Note: In monitor mode, the I2C module may lose the ability to stretch\r
+ * the clock (stall the bus) if the ENA_SCL bit is not set. This means that\r
+ * the processor will have a limited amount of time to read the contents of\r
+ * the data received on the bus. If the processor reads the I2DAT shift\r
+ * register, as it ordinarily would, it could have only one bit-time to\r
+ * respond to the interrupt before the received data is overwritten by\r
+ * new data.\r
+ **********************************************************************/\r
+uint8_t I2C_MonitorGetDatabuffer(LPC_I2C_TypeDef *I2Cx)\r
+{\r
+ CHECK_PARAM(PARAM_I2Cx(I2Cx));\r
+ return ((uint8_t)(I2Cx->I2DATA_BUFFER));\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief Standard Interrupt handler for I2C0 peripheral\r
+ * @param[in] None\r
+ * @return None\r
+ **********************************************************************/\r
+void I2C0_StdIntHandler(void)\r
+{\r
+ i2cdat[0].inthandler(LPC_I2C0);\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief Standard Interrupt handler for I2C1 peripheral\r
+ * @param[in] None\r
+ * @return None\r
+ **********************************************************************/\r
+void I2C1_StdIntHandler(void)\r
+{\r
+ i2cdat[1].inthandler(LPC_I2C1);\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief Standard Interrupt handler for I2C2 peripheral\r
+ * @param[in] None\r
+ * @return None\r
+ **********************************************************************/\r
+void I2C2_StdIntHandler(void)\r
+{\r
+ i2cdat[2].inthandler(LPC_I2C2);\r
+}\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#endif /* _I2C */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* --------------------------------- End Of File ------------------------------ */\r
--- /dev/null
+/***********************************************************************//**\r
+ * @file : lpc17xx_i2c.h\r
+ * @brief : Contains all macro definitions and function prototypes\r
+ * support for I2C firmware library on LPC17xx\r
+ * @version : 1.0\r
+ * @date : 13. Apr. 2009\r
+ * @author : HieuNguyen\r
+ **************************************************************************\r
+ * Software that is described herein is for illustrative purposes only\r
+ * which provides customers with programming information regarding the\r
+ * products. This software is supplied "AS IS" without any warranties.\r
+ * NXP Semiconductors assumes no responsibility or liability for the\r
+ * use of the software, conveys no license or title under any patent,\r
+ * copyright, or mask work right to the product. NXP Semiconductors\r
+ * reserves the right to make changes in the software without\r
+ * notification. NXP Semiconductors also make no representation or\r
+ * warranty that such application will be suitable for the specified\r
+ * use without further testing or modification.\r
+ **************************************************************************/\r
+\r
+/* Peripheral group ----------------------------------------------------------- */\r
+/** @defgroup I2C\r
+ * @ingroup LPC1700CMSIS_FwLib_Drivers\r
+ * @{\r
+ */\r
+\r
+#ifndef LPC17XX_I2C_H_\r
+#define LPC17XX_I2C_H_\r
+\r
+/* Includes ------------------------------------------------------------------- */\r
+#include "LPC17xx.h"\r
+#include "lpc_types.h"\r
+\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif\r
+\r
+\r
+/* Private Macros ------------------------------------------------------------- */\r
+/** @defgroup I2C_Private_Macros\r
+ * @{\r
+ */\r
+\r
+/** @defgroup I2C_REGISTER_BIT_DEFINITIONS\r
+ * @{\r
+ */\r
+\r
+/*******************************************************************//**\r
+ * I2C Control Set register description\r
+ *********************************************************************/\r
+#define I2C_I2CONSET_AA ((0x04)) /*!< Assert acknowledge flag */\r
+#define I2C_I2CONSET_SI ((0x08)) /*!< I2C interrupt flag */\r
+#define I2C_I2CONSET_STO ((0x10)) /*!< STOP flag */\r
+#define I2C_I2CONSET_STA ((0x20)) /*!< START flag */\r
+#define I2C_I2CONSET_I2EN ((0x40)) /*!< I2C interface enable */\r
+\r
+\r
+/*******************************************************************//**\r
+ * I2C Control Clear register description\r
+ *********************************************************************/\r
+/** Assert acknowledge Clear bit */\r
+#define I2C_I2CONCLR_AAC ((1<<2))\r
+/** I2C interrupt Clear bit */\r
+#define I2C_I2CONCLR_SIC ((1<<3))\r
+/** START flag Clear bit */\r
+#define I2C_I2CONCLR_STAC ((1<<5))\r
+/** I2C interface Disable bit */\r
+#define I2C_I2CONCLR_I2ENC ((1<<6))\r
+\r
+\r
+/********************************************************************//**\r
+ * I2C Status Code definition (I2C Status register)\r
+ *********************************************************************/\r
+/* Return Code in I2C status register */\r
+#define I2C_STAT_CODE_BITMASK ((0xF8))\r
+\r
+/* I2C return status code definitions ----------------------------- */\r
+\r
+/** No relevant information */\r
+#define I2C_I2STAT_NO_INF ((0xF8))\r
+\r
+/* Master transmit mode -------------------------------------------- */\r
+/** A start condition has been transmitted */\r
+#define I2C_I2STAT_M_TX_START ((0x08))\r
+/** A repeat start condition has been transmitted */\r
+#define I2C_I2STAT_M_TX_RESTART ((0x10))\r
+/** SLA+W has been transmitted, ACK has been received */\r
+#define I2C_I2STAT_M_TX_SLAW_ACK ((0x18))\r
+/** SLA+W has been transmitted, NACK has been received */\r
+#define I2C_I2STAT_M_TX_SLAW_NACK ((0x20))\r
+/** Data has been transmitted, ACK has been received */\r
+#define I2C_I2STAT_M_TX_DAT_ACK ((0x28))\r
+/** Data has been transmitted, NACK has been received */\r
+#define I2C_I2STAT_M_TX_DAT_NACK ((0x30))\r
+/** Arbitration lost in SLA+R/W or Data bytes */\r
+#define I2C_I2STAT_M_TX_ARB_LOST ((0x38))\r
+\r
+/* Master receive mode -------------------------------------------- */\r
+/** A start condition has been transmitted */\r
+#define I2C_I2STAT_M_RX_START ((0x08))\r
+/** A repeat start condition has been transmitted */\r
+#define I2C_I2STAT_M_RX_RESTART ((0x10))\r
+/** Arbitration lost */\r
+#define I2C_I2STAT_M_RX_ARB_LOST ((0x38))\r
+/** SLA+R has been transmitted, ACK has been received */\r
+#define I2C_I2STAT_M_RX_SLAR_ACK ((0x40))\r
+/** SLA+R has been transmitted, NACK has been received */\r
+#define I2C_I2STAT_M_RX_SLAR_NACK ((0x48))\r
+/** Data has been received, ACK has been returned */\r
+#define I2C_I2STAT_M_RX_DAT_ACK ((0x50))\r
+/** Data has been received, NACK has been return */\r
+#define I2C_I2STAT_M_RX_DAT_NACK ((0x58))\r
+\r
+/* Slave receive mode -------------------------------------------- */\r
+/** Own slave address has been received, ACK has been returned */\r
+#define I2C_I2STAT_S_RX_SLAW_ACK ((0x60))\r
+\r
+/** Arbitration lost in SLA+R/W as master */\r
+#define I2C_I2STAT_S_RX_ARB_LOST_M_SLA ((0x68))\r
+/** Own SLA+W has been received, ACK returned */\r
+//#define I2C_I2STAT_S_RX_SLAW_ACK ((0x68))\r
+\r
+/** General call address has been received, ACK has been returned */\r
+#define I2C_I2STAT_S_RX_GENCALL_ACK ((0x70))\r
+\r
+/** Arbitration lost in SLA+R/W (GENERAL CALL) as master */\r
+#define I2C_I2STAT_S_RX_ARB_LOST_M_GENCALL ((0x78))\r
+/** General call address has been received, ACK has been returned */\r
+//#define I2C_I2STAT_S_RX_GENCALL_ACK ((0x78))\r
+\r
+/** Previously addressed with own SLV address;\r
+ * Data has been received, ACK has been return */\r
+#define I2C_I2STAT_S_RX_PRE_SLA_DAT_ACK ((0x80))\r
+/** Previously addressed with own SLA;\r
+ * Data has been received and NOT ACK has been return */\r
+#define I2C_I2STAT_S_RX_PRE_SLA_DAT_NACK ((0x88))\r
+/** Previously addressed with General Call;\r
+ * Data has been received and ACK has been return */\r
+#define I2C_I2STAT_S_RX_PRE_GENCALL_DAT_ACK ((0x90))\r
+/** Previously addressed with General Call;\r
+ * Data has been received and NOT ACK has been return */\r
+#define I2C_I2STAT_S_RX_PRE_GENCALL_DAT_NACK ((0x98))\r
+/** A STOP condition or repeated START condition has\r
+ * been received while still addressed as SLV/REC\r
+ * (Slave Receive) or SLV/TRX (Slave Transmit) */\r
+#define I2C_I2STAT_S_RX_STA_STO_SLVREC_SLVTRX ((0xA0))\r
+\r
+/** Slave transmit mode */\r
+/** Own SLA+R has been received, ACK has been returned */\r
+#define I2C_I2STAT_S_TX_SLAR_ACK ((0xA8))\r
+\r
+/** Arbitration lost in SLA+R/W as master */\r
+#define I2C_I2STAT_S_TX_ARB_LOST_M_SLA ((0xB0))\r
+/** Own SLA+R has been received, ACK has been returned */\r
+//#define I2C_I2STAT_S_TX_SLAR_ACK ((0xB0))\r
+\r
+/** Data has been transmitted, ACK has been received */\r
+#define I2C_I2STAT_S_TX_DAT_ACK ((0xB8))\r
+/** Data has been transmitted, NACK has been received */\r
+#define I2C_I2STAT_S_TX_DAT_NACK ((0xC0))\r
+/** Last data byte in I2DAT has been transmitted (AA = 0);\r
+ ACK has been received */\r
+#define I2C_I2STAT_S_TX_LAST_DAT_ACK ((0xC8))\r
+\r
+/** Time out in case of using I2C slave mode */\r
+#define I2C_SLAVE_TIME_OUT 0x10000UL\r
+\r
+/********************************************************************//**\r
+ * I2C Data register definition\r
+ *********************************************************************/\r
+/** Mask for I2DAT register*/\r
+#define I2C_I2DAT_BITMASK ((0xFF))\r
+\r
+/** Idle data value will be send out in slave mode in case of the actual\r
+ * expecting data requested from the master is greater than its sending data\r
+ * length that can be supported */\r
+#define I2C_I2DAT_IDLE_CHAR (0xFF)\r
+\r
+\r
+/********************************************************************//**\r
+ * I2C Monitor mode control register description\r
+ *********************************************************************/\r
+#define I2C_I2MMCTRL_MM_ENA ((1<<0)) /**< Monitor mode enable */\r
+#define I2C_I2MMCTRL_ENA_SCL ((1<<1)) /**< SCL output enable */\r
+#define I2C_I2MMCTRL_MATCH_ALL ((1<<2)) /**< Select interrupt register match */\r
+#define I2C_I2MMCTRL_BITMASK ((0x07)) /**< Mask for I2MMCTRL register */\r
+\r
+\r
+/********************************************************************//**\r
+ * I2C Data buffer register description\r
+ *********************************************************************/\r
+/** I2C Data buffer register bit mask */\r
+#define I2DATA_BUFFER_BITMASK ((0xFF))\r
+\r
+\r
+/********************************************************************//**\r
+ * I2C Slave Address registers definition\r
+ *********************************************************************/\r
+/** General Call enable bit */\r
+#define I2C_I2ADR_GC ((1<<0))\r
+/** I2C Slave Address registers bit mask */\r
+#define I2C_I2ADR_BITMASK ((0xFF))\r
+\r
+\r
+/********************************************************************//**\r
+ * I2C Mask Register definition\r
+ *********************************************************************/\r
+/** I2C Mask Register mask field */\r
+#define I2C_I2MASK_MASK(n) ((n&0xFE))\r
+\r
+\r
+/********************************************************************//**\r
+ * I2C SCL HIGH duty cycle Register definition\r
+ *********************************************************************/\r
+/** I2C SCL HIGH duty cycle Register bit mask */\r
+#define I2C_I2SCLH_BITMASK ((0xFFFF))\r
+\r
+\r
+/********************************************************************//**\r
+ * I2C SCL LOW duty cycle Register definition\r
+ *********************************************************************/\r
+/** I2C SCL LOW duty cycle Register bit mask */\r
+#define I2C_I2SCLL_BITMASK ((0xFFFF))\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+\r
+/* Public Types --------------------------------------------------------------- */\r
+/** @defgroup I2C_Public_Types\r
+ * @{\r
+ */\r
+\r
+/** @brief I2C Own slave address setting structure */\r
+typedef struct {\r
+ uint8_t SlaveAddrChannel; /**< Slave Address channel in I2C control,\r
+ should be in range from 0..3\r
+ */\r
+ uint8_t SlaveAddr_7bit; /**< Value of 7-bit slave address */\r
+ uint8_t GeneralCallState; /**< Enable/Disable General Call Functionality\r
+ when I2C control being in Slave mode, should be:\r
+ - ENABLE: Enable General Call function.\r
+ - DISABLE: Disable General Call function.\r
+ */\r
+ uint8_t SlaveAddrMaskValue; /**< Any bit in this 8-bit value (bit 7:1)\r
+ which is set to '1' will cause an automatic compare on\r
+ the corresponding bit of the received address when it\r
+ is compared to the SlaveAddr_7bit value associated with this\r
+ mask register. In other words, bits in SlaveAddr_7bit value\r
+ which are masked are not taken into account in determining\r
+ an address match\r
+ */\r
+} I2C_OWNSLAVEADDR_CFG_Type;\r
+\r
+\r
+/** @brief Master transfer setup data structure definitions */\r
+typedef struct\r
+{\r
+ uint32_t sl_addr7bit; /**< Slave address in 7bit mode */\r
+ uint8_t* tx_data; /**< Pointer to Transmit data - NULL if data transmit\r
+ is not used */\r
+ uint32_t tx_length; /**< Transmit data length - 0 if data transmit\r
+ is not used*/\r
+ uint32_t tx_count; /**< Current Transmit data counter */\r
+ uint8_t* rx_data; /**< Pointer to Receive data - NULL if data receive\r
+ is not used */\r
+ uint32_t rx_length; /**< Receive data length - 0 if data receive is\r
+ not used */\r
+ uint32_t rx_count; /**< Current Receive data counter */\r
+ uint32_t retransmissions_max; /**< Max Re-Transmission value */\r
+ uint32_t retransmissions_count; /**< Current Re-Transmission counter */\r
+ uint32_t status; /**< Current status of I2C activity */\r
+ void (*callback)(void); /**< Pointer to Call back function when transmission complete\r
+ used in interrupt transfer mode */\r
+} I2C_M_SETUP_Type;\r
+\r
+\r
+/** @brief Slave transfer setup data structure definitions */\r
+typedef struct\r
+{\r
+ uint8_t* tx_data;\r
+ uint32_t tx_length;\r
+ uint32_t tx_count;\r
+ uint8_t* rx_data;\r
+ uint32_t rx_length;\r
+ uint32_t rx_count;\r
+ uint32_t status;\r
+ void (*callback)(void);\r
+} I2C_S_SETUP_Type;\r
+\r
+/**\r
+ * @brief Transfer option type definitions\r
+ */\r
+typedef enum {\r
+ I2C_TRANSFER_POLLING = 0, /**< Transfer in polling mode */\r
+ I2C_TRANSFER_INTERRUPT /**< Transfer in interrupt mode */\r
+} I2C_TRANSFER_OPT_Type;\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Macros -------------------------------------------------------------- */\r
+/** @defgroup I2C_Public_Macros\r
+ * @{\r
+ */\r
+\r
+#define PARAM_I2C_SLAVEADDR_CH(n) ((n>=0) && (n<=3))\r
+\r
+/** Macro to determine if it is valid SSP port number */\r
+#define PARAM_I2Cx(n) ((((uint32_t *)n)==((uint32_t *)LPC_I2C0)) \\r
+|| (((uint32_t *)n)==((uint32_t *)LPC_I2C1)) \\r
+|| (((uint32_t *)n)==((uint32_t *)LPC_I2C2)))\r
+\r
+/* I2C status values */\r
+#define I2C_SETUP_STATUS_ARBF (1<<8) /**< Arbitration false */\r
+#define I2C_SETUP_STATUS_NOACKF (1<<9) /**< No ACK returned */\r
+#define I2C_SETUP_STATUS_DONE (1<<10) /**< Status DONE */\r
+\r
+\r
+/*********************************************************************//**\r
+ * I2C monitor control configuration defines\r
+ **********************************************************************/\r
+#define I2C_MONITOR_CFG_SCL_OUTPUT I2C_I2MMCTRL_ENA_SCL /**< SCL output enable */\r
+#define I2C_MONITOR_CFG_MATCHALL I2C_I2MMCTRL_MATCH_ALL /**< Select interrupt register match */\r
+\r
+#define PARAM_I2C_MONITOR_CFG(n) ((n==I2C_MONITOR_CFG_SCL_OUTPUT) || (I2C_MONITOR_CFG_MATCHALL))\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Functions ----------------------------------------------------------- */\r
+/** @defgroup I2C_Public_Functions\r
+ * @{\r
+ */\r
+\r
+void I2C_SetClock (LPC_I2C_TypeDef *I2Cx, uint32_t target_clock);\r
+void I2C_DeInit(LPC_I2C_TypeDef* I2Cx);\r
+void I2C_Init(LPC_I2C_TypeDef *I2Cx, uint32_t clockrate);\r
+void I2C_Cmd(LPC_I2C_TypeDef* I2Cx, FunctionalState NewState);\r
+\r
+Status I2C_MasterTransferData(LPC_I2C_TypeDef *I2Cx, \\r
+ I2C_M_SETUP_Type *TransferCfg, I2C_TRANSFER_OPT_Type Opt);\r
+Status I2C_SlaveTransferData(LPC_I2C_TypeDef *I2Cx, \\r
+ I2C_S_SETUP_Type *TransferCfg, I2C_TRANSFER_OPT_Type Opt);\r
+\r
+void I2C_SetOwnSlaveAddr(LPC_I2C_TypeDef *I2Cx, I2C_OWNSLAVEADDR_CFG_Type *OwnSlaveAddrConfigStruct);\r
+uint8_t I2C_GetLastStatusCode(LPC_I2C_TypeDef* I2Cx);\r
+\r
+void I2C_MonitorModeConfig(LPC_I2C_TypeDef *I2Cx, uint32_t MonitorCfgType, FunctionalState NewState);\r
+void I2C_MonitorModeCmd(LPC_I2C_TypeDef *I2Cx, FunctionalState NewState);\r
+uint8_t I2C_MonitorGetDatabuffer(LPC_I2C_TypeDef *I2Cx);\r
+\r
+void I2C0_StdIntHandler(void);\r
+void I2C1_StdIntHandler(void);\r
+void I2C2_StdIntHandler(void);\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* LPC17XX_I2C_H_ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* --------------------------------- End Of File ------------------------------ */\r
--- /dev/null
+/**\r
+ * @file : lpc17xx_nvic.c\r
+ * @brief : Contains all expansion functions support for\r
+ * NVIC firmware library on LPC17xx. The main\r
+ * NVIC functions are defined in core_cm3.h\r
+ * @version : 1.0\r
+ * @date : 18. Mar. 2009\r
+ * @author : HieuNguyen\r
+ **************************************************************************\r
+ * Software that is described herein is for illustrative purposes only\r
+ * which provides customers with programming information regarding the\r
+ * products. This software is supplied "AS IS" without any warranties.\r
+ * NXP Semiconductors assumes no responsibility or liability for the\r
+ * use of the software, conveys no license or title under any patent,\r
+ * copyright, or mask work right to the product. NXP Semiconductors\r
+ * reserves the right to make changes in the software without\r
+ * notification. NXP Semiconductors also make no representation or\r
+ * warranty that such application will be suitable for the specified\r
+ * use without further testing or modification.\r
+ **********************************************************************/\r
+\r
+/* Peripheral group ----------------------------------------------------------- */\r
+/** @addtogroup NVIC\r
+ * @{\r
+ */\r
+\r
+/* Includes ------------------------------------------------------------------- */\r
+#include "lpc17xx_nvic.h"\r
+\r
+\r
+/* Private Macros ------------------------------------------------------------- */\r
+/** @addtogroup NVIC_Private_Macros\r
+ * @{\r
+ */\r
+\r
+/* Vector table offset bit mask */\r
+#define NVIC_VTOR_MASK 0x3FFFFF80\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Functions ----------------------------------------------------------- */\r
+/** @addtogroup NVIC_Public_Functions\r
+ * @{\r
+ */\r
+\r
+\r
+/*****************************************************************************//**\r
+ * @brief De-initializes the NVIC peripheral registers to their default\r
+ * reset values.\r
+ * @param None\r
+ * @return None\r
+ *\r
+ * These following NVIC peripheral registers will be de-initialized:\r
+ * - Disable Interrupt (32 IRQ interrupt sources that matched with LPC17xx)\r
+ * - Clear all Pending Interrupts (32 IRQ interrupt source that matched with LPC17xx)\r
+ * - Clear all Interrupt Priorities (32 IRQ interrupt source that matched with LPC17xx)\r
+ *******************************************************************************/\r
+void NVIC_DeInit(void)\r
+{\r
+ uint8_t tmp;\r
+\r
+ /* Disable all interrupts */\r
+ NVIC->ICER[0] = 0xFFFFFFFF;\r
+ NVIC->ICER[1] = 0x00000001;\r
+ /* Clear all pending interrupts */\r
+ NVIC->ICPR[0] = 0xFFFFFFFF;\r
+ NVIC->ICPR[1] = 0x00000001;\r
+\r
+ /* Clear all interrupt priority */\r
+ for (tmp = 0; tmp < 32; tmp++) {\r
+ NVIC->IP[tmp] = 0x00;\r
+ }\r
+}\r
+\r
+/*****************************************************************************//**\r
+ * @brief De-initializes the SCB peripheral registers to their default\r
+ * reset values.\r
+ * @param none\r
+ * @return none\r
+ *\r
+ * These following SCB NVIC peripheral registers will be de-initialized:\r
+ * - Interrupt Control State register\r
+ * - Interrupt Vector Table Offset register\r
+ * - Application Interrupt/Reset Control register\r
+ * - System Control register\r
+ * - Configuration Control register\r
+ * - System Handlers Priority Registers\r
+ * - System Handler Control and State Register\r
+ * - Configurable Fault Status Register\r
+ * - Hard Fault Status Register\r
+ * - Debug Fault Status Register\r
+ *******************************************************************************/\r
+void NVIC_SCBDeInit(void)\r
+{\r
+ uint8_t tmp;\r
+\r
+ SCB->ICSR = 0x0A000000;\r
+ SCB->VTOR = 0x00000000;\r
+ SCB->AIRCR = 0x05FA0000;\r
+ SCB->SCR = 0x00000000;\r
+ SCB->CCR = 0x00000000;\r
+\r
+ for (tmp = 0; tmp < 32; tmp++) {\r
+ SCB->SHP[tmp] = 0x00;\r
+ }\r
+\r
+ SCB->SHCSR = 0x00000000;\r
+ SCB->CFSR = 0xFFFFFFFF;\r
+ SCB->HFSR = 0xFFFFFFFF;\r
+ SCB->DFSR = 0xFFFFFFFF;\r
+}\r
+\r
+\r
+/*****************************************************************************//**\r
+ * @brief Set Vector Table Offset value\r
+ * @param offset Offset value\r
+ * @return None\r
+ *******************************************************************************/\r
+void NVIC_SetVTOR(uint32_t offset)\r
+{\r
+ SCB->VTOR = (offset & NVIC_VTOR_MASK);\r
+}\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* --------------------------------- End Of File ------------------------------ */\r
--- /dev/null
+/***********************************************************************//**\r
+ * @file : lpc17xx_nvic.h\r
+ * @brief : Contains all macro definitions and function prototypes\r
+ * support for Nesting Vectored Interrupt firmware library\r
+ * on LPC17xx\r
+ * @version : 1.0\r
+ * @date : 18. Mar. 2009\r
+ * @author : HieuNguyen\r
+ **************************************************************************\r
+ * Software that is described herein is for illustrative purposes only\r
+ * which provides customers with programming information regarding the\r
+ * products. This software is supplied "AS IS" without any warranties.\r
+ * NXP Semiconductors assumes no responsibility or liability for the\r
+ * use of the software, conveys no license or title under any patent,\r
+ * copyright, or mask work right to the product. NXP Semiconductors\r
+ * reserves the right to make changes in the software without\r
+ * notification. NXP Semiconductors also make no representation or\r
+ * warranty that such application will be suitable for the specified\r
+ * use without further testing or modification.\r
+ **************************************************************************/\r
+\r
+/* Peripheral group ----------------------------------------------------------- */\r
+/** @defgroup NVIC\r
+ * @ingroup LPC1700CMSIS_FwLib_Drivers\r
+ * @{\r
+ */\r
+\r
+#ifndef LPC17XX_NVIC_H_\r
+#define LPC17XX_NVIC_H_\r
+\r
+/* Includes ------------------------------------------------------------------- */\r
+#include "LPC17xx.h"\r
+#include "lpc_types.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif\r
+\r
+\r
+/* Public Functions ----------------------------------------------------------- */\r
+/** @defgroup NVIC_Public_Functions\r
+ * @{\r
+ */\r
+\r
+void NVIC_DeInit(void);\r
+void NVIC_SCBDeInit(void);\r
+void NVIC_SetVTOR(uint32_t offset);\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* LPC17XX_NVIC_H_ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* --------------------------------- End Of File ------------------------------ */\r
--- /dev/null
+/**\r
+ * @file : lpc17xx_rtc.c\r
+ * @brief : Contains all functions support for RTC firmware library on LPC17xx\r
+ * @version : 1.0\r
+ * @date : 23. Apr. 2009\r
+ * @author : HieuNguyen\r
+ **************************************************************************\r
+ * Software that is described herein is for illustrative purposes only\r
+ * which provides customers with programming information regarding the\r
+ * products. This software is supplied "AS IS" without any warranties.\r
+ * NXP Semiconductors assumes no responsibility or liability for the\r
+ * use of the software, conveys no license or title under any patent,\r
+ * copyright, or mask work right to the product. NXP Semiconductors\r
+ * reserves the right to make changes in the software without\r
+ * notification. NXP Semiconductors also make no representation or\r
+ * warranty that such application will be suitable for the specified\r
+ * use without further testing or modification.\r
+ **********************************************************************/\r
+\r
+\r
+/* Peripheral group ----------------------------------------------------------- */\r
+/** @addtogroup RTC\r
+ * @{\r
+ */\r
+\r
+/* Includes ------------------------------------------------------------------- */\r
+#include "lpc17xx_rtc.h"\r
+#include "lpc17xx_clkpwr.h"\r
+\r
+\r
+/* If this source file built with example, the LPC17xx FW library configuration\r
+ * file in each example directory ("lpc17xx_libcfg.h") must be included,\r
+ * otherwise the default FW library configuration file must be included instead\r
+ */\r
+#ifdef __BUILD_WITH_EXAMPLE__\r
+#include "lpc17xx_libcfg.h"\r
+#else\r
+#include "lpc17xx_libcfg_default.h"\r
+#endif /* __BUILD_WITH_EXAMPLE__ */\r
+\r
+\r
+#ifdef _RTC\r
+\r
+/* Public Functions ----------------------------------------------------------- */\r
+/** @addtogroup RTC_Public_Functions\r
+ * @{\r
+ */\r
+\r
+/********************************************************************//**\r
+ * @brief Initializes the RTC peripheral.\r
+ * @param[in] RTCx RTC peripheral selected, should be RTC\r
+ * @return None\r
+ *********************************************************************/\r
+void RTC_Init (LPC_RTC_TypeDef *RTCx)\r
+{\r
+ CHECK_PARAM(PARAM_RTCx(RTCx));\r
+\r
+ /* Set up clock and power for RTC module */\r
+ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCRTC, ENABLE);\r
+\r
+ // Clear all register to be default\r
+ RTCx->ILR = 0x00;\r
+ RTCx->CCR = 0x00;\r
+ RTCx->CIIR = 0x00;\r
+ RTCx->AMR = 0xFF;\r
+ RTCx->CALIBRATION = 0x00;\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief De-initializes the RTC peripheral registers to their\r
+* default reset values.\r
+ * @param[in] RTCx RTC peripheral selected, should be RTC\r
+ * @return None\r
+ **********************************************************************/\r
+void RTC_DeInit(LPC_RTC_TypeDef *RTCx)\r
+{\r
+ CHECK_PARAM(PARAM_RTCx(RTCx));\r
+\r
+ RTCx->CCR = 0x00;\r
+ // Disable power and clock for RTC module\r
+ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCRTC, DISABLE);\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief Reset clock tick counter in RTC peripheral\r
+ * @param[in] RTCx RTC peripheral selected, should be RTC\r
+ * @return None\r
+ **********************************************************************/\r
+void RTC_ResetClockTickCounter(LPC_RTC_TypeDef *RTCx)\r
+{\r
+ CHECK_PARAM(PARAM_RTCx(RTCx));\r
+\r
+ RTCx->CCR |= RTC_CCR_CTCRST;\r
+ RTCx->CCR &= (~RTC_CCR_CTCRST) & RTC_CCR_BITMASK;\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief Start/Stop RTC peripheral\r
+ * @param[in] RTCx RTC peripheral selected, should be RTC\r
+ * @param[in] NewState New State of this function, should be:\r
+ * - ENABLE: The time counters are enabled\r
+ * - DISABLE: The time counters are disabled\r
+ * @return None\r
+ **********************************************************************/\r
+void RTC_Cmd (LPC_RTC_TypeDef *RTCx, FunctionalState NewState)\r
+{\r
+ CHECK_PARAM(PARAM_RTCx(RTCx));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));\r
+\r
+ if (NewState == ENABLE)\r
+ {\r
+ RTCx->CCR |= RTC_CCR_CLKEN;\r
+ }\r
+ else\r
+ {\r
+ RTCx->CCR &= (~RTC_CCR_CLKEN) & RTC_CCR_BITMASK;\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Enable/Disable Counter increment interrupt for each time type\r
+ * in RTC peripheral\r
+ * @param[in] RTCx RTC peripheral selected, should be RTC\r
+ * @param[in] CntIncrIntType: Counter Increment Interrupt type,\r
+ * an increment of this type value below will generates\r
+ * an interrupt, should be:\r
+ * - RTC_TIMETYPE_SECOND\r
+ * - RTC_TIMETYPE_MINUTE\r
+ * - RTC_TIMETYPE_HOUR\r
+ * - RTC_TIMETYPE_DAYOFWEEK\r
+ * - RTC_TIMETYPE_DAYOFMONTH\r
+ * - RTC_TIMETYPE_DAYOFYEAR\r
+ * - RTC_TIMETYPE_MONTH\r
+ * - RTC_TIMETYPE_YEAR\r
+ * @param[in] NewState New State of this function, should be:\r
+ * - ENABLE: Counter Increment interrupt for this\r
+ * time type are enabled\r
+ * - DISABLE: Counter Increment interrupt for this\r
+ * time type are disabled\r
+ * @return None\r
+ **********************************************************************/\r
+void RTC_CntIncrIntConfig (LPC_RTC_TypeDef *RTCx, uint32_t CntIncrIntType, \\r
+ FunctionalState NewState)\r
+{\r
+ CHECK_PARAM(PARAM_RTCx(RTCx));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));\r
+ CHECK_PARAM(PARAM_RTC_TIMETYPE(CntIncrIntType));\r
+\r
+ if (NewState == ENABLE)\r
+ {\r
+ switch (CntIncrIntType)\r
+ {\r
+ case RTC_TIMETYPE_SECOND:\r
+ RTCx->CIIR |= RTC_CIIR_IMSEC;\r
+ break;\r
+ case RTC_TIMETYPE_MINUTE:\r
+ RTCx->CIIR |= RTC_CIIR_IMMIN;\r
+ break;\r
+ case RTC_TIMETYPE_HOUR:\r
+ RTCx->CIIR |= RTC_CIIR_IMHOUR;\r
+ break;\r
+ case RTC_TIMETYPE_DAYOFWEEK:\r
+ RTCx->CIIR |= RTC_CIIR_IMDOW;\r
+ break;\r
+ case RTC_TIMETYPE_DAYOFMONTH:\r
+ RTCx->CIIR |= RTC_CIIR_IMDOM;\r
+ break;\r
+ case RTC_TIMETYPE_DAYOFYEAR:\r
+ RTCx->CIIR |= RTC_CIIR_IMDOY;\r
+ break;\r
+ case RTC_TIMETYPE_MONTH:\r
+ RTCx->CIIR |= RTC_CIIR_IMMON;\r
+ break;\r
+ case RTC_TIMETYPE_YEAR:\r
+ RTCx->CIIR |= RTC_CIIR_IMYEAR;\r
+ break;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ switch (CntIncrIntType)\r
+ {\r
+ case RTC_TIMETYPE_SECOND:\r
+ RTCx->CIIR &= (~RTC_CIIR_IMSEC) & RTC_CIIR_BITMASK;\r
+ break;\r
+ case RTC_TIMETYPE_MINUTE:\r
+ RTCx->CIIR &= (~RTC_CIIR_IMMIN) & RTC_CIIR_BITMASK;\r
+ break;\r
+ case RTC_TIMETYPE_HOUR:\r
+ RTCx->CIIR &= (~RTC_CIIR_IMHOUR) & RTC_CIIR_BITMASK;\r
+ break;\r
+ case RTC_TIMETYPE_DAYOFWEEK:\r
+ RTCx->CIIR &= (~RTC_CIIR_IMDOW) & RTC_CIIR_BITMASK;\r
+ break;\r
+ case RTC_TIMETYPE_DAYOFMONTH:\r
+ RTCx->CIIR &= (~RTC_CIIR_IMDOM) & RTC_CIIR_BITMASK;\r
+ break;\r
+ case RTC_TIMETYPE_DAYOFYEAR:\r
+ RTCx->CIIR &= (~RTC_CIIR_IMDOY) & RTC_CIIR_BITMASK;\r
+ break;\r
+ case RTC_TIMETYPE_MONTH:\r
+ RTCx->CIIR &= (~RTC_CIIR_IMMON) & RTC_CIIR_BITMASK;\r
+ break;\r
+ case RTC_TIMETYPE_YEAR:\r
+ RTCx->CIIR &= (~RTC_CIIR_IMYEAR) & RTC_CIIR_BITMASK;\r
+ break;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Enable/Disable Alarm interrupt for each time type\r
+ * in RTC peripheral\r
+ * @param[in] RTCx RTC peripheral selected, should be RTC\r
+ * @param[in] AlarmTimeType: Alarm Time Interrupt type,\r
+ * an matching of this type value below with current time\r
+ * in RTC will generates an interrupt, should be:\r
+ * - RTC_TIMETYPE_SECOND\r
+ * - RTC_TIMETYPE_MINUTE\r
+ * - RTC_TIMETYPE_HOUR\r
+ * - RTC_TIMETYPE_DAYOFWEEK\r
+ * - RTC_TIMETYPE_DAYOFMONTH\r
+ * - RTC_TIMETYPE_DAYOFYEAR\r
+ * - RTC_TIMETYPE_MONTH\r
+ * - RTC_TIMETYPE_YEAR\r
+ * @param[in] NewState New State of this function, should be:\r
+ * - ENABLE: Alarm interrupt for this\r
+ * time type are enabled\r
+ * - DISABLE: Alarm interrupt for this\r
+ * time type are disabled\r
+ * @return None\r
+ **********************************************************************/\r
+void RTC_AlarmIntConfig (LPC_RTC_TypeDef *RTCx, uint32_t AlarmTimeType, \\r
+ FunctionalState NewState)\r
+{\r
+ CHECK_PARAM(PARAM_RTCx(RTCx));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));\r
+ CHECK_PARAM(PARAM_RTC_TIMETYPE(AlarmTimeType));\r
+\r
+ if (NewState == ENABLE)\r
+ {\r
+ switch (AlarmTimeType)\r
+ {\r
+ case RTC_TIMETYPE_SECOND:\r
+ RTCx->AMR &= (~RTC_AMR_AMRSEC) & RTC_AMR_BITMASK;\r
+ break;\r
+ case RTC_TIMETYPE_MINUTE:\r
+ RTCx->AMR &= (~RTC_AMR_AMRMIN) & RTC_AMR_BITMASK;\r
+ break;\r
+ case RTC_TIMETYPE_HOUR:\r
+ RTCx->AMR &= (~RTC_AMR_AMRHOUR) & RTC_AMR_BITMASK;\r
+ break;\r
+ case RTC_TIMETYPE_DAYOFWEEK:\r
+ RTCx->AMR &= (~RTC_AMR_AMRDOW) & RTC_AMR_BITMASK;\r
+ break;\r
+ case RTC_TIMETYPE_DAYOFMONTH:\r
+ RTCx->AMR &= (~RTC_AMR_AMRDOM) & RTC_AMR_BITMASK;\r
+ break;\r
+ case RTC_TIMETYPE_DAYOFYEAR:\r
+ RTCx->AMR &= (~RTC_AMR_AMRDOY) & RTC_AMR_BITMASK;\r
+ break;\r
+ case RTC_TIMETYPE_MONTH:\r
+ RTCx->AMR &= (~RTC_AMR_AMRMON) & RTC_AMR_BITMASK;\r
+ break;\r
+ case RTC_TIMETYPE_YEAR:\r
+ RTCx->AMR &= (~RTC_AMR_AMRYEAR) & RTC_AMR_BITMASK;\r
+ break;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ switch (AlarmTimeType)\r
+ {\r
+ case RTC_TIMETYPE_SECOND:\r
+ RTCx->AMR |= (RTC_AMR_AMRSEC);\r
+ break;\r
+ case RTC_TIMETYPE_MINUTE:\r
+ RTCx->AMR |= (RTC_AMR_AMRMIN);\r
+ break;\r
+ case RTC_TIMETYPE_HOUR:\r
+ RTCx->AMR |= (RTC_AMR_AMRHOUR);\r
+ break;\r
+ case RTC_TIMETYPE_DAYOFWEEK:\r
+ RTCx->AMR |= (RTC_AMR_AMRDOW);\r
+ break;\r
+ case RTC_TIMETYPE_DAYOFMONTH:\r
+ RTCx->AMR |= (RTC_AMR_AMRDOM);\r
+ break;\r
+ case RTC_TIMETYPE_DAYOFYEAR:\r
+ RTCx->AMR |= (RTC_AMR_AMRDOY);\r
+ break;\r
+ case RTC_TIMETYPE_MONTH:\r
+ RTCx->AMR |= (RTC_AMR_AMRMON);\r
+ break;\r
+ case RTC_TIMETYPE_YEAR:\r
+ RTCx->AMR |= (RTC_AMR_AMRYEAR);\r
+ break;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Set current time value for each time type in RTC peripheral\r
+ * @param[in] RTCx RTC peripheral selected, should be RTC\r
+ * @param[in] Timetype: Time Type, should be:\r
+ * - RTC_TIMETYPE_SECOND\r
+ * - RTC_TIMETYPE_MINUTE\r
+ * - RTC_TIMETYPE_HOUR\r
+ * - RTC_TIMETYPE_DAYOFWEEK\r
+ * - RTC_TIMETYPE_DAYOFMONTH\r
+ * - RTC_TIMETYPE_DAYOFYEAR\r
+ * - RTC_TIMETYPE_MONTH\r
+ * - RTC_TIMETYPE_YEAR\r
+ * @param[in] TimeValue Time value to set\r
+ * @return None\r
+ **********************************************************************/\r
+void RTC_SetTime (LPC_RTC_TypeDef *RTCx, uint32_t Timetype, uint32_t TimeValue)\r
+{\r
+ CHECK_PARAM(PARAM_RTCx(RTCx));\r
+ CHECK_PARAM(PARAM_RTC_TIMETYPE(Timetype));\r
+\r
+ switch ( Timetype)\r
+ {\r
+ case RTC_TIMETYPE_SECOND:\r
+ CHECK_PARAM(TimeValue < RTC_SECOND_MAX);\r
+\r
+ RTCx->SEC = TimeValue & RTC_SEC_MASK;\r
+ break;\r
+\r
+ case RTC_TIMETYPE_MINUTE:\r
+ CHECK_PARAM(TimeValue < RTC_MINUTE_MAX);\r
+\r
+ RTCx->MIN = TimeValue & RTC_MIN_MASK;\r
+ break;\r
+\r
+ case RTC_TIMETYPE_HOUR:\r
+ CHECK_PARAM(TimeValue < RTC_HOUR_MAX);\r
+\r
+ RTCx->HOUR = TimeValue & RTC_HOUR_MASK;\r
+ break;\r
+\r
+ case RTC_TIMETYPE_DAYOFWEEK:\r
+ CHECK_PARAM(TimeValue < RTC_DAYOFWEEK_MAX);\r
+\r
+ RTCx->DOW = TimeValue & RTC_DOW_MASK;\r
+ break;\r
+\r
+ case RTC_TIMETYPE_DAYOFMONTH:\r
+ CHECK_PARAM((TimeValue < RTC_DAYOFMONTH_MAX) \\r
+ && (TimeValue > RTC_DAYOFMONTH_MIN));\r
+\r
+ RTCx->DOM = TimeValue & RTC_DOM_MASK;\r
+ break;\r
+\r
+ case RTC_TIMETYPE_DAYOFYEAR:\r
+ CHECK_PARAM((TimeValue > RTC_DAYOFYEAR_MIN) \\r
+ && (TimeValue < RTC_DAYOFYEAR_MAX));\r
+\r
+ RTCx->DOY = TimeValue & RTC_DOY_MASK;\r
+ break;\r
+\r
+ case RTC_TIMETYPE_MONTH:\r
+ CHECK_PARAM((TimeValue > RTC_MONTH_MIN) \\r
+ && (TimeValue < RTC_MONTH_MAX));\r
+\r
+ RTCx->MONTH = TimeValue & RTC_MONTH_MASK;\r
+ break;\r
+\r
+ case RTC_TIMETYPE_YEAR:\r
+ CHECK_PARAM(TimeValue < RTC_YEAR_MAX);\r
+\r
+ RTCx->YEAR = TimeValue & RTC_YEAR_MASK;\r
+ break;\r
+ }\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief Get current time value for each type time type\r
+ * @param[in] RTCx RTC peripheral selected, should be RTC\r
+ * @param[in] Timetype: Time Type, should be:\r
+ * - RTC_TIMETYPE_SECOND\r
+ * - RTC_TIMETYPE_MINUTE\r
+ * - RTC_TIMETYPE_HOUR\r
+ * - RTC_TIMETYPE_DAYOFWEEK\r
+ * - RTC_TIMETYPE_DAYOFMONTH\r
+ * - RTC_TIMETYPE_DAYOFYEAR\r
+ * - RTC_TIMETYPE_MONTH\r
+ * - RTC_TIMETYPE_YEAR\r
+ * @return Value of time according to specified time type\r
+ **********************************************************************/\r
+uint32_t RTC_GetTime(LPC_RTC_TypeDef *RTCx, uint32_t Timetype)\r
+{\r
+ CHECK_PARAM(PARAM_RTCx(RTCx));\r
+ CHECK_PARAM(PARAM_RTC_TIMETYPE(Timetype));\r
+\r
+ switch (Timetype)\r
+ {\r
+ case RTC_TIMETYPE_SECOND:\r
+ return (RTCx->SEC & RTC_SEC_MASK);\r
+ break;\r
+ case RTC_TIMETYPE_MINUTE:\r
+ return (RTCx->MIN & RTC_MIN_MASK);\r
+ break;\r
+ case RTC_TIMETYPE_HOUR:\r
+ return (RTCx->HOUR & RTC_HOUR_MASK);\r
+ break;\r
+ case RTC_TIMETYPE_DAYOFWEEK:\r
+ return (RTCx->DOW & RTC_DOW_MASK);\r
+ break;\r
+ case RTC_TIMETYPE_DAYOFMONTH:\r
+ return (RTCx->DOM & RTC_DOM_MASK);\r
+ break;\r
+ case RTC_TIMETYPE_DAYOFYEAR:\r
+ return (RTCx->DOY & RTC_DOY_MASK);\r
+ break;\r
+ case RTC_TIMETYPE_MONTH:\r
+ return (RTCx->MONTH & RTC_MONTH_MASK);\r
+ break;\r
+ case RTC_TIMETYPE_YEAR:\r
+ return (RTCx->YEAR & RTC_YEAR_MASK);\r
+ break;\r
+ default:\r
+ return (0);\r
+ break;\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Set full of time in RTC peripheral\r
+ * @param[in] RTCx RTC peripheral selected, should be RTC\r
+ * @param[in] pFullTime Pointer to a RTC_TIME_Type structure that\r
+ * contains time value in full.\r
+ * @return None\r
+ **********************************************************************/\r
+void RTC_SetFullTime (LPC_RTC_TypeDef *RTCx, RTC_TIME_Type *pFullTime)\r
+{\r
+ CHECK_PARAM(PARAM_RTCx(RTCx));\r
+\r
+ RTCx->DOM = pFullTime->DOM & RTC_DOM_MASK;\r
+ RTCx->DOW = pFullTime->DOW & RTC_DOW_MASK;\r
+ RTCx->DOY = pFullTime->DOY & RTC_DOY_MASK;\r
+ RTCx->HOUR = pFullTime->HOUR & RTC_HOUR_MASK;\r
+ RTCx->MIN = pFullTime->MIN & RTC_MIN_MASK;\r
+ RTCx->SEC = pFullTime->SEC & RTC_SEC_MASK;\r
+ RTCx->MONTH = pFullTime->MONTH & RTC_MONTH_MASK;\r
+ RTCx->YEAR = pFullTime->YEAR & RTC_YEAR_MASK;\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Get full of time in RTC peripheral\r
+ * @param[in] RTCx RTC peripheral selected, should be RTC\r
+ * @param[in] pFullTime Pointer to a RTC_TIME_Type structure that\r
+ * will be stored time in full.\r
+ * @return None\r
+ **********************************************************************/\r
+void RTC_GetFullTime (LPC_RTC_TypeDef *RTCx, RTC_TIME_Type *pFullTime)\r
+{\r
+ CHECK_PARAM(PARAM_RTCx(RTCx));\r
+\r
+ pFullTime->DOM = RTCx->DOM & RTC_DOM_MASK;\r
+ pFullTime->DOW = RTCx->DOW & RTC_DOW_MASK;\r
+ pFullTime->DOY = RTCx->DOY & RTC_DOY_MASK;\r
+ pFullTime->HOUR = RTCx->HOUR & RTC_HOUR_MASK;\r
+ pFullTime->MIN = RTCx->MIN & RTC_MIN_MASK;\r
+ pFullTime->SEC = RTCx->SEC & RTC_SEC_MASK;\r
+ pFullTime->MONTH = RTCx->MONTH & RTC_MONTH_MASK;\r
+ pFullTime->YEAR = RTCx->YEAR & RTC_YEAR_MASK;\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Set alarm time value for each time type\r
+ * @param[in] RTCx RTC peripheral selected, should be RTC\r
+ * @param[in] Timetype: Time Type, should be:\r
+ * - RTC_TIMETYPE_SECOND\r
+ * - RTC_TIMETYPE_MINUTE\r
+ * - RTC_TIMETYPE_HOUR\r
+ * - RTC_TIMETYPE_DAYOFWEEK\r
+ * - RTC_TIMETYPE_DAYOFMONTH\r
+ * - RTC_TIMETYPE_DAYOFYEAR\r
+ * - RTC_TIMETYPE_MONTH\r
+ * - RTC_TIMETYPE_YEAR\r
+ * @param[in] ALValue Alarm time value to set\r
+ * @return None\r
+ **********************************************************************/\r
+void RTC_SetAlarmTime (LPC_RTC_TypeDef *RTCx, uint32_t Timetype, uint32_t ALValue)\r
+{\r
+ CHECK_PARAM(PARAM_RTCx(RTCx));\r
+\r
+ switch (Timetype)\r
+ {\r
+ case RTC_TIMETYPE_SECOND:\r
+ CHECK_PARAM(ALValue < RTC_SECOND_MAX);\r
+\r
+ RTCx->ALSEC = ALValue & RTC_SEC_MASK;\r
+ break;\r
+\r
+ case RTC_TIMETYPE_MINUTE:\r
+ CHECK_PARAM(ALValue < RTC_MINUTE_MAX);\r
+\r
+ RTCx->ALMIN = ALValue & RTC_MIN_MASK;\r
+ break;\r
+\r
+ case RTC_TIMETYPE_HOUR:\r
+ CHECK_PARAM(ALValue < RTC_HOUR_MAX);\r
+\r
+ RTCx->ALHOUR = ALValue & RTC_HOUR_MASK;\r
+ break;\r
+\r
+ case RTC_TIMETYPE_DAYOFWEEK:\r
+ CHECK_PARAM(ALValue < RTC_DAYOFWEEK_MAX);\r
+\r
+ RTCx->ALDOW = ALValue & RTC_DOW_MASK;\r
+ break;\r
+\r
+ case RTC_TIMETYPE_DAYOFMONTH:\r
+ CHECK_PARAM((ALValue < RTC_DAYOFMONTH_MAX) \\r
+ && (ALValue > RTC_DAYOFMONTH_MIN));\r
+\r
+ RTCx->ALDOM = ALValue & RTC_DOM_MASK;\r
+ break;\r
+\r
+ case RTC_TIMETYPE_DAYOFYEAR:\r
+ CHECK_PARAM((ALValue > RTC_DAYOFYEAR_MIN) \\r
+ && (ALValue < RTC_DAYOFYEAR_MAX));\r
+\r
+ RTCx->ALDOY = ALValue & RTC_DOY_MASK;\r
+ break;\r
+\r
+ case RTC_TIMETYPE_MONTH:\r
+ CHECK_PARAM((ALValue > RTC_MONTH_MIN) \\r
+ && (ALValue < RTC_MONTH_MAX));\r
+\r
+ RTCx->ALMON = ALValue & RTC_MONTH_MASK;\r
+ break;\r
+\r
+ case RTC_TIMETYPE_YEAR:\r
+ CHECK_PARAM(ALValue < RTC_YEAR_MAX);\r
+\r
+ RTCx->ALYEAR = ALValue & RTC_YEAR_MASK;\r
+ break;\r
+ }\r
+}\r
+\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Get alarm time value for each time type\r
+ * @param[in] RTCx RTC peripheral selected, should be RTC\r
+ * @param[in] Timetype: Time Type, should be:\r
+ * - RTC_TIMETYPE_SECOND\r
+ * - RTC_TIMETYPE_MINUTE\r
+ * - RTC_TIMETYPE_HOUR\r
+ * - RTC_TIMETYPE_DAYOFWEEK\r
+ * - RTC_TIMETYPE_DAYOFMONTH\r
+ * - RTC_TIMETYPE_DAYOFYEAR\r
+ * - RTC_TIMETYPE_MONTH\r
+ * - RTC_TIMETYPE_YEAR\r
+ * @return Value of Alarm time according to specified time type\r
+ **********************************************************************/\r
+uint32_t RTC_GetAlarmTime (LPC_RTC_TypeDef *RTCx, uint32_t Timetype)\r
+{\r
+ switch (Timetype)\r
+ {\r
+ case RTC_TIMETYPE_SECOND:\r
+ return (RTCx->ALSEC & RTC_SEC_MASK);\r
+ break;\r
+ case RTC_TIMETYPE_MINUTE:\r
+ return (RTCx->ALMIN & RTC_MIN_MASK);\r
+ break;\r
+ case RTC_TIMETYPE_HOUR:\r
+ return (RTCx->ALHOUR & RTC_HOUR_MASK);\r
+ break;\r
+ case RTC_TIMETYPE_DAYOFWEEK:\r
+ return (RTCx->ALDOW & RTC_DOW_MASK);\r
+ break;\r
+ case RTC_TIMETYPE_DAYOFMONTH:\r
+ return (RTCx->ALDOM & RTC_DOM_MASK);\r
+ break;\r
+ case RTC_TIMETYPE_DAYOFYEAR:\r
+ return (RTCx->ALDOY & RTC_DOY_MASK);\r
+ break;\r
+ case RTC_TIMETYPE_MONTH:\r
+ return (RTCx->ALMON & RTC_MONTH_MASK);\r
+ break;\r
+ case RTC_TIMETYPE_YEAR:\r
+ return (RTCx->ALYEAR & RTC_YEAR_MASK);\r
+ break;\r
+ default:\r
+ return (0);\r
+ break;\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Set full of alarm time in RTC peripheral\r
+ * @param[in] RTCx RTC peripheral selected, should be RTC\r
+ * @param[in] pFullTime Pointer to a RTC_TIME_Type structure that\r
+ * contains alarm time value in full.\r
+ * @return None\r
+ **********************************************************************/\r
+void RTC_SetFullAlarmTime (LPC_RTC_TypeDef *RTCx, RTC_TIME_Type *pFullTime)\r
+{\r
+ CHECK_PARAM(PARAM_RTCx(RTCx));\r
+\r
+ RTCx->ALDOM = pFullTime->DOM & RTC_DOM_MASK;\r
+ RTCx->ALDOW = pFullTime->DOW & RTC_DOW_MASK;\r
+ RTCx->ALDOY = pFullTime->DOY & RTC_DOY_MASK;\r
+ RTCx->ALHOUR = pFullTime->HOUR & RTC_HOUR_MASK;\r
+ RTCx->ALMIN = pFullTime->MIN & RTC_MIN_MASK;\r
+ RTCx->ALSEC = pFullTime->SEC & RTC_SEC_MASK;\r
+ RTCx->ALMON = pFullTime->MONTH & RTC_MONTH_MASK;\r
+ RTCx->ALYEAR = pFullTime->YEAR & RTC_YEAR_MASK;\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Get full of alarm time in RTC peripheral\r
+ * @param[in] RTCx RTC peripheral selected, should be RTC\r
+ * @param[in] pFullTime Pointer to a RTC_TIME_Type structure that\r
+ * will be stored alarm time in full.\r
+ * @return None\r
+ **********************************************************************/\r
+void RTC_GetFullAlarmTime (LPC_RTC_TypeDef *RTCx, RTC_TIME_Type *pFullTime)\r
+{\r
+ CHECK_PARAM(PARAM_RTCx(RTCx));\r
+\r
+ pFullTime->DOM = RTCx->ALDOM & RTC_DOM_MASK;\r
+ pFullTime->DOW = RTCx->ALDOW & RTC_DOW_MASK;\r
+ pFullTime->DOY = RTCx->ALDOY & RTC_DOY_MASK;\r
+ pFullTime->HOUR = RTCx->ALHOUR & RTC_HOUR_MASK;\r
+ pFullTime->MIN = RTCx->ALMIN & RTC_MIN_MASK;\r
+ pFullTime->SEC = RTCx->ALSEC & RTC_SEC_MASK;\r
+ pFullTime->MONTH = RTCx->ALMON & RTC_MONTH_MASK;\r
+ pFullTime->YEAR = RTCx->ALYEAR & RTC_YEAR_MASK;\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Check whether if specified Location interrupt in\r
+ * RTC peripheral is set or not\r
+ * @param[in] RTCx RTC peripheral selected, should be RTC\r
+ * @param[in] IntType Interrupt location type, should be:\r
+ * - RTC_INT_COUNTER_INCREASE: Counter Increment Interrupt\r
+ * block generated an interrupt.\r
+ * - RTC_INT_ALARM: Alarm generated an\r
+ * interrupt.\r
+ * @return New state of specified Location interrupt in RTC peripheral\r
+ * (SET or RESET)\r
+ **********************************************************************/\r
+IntStatus RTC_GetIntPending (LPC_RTC_TypeDef *RTCx, uint32_t IntType)\r
+{\r
+ CHECK_PARAM(PARAM_RTCx(RTCx));\r
+ CHECK_PARAM(PARAM_RTC_INT(IntType));\r
+\r
+ return ((RTCx->ILR & IntType) ? SET : RESET);\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Clear specified Location interrupt pending in\r
+ * RTC peripheral\r
+ * @param[in] RTCx RTC peripheral selected, should be RTC\r
+ * @param[in] IntType Interrupt location type, should be:\r
+ * - RTC_INT_COUNTER_INCREASE: Clear Counter Increment\r
+ * Interrupt pending.\r
+ * - RTC_INT_ALARM: Clear alarm interrupt pending\r
+ * @return None\r
+ **********************************************************************/\r
+void RTC_ClearIntPending (LPC_RTC_TypeDef *RTCx, uint32_t IntType)\r
+{\r
+ CHECK_PARAM(PARAM_RTCx(RTCx));\r
+ CHECK_PARAM(PARAM_RTC_INT(IntType));\r
+\r
+ RTCx->ILR = IntType;\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief Enable/Disable calibration counter in RTC peripheral\r
+ * @param[in] RTCx RTC peripheral selected, should be RTC\r
+ * @param[in] NewState New State of this function, should be:\r
+ * - ENABLE: The calibration counter is enabled and counting\r
+ * - DISABLE: The calibration counter is disabled and reset to zero\r
+ * @return None\r
+ **********************************************************************/\r
+void RTC_CalibCounterCmd(LPC_RTC_TypeDef *RTCx, FunctionalState NewState)\r
+{\r
+ CHECK_PARAM(PARAM_RTCx(RTCx));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));\r
+\r
+ if (NewState == ENABLE)\r
+ {\r
+ RTCx->CCR &= (~RTC_CCR_CCALEN) & RTC_CCR_BITMASK;\r
+ }\r
+ else\r
+ {\r
+ RTCx->CCR |= RTC_CCR_CCALEN;\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Configures Calibration in RTC peripheral\r
+ * @param[in] RTCx RTC peripheral selected, should be RTC\r
+ * @param[in] CalibValue Calibration value, should be in range from\r
+ * 0 to 131,072\r
+ * @param[in] CalibDir Calibration Direction, should be:\r
+ * - RTC_CALIB_DIR_FORWARD: Forward calibration\r
+ * - RTC_CALIB_DIR_BACKWARD: Backward calibration\r
+ * @return None\r
+ **********************************************************************/\r
+void RTC_CalibConfig(LPC_RTC_TypeDef *RTCx, uint32_t CalibValue, uint8_t CalibDir)\r
+{\r
+ CHECK_PARAM(PARAM_RTCx(RTCx));\r
+ CHECK_PARAM(PARAM_RTC_CALIB_DIR(CalibDir));\r
+ CHECK_PARAM(CalibValue > RTC_CALIBRATION_MAX);\r
+\r
+ RTCx->CALIBRATION = ((CalibValue - 1) & RTC_CALIBRATION_CALVAL_MASK) \\r
+ | ((CalibDir == RTC_CALIB_DIR_BACKWARD) ? RTC_CALIBRATION_LIBDIR : 0);\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Write value to General purpose registers\r
+ * @param[in] RTCx RTC peripheral selected, should be RTC\r
+ * @param[in] Channel General purpose registers Channel number,\r
+ * should be in range from 0 to 4.\r
+ * @param[in] Value Value to write\r
+ * @return None\r
+ * Note: These General purpose registers can be used to store important\r
+ * information when the main power supply is off. The value in these\r
+ * registers is not affected by chip reset.\r
+ **********************************************************************/\r
+void RTC_WriteGPREG (LPC_RTC_TypeDef *RTCx, uint8_t Channel, uint32_t Value)\r
+{\r
+ uint32_t *preg;\r
+\r
+ CHECK_PARAM(PARAM_RTCx(RTCx));\r
+ CHECK_PARAM(PARAM_RTC_GPREG_CH(Channel));\r
+\r
+ preg = (uint32_t *)&RTCx->GPREG0;\r
+ preg += Channel;\r
+ *preg = Value;\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Read value from General purpose registers\r
+ * @param[in] RTCx RTC peripheral selected, should be RTC\r
+ * @param[in] Channel General purpose registers Channel number,\r
+ * should be in range from 0 to 4.\r
+ * @return Read Value\r
+ * Note: These General purpose registers can be used to store important\r
+ * information when the main power supply is off. The value in these\r
+ * registers is not affected by chip reset.\r
+ **********************************************************************/\r
+uint32_t RTC_ReadGPREG (LPC_RTC_TypeDef *RTCx, uint8_t Channel)\r
+{\r
+ uint32_t *preg;\r
+ uint32_t value;\r
+\r
+ CHECK_PARAM(PARAM_RTCx(RTCx));\r
+ CHECK_PARAM(PARAM_RTC_GPREG_CH(Channel));\r
+\r
+ preg = (uint32_t *)&RTCx->GPREG0;\r
+ preg += Channel;\r
+ value = *preg;\r
+ return (value);\r
+}\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#endif /* _RTC */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* --------------------------------- End Of File ------------------------------ */\r
+\r
--- /dev/null
+/***********************************************************************//**\r
+ * @file : lpc17xx_rtc.h\r
+ * @brief : Contains all macro definitions and function prototypes\r
+ * support for RTC firmware library on LPC17xx\r
+ * @version : 1.0\r
+ * @date : 23. Apr. 2009\r
+ * @author : HieuNguyen\r
+ **************************************************************************\r
+ * Software that is described herein is for illustrative purposes only\r
+ * which provides customers with programming information regarding the\r
+ * products. This software is supplied "AS IS" without any warranties.\r
+ * NXP Semiconductors assumes no responsibility or liability for the\r
+ * use of the software, conveys no license or title under any patent,\r
+ * copyright, or mask work right to the product. NXP Semiconductors\r
+ * reserves the right to make changes in the software without\r
+ * notification. NXP Semiconductors also make no representation or\r
+ * warranty that such application will be suitable for the specified\r
+ * use without further testing or modification.\r
+ **************************************************************************/\r
+\r
+/* Peripheral group ----------------------------------------------------------- */\r
+/** @defgroup RTC\r
+ * @ingroup LPC1700CMSIS_FwLib_Drivers\r
+ * @{\r
+ */\r
+\r
+#ifndef LPC17XX_RTC_H_\r
+#define LPC17XX_RTC_H_\r
+\r
+/* Includes ------------------------------------------------------------------- */\r
+#include "LPC17xx.h"\r
+#include "lpc_types.h"\r
+\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif\r
+\r
+\r
+/* Private Macros ------------------------------------------------------------- */\r
+/** @defgroup RTC_Private_Macros\r
+ * @{\r
+ */\r
+\r
+/** @defgroup RTC_REGISTER_BIT_DEFINITIONS\r
+ * @{\r
+ */\r
+\r
+/* Miscellaneous register group --------------------------------------------- */\r
+\r
+/**********************************************************************\r
+* ILR register definitions\r
+**********************************************************************/\r
+/** ILR register mask */\r
+#define RTC_ILR_BITMASK ((0x00000003))\r
+/** Bit inform the source interrupt is counter increment*/\r
+#define RTC_IRL_RTCCIF ((1<<0))\r
+/** Bit inform the source interrupt is alarm match*/\r
+#define RTC_IRL_RTCALF ((1<<1))\r
+\r
+\r
+/**********************************************************************\r
+* CCR register definitions\r
+**********************************************************************/\r
+/** CCR register mask */\r
+#define RTC_CCR_BITMASK ((0x00000013))\r
+/** Clock enable */\r
+#define RTC_CCR_CLKEN ((1<<0))\r
+/** Clock reset */\r
+#define RTC_CCR_CTCRST ((1<<1))\r
+/** Calibration counter enable */\r
+#define RTC_CCR_CCALEN ((1<<4))\r
+\r
+\r
+/**********************************************************************\r
+* CIIR register definitions\r
+**********************************************************************/\r
+/** Counter Increment Interrupt bit for second */\r
+#define RTC_CIIR_IMSEC ((1<<0))\r
+/** Counter Increment Interrupt bit for minute */\r
+#define RTC_CIIR_IMMIN ((1<<1))\r
+/** Counter Increment Interrupt bit for hour */\r
+#define RTC_CIIR_IMHOUR ((1<<2))\r
+/** Counter Increment Interrupt bit for day of month */\r
+#define RTC_CIIR_IMDOM ((1<<3))\r
+/** Counter Increment Interrupt bit for day of week */\r
+#define RTC_CIIR_IMDOW ((1<<4))\r
+/** Counter Increment Interrupt bit for day of year */\r
+#define RTC_CIIR_IMDOY ((1<<5))\r
+/** Counter Increment Interrupt bit for month */\r
+#define RTC_CIIR_IMMON ((1<<6))\r
+/** Counter Increment Interrupt bit for year */\r
+#define RTC_CIIR_IMYEAR ((1<<7))\r
+/** CIIR bit mask */\r
+#define RTC_CIIR_BITMASK ((0xFF))\r
+\r
+/**********************************************************************\r
+* AMR register definitions\r
+**********************************************************************/\r
+/** Counter Increment Select Mask bit for second */\r
+#define RTC_AMR_AMRSEC ((1<<0))\r
+/** Counter Increment Select Mask bit for minute */\r
+#define RTC_AMR_AMRMIN ((1<<1))\r
+/** Counter Increment Select Mask bit for hour */\r
+#define RTC_AMR_AMRHOUR ((1<<2))\r
+/** Counter Increment Select Mask bit for day of month */\r
+#define RTC_AMR_AMRDOM ((1<<3))\r
+/** Counter Increment Select Mask bit for day of week */\r
+#define RTC_AMR_AMRDOW ((1<<4))\r
+/** Counter Increment Select Mask bit for day of year */\r
+#define RTC_AMR_AMRDOY ((1<<5))\r
+/** Counter Increment Select Mask bit for month */\r
+#define RTC_AMR_AMRMON ((1<<6))\r
+/** Counter Increment Select Mask bit for year */\r
+#define RTC_AMR_AMRYEAR ((1<<7))\r
+/** AMR bit mask */\r
+#define RTC_AMR_BITMASK ((0xFF))\r
+\r
+/**********************************************************************\r
+* RTC_AUX register definitions\r
+**********************************************************************/\r
+/** RTC Oscillator Fail detect flag */\r
+#define RTC_AUX_RTC_OSCF ((1<<4))\r
+\r
+/**********************************************************************\r
+* RTC_AUXEN register definitions\r
+**********************************************************************/\r
+/** Oscillator Fail Detect interrupt enable*/\r
+#define RTC_AUXEN_RTC_OSCFEN ((1<<4))\r
+\r
+\r
+/* Consolidated time register group ----------------------------------- */\r
+/** Consolidated Time Register 0 */\r
+#define RTC_CTIME0_SECONDS_MASK ((0x3F))\r
+#define RTC_CTIME0_MINUTES_MASK ((0x3F00))\r
+#define RTC_CTIME0_HOURS_MASK ((0x1F0000))\r
+#define RTC_CTIME0_DOW_MASK ((0x7000000))\r
+/** Consolidated Time Register 1 */\r
+#define RTC_CTIME1_DOM_MASK ((0x1F))\r
+#define RTC_CTIME1_MONTH_MASK ((0xF00))\r
+#define RTC_CTIME1_YEAR_MASK ((0xFFF0000))\r
+/** Consolidated Time Register 2 */\r
+#define RTC_CTIME2_DOY_MASK ((0xFFF))\r
+\r
+\r
+/* Time Counter Group and Alarm register group ----------------------------- */\r
+/** SEC register mask */\r
+#define RTC_SEC_MASK (0x0000003F)\r
+/** MIN register mask */\r
+#define RTC_MIN_MASK (0x0000003F)\r
+/** HOUR register mask */\r
+#define RTC_HOUR_MASK (0x0000001F)\r
+/** DOM register mask */\r
+#define RTC_DOM_MASK (0x0000001F)\r
+/** DOW register mask */\r
+#define RTC_DOW_MASK (0x00000007)\r
+/** DOY register mask */\r
+#define RTC_DOY_MASK (0x000001FF)\r
+/** MONTH register mask */\r
+#define RTC_MONTH_MASK (0x0000000F)\r
+/** YEAR register mask */\r
+#define RTC_YEAR_MASK (0x00000FFF)\r
+\r
+#define RTC_SECOND_MAX 59 /*!< Maximum value of second */\r
+#define RTC_MINUTE_MAX 59 /*!< Maximum value of minute*/\r
+#define RTC_HOUR_MAX 23 /*!< Maximum value of hour*/\r
+#define RTC_MONTH_MIN 1 /*!< Minimum value of month*/\r
+#define RTC_MONTH_MAX 12 /*!< Maximum value of month*/\r
+#define RTC_DAYOFMONTH_MIN 1 /*!< Minimum value of day of month*/\r
+#define RTC_DAYOFMONTH_MAX 31 /*!< Maximum value of day of month*/\r
+#define RTC_DAYOFWEEK_MAX 6 /*!< Maximum value of day of week*/\r
+#define RTC_DAYOFYEAR_MIN 1 /*!< Minimum value of day of year*/\r
+#define RTC_DAYOFYEAR_MAX 366 /*!< Maximum value of day of year*/\r
+#define RTC_YEAR_MAX 4095 /*!< Maximum value of year*/\r
+\r
+/* Calibration register */\r
+/** Calibration value */\r
+#define RTC_CALIBRATION_CALVAL_MASK ((0x1FFFF))\r
+/** Calibration direction */\r
+#define RTC_CALIBRATION_LIBDIR ((1<<17))\r
+/** Calibration max value */\r
+#define RTC_CALIBRATION_MAX ((0x20000))\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Types --------------------------------------------------------------- */\r
+/** @defgroup RTC_Public_Types\r
+ * @{\r
+ */\r
+\r
+/** @brief Time structure definitions for easy manipulate the data */\r
+typedef struct {\r
+ uint32_t SEC; /*!< Seconds Register */\r
+ uint32_t MIN; /*!< Minutes Register */\r
+ uint32_t HOUR; /*!< Hours Register */\r
+ uint32_t DOM; /*!< Day of Month Register */\r
+ uint32_t DOW; /*!< Day of Week Register */\r
+ uint32_t DOY; /*!< Day of Year Register */\r
+ uint32_t MONTH; /*!< Months Register */\r
+ uint32_t YEAR; /*!< Years Register */\r
+} RTC_TIME_Type;\r
+\r
+/** @brief RTC interrupt source */\r
+typedef enum {\r
+ RTC_INT_COUNTER_INCREASE = RTC_IRL_RTCCIF, /*!< Counter Increment Interrupt */\r
+ RTC_INT_ALARM = RTC_IRL_RTCALF, /*!< The alarm interrupt */\r
+} RTC_INT_OPT;\r
+\r
+#define PARAM_RTC_INT(n) ((n==RTC_INT_COUNTER_INCREASE) || (n==RTC_INT_ALARM))\r
+\r
+\r
+/** @brief RTC time type option */\r
+typedef enum {\r
+ RTC_TIMETYPE_SECOND = 0, /*!< Second */\r
+ RTC_TIMETYPE_MINUTE = 1, /*!< Month */\r
+ RTC_TIMETYPE_HOUR = 2, /*!< Hour */\r
+ RTC_TIMETYPE_DAYOFWEEK = 3, /*!< Day of week */\r
+ RTC_TIMETYPE_DAYOFMONTH = 4, /*!< Day of month */\r
+ RTC_TIMETYPE_DAYOFYEAR = 5, /*!< Day of year */\r
+ RTC_TIMETYPE_MONTH = 6, /*!< Month */\r
+ RTC_TIMETYPE_YEAR = 7, /*!< Year */\r
+} RTC_TIMETYPE_Num;\r
+\r
+#define PARAM_RTC_TIMETYPE(n) ((n==RTC_TIMETYPE_SECOND) || (n==RTC_TIMETYPE_MINUTE) \\r
+|| (n==RTC_TIMETYPE_HOUR) || (n==RTC_TIMETYPE_DAYOFWEEK) \\r
+|| (n==RTC_TIMETYPE_DAYOFMONTH) || (n==RTC_TIMETYPE_DAYOFYEAR) \\r
+|| (n==RTC_TIMETYPE_MONTH) || (n==RTC_TIMETYPE_YEAR))\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Macros -------------------------------------------------------------- */\r
+/** @defgroup RTC_Public_Macros\r
+ * @{\r
+ */\r
+\r
+/** Macro to determine if it is valid RTC peripheral */\r
+#define PARAM_RTCx(x) (((uint32_t *)x)==((uint32_t *)LPC_RTC))\r
+\r
+/** Calibration definitions */\r
+#define RTC_CALIB_DIR_FORWARD ((uint8_t)(0))\r
+#define RTC_CALIB_DIR_BACKWARD ((uint8_t)(1))\r
+\r
+#define PARAM_RTC_CALIB_DIR(n) ((n==RTC_CALIB_DIR_FORWARD) || (n==RTC_CALIB_DIR_BACKWARD))\r
+#define PARAM_RTC_GPREG_CH(n) ((n>=0) && (n<=4))\r
+\r
+#define PARAM_RTC_CALIBRATION_DIR(n)\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Functions ----------------------------------------------------------- */\r
+/** @defgroup RTC_Public_Functions\r
+ * @{\r
+ */\r
+\r
+void RTC_Init (LPC_RTC_TypeDef *RTCx);\r
+void RTC_DeInit(LPC_RTC_TypeDef *RTCx);\r
+void RTC_ResetClockTickCounter(LPC_RTC_TypeDef *RTCx);\r
+void RTC_Cmd (LPC_RTC_TypeDef *RTCx, FunctionalState NewState);\r
+void RTC_CntIncrIntConfig (LPC_RTC_TypeDef *RTCx, uint32_t CntIncrIntType, \\r
+ FunctionalState NewState);\r
+void RTC_AlarmIntConfig (LPC_RTC_TypeDef *RTCx, uint32_t AlarmTimeType, \\r
+ FunctionalState NewState);\r
+void RTC_SetTime (LPC_RTC_TypeDef *RTCx, uint32_t Timetype, uint32_t TimeValue);\r
+uint32_t RTC_GetTime(LPC_RTC_TypeDef *RTCx, uint32_t Timetype);\r
+void RTC_SetFullTime (LPC_RTC_TypeDef *RTCx, RTC_TIME_Type *pFullTime);\r
+void RTC_GetFullTime (LPC_RTC_TypeDef *RTCx, RTC_TIME_Type *pFullTime);\r
+void RTC_SetAlarmTime (LPC_RTC_TypeDef *RTCx, uint32_t Timetype, uint32_t ALValue);\r
+uint32_t RTC_GetAlarmTime (LPC_RTC_TypeDef *RTCx, uint32_t Timetype);\r
+void RTC_SetFullAlarmTime (LPC_RTC_TypeDef *RTCx, RTC_TIME_Type *pFullTime);\r
+void RTC_GetFullAlarmTime (LPC_RTC_TypeDef *RTCx, RTC_TIME_Type *pFullTime);\r
+IntStatus RTC_GetIntPending (LPC_RTC_TypeDef *RTCx, uint32_t IntType);\r
+void RTC_ClearIntPending (LPC_RTC_TypeDef *RTCx, uint32_t IntType);\r
+void RTC_CalibCounterCmd(LPC_RTC_TypeDef *RTCx, FunctionalState NewState);\r
+void RTC_CalibConfig(LPC_RTC_TypeDef *RTCx, uint32_t CalibValue, uint8_t CalibDir);\r
+void RTC_WriteGPREG (LPC_RTC_TypeDef *RTCx, uint8_t Channel, uint32_t Value);\r
+uint32_t RTC_ReadGPREG (LPC_RTC_TypeDef *RTCx, uint8_t Channel);\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* LPC17XX_RTC_H_ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* --------------------------------- End Of File ------------------------------ */\r
--- /dev/null
+/**\r
+ * @file : lpc17xx_spi.c\r
+ * @brief : Contains all functions support for SPI firmware library on LPC17xx\r
+ * @version : 1.0\r
+ * @date : 3. April. 2009\r
+ * @author : HieuNguyen\r
+ **************************************************************************\r
+ * Software that is described herein is for illustrative purposes only\r
+ * which provides customers with programming information regarding the\r
+ * products. This software is supplied "AS IS" without any warranties.\r
+ * NXP Semiconductors assumes no responsibility or liability for the\r
+ * use of the software, conveys no license or title under any patent,\r
+ * copyright, or mask work right to the product. NXP Semiconductors\r
+ * reserves the right to make changes in the software without\r
+ * notification. NXP Semiconductors also make no representation or\r
+ * warranty that such application will be suitable for the specified\r
+ * use without further testing or modification.\r
+ **********************************************************************/\r
+\r
+/* Peripheral group ----------------------------------------------------------- */\r
+/** @addtogroup SPI\r
+ * @{\r
+ */\r
+\r
+/* Includes ------------------------------------------------------------------- */\r
+#include "lpc17xx_spi.h"\r
+#include "lpc17xx_clkpwr.h"\r
+\r
+/* If this source file built with example, the LPC17xx FW library configuration\r
+ * file in each example directory ("lpc17xx_libcfg.h") must be included,\r
+ * otherwise the default FW library configuration file must be included instead\r
+ */\r
+#ifdef __BUILD_WITH_EXAMPLE__\r
+#include "lpc17xx_libcfg.h"\r
+#else\r
+#include "lpc17xx_libcfg_default.h"\r
+#endif /* __BUILD_WITH_EXAMPLE__ */\r
+\r
+#ifdef _SPI\r
+\r
+/* Private Types -------------------------------------------------------------- */\r
+/** @defgroup SPI_Private_Types\r
+ * @{\r
+ */\r
+\r
+/** @brief SPI device configuration structure type */\r
+typedef struct\r
+{\r
+ int32_t dataword; /* Current data word: 0 - 8 bit; 1 - 16 bit */\r
+ uint32_t txrx_setup; /* Transmission setup */\r
+ void (*inthandler)(void); /* Transmission interrupt handler */\r
+} SPI_CFG_T;\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Private Variables ---------------------------------------------------------- */\r
+/* SPI configuration data */\r
+static SPI_CFG_T spidat;\r
+\r
+\r
+/* Private Functions ---------------------------------------------------------- */\r
+/** @defgroup SPI_Private_Functions\r
+ * @{\r
+ */\r
+\r
+/*********************************************************************//**\r
+ * @brief Standard Private SPI Interrupt handler\r
+ * @param[in] None\r
+ * @return None\r
+ ***********************************************************************/\r
+void SPI_IntHandler(void)\r
+{\r
+ SPI_DATA_SETUP_Type *xf_setup;\r
+ uint16_t tmp;\r
+\r
+ xf_setup = (SPI_DATA_SETUP_Type *)spidat.txrx_setup;\r
+\r
+ /* Dummy read to clear SPI interrupt flag */\r
+ if (LPC_SPI->SPINT & SPI_SPINT_INTFLAG){\r
+ LPC_SPI->SPINT = SPI_SPINT_INTFLAG;\r
+ }\r
+\r
+ // save status\r
+ tmp = LPC_SPI->SPSR;\r
+ xf_setup->status = tmp;\r
+ // Check for error\r
+ if (tmp & (SPI_SPSR_ABRT | SPI_SPSR_MODF | SPI_SPSR_ROVR | SPI_SPSR_WCOL)){\r
+ xf_setup->status |= SPI_STAT_ERROR;\r
+ // Disable Interrupt and call call-back\r
+ SPI_IntCmd(LPC_SPI, DISABLE);\r
+ if (xf_setup->callback != NULL){\r
+ xf_setup->callback();\r
+ }\r
+ return;\r
+ }\r
+\r
+ /* Check SPI complete flag */\r
+ if (tmp & SPI_SPSR_SPIF){\r
+ // Read data from SPI data\r
+ tmp = SPI_ReceiveData(LPC_SPI);\r
+ if (xf_setup->rx_data != NULL)\r
+ {\r
+// if (spidat.dataword == 0){\r
+// *(uint8_t *)(xf_setup->rx_data + xf_setup->counter) = (uint8_t) tmp;\r
+// } else {\r
+// *(uint16_t *)(xf_setup->rx_data + xf_setup->counter) = (uint8_t) tmp;\r
+// }\r
+ if (spidat.dataword == 0){\r
+ *(uint8_t *)((uint8_t *)(xf_setup->rx_data) + xf_setup->counter) = (uint8_t) tmp;\r
+ } else {\r
+ *(uint16_t *)((uint8_t *)(xf_setup->rx_data) + xf_setup->counter) = (uint8_t) tmp;\r
+ }\r
+ }\r
+ // Increase counter\r
+ if (spidat.dataword == 0){\r
+ xf_setup->counter++;\r
+ } else {\r
+ xf_setup->counter += 2;\r
+ }\r
+ }\r
+\r
+ if (xf_setup->counter < xf_setup->length){\r
+ // Write data to buffer\r
+ if(xf_setup->tx_data == NULL){\r
+ if (spidat.dataword == 0){\r
+ SPI_SendData(LPC_SPI, 0xFF);\r
+ } else {\r
+ SPI_SendData(LPC_SPI, 0xFFFF);\r
+ }\r
+ } else {\r
+// if (spidat.dataword == 0){\r
+// SPI_SendData(SPI, (*(uint8_t *)(xf_setup->tx_data + xf_setup->counter)));\r
+// } else {\r
+// SPI_SendData(SPI, (*(uint16_t *)(xf_setup->tx_data + xf_setup->counter)));\r
+// }\r
+ if (spidat.dataword == 0){\r
+ SPI_SendData(LPC_SPI, (*(uint8_t *)((uint8_t *)(xf_setup->tx_data) + xf_setup->counter)));\r
+ } else {\r
+ SPI_SendData(LPC_SPI, (*(uint16_t *)((uint8_t *)(xf_setup->tx_data) + xf_setup->counter)));\r
+ }\r
+ }\r
+ }\r
+ // No more data to send\r
+ else {\r
+ xf_setup->status |= SPI_STAT_DONE;\r
+ // Disable Interrupt and call call-back\r
+ SPI_IntCmd(LPC_SPI, DISABLE);\r
+ if (xf_setup->callback != NULL){\r
+ xf_setup->callback();\r
+ }\r
+ }\r
+}\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* Public Functions ----------------------------------------------------------- */\r
+/** @addtogroup SPI_Public_Functions\r
+ * @{\r
+ */\r
+\r
+/*********************************************************************//**\r
+ * @brief Setup clock rate for SPI device\r
+ * @param[in] SPIx SPI peripheral definition, should be SPI\r
+ * @param[in] target_clock : clock of SPI (Hz)\r
+ * @return None\r
+ ***********************************************************************/\r
+void SPI_SetClock (LPC_SPI_TypeDef *SPIx, uint32_t target_clock)\r
+{\r
+ uint32_t spi_pclk;\r
+ uint32_t prescale, temp;\r
+\r
+ CHECK_PARAM(PARAM_SPIx(SPIx));\r
+\r
+ if (SPIx == LPC_SPI){\r
+ spi_pclk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_SPI);\r
+ } else {\r
+ return;\r
+ }\r
+\r
+ prescale = 8;\r
+ // Find closest clock to target clock\r
+ while (1){\r
+ temp = target_clock * prescale;\r
+ if (temp >= spi_pclk){\r
+ break;\r
+ }\r
+ prescale += 2;\r
+ if(prescale >= 254){\r
+ break;\r
+ }\r
+ }\r
+\r
+ // Write to register\r
+ SPIx->SPCCR = SPI_SPCCR_COUNTER(prescale);\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief De-initializes the SPIx peripheral registers to their\r
+* default reset values.\r
+ * @param[in] SPIx SPI peripheral selected, should be SPI\r
+ * @return None\r
+ **********************************************************************/\r
+void SPI_DeInit(LPC_SPI_TypeDef *SPIx)\r
+{\r
+ CHECK_PARAM(PARAM_SPIx(SPIx));\r
+\r
+ if (SPIx == LPC_SPI){\r
+ /* Set up clock and power for SPI module */\r
+ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCSPI, DISABLE);\r
+ }\r
+}\r
+\r
+\r
+\r
+/********************************************************************//**\r
+ * @brief Initializes the SPIx peripheral according to the specified\r
+* parameters in the UART_ConfigStruct.\r
+ * @param[in] SPIx SPI peripheral selected, should be SPI\r
+ * @param[in] SPI_ConfigStruct Pointer to a SPI_CFG_Type structure\r
+* that contains the configuration information for the\r
+* specified SPI peripheral.\r
+ * @return None\r
+ *********************************************************************/\r
+void SPI_Init(LPC_SPI_TypeDef *SPIx, SPI_CFG_Type *SPI_ConfigStruct)\r
+{\r
+ uint32_t tmp;\r
+\r
+ CHECK_PARAM(PARAM_SPIx(SPIx));\r
+\r
+ if(SPIx == LPC_SPI){\r
+ /* Set up clock and power for UART module */\r
+ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCSPI, ENABLE);\r
+ } else {\r
+ return;\r
+ }\r
+\r
+ // Configure SPI, interrupt is disable as default\r
+ tmp = ((SPI_ConfigStruct->CPHA) | (SPI_ConfigStruct->CPOL) \\r
+ | (SPI_ConfigStruct->DataOrder) | (SPI_ConfigStruct->Databit) \\r
+ | (SPI_ConfigStruct->Mode) | SPI_SPCR_BIT_EN) & SPI_SPCR_BITMASK;\r
+ // write back to SPI control register\r
+ SPIx->SPCR = tmp;\r
+\r
+ if (SPI_ConfigStruct->Databit > SPI_DATABIT_8){\r
+ spidat.dataword = 1;\r
+ } else {\r
+ spidat.dataword = 0;\r
+ }\r
+\r
+ // Set clock rate for SPI peripheral\r
+ SPI_SetClock(SPIx, SPI_ConfigStruct->ClockRate);\r
+\r
+ // If interrupt flag is set, Write '1' to Clear interrupt flag\r
+ if (SPIx->SPINT & SPI_SPINT_INTFLAG){\r
+ SPIx->SPINT = SPI_SPINT_INTFLAG;\r
+ }\r
+}\r
+\r
+\r
+\r
+/*****************************************************************************//**\r
+* @brief Fills each SPI_InitStruct member with its default value:\r
+* - CPHA = SPI_CPHA_FIRST\r
+* - CPOL = SPI_CPOL_HI\r
+* - ClockRate = 1000000\r
+* - DataOrder = SPI_DATA_MSB_FIRST\r
+* - Databit = SPI_DATABIT_8\r
+* - Mode = SPI_MASTER_MODE\r
+* @param[in] SPI_InitStruct Pointer to a SPI_CFG_Type structure\r
+* which will be initialized.\r
+* @return None\r
+*******************************************************************************/\r
+void SPI_ConfigStructInit(SPI_CFG_Type *SPI_InitStruct)\r
+{\r
+ SPI_InitStruct->CPHA = SPI_CPHA_FIRST;\r
+ SPI_InitStruct->CPOL = SPI_CPOL_HI;\r
+ SPI_InitStruct->ClockRate = 1000000;\r
+ SPI_InitStruct->DataOrder = SPI_DATA_MSB_FIRST;\r
+ SPI_InitStruct->Databit = SPI_DATABIT_8;\r
+ SPI_InitStruct->Mode = SPI_MASTER_MODE;\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief Transmit a single data through SPIx peripheral\r
+ * @param[in] SPIx SPI peripheral selected, should be SPI\r
+ * @param[in] Data Data to transmit (must be 16 or 8-bit long,\r
+ * this depend on SPI data bit number configured)\r
+ * @return none\r
+ **********************************************************************/\r
+void SPI_SendData(LPC_SPI_TypeDef* SPIx, uint16_t Data)\r
+{\r
+ CHECK_PARAM(PARAM_SPIx(SPIx));\r
+\r
+ SPIx->SPDR = Data & SPI_SPDR_BITMASK;\r
+}\r
+\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Receive a single data from SPIx peripheral\r
+ * @param[in] SPIx SPI peripheral selected, should be SPI\r
+ * @return Data received (16-bit long)\r
+ **********************************************************************/\r
+uint16_t SPI_ReceiveData(LPC_SPI_TypeDef* SPIx)\r
+{\r
+ CHECK_PARAM(PARAM_SPIx(SPIx));\r
+\r
+ return ((uint16_t) (SPIx->SPDR & SPI_SPDR_BITMASK));\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief SPI Read write data function\r
+ * @param[in] SPIx Pointer to SPI peripheral, should be SPI\r
+ * @param[in] dataCfg Pointer to a SPI_DATA_SETUP_Type structure that\r
+ * contains specified information about transmit\r
+ * data configuration.\r
+ * @param[in] xfType Transfer type, should be:\r
+ * - SPI_TRANSFER_POLLING: Polling mode\r
+ * - SPI_TRANSFER_INTERRUPT: Interrupt mode\r
+ * @return Actual Data length has been transferred in polling mode.\r
+ * In interrupt mode, always return (0)\r
+ * Return (-1) if error.\r
+ * Note: This function can be used in both master and slave mode.\r
+ ***********************************************************************/\r
+int32_t SPI_ReadWrite (LPC_SPI_TypeDef *SPIx, SPI_DATA_SETUP_Type *dataCfg, \\r
+ SPI_TRANSFER_Type xfType)\r
+{\r
+ uint8_t *rdata8;\r
+ uint8_t *wdata8;\r
+ uint16_t *rdata16;\r
+ uint16_t *wdata16;\r
+ uint32_t stat;\r
+ uint32_t temp;\r
+\r
+ //read for empty buffer\r
+ temp = SPIx->SPDR;\r
+ //dummy to clear status\r
+ temp = SPIx->SPSR;\r
+ dataCfg->counter = 0;\r
+ dataCfg->status = 0;\r
+\r
+ if (xfType == SPI_TRANSFER_POLLING){\r
+\r
+ if (spidat.dataword == 0){\r
+ rdata8 = (uint8_t *)dataCfg->rx_data;\r
+ wdata8 = (uint8_t *)dataCfg->tx_data;\r
+ } else {\r
+ rdata16 = (uint16_t *)dataCfg->rx_data;\r
+ wdata16 = (uint16_t *)dataCfg->tx_data;\r
+ }\r
+\r
+ while(dataCfg->counter < dataCfg->length)\r
+ {\r
+ // Write data to buffer\r
+ if(dataCfg->tx_data == NULL){\r
+ if (spidat.dataword == 0){\r
+ SPI_SendData(SPIx, 0xFF);\r
+ } else {\r
+ SPI_SendData(SPIx, 0xFFFF);\r
+ }\r
+ } else {\r
+ if (spidat.dataword == 0){\r
+ SPI_SendData(SPIx, *wdata8);\r
+ wdata8++;\r
+ } else {\r
+ SPI_SendData(SPIx, *wdata16);\r
+ wdata16++;\r
+ }\r
+ }\r
+ // Wait for transfer complete\r
+ while (!((stat = SPIx->SPSR) & SPI_SPSR_SPIF));\r
+ // Check for error\r
+ if (stat & (SPI_SPSR_ABRT | SPI_SPSR_MODF | SPI_SPSR_ROVR | SPI_SPSR_WCOL)){\r
+ // save status\r
+ dataCfg->status = stat | SPI_STAT_ERROR;\r
+ return (dataCfg->counter);\r
+ }\r
+ // Read data from SPI dat\r
+ temp = (uint32_t) SPI_ReceiveData(SPIx);\r
+\r
+ // Store data to destination\r
+ if (dataCfg->rx_data != NULL)\r
+ {\r
+ if (spidat.dataword == 0){\r
+ *(rdata8) = (uint8_t) temp;\r
+ rdata8++;\r
+ } else {\r
+ *(rdata16) = (uint16_t) temp;\r
+ rdata16++;\r
+ }\r
+ }\r
+ // Increase counter\r
+ if (spidat.dataword == 0){\r
+ dataCfg->counter++;\r
+ } else {\r
+ dataCfg->counter += 2;\r
+ }\r
+ }\r
+\r
+ // Return length of actual data transferred\r
+ // save status\r
+ dataCfg->status = stat | SPI_STAT_DONE;\r
+ return (dataCfg->counter);\r
+ }\r
+ // Interrupt mode\r
+ else {\r
+ spidat.txrx_setup = (uint32_t)dataCfg;\r
+ spidat.inthandler = SPI_IntHandler;\r
+\r
+ // Check if interrupt flag is already set\r
+ if(SPIx->SPINT & SPI_SPINT_INTFLAG){\r
+ SPIx->SPINT = SPI_SPINT_INTFLAG;\r
+ }\r
+ if (dataCfg->counter < dataCfg->length){\r
+ // Write data to buffer\r
+ if(dataCfg->tx_data == NULL){\r
+ if (spidat.dataword == 0){\r
+ SPI_SendData(SPIx, 0xFF);\r
+ } else {\r
+ SPI_SendData(SPIx, 0xFFFF);\r
+ }\r
+ } else {\r
+ if (spidat.dataword == 0){\r
+ SPI_SendData(SPIx, (*(uint8_t *)dataCfg->tx_data));\r
+ } else {\r
+ SPI_SendData(SPIx, (*(uint16_t *)dataCfg->tx_data));\r
+ }\r
+ }\r
+ SPI_IntCmd(SPIx, ENABLE);\r
+ } else {\r
+ // Save status\r
+ dataCfg->status = SPI_STAT_DONE;\r
+ }\r
+ return (0);\r
+ }\r
+ return (0);\r
+}\r
+\r
+\r
+/********************************************************************//**\r
+ * @brief Enable or disable SPIx interrupt.\r
+ * @param[in] SPIx SPI peripheral selected, should be SPI\r
+ * @param[in] NewState New state of specified UART interrupt type,\r
+ * should be:\r
+ * - ENALBE: Enable this SPI interrupt.\r
+* - DISALBE: Disable this SPI interrupt.\r
+ * @return None\r
+ *********************************************************************/\r
+void SPI_IntCmd(LPC_SPI_TypeDef *SPIx, FunctionalState NewState)\r
+{\r
+ CHECK_PARAM(PARAM_SPIx(SPIx));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));\r
+\r
+ if (NewState == ENABLE)\r
+ {\r
+ SPIx->SPCR |= SPI_SPCR_SPIE;\r
+ }\r
+ else\r
+ {\r
+ SPIx->SPCR &= (~SPI_SPCR_SPIE) & SPI_SPCR_BITMASK;\r
+ }\r
+}\r
+\r
+\r
+/********************************************************************//**\r
+ * @brief Checks whether the SPI interrupt flag is set or not.\r
+ * @param[in] SPIx SPI peripheral selected, should be SPI\r
+ * @return The new state of SPI Interrupt Flag (SET or RESET)\r
+ *********************************************************************/\r
+IntStatus SPI_GetIntStatus (LPC_SPI_TypeDef *SPIx)\r
+{\r
+ CHECK_PARAM(PARAM_SPIx(SPIx));\r
+\r
+ return ((SPIx->SPINT & SPI_SPINT_INTFLAG) ? SET : RESET);\r
+}\r
+\r
+\r
+/********************************************************************//**\r
+ * @brief Clear SPI interrupt flag.\r
+ * @param[in] SPIx SPI peripheral selected, should be SPI\r
+ * @return None\r
+ *********************************************************************/\r
+void SPI_ClearIntPending(LPC_SPI_TypeDef *SPIx)\r
+{\r
+ CHECK_PARAM(PARAM_SPIx(SPIx));\r
+\r
+ SPIx->SPINT = SPI_SPINT_INTFLAG;\r
+}\r
+\r
+\r
+/********************************************************************//**\r
+ * @brief Get current value of SPI Status register in SPIx peripheral.\r
+ * @param[in] SPIx SPI peripheral selected, should be SPI\r
+ * @return Current value of SPI Status register in SPI peripheral.\r
+ * Note: The return value of this function must be used with\r
+ * SPI_CheckStatus() to determine current flag status\r
+ * corresponding to each SPI status type. Because some flags in\r
+ * SPI Status register will be cleared after reading, the next reading\r
+ * SPI Status register could not be correct. So this function used to\r
+ * read SPI status register in one time only, then the return value\r
+ * used to check all flags.\r
+ *********************************************************************/\r
+uint32_t SPI_GetStatus(LPC_SPI_TypeDef* SPIx)\r
+{\r
+ CHECK_PARAM(PARAM_SPIx(SPIx));\r
+\r
+ return (SPIx->SPSR & SPI_SPSR_BITMASK);\r
+}\r
+\r
+\r
+\r
+/********************************************************************//**\r
+ * @brief Checks whether the specified SPI Status flag is set or not\r
+ * via inputSPIStatus parameter.\r
+ * @param[in] inputSPIStatus Value to check status of each flag type.\r
+ * This value is the return value from SPI_GetStatus().\r
+ * @param[in] SPIStatus Specifies the SPI status flag to check,\r
+ * should be one of the following:\r
+ - SPI_STAT_ABRT: Slave abort.\r
+ - SPI_STAT_MODF: Mode fault.\r
+ - SPI_STAT_ROVR: Read overrun.\r
+ - SPI_STAT_WCOL: Write collision.\r
+ - SPI_STAT_SPIF: SPI transfer complete.\r
+ * @return The new state of SPIStatus (SET or RESET)\r
+ *********************************************************************/\r
+FlagStatus SPI_CheckStatus (uint32_t inputSPIStatus, uint8_t SPIStatus)\r
+{\r
+ CHECK_PARAM(PARAM_SPI_STAT(SPIStatus));\r
+\r
+ return ((inputSPIStatus & SPIStatus) ? SET : RESET);\r
+}\r
+\r
+/**\r
+ * @brief Standard SPI Interrupt handler\r
+ * @param[in] None\r
+ * @return None\r
+ */\r
+void SPI_StdIntHandler(void)\r
+{\r
+ // Call relevant handler\r
+ spidat.inthandler();\r
+}\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#endif /* _SPI */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* --------------------------------- End Of File ------------------------------ */\r
--- /dev/null
+/***********************************************************************//**\r
+ * @file : lpc17xx_spi.h\r
+ * @brief : Contains all macro definitions and function prototypes\r
+ * support for SPI firmware library on LPC17xx\r
+ * @version : 1.0\r
+ * @date : 3. April. 2009\r
+ * @author : HieuNguyen\r
+ **************************************************************************\r
+ * Software that is described herein is for illustrative purposes only\r
+ * which provides customers with programming information regarding the\r
+ * products. This software is supplied "AS IS" without any warranties.\r
+ * NXP Semiconductors assumes no responsibility or liability for the\r
+ * use of the software, conveys no license or title under any patent,\r
+ * copyright, or mask work right to the product. NXP Semiconductors\r
+ * reserves the right to make changes in the software without\r
+ * notification. NXP Semiconductors also make no representation or\r
+ * warranty that such application will be suitable for the specified\r
+ * use without further testing or modification.\r
+ **************************************************************************/\r
+\r
+/* Peripheral group ----------------------------------------------------------- */\r
+/** @defgroup SPI\r
+ * @ingroup LPC1700CMSIS_FwLib_Drivers\r
+ * @{\r
+ */\r
+\r
+#ifndef LPC17XX_SPI_H_\r
+#define LPC17XX_SPI_H_\r
+\r
+/* Includes ------------------------------------------------------------------- */\r
+#include "LPC17xx.h"\r
+#include "lpc_types.h"\r
+\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif\r
+\r
+/* Private Macros ------------------------------------------------------------- */\r
+/** @defgroup SPI_Private_Macros\r
+ * @{\r
+ */\r
+\r
+/*********************************************************************//**\r
+ * Macro defines for SPI Control Register\r
+ **********************************************************************/\r
+/** @defgroup SPI_REGISTER_BIT_DEFINITION\r
+ * @{\r
+ */\r
+\r
+/** Bit enable, the SPI controller sends and receives the number\r
+ * of bits selected by bits 11:8 */\r
+#define SPI_SPCR_BIT_EN ((uint32_t)(1<<2))\r
+/** Clock phase control bit */\r
+#define SPI_SPCR_CPHA_SECOND ((uint32_t)(1<<3))\r
+/** Clock polarity control bit */\r
+#define SPI_SPCR_CPOL_LOW ((uint32_t)(1<<4))\r
+/** SPI master mode enable */\r
+#define SPI_SPCR_MSTR ((uint32_t)(1<<5))\r
+/** LSB enable bit */\r
+#define SPI_SPCR_LSBF ((uint32_t)(1<<6))\r
+/** SPI interrupt enable bit */\r
+#define SPI_SPCR_SPIE ((uint32_t)(1<<7))\r
+/** When bit 2 of this register is 1, this field controls the\r
+number of bits per transfer */\r
+#define SPI_SPCR_BITS(n) ((n==0) ? ((uint32_t)0) : ((uint32_t)((n&0x0F)<<8)))\r
+/** SPI Control bit mask */\r
+#define SPI_SPCR_BITMASK ((uint32_t)(0xFFC))\r
+\r
+\r
+/*********************************************************************//**\r
+ * Macro defines for SPI Status Register\r
+ **********************************************************************/\r
+/** Slave abort */\r
+#define SPI_SPSR_ABRT ((uint32_t)(1<<3))\r
+/** Mode fault */\r
+#define SPI_SPSR_MODF ((uint32_t)(1<<4))\r
+/** Read overrun */\r
+#define SPI_SPSR_ROVR ((uint32_t)(1<<5))\r
+/** Write collision */\r
+#define SPI_SPSR_WCOL ((uint32_t)(1<<6))\r
+/** SPI transfer complete flag */\r
+#define SPI_SPSR_SPIF ((uint32_t)(1<<7))\r
+/** SPI Status bit mask */\r
+#define SPI_SPSR_BITMASK ((uint32_t)(0xF8))\r
+\r
+\r
+/*********************************************************************//**\r
+ * Macro defines for SPI Data Register\r
+ **********************************************************************/\r
+/** SPI Data low bit-mask */\r
+#define SPI_SPDR_LO_MASK ((uint32_t)(0xFF))\r
+/** SPI Data high bit-mask */\r
+#define SPI_SPDR_HI_MASK ((uint32_t)(0xFF00))\r
+/** SPI Data bit-mask */\r
+#define SPI_SPDR_BITMASK ((uint32_t)(0xFFFF))\r
+\r
+\r
+/*********************************************************************//**\r
+ * Macro defines for SPI Clock Counter Register\r
+ **********************************************************************/\r
+/** SPI clock counter setting */\r
+#define SPI_SPCCR_COUNTER(n) ((uint32_t)(n&0xFF))\r
+/** SPI clock counter bit-mask */\r
+#define SPI_SPCCR_BITMASK ((uint32_t)(0xFF))\r
+\r
+\r
+/***********************************************************************\r
+ * Macro defines for SPI Test Control Register\r
+ **********************************************************************/\r
+/** SPI Test bit */\r
+#define SPI_SPTCR_TEST_MASK ((uint32_t)(0xFE))\r
+/** SPI Test register bit mask */\r
+#define SPI_SPTCR_BITMASK ((uint32_t)(0xFE))\r
+\r
+\r
+\r
+/*********************************************************************//**\r
+ * Macro defines for SPI Test Status Register\r
+ **********************************************************************/\r
+/** Slave abort */\r
+#define SPI_SPTSR_ABRT ((uint32_t)(1<<3))\r
+/** Mode fault */\r
+#define SPI_SPTSR_MODF ((uint32_t)(1<<4))\r
+/** Read overrun */\r
+#define SPI_SPTSR_ROVR ((uint32_t)(1<<5))\r
+/** Write collision */\r
+#define SPI_SPTSR_WCOL ((uint32_t)(1<<6))\r
+/** SPI transfer complete flag */\r
+#define SPI_SPTSR_SPIF ((uint32_t)(1<<7))\r
+/** SPI Status bit mask */\r
+#define SPI_SPTSR_MASKBIT ((uint32_t)(0xF8))\r
+\r
+\r
+\r
+/*********************************************************************//**\r
+ * Macro defines for SPI Interrupt Register\r
+ **********************************************************************/\r
+/** SPI interrupt flag */\r
+#define SPI_SPINT_INTFLAG ((uint32_t)(1<<0))\r
+/** SPI interrupt register bit mask */\r
+#define SPI_SPINT_BITMASK ((uint32_t)(0x01))\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Types --------------------------------------------------------------- */\r
+/** @defgroup SPI_Public_Types\r
+ * @{\r
+ */\r
+\r
+/** @brief SPI configuration structure */\r
+typedef struct {\r
+ uint32_t Databit; /** Databit number, should be SPI_DATABIT_x,\r
+ where x is in range from 8 - 16 */\r
+ uint32_t CPHA; /** Clock phase, should be:\r
+ - SPI_CPHA_FIRST: first clock edge\r
+ - SPI_CPHA_SECOND: second clock edge */\r
+ uint32_t CPOL; /** Clock polarity, should be:\r
+ - SPI_CPOL_HI: high level\r
+ - SPI_CPOL_LO: low level */\r
+ uint32_t Mode; /** SPI mode, should be:\r
+ - SPI_MASTER_MODE: Master mode\r
+ - SPI_SLAVE_MODE: Slave mode */\r
+ uint32_t DataOrder; /** Data order, should be:\r
+ - SPI_DATA_MSB_FIRST: MSB first\r
+ - SPI_DATA_LSB_FIRST: LSB first */\r
+ uint32_t ClockRate; /** Clock rate,in Hz, should not exceed\r
+ (SPI peripheral clock)/8 */\r
+} SPI_CFG_Type;\r
+\r
+\r
+/**\r
+ * @brief SPI Transfer Type definitions\r
+ */\r
+typedef enum {\r
+ SPI_TRANSFER_POLLING = 0, /**< Polling transfer */\r
+ SPI_TRANSFER_INTERRUPT /**< Interrupt transfer */\r
+} SPI_TRANSFER_Type;\r
+\r
+/**\r
+ * @brief SPI Data configuration structure definitions\r
+ */\r
+typedef struct {\r
+ void *tx_data; /**< Pointer to transmit data */\r
+ void *rx_data; /**< Pointer to transmit data */\r
+ uint32_t length; /**< Length of transfer data */\r
+ uint32_t counter; /**< Data counter index */\r
+ uint32_t status; /**< Current status of SPI activity */\r
+ void (*callback)(void); /**< Pointer to Call back function when transmission complete\r
+ used in interrupt transfer mode */\r
+} SPI_DATA_SETUP_Type;\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Macros -------------------------------------------------------------- */\r
+/** @defgroup SPI_Public_Macros\r
+ * @{\r
+ */\r
+\r
+/** Macro to determine if it is valid SPI port number */\r
+#define PARAM_SPIx(n) (((uint32_t *)n)==((uint32_t *)LPC_SPI))\r
+\r
+/*********************************************************************//**\r
+ * SPI configuration parameter defines\r
+ **********************************************************************/\r
+/** Clock phase control bit */\r
+#define SPI_CPHA_FIRST ((uint32_t)(0))\r
+#define SPI_CPHA_SECOND SPI_SPCR_CPHA_SECOND\r
+#define PARAM_SPI_CPHA(n) ((n==SPI_CPHA_FIRST) || (n==SPI_CPHA_SECOND))\r
+\r
+/** Clock polarity control bit */\r
+#define SPI_CPOL_HI ((uint32_t)(0))\r
+#define SPI_CPOL_LO SPI_SPCR_CPOL_LOW\r
+#define PARAM_SPI_CPOL(n) ((n==SPI_CPOL_HI) || (n==SPI_CPOL_LO))\r
+\r
+/** SPI master mode enable */\r
+#define SPI_SLAVE_MODE ((uint32_t)(0))\r
+#define SPI_MASTER_MODE SPI_SPCR_MSTR\r
+#define PARAM_SPI_MODE(n) ((n==SPI_SLAVE_MODE) || (n==SPI_MASTER_MODE))\r
+\r
+/** LSB enable bit */\r
+#define SPI_DATA_MSB_FIRST ((uint32_t)(0))\r
+#define SPI_DATA_LSB_FIRST SPI_SPCR_LSBF\r
+#define PARAM_SPI_DATA_ORDER(n) ((n==SPI_DATA_MSB_FIRST) || (n==SPI_DATA_LSB_FIRST))\r
+\r
+/** SPI data bit number defines */\r
+#define SPI_DATABIT_16 SPI_SPCR_BITS(0) /*!< Databit number = 16 */\r
+#define SPI_DATABIT_8 SPI_SPCR_BITS(0x08) /*!< Databit number = 8 */\r
+#define SPI_DATABIT_9 SPI_SPCR_BITS(0x09) /*!< Databit number = 9 */\r
+#define SPI_DATABIT_10 SPI_SPCR_BITS(0x0A) /*!< Databit number = 10 */\r
+#define SPI_DATABIT_11 SPI_SPCR_BITS(0x0B) /*!< Databit number = 11 */\r
+#define SPI_DATABIT_12 SPI_SPCR_BITS(0x0C) /*!< Databit number = 12 */\r
+#define SPI_DATABIT_13 SPI_SPCR_BITS(0x0D) /*!< Databit number = 13 */\r
+#define SPI_DATABIT_14 SPI_SPCR_BITS(0x0E) /*!< Databit number = 14 */\r
+#define SPI_DATABIT_15 SPI_SPCR_BITS(0x0F) /*!< Databit number = 15 */\r
+#define PARAM_SPI_DATABIT(n) ((n==SPI_DATABIT_16) || (n==SPI_DATABIT_8) \\r
+|| (n==SPI_DATABIT_9) || (n==SPI_DATABIT_10) \\r
+|| (n==SPI_DATABIT_11) || (n==SPI_DATABIT_12) \\r
+|| (n==SPI_DATABIT_13) || (n==SPI_DATABIT_14) \\r
+|| (n==SPI_DATABIT_15))\r
+\r
+\r
+/*********************************************************************//**\r
+ * SPI Status Flag defines\r
+ **********************************************************************/\r
+/** Slave abort */\r
+#define SPI_STAT_ABRT SPI_SPSR_ABRT\r
+/** Mode fault */\r
+#define SPI_STAT_MODF SPI_SPSR_MODF\r
+/** Read overrun */\r
+#define SPI_STAT_ROVR SPI_SPSR_ROVR\r
+/** Write collision */\r
+#define SPI_STAT_WCOL SPI_SPSR_WCOL\r
+/** SPI transfer complete flag */\r
+#define SPI_STAT_SPIF SPI_SPSR_SPIF\r
+#define PARAM_SPI_STAT(n) ((n==SPI_STAT_ABRT) || (n==SPI_STAT_MODF) \\r
+|| (n==SPI_STAT_ROVR) || (n==SPI_STAT_WCOL) \\r
+|| (n==SPI_STAT_SPIF))\r
+\r
+\r
+/* SPI Status Implementation definitions */\r
+#define SPI_STAT_DONE (1UL<<8) /**< Done */\r
+#define SPI_STAT_ERROR (1UL<<9) /**< Error */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Functions ----------------------------------------------------------- */\r
+/** @defgroup SPI_Public_Functions\r
+ * @{\r
+ */\r
+\r
+void SPI_SetClock (LPC_SPI_TypeDef *SPIx, uint32_t target_clock);\r
+void SPI_DeInit(LPC_SPI_TypeDef *SPIx);\r
+void SPI_Init(LPC_SPI_TypeDef *SPIx, SPI_CFG_Type *SPI_ConfigStruct);\r
+void SPI_ConfigStructInit(SPI_CFG_Type *SPI_InitStruct);\r
+void SPI_SendData(LPC_SPI_TypeDef *SPIx, uint16_t Data);\r
+uint16_t SPI_ReceiveData(LPC_SPI_TypeDef *SPIx);\r
+int32_t SPI_ReadWrite (LPC_SPI_TypeDef *SPIx, SPI_DATA_SETUP_Type *dataCfg, SPI_TRANSFER_Type xfType);\r
+void SPI_IntCmd(LPC_SPI_TypeDef *SPIx, FunctionalState NewState);\r
+IntStatus SPI_GetIntStatus (LPC_SPI_TypeDef *SPIx);\r
+void SPI_ClearIntPending(LPC_SPI_TypeDef *SPIx);\r
+uint32_t SPI_GetStatus(LPC_SPI_TypeDef *SPIx);\r
+FlagStatus SPI_CheckStatus (uint32_t inputSPIStatus, uint8_t SPIStatus);\r
+void SPI_StdIntHandler(void);\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* LPC17XX_SPI_H_ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* --------------------------------- End Of File ------------------------------ */\r
--- /dev/null
+/**\r
+ * @file : lpc17xx_ssp.c\r
+ * @brief : Contains all functions support for SSP firmware library on LPC17xx\r
+ * @version : 1.0\r
+ * @date : 9. April. 2009\r
+ * @author : HieuNguyen\r
+ **************************************************************************\r
+ * Software that is described herein is for illustrative purposes only\r
+ * which provides customers with programming information regarding the\r
+ * products. This software is supplied "AS IS" without any warranties.\r
+ * NXP Semiconductors assumes no responsibility or liability for the\r
+ * use of the software, conveys no license or title under any patent,\r
+ * copyright, or mask work right to the product. NXP Semiconductors\r
+ * reserves the right to make changes in the software without\r
+ * notification. NXP Semiconductors also make no representation or\r
+ * warranty that such application will be suitable for the specified\r
+ * use without further testing or modification.\r
+ **********************************************************************/\r
+\r
+/* Peripheral group ----------------------------------------------------------- */\r
+/** @addtogroup SSP\r
+ * @{\r
+ */\r
+\r
+/* Includes ------------------------------------------------------------------- */\r
+#include "lpc17xx_ssp.h"\r
+#include "lpc17xx_clkpwr.h"\r
+\r
+\r
+/* If this source file built with example, the LPC17xx FW library configuration\r
+ * file in each example directory ("lpc17xx_libcfg.h") must be included,\r
+ * otherwise the default FW library configuration file must be included instead\r
+ */\r
+#ifdef __BUILD_WITH_EXAMPLE__\r
+#include "lpc17xx_libcfg.h"\r
+#else\r
+#include "lpc17xx_libcfg_default.h"\r
+#endif /* __BUILD_WITH_EXAMPLE__ */\r
+\r
+\r
+#ifdef _SSP\r
+\r
+/* Private Types -------------------------------------------------------------- */\r
+/** @defgroup SSP_Private_Types\r
+ * @{\r
+ */\r
+\r
+/** @brief SSP device configuration structure type */\r
+typedef struct\r
+{\r
+ int32_t dataword; /* Current data word: 0 - 8 bit; 1 - 16 bit */\r
+ uint32_t txrx_setup; /* Transmission setup */\r
+ void (*inthandler)(LPC_SSP_TypeDef *SSPx); /* Transmission interrupt handler */\r
+} SSP_CFG_T;\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* Private Variables ---------------------------------------------------------- */\r
+/* SSP configuration data */\r
+static SSP_CFG_T sspdat[2];\r
+\r
+\r
+/* Private Functions ---------------------------------------------------------- */\r
+/** @defgroup SSP_Private_Functions\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief Convert from SSP peripheral to number\r
+ */\r
+static int32_t SSP_getNum(LPC_SSP_TypeDef *SSPx){\r
+ if (SSPx == LPC_SSP0) {\r
+ return (0);\r
+ } else if (SSPx == LPC_SSP1) {\r
+ return (1);\r
+ }\r
+ return (-1);\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Standard Private SSP Interrupt handler\r
+ * @param SSPx: SSP peripheral definition, should be\r
+ * SSP0 or SSP1.\r
+ * @return None\r
+ ***********************************************************************/\r
+void SSP_IntHandler(LPC_SSP_TypeDef *SSPx)\r
+{\r
+ SSP_DATA_SETUP_Type *xf_setup;\r
+ uint16_t tmp;\r
+ int32_t sspnum;\r
+\r
+ // Disable interrupt\r
+ SSPx->IMSC = 0;\r
+\r
+ sspnum = SSP_getNum(SSPx);\r
+ xf_setup = (SSP_DATA_SETUP_Type *)sspdat[sspnum].txrx_setup;\r
+\r
+ // save status\r
+ tmp = SSPx->RIS;\r
+ xf_setup->status = tmp;\r
+\r
+ // Check overrun error\r
+ if (tmp & SSP_RIS_ROR){\r
+ // Clear interrupt\r
+ SSPx->ICR = SSP_RIS_ROR;\r
+ // update status\r
+ xf_setup->status |= SSP_STAT_ERROR;\r
+ // Callback\r
+ if (xf_setup->callback != NULL){\r
+ xf_setup->callback();\r
+ }\r
+ return;\r
+ }\r
+\r
+ if ((xf_setup->tx_cnt != xf_setup->length) || (xf_setup->rx_cnt != xf_setup->length)){\r
+ /* check if RX FIFO contains data */\r
+ while ((SSPx->SR & SSP_SR_RNE) && (xf_setup->rx_cnt != xf_setup->length)){\r
+ // Read data from SSP data\r
+ tmp = SSP_ReceiveData(SSPx);\r
+\r
+ // Store data to destination\r
+ if (xf_setup->rx_data != NULL)\r
+ {\r
+ if (sspdat[sspnum].dataword == 0){\r
+ *(uint8_t *)((uint32_t)xf_setup->rx_data + xf_setup->rx_cnt) = (uint8_t) tmp;\r
+ } else {\r
+ *(uint16_t *)((uint32_t)xf_setup->rx_data + xf_setup->rx_cnt) = (uint16_t) tmp;\r
+ }\r
+ }\r
+ // Increase counter\r
+ if (sspdat[sspnum].dataword == 0){\r
+ xf_setup->rx_cnt++;\r
+ } else {\r
+ xf_setup->rx_cnt += 2;\r
+ }\r
+ }\r
+\r
+ while ((SSPx->SR & SSP_SR_TNF) && (xf_setup->tx_cnt != xf_setup->length)){\r
+ // Write data to buffer\r
+ if(xf_setup->tx_data == NULL){\r
+ if (sspdat[sspnum].dataword == 0){\r
+ SSP_SendData(SSPx, 0xFF);\r
+ xf_setup->tx_cnt++;\r
+ } else {\r
+ SSP_SendData(SSPx, 0xFFFF);\r
+ xf_setup->tx_cnt += 2;\r
+ }\r
+ } else {\r
+ if (sspdat[sspnum].dataword == 0){\r
+ SSP_SendData(SSPx, (*(uint8_t *)((uint32_t)xf_setup->tx_data + xf_setup->tx_cnt)));\r
+ xf_setup->tx_cnt++;\r
+ } else {\r
+ SSP_SendData(SSPx, (*(uint16_t *)((uint32_t)xf_setup->tx_data + xf_setup->tx_cnt)));\r
+ xf_setup->tx_cnt += 2;\r
+ }\r
+ }\r
+\r
+ // Check overrun error\r
+ if ((tmp = SSPx->RIS) & SSP_RIS_ROR){\r
+ // update status\r
+ xf_setup->status |= SSP_STAT_ERROR;\r
+ // Callback\r
+ if (xf_setup->callback != NULL){\r
+ xf_setup->callback();\r
+ }\r
+ return;\r
+ }\r
+\r
+ // Check for any data available in RX FIFO\r
+ while ((SSPx->SR & SSP_SR_RNE) && (xf_setup->rx_cnt != xf_setup->length)){\r
+ // Read data from SSP data\r
+ tmp = SSP_ReceiveData(SSPx);\r
+\r
+ // Store data to destination\r
+ if (xf_setup->rx_data != NULL)\r
+ {\r
+ if (sspdat[sspnum].dataword == 0){\r
+ *(uint8_t *)((uint32_t)xf_setup->rx_data + xf_setup->rx_cnt) = (uint8_t) tmp;\r
+ } else {\r
+ *(uint16_t *)((uint32_t)xf_setup->rx_data + xf_setup->rx_cnt) = (uint16_t) tmp;\r
+ }\r
+ }\r
+ // Increase counter\r
+ if (sspdat[sspnum].dataword == 0){\r
+ xf_setup->rx_cnt++;\r
+ } else {\r
+ xf_setup->rx_cnt += 2;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ // If there more data to sent or receive\r
+ if ((xf_setup->rx_cnt != xf_setup->length) || (xf_setup->tx_cnt != xf_setup->length)){\r
+ // Enable all interrupt\r
+ SSPx->IMSC = SSP_IMSC_BITMASK;\r
+ } else {\r
+ // Save status\r
+ xf_setup->status = SSP_STAT_DONE;\r
+ // Callback\r
+ if (xf_setup->callback != NULL){\r
+ xf_setup->callback();\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Functions ----------------------------------------------------------- */\r
+/** @addtogroup SSP_Public_Functions\r
+ * @{\r
+ */\r
+\r
+/*********************************************************************//**\r
+ * @brief Setup clock rate for SSP device\r
+ * @param[in] SSPx SSP peripheral definition, should be\r
+ * SSP0 or SSP1.\r
+ * @param[in] target_clock : clock of SSP (Hz)\r
+ * @return None\r
+ ***********************************************************************/\r
+void SSP_SetClock (LPC_SSP_TypeDef *SSPx, uint32_t target_clock)\r
+{\r
+ uint32_t prescale, cr0_div, cmp_clk, ssp_clk;\r
+\r
+ CHECK_PARAM(PARAM_SSPx(SSPx));\r
+\r
+ /* The SSP clock is derived from the (main system oscillator / 2),\r
+ so compute the best divider from that clock */\r
+ if (SSPx == LPC_SSP0){\r
+ ssp_clk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_SSP0);\r
+ } else if (SSPx == LPC_SSP1) {\r
+ ssp_clk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_SSP1);\r
+ } else {\r
+ return;\r
+ }\r
+\r
+ /* Find closest divider to get at or under the target frequency.\r
+ Use smallest prescale possible and rely on the divider to get\r
+ the closest target frequency */\r
+ cr0_div = 0;\r
+ cmp_clk = 0xFFFFFFFF;\r
+ prescale = 2;\r
+ while (cmp_clk > target_clock)\r
+ {\r
+ cmp_clk = ssp_clk / ((cr0_div + 1) * prescale);\r
+ if (cmp_clk > target_clock)\r
+ {\r
+ cr0_div++;\r
+ if (cr0_div > 0xFF)\r
+ {\r
+ cr0_div = 0;\r
+ prescale += 2;\r
+ }\r
+ }\r
+ }\r
+\r
+ /* Write computed prescaler and divider back to register */\r
+ SSPx->CR0 &= (~SSP_CR0_SCR(0xFF)) & SSP_CR0_BITMASK;\r
+ SSPx->CR0 |= (SSP_CR0_SCR(cr0_div)) & SSP_CR0_BITMASK;\r
+ SSPx->CPSR = prescale & SSP_CPSR_BITMASK;\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief De-initializes the SSPx peripheral registers to their\r
+* default reset values.\r
+ * @param[in] SSPx SSP peripheral selected, should be SSP0 or SSP1\r
+ * @return None\r
+ **********************************************************************/\r
+void SSP_DeInit(LPC_SSP_TypeDef* SSPx)\r
+{\r
+ CHECK_PARAM(PARAM_SSPx(SSPx));\r
+\r
+ if (SSPx == LPC_SSP0){\r
+ /* Set up clock and power for SSP0 module */\r
+ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCSSP0, DISABLE);\r
+ } else if (SSPx == LPC_SSP1) {\r
+ /* Set up clock and power for SSP1 module */\r
+ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCSSP1, DISABLE);\r
+ }\r
+}\r
+\r
+\r
+\r
+/********************************************************************//**\r
+ * @brief Initializes the SSPx peripheral according to the specified\r
+* parameters in the SSP_ConfigStruct.\r
+ * @param[in] SSPx SSP peripheral selected, should be SSP0 or SSP1\r
+ * @param[in] SSP_ConfigStruct Pointer to a SSP_CFG_Type structure\r
+* that contains the configuration information for the\r
+* specified SSP peripheral.\r
+ * @return None\r
+ *********************************************************************/\r
+void SSP_Init(LPC_SSP_TypeDef *SSPx, SSP_CFG_Type *SSP_ConfigStruct)\r
+{\r
+ uint32_t tmp;\r
+\r
+ CHECK_PARAM(PARAM_SSPx(SSPx));\r
+\r
+ if(SSPx == LPC_SSP0) {\r
+ /* Set up clock and power for SSP0 module */\r
+ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCSSP0, ENABLE);\r
+ } else if(SSPx == LPC_SSP1) {\r
+ /* Set up clock and power for SSP1 module */\r
+ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCSSP1, ENABLE);\r
+ } else {\r
+ return;\r
+ }\r
+\r
+ /* Configure SSP, interrupt is disable, LoopBack mode is disable,\r
+ * SSP is disable, Slave output is disable as default\r
+ */\r
+ tmp = ((SSP_ConfigStruct->CPHA) | (SSP_ConfigStruct->CPOL) \\r
+ | (SSP_ConfigStruct->FrameFormat) | (SSP_ConfigStruct->Databit))\r
+ & SSP_CR0_BITMASK;\r
+ // write back to SSP control register\r
+ SSPx->CR0 = tmp;\r
+ tmp = SSP_getNum(SSPx);\r
+ if (SSP_ConfigStruct->Databit > SSP_DATABIT_8){\r
+ sspdat[tmp].dataword = 1;\r
+ } else {\r
+ sspdat[tmp].dataword = 0;\r
+ }\r
+\r
+ tmp = SSP_ConfigStruct->Mode & SSP_CR1_BITMASK;\r
+ // Write back to CR1\r
+ SSPx->CR1 = tmp;\r
+\r
+ // Set clock rate for SSP peripheral\r
+ SSP_SetClock(SSPx, SSP_ConfigStruct->ClockRate);\r
+}\r
+\r
+\r
+\r
+/*****************************************************************************//**\r
+* @brief Fills each SSP_InitStruct member with its default value:\r
+* - CPHA = SSP_CPHA_FIRST\r
+* - CPOL = SSP_CPOL_HI\r
+* - ClockRate = 1000000\r
+* - Databit = SSP_DATABIT_8\r
+* - Mode = SSP_MASTER_MODE\r
+* - FrameFormat = SSP_FRAME_SSP\r
+* @param[in] SSP_InitStruct Pointer to a SSP_CFG_Type structure\r
+* which will be initialized.\r
+* @return None\r
+*******************************************************************************/\r
+void SSP_ConfigStructInit(SSP_CFG_Type *SSP_InitStruct)\r
+{\r
+ SSP_InitStruct->CPHA = SSP_CPHA_FIRST;\r
+ SSP_InitStruct->CPOL = SSP_CPOL_HI;\r
+ SSP_InitStruct->ClockRate = 1000000;\r
+ SSP_InitStruct->Databit = SSP_DATABIT_8;\r
+ SSP_InitStruct->Mode = SSP_MASTER_MODE;\r
+ SSP_InitStruct->FrameFormat = SSP_FRAME_SPI;\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Enable or disable SSP peripheral's operation\r
+ * @param[in] SSPx SSP peripheral, should be SSP0 or SSP1\r
+ * @param[in] NewState New State of SSPx peripheral's operation\r
+ * @return none\r
+ **********************************************************************/\r
+void SSP_Cmd(LPC_SSP_TypeDef* SSPx, FunctionalState NewState)\r
+{\r
+ CHECK_PARAM(PARAM_SSPx(SSPx));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));\r
+\r
+ if (NewState == ENABLE)\r
+ {\r
+ SSPx->CR1 |= SSP_CR1_SSP_EN;\r
+ }\r
+ else\r
+ {\r
+ SSPx->CR1 &= (~SSP_CR1_SSP_EN) & SSP_CR1_BITMASK;\r
+ }\r
+}\r
+\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Enable or disable Loop Back mode function in SSP peripheral\r
+ * @param[in] SSPx SSP peripheral selected, should be SSP0 or SSP1\r
+ * @param[in] NewState New State of Loop Back mode, should be:\r
+ * - ENABLE: Enable this function\r
+ * - DISABLE: Disable this function\r
+ * @return None\r
+ **********************************************************************/\r
+void SSP_LoopBackCmd(LPC_SSP_TypeDef* SSPx, FunctionalState NewState)\r
+{\r
+ CHECK_PARAM(PARAM_SSPx(SSPx));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));\r
+\r
+ if (NewState == ENABLE)\r
+ {\r
+ SSPx->CR1 |= SSP_CR1_LBM_EN;\r
+ }\r
+ else\r
+ {\r
+ SSPx->CR1 &= (~SSP_CR1_LBM_EN) & SSP_CR1_BITMASK;\r
+ }\r
+}\r
+\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Enable or disable Slave Output function in SSP peripheral\r
+ * @param[in] SSPx SSP peripheral selected, should be SSP0 or SSP1\r
+ * @param[in] NewState New State of Slave Output function, should be:\r
+ * - ENABLE: Slave Output in normal operation\r
+ * - DISABLE: Slave Output is disabled. This blocks\r
+ * SSP controller from driving the transmit data\r
+ * line (MISO)\r
+ * Note: This function is available when SSP peripheral in Slave mode\r
+ * @return None\r
+ **********************************************************************/\r
+void SSP_SlaveOutputCmd(LPC_SSP_TypeDef* SSPx, FunctionalState NewState)\r
+{\r
+ CHECK_PARAM(PARAM_SSPx(SSPx));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));\r
+\r
+ if (NewState == ENABLE)\r
+ {\r
+ SSPx->CR1 &= (~SSP_CR1_SO_DISABLE) & SSP_CR1_BITMASK;\r
+ }\r
+ else\r
+ {\r
+ SSPx->CR1 |= SSP_CR1_SO_DISABLE;\r
+ }\r
+}\r
+\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Transmit a single data through SSPx peripheral\r
+ * @param[in] SSPx SSP peripheral selected, should be SSP\r
+ * @param[in] Data Data to transmit (must be 16 or 8-bit long,\r
+ * this depend on SSP data bit number configured)\r
+ * @return none\r
+ **********************************************************************/\r
+void SSP_SendData(LPC_SSP_TypeDef* SSPx, uint16_t Data)\r
+{\r
+ CHECK_PARAM(PARAM_SSPx(SSPx));\r
+\r
+ SSPx->DR = SSP_DR_BITMASK(Data);\r
+}\r
+\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Receive a single data from SSPx peripheral\r
+ * @param[in] SSPx SSP peripheral selected, should be SSP\r
+ * @return Data received (16-bit long)\r
+ **********************************************************************/\r
+uint16_t SSP_ReceiveData(LPC_SSP_TypeDef* SSPx)\r
+{\r
+ CHECK_PARAM(PARAM_SSPx(SSPx));\r
+\r
+ return ((uint16_t) (SSP_DR_BITMASK(SSPx->DR)));\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief SSP Read write data function\r
+ * @param[in] SSPx Pointer to SSP peripheral, should be SSP0 or SSP1\r
+ * @param[in] dataCfg Pointer to a SSP_DATA_SETUP_Type structure that\r
+ * contains specified information about transmit\r
+ * data configuration.\r
+ * @param[in] xfType Transfer type, should be:\r
+ * - SSP_TRANSFER_POLLING: Polling mode\r
+ * - SSP_TRANSFER_INTERRUPT: Interrupt mode\r
+ * @return Actual Data length has been transferred in polling mode.\r
+ * In interrupt mode, always return (0)\r
+ * Return (-1) if error.\r
+ * Note: This function can be used in both master and slave mode.\r
+ ***********************************************************************/\r
+int32_t SSP_ReadWrite (LPC_SSP_TypeDef *SSPx, SSP_DATA_SETUP_Type *dataCfg, \\r
+ SSP_TRANSFER_Type xfType)\r
+{\r
+ uint8_t *rdata8;\r
+ uint8_t *wdata8;\r
+ uint16_t *rdata16;\r
+ uint16_t *wdata16;\r
+ uint32_t stat;\r
+ uint32_t tmp;\r
+ int32_t sspnum;\r
+ int32_t dataword;\r
+\r
+ dataCfg->rx_cnt = 0;\r
+ dataCfg->tx_cnt = 0;\r
+ dataCfg->status = 0;\r
+\r
+\r
+ /* Clear all remaining data in RX FIFO */\r
+ while (SSPx->SR & SSP_SR_RNE){\r
+ tmp = (uint32_t) SSP_ReceiveData(SSPx);\r
+ }\r
+\r
+ // Clear status\r
+ SSPx->ICR = SSP_ICR_BITMASK;\r
+\r
+ sspnum = SSP_getNum(SSPx);\r
+ dataword = sspdat[sspnum].dataword;\r
+\r
+ // Polling mode ----------------------------------------------------------------------\r
+ if (xfType == SSP_TRANSFER_POLLING){\r
+ if (dataword == 0){\r
+ rdata8 = (uint8_t *)dataCfg->rx_data;\r
+ wdata8 = (uint8_t *)dataCfg->tx_data;\r
+ } else {\r
+ rdata16 = (uint16_t *)dataCfg->rx_data;\r
+ wdata16 = (uint16_t *)dataCfg->tx_data;\r
+ }\r
+ while ((dataCfg->tx_cnt != dataCfg->length) || (dataCfg->rx_cnt != dataCfg->length)){\r
+ if ((SSPx->SR & SSP_SR_TNF) && (dataCfg->tx_cnt != dataCfg->length)){\r
+ // Write data to buffer\r
+ if(dataCfg->tx_data == NULL){\r
+ if (dataword == 0){\r
+ SSP_SendData(SSPx, 0xFF);\r
+ dataCfg->tx_cnt++;\r
+ } else {\r
+ SSP_SendData(SSPx, 0xFFFF);\r
+ dataCfg->tx_cnt += 2;\r
+ }\r
+ } else {\r
+ if (dataword == 0){\r
+ SSP_SendData(SSPx, *wdata8);\r
+ wdata8++;\r
+ dataCfg->tx_cnt++;\r
+ } else {\r
+ SSP_SendData(SSPx, *wdata16);\r
+ wdata16++;\r
+ dataCfg->tx_cnt += 2;\r
+ }\r
+ }\r
+ }\r
+\r
+ // Check overrun error\r
+ if ((stat = SSPx->RIS) & SSP_RIS_ROR){\r
+ // save status and return\r
+ dataCfg->status = stat | SSP_STAT_ERROR;\r
+ return (-1);\r
+ }\r
+\r
+ // Check for any data available in RX FIFO\r
+ while ((SSPx->SR & SSP_SR_RNE) && (dataCfg->rx_cnt != dataCfg->length)){\r
+ // Read data from SSP data\r
+ tmp = SSP_ReceiveData(SSPx);\r
+\r
+ // Store data to destination\r
+ if (dataCfg->rx_data != NULL)\r
+ {\r
+ if (dataword == 0){\r
+ *(rdata8) = (uint8_t) tmp;\r
+ rdata8++;\r
+ } else {\r
+ *(rdata16) = (uint16_t) tmp;\r
+ rdata16++;\r
+ }\r
+ }\r
+ // Increase counter\r
+ if (dataword == 0){\r
+ dataCfg->rx_cnt++;\r
+ } else {\r
+ dataCfg->rx_cnt += 2;\r
+ }\r
+ }\r
+ }\r
+\r
+ // save status\r
+ dataCfg->status = SSP_STAT_DONE;\r
+\r
+ if (dataCfg->tx_data != NULL){\r
+ return dataCfg->tx_cnt;\r
+ } else if (dataCfg->rx_data != NULL){\r
+ return dataCfg->rx_cnt;\r
+ } else {\r
+ return (0);\r
+ }\r
+ }\r
+\r
+ // Interrupt mode ----------------------------------------------------------------------\r
+ else if (xfType == SSP_TRANSFER_INTERRUPT){\r
+ sspdat[sspnum].inthandler = SSP_IntHandler;\r
+ sspdat[sspnum].txrx_setup = (uint32_t)dataCfg;\r
+\r
+ while ((SSPx->SR & SSP_SR_TNF) && (dataCfg->tx_cnt != dataCfg->length)){\r
+ // Write data to buffer\r
+ if(dataCfg->tx_data == NULL){\r
+ if (sspdat[sspnum].dataword == 0){\r
+ SSP_SendData(SSPx, 0xFF);\r
+ dataCfg->tx_cnt++;\r
+ } else {\r
+ SSP_SendData(SSPx, 0xFFFF);\r
+ dataCfg->tx_cnt += 2;\r
+ }\r
+ } else {\r
+ if (sspdat[sspnum].dataword == 0){\r
+ SSP_SendData(SSPx, (*(uint8_t *)((uint32_t)dataCfg->tx_data + dataCfg->tx_cnt)));\r
+ dataCfg->tx_cnt++;\r
+ } else {\r
+ SSP_SendData(SSPx, (*(uint16_t *)((uint32_t)dataCfg->tx_data + dataCfg->tx_cnt)));\r
+ dataCfg->tx_cnt += 2;\r
+ }\r
+ }\r
+\r
+ // Check error\r
+ if ((stat = SSPx->RIS) & SSP_RIS_ROR){\r
+ // save status and return\r
+ dataCfg->status = stat | SSP_STAT_ERROR;\r
+ return (-1);\r
+ }\r
+\r
+ // Check for any data available in RX FIFO\r
+ while ((SSPx->SR & SSP_SR_RNE) && (dataCfg->rx_cnt != dataCfg->length)){\r
+ // Read data from SSP data\r
+ tmp = SSP_ReceiveData(SSPx);\r
+\r
+ // Store data to destination\r
+ if (dataCfg->rx_data != NULL)\r
+ {\r
+ if (sspdat[sspnum].dataword == 0){\r
+ *(uint8_t *)((uint32_t)dataCfg->rx_data + dataCfg->rx_cnt) = (uint8_t) tmp;\r
+ } else {\r
+ *(uint16_t *)((uint32_t)dataCfg->rx_data + dataCfg->rx_cnt) = (uint16_t) tmp;\r
+ }\r
+ }\r
+ // Increase counter\r
+ if (sspdat[sspnum].dataword == 0){\r
+ dataCfg->rx_cnt++;\r
+ } else {\r
+ dataCfg->rx_cnt += 2;\r
+ }\r
+ }\r
+ }\r
+\r
+ // If there more data to sent or receive\r
+ if ((dataCfg->rx_cnt != dataCfg->length) || (dataCfg->tx_cnt != dataCfg->length)){\r
+ // Enable all interrupt\r
+ SSPx->IMSC = SSP_IMSC_BITMASK;\r
+ } else {\r
+ // Save status\r
+ dataCfg->status = SSP_STAT_DONE;\r
+ }\r
+ return (0);\r
+ }\r
+\r
+ return (-1);\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief Checks whether the specified SSP status flag is set or not\r
+ * @param[in] SSPx SSP peripheral selected, should be SSP0 or SSP1\r
+ * @param[in] FlagType Type of flag to check status, should be one\r
+ * of following:\r
+ * - SSP_STAT_TXFIFO_EMPTY: TX FIFO is empty\r
+ * - SSP_STAT_TXFIFO_NOTFULL: TX FIFO is not full\r
+ * - SSP_STAT_RXFIFO_NOTEMPTY: RX FIFO is not empty\r
+ * - SSP_STAT_RXFIFO_FULL: RX FIFO is full\r
+ * - SSP_STAT_BUSY: SSP peripheral is busy\r
+ * @return New State of specified SSP status flag\r
+ **********************************************************************/\r
+FlagStatus SSP_GetStatus(LPC_SSP_TypeDef* SSPx, uint32_t FlagType)\r
+{\r
+ CHECK_PARAM(PARAM_SSPx(SSPx));\r
+ CHECK_PARAM(PARAM_SSP_STAT(FlagType));\r
+\r
+ return ((SSPx->SR & FlagType) ? SET : RESET);\r
+}\r
+\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Enable or disable specified interrupt type in SSP peripheral\r
+ * @param[in] SSPx SSP peripheral selected, should be SSP0 or SSP1\r
+ * @param[in] IntType Interrupt type in SSP peripheral, should be:\r
+ * - SSP_INTCFG_ROR: Receive Overrun interrupt\r
+ * - SSP_INTCFG_RT: Receive Time out interrupt\r
+ * - SSP_INTCFG_RX: RX FIFO is at least half full interrupt\r
+ * - SSP_INTCFG_TX: TX FIFO is at least half empty interrupt\r
+ * @param[in] NewState New State of specified interrupt type, should be:\r
+ * - ENABLE: Enable this interrupt type\r
+ * - DISABLE: Disable this interrupt type\r
+ * @return None\r
+ **********************************************************************/\r
+void SSP_IntConfig(LPC_SSP_TypeDef *SSPx, uint32_t IntType, FunctionalState NewState)\r
+{\r
+ CHECK_PARAM(PARAM_SSPx(SSPx));\r
+ CHECK_PARAM(PARAM_SSP_INTCFG(IntType));\r
+\r
+ if (NewState == ENABLE)\r
+ {\r
+ SSPx->IMSC |= IntType;\r
+ }\r
+ else\r
+ {\r
+ SSPx->IMSC &= (~IntType) & SSP_IMSC_BITMASK;\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Check whether the specified Raw interrupt status flag is\r
+ * set or not\r
+ * @param[in] SSPx SSP peripheral selected, should be SSP0 or SSP1\r
+ * @param[in] RawIntType Raw Interrupt Type, should be:\r
+ * - SSP_INTSTAT_RAW_ROR: Receive Overrun interrupt\r
+ * - SSP_INTSTAT_RAW_RT: Receive Time out interrupt\r
+ * - SSP_INTSTAT_RAW_RX: RX FIFO is at least half full interrupt\r
+ * - SSP_INTSTAT_RAW_TX: TX FIFO is at least half empty interrupt\r
+ * @return New State of specified Raw interrupt status flag in SSP peripheral\r
+ * Note: Enabling/Disabling specified interrupt in SSP peripheral does not\r
+ * effect to Raw Interrupt Status flag.\r
+ **********************************************************************/\r
+IntStatus SSP_GetRawIntStatus(LPC_SSP_TypeDef *SSPx, uint32_t RawIntType)\r
+{\r
+ CHECK_PARAM(PARAM_SSPx(SSPx));\r
+ CHECK_PARAM(PARAM_SSP_INTSTAT_RAW(RawIntType));\r
+\r
+ return ((SSPx->RIS & RawIntType) ? SET : RESET);\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Check whether the specified interrupt status flag is\r
+ * set or not\r
+ * @param[in] SSPx SSP peripheral selected, should be SSP0 or SSP1\r
+ * @param[in] IntType Raw Interrupt Type, should be:\r
+ * - SSP_INTSTAT_ROR: Receive Overrun interrupt\r
+ * - SSP_INTSTAT_RT: Receive Time out interrupt\r
+ * - SSP_INTSTAT_RX: RX FIFO is at least half full interrupt\r
+ * - SSP_INTSTAT_TX: TX FIFO is at least half empty interrupt\r
+ * @return New State of specified interrupt status flag in SSP peripheral\r
+ * Note: Enabling/Disabling specified interrupt in SSP peripheral effects\r
+ * to Interrupt Status flag.\r
+ **********************************************************************/\r
+IntStatus SSP_GetIntStatus (LPC_SSP_TypeDef *SSPx, uint32_t IntType)\r
+{\r
+ CHECK_PARAM(PARAM_SSPx(SSPx));\r
+ CHECK_PARAM(PARAM_SSP_INTSTAT(IntType));\r
+\r
+ return ((SSPx->MIS & IntType) ? SET :RESET);\r
+}\r
+\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Clear specified interrupt pending in SSP peripheral\r
+ * @param[in] SSPx SSP peripheral selected, should be SSP0 or SSP1\r
+ * @param[in] IntType Interrupt pending to clear, should be:\r
+ * - SSP_INTCLR_ROR: clears the "frame was received when\r
+ * RxFIFO was full" interrupt.\r
+ * - SSP_INTCLR_RT: clears the "Rx FIFO was not empty and\r
+ * has not been read for a timeout period" interrupt.\r
+ * @return None\r
+ **********************************************************************/\r
+void SSP_ClearIntPending(LPC_SSP_TypeDef *SSPx, uint32_t IntType)\r
+{\r
+ CHECK_PARAM(PARAM_SSPx(SSPx));\r
+ CHECK_PARAM(PARAM_SSP_INTCLR(IntType));\r
+\r
+ SSPx->ICR = IntType;\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief Enable/Disable DMA function for SSP peripheral\r
+ * @param[in] SSPx SSP peripheral selected, should be SSP0 or SSP1\r
+ * @param[in] DMAMode Type of DMA, should be:\r
+ * - SSP_DMA_TX: DMA for the transmit FIFO\r
+ * - SSP_DMA_RX: DMA for the Receive FIFO\r
+ * @param[in] NewState New State of DMA function on SSP peripheral,\r
+ * should be:\r
+ * - ENALBE: Enable this function\r
+ * - DISABLE: Disable this function\r
+ * @return None\r
+ **********************************************************************/\r
+void SSP_DMACmd(LPC_SSP_TypeDef *SSPx, uint32_t DMAMode, FunctionalState NewState)\r
+{\r
+ CHECK_PARAM(PARAM_SSPx(SSPx));\r
+ CHECK_PARAM(PARAM_SSP_DMA(DMAMode));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));\r
+\r
+ if (NewState == ENABLE)\r
+ {\r
+ SSPx->DMACR |= DMAMode;\r
+ }\r
+ else\r
+ {\r
+ SSPx->DMACR &= (~DMAMode) & SSP_DMA_BITMASK;\r
+ }\r
+}\r
+\r
+/**\r
+ * @brief Standard SSP0 Interrupt handler\r
+ * @param[in] None\r
+ * @return None\r
+ */\r
+void SSP0_StdIntHandler(void)\r
+{\r
+ // Call relevant handler\r
+ sspdat[0].inthandler(LPC_SSP0);\r
+}\r
+\r
+/**\r
+ * @brief Standard SSP1 Interrupt handler\r
+ * @param[in] None\r
+ * @return None\r
+ */\r
+void SSP1_StdIntHandler(void)\r
+{\r
+ // Call relevant handler\r
+ sspdat[1].inthandler(LPC_SSP1);\r
+}\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#endif /* _SSP */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* --------------------------------- End Of File ------------------------------ */\r
+\r
--- /dev/null
+/***********************************************************************//**\r
+ * @file : lpc17xx_ssp.h\r
+ * @brief : Contains all macro definitions and function prototypes\r
+ * support for SSP firmware library on LPC17xx\r
+ * @version : 1.0\r
+ * @date : 9. April. 2009\r
+ * @author : HieuNguyen\r
+ **************************************************************************\r
+ * Software that is described herein is for illustrative purposes only\r
+ * which provides customers with programming information regarding the\r
+ * products. This software is supplied "AS IS" without any warranties.\r
+ * NXP Semiconductors assumes no responsibility or liability for the\r
+ * use of the software, conveys no license or title under any patent,\r
+ * copyright, or mask work right to the product. NXP Semiconductors\r
+ * reserves the right to make changes in the software without\r
+ * notification. NXP Semiconductors also make no representation or\r
+ * warranty that such application will be suitable for the specified\r
+ * use without further testing or modification.\r
+ **************************************************************************/\r
+\r
+/* Peripheral group ----------------------------------------------------------- */\r
+/** @defgroup SSP\r
+ * @ingroup LPC1700CMSIS_FwLib_Drivers\r
+ * @{\r
+ */\r
+\r
+#ifndef LPC17XX_SSP_H_\r
+#define LPC17XX_SSP_H_\r
+\r
+/* Includes ------------------------------------------------------------------- */\r
+#include "LPC17xx.h"\r
+#include "lpc_types.h"\r
+\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif\r
+\r
+\r
+/* Private Macros ------------------------------------------------------------- */\r
+/** @defgroup SSP_Private_Macros\r
+ * @{\r
+ */\r
+\r
+/*********************************************************************//**\r
+ * Macro defines for CR0 register\r
+ **********************************************************************/\r
+\r
+/** @defgroup SSP_REGISTER_BIT_DEFINITION\r
+ * @{\r
+ */\r
+\r
+/** SSP data size select, must be 4 bits to 16 bits */\r
+#define SSP_CR0_DSS(n) ((uint32_t)((n-1)&0xF))\r
+/** SSP control 0 Motorola SPI mode */\r
+#define SSP_CR0_FRF_SPI ((uint32_t)(0<<4))\r
+/** SSP control 0 TI synchronous serial mode */\r
+#define SSP_CR0_FRF_TI ((uint32_t)(1<<4))\r
+/** SSP control 0 National Micro-wire mode */\r
+#define SSP_CR0_FRF_MICROWIRE ((uint32_t)(2<<4))\r
+/** SPI clock polarity bit (used in SPI mode only), (1) = maintains the\r
+ bus clock high between frames, (0) = low */\r
+#define SSP_CR0_CPOL_HI ((uint32_t)(1<<6))\r
+/** SPI clock out phase bit (used in SPI mode only), (1) = captures data\r
+ on the second clock transition of the frame, (0) = first */\r
+#define SSP_CR0_CPHA_SECOND ((uint32_t)(1<<7))\r
+/** SSP serial clock rate value load macro, divider rate is\r
+ PERIPH_CLK / (cpsr * (SCR + 1)) */\r
+#define SSP_CR0_SCR(n) ((uint32_t)((n&0xFF)<<8))\r
+/** SSP CR0 bit mask */\r
+#define SSP_CR0_BITMASK ((uint32_t)(0xFFFF))\r
+\r
+\r
+/*********************************************************************//**\r
+ * Macro defines for CR1 register\r
+ **********************************************************************/\r
+/** SSP control 1 loopback mode enable bit */\r
+#define SSP_CR1_LBM_EN ((uint32_t)(1<<0))\r
+/** SSP control 1 enable bit */\r
+#define SSP_CR1_SSP_EN ((uint32_t)(1<<1))\r
+/** SSP control 1 slave enable */\r
+#define SSP_CR1_SLAVE_EN ((uint32_t)(1<<2))\r
+/** SSP control 1 slave out disable bit, disables transmit line in slave\r
+ mode */\r
+#define SSP_CR1_SO_DISABLE ((uint32_t)(1<<3))\r
+/** SSP CR1 bit mask */\r
+#define SSP_CR1_BITMASK ((uint32_t)(0x0F))\r
+\r
+\r
+/*********************************************************************//**\r
+ * Macro defines for DR register\r
+ **********************************************************************/\r
+/** SSP data bit mask */\r
+#define SSP_DR_BITMASK(n) ((n)&0xFFFF)\r
+\r
+/*********************************************************************//**\r
+ * Macro defines for SR register\r
+ **********************************************************************/\r
+/** SSP status TX FIFO Empty bit */\r
+#define SSP_SR_TFE ((uint32_t)(1<<0))\r
+/** SSP status TX FIFO not full bit */\r
+#define SSP_SR_TNF ((uint32_t)(1<<1))\r
+/** SSP status RX FIFO not empty bit */\r
+#define SSP_SR_RNE ((uint32_t)(1<<2))\r
+/** SSP status RX FIFO full bit */\r
+#define SSP_SR_RFF ((uint32_t)(1<<3))\r
+/** SSP status SSP Busy bit */\r
+#define SSP_SR_BSY ((uint32_t)(1<<4))\r
+/** SSP SR bit mask */\r
+#define SSP_SR_BITMASK ((uint32_t)(0x1F))\r
+\r
+\r
+/*********************************************************************//**\r
+ * Macro defines for CPSR register\r
+ **********************************************************************/\r
+/** SSP clock prescaler */\r
+#define SSP_CPSR_CPDVSR(n) ((uint32_t)(n&0xFF))\r
+/** SSP CPSR bit mask */\r
+#define SSP_CPSR_BITMASK ((uint32_t)(0xFF))\r
+\r
+\r
+/*********************************************************************//**\r
+ * Macro define for (IMSC) Interrupt Mask Set/Clear registers\r
+ **********************************************************************/\r
+/** Receive Overrun */\r
+#define SSP_IMSC_ROR ((uint32_t)(1<<0))\r
+/** Receive TimeOut */\r
+#define SSP_IMSC_RT ((uint32_t)(1<<1))\r
+/** Rx FIFO is at least half full */\r
+#define SSP_IMSC_RX ((uint32_t)(1<<2))\r
+/** Tx FIFO is at least half empty */\r
+#define SSP_IMSC_TX ((uint32_t)(1<<3))\r
+/** IMSC bit mask */\r
+#define SSP_IMSC_BITMASK ((uint32_t)(0x0F))\r
+\r
+/*********************************************************************//**\r
+ * Macro define for (RIS) Raw Interrupt Status registers\r
+ **********************************************************************/\r
+/** Receive Overrun */\r
+#define SSP_RIS_ROR ((uint32_t)(1<<0))\r
+/** Receive TimeOut */\r
+#define SSP_RIS_RT ((uint32_t)(1<<1))\r
+/** Rx FIFO is at least half full */\r
+#define SSP_RIS_RX ((uint32_t)(1<<2))\r
+/** Tx FIFO is at least half empty */\r
+#define SSP_RIS_TX ((uint32_t)(1<<3))\r
+/** RIS bit mask */\r
+#define SSP_RIS_BITMASK ((uint32_t)(0x0F))\r
+\r
+\r
+/*********************************************************************//**\r
+ * Macro define for (MIS) Masked Interrupt Status registers\r
+ **********************************************************************/\r
+/** Receive Overrun */\r
+#define SSP_MIS_ROR ((uint32_t)(1<<0))\r
+/** Receive TimeOut */\r
+#define SSP_MIS_RT ((uint32_t)(1<<1))\r
+/** Rx FIFO is at least half full */\r
+#define SSP_MIS_RX ((uint32_t)(1<<2))\r
+/** Tx FIFO is at least half empty */\r
+#define SSP_MIS_TX ((uint32_t)(1<<3))\r
+/** MIS bit mask */\r
+#define SSP_MIS_BITMASK ((uint32_t)(0x0F))\r
+\r
+\r
+/*********************************************************************//**\r
+ * Macro define for (ICR) Interrupt Clear registers\r
+ **********************************************************************/\r
+/** Writing a 1 to this bit clears the "frame was received when\r
+ * RxFIFO was full" interrupt */\r
+#define SSP_ICR_ROR ((uint32_t)(1<<0))\r
+/** Writing a 1 to this bit clears the "Rx FIFO was not empty and\r
+ * has not been read for a timeout period" interrupt */\r
+#define SSP_ICR_RT ((uint32_t)(1<<1))\r
+/** ICR bit mask */\r
+#define SSP_ICR_BITMASK ((uint32_t)(0x03))\r
+\r
+\r
+/*********************************************************************//**\r
+ * Macro defines for DMACR register\r
+ **********************************************************************/\r
+/** SSP bit for enabling RX DMA */\r
+#define SSP_DMA_RXDMA_EN ((uint32_t)(1<<0))\r
+/** SSP bit for enabling TX DMA */\r
+#define SSP_DMA_TXDMA_EN ((uint32_t)(1<<1))\r
+/** DMACR bit mask */\r
+#define SSP_DMA_BITMASK ((uint32_t)(0x03))\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Types --------------------------------------------------------------- */\r
+/** @defgroup SSP_Public_Types\r
+ * @{\r
+ */\r
+\r
+/** @brief SSP configuration structure */\r
+typedef struct {\r
+ uint32_t Databit; /** Databit number, should be SSP_DATABIT_x,\r
+ where x is in range from 4 - 16 */\r
+ uint32_t CPHA; /** Clock phase, should be:\r
+ - SSP_CPHA_FIRST: first clock edge\r
+ - SSP_CPHA_SECOND: second clock edge */\r
+ uint32_t CPOL; /** Clock polarity, should be:\r
+ - SSP_CPOL_HI: high level\r
+ - SSP_CPOL_LO: low level */\r
+ uint32_t Mode; /** SSP mode, should be:\r
+ - SSP_MASTER_MODE: Master mode\r
+ - SSP_SLAVE_MODE: Slave mode */\r
+ uint32_t FrameFormat; /** Frame Format:\r
+ - SSP_FRAME_SPI: Motorola SPI frame format\r
+ - SSP_FRAME_TI: TI frame format\r
+ - SSP_FRAME_MICROWIRE: National Microwire frame format */\r
+ uint32_t ClockRate; /** Clock rate,in Hz */\r
+} SSP_CFG_Type;\r
+\r
+/**\r
+ * @brief SSP Transfer Type definitions\r
+ */\r
+typedef enum {\r
+ SSP_TRANSFER_POLLING = 0, /**< Polling transfer */\r
+ SSP_TRANSFER_INTERRUPT /**< Interrupt transfer */\r
+} SSP_TRANSFER_Type;\r
+\r
+/**\r
+ * @brief SPI Data configuration structure definitions\r
+ */\r
+typedef struct {\r
+ void *tx_data; /**< Pointer to transmit data */\r
+ uint32_t tx_cnt; /**< Transmit counter */\r
+ void *rx_data; /**< Pointer to transmit data */\r
+ uint32_t rx_cnt; /**< Receive counter */\r
+ uint32_t length; /**< Length of transfer data */\r
+ uint32_t status; /**< Current status of SSP activity */\r
+ void (*callback)(void); /**< Pointer to Call back function when transmission complete\r
+ used in interrupt transfer mode */\r
+} SSP_DATA_SETUP_Type;\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Macros -------------------------------------------------------------- */\r
+/** @defgroup SSP_Public_Macros\r
+ * @{\r
+ */\r
+\r
+/** Macro to determine if it is valid SSP port number */\r
+#define PARAM_SSPx(n) ((((uint32_t *)n)==((uint32_t *)LPC_SSP0)) \\r
+|| (((uint32_t *)n)==((uint32_t *)LPC_SSP1)))\r
+\r
+/*********************************************************************//**\r
+ * SSP configuration parameter defines\r
+ **********************************************************************/\r
+/** Clock phase control bit */\r
+#define SSP_CPHA_FIRST ((uint32_t)(0))\r
+#define SSP_CPHA_SECOND SSP_CR0_CPHA_SECOND\r
+#define PARAM_SSP_CPHA(n) ((n==SSP_CPHA_FIRST) || (n==SSP_CPHA_SECOND))\r
+\r
+/** Clock polarity control bit */\r
+/* There's no bug here!!!\r
+ * - If bit[6] in SSPnCR0 is 0: SSP controller maintains the bus clock low between frames.\r
+ * That means the active clock is in HI state.\r
+ * - If bit[6] in SSPnCR0 is 1 (SSP_CR0_CPOL_HI): SSP controller maintains the bus clock\r
+ * high between frames. That means the active clock is in LO state.\r
+ */\r
+#define SSP_CPOL_HI ((uint32_t)(0))\r
+#define SSP_CPOL_LO SSP_CR0_CPOL_HI\r
+#define PARAM_SSP_CPOL(n) ((n==SSP_CPOL_HI) || (n==SSP_CPOL_LO))\r
+\r
+/** SSP master mode enable */\r
+#define SSP_SLAVE_MODE SSP_CR1_SLAVE_EN\r
+#define SSP_MASTER_MODE ((uint32_t)(0))\r
+#define PARAM_SSP_MODE(n) ((n==SSP_SLAVE_MODE) || (n==SSP_MASTER_MODE))\r
+\r
+/** SSP data bit number defines */\r
+#define SSP_DATABIT_4 SSP_CR0_DSS(4) /*!< Databit number = 4 */\r
+#define SSP_DATABIT_5 SSP_CR0_DSS(5) /*!< Databit number = 5 */\r
+#define SSP_DATABIT_6 SSP_CR0_DSS(6) /*!< Databit number = 6 */\r
+#define SSP_DATABIT_7 SSP_CR0_DSS(7) /*!< Databit number = 7 */\r
+#define SSP_DATABIT_8 SSP_CR0_DSS(8) /*!< Databit number = 8 */\r
+#define SSP_DATABIT_9 SSP_CR0_DSS(9) /*!< Databit number = 9 */\r
+#define SSP_DATABIT_10 SSP_CR0_DSS(10) /*!< Databit number = 10 */\r
+#define SSP_DATABIT_11 SSP_CR0_DSS(11) /*!< Databit number = 11 */\r
+#define SSP_DATABIT_12 SSP_CR0_DSS(12) /*!< Databit number = 12 */\r
+#define SSP_DATABIT_13 SSP_CR0_DSS(13) /*!< Databit number = 13 */\r
+#define SSP_DATABIT_14 SSP_CR0_DSS(14) /*!< Databit number = 14 */\r
+#define SSP_DATABIT_15 SSP_CR0_DSS(15) /*!< Databit number = 15 */\r
+#define SSP_DATABIT_16 SSP_CR0_DSS(16) /*!< Databit number = 16 */\r
+#define PARAM_SSP_DATABIT(n) ((n==SSP_DATABIT_4) || (n==SSP_DATABIT_5) \\r
+|| (n==SSP_DATABIT_6) || (n==SSP_DATABIT_16) \\r
+|| (n==SSP_DATABIT_7) || (n==SSP_DATABIT_8) \\r
+|| (n==SSP_DATABIT_9) || (n==SSP_DATABIT_10) \\r
+|| (n==SSP_DATABIT_11) || (n==SSP_DATABIT_12) \\r
+|| (n==SSP_DATABIT_13) || (n==SSP_DATABIT_14) \\r
+|| (n==SSP_DATABIT_15))\r
+\r
+/** SSP Frame Format definition */\r
+/** Motorola SPI mode */\r
+#define SSP_FRAME_SPI SSP_CR0_FRF_SPI\r
+/** TI synchronous serial mode */\r
+#define SSP_FRAME_TI SSP_CR0_FRF_TI\r
+/** National Micro-wire mode */\r
+#define SSP_FRAME_MICROWIRE SSP_CR0_FRF_MICROWIRE\r
+\r
+#define PARAM_SSP_FRAME(n) ((n==SSP_FRAME_SPI) || (n==SSP_FRAME_TI)\\r
+|| (n==SSP_FRAME_MICROWIRE))\r
+\r
+\r
+/*********************************************************************//**\r
+ * SSP Status defines\r
+ **********************************************************************/\r
+/** SSP status TX FIFO Empty bit */\r
+#define SSP_STAT_TXFIFO_EMPTY SSP_SR_TFE\r
+/** SSP status TX FIFO not full bit */\r
+#define SSP_STAT_TXFIFO_NOTFULL SSP_SR_TNF\r
+/** SSP status RX FIFO not empty bit */\r
+#define SSP_STAT_RXFIFO_NOTEMPTY SSP_SR_RNE\r
+/** SSP status RX FIFO full bit */\r
+#define SSP_STAT_RXFIFO_FULL SSP_SR_RFF\r
+/** SSP status SSP Busy bit */\r
+#define SSP_STAT_BUSY SSP_SR_BSY\r
+\r
+#define PARAM_SSP_STAT(n) ((n==SSP_STAT_TXFIFO_EMPTY) || (n==SSP_STAT_TXFIFO_NOTFULL) \\r
+|| (n==SSP_STAT_RXFIFO_NOTEMPTY) || (n==SSP_STAT_RXFIFO_FULL) \\r
+|| (n==SSP_STAT_BUSY))\r
+\r
+\r
+/*********************************************************************//**\r
+ * SSP Interrupt Configuration defines\r
+ **********************************************************************/\r
+/** Receive Overrun */\r
+#define SSP_INTCFG_ROR SSP_IMSC_ROR\r
+/** Receive TimeOut */\r
+#define SSP_INTCFG_RT SSP_IMSC_RT\r
+/** Rx FIFO is at least half full */\r
+#define SSP_INTCFG_RX SSP_IMSC_RX\r
+/** Tx FIFO is at least half empty */\r
+#define SSP_INTCFG_TX SSP_IMSC_TX\r
+\r
+#define PARAM_SSP_INTCFG(n) ((n==SSP_INTCFG_ROR) || (n==SSP_INTCFG_RT) \\r
+|| (n==SSP_INTCFG_RX) || (n==SSP_INTCFG_TX))\r
+\r
+\r
+/*********************************************************************//**\r
+ * SSP Configured Interrupt Status defines\r
+ **********************************************************************/\r
+/** Receive Overrun */\r
+#define SSP_INTSTAT_ROR SSP_MIS_ROR\r
+/** Receive TimeOut */\r
+#define SSP_INTSTAT_RT SSP_MIS_RT\r
+/** Rx FIFO is at least half full */\r
+#define SSP_INTSTAT_RX SSP_MIS_RX\r
+/** Tx FIFO is at least half empty */\r
+#define SSP_INTSTAT_TX SSP_MIS_TX\r
+\r
+#define PARAM_SSP_INTSTAT(n) ((n==SSP_INTSTAT_ROR) || (n==SSP_INTSTAT_RT) \\r
+|| (n==SSP_INTSTAT_RX) || (n==SSP_INTSTAT_TX))\r
+\r
+\r
+/*********************************************************************//**\r
+ * SSP Raw Interrupt Status defines\r
+ **********************************************************************/\r
+/** Receive Overrun */\r
+#define SSP_INTSTAT_RAW_ROR SSP_RIS_ROR\r
+/** Receive TimeOut */\r
+#define SSP_INTSTAT_RAW_RT SSP_RIS_RT\r
+/** Rx FIFO is at least half full */\r
+#define SSP_INTSTAT_RAW_RX SSP_RIS_RX\r
+/** Tx FIFO is at least half empty */\r
+#define SSP_INTSTAT_RAW_TX SSP_RIS_TX\r
+\r
+#define PARAM_SSP_INTSTAT_RAW(n) ((n==SSP_INTSTAT_RAW_ROR) || (n==SSP_INTSTAT_RAW_RT) \\r
+|| (n==SSP_INTSTAT_RAW_RX) || (n==SSP_INTSTAT_RAW_TX))\r
+\r
+\r
+/*********************************************************************//**\r
+ * SSP Interrupt Clear defines\r
+ **********************************************************************/\r
+/** Writing a 1 to this bit clears the "frame was received when\r
+ * RxFIFO was full" interrupt */\r
+#define SSP_INTCLR_ROR SSP_ICR_ROR\r
+/** Writing a 1 to this bit clears the "Rx FIFO was not empty and\r
+ * has not been read for a timeout period" interrupt */\r
+#define SSP_INTCLR_RT SSP_ICR_RT\r
+\r
+#define PARAM_SSP_INTCLR(n) ((n==SSP_INTCLR_ROR) || (n==SSP_INTCLR_RT))\r
+\r
+\r
+/*********************************************************************//**\r
+ * SSP DMA defines\r
+ **********************************************************************/\r
+/** SSP bit for enabling RX DMA */\r
+#define SSP_DMA_TX SSP_DMA_RXDMA_EN\r
+/** SSP bit for enabling TX DMA */\r
+#define SSP_DMA_RX SSP_DMA_TXDMA_EN\r
+\r
+#define PARAM_SSP_DMA(n) ((n==SSP_DMA_TX) || (n==SSP_DMA_RX))\r
+\r
+/* SSP Status Implementation definitions */\r
+#define SSP_STAT_DONE (1UL<<8) /**< Done */\r
+#define SSP_STAT_ERROR (1UL<<9) /**< Error */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Functions ----------------------------------------------------------- */\r
+/** @defgroup SSP_Public_Functions\r
+ * @{\r
+ */\r
+\r
+void SSP_SetClock (LPC_SSP_TypeDef *SSPx, uint32_t target_clock);\r
+void SSP_DeInit(LPC_SSP_TypeDef* SSPx);\r
+void SSP_Init(LPC_SSP_TypeDef *SSPx, SSP_CFG_Type *SSP_ConfigStruct);\r
+void SSP_ConfigStructInit(SSP_CFG_Type *SSP_InitStruct);\r
+void SSP_Cmd(LPC_SSP_TypeDef* SSPx, FunctionalState NewState);\r
+void SSP_LoopBackCmd(LPC_SSP_TypeDef* SSPx, FunctionalState NewState);\r
+void SSP_SlaveOutputCmd(LPC_SSP_TypeDef* SSPx, FunctionalState NewState);\r
+void SSP_SendData(LPC_SSP_TypeDef* SSPx, uint16_t Data);\r
+uint16_t SSP_ReceiveData(LPC_SSP_TypeDef* SSPx);\r
+int32_t SSP_ReadWrite (LPC_SSP_TypeDef *SSPx, SSP_DATA_SETUP_Type *dataCfg, \\r
+ SSP_TRANSFER_Type xfType);\r
+FlagStatus SSP_GetStatus(LPC_SSP_TypeDef* SSPx, uint32_t FlagType);\r
+void SSP_IntConfig(LPC_SSP_TypeDef *SSPx, uint32_t IntType, FunctionalState NewState);\r
+IntStatus SSP_GetRawIntStatus(LPC_SSP_TypeDef *SSPx, uint32_t RawIntType);\r
+IntStatus SSP_GetIntStatus (LPC_SSP_TypeDef *SSPx, uint32_t IntType);\r
+void SSP_ClearIntPending(LPC_SSP_TypeDef *SSPx, uint32_t IntType);\r
+void SSP_DMACmd(LPC_SSP_TypeDef *SSPx, uint32_t DMAMode, FunctionalState NewState);\r
+void SSP0_StdIntHandler(void);\r
+void SSP1_StdIntHandler(void);\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* LPC17XX_SSP_H_ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* --------------------------------- End Of File ------------------------------ */\r
--- /dev/null
+PACKAGE asp_pdic_uart
+VERSION 1.6.0
+
+MANIFEST
+serial_user.txt
+uart.c
+uart.h
--- /dev/null
+/**\r
+ * @file : lpc17xx_uart.c\r
+ * @brief : Contains all functions support for UART firmware library on LPC17xx\r
+ * @version : 1.0\r
+ * @date : 18. Mar. 2009\r
+ * @author : HieuNguyen\r
+ **************************************************************************\r
+ * Software that is described herein is for illustrative purposes only\r
+ * which provides customers with programming information regarding the\r
+ * products. This software is supplied "AS IS" without any warranties.\r
+ * NXP Semiconductors assumes no responsibility or liability for the\r
+ * use of the software, conveys no license or title under any patent,\r
+ * copyright, or mask work right to the product. NXP Semiconductors\r
+ * reserves the right to make changes in the software without\r
+ * notification. NXP Semiconductors also make no representation or\r
+ * warranty that such application will be suitable for the specified\r
+ * use without further testing or modification.\r
+ **********************************************************************/\r
+\r
+/* Peripheral group ----------------------------------------------------------- */\r
+/** @addtogroup UART\r
+ * @{\r
+ */\r
+\r
+/* Includes ------------------------------------------------------------------- */\r
+#include "lpc17xx_uart.h"\r
+#include "lpc17xx_clkpwr.h"\r
+\r
+/* If this source file built with example, the LPC17xx FW library configuration\r
+ * file in each example directory ("lpc17xx_libcfg.h") must be included,\r
+ * otherwise the default FW library configuration file must be included instead\r
+ */\r
+#ifdef __BUILD_WITH_EXAMPLE__\r
+#include "lpc17xx_libcfg.h"\r
+#else\r
+#include "lpc17xx_libcfg_default.h"\r
+#endif /* __BUILD_WITH_EXAMPLE__ */\r
+\r
+\r
+#ifdef _UART\r
+\r
+/* Private Types -------------------------------------------------------------- */\r
+/** @defgroup UART_Private_Types\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief UART call-back function type definitions\r
+ */\r
+typedef struct {\r
+ fnTxCbs_Type *pfnTxCbs; // Transmit callback\r
+ fnRxCbs_Type *pfnRxCbs; // Receive callback\r
+ fnABCbs_Type *pfnABCbs; // Auto-Baudrate callback\r
+ fnErrCbs_Type *pfnErrCbs; // Error callback\r
+} UART_CBS_Type;\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Private Variables ---------------------------------------------------------- */\r
+/** @defgroup UART_Private_Variables\r
+ * @{\r
+ */\r
+\r
+\r
+/** Call-back function pointer data */\r
+UART_CBS_Type uartCbsDat[4] = {\r
+ {NULL, NULL, NULL, NULL},\r
+ {NULL, NULL, NULL, NULL},\r
+ {NULL, NULL, NULL, NULL},\r
+ {NULL, NULL, NULL, NULL},\r
+};\r
+\r
+/** UART1 modem status interrupt callback pointer data */\r
+fnModemCbs_Type *pfnModemCbs = NULL;\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Private Functions ---------------------------------------------------------- */\r
+/** @defgroup UART_Private_Functions\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief Get UART number due to UART peripheral pointer\r
+ * @param[in] UARTx UART pointer\r
+ * @return UART number\r
+ */\r
+uint8_t getUartNum(LPC_UART_TypeDef *UARTx) {\r
+ if (UARTx == LPC_UART0) return (0);\r
+ else if (UARTx == (LPC_UART_TypeDef *)LPC_UART1) return (1);\r
+ else if (UARTx == LPC_UART2) return (2);\r
+ else return (3);\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief Determines best dividers to get a target clock rate\r
+ * @param[in] UARTx Pointer to selected UART peripheral, should be\r
+ * UART0, UART1, UART2 or UART3.\r
+ * @param[in] baudrate Desired UART baud rate.\r
+ * @return Error status.\r
+ **********************************************************************/\r
+\r
+Status uart_set_divisors(LPC_UART_TypeDef *UARTx, uint32_t baudrate)\r
+{\r
+ Status errorStatus = ERROR;\r
+\r
+ uint32_t uClk;\r
+ uint32_t calcBaudrate = 0;\r
+ uint32_t temp = 0;\r
+\r
+ uint32_t mulFracDiv, dividerAddFracDiv;\r
+ uint32_t diviser = 0 ;\r
+ uint32_t mulFracDivOptimal = 1;\r
+ uint32_t dividerAddOptimal = 0;\r
+ uint32_t diviserOptimal = 0;\r
+\r
+ uint32_t relativeError = 0;\r
+ uint32_t relativeOptimalError = 100000;\r
+\r
+ /* get UART block clock */\r
+ if (UARTx == LPC_UART0)\r
+ {\r
+ uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART0);\r
+ }\r
+ else if (UARTx == (LPC_UART_TypeDef *)LPC_UART1)\r
+ {\r
+ uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART1);\r
+ }\r
+ else if (UARTx == LPC_UART2)\r
+ {\r
+ uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART2);\r
+ }\r
+ else if (UARTx == LPC_UART3)\r
+ {\r
+ uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART3);\r
+ }\r
+\r
+\r
+ uClk = uClk >> 4; /* div by 16 */\r
+ /* In the Uart IP block, baud rate is calculated using FDR and DLL-DLM registers\r
+ * The formula is :\r
+ * BaudRate= uClk * (mulFracDiv/(mulFracDiv+dividerAddFracDiv) / (16 * (DLL)\r
+ * It involves floating point calculations. That's the reason the formulae are adjusted with\r
+ * Multiply and divide method.*/\r
+ /* The value of mulFracDiv and dividerAddFracDiv should comply to the following expressions:\r
+ * 0 < mulFracDiv <= 15, 0 <= dividerAddFracDiv <= 15 */\r
+ for (mulFracDiv = 1 ; mulFracDiv <= 15 ;mulFracDiv++)\r
+ {\r
+ for (dividerAddFracDiv = 0 ; dividerAddFracDiv <= 15 ;dividerAddFracDiv++)\r
+ {\r
+ temp = (mulFracDiv * uClk) / ((mulFracDiv + dividerAddFracDiv));\r
+\r
+ diviser = temp / baudrate;\r
+ if ((temp % baudrate) > (baudrate / 2))\r
+ diviser++;\r
+\r
+ if (diviser > 2 && diviser < 65536)\r
+ {\r
+ calcBaudrate = temp / diviser;\r
+\r
+ if (calcBaudrate <= baudrate)\r
+ relativeError = baudrate - calcBaudrate;\r
+ else\r
+ relativeError = calcBaudrate - baudrate;\r
+\r
+ if ((relativeError < relativeOptimalError))\r
+ {\r
+ mulFracDivOptimal = mulFracDiv ;\r
+ dividerAddOptimal = dividerAddFracDiv;\r
+ diviserOptimal = diviser;\r
+ relativeOptimalError = relativeError;\r
+ if (relativeError == 0)\r
+ break;\r
+ }\r
+ } /* End of if */\r
+ } /* end of inner for loop */\r
+ if (relativeError == 0)\r
+ break;\r
+ } /* end of outer for loop */\r
+\r
+ if (relativeOptimalError < ((baudrate * UART_ACCEPTED_BAUDRATE_ERROR)/100))\r
+ {\r
+ if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)\r
+ {\r
+ ((LPC_UART1_TypeDef *)UARTx)->LCR |= UART_LCR_DLAB_EN;\r
+ ((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/DLM = UART_LOAD_DLM(diviserOptimal);\r
+ ((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/DLL = UART_LOAD_DLL(diviserOptimal);\r
+ /* Then reset DLAB bit */\r
+ ((LPC_UART1_TypeDef *)UARTx)->LCR &= (~UART_LCR_DLAB_EN) & UART_LCR_BITMASK;\r
+ ((LPC_UART1_TypeDef *)UARTx)->FDR = (UART_FDR_MULVAL(mulFracDivOptimal) \\r
+ | UART_FDR_DIVADDVAL(dividerAddOptimal)) & UART_FDR_BITMASK;\r
+ }\r
+ else\r
+ {\r
+ UARTx->LCR |= UART_LCR_DLAB_EN;\r
+ UARTx->/*DLIER.*/DLM = UART_LOAD_DLM(diviserOptimal);\r
+ UARTx->/*RBTHDLR.*/DLL = UART_LOAD_DLL(diviserOptimal);\r
+ /* Then reset DLAB bit */\r
+ UARTx->LCR &= (~UART_LCR_DLAB_EN) & UART_LCR_BITMASK;\r
+ UARTx->FDR = (UART_FDR_MULVAL(mulFracDivOptimal) \\r
+ | UART_FDR_DIVADDVAL(dividerAddOptimal)) & UART_FDR_BITMASK;\r
+ }\r
+ errorStatus = SUCCESS;\r
+ }\r
+\r
+ return errorStatus;\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief General UART interrupt handler and router\r
+ * @param[in] UARTx Selected UART peripheral, should be UART0..3\r
+ * @return None\r
+ *\r
+ * Note:\r
+ * - Handles transmit, receive, and status interrupts for the UART.\r
+ * Based on the interrupt status, routes the interrupt to the\r
+ * respective call-back to be handled by the user application using\r
+ * this driver.\r
+ * - If callback is not installed, corresponding interrupt will be disabled\r
+ * - All these interrupt source below will be checked:\r
+ * - Transmit Holding Register Empty.\r
+ * - Received Data Available and Character Time Out.\r
+ * - Receive Line Status (not implemented)\r
+ * - End of auto-baud interrupt (not implemented)\r
+ * - Auto-Baudrate Time-Out interrupt (not implemented)\r
+ * - Modem Status interrupt (UART0 Modem functionality)\r
+ * - CTS signal transition interrupt (UART0 Modem functionality)\r
+ **********************************************************************/\r
+void UART_GenIntHandler(LPC_UART_TypeDef *UARTx)\r
+{\r
+ uint8_t pUart, modemsts;\r
+ uint32_t intsrc, tmp, tmp1;\r
+\r
+ pUart = getUartNum(UARTx);\r
+\r
+ /* Determine the interrupt source */\r
+ intsrc = UARTx->IIR;\r
+ tmp = intsrc & UART_IIR_INTID_MASK;\r
+\r
+ /*\r
+ * In case of using UART1 with full modem,\r
+ * interrupt ID = 0 that means modem status interrupt has been detected\r
+ */\r
+ if (pUart == 1) {\r
+ if (tmp == 0){\r
+ // Check Modem status\r
+ modemsts = LPC_UART1->MSR & UART1_MSR_BITMASK;\r
+ // Call modem status call-back\r
+ if (pfnModemCbs != NULL){\r
+ pfnModemCbs(modemsts);\r
+ }\r
+ // disable modem status interrupt and CTS status change interrupt\r
+ // if its callback is not installed\r
+ else {\r
+ LPC_UART1->IER &= ~(UART1_IER_MSINT_EN | UART1_IER_CTSINT_EN);\r
+ }\r
+ }\r
+ }\r
+\r
+ // Receive Line Status\r
+ if (tmp == UART_IIR_INTID_RLS){\r
+ // Check line status\r
+ tmp1 = UARTx->LSR;\r
+ // Mask out the Receive Ready and Transmit Holding empty status\r
+ tmp1 &= (UART_LSR_OE | UART_LSR_PE | UART_LSR_FE \\r
+ | UART_LSR_BI | UART_LSR_RXFE);\r
+ // If any error exist\r
+ if (tmp1) {\r
+ // Call Call-back function with error input value\r
+ if (uartCbsDat[pUart].pfnErrCbs != NULL) {\r
+ uartCbsDat[pUart].pfnErrCbs(tmp1);\r
+ }\r
+ // Disable interrupt if its call-back is not install\r
+ else {\r
+ UARTx->IER &= ~(UART_IER_RLSINT_EN);\r
+ }\r
+ }\r
+ }\r
+\r
+ // Receive Data Available or Character time-out\r
+ if ((tmp == UART_IIR_INTID_RDA) || (tmp == UART_IIR_INTID_CTI)){\r
+ // Call Rx call back function\r
+ if (uartCbsDat[pUart].pfnRxCbs != NULL) {\r
+ uartCbsDat[pUart].pfnRxCbs();\r
+ }\r
+ // Disable interrupt if its call-back is not install\r
+ else {\r
+ UARTx->IER &= ~(UART_IER_RBRINT_EN);\r
+ }\r
+ }\r
+\r
+ // Transmit Holding Empty\r
+ if (tmp == UART_IIR_INTID_THRE){\r
+ // Call Tx call back function\r
+ if (uartCbsDat[pUart].pfnTxCbs != NULL) {\r
+ uartCbsDat[pUart].pfnTxCbs();\r
+ }\r
+ // Disable interrupt if its call-back is not install\r
+ else {\r
+ UARTx->IER &= ~(UART_IER_THREINT_EN);\r
+ }\r
+ }\r
+\r
+ intsrc &= (UART_IIR_ABEO_INT | UART_IIR_ABTO_INT);\r
+ // Check if End of auto-baudrate interrupt or Auto baudrate time out\r
+ if (intsrc){\r
+ // Clear interrupt pending\r
+ UARTx->ACR |= ((intsrc & UART_IIR_ABEO_INT) ? UART_ACR_ABEOINT_CLR : 0) \\r
+ | ((intsrc & UART_IIR_ABTO_INT) ? UART_ACR_ABTOINT_CLR : 0);\r
+ if (uartCbsDat[pUart].pfnABCbs != NULL) {\r
+ uartCbsDat[pUart].pfnABCbs(intsrc);\r
+ } else {\r
+ // Disable End of AB interrupt\r
+ UARTx->IER &= ~(UART_IER_ABEOINT_EN | UART_IER_ABTOINT_EN);\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Functions ----------------------------------------------------------- */\r
+/** @addtogroup UART_Public_Functions\r
+ * @{\r
+ */\r
+\r
+/*********************************************************************//**\r
+ * @brief De-initializes the UARTx peripheral registers to their\r
+* default reset values.\r
+ * @param[in] UARTx UART peripheral selected, should be UART0, UART1,\r
+ * UART2 or UART3.\r
+ * @return None\r
+ **********************************************************************/\r
+void UART_DeInit(LPC_UART_TypeDef* UARTx)\r
+{\r
+ // For debug mode\r
+ CHECK_PARAM(PARAM_UARTx(UARTx));\r
+\r
+ UART_TxCmd(UARTx, DISABLE);\r
+\r
+#ifdef _UART0\r
+ if (UARTx == LPC_UART0)\r
+ {\r
+ /* Set up clock and power for UART module */\r
+ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART0, DISABLE);\r
+ }\r
+#endif\r
+\r
+#ifdef _UART1\r
+ if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)\r
+ {\r
+ /* Set up clock and power for UART module */\r
+ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART1, DISABLE);\r
+ }\r
+#endif\r
+\r
+#ifdef _UART2\r
+ if (UARTx == LPC_UART2)\r
+ {\r
+ /* Set up clock and power for UART module */\r
+ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART2, DISABLE);\r
+ }\r
+#endif\r
+\r
+#ifdef _UART3\r
+ if (UARTx == LPC_UART3)\r
+ {\r
+ /* Set up clock and power for UART module */\r
+ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART3, DISABLE);\r
+ }\r
+#endif\r
+}\r
+\r
+/********************************************************************//**\r
+ * @brief Initializes the UARTx peripheral according to the specified\r
+* parameters in the UART_ConfigStruct.\r
+ * @param[in] UARTx UART peripheral selected, should be UART0, UART1,\r
+ * UART2 or UART3.\r
+ * @param[in] UART_ConfigStruct Pointer to a UART_CFG_Type structure\r
+* that contains the configuration information for the\r
+* specified UART peripheral.\r
+ * @return None\r
+ *********************************************************************/\r
+void UART_Init(LPC_UART_TypeDef *UARTx, UART_CFG_Type *UART_ConfigStruct)\r
+{\r
+ uint32_t tmp;\r
+\r
+ // For debug mode\r
+ CHECK_PARAM(PARAM_UARTx(UARTx));\r
+ CHECK_PARAM(PARAM_UART_DATABIT(UART_ConfigStruct->Databits));\r
+ CHECK_PARAM(PARAM_UART_STOPBIT(UART_ConfigStruct->Stopbits));\r
+ CHECK_PARAM(PARAM_UART_PARITY(UART_ConfigStruct->Parity));\r
+\r
+#ifdef _UART0\r
+ if(UARTx == LPC_UART0)\r
+ {\r
+ /* Set up clock and power for UART module */\r
+ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART0, ENABLE);\r
+ }\r
+#endif\r
+\r
+#ifdef _UART1\r
+ if(((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)\r
+ {\r
+ /* Set up clock and power for UART module */\r
+ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART1, ENABLE);\r
+ }\r
+#endif\r
+\r
+#ifdef _UART2\r
+ if(UARTx == LPC_UART2)\r
+ {\r
+ /* Set up clock and power for UART module */\r
+ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART2, ENABLE);\r
+ }\r
+#endif\r
+\r
+#ifdef _UART3\r
+ if(UARTx == LPC_UART3)\r
+ {\r
+ /* Set up clock and power for UART module */\r
+ CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUART3, ENABLE);\r
+ }\r
+#endif\r
+\r
+ if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)\r
+ {\r
+ /* FIFOs are empty */\r
+ ((LPC_UART1_TypeDef *)UARTx)->/*IIFCR.*/FCR = ( UART_FCR_FIFO_EN \\r
+ | UART_FCR_RX_RS | UART_FCR_TX_RS);\r
+ // Disable FIFO\r
+ ((LPC_UART1_TypeDef *)UARTx)->/*IIFCR.*/FCR = 0;\r
+\r
+ // Dummy reading\r
+ while (((LPC_UART1_TypeDef *)UARTx)->LSR & UART_LSR_RDR)\r
+ {\r
+ tmp = ((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/RBR;\r
+ }\r
+\r
+ ((LPC_UART1_TypeDef *)UARTx)->TER = UART_TER_TXEN;\r
+ // Wait for current transmit complete\r
+ while (!(((LPC_UART1_TypeDef *)UARTx)->LSR & UART_LSR_THRE));\r
+ // Disable Tx\r
+ ((LPC_UART1_TypeDef *)UARTx)->TER = 0;\r
+\r
+ // Disable interrupt\r
+ ((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/IER = 0;\r
+ // Set LCR to default state\r
+ ((LPC_UART1_TypeDef *)UARTx)->LCR = 0;\r
+ // Set ACR to default state\r
+ ((LPC_UART1_TypeDef *)UARTx)->ACR = 0;\r
+ // Set Modem Control to default state\r
+ ((LPC_UART1_TypeDef *)UARTx)->MCR = 0;\r
+ // Set RS485 control to default state\r
+ ((LPC_UART1_TypeDef *)UARTx)->RS485CTRL = 0;\r
+ // Set RS485 delay timer to default state\r
+ ((LPC_UART1_TypeDef *)UARTx)->RS485DLY = 0;\r
+ // Set RS485 addr match to default state\r
+ ((LPC_UART1_TypeDef *)UARTx)->ADRMATCH = 0;\r
+ //Dummy Reading to Clear Status\r
+ tmp = ((LPC_UART1_TypeDef *)UARTx)->MSR;\r
+ tmp = ((LPC_UART1_TypeDef *)UARTx)->LSR;\r
+ }\r
+ else\r
+ {\r
+ /* FIFOs are empty */\r
+ UARTx->/*IIFCR.*/FCR = ( UART_FCR_FIFO_EN | UART_FCR_RX_RS | UART_FCR_TX_RS);\r
+ // Disable FIFO\r
+ UARTx->/*IIFCR.*/FCR = 0;\r
+\r
+ // Dummy reading\r
+ while (UARTx->LSR & UART_LSR_RDR)\r
+ {\r
+ tmp = UARTx->/*RBTHDLR.*/RBR;\r
+ }\r
+\r
+ UARTx->TER = UART_TER_TXEN;\r
+ // Wait for current transmit complete\r
+ while (!(UARTx->LSR & UART_LSR_THRE));\r
+ // Disable Tx\r
+ UARTx->TER = 0;\r
+\r
+ // Disable interrupt\r
+ UARTx->/*DLIER.*/IER = 0;\r
+ // Set LCR to default state\r
+ UARTx->LCR = 0;\r
+ // Set ACR to default state\r
+ UARTx->ACR = 0;\r
+ // Dummy reading\r
+ tmp = UARTx->LSR;\r
+ }\r
+\r
+ if (UARTx == LPC_UART3)\r
+ {\r
+ // Set IrDA to default state\r
+ UARTx->ICR = 0;\r
+ }\r
+\r
+ // Set Line Control register ----------------------------\r
+\r
+ uart_set_divisors(UARTx, (UART_ConfigStruct->Baud_rate));\r
+\r
+ if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)\r
+ {\r
+ tmp = (((LPC_UART1_TypeDef *)UARTx)->LCR & (UART_LCR_DLAB_EN | UART_LCR_BREAK_EN)) \\r
+ & UART_LCR_BITMASK;\r
+ }\r
+ else\r
+ {\r
+ tmp = (UARTx->LCR & (UART_LCR_DLAB_EN | UART_LCR_BREAK_EN)) & UART_LCR_BITMASK;\r
+ }\r
+\r
+ switch (UART_ConfigStruct->Databits){\r
+ case UART_DATABIT_5:\r
+ tmp |= UART_LCR_WLEN5;\r
+ break;\r
+ case UART_DATABIT_6:\r
+ tmp |= UART_LCR_WLEN6;\r
+ break;\r
+ case UART_DATABIT_7:\r
+ tmp |= UART_LCR_WLEN7;\r
+ break;\r
+ case UART_DATABIT_8:\r
+ default:\r
+ tmp |= UART_LCR_WLEN8;\r
+ break;\r
+ }\r
+\r
+ if (UART_ConfigStruct->Parity == UART_PARITY_NONE)\r
+ {\r
+ // Do nothing...\r
+ }\r
+ else\r
+ {\r
+ tmp |= UART_LCR_PARITY_EN;\r
+ switch (UART_ConfigStruct->Parity)\r
+ {\r
+ case UART_PARITY_ODD:\r
+ tmp |= UART_LCR_PARITY_ODD;\r
+ break;\r
+\r
+ case UART_PARITY_EVEN:\r
+ tmp |= UART_LCR_PARITY_EVEN;\r
+ break;\r
+\r
+ case UART_PARITY_SP_1:\r
+ tmp |= UART_LCR_PARITY_F_1;\r
+ break;\r
+\r
+ case UART_PARITY_SP_0:\r
+ tmp |= UART_LCR_PARITY_F_0;\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+\r
+ switch (UART_ConfigStruct->Stopbits){\r
+ case UART_STOPBIT_2:\r
+ tmp |= UART_LCR_STOPBIT_SEL;\r
+ break;\r
+ case UART_STOPBIT_1:\r
+ default:\r
+ // Do no thing\r
+ break;\r
+ }\r
+\r
+\r
+ // Write back to LCR, configure FIFO and Disable Tx\r
+ if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)\r
+ {\r
+ ((LPC_UART1_TypeDef *)UARTx)->LCR = (uint8_t)(tmp & UART_LCR_BITMASK);\r
+ }\r
+ else\r
+ {\r
+ UARTx->LCR = (uint8_t)(tmp & UART_LCR_BITMASK);\r
+ }\r
+}\r
+\r
+\r
+/*****************************************************************************//**\r
+* @brief Fills each UART_InitStruct member with its default value:\r
+* 9600 bps\r
+* 8-bit data\r
+* 1 Stopbit\r
+* None Parity\r
+* @param[in] UART_InitStruct Pointer to a UART_CFG_Type structure\r
+* which will be initialized.\r
+* @return None\r
+*******************************************************************************/\r
+void UART_ConfigStructInit(UART_CFG_Type *UART_InitStruct)\r
+{\r
+ UART_InitStruct->Baud_rate = 9600;\r
+ UART_InitStruct->Databits = UART_DATABIT_8;\r
+ UART_InitStruct->Parity = UART_PARITY_NONE;\r
+ UART_InitStruct->Stopbits = UART_STOPBIT_1;\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Transmit a single data through UART peripheral\r
+ * @param[in] UARTx UART peripheral selected, should be UART0, UART1,\r
+ * UART2 or UART3.\r
+ * @param[in] Data Data to transmit (must be 8-bit long)\r
+ * @return none\r
+ **********************************************************************/\r
+void UART_SendData(LPC_UART_TypeDef* UARTx, uint8_t Data)\r
+{\r
+ CHECK_PARAM(PARAM_UARTx(UARTx));\r
+\r
+ if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)\r
+ {\r
+ ((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/THR = Data & UART_THR_MASKBIT;\r
+ }\r
+ else\r
+ {\r
+ UARTx->/*RBTHDLR.*/THR = Data & UART_THR_MASKBIT;\r
+ }\r
+\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Receive a single data from UART peripheral\r
+ * @param[in] UARTx UART peripheral selected, should be UART0, UART1,\r
+ * UART2 or UART3.\r
+ * @return Data received\r
+ **********************************************************************/\r
+uint8_t UART_ReceiveData(LPC_UART_TypeDef* UARTx)\r
+{\r
+ CHECK_PARAM(PARAM_UARTx(UARTx));\r
+\r
+ if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)\r
+ {\r
+ return (((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/RBR & UART_RBR_MASKBIT);\r
+ }\r
+ else\r
+ {\r
+ return (UARTx->/*RBTHDLR.*/RBR & UART_RBR_MASKBIT);\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Force BREAK character on UART line, output pin UARTx TXD is\r
+ forced to logic 0.\r
+ * @param[in] UARTx UART peripheral selected, should be UART0, UART1,\r
+ * UART2 or UART3.\r
+ * @return none\r
+ **********************************************************************/\r
+void UART_ForceBreak(LPC_UART_TypeDef* UARTx)\r
+{\r
+ CHECK_PARAM(PARAM_UARTx(UARTx));\r
+\r
+ if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)\r
+ {\r
+ ((LPC_UART1_TypeDef *)UARTx)->LCR |= UART_LCR_BREAK_EN;\r
+ }\r
+ else\r
+ {\r
+ UARTx->LCR |= UART_LCR_BREAK_EN;\r
+ }\r
+}\r
+\r
+\r
+#ifdef _UART3\r
+\r
+/*********************************************************************//**\r
+ * @brief Enable or disable inverting serial input function of IrDA\r
+ * on UART peripheral.\r
+ * @param[in] UARTx UART peripheral selected, should be UART3 (only)\r
+ * @param[in] NewState New state of inverting serial input, should be:\r
+ * - ENABLE: Enable this function.\r
+ * - DISABLE: Disable this function.\r
+ * @return none\r
+ **********************************************************************/\r
+void UART_IrDAInvtInputCmd(LPC_UART_TypeDef* UARTx, FunctionalState NewState)\r
+{\r
+ CHECK_PARAM(PARAM_UART_IrDA(UARTx));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));\r
+\r
+ if (NewState == ENABLE)\r
+ {\r
+ UARTx->ICR |= UART_ICR_IRDAINV;\r
+ }\r
+ else if (NewState == DISABLE)\r
+ {\r
+ UARTx->ICR &= (~UART_ICR_IRDAINV) & UART_ICR_BITMASK;\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Enable or disable IrDA function on UART peripheral.\r
+ * @param[in] UARTx UART peripheral selected, should be UART3 (only)\r
+ * @param[in] NewState New state of IrDA function, should be:\r
+ * - ENABLE: Enable this function.\r
+ * - DISABLE: Disable this function.\r
+ * @return none\r
+ **********************************************************************/\r
+void UART_IrDACmd(LPC_UART_TypeDef* UARTx, FunctionalState NewState)\r
+{\r
+ CHECK_PARAM(PARAM_UART_IrDA(UARTx));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));\r
+\r
+ if (NewState == ENABLE)\r
+ {\r
+ UARTx->ICR |= UART_ICR_IRDAEN;\r
+ }\r
+ else\r
+ {\r
+ UARTx->ICR &= (~UART_ICR_IRDAEN) & UART_ICR_BITMASK;\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Configure Pulse divider for IrDA function on UART peripheral.\r
+ * @param[in] UARTx UART peripheral selected, should be UART3 (only)\r
+ * @param[in] PulseDiv Pulse Divider value from Peripheral clock,\r
+ * should be one of the following:\r
+ - UART_IrDA_PULSEDIV2 : Pulse width = 2 * Tpclk\r
+ - UART_IrDA_PULSEDIV4 : Pulse width = 4 * Tpclk\r
+ - UART_IrDA_PULSEDIV8 : Pulse width = 8 * Tpclk\r
+ - UART_IrDA_PULSEDIV16 : Pulse width = 16 * Tpclk\r
+ - UART_IrDA_PULSEDIV32 : Pulse width = 32 * Tpclk\r
+ - UART_IrDA_PULSEDIV64 : Pulse width = 64 * Tpclk\r
+ - UART_IrDA_PULSEDIV128 : Pulse width = 128 * Tpclk\r
+ - UART_IrDA_PULSEDIV256 : Pulse width = 256 * Tpclk\r
+\r
+ * @return none\r
+ **********************************************************************/\r
+void UART_IrDAPulseDivConfig(LPC_UART_TypeDef *UARTx, UART_IrDA_PULSE_Type PulseDiv)\r
+{\r
+ uint32_t tmp, tmp1;\r
+ CHECK_PARAM(PARAM_UART_IrDA(UARTx));\r
+ CHECK_PARAM(PARAM_UART_IrDA_PULSEDIV(PulseDiv));\r
+\r
+ tmp1 = UART_ICR_PULSEDIV(PulseDiv);\r
+ tmp = UARTx->ICR & (~UART_ICR_PULSEDIV(7));\r
+ tmp |= tmp1 | UART_ICR_FIXPULSE_EN;\r
+ UARTx->ICR = tmp & UART_ICR_BITMASK;\r
+}\r
+\r
+#endif\r
+\r
+\r
+/********************************************************************//**\r
+ * @brief Enable or disable specified UART interrupt.\r
+ * @param[in] UARTx UART peripheral selected, should be UART0, UART1,\r
+ * UART2 or UART3.\r
+ * @param[in] UARTIntCfg Specifies the interrupt flag,\r
+ * should be one of the following:\r
+ - UART_INTCFG_RBR : RBR Interrupt enable\r
+ - UART_INTCFG_THRE : THR Interrupt enable\r
+ - UART_INTCFG_RLS : RX line status interrupt enable\r
+ - UART1_INTCFG_MS : Modem status interrupt enable (UART1 only)\r
+ - UART1_INTCFG_CTS : CTS1 signal transition interrupt enable (UART1 only)\r
+ - UART_INTCFG_ABEO : Enables the end of auto-baud interrupt\r
+ - UART_INTCFG_ABTO : Enables the auto-baud time-out interrupt\r
+ * @param[in] NewState New state of specified UART interrupt type,\r
+ * should be:\r
+ * - ENALBE: Enable this UART interrupt type.\r
+* - DISALBE: Disable this UART interrupt type.\r
+ * @return None\r
+ *********************************************************************/\r
+void UART_IntConfig(LPC_UART_TypeDef *UARTx, UART_INT_Type UARTIntCfg, FunctionalState NewState)\r
+{\r
+ uint32_t tmp;\r
+\r
+ CHECK_PARAM(PARAM_UARTx(UARTx));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));\r
+\r
+ switch(UARTIntCfg){\r
+ case UART_INTCFG_RBR:\r
+ tmp = UART_IER_RBRINT_EN;\r
+ break;\r
+ case UART_INTCFG_THRE:\r
+ tmp = UART_IER_THREINT_EN;\r
+ break;\r
+ case UART_INTCFG_RLS:\r
+ tmp = UART_IER_RLSINT_EN;\r
+ break;\r
+ case UART1_INTCFG_MS:\r
+ tmp = UART1_IER_MSINT_EN;\r
+ break;\r
+ case UART1_INTCFG_CTS:\r
+ tmp = UART1_IER_CTSINT_EN;\r
+ break;\r
+ case UART_INTCFG_ABEO:\r
+ tmp = UART_IER_ABEOINT_EN;\r
+ break;\r
+ case UART_INTCFG_ABTO:\r
+ tmp = UART_IER_ABTOINT_EN;\r
+ break;\r
+ }\r
+\r
+ if ((LPC_UART1_TypeDef *) UARTx == LPC_UART1)\r
+ {\r
+ CHECK_PARAM((PARAM_UART_INTCFG(UARTIntCfg)) || (PARAM_UART1_INTCFG(UARTIntCfg)));\r
+ }\r
+ else\r
+ {\r
+ CHECK_PARAM(PARAM_UART_INTCFG(UARTIntCfg));\r
+ }\r
+\r
+ if (NewState == ENABLE)\r
+ {\r
+ if ((LPC_UART1_TypeDef *) UARTx == LPC_UART1)\r
+ {\r
+ ((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/IER |= tmp;\r
+ }\r
+ else\r
+ {\r
+ UARTx->/*DLIER.*/IER |= tmp;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if ((LPC_UART1_TypeDef *) UARTx == LPC_UART1)\r
+ {\r
+ ((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/IER &= (~tmp) & UART1_IER_BITMASK;\r
+ }\r
+ else\r
+ {\r
+ UARTx->/*DLIER.*/IER &= (~tmp) & UART_IER_BITMASK;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+/********************************************************************//**\r
+ * @brief Get current value of Line Status register in UART peripheral.\r
+ * @param[in] UARTx UART peripheral selected, should be UART0, UART1,\r
+ * UART2 or UART3.\r
+ * @return Current value of Line Status register in UART peripheral.\r
+ * Note: The return value of this function must be ANDed with each member in\r
+ * UART_LS_Type enumeration to determine current flag status\r
+ * corresponding to each Line status type. Because some flags in\r
+ * Line Status register will be cleared after reading, the next reading\r
+ * Line Status register could not be correct. So this function used to\r
+ * read Line status register in one time only, then the return value\r
+ * used to check all flags.\r
+ *********************************************************************/\r
+uint8_t UART_GetLineStatus(LPC_UART_TypeDef* UARTx)\r
+{\r
+ CHECK_PARAM(PARAM_UARTx(UARTx));\r
+\r
+ if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)\r
+ {\r
+ return ((((LPC_UART1_TypeDef *)LPC_UART1)->LSR) & UART_LSR_BITMASK);\r
+ }\r
+ else\r
+ {\r
+ return ((UARTx->LSR) & UART_LSR_BITMASK);\r
+ }\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief Check whether if UART is busy or not\r
+ * @param[in] UARTx UART peripheral selected, should be UART0, UART1,\r
+ * UART2 or UART3.\r
+ * @return RESET if UART is not busy, otherwise return SET.\r
+ **********************************************************************/\r
+FlagStatus UART_CheckBusy(LPC_UART_TypeDef *UARTx)\r
+{\r
+ if (UARTx->LSR & UART_LSR_TEMT){\r
+ return RESET;\r
+ } else {\r
+ return SET;\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Configure FIFO function on selected UART peripheral\r
+ * @param[in] UARTx UART peripheral selected, should be UART0, UART1,\r
+ * UART2 or UART3.\r
+ * @param[in] FIFOCfg Pointer to a UART_FIFO_CFG_Type Structure that\r
+ * contains specified information about FIFO configuration\r
+ * @return none\r
+ **********************************************************************/\r
+void UART_FIFOConfig(LPC_UART_TypeDef *UARTx, UART_FIFO_CFG_Type *FIFOCfg)\r
+{\r
+ uint8_t tmp = 0;\r
+\r
+ CHECK_PARAM(PARAM_UARTx(UARTx));\r
+ CHECK_PARAM(PARAM_UART_FIFO_LEVEL(FIFOCfg->FIFO_Level));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(FIFOCfg->FIFO_DMAMode));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(FIFOCfg->FIFO_ResetRxBuf));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(FIFOCfg->FIFO_ResetTxBuf));\r
+\r
+ tmp |= UART_FCR_FIFO_EN;\r
+ switch (FIFOCfg->FIFO_Level){\r
+ case UART_FIFO_TRGLEV0:\r
+ tmp |= UART_FCR_TRG_LEV0;\r
+ break;\r
+ case UART_FIFO_TRGLEV1:\r
+ tmp |= UART_FCR_TRG_LEV1;\r
+ break;\r
+ case UART_FIFO_TRGLEV2:\r
+ tmp |= UART_FCR_TRG_LEV2;\r
+ break;\r
+ case UART_FIFO_TRGLEV3:\r
+ default:\r
+ tmp |= UART_FCR_TRG_LEV3;\r
+ break;\r
+ }\r
+\r
+ if (FIFOCfg->FIFO_ResetTxBuf == ENABLE)\r
+ {\r
+ tmp |= UART_FCR_TX_RS;\r
+ }\r
+ if (FIFOCfg->FIFO_ResetRxBuf == ENABLE)\r
+ {\r
+ tmp |= UART_FCR_RX_RS;\r
+ }\r
+ if (FIFOCfg->FIFO_DMAMode == ENABLE)\r
+ {\r
+ tmp |= UART_FCR_DMAMODE_SEL;\r
+ }\r
+\r
+\r
+ //write to FIFO control register\r
+ if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)\r
+ {\r
+ ((LPC_UART1_TypeDef *)UARTx)->/*IIFCR.*/FCR = tmp & UART_FCR_BITMASK;\r
+ }\r
+ else\r
+ {\r
+ UARTx->/*IIFCR.*/FCR = tmp & UART_FCR_BITMASK;\r
+ }\r
+\r
+}\r
+\r
+\r
+/*****************************************************************************//**\r
+* @brief Fills each UART_FIFOInitStruct member with its default value:\r
+* - FIFO_DMAMode = DISABLE\r
+* - FIFO_Level = UART_FIFO_TRGLEV0\r
+* - FIFO_ResetRxBuf = ENABLE\r
+* - FIFO_ResetTxBuf = ENABLE\r
+* - FIFO_State = ENABLE\r
+\r
+* @param[in] UART_FIFOInitStruct Pointer to a UART_FIFO_CFG_Type structure\r
+* which will be initialized.\r
+* @return None\r
+*******************************************************************************/\r
+void UART_FIFOConfigStructInit(UART_FIFO_CFG_Type *UART_FIFOInitStruct)\r
+{\r
+ UART_FIFOInitStruct->FIFO_DMAMode = DISABLE;\r
+ UART_FIFOInitStruct->FIFO_Level = UART_FIFO_TRGLEV0;\r
+ UART_FIFOInitStruct->FIFO_ResetRxBuf = ENABLE;\r
+ UART_FIFOInitStruct->FIFO_ResetTxBuf = ENABLE;\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Start/Stop Auto Baudrate activity\r
+ * @param[in] UARTx UART peripheral selected, should be UART0, UART1,\r
+ * UART2 or UART3.\r
+ * @param[in] ABConfigStruct A pointer to UART_AB_CFG_Type structure that\r
+ * contains specified information about UART\r
+ * auto baudrate configuration\r
+ * @param[in] NewState New State of Auto baudrate activity, should be:\r
+ * - ENABLE: Start this activity\r
+ * - DISABLE: Stop this activity\r
+ * Note: Auto-baudrate mode enable bit will be cleared once this mode\r
+ * completed.\r
+ * @return none\r
+ **********************************************************************/\r
+void UART_ABCmd(LPC_UART_TypeDef *UARTx, UART_AB_CFG_Type *ABConfigStruct, \\r
+ FunctionalState NewState)\r
+{\r
+ uint32_t tmp;\r
+\r
+ CHECK_PARAM(PARAM_UARTx(UARTx));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));\r
+\r
+ tmp = 0;\r
+ if (NewState == ENABLE) {\r
+ if (ABConfigStruct->ABMode == UART_AUTOBAUD_MODE1){\r
+ tmp |= UART_ACR_MODE;\r
+ }\r
+ if (ABConfigStruct->AutoRestart == ENABLE){\r
+ tmp |= UART_ACR_AUTO_RESTART;\r
+ }\r
+ }\r
+\r
+ if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)\r
+ {\r
+ if (NewState == ENABLE)\r
+ {\r
+ // Clear DLL and DLM value\r
+ ((LPC_UART1_TypeDef *)UARTx)->LCR |= UART_LCR_DLAB_EN;\r
+ ((LPC_UART1_TypeDef *)UARTx)->DLL = 0;\r
+ ((LPC_UART1_TypeDef *)UARTx)->DLM = 0;\r
+ ((LPC_UART1_TypeDef *)UARTx)->LCR &= ~UART_LCR_DLAB_EN;\r
+ // FDR value must be reset to default value\r
+ ((LPC_UART1_TypeDef *)UARTx)->FDR = 0x10;\r
+ ((LPC_UART1_TypeDef *)UARTx)->ACR = UART_ACR_START | tmp;\r
+ }\r
+ else\r
+ {\r
+ ((LPC_UART1_TypeDef *)UARTx)->ACR = 0;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (NewState == ENABLE)\r
+ {\r
+ // Clear DLL and DLM value\r
+ UARTx->LCR |= UART_LCR_DLAB_EN;\r
+ UARTx->DLL = 0;\r
+ UARTx->DLM = 0;\r
+ UARTx->LCR &= ~UART_LCR_DLAB_EN;\r
+ // FDR value must be reset to default value\r
+ UARTx->FDR = 0x10;\r
+ UARTx->ACR = UART_ACR_START | tmp;\r
+ }\r
+ else\r
+ {\r
+ UARTx->ACR = 0;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Enable/Disable transmission on UART TxD pin\r
+ * @param[in] UARTx UART peripheral selected, should be UART0, UART1,\r
+ * UART2 or UART3.\r
+ * @param[in] NewState New State of Tx transmission function, should be:\r
+ * - ENABLE: Enable this function\r
+ - DISABLE: Disable this function\r
+ * @return none\r
+ **********************************************************************/\r
+void UART_TxCmd(LPC_UART_TypeDef *UARTx, FunctionalState NewState)\r
+{\r
+ CHECK_PARAM(PARAM_UARTx(UARTx));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));\r
+\r
+ if (NewState == ENABLE)\r
+ {\r
+ if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)\r
+ {\r
+ ((LPC_UART1_TypeDef *)UARTx)->TER |= UART_TER_TXEN;\r
+ }\r
+ else\r
+ {\r
+ UARTx->TER |= UART_TER_TXEN;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)\r
+ {\r
+ ((LPC_UART1_TypeDef *)UARTx)->TER &= (~UART_TER_TXEN) & UART_TER_BITMASK;\r
+ }\r
+ else\r
+ {\r
+ UARTx->TER &= (~UART_TER_TXEN) & UART_TER_BITMASK;\r
+ }\r
+ }\r
+}\r
+\r
+#ifdef _UART1\r
+\r
+/*********************************************************************//**\r
+ * @brief Force pin DTR/RTS corresponding to given state (Full modem mode)\r
+ * @param[in] UARTx UART1 (only)\r
+ * @param[in] Pin Pin that NewState will be applied to, should be:\r
+ * - UART1_MODEM_PIN_DTR: DTR pin.\r
+ * - UART1_MODEM_PIN_RTS: RTS pin.\r
+ * @param[in] NewState New State of DTR/RTS pin, should be:\r
+ * - INACTIVE: Force the pin to inactive signal.\r
+ - ACTIVE: Force the pin to active signal.\r
+ * @return none\r
+ **********************************************************************/\r
+void UART_FullModemForcePinState(LPC_UART1_TypeDef *UARTx, UART_MODEM_PIN_Type Pin, \\r
+ UART1_SignalState NewState)\r
+{\r
+ uint8_t tmp = 0;\r
+\r
+ CHECK_PARAM(PARAM_UART1_MODEM(UARTx));\r
+ CHECK_PARAM(PARAM_UART1_MODEM_PIN(Pin));\r
+ CHECK_PARAM(PARAM_UART1_SIGNALSTATE(NewState));\r
+\r
+ switch (Pin){\r
+ case UART1_MODEM_PIN_DTR:\r
+ tmp = UART1_MCR_DTR_CTRL;\r
+ break;\r
+ case UART1_MODEM_PIN_RTS:\r
+ tmp = UART1_MCR_RTS_CTRL;\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+\r
+ if (NewState == ACTIVE){\r
+ UARTx->MCR |= tmp;\r
+ } else {\r
+ UARTx->MCR &= (~tmp) & UART1_MCR_BITMASK;\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Configure Full Modem mode for UART peripheral\r
+ * @param[in] UARTx UART1 (only)\r
+ * @param[in] Mode Full Modem mode, should be:\r
+ * - UART1_MODEM_MODE_LOOPBACK: Loop back mode.\r
+ * - UART1_MODEM_MODE_AUTO_RTS: Auto-RTS mode.\r
+ * - UART1_MODEM_MODE_AUTO_CTS: Auto-CTS mode.\r
+ * @param[in] NewState New State of this mode, should be:\r
+ * - ENABLE: Enable this mode.\r
+ - DISABLE: Disable this mode.\r
+ * @return none\r
+ **********************************************************************/\r
+void UART_FullModemConfigMode(LPC_UART1_TypeDef *UARTx, UART_MODEM_MODE_Type Mode, \\r
+ FunctionalState NewState)\r
+{\r
+ uint8_t tmp;\r
+\r
+ CHECK_PARAM(PARAM_UART1_MODEM(UARTx));\r
+ CHECK_PARAM(PARAM_UART1_MODEM_MODE(Mode));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));\r
+\r
+ switch(Mode){\r
+ case UART1_MODEM_MODE_LOOPBACK:\r
+ tmp = UART1_MCR_LOOPB_EN;\r
+ break;\r
+ case UART1_MODEM_MODE_AUTO_RTS:\r
+ tmp = UART1_MCR_AUTO_RTS_EN;\r
+ break;\r
+ case UART1_MODEM_MODE_AUTO_CTS:\r
+ tmp = UART1_MCR_AUTO_CTS_EN;\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+\r
+ if (NewState == ENABLE)\r
+ {\r
+ UARTx->MCR |= tmp;\r
+ }\r
+ else\r
+ {\r
+ UARTx->MCR &= (~tmp) & UART1_MCR_BITMASK;\r
+ }\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Get current status of modem status register\r
+ * @param[in] UARTx UART1 (only)\r
+ * @return Current value of modem status register\r
+ * Note: The return value of this function must be ANDed with each member\r
+ * UART_MODEM_STAT_type enumeration to determine current flag status\r
+ * corresponding to each modem flag status. Because some flags in\r
+ * modem status register will be cleared after reading, the next reading\r
+ * modem register could not be correct. So this function used to\r
+ * read modem status register in one time only, then the return value\r
+ * used to check all flags.\r
+ **********************************************************************/\r
+uint8_t UART_FullModemGetStatus(LPC_UART1_TypeDef *UARTx)\r
+{\r
+ CHECK_PARAM(PARAM_UART1_MODEM(UARTx));\r
+ return ((UARTx->MSR) & UART1_MSR_BITMASK);\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Configure UART peripheral in RS485 mode according to the specified\r
+* parameters in the RS485ConfigStruct.\r
+ * @param[in] UARTx UART1 (only)\r
+ * @param[in] RS485ConfigStruct Pointer to a UART1_RS485_CTRLCFG_Type structure\r
+* that contains the configuration information for specified UART\r
+* in RS485 mode.\r
+ * @return None\r
+ **********************************************************************/\r
+void UART_RS485Config(LPC_UART1_TypeDef *UARTx, UART1_RS485_CTRLCFG_Type *RS485ConfigStruct)\r
+{\r
+ uint32_t tmp;\r
+\r
+ CHECK_PARAM(PARAM_UART1_MODEM(UARTx));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(RS485ConfigStruct->AutoAddrDetect_State));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(RS485ConfigStruct->AutoDirCtrl_State));\r
+ CHECK_PARAM(PARAM_UART1_RS485_CFG_DELAYVALUE(RS485ConfigStruct->DelayValue));\r
+ CHECK_PARAM(PARAM_SETSTATE(RS485ConfigStruct->DirCtrlPol_Level));\r
+ CHECK_PARAM(PARAM_UART_RS485_DIRCTRL_PIN(RS485ConfigStruct->DirCtrlPin));\r
+ CHECK_PARAM(PARAM_UART1_RS485_CFG_MATCHADDRVALUE(RS485ConfigStruct->MatchAddrValue));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(RS485ConfigStruct->NormalMultiDropMode_State));\r
+ CHECK_PARAM(PARAM_FUNCTIONALSTATE(RS485ConfigStruct->Rx_State));\r
+\r
+ tmp = 0;\r
+ // If Auto Direction Control is enabled - This function is used in Master mode\r
+ if (RS485ConfigStruct->AutoDirCtrl_State == ENABLE)\r
+ {\r
+ tmp |= UART1_RS485CTRL_DCTRL_EN;\r
+\r
+ // Set polar\r
+ if (RS485ConfigStruct->DirCtrlPol_Level == SET)\r
+ {\r
+ tmp |= UART1_RS485CTRL_OINV_1;\r
+ }\r
+\r
+ // Set pin according to\r
+ if (RS485ConfigStruct->DirCtrlPin == UART1_RS485_DIRCTRL_DTR)\r
+ {\r
+ tmp |= UART1_RS485CTRL_SEL_DTR;\r
+ }\r
+\r
+ // Fill delay time\r
+ UARTx->RS485DLY = RS485ConfigStruct->DelayValue & UART1_RS485DLY_BITMASK;\r
+ }\r
+\r
+ // MultiDrop mode is enable\r
+ if (RS485ConfigStruct->NormalMultiDropMode_State == ENABLE)\r
+ {\r
+ tmp |= UART1_RS485CTRL_NMM_EN;\r
+ }\r
+\r
+ // Auto Address Detect function\r
+ if (RS485ConfigStruct->AutoAddrDetect_State == ENABLE)\r
+ {\r
+ tmp |= UART1_RS485CTRL_AADEN;\r
+ // Fill Match Address\r
+ UARTx->ADRMATCH = RS485ConfigStruct->MatchAddrValue & UART1_RS485ADRMATCH_BITMASK;\r
+ }\r
+\r
+\r
+ // Receiver is disable\r
+ if (RS485ConfigStruct->Rx_State == DISABLE)\r
+ {\r
+ tmp |= UART1_RS485CTRL_RX_DIS;\r
+ }\r
+\r
+ // write back to RS485 control register\r
+ UARTx->RS485CTRL = tmp & UART1_RS485CTRL_BITMASK;\r
+\r
+ // Enable Parity function and leave parity in stick '0' parity as default\r
+ UARTx->LCR |= (UART_LCR_PARITY_F_0 | UART_LCR_PARITY_EN);\r
+}\r
+\r
+\r
+/**\r
+ * @brief Enable/Disable receiver in RS485 module in UART1\r
+ * @param[in] UARTx UART1 only.\r
+ * @param[in] NewState New State of command, should be:\r
+ * - ENABLE: Enable this function.\r
+ * - DISABLE: Disable this function.\r
+ * @return None\r
+ */\r
+void UART_RS485ReceiverCmd(LPC_UART1_TypeDef *UARTx, FunctionalState NewState)\r
+{\r
+ if (NewState == ENABLE){\r
+ UARTx->RS485CTRL &= ~UART1_RS485CTRL_RX_DIS;\r
+ } else {\r
+ UARTx->RS485CTRL |= UART1_RS485CTRL_RX_DIS;\r
+ }\r
+}\r
+\r
+\r
+/**\r
+ * @brief Send data on RS485 bus with specified parity stick value (9-bit mode).\r
+ * @param[in] UARTx UART1 (only).\r
+ * @param[in] pDatFrm Pointer to data frame.\r
+ * @param[in] size Size of data.\r
+ * @param[in] ParityStick Parity Stick value, should be 0 or 1.\r
+ * @return None.\r
+ */\r
+uint32_t UART_RS485Send(LPC_UART1_TypeDef *UARTx, uint8_t *pDatFrm, \\r
+ uint32_t size, uint8_t ParityStick)\r
+{\r
+ uint8_t tmp, save;\r
+ uint32_t cnt;\r
+\r
+ if (ParityStick){\r
+ save = tmp = UARTx->LCR & UART_LCR_BITMASK;\r
+ tmp &= ~(UART_LCR_PARITY_EVEN);\r
+ UARTx->LCR = tmp;\r
+ cnt = UART_Send((LPC_UART_TypeDef *)UARTx, pDatFrm, size, BLOCKING);\r
+ while (!(UARTx->LSR & UART_LSR_TEMT));\r
+ UARTx->LCR = save;\r
+ } else {\r
+ cnt = UART_Send((LPC_UART_TypeDef *)UARTx, pDatFrm, size, BLOCKING);\r
+ while (!(UARTx->LSR & UART_LSR_TEMT));\r
+ }\r
+ return cnt;\r
+}\r
+\r
+\r
+/**\r
+ * @brief Send Slave address frames on RS485 bus.\r
+ * @param[in] UARTx UART1 (only).\r
+ * @param[in] SlvAddr Slave Address.\r
+ * @return None.\r
+ */\r
+void UART_RS485SendSlvAddr(LPC_UART1_TypeDef *UARTx, uint8_t SlvAddr)\r
+{\r
+ UART_RS485Send(UARTx, &SlvAddr, 1, 1);\r
+}\r
+\r
+\r
+/**\r
+ * @brief Send Data frames on RS485 bus.\r
+ * @param[in] UARTx UART1 (only).\r
+ * @param[in] pData Pointer to data to be sent.\r
+ * @param[in] size Size of data frame to be sent.\r
+ * @return None.\r
+ */\r
+uint32_t UART_RS485SendData(LPC_UART1_TypeDef *UARTx, uint8_t *pData, uint32_t size)\r
+{\r
+ return (UART_RS485Send(UARTx, pData, size, 0));\r
+}\r
+\r
+#endif /* _UART1 */\r
+\r
+\r
+/* Additional driver APIs ----------------------------------------------------------------------- */\r
+\r
+/*********************************************************************//**\r
+ * @brief Send a block of data via UART peripheral\r
+ * @param[in] UARTx Selected UART peripheral used to send data,\r
+ * should be UART0, UART1, UART2 or UART3.\r
+ * @param[in] txbuf Pointer to Transmit buffer\r
+ * @param[in] buflen Length of Transmit buffer\r
+ * @param[in] flag Flag used in UART transfer, should be\r
+ * NONE_BLOCKING or BLOCKING\r
+ * @return Number of bytes sent.\r
+ *\r
+ * Note: when using UART in BLOCKING mode, a time-out condition is used\r
+ * via defined symbol UART_BLOCKING_TIMEOUT.\r
+ **********************************************************************/\r
+uint32_t UART_Send(LPC_UART_TypeDef *UARTx, uint8_t *txbuf,\r
+ uint32_t buflen, TRANSFER_BLOCK_Type flag)\r
+{\r
+ uint32_t bToSend, bSent, timeOut, fifo_cnt;\r
+ uint8_t *pChar = txbuf;\r
+\r
+ bToSend = buflen;\r
+\r
+ // blocking mode\r
+ if (flag == BLOCKING) {\r
+ bSent = 0;\r
+ while (bToSend){\r
+ timeOut = UART_BLOCKING_TIMEOUT;\r
+ // Wait for THR empty with timeout\r
+ while (!(UARTx->LSR & UART_LSR_THRE)) {\r
+ if (timeOut == 0) break;\r
+ timeOut--;\r
+ }\r
+ // Time out!\r
+ if(timeOut == 0) break;\r
+ fifo_cnt = UART_TX_FIFO_SIZE;\r
+ while (fifo_cnt && bToSend){\r
+ UART_SendData(UARTx, (*pChar++));\r
+ fifo_cnt--;\r
+ bToSend--;\r
+ bSent++;\r
+ }\r
+ }\r
+ }\r
+ // None blocking mode\r
+ else {\r
+ bSent = 0;\r
+ while (bToSend) {\r
+ if (!(UARTx->LSR & UART_LSR_THRE)){\r
+ break;\r
+ }\r
+ fifo_cnt = UART_TX_FIFO_SIZE;\r
+ while (fifo_cnt && bToSend) {\r
+ UART_SendData(UARTx, (*pChar++));\r
+ bToSend--;\r
+ fifo_cnt--;\r
+ bSent++;\r
+ }\r
+ }\r
+ }\r
+ return bSent;\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief Receive a block of data via UART peripheral\r
+ * @param[in] UARTx Selected UART peripheral used to send data,\r
+ * should be UART0, UART1, UART2 or UART3.\r
+ * @param[out] rxbuf Pointer to Received buffer\r
+ * @param[in] buflen Length of Received buffer\r
+ * @param[in] flag Flag mode, should be NONE_BLOCKING or BLOCKING\r
+\r
+ * @return Number of bytes received\r
+ *\r
+ * Note: when using UART in BLOCKING mode, a time-out condition is used\r
+ * via defined symbol UART_BLOCKING_TIMEOUT.\r
+ **********************************************************************/\r
+uint32_t UART_Receive(LPC_UART_TypeDef *UARTx, uint8_t *rxbuf, \\r
+ uint32_t buflen, TRANSFER_BLOCK_Type flag)\r
+{\r
+ uint32_t bToRecv, bRecv, timeOut;\r
+ uint8_t *pChar = rxbuf;\r
+\r
+ bToRecv = buflen;\r
+\r
+ // Blocking mode\r
+ if (flag == BLOCKING) {\r
+ bRecv = 0;\r
+ while (bToRecv){\r
+ timeOut = UART_BLOCKING_TIMEOUT;\r
+ while (!(UARTx->LSR & UART_LSR_RDR)){\r
+ if (timeOut == 0) break;\r
+ timeOut--;\r
+ }\r
+ // Time out!\r
+ if(timeOut == 0) break;\r
+ // Get data from the buffer\r
+ (*pChar++) = UART_ReceiveData(UARTx);\r
+ bToRecv--;\r
+ bRecv++;\r
+ }\r
+ }\r
+ // None blocking mode\r
+ else {\r
+ bRecv = 0;\r
+ while (bToRecv) {\r
+ if (!(UARTx->LSR & UART_LSR_RDR)) {\r
+ break;\r
+ } else {\r
+ (*pChar++) = UART_ReceiveData(UARTx);\r
+ bRecv++;\r
+ bToRecv--;\r
+ }\r
+ }\r
+ }\r
+ return bRecv;\r
+}\r
+\r
+\r
+/*********************************************************************//**\r
+ * @brief Setup call-back function for UART interrupt handler for each\r
+ * UART peripheral\r
+ * @param[in] UARTx Selected UART peripheral, should be UART0..3\r
+ * @param[in] CbType Call-back type, should be:\r
+ * 0 - Receive Call-back\r
+ * 1 - Transmit Call-back\r
+ * 2 - Auto Baudrate Callback\r
+ * 3 - Error Call-back\r
+ * 4 - Modem Status Call-back (UART1 only)\r
+ * @param[in] pfnCbs Pointer to Call-back function\r
+ * @return None\r
+ **********************************************************************/\r
+void UART_SetupCbs(LPC_UART_TypeDef *UARTx, uint8_t CbType, void *pfnCbs)\r
+{\r
+ uint8_t pUartNum;\r
+\r
+ pUartNum = getUartNum(UARTx);\r
+ switch(CbType){\r
+ case 0:\r
+ uartCbsDat[pUartNum].pfnRxCbs = (fnTxCbs_Type *)pfnCbs;\r
+ break;\r
+ case 1:\r
+ uartCbsDat[pUartNum].pfnTxCbs = (fnRxCbs_Type *)pfnCbs;\r
+ break;\r
+ case 2:\r
+ uartCbsDat[pUartNum].pfnABCbs = (fnABCbs_Type *)pfnCbs;\r
+ break;\r
+ case 3:\r
+ uartCbsDat[pUartNum].pfnErrCbs = (fnErrCbs_Type *)pfnCbs;\r
+ break;\r
+ case 4:\r
+ pfnModemCbs = (fnModemCbs_Type *)pfnCbs;\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief Standard UART0 interrupt handler\r
+ * @param[in] None\r
+ * @return None\r
+ **********************************************************************/\r
+void UART0_StdIntHandler(void)\r
+{\r
+ UART_GenIntHandler(LPC_UART0);\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief Standard UART1 interrupt handler\r
+ * @param[in] None\r
+ * @return None\r
+ **********************************************************************/\r
+void UART1_StdIntHandler(void)\r
+{\r
+ UART_GenIntHandler((LPC_UART_TypeDef *)LPC_UART1);\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief Standard UART2 interrupt handler\r
+ * @param[in] None\r
+ * @return None\r
+ **********************************************************************/\r
+void UART2_StdIntHandler(void)\r
+{\r
+ UART_GenIntHandler(LPC_UART2);\r
+}\r
+\r
+/*********************************************************************//**\r
+ * @brief Standard UART3 interrupt handler\r
+ * @param[in] None\r
+ * @return\r
+ **********************************************************************/\r
+void UART3_StdIntHandler(void)\r
+{\r
+ UART_GenIntHandler(LPC_UART3);\r
+}\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+#endif /* _UART */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* --------------------------------- End Of File ------------------------------ */\r
+\r
--- /dev/null
+/***********************************************************************//**\r
+ * @file : lpc17xx_uart.h\r
+ * @brief : Contains all macro definitions and function prototypes\r
+ * support for UART firmware library on LPC17xx\r
+ * @version : 1.0\r
+ * @date : 18. Mar. 2009\r
+ * @author : HieuNguyen\r
+ **************************************************************************\r
+ * Software that is described herein is for illustrative purposes only\r
+ * which provides customers with programming information regarding the\r
+ * products. This software is supplied "AS IS" without any warranties.\r
+ * NXP Semiconductors assumes no responsibility or liability for the\r
+ * use of the software, conveys no license or title under any patent,\r
+ * copyright, or mask work right to the product. NXP Semiconductors\r
+ * reserves the right to make changes in the software without\r
+ * notification. NXP Semiconductors also make no representation or\r
+ * warranty that such application will be suitable for the specified\r
+ * use without further testing or modification.\r
+ **************************************************************************/\r
+\r
+/* Peripheral group ----------------------------------------------------------- */\r
+/** @defgroup UART\r
+ * @ingroup LPC1700CMSIS_FwLib_Drivers\r
+ * @{\r
+ */\r
+\r
+#ifndef __LPC17XX_UART_H\r
+#define __LPC17XX_UART_H\r
+\r
+/* Includes ------------------------------------------------------------------- */\r
+#include "LPC17xx.h"\r
+#include "lpc_types.h"\r
+\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif\r
+\r
+\r
+/* Private Macros ------------------------------------------------------------- */\r
+/** @defgroup UART_Private_Macros\r
+ * @{\r
+ */\r
+\r
+\r
+/** @defgroup UART_REGISTER_BIT_DEFINITIONS\r
+ * @{\r
+ */\r
+\r
+/* Accepted Error baud rate value (in percent unit) */\r
+#define UART_ACCEPTED_BAUDRATE_ERROR (3) /*!< Acceptable UART baudrate error */\r
+\r
+/* Macro defines for UARTn Receiver Buffer Register */\r
+#define UART_RBR_MASKBIT ((uint8_t)0xFF) /*!< UART Received Buffer mask bit (8 bits) */\r
+\r
+/* Macro defines for UARTn Transmit Holding Register */\r
+#define UART_THR_MASKBIT ((uint8_t)0xFF) /*!< UART Transmit Holding mask bit (8 bits) */\r
+\r
+/* Macro defines for UARTn Divisor Latch LSB register */\r
+#define UART_LOAD_DLL(div) ((div) & 0xFF) /**< Macro for loading least significant halfs of divisors */\r
+#define UART_DLL_MASKBIT ((uint8_t)0xFF) /*!< Divisor latch LSB bit mask */\r
+\r
+/* Macro defines for UARTn Divisor Latch MSB register */\r
+#define UART_DLM_MASKBIT ((uint8_t)0xFF) /*!< Divisor latch MSB bit mask */\r
+#define UART_LOAD_DLM(div) (((div) >> 8) & 0xFF) /**< Macro for loading most significant halfs of divisors */\r
+\r
+\r
+/* Macro defines for UART interrupt enable register */\r
+#define UART_IER_RBRINT_EN ((uint32_t)(1<<0)) /*!< RBR Interrupt enable*/\r
+#define UART_IER_THREINT_EN ((uint32_t)(1<<1)) /*!< THR Interrupt enable*/\r
+#define UART_IER_RLSINT_EN ((uint32_t)(1<<2)) /*!< RX line status interrupt enable*/\r
+#define UART1_IER_MSINT_EN ((uint32_t)(1<<3)) /*!< Modem status interrupt enable */\r
+#define UART1_IER_CTSINT_EN ((uint32_t)(1<<7)) /*!< CTS1 signal transition interrupt enable */\r
+#define UART_IER_ABEOINT_EN ((uint32_t)(1<<8)) /*!< Enables the end of auto-baud interrupt */\r
+#define UART_IER_ABTOINT_EN ((uint32_t)(1<<9)) /*!< Enables the auto-baud time-out interrupt */\r
+#define UART_IER_BITMASK ((uint32_t)(0x307)) /*!< UART interrupt enable register bit mask */\r
+#define UART1_IER_BITMASK ((uint32_t)(0x38F)) /*!< UART1 interrupt enable register bit mask */\r
+\r
+\r
+/* UART interrupt identification register defines */\r
+#define UART_IIR_INTSTAT_PEND ((uint32_t)(1<<0)) /*!<Interrupt Status - Active low */\r
+#define UART_IIR_INTID_RLS ((uint32_t)(3<<1)) /*!<Interrupt identification: Receive line status*/\r
+#define UART_IIR_INTID_RDA ((uint32_t)(2<<1)) /*!<Interrupt identification: Receive data available*/\r
+#define UART_IIR_INTID_CTI ((uint32_t)(6<<1)) /*!<Interrupt identification: Character time-out indicator*/\r
+#define UART_IIR_INTID_THRE ((uint32_t)(1<<1)) /*!<Interrupt identification: THRE interrupt*/\r
+#define UART1_IIR_INTID_MODEM ((uint32_t)(0<<1)) /*!<Interrupt identification: Modem interrupt*/\r
+#define UART_IIR_INTID_MASK ((uint32_t)(7<<1)) /*!<Interrupt identification: Interrupt ID mask */\r
+#define UART_IIR_FIFO_EN ((uint32_t)(3<<6)) /*!<These bits are equivalent to UnFCR[0] */\r
+#define UART_IIR_ABEO_INT ((uint32_t)(1<<8)) /*!< End of auto-baud interrupt */\r
+#define UART_IIR_ABTO_INT ((uint32_t)(1<<9)) /*!< Auto-baud time-out interrupt */\r
+#define UART_IIR_BITMASK ((uint32_t)(0x3CF)) /*!< UART interrupt identification register bit mask */\r
+\r
+\r
+/* Macro defines for UART FIFO control register */\r
+#define UART_FCR_FIFO_EN ((uint8_t)(1<<0)) /*!< UART FIFO enable */\r
+#define UART_FCR_RX_RS ((uint8_t)(1<<1)) /*!< UART FIFO RX reset */\r
+#define UART_FCR_TX_RS ((uint8_t)(1<<2)) /*!< UART FIFO TX reset */\r
+#define UART_FCR_DMAMODE_SEL ((uint8_t)(1<<3)) /*!< UART DMA mode selection */\r
+#define UART_FCR_TRG_LEV0 ((uint8_t)(0)) /*!< UART FIFO trigger level 0: 1 character */\r
+#define UART_FCR_TRG_LEV1 ((uint8_t)(1<<6)) /*!< UART FIFO trigger level 1: 4 character */\r
+#define UART_FCR_TRG_LEV2 ((uint8_t)(2<<6)) /*!< UART FIFO trigger level 2: 8 character */\r
+#define UART_FCR_TRG_LEV3 ((uint8_t)(3<<6)) /*!< UART FIFO trigger level 3: 14 character */\r
+#define UART_FCR_BITMASK ((uint8_t)(0xCF)) /*!< UART FIFO control bit mask */\r
+#define UART_TX_FIFO_SIZE (16)\r
+\r
+/* Macro defines for UART line control register */\r
+#define UART_LCR_WLEN5 ((uint8_t)(0)) /*!< UART 5 bit data mode */\r
+#define UART_LCR_WLEN6 ((uint8_t)(1<<0)) /*!< UART 6 bit data mode */\r
+#define UART_LCR_WLEN7 ((uint8_t)(2<<0)) /*!< UART 7 bit data mode */\r
+#define UART_LCR_WLEN8 ((uint8_t)(3<<0)) /*!< UART 8 bit data mode */\r
+#define UART_LCR_STOPBIT_SEL ((uint8_t)(1<<2)) /*!< UART Two Stop Bits Select */\r
+#define UART_LCR_PARITY_EN ((uint8_t)(1<<3)) /*!< UART Parity Enable */\r
+#define UART_LCR_PARITY_ODD ((uint8_t)(0)) /*!< UART Odd Parity Select */\r
+#define UART_LCR_PARITY_EVEN ((uint8_t)(1<<4)) /*!< UART Even Parity Select */\r
+#define UART_LCR_PARITY_F_1 ((uint8_t)(2<<4)) /*!< UART force 1 stick parity */\r
+#define UART_LCR_PARITY_F_0 ((uint8_t)(3<<4)) /*!< UART force 0 stick parity */\r
+#define UART_LCR_BREAK_EN ((uint8_t)(1<<6)) /*!< UART Transmission Break enable */\r
+#define UART_LCR_DLAB_EN ((uint8_t)(1<<7)) /*!< UART Divisor Latches Access bit enable */\r
+#define UART_LCR_BITMASK ((uint8_t)(0xFF)) /*!< UART line control bit mask */\r
+\r
+\r
+/* Macro defines for UART1 Modem Control Register */\r
+#define UART1_MCR_DTR_CTRL ((uint8_t)(1<<0)) /*!< Source for modem output pin DTR */\r
+#define UART1_MCR_RTS_CTRL ((uint8_t)(1<<1)) /*!< Source for modem output pin RTS */\r
+#define UART1_MCR_LOOPB_EN ((uint8_t)(1<<4)) /*!< Loop back mode select */\r
+#define UART1_MCR_AUTO_RTS_EN ((uint8_t)(1<<6)) /*!< Enable Auto RTS flow-control */\r
+#define UART1_MCR_AUTO_CTS_EN ((uint8_t)(1<<7)) /*!< Enable Auto CTS flow-control */\r
+#define UART1_MCR_BITMASK ((uint8_t)(0x0F3)) /*!< UART1 bit mask value */\r
+\r
+\r
+/* Macro defines for UART line status register */\r
+#define UART_LSR_RDR ((uint8_t)(1<<0)) /*!<Line status register: Receive data ready*/\r
+#define UART_LSR_OE ((uint8_t)(1<<1)) /*!<Line status register: Overrun error*/\r
+#define UART_LSR_PE ((uint8_t)(1<<2)) /*!<Line status register: Parity error*/\r
+#define UART_LSR_FE ((uint8_t)(1<<3)) /*!<Line status register: Framing error*/\r
+#define UART_LSR_BI ((uint8_t)(1<<4)) /*!<Line status register: Break interrupt*/\r
+#define UART_LSR_THRE ((uint8_t)(1<<5)) /*!<Line status register: Transmit holding register empty*/\r
+#define UART_LSR_TEMT ((uint8_t)(1<<6)) /*!<Line status register: Transmitter empty*/\r
+#define UART_LSR_RXFE ((uint8_t)(1<<7)) /*!<Error in RX FIFO*/\r
+#define UART_LSR_BITMASK ((uint8_t)(0xFF)) /*!<UART Line status bit mask */\r
+\r
+\r
+/* Macro defines for UART Modem (UART1 only) status register */\r
+#define UART1_MSR_DELTA_CTS ((uint8_t)(1<<0)) /*!< Set upon state change of input CTS */\r
+#define UART1_MSR_DELTA_DSR ((uint8_t)(1<<1)) /*!< Set upon state change of input DSR */\r
+#define UART1_MSR_LO2HI_RI ((uint8_t)(1<<2)) /*!< Set upon low to high transition of input RI */\r
+#define UART1_MSR_DELTA_DCD ((uint8_t)(1<<3)) /*!< Set upon state change of input DCD */\r
+#define UART1_MSR_CTS ((uint8_t)(1<<4)) /*!< Clear To Send State */\r
+#define UART1_MSR_DSR ((uint8_t)(1<<5)) /*!< Data Set Ready State */\r
+#define UART1_MSR_RI ((uint8_t)(1<<6)) /*!< Ring Indicator State */\r
+#define UART1_MSR_DCD ((uint8_t)(1<<7)) /*!< Data Carrier Detect State */\r
+#define UART1_MSR_BITMASK ((uint8_t)(0xFF)) /*!< MSR register bit-mask value */\r
+\r
+\r
+/* Macro defines for UART Scratch Pad Register */\r
+#define UART_SCR_BIMASK ((uint8_t)(0xFF)) /*!< UART Scratch Pad bit mask */\r
+\r
+/* Macro defines for UART Auto baudrate control register */\r
+#define UART_ACR_START ((uint32_t)(1<<0)) /**< UART Auto-baud start */\r
+#define UART_ACR_MODE ((uint32_t)(1<<1)) /**< UART Auto baudrate Mode 1 */\r
+#define UART_ACR_AUTO_RESTART ((uint32_t)(1<<2)) /**< UART Auto baudrate restart */\r
+#define UART_ACR_ABEOINT_CLR ((uint32_t)(1<<8)) /**< UART End of auto-baud interrupt clear */\r
+#define UART_ACR_ABTOINT_CLR ((uint32_t)(1<<9)) /**< UART Auto-baud time-out interrupt clear */\r
+#define UART_ACR_BITMASK ((uint32_t)(0x307)) /**< UART Auto Baudrate register bit mask */\r
+\r
+/* UART IrDA control register defines */\r
+#define UART_ICR_IRDAEN ((uint32_t)(1<<0)) /**< IrDA mode enable */\r
+#define UART_ICR_IRDAINV ((uint32_t)(1<<1)) /**< IrDA serial input inverted */\r
+#define UART_ICR_FIXPULSE_EN ((uint32_t)(1<<2)) /**< IrDA fixed pulse width mode */\r
+#define UART_ICR_PULSEDIV(n) ((uint32_t)((n&0x07)<<3)) /**< PulseDiv - Configures the pulse when FixPulseEn = 1 */\r
+#define UART_ICR_BITMASK ((uint32_t)(0x3F)) /*!< UART IRDA bit mask */\r
+\r
+/* Macro defines for UART Fractional divider register */\r
+#define UART_FDR_DIVADDVAL(n) ((uint32_t)(n&0x0F)) /**< Baud-rate generation pre-scaler divisor */\r
+#define UART_FDR_MULVAL(n) ((uint32_t)((n<<4)&0xF0)) /**< Baud-rate pre-scaler multiplier value */\r
+#define UART_FDR_BITMASK ((uint32_t)(0xFF)) /**< UART Fractional Divider register bit mask */\r
+\r
+/* Macro defines for UART Tx Enable register */\r
+#define UART_TER_TXEN ((uint8_t)(1<<7)) /*!< Transmit enable bit */\r
+#define UART_TER_BITMASK ((uint8_t)(0x80)) /**< UART Transmit Enable Register bit mask */\r
+\r
+\r
+/* Macro defines for UART1 RS485 Control register */\r
+#define UART1_RS485CTRL_NMM_EN ((uint32_t)(1<<0)) /*!< RS-485/EIA-485 Normal Multi-drop Mode (NMM)\r
+ is disabled */\r
+#define UART1_RS485CTRL_RX_DIS ((uint32_t)(1<<1)) /*!< The receiver is disabled */\r
+#define UART1_RS485CTRL_AADEN ((uint32_t)(1<<2)) /*!< Auto Address Detect (AAD) is enabled */\r
+#define UART1_RS485CTRL_SEL_DTR ((uint32_t)(1<<3)) /*!< If direction control is enabled\r
+ (bit DCTRL = 1), pin DTR is used for direction control */\r
+#define UART1_RS485CTRL_DCTRL_EN ((uint32_t)(1<<4)) /*!< Enable Auto Direction Control */\r
+#define UART1_RS485CTRL_OINV_1 ((uint32_t)(1<<5)) /*!< This bit reverses the polarity of the direction\r
+ control signal on the RTS (or DTR) pin. The direction control pin\r
+ will be driven to logic "1" when the transmitter has data to be sent */\r
+#define UART1_RS485CTRL_BITMASK ((uint32_t)(0x3F)) /**< RS485 control bit-mask value */\r
+\r
+\r
+/* Macro defines for UART1 RS-485 Address Match register */\r
+#define UART1_RS485ADRMATCH_BITMASK ((uint8_t)(0xFF)) /**< Bit mask value */\r
+\r
+/* Macro defines for UART1 RS-485 Delay value register */\r
+#define UART1_RS485DLY_BITMASK ((uint8_t)(0xFF)) /** Bit mask value */\r
+\r
+\r
+/* Macro defines for UART FIFO Level register */\r
+#define UART_FIFOLVL_RXFIFOLVL(n) ((uint32_t)(n&0x0F)) /**< Reflects the current level of the UART receiver FIFO */\r
+#define UART_FIFOLVL_TXFIFOLVL(n) ((uint32_t)((n>>8)&0x0F)) /**< Reflects the current level of the UART transmitter FIFO */\r
+#define UART_FIFOLVL_BITMASK ((uint32_t)(0x0F0F)) /**< UART FIFO Level Register bit mask */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Types --------------------------------------------------------------- */\r
+/** @defgroup UART_Public_Types\r
+ * @{\r
+ */\r
+\r
+\r
+/**\r
+ * @brief UART Databit type definitions\r
+ */\r
+typedef enum {\r
+ UART_DATABIT_5 = 0, /*!< UART 5 bit data mode */\r
+ UART_DATABIT_6, /*!< UART 6 bit data mode */\r
+ UART_DATABIT_7, /*!< UART 7 bit data mode */\r
+ UART_DATABIT_8 /*!< UART 8 bit data mode */\r
+} UART_DATABIT_Type;\r
+\r
+/** Macro to check the input UART_DATABIT parameters */\r
+#define PARAM_UART_DATABIT(databit) ((databit==UART_DATABIT_5) || (databit==UART_DATABIT_6)\\r
+|| (databit==UART_DATABIT_7) || (databit==UART_DATABIT_8))\r
+\r
+/**\r
+ * @brief UART Stop bit type definitions\r
+ */\r
+typedef enum {\r
+ UART_STOPBIT_1 = (0), /*!< UART 1 Stop Bits Select */\r
+ UART_STOPBIT_2, /*!< UART Two Stop Bits Select */\r
+} UART_STOPBIT_Type;\r
+\r
+/** Macro to check the input UART_STOPBIT parameters */\r
+#define PARAM_UART_STOPBIT(stopbit) ((stopbit==UART_STOPBIT_1) || (stopbit==UART_STOPBIT_2))\r
+\r
+/**\r
+ * @brief UART Parity type definitions\r
+ */\r
+typedef enum {\r
+ UART_PARITY_NONE = 0, /*!< No parity */\r
+ UART_PARITY_ODD, /*!< Odd parity */\r
+ UART_PARITY_EVEN, /*!< Even parity */\r
+ UART_PARITY_SP_1, /*!< Forced "1" stick parity */\r
+ UART_PARITY_SP_0 /*!< Forced "0" stick parity */\r
+} UART_PARITY_Type;\r
+\r
+/** Macro to check the input UART_PARITY parameters */\r
+#define PARAM_UART_PARITY(parity) ((parity==UART_PARITY_NONE) || (parity==UART_PARITY_ODD) \\r
+|| (parity==UART_PARITY_EVEN) || (parity==UART_PARITY_SP_1) \\r
+|| (parity==UART_PARITY_SP_0))\r
+\r
+/**\r
+ * @brief FIFO Level type definitions\r
+ */\r
+typedef enum {\r
+ UART_FIFO_TRGLEV0 = 0, /*!< UART FIFO trigger level 0: 1 character */\r
+ UART_FIFO_TRGLEV1, /*!< UART FIFO trigger level 1: 4 character */\r
+ UART_FIFO_TRGLEV2, /*!< UART FIFO trigger level 2: 8 character */\r
+ UART_FIFO_TRGLEV3 /*!< UART FIFO trigger level 3: 14 character */\r
+} UART_FITO_LEVEL_Type;\r
+\r
+/** Macro to check the input UART_FIFO parameters */\r
+#define PARAM_UART_FIFO_LEVEL(fifo) ((fifo==UART_FIFO_TRGLEV0) \\r
+|| (fifo==UART_FIFO_TRGLEV1) || (fifo==UART_FIFO_TRGLEV2) \\r
+|| (fifo==UART_FIFO_TRGLEV3))\r
+\r
+/********************************************************************//**\r
+* @brief UART Interrupt Type definitions\r
+**********************************************************************/\r
+typedef enum {\r
+ UART_INTCFG_RBR = 0, /*!< RBR Interrupt enable*/\r
+ UART_INTCFG_THRE, /*!< THR Interrupt enable*/\r
+ UART_INTCFG_RLS, /*!< RX line status interrupt enable*/\r
+ UART1_INTCFG_MS, /*!< Modem status interrupt enable (UART1 only) */\r
+ UART1_INTCFG_CTS, /*!< CTS1 signal transition interrupt enable (UART1 only) */\r
+ UART_INTCFG_ABEO, /*!< Enables the end of auto-baud interrupt */\r
+ UART_INTCFG_ABTO /*!< Enables the auto-baud time-out interrupt */\r
+} UART_INT_Type;\r
+\r
+/** Macro to check the input UART_INTCFG parameters */\r
+#define PARAM_UART_INTCFG(IntCfg) ((IntCfg==UART_INTCFG_RBR) || (IntCfg==UART_INTCFG_THRE) \\r
+|| (IntCfg==UART_INTCFG_RLS) || (IntCfg==UART_INTCFG_ABEO) \\r
+|| (IntCfg==UART_INTCFG_ABTO))\r
+\r
+/** Macro to check the input UART1_INTCFG parameters - expansion input parameter for UART1 */\r
+#define PARAM_UART1_INTCFG(IntCfg) ((IntCfg==UART1_INTCFG_MS) || (IntCfg==UART1_INTCFG_CTS))\r
+\r
+\r
+/**\r
+ * @brief UART Line Status Type definition\r
+ */\r
+typedef enum {\r
+ UART_LINESTAT_RDR = UART_LSR_RDR, /*!<Line status register: Receive data ready*/\r
+ UART_LINESTAT_OE = UART_LSR_OE, /*!<Line status register: Overrun error*/\r
+ UART_LINESTAT_PE = UART_LSR_PE, /*!<Line status register: Parity error*/\r
+ UART_LINESTAT_FE = UART_LSR_FE, /*!<Line status register: Framing error*/\r
+ UART_LINESTAT_BI = UART_LSR_BI, /*!<Line status register: Break interrupt*/\r
+ UART_LINESTAT_THRE = UART_LSR_THRE, /*!<Line status register: Transmit holding register empty*/\r
+ UART_LINESTAT_TEMT = UART_LSR_TEMT, /*!<Line status register: Transmitter empty*/\r
+ UART_LINESTAT_RXFE = UART_LSR_RXFE /*!<Error in RX FIFO*/\r
+} UART_LS_Type;\r
+\r
+\r
+/**\r
+ * @brief UART Auto-baudrate mode type definition\r
+ */\r
+typedef enum {\r
+ UART_AUTOBAUD_MODE0 = 0, /**< UART Auto baudrate Mode 0 */\r
+ UART_AUTOBAUD_MODE1, /**< UART Auto baudrate Mode 1 */\r
+} UART_AB_MODE_Type;\r
+\r
+/** Macro to check the input UART_AUTOBAUD_MODE parameters */\r
+#define PARAM_UART_AUTOBAUD_MODE(ABmode) ((ABmode==UART_AUTOBAUD_MODE0) || (ABmode==UART_AUTOBAUD_MODE1))\r
+\r
+/**\r
+ * @brief Auto Baudrate mode configuration type definition\r
+ */\r
+typedef struct {\r
+ UART_AB_MODE_Type ABMode; /**< Autobaudrate mode */\r
+ FunctionalState AutoRestart; /**< Auto Restart state */\r
+} UART_AB_CFG_Type;\r
+\r
+\r
+/**\r
+ * @brief UART End of Auto-baudrate type definition\r
+ */\r
+typedef enum {\r
+ UART_AUTOBAUD_INTSTAT_ABEO = UART_IIR_ABEO_INT, /**< UART End of auto-baud interrupt */\r
+ UART_AUTOBAUD_INTSTAT_ABTO = UART_IIR_ABTO_INT /**< UART Auto-baud time-out interrupt */\r
+}UART_ABEO_Type;\r
+\r
+/** Macro to check the input UART_AUTOBAUD_INTSTAT parameters */\r
+#define PARAM_UART_AUTOBAUD_INTSTAT(ABIntStat) ((ABIntStat==UART_AUTOBAUD_INTSTAT_ABEO) || (ABIntStat==UART_AUTOBAUD_INTSTAT_ABTO))\r
+\r
+/**\r
+ * UART IrDA Control type Definition\r
+ */\r
+typedef enum {\r
+ UART_IrDA_PULSEDIV2 = 0, /**< Pulse width = 2 * Tpclk\r
+ - Configures the pulse when FixPulseEn = 1 */\r
+ UART_IrDA_PULSEDIV4, /**< Pulse width = 4 * Tpclk\r
+ - Configures the pulse when FixPulseEn = 1 */\r
+ UART_IrDA_PULSEDIV8, /**< Pulse width = 8 * Tpclk\r
+ - Configures the pulse when FixPulseEn = 1 */\r
+ UART_IrDA_PULSEDIV16, /**< Pulse width = 16 * Tpclk\r
+ - Configures the pulse when FixPulseEn = 1 */\r
+ UART_IrDA_PULSEDIV32, /**< Pulse width = 32 * Tpclk\r
+ - Configures the pulse when FixPulseEn = 1 */\r
+ UART_IrDA_PULSEDIV64, /**< Pulse width = 64 * Tpclk\r
+ - Configures the pulse when FixPulseEn = 1 */\r
+ UART_IrDA_PULSEDIV128, /**< Pulse width = 128 * Tpclk\r
+ - Configures the pulse when FixPulseEn = 1 */\r
+ UART_IrDA_PULSEDIV256 /**< Pulse width = 256 * Tpclk\r
+ - Configures the pulse when FixPulseEn = 1 */\r
+} UART_IrDA_PULSE_Type;\r
+\r
+\r
+/** Macro to check the input UART_IrDA_PULSEDIV parameters */\r
+#define PARAM_UART_IrDA_PULSEDIV(PulseDiv) ((PulseDiv==UART_IrDA_PULSEDIV2) || (PulseDiv==UART_IrDA_PULSEDIV4) \\r
+|| (PulseDiv==UART_IrDA_PULSEDIV8) || (PulseDiv==UART_IrDA_PULSEDIV16) \\r
+|| (PulseDiv==UART_IrDA_PULSEDIV32) || (PulseDiv==UART_IrDA_PULSEDIV64) \\r
+|| (PulseDiv==UART_IrDA_PULSEDIV128) || (PulseDiv==UART_IrDA_PULSEDIV256))\r
+\r
+/********************************************************************//**\r
+* @brief UART1 Full modem - Signal states definition\r
+**********************************************************************/\r
+typedef enum {\r
+ INACTIVE = 0, /* In-active state */\r
+ ACTIVE = !INACTIVE /* Active state */\r
+}UART1_SignalState;\r
+\r
+/* Macro to check the input UART1_SignalState parameters */\r
+#define PARAM_UART1_SIGNALSTATE(x) ((x==INACTIVE) || (x==ACTIVE))\r
+\r
+/**\r
+ * @brief UART modem status type definition\r
+ */\r
+typedef enum {\r
+ UART1_MODEM_STAT_DELTA_CTS = UART1_MSR_DELTA_CTS, /*!< Set upon state change of input CTS */\r
+ UART1_MODEM_STAT_DELTA_DSR = UART1_MSR_DELTA_DSR, /*!< Set upon state change of input DSR */\r
+ UART1_MODEM_STAT_LO2HI_RI = UART1_MSR_LO2HI_RI, /*!< Set upon low to high transition of input RI */\r
+ UART1_MODEM_STAT_DELTA_DCD = UART1_MSR_DELTA_DCD, /*!< Set upon state change of input DCD */\r
+ UART1_MODEM_STAT_CTS = UART1_MSR_CTS, /*!< Clear To Send State */\r
+ UART1_MODEM_STAT_DSR = UART1_MSR_DSR, /*!< Data Set Ready State */\r
+ UART1_MODEM_STAT_RI = UART1_MSR_RI, /*!< Ring Indicator State */\r
+ UART1_MODEM_STAT_DCD = UART1_MSR_DCD /*!< Data Carrier Detect State */\r
+} UART_MODEM_STAT_type;\r
+\r
+/**\r
+ * @brief Modem output pin type definition\r
+ */\r
+typedef enum {\r
+ UART1_MODEM_PIN_DTR = 0, /*!< Source for modem output pin DTR */\r
+ UART1_MODEM_PIN_RTS /*!< Source for modem output pin RTS */\r
+} UART_MODEM_PIN_Type;\r
+\r
+/** Macro to check the input PARAM_UART1_MODEM_PIN parameters */\r
+#define PARAM_UART1_MODEM_PIN(x) ((x==UART1_MODEM_PIN_DTR) || (x==UART1_MODEM_PIN_RTS))\r
+\r
+\r
+/**\r
+ * @brief UART Modem mode type definition\r
+ */\r
+typedef enum {\r
+ UART1_MODEM_MODE_LOOPBACK = 0, /*!< Loop back mode select */\r
+ UART1_MODEM_MODE_AUTO_RTS, /*!< Enable Auto RTS flow-control */\r
+ UART1_MODEM_MODE_AUTO_CTS /*!< Enable Auto CTS flow-control */\r
+} UART_MODEM_MODE_Type;\r
+\r
+/** Macro to check the input PARAM_UART1_MODEM_MODE parameters */\r
+#define PARAM_UART1_MODEM_MODE(x) ((x==UART1_MODEM_MODE_LOOPBACK) || (x==UART1_MODEM_MODE_AUTO_RTS) \\r
+|| (x==UART1_MODEM_MODE_AUTO_CTS))\r
+\r
+\r
+/**\r
+ * @brief UART Direction Control Pin type definition\r
+ */\r
+typedef enum {\r
+ UART1_RS485_DIRCTRL_RTS = 0, /**< Pin RTS is used for direction control */\r
+ UART1_RS485_DIRCTRL_DTR /**< Pin DTR is used for direction control */\r
+} UART_RS485_DIRCTRL_PIN_Type;\r
+\r
+/** Macro to check the direction control pin type */\r
+#define PARAM_UART_RS485_DIRCTRL_PIN(x) ((x==UART1_RS485_DIRCTRL_RTS) || (x==UART1_RS485_DIRCTRL_DTR))\r
+\r
+\r
+/********************************************************************//**\r
+* @brief UART Configuration Structure definition\r
+**********************************************************************/\r
+typedef struct {\r
+ uint32_t Baud_rate; /**< UART baud rate */\r
+ UART_PARITY_Type Parity; /**< Parity selection, should be:\r
+ - UART_PARITY_NONE: No parity\r
+ - UART_PARITY_ODD: Odd parity\r
+ - UART_PARITY_EVEN: Even parity\r
+ - UART_PARITY_SP_1: Forced "1" stick parity\r
+ - UART_PARITY_SP_0: Forced "0" stick parity\r
+ */\r
+ UART_DATABIT_Type Databits; /**< Number of data bits, should be:\r
+ - UART_DATABIT_5: UART 5 bit data mode\r
+ - UART_DATABIT_6: UART 6 bit data mode\r
+ - UART_DATABIT_7: UART 7 bit data mode\r
+ - UART_DATABIT_8: UART 8 bit data mode\r
+ */\r
+ UART_STOPBIT_Type Stopbits; /**< Number of stop bits, should be:\r
+ - UART_STOPBIT_1: UART 1 Stop Bits Select\r
+ - UART_STOPBIT_2: UART 2 Stop Bits Select\r
+ */\r
+} UART_CFG_Type;\r
+\r
+/********************************************************************//**\r
+* @brief UART FIFO Configuration Structure definition\r
+**********************************************************************/\r
+\r
+typedef struct {\r
+ FunctionalState FIFO_ResetRxBuf; /**< Reset Rx FIFO command state , should be:\r
+ - ENABLE: Reset Rx FIFO in UART\r
+ - DISABLE: Do not reset Rx FIFO in UART\r
+ */\r
+ FunctionalState FIFO_ResetTxBuf; /**< Reset Tx FIFO command state , should be:\r
+ - ENABLE: Reset Tx FIFO in UART\r
+ - DISABLE: Do not reset Tx FIFO in UART\r
+ */\r
+ FunctionalState FIFO_DMAMode; /**< DMA mode, should be:\r
+ - ENABLE: Enable DMA mode in UART\r
+ - DISABLE: Disable DMA mode in UART\r
+ */\r
+ UART_FITO_LEVEL_Type FIFO_Level; /**< Rx FIFO trigger level, should be:\r
+ - UART_FIFO_TRGLEV0: UART FIFO trigger level 0: 1 character\r
+ - UART_FIFO_TRGLEV1: UART FIFO trigger level 1: 4 character\r
+ - UART_FIFO_TRGLEV2: UART FIFO trigger level 2: 8 character\r
+ - UART_FIFO_TRGLEV3: UART FIFO trigger level 3: 14 character\r
+ */\r
+} UART_FIFO_CFG_Type;\r
+\r
+\r
+/********************************************************************//**\r
+* @brief UART1 Full modem - RS485 Control configuration type\r
+**********************************************************************/\r
+typedef struct {\r
+ FunctionalState NormalMultiDropMode_State; /*!< Normal MultiDrop mode State:\r
+ - ENABLE: Enable this function.\r
+ - DISABLE: Disable this function. */\r
+ FunctionalState Rx_State; /*!< Receiver State:\r
+ - ENABLE: Enable Receiver.\r
+ - DISABLE: Disable Receiver. */\r
+ FunctionalState AutoAddrDetect_State; /*!< Auto Address Detect mode state:\r
+ - ENABLE: ENABLE this function.\r
+ - DISABLE: Disable this function. */\r
+ FunctionalState AutoDirCtrl_State; /*!< Auto Direction Control State:\r
+ - ENABLE: Enable this function.\r
+ - DISABLE: Disable this function. */\r
+ UART_RS485_DIRCTRL_PIN_Type DirCtrlPin; /*!< If direction control is enabled, state:\r
+ - UART1_RS485_DIRCTRL_RTS:\r
+ pin RTS is used for direction control.\r
+ - UART1_RS485_DIRCTRL_DTR:\r
+ pin DTR is used for direction control. */\r
+ SetState DirCtrlPol_Level; /*!< Polarity of the direction control signal on\r
+ the RTS (or DTR) pin:\r
+ - RESET: The direction control pin will be driven\r
+ to logic "0" when the transmitter has data to be sent.\r
+ - SET: The direction control pin will be driven\r
+ to logic "1" when the transmitter has data to be sent. */\r
+ uint8_t MatchAddrValue; /*!< address match value for RS-485/EIA-485 mode, 8-bit long */\r
+ uint8_t DelayValue; /*!< delay time is in periods of the baud clock, 8-bit long */\r
+} UART1_RS485_CTRLCFG_Type;\r
+\r
+\r
+/* UART call-back function type definitions */\r
+/** UART Receive Call-back function type */\r
+typedef void (fnRxCbs_Type)(void);\r
+/** UART Transmit Call-back function type */\r
+typedef void (fnTxCbs_Type)(void);\r
+/** UART Auto-Baudrate Call-back function type */\r
+typedef void (fnABCbs_Type)(uint32_t bABIntType);\r
+/** UART Error Call-back function type */\r
+typedef void (fnErrCbs_Type)(uint8_t bError);\r
+/** UART1 modem status interrupt callback type */\r
+typedef void (fnModemCbs_Type)(uint8_t ModemStatus);\r
+\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Macros -------------------------------------------------------------- */\r
+/** @defgroup UART_Public_Macros\r
+ * @{\r
+ */\r
+\r
+\r
+/* Macro to determine if it is valid UART port number */\r
+#define PARAM_UARTx(x) ((((uint32_t *)x)==((uint32_t *)LPC_UART0)) \\r
+|| (((uint32_t *)x)==((uint32_t *)LPC_UART1)) \\r
+|| (((uint32_t *)x)==((uint32_t *)LPC_UART2)) \\r
+|| (((uint32_t *)x)==((uint32_t *)LPC_UART3)))\r
+#define PARAM_UART_IrDA(x) (((uint32_t *)x)==((uint32_t *)LPC_UART3))\r
+#define PARAM_UART1_MODEM(x) (((uint32_t *)x)==((uint32_t *)LPC_UART1))\r
+\r
+\r
+/** Macro to check the input value for UART1_RS485_CFG_MATCHADDRVALUE parameter */\r
+#define PARAM_UART1_RS485_CFG_MATCHADDRVALUE(x) ((x<0xFF))\r
+\r
+/** Macro to check the input value for UART1_RS485_CFG_DELAYVALUE parameter */\r
+#define PARAM_UART1_RS485_CFG_DELAYVALUE(x) ((x<0xFF))\r
+\r
+\r
+/** UART time-out definitions in case of using Read() and Write function\r
+ * with Blocking Flag mode\r
+ */\r
+\r
+#define UART_BLOCKING_TIMEOUT (0xFFFFFFFFUL)\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+/* Public Functions ----------------------------------------------------------- */\r
+/** @defgroup UART_Public_Functions\r
+ * @{\r
+ */\r
+\r
+void UART_DeInit(LPC_UART_TypeDef* UARTx);\r
+void UART_Init(LPC_UART_TypeDef *UARTx, UART_CFG_Type *UART_ConfigStruct);\r
+void UART_ConfigStructInit(UART_CFG_Type *UART_InitStruct);\r
+void UART_SendData(LPC_UART_TypeDef* UARTx, uint8_t Data);\r
+uint8_t UART_ReceiveData(LPC_UART_TypeDef* UARTx);\r
+void UART_ForceBreak(LPC_UART_TypeDef* UARTx);\r
+void UART_IrDAInvtInputCmd(LPC_UART_TypeDef* UARTx, FunctionalState NewState);\r
+void UART_IrDACmd(LPC_UART_TypeDef* UARTx, FunctionalState NewState);\r
+void UART_IrDAPulseDivConfig(LPC_UART_TypeDef *UARTx, UART_IrDA_PULSE_Type PulseDiv);\r
+void UART_IntConfig(LPC_UART_TypeDef *UARTx, UART_INT_Type UARTIntCfg, \\r
+ FunctionalState NewState);\r
+uint8_t UART_GetLineStatus(LPC_UART_TypeDef* UARTx);\r
+FlagStatus UART_CheckBusy(LPC_UART_TypeDef *UARTx);\r
+void UART_FIFOConfig(LPC_UART_TypeDef *UARTx, UART_FIFO_CFG_Type *FIFOCfg);\r
+void UART_FIFOConfigStructInit(UART_FIFO_CFG_Type *UART_FIFOInitStruct);\r
+void UART_ABCmd(LPC_UART_TypeDef *UARTx, UART_AB_CFG_Type *ABConfigStruct, \\r
+ FunctionalState NewState);\r
+void UART_TxCmd(LPC_UART_TypeDef *UARTx, FunctionalState NewState);\r
+void UART_FullModemForcePinState(LPC_UART1_TypeDef *UARTx, UART_MODEM_PIN_Type Pin, \\r
+ UART1_SignalState NewState);\r
+void UART_FullModemConfigMode(LPC_UART1_TypeDef *UARTx, UART_MODEM_MODE_Type Mode, \\r
+ FunctionalState NewState);\r
+uint8_t UART_FullModemGetStatus(LPC_UART1_TypeDef *UARTx);\r
+void UART_RS485Config(LPC_UART1_TypeDef *UARTx, \\r
+ UART1_RS485_CTRLCFG_Type *RS485ConfigStruct);\r
+void UART_RS485ReceiverCmd(LPC_UART1_TypeDef *UARTx, FunctionalState NewState);\r
+void UART_RS485SendSlvAddr(LPC_UART1_TypeDef *UARTx, uint8_t SlvAddr);\r
+uint32_t UART_RS485SendData(LPC_UART1_TypeDef *UARTx, uint8_t *pData, uint32_t size);\r
+uint32_t UART_Send(LPC_UART_TypeDef *UARTx, uint8_t *txbuf,\r
+ uint32_t buflen, TRANSFER_BLOCK_Type flag);\r
+uint32_t UART_Receive(LPC_UART_TypeDef *UARTx, uint8_t *rxbuf, \\r
+ uint32_t buflen, TRANSFER_BLOCK_Type flag);\r
+void UART_SetupCbs(LPC_UART_TypeDef *UARTx, uint8_t CbType, void *pfnCbs);\r
+void UART0_StdIntHandler(void);\r
+void UART1_StdIntHandler(void);\r
+void UART2_StdIntHandler(void);\r
+void UART3_StdIntHandler(void);\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+\r
+#endif /* __LPC17XX_UART_H */\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* --------------------------------- End Of File ------------------------------ */\r
--- /dev/null
+=====================================================================
+ UARTドライバ (asp-1.6.0対応)
+ Last Modified: 2010/Oct/11
+=====================================================================
+
+○概要
+
+16450互換UART用ドライバである。LPC17xx用に開発したが、互換性を考慮している
+ので、移植性は高いはずである。
+
+このドライバは内蔵UARTだけを使うシステムを想定している。そのため、
+target_serial.hからuart.hを読み込むだけでビルドできる。
+
+○コンパイラ
+
+GCC 4.4.1 で動作確認を行った.動作確認した GCC 4.4.1 は,以下のサイトから
+バイナリパッケージをダウンロードして用いた.
+
+ http://www.codesourcery.com/gnu_toolchains/arm/download.html
+
+
+○各種設定の変更
+
+SIO_PORTID
+ 1から始まるTOPPERSのシリアルポート番号。コンソールに使うポート番号を
+ 指定する。target_syssvc.hで宣言する。
+
+TNUM_PORT
+ 1から始まる数字で、TOPPERS/ASPの管理下に置かれるUARTの個数を指定する。
+ target_syssvc.hで宣言する。
+
+SIO_BAUD_RATE_DEFAULT
+ SIOポート1で使用されるボーレート。target_syssvc.hで宣言する。
+ SIOx_BAUD_RATEを宣言しない場合、他のSIOポートでもこの値を使用する。
+
+SIO2_BAUD_RATE
+ SIOポート2で使用されるボーレート。target_syssvc.hで宣言する。
+ 宣言しない場合はSIO_BAUD_RATE_DEFAULTが使われる。他のポートでも同様
+ である。
+
+SIO_UART_CLOCK
+ 内蔵UARTブロックに入力されるクロック周波数をヘルツで指定する。DLL/DLMが
+ 分周するクロックはこの信号である。すべてのSIOポートが同じ信号を使用すると
+ 仮定している。
+
+uart_write, uart_read
+ 整数で与えられるベースアドレスとレジスタ・オフセットを使ってレジスタに
+ 読み書きするための補助関数。チップ依存部やターゲット依存部ごとにuart.cの
+ 中で用意する。
+
+UART_BOUNDARY
+ 1,2,4のいずれか。UARTレジスタの間隔を指定する。バイト・アドレスのシステム
+ ならば1、CORTEX-M3のような32bitシステムではたいてい4である。
+ UART_BOUNDARYはuart.cの中でしか使わないので、uart.cで宣言する。
+ 変更する場合には、チップ依存部、あるいはターゲット依存部識別マクロによる
+ 条件コンパイルを追加する。
+
+INTNO_SIO, INHNO_SIO
+ コンソールに使用するシリアルポート(PORTID)が使用する割り込みハンドラ番号、
+ 割り込み番号を指定する。これはtarget_serial.cfgで使用する。
+
+sioreg_table
+ シリアルポートのベースアドレスを納めた配列。配列の0番にシリアルポート1の
+ ベースアドレスを格納する。uart.cで定義する。
+
+○変更履歴
+
+2010/Oct/11
+ 初版
\ No newline at end of file
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ * Copyright (C) 2010 by TOPPERS/ASP for LPC project
+ * http://sourceforge.jp/projects/toppersasp4lpc/
+ *
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/**
+ * \file uart.c
+ * \ingroup TOPPERS_SIO
+ * \brief ターゲット依存のシリアル・ペリフェラル制御ルーチン群
+ * \details
+ * ターゲット依存のシリアル・ペリフェラル制御ルーチン群。TOPPERS/ASPのシリアル
+ * ・タスクの下請けとして働く。詳細に関してはporting.txtを参照のこと。
+ *
+ */
+
+/*
+ * シリアルドライバ(UART汎用)
+ */
+
+#include <kernel.h>
+#include <sil.h>
+#include "uart.h"
+#include "target_syssvc.h"
+
+/*
+ * レジスタ設定値
+ */
+
+/**
+ * \brief SIOPCBのインデックスからポートID番号への変換
+ * \details
+ * TOPPERS/ASPのSIOポートID番号は1オリジンだが、 siopcb_table[]は
+ * 0オリジンである。そのため、変換関数を使って与えられたインデックス番号から
+ * ポートID番号を作り出す。
+ *
+ */
+#define INDEX2SIOPID(x) ((x) + 1)
+
+/**
+ * \brief ポート番号からSIOPCBのインデックスへの変換
+ * \details
+ * TOPPERS/ASPのSIOポートID番号は1オリジンだが、 siopcb_table[]は
+ * 0オリジンである。そのため、変換関数を使って与えられたポートID番号から
+ * PCBを取得するためのインデックスを作り出す。
+ */
+#define SIOPID2INDEX(x) ((x) - 1)
+
+/**
+ * \brief ポートID番号からSIOPCBを取得する
+ * \details
+ * ポートID番号を元に、SIOPCBへのポインタを取得する。
+ */
+#define GET_SIOPCB(x) (&siopcb_table[SIOPID2INDEX(x)])
+
+/**
+ * \brief ペリフェラル・レジスタの間隔
+ * \details
+ * ペリフェラルレジスタが何バイトごとに現れるかを記述する。この
+ * 記述はチップごとに変わる。
+ */
+#ifdef TOPPERS_CHIP_LPC17XX
+#define UART_BOUNDARY 4
+#else
+#error "You must define UART_BOUNDARY for your architecture"
+#endif
+
+/**
+ * \brief 8250, 16450, 16550各レジスタのアドレス・オフセット。
+ * \details
+ * UART_RHRを基点とする。
+ * システムごとに異なるのでUART_BOUNDARYによってレジスタの配置境界を指定する。
+ * たとえばすべてのレジスタが8ビット境界で配置されているなら、UART_BOUNDARYは1,
+ * 16bit境界なら2, 32ビット境界なら4を指定する。
+ * UART_BOUNDARYはsys_config.hで定義する。
+ */
+
+#define UART_RBR (0x00 * UART_BOUNDARY) /* 受信バッファレジスタ */
+#define UART_THR (0x00 * UART_BOUNDARY) /* 送信データ・ホールド・レジスタ */
+#define UART_DLL (0x00 * UART_BOUNDARY) /* 分周レジスタ下位バイト */
+#define UART_IER (0x01 * UART_BOUNDARY) /* 割込みイネーブルレジスタ */
+#define UART_DLM (0x01 * UART_BOUNDARY) /* 分周レジスタ上位バイト */
+#define UART_IIR (0x02 * UART_BOUNDARY) /* 割込み識別レジスタ */
+#define UART_FCR (0x02 * UART_BOUNDARY) /* FIFO制御レジスタ */
+#define UART_LCR (0x03 * UART_BOUNDARY) /* ライン制御レジスタ */
+#define UART_MCR (0x04 * UART_BOUNDARY) /* モデム制御レジスタ */
+#define UART_LSR (0x05 * UART_BOUNDARY) /* ライン・ステータス・レジスタ */
+#define UART_MSR (0x06 * UART_BOUNDARY) /* モデム・ステータス・レジスタ */
+#define UART_SCR (0x07 * UART_BOUNDARY) /* スクラッチ・パッド・レジスタ */
+#define UART_GCTL (0x09 * UART_BOUNDARY) /* Blackfinのみ。グローバル制御レジスタ */
+
+#define ISR_TX 0x02 /* 送信割り込み発生 */
+#define IER_TX 0x02 /* 送信割り込み許可 */
+#define ISR_RX 0x01 /* 受信割り込み発生 */
+#define IER_RX 0x01 /* 受信割り込み許可 */
+
+#define LCR_DLAB 0x80 /* Divisor Enable */
+#define LCR_NP_8_1 0x03 /* 8bit,1stop,Noparity,No break */
+#define FCR_FIFO_DISABLE 0x00
+
+#define LSR_RX_DATA_READY 0x01
+#define LSR_TX_EMPTY 0x20
+
+#define MCR_INT_ENABLE 0x08
+
+/* ディバイザ計算マクロ */
+#define DLM(divisor) (divisor/256)
+#define DLL(divisor) (divisor%256)
+
+
+/**
+ * \brief シリアルI/Oポート管理ブロックエリア
+ */
+SIOPCB siopcb_table[TNUM_PORT];
+
+/**
+ * \brief 各シリアル・ペリフェラルのレジスタのベースアドレス。
+ * \details
+ * この変数は初期化関数 sio_initialize()の中で参照され、
+ * レジスタアドレスは siopcb_table[]のしかるべきメンバー変数に
+ * 代入される。
+ */
+
+#ifdef TOPPERS_CHIP_LPC17XX
+static const uint32_t sioreg_table[TNUM_PORT] = {
+ LPC_UART0_BASE
+#if (TNUM_PORT >= 2)
+ ,LPC_UART1_BASE
+#endif
+#if (TNUM_PORT >= 3)
+ ,LPC_UART2_BASE
+#endif
+#if (TNUM_PORT >= 4)
+ ,LPC_UART3_BASE
+#endif
+};
+#else
+#error "You must define sioreg_table[]"
+#endif
+
+/**
+ * \ingroup SIOSUPPORT
+ * \brief シリアルポート・ペリフェラル書き込み関数
+ * \param addr UARTペリフェラルのベースアドレス。通常はTHRのアドレスである。
+ * \param offset ベースアドレスに対する、オフセット値。単位はバイト。
+ * \param val レジスタに書き込む値。
+ * \details
+ * ベースアドレスとオフセットを整数で受け取り、ペリフェラルレジスタに
+ * アクセスする。
+ */
+Inline void
+uart_write(uint32_t addr, uint32_t offset, uint8_t val)
+{
+#ifdef TOPPERS_CHIP_LPC17XX
+ sil_wrb_mem((void *)(addr + offset),val);
+#else
+#error "You must define access method for your architecture"
+#endif
+}
+
+/**
+ * \ingroup SIOSUPPORT
+ * \brief シリアルポート・ペリフェラル読み込み関数
+ * \param addr UARTペリフェラルのベースアドレス。通常はTHRのアドレスである。
+ * \param offset ベースアドレスに対する、オフセット値。単位はバイト。
+ * \return レジスタから読み込んだ値。
+ * \details
+ * ベースアドレスとオフセットを整数で受け取り、ペリフェラルレジスタに
+ * アクセスする。
+ */
+Inline uint8_t
+uart_read(uint32_t addr, uint32_t offset)
+{
+#ifdef TOPPERS_CHIP_LPC17XX
+ return(sil_reb_mem((void *)(addr + offset)));
+#else
+#error "You must define access method for your architecture"
+#endif
+}
+
+/**
+ * \ingroup TOPPERS_SIO
+ * \defgroup SIOAPI シリアル・サービス・タスク用API
+ * \details
+ * シリアル・サービス・タスクから呼び出される関数群。シリアル・サービス・タスクはこれらの
+ * 関数を使ってペリフェラルを制御する。詳細はporting.txtの8.3節を参照。
+ * \{
+ */
+
+
+/**
+ * \brief シリアル・ポートが送信可能か調べる
+ * \param siopcb SIOを指し示すポート・コントロール・ブロックへのポインタ
+ * \return 送信可能であれば真、不能であれば偽を返す
+ * \details
+ * siopcbが指し示すシリアル・ペリフェラルを調べ、送信可能なら真を返す。
+ *
+ * 送信可能か否かの判断には、送信割り込みが許可されているかどうかも含まれる。イネーブルかつ送信レジスタに空きがあるなら
+ * 送信可能である。送信の可否に割り込み許可状態を含めるのは、送信割り込み禁止状態で送信コールバックを呼ぶことを防ぐため
+ * である。
+ *
+ * sio_putready()関数は sio_isr()関数から送信可能かどうかをチェックするために呼ばれる。もし、可能であれば sio_isr()は
+ * シリアル制御サービスの sio_irdy_snd()コールバック関数を呼び出してしまう。コールバック禁止状態でこの関数を呼ばない
+ * ようにするには、割り込み許可状態の確認が不可欠である。割り込み許可状態の設定に関しては sio_ena_cbr()関数と
+ * sio_dis_cbr()関数を参照のこと。
+ */
+Inline bool_t sio_putready(SIOPCB* siopcb)
+{
+
+ uint32_t reg = siopcb->reg_base; /* UARTのベースアドレスを取得 */
+
+ /* THRが空ならば送信可能なので真を返す */
+ return (uart_read( reg, UART_LSR ) & LSR_TX_EMPTY);
+}
+
+/**
+ * \brief シリアル・ポートに受信データがあるか調べる
+ * \param siopcb SIOを指し示すポート・コントロール・ブロックへのポインタ
+ * \return 送信受信データがあれば真、なければ偽を返す
+ * \details
+ * siopcbが指し示すシリアル・ペリフェラルを調べ、受信データがあるなら真を返す。
+ *
+ * 受信可能か否かの判断には、受信割り込みが許可されているかどうかも含まれる。イネーブルかつ受信レジスタに受信データがあるなら
+ * 受信可能である。受信の可否に割り込み許可状態を含めるのは、受信割り込み禁止状態で受信コールバックを呼ぶことを防ぐため
+ * である。
+ *
+ * sio_getready()関数は sio_isr() 関数から受信可能かどうかをチェックするために呼ばれる。もし、可能であれば sio_isr()は
+ * シリアル制御サービスの sio_irdy_rcv()コールバック関数を呼び出してしまう。コールバック禁止状態でこの関数を呼ばない
+ * ようにするには、割り込み許可状態の確認が不可欠である。割り込み許可状態の設定に関しては sio_ena_cbr()関数と
+ * sio_dis_cbr()関数を参照のこと。
+ */
+Inline bool_t sio_getready(SIOPCB* siopcb)
+{
+ uint32_t reg = siopcb->reg_base; /* UARTのベースアドレスを取得 */
+
+ /* RBRがいっぱいならば受信可能なので真を返す */
+ return (uart_read( reg, UART_LSR ) & LSR_RX_DATA_READY);
+}
+
+/**
+ * \}
+ */
+
+/**
+ * \ingroup TOPPERS_SIO
+ * \defgroup SIOSUPPORT SIOサポート関数群
+ * \{
+ */
+
+/**
+ * \brief ターゲットのシリアル初期化
+ * \param siopid SIOのポートID
+ * \details
+ * siopidで指定されるターゲットのSIOペリフェラルを初期化する。初期化するのは、ストップビットやビット数といった
+ * プロトコルのほか、ボーレートも含む。この館数は、target_initialize() 関数からも呼び出され、バナー出力用の
+ * ポート初期化に使用される。
+ *
+ * ボーレートの設定にはUARTへ供給されるクロック周波数の設定が必要であるが、これは全UARTで共通であると
+ * 仮定して決めうちしている。周波数はSIO_UART_CLOCKで指定する。単位はHzである。また、ボーレートは
+ *
+ * SIO_BAUD_RATE_DEFAULTに設定されるが、上書きしたければSIOx_BAUD_RATEを宣言する。単位はBAUDである。
+ */
+void target_uart_init(ID siopid)
+{
+ uint32_t reg = sioreg_table[SIOPID2INDEX(siopid)]; /* 使用するUARTのベースアドレスを取得 */
+
+ /* UARTの無効化 */
+ uart_write( reg, UART_LCR, 0 ); /* DLAB モードをいったんクリアする */
+ uart_write( reg, UART_FCR, 0 ); /* FIFO クリア*/
+ uart_write( reg, UART_IER, 0 ); /* 割り込みをディセーブルにする */
+
+ /* ボーレートの設定 */
+ uart_write( reg, UART_LCR, LCR_DLAB ); /* ディバイザ設定モードに移行 */
+
+ switch (siopid) {
+ case 1:
+#if defined(SIO_BAUD_RATE_PORT1)
+ uart_write( reg, UART_DLL, DLL((SIO_UART_CLOCK/SIO_BAUD_RATE_PORT1/16)) );
+ uart_write( reg, UART_DLM, DLM((SIO_UART_CLOCK/SIO_BAUD_RATE_PORT1/16)) );
+#else
+ uart_write( reg, UART_DLL, DLL((SIO_UART_CLOCK/SIO_BAUD_RATE_DEFAULT/16)) );
+ uart_write( reg, UART_DLM, DLM((SIO_UART_CLOCK/SIO_BAUD_RATE_DEFAULT/16)) );
+#endif
+ break;
+ case 2:
+#if defined(SIO_BAUD_RATE_PORT2)
+ uart_write( reg, UART_DLL, DLL((SIO_UART_CLOCK/SIO_BAUD_RATE_PORT2/16)) );
+ uart_write( reg, UART_DLM, DLM((SIO_UART_CLOCK/SIO_BAUD_RATE_PORT2/16)) );
+#else
+ uart_write( reg, UART_DLL, DLL((SIO_UART_CLOCK/SIO_BAUD_RATE_DEFAULT/16)) );
+ uart_write( reg, UART_DLM, DLM((SIO_UART_CLOCK/SIO_BAUD_RATE_DEFAULT/16)) );
+#endif
+ break;
+ case 3:
+#if defined(SIO_BAUD_RATE_PORT3)
+ uart_write( reg, UART_DLL, DLL((SIO_UART_CLOCK/SIO_BAUD_RATE_PORT3/16)) );
+ uart_write( reg, UART_DLM, DLM((SIO_UART_CLOCK/SIO_BAUD_RATE_PORT3/16)) );
+#else
+ uart_write( reg, UART_DLL, DLL((SIO_UART_CLOCK/SIO_BAUD_RATE_DEFAULT/16)) );
+ uart_write( reg, UART_DLM, DLM((SIO_UART_CLOCK/SIO_BAUD_RATE_DEFAULT/16)) );
+#endif
+ break;
+ case 4:
+#if defined(SIO_BAUD_RATE_PORT4)
+ uart_write( reg, UART_DLL, DLL((SIO_UART_CLOCK/SIO_BAUD_RATE_PORT4/16)) );
+ uart_write( reg, UART_DLM, DLM((SIO_UART_CLOCK/SIO_BAUD_RATE_PORT4/16)) );
+#else
+ uart_write( reg, UART_DLL, DLL((SIO_UART_CLOCK/SIO_BAUD_RATE_DEFAULT/16)) );
+ uart_write( reg, UART_DLM, DLM((SIO_UART_CLOCK/SIO_BAUD_RATE_DEFAULT/16)) );
+#endif
+ break;
+ }
+
+ /* デバイザ設定モードから、通常モードに戻す */
+ uart_write( reg, UART_LCR, 0 ); /* 通常モードに移行 */
+
+ /* プロトコルを設定。8bit, 1stop bit, parityなし */
+ uart_write( reg, UART_LCR, LCR_NP_8_1 ); /* 通常モードに移行 */
+
+}
+
+/**
+ * \brief ターゲットのシリアル終了
+ * \param siopid 終了するポートの番号
+ * \details
+ * 指定したポートをディセーブルする。
+ *
+ */
+void target_uart_term(ID siopid)
+{
+ uint32_t reg = sioreg_table[SIOPID2INDEX(siopid)];
+
+ /* UARTの無効化 */
+ uart_write( reg, UART_IER, 0 ); /* 割り込みをディセーブルにする */
+}
+
+/**
+ * \}
+ */
+
+/**
+ * \ingroup SIOAPI
+ * \brief SIO初期化
+ * \param exinf ATTINI静的APIが渡す引数
+ * \details
+ * porting.txtにはtarget_serial.cfgにこの関数を初期化ルーチンとして
+ * 登録する静的APIを含めることになっている( ASP 1.3.2 )。
+ *
+ * この関数はシリアル・ポート・サービス・タスク用に内部変数を初期化するだけであり、
+ * デバイスの初期化は行っていない。デバイスの初期化はsio_opn_porが呼ばれたときに毎回行われる。
+ */
+void sio_initialize(intptr_t exinf)
+{
+ int i;
+
+ for (i = 0; i < TNUM_PORT; i++)
+ {
+ siopcb_table[i].peripheral_index = i;
+ siopcb_table[i].reg_base = sioreg_table[i];
+ siopcb_table[i].exinf = 0;
+ }
+}
+
+/**
+ * \ingroup SIOAPI
+ * \brief シリアル・オープン
+ * \param siopid SIOを識別する番号。1から TNUM_PORTまでの整数
+ * \param exinf 拡張情報。コールバックを呼ぶときに引数として渡す
+ * \details
+ * シリアル・ペリフェラルを初期化する。ペリフェラルはプロトコル、スピードなどの
+ * 設定を終え、割り込み禁止状態で待機する。この関数に続いて sio_ena_cbrが
+ * 呼び出される。
+ *
+ * 引数extinfで渡される情報を処理する必要はない。この引数はそのまま
+ * sio_irdy_sndおよび sio_irdy_rcvコールバックに渡される。
+ *
+ * プロトコルは8bit, 1stopbit, parityなしに決めうちしていい。
+ */
+SIOPCB *sio_opn_por(ID siopid, intptr_t exinf)
+{
+ SIOPCB* siopcb;
+
+ if (siopid > TNUM_PORT) {
+ return NULL;
+ }
+
+ siopcb = GET_SIOPCB(siopid);
+ siopcb->exinf = exinf;
+
+ target_uart_init(siopid);
+
+ return siopcb;
+}
+
+/**
+ * \ingroup SIOAPI
+ * \brief シリアルクローズ
+ * \param p_siopcb ポート識別用PCBへのポインタ
+ * \details
+ * ターゲットのポートを閉じる。ポートはディセーブルされ、割り込みは起きない。
+ */
+void sio_cls_por(SIOPCB *p_siopcb)
+{
+ target_uart_term(INDEX2SIOPID(p_siopcb->peripheral_index));
+}
+
+/**
+ * \ingroup SIOAPI
+ * \brief 割込みサービスルーチン
+ * \param exinf 拡張
+ * \details
+ * porting.txtの8.3節で養成されている割り込みサービスルーチン。
+ * このルーチンはextinfの情報を元にどの割り込みが発生したか自動判別
+ * している。
+ *
+ * extinfにどのような情報を与えるかは、明言されていないように思える。
+ * CORTEX-M3版ではポート番号(1から始まってTNUM_PORTまでの識別
+ * 番号)がtarget_erial.cfgの中でATTISRのextinf引数として与えられている。
+ */
+void sio_isr(intptr_t exinf)
+{
+ SIOPCB* siopcb = GET_SIOPCB(exinf);
+ int32_t reg = siopcb->reg_base;
+ /* 送信コールバック可能でかつ送信可能なら、送信コールバックを呼ぶ */
+ if (sio_putready(siopcb) && ( uart_read(reg, UART_IER) & IER_TX)) {
+ sio_irdy_snd(siopcb->exinf);
+ }
+ /* 受信コールバック可能でかつ受信可能なら、受信コールバックを呼ぶ */
+ if (sio_getready(siopcb) && ( uart_read(reg, UART_IER) & IER_RX)) {
+ sio_irdy_rcv(siopcb->exinf);
+ }
+}
+
+/**
+ * \ingroup SIOAPI
+ * \brief 1文字送信
+ * \param siopcb 送信するSIOポート
+ * \param c 送信する文字
+ * \return 送信に成功したら真、失敗したら偽
+ * \details
+ * シリアル制御タスクから呼び出されて1文字送信する関数。送信できた時には真を、できなかったときには偽を返す。
+ * 送信の成否は実際の出力ではなく、送信レジスタへ書き込めたかどうかで判断してよい。この場合、送信レジスタが
+ * いっぱいであれば、送信できなかったことになる
+ */
+bool_t sio_snd_chr(SIOPCB *siopcb, char_t c)
+{
+ uint32_t reg = siopcb->reg_base; /* UARTのベースアドレスを取得 */
+
+ if (sio_putready(siopcb)) {
+ uart_write( reg, UART_THR, c);
+
+ return true;
+ }
+ else
+ return false;
+}
+
+/**
+ * \ingroup SIOAPI
+ * \brief 1文字受信
+ * \param siopcb 受信するSIOポート
+ * \return 受信した文字 受信した文字を+0から+255までの正の値として返す。何も受信していないときには-1を返す。
+ * \details
+ * シリアル制御タスクから呼び出されて1文字受信する関数。何も受信していない時には、-1を返す。受信した文字は0から255までの正の数として返す。
+ */
+int_t sio_rcv_chr(SIOPCB *siopcb)
+{
+
+ int_t c = -1;
+ uint32_t reg = siopcb->reg_base; /* UARTのベースアドレスを取得 */
+
+ if (sio_getready(siopcb)) {
+ c = uart_read( reg, UART_RBR ) & 0xFF;
+ }
+
+ return c;
+}
+
+/**
+ * \ingroup SIOAPI
+ * \brief コールバックの許可
+ * \param siopcb コールバックを許可するSIOポート
+ * \param cbrtn SIO_RDY_SND あるいは SIO_RDY_RCV
+ * \details
+ * シリアル制御タスクのコールバック関数の呼び出しを許可する関数。 cbrtn 引数を使って送信と受信のいずれの側で許可するかを
+ * 指定する。
+ *
+ * この関数はTOPPERS/ASPのシリアル制御タスクの中から呼び出される。コールバックの許可にはペリフェラルの割り込み許可機能を使う。
+ */
+void sio_ena_cbr(SIOPCB *siopcb, uint_t cbrtn)
+{
+ uint32_t reg = siopcb->reg_base; /* UARTのベースアドレスを取得 */
+
+ switch (cbrtn) {
+ case SIO_RDY_SND:
+ uart_write( reg, UART_IER, uart_read(reg, UART_IER) | IER_TX ); /* 送信割り込みを許可 */
+ break;
+ case SIO_RDY_RCV:
+ uart_write( reg, UART_IER, uart_read(reg, UART_IER) | IER_RX ); /* 受信割り込みを許可 */
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * \ingroup SIOAPI
+ * \brief コールバックの禁止
+ * \param siopcb コールバックを禁止するSIOポート
+ * \param cbrtn SIO_RDY_SND あるいは SIO_RDY_RCV
+ * \details
+ * シリアル制御タスクのコールバック関数の呼び出しを禁止する関数。 cbrtn 引数を使って送信と受信のいずれの側で禁止するかを
+ * 指定する。
+ *
+ * この関数はTOPPERS/ASPのシリアル制御タスクの中から呼び出される。コールバックの禁止にはペリフェラルの割り込み禁止機能を使う。
+ */
+void sio_dis_cbr(SIOPCB *siopcb, uint_t cbrtn)
+{
+ uint32_t reg = siopcb->reg_base; /* UARTのベースアドレスを取得 */
+
+ switch (cbrtn) {
+ case SIO_RDY_SND:
+ uart_write( reg, UART_IER, uart_read(reg, UART_IER) & ~IER_TX ); /* 送信割り込みを禁止 */
+ break;
+ case SIO_RDY_RCV:
+ uart_write( reg, UART_IER, uart_read(reg, UART_IER) & ~IER_RX ); /* 受信割り込みを禁止 */
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * \brief 1文字出力(ポーリングでの出力)
+ * \ingroup SIOSUPPORT
+ * \param c 出力する文字
+ * \param siopid 出力するポートのID
+ * \details
+ * 出力ポートにポーリングで一文字出力する。これはTOPPERS/ASPで割り込みが有効になる前に使用する関数である。
+ * ポーリングを使うので通常タスクが使ってはいけない。
+ */
+void sio_pol_snd_chr(char_t c, ID siopid)
+{
+ uint32_t reg = sioreg_table[SIOPID2INDEX(siopid)]; /* 使用するUARTのベースアドレスを取得 */
+
+ uart_write( reg, UART_THR, c);
+
+ while ((uart_read( reg, UART_LSR ) & LSR_TX_EMPTY) == 0)
+ ;
+}
+
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ * Copyright (C) 2010 by TOPPERS/ASP for LPC project
+ * http://sourceforge.jp/projects/toppersasp4lpc/
+ *
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/**
+ * \defgroup TOPPERS_SIO SIOドライバ
+ * \ingroup TOPPERS_ASP
+ */
+/* \{ */
+/**
+ * \file uart.h
+ * \brief シリアルI/Oデバイス(SIO)ドライバ(UART汎用)
+ */
+
+#ifndef TOPPERS_UART_H
+#define TOPPERS_UART_H
+
+#include "kernel.h"
+
+/*
+ * SIOの割込みベクタ番号
+ */
+#if (SIO_PORTID == 1)
+#define INHNO_SIO INHNO_UART0
+#define INTNO_SIO INHNO_UART0
+#elif (SIO_PORTID == 2)
+#define INHNO_SIO INHNO_UART1
+#define INTNO_SIO INHNO_UART1
+#elif (SIO_PORTID == 3)
+#define INHNO_SIO INHNO_UART2
+#define INTNO_SIO INHNO_UART2
+#elif (SIO_PORTID == 4)
+#define INHNO_SIO INHNO_UART3
+#define INTNO_SIO INHNO_UART3
+#endif
+
+#define INTPRI_SIO -3 /* 割込み優先度 */
+#define INTATR_SIO 0 /* 割込み属性 */
+
+/**
+ * \ingroup SIOAPI
+ * \brief コールバックルーチンの識別番号
+ * \details
+ * porting.txt で要請されている識別番号の宣言。 SIO_RDY_RCVと区別できる
+ * 番号なら何でもいい。
+ */
+#define SIO_RDY_SND 1U /* 送信可能コールバック */
+/**
+ * \ingroup SIOAPI
+ * \brief コールバックルーチンの識別番号
+ * \details
+ * porting.txt で要請されている識別番号の宣言。 SIO_RDY_SNDと区別できる
+ * 番号なら何でもいい。
+ */
+#define SIO_RDY_RCV 2U /* 受信通知コールバック */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/**
+ * \ingroup SIOAPI
+ * \brief シリアルポートの管理ブロック
+ * \details
+ * porting.txtの8.3節で要請されている管理ブロックデータ型。
+ * シリアル・サービス・タスクとSIOペリフェラルAPIの間での管理データの
+ * やりとりに使われる。
+ */
+typedef struct sio_port_control_block {
+ ID peripheral_index; /**< ペリフェラル番号。0オリジン */
+ uint32_t reg_base; /**< SIOペリフェラルのレジスタ・ベース・アドレス */
+ intptr_t exinf; /**< sio_opn_porが渡すexinf引数の格納場所。 */
+} SIOPCB;
+
+/*
+ * SIO初期化
+ */
+extern void sio_initialize(intptr_t exinf);
+
+/*
+ * シリアルオープン
+ */
+extern SIOPCB *sio_opn_por(ID siopid, intptr_t exinf);
+
+/*
+ * シリアルクローズ
+ */
+extern void sio_cls_por(SIOPCB *p_siopcb);
+
+/*
+ * 割込みハンドラ
+ */
+extern void sio_isr(intptr_t exinf);
+
+/*
+ * 1文字送信
+ */
+extern bool_t sio_snd_chr(SIOPCB *siopcb, char_t c);
+
+/*
+ * 1文字受信
+ */
+extern int_t sio_rcv_chr(SIOPCB *siopcb);
+
+/*
+ * コールバックの許可
+ */
+extern void sio_ena_cbr(SIOPCB *siopcb, uint_t cbrtn);
+
+/*
+ * コールバックの禁止
+ */
+extern void sio_dis_cbr(SIOPCB *siopcb, uint_t cbrtn);
+
+/*
+ * 送信可能コールバック
+ */
+extern void sio_irdy_snd(intptr_t exinf);
+
+/*
+ * 受信通知コールバック
+ */
+extern void sio_irdy_rcv(intptr_t exinf);
+
+/*
+ * 1文字送信(ポーリングでの出力)
+ */
+extern void sio_pol_snd_chr(char_t c, ID siopid);
+
+/*
+ * ターゲットのシリアル初期化
+ */
+extern void target_uart_init(ID siopid);
+
+#endif /* TOPPERS_MACRO_ONLY */
+#endif /* TOPPERS_TARGET_SERIAL_H */
+/* \} */
--- /dev/null
+PACKAGE asp
+
+MANIFEST
+upd72001.c
+upd72001.h
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2006-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: upd72001.c 873 2008-04-11 10:32:26Z hiro $
+ */
+
+/*
+ * μPD72001用 簡易SIOドライバ
+ */
+
+#include <sil.h>
+#include "target_syssvc.h"
+#include "upd72001.h"
+
+/*
+ * デバイスレジスタのアクセス間隔時間(nsec単位)
+ *
+ * 200という値にあまり根拠はない.
+ */
+#define UPD72001_DELAY 200U
+
+/*
+ * μPD72001のレジスタの番号
+ */
+#define UPD72001_CR0 0x00U /* コントロールレジスタ */
+#define UPD72001_CR1 0x01U
+#define UPD72001_CR2 0x02U
+#define UPD72001_CR3 0x03U
+#define UPD72001_CR4 0x04U
+#define UPD72001_CR5 0x05U
+#define UPD72001_CR10 0x0aU
+#define UPD72001_CR12 0x0cU
+#define UPD72001_CR14 0x0eU
+#define UPD72001_CR15 0x0fU
+
+#define UPD72001_SR0 0x00U /* ステータスレジスタ */
+
+/*
+ * コントロールレジスタの設定値
+ */
+#define CR_RESET 0x18U /* ポートリセットコマンド */
+
+#define CR0_EOI 0x38U /* EOI(End of Interrupt)*/
+
+#define CR1_DOWN 0x00U /* 全割込みを禁止 */
+#define CR1_RECV 0x10U /* 受信割込み許可ビット */
+#define CR1_SEND 0x02U /* 送信割込み許可ビット */
+
+#define CR3_DEF 0xc1U /* データ 8bit,受信イネーブル */
+#define CR4_DEF 0x44U /* ストップビット 1bit,パリティなし */
+#define CR5_DEF 0xeaU /* データ 8bit,送信イネーブル */
+
+#define CR10_DEF 0x00U /* NRZ */
+#define CR14_DEF 0x07U /* ボーレートジェネレータイネーブル */
+#define CR15_DEF 0x56U /* ボーレートジェネレータ使用 */
+
+#define SR0_RECV 0x01U /* 受信通知ビット */
+#define SR0_SEND 0x04U /* 送信可能ビット */
+
+/*
+ * シリアルI/Oポート初期化ブロックの定義
+ */
+typedef struct sio_port_initialization_block {
+ void *data; /* データレジスタの番地 */
+ void *ctrl; /* コントロールレジスタの番地 */
+
+ uint8_t cr3_def; /* CR3の設定値(受信ビット数)*/
+ uint8_t cr4_def; /* CR4の設定値(ストップビット,パリティ)*/
+ uint8_t cr5_def; /* CR5の設定値(送信ビット数)*/
+ uint8_t brg1_def; /* ボーレート上位の設定値 */
+ uint8_t brg2_def; /* ボーレート下位の設定値 */
+} SIOPINIB;
+
+/*
+ * シリアルI/Oポート管理ブロックの定義
+ */
+struct sio_port_control_block {
+ const SIOPINIB *p_siopinib; /* シリアルI/Oポート初期化ブロック */
+ intptr_t exinf; /* 拡張情報 */
+ bool_t openflag; /* オープン済みフラグ */
+ uint8_t cr1; /* CR1の設定値(割込み許可)*/
+ bool_t getready; /* 文字を受信した状態 */
+ bool_t putready; /* 文字を送信できる状態 */
+};
+
+/*
+ * シリアルI/Oポート初期化ブロック
+ */
+const SIOPINIB siopinib_table[TNUM_SIOP] = {
+ { (void *) TADR_UPD72001_DATAA, (void *) TADR_UPD72001_CTRLA,
+ CR3_DEF, CR4_DEF, CR5_DEF, BRG1_DEF, BRG2_DEF },
+ { (void *) TADR_UPD72001_DATAB, (void *) TADR_UPD72001_CTRLB,
+ CR3_DEF, CR4_DEF, CR5_DEF, BRG1_DEF, BRG2_DEF }
+};
+
+/*
+ * シリアルI/Oポート管理ブロックのエリア
+ */
+SIOPCB siopcb_table[TNUM_SIOP];
+
+/*
+ * シリアルI/OポートIDから管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_SIOP(siopid) ((uint_t)((siopid) - 1))
+#define get_siopcb(siopid) (&(siopcb_table[INDEX_SIOP(siopid)]))
+
+/*
+ * デバイスレジスタへのアクセス関数
+ */
+Inline uint8_t
+upd72001_read_reg(void *addr)
+{
+ uint8_t val;
+
+ val = upd72001_reb_reg(addr);
+ sil_dly_nse(UPD72001_DELAY);
+ return(val);
+}
+
+Inline void
+upd72001_write_reg(void *addr, uint8_t val)
+{
+ upd72001_wrb_reg(addr, val);
+ sil_dly_nse(UPD72001_DELAY);
+}
+
+Inline uint8_t
+upd72001_read_ctrl(void *addr, uint8_t reg)
+{
+ upd72001_write_reg(addr, reg);
+ return(upd72001_read_reg(addr));
+}
+
+Inline void
+upd72001_write_ctrl(void *addr, uint8_t reg, uint8_t val)
+{
+ upd72001_write_reg(addr, reg);
+ upd72001_write_reg(addr, val);
+}
+
+Inline void
+upd72001_write_brg(void *addr, uint8_t reg, uint8_t val,
+ uint8_t brg2, uint8_t brg1)
+{
+ upd72001_write_reg(addr, reg);
+ upd72001_write_reg(addr, val);
+ upd72001_write_reg(addr, brg2);
+ upd72001_write_reg(addr, brg1);
+ (void) upd72001_read_reg(addr); /* ダミーリード */
+}
+
+/*
+ * 状態の読出し(SR0の読出し)
+ *
+ * μPD72001は,状態(SR0)を一度読むと受信通知ビットが落ちてしまうた
+ * め,状態を読み出す関数を設け,シリアルI/Oポート管理ブロック中の
+ * getreadyに受信通知状態,putreadyに送信可能状態を保存している(送信
+ * 可能状態の保存は不要かもしれない).
+ * 状態レジスタを読んでも受信通知ビットが落ちないデバイス(こちらが普
+ * 通と思われる)では,この関数は必要ない.
+ */
+static void
+upd72001_get_stat(SIOPCB *p_siopcb)
+{
+ uint8_t sr0;
+
+ sr0 = upd72001_read_ctrl(p_siopcb->p_siopinib->ctrl, UPD72001_SR0);
+ if ((sr0 & SR0_RECV) != 0) {
+ p_siopcb->getready = true;
+ }
+ if ((sr0 & SR0_SEND) != 0) {
+ p_siopcb->putready = true;
+ }
+}
+
+/*
+ * 文字を受信できるか?
+ */
+Inline bool_t
+upd72001_getready(SIOPCB *p_siopcb)
+{
+ upd72001_get_stat(p_siopcb);
+ return(p_siopcb->getready);
+}
+
+/*
+ * 文字を送信できるか?
+ */
+Inline bool_t
+upd72001_putready(SIOPCB *p_siopcb)
+{
+ upd72001_get_stat(p_siopcb);
+ return(p_siopcb->putready);
+}
+
+/*
+ * 受信した文字の取出し
+ */
+Inline char_t
+upd72001_getchar(SIOPCB *p_siopcb)
+{
+ p_siopcb->getready = false;
+ return((char_t) upd72001_read_reg(p_siopcb->p_siopinib->data));
+}
+
+/*
+ * 送信する文字の書込み
+ */
+Inline void
+upd72001_putchar(SIOPCB *p_siopcb, char_t c)
+{
+ p_siopcb->putready = false;
+ upd72001_write_reg(p_siopcb->p_siopinib->data, (uint8_t) c);
+}
+
+/*
+ * EOI(End Of Interrupt)発行
+ */
+Inline void
+upd72001_eoi(void)
+{
+ upd72001_write_ctrl((void *) TADR_UPD72001_CTRLA, UPD72001_CR0, CR0_EOI);
+}
+
+/*
+ * SIOドライバの初期化
+ */
+void
+upd72001_initialize(void)
+{
+ SIOPCB *p_siopcb;
+ uint_t i;
+
+ /*
+ * シリアルI/Oポート管理ブロックの初期化
+ */
+ for (p_siopcb = siopcb_table, i = 0; i < TNUM_SIOP; p_siopcb++, i++) {
+ p_siopcb->p_siopinib = &(siopinib_table[i]);
+ p_siopcb->openflag = false;
+ }
+}
+
+/*
+ * オープンしているポートがあるか?
+ */
+bool_t
+upd72001_openflag(void)
+{
+ return(siopcb_table[0].openflag || siopcb_table[1].openflag);
+}
+
+/*
+ * シリアルI/Oポートのオープン
+ */
+SIOPCB *
+upd72001_opn_por(ID siopid, intptr_t exinf)
+{
+ SIOPCB *p_siopcb;
+ const SIOPINIB *p_siopinib;
+
+ p_siopcb = get_siopcb(siopid);
+ p_siopinib = p_siopcb->p_siopinib;
+
+ upd72001_write_reg(p_siopinib->ctrl, CR_RESET);
+ if (!upd72001_openflag()) {
+ upd72001_write_ctrl((void *) TADR_UPD72001_CTRLA, UPD72001_CR2, 0x18);
+ upd72001_write_ctrl((void *) TADR_UPD72001_CTRLB, UPD72001_CR2, 0x00);
+ }
+ p_siopcb->cr1 = CR1_DOWN;
+ upd72001_write_ctrl(p_siopinib->ctrl, UPD72001_CR1, p_siopcb->cr1);
+ upd72001_write_ctrl(p_siopinib->ctrl, UPD72001_CR4, p_siopinib->cr4_def);
+ upd72001_write_brg(p_siopinib->ctrl, UPD72001_CR12, 0x01U,
+ p_siopinib->brg2_def, p_siopinib->brg1_def);
+ upd72001_write_brg(p_siopinib->ctrl, UPD72001_CR12, 0x02U,
+ p_siopinib->brg2_def, p_siopinib->brg1_def);
+ upd72001_write_ctrl(p_siopinib->ctrl, UPD72001_CR15, CR15_DEF);
+ upd72001_write_ctrl(p_siopinib->ctrl, UPD72001_CR14, CR14_DEF);
+ upd72001_write_ctrl(p_siopinib->ctrl, UPD72001_CR10, CR10_DEF);
+ upd72001_write_ctrl(p_siopinib->ctrl, UPD72001_CR3, p_siopinib->cr3_def);
+ upd72001_write_ctrl(p_siopinib->ctrl, UPD72001_CR5, p_siopinib->cr5_def);
+ p_siopcb->exinf = exinf;
+ p_siopcb->getready = p_siopcb->putready = false;
+ p_siopcb->openflag = true;
+ return(p_siopcb);
+}
+
+/*
+ * シリアルI/Oポートのクローズ
+ */
+void
+upd72001_cls_por(SIOPCB *p_siopcb)
+{
+ upd72001_write_ctrl(p_siopcb->p_siopinib->ctrl, UPD72001_CR1, CR1_DOWN);
+ p_siopcb->openflag = false;
+}
+
+/*
+ * シリアルI/Oポートへの文字送信
+ */
+bool_t
+upd72001_snd_chr(SIOPCB *p_siopcb, char_t c)
+{
+ if (upd72001_putready(p_siopcb)) {
+ upd72001_putchar(p_siopcb, c);
+ return(true);
+ }
+ return(false);
+}
+
+/*
+ * シリアルI/Oポートからの文字受信
+ */
+int_t
+upd72001_rcv_chr(SIOPCB *p_siopcb)
+{
+ if (upd72001_getready(p_siopcb)) {
+ return((int_t)(uint8_t) upd72001_getchar(p_siopcb));
+ }
+ return(-1);
+}
+
+/*
+ * シリアルI/Oポートからのコールバックの許可
+ */
+void
+upd72001_ena_cbr(SIOPCB *p_siopcb, uint_t cbrtn)
+{
+ uint8_t cr1_bit = 0;
+
+ switch (cbrtn) {
+ case SIO_RDY_SND:
+ cr1_bit = CR1_SEND;
+ break;
+ case SIO_RDY_RCV:
+ cr1_bit = CR1_RECV;
+ break;
+ }
+ p_siopcb->cr1 |= cr1_bit;
+ upd72001_write_ctrl(p_siopcb->p_siopinib->ctrl,
+ UPD72001_CR1, p_siopcb->cr1);
+}
+
+/*
+ * シリアルI/Oポートからのコールバックの禁止
+ */
+void
+upd72001_dis_cbr(SIOPCB *p_siopcb, uint_t cbrtn)
+{
+ uint8_t cr1_bit = 0;
+
+ switch (cbrtn) {
+ case SIO_RDY_SND:
+ cr1_bit = CR1_SEND;
+ break;
+ case SIO_RDY_RCV:
+ cr1_bit = CR1_RECV;
+ break;
+ }
+ p_siopcb->cr1 &= ~cr1_bit;
+ upd72001_write_ctrl(p_siopcb->p_siopinib->ctrl,
+ UPD72001_CR1, p_siopcb->cr1);
+}
+
+/*
+ * シリアルI/Oポートに対する割込み処理
+ */
+static void
+upd72001_isr_siop(SIOPCB *p_siopcb)
+{
+ if ((p_siopcb->cr1 & CR1_RECV) != 0U && upd72001_getready(p_siopcb)) {
+ /*
+ * 受信通知コールバックルーチンを呼び出す.
+ */
+ upd72001_irdy_rcv(p_siopcb->exinf);
+ }
+ if ((p_siopcb->cr1 & CR1_SEND) != 0U && upd72001_putready(p_siopcb)) {
+ /*
+ * 送信可能コールバックルーチンを呼び出す.
+ */
+ upd72001_irdy_snd(p_siopcb->exinf);
+ }
+}
+
+/*
+ * SIOの割込みサービスルーチン
+ */
+void
+upd72001_isr(void)
+{
+ if (siopcb_table[0].openflag) {
+ upd72001_isr_siop(&(siopcb_table[0]));
+ }
+ if (siopcb_table[1].openflag) {
+ upd72001_isr_siop(&(siopcb_table[1]));
+ }
+ upd72001_eoi();
+}
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2006-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: upd72001.h 873 2008-04-11 10:32:26Z hiro $
+ */
+
+/*
+ * μPD72001用 簡易SIOドライバ
+ */
+
+#ifndef TOPPERS_UPD72001_H
+#define TOPPERS_UPD72001_H
+
+/*
+ * シリアルI/Oポート数の定義
+ */
+#define TNUM_SIOP 2 /* サポートするシリアルI/Oポートの数 */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ * シリアルI/Oポート管理ブロックの定義
+ */
+typedef struct sio_port_control_block SIOPCB;
+
+/*
+ * コールバックルーチンの識別番号
+ */
+#define SIO_RDY_SND 1U /* 送信可能コールバック */
+#define SIO_RDY_RCV 2U /* 受信通知コールバック */
+
+/*
+ * SIOドライバの初期化ルーチン
+ */
+extern void upd72001_initialize(void);
+
+/*
+ * オープンしているポートがあるか?
+ */
+extern bool_t upd72001_openflag(void);
+
+/*
+ * シリアルI/Oポートのオープン
+ */
+extern SIOPCB *upd72001_opn_por(ID siopid, intptr_t exinf);
+
+/*
+ * シリアルI/Oポートのクローズ
+ */
+extern void upd72001_cls_por(SIOPCB *siopcb);
+
+/*
+ * シリアルI/Oポートへの文字送信
+ */
+extern bool_t upd72001_snd_chr(SIOPCB *siopcb, char_t c);
+
+/*
+ * シリアルI/Oポートからの文字受信
+ */
+extern int_t upd72001_rcv_chr(SIOPCB *siopcb);
+
+/*
+ * シリアルI/Oポートからのコールバックの許可
+ */
+extern void upd72001_ena_cbr(SIOPCB *siopcb, uint_t cbrtn);
+
+/*
+ * シリアルI/Oポートからのコールバックの禁止
+ */
+extern void upd72001_dis_cbr(SIOPCB *siopcb, uint_t cbrtn);
+
+/*
+ * SIOの割込みサービスルーチン
+ */
+extern void upd72001_isr(void);
+
+/*
+ * シリアルI/Oポートからの送信可能コールバック
+ */
+extern void upd72001_irdy_snd(intptr_t exinf);
+
+/*
+ * シリアルI/Oポートからの受信通知コールバック
+ */
+extern void upd72001_irdy_rcv(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
+#endif /* TOPPERS_UPD72001_H */
--- /dev/null
+#
+# TOPPERS/ASP Kernel
+# Toyohashi Open Platform for Embedded Real-Time Systems/
+# Advanced Standard Profile Kernel
+#
+# Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+# Toyohashi Univ. of Technology, JAPAN
+# Copyright (C) 2006-2010 by Embedded and Real-Time Systems Laboratory
+# Graduate School of Information Science, Nagoya Univ., JAPAN
+#
+# 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+# スコード中に含まれていること.
+# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+# の無保証規定を掲載すること.
+# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+# と.
+# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+# 作権表示,この利用条件および下記の無保証規定を掲載すること.
+# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+# 報告すること.
+# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+# 免責すること.
+#
+# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+# の責任を負わない.
+#
+# @(#) $Id: Makefile 1786 2010-05-16 20:27:00Z ertl-hiro $
+#
+
+#
+# ターゲットの指定(Makefile.targetで上書きされるのを防ぐため)
+#
+all:
+
+#
+# ターゲット略称の定義
+#
+TARGET = @(TARGET)
+
+#
+# プログラミング言語の定義
+#
+SRCLANG = @(SRCLANG)
+ifeq ($(SRCLANG),c++)
+ USE_CXX = true
+ CXXLIBS = -lstdc++ -lm -lc
+ CXXRTS = cxxrt.o newlibrt.o
+endif
+
+#
+# ソースファイルのディレクトリの定義
+#
+SRCDIR = @(SRCDIR)
+
+#
+# オブジェクトファイル名の拡張子の設定
+#
+OBJEXT = @(OBJEXT)
+
+#
+# 実行環境の定義(ターゲット依存に上書きされる場合がある)
+#
+DBGENV := @(DBGENV)
+
+#
+# カーネルライブラリ(libkernel.a)のディレクトリ名
+# (カーネルライブラリもmake対象にする時は,空に定義する)
+#
+KERNEL_LIB = @(KERNEL_LIB)
+
+#
+# カーネルを関数単位でコンパイルするかどうかの定義
+#
+KERNEL_FUNCOBJS = @(KERNEL_FUNCOBJS)
+
+#
+# トレースログを取得するかどうかの定義
+#
+ENABLE_TRACE = @(ENABLE_TRACE)
+
+#
+# ユーティリティプログラムの名称
+#
+PERL = @(PERL)
+CFG = @(CFG)
+
+#
+# オブジェクトファイル名の定義
+#
+OBJNAME = asp
+ifdef OBJEXT
+ OBJFILE = $(OBJNAME).$(OBJEXT)
+ CFG1_OUT = cfg1_out.$(OBJEXT)
+else
+ OBJFILE = $(OBJNAME)
+ CFG1_OUT = cfg1_out
+endif
+
+#
+# ターゲット依存部のディレクトリの定義
+#
+TARGETDIR = $(SRCDIR)/target/$(TARGET)
+
+#
+# ターゲット依存の定義のインクルード
+#
+include $(TARGETDIR)/Makefile.target
+
+#
+# コンフィギュレータ関係の変数の定義
+#
+CFG_TABS := --api-table $(SRCDIR)/kernel/kernel_api.csv \
+ --cfg1-def-table $(SRCDIR)/kernel/kernel_def.csv $(CFG_TABS)
+CFG_OBJS := kernel_cfg.o $(CFG_OBJS)
+CFG2_OUT := kernel_cfg.c kernel_cfg.h $(CFG2_OUT)
+
+#
+# 共通コンパイルオプションの定義
+#
+COPTS := $(COPTS) -g
+ifndef OMIT_WARNING_ALL
+ COPTS := $(COPTS) -Wall
+endif
+ifndef OMIT_OPTIMIZATION
+ COPTS := $(COPTS) -O2
+endif
+CDEFS := $(CDEFS)
+INCLUDES := -I. -I$(SRCDIR)/include -I$(SRCDIR)/arch -I$(SRCDIR) $(INCLUDES)
+LDFLAGS := $(LDFLAGS)
+LIBS := $(LIBS) $(CXXLIBS)
+CFLAGS = $(COPTS) $(CDEFS) $(INCLUDES)
+
+#
+# アプリケーションプログラムに関する定義
+#
+APPLNAME = @(APPLNAME)
+APPLDIR = @(APPLDIR)
+APPL_CFG = $(APPLNAME).cfg
+
+APPL_DIR = $(APPLDIR) $(SRCDIR)/library
+APPL_ASMOBJS =
+ifdef USE_CXX
+ APPL_CXXOBJS = $(APPLNAME).o @(APPLOBJS)
+ APPL_COBJS =
+else
+ APPL_COBJS = $(APPLNAME).o @(APPLOBJS)
+endif
+APPL_CFLAGS =
+APPL_LIBS =
+ifdef APPLDIR
+ INCLUDES := $(INCLUDES) $(foreach dir,$(APPLDIR),-I$(dir))
+endif
+
+#
+# システムサービスに関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR) $(SRCDIR)/syssvc $(SRCDIR)/library
+SYSSVC_ASMOBJS := $(SYSSVC_ASMOBJS)
+SYSSVC_COBJS := $(SYSSVC_COBJS) banner.o syslog.o serial.o logtask.o \
+ log_output.o vasyslog.o t_perror.o strerror.o \
+ $(CXXRTS)
+SYSSVC_CFLAGS := $(SYSSVC_CFLAGS)
+SYSSVC_LIBS := $(SYSSVC_LIBS)
+INCLUDES := $(INCLUDES)
+
+#
+# カーネルに関する定義
+#
+# KERNEL_ASMOBJS: カーネルライブラリに含める,ソースがアセンブリ言語の
+# オブジェクトファイル.
+# KERNEL_COBJS: カーネルのライブラリに含める,ソースがC言語で,ソース
+# ファイルと1対1に対応するオブジェクトファイル.
+# KERNEL_LCSRCS: カーネルのライブラリに含めるC言語のソースファイルで,
+# 1つのソースファイルから複数のオブジェクトファイルを生
+# 成するもの.
+# KERNEL_LCOBJS: 上のソースファイルから生成されるオブジェクトファイル.
+# KERNEL_AUX_COBJS: ロードモジュールに含めないが,カーネルのソースファ
+# イルと同じオプションを適用してコンパイルすべき,ソー
+# スがC言語のオブジェクトファイル.
+#
+KERNEL_DIR := $(KERNEL_DIR) $(SRCDIR)/kernel
+KERNEL_ASMOBJS := $(KERNEL_ASMOBJS)
+KERNEL_COBJS := $(KERNEL_COBJS)
+KERNEL_CFLAGS := $(KERNEL_CFLAGS) -I$(SRCDIR)/kernel
+ifdef OMIT_MAKEOFFSET
+ OFFSET_H =
+ KERNEL_AUX_COBJS =
+else
+ OFFSET_H = offset.h
+ KERNEL_AUX_COBJS = makeoffset.o
+endif
+
+#
+# ターゲットファイル(複数を同時に選択してはならない)
+#
+all: $(OBJFILE)
+#all: $(OBJNAME).bin
+#all: $(OBJNAME).srec
+
+##### 以下は編集しないこと #####
+
+#
+# 環境に依存するコンパイルオプションの定義
+#
+ifdef DBGENV
+ CDEFS := $(CDEFS) -D$(DBGENV)
+endif
+
+#
+# カーネルライブラリに関連する定義
+#
+ifdef KERNEL_LIB
+ LIBKERNEL = $(KERNEL_LIB)/libkernel.a
+else
+ LIBKERNEL = libkernel.a
+endif
+
+#
+# カーネルのファイル構成の定義
+#
+include $(SRCDIR)/kernel/Makefile.kernel
+ifdef KERNEL_FUNCOBJS
+ KERNEL_LCSRCS := $(KERNEL_FCSRCS)
+ KERNEL_LCOBJS := $(foreach file,$(KERNEL_FCSRCS),$($(file:.c=)))
+else
+ KERNEL_CFLAGS := -DALLFUNC $(KERNEL_CFLAGS)
+ KERNEL_COBJS := $(KERNEL_COBJS) \
+ $(foreach file,$(KERNEL_FCSRCS),$(file:.c=.o))
+endif
+
+#
+# ソースファイルのあるディレクトリに関する定義
+#
+vpath %.c $(KERNEL_DIR) $(SYSSVC_DIR) $(APPL_DIR)
+vpath %.S $(KERNEL_DIR) $(SYSSVC_DIR) $(APPL_DIR)
+
+#
+# コンパイルのための変数の定義
+#
+KERNEL_LIB_OBJS = $(KERNEL_ASMOBJS) $(KERNEL_COBJS) $(KERNEL_LCOBJS)
+SYSSVC_OBJS = $(SYSSVC_ASMOBJS) $(SYSSVC_COBJS)
+APPL_OBJS = $(APPL_ASMOBJS) $(APPL_COBJS) $(APPL_CXXOBJS)
+ALL_OBJS = $(START_OBJS) $(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) \
+ $(END_OBJS) $(HIDDEN_OBJS)
+ALL_LIBS = $(APPL_LIBS) $(SYSSVC_LIBS) $(LIBKERNEL) $(LIBS)
+
+ifdef TEXT_START_ADDRESS
+ LDFLAGS := $(LDFLAGS) -Wl,-Ttext,$(TEXT_START_ADDRESS)
+endif
+ifdef DATA_START_ADDRESS
+ LDFLAGS := $(LDFLAGS) -Wl,-Tdata,$(DATA_START_ADDRESS)
+endif
+ifdef LDSCRIPT
+ LDFLAGS := $(LDFLAGS) -T $(LDSCRIPT)
+endif
+
+#
+# offset.h の生成規則(構造体内のオフセット値の算出)
+#
+offset.h: makeoffset.s $(SRCDIR)/utils/genoffset
+ $(PERL) $(SRCDIR)/utils/genoffset makeoffset.s > offset.h
+
+#
+# カーネルのコンフィギュレーションファイルの生成
+#
+cfg1_out.c:
+ $(CFG) --pass 1 --kernel asp $(INCLUDES) $(CFG_TABS) $(APPL_CFG)
+
+kernel_cfg.timestamp: $(START_OBJS) cfg1_out.o $(END_OBJS) $(HIDDEN_OBJS)
+kernel_cfg.timestamp $(CFG2_OUT):
+ $(LINK) $(CFLAGS) $(LDFLAGS) $(CFG1_OUT_LDFLAGS) -o $(CFG1_OUT) \
+ $(START_OBJS) cfg1_out.o $(END_OBJS)
+ $(NM) -C $(CFG1_OUT) > cfg1_out.syms
+ $(OBJCOPY) -O srec -S $(CFG1_OUT) cfg1_out.srec
+ $(CFG) --pass 2 --kernel asp $(INCLUDES) \
+ -T $(TARGETDIR)/target.tf $(CFG_TABS) $(APPL_CFG)
+ touch kernel_cfg.timestamp
+
+#
+# カーネルライブラリファイルの生成
+#
+libkernel.a: $(OFFSET_H) $(KERNEL_LIB_OBJS)
+ rm -f libkernel.a
+ $(AR) -rcs libkernel.a $(KERNEL_LIB_OBJS)
+ $(RANLIB) libkernel.a
+
+#
+# 特別な依存関係の定義
+#
+banner.o: kernel_cfg.timestamp $(filter-out banner.o,$(ALL_OBJS)) \
+ $(filter %.a,$(ALL_LIBS))
+
+#
+# 全体のリンク
+#
+$(OBJFILE): kernel_cfg.timestamp $(ALL_OBJS) $(filter %.a,$(ALL_LIBS))
+ $(LINK) $(CFLAGS) $(LDFLAGS) -o $(OBJFILE) $(START_OBJS) \
+ $(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) $(ALL_LIBS) $(END_OBJS)
+ $(NM) -C $(OBJFILE) > $(OBJNAME).syms
+ $(OBJCOPY) -O srec -S $(OBJFILE) $(OBJNAME).srec
+ $(CFG) --pass 3 --kernel asp $(INCLUDES) \
+ --rom-image $(OBJNAME).srec --symbol-table $(OBJNAME).syms \
+ -T $(TARGETDIR)/target_check.tf $(CFG_TABS) $(APPL_CFG)
+
+#
+# バイナリファイルの生成
+#
+$(OBJNAME).bin: $(OBJFILE)
+ $(OBJCOPY) -O binary -S $(OBJFILE) $(OBJNAME).bin
+
+#
+# Sレコードファイルの生成
+#
+$(OBJNAME).srec: $(OBJFILE)
+ $(OBJCOPY) -O srec -S $(OBJFILE) $(OBJNAME).srec
+
+#
+# コンパイル結果の消去
+#
+.PHONY: clean
+clean:
+ rm -f \#* *~ *.o $(CLEAN_FILES)
+ rm -f $(OBJFILE) $(OBJNAME).syms $(OBJNAME).srec $(OBJNAME).bin
+ rm -f kernel_cfg.timestamp $(CFG2_OUT)
+ rm -f cfg1_out.c $(CFG1_OUT) cfg1_out.syms cfg1_out.srec
+ifndef KERNEL_LIB
+ rm -f $(LIBKERNEL)
+endif
+ rm -f makeoffset.s offset.h
+
+.PHONY: cleankernel
+cleankernel:
+ rm -rf $(KERNEL_LIB_OBJS)
+ rm -f makeoffset.s offset.h
+
+.PHONY: cleandep
+cleandep:
+ if ! [ -f Makefile.depend ]; then \
+ rm -f kernel_cfg.timestamp $(CFG2_OUT); \
+ rm -f cfg1_out.c cfg1_out.o $(CFG1_OUT) cfg1_out.syms cfg1_out.srec; \
+ rm -f makeoffset.s offset.h; \
+ fi
+ rm -f Makefile.depend
+
+.PHONY: realclean
+realclean: cleandep clean
+ rm -f $(REALCLEAN_FILES)
+
+#
+# kernel_cfg.cとcfg1_out.cのコンパイルルールと依存関係作成ルールの定義
+#
+# kernel_cfg.cとcfg1_out.cは,アプリケーションプログラム用,システムサー
+# ビス用,カーネル用のすべてのオプションを付けてコンパイルする.
+#
+KERNEL_CFG_CFLAGS = $(APPL_CFLAGS) $(SYSSVC_CFLAGS) $(KERNEL_CFLAGS)
+
+kernel_cfg.o cfg1_out.o: %.o: %.c
+ $(CC) -c $(CFLAGS) $(KERNEL_CFG_CFLAGS) $<
+
+kernel_cfg.s cfg1_out.s: %.s: %.c
+ $(CC) -S $(CFLAGS) $(KERNEL_CFG_CFLAGS) $<
+
+kernel_cfg.d cfg1_out.d: %.d: %.c
+ @$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+ -O "$(CFLAGS) $(KERNEL_CFG_CFLAGS)" $< >> Makefile.depend
+
+#
+# 特殊な依存関係作成ルールの定義
+#
+cfg1_out.depend:
+ @$(CFG) -M cfg1_out.c $(INCLUDES) $(APPL_CFG) >> Makefile.depend
+
+makeoffset.d: makeoffset.c
+ @$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+ -T "makeoffset.s" -O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+#
+# 依存関係ファイルの生成
+#
+.PHONY: gendepend
+gendepend:
+ @echo "Generating Makefile.depend."
+
+.PHONY: depend
+ifdef KERNEL_LIB
+depend: cleandep kernel_cfg.timestamp gendepend \
+ cfg1_out.depend cfg1_out.d \
+ $(ALL_OBJS:.o=.d)
+else
+depend: cleandep $(OFFSET_H) kernel_cfg.timestamp gendepend \
+ cfg1_out.depend cfg1_out.d \
+ $(KERNEL_AUX_COBJS:.o=.d) $(KERNEL_ASMOBJS:.o=.d) \
+ $(KERNEL_COBJS:.o=.d) $(KERNEL_LCSRCS:.c=.d) $(ALL_OBJS:.o=.d)
+endif
+
+#
+# 依存関係ファイルをインクルード
+#
+-include Makefile.depend
+
+#
+# 開発ツールのコマンド名の定義
+#
+ifeq ($(TOOL),gcc)
+ #
+ # GNU開発環境用
+ #
+ ifdef GCC_TARGET
+ GCC_TARGET_PREFIX = $(GCC_TARGET)-
+ else
+ GCC_TARGET_PREFIX =
+ endif
+ CC = $(GCC_TARGET_PREFIX)gcc
+ CXX = $(GCC_TARGET_PREFIX)g++
+ AS = $(GCC_TARGET_PREFIX)as
+ LD = $(GCC_TARGET_PREFIX)ld
+ AR = $(GCC_TARGET_PREFIX)ar
+ NM = $(GCC_TARGET_PREFIX)nm
+ RANLIB = $(GCC_TARGET_PREFIX)ranlib
+ OBJCOPY = $(GCC_TARGET_PREFIX)objcopy
+ OBJDUMP = $(GCC_TARGET_PREFIX)objdump
+endif
+
+ifdef USE_CXX
+ LINK = $(CXX)
+else
+ LINK = $(CC)
+endif
+
+#
+# コンパイルルールの定義
+#
+KERNEL_ALL_COBJS = $(KERNEL_COBJS) $(KERNEL_AUX_COBJS)
+
+$(KERNEL_ALL_COBJS): %.o: %.c
+ $(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_ALL_COBJS:.o=.s): %.s: %.c
+ $(CC) -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS): %.o:
+ $(CC) -DTOPPERS_$(*F) -o $@ -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_LCOBJS:.o=.s): %.s:
+ $(CC) -DTOPPERS_$(*F) -o $@ -S $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(KERNEL_ASMOBJS): %.o: %.S
+ $(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $<
+
+$(SYSSVC_COBJS): %.o: %.c
+ $(CC) -c $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_COBJS:.o=.s): %.s: %.c
+ $(CC) -S $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(SYSSVC_ASMOBJS): %.o: %.S
+ $(CC) -c $(CFLAGS) $(SYSSVC_CFLAGS) $<
+
+$(APPL_COBJS): %.o: %.c
+ $(CC) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_COBJS:.o=.s): %.s: %.c
+ $(CC) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS): %.o: %.cpp
+ $(CXX) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_CXXOBJS:.o=.s): %.s: %.cpp
+ $(CXX) -S $(CFLAGS) $(APPL_CFLAGS) $<
+
+$(APPL_ASMOBJS): %.o: %.S
+ $(CC) -c $(CFLAGS) $(APPL_CFLAGS) $<
+
+#
+# 依存関係作成ルールの定義
+#
+$(KERNEL_COBJS:.o=.d): %.d: %.c
+ @$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+ -O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(KERNEL_LCSRCS:.c=.d): %.d: %.c
+ @$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) -T "$($*)" \
+ -O "-DALLFUNC $(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(KERNEL_ASMOBJS:.o=.d): %.d: %.S
+ @$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+ -O "$(CFLAGS) $(KERNEL_CFLAGS)" $< >> Makefile.depend
+
+$(SYSSVC_COBJS:.o=.d): %.d: %.c
+ @$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+ -O "$(CFLAGS) $(SYSSVC_CFLAGS)" $< >> Makefile.depend
+
+$(SYSSVC_ASMOBJS:.o=.d): %.d: %.S
+ @$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+ -O "$(CFLAGS) $(SYSSVC_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_COBJS:.o=.d): %.d: %.c
+ @$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+ -O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_CXXOBJS:.o=.d): %.d: %.cpp
+ @$(PERL) $(SRCDIR)/utils/makedep -C $(CXX) $(MAKEDEP_OPTS) \
+ -O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+$(APPL_ASMOBJS:.o=.d): %.d: %.S
+ @$(PERL) $(SRCDIR)/utils/makedep -C $(CC) $(MAKEDEP_OPTS) \
+ -O "$(CFLAGS) $(APPL_CFLAGS)" $< >> Makefile.depend
+
+#
+# デフォルトコンパイルルールを上書き
+#
+%.o: %.c
+ @echo "*** Default compile rules should not be used."
+ $(CC) -c $(CFLAGS) $<
+
+%.s: %.c
+ @echo "*** Default compile rules should not be used."
+ $(CC) -S $(CFLAGS) $<
+
+%.o: %.cpp
+ @echo "*** Default compile rules should not be used."
+ $(CXX) -c $(CFLAGS) $<
+
+%.s: %.cpp
+ @echo "*** Default compile rules should not be used."
+ $(CXX) -S $(CFLAGS) $<
+
+%.o: %.S
+ @echo "*** Default compile rules should not be used."
+ $(CC) -c $(CFLAGS) $<
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: sample1.c 1797 2010-06-07 04:24:19Z ertl-hiro $
+ */
+
+/*
+ * サンプルプログラム(1)の本体
+ *
+ * ASPカーネルの基本的な動作を確認するためのサンプルプログラム.
+ *
+ * プログラムの概要:
+ *
+ * ユーザインタフェースを受け持つメインタスク(タスクID: MAIN_TASK,優
+ * 先度: MAIN_PRIORITY)と,3つの並列実行されるタスク(タスクID:
+ * TASK1〜TASK3,初期優先度: MID_PRIORITY)で構成される.また,起動周
+ * 期が2秒の周期ハンドラ(周期ハンドラID: CYCHDR1)を用いる.
+ *
+ * 並列実行されるタスクは,task_loop回空ループを実行する度に,タスクが
+ * 実行中であることをあらわすメッセージを表示する.
+ *
+ * 周期ハンドラは,三つの優先度(HIGH_PRIORITY,MID_PRIORITY,
+ * LOW_PRIORITY)のレディキューを回転させる.プログラムの起動直後は,
+ * 周期ハンドラは停止状態になっている.
+ *
+ * メインタスクは,シリアルI/Oポートからの文字入力を行い(文字入力を
+ * 待っている間は,並列実行されるタスクが実行されている),入力された
+ * 文字に対応した処理を実行する.入力された文字と処理の関係は次の通り.
+ * Control-Cまたは'Q'が入力されると,プログラムを終了する.
+ *
+ * '1' : 対象タスクをTASK1に切り換える(初期設定).
+ * '2' : 対象タスクをTASK2に切り換える.
+ * '3' : 対象タスクをTASK3に切り換える.
+ * 'a' : 対象タスクをact_tskにより起動する.
+ * 'A' : 対象タスクに対する起動要求をcan_actによりキャンセルする.
+ * 'e' : 対象タスクにext_tskを呼び出させ,終了させる.
+ * 't' : 対象タスクをter_tskにより強制終了する.
+ * '>' : 対象タスクの優先度をHIGH_PRIORITYにする.
+ * '=' : 対象タスクの優先度をMID_PRIORITYにする.
+ * '<' : 対象タスクの優先度をLOW_PRIORITYにする.
+ * 'G' : 対象タスクの優先度をget_priで読み出す.
+ * 's' : 対象タスクにslp_tskを呼び出させ,起床待ちにさせる.
+ * 'S' : 対象タスクにtslp_tsk(10秒)を呼び出させ,起床待ちにさせる.
+ * 'w' : 対象タスクをwup_tskにより起床する.
+ * 'W' : 対象タスクに対する起床要求をcan_wupによりキャンセルする.
+ * 'l' : 対象タスクをrel_waiにより強制的に待ち解除にする.
+ * 'u' : 対象タスクをsus_tskにより強制待ち状態にする.
+ * 'm' : 対象タスクの強制待ち状態をrsm_tskにより解除する.
+ * 'd' : 対象タスクにdly_tsk(10秒)を呼び出させ,時間経過待ちにさせる.
+ * 'x' : 対象タスクに例外パターン0x0001の例外処理を要求する.
+ * 'X' : 対象タスクに例外パターン0x0002の例外処理を要求する.
+ * 'y' : 対象タスクにdis_texを呼び出させ,タスク例外を禁止する.
+ * 'Y' : 対象タスクにena_texを呼び出させ,タスク例外を許可する.
+ * 'r' : 3つの優先度(HIGH_PRIORITY,MID_PRIORITY,LOW_PRIORITY)のレ
+ * ディキューを回転させる.
+ * 'c' : 周期ハンドラを動作開始させる.
+ * 'C' : 周期ハンドラを動作停止させる.
+ * 'b' : アラームハンドラを5秒後に起動するよう動作開始させる.
+ * 'B' : アラームハンドラを動作停止させる.
+ * 'z' : 対象タスクにCPU例外を発生させる(タスクを終了させる).
+ * 'Z' : 対象タスクにCPUロック状態でCPU例外を発生させる(プログラムを
+ * 終了する).
+ * 'V' : get_utmで性能評価用システム時刻を2回読む.
+ * 'v' : 発行したシステムコールを表示する(デフォルト).
+ * 'q' : 発行したシステムコールを表示しない.
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "kernel_cfg.h"
+#include "sample1.h"
+
+/*
+ * サービスコールのエラーのログ出力
+ */
+Inline void
+svc_perror(const char *file, int_t line, const char *expr, ER ercd)
+{
+ if (ercd < 0) {
+ t_perror(LOG_ERROR, file, line, expr, ercd);
+ }
+}
+
+#define SVC_PERROR(expr) svc_perror(__FILE__, __LINE__, #expr, (expr))
+
+/*
+ * 並行実行されるタスクへのメッセージ領域
+ */
+char_t message[3];
+
+/*
+ * ループ回数
+ */
+ulong_t task_loop; /* タスク内でのループ回数 */
+ulong_t tex_loop; /* 例外処理ルーチン内でのループ回数 */
+
+/*
+ * 並行実行されるタスク
+ */
+void task(intptr_t exinf)
+{
+ volatile ulong_t i;
+ int_t n = 0;
+ int_t tskno = (int_t) exinf;
+ const char *graph[] = { "|", " +", " *" };
+ char_t c;
+
+ SVC_PERROR(ena_tex());
+ while (1) {
+ syslog(LOG_NOTICE, "task%d is running (%03d). %s",
+ tskno, ++n, graph[tskno-1]);
+ for (i = 0; i < task_loop; i++);
+ c = message[tskno-1];
+ message[tskno-1] = 0;
+ switch (c) {
+ case 'e':
+ syslog(LOG_INFO, "#%d#ext_tsk()", tskno);
+ SVC_PERROR(ext_tsk());
+ assert(0);
+ case 's':
+ syslog(LOG_INFO, "#%d#slp_tsk()", tskno);
+ SVC_PERROR(slp_tsk());
+ break;
+ case 'S':
+ syslog(LOG_INFO, "#%d#tslp_tsk(10000)", tskno);
+ SVC_PERROR(tslp_tsk(10000));
+ break;
+ case 'd':
+ syslog(LOG_INFO, "#%d#dly_tsk(10000)", tskno);
+ SVC_PERROR(dly_tsk(10000));
+ break;
+ case 'y':
+ syslog(LOG_INFO, "#%d#dis_tex()", tskno);
+ SVC_PERROR(dis_tex());
+ break;
+ case 'Y':
+ syslog(LOG_INFO, "#%d#ena_tex()", tskno);
+ SVC_PERROR(ena_tex());
+ break;
+#ifdef CPUEXC1
+ case 'z':
+ syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno);
+ RAISE_CPU_EXCEPTION;
+ break;
+ case 'Z':
+ SVC_PERROR(loc_cpu());
+ syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno);
+ RAISE_CPU_EXCEPTION;
+ SVC_PERROR(unl_cpu());
+ break;
+#endif /* CPUEXC1 */
+ default:
+ break;
+ }
+ }
+}
+
+/*
+ * 並行して実行されるタスク用のタスク例外処理ルーチン
+ */
+void tex_routine(TEXPTN texptn, intptr_t exinf)
+{
+ volatile ulong_t i;
+ int_t tskno = (int_t) exinf;
+
+ syslog(LOG_NOTICE, "task%d receives exception 0x%04x.", tskno, texptn);
+ for (i = 0; i < tex_loop; i++);
+
+ if ((texptn & 0x8000U) != 0U) {
+ syslog(LOG_INFO, "#%d#ext_tsk()", tskno);
+ SVC_PERROR(ext_tsk());
+ assert(0);
+ }
+}
+
+/*
+ * CPU例外ハンドラ
+ */
+#ifdef CPUEXC1
+
+void
+cpuexc_handler(void *p_excinf)
+{
+ ID tskid;
+
+ syslog(LOG_NOTICE, "CPU exception handler (p_excinf = %08p).", p_excinf);
+ if (sns_ctx() != true) {
+ syslog(LOG_WARNING,
+ "sns_ctx() is not true in CPU exception handler.");
+ }
+ if (sns_dpn() != true) {
+ syslog(LOG_WARNING,
+ "sns_dpn() is not true in CPU exception handler.");
+ }
+ syslog(LOG_INFO, "sns_loc = %d sns_dsp = %d sns_tex = %d",
+ sns_loc(), sns_dsp(), sns_tex());
+ syslog(LOG_INFO, "xsns_dpn = %d xsns_xpn = %d",
+ xsns_dpn(p_excinf), xsns_xpn(p_excinf));
+
+ if (xsns_xpn(p_excinf)) {
+ syslog(LOG_NOTICE, "Sample program ends with exception.");
+ SVC_PERROR(ext_ker());
+ assert(0);
+ }
+
+ SVC_PERROR(iget_tid(&tskid));
+ SVC_PERROR(iras_tex(tskid, 0x8000U));
+}
+
+#endif /* CPUEXC1 */
+
+/*
+ * 周期ハンドラ
+ *
+ * HIGH_PRIORITY,MID_PRIORITY,LOW_PRIORITY の各優先度のレディキュー
+ * を回転させる.
+ */
+void cyclic_handler(intptr_t exinf)
+{
+ SVC_PERROR(irot_rdq(HIGH_PRIORITY));
+ SVC_PERROR(irot_rdq(MID_PRIORITY));
+ SVC_PERROR(irot_rdq(LOW_PRIORITY));
+}
+
+/*
+ * アラームハンドラ
+ *
+ * HIGH_PRIORITY,MID_PRIORITY,LOW_PRIORITY の各優先度のレディキュー
+ * を回転させる.
+ */
+void alarm_handler(intptr_t exinf)
+{
+ SVC_PERROR(irot_rdq(HIGH_PRIORITY));
+ SVC_PERROR(irot_rdq(MID_PRIORITY));
+ SVC_PERROR(irot_rdq(LOW_PRIORITY));
+}
+
+/*
+ * メインタスク
+ */
+void main_task(intptr_t exinf)
+{
+ char_t c;
+ ID tskid = TASK1;
+ int_t tskno = 1;
+ ER_UINT ercd;
+ PRI tskpri;
+#ifndef TASK_LOOP
+ volatile ulong_t i;
+ SYSTIM stime1, stime2;
+#endif /* TASK_LOOP */
+#ifdef TOPPERS_SUPPORT_GET_UTM
+ SYSUTM utime1, utime2;
+#endif /* TOPPERS_SUPPORT_GET_UTM */
+
+ SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG)));
+ syslog(LOG_NOTICE, "Sample program starts (exinf = %d).", (int_t) exinf);
+
+ /*
+ * シリアルポートの初期化
+ *
+ * システムログタスクと同じシリアルポートを使う場合など,シリアル
+ * ポートがオープン済みの場合にはここでE_OBJエラーになるが,支障は
+ * ない.
+ */
+ ercd = serial_opn_por(TASK_PORTID);
+ if (ercd < 0 && MERCD(ercd) != E_OBJ) {
+ syslog(LOG_ERROR, "%s (%d) reported by `serial_opn_por'.",
+ itron_strerror(ercd), SERCD(ercd));
+ }
+ SVC_PERROR(serial_ctl_por(TASK_PORTID,
+ (IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV)));
+
+ /*
+ * ループ回数の設定
+ *
+ * TASK_LOOPがマクロ定義されている場合,測定せずに,TASK_LOOPに定
+ * 義された値を,タスク内でのループ回数とする.
+ *
+ * MEASURE_TWICEがマクロ定義されている場合,1回目の測定結果を捨て
+ * て,2回目の測定結果を使う.1回目の測定は長めの時間が出るため.
+ */
+#ifdef TASK_LOOP
+ task_loop = TASK_LOOP;
+#else /* TASK_LOOP */
+
+#ifdef MEASURE_TWICE
+ task_loop = LOOP_REF;
+ SVC_PERROR(get_tim(&stime1));
+ for (i = 0; i < task_loop; i++);
+ SVC_PERROR(get_tim(&stime2));
+#endif /* MEASURE_TWICE */
+
+ task_loop = LOOP_REF;
+ SVC_PERROR(get_tim(&stime1));
+ for (i = 0; i < task_loop; i++);
+ SVC_PERROR(get_tim(&stime2));
+ task_loop = LOOP_REF * 400UL / (stime2 - stime1);
+
+#endif /* TASK_LOOP */
+ tex_loop = task_loop / 5;
+
+ /*
+ * タスクの起動
+ */
+ SVC_PERROR(act_tsk(TASK1));
+ SVC_PERROR(act_tsk(TASK2));
+ SVC_PERROR(act_tsk(TASK3));
+
+ /*
+ * メインループ
+ */
+ do {
+ SVC_PERROR(serial_rea_dat(TASK_PORTID, &c, 1));
+ switch (c) {
+ case 'e':
+ case 's':
+ case 'S':
+ case 'd':
+ case 'y':
+ case 'Y':
+ case 'z':
+ case 'Z':
+ message[tskno-1] = c;
+ break;
+ case '1':
+ tskno = 1;
+ tskid = TASK1;
+ break;
+ case '2':
+ tskno = 2;
+ tskid = TASK2;
+ break;
+ case '3':
+ tskno = 3;
+ tskid = TASK3;
+ break;
+ case 'a':
+ syslog(LOG_INFO, "#act_tsk(%d)", tskno);
+ SVC_PERROR(act_tsk(tskid));
+ break;
+ case 'A':
+ syslog(LOG_INFO, "#can_act(%d)", tskno);
+ SVC_PERROR(ercd = can_act(tskid));
+ if (ercd >= 0) {
+ syslog(LOG_NOTICE, "can_act(%d) returns %d", tskno, ercd);
+ }
+ break;
+ case 't':
+ syslog(LOG_INFO, "#ter_tsk(%d)", tskno);
+ SVC_PERROR(ter_tsk(tskid));
+ break;
+ case '>':
+ syslog(LOG_INFO, "#chg_pri(%d, HIGH_PRIORITY)", tskno);
+ SVC_PERROR(chg_pri(tskid, HIGH_PRIORITY));
+ break;
+ case '=':
+ syslog(LOG_INFO, "#chg_pri(%d, MID_PRIORITY)", tskno);
+ SVC_PERROR(chg_pri(tskid, MID_PRIORITY));
+ break;
+ case '<':
+ syslog(LOG_INFO, "#chg_pri(%d, LOW_PRIORITY)", tskno);
+ SVC_PERROR(chg_pri(tskid, LOW_PRIORITY));
+ break;
+ case 'G':
+ syslog(LOG_INFO, "#get_pri(%d, &tskpri)", tskno);
+ SVC_PERROR(ercd = get_pri(tskid, &tskpri));
+ if (ercd >= 0) {
+ syslog(LOG_NOTICE, "priority of task %d is %d", tskno, tskpri);
+ }
+ break;
+ case 'w':
+ syslog(LOG_INFO, "#wup_tsk(%d)", tskno);
+ SVC_PERROR(wup_tsk(tskid));
+ break;
+ case 'W':
+ syslog(LOG_INFO, "#can_wup(%d)", tskno);
+ SVC_PERROR(ercd = can_wup(tskid));
+ if (ercd >= 0) {
+ syslog(LOG_NOTICE, "can_wup(%d) returns %d", tskno, ercd);
+ }
+ break;
+ case 'l':
+ syslog(LOG_INFO, "#rel_wai(%d)", tskno);
+ SVC_PERROR(rel_wai(tskid));
+ break;
+ case 'u':
+ syslog(LOG_INFO, "#sus_tsk(%d)", tskno);
+ SVC_PERROR(sus_tsk(tskid));
+ break;
+ case 'm':
+ syslog(LOG_INFO, "#rsm_tsk(%d)", tskno);
+ SVC_PERROR(rsm_tsk(tskid));
+ break;
+ case 'x':
+ syslog(LOG_INFO, "#ras_tex(%d, 0x0001U)", tskno);
+ SVC_PERROR(ras_tex(tskid, 0x0001U));
+ break;
+ case 'X':
+ syslog(LOG_INFO, "#ras_tex(%d, 0x0002U)", tskno);
+ SVC_PERROR(ras_tex(tskid, 0x0002U));
+ break;
+ case 'r':
+ syslog(LOG_INFO, "#rot_rdq(three priorities)");
+ SVC_PERROR(rot_rdq(HIGH_PRIORITY));
+ SVC_PERROR(rot_rdq(MID_PRIORITY));
+ SVC_PERROR(rot_rdq(LOW_PRIORITY));
+ break;
+ case 'c':
+ syslog(LOG_INFO, "#sta_cyc(1)");
+ SVC_PERROR(sta_cyc(CYCHDR1));
+ break;
+ case 'C':
+ syslog(LOG_INFO, "#stp_cyc(1)");
+ SVC_PERROR(stp_cyc(CYCHDR1));
+ break;
+ case 'b':
+ syslog(LOG_INFO, "#sta_alm(1, 5000)");
+ SVC_PERROR(sta_alm(ALMHDR1, 5000));
+ break;
+ case 'B':
+ syslog(LOG_INFO, "#stp_alm(1)");
+ SVC_PERROR(stp_alm(ALMHDR1));
+ break;
+
+ case 'V':
+#ifdef TOPPERS_SUPPORT_GET_UTM
+ SVC_PERROR(get_utm(&utime1));
+ SVC_PERROR(get_utm(&utime2));
+ syslog(LOG_NOTICE, "utime1 = %ld, utime2 = %ld",
+ (ulong_t) utime1, (ulong_t) utime2);
+#else /* TOPPERS_SUPPORT_GET_UTM */
+ syslog(LOG_NOTICE, "get_utm is not supported.");
+#endif /* TOPPERS_SUPPORT_GET_UTM */
+ break;
+
+ case 'v':
+ SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_INFO),
+ LOG_UPTO(LOG_EMERG)));
+ break;
+ case 'q':
+ SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_NOTICE),
+ LOG_UPTO(LOG_EMERG)));
+ break;
+
+#ifdef BIT_KERNEL
+ case ' ':
+ SVC_PERROR(loc_cpu());
+ {
+ extern ER bit_kernel(void);
+
+ SVC_PERROR(ercd = bit_kernel());
+ if (ercd >= 0) {
+ syslog(LOG_NOTICE, "bit_kernel passed.");
+ }
+ }
+ SVC_PERROR(unl_cpu());
+ break;
+#endif /* BIT_KERNEL */
+
+ default:
+ break;
+ }
+ } while (c != '\003' && c != 'Q');
+
+ syslog(LOG_NOTICE, "Sample program ends.");
+ SVC_PERROR(ext_ker());
+ assert(0);
+}
--- /dev/null
+/*
+ * @(#) $Id: sample1.cfg 718 2008-01-01 12:30:48Z hiro $
+ */
+
+/*
+ * サンプルプログラム(1)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+INCLUDE("syssvc/logtask.cfg");
+
+#include "sample1.h"
+CRE_TSK(TASK1, { TA_NULL, 1, task, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK3, { TA_NULL, 3, task, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(MAIN_TASK, { TA_ACT, 0, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
+DEF_TEX(TASK1, { TA_NULL, tex_routine });
+DEF_TEX(TASK2, { TA_NULL, tex_routine });
+DEF_TEX(TASK3, { TA_NULL, tex_routine });
+CRE_CYC(CYCHDR1, { TA_NULL, 0, cyclic_handler, 2000, 0 });
+CRE_ALM(ALMHDR1, { TA_NULL, 0, alarm_handler });
+#ifdef CPUEXC1
+DEF_EXC(CPUEXC1, { TA_NULL, cpuexc_handler });
+#endif /* CPUEXC1 */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: sample1.h 1716 2010-01-31 11:39:18Z ertl-hiro $
+ */
+
+/*
+ * サンプルプログラム(1)のヘッダファイル
+ */
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 各タスクの優先度の定義
+ */
+
+#define MAIN_PRIORITY 5 /* メインタスクの優先度 */
+ /* HIGH_PRIORITYより高くすること */
+
+#define HIGH_PRIORITY 9 /* 並列に実行されるタスクの優先度 */
+#define MID_PRIORITY 10
+#define LOW_PRIORITY 11
+
+/*
+ * ターゲットに依存する可能性のある定数の定義
+ */
+
+#ifndef TASK_PORTID
+#define TASK_PORTID 1 /* 文字入力するシリアルポートID */
+#endif /* TASK_PORTID */
+
+#ifndef STACK_SIZE
+#define STACK_SIZE 4096 /* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+#ifndef LOOP_REF
+#define LOOP_REF ULONG_C(1000000) /* 速度計測用のループ回数 */
+#endif /* LOOP_REF */
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void task(intptr_t exinf);
+extern void main_task(intptr_t exinf);
+extern void tex_routine(TEXPTN texptn, intptr_t exinf);
+#ifdef CPUEXC1
+extern void cpuexc_handler(void *p_excinf);
+#endif /* CPUEXC1 */
+extern void cyclic_handler(intptr_t exinf);
+extern void alarm_handler(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: banner.c 1691 2010-01-01 15:55:49Z ertl-hiro $
+ */
+
+/*
+ * カーネル起動メッセージの出力
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include "target_syssvc.h"
+
+#ifndef TARGET_COPYRIGHT
+#define TARGET_COPYRIGHT
+#endif /* TARGET_COPYRIGHT */
+
+static const char banner[] = "\n"
+"TOPPERS/ASP Kernel Release %d.%X.%d for " TARGET_NAME
+" (" __DATE__ ", " __TIME__ ")\n"
+"Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory\n"
+" Toyohashi Univ. of Technology, JAPAN\n"
+"Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory\n"
+" Graduate School of Information Science, Nagoya Univ., JAPAN\n"
+TARGET_COPYRIGHT;
+
+void
+print_banner(intptr_t exinf)
+{
+ syslog_3(LOG_NOTICE, banner,
+ (TKERNEL_PRVER >> 12) & 0x0fU,
+ (TKERNEL_PRVER >> 4) & 0xffU,
+ TKERNEL_PRVER & 0x0fU);
+}
--- /dev/null
+/*
+ * @(#) $Id: banner.cfg 823 2008-03-18 13:02:11Z hiro $
+ */
+
+/*
+ * カーネル起動メッセージの出力のコンフィギュレーションファイル
+ */
+
+#include "syssvc/banner.h"
+ATT_INI({ TA_NULL, 0, print_banner });
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: banner.h 774 2008-03-08 06:35:57Z hiro $
+ */
+
+/*
+ * カーネル起動メッセージの出力
+ */
+
+#ifndef TOPPERS_BANNER_H
+#define TOPPERS_BANNER_H
+
+/*
+ * カーネル起動メッセージの出力
+ */
+extern void print_banner(intptr_t exinf) throw();
+
+#endif /* TOPPERS_BANNER_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: logtask.c 1111 2008-06-12 08:42:26Z ertl-hiro $
+ */
+
+/*
+ * システムログタスク
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <log_output.h>
+#include "syssvc/serial.h"
+#include "syssvc/syslog.h"
+#include "logtask.h"
+
+/*
+ * システムログタスクの出力先のポートID
+ */
+static ID logtask_portid;
+
+/*
+ * シリアルインタフェースへの1文字出力
+ */
+static void
+logtask_putc(char_t c)
+{
+ serial_wri_dat(logtask_portid, &c, 1);
+}
+
+/*
+ * システムログ出力の待ち合わせ
+ */
+ER
+logtask_flush(uint_t count)
+{
+ T_SYSLOG_RLOG rlog;
+ T_SERIAL_RPOR rpor;
+ ER ercd, rercd;
+
+ if (sns_dpn()) {
+ ercd = E_CTX;
+ }
+ else {
+ for (;;) {
+ if (syslog_ref_log(&rlog) < 0) {
+ ercd = E_SYS;
+ goto error_exit;
+ }
+ if (rlog.count <= count) {
+ if (count == 0U) {
+ /*
+ * countが0の場合には,シリアルバッファが空かを確
+ * 認する.
+ */
+ if (serial_ref_por(logtask_portid, &rpor) < 0) {
+ ercd = E_SYS;
+ goto error_exit;
+ }
+ if (rpor.wricnt == 0U) {
+ ercd = E_OK;
+ goto error_exit;
+ }
+ }
+ else {
+ ercd = E_OK;
+ goto error_exit;
+ }
+ }
+
+ /*
+ * LOGTASK_FLUSH_WAITミリ秒待つ.
+ */
+ rercd = dly_tsk(LOGTASK_FLUSH_WAIT);
+ if (rercd < 0) {
+ ercd = (rercd == E_RLWAI) ? rercd : E_SYS;
+ goto error_exit;
+ }
+ }
+ }
+
+ error_exit:
+ return(ercd);
+}
+
+/*
+ * システムログタスクの本体
+ */
+void
+logtask_main(intptr_t exinf)
+{
+ SYSLOG syslog;
+ uint_t lost;
+ ER_UINT rercd;
+
+ logtask_portid = (ID) exinf;
+ serial_opn_por(logtask_portid);
+ syslog_msk_log(LOG_UPTO(LOG_NOTICE), LOG_UPTO(LOG_EMERG));
+ syslog_1(LOG_NOTICE, "System logging task is started on port %d.",
+ logtask_portid);
+ for (;;) {
+ lost = 0U;
+ while ((rercd = syslog_rea_log(&syslog)) >= 0) {
+ lost += (uint_t) rercd;
+ if (syslog.logtype >= LOG_TYPE_COMMENT) {
+ if (lost > 0U) {
+ syslog_lostmsg(lost, logtask_putc);
+ lost = 0U;
+ }
+ syslog_print(&syslog, logtask_putc);
+ logtask_putc('\n');
+ }
+ }
+ if (lost > 0U) {
+ syslog_lostmsg(lost, logtask_putc);
+ }
+ dly_tsk(LOGTASK_INTERVAL);
+ }
+}
+
+/*
+ * システムログタスクの終了処理
+ */
+void
+logtask_terminate(intptr_t exinf)
+{
+ char_t c;
+ SYSLOG syslog;
+ bool_t msgflg = false;
+ ER_UINT rercd;
+
+ /*
+ * シリアルインタフェースドライバの送信バッファに蓄積されたデータ
+ * を,低レベル出力機能を用いて出力する.
+ */
+ while (serial_get_chr(logtask_portid, &c)) {
+ target_fput_log(c);
+ }
+
+ /*
+ * ログバッファに記録されたログ情報を,低レベル出力機能を用いて出
+ * 力する.
+ */
+ while ((rercd = syslog_rea_log(&syslog)) >= 0) {
+ if (!msgflg) {
+ /*
+ * ログバッファに残ったログ情報であることを示す文字列を出
+ * 力する.
+ */
+ syslog_printf("-- buffered messages --\n", NULL, target_fput_log);
+ msgflg = true;
+ }
+ if (rercd > 0) {
+ syslog_lostmsg((uint_t) rercd, target_fput_log);
+ }
+ if (syslog.logtype >= LOG_TYPE_COMMENT) {
+ syslog_print(&syslog, target_fput_log);
+ target_fput_log('\n');
+ }
+ }
+}
--- /dev/null
+/*
+ * @(#) $Id: logtask.cfg 823 2008-03-18 13:02:11Z hiro $
+ */
+
+/*
+ * システムログタスクのコンフィギュレーションファイル
+ */
+
+#include "syssvc/logtask.h"
+CRE_TSK(LOGTASK, { TA_ACT, LOGTASK_PORTID, logtask_main,
+ LOGTASK_PRIORITY, LOGTASK_STACK_SIZE, NULL });
+ATT_TER({ TA_NULL, 0, logtask_terminate });
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: logtask.h 774 2008-03-08 06:35:57Z hiro $
+ */
+
+/*
+ * システムログタスク
+ */
+
+#ifndef TOPPERS_LOGTASK_H
+#define TOPPERS_LOGTASK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "target_syssvc.h"
+
+/*
+ * システムログタスク関連の定数のデフォルト値の定義
+ */
+#ifndef LOGTASK_PRIORITY
+#define LOGTASK_PRIORITY 3 /* 初期優先度 */
+#endif /* LOGTASK_PRIORITY */
+
+#ifndef LOGTASK_STACK_SIZE
+#define LOGTASK_STACK_SIZE 1024 /* スタック領域のサイズ */
+#endif /* LOGTASK_STACK_SIZE */
+
+#ifndef LOGTASK_PORTID
+#define LOGTASK_PORTID SIO_PORTID /* システムログ用のシリアルポート番号 */
+#endif /* LOGTASK_PORTID */
+
+#ifndef LOGTASK_INTERVAL
+#define LOGTASK_INTERVAL 10U /* システムログタスクの動作間隔(ミリ秒)*/
+#endif /* LOGTASK_INTERVAL */
+
+#ifndef LOGTASK_FLUSH_WAIT
+#define LOGTASK_FLUSH_WAIT 1U /* フラッシュ待ちの単位時間(ミリ秒)*/
+#endif /* LOGTASK_FLUSH_WAIT */
+
+/*
+ * システムログ出力の待ち合わせ
+ *
+ * ログバッファ中のログの数がcount以下になるまで待つ.countが0の場合に
+ * は,シリアルバッファが空になるのも待つ.
+ */
+extern ER logtask_flush(uint_t count) throw();
+
+/*
+ * システムログタスクの本体
+ */
+extern void logtask_main(intptr_t exinf) throw();
+
+/*
+ * システムログタスクの終了処理
+ */
+extern void logtask_terminate(intptr_t exinf) throw();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_LOGTASK_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2006-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: serial.c 1176 2008-07-01 10:24:46Z ertl-hiro $
+ */
+
+/*
+ * シリアルインタフェースドライバ
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include "target_syssvc.h"
+#include "target_serial.h"
+#include "serial.h"
+#include "kernel_cfg.h"
+
+/*
+ * バッファサイズのデフォルト値とバッファの定義
+ */
+#ifndef SERIAL_RCV_BUFSZ1
+#define SERIAL_RCV_BUFSZ1 256 /* ポート1の受信バッファサイズ */
+#endif /* SERIAL_RCV_BUFSZ1 */
+
+#ifndef SERIAL_SND_BUFSZ1
+#define SERIAL_SND_BUFSZ1 256 /* ポート1の送信バッファサイズ */
+#endif /* SERIAL_SND_BUFSZ1 */
+
+static char_t rcv_buffer1[SERIAL_RCV_BUFSZ1];
+static char_t snd_buffer1[SERIAL_SND_BUFSZ1];
+
+#if TNUM_PORT >= 2 /* ポート2に関する定義 */
+
+#ifndef SERIAL_RCV_BUFSZ2
+#define SERIAL_RCV_BUFSZ2 256 /* ポート2の受信バッファサイズ */
+#endif /* SERIAL_RCV_BUFSZ2 */
+
+#ifndef SERIAL_SND_BUFSZ2
+#define SERIAL_SND_BUFSZ2 256 /* ポート2の送信バッファサイズ */
+#endif /* SERIAL_SND_BUFSZ2 */
+
+static char_t rcv_buffer2[SERIAL_RCV_BUFSZ2];
+static char_t snd_buffer2[SERIAL_SND_BUFSZ2];
+
+#endif /* TNUM_PORT >= 2 */
+
+#if TNUM_PORT >= 3 /* ポート3に関する定義 */
+
+#ifndef SERIAL_RCV_BUFSZ3
+#define SERIAL_RCV_BUFSZ3 256 /* ポート3の受信バッファサイズ */
+#endif /* SERIAL_RCV_BUFSZ3 */
+
+#ifndef SERIAL_SND_BUFSZ3
+#define SERIAL_SND_BUFSZ3 256 /* ポート3の送信バッファサイズ */
+#endif /* SERIAL_SND_BUFSZ3 */
+
+static char_t rcv_buffer3[SERIAL_RCV_BUFSZ3];
+static char_t snd_buffer3[SERIAL_SND_BUFSZ3];
+
+#endif /* TNUM_PORT >= 3 */
+
+#if TNUM_PORT >= 4 /* ポート4に関する定義 */
+
+#ifndef SERIAL_RCV_BUFSZ4
+#define SERIAL_RCV_BUFSZ4 256 /* ポート4の受信バッファサイズ */
+#endif /* SERIAL_RCV_BUFSZ4 */
+
+#ifndef SERIAL_SND_BUFSZ4
+#define SERIAL_SND_BUFSZ4 256 /* ポート4の送信バッファサイズ */
+#endif /* SERIAL_SND_BUFSZ4 */
+
+static char_t rcv_buffer4[SERIAL_RCV_BUFSZ4];
+static char_t snd_buffer4[SERIAL_SND_BUFSZ4];
+
+#endif /* TNUM_PORT >= 4 */
+
+/*
+ * フロー制御に関連する定数とマクロ
+ */
+#define FC_STOP '\023' /* コントロール-S */
+#define FC_START '\021' /* コントロール-Q */
+
+#define BUFCNT_STOP(bufsz) ((bufsz) * 3 / 4) /* STOPを送る基準文字数 */
+#define BUFCNT_START(bufsz) ((bufsz) / 2) /* STARTを送る基準文字数 */
+
+/*
+ * シリアルポート初期化ブロック
+ */
+typedef struct serial_port_initialization_block {
+ ID rcv_semid; /* 受信バッファ管理用セマフォのID */
+ ID snd_semid; /* 送信バッファ管理用セマフォのID */
+ uint_t rcv_bufsz; /* 受信バッファサイズ */
+ char_t *rcv_buffer; /* 受信バッファ */
+ uint_t snd_bufsz; /* 送信バッファサイズ */
+ char_t *snd_buffer; /* 送信バッファ */
+} SPINIB;
+
+static const SPINIB spinib_table[TNUM_PORT] = {
+ { SERIAL_RCV_SEM1, SERIAL_SND_SEM1,
+ SERIAL_RCV_BUFSZ1, rcv_buffer1,
+ SERIAL_SND_BUFSZ1, snd_buffer1 },
+#if TNUM_PORT >= 2
+ { SERIAL_RCV_SEM2, SERIAL_SND_SEM2,
+ SERIAL_RCV_BUFSZ2, rcv_buffer2,
+ SERIAL_SND_BUFSZ2, snd_buffer2 },
+#endif /* TNUM_PORT >= 2 */
+#if TNUM_PORT >= 3
+ { SERIAL_RCV_SEM3, SERIAL_SND_SEM3,
+ SERIAL_RCV_BUFSZ3, rcv_buffer3,
+ SERIAL_SND_BUFSZ3, snd_buffer3 },
+#endif /* TNUM_PORT >= 3 */
+#if TNUM_PORT >= 4
+ { SERIAL_RCV_SEM4, SERIAL_SND_SEM4,
+ SERIAL_RCV_BUFSZ4, rcv_buffer4,
+ SERIAL_SND_BUFSZ4, snd_buffer4 },
+#endif /* TNUM_PORT >= 4 */
+};
+
+/*
+ * シリアルポート管理ブロック
+ */
+typedef struct serial_port_control_block {
+ const SPINIB *p_spinib; /* シリアルポート初期化ブロック */
+ SIOPCB *p_siopcb; /* シリアルI/Oポート管理ブロック */
+ bool_t openflag; /* オープン済みフラグ */
+ bool_t errorflag; /* エラーフラグ */
+ uint_t ioctl; /* 動作制御の設定値 */
+
+ uint_t rcv_read_ptr; /* 受信バッファ読出しポインタ */
+ uint_t rcv_write_ptr; /* 受信バッファ書込みポインタ */
+ uint_t rcv_count; /* 受信バッファ中の文字数 */
+ char_t rcv_fc_chr; /* 送るべきSTART/STOP */
+ bool_t rcv_stopped; /* STOPを送った状態か? */
+
+ uint_t snd_read_ptr; /* 送信バッファ読出しポインタ */
+ uint_t snd_write_ptr; /* 送信バッファ書込みポインタ */
+ uint_t snd_count; /* 送信バッファ中の文字数 */
+ bool_t snd_stopped; /* STOPを受け取った状態か? */
+} SPCB;
+
+static SPCB spcb_table[TNUM_PORT];
+
+/*
+ * シリアルポートIDからシリアルポート管理ブロックを取り出すためのマクロ
+ */
+#define INDEX_PORT(portid) ((uint_t)((portid) - 1))
+#define get_spcb(portid) (&(spcb_table[INDEX_PORT(portid)]))
+
+/*
+ * ポインタのインクリメント
+ */
+#define INC_PTR(ptr, bufsz) { if (++(ptr) == (bufsz)) { (ptr) = 0; }}
+
+/*
+ * サービスコール呼出しマクロ
+ *
+ * サービスコール呼出しを含む式expを評価し,返値がエラー(負の値)の場
+ * 合には,ercにercd_expを評価した値を代入し,error_exitにgotoする.
+ */
+#define SVC(exp, ercd_exp) \
+ { if ((exp) < 0) { ercd = (ercd_exp); goto error_exit; }}
+
+/*
+ * E_SYSエラーの生成
+ */
+static ER
+gen_ercd_sys(SPCB *p_spcb)
+{
+ p_spcb->errorflag = true;
+ return(E_SYS);
+}
+
+/*
+ * 待ちに入るサービスコールからのエラーの変換
+ */
+static ER
+gen_ercd_wait(ER rercd, SPCB *p_spcb)
+{
+ switch (MERCD(rercd)) {
+ case E_RLWAI:
+ case E_DLT:
+ return(rercd);
+ default:
+ p_spcb->errorflag = true;
+ return(E_SYS);
+ }
+}
+
+/*
+ * シリアルインタフェースドライバの初期化ルーチン
+ */
+void
+serial_initialize(intptr_t exinf)
+{
+ uint_t i;
+ SPCB *p_spcb;
+
+ for (p_spcb = spcb_table, i = 0; i < TNUM_PORT; p_spcb++, i++) {
+ p_spcb->p_spinib = &(spinib_table[i]);
+ p_spcb->openflag = false;
+ }
+}
+
+/*
+ * シリアルポートのオープン(サービスコール)
+ */
+ER
+serial_opn_por(ID portid)
+{
+ SPCB *p_spcb;
+ ER ercd;
+
+ if (sns_dpn()) { /* コンテキストのチェック */
+ return(E_CTX);
+ }
+ if (!(1 <= portid && portid <= TNUM_PORT)) {
+ return(E_ID); /* ポート番号のチェック */
+ }
+ p_spcb = get_spcb(portid);
+
+ SVC(dis_dsp(), gen_ercd_sys(p_spcb));
+ if (p_spcb->openflag) { /* オープン済みかのチェック */
+ ercd = E_OBJ;
+ }
+ else {
+ /*
+ * 変数の初期化
+ * エコーバックさせたい時にはIOCTL_ECHOを追加すると良い。
+ */
+ p_spcb->ioctl = (IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV);
+
+ p_spcb->rcv_read_ptr = p_spcb->rcv_write_ptr = 0U;
+ p_spcb->rcv_count = 0U;
+ p_spcb->rcv_fc_chr = '\0';
+ p_spcb->rcv_stopped = false;
+
+ p_spcb->snd_read_ptr = p_spcb->snd_write_ptr = 0U;
+ p_spcb->snd_count = 0U;
+ p_spcb->snd_stopped = false;
+
+ /*
+ * これ以降,割込みを禁止する.
+ */
+ if (loc_cpu() < 0) {
+ ercd = E_SYS;
+ goto error_exit_enadsp;
+ }
+
+ /*
+ * ハードウェア依存のオープン処理
+ */
+ p_spcb->p_siopcb = sio_opn_por(portid, (intptr_t) p_spcb);
+
+ /*
+ * 受信通知コールバックを許可する.
+ */
+ sio_ena_cbr(p_spcb->p_siopcb, SIO_RDY_RCV);
+ p_spcb->openflag = true;
+ p_spcb->errorflag = false;
+
+ if (unl_cpu() < 0) {
+ p_spcb->errorflag = true;
+ ercd = E_SYS;
+ goto error_exit_enadsp;
+ }
+ ercd = E_OK;
+ }
+
+ error_exit_enadsp:
+ SVC(ena_dsp(), gen_ercd_sys(p_spcb));
+
+ error_exit:
+ return(ercd);
+}
+
+/*
+ * シリアルポートのクローズ(サービスコール)
+ */
+ER
+serial_cls_por(ID portid)
+{
+ SPCB *p_spcb;
+ ER ercd;
+ bool_t eflag = false;
+
+ if (sns_dpn()) { /* コンテキストのチェック */
+ return(E_CTX);
+ }
+ if (!(1 <= portid && portid <= TNUM_PORT)) {
+ return(E_ID); /* ポート番号のチェック */
+ }
+ p_spcb = get_spcb(portid);
+
+ SVC(dis_dsp(), gen_ercd_sys(p_spcb));
+ if (!(p_spcb->openflag)) { /* オープン済みかのチェック */
+ ercd = E_OBJ;
+ }
+ else {
+ /*
+ * ハードウェア依存のクローズ処理
+ */
+ if (loc_cpu() < 0) {
+ eflag = true;
+ }
+ sio_cls_por(p_spcb->p_siopcb);
+ p_spcb->openflag = false;
+ if (unl_cpu() < 0) {
+ eflag = true;
+ }
+
+ /*
+ * セマフォの初期化
+ */
+ if (ini_sem(p_spcb->p_spinib->snd_semid) < 0) {
+ eflag = true;
+ }
+ if (ini_sem(p_spcb->p_spinib->rcv_semid) < 0) {
+ eflag = true;
+ }
+
+ /*
+ * エラーコードの設定
+ */
+ if (eflag) {
+ ercd = gen_ercd_sys(p_spcb);
+ }
+ else {
+ ercd = E_OK;
+ }
+ }
+ SVC(ena_dsp(), gen_ercd_sys(p_spcb));
+
+ error_exit:
+ return(ercd);
+}
+
+/*
+ * シリアルポートへの文字送信
+ *
+ * p_spcbで指定されるシリアルI/Oポートに対して,文字cを送信する.文字
+ * を送信レジスタにいれた場合にはtrueを返す.そうでない場合には,送信
+ * レジスタが空いたことを通知するコールバック関数を許可し,falseを返す.
+ * この関数は,CPUロック状態で呼び出される.
+ */
+Inline bool_t
+serial_snd_chr(SPCB *p_spcb, char_t c)
+{
+ if (sio_snd_chr(p_spcb->p_siopcb, c)) {
+ return(true);
+ }
+ else {
+ sio_ena_cbr(p_spcb->p_siopcb, SIO_RDY_SND);
+ return(false);
+ }
+}
+
+/*
+ * シリアルポートへの1文字送信
+ */
+static ER_BOOL
+serial_wri_chr(SPCB *p_spcb, char_t c)
+{
+ bool_t buffer_full;
+ ER ercd, rercd;
+
+ /*
+ * LFの前にCRを送信する.
+ */
+ if (c == '\n' && (p_spcb->ioctl & IOCTL_CRLF) != 0U) {
+ SVC(rercd = serial_wri_chr(p_spcb, '\r'), rercd);
+ if ((bool_t) rercd) {
+ SVC(rercd = wai_sem(p_spcb->p_spinib->snd_semid),
+ gen_ercd_wait(rercd, p_spcb));
+ }
+ }
+
+ SVC(loc_cpu(), gen_ercd_sys(p_spcb));
+ if (p_spcb->snd_count == 0U && !(p_spcb->snd_stopped)
+ && serial_snd_chr(p_spcb, c)) {
+ /*
+ * シリアルI/Oデバイスの送信レジスタに文字を入れることに成功し
+ * た場合.
+ */
+ buffer_full = false;
+ }
+ else {
+ /*
+ * 送信バッファに文字を入れる.
+ */
+ p_spcb->p_spinib->snd_buffer[p_spcb->snd_write_ptr] = c;
+ INC_PTR(p_spcb->snd_write_ptr, p_spcb->p_spinib->snd_bufsz);
+ p_spcb->snd_count++;
+ buffer_full = (p_spcb->snd_count == p_spcb->p_spinib->snd_bufsz);
+ }
+
+ SVC(unl_cpu(), gen_ercd_sys(p_spcb));
+ ercd = (ER_BOOL) buffer_full;
+
+ error_exit:
+ return(ercd);
+}
+
+/*
+ * シリアルポートへの文字列送信(サービスコール)
+ */
+ER_UINT
+serial_wri_dat(ID portid, const char_t *buf, uint_t len)
+{
+ SPCB *p_spcb;
+ bool_t buffer_full;
+ uint_t wricnt = 0U;
+ ER ercd, rercd;
+
+ if (sns_dpn()) { /* コンテキストのチェック */
+ return(E_CTX);
+ }
+ if (!(1 <= portid && portid <= TNUM_PORT)) {
+ return(E_ID); /* ポート番号のチェック */
+ }
+
+ p_spcb = get_spcb(portid);
+ if (!(p_spcb->openflag)) { /* オープン済みかのチェック */
+ return(E_OBJ);
+ }
+ if (p_spcb->errorflag) { /* エラー状態かのチェック */
+ return(E_SYS);
+ }
+
+ buffer_full = true; /* ループの1回めはwai_semする */
+ while (wricnt < len) {
+ if (buffer_full) {
+ SVC(rercd = wai_sem(p_spcb->p_spinib->snd_semid),
+ gen_ercd_wait(rercd, p_spcb));
+ }
+ SVC(rercd = serial_wri_chr(p_spcb, *buf++), rercd);
+ wricnt++;
+ buffer_full = (bool_t) rercd;
+ }
+ if (!buffer_full) {
+ SVC(sig_sem(p_spcb->p_spinib->snd_semid), gen_ercd_sys(p_spcb));
+ }
+ ercd = E_OK;
+
+ error_exit:
+ return(wricnt > 0U ? (ER_UINT) wricnt : ercd);
+}
+
+/*
+ * シリアルポートからの1文字受信
+ */
+static bool_t
+serial_rea_chr(SPCB *p_spcb, char_t *p_c)
+{
+ bool_t buffer_empty;
+ ER ercd;
+
+ SVC(loc_cpu(), gen_ercd_sys(p_spcb));
+
+ /*
+ * 受信バッファから文字を取り出す.
+ */
+ *p_c = p_spcb->p_spinib->rcv_buffer[p_spcb->rcv_read_ptr];
+ INC_PTR(p_spcb->rcv_read_ptr, p_spcb->p_spinib->rcv_bufsz);
+ p_spcb->rcv_count--;
+ buffer_empty = (p_spcb->rcv_count == 0U);
+
+ /*
+ * STARTを送信する.
+ */
+ if (p_spcb->rcv_stopped && p_spcb->rcv_count
+ <= BUFCNT_START(p_spcb->p_spinib->rcv_bufsz)) {
+ if (!serial_snd_chr(p_spcb, FC_START)) {
+ p_spcb->rcv_fc_chr = FC_START;
+ }
+ p_spcb->rcv_stopped = false;
+ }
+
+ SVC(unl_cpu(), gen_ercd_sys(p_spcb));
+ ercd = (ER_BOOL) buffer_empty;
+
+ error_exit:
+ return(ercd);
+}
+
+/*
+ * シリアルポートからの文字列受信(サービスコール)
+ */
+ER_UINT
+serial_rea_dat(ID portid, char_t *buf, uint_t len)
+{
+ SPCB *p_spcb;
+ bool_t buffer_empty;
+ uint_t reacnt = 0U;
+ char_t c = '\0'; /* コンパイラの警告を抑止するために初期化する */
+ ER ercd, rercd;
+
+ if (sns_dpn()) { /* コンテキストのチェック */
+ return(E_CTX);
+ }
+ if (!(1 <= portid && portid <= TNUM_PORT)) {
+ return(E_ID); /* ポート番号のチェック */
+ }
+
+ p_spcb = get_spcb(portid);
+ if (!(p_spcb->openflag)) { /* オープン済みかのチェック */
+ return(E_OBJ);
+ }
+ if (p_spcb->errorflag) { /* エラー状態かのチェック */
+ return(E_SYS);
+ }
+
+ buffer_empty = true; /* ループの1回めはwai_semする */
+ while (reacnt < len) {
+ if (buffer_empty) {
+ SVC(rercd = wai_sem(p_spcb->p_spinib->rcv_semid),
+ gen_ercd_wait(rercd, p_spcb));
+ }
+ SVC(rercd = serial_rea_chr(p_spcb, &c), rercd);
+ *buf++ = c;
+ reacnt++;
+ buffer_empty = (bool_t) rercd;
+
+ /*
+ * エコーバック処理.
+ */
+ if ((p_spcb->ioctl & IOCTL_ECHO) != 0U) {
+ SVC(rercd = wai_sem(p_spcb->p_spinib->snd_semid),
+ gen_ercd_wait(rercd, p_spcb));
+ SVC(rercd = serial_wri_chr(p_spcb, c), rercd);
+ if (!((bool_t) rercd)) {
+ SVC(sig_sem(p_spcb->p_spinib->snd_semid),
+ gen_ercd_sys(p_spcb));
+ }
+ }
+ }
+ if (!buffer_empty) {
+ SVC(sig_sem(p_spcb->p_spinib->rcv_semid), gen_ercd_sys(p_spcb));
+ }
+ ercd = E_OK;
+
+ error_exit:
+ return(reacnt > 0U ? (ER_UINT) reacnt : ercd);
+}
+
+/*
+ * シリアルポートの制御(サービスコール)
+ */
+ER
+serial_ctl_por(ID portid, uint_t ioctl)
+{
+ SPCB *p_spcb;
+
+ if (sns_dpn()) { /* コンテキストのチェック */
+ return(E_CTX);
+ }
+ if (!(1 <= portid && portid <= TNUM_PORT)) {
+ return(E_ID); /* ポート番号のチェック */
+ }
+
+ p_spcb = get_spcb(portid);
+ if (!(p_spcb->openflag)) { /* オープン済みかのチェック */
+ return(E_OBJ);
+ }
+ if (p_spcb->errorflag) { /* エラー状態かのチェック */
+ return(E_SYS);
+ }
+
+ p_spcb->ioctl = ioctl;
+ return(E_OK);
+}
+
+/*
+ * シリアルポート状態の参照(サービスコール)
+ */
+ER
+serial_ref_por(ID portid, T_SERIAL_RPOR *pk_rpor)
+{
+ SPCB *p_spcb;
+
+ if (sns_dpn()) { /* コンテキストのチェック */
+ return(E_CTX);
+ }
+ if (!(1 <= portid && portid <= TNUM_PORT)) {
+ return(E_ID); /* ポート番号のチェック */
+ }
+
+ p_spcb = get_spcb(portid);
+ if (!(p_spcb->openflag)) { /* オープン済みかのチェック */
+ return(E_OBJ);
+ }
+ if (p_spcb->errorflag) { /* エラー状態かのチェック */
+ return(E_SYS);
+ }
+
+ pk_rpor->reacnt = p_spcb->rcv_count;
+ pk_rpor->wricnt = p_spcb->snd_count;
+ return(E_OK);
+}
+
+/*
+ * シリアルポートからの送信可能コールバック
+ */
+void
+sio_irdy_snd(intptr_t exinf)
+{
+ SPCB *p_spcb;
+
+ p_spcb = (SPCB *) exinf;
+ if (p_spcb->rcv_fc_chr != '\0') {
+ /*
+ * START/STOP を送信する.
+ */
+ (void) sio_snd_chr(p_spcb->p_siopcb, p_spcb->rcv_fc_chr);
+ p_spcb->rcv_fc_chr = '\0';
+ }
+ else if (!(p_spcb->snd_stopped) && p_spcb->snd_count > 0U) {
+ /*
+ * 送信バッファ中から文字を取り出して送信する.
+ */
+ (void) sio_snd_chr(p_spcb->p_siopcb,
+ p_spcb->p_spinib->snd_buffer[p_spcb->snd_read_ptr]);
+ INC_PTR(p_spcb->snd_read_ptr, p_spcb->p_spinib->snd_bufsz);
+ if (p_spcb->snd_count == p_spcb->p_spinib->snd_bufsz) {
+ if (isig_sem(p_spcb->p_spinib->snd_semid) < 0) {
+ p_spcb->errorflag = true;
+ }
+ }
+ p_spcb->snd_count--;
+ }
+ else {
+ /*
+ * 送信すべき文字がない場合は,送信可能コールバックを禁止する.
+ */
+ sio_dis_cbr(p_spcb->p_siopcb, SIO_RDY_SND);
+ }
+}
+
+/*
+ * シリアルポートからの受信通知コールバック
+ */
+void
+sio_irdy_rcv(intptr_t exinf)
+{
+ SPCB *p_spcb;
+ char_t c;
+
+ p_spcb = (SPCB *) exinf;
+ c = (char_t) sio_rcv_chr(p_spcb->p_siopcb);
+ if ((p_spcb->ioctl & IOCTL_FCSND) != 0U && c == FC_STOP) {
+ /*
+ * 送信を一時停止する.送信中の文字はそのまま送信する.
+ */
+ p_spcb->snd_stopped = true;
+ }
+ else if (p_spcb->snd_stopped && (c == FC_START
+ || (p_spcb->ioctl & IOCTL_FCANY) != 0U)) {
+ /*
+ * 送信を再開する.
+ */
+ p_spcb->snd_stopped = false;
+ if (p_spcb->snd_count > 0U) {
+ c = p_spcb->p_spinib->snd_buffer[p_spcb->snd_read_ptr];
+ if (serial_snd_chr(p_spcb, c)) {
+ INC_PTR(p_spcb->snd_read_ptr, p_spcb->p_spinib->snd_bufsz);
+ if (p_spcb->snd_count == p_spcb->p_spinib->snd_bufsz) {
+ if (isig_sem(p_spcb->p_spinib->snd_semid) < 0) {
+ p_spcb->errorflag = true;
+ }
+ }
+ p_spcb->snd_count--;
+ }
+ }
+ }
+ else if ((p_spcb->ioctl & IOCTL_FCSND) != 0U && c == FC_START) {
+ /*
+ * 送信に対してフロー制御している場合,START は捨てる.
+ */
+ }
+ else if (p_spcb->rcv_count == p_spcb->p_spinib->rcv_bufsz) {
+ /*
+ * バッファフルの場合,受信した文字を捨てる.
+ */
+ }
+ else {
+ /*
+ * 受信した文字を受信バッファに入れる.
+ */
+ p_spcb->p_spinib->rcv_buffer[p_spcb->rcv_write_ptr] = c;
+ INC_PTR(p_spcb->rcv_write_ptr, p_spcb->p_spinib->rcv_bufsz);
+ if (p_spcb->rcv_count == 0U) {
+ if (isig_sem(p_spcb->p_spinib->rcv_semid) < 0) {
+ p_spcb->errorflag = true;
+ }
+ }
+ p_spcb->rcv_count++;
+
+ /*
+ * STOPを送信する.
+ */
+ if ((p_spcb->ioctl & IOCTL_FCRCV) != 0U && !(p_spcb->rcv_stopped)
+ && p_spcb->rcv_count
+ >= BUFCNT_STOP(p_spcb->p_spinib->rcv_bufsz)) {
+ if (!serial_snd_chr(p_spcb, FC_STOP)) {
+ p_spcb->rcv_fc_chr = FC_STOP;
+ }
+ p_spcb->rcv_stopped = true;
+ }
+ }
+}
+
+/*
+ * シリアルインタフェースドライバからの未送信文字の取出し
+ */
+bool_t
+serial_get_chr(ID portid, char_t *p_c)
+{
+ SPCB *p_spcb;
+
+ if (1 <= portid && portid <= TNUM_PORT) { /* ポート番号のチェック */
+ p_spcb = get_spcb(portid);
+ if (p_spcb->openflag) { /* オープン済みかのチェック */
+ if (p_spcb->snd_count > 0U) {
+ *p_c = p_spcb->p_spinib->snd_buffer[p_spcb->snd_read_ptr];
+ INC_PTR(p_spcb->snd_read_ptr, p_spcb->p_spinib->snd_bufsz);
+ p_spcb->snd_count--;
+ return(true);
+ }
+ }
+ }
+ return(false);
+}
--- /dev/null
+/*
+ * @(#) $Id: serial.cfg 823 2008-03-18 13:02:11Z hiro $
+ */
+
+/*
+ * シリアルインタフェースドライバのコンフィギュレーションファイル
+ */
+
+#include "target_syssvc.h"
+INCLUDE("target_serial.cfg");
+
+#include "syssvc/serial.h"
+ATT_INI({ TA_NULL, 0, serial_initialize });
+
+CRE_SEM(SERIAL_RCV_SEM1, { TA_TPRI, 0, 1 });
+CRE_SEM(SERIAL_SND_SEM1, { TA_TPRI, 1, 1 });
+#if TNUM_PORT >= 2
+CRE_SEM(SERIAL_RCV_SEM2, { TA_TPRI, 0, 1 });
+CRE_SEM(SERIAL_SND_SEM2, { TA_TPRI, 1, 1 });
+#endif /* TNUM_PORT >= 2 */
+#if TNUM_PORT >= 3
+CRE_SEM(SERIAL_RCV_SEM3, { TA_TPRI, 0, 1 });
+CRE_SEM(SERIAL_SND_SEM3, { TA_TPRI, 1, 1 });
+#endif /* TNUM_PORT >= 3 */
+#if TNUM_PORT >= 4
+CRE_SEM(SERIAL_RCV_SEM4, { TA_TPRI, 0, 1 });
+CRE_SEM(SERIAL_SND_SEM4, { TA_TPRI, 1, 1 });
+#endif /* TNUM_PORT >= 4 */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: serial.h 1176 2008-07-01 10:24:46Z ertl-hiro $
+ */
+
+/*
+ * シリアルインタフェースドライバ
+ */
+
+#ifndef TOPPERS_SERIAL_H
+#define TOPPERS_SERIAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * シリアルインタフェースドライバの用いるパケット
+ */
+typedef struct {
+ uint_t reacnt; /* 受信バッファ中の文字数 */
+ uint_t wricnt; /* 送信バッファ中の文字数 */
+} T_SERIAL_RPOR;
+
+/*
+ * シリアルインタフェースドライバの初期化ルーチン
+ */
+extern void serial_initialize(intptr_t exinf) throw();
+
+/*
+ * シリアルインタフェースドライバからの未送信文字の取出し
+ */
+extern bool_t serial_get_chr(ID portid, char_t *p_c) throw();
+
+/*
+ * シリアルインタフェースドライバのサービスコール
+ */
+extern ER serial_opn_por(ID portid) throw();
+extern ER serial_cls_por(ID portid) throw();
+extern ER_UINT serial_rea_dat(ID portid, char_t *buf, uint_t len) throw();
+extern ER_UINT serial_wri_dat(ID portid, const char_t *buf, uint_t len)
+ throw();
+extern ER serial_ctl_por(ID portid, uint_t ioctl) throw();
+extern ER serial_ref_por(ID portid, T_SERIAL_RPOR *pk_rpor) throw();
+
+/*
+ * シリアルインタフェースドライバの動作制御用のための定数
+ *
+ * 以下の定数は,ビット毎に論理和をとって用いる.
+ */
+#define IOCTL_NULL 0U /* 指定なし */
+#define IOCTL_ECHO 0x0001U /* 受信した文字をエコーバック */
+#define IOCTL_CRLF 0x0010U /* LFを送信する前にCRを付加 */
+#define IOCTL_FCSND 0x0100U /* 送信に対してフロー制御を行う */
+#define IOCTL_FCANY 0x0200U /* どのような文字でも送信再開 */
+#define IOCTL_FCRCV 0x0400U /* 受信に対してフロー制御を行う */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_SERIAL_H */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * $Id: syslog.c 1846 2010-07-14 07:37:41Z ertl-hiro $
+ */
+
+/*
+ * システムログ機能
+ */
+
+#include <sil.h>
+#undef TOPPERS_OMIT_SYSLOG
+#include <t_syslog.h>
+#include <log_output.h>
+#include "target_syssvc.h"
+#include "syslog.h"
+
+/*
+ * トレースログマクロのデフォルト定義
+ */
+#ifndef LOG_SYSLOG_WRI_LOG_ENTER
+#define LOG_SYSLOG_WRI_LOG_ENTER(prio, p_syslog)
+#endif /* LOG_SYSLOG_WRI_LOG_ENTER */
+
+#ifndef LOG_SYSLOG_WRI_LOG_LEAVE
+#define LOG_SYSLOG_WRI_LOG_LEAVE(ercd)
+#endif /* LOG_SYSLOG_WRI_LOG_LEAVE */
+
+#ifndef LOG_SYSLOG_REA_LOG_ENTER
+#define LOG_SYSLOG_REA_LOG_ENTER(p_syslog)
+#endif /* LOG_SYSLOG_REA_LOG_ENTER */
+
+#ifndef LOG_SYSLOG_REA_LOG_LEAVE
+#define LOG_SYSLOG_REA_LOG_LEAVE(ercd, p_syslog)
+#endif /* LOG_SYSLOG_REA_LOG_LEAVE */
+
+#ifndef LOG_SYSLOG_MSK_LOG_ENTER
+#define LOG_SYSLOG_MSK_LOG_ENTER(logmask, lowmask)
+#endif /* LOG_SYSLOG_MSK_LOG_ENTER */
+
+#ifndef LOG_SYSLOG_MSK_LOG_LEAVE
+#define LOG_SYSLOG_MSK_LOG_LEAVE(ercd)
+#endif /* LOG_SYSLOG_MSK_LOG_LEAVE */
+
+#ifndef LOG_SYSLOG_REF_LOG_ENTER
+#define LOG_SYSLOG_REF_LOG_ENTER(pk_rlog)
+#endif /* LOG_SYSLOG_REF_LOG_ENTER */
+
+#ifndef LOG_SYSLOG_REF_LOG_LEAVE
+#define LOG_SYSLOG_REF_LOG_LEAVE(pk_rlog)
+#endif /* LOG_SYSLOG_REF_LOG_LEAVE */
+
+/*
+ * 現在のシステム時刻
+ *
+ * ログ時刻を取り出すために,やむなく,カーネルの内部変数を参照してい
+ * る.
+ */
+extern ulong_t _kernel_current_time;
+
+/*
+ * ログバッファとそれにアクセスするためのポインタ
+ */
+static SYSLOG syslog_buffer[TCNT_SYSLOG_BUFFER]; /* ログバッファ */
+static uint_t syslog_count; /* ログバッファ中のログの数 */
+static uint_t syslog_head; /* 先頭のログの格納位置 */
+static uint_t syslog_tail; /* 次のログの格納位置 */
+static uint_t syslog_lost; /* 失われたログの数 */
+
+/*
+ * 出力すべきログ情報の重要度(ビットマップ)
+ */
+static uint_t syslog_logmask; /* ログバッファに記録すべき重要度 */
+static uint_t syslog_lowmask_not; /* 低レベル出力すべき重要度(反転)*/
+
+/*
+ * システムログ機能の初期化
+ */
+void
+syslog_initialize(intptr_t exinf)
+{
+ syslog_count = 0U;
+ syslog_head = syslog_tail = 0U;
+ syslog_lost = 0U;
+ syslog_logmask = 0U;
+ syslog_lowmask_not = 0U;
+}
+
+/*
+ * ログ情報の出力
+ *
+ * CPUロック状態や実行コンテキストによらず動作できるように実装してある.
+ */
+ER
+syslog_wri_log(uint_t prio, const SYSLOG *p_syslog)
+{
+ SIL_PRE_LOC;
+
+ LOG_SYSLOG_WRI_LOG_ENTER(prio, p_syslog);
+ SIL_LOC_INT();
+
+ /*
+ * ログ時刻の設定
+ */
+ ((SYSLOG *) p_syslog)->logtim = _kernel_current_time;
+
+ /*
+ * ログバッファに記録
+ */
+ if ((syslog_logmask & LOG_MASK(prio)) != 0U) {
+ syslog_buffer[syslog_tail] = *p_syslog;
+ syslog_tail++;
+ if (syslog_tail >= TCNT_SYSLOG_BUFFER) {
+ syslog_tail = 0U;
+ }
+ if (syslog_count < TCNT_SYSLOG_BUFFER) {
+ syslog_count++;
+ }
+ else {
+ syslog_head = syslog_tail;
+ syslog_lost++;
+ }
+ }
+
+ /*
+ * 低レベル出力
+ */
+ if (((~syslog_lowmask_not) & LOG_MASK(prio)) != 0U) {
+ syslog_print(p_syslog, target_fput_log);
+ (*target_fput_log)('\n');
+ }
+
+ SIL_UNL_INT();
+ LOG_SYSLOG_WRI_LOG_LEAVE(E_OK);
+ return(E_OK);
+}
+
+/*
+ * ログバッファからの読出し
+ *
+ * CPUロック状態や実行コンテキストによらず動作できるように実装してある.
+ */
+ER_UINT
+syslog_rea_log(SYSLOG *p_syslog)
+{
+ ER_UINT ercd;
+ SIL_PRE_LOC;
+
+ LOG_SYSLOG_REA_LOG_ENTER(p_syslog);
+ SIL_LOC_INT();
+
+ /*
+ * ログバッファからの取出し
+ */
+ if (syslog_count > 0U) {
+ *p_syslog = syslog_buffer[syslog_head];
+ syslog_count--;
+ syslog_head++;
+ if (syslog_head >= TCNT_SYSLOG_BUFFER) {
+ syslog_head = 0U;
+ }
+ ercd = (ER_UINT) syslog_lost;
+ syslog_lost = 0U;
+ }
+ else {
+ ercd = E_OBJ;
+ }
+
+ SIL_UNL_INT();
+ LOG_SYSLOG_REA_LOG_LEAVE(ercd, p_syslog);
+ return(ercd);
+}
+
+/*
+ * 出力すべきログ情報の重要度の設定
+ */
+ER
+syslog_msk_log(uint_t logmask, uint_t lowmask)
+{
+ LOG_SYSLOG_MSK_LOG_ENTER(logmask, lowmask);
+ syslog_logmask = logmask;
+ syslog_lowmask_not = ~lowmask;
+ LOG_SYSLOG_MSK_LOG_LEAVE(E_OK);
+ return(E_OK);
+}
+
+/*
+ * ログバッファの状態参照
+ */
+ER_UINT
+syslog_ref_log(T_SYSLOG_RLOG *pk_rlog)
+{
+ SIL_PRE_LOC;
+
+ LOG_SYSLOG_REF_LOG_ENTER(pk_rlog);
+ SIL_LOC_INT();
+
+ pk_rlog->count = syslog_count;
+ pk_rlog->lost = syslog_lost;
+ pk_rlog->logmask = syslog_logmask;
+ pk_rlog->lowmask = ~syslog_lowmask_not;
+
+ SIL_UNL_INT();
+ LOG_SYSLOG_REF_LOG_LEAVE(pk_rlog);
+ return(E_OK);
+}
--- /dev/null
+/*
+ * $Id: syslog.cfg 1788 2010-05-16 21:06:02Z ertl-hiro $
+ */
+
+/*
+ * システムログ機能のコンフィギュレーションファイル
+ */
+
+#include "syssvc/syslog.h"
+ATT_INI({ TA_NULL, 0, syslog_initialize });
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * $Id: syslog.h 1788 2010-05-16 21:06:02Z ertl-hiro $
+ */
+
+/*
+ * システムログ機能
+ */
+
+#ifndef TOPPERS_SYSLOG_H
+#define TOPPERS_SYSLOG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * システムログ出力を行うための定義
+ */
+#include <t_syslog.h>
+
+/*
+ * ログバッファとそれにアクセスするためのポインタ
+ */
+#ifndef TCNT_SYSLOG_BUFFER
+#define TCNT_SYSLOG_BUFFER 64 /* ログバッファのサイズ */
+#endif /* TCNT_SYSLOG_BUFFER */
+
+/*
+ * システムログ機能の初期化
+ */
+extern void syslog_initialize(intptr_t exinf) throw();
+
+/*
+ * ログ情報の出力
+ */
+extern ER syslog_wri_log(uint_t prio, const SYSLOG *p_syslog) throw();
+
+/*
+ * ログバッファからのログ情報の読出し
+ */
+extern ER_UINT syslog_rea_log(SYSLOG *p_syslog) throw();
+
+/*
+ * 出力すべきログ情報の重要度の設定
+ */
+extern ER syslog_msk_log(uint_t logmask, uint_t lowmask) throw();
+
+/*
+ * ログバッファの状態参照
+ */
+extern ER syslog_ref_log(T_SYSLOG_RLOG *pk_rlog) throw();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TOPPERS_SYSLOG_H */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2004-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: vasyslog.c 755 2008-03-07 17:42:37Z hiro $
+ */
+
+/*
+ * 可変数引数のシステムログライブラリ
+ */
+
+#include <t_stddef.h>
+#include <t_syslog.h>
+#include <stdarg.h>
+
+void
+syslog(uint_t prio, const char *format, ...)
+{
+ SYSLOG syslog;
+ va_list ap;
+ uint_t i;
+ char c;
+ bool_t lflag;
+
+ syslog.logtype = LOG_TYPE_COMMENT;
+ syslog.loginfo[0] = (intptr_t) format;
+ i = 1U;
+ va_start(ap, format);
+
+ while ((c = *format++) != '\0' && i < TMAX_LOGINFO) {
+ if (c != '%') {
+ continue;
+ }
+
+ lflag = false;
+ c = *format++;
+ while ('0' <= c && c <= '9') {
+ c = *format++;
+ }
+ if (c == 'l') {
+ lflag = true;
+ c = *format++;
+ }
+ switch (c) {
+ case 'd':
+ syslog.loginfo[i++] = lflag ? (intptr_t) va_arg(ap, long_t)
+ : (intptr_t) va_arg(ap, int_t);
+ break;
+ case 'u':
+ case 'x':
+ case 'X':
+ syslog.loginfo[i++] = lflag ? (intptr_t) va_arg(ap, ulong_t)
+ : (intptr_t) va_arg(ap, uint_t);
+ break;
+ case 'p':
+ syslog.loginfo[i++] = (intptr_t) va_arg(ap, void *);
+ break;
+ case 'c':
+ syslog.loginfo[i++] = (intptr_t) va_arg(ap, int);
+ break;
+ case 's':
+ syslog.loginfo[i++] = (intptr_t) va_arg(ap, const char *);
+ break;
+ case '\0':
+ format--;
+ break;
+ default:
+ break;
+ }
+ }
+ va_end(ap);
+ (void) syslog_wri_log(prio, &syslog);
+}
--- /dev/null
+E_PACKAGE asp_lpc1768_generic_gcc
+VERSION %date
+
+INCLUDE ../../MANIFEST
+INCLUDE ../../cfg/MANIFEST
+INCLUDE ../../arch/arm_m_gcc/MANIFEST
+INCLUDE ../../pdic/uart/MANIFEST
--- /dev/null
+PACKAGE asp_arch_arm_m_gcc
+
+asp.doxyfile
+doxygen.css
+E_PACKAGE
+MANIFEST
+Makefile.target
+lpc1768_generic.h
+lpc1768_debug.ld
+lpc1768_release.ld
+target.tf
+target_cfg1_out.h
+target_check.tf
+target_config.c
+target_config.h
+target_def.csv
+target_kernel.h
+target_rename.def
+target_rename.h
+target_serial.cfg
+target_serial.h
+target_sil.h
+target_stddef.h
+target_syssvc.h
+target_test.h
+target_timer.cfg
+target_timer.h
+target_unrename.h
+target_user.txt
+
+
--- /dev/null
+#
+# Makefile のターゲット依存部(LPC1768用)
+#
+
+#
+# ボード名,プロセッサ名,開発環境名の定義
+# それぞれの名前はディレクトリ名に対応していることに注意。
+#
+PRC = arm_m
+CHIP = lpc17xx
+TOOL = gcc
+BOARD = lpc1768_generic
+
+#
+# for LPCXpresso environment.
+#
+CDEFS=-DDEBUG -D__CODE_RED -D__REDLIB__
+
+#
+# コンパイルオプション
+#
+INCLUDES := $(INCLUDES) -I$(TARGETDIR)
+CDEFS := $(CDEFS)
+COPTS := $(COPTS)
+
+#
+# カーネルに関する定義
+#
+KERNEL_DIR := $(KERNEL_DIR) $(TARGETDIR)
+KERNEL_ASMOBJS := $(KERNEL_ASMOBJS)
+KERNEL_COBJS := $(KERNEL_COBJS) target_config.o
+KERNEL_CFLAGS := $(KERNEL_CFLAGS)
+
+#
+# システムサービスに関する定義
+#
+SYSSVC_DIR := $(SYSSVC_DIR)
+SYSSVC_COBJS := $(SYSSVC_COBJS)
+
+#
+# コンフィギュレータ関係の変数の定義
+#
+CFG_TABS := $(CFG_TABS) --cfg1-def-table $(TARGETDIR)/target_def.csv
+
+#
+# リンカスクリプトの定義
+#
+ifeq ($(MAKECMDGOALS),debug)
+LDSCRIPT = $(SRCDIR)/target/$(BOARD)_$(TOOL)/lpc1768_debug.ld
+else
+LDSCRIPT = $(SRCDIR)/target/$(BOARD)_$(TOOL)/lpc1768_release.ld
+endif
+
+#
+# Intel Hexファイルの生成
+#
+$(OBJNAME).hex: $(OBJFILE)
+ $(OBJCOPY) -O ihex -S $(OBJFILE) $(OBJNAME).hex
+
+CLEAN_FILES := $(CLEAN_FILES) $(OBJNAME).hex
+# 依存関係の定義
+#
+cfg1_out.c: $(TARGETDIR)/target_def.csv
+kernel_cfg.timestamp: $(TARGETDIR)/target.tf
+$(OBJFILE): $(TARGETDIR)/target_check.tf
+all: $(OBJNAME).hex
+sram: all
+
+
+#
+# プロセッサ依存部のインクルード
+#
+include $(SRCDIR)/chip/$(CHIP)_$(TOOL)/Makefile.chip
--- /dev/null
+# Doxyfile 1.6.3
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = "LPC1768 Generic dependent part"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = 1.6.0
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY =
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak,
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH = /home/takemasa/asp/
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it parses.
+# With this tag you can assign which parser to use for a given extension.
+# Doxygen has a built-in mapping, but you can override or extend it using this tag.
+# The format is ext=language, where ext is a file extension, and language is one of
+# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP,
+# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat
+# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran),
+# use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen to replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penality.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will rougly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = YES
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = YES
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
+# will list include files with double quotes in the documentation
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST = YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by
+# doxygen. The layout file controls the global structure of the generated output files
+# in an output format independent way. The create the layout file that represents
+# doxygen's defaults, run doxygen with the -l option. You can optionally specify a
+# file name after the option, if omitted DoxygenLayout.xml will be used as the name
+# of the layout file.
+
+LAYOUT_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = . ../../chip/lpc17xx_gcc ../../chip/lpc17xx_gcc/cmsis ../../pdic/uart ../../arch/arm_m_gcc
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS =
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.
+# Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET = doxygen.css
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP = YES
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER
+# are set, an additional index file will be generated that can be used as input for
+# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated
+# HTML documentation.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add.
+# For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
+# will be generated, which together with the HTML files, form an Eclipse help
+# plugin. To install this plugin and make it available under the help contents
+# menu in Eclipse, the contents of the directory containing the HTML and XML
+# files needs to be copied into the plugins directory of eclipse. The name of
+# the directory within the plugins directory should be the same as
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before the help appears.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have
+# this name.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
+# and Class Hierarchy pages using a tree view instead of an ordered list.
+
+USE_INLINE_TREES = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) there is already a search function so this one should
+# typically be disabled. For large projects the javascript based search engine
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE = NO
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be implemented using a PHP enabled web server instead of at the web client using Javascript. Doxygen will generate the search PHP script and index
+# file to put on the web server. The advantage of the server based approach is that it scales better to large projects and allows full text search. The disadvances is that it is more difficult to setup
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+# Note that when enabling USE_PDFLATEX this option is only used for
+# generating bitmaps for formulas in the HTML output, but not in the
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# By default doxygen will write a font called FreeSans.ttf to the output
+# directory and reference it in all dot files that doxygen generates. This
+# font does not include all possible unicode characters however, so when you need
+# these (or just want a differently looking font) you can specify the font name
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
+# which can be done by putting it in a standard location or by setting the
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
+# containing the font.
+
+DOT_FONTNAME = FreeSans
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the output directory to look for the
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a
+# different font using DOT_FONTNAME you can set the path where dot
+# can find it using this tag.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = YES
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
--- /dev/null
+/* The standard CSS for doxygen */
+
+body, table, div, p, dl {
+ font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif;
+ font-size: 12px;
+}
+
+/* @group Heading Levels */
+
+h1 {
+ text-align: center;
+ font-size: 150%;
+}
+
+h2 {
+ font-size: 120%;
+}
+
+h3 {
+ font-size: 100%;
+}
+
+dt {
+ font-weight: bold;
+}
+
+div.multicol {
+ -moz-column-gap: 1em;
+ -webkit-column-gap: 1em;
+ -moz-column-count: 3;
+ -webkit-column-count: 3;
+}
+
+p.startli, p.startdd, p.starttd {
+ margin-top: 2px;
+}
+
+p.endli {
+ margin-bottom: 0px;
+}
+
+p.enddd {
+ margin-bottom: 4px;
+}
+
+p.endtd {
+ margin-bottom: 2px;
+}
+
+/* @end */
+
+caption {
+ font-weight: bold;
+}
+
+span.legend {
+ font-size: 70%;
+ text-align: center;
+}
+
+h3.version {
+ font-size: 90%;
+ text-align: center;
+}
+
+div.qindex, div.navtab{
+ background-color: #e8eef2;
+ border: 1px solid #84b0c7;
+ text-align: center;
+ margin: 2px;
+ padding: 2px;
+}
+
+div.qindex, div.navpath {
+ width: 100%;
+ line-height: 140%;
+}
+
+div.navtab {
+ margin-right: 15px;
+}
+
+/* @group Link Styling */
+
+a {
+ color: #153788;
+ font-weight: normal;
+ text-decoration: none;
+}
+
+.contents a:visited {
+ color: #1b77c5;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+a.qindex {
+ font-weight: bold;
+}
+
+a.qindexHL {
+ font-weight: bold;
+ background-color: #6666cc;
+ color: #ffffff;
+ border: 1px double #9295C2;
+}
+
+.contents a.qindexHL:visited {
+ color: #ffffff;
+}
+
+a.el {
+ font-weight: bold;
+}
+
+a.elRef {
+}
+
+a.code {
+ color: #3030f0;
+}
+
+a.codeRef {
+ color: #3030f0;
+}
+
+/* @end */
+
+dl.el {
+ margin-left: -1cm;
+}
+
+.fragment {
+ font-family: monospace, fixed;
+ font-size: 105%;
+}
+
+pre.fragment {
+ border: 1px solid #CCCCCC;
+ background-color: #f5f5f5;
+ padding: 4px 6px;
+ margin: 4px 8px 4px 2px;
+ overflow: auto;
+ word-wrap: break-word;
+ font-size: 9pt;
+ line-height: 125%;
+}
+
+div.ah {
+ background-color: black;
+ font-weight: bold;
+ color: #ffffff;
+ margin-bottom: 3px;
+ margin-top: 3px
+}
+
+div.groupHeader {
+ margin-left: 16px;
+ margin-top: 12px;
+ margin-bottom: 6px;
+ font-weight: bold;
+}
+
+div.groupText {
+ margin-left: 16px;
+ font-style: italic;
+}
+
+body {
+ background: white;
+ color: black;
+ margin-right: 20px;
+ margin-left: 20px;
+ margin-bottom: 1024px;
+}
+
+td.indexkey {
+ background-color: #e8eef2;
+ font-weight: bold;
+ border: 1px solid #CCCCCC;
+ margin: 2px 0px 2px 0;
+ padding: 2px 10px;
+}
+
+td.indexvalue {
+ background-color: #e8eef2;
+ border: 1px solid #CCCCCC;
+ padding: 2px 10px;
+ margin: 2px 0px;
+}
+
+tr.memlist {
+ background-color: #f0f0f0;
+}
+
+p.formulaDsp {
+ text-align: center;
+}
+
+img.formulaDsp {
+
+}
+
+img.formulaInl {
+ vertical-align: middle;
+}
+
+div.center {
+ text-align: center;
+ margin-top: 0px;
+ margin-bottom: 0px;
+ padding: 0px;
+}
+
+div.center img {
+ border: 0px;
+}
+
+img.footer {
+ border: 0px;
+ vertical-align: middle;
+}
+
+/* @group Code Colorization */
+
+span.keyword {
+ color: #008000
+}
+
+span.keywordtype {
+ color: #604020
+}
+
+span.keywordflow {
+ color: #e08000
+}
+
+span.comment {
+ color: #800000
+}
+
+span.preprocessor {
+ color: #806020
+}
+
+span.stringliteral {
+ color: #002080
+}
+
+span.charliteral {
+ color: #008080
+}
+
+span.vhdldigit {
+ color: #ff00ff
+}
+
+span.vhdlchar {
+ color: #000000
+}
+
+span.vhdlkeyword {
+ color: #700070
+}
+
+span.vhdllogic {
+ color: #ff0000
+}
+
+/* @end */
+
+.search {
+ color: #003399;
+ font-weight: bold;
+}
+
+form.search {
+ margin-bottom: 0px;
+ margin-top: 0px;
+}
+
+input.search {
+ font-size: 75%;
+ color: #000080;
+ font-weight: normal;
+ background-color: #e8eef2;
+}
+
+td.tiny {
+ font-size: 75%;
+}
+
+.dirtab {
+ padding: 4px;
+ border-collapse: collapse;
+ border: 1px solid #84b0c7;
+}
+
+th.dirtab {
+ background: #e8eef2;
+ font-weight: bold;
+}
+
+hr {
+ height: 0px;
+ border: none;
+ border-top: 1px solid #666;
+}
+
+hr.footer {
+ height: 1px;
+}
+
+/* @group Member Descriptions */
+
+.mdescLeft, .mdescRight,
+.memItemLeft, .memItemRight,
+.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
+ background-color: #FAFAFA;
+ border: none;
+ margin: 4px;
+ padding: 1px 0 0 8px;
+}
+
+.mdescLeft, .mdescRight {
+ padding: 0px 8px 4px 8px;
+ color: #555;
+}
+
+.memItemLeft, .memItemRight, .memTemplParams {
+ border-top: 1px solid #ccc;
+}
+
+.memItemLeft, .memTemplItemLeft {
+ white-space: nowrap;
+}
+
+.memTemplParams {
+ color: #606060;
+ white-space: nowrap;
+}
+
+/* @end */
+
+/* @group Member Details */
+
+/* Styles for detailed member documentation */
+
+.memtemplate {
+ font-size: 80%;
+ color: #606060;
+ font-weight: normal;
+ margin-left: 3px;
+}
+
+.memnav {
+ background-color: #e8eef2;
+ border: 1px solid #84b0c7;
+ text-align: center;
+ margin: 2px;
+ margin-right: 15px;
+ padding: 2px;
+}
+
+.memitem {
+ padding: 0;
+ margin-bottom: 10px;
+}
+
+.memname {
+ white-space: nowrap;
+ font-weight: bold;
+ margin-left: 6px;
+}
+
+.memproto {
+ border-top: 1px solid #84b0c7;
+ border-left: 1px solid #84b0c7;
+ border-right: 1px solid #84b0c7;
+ padding: 0;
+ background-color: #d5e1e8;
+ font-weight: bold;
+ /* firefox specific markup */
+ background-image: -moz-linear-gradient(rgba(228, 233, 245, 1.0) 0%, rgba(193, 205, 232, 1.0) 100%);
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+ -moz-border-radius-topright: 8px;
+ -moz-border-radius-topleft: 8px;
+ /* webkit specific markup */
+ background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(228, 233, 245, 1.0)), to(rgba(193, 205, 232, 1.0)));
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+ -webkit-border-top-right-radius: 8px;
+ -webkit-border-top-left-radius: 8px;
+
+}
+
+.memdoc {
+ border-bottom: 1px solid #84b0c7;
+ border-left: 1px solid #84b0c7;
+ border-right: 1px solid #84b0c7;
+ padding: 2px 5px;
+ background-color: #eef3f5;
+ border-top-width: 0;
+ /* firefox specific markup */
+ -moz-border-radius-bottomleft: 8px;
+ -moz-border-radius-bottomright: 8px;
+ -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+ /* webkit specific markup */
+ -webkit-border-bottom-left-radius: 8px;
+ -webkit-border-bottom-right-radius: 8px;
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+}
+
+.paramkey {
+ text-align: right;
+}
+
+.paramtype {
+ white-space: nowrap;
+}
+
+.paramname {
+ color: #602020;
+ white-space: nowrap;
+}
+.paramname em {
+ font-style: normal;
+}
+
+/* @end */
+
+/* @group Directory (tree) */
+
+/* for the tree view */
+
+.ftvtree {
+ font-family: sans-serif;
+ margin: 0.5em;
+}
+
+/* these are for tree view when used as main index */
+
+.directory {
+ font-size: 9pt;
+ font-weight: bold;
+}
+
+.directory h3 {
+ margin: 0px;
+ margin-top: 1em;
+ font-size: 11pt;
+}
+
+/*
+The following two styles can be used to replace the root node title
+with an image of your choice. Simply uncomment the next two styles,
+specify the name of your image and be sure to set 'height' to the
+proper pixel height of your image.
+*/
+
+/*
+.directory h3.swap {
+ height: 61px;
+ background-repeat: no-repeat;
+ background-image: url("yourimage.gif");
+}
+.directory h3.swap span {
+ display: none;
+}
+*/
+
+.directory > h3 {
+ margin-top: 0;
+}
+
+.directory p {
+ margin: 0px;
+ white-space: nowrap;
+}
+
+.directory div {
+ display: none;
+ margin: 0px;
+}
+
+.directory img {
+ vertical-align: -30%;
+}
+
+/* these are for tree view when not used as main index */
+
+.directory-alt {
+ font-size: 100%;
+ font-weight: bold;
+}
+
+.directory-alt h3 {
+ margin: 0px;
+ margin-top: 1em;
+ font-size: 11pt;
+}
+
+.directory-alt > h3 {
+ margin-top: 0;
+}
+
+.directory-alt p {
+ margin: 0px;
+ white-space: nowrap;
+}
+
+.directory-alt div {
+ display: none;
+ margin: 0px;
+}
+
+.directory-alt img {
+ vertical-align: -30%;
+}
+
+/* @end */
+
+address {
+ font-style: normal;
+ color: #333;
+}
+
+table.doxtable {
+ border-collapse:collapse;
+}
+
+table.doxtable td, table.doxtable th {
+ border: 1px solid #153788;
+ padding: 3px 7px 2px;
+}
+
+table.doxtable th {
+ background-color: #254798;
+ color: #FFFFFF;
+ font-size: 110%;
+ padding-bottom: 4px;
+ padding-top: 5px;
+ text-align:left;
+}
+
--- /dev/null
+/*
+ * GENERATED FILE - DO NOT EDIT
+ * (C) Code Red Technologies Ltd, 2008-10
+ * Generated linker script file for LPC1768
+ * Created from nxp_lpc17_c.ld (vLPCXpresso 3.8 (2 [Build 129] [31/01/2011] ))
+ * By LPCXpresso 3.8.2 [Build 129] [31/01/2011] on Mon Feb 21 16:49:44 PST 2011
+ */
+
+GROUP(libcr_c.a libcr_eabihelpers.a)
+
+MEMORY
+{
+ /* Define each memory region */
+ MFlash512 (rx) : ORIGIN = 0x0, LENGTH = 0x20000 /* 128k */
+ RamLoc32 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x8000 /* 32k */
+ RamAHB32 (rwx) : ORIGIN = 0x2007c000, LENGTH = 0x8000 /* 32k */
+
+}
+ /* Define a symbol for the top of each memory region */
+ __top_MFlash512 = 0x0 + 0x80000;
+ __top_RamLoc32 = 0x10000000 + 0x8000;
+ __top_RamAHB32 = 0x2007c000 + 0x8000;
+
+PROVIDE(hardware_init_hook = 0);
+PROVIDE(software_init_hook = 0);
+PROVIDE(software_term_hook = 0);
+
+STARTUP(start.o)
+ENTRY(_start)
+
+SECTIONS
+{
+ _vector_start_lma = ALIGN(8);
+
+ /* MAIN TEXT SECTION */
+ .text : ALIGN(4)
+ {
+ FILL(0xff)
+ KEEP(*(.vector))
+
+ /* Global Section Table */
+ . = ALIGN(4) ;
+ __section_table_start = .;
+ __data_section_table = .;
+ LONG(LOADADDR(.data));
+ LONG( ADDR(.data)) ;
+ LONG( SIZEOF(.data));
+ LONG(LOADADDR(.data_RAM2));
+ LONG( ADDR(.data_RAM2)) ;
+ LONG( SIZEOF(.data_RAM2));
+ __data_section_table_end = .;
+ __bss_section_table = .;
+ LONG( ADDR(.bss));
+ LONG( SIZEOF(.bss));
+ LONG( ADDR(.bss_RAM2));
+ LONG( SIZEOF(.bss_RAM2));
+ __bss_section_table_end = .;
+ __section_table_end = . ;
+ /* End of Global Section Table */
+
+
+ *(.after_vectors*)
+
+ *(.text*)
+ *(.rodata .rodata.*)
+ . = ALIGN(4);
+
+ } > MFlash512
+
+ /*
+ * for exception handling/unwind - some Newlib functions (in common
+ * with C++ and STDC++) use this.
+ */
+ .ARM.extab : ALIGN(4)
+ {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ } > MFlash512
+ __exidx_start = .;
+
+ .ARM.exidx : ALIGN(4)
+ {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } > MFlash512
+ __exidx_end = .;
+
+ _etext = .;
+
+
+ .data_RAM2 : ALIGN(4)
+ {
+ FILL(0xff)
+ *(.data.$RAM2*)
+ *(.data.$RamAHB32*)
+ . = ALIGN(4) ;
+ } > RamAHB32 AT>MFlash512
+
+ /* MAIN DATA SECTION */
+
+ .uninit_RESERVED : ALIGN(4)
+ {
+ KEEP(*(.bss.$RESERVED*))
+ } > RamLoc32
+
+ __idata_start = .;
+ .data : ALIGN(4)
+ {
+ FILL(0xff)
+ _data = .;
+ __data_start = .;
+ *(vtable)
+ *(.data*)
+ . = ALIGN(4) ;
+ _edata = .;
+ } > RamLoc32 AT>MFlash512
+ __idata_end = __idata_start + SIZEOF(.data);
+
+
+ .bss_RAM2 : ALIGN(4)
+ {
+ *(.bss.$RAM2*)
+ *(.bss.$RamAHB32*)
+ . = ALIGN(4) ;
+ } > RamAHB32
+
+ /* MAIN BSS SECTION */
+ .bss : ALIGN(4)
+ {
+ _bss = .;
+ __bss_start = .;
+ *(.bss*)
+ *(COMMON)
+ . = ALIGN(4) ;
+ _ebss = .;
+ __bss_end = .;
+ PROVIDE(end = .);
+ } > RamLoc32
+
+ PROVIDE(_pvHeapStart = .);
+ PROVIDE(_vStackTop = __top_RamLoc32 - 0);
+}
--- /dev/null
+/*
+ * TOPPERS/JSP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Just Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ * Copyright (C) 2010 by TOPPERS/ASP for LPC project
+ * http://sourceforge.jp/projects/toppersasp4lpc/
+ *
+ * 上記著作権者は,Free Software Foundation によって公表されている
+ * GNU General Public License の Version 2 に記述されている条件か,以
+ * 下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェア(本ソフトウェ
+ * アを改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
+ * 利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを再利用可能なバイナリコード(リロケータブルオブ
+ * ジェクトファイルやライブラリなど)の形で利用する場合には,利用
+ * に伴うドキュメント(利用者マニュアルなど)に,上記の著作権表示,
+ * この利用条件および下記の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを再利用不可能なバイナリコードの形または機器に組
+ * み込んだ形で利用する場合には,次のいずれかの条件を満たすこと.
+ * (a) 利用に伴うドキュメント(利用者マニュアルなど)に,上記の著作
+ * 権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 利用の形態を,別に定める方法によって,上記著作権者に報告する
+ * こと.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者を免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者は,
+ * 本ソフトウェアに関して,その適用可能性も含めて,いかなる保証も行わ
+ * ない.また,本ソフトウェアの利用により直接的または間接的に生じたい
+ * かなる損害に関しても,その責任を負わない.
+ *
+ */
+/**
+ * \defgroup TOPPERS_ASP TOPPERS/ASP
+ */
+/**
+ * \ingroup TOPPERS_ASP
+ * \defgroup TOPPERS_TARGET LPC1768 ターゲット依存部
+ */
+/* \{ */
+/**
+ * \file lpc1768_generic.h
+ * \brief ターゲットハードウェアに依存する宣言を納める
+ * \details
+ * アプリケーション、システムサービス、カーネルなどで利用されるハードウェア
+ * 関係の宣言をまとめるファイル。
+ */
+
+/**
+ * NXP社LPC1768用のターゲット依存部。TOPPERS/ASPターゲット非依存部1.6に対応している。
+ * 最新ソースコードは http://sourceforge.jp/projects/toppersasp4lpc/ より入手できる。
+ *
+ * クロックとして内蔵オシレーターを使用しているため、外部にオシレーターをつけなくても
+ * 動作させることができる。そのため、ほとんどのボードで動作する。オシレーターの設定を
+ * 変更する場合には、\ref target_config.cを変更するとよい。
+ *
+ * コンソールはシリアルポート1(UART0)を使用している。設定は 8 data bit, 1 start bit, 1 stop bit,
+ * none-parity, 57600baudである。使用するポートや速度を変更する場合には、\ref target_syssvc.hの内容を変更する。
+ *
+ * システム・タイマーはSYSTICK割り込みを使っている。
+ *
+ * ビルドするには、次のコマンドを実行してコンフィギュレータをビルドする。
+ * \code
+ * $ cd asp/cfg
+ * $ .configure
+ * $ make
+ * \endcode
+ *
+ * また、アプリケーションのビルド時には、makeあるいはmake sramを使用する。makeはROM化コードを生成し、
+ * make sramはSRAM上で走るデバッグ用コードを生成する。
+ */
+
+#ifndef TOPPERS_LPC1768_GENERIC_H
+#define TOPPERS_LPC1768_GENERIC_H
+
+#include <sil.h>
+
+/*
+ * システムクロックの定義(発振子周波数8MHz)
+ */
+/**
+ * \brief 内蔵クロックの発信周波数
+ * \details
+ * 内蔵発振器のクロック周波数[Hz]。SYS_CLOCKが参照する。LPC1768の場合は4MHzである。
+ */
+#define INTERNAL_CLOCK (4000000) // 内蔵発振器は4MHz
+
+/**
+ * \brief コア・クロック周波数
+ * \details
+ * CORTEX-M3コアに入力する動作クロックの周波数[Hz]。
+ */
+#define SYS_CLOCK (INTERNAL_CLOCK * 25) // コアに入力するクロック 100MHz
+
+
+#ifndef TOPPERS_MACRO_ONLY
+
+#endif /* TOPPERS_MACRO_ONLY */
+#endif /* TOPPERS_LPC1768_GENERIC_H */
+/* \} */
--- /dev/null
+/*
+ * GENERATED FILE - DO NOT EDIT
+ * (C) Code Red Technologies Ltd, 2008-10
+ * Generated linker script file for LPC1768
+ * Created from nxp_lpc17_c.ld (vLPCXpresso 3.8 (2 [Build 129] [31/01/2011] ))
+ * By LPCXpresso 3.8.2 [Build 129] [31/01/2011] on Mon Feb 21 16:49:51 PST 2011
+ */
+
+GROUP(libcr_c.a libcr_eabihelpers.a)
+
+MEMORY
+{
+ /* Define each memory region */
+ MFlash512 (rx) : ORIGIN = 0x0, LENGTH = 0x20000 /* 128k */
+ RamLoc32 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x8000 /* 32k */
+ RamAHB32 (rwx) : ORIGIN = 0x2007c000, LENGTH = 0x8000 /* 32k */
+
+}
+ /* Define a symbol for the top of each memory region */
+ __top_MFlash512 = 0x0 + 0x80000;
+ __top_RamLoc32 = 0x10000000 + 0x8000;
+ __top_RamAHB32 = 0x2007c000 + 0x8000;
+
+PROVIDE(hardware_init_hook = 0);
+PROVIDE(software_init_hook = 0);
+PROVIDE(software_term_hook = 0);
+
+STARTUP(start.o)
+ENTRY(_start)
+
+SECTIONS
+{
+ _vector_start_lma = ALIGN(8);
+
+ /* MAIN TEXT SECTION */
+ .text : ALIGN(4)
+ {
+ FILL(0xff)
+ KEEP(*(.vector))
+
+ /* Global Section Table */
+ . = ALIGN(4) ;
+ __section_table_start = .;
+ __data_section_table = .;
+ LONG(LOADADDR(.data));
+ LONG( ADDR(.data)) ;
+ LONG( SIZEOF(.data));
+ LONG(LOADADDR(.data_RAM2));
+ LONG( ADDR(.data_RAM2)) ;
+ LONG( SIZEOF(.data_RAM2));
+ __data_section_table_end = .;
+ __bss_section_table = .;
+ LONG( ADDR(.bss));
+ LONG( SIZEOF(.bss));
+ LONG( ADDR(.bss_RAM2));
+ LONG( SIZEOF(.bss_RAM2));
+ __bss_section_table_end = .;
+ __section_table_end = . ;
+ /* End of Global Section Table */
+
+
+ *(.after_vectors*)
+
+ *(.text*)
+ *(.rodata .rodata.*)
+ . = ALIGN(4);
+
+ } > MFlash512
+
+ /*
+ * for exception handling/unwind - some Newlib functions (in common
+ * with C++ and STDC++) use this.
+ */
+ .ARM.extab : ALIGN(4)
+ {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ } > MFlash512
+ __exidx_start = .;
+
+ .ARM.exidx : ALIGN(4)
+ {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } > MFlash512
+ __exidx_end = .;
+
+ _etext = .;
+
+
+ .data_RAM2 : ALIGN(4)
+ {
+ FILL(0xff)
+ *(.data.$RAM2*)
+ *(.data.$RamAHB32*)
+ . = ALIGN(4) ;
+ } > RamAHB32 AT>MFlash512
+
+ /* MAIN DATA SECTION */
+
+ .uninit_RESERVED : ALIGN(4)
+ {
+ KEEP(*(.bss.$RESERVED*))
+ } > RamLoc32
+
+ __idata_start = .;
+ .data : ALIGN(4)
+ {
+ FILL(0xff)
+ _data = .;
+ __data_start = .;
+ *(vtable)
+ *(.data*)
+ . = ALIGN(4) ;
+ _edata = .;
+ } > RamLoc32 AT>MFlash512
+ __idata_end = __idata_start + SIZEOF(.data);
+
+
+ .bss_RAM2 : ALIGN(4)
+ {
+ *(.bss.$RAM2*)
+ *(.bss.$RamAHB32*)
+ . = ALIGN(4) ;
+ } > RamAHB32
+
+ /* MAIN BSS SECTION */
+ .bss : ALIGN(4)
+ {
+ _bss = .;
+ __bss_start = .;
+ *(.bss*)
+ *(COMMON)
+ . = ALIGN(4) ;
+ _ebss = .;
+ __bss_end = .;
+ PROVIDE(end = .);
+ } > RamLoc32
+
+ PROVIDE(_pvHeapStart = .);
+ PROVIDE(_vStackTop = __top_RamLoc32 - 0);
+}
--- /dev/null
+/*
+* LPC1768のFlash ROM上でプログラムを動かすための最低限度のLDファイル。
+* 変数をSRAM上に配置する。Sourcery G++ 2010q1-188の
+* Generic-m-hosted.ldを修正して使用。
+*/
+
+OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
+ENTRY(_start)
+SEARCH_DIR(.)
+
+MEMORY
+{
+ rom_vector (rwx) : ORIGIN = 0x00000000, LENGTH = 256
+ rom (rwx) : ORIGIN = 0x00000100, LENGTH = 511K
+ ram(rx) : ORIGIN = 0x10000000, LENGTH = 32K
+}
+
+
+PROVIDE(hardware_init_hook = 0);
+PROVIDE(software_init_hook = 0);
+PROVIDE(software_term_hook = 0);
+STARTUP(start.o)
+
+SECTIONS
+{
+
+ _vector_start_lma = ALIGN(8);
+
+ .vector :
+ {
+ *(.vector)
+ } > rom_vector
+
+
+ .text :
+ {
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ *(.gnu.warning)
+ *(.glue_7t) *(.glue_7) *(.vfp11_veneer)
+
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ *(.gcc_except_table)
+ } >rom
+
+ .eh_frame_hdr : ALIGN (4)
+ {
+ KEEP (*(.eh_frame_hdr))
+ } >rom
+
+ /* .ARM.exidx is sorted, so has to go in its own output section. */
+ PROVIDE_HIDDEN (__exidx_start = .);
+ .ARM.exidx :
+ {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } >rom
+
+ PROVIDE_HIDDEN (__exidx_end = .);
+
+ .rodata : ALIGN (4)
+ {
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+
+ . = ALIGN(4);
+ KEEP(*(.init))
+
+ . = ALIGN(4);
+ __preinit_array_start = .;
+ KEEP (*(.preinit_array))
+ __preinit_array_end = .;
+
+ . = ALIGN(4);
+ __init_array_start = .;
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ __init_array_end = .;
+
+ . = ALIGN(4);
+ KEEP(*(.fini))
+
+ . = ALIGN(4);
+ __fini_array_start = .;
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ __fini_array_end = .;
+
+ . = ALIGN(0x4);
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+
+ . = ALIGN(0x4);
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ . = ALIGN (8);
+ _etext = .;
+ } >rom
+
+ __idata_start = ALIGN(8);
+ .data : AT (__idata_start )
+ {
+ . = ALIGN(8);
+ __data_start = .;
+ KEEP(*(.jcr))
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN (8);
+ *(.ram)
+ KEEP (*(.eh_frame))
+ . = ALIGN(8);
+ _edata = .;
+ } >ram
+ __idata_end = __idata_start + SIZEOF(.data);
+
+ .bss : ALIGN(8)
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN (8);
+ *(.ram.b .bss.ram)
+ _end = .;
+ __end = .;
+ __bss_end = .;
+ } >ram
+
+ .stab 0 (NOLOAD) : { *(.stab) }
+ .stabstr 0 (NOLOAD) : { *(.stabstr) }
+ /* DWARF debug sections.
+ * Symbols in the DWARF debugging sections are relative to
+ * the beginning of the section so we begin them at 0.
+ */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* DWARF 2.1 */
+ .debug_ranges 0 : { *(.debug_ranges) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+
+ .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
+ .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
+ /DISCARD/ : { *(.note.GNU-stack) }
+}
--- /dev/null
+/*
+* LPC1768のSRAM上でプログラムを動かすための最低限度のLDファイル。
+* すべての資源をSRAM上に配置する。Sourcery G++ 2010q1-188の
+* Generic-m-hosted.ldを修正して使用。
+*/
+
+OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
+ENTRY(_start)
+SEARCH_DIR(.)
+
+MEMORY
+{
+ rom (rwx) : ORIGIN = 0x00000000, LENGTH = 512K
+ ram (rx) : ORIGIN = 0x10000000, LENGTH = 32K
+}
+
+
+/* Provide fall-back values */
+PROVIDE( __data_start = 0x0 ); /* 以下の3シンボルはダミーだが、0でなければならない */
+PROVIDE( __idata_start = 0x0 );
+PROVIDE( __idata_end = 0x0 );
+PROVIDE( _vector_start = 0x0 ); /* SRAM版とROM版でコードを共有するためのダミー*/
+PROVIDE( _vector_end = 0x0 );
+
+
+PROVIDE(hardware_init_hook = 0);
+PROVIDE(software_init_hook = 0);
+PROVIDE(software_term_hook = 0);
+STARTUP(start.o)
+
+
+SECTIONS
+{
+ .text :
+ {
+ _vector_start_lma = .;
+ *( .vector ) /* RAM領域の先頭に割り当てているのは、 256byte境界を守るため */
+ *(.text .text.* .gnu.linkonce.t.*)
+ *(.plt)
+ *(.gnu.warning)
+ *(.glue_7t) *(.glue_7) *(.vfp11_veneer)
+
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ *(.gcc_except_table)
+ } >ram
+
+ .eh_frame_hdr : ALIGN (4)
+ {
+ KEEP (*(.eh_frame_hdr))
+ } >ram
+
+ .eh_frame : ALIGN (4)
+ {
+ KEEP (*(.eh_frame))
+ } >ram
+
+ /* .ARM.exidx is sorted, so has to go in its own output section. */
+ PROVIDE_HIDDEN (__exidx_start = .);
+ .ARM.exidx :
+ {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } >ram
+
+ PROVIDE_HIDDEN (__exidx_end = .);
+ .rodata : ALIGN (4)
+ {
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+
+ . = ALIGN(4);
+ KEEP(*(.init))
+
+ . = ALIGN(4);
+ __preinit_array_start = .;
+ KEEP (*(.preinit_array))
+ __preinit_array_end = .;
+
+ . = ALIGN(4);
+ __init_array_start = .;
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ __init_array_end = .;
+
+ . = ALIGN(4);
+ KEEP(*(.fini))
+
+ . = ALIGN(4);
+ __fini_array_start = .;
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ __fini_array_end = .;
+
+ . = ALIGN(0x4);
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*crtend.o(.ctors))
+
+ . = ALIGN(0x4);
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*crtend.o(.dtors))
+
+ . = ALIGN (8);
+ _etext = .;
+ } >ram
+
+ .data : ALIGN (8)
+ {
+ KEEP(*(.jcr))
+ *(.got.plt) *(.got)
+ *(.shdata)
+ *(.data .data.* .gnu.linkonce.d.*)
+ . = ALIGN (8);
+ *(.ram)
+ _edata = .;
+ } >ram
+
+ .bss :
+ {
+ __bss_start = .;
+ *(.shbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN (8);
+ *(.ram.b .bss.ram)
+ _end = .;
+ __end = .;
+ __bss_end = .;
+ } >ram
+
+ .stab 0 (NOLOAD) : { *(.stab) }
+ .stabstr 0 (NOLOAD) : { *(.stabstr) }
+ /* DWARF debug sections.
+ * Symbols in the DWARF debugging sections are relative to
+ * the beginning of the section so we begin them at 0.
+ */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* DWARF 2.1 */
+ .debug_ranges 0 : { *(.debug_ranges) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+
+ .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
+ .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
+ /DISCARD/ : { *(.note.GNU-stack) }
+}
--- /dev/null
+$
+$ パス2のターゲット依存テンプレート(NXP LPC1768用)
+$
+
+$
+$ プロセッサ依存のテンプレートファイルのインクルード
+$
+$INCLUDE"arm_m_gcc/prc.tf"$
--- /dev/null
+/**
+ * \addtogroup TOPPERS_TARGET
+ * \{
+ */
+
+/**
+ * \file target_cfg1_out.h
+ * \brief cfg1_out.cをリンクするために必要なスタブの定義
+ * \details
+ * ターゲット依存部で宣言することは何もない。
+ */
+
+/*
+ * チップ依存のスタブの定義を読み込む
+ */
+#include "chip_cfg1_out.h"
+
+/**
+ * \}
+ */
--- /dev/null
+$
+$ パス3のターゲット依存テンプレート(NXP LPC17XX汎用)
+$
+
+$
+$ パス3のチップ依存のテンプレートのインクルード
+$
+$INCLUDE"chip_check.tf"$
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ * Copyright (C) 2010 by TOPPERS/ASP for LPC project
+ * http://sourceforge.jp/projects/toppersasp4lpc/
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/**
+ * \addtogroup TOPPERS_TARGET
+ * \{
+ */
+
+/**
+ * \file target_config.c
+ * \brief カーネル実装のターゲット依存モジュール(NXP LPC1768用)
+ * \details
+ * カーネル構築に必要でターゲットに依存する定義をこのファイルで行う。
+ */
+#include "kernel_impl.h"
+#include <sil.h>
+#include "lpc1768_generic.h"
+#include "target_serial.h"
+#include "target_syssvc.h"
+
+/**
+ * \brief UART0のTX信号にピンを割り付けるためのビットフィールド定義
+ *
+ */
+#define PINSEL_UART0_TX 0x10
+
+/**
+ * \brief UART0のRX信号にピンを割り付けるためのビットフィールド定義
+ *
+ */
+#define PINSEL_UART0_RX 0x40
+
+/**
+ * \brief ターゲット依存部 初期化処理
+ * \details
+ * sta_ker() の中から呼び出されてターゲットのハードウェアの初期化を行う。この関数の中では
+ * PLLの初期化やペリフェラル・ピンの初期化などを行う。
+ */
+void target_initialize(void)
+{
+ /*
+ * チップ依存部の初期化。この呼び出しは削除してはいけない。
+ */
+ chip_initialize();
+
+ /*
+ * CMSISのSystemInitを使ってターゲットを初期化する。
+ */
+ SystemInit();
+
+ /*
+ * I/Oポートの初期化
+ */
+ /* bit5:4=01, bit7:6=01, ピンをUART0に割り当てる。*/
+ LPC_PINCON->PINSEL0 = PINSEL_UART0_TX | PINSEL_UART0_RX;
+
+ /*
+ * バナー出力用のシリアル初期化
+ */
+ target_uart_init(SIO_PORTID);
+}
+
+/**
+ * \brief ターゲット依存部 終了処理
+ * \details
+ * システム終了時にカーネルから呼ばれる。この関数は呼び出し元に戻らない。
+ */
+void target_exit(void)
+{
+ /* チップ依存部の終了処理 */
+ chip_exit();
+
+ while(1) {}
+}
+
+/**
+ * \brief システムログの低レベル出力のための文字出力
+ * \param c 出力キャラクタ
+ * \details
+ * コンソールに1文字出力する。チップ依存部が供給する出力関数をそのまま利用する。
+ */
+void target_fput_log(char_t c)
+{
+ chip_fput_log(c);
+}
+
+/**
+ * \}
+ */
+
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2005-2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ * Copyright (C) 2010 by TOPPERS/ASP for LPC project
+ * http://sourceforge.jp/projects/toppersasp4lpc/
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/**
+ * \addtogroup TOPPERS_TARGET
+ * \{
+ */
+
+#ifndef TOPPERS_TARGET_CONFIG_H
+#define TOPPERS_TARGET_CONFIG_H
+
+/**
+ * \file target_config.h
+ * \brief カーネル実装のターゲット依存部モジュール(NXP LPC1768用)
+ * \details
+ * カーネルのターゲット依存部のインクルードファイル.kernel_impl.hのター
+ * ゲット依存部の位置付けとなす.
+ */
+
+
+
+/**
+ * \brief デフォルトの非タスクコンテキスト用のスタック領域の定義
+ * \details
+ * 8の倍数として指定すること
+ */
+#define DEFAULT_ISTKSZ (512) /* 0.5kB */
+
+/**
+ * \brief 微少時間待ちのための定義(本来はSILのターゲット依存部)
+ * \details
+ * 値はtest_dly_nseアプリケーションを使って、SYSCLK=100MHz,
+ * SRAM実行時に更正した。
+ */
+#define SIL_DLY_TIM1 79
+
+/**
+ * \brief 微少時間待ちのための定義(本来はSILのターゲット依存部)
+ * \details
+ * 値はtest_dly_nseアプリケーションを使って、SYSCLK=100MHz,
+ * SRAM実行時に更正した。
+ */
+#define SIL_DLY_TIM2 50
+
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void target_exit(void);
+extern void target_initialize(void);
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+/*
+ * チップ依存部の読み込み
+ */
+#include "chip_config.h"
+
+#endif /* TOPPERS_TARGET_CONFIG_H */
+
+/**
+ * \}
+ */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ * Copyright (C) 2010 by TOPPERS/ASP for LPC project
+ * http://sourceforge.jp/projects/toppersasp4lpc/
+ *
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/**
+ * \addtogroup TOPPERS_TARGET
+ * \{
+ */
+
+/**
+ * \file target_kernel.h
+ * \brief kernel.hのターゲット依存部(NXP LPC17XX汎用)
+ * \details
+ *
+ * porting.txtの5章で解説されるターゲット依存部のカーネル定義ファイル。
+ *
+ * このインクルードファイルは,kernel.hでインクルードされる.他のファ
+ * イルから直接インクルードすることはない.このファイルをインクルード
+ * する前に,t_stddef.hがインクルードされるので,それらに依存してもよ
+ * い.
+ */
+
+#ifndef TOPPERS_TARGET_KERNEL_H
+#define TOPPERS_TARGET_KERNEL_H
+
+
+/*
+ * チップで共通な定義
+ */
+#include "chip_kernel.h"
+
+#endif /* TOPPERS_TARGET_KERNEL_H */
+
+/**
+ * \}
+ */
--- /dev/null
+INCLUDE "chip"
+
+# target_config.c
+target_initialize
+target_exit
+
+# trace_config.c
+log_dsp_enter
+log_dsp_leave
+log_inh_enter
+log_inh_leave
+log_exc_enter
+log_exc_leave
+
--- /dev/null
+/* This file is generated from target_rename.def by genrename. */
+
+#ifndef TOPPERS_TARGET_RENAME_H
+#define TOPPERS_TARGET_RENAME_H
+
+
+#define target_initialize _kernel_target_initialize
+#define target_exit _kernel_target_exit
+
+
+#ifdef TOPPERS_LABEL_ASM
+
+/*
+ * target_config.c
+ */
+#define _target_initialize __kernel_target_initialize
+#define _target_exit __kernel_target_exit
+
+ /*
+ * trace_config.c
+ */
+#define log_dsp_enter _kernel_log_dsp_enter
+#define log_dsp_leave _kernel_log_dsp_leave
+#define log_inh_enter _kernel_log_inh_enter
+#define log_inh_leave _kernel_log_inh_leave
+#define log_exc_enter _kernel_log_exc_enter
+#define log_exc_leave _kernel_log_exc_leave
+
+
+#endif /* TOPPERS_LABEL_ASM */
+
+#include "chip_rename.h"
+
+#endif /* TOPPERS_TARGET_RENAME_H */
--- /dev/null
+/*
+ * SIOドライバ(UART汎用)のコンフィグレーションファイル
+ */
+
+INCLUDE( "chip_serial.cfg" );
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ * Copyright (C) 2010 by TOPPERS/ASP for LPC project
+ * http://sourceforge.jp/projects/toppersasp4lpc/
+ *
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+
+/**
+ * \addtogroup TOPPERS_TARGET
+ * \{
+ */
+
+/**
+ * \file target_serial.h
+ * \brief シリアルI/Oデバイス(SIO)ドライバ(UART汎用)
+ * \details
+ * このファイルはchip_serial.hをそのまま読み込む。
+ * それによって、あらかじめ用意されているドライバを使用する。
+ */
+
+#ifndef TOPPERS_TARGET_SERIAL_H
+#define TOPPERS_TARGET_SERIAL_H
+
+#include "chip_serial.h"
+
+
+#endif /* TOPPERS_TARGET_SERIAL_H */
+
+/**
+ * \}
+ */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ * Copyright (C) 2010 by TOPPERS/ASP for LPC project
+ * http://sourceforge.jp/projects/toppersasp4lpc/
+ *
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/**
+ * \addtogroup TOPPERS_TARGET
+ * \{
+ */
+
+/**
+ * \file target_sil.h
+ * \brief sil.hのチップ依存部(NXP LPC17XX汎用)
+ * \details
+ *
+ * porting.txtの4章で説明されているsil.hのターゲット依存部。
+ *
+ * このインクルードファイルは,sil.hの先頭でインクルードされる.他のファ
+ * イルからは直接インクルードすることはない.このファイルをインクルー
+ * ドする前に,t_stddef.hがインクルードされるので,それらに依存しても
+ * よい.
+ */
+
+#ifndef TOPPERS_TARGET_SIL_H
+#define TOPPERS_TARGET_SIL_H
+
+
+/*
+ * チップで共通な定義
+ */
+#include "chip_sil.h"
+
+
+#endif /* TOPPERS_TARGET_SIL_H */
+
+/**
+ * \}
+ */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ * Copyright (C) 2010 by TOPPERS/ASP for LPC project
+ * http://sourceforge.jp/projects/toppersasp4lpc/
+ *
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/**
+ * \addtogroup TOPPERS_TARGET
+ * \{
+ */
+
+/**
+ * \file target_stddef.h
+ * \brief t_stddef.hのターゲット依存部(LPC1768汎用)
+ * \details
+ * porting.txtの3賞に示される、TOPPERS共通定義のターゲット依存部である。
+ *
+ * このインクルードファイルは,t_stddef.hの先頭でインクルードされる.
+ * 他のファイルからは直接インクルードすることはない.他のインクルード
+ * ファイルに先立って処理されるため,他のインクルードファイルに依存し
+ * てはならない.
+ */
+
+#ifndef TOPPERS_TARGET_STDDEF_H
+#define TOPPERS_TARGET_STDDEF_H
+
+#include "chip_stddef.h"
+
+/**
+ *
+ * \brief ターゲットを識別するためのマクロの定義
+ * \details
+ * porting.txtの規定により、"TOPPERS_"にターゲット識別名を
+ * 連結したものがターゲット識別マクロになる。
+ */
+#define TOPPERS_LPC1768_GENERIC /* ターゲット識別*/
+
+
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/*
+ * アサーションの失敗時の実行中断処理(T.B.D)
+ */
+Inline void
+TOPPERS_assert_abort(void)
+{
+ while(1);
+}
+
+#endif /* TOPPERS_MACRO_ONLY */
+#endif /* TOPPERS_TARGET_STDDEF_H */
+
+/**
+ * \}
+ */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ * Copyright (C) 2010 by TOPPERS/ASP for LPC project
+ * http://sourceforge.jp/projects/toppersasp4lpc/
+ *
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/**
+ * \addtogroup TOPPERS_TARGET
+ * \{
+ */
+
+/**
+ * \file target_syssvc.h
+ * \brief システムサービスのターゲット依存部(LPC1768用)
+ * \details
+ * porting.txt8章で示される、システムサービスのターゲット依存部。
+ *
+ * システムサービスのターゲット依存部のインクルードファイル.このファ
+ * イルの内容は,コンポーネント記述ファイルに記述され,このファイルは
+ * 無くなる見込み.
+ */
+
+#ifndef TOPPERS_TARGET_SYSSVC_H
+#define TOPPERS_TARGET_SYSSVC_H
+
+
+/*
+ * ターゲットシステムのハードウェア資源の定義
+ */
+#include "lpc1768_generic.h"
+/*
+ * チップ共有のハードウェア資源の読み込み
+ */
+#include "chip_syssvc.h"
+
+
+/**
+ * \brief 起動メッセージのターゲットシステム名
+ */
+#define TARGET_NAME "LPC1768 Generic"
+
+/*
+ * 起動メッセージにターゲット依存部の著作権表示を
+ * 追加する必要があるときには、このマクロを使う。
+ */
+#if 0
+#define TARGET_COPYRIGHT CHIP_COPYRIGHT "Copyright (C) 2010 by TOPPERS/ASP for LPC project\n http://sourceforge.jp/projects/toppersasp4lpc/"
+#else
+#define TARGET_COPYRIGHT CHIP_COPYRIGHT
+#endif
+
+/**
+ * \brief コンソールが使用するシリアルポートID
+ * \details
+ * UIF用コンソールに使用するポート番号である。ポート番号は1から始まる整数。
+ */
+#define SIO_PORTID (1)
+
+/**
+ * \brief UARTドライバが管理する内蔵UARTの数
+ */
+#define TNUM_SIOP_UART (1)
+
+/**
+ * \brief システムが管理するシリアル・ポートの総数
+ * \details
+ * この実装では内蔵UARTしか使用しないので、TNUM_PORT = TNUM_SIOP_UARTになる
+ */
+#define TNUM_PORT TNUM_SIOP_UART /* システムが管理するシリアルポートの総数 */
+
+/**
+ * \brief システムログ用のシリアルポート番号
+ * \details
+ * logtaskで使用する。1オリジン。
+ *
+ * システムログ用のシリアルポートは、コンソール用のシリアルポートと強要することが多い。
+ */
+#define LOGTASK_PORTID SIO_PORTID
+
+/**
+ * \brief シリアルポートのデフォルトボーレート
+ * \details
+ * TOPPERS/ASPのシリアルポート1に対するボーレート設定値である。
+ * シリアルポートの番号は1オリジンになっている。
+ * 特に設定しない限り、シリアルポートにはデフォルトの値が設定される。
+ * シリアルポートの速度を変えたければ、マクロSIO_BAUD_RATE_PORTxを宣言する。
+ */
+#define SIO_BAUD_RATE_DEFAULT (57600)
+
+//#define SIO_BAUD_RATE_PORT1 (57600)
+//#define SIO_BAUD_RATE_PORT2 (57600)
+//#define SIO_BAUD_RATE_PORT3 (57600)
+//#define SIO_BAUD_RATE_PORT4 (57600)
+
+/**
+ * \brief システムログの低レベル出力のための文字出力
+ * \details
+ * ターゲット依存の方法で,文字cを表示/出力/保存する.
+ */
+extern void target_fput_log(char_t c);
+
+#endif /* TOPPERS_TARGET_SYSSVC_H */
+/**
+ * \}
+ */
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ * Copyright (C) 2010 by TOPPERS/ASP for LPC project
+ * http://sourceforge.jp/projects/toppersasp4lpc/
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/**
+ * \addtogroup TOPPERS_TARGET
+ * \{
+ */
+
+/**
+ * \file target_test.h
+ * \brief テストプログラムのターゲット依存定義(NXP LPC1768用)
+ */
+
+#ifndef TOPPERS_TARGET_TEST_H
+#define TOPPERS_TARGET_TEST_H
+
+
+/**
+ * \brief sample1で使うタスクスタックのサイズ
+ * \details
+ * サンプルアプリケーション、sample1で使用するタスクのスタックサイズ。
+ * これを宣言しない場合にはデフォルトのスタックサイズが使用される。
+ */
+#define STACK_SIZE (2048)
+
+/*
+ * チップ依存モジュール(LPCM17xx用)
+ */
+#include "chip_test.h"
+
+#endif /* TOPPERS_TARGET_TEST_H */
+
+/**
+ * \}
+ */
--- /dev/null
+#include "target_timer.h"
+
+INCLUDE("chip_timer.cfg");
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ * Copyright (C) 2010 by TOPPERS/ASP for LPC project
+ * http://sourceforge.jp/projects/toppersasp4lpc/
+ *
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ */
+/**
+ * \addtogroup TOPPERS_TARGET
+ * \{
+ */
+
+/**
+ * \file target_timer.h
+ * \brief タイマドライバ(NXP LPC17XX汎用)
+ */
+
+#ifndef TOPPERS_TARGET_TIMER_H
+#define TOPPERS_TARGET_TIMER_H
+
+#include "target_syssvc.h"
+
+/*
+ * チップ依存部の定義
+ */
+#include "chip_timer.h"
+
+#endif /* TOPPERS_TARGET_TIMER_H */
+
+/**
+ * \}
+ */
--- /dev/null
+/* This file is generated from target_rename.def by genrename. */
+
+/* This file is included only when target_rename.h has been included. */
+#ifdef TOPPERS_TARGET_RENAME_H
+#undef TOPPERS_TARGET_RENAME_H
+
+
+#undef target_initialize
+#undef target_exit
+
+
+#ifdef TOPPERS_LABEL_ASM
+
+/*
+ * target_config.c
+ */
+#undef _target_initialize
+#undef _target_exit
+
+/*
+ * trace_config.c
+ */
+#undef log_dsp_enter
+#undef log_dsp_leave
+#undef log_inh_enter
+#undef log_inh_leave
+#undef log_exc_enter
+#undef log_exc_leave
+
+
+#endif /* TOPPERS_LABEL_ASM */
+
+#include "chip_unrename.h"
+
+#endif /* TOPPERS_TARGET_RENAME_H */
--- /dev/null
+=====================================================================
+ LPC1768 GENERICターゲット依存部 (asp-1.6.0対応)
+ Last Modified: 2010/Oct/23
+=====================================================================
+
+(1) 対応しているターゲットシステムの種類・構成,バージョン番号
+
+ ・ターゲットハードウェア(ボード等)の名称と対応している構成
+ NXP製LPC1768を使用したボード一般。発振器は内蔵発振器を使う。
+
+ ・ターゲット略称
+ lpc1768_generic_gcc
+
+ ・ターゲット非依存部のバージョン番号
+ 1.6
+
+ ・プロセッサ,チップ,開発環境依存部の構成とバージョン番号
+ 1.6.1
+
+ ・使用するPDICとバージョン番号
+ pdic/uart
+
+(2) 使用する開発環境と動作検証した条件(バージョン,オプション等)
+
+ ・言語処理系(コンパイラ,アセンブラ,リンカ等)
+ gcc version 4.4.1 (Sourcery G++ Lite 2010q1-188)
+
+ ・デバッグ環境
+ GNU gdb (Sourcery G++ Lite 2010q1-188) 7.0.50.20100218-cvs
+ Open On-Chip Debugger 0.4.0 (2010-08-12-22:40)
+ HJ/LINK USB
+
+(3) ターゲット定義事項の規定
+(3-1) データ型に関する規定
+(3-2) 割込み処理に関する規定
+(3-3) カーネル管理外の割込みに関する規定
+(3-4) CPU例外処理に関する規定
+(3-5) 性能評価用システム時刻の参照に関する規定
+(3-6) オーバランハンドラ機能拡張のサポートに関する規定
+(3-7) その他
+
+(4) カーネルの起動/終了処理に関する情報
+ ・用意しているスタートアップモジュールの処理内容
+ target_initialize()では、PLLの設定、GPIOの設定、シリアル・ポートの設定を行う。
+
+ ・スタートアップモジュールからhardware_init_hookを呼び出している場
+ 合には,hardware_init_hookをアプリケーションで用意する場合の作成
+ 方法や制限事項など
+ chip_user.txtを参照。
+
+ ・カーネルを終了した後の振舞い
+ target_exit()はchip_exit()を呼び出したあと、無限ループを実行する。
+
+(5) メモリマップ
+
+ ・SRAM版のメモリマップ
+ rom (rwx) : ORIGIN = 0x00000000, LENGTH = 512K
+ ram (rx) : ORIGIN = 0x10000000, LENGTH = 32K
+ .vector, .text, .rodata, .data, .bss
+
+ ・ROM版のメモリマップ
+ rom_vector (rwx) : ORIGIN = 0x00000000, LENGTH = 256
+ .vector
+ rom (rwx) : ORIGIN = 0x00000100, LENGTH = 511K
+ .text, .rodata
+ ram (rx) : ORIGIN = 0x10000000, LENGTH = 32K
+ .data, .bss
+
+ メモリマップを変更するには、*.ldの内容を変更する。
+
+(6) タイマドライバ関連の情報
+
+ chip_user.txtを参照
+
+(7) シリアルインタフェースドライバの情報
+
+ ・使用するリソース(SIOコントローラ)
+ UART0を使用する。
+
+ ・通信パラメータ(ボーレート,ビット数,パリティの有無,ストップビット)
+ 57600baud, 8data bit, none-parity, 1stop bit
+
+(8) システムログ機能の情報
+
+ ・システムログの低レベル出力の実現方法
+ target_config.hのtarget_fput_log()からUART0へポーリングをかけて出力している。
+
+ ・通信パラメータ(ボーレート,ビット数,パリティの有無,ストップビット)
+ 57600baud, 8data bit, none-parity, 1stop bit
+
+(9) システム構築手順
+
+ カーネルツリーが、アプリケーションのkernelサブディレクトリにあると仮定する。
+
+ $ cd kernel/cfg
+ $ ./configure
+ $ make
+ $ cd ../..
+ $ kernel configure -T lpc1768_generic_gcc
+ $ make depend
+ $ make
+
+ 以上のコマンド列により、ROM化コードが生成される。SRAM実行用コードを生成するには最後のコマンドを
+ 以下に変更する。
+
+ $ make sram
+
+(10) ターゲットシステム固有の注意事項
+
+(10) 類似のターゲットにポーティングする開発者向けの参考情報
+ LPC1768を使った他のボードにポーティングする場合には、以下のオブジェクトを修正する
+
+ lpc1768_generic.h (名前をターゲット識別名に変更する)
+ SYS_CLOCK CPUコアへの入力周波数[Hz]
+
+ target_config.h
+ DEFAULT_ISTKSZ 割り込みスタックの領域のサイズ[BYTE]
+
+ target_config.c
+ target_initialize() PLLやピンの初期化を行う。
+
+ target_stddef.h
+ TOPPERS_LPC1768_GENERIC ターゲット識別マクロ。ターゲット識別名を大文字にし、頭に
+ TOPPERS_をつける。
+
+ target_syssvc.h
+ TARGET_NAME 著作権表示用のターゲット識別文字列
+ SIO_PORTID SIOとして使うポート番号(1から始まる整数)
+ SIO_BAUD_RATE_DEFAULT ボーレートを変更したい場合
+ TARGET_COPYRIGHT 著作権表示文字列
+
+ LPC1700シリーズの他のプロセッサにポーティングするには、上の修正に加えてターゲットのLDファイルの
+ MEMORY宣言を変更する。一般にLPC1700シリーズはメモリ構成以外のプログラミングモデルは同じである。
+
+(12) ディレクトリ構成・ファイル構成
+asp:
+ arch:
+ arm_m_gcc:
+ MANIFEST
+ Makefile.prc
+ arm_m.h
+ makeoffset.c
+ prc.tf
+ prc_cfg1_out.h
+ prc_check.tf
+ prc_config.c
+ prc_config.h
+ prc_def.csv
+ prc_design.txt
+ prc_insn.h
+ prc_kernel.h
+ prc_rename.def
+ prc_rename.h
+ prc_sil.h
+ prc_stddef.h
+ prc_support.S
+ prc_test.h
+ prc_timer.c
+ prc_timer.cfg
+ prc_timer.h
+ prc_unrename.h
+ prc_user.txt
+ prc_user_annex.txt
+ start.S
+ chip:
+ lpc17xx_gcc:
+ MANIFEST
+ Makefile.chip
+ chip.tf
+ chip_cfg1_out.h
+ chip_check.tf
+ chip_config.c
+ chip_config.h
+ chip_kernel.h
+ chip_rename.def
+ chip_rename.h
+ chip_serial.cfg
+ chip_serial.h
+ chip_sil.h
+ chip_stddef.h
+ chip_syssvc.h
+ chip_test.h
+ chip_timer.cfg
+ chip_timer.h
+ chip_unrename.h
+ chip_user.txt
+ cmsis
+ lpc17xx.h
+
+ msis:
+ LPC17xx.h
+ core_cm3.h
+ system_LPC17xx.h
+
+ pdic:
+ uart:
+ MANIFEST
+ serial_user.txt
+ uart.c
+ uart.h
+
+ target:
+ lpc1768_generic_gcc:
+ E_PACKAGE
+ MANIFEST
+ Makefile.target
+ asp.doxyfile
+ doxygen.css
+ html
+ lpc1768_generic.h
+ lpc1768_rom.ld
+ lpc1768_sram.ld
+ target.tf
+ target_cfg1_out.h
+ target_check.tf
+ target_config.c
+ target_config.h
+ target_def.csv
+ target_kernel.h
+ target_rename.def
+ target_rename.h
+ target_serial.cfg
+ target_serial.h
+ target_sil.h
+ target_stddef.h
+ target_syssvc.h
+ target_test.h
+ target_timer.cfg
+ target_timer.h
+ target_unrename.h
+ target_user.txt
+
+
+(13) バージョン履歴
+
+2010/Oct/23
+ ver 1.6.0
+
+
+
+
--- /dev/null
+PACKAGE asp
+
+MANIFEST
+bit_kernel.c
+perf0.c
+perf0.cfg
+perf0.h
+perf1.c
+perf1.cfg
+perf1.h
+perf2.c
+perf2.cfg
+perf2.h
+perf3.c
+perf3.cfg
+perf3.h
+perf4.c
+perf4.cfg
+perf4.h
+test_cpuexc.cfg
+test_cpuexc.h
+test_cpuexc.txt
+test_cpuexc1.c
+test_cpuexc2.c
+test_cpuexc3.c
+test_cpuexc4.c
+test_cpuexc5.c
+test_cpuexc6.c
+test_cpuexc7.c
+test_cpuexc8.c
+test_cpuexc9.c
+test_cpuexc10.c
+test_cpuexc11.c
+test_cpuexc12.c
+test_cpuexc13.c
+test_dlynse.c
+test_dlynse.cfg
+test_dlynse.h
+test_sem1.c
+test_sem1.cfg
+test_sem1.h
+test_sem2.c
+test_sem2.cfg
+test_sem2.h
+test_sysstat1.c
+test_sysstat1.cfg
+test_sysstat1.h
+test_task1.c
+test_task1.cfg
+test_task1.h
+test_tex1.c
+test_tex1.cfg
+test_tex1.h
+test_tex2.c
+test_tex2.cfg
+test_tex2.h
+test_utm1.c
+test_utm1.cfg
+test_utm1.h
--- /dev/null
+/*
+ * TOPPERS/ASP Kernel
+ * Toyohashi Open Platform for Embedded Real-Time Systems/
+ * Advanced Standard Profile Kernel
+ *
+ * Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: bit_kernel.c 1234 2008-08-09 14:24:38Z ertl-hiro $
+ */
+
+/*
+ * カーネルの整合性検査
+ */
+
+#include "kernel/kernel_impl.h"
+#include "kernel/task.h"
+#include "kernel/wait.h"
+#include "kernel/semaphore.h"
+#include "kernel/eventflag.h"
+#include "kernel/dataqueue.h"
+#include "kernel/pridataq.h"
+#include "kernel/mailbox.h"
+#include "kernel/mempfix.h"
+#include "kernel/time_event.h"
+
+/*
+ * エラーコードの定義
+ */
+#define E_SYS_LINENO ERCD(E_SYS, -(__LINE__))
+
+/*
+ * 管理ブロックのアドレスの正当性のチェック
+ */
+#define VALID_TCB(p_tcb) \
+ ((((char *) p_tcb) - ((char *) tcb_table)) % sizeof(TCB) == 0 \
+ && TMIN_TSKID <= TSKID(p_tcb) && TSKID(p_tcb) <= tmax_tskid)
+
+#define VALID_SEMCB(p_semcb) \
+ ((((char *) p_semcb) - ((char *) semcb_table)) % sizeof(SEMCB) == 0 \
+ && TMIN_SEMID <= SEMID(p_semcb) && SEMID(p_semcb) <= tmax_semid)
+
+#define VALID_FLGCB(p_flgcb) \
+ ((((char *) p_flgcb) - ((char *) flgcb_table)) % sizeof(FLGCB) == 0 \
+ && TMIN_FLGID <= FLGID(p_flgcb) && FLGID(p_flgcb) <= tmax_flgid)
+
+#define VALID_DTQCB(p_dtqcb) \
+ ((((char *) p_dtqcb) - ((char *) dtqcb_table)) % sizeof(DTQCB) == 0 \
+ && TMIN_DTQID <= DTQID(p_dtqcb) && DTQID(p_dtqcb) <= tmax_dtqid)
+
+#define VALID_PDQCB(p_pdqcb) \
+ ((((char *) p_pdqcb) - ((char *) pdqcb_table)) % sizeof(PDQCB) == 0 \
+ && TMIN_PDQID <= PDQID(p_pdqcb) && PDQID(p_pdqcb) <= tmax_pdqid)
+
+#define VALID_MBXCB(p_mbxcb) \
+ ((((char *) p_mbxcb) - ((char *) mbxcb_table)) % sizeof(MBXCB) == 0 \
+ && TMIN_MBXID <= MBXID(p_mbxcb) && MBXID(p_mbxcb) <= tmax_mbxid)
+
+#define VALID_MPFCB(p_mpfcb) \
+ ((((char *) p_mpfcb) - ((char *) mpfcb_table)) % sizeof(MPFCB) == 0 \
+ && TMIN_MPFID <= MPFID(p_mpfcb) && MPFID(p_mpfcb) <= tmax_mpfid)
+
+/*
+ * キューのチェックのための関数
+ *
+ * p_queueにp_entryが含まれているかを調べる.含まれていればtrue,含ま
+ * れていない場合にはfalseを返す.ダブルリンクの不整合の場合にも,
+ * falseを返す.
+ */
+static bool_t
+in_queue(QUEUE *p_queue, QUEUE *p_entry)
+{
+ QUEUE *p_current, *p_next;
+
+ p_current = p_queue->p_next;
+ if (p_current->p_prev != p_queue) {
+ return(false); /* ダブルリンクの不整合 */
+ }
+ while (p_current != p_queue) {
+ if (p_current == p_entry) {
+ return(true); /* p_entryが含まれていた */
+ }
+
+ /*
+ * キューの次の要素に進む
+ */
+ p_next = p_current->p_next;
+ if (p_next->p_prev != p_current) {
+ return(false); /* ダブルリンクの不整合 */
+ }
+ p_current = p_next;
+ }
+ return(false);
+}
+
+/*
+ * スタック上を指しているかの検査
+ */
+static bool_t
+on_stack(void *addr, const TINIB *p_tinib)
+{
+ if (p_tinib->stk <= addr
+ && addr < (void *)((char *)(p_tinib->stk) + p_tinib->stksz)) {
+ return(true);
+ }
+ return(false);
+}
+
+/*
+ * タスク毎の整合性検査
+ */
+static ER
+bit_task(ID tskid)
+{
+ TCB *p_tcb;
+ const TINIB *p_tinib;
+ uint_t tstat, tstat_wait, priority;
+ TMEVTB *p_tmevtb;
+ SEMCB *p_semcb;
+ FLGCB *p_flgcb;
+ DTQCB *p_dtqcb;
+ PDQCB *p_pdqcb;
+ MBXCB *p_mbxcb;
+ MPFCB *p_mpfcb;
+
+ if (!(TMIN_TSKID <= (tskid) && (tskid) <= tmax_tskid)) {
+ return(E_ID);
+ }
+ p_tcb = get_tcb(tskid);
+ p_tinib = p_tcb->p_tinib;
+ tstat = p_tcb->tstat;
+ tstat_wait = (tstat & TS_WAIT_MASK);
+ priority = p_tcb->priority;
+
+ /*
+ * 初期化ブロックへのポインタの検査
+ */
+ if (p_tinib != &(tinib_table[INDEX_TSK(tskid)])) {
+ return(E_SYS_LINENO);
+ }
+
+ /*
+ * tstatの検査
+ */
+ switch (tstat & (TS_RUNNABLE | TS_WAITING | TS_SUSPENDED)) {
+ case TS_DORMANT:
+ if (tstat != TS_DORMANT) {
+ return(E_SYS_LINENO);
+ }
+ break;
+ case TS_RUNNABLE:
+ if (tstat != TS_RUNNABLE) {
+ return(E_SYS_LINENO);
+ }
+ break;
+ case TS_WAITING:
+ case (TS_WAITING | TS_SUSPENDED):
+ if (!(TS_WAIT_DLY <= tstat_wait && tstat_wait <= TS_WAIT_MPF)) {
+ return(E_SYS_LINENO);
+ }
+ if ((tstat & ~(TS_WAIT_MASK | TS_RUNNABLE | TS_WAITING | TS_SUSPENDED))
+ != 0U) {
+ return(E_SYS_LINENO);
+ }
+ break;
+ case TS_SUSPENDED:
+ if (tstat != TS_SUSPENDED) {
+ return(E_SYS_LINENO);
+ }
+ break;
+ default:
+ return(E_SYS_LINENO);
+ }
+
+ /*
+ * actqueの検査
+ */
+ if (TSTAT_DORMANT(tstat) && p_tcb->actque) {
+ return(E_SYS_LINENO);
+ }
+
+ /*
+ * タスク優先度の検査
+ */
+ if (priority >= TNUM_TPRI) {
+ return(E_SYS_LINENO);
+ }
+
+ /*
+ * texptnの検査
+ */
+ if (p_tcb->p_tinib->texrtn == NULL && p_tcb->texptn != 0U) {
+ return(E_SYS_LINENO);
+ }
+
+ /*
+ * 休止状態におけるチェック
+ */
+ if (TSTAT_DORMANT(tstat)) {
+ if (!(priority == p_tinib->ipriority)
+ && (p_tcb->wupque == false)
+ && (p_tcb->enatex == false)
+ && (p_tcb->texptn == 0U)) {
+ return(E_SYS_LINENO);
+ }
+ }
+
+ /*
+ * 実行できる状態におけるチェック
+ */
+ if (TSTAT_RUNNABLE(tstat)) {
+ if (!in_queue(&ready_queue[priority], &(p_tcb->task_queue))) {
+ return(E_SYS_LINENO);
+ }
+ }
+
+ /*
+ * 待ち状態におけるチェック
+ */
+ if (TSTAT_WAITING(tstat)) {
+ if (!on_stack(p_tcb->p_winfo, p_tinib)) {
+ return(E_SYS_LINENO);
+ }
+ p_tmevtb = p_tcb->p_winfo->p_tmevtb;
+ if (p_tmevtb != NULL) {
+ if (!on_stack(p_tmevtb, p_tinib)) {
+ return(E_SYS_LINENO);
+ }
+ /*
+ * (*p_tmevtb)の検査(未完成)
+ */
+ }
+
+ switch (tstat & TS_WAIT_MASK) {
+ case TS_WAIT_SLP:
+ if (p_tcb->wupque == true) {
+ return(E_SYS_LINENO);
+ }
+ break;
+
+ case TS_WAIT_DLY:
+ if (p_tmevtb == NULL) {
+ return(E_SYS_LINENO);
+ }
+ break;
+
+ case TS_WAIT_SEM:
+ p_semcb = ((WINFO_SEM *)(p_tcb->p_winfo))->p_semcb;
+ if (!VALID_SEMCB(p_semcb)) {
+ return(E_SYS_LINENO);
+ }
+ if (!in_queue(&(p_semcb->wait_queue), &(p_tcb->task_queue))) {
+ return(E_SYS_LINENO);
+ }
+ break;
+
+ case TS_WAIT_FLG:
+ p_flgcb = ((WINFO_FLG *)(p_tcb->p_winfo))->p_flgcb;
+ if (!VALID_FLGCB(p_flgcb)) {
+ return(E_SYS_LINENO);
+ }
+ if (!in_queue(&(p_flgcb->wait_queue), &(p_tcb->task_queue))) {
+ return(E_SYS_LINENO);
+ }
+ break;
+
+ case TS_WAIT_SDTQ:
+ p_dtqcb = ((WINFO_DTQ *)(p_tcb->p_winfo))->p_dtqcb;
+ if (!VALID_DTQCB(p_dtqcb)) {
+ return(E_SYS_LINENO);
+ }
+ if (!in_queue(&(p_dtqcb->swait_queue), &(p_tcb->task_queue))) {
+ return(E_SYS_LINENO);
+ }
+ break;
+
+ case TS_WAIT_RDTQ:
+ p_dtqcb = ((WINFO_DTQ *)(p_tcb->p_winfo))->p_dtqcb;
+ if (!VALID_DTQCB(p_dtqcb)) {
+ return(E_SYS_LINENO);
+ }
+ if (!in_queue(&(p_dtqcb->rwait_queue), &(p_tcb->task_queue))) {
+ return(E_SYS_LINENO);
+ }
+ break;
+
+ case TS_WAIT_SPDQ:
+ p_pdqcb = ((WINFO_PDQ *)(p_tcb->p_winfo))->p_pdqcb;
+ if (!VALID_PDQCB(p_pdqcb)) {
+ return(E_SYS_LINENO);
+ }
+ if (!in_queue(&(p_pdqcb->swait_queue), &(p_tcb->task_queue))) {
+ return(E_SYS_LINENO);
+ }
+ break;
+
+ case TS_WAIT_RPDQ:
+ p_pdqcb = ((WINFO_PDQ *)(p_tcb->p_winfo))->p_pdqcb;
+ if (!VALID_PDQCB(p_pdqcb)) {
+ return(E_SYS_LINENO);
+ }
+ if (!in_queue(&(p_pdqcb->rwait_queue), &(p_tcb->task_queue))) {
+ return(E_SYS_LINENO);
+ }
+ break;
+
+ case TS_WAIT_MBX:
+ p_mbxcb = ((WINFO_MBX *)(p_tcb->p_winfo))->p_mbxcb;
+ if (!VALID_MBXCB(p_mbxcb)) {
+ return(E_SYS_LINENO);
+ }
+ if (!in_queue(&(p_mbxcb->wait_queue), &(p_tcb->task_queue))) {
+ return(E_SYS_LINENO);
+ }
+ break;
+
+ case TS_WAIT_MPF:
+ p_mpfcb = ((WINFO_MPF *)(p_tcb->p_winfo))->p_mpfcb;
+ if (!VALID_MPFCB(p_mpfcb)) {
+ return(E_SYS_LINENO);
+ }
+ if (!in_queue(&(p_mpfcb->wait_queue), &(p_tcb->task_queue))) {
+ return(E_SYS_LINENO);
+ }
+ break;
+ }
+ }
+
+ /*
+ * tskctxbの検査
+ */
+ if (!TSTAT_DORMANT(tstat) && p_tcb != p_runtsk) {
+ /*
+ * ターゲット依存の検査
+ */
+#if 0
+ if (bit_tskctxb(&(p_tcb->tskctxb))) {
+ return(E_SYS_LINENO);
+ }
+#endif
+ }
+ return(E_OK);
+}
+
+/*
+ * セマフォ毎の整合性検査
+ */
+#define INDEX_SEM(semid) ((uint_t)((semid) - TMIN_SEMID))
+#define get_semcb(semid) (&(semcb_table[INDEX_SEM(semid)]))
+
+static ER
+bit_semaphore(ID semid)
+{
+ SEMCB *p_semcb;
+ const SEMINIB *p_seminib;
+ uint_t semcnt;
+ QUEUE *p_queue;
+ TCB *p_tcb;
+
+ if (!(TMIN_SEMID <= (semid) && (semid) <= tmax_semid)) {
+ return(E_ID);
+ }
+ p_semcb = get_semcb(semid);
+ p_seminib = p_semcb->p_seminib;
+ semcnt = p_semcb->semcnt;
+
+ /*
+ * 初期化ブロックへのポインタの検査
+ */
+ if (p_seminib != &(seminib_table[INDEX_SEM(semid)])) {
+ return(E_SYS_LINENO);
+ }
+
+ /*
+ * semcntの検査
+ */
+ if (semcnt > p_seminib->maxsem) {
+ return(E_SYS_LINENO);
+ }
+
+ /*
+ * wait_queueの検査
+ */
+ if (semcnt == 0) {
+ p_queue = p_semcb->wait_queue.p_next;
+ while (p_queue != &(p_semcb->wait_queue)) {
+ p_tcb = (TCB *) p_queue;
+ p_queue = p_queue->p_next;
+ if (!VALID_TCB(p_tcb)) {
+ return(E_SYS_LINENO);
+ }
+ if (p_tcb->tstat != (TS_WAITING | TS_WAIT_SEM)) {
+ return(E_SYS_LINENO);
+ }
+ if (p_semcb != ((WINFO_SEM *)(p_tcb->p_winfo))->p_semcb) {
+ return(E_SYS_LINENO);
+ }
+ }
+ }
+ else {
+ if (!queue_empty(&(p_semcb->wait_queue))) {
+ return(E_SYS_LINENO);
+ }
+ }
+ return(E_OK);
+}
+
+/*
+ * 整合性検査ルーチン本体
+ */
+ER
+bit_kernel(void)
+{
+ ID tskid;
+ ID semid;
+ ER ercd;
+
+ /*
+ * タスク毎の検査
+ */
+ for (tskid = TMIN_TSKID; tskid <= tmax_tskid; tskid++) {
+ ercd = bit_task(tskid);
+ if (ercd != E_OK) {
+ return(ercd);
+ }
+ }
+
+ /*
+ * セマフォ毎の検査
+ */
+ for (semid = TMIN_SEMID; semid <= tmax_semid; semid++) {
+ ercd = bit_semaphore(semid);
+ if (ercd != E_OK) {
+ return(ercd);
+ }
+ }
+
+ return(E_OK);
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2006-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: perf0.c 1575 2009-05-31 14:15:46Z ertl-hiro $
+ */
+
+/*
+ * カーネル性能評価プログラム(0)
+ *
+ * 時間計測のオーバヘッドを計測するためのプログラム.
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <test_lib.h>
+#include <histogram.h>
+#include "kernel_cfg.h"
+#include "perf0.h"
+
+/*
+ * 計測回数と実行時間分布を記録する最大時間
+ */
+#define NO_MEASURE 10000U /* 計測回数 */
+#define MAX_TIME 1000U /* 実行時間分布を記録する最大時間 */
+
+/*
+ * 実行時間分布を記録するメモリ領域
+ */
+static uint_t histarea1[MAX_TIME + 1];
+
+/*
+ * メインタスク
+ */
+void main_task(intptr_t exinf)
+{
+ uint_t i;
+
+ syslog_0(LOG_NOTICE, "Performance evaluation program (0)");
+ init_hist(1, MAX_TIME, histarea1);
+ syslog_flush();
+
+ for (i = 0; i < NO_MEASURE; i++) {
+ begin_measure(1);
+ end_measure(1);
+ }
+
+ syslog_0(LOG_NOTICE, "Measurement overhead");
+ print_hist(1);
+ test_finish();
+}
--- /dev/null
+/*
+ * @(#) $Id: perf0.cfg 1575 2009-05-31 14:15:46Z ertl-hiro $
+ */
+
+/*
+ * カーネル性能評価プログラム(0)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "perf0.h"
+CRE_TSK(MAIN_TASK, { TA_ACT, 0, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2006,2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: perf0.h 329 2007-07-17 07:28:32Z hiro $
+ */
+
+/*
+ * カーネル性能評価プログラム(0)
+ */
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 各タスクの優先度の定義
+ */
+#define MAIN_PRIORITY 11 /* メインタスクの優先度 */
+
+/*
+ * ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define STACK_SIZE 4096 /* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+extern void main_task(intptr_t exinf);
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2006-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: perf1.c 1575 2009-05-31 14:15:46Z ertl-hiro $
+ */
+
+/*
+ * カーネル性能評価プログラム(1)
+ *
+ * slp_tsk,wup_tskによるタスク切換え時間を計測するためのプログラム.
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <test_lib.h>
+#include <histogram.h>
+#include "kernel_cfg.h"
+#include "perf1.h"
+
+/*
+ * 計測回数と実行時間分布を記録する最大時間
+ */
+#define NO_MEASURE 10000U /* 計測回数 */
+#define MAX_TIME 1000U /* 実行時間分布を記録する最大時間 */
+
+/*
+ * 実行時間分布を記録するメモリ領域
+ */
+static uint_t histarea1[MAX_TIME + 1];
+static uint_t histarea2[MAX_TIME + 1];
+
+/*
+ * 計測タスク1(高優先度)
+ */
+void task1(intptr_t exinf)
+{
+ uint_t i;
+
+ slp_tsk();
+ end_measure(1);
+ for (i = 1; i < NO_MEASURE; i++) {
+ begin_measure(2);
+ slp_tsk();
+ end_measure(1);
+ }
+ begin_measure(2);
+ slp_tsk();
+}
+
+/*
+ * 計測タスク2(中優先度)
+ */
+void task2(intptr_t exinf)
+{
+ uint_t i;
+
+ for (i = 0; i < NO_MEASURE; i++) {
+ begin_measure(1);
+ wup_tsk(TASK1);
+ end_measure(2);
+ }
+ wup_tsk(TASK1);
+}
+
+/*
+ * メインタスク(低優先度)
+ */
+void main_task(intptr_t exinf)
+{
+ syslog_0(LOG_NOTICE, "Performance evaluation program (1)");
+ init_hist(1, MAX_TIME, histarea1);
+ init_hist(2, MAX_TIME, histarea2);
+ syslog_flush();
+
+ act_tsk(TASK1);
+ act_tsk(TASK2);
+
+ syslog_0(LOG_NOTICE, "Execution times of wup_tsk -> slp_tsk");
+ print_hist(1);
+ syslog_0(LOG_NOTICE, "Execution times of slp_tsk -> wup_tsk");
+ print_hist(2);
+ test_finish();
+}
--- /dev/null
+/*
+ * @(#) $Id: perf1.cfg 1575 2009-05-31 14:15:46Z ertl-hiro $
+ */
+
+/*
+ * カーネル性能評価プログラム(1)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "perf1.h"
+CRE_TSK(TASK1, { TA_NULL, 1, task1, TASK1_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task2, TASK2_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(MAIN_TASK, { TA_ACT, 0, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2006,2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: perf1.h 329 2007-07-17 07:28:32Z hiro $
+ */
+
+/*
+ * カーネル性能評価プログラム(1)
+ */
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 各タスクの優先度の定義
+ */
+#define TASK1_PRIORITY 9 /* 計測タスク1の優先度 */
+#define TASK2_PRIORITY 10 /* 計測タスク2の優先度 */
+#define MAIN_PRIORITY 11 /* メインタスクの優先度 */
+
+/*
+ * ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define STACK_SIZE 4096 /* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+extern void task1(intptr_t exinf);
+extern void task2(intptr_t exinf);
+extern void main_task(intptr_t exinf);
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: perf2.c 1575 2009-05-31 14:15:46Z ertl-hiro $
+ */
+
+/*
+ * カーネル性能評価プログラム(2)
+ *
+ * 優先度データキューに蓄積されているデータの数により,snd_pdqの処理時
+ * 間がどのように変化するかを計測するためのプログラム.
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <test_lib.h>
+#include <histogram.h>
+#include "kernel_cfg.h"
+#include "perf2.h"
+
+/*
+ * 計測回数と実行時間分布を記録する最大時間
+ */
+#define NO_MEASURE 10000U /* 計測回数 */
+#define MAX_TIME 1000U /* 実行時間分布を記録する最大時間 */
+
+/*
+ * 実行時間分布を記録するメモリ領域
+ */
+static uint_t histarea1[MAX_TIME + 1];
+
+/*
+ * 計測ルーチン
+ */
+void
+perf_eval(uint_t n)
+{
+ uint_t i;
+ intptr_t data;
+ PRI pri;
+
+ ini_pdq(PDQ1);
+ init_hist(1, MAX_TIME, histarea1);
+
+ for (i = 0; i < n; i++) {
+ data = i;
+ snd_pdq(PDQ1, data, 1);
+ }
+
+ for (i = 0; i < NO_MEASURE; i++) {
+ data = i;
+ begin_measure(1);
+ snd_pdq(PDQ1, data, 2);
+ end_measure(1);
+ rcv_pdq(PDQ1, &data, &pri);
+ }
+
+ syslog_1(LOG_NOTICE, "Execution times of snd_pdq"
+ " when %d data are queued.", n);
+ print_hist(1);
+ syslog_flush();
+}
+
+/*
+ * メインタスク(低優先度)
+ */
+void main_task(intptr_t exinf)
+{
+ syslog_0(LOG_NOTICE, "Performance evaluation program (2)");
+ syslog_flush();
+
+ perf_eval(0);
+ perf_eval(10);
+ perf_eval(20);
+ perf_eval(30);
+ perf_eval(40);
+ perf_eval(50);
+ perf_eval(100);
+ perf_eval(200);
+ perf_eval(300);
+ test_finish();
+}
--- /dev/null
+/*
+ * @(#) $Id: perf2.cfg 1575 2009-05-31 14:15:46Z ertl-hiro $
+ */
+
+/*
+ * カーネル性能評価プログラム(2)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "perf2.h"
+CRE_TSK(MAIN_TASK, { TA_ACT, 0, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
+CRE_PDQ(PDQ1, { TA_NULL, 301, 16, NULL });
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: perf2.h 459 2007-08-05 14:08:56Z hiro $
+ */
+
+/*
+ * カーネル性能評価プログラム(2)
+ */
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 各タスクの優先度の定義
+ */
+#define MAIN_PRIORITY 11 /* メインタスクの優先度 */
+
+/*
+ * ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define STACK_SIZE 4096 /* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+extern void main_task(intptr_t exinf);
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: perf3.c 1575 2009-05-31 14:15:46Z ertl-hiro $
+ */
+
+/*
+ * カーネル性能評価プログラム(3)
+ *
+ * 待ち解除するタスクの数により,set_flgの処理時間がどのように変化する
+ * かを計測するためのプログラム.
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <test_lib.h>
+#include <histogram.h>
+#include "kernel_cfg.h"
+#include "perf3.h"
+
+/*
+ * 計測回数と実行時間分布を記録する最大時間
+ */
+#define NO_MEASURE 10000U /* 計測回数 */
+#define MAX_TIME 1000U /* 実行時間分布を記録する最大時間 */
+
+/*
+ * 実行時間分布を記録するメモリ領域
+ */
+static uint_t histarea1[MAX_TIME + 1];
+
+/*
+ * 計測タスクのリスト
+ */
+static ID task_list[20] = {
+ TASK1, TASK2, TASK3, TASK4, TASK5,
+ TASK6, TASK7, TASK8, TASK9, TASK10,
+ TASK11, TASK12, TASK13, TASK14, TASK15,
+ TASK16, TASK17, TASK18, TASK19, TASK20
+};
+
+/*
+ * 計測タスク(中優先度)
+ */
+void task(intptr_t exinf)
+{
+ FLGPTN flgptn;
+
+ wai_flg(FLG1, 0x01U, TWF_ORW, &flgptn);
+}
+
+/*
+ * 計測ルーチン
+ */
+void
+perf_eval(uint_t n)
+{
+ uint_t i, j;
+
+ init_hist(1, MAX_TIME, histarea1);
+
+ for (i = 0; i < NO_MEASURE; i++) {
+ ini_flg(FLG1);
+ for (j = 0; j < n; j++) {
+ act_tsk(task_list[j]);
+ }
+ chg_pri(TSK_SELF, MAIN_PRIORITY_LOW);
+ /* タスクが待ち状態に入るのを待つ */
+ chg_pri(TSK_SELF, TPRI_INI);
+
+ begin_measure(1);
+ set_flg(FLG1, 0x01U);
+ end_measure(1);
+
+ chg_pri(TSK_SELF, MAIN_PRIORITY_LOW);
+ /* タスクが終了するのを待つ */
+ chg_pri(TSK_SELF, TPRI_INI);
+ }
+
+ syslog_1(LOG_NOTICE, "Execution times of set_flg"
+ " when %d tasks are released from waiting.", n);
+ print_hist(1);
+ syslog_flush();
+}
+
+/*
+ * メインタスク(高優先度)
+ */
+void main_task(intptr_t exinf)
+{
+ syslog_0(LOG_NOTICE, "Performance evaluation program (3)");
+ syslog_flush();
+
+ perf_eval(0);
+ perf_eval(1);
+ perf_eval(2);
+ perf_eval(3);
+ perf_eval(4);
+ perf_eval(5);
+ perf_eval(10);
+ perf_eval(20);
+ test_finish();
+}
--- /dev/null
+/*
+ * @(#) $Id: perf3.cfg 1575 2009-05-31 14:15:46Z ertl-hiro $
+ */
+
+/*
+ * カーネル性能評価プログラム(3)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "perf3.h"
+CRE_TSK(TASK1, { TA_NULL, 1, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK3, { TA_NULL, 3, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK4, { TA_NULL, 4, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK5, { TA_NULL, 5, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK6, { TA_NULL, 6, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK7, { TA_NULL, 7, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK8, { TA_NULL, 8, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK9, { TA_NULL, 9, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK10, { TA_NULL, 10, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK11, { TA_NULL, 11, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK12, { TA_NULL, 12, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK13, { TA_NULL, 13, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK14, { TA_NULL, 14, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK15, { TA_NULL, 15, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK16, { TA_NULL, 16, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK17, { TA_NULL, 17, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK18, { TA_NULL, 18, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK19, { TA_NULL, 19, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK20, { TA_NULL, 20, task, TASK_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(MAIN_TASK, { TA_ACT, 0, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
+CRE_FLG(FLG1, { TA_WMUL, 0x00U });
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: perf3.h 459 2007-08-05 14:08:56Z hiro $
+ */
+
+/*
+ * カーネル性能評価プログラム(3)
+ */
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 各タスクの優先度の定義
+ */
+#define TASK_PRIORITY 10 /* タスクの優先度 */
+#define MAIN_PRIORITY 9 /* メインタスクの優先度 */
+#define MAIN_PRIORITY_LOW 11 /* メインタスクの低優先度 */
+
+/*
+ * ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define STACK_SIZE 4096 /* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+extern void task(intptr_t exinf);
+extern void main_task(intptr_t exinf);
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2006-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: perf4.c 1575 2009-05-31 14:15:46Z ertl-hiro $
+ */
+
+/*
+ * カーネル性能評価プログラム(4)
+ *
+ * act_tsk,iact_tskの処理時間とタスク切換え時間を計測するためのプログ
+ * ラム.以下の3つの時間を測定する.
+ *
+ * (1) タスク切換えを起こさないact_tskの処理時間.自タスクよりも優先度
+ * の低いタスクに対してact_tskを発行し,休止状態から実行できる状態
+ * に遷移させる処理の時間.
+ *
+ * (2) タスク切換えを起こすact_tskの処理時間.自タスクよりも優先度の高
+ * いタスクに対してact_tskを発行し,休止状態から実行できる状態に遷
+ * 移させ,タスク切換えを起こして,高い優先度のタスクの実行が始ま
+ * るまでの時間.
+ *
+ * (3) タスク切換えを起こすiact_tskの処理時間.周期ハンドラから,実行
+ * 状態のタスクよりも高い優先度のタスクに対してact_tskを発行し,休
+ * 止状態から実行できる状態に遷移させたあとに周期ハンドラからリター
+ * ンし,タスク切換えを起こして,高い優先度のタスクの実行が始まる
+ * までの時間.
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <test_lib.h>
+#include <histogram.h>
+#include "kernel_cfg.h"
+#include "perf4.h"
+
+/*
+ * 計測回数と実行時間分布を記録する最大時間
+ */
+#define NO_MEASURE 10000U /* 計測回数 */
+#define MAX_TIME 1000U /* 実行時間分布を記録する最大時間 */
+
+/*
+ * 実行時間分布を記録するメモリ領域
+ */
+static uint_t histarea1[MAX_TIME + 1];
+static uint_t histarea2[MAX_TIME + 1];
+static uint_t histarea3[MAX_TIME + 1];
+
+/*
+ * 計測タスク1(高優先度)
+ */
+void task1(intptr_t exinf)
+{
+ end_measure(2);
+ ext_tsk();
+}
+
+/*
+ * 計測タスク2とメインタスクの共有変数
+ */
+volatile uint_t task2_count;
+
+/*
+ * 計測タスク2(高優先度)
+ */
+void task2(intptr_t exinf)
+{
+ end_measure(3);
+ task2_count++;
+ ext_tsk();
+}
+
+/*
+ * 計測タスク3(低優先度)
+ */
+void task3(intptr_t exinf)
+{
+ ext_tsk();
+}
+
+/*
+ * 計測タスク4(最低優先度)
+ */
+void task4(intptr_t exinf)
+{
+ while (true) {
+ wup_tsk(MAIN_TASK);
+ }
+}
+
+/*
+ * 周期ハンドラ
+ */
+void cyclic_handler(intptr_t exinf)
+{
+ begin_measure(3);
+ iact_tsk(TASK2);
+}
+
+/*
+ * メインタスク(中優先度)
+ */
+void main_task(intptr_t exinf)
+{
+ uint_t i;
+
+ syslog_0(LOG_NOTICE, "Performance evaluation program (4)");
+ init_hist(1, MAX_TIME, histarea1);
+ init_hist(2, MAX_TIME, histarea2);
+ init_hist(3, MAX_TIME, histarea3);
+ syslog_flush();
+
+ /*
+ * タスク切換えを起こさないact_tskの処理時間の測定
+ */
+ for (i = 0; i < NO_MEASURE; i++) {
+ begin_measure(1);
+ act_tsk(TASK3);
+ end_measure(1);
+ slp_tsk();
+ }
+
+ /*
+ * タスク切換えを起こすact_tskの処理時間の測定
+ */
+ for (i = 0; i < NO_MEASURE; i++) {
+ begin_measure(2);
+ act_tsk(TASK1);
+ }
+
+ /*
+ * タスク切換えを起こすiact_tskの処理時間の測定(測定回数は10分の1)
+ */
+ task2_count = 0;
+ sta_cyc(CYC1);
+ while (task2_count < NO_MEASURE / 10) ;
+ stp_cyc(CYC1);
+
+ syslog_0(LOG_NOTICE, "Execution times of act_tsk without task switch");
+ print_hist(1);
+ syslog_0(LOG_NOTICE, "Execution times of act_tsk with task switch");
+ print_hist(2);
+ syslog_0(LOG_NOTICE, "Execution times of iact_tsk with task switch");
+ print_hist(3);
+ test_finish();
+}
--- /dev/null
+/*
+ * @(#) $Id: perf4.cfg 1575 2009-05-31 14:15:46Z ertl-hiro $
+ */
+
+/*
+ * カーネル性能評価プログラム(4)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "perf4.h"
+CRE_TSK(TASK1, { TA_NULL, 1, task1, TASK1_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task2, TASK2_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK3, { TA_NULL, 3, task3, TASK3_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK4, { TA_ACT, 4, task4, TASK4_PRIORITY, STACK_SIZE, NULL });
+CRE_CYC(CYC1, { TA_NULL, 0, cyclic_handler,
+ (TIC_NUME + TIC_DENO - 1) / TIC_DENO,
+ (TIC_NUME + TIC_DENO - 1) / TIC_DENO });
+CRE_TSK(MAIN_TASK, { TA_ACT, 0, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2006-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: perf4.h 1552 2009-05-12 02:35:57Z ertl-hiro $
+ */
+
+/*
+ * カーネル性能評価プログラム(4)
+ */
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 各タスクの優先度の定義
+ */
+#define TASK1_PRIORITY 9 /* 計測タスク1の優先度 */
+#define TASK2_PRIORITY 9 /* 計測タスク2の優先度 */
+#define TASK3_PRIORITY 11 /* 計測タスク3の優先度 */
+#define TASK4_PRIORITY 12 /* 計測タスク4の優先度 */
+#define MAIN_PRIORITY 10 /* メインタスクの優先度 */
+
+/*
+ * ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define STACK_SIZE 4096 /* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+extern void task1(intptr_t exinf);
+extern void task2(intptr_t exinf);
+extern void task3(intptr_t exinf);
+extern void task4(intptr_t exinf);
+extern void cyclic_handler(intptr_t exinf);
+extern void main_task(intptr_t exinf);
--- /dev/null
+/*
+ * @(#) $Id: test_cpuexc.cfg 1572 2009-05-31 13:40:39Z ertl-hiro $
+ */
+
+/*
+ * CPU例外処理のテスト(1)〜(13)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "test_cpuexc.h"
+
+CRE_TSK(TASK1, { TA_ACT, 1, task1, MID_PRIORITY, STACK_SIZE, NULL });
+DEF_TEX(TASK1, { TA_NULL, tex_task1 });
+
+CRE_TSK(TASK2, { TA_NULL, 2, task2, HIGH_PRIORITY, STACK_SIZE, NULL });
+
+CRE_ALM(ALM1, { TA_NULL, 1, alarm1_handler });
+
+DEF_EXC(CPUEXC1, { TA_NULL, cpuexc_handler });
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_cpuexc.h 329 2007-07-17 07:28:32Z hiro $
+ */
+
+/*
+ * CPU例外処理のテスト(1)〜(13)
+ */
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 各タスクの優先度の定義
+ */
+#define HIGH_PRIORITY 9 /* 高優先度 */
+#define MID_PRIORITY 10 /* 中優先度 */
+
+/*
+ * ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define STACK_SIZE 4096 /* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void task1(intptr_t exinf);
+extern void tex_task1(TEXPTN texptn, intptr_t exinf);
+
+extern void task2(intptr_t exinf);
+
+extern void alarm1_handler(intptr_t exinf);
+
+extern void cpuexc_handler(void *p_excinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
--- /dev/null
+
+ CPU例外処理のテスト
+
+【テストの目的】
+
+CPU例外ハンドラの実行開始/リターン時のシステム状態と,CPU例外ハンドラ
+中でのxsns_dpnとxsns_xpnの動作を網羅的にテストする.
+
+【テスト項目】
+
+(A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+
+(B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ !CPU例外ハンドラ中で割込み優先度マスクを読めないため,テストできな
+ い.
+
+(C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+
+(D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+
+(E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+
+(F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+
+(G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+
+(H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+
+(I) xsns_xpnが正しい値を返すこと
+
+xsns_xpnは,CPU例外が発生した状況が次の条件をすべて満たす場合にfalse,
+そうでない場合にtrueを返す.
+ ・タスクコンテキスト
+ ・割込みロック解除状態
+ ・CPUロック解除状態
+ ・タスク例外許可状態
+
+(J) xsns_dpnが正しい値を返すこと
+
+xsns_dpnは,CPU例外が発生した状況が次の条件をすべて満たす場合にfalse,
+そうでない場合にtrueを返す.
+ ・タスクコンテキスト
+ ・割込みロック解除状態
+ ・CPUロック解除状態
+ ・割込み優先度マスク全解除状態
+ ・ディスパッチ許可状態
+
+(K) タスク切換えによるリカバリーができること
+
+(L) タスク例外によるリカバリーができること
+
+【テストを実施する状況】
+
+CPU例外の発生する状況は,次のように分類することができる.これらの状況毎
+にテストプログラムを用意する.
+
+(a-1) 非タスクコンテキスト
+(a-2) タスクコンテキスト
+
+(b-1) 割込みロック状態
+(b-2) 割込みロック解除状態
+
+(c-1) CPUロック状態
+(c-2) CPUロック解除状態
+
+(d-1) 割込み優先度マスク=TIPM_ENAALL
+(d-2) 割込み優先度マスク=TMAX_INTPRI
+ !TMAX_INTPRI=TMIN_INTPRIの場合は(d-3)と同じになるので実施しない.
+(d-3) 割込み優先度マスク=TMIN_INTPRI
+(d-4) 割込み優先度マスク=TMIN_INTPRI-1
+ !TMAX_INTPRI-1が設定できるかはターゲットに依存する.
+
+(e-1) ディスパッチ禁止状態
+(e-2) ディスパッチ許可状態
+
+(f-1) タスク例外禁止状態
+(f-2) タスク例外許可状態
+
+この組み合わせをすべてテストすることは現実的でないため,代表的なパター
+ンに絞り込む.
+
+まず,(a)〜(c)の組み合わせで,次の5つのパターンをテストする.これらのテ
+ストをする際には,(d)〜(f)については,(d-1)(e-1)(f-2)の組み合わせに固定
+する.
+
+(1) (a-1)(b-1)(c-2) → リカバリー不可
+ !(a-1)(b-1)(c-1)のテストは省く.
+(2) (a-1)(b-2)(c-1) → リカバリー不可
+(3) (a-1)(b-2)(c-2) → リカバリー不可
+
+(4) (a-2)(b-1)(c-2) → リカバリー不可
+ !(a-2)(b-1)(c-1)のテストは省く.
+(5) (a-2)(b-2)(c-1) → リカバリー不可
+
+次に,(a)〜(c)を(a-2)(b-2)(c-2)に固定して,(d)〜(f)の組み合わせで,次の
+8つのパターンをテストする.
+
+(6) (d-1)(e-2)(f-1) → タスク切換えによるリカバリー可能
+
+(7) (d-1)(e-1)(f-2) → タスク例外によるリカバリー可能
+
+(8) (d-2)(e-2)(f-2) → タスク例外によるリカバリー可能
+ !(d-2)(e-1)(f-2)のテストは省く.
+
+(9) (d-3)(e-2)(f-2) → タスク例外によるリカバリー可能
+ !(d-3)(e-1)(f-2)のテストは省く.
+
+(10) (d-4)(e-2)(f-2) → タスク例外によるリカバリー可能
+ !(d-4)(e-1)(f-2)のテストは省く.
+
+(11) (d-1)(e-2)(f-2) → 両方法によるリカバリー可能
+
+(12) (d-1)(e-1)(f-1) → リカバリー不可
+ (d-2)〜(d-4)×(e-1)×(f-1) のテスト(3パターン)は省く.
+
+(13) (d-3)(e-2)(f-1) → リカバリー不可
+ (d-2),(d-4)×(e-2)×(f-1) のテスト(2パターン)は省く.
+
+【使用リソース】
+
+TASK1: TA_ACT,中優先度,タスク例外処理ルーチン登録
+TASK2: TA_NULL,高優先度
+CPUEXC1: TA_NULL
+ALM1: TA_NULL
+
+以上
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_cpuexc1.c 1577 2009-05-31 14:30:51Z ertl-hiro $
+ */
+
+/*
+ * CPU例外処理のテスト(1)
+ *
+ * 【テストの目的】
+ *
+ * 非タスクコンテキスト,割込ロック状態で発生したCPU例外におけるシステ
+ * ム状態のテスト.割込み優先度マスク=TIPM_ENAALL,ディスパッチ禁止状
+ * 態,タスク例外許可状態でテストする.
+ *
+ * 【テスト項目】
+ *
+ * いずれも,非タスクコンテキスト,割込ロック状態で発生したCPU例外にお
+ * いて,
+ *
+ * (A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ * !割込みロック状態で発生したCPU例外では,システム状態を正しく読
+ * めることが保証されないため,テストできない.
+ * (B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ * !割込みロック状態で発生したCPU例外では,システム状態を正しく読
+ * めることが保証されないため,テストできない.
+ * (C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ * !割込みロック状態で発生したCPU例外では,システム状態を正しく読
+ * めることが保証されないため,テストできない.
+ * (D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ * !割込みロック状態で発生したCPU例外では,システム状態を正しく読
+ * めることが保証されないため,テストできない.
+ * (E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (I) xsns_xpnがtrueを返すこと
+ * (J) xsns_dpnがtrueを返すこと
+ *
+ * 【使用リソース】
+ *
+ * TASK1: TA_ACT,中優先度,タスク例外処理ルーチン登録
+ * CPUEXC1: TA_NULL
+ * ALM1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(中優先度)==
+ * 1: 状態のチェック
+ * dis_dsp()
+ * ena_tex()
+ * 2: 状態のチェック
+ * sta_alm(ALM1, 1U)
+ * アラームハンドラ1の実行を待つ
+ * == ALM1 ==
+ * 3: 状態のチェック
+ * SIL_LOC_INT()
+ * RAISE_CPU_EXCEPTION
+ * == CPUEXC1 ==
+ * 4: xsns_xpn() == true ... (I)
+ * xsns_dpn() == true ... (J)
+ * 5: CPU例外ハンドラからリターンできない場合は,ここで終了
+ * 5: リターン
+ * == ALM1(続き)==
+ * 6: SIL_UNL_LOC()
+ * 7: 状態のチェック ... (E)(G)(H)
+ * リターン
+ * == TASK1(続き)==
+ * 8: 状態のチェック ... (F)
+ * 9: テスト終了
+ */
+
+#include <sil.h>
+#include <kernel.h>
+#include <t_syslog.h>
+#include <test_lib.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+volatile bool_t alm1_flag = false;
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(1);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+ ercd = ena_tex();
+ check_ercd(ercd, E_OK);
+
+ check_point(2);
+ check_state(false, false, TIPM_ENAALL, true, true, false);
+ ercd = sta_alm(ALM1, 1U);
+ check_ercd(ercd, E_OK);
+
+ while (!(alm1_flag));
+
+ check_point(8);
+ check_state(false, false, TIPM_ENAALL, true, true, false);
+
+ check_finish(9);
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+ SIL_PRE_LOC;
+
+ check_point(3);
+ check_state_i(true, false, true, true, false);
+ SIL_LOC_INT();
+ RAISE_CPU_EXCEPTION;
+
+ check_point(6);
+ SIL_UNL_INT();
+
+ check_point(7);
+ check_state_i(true, false, true, true, false);
+ alm1_flag = true;
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+ check_point(4);
+ check_assert(xsns_xpn(p_excinf) == true);
+ check_assert(xsns_dpn(p_excinf) == true);
+
+#ifdef CANNOT_RETURN_CPUEXC
+ check_finish(5);
+#endif /* CANNOT_RETURN_CPUEXC */
+
+ check_point(5);
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_cpuexc10.c 1577 2009-05-31 14:30:51Z ertl-hiro $
+ */
+
+/*
+ * CPU例外処理のテスト(10)
+ *
+ * 【テストの目的】
+ *
+ * 割込み優先度マスク=TMIN_INTPRI-1,ディスパッチ許可状態,タスク例外
+ * 許可状態で発生したCPU例外におけるシステム状態のテスト.タスク例外に
+ * よりリカバリーできることもテストする.
+ *
+ * このテストは,割込み優先度マスクをTMIN_INTPRI-1に設定できる場合のみ
+ * 実施する.
+ *
+ * 【テスト項目】
+ *
+ * いずれも,割込み優先度マスク=TMIN_INTPRI-1,ディスパッチ許可状態,
+ * タスク例外許可状態で発生したCPU例外において,
+ *
+ * (A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ * (B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ * !CPU例外ハンドラ中で割込み優先度マスクを読めないため,テストで
+ * きない.
+ * (C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ * (D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ * (E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ * (F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ * (G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ * (H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ * (I) xsns_xpnがfalseを返すこと.ただし,trueを返すことも許されている
+ * (J) xsns_dpnがtrueを返すこと
+ * (L) タスク例外によるリカバリーができること
+ *
+ * 【使用リソース】
+ *
+ * TASK1: TA_ACT,中優先度,タスク例外処理ルーチン登録
+ * CPUEXC1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(中優先度,1回目)==
+ * 1: 状態のチェック
+ * chg_ipm(TMIN_INTPRI-1)
+ * ena_tex()
+ * 2: 状態のチェック
+ * RAISE_CPU_EXCEPTION
+ * == CPUEXC1 ==
+ * 3: 状態のチェック ... (A),(C),(D)
+ * xsns_xpn() == false ... (I)
+ * !trueであってもテストプログラムを続行する
+ * xsns_dpn() == true ... (J)
+ * 4: iras_tex(TASK1, 1U)
+ * iloc_cpu()
+ * リターン
+ * == TASK1のタスク例外処理ルーチン ==
+ * 5: 状態のチェック ... (E),(F),(G),(H)
+ * 6: act_tsk(TASK1) ... (L)
+ * 7: ext_tsk() ... (L)
+ * == TASK1(中優先度,2回目)==
+ * 8: 状態のチェック ... (L)
+ * 9: テスト終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+int_t task1_count = 0;
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+
+ switch (++task1_count) {
+ case 1:
+ check_point(1);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+ ercd = chg_ipm(TMAX_INTPRI - 1);
+ if (ercd == E_PAR) {
+ syslog_0(LOG_NOTICE, "This test program is not necessary.");
+ ext_ker();
+ }
+ check_ercd(ercd, E_OK);
+ ercd = ena_tex();
+ check_ercd(ercd, E_OK);
+
+ check_point(2);
+ check_state(false, false, TMAX_INTPRI - 1, false, true, false);
+ RAISE_CPU_EXCEPTION;
+
+ check_point(0);
+ break;
+
+ case 2:
+ check_point(8);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+
+ check_finish(9);
+ break;
+
+ default:
+ check_point(0);
+ break;
+ }
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(5);
+ check_state(false, false, TMAX_INTPRI - 1, false, true, true);
+
+ check_point(6);
+ ercd = act_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(7);
+ ercd = ext_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+ ER ercd;
+
+ check_point(3);
+ check_state_i(true, false, false, true, false);
+ if (xsns_xpn(p_excinf) == true) {
+ syslog_0(LOG_WARNING, "xsns_xpn returns true.");
+ }
+ check_assert(xsns_dpn(p_excinf) == true);
+
+ check_point(4);
+ ercd = iras_tex(TASK1, 1U);
+ check_ercd(ercd, E_OK);
+ ercd = iloc_cpu();
+ check_ercd(ercd, E_OK);
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_cpuexc11.c 1577 2009-05-31 14:30:51Z ertl-hiro $
+ */
+
+/*
+ * CPU例外処理のテスト(11)
+ *
+ * 【テストの目的】
+ *
+ * 割込み優先度マスク=TIPM_ENAALL,ディスパッチ許可状態,タスク例外許
+ * 可状態で発生したCPU例外におけるシステム状態のテスト.タスク切換えに
+ * よりリカバリーできることもテストする.
+ *
+ * 【テスト項目】
+ *
+ * いずれも,割込み優先度マスク=TIPM_ENAALL,ディスパッチ許可状態,タ
+ * スク例外許可状態で発生したCPU例外において,
+ *
+ * (A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ * (B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ * !CPU例外ハンドラ中で割込み優先度マスクを読めないため,テストで
+ * きない.
+ * (C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ * (D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ * (E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ * (F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ * (G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ * (H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ * (I) xsns_xpnがfalseを返すこと
+ * (J) xsns_dpnがfalseを返すこと
+ * (K) タスク切換えによるリカバリーができること
+ * (L) タスク例外によるリカバリーができること
+ *
+ * 【使用リソース】
+ *
+ * TASK1: TA_ACT,中優先度,タスク例外処理ルーチン登録
+ * TASK2: TA_NULL,高優先度
+ * CPUEXC1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(中優先度,1回目)==
+ * 1: 状態のチェック
+ * ena_tex()
+ * 2: 状態のチェック
+ * RAISE_CPU_EXCEPTION
+ * == CPUEXC1(1回目)==
+ * 3: 状態のチェック ... (A),(C),(D)
+ * xsns_xpn() == false ... (I)
+ * xsns_dpn() == false ... (J)
+ * 4: iact_tsk(TASK2)
+ * iloc_cpu()
+ * リターン
+ * == TASK2(高優先度)==
+ * 5: 状態のチェック ... (E),(F),(G),(H)
+ * 6: ter_tsk(TASK1) ... (K)
+ * 7: act_tsk(TASK1) ... (K)
+ * 8: ext_tsk()
+ * == TASK1(中優先度,2回目)==
+ * 9: 状態のチェック ... (K)
+ * ena_tex()
+ * 10: 状態のチェック
+ * RAISE_CPU_EXCEPTION
+ * == CPUEXC1(2回目)==
+ * 11: 状態のチェック ... (A),(C),(D)
+ * xsns_xpn() == false ... (I)
+ * xsns_dpn() == false ... (J)
+ * 12: iras_tex(TASK1, 1U)
+ * iloc_cpu()
+ * リターン
+ * == TASK1のタスク例外処理ルーチン ==
+ * 13: 状態のチェック ... (E),(F),(G),(H)
+ * 14: act_tsk(TASK1) ... (L)
+ * 15: ext_tsk() ... (L)
+ * == TASK1(中優先度,3回目)==
+ * 16: 状態のチェック ... (L)
+ * 17: テスト終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+int_t task1_count = 0;
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+
+ switch (++task1_count) {
+ case 1:
+ check_point(1);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+ ercd = ena_tex();
+ check_ercd(ercd, E_OK);
+
+ check_point(2);
+ check_state(false, false, TIPM_ENAALL, false, false, false);
+ RAISE_CPU_EXCEPTION;
+
+ check_point(0);
+ break;
+
+ case 2:
+ check_point(9);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+ ercd = ena_tex();
+ check_ercd(ercd, E_OK);
+
+ check_point(10);
+ check_state(false, false, TIPM_ENAALL, false, false, false);
+ RAISE_CPU_EXCEPTION;
+
+ check_point(0);
+ break;
+
+ case 3:
+ check_point(16);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+
+ check_finish(17);
+ break;
+
+ default:
+ check_point(0);
+ break;
+ }
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(13);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+
+ check_point(14);
+ ercd = act_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(15);
+ ercd = ext_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(5);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+
+ check_point(6);
+ ercd = ter_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(7);
+ ercd = act_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(8);
+ ercd = ext_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+ check_point(0);
+}
+
+int_t cpuexc_count = 0;
+
+void
+cpuexc_handler(void *p_excinf)
+{
+ ER ercd;
+
+ switch (++cpuexc_count) {
+ case 1:
+ check_point(3);
+ check_state_i(true, false, false, true, false);
+ check_assert(xsns_xpn(p_excinf) == false);
+ check_assert(xsns_dpn(p_excinf) == false);
+
+ check_point(4);
+ ercd = iact_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+ ercd = iloc_cpu();
+ check_ercd(ercd, E_OK);
+ break;
+
+ case 2:
+ check_point(11);
+ check_state_i(true, false, false, true, false);
+ check_assert(xsns_xpn(p_excinf) == false);
+ check_assert(xsns_dpn(p_excinf) == false);
+
+ check_point(12);
+ ercd = iras_tex(TASK1, 1U);
+ check_ercd(ercd, E_OK);
+ ercd = iloc_cpu();
+ check_ercd(ercd, E_OK);
+ break;
+
+ default:
+ check_point(0);
+ break;
+ }
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_cpuexc12.c 1577 2009-05-31 14:30:51Z ertl-hiro $
+ */
+
+/*
+ * CPU例外処理のテスト(12)
+ *
+ * 【テストの目的】
+ *
+ * 割込み優先度マスク=TIPM_ENAALL,ディスパッチ禁止状態,タスク例外禁
+ * 止状態で発生したCPU例外におけるシステム状態のテスト.
+ *
+ * 【テスト項目】
+ *
+ * いずれも,割込み優先度マスク=TIPM_ENAALL,ディスパッチ禁止状態,タ
+ * スク例外禁止状態で発生したCPU例外において,
+ *
+ * (A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ * (B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ * !CPU例外ハンドラ中で割込み優先度マスクを読めないため,テストで
+ * きない.
+ * (C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ * (D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ * (E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (I) xsns_xpnがtrueを返すこと
+ * (J) xsns_dpnがtrueを返すこと
+ *
+ * 【使用リソース】
+ *
+ * TASK1: TA_ACT,中優先度,タスク例外処理ルーチン登録
+ * CPUEXC1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(中優先度)==
+ * 1: 状態のチェック
+ * dis_dsp()
+ * 2: 状態のチェック
+ * RAISE_CPU_EXCEPTION
+ * == CPUEXC1 ==
+ * 3: 状態のチェック ... (A),(C),(D)
+ * xsns_xpn() == true ... (I)
+ * xsns_dpn() == true ... (J)
+ * 4: CPU例外ハンドラからリターンできない場合は,ここで終了
+ * 4: iloc_cpu()
+ * リターン
+ * == TASK1(続き)==
+ * 5: 状態のチェック ... (E)(F)(G)(H)
+ * 6: テスト終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(1);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(2);
+ check_state(false, false, TIPM_ENAALL, true, true, true);
+ RAISE_CPU_EXCEPTION;
+
+ check_point(5);
+ check_state(false, false, TIPM_ENAALL, true, true, true);
+
+ check_finish(6);
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+ ER ercd;
+
+ check_point(3);
+ check_state_i(true, false, true, true, true);
+ check_assert(xsns_xpn(p_excinf) == true);
+ check_assert(xsns_dpn(p_excinf) == true);
+
+#ifdef CANNOT_RETURN_CPUEXC
+ check_finish(4);
+#endif /* CANNOT_RETURN_CPUEXC */
+
+ check_point(4);
+ ercd = iloc_cpu();
+ check_ercd(ercd, E_OK);
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_cpuexc13.c 1577 2009-05-31 14:30:51Z ertl-hiro $
+ */
+
+/*
+ * CPU例外処理のテスト(13)
+ *
+ * 【テストの目的】
+ *
+ * 割込み優先度マスク=TMIN_INTPRI,ディスパッチ許可状態,タスク例外禁
+ * 止状態で発生したCPU例外におけるシステム状態のテスト.
+ *
+ * 【テスト項目】
+ *
+ * いずれも,割込み優先度マスク=TMIN_INTPRI,ディスパッチ許可状態,タ
+ * スク例外禁止状態で発生したCPU例外において,
+ *
+ * (A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ * (B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ * !CPU例外ハンドラ中で割込み優先度マスクを読めないため,テストで
+ * きない.
+ * (C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ * (D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ * (E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (I) xsns_xpnがtrueを返すこと
+ * (J) xsns_dpnがtrueを返すこと
+ *
+ * 【使用リソース】
+ *
+ * TASK1: TA_ACT,中優先度,タスク例外処理ルーチン登録
+ * CPUEXC1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(中優先度)==
+ * 1: 状態のチェック
+ * chg_ipm(TMIN_INTPRI)
+ * 2: 状態のチェック
+ * RAISE_CPU_EXCEPTION
+ * == CPUEXC1 ==
+ * 3: 状態のチェック ... (A),(C),(D)
+ * xsns_xpn() == true ... (I)
+ * xsns_dpn() == true ... (J)
+ * 4: CPU例外ハンドラからリターンできない場合は,ここで終了
+ * 4: iloc_cpu()
+ * リターン
+ * == TASK1(続き)==
+ * 5: 状態のチェック ... (E)(F)(G)(H)
+ * 6: テスト終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(1);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+ ercd = chg_ipm(TMIN_INTPRI);
+ check_ercd(ercd, E_OK);
+
+ check_point(2);
+ check_state(false, false, TMIN_INTPRI, false, true, true);
+ RAISE_CPU_EXCEPTION;
+
+ check_point(5);
+ check_state(false, false, TMIN_INTPRI, false, true, true);
+
+ check_finish(6);
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+ ER ercd;
+
+ check_point(3);
+ check_state_i(true, false, false, true, true);
+ check_assert(xsns_xpn(p_excinf) == true);
+ check_assert(xsns_dpn(p_excinf) == true);
+
+#ifdef CANNOT_RETURN_CPUEXC
+ check_finish(4);
+#endif /* CANNOT_RETURN_CPUEXC */
+
+ check_point(4);
+ ercd = iloc_cpu();
+ check_ercd(ercd, E_OK);
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_cpuexc2.c 1577 2009-05-31 14:30:51Z ertl-hiro $
+ */
+
+/*
+ * CPU例外処理のテスト(2)
+ *
+ * 【テストの目的】
+ *
+ * 非タスクコンテキスト,割込ロック解除,CPUロック状態で発生したCPU例
+ * 外におけるシステム状態のテスト.割込み優先度マスク=TIPM_ENAALL,ディ
+ * スパッチ禁止状態,タスク例外許可状態でテストする.
+ *
+ * 【テスト項目】
+ *
+ * いずれも,非タスクコンテキスト,割込ロック解除,CPUロック状態で発生
+ * したCPU例外において,
+ *
+ * (A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ * (B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ * !CPU例外ハンドラ中で割込み優先度マスクを読めないため,テストで
+ * きない.
+ * (C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ * (D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ * (E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (I) xsns_xpnがtrueを返すこと
+ * (J) xsns_dpnがtrueを返すこと
+ *
+ * 【使用リソース】
+ *
+ * TASK1: TA_ACT,中優先度,タスク例外処理ルーチン登録
+ * CPUEXC1: TA_NULL
+ * ALM1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(中優先度)==
+ * 1: 状態のチェック
+ * dis_dsp()
+ * ena_tex()
+ * 2: 状態のチェック
+ * sta_alm(ALM1, 1U)
+ * アラームハンドラ1の実行を待つ
+ * == ALM1 ==
+ * 3: 状態のチェック
+ * iloc_cpu()
+ * RAISE_CPU_EXCEPTION
+ * == CPUEXC1 ==
+ * 4: 状態のチェック ... (A)(C)(D)
+ * xsns_xpn() == true ... (I)
+ * xsns_dpn() == true ... (J)
+ * 5: CPU例外ハンドラからリターンできない場合は,ここで終了
+ * 5: iunl_cpu()
+ * リターン
+ * == ALM1(続き)==
+ * 6: 状態のチェック ... (E)(G)(H)
+ * リターン
+ * == TASK1(続き)==
+ * 7: 状態のチェック ... (F)
+ * 8: テスト終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+volatile bool_t alm1_flag = false;
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(1);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+ ercd = ena_tex();
+ check_ercd(ercd, E_OK);
+
+ check_point(2);
+ check_state(false, false, TIPM_ENAALL, true, true, false);
+ ercd = sta_alm(ALM1, 1U);
+ check_ercd(ercd, E_OK);
+
+ while (!(alm1_flag));
+
+ check_point(7);
+ check_state(false, false, TIPM_ENAALL, true, true, false);
+
+ check_finish(8);
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(3);
+ check_state_i(true, false, true, true, false);
+ ercd = iloc_cpu();
+ check_ercd(ercd, E_OK);
+ RAISE_CPU_EXCEPTION;
+
+ check_point(6);
+ check_state_i(true, true, true, true, false);
+ alm1_flag = true;
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+ ER ercd;
+
+ check_point(4);
+ check_state_i(true, true, true, true, false);
+ check_assert(xsns_xpn(p_excinf) == true);
+ check_assert(xsns_dpn(p_excinf) == true);
+
+#ifdef CANNOT_RETURN_CPUEXC
+ check_finish(5);
+#endif /* CANNOT_RETURN_CPUEXC */
+
+ check_point(5);
+ ercd = iunl_cpu();
+ check_ercd(ercd, E_OK);
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_cpuexc3.c 1577 2009-05-31 14:30:51Z ertl-hiro $
+ */
+
+/*
+ * CPU例外処理のテスト(3)
+ *
+ * 【テストの目的】
+ *
+ * 非タスクコンテキスト,割込ロック解除,CPUロック解除で発生したCPU例
+ * 外におけるシステム状態のテスト.割込み優先度マスク=TIPM_ENAALL,ディ
+ * スパッチ禁止状態,タスク例外許可状態でテストする.
+ *
+ * 【テスト項目】
+ *
+ * いずれも,非タスクコンテキスト,割込ロック解除,CPUロック解除で発生
+ * したCPU例外において,
+ *
+ * (A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ * (B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ * !CPU例外ハンドラ中で割込み優先度マスクを読めないため,テストで
+ * きない.
+ * (C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ * (D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ * (E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (I) xsns_xpnがtrueを返すこと
+ * (J) xsns_dpnがtrueを返すこと
+ *
+ * 【使用リソース】
+ *
+ * TASK1: TA_ACT,中優先度,タスク例外処理ルーチン登録
+ * CPUEXC1: TA_NULL
+ * ALM1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(中優先度)==
+ * 1: 状態のチェック
+ * dis_dsp()
+ * ena_tex()
+ * 2: 状態のチェック
+ * sta_alm(ALM1, 1U)
+ * アラームハンドラ1の実行を待つ
+ * == ALM1 ==
+ * 3: 状態のチェック
+ * RAISE_CPU_EXCEPTION
+ * == CPUEXC1 ==
+ * 4: 状態のチェック ... (A),(C),(D)
+ * xsns_xpn() == true ... (I)
+ * xsns_dpn() == true ... (J)
+ * 5: CPU例外ハンドラからリターンできない場合は,ここで終了
+ * 5: iloc_cpu()
+ * リターン
+ * == ALM1(続き)==
+ * 6: 状態のチェック ... (E)(G)(H)
+ * リターン
+ * == TASK1(続き)==
+ * 7: 状態のチェック ... (F)
+ * 8: テスト終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+volatile bool_t alm1_flag = false;
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(1);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+ ercd = ena_tex();
+ check_ercd(ercd, E_OK);
+
+ check_point(2);
+ check_state(false, false, TIPM_ENAALL, true, true, false);
+ ercd = sta_alm(ALM1, 1U);
+ check_ercd(ercd, E_OK);
+
+ while (!(alm1_flag));
+
+ check_point(7);
+ check_state(false, false, TIPM_ENAALL, true, true, false);
+
+ check_finish(8);
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+ check_point(3);
+ check_state_i(true, false, true, true, false);
+ RAISE_CPU_EXCEPTION;
+
+ check_point(6);
+ check_state_i(true, false, true, true, false);
+ alm1_flag = true;
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+ ER ercd;
+
+ check_point(4);
+ check_state_i(true, false, true, true, false);
+ check_assert(xsns_xpn(p_excinf) == true);
+ check_assert(xsns_dpn(p_excinf) == true);
+
+#ifdef CANNOT_RETURN_CPUEXC
+ check_finish(5);
+#endif /* CANNOT_RETURN_CPUEXC */
+
+ check_point(5);
+ ercd = iloc_cpu();
+ check_ercd(ercd, E_OK);
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_cpuexc4.c 1577 2009-05-31 14:30:51Z ertl-hiro $
+ */
+
+/*
+ * CPU例外処理のテスト(4)
+ *
+ * 【テストの目的】
+ *
+ * タスクコンテキスト,割込ロック状態で発生したCPU例外におけるシステム
+ * 状態のテスト.割込み優先度マスク=TIPM_ENAALL,ディスパッチ禁止状態,
+ * タスク例外許可状態でテストする.
+ *
+ * 【テスト項目】
+ *
+ * いずれも,タスクコンテキスト,割込ロック状態で発生したCPU例外におい
+ * て,
+ *
+ * (A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ * !割込みロック状態で発生したCPU例外では,システム状態を正しく読
+ * めることが保証されないため,テストできない.
+ * (B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ * !割込みロック状態で発生したCPU例外では,システム状態を正しく読
+ * めることが保証されないため,テストできない.
+ * (C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ * !割込みロック状態で発生したCPU例外では,システム状態を正しく読
+ * めることが保証されないため,テストできない.
+ * (D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ * !割込みロック状態で発生したCPU例外では,システム状態を正しく読
+ * めることが保証されないため,テストできない.
+ * (E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (I) xsns_xpnがtrueを返すこと
+ * (J) xsns_dpnがtrueを返すこと
+ *
+ * 【使用リソース】
+ *
+ * TASK1: TA_ACT,中優先度,タスク例外処理ルーチン登録
+ * CPUEXC1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(中優先度)==
+ * 1: 状態のチェック
+ * dis_dsp()
+ * ena_tex()
+ * 2: 状態のチェック
+ * SIL_LOC_INT()
+ * RAISE_CPU_EXCEPTION
+ * == CPUEXC1 ==
+ * 3: xsns_xpn() == true ... (I)
+ * xsns_dpn() == true ... (J)
+ * 4: CPU例外ハンドラからリターンできない場合は,ここで終了
+ * 4: リターン
+ * == TASK1(続き)==
+ * 5: SIL_UNL_LOC()
+ * 6: 状態のチェック ... (E)(F)(G)(H)
+ * 7: テスト終了
+ */
+
+#include <sil.h>
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+ SIL_PRE_LOC;
+
+ check_point(1);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+ ercd = ena_tex();
+ check_ercd(ercd, E_OK);
+
+ check_point(2);
+ check_state(false, false, TIPM_ENAALL, true, true, false);
+ SIL_LOC_INT();
+ RAISE_CPU_EXCEPTION;
+
+ check_point(5);
+ SIL_UNL_INT();
+
+ check_point(6);
+ check_state(false, false, TIPM_ENAALL, true, true, false);
+
+ check_finish(7);
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+ check_point(3);
+ check_assert(xsns_xpn(p_excinf) == true);
+ check_assert(xsns_dpn(p_excinf) == true);
+
+#ifdef CANNOT_RETURN_CPUEXC
+ check_finish(4);
+#endif /* CANNOT_RETURN_CPUEXC */
+
+ check_point(4);
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_cpuexc5.c 1577 2009-05-31 14:30:51Z ertl-hiro $
+ */
+
+/*
+ * CPU例外処理のテスト(5)
+ *
+ * 【テストの目的】
+ *
+ * タスクコンテキスト,割込ロック解除,CPUロック状態で発生したCPU例外
+ * におけるシステム状態のテスト.割込み優先度マスク=TIPM_ENAALL,ディ
+ * スパッチ禁止状態,タスク例外許可状態でテストする.
+ *
+ * 【テスト項目】
+ *
+ * いずれも,タスクコンテキスト,割込ロック解除,CPUロック状態で発生し
+ * たCPU例外において,
+ *
+ * (A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ * (B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ * !CPU例外ハンドラ中で割込み優先度マスクを読めないため,テストで
+ * きない.
+ * (C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ * (D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ * (E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ * !CPU例外ハンドラからリターンできる場合のみテストする.
+ * (I) xsns_xpnがtrueを返すこと
+ * (J) xsns_dpnがtrueを返すこと
+ *
+ * 【使用リソース】
+ *
+ * TASK1: TA_ACT,中優先度,タスク例外処理ルーチン登録
+ * CPUEXC1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(中優先度)==
+ * 1: 状態のチェック
+ * dis_dsp()
+ * ena_tex()
+ * loc_cpu()
+ * 2: 状態のチェック
+ * RAISE_CPU_EXCEPTION
+ * == CPUEXC1 ==
+ * 3: 状態のチェック ... (A)(C)(D)
+ * xsns_xpn() == true ... (I)
+ * xsns_dpn() == true ... (J)
+ * 4: CPU例外ハンドラからリターンできない場合は,ここで終了
+ * 4: リターン
+ * == TASK1(続き)==
+ * 5: 状態のチェック ... (E)(F)(G)(H)
+ * 6: テスト終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(1);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+ ercd = ena_tex();
+ check_ercd(ercd, E_OK);
+ ercd = loc_cpu();
+ check_ercd(ercd, E_OK);
+
+ check_point(2);
+ check_state(false, true, TIPM_ENAALL, true, true, false);
+ RAISE_CPU_EXCEPTION;
+
+ check_point(5);
+ check_state(false, true, TIPM_ENAALL, true, true, false);
+
+ check_finish(6);
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+ check_point(3);
+ check_state_i(true, true, true, true, false);
+ check_assert(xsns_xpn(p_excinf) == true);
+ check_assert(xsns_dpn(p_excinf) == true);
+
+#ifdef CANNOT_RETURN_CPUEXC
+ check_finish(4);
+#endif /* CANNOT_RETURN_CPUEXC */
+
+ check_point(4);
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_cpuexc6.c 1577 2009-05-31 14:30:51Z ertl-hiro $
+ */
+
+/*
+ * CPU例外処理のテスト(6)
+ *
+ * 【テストの目的】
+ *
+ * 割込み優先度マスク=TIPM_ENAALL,ディスパッチ許可状態,タスク例外禁
+ * 止状態で発生したCPU例外におけるシステム状態のテスト.タスク切換えに
+ * よりリカバリーできることもテストする.
+ *
+ * 【テスト項目】
+ *
+ * いずれも,割込み優先度マスク=TIPM_ENAALL,ディスパッチ許可状態,タ
+ * スク例外禁止状態で発生したCPU例外において,
+ *
+ * (A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ * (B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ * !CPU例外ハンドラ中で割込み優先度マスクを読めないため,テストで
+ * きない.
+ * (C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ * (D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ * (E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ * (F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ * (G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ * (H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ * (I) xsns_xpnがtrueを返すこと
+ * (J) xsns_dpnがfalseを返すこと
+ * (K) タスク切換えによるリカバリーができること
+ *
+ * 【使用リソース】
+ *
+ * TASK1: TA_ACT,中優先度,タスク例外処理ルーチン登録
+ * TASK2: TA_NULL,高優先度
+ * CPUEXC1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(中優先度,1回目)==
+ * 1: 状態のチェック
+ * 2: RAISE_CPU_EXCEPTION
+ * == CPUEXC1 ==
+ * 3: 状態のチェック ... (A),(C),(D)
+ * xsns_xpn() == true ... (I)
+ * xsns_dpn() == false ... (J)
+ * 4: iact_tsk(TASK2)
+ * iloc_cpu()
+ * リターン
+ * == TASK2(高優先度)==
+ * 5: 状態のチェック ... (E),(F),(G),(H)
+ * 6: ter_tsk(TASK1) ... (K)
+ * 7: act_tsk(TASK1) ... (K)
+ * 8: ext_tsk()
+ * == TASK1(中優先度,2回目)==
+ * 9: 状態のチェック ... (K)
+ * 10: テスト終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+int_t task1_count = 0;
+
+void
+task1(intptr_t exinf)
+{
+ switch (++task1_count) {
+ case 1:
+ check_point(1);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+
+ check_point(2);
+ RAISE_CPU_EXCEPTION;
+
+ check_point(0);
+ break;
+
+ case 2:
+ check_point(9);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+
+ check_finish(10);
+ break;
+
+ default:
+ check_point(0);
+ break;
+ }
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(5);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+
+ check_point(6);
+ ercd = ter_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(7);
+ ercd = act_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(8);
+ ercd = ext_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+ ER ercd;
+
+ check_point(3);
+ check_state_i(true, false, false, true, true);
+ check_assert(xsns_xpn(p_excinf) == true);
+ check_assert(xsns_dpn(p_excinf) == false);
+
+ check_point(4);
+ ercd = iact_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+ ercd = iloc_cpu();
+ check_ercd(ercd, E_OK);
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_cpuexc7.c 1577 2009-05-31 14:30:51Z ertl-hiro $
+ */
+
+/*
+ * CPU例外処理のテスト(7)
+ *
+ * 【テストの目的】
+ *
+ * 割込み優先度マスク=TIPM_ENAALL,ディスパッチ禁止状態,タスク例外許
+ * 可状態で発生したCPU例外におけるシステム状態のテスト.タスク例外によ
+ * りリカバリーできることもテストする.
+ *
+ * 【テスト項目】
+ *
+ * いずれも,割込み優先度マスク=TIPM_ENAALL,ディスパッチ禁止状態,タ
+ * スク例外許可状態で発生したCPU例外において,
+ *
+ * (A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ * (B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ * !CPU例外ハンドラ中で割込み優先度マスクを読めないため,テストで
+ * きない.
+ * (C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ * (D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ * (E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ * (F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ * (G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ * (H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ * (I) xsns_xpnがfalseを返すこと
+ * (J) xsns_dpnがtrueを返すこと
+ * (L) タスク例外によるリカバリーができること
+ *
+ * 【使用リソース】
+ *
+ * TASK1: TA_ACT,中優先度,タスク例外処理ルーチン登録
+ * CPUEXC1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(中優先度,1回目)==
+ * 1: 状態のチェック
+ * dis_dsp()
+ * ena_tex()
+ * 2: 状態のチェック
+ * RAISE_CPU_EXCEPTION
+ * == CPUEXC1 ==
+ * 3: 状態のチェック ... (A),(C),(D)
+ * xsns_xpn() == false ... (I)
+ * xsns_dpn() == true ... (J)
+ * 4: iras_tex(TASK1, 1U)
+ * iloc_cpu()
+ * リターン
+ * == TASK1のタスク例外処理ルーチン ==
+ * 5: 状態のチェック ... (E),(F),(G),(H)
+ * 6: act_tsk(TASK1) ... (L)
+ * 7: ext_tsk() ... (L)
+ * == TASK1(中優先度,2回目)==
+ * 8: 状態のチェック ... (L)
+ * 9: テスト終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+int_t task1_count = 0;
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+
+ switch (++task1_count) {
+ case 1:
+ check_point(1);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+ ercd = ena_tex();
+ check_ercd(ercd, E_OK);
+
+ check_point(2);
+ check_state(false, false, TIPM_ENAALL, true, true, false);
+ RAISE_CPU_EXCEPTION;
+
+ check_point(0);
+ break;
+
+ case 2:
+ check_point(8);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+
+ check_finish(9);
+ break;
+
+ default:
+ check_point(0);
+ break;
+ }
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(5);
+ check_state(false, false, TIPM_ENAALL, true, true, true);
+
+ check_point(6);
+ ercd = act_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(7);
+ ercd = ext_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+ ER ercd;
+
+ check_point(3);
+ check_state_i(true, false, true, true, false);
+ check_assert(xsns_xpn(p_excinf) == false);
+ check_assert(xsns_dpn(p_excinf) == true);
+
+ check_point(4);
+ ercd = iras_tex(TASK1, 1U);
+ check_ercd(ercd, E_OK);
+ ercd = iloc_cpu();
+ check_ercd(ercd, E_OK);
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_cpuexc8.c 1577 2009-05-31 14:30:51Z ertl-hiro $
+ */
+
+/*
+ * CPU例外処理のテスト(8)
+ *
+ * 【テストの目的】
+ *
+ * 割込み優先度マスク=TMAX_INTPRI,ディスパッチ許可状態,タスク例外許
+ * 可状態で発生したCPU例外におけるシステム状態のテスト.タスク例外によ
+ * りリカバリーできることもテストする.
+ *
+ * このテストは,TMAX_INTPRIとTMIN_INTPRIが異なる場合のみ実施する.
+ *
+ * 【テスト項目】
+ *
+ * いずれも,割込み優先度マスク=TMAX_INTPRI,ディスパッチ許可状態,タ
+ * スク例外許可状態で発生したCPU例外において,
+ *
+ * (A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ * (B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ * !CPU例外ハンドラ中で割込み優先度マスクを読めないため,テストで
+ * きない.
+ * (C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ * (D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ * (E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ * (F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ * (G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ * (H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ * (I) xsns_xpnがfalseを返すこと
+ * (J) xsns_dpnがtrueを返すこと
+ * (L) タスク例外によるリカバリーができること
+ *
+ * 【使用リソース】
+ *
+ * TASK1: TA_ACT,中優先度,タスク例外処理ルーチン登録
+ * CPUEXC1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(中優先度,1回目)==
+ * 1: 状態のチェック
+ * chg_ipm(TMAX_INTPRI)
+ * ena_tex()
+ * 2: 状態のチェック
+ * RAISE_CPU_EXCEPTION
+ * == CPUEXC1 ==
+ * 3: 状態のチェック ... (A),(C),(D)
+ * xsns_xpn() == false ... (I)
+ * xsns_dpn() == true ... (J)
+ * 4: iras_tex(TASK1, 1U)
+ * iloc_cpu()
+ * リターン
+ * == TASK1のタスク例外処理ルーチン ==
+ * 5: 状態のチェック ... (E),(F),(G),(H)
+ * 6: act_tsk(TASK1) ... (L)
+ * 7: ext_tsk() ... (L)
+ * == TASK1(中優先度,2回目)==
+ * 8: 状態のチェック ... (L)
+ * 9: テスト終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+int_t task1_count = 0;
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+
+ switch (++task1_count) {
+ case 1:
+ if (TMAX_INTPRI == TMIN_INTPRI) {
+ syslog_0(LOG_NOTICE, "This test program is not necessary.");
+ ext_ker();
+ }
+
+ check_point(1);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+ ercd = chg_ipm(TMAX_INTPRI);
+ check_ercd(ercd, E_OK);
+ ercd = ena_tex();
+ check_ercd(ercd, E_OK);
+
+ check_point(2);
+ check_state(false, false, TMAX_INTPRI, false, true, false);
+ RAISE_CPU_EXCEPTION;
+
+ check_point(0);
+ break;
+
+ case 2:
+ check_point(8);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+
+ check_finish(9);
+ break;
+
+ default:
+ check_point(0);
+ break;
+ }
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(5);
+ check_state(false, false, TMAX_INTPRI, false, true, true);
+
+ check_point(6);
+ ercd = act_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(7);
+ ercd = ext_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+ ER ercd;
+
+ check_point(3);
+ check_state_i(true, false, false, true, false);
+ check_assert(xsns_xpn(p_excinf) == false);
+ check_assert(xsns_dpn(p_excinf) == true);
+
+ check_point(4);
+ ercd = iras_tex(TASK1, 1U);
+ check_ercd(ercd, E_OK);
+ ercd = iloc_cpu();
+ check_ercd(ercd, E_OK);
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_cpuexc9.c 1577 2009-05-31 14:30:51Z ertl-hiro $
+ */
+
+/*
+ * CPU例外処理のテスト(9)
+ *
+ * 【テストの目的】
+ *
+ * 割込み優先度マスク=TMIN_INTPRI,ディスパッチ許可状態,タスク例外許
+ * 可状態で発生したCPU例外におけるシステム状態のテスト.タスク例外によ
+ * りリカバリーできることもテストする.
+ *
+ * 【テスト項目】
+ *
+ * いずれも,割込み優先度マスク=TMIN_INTPRI,ディスパッチ許可状態,タ
+ * スク例外許可状態で発生したCPU例外において,
+ *
+ * (A) CPU例外ハンドラ実行開始時にCPUロックフラグが変化しないこと
+ * (B) CPU例外ハンドラ実行開始時に割込み優先度マスクが変化しないこと
+ * !CPU例外ハンドラ中で割込み優先度マスクを読めないため,テストで
+ * きない.
+ * (C) CPU例外ハンドラ実行開始時にディスパッチ禁止フラグが変化しないこと
+ * (D) CPU例外ハンドラ実行開始時にタスク例外処理禁止フラグが変化しないこと
+ * (E) CPU例外ハンドラリターン時にCPUロックフラグが元に戻ること
+ * (F) CPU例外ハンドラリターン時に割込み優先度マスクが元に戻ること
+ * (G) CPU例外ハンドラリターン時にディスパッチ禁止フラグが変化しないこと
+ * (H) CPU例外ハンドラリターン時にタスク例外処理禁止フラグが変化しないこと
+ * (I) xsns_xpnがfalseを返すこと.ただし,trueを返すことも許されている
+ * (J) xsns_dpnがtrueを返すこと
+ * (L) タスク例外によるリカバリーができること
+ *
+ * 【使用リソース】
+ *
+ * TASK1: TA_ACT,中優先度,タスク例外処理ルーチン登録
+ * CPUEXC1: TA_NULL
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(中優先度,1回目)==
+ * 1: 状態のチェック
+ * chg_ipm(TMIN_INTPRI)
+ * ena_tex()
+ * 2: 状態のチェック
+ * RAISE_CPU_EXCEPTION
+ * == CPUEXC1 ==
+ * 3: 状態のチェック ... (A),(C),(D)
+ * xsns_xpn() == false ... (I)
+ * !trueであってもテストプログラムを続行する
+ * xsns_dpn() == true ... (J)
+ * 4: iras_tex(TASK1, 1U)
+ * iloc_cpu()
+ * リターン
+ * == TASK1のタスク例外処理ルーチン ==
+ * 5: 状態のチェック ... (E),(F),(G),(H)
+ * 6: act_tsk(TASK1) ... (L)
+ * 7: ext_tsk() ... (L)
+ * == TASK1(中優先度,2回目)==
+ * 8: 状態のチェック ... (L)
+ * 9: テスト終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_cpuexc.h"
+
+int_t task1_count = 0;
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+
+ switch (++task1_count) {
+ case 1:
+ check_point(1);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+ ercd = chg_ipm(TMAX_INTPRI);
+ check_ercd(ercd, E_OK);
+ ercd = ena_tex();
+ check_ercd(ercd, E_OK);
+
+ check_point(2);
+ check_state(false, false, TMAX_INTPRI, false, true, false);
+ RAISE_CPU_EXCEPTION;
+
+ check_point(0);
+ break;
+
+ case 2:
+ check_point(8);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+
+ check_finish(9);
+ break;
+
+ default:
+ check_point(0);
+ break;
+ }
+}
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(5);
+ check_state(false, false, TMAX_INTPRI, false, true, true);
+
+ check_point(6);
+ ercd = act_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(7);
+ ercd = ext_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+ ER ercd;
+
+ check_point(3);
+ check_state_i(true, false, false, true, false);
+ if (xsns_xpn(p_excinf) == true) {
+ syslog_0(LOG_WARNING, "xsns_xpn returns true.");
+ }
+ check_assert(xsns_dpn(p_excinf) == true);
+
+ check_point(4);
+ ercd = iras_tex(TASK1, 1U);
+ check_ercd(ercd, E_OK);
+ ercd = iloc_cpu();
+ check_ercd(ercd, E_OK);
+}
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2007-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_dlynse.c 1803 2010-06-20 08:55:06Z ertl-hiro $
+ */
+
+/*
+ * sil_dly_nseに関するテスト
+ */
+
+#include <kernel.h>
+#include <sil.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_dlynse.h"
+
+/*
+ * SIL_DLY_TIM1とSIL_DLY_TIM2を参照するために,カーネル用のヘッダファ
+ * イルをインクルードする.
+ */
+#include "kernel/kernel_impl.h"
+
+#define NO_LOOP ULONG_C(1000000)
+
+SYSTIM empty_time;
+
+static void
+test_empty(void)
+{
+ SYSTIM stime, etime;
+ volatile ulong_t i;
+
+ get_tim(&stime);
+ for (i = 0; i < NO_LOOP; i++) {
+ }
+ get_tim(&etime);
+ empty_time = etime - stime;
+ syslog(LOG_NOTICE, "empty loop: %u", empty_time);
+ syslog_flush();
+}
+
+static void
+test_dly_nse(ulong_t dlytim)
+{
+ SYSTIM stime, etime, delay_time;
+ volatile ulong_t i;
+
+ get_tim(&stime);
+ for (i = 0; i < NO_LOOP; i++) {
+ sil_dly_nse(dlytim);
+ }
+ get_tim(&etime);
+ delay_time = (etime - stime) - empty_time;
+ syslog(LOG_NOTICE, "sil_dly_nse(%u): %u %s", (uint_t)(dlytim),
+ (uint_t)(delay_time), delay_time > dlytim ? "OK" : "NG");
+ syslog_flush();
+}
+
+void
+main_task(intptr_t exinf)
+{
+ test_empty();
+
+ syslog(LOG_NOTICE, "-- for fitting parameters --");
+ test_dly_nse(0);
+ test_dly_nse(SIL_DLY_TIM1);
+ test_dly_nse(SIL_DLY_TIM1 + SIL_DLY_TIM2 * 1);
+ test_dly_nse(SIL_DLY_TIM1 + SIL_DLY_TIM2 * 2);
+ test_dly_nse(SIL_DLY_TIM1 + SIL_DLY_TIM2 * 3);
+ test_dly_nse(SIL_DLY_TIM1 + SIL_DLY_TIM2 * 4);
+ test_dly_nse(SIL_DLY_TIM1 + SIL_DLY_TIM2 * 5);
+ test_dly_nse(SIL_DLY_TIM1 + SIL_DLY_TIM2 * 10);
+ test_dly_nse(SIL_DLY_TIM1 + SIL_DLY_TIM2 * 20);
+ test_dly_nse(SIL_DLY_TIM1 + SIL_DLY_TIM2 * 50);
+
+ syslog(LOG_NOTICE, "-- for checking boundary conditions --");
+ test_dly_nse(SIL_DLY_TIM1 + 1);
+ test_dly_nse(SIL_DLY_TIM1 + SIL_DLY_TIM2 * 1 + 1);
+ test_dly_nse(SIL_DLY_TIM1 + SIL_DLY_TIM2 * 2 + 1);
+
+ test_finish();
+}
--- /dev/null
+/*
+ * @(#) $Id: test_dlynse.cfg 1572 2009-05-31 13:40:39Z ertl-hiro $
+ */
+
+/*
+ * sil_dly_nseに関するテストのシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "test_dlynse.h"
+CRE_TSK(MAIN_TASK, { TA_ACT, 0, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2006,2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_dlynse.h 329 2007-07-17 07:28:32Z hiro $
+ */
+
+/*
+ * sil_dly_nseに関するテスト
+ */
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 各タスクの優先度の定義
+ */
+#define MAIN_PRIORITY 10
+
+/*
+ * ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define STACK_SIZE 4096 /* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void main_task(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2008,2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_sem1.c 1577 2009-05-31 14:30:51Z ertl-hiro $
+ */
+
+/*
+ * セマフォ機能のテスト(1)
+ *
+ * 【テストの目的】
+ *
+ * sig_sem,wai_sem,CRE_SEMを網羅的にテストする.
+ * ただし,CRE_SEMのエラーのテストは除く.
+ *
+ * 【テスト項目】
+ *
+ * (A) sig_semの静的エラーのテスト
+ * (A-1) 非タスクコンテキストからの呼出し
+ * (A-2) CPUロック状態からの呼出し
+ * (A-3) semidが不正(小さすぎる)
+ * (A-4) semidが不正(大きすぎる)
+ * (B) sig_semによりセマフォ待ち状態のタスクが待ち解除される
+ * (B-1) 待ち解除されたタスクに切り換わる
+ * (B-2) ディスパッチ保留状態で,切り換わらない
+ * (B-3) 待ち解除されたタスクが強制待ち状態で,切り換わらない
+ * (B-4) 待ち解除されたタスクが優先度が低く,切り換わらない
+ * (C) sig_semによりセマフォの資源数が1増える
+ * (C-1) セマフォの資源数が0から1になる
+ * (C-2) セマフォの資源数が1から2になる
+ * (D) sig_semがE_QOVRエラーとなる
+ * (D-1) セマフォの最大資源数が1の時
+ * (D-2) セマフォの最大資源数が2の時
+ * (E) wai_semの静的エラーのテスト
+ * (E-1) 非タスクコンテキストからの呼出し
+ * (E-2) CPUロック状態からの呼出し
+ * (E-3) ディスパッチ禁止状態からの呼出し
+ * (E-4) 割込み優先度マスク全解除でない状態からの呼出し
+ * (E-5) semidが不正(小さすぎる)
+ * (E-6) semidが不正(大きすぎる)
+ * (F) wai_semによりセマフォの資源数が1減る
+ * (F-1) セマフォの資源数が1から0になる
+ * (F-2) セマフォの資源数が2から1になる
+ * (G) wai_semによりセマフォ待ち状態になる
+ * (G-1) TA_TNULL属性のセマフォで,待っているタスクがなかった場合
+ * (G-2) TA_TNULL属性のセマフォで,待っているタスクがあった場合
+ * (G-3) TA_TPRI属性のセマフォで,待っているタスクがなかった場合
+ * (G-4) TA_TPRI属性のセマフォで,優先度が高いタスクが待っている場合
+ * (G-5) TA_TPRI属性のセマフォで,優先度が同じタスクが待っている場合
+ * (G-6) TA_TPRI属性のセマフォで,優先度が低いタスクが待っている場合
+ * (H) セマフォ待ち状態が強制解除される
+ * (I) セマフォ待ち状態の間にセマフォが初期化される
+ * (J) セマフォの資源数の初期値が正しく設定される
+ * (J-1) セマフォの資源数の初期値が0
+ * (J-2) セマフォの資源数の初期値が1
+ * (J-3) セマフォの資源数の初期値が2
+ *
+ * 【使用リソース】
+ *
+ * TASK1: 中優先度タスク,TA_ACT属性
+ * TASK2: 高優先度タスク
+ * TASK3: 低優先度タスク
+ * TASK4: 中優先度タスク
+ * TASK5: 中優先度タスク
+ * ALM1: アラームハンドラ
+ * SEM1: TA_NULL属性,初期資源数1,最大資源数1
+ * SEM2: TA_NULL属性,初期資源数2,最大資源数2
+ * SEM3: TA_TPRI属性,初期資源数0,最大資源数1
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(優先度:中)==
+ * 1: ref_sem(SEM1, &rsem)
+ * assert(rsem.wtskid == TSK_NONE)
+ * assert(rsem.semcnt == 1) ... (J-2)
+ * ref_sem(SEM2, &rsem)
+ * assert(rsem.wtskid == TSK_NONE)
+ * assert(rsem.semcnt == 2) ... (J-3)
+ * ref_sem(SEM3, &rsem)
+ * assert(rsem.wtskid == TSK_NONE)
+ * assert(rsem.semcnt == 0) ... (J-1)
+ * 2: loc_cpu()
+ * sig_sem(SEM1) -> E_CTX ... (A-2)
+ * wai_sem(SEM1) -> E_CTX ... (E-2)
+ * unl_cpu()
+ * dis_dsp()
+ * wai_sem(SEM1) -> E_CTX ... (E-3)
+ * ena_dsp()
+ * chg_ipm(TMAX_INTPRI)
+ * wai_sem(SEM1) -> E_CTX ... (E-4)
+ * chg_ipm(TIPM_ENAALL)
+ * sig_sem(0) -> E_ID ... (A-3)
+ * wai_sem(0) -> E_ID ... (E-5)
+ * sig_sem(TNUM_SEMID+1) -> E_ID ... (A-4)
+ * wai_sem(TNUM_SEMID+1) -> E_ID ... (E-6)
+ * 3: act_tsk(TASK3)
+ * 4: slp_tsk()
+ * == TASK3(優先度:低)==
+ * 5: wai_sem(SEM1) ... (F-1)
+ * 6: ref_sem(SEM1, &rsem)
+ * assert(rsem.wtskid == TSK_NONE)
+ * assert(rsem.semcnt == 0)
+ * 7: sta_alm(ALM1, 10)
+ * 8: wai_sem(SEM1) ... (G-1)
+ * == ALM1 ==
+ * 9: sig_sem(SEM1) -> E_CTX ... (A-1)
+ * wai_sem(SEM1) -> E_CTX ... (E-1)
+ * 10: iwup_tsk(TASK1)
+ * 11: RETURN
+ * == TASK1(続き)==
+ * 12: act_tsk(TASK2)
+ * == TASK2(優先度:高)==
+ * 13: wai_sem(SEM1) ... (G-2)
+ * == TASK1(続き)==
+ * 14: ref_sem(SEM1, &rsem)
+ * assert(rsem.wtskid == TASK3)
+ * assert(rsem.semcnt == 0)
+ * 15: sig_sem(SEM1) ... (B-4)
+ * 16: sig_sem(SEM1) ... (B-1)
+ * == TASK2(続き)==
+ * 17: wai_sem(SEM1) ... (G-1)
+ * == TASK1(続き)==
+ * 18: dis_dsp()
+ * 19: sig_sem(SEM1) ... (B-2)
+ * 20: ena_dsp()
+ * == TASK2(続き)==
+ * 21: wai_sem(SEM1) ... (G-1)
+ * == TASK1(続き)==
+ * 22: sus_tsk(TASK2)
+ * 23: sig_sem(SEM1) ... (B-3)
+ * 24: sig_sem(SEM1) ... (C-1)
+ * 25: sig_sem(SEM1) -> E_QOVR ... (D-1)
+ * 26: ref_sem(SEM1, &rsem)
+ * assert(rsem.wtskid == TSK_NONE)
+ * assert(rsem.semcnt == 1)
+ * 27: rsm_tsk(TASK2)
+ * == TASK2(続き)==
+ * 28: wai_sem(SEM2) ... (F-2)
+ * 29: ref_sem(SEM2, &rsem)
+ * assert(rsem.wtskid == TSK_NONE)
+ * assert(rsem.semcnt == 1)
+ * 30: wai_sem(SEM2) ... (F-1)
+ * 31: wai_sem(SEM2) ... (G-1)
+ * == TASK1(続き)==
+ * 32: sig_sem(SEM2) ... (B-1)
+ * == TASK2(続き)==
+ * 33: wai_sem(SEM3) ... (G-3)
+ * == TASK1(続き)==
+ * 34: sig_sem(SEM2) ... (C-1)
+ * 35: sig_sem(SEM2) ... (C-2)
+ * 36: ref_sem(SEM2, &rsem)
+ * assert(rsem.wtskid == TSK_NONE)
+ * assert(rsem.semcnt == 2)
+ * 37: sig_sem(SEM2) -> E_QOVR ... (D-2)
+ * 38: ref_sem(SEM2, &rsem)
+ * assert(rsem.wtskid == TSK_NONE)
+ * assert(rsem.semcnt == 2)
+ * 39: MISSING
+ * 40: tslp_tsk(10) -> E_TMOUT
+ * == TASK3(続き)==
+ * 41: wai_sem(SEM3) ... (G-4)
+ * == TASK1(続き)==
+ * 42: act_tsk(TASK4)
+ * 43: act_tsk(TASK5)
+ * 44: rot_rdq(TPRI_SELF)
+ * == TASK4(優先度:中)==
+ * 45: wai_sem(SEM3) ... (G-6)
+ * == TASK5(優先度:中)==
+ * 46: wai_sem(SEM3) ... (G-5)
+ * == TASK1(続き)==
+ * 47: sig_sem(SEM3) ... (B-1)
+ * == TASK2(続き)==
+ * 48: wai_sem(SEM1)
+ * wai_sem(SEM1) -> E_RLWAI
+ * == TASK1(続き)==
+ * 49: sig_sem(SEM3) ... (B-4)
+ * 50: tslp_tsk(10) -> E_TMOUT
+ * == TASK4(続き)==
+ * 51: ext_tsk() -> noreturn
+ * == TASK1(続き)==
+ * 52: sig_sem(SEM3) ... (B-4)
+ * 53: tslp_tsk(10) -> E_TMOUT
+ * == TASK5(続き)==
+ * 54: ext_tsk() -> noreturn
+ * == TASK1(続き)==
+ * 55: sig_sem(SEM3) ... (B-4)
+ * 56: tslp_tsk(10) -> E_TMOUT
+ * == TASK3(続き)==
+ * 57: ext_tsk() -> noreturn
+ * == TASK1(続き)==
+ * 58: rel_wai(TASK2) ... (H)
+ * == TASK2(続き)==
+ * 59: wai_sem(SEM1) -> E_DLT
+ * == TASK1(続き)==
+ * 60: ini_sem(SEM1) ... (I)
+ * == TASK2(続き)==
+ * 61: ext_tsk() -> noreturn
+ * == TASK1(続き)==
+ * 62: END
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_sem1.h"
+
+void
+alarm1_handler(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(9);
+ ercd = sig_sem(SEM1);
+ check_ercd(ercd, E_CTX);
+
+ ercd = wai_sem(SEM1);
+ check_ercd(ercd, E_CTX);
+
+ check_point(10);
+ ercd = iwup_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(11);
+ return;
+
+ check_point(0);
+}
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+ T_RSEM rsem;
+
+ check_point(1);
+ ercd = ref_sem(SEM1, &rsem);
+ check_ercd(ercd, E_OK);
+ check_assert(rsem.wtskid == TSK_NONE);
+ check_assert(rsem.semcnt == 1);
+
+ ercd = ref_sem(SEM2, &rsem);
+ check_ercd(ercd, E_OK);
+ check_assert(rsem.wtskid == TSK_NONE);
+ check_assert(rsem.semcnt == 2);
+
+ ercd = ref_sem(SEM3, &rsem);
+ check_ercd(ercd, E_OK);
+ check_assert(rsem.wtskid == TSK_NONE);
+ check_assert(rsem.semcnt == 0);
+
+ check_point(2);
+ ercd = loc_cpu();
+ check_ercd(ercd, E_OK);
+
+ ercd = sig_sem(SEM1);
+ check_ercd(ercd, E_CTX);
+
+ ercd = wai_sem(SEM1);
+ check_ercd(ercd, E_CTX);
+
+ ercd = unl_cpu();
+ check_ercd(ercd, E_OK);
+
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+
+ ercd = wai_sem(SEM1);
+ check_ercd(ercd, E_CTX);
+
+ ercd = ena_dsp();
+ check_ercd(ercd, E_OK);
+
+ ercd = chg_ipm(TMAX_INTPRI);
+ check_ercd(ercd, E_OK);
+
+ ercd = wai_sem(SEM1);
+ check_ercd(ercd, E_CTX);
+
+ ercd = chg_ipm(TIPM_ENAALL);
+ check_ercd(ercd, E_OK);
+
+ ercd = sig_sem(0);
+ check_ercd(ercd, E_ID);
+
+ ercd = wai_sem(0);
+ check_ercd(ercd, E_ID);
+
+ ercd = sig_sem(TNUM_SEMID+1);
+ check_ercd(ercd, E_ID);
+
+ ercd = wai_sem(TNUM_SEMID+1);
+ check_ercd(ercd, E_ID);
+
+ check_point(3);
+ ercd = act_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ check_point(4);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(12);
+ ercd = act_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(14);
+ ercd = ref_sem(SEM1, &rsem);
+ check_ercd(ercd, E_OK);
+ check_assert(rsem.wtskid == TASK3);
+ check_assert(rsem.semcnt == 0);
+
+ check_point(15);
+ ercd = sig_sem(SEM1);
+ check_ercd(ercd, E_OK);
+
+ check_point(16);
+ ercd = sig_sem(SEM1);
+ check_ercd(ercd, E_OK);
+
+ check_point(18);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(19);
+ ercd = sig_sem(SEM1);
+ check_ercd(ercd, E_OK);
+
+ check_point(20);
+ ercd = ena_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(22);
+ ercd = sus_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(23);
+ ercd = sig_sem(SEM1);
+ check_ercd(ercd, E_OK);
+
+ check_point(24);
+ ercd = sig_sem(SEM1);
+ check_ercd(ercd, E_OK);
+
+ check_point(25);
+ ercd = sig_sem(SEM1);
+ check_ercd(ercd, E_QOVR);
+
+ check_point(26);
+ ercd = ref_sem(SEM1, &rsem);
+ check_ercd(ercd, E_OK);
+ check_assert(rsem.wtskid == TSK_NONE);
+ check_assert(rsem.semcnt == 1);
+
+ check_point(27);
+ ercd = rsm_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(32);
+ ercd = sig_sem(SEM2);
+ check_ercd(ercd, E_OK);
+
+ check_point(34);
+ ercd = sig_sem(SEM2);
+ check_ercd(ercd, E_OK);
+
+ check_point(35);
+ ercd = sig_sem(SEM2);
+ check_ercd(ercd, E_OK);
+
+ check_point(36);
+ ercd = ref_sem(SEM2, &rsem);
+ check_ercd(ercd, E_OK);
+ check_assert(rsem.wtskid == TSK_NONE);
+ check_assert(rsem.semcnt == 2);
+
+ check_point(37);
+ ercd = sig_sem(SEM2);
+ check_ercd(ercd, E_QOVR);
+
+ check_point(38);
+ ercd = ref_sem(SEM2, &rsem);
+ check_ercd(ercd, E_OK);
+ check_assert(rsem.wtskid == TSK_NONE);
+ check_assert(rsem.semcnt == 2);
+
+ check_point(39);
+
+ check_point(40);
+ ercd = tslp_tsk(10);
+ check_ercd(ercd, E_TMOUT);
+
+ check_point(42);
+ ercd = act_tsk(TASK4);
+ check_ercd(ercd, E_OK);
+
+ check_point(43);
+ ercd = act_tsk(TASK5);
+ check_ercd(ercd, E_OK);
+
+ check_point(44);
+ ercd = rot_rdq(TPRI_SELF);
+ check_ercd(ercd, E_OK);
+
+ check_point(47);
+ ercd = sig_sem(SEM3);
+ check_ercd(ercd, E_OK);
+
+ check_point(49);
+ ercd = sig_sem(SEM3);
+ check_ercd(ercd, E_OK);
+
+ check_point(50);
+ ercd = tslp_tsk(10);
+ check_ercd(ercd, E_TMOUT);
+
+ check_point(52);
+ ercd = sig_sem(SEM3);
+ check_ercd(ercd, E_OK);
+
+ check_point(53);
+ ercd = tslp_tsk(10);
+ check_ercd(ercd, E_TMOUT);
+
+ check_point(55);
+ ercd = sig_sem(SEM3);
+ check_ercd(ercd, E_OK);
+
+ check_point(56);
+ ercd = tslp_tsk(10);
+ check_ercd(ercd, E_TMOUT);
+
+ check_point(58);
+ ercd = rel_wai(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(60);
+ ercd = ini_sem(SEM1);
+ check_ercd(ercd, E_OK);
+
+ check_finish(62);
+
+ check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+ ER ercd;
+ T_RSEM rsem;
+
+ check_point(13);
+ ercd = wai_sem(SEM1);
+ check_ercd(ercd, E_OK);
+
+ check_point(17);
+ ercd = wai_sem(SEM1);
+ check_ercd(ercd, E_OK);
+
+ check_point(21);
+ ercd = wai_sem(SEM1);
+ check_ercd(ercd, E_OK);
+
+ check_point(28);
+ ercd = wai_sem(SEM2);
+ check_ercd(ercd, E_OK);
+
+ check_point(29);
+ ercd = ref_sem(SEM2, &rsem);
+ check_ercd(ercd, E_OK);
+ check_assert(rsem.wtskid == TSK_NONE);
+ check_assert(rsem.semcnt == 1);
+
+ check_point(30);
+ ercd = wai_sem(SEM2);
+ check_ercd(ercd, E_OK);
+
+ check_point(31);
+ ercd = wai_sem(SEM2);
+ check_ercd(ercd, E_OK);
+
+ check_point(33);
+ ercd = wai_sem(SEM3);
+ check_ercd(ercd, E_OK);
+
+ check_point(48);
+ ercd = wai_sem(SEM1);
+ check_ercd(ercd, E_OK);
+
+ ercd = wai_sem(SEM1);
+ check_ercd(ercd, E_RLWAI);
+
+ check_point(59);
+ ercd = wai_sem(SEM1);
+ check_ercd(ercd, E_DLT);
+
+ check_point(61);
+ ercd = ext_tsk();
+
+ check_point(0);
+}
+
+void
+task3(intptr_t exinf)
+{
+ ER ercd;
+ T_RSEM rsem;
+
+ check_point(5);
+ ercd = wai_sem(SEM1);
+ check_ercd(ercd, E_OK);
+
+ check_point(6);
+ ercd = ref_sem(SEM1, &rsem);
+ check_ercd(ercd, E_OK);
+ check_assert(rsem.wtskid == TSK_NONE);
+ check_assert(rsem.semcnt == 0);
+
+ check_point(7);
+ ercd = sta_alm(ALM1, 10);
+ check_ercd(ercd, E_OK);
+
+ check_point(8);
+ ercd = wai_sem(SEM1);
+ check_ercd(ercd, E_OK);
+
+ check_point(41);
+ ercd = wai_sem(SEM3);
+ check_ercd(ercd, E_OK);
+
+ check_point(57);
+ ercd = ext_tsk();
+
+ check_point(0);
+}
+
+void
+task4(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(45);
+ ercd = wai_sem(SEM3);
+ check_ercd(ercd, E_OK);
+
+ check_point(51);
+ ercd = ext_tsk();
+
+ check_point(0);
+}
+
+void
+task5(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(46);
+ ercd = wai_sem(SEM3);
+ check_ercd(ercd, E_OK);
+
+ check_point(54);
+ ercd = ext_tsk();
+
+ check_point(0);
+}
--- /dev/null
+/*
+ * @(#) $Id: test_sem1.cfg 1572 2009-05-31 13:40:39Z ertl-hiro $
+ */
+
+/*
+ * セマフォ機能のテスト(1)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "test_sem1.h"
+
+CRE_TSK(TASK1, { TA_ACT, 1, task1, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task2, HIGH_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK3, { TA_NULL, 3, task3, LOW_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK4, { TA_NULL, 4, task4, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK5, { TA_NULL, 5, task5, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_ALM(ALM1, { TA_NULL, 1, alarm1_handler });
+CRE_SEM(SEM1, { TA_NULL, 1, 1 });
+CRE_SEM(SEM2, { TA_NULL, 2, 2 });
+CRE_SEM(SEM3, { TA_TPRI, 0, 1 });
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_sem1.h 1232 2008-08-09 13:30:32Z ertl-hiro $
+ */
+
+/*
+ * セマフォ機能のテスト(1)
+ */
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 優先度の定義
+ */
+#define HIGH_PRIORITY 9 /* 高優先度 */
+#define MID_PRIORITY 10 /* 中優先度 */
+#define LOW_PRIORITY 11 /* 低優先度 */
+
+/*
+ * ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define STACK_SIZE 4096 /* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void task1(intptr_t exinf);
+extern void task2(intptr_t exinf);
+extern void task3(intptr_t exinf);
+extern void task4(intptr_t exinf);
+extern void task5(intptr_t exinf);
+extern void alarm1_handler(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2008,2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_sem2.c 1577 2009-05-31 14:30:51Z ertl-hiro $
+ */
+
+/*
+ * セマフォ機能のテスト(2)
+ *
+ * 【テストの目的】
+ *
+ * isig_semを,sig_semとの違いを中心にテストする.
+ * pol_sem,twai_semを,wai_semとの違いを中心にテストする.
+ *
+ * 【テスト項目】
+ *
+ * (A) isig_semの静的エラーのテスト
+ * (A-1) タスクコンテキストからの呼出し
+ * (A-2) CPUロック状態からの呼出し
+ * (B) isig_semによりセマフォ待ち状態のタスクが待ち解除される
+ * (B-1) アイドル状態から,待ち解除されたタスクに切り換わる
+ * (B-2) 実行状態のタスクから,待ち解除されたタスクに切り換わる
+ * (B-3) ディスパッチ保留状態で,切り換わらない
+ * (B-4) 待ち解除されたタスクが強制待ち状態で,切り換わらない
+ * (B-5) 待ち解除されたタスクが優先度が低く,切り換わらない
+ * (C) pol_semの静的エラーのテスト
+ * (C-1) 非タスクコンテキストからの呼出し
+ * (C-2) CPUロック状態からの呼出し
+ * (C-3) ディスパッチ禁止状態からの呼出し(E_CTXエラーにならない)
+ * (C-4) 割込み優先度マスク全解除でない状態からの呼出し(E_CTXエラー
+ * にならない)
+ * (D) pol_semでポーリング失敗する
+ * (E) twai_semの静的エラーのテスト
+ * (E-1) 非タスクコンテキストからの呼出し
+ * (E-2) CPUロック状態からの呼出し
+ * (E-3) ディスパッチ禁止状態からの呼出し
+ * (E-4) 割込み優先度マスク全解除でない状態からの呼出し
+ * (E-5) tmoutが不正
+ * (F) twai_semでtmout=TMO_POLの時にポーリング失敗する
+ * (G) twai_semでtmout=TMO_FEVRの時にセマフォ待ち状態になる
+ * (H) twai_semでtmoutにタイムアウトを設定した時に,タイムアウト付きの
+ * セマフォ待ち状態になる
+ *
+ * 【使用リソース】
+ *
+ * TASK1: 中優先度タスク,TA_ACT属性
+ * TASK2: 高優先度タスク
+ * TASK3: 低優先度タスク
+ * TASK4: 中優先度タスク
+ * TASK5: 中優先度タスク
+ * ALM1: アラームハンドラ
+ * SEM1: TA_NULL属性,初期資源数1,最大資源数1
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(優先度:中)==
+ * 1: isig_sem(SEM1) -> E_CTX ... (A-1)
+ * 2: loc_cpu()
+ * pol_sem(SEM1) -> E_CTX ... (C-2)
+ * twai_sem(SEM1, TMO_POL) -> E_CTX ... (E-2)
+ * unl_cpu()
+ * 3: dis_dsp()
+ * pol_sem(SEM1) ... (C-3)
+ * twai_sem(SEM1, TMO_POL) -> E_CTX ... (E-3)
+ * ena_dsp()
+ * 4: chg_ipm(TMAX_INTPRI)
+ * pol_sem(SEM1) -> E_TMOUT ... (C-4)(D)
+ * twai_sem(SEM1, TMO_POL) -> E_CTX ... (E-4)
+ * chg_ipm(TIPM_ENAALL)
+ * 5: twai_sem(SEM1, -2) -> E_PAR ... (E-5)
+ * twai_sem(SEM1, TMO_POL) -> E_TMOUT ... (F)
+ * 6: sta_alm(ALM1, 10)
+ * 7: twai_sem(SEM1, TMO_FEVR) ... (G)
+ * == ALM1-1 ==
+ * 8: pol_sem(SEM1) -> E_CTX ... (C-1)
+ * twai_sem(SEM1, TMO_POL) -> E_CTX ... (E-1)
+ * 9: iloc_cpu()
+ * isig_sem(SEM1) -> E_CTX ... (A-2)
+ * iunl_cpu()
+ * 10: isig_sem(SEM1) ... (B-1)
+ * RETURN
+ * == TASK1(続き)==
+ * 11: act_tsk(TASK3)
+ * 12: wai_sem(SEM1)
+ * == TASK3(優先度:低)==
+ * 13: sta_alm(ALM1, 10)
+ * call(wait_var())
+ * == ALM1-2 ==
+ * 14: isig_sem(SEM1) ... (B-2)
+ * call(signal_var())
+ * RETURN
+ * == TASK1(続き)==
+ * 15: wai_sem(SEM1)
+ * == TASK3(続き)==
+ * 16: sta_alm(ALM1, 10)
+ * dis_dsp()
+ * call(wait_var())
+ * == ALM1-3 ==
+ * 17: isig_sem(SEM1) ... (B-3)
+ * call(signal_var())
+ * RETURN
+ * == TASK3(続き)==
+ * 18: ena_dsp()
+ * == TASK1(続き)==
+ * 19: wai_sem(SEM1)
+ * == TASK3(続き)==
+ * 20: sta_alm(ALM1, 10)
+ * sus_tsk(TASK1)
+ * call(wait_var())
+ * == ALM1-4 ==
+ * 21: isig_sem(SEM1) ... (B-4)
+ * call(signal_var())
+ * RETURN
+ * == TASK3(続き)==
+ * 22: rsm_tsk(TASK1)
+ * == TASK1(続き)==
+ * 23: act_tsk(TASK2)
+ * == TASK2(優先度:高)==
+ * 24: tslp_tsk(10) -> E_TMOUT
+ * == TASK1(続き)==
+ * 25: wai_sem(SEM1)
+ * == TASK3(続き)==
+ * 26: ext_tsk() -> noreturn
+ * == TASK2(続き)==
+ * 27: sta_alm(ALM1, 10)
+ * call(wait_var())
+ * == ALM1-5 ==
+ * 28: isig_sem(SEM1) ... (B-5)
+ * call(signal_var())
+ * RETURN
+ * == TASK2(続き)==
+ * 29: ext_tsk() -> noreturn
+ * == TASK1(続き)==
+ * 30: sta_alm(ALM1, 10)
+ * 31: twai_sem(SEM1, 100) -> E_RLWAI
+ * == ALM1-6 ==
+ * 32: irel_wai(TASK1)
+ * RETURN
+ * == TASK1(続き)==
+ * 33: sta_alm(ALM1, 100)
+ * 34: twai_sem(SEM1, 10) -> E_TMOUT ... (H)
+ * 35: stp_alm(ALM1)
+ * 36: END
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_sem2.h"
+
+static volatile bool_t flagvar;
+
+static void
+wait_var(void)
+{
+ flagvar = false;
+ while (!flagvar);
+}
+
+static void
+signal_var(void)
+{
+ flagvar = true;
+}
+
+static uint_t alarm1_count = 0;
+
+void
+alarm1_handler(intptr_t exinf)
+{
+ ER ercd;
+
+ switch (++alarm1_count) {
+ case 1:
+ check_point(8);
+ ercd = pol_sem(SEM1);
+ check_ercd(ercd, E_CTX);
+
+ ercd = twai_sem(SEM1, TMO_POL);
+ check_ercd(ercd, E_CTX);
+
+ check_point(9);
+ ercd = iloc_cpu();
+ check_ercd(ercd, E_OK);
+
+ ercd = isig_sem(SEM1);
+ check_ercd(ercd, E_CTX);
+
+ ercd = iunl_cpu();
+ check_ercd(ercd, E_OK);
+
+ check_point(10);
+ ercd = isig_sem(SEM1);
+ check_ercd(ercd, E_OK);
+
+ return;
+
+ check_point(0);
+
+ case 2:
+ check_point(14);
+ ercd = isig_sem(SEM1);
+ check_ercd(ercd, E_OK);
+
+ signal_var();
+
+ return;
+
+ check_point(0);
+
+ case 3:
+ check_point(17);
+ ercd = isig_sem(SEM1);
+ check_ercd(ercd, E_OK);
+
+ signal_var();
+
+ return;
+
+ check_point(0);
+
+ case 4:
+ check_point(21);
+ ercd = isig_sem(SEM1);
+ check_ercd(ercd, E_OK);
+
+ signal_var();
+
+ return;
+
+ check_point(0);
+
+ case 5:
+ check_point(28);
+ ercd = isig_sem(SEM1);
+ check_ercd(ercd, E_OK);
+
+ signal_var();
+
+ return;
+
+ check_point(0);
+
+ case 6:
+ check_point(32);
+ ercd = irel_wai(TASK1);
+ check_ercd(ercd, E_OK);
+
+ return;
+
+ check_point(0);
+ }
+ check_point(0);
+}
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(1);
+ ercd = isig_sem(SEM1);
+ check_ercd(ercd, E_CTX);
+
+ check_point(2);
+ ercd = loc_cpu();
+ check_ercd(ercd, E_OK);
+
+ ercd = pol_sem(SEM1);
+ check_ercd(ercd, E_CTX);
+
+ ercd = twai_sem(SEM1, TMO_POL);
+ check_ercd(ercd, E_CTX);
+
+ ercd = unl_cpu();
+ check_ercd(ercd, E_OK);
+
+ check_point(3);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+
+ ercd = pol_sem(SEM1);
+ check_ercd(ercd, E_OK);
+
+ ercd = twai_sem(SEM1, TMO_POL);
+ check_ercd(ercd, E_CTX);
+
+ ercd = ena_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(4);
+ ercd = chg_ipm(TMAX_INTPRI);
+ check_ercd(ercd, E_OK);
+
+ ercd = pol_sem(SEM1);
+ check_ercd(ercd, E_TMOUT);
+
+ ercd = twai_sem(SEM1, TMO_POL);
+ check_ercd(ercd, E_CTX);
+
+ ercd = chg_ipm(TIPM_ENAALL);
+ check_ercd(ercd, E_OK);
+
+ check_point(5);
+ ercd = twai_sem(SEM1, -2);
+ check_ercd(ercd, E_PAR);
+
+ ercd = twai_sem(SEM1, TMO_POL);
+ check_ercd(ercd, E_TMOUT);
+
+ check_point(6);
+ ercd = sta_alm(ALM1, 10);
+ check_ercd(ercd, E_OK);
+
+ check_point(7);
+ ercd = twai_sem(SEM1, TMO_FEVR);
+ check_ercd(ercd, E_OK);
+
+ check_point(11);
+ ercd = act_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ check_point(12);
+ ercd = wai_sem(SEM1);
+ check_ercd(ercd, E_OK);
+
+ check_point(15);
+ ercd = wai_sem(SEM1);
+ check_ercd(ercd, E_OK);
+
+ check_point(19);
+ ercd = wai_sem(SEM1);
+ check_ercd(ercd, E_OK);
+
+ check_point(23);
+ ercd = act_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(25);
+ ercd = wai_sem(SEM1);
+ check_ercd(ercd, E_OK);
+
+ check_point(30);
+ ercd = sta_alm(ALM1, 10);
+ check_ercd(ercd, E_OK);
+
+ check_point(31);
+ ercd = twai_sem(SEM1, 100);
+ check_ercd(ercd, E_RLWAI);
+
+ check_point(33);
+ ercd = sta_alm(ALM1, 100);
+ check_ercd(ercd, E_OK);
+
+ check_point(34);
+ ercd = twai_sem(SEM1, 10);
+ check_ercd(ercd, E_TMOUT);
+
+ check_point(35);
+ ercd = stp_alm(ALM1);
+ check_ercd(ercd, E_OK);
+
+ check_finish(36);
+
+ check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(24);
+ ercd = tslp_tsk(10);
+ check_ercd(ercd, E_TMOUT);
+
+ check_point(27);
+ ercd = sta_alm(ALM1, 10);
+ check_ercd(ercd, E_OK);
+
+ wait_var();
+
+ check_point(29);
+ ercd = ext_tsk();
+
+ check_point(0);
+}
+
+void
+task3(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(13);
+ ercd = sta_alm(ALM1, 10);
+ check_ercd(ercd, E_OK);
+
+ wait_var();
+
+ check_point(16);
+ ercd = sta_alm(ALM1, 10);
+ check_ercd(ercd, E_OK);
+
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+
+ wait_var();
+
+ check_point(18);
+ ercd = ena_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(20);
+ ercd = sta_alm(ALM1, 10);
+ check_ercd(ercd, E_OK);
+
+ ercd = sus_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ wait_var();
+
+ check_point(22);
+ ercd = rsm_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(26);
+ ercd = ext_tsk();
+
+ check_point(0);
+}
--- /dev/null
+/*
+ * @(#) $Id: test_sem2.cfg 1572 2009-05-31 13:40:39Z ertl-hiro $
+ */
+
+/*
+ * セマフォ機能のテスト(2)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "test_sem2.h"
+
+CRE_TSK(TASK1, { TA_ACT, 1, task1, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task2, HIGH_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK3, { TA_NULL, 3, task3, LOW_PRIORITY, STACK_SIZE, NULL });
+CRE_ALM(ALM1, { TA_NULL, 1, alarm1_handler });
+CRE_SEM(SEM1, { TA_NULL, 1, 1 });
+CRE_SEM(SEM2, { TA_TPRI, 0, 1 });
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_sem2.h 1390 2008-11-23 14:24:08Z ertl-hiro $
+ */
+
+/*
+ * セマフォ機能のテスト(2)
+ */
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 優先度の定義
+ */
+#define HIGH_PRIORITY 9 /* 高優先度 */
+#define MID_PRIORITY 10 /* 中優先度 */
+#define LOW_PRIORITY 11 /* 低優先度 */
+
+/*
+ * ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define STACK_SIZE 4096 /* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void task1(intptr_t exinf);
+extern void task2(intptr_t exinf);
+extern void task3(intptr_t exinf);
+extern void alarm1_handler(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2006-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_sysstat1.c 1652 2009-10-10 18:01:05Z ertl-hiro $
+ */
+
+/*
+ * システム状態に関するテスト(1)
+ *
+ * テストシーケンス:
+ *
+ * == TASK1(優先度:10)==
+ * 1: 初期状態のチェック
+ * 2: loc_cpu() ... システム状態をランダムに変化させる
+ * chg_ipm(TMAX_INTPRI) -> E_CTX
+ * 3: unl_cpu()
+ * 4: chg_ipm(TMAX_INTPRI)
+ * 5: dis_dsp()
+ * 6: ena_tex()
+ * 7: chg_ipm(TIPM_ENAALL)
+ * 8: ena_dsp()
+ * 9: dis_tex()
+ * 10: dis_dsp() ... タスク例外処理ルーチンを呼び出す準備
+ * chg_ipm(TMIN_INTPRI)
+ * ena_tex()
+ * 11: ras_tex(TSK_SELF, 0x0001)
+ * == TASK1タスク例外処理ルーチン(1回目)==
+ * 12: 初期状態のチェック
+ * 13: ena_dsp() ... 3つの状態を変化させ,リターンで元にもどるか調べる
+ * chg_ipm(TIPM_ENAALL)
+ * ena_tex()
+ * リターン
+ * == TASK1(続き)==
+ * 14: 戻ってきた状態のチェック
+ * 15: loc_cpu() ... CPUロック状態のままタスクを終了させる
+ * 16: リターン(=タスク終了)
+ * == TASK2(優先度:10) ==
+ * 17: 初期状態のチェック
+ * 18: 終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_sysstat1.h"
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+ ER ercd;
+
+ switch (texptn) {
+ case 0x0001:
+ check_point(12);
+ check_state(false, false, TMIN_INTPRI, true, true, true);
+
+ /*
+ * ディスパッチ許可,割込み優先度マスク変更,タスク例外処理許可
+ */
+ check_point(13);
+ ercd = ena_dsp();
+ check_ercd(ercd, E_OK);
+ ercd = chg_ipm(TIPM_ENAALL);
+ check_ercd(ercd, E_OK);
+ ercd = ena_tex();
+ check_ercd(ercd, E_OK);
+ check_state(false, false, TIPM_ENAALL, false, false, false);
+ break;
+
+ default:
+ check_point(0);
+ break;
+ }
+}
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+
+ /*
+ * 初期状態のチェック
+ */
+ check_point(1);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+
+ /*
+ * CPUロック状態のチェック
+ */
+ check_point(2);
+ ercd = loc_cpu();
+ check_ercd(ercd, E_OK);
+ check_state(false, true, TIPM_ENAALL, false, true, true);
+
+ /*
+ * 割込み優先度マスク変更のチェック
+ */
+ ercd = chg_ipm(TMAX_INTPRI);
+ check_ercd(ercd, E_CTX);
+ check_state(false, true, TIPM_ENAALL, false, true, true);
+
+ /*
+ * CPUロック解除のチェック
+ */
+ check_point(3);
+ ercd = unl_cpu();
+ check_ercd(ercd, E_OK);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+
+ /*
+ * 割込み優先度マスク変更のチェック
+ */
+ check_point(4);
+ ercd = chg_ipm(TMAX_INTPRI);
+ check_ercd(ercd, E_OK);
+ check_state(false, false, TMAX_INTPRI, false, true, true);
+
+ /*
+ * ディスパッチ禁止のチェック
+ */
+ check_point(5);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+ check_state(false, false, TMAX_INTPRI, true, true, true);
+
+ /*
+ * タスク例外処理許可のチェック
+ */
+ check_point(6);
+ ercd = ena_tex();
+ check_ercd(ercd, E_OK);
+ check_state(false, false, TMAX_INTPRI, true, true, false);
+
+ /*
+ * 割込み優先度マスク全解除のチェック
+ */
+ check_point(7);
+ ercd = chg_ipm(TIPM_ENAALL);
+ check_ercd(ercd, E_OK);
+ check_state(false, false, TIPM_ENAALL, true, true, false);
+
+ /*
+ * ディスパッチ許可のチェック
+ */
+ check_point(8);
+ ercd = ena_dsp();
+ check_ercd(ercd, E_OK);
+ check_state(false, false, TIPM_ENAALL, false, false, false);
+
+ /*
+ * タスク例外処理禁止のチェック
+ */
+ check_point(9);
+ ercd = dis_tex();
+ check_ercd(ercd, E_OK);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+
+ /*
+ * ディスパッチ禁止,割込み優先度マスク変更,タスク例外処理許可
+ */
+ check_point(10);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+ ercd = chg_ipm(TMIN_INTPRI);
+ check_ercd(ercd, E_OK);
+ ercd = ena_tex();
+ check_ercd(ercd, E_OK);
+ check_state(false, false, TMIN_INTPRI, true, true, false);
+
+ /*
+ * タスク例外処理を要求
+ */
+ check_point(11);
+ ercd = ras_tex(TSK_SELF, 0x0001);
+ /* ここでタスク例外処理ルーチンが動作する */
+ check_ercd(ercd, E_OK);
+
+ /*
+ * タスク例外処理からのリターンにより元の状態に戻っていることを
+ * チェック
+ */
+ check_point(14);
+ check_state(false, false, TMIN_INTPRI, true, true, false);
+
+ /*
+ * CPUロック状態に
+ */
+ check_point(15);
+ ercd = loc_cpu();
+ check_ercd(ercd, E_OK);
+
+ /*
+ * そのままタスク終了
+ */
+ check_point(16);
+}
+
+void
+task2(intptr_t exinf)
+{
+ /*
+ * 初期状態のチェック
+ */
+ check_point(17);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+
+ check_finish(18);
+}
--- /dev/null
+/*
+ * @(#) $Id: test_sysstat1.cfg 1572 2009-05-31 13:40:39Z ertl-hiro $
+ */
+
+/*
+ * システム状態に関するテスト(1)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "test_sysstat1.h"
+
+CRE_TSK(TASK1, { TA_ACT, 1, task1, TASK1_PRIORITY, STACK_SIZE, NULL });
+DEF_TEX(TASK1, { TA_NULL, tex_task1 });
+
+CRE_TSK(TASK2, { TA_ACT, 2, task2, TASK2_PRIORITY, STACK_SIZE, NULL });
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2006,2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_sysstat1.h 329 2007-07-17 07:28:32Z hiro $
+ */
+
+/*
+ * システム状態に関するテスト(1)
+ */
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 各タスクの優先度の定義
+ */
+#define TASK1_PRIORITY 10 /* タスク1の優先度 */
+#define TASK2_PRIORITY 10 /* タスク2の優先度 */
+
+/*
+ * ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define STACK_SIZE 4096 /* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void tex_task1(TEXPTN texptn, intptr_t exinf);
+extern void task1(intptr_t exinf);
+
+extern void task2(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_task1.c 1577 2009-05-31 14:30:51Z ertl-hiro $
+ */
+
+/*
+ * タスク管理モジュールのテスト(1)
+ *
+ * 【テストの目的】
+ *
+ * make_runnableとmake_non_runnableを網羅的にテストする.
+ *
+ * 【テスト項目】
+ *
+ * (A) 実行状態のタスクよりも高い優先度のタスクを実行できる状態にする
+ * (A-1) ディスパッチ保留状態ではない場合
+ * (A-2) ディスパッチ保留状態の場合
+ * (B) 実行状態のタスクと同じ優先度のタスクを実行できる状態にする
+ * !同じ優先度のタスクの中の末尾に入ることを確認する
+ * (C) 実行状態のタスクよりも低い優先度のタスクを実行できる状態にする
+ * !同じ優先度のタスクの中の末尾に入ることを確認する
+ * (D) 実行できる状態のタスクがない状態で,タスクを実行できる状態にする
+ * !この場合は,ディスパッチ保留状態ではない
+ * (E) ディスパッチ保留状態で,実行状態になるべきだが実行可能状態タス
+ * クよりも高い優先度のタスクを,実行できる状態にする
+ * (F) ディスパッチ保留状態で,実行状態になるべきだが実行可能状態タス
+ * クと同じ優先度のタスクを,実行できる状態にする
+ * (G) ディスパッチ保留状態で,実行状態になるべきだが実行可能状態タス
+ * クよりも低い優先度のタスクを,実行できる状態にする
+ * (H) 実行状態のタスクを,実行できる状態でなくす
+ * (H-1) 実行できる状態のタスクがなくなる場合
+ * (H-2) 同一優先度のタスクがなくなる場合
+ * (H-3) 同一優先度のタスクがなくならない場合
+ * (I) 実行可能状態のタスクを,実行できる状態でなくす
+ * (I-1) 同一優先度のタスクがなくなる場合
+ * (I-2) 同一優先度のタスクがなくならない場合
+ * (J) ディスパッチ保留状態で,実行状態になるべきだが実行可能状態となっ
+ * ているタスクを,実行できる状態でなくす
+ * (J-1) 同一優先度のタスクがなくなる場合
+ * (J-2) 同一優先度のタスクがなくならない場合
+ * (K) ディスパッチ保留状態で,実行可能状態になるべきだが実行状態のタ
+ * スクを,実行できる状態でなくす
+ * !ディスパッチ保留では,実行状態のタスクが実行できる状態でなく
+ * なるような遷移を起こすことができないため,この状況は起こらない.
+ *
+ * 【使用リソース】
+ *
+ * TASK1: 中優先度タスク,メインタスク,最初から起動
+ * TASK2: 高優先度タスク
+ * TASK3: 中優先度タスク
+ * TASK4: 中優先度タスク
+ * TASK5: 低優先度タスク
+ * TASK6: 低優先度タスク
+ * ALM1: アラームハンドラ
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(優先度:中)==
+ * 1: act_tsk(TASK2) ... (A-1)
+ * == TASK2(優先度:高)==
+ * 2: slp_tsk() ... (H-2)
+ * == TASK1(続き)==
+ * 3: act_tsk(TASK3) ... (B)
+ * 4: act_tsk(TASK4) ... (B)
+ * 5: slp_tsk() ... (H-3)
+ * == TASK3(優先度:中)==
+ * 6: slp_tsk() ... (H-3)
+ * == TASK4(優先度:中)==
+ * 7: wup_tsk(TASK1)
+ * 8: slp_tsk() ... (H-3)
+ * == TASK1(続き)==
+ * 9: act_tsk(TASK5) ... (C)
+ * 10: act_tsk(TASK6) ... (C)
+ * 11: sus_tsk(TASK6) ... (I-2)
+ * 12: sus_tsk(TASK5) ... (I-1)
+ * 13: rsm_tsk(TASK5) ... (C)
+ * 14: rsm_tsk(TASK6) ... (C)
+ * 15: slp_tsk() ... (H-2)
+ * == TASK5(優先度:低)==
+ * 16: slp_tsk() ... (H-3)
+ * == TASK6(優先度:低)==
+ * 17: dis_dsp()
+ * 18: wup_tsk(TASK1) ... (A-2)
+ * 19: wup_tsk(TASK2) ... (E)
+ * 20: sus_tsk(TASK2) ... (J-1)
+ * 21: wup_tsk(TASK3) ... (F)
+ * 22: wup_tsk(TASK4) ... (F)
+ * 23: sus_tsk(TASK1) ... (J-2)
+ * 24: ena_dsp()
+ * == TASK3(続き)==
+ * 25: slp_tsk() ... (H-3)
+ * == TASK4(続き)==
+ * 26: slp_tsk() ... (H-2)
+ * == TASK6(続き)==
+ * 27: dis_dsp()
+ * 28: rsm_tsk(TASK1) ... (A-2)
+ * 29: wup_tsk(TASK5) ... (G)
+ * 30: ena_dsp()
+ * == TASK1(続き)==
+ * 31: slp_tsk() ... (H-2)
+ * == TASK6(続き)==
+ * 32: slp_tsk() ... (H-3)
+ * == TASK5(続き)==
+ * 33: sta_alm(ALM1, 10)
+ * 34: slp_tsk() ... (H-1)
+ * == ALM1 ==
+ * 35: iget_tid(&tskid)
+ * assert(tskid == TSK_NONE)
+ * 36: iwup_tsk(TASK1) ... (D)
+ * 37: RETURN
+ * == TASK1(続き)==
+ * 38: END
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_task1.h"
+
+void
+alarm1_handler(intptr_t exinf)
+{
+ ER ercd;
+ ID tskid;
+
+ check_point(35);
+ ercd = iget_tid(&tskid);
+ check_ercd(ercd, E_OK);
+ check_assert(tskid == TSK_NONE);
+
+ check_point(36);
+ ercd = iwup_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(37);
+ return;
+
+ check_point(0);
+}
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(1);
+ ercd = act_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(3);
+ ercd = act_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ check_point(4);
+ ercd = act_tsk(TASK4);
+ check_ercd(ercd, E_OK);
+
+ check_point(5);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(9);
+ ercd = act_tsk(TASK5);
+ check_ercd(ercd, E_OK);
+
+ check_point(10);
+ ercd = act_tsk(TASK6);
+ check_ercd(ercd, E_OK);
+
+ check_point(11);
+ ercd = sus_tsk(TASK6);
+ check_ercd(ercd, E_OK);
+
+ check_point(12);
+ ercd = sus_tsk(TASK5);
+ check_ercd(ercd, E_OK);
+
+ check_point(13);
+ ercd = rsm_tsk(TASK5);
+ check_ercd(ercd, E_OK);
+
+ check_point(14);
+ ercd = rsm_tsk(TASK6);
+ check_ercd(ercd, E_OK);
+
+ check_point(15);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(31);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_finish(38);
+
+ check_point(0);
+}
+
+void
+task2(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(2);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(0);
+}
+
+void
+task3(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(6);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(25);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(0);
+}
+
+void
+task4(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(7);
+ ercd = wup_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(8);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(26);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(0);
+}
+
+void
+task5(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(16);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(33);
+ ercd = sta_alm(ALM1, 10);
+ check_ercd(ercd, E_OK);
+
+ check_point(34);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(0);
+}
+
+void
+task6(intptr_t exinf)
+{
+ ER ercd;
+
+ check_point(17);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(18);
+ ercd = wup_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(19);
+ ercd = wup_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(20);
+ ercd = sus_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+
+ check_point(21);
+ ercd = wup_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ check_point(22);
+ ercd = wup_tsk(TASK4);
+ check_ercd(ercd, E_OK);
+
+ check_point(23);
+ ercd = sus_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(24);
+ ercd = ena_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(27);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(28);
+ ercd = rsm_tsk(TASK1);
+ check_ercd(ercd, E_OK);
+
+ check_point(29);
+ ercd = wup_tsk(TASK5);
+ check_ercd(ercd, E_OK);
+
+ check_point(30);
+ ercd = ena_dsp();
+ check_ercd(ercd, E_OK);
+
+ check_point(32);
+ ercd = slp_tsk();
+ check_ercd(ercd, E_OK);
+
+ check_point(0);
+}
--- /dev/null
+/*
+ * @(#) $Id: test_task1.cfg 1569 2009-05-31 13:23:47Z ertl-hiro $
+ */
+
+/*
+ * タスク管理モジュールのテスト(1)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "test_task1.h"
+
+CRE_TSK(TASK1, { TA_ACT, 1, task1, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK2, { TA_NULL, 2, task2, HIGH_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK3, { TA_NULL, 3, task3, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK4, { TA_NULL, 4, task4, MID_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK5, { TA_NULL, 5, task5, LOW_PRIORITY, STACK_SIZE, NULL });
+CRE_TSK(TASK6, { TA_NULL, 6, task6, LOW_PRIORITY, STACK_SIZE, NULL });
+CRE_ALM(ALM1, { TA_NULL, 1, alarm1_handler });
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_task1.h 329 2007-07-17 07:28:32Z hiro $
+ */
+
+/*
+ * タスク管理モジュールのテスト(1)
+ */
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 優先度の定義
+ */
+#define HIGH_PRIORITY 4 /* 高優先度 */
+#define MID_PRIORITY 9 /* 中優先度 */
+#define LOW_PRIORITY 14 /* 低優先度 */
+
+/*
+ * ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define STACK_SIZE 4096 /* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void task1(intptr_t exinf);
+extern void task2(intptr_t exinf);
+extern void task3(intptr_t exinf);
+extern void task4(intptr_t exinf);
+extern void task5(intptr_t exinf);
+extern void task6(intptr_t exinf);
+extern void alarm1_handler(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2006-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_tex1.c 1577 2009-05-31 14:30:51Z ertl-hiro $
+ */
+
+/*
+ * タスク例外処理に関するテスト(1)
+ *
+ * 【テストの目的】
+ *
+ * タスクからタスク例外処理ルーチンを起動する処理を網羅的にテストする.
+ *
+ * 【テスト項目】
+ *
+ * (A) ras_tex,ref_texのエラー検出
+ * (A-1) 対象タスクが休止状態
+ * (A-2) 対象タスクのタスク例外処理ルーチンが定義されていない
+ * (B) dis_tex,ena_texのエラー検出
+ * (B-1) 自タスクのタスク例外処理ルーチンが定義されていない
+ * (C) ras_texの正常処理
+ * (C-1) 対象タスクが自タスクかつタスク例外処理許可で,すぐに起動
+ * (C-2) 対象タスクが自タスクでない
+ * (C-3) 対象タスクが自タスクだがタスク例外処理禁止
+ * (D) ena_texの正常処理
+ * (D-1) タスク例外処理要求があり,すぐに起動
+ * (D-2) タスク例外処理要求がない
+ * (E) タスクディスパッチャによる起動
+ * (E-1) ディスパッチ後のタスクがタスク例外許可でタスク例外処理要
+ * 求あり
+ * (F) タスク例外処理ルーチンからのリターンによる起動(連続起動)
+ * (G) タスク例外処理ルーチンからの戻り時による状態復帰
+ * (G-1) タスクに戻ってくる時
+ * (G-2) タスク例外処理ルーチンが連続起動される時
+ * (H) タスク例外処理ルーチンの多重起動
+ * (I) タスク例外処理ルーチンからの戻り時のタスク切換え
+ *
+ * 【使用リソース】
+ *
+ * TASK1: メインのタスク.自タスクに対してタスク例外処理を要求する
+ * TASK2: 他タスクに対してタスク例外処理を要求する対象タスク
+ * TASK3: タスク例外処理ルーチンが定義されていないタスク
+ * TASK4: 休止状態のタスク
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(優先度:10)==
+ * 1: 初期状態のチェック
+ * ref_tex(TSK_SELF, &rtex)
+ * ras_tex(TASK3, 0x0001) ... (A-2)
+ * ras_tex(TASK4, 0x0001) ... (A-1)
+ * ref_tex(TASK3, &rtex) ... (A-2)
+ * ref_tex(TASK4, &rtex) ... (A-1)
+ * 2: ena_tex() ... (D-2)
+ * ref_tex(TSK_SELF, &rtex)
+ * 3: ras_tex(TSK_SELF, 0x0001) ... (C-1)
+ * == TASK1タスク例外処理ルーチン(1回目)==
+ * 4: 初期状態のチェック
+ * 5: dis_dsp() ... 4つの状態をそれぞれ変化させる
+ * chg_ipm(TMAX_INTPRI)
+ * ena_tex()
+ * loc_cpu()
+ * リターン
+ * == TASK1(続き)==
+ * 6: 戻ってきた状態のチェック ... (G-1)
+ * 7: dis_dsp() ... 3つの状態をそれぞれ変化させる
+ * chg_ipm(TMIN_INTPRI)
+ * dis_tex()
+ * 8: ras_tex(TASK1, 0x0002) ... (C-3)
+ * ref_tex(TSK_SELF, &rtex)
+ * 9: ena_tex() ... (D-1)
+ * == TASK1タスク例外処理ルーチン(2回目)==
+ * 10: 初期状態のチェック
+ * 11: ras_tex(TASK1, 0x0001) ... (C-3)
+ * ras_tex(TASK1, 0x0002) ... (C-3)
+ * 12: ena_dsp() ... 3つの状態をそれぞれ変化させる
+ * chg_ipm(TMAX_INTPRI)
+ * loc_cpu()
+ * リターン ... (F)
+ * == TASK1タスク例外処理ルーチン(3回目)==
+ * 13: 初期状態のチェック
+ * 14: ena_dsp() ... 3つの状態をそれぞれ変化させる
+ * chg_ipm(TMAX_INTPRI)
+ * ena_tex()
+ * 15: ras_tex(TSK_SELF, 0x0004) ... (H)
+ * == TASK1タスク例外処理ルーチン(4回目)==
+ * 16: 初期状態のチェック
+ * 17: dis_dsp() ... 3つの状態をそれぞれ変化させる
+ * chg_ipm(TIPM_ENAALL)
+ * loc_cpu()
+ * リターン
+ * == TASK1タスク例外処理ルーチン(3回目続き)==
+ * 18: 戻ってきた状態のチェック ... (G-2)
+ * リターン
+ * == TASK1(続き)==
+ * 19: 戻ってきた状態のチェック ... (G-1)
+ * 20: ena_dsp()
+ * chg_ipm(TIPM_ENAALL)
+ * rot_rdq(TPRI_SELF)
+ * == TASK2(優先度:10) ==
+ * 21: 初期状態のチェック
+ * 22: ena_tex()
+ * rot_rdq(TPRI_SELF)
+ * == TASK3(優先度:10) ==
+ * 23: 初期状態のチェック
+ * 24: ena_tex()
+ * 25: dis_tex() ... (B-1)
+ * ext_tsk() ... (B-1)
+ * == TASK1(続き)==
+ * 26: ras_tex(TASK2, 0x0001) ... (C-2)
+ * ref_tex(TASK2, &rtex)
+ * 27: rot_rdq(TPRI_SELF) ... (E-1)
+ * == TASK2タスク例外処理ルーチン(1回目)==
+ * 28: 初期状態のチェック
+ * リターン
+ * == TASK2(続き)==
+ * 29: ras_tex(TSK_SELF, 0x0002)
+ * == TASK2タスク例外処理ルーチン(2回目)==
+ * 30: 初期状態のチェック
+ * 31: dis_dsp
+ * rot_rdq(TPRI_SELF)
+ * 32: リターン ... (I)
+ * == TASK1(続き)==
+ * 33: リターン(タスク終了)
+ * == TASK2(続き)==
+ * 34: テスト終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_tex1.h"
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+ ER ercd;
+
+ switch (texptn) {
+ case 0x0001:
+ check_point(4);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+
+ /*
+ * ディスパッチ禁止,割込み優先度マスク変更,タスク例外処理許可
+ */
+ check_point(5);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+ ercd = chg_ipm(TMAX_INTPRI);
+ check_ercd(ercd, E_OK);
+ ercd = ena_tex();
+ check_ercd(ercd, E_OK);
+ ercd = loc_cpu();
+ check_ercd(ercd, E_OK);
+ check_state(false, true, TMAX_INTPRI, true, true, false);
+ break;
+
+ case 0x0002:
+ check_point(10);
+ check_state(false, false, TMIN_INTPRI, true, true, true);
+
+ /*
+ * タスク例外処理を要求
+ */
+ check_point(11);
+ ercd = ras_tex(TSK_SELF, 0x0001);
+ check_ercd(ercd, E_OK);
+ ercd = ras_tex(TSK_SELF, 0x0002);
+ check_ercd(ercd, E_OK);
+
+ /*
+ * ディスパッチ許可,割込み優先度マスク変更,CPUロック
+ */
+ check_point(12);
+ ercd = ena_dsp();
+ check_ercd(ercd, E_OK);
+ ercd = chg_ipm(TMAX_INTPRI);
+ check_ercd(ercd, E_OK);
+ ercd = loc_cpu();
+ check_ercd(ercd, E_OK);
+ check_state(false, true, TMAX_INTPRI, false, true, true);
+ break;
+
+ case 0x0003:
+ check_point(13);
+ check_state(false, false, TMIN_INTPRI, true, true, true);
+
+ /*
+ * ディスパッチ許可,割込み優先度マスク変更,タスク例外許可
+ */
+ check_point(14);
+ ercd = ena_dsp();
+ check_ercd(ercd, E_OK);
+ ercd = chg_ipm(TMAX_INTPRI);
+ check_ercd(ercd, E_OK);
+ ercd = ena_tex();
+ check_ercd(ercd, E_OK);
+ check_state(false, false, TMAX_INTPRI, false, true, false);
+
+ /*
+ * タスク例外処理を要求
+ */
+ check_point(15);
+ ercd = ras_tex(TSK_SELF, 0x0004);
+ /* ここでタスク例外処理ルーチンが動作する */
+ check_ercd(ercd, E_OK);
+
+ /*
+ * タスク例外処理からのリターンにより元の状態に戻っていること
+ * をチェック
+ */
+ check_point(18);
+ check_state(false, false, TMAX_INTPRI, false, true, false);
+ break;
+
+ case 0x0004:
+ check_point(16);
+ check_state(false, false, TMAX_INTPRI, false, true, true);
+
+ /*
+ * ディスパッチ禁止,割込み優先度マスク変更,CPUロック
+ */
+ check_point(17);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+ ercd = chg_ipm(TIPM_ENAALL);
+ check_ercd(ercd, E_OK);
+ ercd = loc_cpu();
+ check_ercd(ercd, E_OK);
+ check_state(false, true, TIPM_ENAALL, true, true, true);
+ break;
+
+ default:
+ check_point(0);
+ break;
+ }
+}
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+ T_RTEX rtex;
+
+ /*
+ * 初期状態のチェック
+ */
+ check_point(1);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+ ercd = ref_tex(TSK_SELF, &rtex);
+ check_ercd(ercd, E_OK);
+ check_assert((rtex.texstat & TTEX_DIS) != 0);
+ check_assert(rtex.pndptn == 0);
+
+ /*
+ * ras_texのエラー検出
+ */
+ ercd = ras_tex(TASK3, 0x0001);
+ check_ercd(ercd, E_OBJ);
+ ercd = ras_tex(TASK4, 0x0001);
+ check_ercd(ercd, E_OBJ);
+
+ /*
+ * ref_texのエラー検出
+ */
+ ercd = ref_tex(TASK3, &rtex);
+ check_ercd(ercd, E_OBJ);
+ ercd = ref_tex(TASK4, &rtex);
+ check_ercd(ercd, E_OBJ);
+
+ /*
+ * タスク例外処理の許可
+ */
+ check_point(2);
+ ercd = ena_tex();
+ check_ercd(ercd, E_OK);
+ check_state(false, false, TIPM_ENAALL, false, false, false);
+ ercd = ref_tex(TSK_SELF, &rtex);
+ check_ercd(ercd, E_OK);
+ check_assert((rtex.texstat & TTEX_ENA) != 0);
+ check_assert(rtex.pndptn == 0);
+
+ /*
+ * タスク例外処理を要求
+ */
+ check_point(3);
+ ercd = ras_tex(TSK_SELF, 0x0001);
+ /* ここでタスク例外処理ルーチンが動作する */
+ check_ercd(ercd, E_OK);
+
+ /*
+ * タスク例外処理からのリターンにより元の状態に戻っていることを
+ * チェック
+ */
+ check_point(6);
+ check_state(false, false, TIPM_ENAALL, false, false, false);
+
+ /*
+ * ディスパッチ禁止,割込み優先度マスク変更,タスク例外処理禁止
+ */
+ check_point(7);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+ ercd = chg_ipm(TMIN_INTPRI);
+ check_ercd(ercd, E_OK);
+ ercd = dis_tex();
+ check_ercd(ercd, E_OK);
+ check_state(false, false, TMIN_INTPRI, true, true, true);
+
+ /*
+ * タスク例外処理を要求
+ */
+ check_point(8);
+ ercd = ras_tex(TASK1, 0x0002);
+ check_ercd(ercd, E_OK);
+ ercd = ref_tex(TSK_SELF, &rtex);
+ check_ercd(ercd, E_OK);
+ check_assert((rtex.texstat & TTEX_DIS) != 0);
+ check_assert(rtex.pndptn == 0x0002);
+
+ /*
+ * タスク例外処理を許可
+ */
+ check_point(9);
+ ercd = ena_tex();
+ /* ここでタスク例外処理ルーチンが動作する */
+ check_ercd(ercd, E_OK);
+
+ /*
+ * タスク例外処理からのリターンにより元の状態に戻っていることを
+ * チェック
+ */
+ check_point(19);
+ check_state(false, false, TMIN_INTPRI, true, true, false);
+
+ /*
+ * タスク2に切り換える
+ */
+ check_point(20);
+ ercd = ena_dsp();
+ check_ercd(ercd, E_OK);
+ ercd = chg_ipm(TIPM_ENAALL);
+ check_ercd(ercd, E_OK);
+ ercd = rot_rdq(TPRI_SELF);
+ /* ここで他のタスクが動作する */
+ check_ercd(ercd, E_OK);
+
+ /*
+ * タスク2に対してタスク例外処理を要求
+ */
+ check_point(26);
+ ercd = ras_tex(TASK2, 0x0001);
+ check_ercd(ercd, E_OK);
+ ercd = ref_tex(TASK2, &rtex);
+ check_ercd(ercd, E_OK);
+ check_assert((rtex.texstat & TTEX_ENA) != 0);
+ check_assert(rtex.pndptn == 0x0001);
+
+ /*
+ * タスク2に切り換える
+ */
+ check_point(27);
+ ercd = rot_rdq(TPRI_SELF);
+ /* ここで他のタスクが動作する */
+ check_ercd(ercd, E_OK);
+
+ /*
+ * タスク終了
+ */
+ check_point(33);
+}
+
+void
+tex_task2(TEXPTN texptn, intptr_t exinf)
+{
+ ER ercd;
+
+ switch (texptn) {
+ case 0x0001:
+ check_point(28);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+ break;
+
+ case 0x0002:
+ check_point(30);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+
+ /*
+ * ディスパッチを禁止して,タスク切換えを要求する.
+ */
+ check_point(31);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+ ercd = rot_rdq(TPRI_SELF);
+ check_ercd(ercd, E_OK);
+
+ /*
+ * タスク例外処理ルーチンからのリターンで,タスク切換えが発生
+ * する.
+ */
+ check_point(32);
+ break;
+
+ default:
+ check_point(0);
+ break;
+ }
+}
+
+void
+task2(intptr_t exinf)
+{
+ ER ercd;
+
+ /*
+ * 初期状態のチェック
+ */
+ check_point(21);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+
+ /*
+ * タスク例外処理の許可
+ */
+ check_point(22);
+ ercd = ena_tex();
+ check_ercd(ercd, E_OK);
+ check_state(false, false, TIPM_ENAALL, false, false, false);
+
+ /*
+ * タスク3に切り換える
+ */
+ ercd = rot_rdq(TPRI_SELF);
+ /* ここで他のタスクが動作する */
+ check_ercd(ercd, E_OK);
+
+ /*
+ * タスク例外処理を要求
+ */
+ check_point(29);
+ ercd = ras_tex(TSK_SELF, 0x0002);
+ /* ここでタスク例外処理ルーチンが動作する */
+ check_ercd(ercd, E_OK);
+
+ /*
+ * テスト終了
+ */
+ check_finish(34);
+}
+
+void
+task3(intptr_t exinf)
+{
+ ER ercd;
+
+ /*
+ * 初期状態のチェック
+ */
+ check_point(23);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+
+ /*
+ * タスク例外処理の許可
+ */
+ check_point(24);
+ ercd = ena_tex();
+ check_ercd(ercd, E_OBJ);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+
+ /*
+ * タスク例外処理の禁止
+ */
+ check_point(25);
+ ercd = dis_tex();
+ check_ercd(ercd, E_OBJ);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+
+ /*
+ * タスク終了
+ */
+ ercd = ext_tsk();
+ check_point(0);
+}
+
+void
+task4(intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+tex_task4(TEXPTN texptn, intptr_t exinf)
+{
+ check_point(0);
+}
--- /dev/null
+/*
+ * @(#) $Id: test_tex1.cfg 1572 2009-05-31 13:40:39Z ertl-hiro $
+ */
+
+/*
+ * タスク例外処理に関するテスト(1)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "test_tex1.h"
+
+CRE_TSK(TASK1, { TA_ACT, 1, task1, TASK1_PRIORITY, STACK_SIZE, NULL });
+DEF_TEX(TASK1, { TA_NULL, tex_task1 });
+
+CRE_TSK(TASK2, { TA_ACT, 2, task2, TASK2_PRIORITY, STACK_SIZE, NULL });
+DEF_TEX(TASK2, { TA_NULL, tex_task2 });
+
+CRE_TSK(TASK3, { TA_ACT, 3, task3, TASK3_PRIORITY, STACK_SIZE, NULL });
+
+CRE_TSK(TASK4, { TA_NULL, 4, task4, TASK4_PRIORITY, STACK_SIZE, NULL });
+DEF_TEX(TASK4, { TA_NULL, tex_task4 });
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2006,2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_tex1.h 329 2007-07-17 07:28:32Z hiro $
+ */
+
+/*
+ * タスク例外処理に関するテスト(1)
+ */
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 各タスクの優先度の定義
+ */
+#define TASK1_PRIORITY 10 /* タスク1の優先度 */
+#define TASK2_PRIORITY 10 /* タスク2の優先度 */
+#define TASK3_PRIORITY 10 /* タスク3の優先度 */
+#define TASK4_PRIORITY 10 /* タスク4の優先度 */
+
+/*
+ * ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define STACK_SIZE 4096 /* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void tex_task1(TEXPTN texptn, intptr_t exinf);
+extern void task1(intptr_t exinf);
+
+extern void tex_task2(TEXPTN texptn, intptr_t exinf);
+extern void task2(intptr_t exinf);
+
+extern void task3(intptr_t exinf);
+
+extern void tex_task4(TEXPTN texptn, intptr_t exinf);
+extern void task4(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007-2009 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_tex2.c 1577 2009-05-31 14:30:51Z ertl-hiro $
+ */
+
+/*
+ * タスク例外処理に関するテスト(2)
+ *
+ * 【テストの目的】
+ *
+ * 割込みハンドラ(アラームハンドラ)およびCPU例外ハンドラからタスク例
+ * 外処理ルーチンを起動する処理を網羅的にテストする.
+ *
+ * 【テスト項目】
+ *
+ * (A) iras_texのエラー検出
+ * (A-1) 対象タスクが休止状態
+ * (A-2) 対象タスクのタスク例外処理ルーチンが定義されていない
+ * (B) 割込みハンドラから呼ばれたiras_texの正常処理
+ * (B-1) 対象タスクが実行状態のタスクかつタスク例外処理許可
+ * (B-2) 対象タスクが実行状態のタスクでない
+ * (B-3) 対象タスクが実行状態のタスクだがタスク例外処理禁止
+ * (C) CPU例外ハンドラから呼ばれたiras_texの正常処理
+ * (C-1) 対象タスクが実行状態のタスクかつタスク例外処理許可
+ * (C-2) 対象タスクが実行状態のタスクでない
+ * (C-3) 対象タスクが実行状態のタスクだがタスク例外処理禁止
+ * → 実施しない(ターゲット非依存に実現できない)
+ * (D) 割込みハンドラの出口処理による起動
+ * (D-1) ディスパッチ後のタスクがタスク例外許可でタスク例外処理要
+ * 求あり
+ * (E) CPU例外ハンドラの出口処理による起動
+ * (E-1) ディスパッチ後のタスクがタスク例外許可でタスク例外処理要
+ * 求あり
+ * (F) sns_texで実行状態のタスクがない
+ *
+ * 【使用リソース】
+ *
+ * TASK1: メインのタスク.実行状態のタスクに対してタスク例外処理を要求す
+ * る対象タスク
+ * TASK2: 実行状態でないタスクに対してタスク例外処理を要求する対象タスク
+ * TASK3: タスク例外処理ルーチンが定義されていないタスク
+ * TASK4: 休止状態のタスク
+ * ALM1: アラームハンドラ1
+ * ALM2: アラームハンドラ2
+ * ALM3: アラームハンドラ3
+ * CPUEXC1: CPU例外ハンドラ
+ *
+ * 【テストシーケンス】
+ *
+ * == TASK1(優先度:10)==
+ * 1: 初期状態のチェック
+ * ref_tex(TSK_SELF, &rtex)
+ * 2: sta_alm(ALM1, 1U)
+ * アラームハンドラ1の実行を待つ
+ * == ALM1 ==
+ * 3: 初期状態のチェック
+ * iras_tex(TASK3, 0x0001) ... (A-2)
+ * iras_tex(TASK4, 0x0001) ... (A-1)
+ * iras_tex(TASK2, 0x0001) ... (B-2)
+ * iras_tex(TASK1, 0x0001) ... (B-3)
+ * リターン
+ * == TASK1(続き)==
+ * 4: ena_tex()
+ * == TASK1タスク例外処理ルーチン(1回目)==
+ * 5: 初期状態のチェック
+ * 6: dis_dsp() ... 4つの状態をそれぞれ変化させる
+ * chg_ipm(TMAX_INTPRI)
+ * ena_tex()
+ * loc_cpu()
+ * リターン
+ * == TASK1(続き)==
+ * 7: 戻ってきた状態のチェック
+ * ref_tex(TSK_SELF, &rtex)
+ * 8: sta_alm(ALM2, 1U)
+ * アラームハンドラ2の実行を待つ
+ * == ALM2 ==
+ * 9: 初期状態のチェック
+ * iras_tex(TASK1, 0x0002) ... (B-1)
+ * リターン ... (D-1)
+ * == TASK1タスク例外処理ルーチン(2回目)==
+ * 10: 初期状態のチェック
+ * リターン
+ * == TASK1(続き)==
+ * 11: sus_tsk(TASK2)
+ * sus_tsk(TASK3)
+ * 12: sta_alm(ALM3, 10U)
+ * 13: dly_tsk(50U)
+ * == ALM3 ==
+ * 14: 初期状態のチェック
+ * [sns_tex()を含む] ... (F)
+ * iget_tid(&tskid)
+ * iras_tex(TASK1, 0x0004) ... (B-2)
+ * リターン
+ * == TASK1タスク例外処理ルーチン(3回目)==
+ * 15: 初期状態のチェック
+ * リターン
+ * == TASK1(続き)==
+ * 16: rsm_tsk(TASK2)
+ * rsm_tsk(TASK3)
+ * dis_dsp()
+ * 17: RAISE_CPU_EXCEPTION
+ * == CPUEXC1 ==
+ * 18: 初期状態のチェック
+ * xsns_xpn(p_excinf)
+ * iras_tex(TASK3, 0x0010) ... (A-2)
+ * iras_tex(TASK4, 0x0010) ... (A-1)
+ * iras_tex(TASK2, 0x0010) ... (C-2)
+ * iras_tex(TASK1, 0x0010) ... (C-1)
+ * リターン ... (E-1)
+ * == TASK1タスク例外処理ルーチン(4回目)==
+ * 19: 初期状態のチェック
+ * 20: ext_tsk()
+ * == TASK2(優先度:10)==
+ * 21: 初期状態のチェック
+ * 22: ena_tex()
+ * == TASK2タスク例外処理ルーチン ==
+ * 23: 初期状態のチェック
+ * リターン
+ * == TASK2(続き)==
+ * 24: sus_tsk(TASK3)
+ * 25: テスト終了
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_tex2.h"
+
+volatile bool_t alm1_flag = false;
+volatile bool_t alm2_flag = false;
+volatile bool_t alm3_flag = false;
+
+void
+tex_task1(TEXPTN texptn, intptr_t exinf)
+{
+ ER ercd;
+
+ switch (texptn) {
+ case 0x0001:
+ check_point(5);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+
+ /*
+ * ディスパッチ禁止,割込み優先度マスク変更,タスク例外処理許可,
+ * CPUロック
+ */
+ check_point(6);
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+ ercd = chg_ipm(TMAX_INTPRI);
+ check_ercd(ercd, E_OK);
+ ercd = ena_tex();
+ check_ercd(ercd, E_OK);
+ ercd = loc_cpu();
+ check_ercd(ercd, E_OK);
+ check_state(false, true, TMAX_INTPRI, true, true, false);
+ break;
+
+ case 0x0002:
+ check_point(10);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+ break;
+
+ case 0x0004:
+ check_point(15);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+ break;
+
+ case 0x0010:
+ check_point(19);
+ check_state(false, false, TIPM_ENAALL, true, true, true);
+
+ /*
+ * タスク終了
+ */
+ check_point(20);
+ ercd = ext_tsk();
+ check_point(0);
+ break;
+
+ default:
+ check_point(0);
+ break;
+ }
+}
+
+void
+task1(intptr_t exinf)
+{
+ ER ercd;
+ T_RTEX rtex;
+
+ /*
+ * 初期状態のチェック
+ */
+ check_point(1);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+ ercd = ref_tex(TSK_SELF, &rtex);
+ check_ercd(ercd, E_OK);
+ check_assert((rtex.texstat & TTEX_DIS) != 0);
+ check_assert(rtex.pndptn == 0);
+
+ /*
+ * アラームハンドラ1の動作開始
+ */
+ check_point(2);
+ ercd = sta_alm(ALM1, 1U);
+ check_ercd(ercd, E_OK);
+
+ /*
+ * アラームハンドラ1の実行を待つ
+ */
+ while (!(alm1_flag));
+
+ /*
+ * タスク例外処理を許可
+ */
+ check_point(4);
+ ercd = ena_tex();
+ /* ここでタスク例外処理ルーチンが動作する */
+ check_ercd(ercd, E_OK);
+
+ /*
+ * タスク例外処理からのリターンにより元の状態に戻っていることを
+ * チェック
+ */
+ check_point(7);
+ check_state(false, false, TIPM_ENAALL, false, false, false);
+ ercd = ref_tex(TSK_SELF, &rtex);
+ check_ercd(ercd, E_OK);
+ check_assert((rtex.texstat & TTEX_ENA) != 0);
+ check_assert(rtex.pndptn == 0);
+
+ /*
+ * アラームハンドラ2の動作開始
+ */
+ check_point(8);
+ ercd = sta_alm(ALM2, 1U);
+ check_ercd(ercd, E_OK);
+
+ /*
+ * アラームハンドラ2の実行を待つ
+ */
+ while (!(alm2_flag));
+
+ /*
+ * TASK2とTASK3を止める.
+ */
+ check_point(11);
+ ercd = sus_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+ ercd = sus_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ /*
+ * アラームハンドラ3の動作開始
+ */
+ check_point(12);
+ ercd = sta_alm(ALM3, 10U);
+ check_ercd(ercd, E_OK);
+
+ /*
+ * 実行遅延
+ */
+ check_point(13);
+ ercd = dly_tsk(50U);
+ /* アラームハンドラ3が動作する */
+ check_ercd(ercd, E_OK);
+
+ /*
+ * TASK2とTASK3を再開する.
+ */
+ check_point(16);
+ ercd = rsm_tsk(TASK2);
+ check_ercd(ercd, E_OK);
+ ercd = rsm_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ /*
+ * ディスパッチ禁止
+ */
+ ercd = dis_dsp();
+ check_ercd(ercd, E_OK);
+
+ /*
+ * CPU例外を発生させる
+ */
+ check_point(17);
+ RAISE_CPU_EXCEPTION;
+
+ check_point(0);
+}
+
+void
+tex_task2(TEXPTN texptn, intptr_t exinf)
+{
+ switch (texptn) {
+ case 0x0011:
+ check_point(23);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+ break;
+
+ default:
+ check_point(0);
+ break;
+ }
+}
+
+void
+task2(intptr_t exinf)
+{
+ ER ercd;
+
+ /*
+ * 初期状態のチェック
+ */
+ check_point(21);
+ check_state(false, false, TIPM_ENAALL, false, false, true);
+
+ /*
+ * タスク例外処理を許可
+ */
+ check_point(22);
+ ercd = ena_tex();
+ /* ここでタスク例外処理ルーチンが動作する */
+ check_ercd(ercd, E_OK);
+
+ /*
+ * TASK3を止める.
+ */
+ check_point(24);
+ ercd = sus_tsk(TASK3);
+ check_ercd(ercd, E_OK);
+
+ /*
+ * テスト終了
+ */
+ check_finish(25);
+}
+
+void
+task3(intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+task4(intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+tex_task4(TEXPTN texptn, intptr_t exinf)
+{
+ check_point(0);
+}
+
+void
+alarm1_handler(intptr_t exinf)
+{
+ ER ercd;
+
+ /*
+ * 初期状態のチェック
+ */
+ check_point(3);
+ check_state_i(true, false, false, true, true);
+
+ /*
+ * iras_texのエラー検出
+ */
+ ercd = iras_tex(TASK3, 0x0001);
+ check_ercd(ercd, E_OBJ);
+ ercd = iras_tex(TASK4, 0x0001);
+ check_ercd(ercd, E_OBJ);
+
+ /*
+ * タスク例外処理を要求
+ */
+ ercd = iras_tex(TASK2, 0x0001);
+ check_ercd(ercd, E_OK);
+ ercd = iras_tex(TASK1, 0x0001);
+ check_ercd(ercd, E_OK);
+
+ alm1_flag = true;
+}
+
+void
+alarm2_handler(intptr_t exinf)
+{
+ ER ercd;
+
+ /*
+ * 初期状態のチェック
+ */
+ check_point(9);
+ check_state_i(true, false, false, true, false);
+
+ /*
+ * タスク例外処理を要求
+ */
+ ercd = iras_tex(TASK1, 0x0002);
+ check_ercd(ercd, E_OK);
+
+ alm2_flag = true;
+}
+
+void
+alarm3_handler(intptr_t exinf)
+{
+ ER ercd;
+ ID tskid;
+
+ check_point(14);
+ check_state_i(true, false, false, true, true);
+ ercd = iget_tid(&tskid);
+ check_ercd(ercd, E_OK);
+ check_assert(tskid == TSK_NONE);
+
+ /*
+ * タスク例外処理を要求
+ */
+ ercd = iras_tex(TASK1, 0x0004);
+ check_ercd(ercd, E_OK);
+
+ alm3_flag = true;
+}
+
+void
+cpuexc_handler(void *p_excinf)
+{
+ ER ercd;
+
+ /*
+ * 初期状態のチェック
+ */
+ check_point(18);
+ check_state_i(true, false, true, true, false);
+ check_assert(xsns_xpn(p_excinf) == false);
+
+ /*
+ * iras_texのエラー検出
+ */
+ ercd = iras_tex(TASK3, 0x0010);
+ check_ercd(ercd, E_OBJ);
+ ercd = iras_tex(TASK4, 0x0010);
+ check_ercd(ercd, E_OBJ);
+
+ /*
+ * タスク例外処理を要求
+ */
+ ercd = iras_tex(TASK2, 0x0010);
+ check_ercd(ercd, E_OK);
+ ercd = iras_tex(TASK1, 0x0010);
+ check_ercd(ercd, E_OK);
+}
--- /dev/null
+/*
+ * @(#) $Id: test_tex2.cfg 1572 2009-05-31 13:40:39Z ertl-hiro $
+ */
+
+/*
+ * タスク例外処理に関するテスト(1)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "test_tex2.h"
+
+CRE_TSK(TASK1, { TA_ACT, 1, task1, TASK1_PRIORITY, STACK_SIZE, NULL });
+DEF_TEX(TASK1, { TA_NULL, tex_task1 });
+
+CRE_TSK(TASK2, { TA_ACT, 2, task2, TASK2_PRIORITY, STACK_SIZE, NULL });
+DEF_TEX(TASK2, { TA_NULL, tex_task2 });
+
+CRE_TSK(TASK3, { TA_ACT, 3, task3, TASK3_PRIORITY, STACK_SIZE, NULL });
+
+CRE_TSK(TASK4, { TA_NULL, 4, task4, TASK4_PRIORITY, STACK_SIZE, NULL });
+DEF_TEX(TASK4, { TA_NULL, tex_task4 });
+
+CRE_ALM(ALM1, { TA_NULL, 1, alarm1_handler });
+CRE_ALM(ALM2, { TA_NULL, 2, alarm2_handler });
+CRE_ALM(ALM3, { TA_NULL, 3, alarm3_handler });
+
+DEF_EXC(CPUEXC1, { TA_NULL, cpuexc_handler });
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * @(#) $Id: test_tex2.h 329 2007-07-17 07:28:32Z hiro $
+ */
+
+/*
+ * タスク例外処理に関するテスト(2)
+ */
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 各タスクの優先度の定義
+ */
+#define TASK1_PRIORITY 10 /* タスク1の優先度 */
+#define TASK2_PRIORITY 10 /* タスク2の優先度 */
+#define TASK3_PRIORITY 10 /* タスク3の優先度 */
+#define TASK4_PRIORITY 10 /* タスク4の優先度 */
+
+/*
+ * ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define STACK_SIZE 4096 /* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void tex_task1(TEXPTN texptn, intptr_t exinf);
+extern void task1(intptr_t exinf);
+
+extern void tex_task2(TEXPTN texptn, intptr_t exinf);
+extern void task2(intptr_t exinf);
+
+extern void task3(intptr_t exinf);
+
+extern void tex_task4(TEXPTN texptn, intptr_t exinf);
+extern void task4(intptr_t exinf);
+
+extern void alarm1_handler(intptr_t exinf);
+extern void alarm2_handler(intptr_t exinf);
+extern void alarm3_handler(intptr_t exinf);
+extern void cpuexc_handler(void *p_excinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+ * Toyohashi Univ. of Technology, JAPAN
+ * Copyright (C) 2007-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * $Id: test_utm1.c 1860 2010-07-25 07:36:40Z ertl-hiro $
+ */
+
+/*
+ * get_utmに関するテスト(1)
+ */
+
+#include <kernel.h>
+#include <test_lib.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "test_utm1.h"
+
+#define NO_LOOP ULONG_C(100000)
+
+SYSUTM recent_sysutm;
+char *recent_sysutm_pos;
+uint_t cyclic_count;
+
+void
+cyclic_handler(intptr_t exinf)
+{
+ SYSUTM sysutm, prev_sysutm;
+ char *prev_sysutm_pos;
+
+ iloc_cpu();
+ get_utm(&sysutm);
+ prev_sysutm = recent_sysutm;
+ prev_sysutm_pos = recent_sysutm_pos;
+ recent_sysutm = sysutm;
+ recent_sysutm_pos = "CYC";
+ iunl_cpu();
+
+ if (prev_sysutm > sysutm) {
+ syslog(LOG_NOTICE,
+ "system performance time goes back: %ld(%s) %ld(CYC)",
+ ((long_t) prev_sysutm), prev_sysutm_pos, ((ulong_t) sysutm));
+ }
+ cyclic_count += 1;
+}
+
+void
+main_task(intptr_t exinf)
+{
+ SYSUTM sysutm, prev_sysutm;
+ char *prev_sysutm_pos;
+ ulong_t i;
+
+ cyclic_count = 0U;
+ get_utm(&recent_sysutm);
+ syslog(LOG_NOTICE, "system performance time test starts.");
+
+ for (i = 0; i < NO_LOOP; i++) {
+ loc_cpu();
+ get_utm(&sysutm);
+ prev_sysutm = recent_sysutm;
+ prev_sysutm_pos = recent_sysutm_pos;
+ recent_sysutm = sysutm;
+ recent_sysutm_pos = "TSK";
+ unl_cpu();
+
+ if (prev_sysutm > sysutm) {
+ syslog(LOG_NOTICE,
+ "system performance time goes back: %ld(%s) %ld(TSK)",
+ ((long_t) prev_sysutm), prev_sysutm_pos, ((ulong_t) sysutm));
+ }
+ }
+
+ syslog(LOG_NOTICE, "system performance time test finishes.");
+ syslog(LOG_NOTICE, "number of cyclic handler execution: %d", cyclic_count);
+ test_finish();
+}
--- /dev/null
+/*
+ * $Id: test_utm1.cfg 1746 2010-02-11 18:18:25Z ertl-hiro $
+ */
+
+/*
+ * get_utmに関するテスト(1)のシステムコンフィギュレーションファイル
+ */
+INCLUDE("target_timer.cfg");
+INCLUDE("syssvc/syslog.cfg");
+INCLUDE("syssvc/banner.cfg");
+INCLUDE("syssvc/serial.cfg");
+
+#include "test_utm1.h"
+
+CRE_CYC(CYC1, { TA_STA, 0, cyclic_handler, 2, 1 });
+CRE_TSK(MAIN_TASK, { TA_ACT, 0, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
--- /dev/null
+/*
+ * TOPPERS Software
+ * Toyohashi Open Platform for Embedded Real-Time Systems
+ *
+ * Copyright (C) 2006-2010 by Embedded and Real-Time Systems Laboratory
+ * Graduate School of Information Science, Nagoya Univ., JAPAN
+ *
+ * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+ * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+ * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+ * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+ * スコード中に含まれていること.
+ * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+ * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+ * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+ * の無保証規定を掲載すること.
+ * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+ * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+ * と.
+ * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+ * 作権表示,この利用条件および下記の無保証規定を掲載すること.
+ * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+ * 報告すること.
+ * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+ * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+ * 免責すること.
+ *
+ * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+ * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+ * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+ * の責任を負わない.
+ *
+ * $Id: test_utm1.h 1746 2010-02-11 18:18:25Z ertl-hiro $
+ */
+
+/*
+ * get_utmに関するテスト(1)
+ */
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 各タスクの優先度の定義
+ */
+#define MAIN_PRIORITY 10
+
+/*
+ * ターゲットに依存する可能性のある定数の定義
+ */
+#ifndef STACK_SIZE
+#define STACK_SIZE 4096 /* タスクのスタックサイズ */
+#endif /* STACK_SIZE */
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+extern void cyclic_handler(intptr_t exinf);
+extern void main_task(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
--- /dev/null
+#! /usr/bin/perl
+#
+# TOPPERS Software
+# Toyohashi Open Platform for Embedded Real-Time Systems
+#
+# Copyright (C) 2003 by Embedded and Real-Time Systems Laboratory
+# Toyohashi Univ. of Technology, JAPAN
+# Copyright (C) 2004-2007 by Embedded and Real-Time Systems Laboratory
+# Graduate School of Information Science, Nagoya Univ., JAPAN
+#
+# 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+# スコード中に含まれていること.
+# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+# の無保証規定を掲載すること.
+# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+# と.
+# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+# 作権表示,この利用条件および下記の無保証規定を掲載すること.
+# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+# 報告すること.
+# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+# 免責すること.
+#
+# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+# の責任を負わない.
+#
+# @(#) $Id: applyrename 332 2007-07-17 12:15:37Z hiro $
+#
+
+#
+# ファイルにリネームを適用する
+#
+sub applyrename
+{
+ local($infile) = @_;
+ local($outfile) = $infile.".new";
+ local($line);
+
+ open(INFILE, "< ".$infile) || die;
+ open(OUTFILE, "> ".$outfile) || die;
+
+ while ($line = <INFILE>) {
+ $line =~ s/\b(_?)($syms)\b/$1_kernel_$2/gc;
+ print OUTFILE $line;
+ }
+
+ close(INFILE);
+ close(OUTFILE);
+
+ if (`cmp $infile $outfile`) {
+ rename($infile, $infile.".bak");
+ rename($outfile, $infile);
+ print STDERR "Modified: ",$infile,"\n";
+ }
+ else {
+ unlink($outfile);
+ }
+}
+
+#
+# エラーチェック
+#
+if ($#ARGV < 1) {
+ die "Usage: appyrename <prefix> <filelist>\n";
+}
+
+#
+# 初期化
+#
+@syms = ();
+$name = $ARGV[0];
+
+#
+# シンボルリストを読み込む
+#
+$deffile = $name."_rename.def";
+open(INFILE, $deffile) || die "Cannot open $deffile";
+while ($line = <INFILE>) {
+ chomp $line;
+ if ($line =~ /^#(.*)$/) {
+ # do nothing
+ }
+ elsif ($line =~ /^INCLUDE[ \t]+(.*)$/) {
+ # do nothing
+ }
+ elsif ($line ne "") {
+ @syms = (@syms, $line)
+ }
+}
+close(INFILE);
+
+#
+# 正規表現を作る
+#
+$syms = join("|", @syms);
+
+#
+# ファイルにリネームを適用する
+#
+shift @ARGV;
+foreach $infile (@ARGV) {
+ # ファイルでなければスキップ
+ next unless (-f $infile);
+
+ do applyrename($infile) if ($infile ne $deffile);
+}
--- /dev/null
+#! /usr/bin/perl
+#
+# TOPPERS Software
+# Toyohashi Open Platform for Embedded Real-Time Systems
+#
+# Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+# Toyohashi Univ. of Technology, JAPAN
+# Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
+# Graduate School of Information Science, Nagoya Univ., JAPAN
+#
+# 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+# スコード中に含まれていること.
+# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+# の無保証規定を掲載すること.
+# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+# と.
+# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+# 作権表示,この利用条件および下記の無保証規定を掲載すること.
+# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+# 報告すること.
+# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+# 免責すること.
+#
+# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+# の責任を負わない.
+#
+# @(#) $Id: genoffset 1840 2010-07-10 17:29:42Z ertl-hiro $
+#
+
+#
+# 初期化
+#
+$infile = $ARGV[0];
+$sil_endian = "";
+
+#
+# 解釈できるディレクティブのテーブル
+#
+%directives = (
+ "long", "",
+ "dword", "",
+ "word", "",
+ "hword", "",
+ "int", "",
+ "short", "",
+ "half", "",
+ "byte", "",
+ "value", "",
+ "uaword", "",
+ "uashort", "",
+ "data32", 4,
+ "data16", 2,
+ "data8", 1,
+ "zero", -1,
+ "space", -1,
+ "globl", 0,
+ "global", 0,
+ "align", 0,
+ "p2align", 0,
+ "even", 0,
+ "data", 0,
+ "stabs", 0,
+ "type", 0,
+ "size", 0,
+ "section", 0,
+ "sdata", 0,
+ "code", 0,
+);
+
+#
+# オフセット値の出力
+#
+sub parse_offset {
+ my($label, $val) = @_;
+
+ printf "#define %s\t%d\n",$label,$val;
+}
+
+#
+# ディレクティブの読み取り
+#
+sub ref_bit {
+ my($size) = @_;
+ my($dir, $directive);
+
+ while ($line = <INFILE>) {
+ chomp $line;
+ next if ($line =~ /^[ \t]*[#;].*$/);
+
+ if ($line =~ /[ \t]*\.([a-zA-Z0-9]+)[ \t]*([^ \t]*)[ \t]*/
+ && defined($dir = $directives{$1})) {
+ $directive = $1;
+ if ($dir eq "") {
+ # 登録すべきディレクティブ
+ $directives{$directive} = $size;
+ }
+ last;
+ }
+ else {
+ # 解析できない行
+ print STDERR "genoffset: cannot parse: $line\n";
+ $error = 1;
+ }
+ }
+}
+
+#
+# ビットサーチ
+#
+sub search_bit {
+ my($val) = @_;
+ my($val_bit);
+
+ return(-1) if ($val == 0);
+
+ $val_bit = 0;
+ while (($val & 1) == 0) {
+ $val >>= 1;
+ $val_bit++;
+ }
+ return($val_bit);
+}
+
+#
+# ビット位置の出力
+#
+sub parse_bit {
+ my($endian, $size, $label) = @_;
+ my($offset, $dir, $val, $val_bit);
+
+ if ($sil_endian && $endian ne $sil_endian) {
+ # エンディアンの不一致
+ print STDERR "genoffset: endian mismatch: $line\n";
+ $error = 1;
+ }
+
+ $offset = 0;
+ while ($line = <INFILE>) {
+ chomp $line;
+ next if ($line =~ /^[ \t]*[#;].*$/);
+
+ if ($line =~ /[ \t]*\.([a-zA-Z0-9]+)[ \t]*([^ \t]*)[ \t]*/
+ && defined($dir = $directives{$1})) {
+ $val = $2;
+
+ # 16進数と8進数の数値への変換処理
+ if ($val =~ /^0x(.+)$/) {
+ $val = hex($1);
+ }
+ elsif ($val =~ /^0(.+)$/) {
+ $val = oct($1);
+ }
+
+ if ($dir eq "") {
+ # サイズを知らないディレクティブ
+ print STDERR "genoffset: unknown directive: $line\n";
+ $error = 1;
+ }
+ elsif ($dir == 0) {
+ # 読み飛ばすべきディレクティブ
+ }
+ elsif ($dir == -1) {
+ # .zeroディレクティブの処理
+ $offset += $val;
+ }
+ elsif ($val == 0) {
+ # 値が0のフィールドの処理
+ $offset += $dir;
+ }
+ else {
+ # 値が0でないフィールドが見つかればループを終了
+ last;
+ }
+ }
+ else {
+ # 解析できない行
+ print STDERR "genoffset: cannot parse: $line\n";
+ $error = 1;
+ }
+ }
+
+ # ビット位置を探す
+ $val_bit = do search_bit($val);
+
+ # バイト単位に換算する
+ if ($endian eq "B") {
+ $offset += $dir - 1;
+ $offset -= $val_bit >> 3;
+ }
+ else {
+ $offset += $val_bit >> 3;
+ }
+ $val_bit &= 0x07;
+
+ # 出力単位に換算する
+ if ($size eq "W") {
+ if ($endian eq "B") {
+ $val_bit += 24;
+ $val_bit -= ($offset & 0x03) << 3;
+ }
+ else {
+ $val_bit += ($offset & 0x03) << 3;
+ }
+ $offset &= ~0x03;
+ }
+ elsif ($size eq "H") {
+ if ($endian eq "B") {
+ $val_bit += 8;
+ $val_bit -= ($offset & 0x01) << 3;
+ }
+ else {
+ $val_bit += ($offset & 0x01) << 3;
+ }
+ $offset &= ~0x01;
+ }
+
+ # 定義の出力
+ $label =~ s/^_//;
+ printf "#define %s\t%d\n",$label,$offset;
+ printf "#define %s_bit\t%d\n",$label,$val_bit;
+ printf "#define %s_mask\t0x%x\n",$label,(1 << $val_bit);
+}
+
+#
+# メインルーチン
+#
+print "/* This file is generated by genoffset. */\n";
+print "\n";
+
+$error = 0;
+open(INFILE, $infile) || die "Cannot open $infile";
+while ($line = <INFILE>) {
+ chomp $line;
+
+ if ($line =~ /^[ \t]*OFFSET_DEF ([^ \t]+) = [#\$]?([^ \t]+)/) {
+ do parse_offset($1, $2);
+ }
+ elsif ($line =~ /^[ \t]*_?BIT_REF_([0-9]+):/) {
+ do ref_bit($1);
+ }
+ elsif ($line =~ /^[ \t]*_?BIT_([BL])([BHW])_([^ \t]+):/) {
+ do parse_bit($1, $2, $3);
+ }
+ elsif ($line =~ /^[ \t]*SIL_ENDIAN = ([BL])/) {
+ $sil_endian = $1;
+ }
+}
+close(INFILE);
+exit($error);
--- /dev/null
+#! /usr/bin/perl
+#
+# TOPPERS Software
+# Toyohashi Open Platform for Embedded Real-Time Systems
+#
+# Copyright (C) 2003 by Embedded and Real-Time Systems Laboratory
+# Toyohashi Univ. of Technology, JAPAN
+# Copyright (C) 2005-2007 by Embedded and Real-Time Systems Laboratory
+# Graduate School of Information Science, Nagoya Univ., JAPAN
+#
+# 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+# スコード中に含まれていること.
+# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+# の無保証規定を掲載すること.
+# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+# と.
+# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+# 作権表示,この利用条件および下記の無保証規定を掲載すること.
+# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+# 報告すること.
+# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+# 免責すること.
+#
+# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+# の責任を負わない.
+#
+# @(#) $Id: genrename 509 2007-08-22 23:09:56Z hiro $
+#
+
+#
+# 先頭につける文字列
+#
+sub prefix_string {
+ local($sym) = @_;
+
+ if ($sym =~ /[a-z]/) {
+ return("_kernel_");
+ }
+ else {
+ return("_KERNEL_");
+ }
+}
+
+#
+# リネーム定義を生成する
+#
+sub generate_define
+{
+ local($sym, $prefix) = @_;
+
+ print FILE "#define ",$prefix,$sym;
+ print FILE "\t" if (length($prefix.$sym) < 4);
+ print FILE "\t" if (length($prefix.$sym) < 8);
+ print FILE "\t" if (length($prefix.$sym) < 12);
+ print FILE "\t" if (length($prefix.$sym) < 16);
+ print FILE "\t" if (length($prefix.$sym) < 20);
+ print FILE "\t" if (length($prefix.$sym) < 24);
+ print FILE "\t",$prefix,do prefix_string($sym),$sym,"\n";
+}
+
+#
+# リネーム解除を生成する
+#
+sub generate_undef
+{
+ local($sym, $prefix) = @_;
+
+ print FILE "#undef ",$prefix,$sym,"\n";
+}
+
+#
+# インクルードディレクティブを生成する
+#
+sub generate_include
+{
+ local($file, $prefix) = @_;
+
+ $file =~ s/([>"])$/_$prefix.h$1/;
+ $includes .= "#include ".$file."\n";
+}
+
+#
+# エラーチェック
+#
+if ($#ARGV != 0) {
+ die "Usage: genrename <prefix>\n";
+}
+
+#
+# 初期化
+#
+@syms = ();
+$name = $ARGV[0];
+$NAME = $name; $NAME =~ y/a-z/A-Z/;
+
+$infile = $name."_rename.def";
+$header_defsym = "TOPPERS_".$NAME."_RENAME_H";
+
+#
+# シンボルリストを読み込む
+#
+open(INFILE, $infile) || die "Cannot open $infile";
+while ($line = <INFILE>) {
+ chomp $line;
+ @syms = (@syms, $line);
+}
+close(INFILE);
+
+#
+# ???_rename.h を生成する
+#
+$includes = "";
+$file = $name."_rename.h";
+open(FILE, "> ".$file);
+
+print FILE <<END;
+/* This file is generated from $infile by genrename. */
+
+#ifndef $header_defsym
+#define $header_defsym
+
+END
+
+foreach $sym (@syms) {
+ if ($sym =~ /^#(.*)$/) {
+ print FILE "/*\n";
+ print FILE " * ",$1,"\n";
+ print FILE " */\n";
+ }
+ elsif ($sym =~ /^INCLUDE[ \t]+(.*)$/) {
+ do generate_include($1, "rename");
+ }
+ elsif ($sym ne "") {
+ do generate_define($sym, "");
+ }
+ else {
+ print FILE "\n";
+ }
+}
+
+print FILE <<END;
+
+#ifdef TOPPERS_LABEL_ASM
+
+END
+
+foreach $sym (@syms) {
+ if ($sym =~ /^#(.*)$/) {
+ print FILE "/*\n";
+ print FILE " * ",$1,"\n";
+ print FILE " */\n";
+ }
+ elsif ($sym =~ /^INCLUDE[ \t]+(.*)$/) {
+ # do nothing
+ }
+ elsif ($sym ne "") {
+ do generate_define($sym, "_");
+ }
+ else {
+ print FILE "\n";
+ }
+}
+
+print FILE <<END;
+
+#endif /* TOPPERS_LABEL_ASM */
+
+$includes
+#endif /* $header_defsym */
+END
+
+#
+# ???_unrename.h を生成する
+#
+$includes = "";
+$file = $name."_unrename.h";
+open(FILE, "> ".$file);
+
+print FILE <<END;
+/* This file is generated from $infile by genrename. */
+
+/* This file is included only when $name\_rename.h has been included. */
+#ifdef $header_defsym
+#undef $header_defsym
+
+END
+
+foreach $sym (@syms) {
+ if ($sym =~ /^#(.*)$/) {
+ print FILE "/*\n";
+ print FILE " * ",$1,"\n";
+ print FILE " */\n";
+ }
+ elsif ($sym =~ /^INCLUDE[ \t]+(.*)$/) {
+ do generate_include($1, "unrename");
+ }
+ elsif ($sym ne "") {
+ do generate_undef($sym, "");
+ }
+ else {
+ print FILE "\n";
+ }
+}
+
+print FILE <<END;
+
+#ifdef TOPPERS_LABEL_ASM
+
+END
+
+foreach $sym (@syms) {
+ if ($sym =~ /^#(.*)$/) {
+ print FILE "/*\n";
+ print FILE " * ",$1,"\n";
+ print FILE " */\n";
+ }
+ elsif ($sym =~ /^INCLUDE[ \t]+(.*)$/) {
+ # do nothing
+ }
+ elsif ($sym ne "") {
+ do generate_undef($sym, "_");
+ }
+ else {
+ print FILE "\n";
+ }
+}
+
+print FILE <<END;
+
+#endif /* TOPPERS_LABEL_ASM */
+
+$includes
+#endif /* $header_defsym */
+END
+
+close(FILE);
--- /dev/null
+#! /usr/bin/perl
+#
+# TOPPERS Software
+# Toyohashi Open Platform for Embedded Real-Time Systems
+#
+# Copyright (C) 2007-2008 by Embedded and Real-Time Systems Laboratory
+# Graduate School of Information Science, Nagoya Univ., JAPAN
+#
+# 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+# スコード中に含まれていること.
+# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+# の無保証規定を掲載すること.
+# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+# と.
+# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+# 作権表示,この利用条件および下記の無保証規定を掲載すること.
+# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+# 報告すること.
+# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+# 免責すること.
+#
+# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+# の責任を負わない.
+#
+# @(#) $Id: gentest 1546 2009-05-08 10:05:22Z ertl-hiro $
+#
+
+#
+# テストプログラム生成ツール
+#
+
+$infile = $ARGV[0];
+
+%parampos = (
+ "get_pri" => 2,
+ "get_inf" => 1,
+ "ref_tsk" => 2,
+ "ref_tex" => 2,
+ "ref_sem" => 2,
+ "ref_flg" => 2,
+ "ref_dtq" => 2,
+ "ref_pdq" => 2,
+ "ref_mbx" => 2,
+ "ref_mtx" => 2,
+ "ref_mpf" => 2,
+ "get_tim" => 1,
+ "get_utm" => 1,
+ "ref_cyc" => 2,
+ "ref_alm" => 2,
+ "get_tid" => 1,
+ "iget_tid" => 1,
+ "get_ipm" => 1,
+);
+
+%paramtype = (
+ "get_pri" => "PRI",
+ "get_inf" => "intptr_t",
+ "ref_tsk" => "T_RTSK",
+ "ref_tex" => "T_RTEX",
+ "ref_sem" => "T_RSEM",
+ "ref_flg" => "T_RFLG",
+ "ref_dtq" => "T_RDTQ",
+ "ref_pdq" => "T_RPDQ",
+ "ref_mbx" => "T_RMBX",
+ "ref_mtx" => "T_RMTX",
+ "ref_mpf" => "T_RMPF",
+ "get_tim" => "SYSTIM",
+ "get_utm" => "SYSUTM",
+ "ref_cyc" => "T_RCYC",
+ "ref_alm" => "T_RALM",
+ "get_tid" => "ID",
+ "iget_tid" => "ID",
+ "get_ipm" => "PRI",
+);
+
+sub gen_var_def {
+ local($svc_call) = @_;
+ local($svcname, @params);
+ local($typename, $varname);
+
+ if ($svc_call =~ /^([a-z_]+)\((.*)\)$/) {
+ $svcname = $1;
+ @params = split(/\s*,\s*/, $2);
+
+ if ($parampos{$svcname}) {
+ $varname = $params[@parampos{$svcname} - 1];
+ $varname =~ s/^\&//;
+ $typename = $paramtype{$svcname};
+ ${$TASKVAR{$tskid}}{$typename} = ${varname};
+ }
+ }
+}
+
+sub gen_svc_call {
+ local($svc_call, $error_code_string) = @_;
+ local($error_code);
+
+ $TASKCODE{$tskid} .= $indentstr;
+ $TASKCODE{$tskid} .= sprintf("ercd = %s;\n", $svc_call);
+ do gen_var_def($svc_call);
+
+ if ($error_code_string eq "") {
+ $TASKCODE{$tskid} .= $indentstr;
+ $TASKCODE{$tskid} .= sprintf("check_ercd(ercd, E_OK);\n");
+ }
+ elsif ($error_code_string =~ /^\-\>\s*noreturn$/) {
+ # do nothing.
+ }
+ else {
+ $error_code = $error_code_string;
+ $error_code =~ s/^\-\>\s*([A-Z_]*)$/$1/;
+ $TASKCODE{$tskid} .= $indentstr;
+ $TASKCODE{$tskid} .= sprintf("check_ercd(ercd, %s);\n", $error_code);
+ }
+}
+
+sub parse_line {
+ local($line) = @_;
+
+ if ($line =~ /^\.\./) {
+ # do nothing.
+ }
+ elsif ($line =~ /^==\s*((TASK|ALM)[0-9]+)(.*)$/) {
+ $startflag = 1;
+ $tskid = $1;
+ $line2 = $3;
+ if ($line2 =~ /^\-([0-9]+)/) {
+ $tskcount = $1;
+ $indentstr = "\t\t";
+ if (!$TASKCOUNT{$tskid}) {
+ $TASKCOUNT{$tskid} = 0;
+ if ($tskid =~ /^TASK([0-9]+)$/) {
+ $countvar = "task$1_count";
+ }
+ elsif ($tskid =~ /^ALM([0-9]+)$/) {
+ $countvar = "alarm$1_count";
+ }
+ $TASKCOUNTVAR{$tskid} = $countvar;
+ }
+ if ($tskcount == $TASKCOUNT{$tskid} + 1) {
+ if ($tskcount > 1) {
+ $TASKCODE{$tskid} .= "\n".$indentstr;
+ $TASKCODE{$tskid} .= sprintf("check_point(0);\n\n");
+ }
+ $TASKCOUNT{$tskid} = $tskcount;
+ $TASKCODE{$tskid} .= sprintf("\tcase %d:", $tskcount);
+ }
+ elsif ($tskcount != $TASKCOUNT{$tskid}) {
+ printf STDERR "Subtask count error: %d-%d\n",$tskid,$tskcount;
+ }
+ }
+ else {
+ $tskcount = "";
+ $indentstr = "\t";
+ }
+ }
+ elsif (!$startflag) {
+ # do nothing.
+ }
+ elsif ($line =~ /^(assert\(.*\))$/) {
+ $assert_string = $1;
+ $TASKCODE{$tskid} .= $indentstr;
+ $TASKCODE{$tskid} .= sprintf("check_%s;\n", $assert_string);
+ }
+ elsif ($line =~ /^call\((.*)\)$/) {
+ $call_string = $1;
+ $TASKCODE{$tskid} .= "\n".$indentstr;
+ $TASKCODE{$tskid} .= sprintf("%s;\n", $call_string);
+ }
+ elsif ($line =~ /^([0-9]+)\:\s*MISSING$/) {
+ $check_no = $1;
+ $TASKCODE{$tskid} .= "\n".$indentstr;
+ $TASKCODE{$tskid} .= sprintf("check_point(%d);\n", $check_no);
+ }
+ elsif ($line =~ /^([0-9]+)\:\s*RETURN$/) {
+ $check_no = $1;
+ $TASKCODE{$tskid} .= "\n".$indentstr;
+ $TASKCODE{$tskid} .= sprintf("check_point(%d);\n", $check_no);
+ $TASKCODE{$tskid} .= $indentstr;
+ $TASKCODE{$tskid} .= "return;\n";
+ }
+ elsif ($line =~ /^RETURN$/) {
+ $TASKCODE{$tskid} .= "\n".$indentstr;
+ $TASKCODE{$tskid} .= "return;\n";
+ }
+ elsif ($line =~ /^([0-9]+)\:\s*END$/) {
+ $check_no = $1;
+ $TASKCODE{$tskid} .= "\n".$indentstr;
+ $TASKCODE{$tskid} .= sprintf("check_finish(%d);\n", $check_no);
+ $endflag = 1;
+ }
+ elsif ($line =~ /^([0-9]+)\:\s*([a-z_]+\(.*\))\s*(\-\>\s*[A-Za-z_]*)?\s*$/) {
+ $check_no = $1;
+ $svc_call = $2;
+ $error_code_string = $3;
+ $TASKCODE{$tskid} .= "\n".$indentstr;
+ $TASKCODE{$tskid} .= sprintf("check_point(%d);\n", $check_no);
+ do gen_svc_call($svc_call, $error_code_string);
+ }
+ elsif ($line =~ /^([a-z_]+\(.*\))\s*(\-\>\s*[A-Za-z_]*)?\s*$/) {
+ $svc_call = $1;
+ $error_code_string = $2;
+ $TASKCODE{$tskid} .= "\n";
+ do gen_svc_call($svc_call, $error_code_string);
+ }
+ else {
+ print STDERR "Error: ",$line,"\n";
+ }
+}
+
+#
+# スクリプトファイル読込み処理
+#
+$startflag = 0;
+$endflag = 0;
+open(INFILE, $infile) || die "Cannot open $infile";
+while (($line = <INFILE>) && !$endflag) {
+ chomp $line;
+ $line =~ s/^\s*\*\s*//;
+ $line =~ s/\s*\/\/.*$//;
+ $line =~ s/\s*\.\.\..*$//;
+ next unless($line);
+ do parse_line($line);
+}
+close(INFILE);
+
+#
+# タスクコードの出力
+#
+sub output_task {
+ if ($TASKCOUNT{$tskid}) {
+ printf "\nstatic uint_t\t%s = 0;\n", $TASKCOUNTVAR{$tskid};
+ }
+ print "\nvoid\n";
+ if ($tskid =~ /^TASK([0-9]+)$/) {
+ print "task$1(intptr_t exinf)\n";
+ }
+ elsif ($tskid =~ /^ALM([0-9]+)$/) {
+ print "alarm$1_handler(intptr_t exinf)\n";
+ }
+ print "{\n";
+ print "\tER\t\tercd;\n";
+ foreach $typename (keys(%{$TASKVAR{$tskid}})) {
+ print "\t",$typename, (length($typename) < 4 ? "\t\t" : "\t"),
+ ${$TASKVAR{$tskid}}{$typename},";\n";
+ }
+ if ($TASKCOUNT{$tskid}) {
+ printf "\n\tswitch (++%s) {\n", $TASKCOUNTVAR{$tskid};
+ }
+ print $TASKCODE{$tskid};
+ if ($TASKCOUNT{$tskid}) {
+ printf "\n\t\tcheck_point(0);\n";
+ printf "\t}\n";
+ }
+ else {
+ print "\n";
+ }
+ print "\tcheck_point(0);\n";
+ print "}\n";
+}
+
+#
+# テストプログラム出力処理
+#
+foreach $tskid (sort(keys(TASKCODE))) {
+ do output_task();
+}
--- /dev/null
+#! /usr/bin/perl
+#
+# TOPPERS Software
+# Toyohashi Open Platform for Embedded Real-Time Systems
+#
+# Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
+# Toyohashi Univ. of Technology, JAPAN
+# Copyright (C) 2004-2007 by Embedded and Real-Time Systems Laboratory
+# Graduate School of Information Science, Nagoya Univ., JAPAN
+#
+# 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+# スコード中に含まれていること.
+# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+# の無保証規定を掲載すること.
+# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+# と.
+# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+# 作権表示,この利用条件および下記の無保証規定を掲載すること.
+# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+# 報告すること.
+# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+# 免責すること.
+#
+# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+# の責任を負わない.
+#
+# @(#) $Id: makedep 1524 2009-04-29 03:37:27Z ertl-hiro $
+#
+
+require "getopt.pl";
+
+# オプションの定義
+#
+# -C <cc_path> Cコンパイラのコマンド名
+# -O <cc_opts> Cコンパイラ/CPPに渡すオプション
+# -X ソースファイルを強制的にCヘッダファイルと見なす
+#
+# -T <target> ターゲットのファイル名
+# -D <t_dir> ターゲットのディレクトリ名を指定する
+# -d ターゲットのディレクトリ部を保持する
+#
+# -R <dirname> Cygwin環境におけるルートディレクトリ名を指定する
+# (デフォルトはcygdrive)
+
+#
+# オプションの処理
+#
+do Getopt("COTDR");
+
+$cc_path = $opt_C;
+$cc_opts = $opt_O;
+
+if ($opt_T) {
+ $target_file = $opt_T;
+}
+elsif ($opt_D) {
+ $target_dir = $opt_D;
+}
+elsif (!$opt_d) {
+ $target_dir = "";
+}
+
+if ($opt_R) {
+ $cygwin_root = $opt_R;
+}
+else {
+ $cygwin_root = "cygdrive";
+}
+
+#
+# Cygwin環境の判別
+#
+use POSIX;
+@uname = do uname();
+if ($uname[0] =~ /^cygwin/i) {
+ $cygwin = 1;
+}
+
+#
+# %dependlist に作られた依存関係を出力する
+#
+sub output_dependlist {
+ local($file) = @_;
+ local($target, $column, $len);
+
+ if ($target_file) {
+ $target = $target_file;
+ }
+ else {
+ $target = $file;
+ $target =~ s/(.*)\.(.*)/$1.o/;
+ }
+ if (defined($target_dir)) {
+ $target =~ s/^.*\/([^\/]+)$/$1/;
+ if ($target_dir) {
+ $target = $target_dir."/".$target;
+ }
+ }
+ print $target, ": ";
+ $column = length($target) + 2;
+
+ foreach $file (keys(%dependlist)) {
+ $len = length($file) + 1;
+ if ($column > 8 && $column + $len >= 70) {
+ print "\\\n\t";
+ $column = 8;
+ }
+ $column += $len;
+ print "$file ";
+ }
+ print "\n";
+}
+
+#
+# $file の依存関係を %dependlist に作る
+#
+sub makedepend_one {
+ local($file) = @_;
+ local($command, $input, $dir, $filename);
+
+ $command = "$cc_path -E $cc_opts";
+ if ($opt_X) {
+ $command .= " -x c-header";
+ }
+ unless (open(INPUT, "$command $file |")) {
+ print STDERR "makedep: can't open $file\n";
+ exit(1);
+ }
+ while ($line = <INPUT>) {
+ if ($line =~ /^\#\s*([0-9]+)\s*\"([^\"]+)\"/) {
+ $filename = $2;
+ $filename =~ s/ /\\ /g;
+ if ($filename !~ /^\<.*\>$/ && $filename !~ /\/$/) {
+ if ($cygwin) {
+ $filename =~ s/^([a-zA-Z]):/\/$cygwin_root\/$1/;
+ }
+ $dependlist{$filename} = 1;
+ }
+ }
+ }
+ unless (close(INPUT)) {
+ print STDERR "makedep: can't execute $command\n";
+ exit(1);
+ }
+}
+
+#
+# メインルーチン
+#
+foreach $file (@ARGV) {
+ %dependlist = ();
+ do makedepend_one($file);
+ do output_dependlist($file) if (%dependlist);
+}
--- /dev/null
+#! /usr/bin/perl
+#
+# TOPPERS Software
+# Toyohashi Open Platform for Embedded Real-Time Systems
+#
+# Copyright (C) 2006-2010 by Embedded and Real-Time Systems Laboratory
+# Graduate School of Information Science, Nagoya Univ., JAPAN
+#
+# 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
+# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
+# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
+# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
+# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
+# スコード中に含まれていること.
+# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
+# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
+# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
+# の無保証規定を掲載すること.
+# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
+# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
+# と.
+# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
+# 作権表示,この利用条件および下記の無保証規定を掲載すること.
+# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
+# 報告すること.
+# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
+# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
+# 免責すること.
+#
+# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
+# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
+# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
+# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
+# の責任を負わない.
+#
+# @(#) $Id: makerelease 1866 2010-07-25 13:19:17Z ertl-hiro $
+#
+
+require 'getcwd.pl';
+
+$cwd = getcwd();
+$cwd =~ s/^.*[\/\\]([^\/\\]+)$/$1/;
+$prefix = "./".$cwd;
+
+@file_list = ();
+%file_list = ();
+
+if ($#ARGV >= 0) {
+ $arg1 = $ARGV[0];
+ $arg1 =~ s/\.\///;
+}
+else {
+ $arg1 = "MANIFEST";
+}
+
+sub gen_path
+{
+ local($base, $path) = @_;
+
+ while ($path =~ /^..\/(.*)$/) {
+ $path = $1;
+ $base =~ s/(\/?)[^\/]*\/$/$1/;
+ }
+ return($base.$path);
+}
+
+sub read_file {
+ local($filename) = @_;
+ local($fh, $dirname);
+
+ if ($filename =~ /^(.*\/)[^\/]*$/) {
+ $dirname = $1;
+ }
+ else {
+ $dirname = "";
+ }
+
+ open($fh, $filename) || die "Cannot open $infile";
+ while ($line = <$fh>) {
+ chomp $line;
+ $line =~ s/\r$//;
+ $line =~ s/[ \t]*\#.*$//;
+ next if ($line =~ /^[ \t]*$/);
+
+ if ($line =~ /^E_PACKAGE[ \t]+(.*)$/) {
+ if ($package) {
+ die "Duplicated E_PACKAGE directive.";
+ }
+ else {
+ $package = $1;
+ $e_package = 1;
+ }
+ }
+ elsif ($line =~ /^PACKAGE[ \t]+(.*)$/) {
+ if ($package) {
+ if (!$e_package && $package != $1) {
+ die "Inconsistent PACKAGE directive.";
+ }
+ }
+ else {
+ $package = $1;
+ }
+ }
+ elsif ($line =~ /^VERSION[ \t]+(.*)$/) {
+ if ($version) {
+ if (!$e_package && $version != $1) {
+ die "Inconsistent VERSION directive.";
+ }
+ }
+ else {
+ $version = $1;
+ if ($version =~ /%date/) {
+ @current_time = localtime();
+ $vdate = sprintf("%04d%02d%02d", $current_time[5]+1900,
+ $current_time[4]+1, $current_time[3]);
+ $version =~ s/%date/$vdate/;
+ }
+ }
+ }
+ elsif ($line =~ /^INCLUDE[ \t]+(.*)$/) {
+ do read_file(do gen_path($dirname, $1));
+ }
+ else {
+ $filename = $prefix."/".$dirname.$line;
+ while ($filename =~ s|/[^/]+/\.\./|/|) {}
+ if ($file_list{$filename}) {
+ die "$filename is duplicated.";
+ }
+ else {
+ push(@file_list, $filename);
+ $file_list{$filename} = $filename;
+ }
+ }
+ }
+ close($fh);
+}
+
+do read_file($arg1);
+unless ($package) {
+ die "PACKAGE/E_PACKAGE directive not found.";
+}
+unless ($version) {
+ die "VERSION directive not found.";
+}
+
+if (! -d "RELEASE") {
+ mkdir("RELEASE");
+}
+
+$archive_name = $package."-".$version.".tar.gz";
+$file_list = join(" ", @file_list);
+$command = "tar cvfz RELEASE/$archive_name -C .. $file_list\n";
+die if (system($command));
+print STDERR "== RELEASE/$archive_name is generated. ==\n";
--- /dev/null
+# NXP LPC1768 Cortex-M3 with 512kB Flash and 32kB+32kB Local On-Chip SRAM,
+# # LPC17xx chips support both JTAG and SWD transports.
+# # Adapt based on what transport is active.
+# source [find target/swj-dp.tcl]
+if { [info exists CHIPNAME] } {
+ set _CHIPNAME $CHIPNAME
+} else {
+ set _CHIPNAME lpc1768
+}
+# After reset the chip is clocked by the ~4MHz internal RC oscillator.
+# When board-specific code (reset-init handler or device firmware)
+# configures another oscillator and/or PLL0, set CCLK to match; if
+# you don't, then flash erase and write operations may misbehave.
+# (The ROM code doing those updates cares about core clock speed...)
+#
+# CCLK is the core clock frequency in KHz
+if { [info exists CCLK ] } {
+ set _CCLK $CCLK
+} else {
+ set _CCLK 4000
+}
+if { [info exists CPUTAPID ] } {
+ set _CPUTAPID $CPUTAPID
+} else {
+ set _CPUTAPID 0x4ba00477
+}
+#delays on reset lines
+#adapter_nsrst_delay 200
+jtag_ntrst_delay 200
+# LPC2000 & LPC1700 -> SRST causes TRST
+reset_config srst_pulls_trst
+jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID
+#swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID
+set _TARGETNAME $_CHIPNAME.cpu
+target create $_TARGETNAME cortex_m3 -chain-position $_TARGETNAME
+# LPC1768 has 32kB of SRAM In the ARMv7-M "Code" area (at 0x10000000)
+# and 32K more on AHB, in the ARMv7-M "SRAM" area, (at 0x2007c000).
+$_TARGETNAME configure -work-area-phys 0x10000000 -work-area-size 0x8000
+# LPC1768 has 512kB of flash memory, managed by ROM code (including a
+# boot loader which verifies the flash exception table's checksum).
+# flash bank (name) lpc2000 (base) (size) 0 0 (target#) (variant) (clock) [calc checksum]
+set _FLASHNAME $_CHIPNAME.flash
+# flash bank $_FLASHNAME lpc2000 0x0 0x80000 0 0 $_TARGETNAME lpc1700 $_CCLK calc_checksum
+flash bank $_FLASHNAME lpc2000 0x0 0x80000 0 0 $_TARGETNAME lpc1700 100000
+
+# Run with *real slow* clock by default since the
+# boot rom could have been playing with the PLL, so
+# we have no idea what clock the target is running at.
+jtag_khz 100
+$_TARGETNAME configure -event reset-init {
+ # Do not remap 0x0000-0x0020 to anything but the flash (i.e. select
+ # "User Flash Mode" where interrupt vectors are _not_ remapped,
+ # and reside in flash instead).
+ #
+ # See Table 612. Memory Mapping Control register (MEMMAP - 0x400F C040) bit description
+ # Bit Symbol Value Description Reset
+ # value
+ # 0 MAP Memory map control. 0
+ # 0 Boot mode. A portion of the Boot ROM is mapped to address 0.
+ # 1 User mode. The on-chip Flash memory is mapped to address 0.
+ # 31:1 - Reserved. The value read from a reserved bit is not defined. NA
+ #
+ # http://ics.nxp.com/support/documents/microcontrollers/?scope=LPC1768&type=user
+ mww 0x400FC040 0x01
+}
+init
+reset init
--- /dev/null
+.SUFFIXES: .tex .dvi .pdf .obj .eps .aux .bb .tgz .tar .gz .out \
+ .bz2 .tbz .zip .jpg .jpeg .bmp .png .log .toc .lof .lot \
+ .idx .glo .ilg .glg .gls .ltx .dtx .bib .bbl .blg
+
+VERSION := $(shell date +%Y-%m-%d)
+ID := $(shell whoami)
+
+# required sources
+MAIN = main
+SRC = section1.tex section2.tex
+ETC =
+
+# program setting
+EDITOR = openemacs
+TEX = platex -kanji=utf8 -src-specials -no-shell-escape
+BIBTEX = jbibtex -kanji=utf8
+DVIPDF = dvipdfmx
+XDVI = open -a Mxdvi.app
+XPDF = open -a Preview.app
+REFGREP = grep "^LaTeX Warning: Label(s) may have changed."
+EBB = ebb
+
+# sub-directory setting
+# JPEG, PNG などのビットマップ画像の保存先
+IMGDIR = img
+# PDF の保存先
+PDFDIR = pdf
+# OmniGraffle 等で作成したオリジナルファイル(dvipdfmx で未対応)
+PICTDIR = pict
+# 表の原稿ファイル
+TABLEDIR = table
+# Gnuplot のプロットデータや CSV ファイルの格納場所
+PLOTDIR = plt
+#
+ETCDIR = tex
+# バックアップファイルの名前
+DISTDIR = $(ID)-$(VERSION)
+
+# default target
+all: dvi
+
+# aliases
+dvi: $(MAIN).dvi
+pdf: $(MAIN).pdf
+bib: $(MAIN).bbl
+
+# indipendency
+$(MAIN).dvi: $(MAIN).tex $(SRC)
+$(MAIN).pdf: $(MAIN).dvi
+$(MAIN).aux: $(MAIN).tex
+$(MAIN).bbl: $(MAIN).bib
+$(MAIN).bib: $(MAIN).aux
+
+# translation rules
+.dvi.pdf:
+ $(DVIPDF) $<
+.tex.dvi:
+ $(TEX) $<
+ (while grep "^No file $*.lo" $*.log; do $(TEX) $<; done)
+ (while $(REFGREP) $*.log; do $(TEX) $<; done)
+.bib.bbl:
+ $(BIBTEX) $*
+.tex.aux:
+ $(TEX) $<
+#
+#
+fast:
+ $(TEX) -interaction=batchmode $(MAIN)
+view: $(MAIN).dvi
+ $(XDVI) $< &
+viewpdf: $(MAIN).pdf
+ $(XPDF) $< &
+
+edit:
+ $(EDITOR) $(MAIN).tex &
+
+dist: clean
+ mkdir $(DISTDIR)
+ cp -r $(IMGDIR) $(PDFDIR) $(PICTDIR) $(TABLEDIR) \
+ $(PLOTDIR) $(ETCDIR) $(DISTDIR)
+ cp $(SRC) $(MAIN).tex $(ETC) Makefile $(DISTDIR)
+ tar cjf ../$(DISTDIR).tar.bz2 $(DISTDIR)
+ rm -fr $(DISTDIR)
+
+clean:
+ rm -f *~
+ rm -f *.{aux,bbl,blg} *.log $(MAIN).{lof,lot,toc,dvi,pdf,out}
+
+help:
+ @echo -e "\nusage: make [<target>]\n"
+ @echo -e "all:\tDVI ファイル $(MAIN).dvi を作成する"
+ @echo -e "bib:\t文献ファイル $(MAIN).bbl を作成する"
+ @echo -e "clean:\t一時ファイルを全て削除する"
+ @echo -e "dist:\tバックアップ $(DISTDIR).tar.bz2 を一つの上のフォルダに作成する"
+ @echo -e "dvi:\tDVI ファイル $(MAIN).dvi を作成する"
+ @echo -e "edit:\tテキストエディッタ $(EDITOR) で $(MAIN).tex を開く\t"
+ @echo -e "fast:\t依存関係を無視して $(MAIN).tex をコンパイルする"
+ @echo -e "help:\tこのメッセージを表示する"
+ @echo -e "pdf:\tPDF ファイル $(MAIN).pdf を作成する"
+ @echo -e "view:\tDVI を $(XDVI) で開く"
+ @echo -e "viewpdf:\tPDF を $(XPDF) で開く\n"
+
--- /dev/null
+\documentclass{jarticle}
+\begin{document}
+
+\include{section1}
+\include{section2}
+
+\end{document}
--- /dev/null
+
+¤³¤ì¤Ï¥»¥¯¥·¥ç¥ó£±
+
--- /dev/null
+
+¤³¤ì¤Ï¥»¥¯¥·¥ç¥ó£²
+
--- /dev/null
+#!/bin/sh
+VERSION="0.0.6"
+FILELIST="ntshell.c ntshell.h ntopt.c ntopt.h ntlibc.c ntlibc.h vtparse.c vtparse.h vtparse_table.c vtparse_table.h text_editor.c text_editor.h text_history.c text_history.h ntshell.readme_en ntshell.readme_ja"
+RELFILE="ntshell-$VERSION.tar.gz"
+
+tar cvfz $RELFILE $FILELIST
+
--- /dev/null
+/**
+ * @file ntlibc.c
+ * @author Shinichiro Nakamura
+ * @brief NT-Shellで用いる小規模libcの実装。
+ */
+
+/*
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell)
+ * Version 0.0.7
+ * ===============================================================
+ * Copyright (c) 2010-2011 Shinichiro Nakamura
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ * ===============================================================
+ */
+
+#include "ntlibc.h"
+
+size_t ntlibc_strlen(const char *s)
+{
+ const char *p = s;
+ int cnt = 0;
+ while (*p) {
+ cnt++;
+ p++;
+ }
+ return cnt;
+}
+
+char *ntlibc_strcpy(char *des, const char *src)
+{
+ char *d = des;
+ const char *s = src;
+ while (*s) {
+ *d = *s;
+ d++;
+ s++;
+ }
+ *d = '\0';
+ return des;
+}
+
+char *ntlibc_strcat(char *des, const char *src)
+{
+ char *d = des;
+ const char *s = src;
+ while (*d) {
+ d++;
+ }
+ while (*s) {
+ *d = *s;
+ d++;
+ s++;
+ }
+ *d = '\0';
+ return des;
+}
+
+int ntlibc_strcmp(const char *s1, const char *s2)
+{
+ char *p1 = (char *)s1;
+ char *p2 = (char *)s2;
+ while (*p1 || *p2) {
+ if (*p1 != *p2) {
+ return (*p1 < *p2) ? -1 : 1;
+ }
+ p1++;
+ p2++;
+ }
+ if (*p1 == *p2) {
+ return 0;
+ } else {
+ return (*p1 < *p2) ? -1 : 1;
+ }
+}
+
+int ntlibc_strncmp(const char *s1, const char *s2, size_t n)
+{
+ char *p1 = (char *)s1;
+ char *p2 = (char *)s2;
+ size_t len = 0;
+ while (*p1 || *p2) {
+ if (n <= len) {
+ break;
+ }
+ if (*p1 != *p2) {
+ return (*p1 < *p2) ? -1 : 1;
+ }
+ p1++;
+ p2++;
+ len++;
+ }
+ return 0;
+}
+
+#if 0
+#include <stdio.h>
+int main(void);
+int main(void) {
+ char *str_a = "That";
+ char *str_b = "The";
+ printf("strcmp(%s,%s) = %d, %d\n",
+ str_a, str_b,
+ strcmp(str_a, str_b),
+ ntlibc_strcmp(str_a, str_b));
+ printf("strncmp(%s,%s,2) = %d, %d\n",
+ str_a, str_b,
+ strncmp(str_a, str_b, 2),
+ ntlibc_strncmp(str_a, str_b, 2));
+ printf("strncmp(%s,%s,3) = %d, %d\n",
+ str_a, str_b,
+ strncmp(str_a, str_b, 3),
+ ntlibc_strncmp(str_a, str_b, 3));
+ return 0;
+}
+#endif
+
--- /dev/null
+/**
+ * @file ntlibc.h
+ * @author Shinichiro Nakamura
+ * @brief NT-Shellで用いる小規模libcの定義。
+ */
+
+/*
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell)
+ * Version 0.0.7
+ * ===============================================================
+ * Copyright (c) 2010-2011 Shinichiro Nakamura
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ * ===============================================================
+ */
+
+#ifndef NTLIBC_H
+#define NTLIBC_H
+
+#ifndef size_t
+typedef unsigned int size_t;
+#endif
+
+size_t ntlibc_strlen(const char *s);
+char *ntlibc_strcpy(char *des, const char *src);
+char *ntlibc_strcat(char *des, const char *src);
+int ntlibc_strcmp(const char *s1, const char *s2);
+int ntlibc_strncmp(const char *s1, const char *s2, size_t n);
+
+#endif
+
--- /dev/null
+/**
+ * @file ntopt.c
+ * @author Shinichiro Nakamura
+ * @brief NT-Shell用オプション解析モジュールの実装。
+ */
+
+/*
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell)
+ * Version 0.0.7
+ * ===============================================================
+ * Copyright (c) 2010-2011 Shinichiro Nakamura
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ * ===============================================================
+ */
+
+#include "ntopt.h"
+
+#define IS_DELIM(c) \
+ (((c) == '\r') || ((c) == '\n') || ((c) == '\t') || ((c) == '\0') || ((c) == ' '))
+
+static int ntopt_get_count(const char *str);
+static char *ntopt_get_text(const char *str, const int n, char *buf, int siz);
+
+static int ntopt_get_count(const char *str)
+{
+ int cnt = 0;
+ int wc = 0;
+ char *p = (char *)str;
+ while (*p) {
+ if (!IS_DELIM(*p)) {
+ wc++;
+ if (wc == 1) {
+ cnt++;
+ }
+ } else {
+ wc = 0;
+ }
+ p++;
+ }
+ return cnt;
+}
+
+static char *ntopt_get_text(const char *str, const int n, char *buf, int siz)
+{
+ int cnt = 0;
+ int wc = 0;
+ char *p = (char *)str;
+ while (*p) {
+ if (!IS_DELIM(*p)) {
+ wc++;
+ if ((wc == 1)) {
+ if (cnt == n) {
+ char *des = buf;
+ int cc = 0;
+ while (!IS_DELIM(*p)) {
+ cc++;
+ if (siz <= cc) {
+ break;
+ }
+ *des = *p;
+ des++;
+ p++;
+ }
+ *des = '\0';
+ return buf;
+ }
+ cnt++;
+ }
+ } else {
+ wc = 0;
+ }
+ p++;
+ }
+ return '\0';
+}
+
+int ntopt_parse(
+ const char *str,
+ void *extobj,
+ int (*func)(int argc, char **argv, void *extobj))
+{
+ int argc;
+ char argv[NTOPT_MAXCNT_ARGC][NTOPT_MAXLEN_ARGV];
+ char *argvp[NTOPT_MAXCNT_ARGC];
+ int i;
+
+ argc = ntopt_get_count(str);
+ if (NTOPT_MAXCNT_ARGC <= argc) {
+ argc = NTOPT_MAXCNT_ARGC;
+ }
+
+ for (i = 0; i < argc; i++) {
+ argvp[i] = ntopt_get_text(str, i, argv[i], sizeof(argv[i]));
+ }
+
+ return func(argc, &argvp[0], extobj);
+}
+
--- /dev/null
+/**
+ * @file ntopt.h
+ * @author Shinichiro Nakamura
+ * @brief NT-Shell用オプション解析モジュールの定義。
+ */
+
+/*
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell)
+ * Version 0.0.7
+ * ===============================================================
+ * Copyright (c) 2010-2011 Shinichiro Nakamura
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ * ===============================================================
+ */
+
+#ifndef _NTOPT_H_
+#define _NTOPT_H_
+
+#define NTOPT_MAXCNT_ARGC 32
+#define NTOPT_MAXLEN_ARGV 32
+
+int ntopt_parse(const char *str, void *extobj, int (*func)(int argc, char **argv, void *extobj));
+
+#endif
+
--- /dev/null
+/**
+ * @file ntshell.c
+ * @author Shinichiro Nakamura
+ * @brief 小規模組み込みシステム向けのシェルシステムの実装。
+ */
+
+/*
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell)
+ * Version 0.0.7
+ * ===============================================================
+ * Copyright (c) 2010-2011 Shinichiro Nakamura
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ * ===============================================================
+ */
+
+#include "ntshell.h"
+#include "ntlibc.h"
+
+#define VERSION_MAJOR 0 /**< メジャー番号。 */
+#define VERSION_MINOR 0 /**< マイナー番号。 */
+#define VERSION_RELEASE 6 /**< リリース番号。 */
+
+/**
+ * @brief 処理で用いるデータ構造体。
+ *
+ * @details
+ * vtparseはユーザデータのポインタを設定することができる。
+ * Natural Tiny Shellはこれを使って自身の処理で必要な情報を保持する。
+ */
+typedef struct {
+ text_editor_t *editor;
+ text_history_t *history;
+ int suggest_index;
+ char suggest_source[TEXTEDITOR_MAXLEN];
+ int (*func_read)(char *buf, int cnt);
+ int (*func_write)(const char *buf, int cnt);
+ int (*func_cb)(const char *text);
+} ntshell_user_data_t;
+
+#define SUGGEST_INDEX(vtp) \
+ ((ntshell_user_data_t *)(vtp)->user_data)->suggest_index
+#define SUGGEST_SOURCE(vtp) \
+ ((ntshell_user_data_t *)(vtp)->user_data)->suggest_source
+
+/**
+ * @brief テキストエディタを取得する。
+ *
+ * @param vtp vtparse構造体。
+ */
+#define GET_EDITOR(vtp) \
+ ((ntshell_user_data_t *)(vtp)->user_data)->editor
+
+/**
+ * @brief テキストヒストリを取得する。
+ *
+ * @param vtp vtparse構造体。
+ */
+#define GET_HISTORY(vtp) \
+ ((ntshell_user_data_t *)(vtp)->user_data)->history
+
+/**
+ * @brief シリアルポートから読み込む。
+ *
+ * @param vtp vtparse構造体。
+ * @param buf 読み込みバッファ。
+ * @param cnt 読み込み文字数。
+ */
+#define SERIAL_READ(vtp,buf,cnt) \
+ ((ntshell_user_data_t *)(vtp)->user_data)->func_read(buf, cnt)
+
+/**
+ * @brief シリアルポートへ書き込む。
+ *
+ * @param vtp vtparse構造体。
+ * @param buf 書き込みバッファ。
+ * @param cnt 書き込み文字数。
+ */
+#define SERIAL_WRITE(vtp,buf,cnt) \
+ ((ntshell_user_data_t *)(vtp)->user_data)->func_write(buf, cnt)
+
+/**
+ * @brief コールバックを呼び出す。
+ *
+ * @param vtp vtparse構造体。
+ * @param text コールバック関数へ渡す文字列。
+ */
+#define CALLBACK(vtp, text) \
+ ((ntshell_user_data_t *)(vtp)->user_data)->func_cb(text)
+
+/**
+ * @brief テキストヒストリで1つ後ろを辿る。
+ *
+ * @param parser パーサー。
+ * @param action アクション。
+ * @param ch 入力文字。
+ */
+static void actfunc_history_prev(
+ vtparse_t *parser,
+ vtparse_action_t action,
+ unsigned char ch) {
+ if (text_history_read_point_prev(GET_HISTORY(parser))) {
+ char txt[TEXTHISTORY_MAXLEN];
+ int n = text_history_read(GET_HISTORY(parser), &txt[0], sizeof(txt));
+ if (0 < n) {
+ SERIAL_WRITE(parser, "\x1b[2K", 4);
+ SERIAL_WRITE(parser, "\x1b[80D", 5);
+ SERIAL_WRITE(parser, ">", 1);
+ SERIAL_WRITE(parser, txt, n);
+ text_editor_set_text(GET_EDITOR(parser), txt);
+ }
+ }
+}
+
+/**
+ * @brief テキストヒストリで1つ前を辿る。
+ *
+ * @param parser パーサー。
+ * @param action アクション。
+ * @param ch 入力文字。
+ */
+static void actfunc_history_next(
+ vtparse_t *parser,
+ vtparse_action_t action,
+ unsigned char ch) {
+ if (text_history_read_point_next(GET_HISTORY(parser))) {
+ char txt[TEXTHISTORY_MAXLEN];
+ int n = text_history_read(GET_HISTORY(parser), &txt[0], sizeof(txt));
+ if (0 < n) {
+ SERIAL_WRITE(parser, "\x1b[2K", 4);
+ SERIAL_WRITE(parser, "\x1b[80D", 5);
+ SERIAL_WRITE(parser, ">", 1);
+ SERIAL_WRITE(parser, txt, n);
+ text_editor_set_text(GET_EDITOR(parser), txt);
+ }
+ }
+}
+
+/**
+ * @brief カーソルを左へ移動させる。
+ *
+ * @param parser パーサー。
+ * @param action アクション。
+ * @param ch 入力文字。
+ */
+static void actfunc_cursor_left(
+ vtparse_t *parser,
+ vtparse_action_t action,
+ unsigned char ch) {
+ if (text_editor_cursor_left(GET_EDITOR(parser))) {
+ SERIAL_WRITE(parser, "\x1b[1D", 4);
+ }
+}
+
+/**
+ * @brief カーソルを右へ移動させる。
+ *
+ * @param parser パーサー。
+ * @param action アクション。
+ * @param ch 入力文字。
+ */
+static void actfunc_cursor_right(
+ vtparse_t *parser,
+ vtparse_action_t action,
+ unsigned char ch) {
+ if (text_editor_cursor_right(GET_EDITOR(parser))) {
+ SERIAL_WRITE(parser, "\x1b[1C", 4);
+ }
+}
+
+/**
+ * @brief エンターキーの処理を実行する。
+ *
+ * @param parser パーサー。
+ * @param action アクション。
+ * @param ch 入力文字。
+ */
+static void actfunc_enter(
+ vtparse_t *parser,
+ vtparse_action_t action,
+ unsigned char ch) {
+ char txt[TEXTEDITOR_MAXLEN];
+ text_editor_get_text(GET_EDITOR(parser), &txt[0], sizeof(txt));
+ text_editor_clear(GET_EDITOR(parser));
+ text_history_write(GET_HISTORY(parser), txt);
+ SERIAL_WRITE(parser, "\r\n", 2);
+ CALLBACK(parser, txt);
+ SERIAL_WRITE(parser, ">", 1);
+}
+
+/**
+ * @brief キャンセルキーの処理を実行する。
+ * @details
+ * 一般的なOSのCTRL+C処理はシグナルを発行し、受信したプロセスが
+ * 中断処理を実行する。
+ * ここでのキャンセルは見た目を再現したもので、
+ * 入力中の文字列を破棄してカーソルを新しい入力に備えて復帰させるものだ。
+ *
+ * @param parser パーサー。
+ * @param action アクション。
+ * @param ch 入力文字。
+ */
+static void actfunc_cancel(
+ vtparse_t *parser,
+ vtparse_action_t action,
+ unsigned char ch) {
+ SERIAL_WRITE(parser, "^C\r\n", 4);
+ text_editor_clear(GET_EDITOR(parser));
+ SERIAL_WRITE(parser, ">", 1);
+}
+
+/**
+ * @brief 挿入処理を実行する。
+ *
+ * @param parser パーサー。
+ * @param action アクション。
+ * @param ch 入力文字。
+ */
+static void actfunc_insert(
+ vtparse_t *parser,
+ vtparse_action_t action,
+ unsigned char ch) {
+
+ /*
+ * 入力があった場合、入力補完状態から抜ける。
+ */
+ SUGGEST_INDEX(parser) = -1;
+
+ /*
+ * テキストエディタを使って文字を文字列に挿入する。
+ */
+ if (text_editor_insert(GET_EDITOR(parser), ch)) {
+ char txt[TEXTEDITOR_MAXLEN];
+ int len = text_editor_get_text(GET_EDITOR(parser), &txt[0], sizeof(txt));
+ int pos = text_editor_cursor_get_position(GET_EDITOR(parser));
+ SERIAL_WRITE(parser, (char *)&ch, sizeof(ch));
+ int n = len - pos;
+ if (n > 0) {
+ int i;
+ SERIAL_WRITE(parser, txt + pos, len - pos);
+ for (i = 0; i < n; i++) {
+ SERIAL_WRITE(parser, "\x1b[1D", 4);
+ }
+ }
+ }
+}
+
+/**
+ * @brief バックスペース処理を実行する。
+ *
+ * @param parser パーサー。
+ * @param action アクション。
+ * @param ch 入力文字。
+ */
+static void actfunc_backspace(
+ vtparse_t *parser,
+ vtparse_action_t action,
+ unsigned char ch) {
+ if (text_editor_backspace(GET_EDITOR(parser))) {
+ char txt[TEXTEDITOR_MAXLEN];
+ SERIAL_WRITE(parser, "\x1b[1D", 4);
+ int len = text_editor_get_text(GET_EDITOR(parser), &txt[0], sizeof(txt));
+ int pos = text_editor_cursor_get_position(GET_EDITOR(parser));
+ int n = len - pos;
+ if (n > 0) {
+ int i;
+ SERIAL_WRITE(parser, txt + pos, len - pos);
+ SERIAL_WRITE(parser, " ", 1);
+ for (i = 0; i < n + 1; i++) {
+ SERIAL_WRITE(parser, "\x1b[1D", 4);
+ }
+ } else {
+ SERIAL_WRITE(parser, " ", 1);
+ SERIAL_WRITE(parser, "\x1b[1D", 4);
+ }
+ }
+}
+
+/**
+ * @brief 入力補完処理を実行する。
+ *
+ * @param parser パーサー。
+ * @param action アクション。
+ * @param ch 入力文字。
+ */
+static void actfunc_suggest(
+ vtparse_t *parser,
+ vtparse_action_t action,
+ unsigned char ch) {
+ char buf[TEXTEDITOR_MAXLEN];
+ if (SUGGEST_INDEX(parser) < 0) {
+ /*
+ * 入力補完モードにこれから入る場合。
+ * 現在の入力文字列を元に補完候補を取得する。
+ */
+ if (text_editor_get_text(
+ GET_EDITOR(parser),
+ SUGGEST_SOURCE(parser),
+ sizeof(SUGGEST_SOURCE(parser))) > 0) {
+ SUGGEST_INDEX(parser) = 0;
+ if (text_history_find(
+ GET_HISTORY(parser),
+ SUGGEST_INDEX(parser),
+ SUGGEST_SOURCE(parser),
+ buf,
+ sizeof(buf)) == 0) {
+ // 候補が見つかればテキストを設定して、インデックスをメモする。
+ int n = ntlibc_strlen((const char *)buf);
+ SERIAL_WRITE(parser, "\x1b[2K", 4);
+ SERIAL_WRITE(parser, "\x1b[80D", 5);
+ SERIAL_WRITE(parser, ">", 1);
+ SERIAL_WRITE(parser, buf, n);
+ text_editor_set_text(GET_EDITOR(parser), buf);
+ } else {
+ // 候補がなければ入力補完モードから抜ける。
+ SUGGEST_INDEX(parser) = -1;
+ }
+ }
+ } else {
+ /*
+ * 既に入力補完モードに入っている場合、
+ * 次の候補を探して見つかればテキストとして設定する。
+ */
+ SUGGEST_INDEX(parser) = SUGGEST_INDEX(parser) + 1;
+ if (text_history_find(
+ GET_HISTORY(parser),
+ SUGGEST_INDEX(parser),
+ SUGGEST_SOURCE(parser),
+ buf,
+ sizeof(buf)) == 0) {
+ // 候補が見つかればテキストを設定する。
+ int n = ntlibc_strlen((const char *)buf);
+ SERIAL_WRITE(parser, "\x1b[2K", 4);
+ SERIAL_WRITE(parser, "\x1b[80D", 5);
+ SERIAL_WRITE(parser, ">", 1);
+ SERIAL_WRITE(parser, buf, n);
+ text_editor_set_text(GET_EDITOR(parser), buf);
+ } else {
+ // 候補が見つからなければ元の入力文字列に戻し、入力補完モードから抜ける。
+ int n = ntlibc_strlen(SUGGEST_SOURCE(parser));
+ SERIAL_WRITE(parser, "\x1b[2K", 4);
+ SERIAL_WRITE(parser, "\x1b[80D", 5);
+ SERIAL_WRITE(parser, ">", 1);
+ SERIAL_WRITE(parser, SUGGEST_SOURCE(parser), n);
+ text_editor_set_text(GET_EDITOR(parser), SUGGEST_SOURCE(parser));
+ SUGGEST_INDEX(parser) = -1;
+ }
+ }
+}
+
+static void actfunc_cursor_head(
+ vtparse_t *parser,
+ vtparse_action_t action,
+ unsigned char ch) {
+ SERIAL_WRITE(parser, "\x1b[80D", 5);
+ SERIAL_WRITE(parser, ">", 1);
+ text_editor_cursor_head(GET_EDITOR(parser));
+}
+
+static void actfunc_cursor_tail(
+ vtparse_t *parser,
+ vtparse_action_t action,
+ unsigned char ch) {
+ char buf[TEXTEDITOR_MAXLEN];
+ int len;
+ text_editor_get_text(GET_EDITOR(parser), buf, sizeof(buf));
+ len = ntlibc_strlen((const char *)buf);
+ SERIAL_WRITE(parser, "\x1b[80D", 5);
+ SERIAL_WRITE(parser, ">", 1);
+ SERIAL_WRITE(parser, buf, len);
+ text_editor_cursor_tail(GET_EDITOR(parser));
+}
+
+/**
+ * @brief アクションテーブルのデータ構造体。
+ * @details
+ * アクションは状態と入力文字によって与えられる。
+ * アクションに対する関数もここで定義する。
+ */
+typedef struct {
+ vtparse_action_t action;
+ unsigned char ch;
+ void (*func)(
+ vtparse_t *parser,
+ vtparse_action_t action,
+ unsigned char ch);
+} ntshell_action_table_t;
+
+/**
+ * @brief アクションに対する処理関数テーブル。
+ * @details
+ * やってくるコードは仮想端末側の処理に依存する。
+ * よって様々なプラットフォームの様々な仮想端末で試すと良い。
+ *
+ * <table>
+ * <th>
+ * <td>Platform</td>
+ * <td>Tools</td>
+ * </th>
+ * <tr>
+ * <td>Windows</td>
+ * <td>Hyper Terminal, Poderossa, TeraTerm</td>
+ * </tr>
+ * <tr>
+ * <td>Linux</td>
+ * <td>minicom, screen, kermit</td>
+ * </tr>
+ * </table>
+ */
+static const ntshell_action_table_t action_table[] = {
+ {VTPARSE_ACTION_EXECUTE, 0x01, actfunc_cursor_head},
+ {VTPARSE_ACTION_EXECUTE, 0x02, actfunc_cursor_left},
+ {VTPARSE_ACTION_EXECUTE, 0x03, actfunc_cancel},
+ {VTPARSE_ACTION_EXECUTE, 0x05, actfunc_cursor_tail},
+ {VTPARSE_ACTION_EXECUTE, 0x06, actfunc_cursor_right},
+ {VTPARSE_ACTION_EXECUTE, 0x08, actfunc_backspace},
+ {VTPARSE_ACTION_EXECUTE, 0x09, actfunc_suggest},
+ {VTPARSE_ACTION_EXECUTE, 0x0d, actfunc_enter},
+ {VTPARSE_ACTION_EXECUTE, 0x0e, actfunc_history_next},
+ {VTPARSE_ACTION_EXECUTE, 0x10, actfunc_history_prev},
+ {VTPARSE_ACTION_CSI_DISPATCH, 0x41, actfunc_history_prev},
+ {VTPARSE_ACTION_CSI_DISPATCH, 0x42, actfunc_history_next},
+ {VTPARSE_ACTION_CSI_DISPATCH, 0x43, actfunc_cursor_right},
+ {VTPARSE_ACTION_CSI_DISPATCH, 0x44, actfunc_cursor_left},
+ {VTPARSE_ACTION_PRINT, 0x7f, actfunc_backspace},
+};
+
+/**
+ * @brief パーサーに対するコールバック関数。
+ * @details vtparseモジュールのコールバック関数に従った実装である。
+ *
+ * @param parser パーサー。
+ * @param action アクション。
+ * @param ch キャラクタ。
+ */
+void parser_callback(
+ vtparse_t *parser,
+ vtparse_action_t action,
+ unsigned char ch) {
+ ntshell_action_table_t *p;
+ int i;
+ const int ACTTBLSIZ = sizeof(action_table) / sizeof(action_table[0]);
+
+ /*
+ * 制御コードに対する処理はテーブルから探す。
+ */
+ p = (ntshell_action_table_t *)action_table;
+ for (i = 0; i < ACTTBLSIZ; i++) {
+ if ((p->action == action) && (p->ch == ch)) {
+ p->func(parser, action, ch);
+ return;
+ }
+ p++;
+ }
+
+ /*
+ * 通常の文字列は入力として扱う。
+ */
+ if (VTPARSE_ACTION_PRINT == action) {
+ actfunc_insert(parser, action, ch);
+ }
+}
+
+/**
+ * @brief Natural Tiny Shellのバージョンを返す。
+ * @details 返すバージョンはリリースバージョンである。
+ *
+ * @param major メージャーバージョン。
+ * @param minor マイナーバージョン。
+ * @param release リリースバージョン。
+ */
+void ntshell_version(int *major, int *minor, int *release)
+{
+ *major = VERSION_MAJOR;
+ *minor = VERSION_MINOR;
+ *release = VERSION_RELEASE;
+}
+
+/**
+ * @brief Natural Tiny Shellを実行する。
+ * @details この関数は実行を返さない。
+ *
+ * @param parser VT100パーサー。
+ * @param editor テキストエディタ。
+ * @param history テキストヒストリ。
+ * @param func_read シリアルリード関数。
+ * @param func_write シリアルライト関数。
+ * @param func_cb コールバック関数。
+ */
+void ntshell_execute(
+ ntshell_t *p,
+ int (*func_read)(char *buf, int cnt),
+ int (*func_write)(const char *buf, int cnt),
+ int (*func_cb)(const char *text))
+{
+ /*
+ * vtparseはユーザデータへのポインタを設定できるようになっている。
+ * Natural Tiny Shellはこれを利用してテキストエディタやヒストリ、
+ * リード関数やライト関数、コールバック関数を処理の中で使用できる
+ * ようにしてある。
+ */
+ ntshell_user_data_t user_data;
+
+ user_data.editor = &(p->editor);
+ user_data.history = &(p->history);
+ user_data.func_read = func_read;
+ user_data.func_write = func_write;
+ user_data.func_cb = func_cb;
+
+ p->parser.user_data = &user_data;
+
+ /*
+ * 各モジュールを初期化する。
+ */
+ vtparse_init(&(p->parser), parser_callback);
+ text_editor_init(GET_EDITOR(&(p->parser)));
+ text_history_init(GET_HISTORY(&(p->parser)));
+ SUGGEST_INDEX(&(p->parser)) = -1;
+
+ /*
+ * ユーザ入力ループ。
+ */
+ SERIAL_WRITE(&(p->parser), ">", 1);
+ while(1)
+ {
+ unsigned char ch;
+ SERIAL_READ(&(p->parser), (char *)&ch, sizeof(ch));
+ vtparse(&(p->parser), &ch, sizeof(ch));
+ }
+}
+
--- /dev/null
+/**
+ * @file ntshell.h
+ * @author Shinichiro Nakamura
+ * @brief 小規模組み込みシステム向けのシェルシステムの定義。
+ */
+
+/*
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell)
+ * Version 0.0.7
+ * ===============================================================
+ * Copyright (c) 2010-2011 Shinichiro Nakamura
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ * ===============================================================
+ */
+
+#ifndef _NTSHELL_H_
+#define _NTSHELL_H_
+
+#include "vtparse.h"
+#include "text_editor.h"
+#include "text_history.h"
+
+typedef struct {
+ vtparse_t parser;
+ text_editor_t editor;
+ text_history_t history;
+} ntshell_t;
+
+void ntshell_version(int *major, int *minor, int *release);
+void ntshell_execute(
+ ntshell_t *p,
+ int (*func_read)(char *buf, int cnt),
+ int (*func_write)(const char *buf, int cnt),
+ int (*func_cb)(const char *text));
+
+#endif
+
--- /dev/null
+===============================================================
+ Natural Tiny Shell - A tiny shell for a small embedded system
+ Copyright(C) 2011 Shinichiro Nakamura
+===============================================================
+
+ Natural Tiny Shell (NT-Shell) is a tiny shell for a small
+ embedded system.
+
+1. Special thanks
+
+ Mr.Paul Williams
+ - He created a draw of DEC compatible state machine parser.
+
+ Mr.Joshua Haberman
+ - He implemented the state machine parser with C language.
+ And it has great interface. It's really simple and smart!
+
+2. The background
+
+ Today, There are so many great MPUs.
+ And the developper can design a small embedded system with it.
+ It's really great things and I never imagine 20 years ago.
+
+ There is a way to debug a embedded system using UART interface.
+ It is same as UNIX terminal interfaces.
+
+ The developper can be control a embedded system with it.
+
+3. The basic concepts
+
+ * Small :)
+ * Simple :)
+ * Compatible with VT100 :)
+ * No need any C runtime library :)
+
+4. Features
+
+ CTRL+A : Head
+ CTRL+E : Tail
+ CTRL+F : Cursor right
+ CTRL+B : Cursor left
+ CTRL+C : Cancel
+ CTRL+P : History(Prev)
+ CTRL+N : History(Next)
+ TAB : Suggestion
+
+5. The structure
+
+ NT-Shell are consists from 5 modules.
+
+ * Top interface module
+ ntshell.c
+ ntshell.h
+ * Utility
+ ntopt.c
+ ntopt.h
+ ntlibc.c
+ ntlibc.h
+ * VT100 parser
+ vtparse.c
+ vtparse.h
+ vtparse_table.c
+ vtparse_table.h
+ * Text editor
+ text_editor.c
+ text_editor.h
+ * Text history
+ text_history.c
+ text_history.h
+
+6. Porting guide
+
+ The NT-Shell interface is really simple.
+ It need 2 I/O interfaces for UART and a callback interface
+ for getting a user request.
+
+ void ntshell(
+ int (*func_read)(char *buf, int cnt),
+ int (*func_write)(const char *buf, int cnt),
+ int (*func_cb)(const char *text));
+
+ 6-1. func_read
+
+ func_read is a interface for reading user key inputs.
+ It's blocking interface.
+
+ 6-2. func_write
+
+ func_write is a interface for writing shell outputs.
+ It's blocking interface.
+
+ 6-3. func_cb
+
+ func_cb is a callback interface for user request to your system.
+
+7. The license
+
+ * vtparse and vtparse_table are in the public domain.
+ * ntshell, ntopt, ntlibc, text_editor, text_history are in the MIT license.
+
+ ===============================================================
+ The MIT license for Natural Tiny Shell (NT-Shell)
+ ===============================================================
+ Copyright (c) 2010-2011 Shinichiro Nakamura
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or
+ sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ===============================================================
+
+ So you can use this software in non-commercial or commercial products.
+ But there aren't any warranty.
+
+ Please do NOT remove copyright texts, if you redistribute this package.
+
+8. References
+
+ * A parser for DEC's ANSI-compatible video terminal
+ http://vt100.net/emu/dec_ansi_parser
+
+9. Version
+
+ * 2011/03/01 Version 0.0.1 Initial version.
+ * 2011/03/02 Version 0.0.2 Added a utility module.
+ * 2011/03/04 Version 0.0.3 Buf fixed.
+ * 2011/04/30 Version 0.0.4 Changed an implementation of the vtparse table.
+ Added ntopt.
+ Added ntlibc.
+ * 2011/05/16 Version 0.0.5 Added input suggestion features.
+ Changed the interface of the ntshell.
+ * 2011/05/22 Version 0.0.6 Added cursor head and tail feautures.
+ * 2011/09/22 Version 0.0.7 Updated ntopt interface.
--- /dev/null
+===============================================================
+ Natural Tiny Shell - A tiny shell for a small embedded system
+ Copyright(C) 2011 Shinichiro Nakamura
+===============================================================
+
+ Natural Tiny Shell (NT-Shell) は小規模組み込みシステム用の
+ 小さなシェルです。
+
+1. 謝辞
+
+ Paul Williamsさん
+ - 彼はDEC互換のステートマシンパーサの図を作りました。
+
+ Joshua Habermanさん
+ - 彼はステートマシンパーサの実装をC言語で行ないました。
+ それは素晴らしいインターフェースを持ち、シンプルで賢いです。
+
+2. 背景
+
+ 今日、沢山の優れたMPUが手に入ります。
+ 我々はそれらを使って小規模組み込みシステムを設計することができます。
+ それは素晴らしいことで、20年前には考えられなかったことです。
+
+ システムを設計実装している時点で有効なデバッグ手段の1つにUARTを
+ インターフェースとして端末のようなものを実現する手段があります。
+ これは我々がUNIX端末上でシステムに対して要求を出すような形式で
+ MPUを使ったシステムに対して要求を出すことができます。
+
+ 対話形式でシステムの状態を観察したり、状態を変化させるためのパラメータを
+ 入力することができますので、スムーズに作業することができるのが特徴です。
+
+ しかしながら、世の中に存在する沢山の小規模組み込みシステムの端末の実装は
+ あまり良いものがないのが現状でした。
+ 一部の制御コードのみに対応した結果、様々なキー入力によって表示や入力文字列
+ が破綻してしまうものなどが大多数です。
+
+ 今回はこれらの状況を打開すべくVT100をエミュレートした小さなシェルを
+ 実装してみました。
+ このシェルを組み込み機器に搭載すれば、キー入力に慎重になる必要がなく、
+ スムーズにデバッグを行うことができます。
+
+ このシェルには履歴機能もあります。
+ 過去に入力したコマンドを選択して編集した後で実行することもできます。
+
+3. 基本コンセプト
+
+ * 小さい :)
+ * シンプル :)
+ * VT100互換 :)
+ * Cランタイムライブラリが不要 :)
+
+4. 機能
+
+ CTRL+A : Head
+ CTRL+E : Tail
+ CTRL+F : Cursor right
+ CTRL+B : Cursor left
+ CTRL+C : Cancel
+ CTRL+P : History(Prev)
+ CTRL+N : History(Next)
+ TAB : Suggestion
+
+5. 構造
+
+ NT-Shellは5つの部品から構成されています。
+
+ * 最上位インターフェースモジュール
+ ntshell.c
+ ntshell.h
+ * ユティリティ
+ ntopt.c
+ ntopt.h
+ * VT100パーサ
+ vtparse.c
+ vtparse.h
+ vtparse_table.c
+ vtparse_table.h
+ * テキストエディタ
+ text_editor.c
+ text_editor.h
+ * テキストヒストリ
+ text_history.c
+ text_history.h
+
+6. ポーティングガイド
+
+ NT-Shellのインターフェースは非常にシンプルです。
+ UARTのための2つの入出力インターフェースとユーザ要求を取得するための
+ 1つのコールバックインターフェースを必要とします。
+
+ void ntshell(
+ int (*func_read)(char *buf, int cnt),
+ int (*func_write)(const char *buf, int cnt),
+ int (*func_cb)(const char *text));
+
+ 6-1. func_read
+
+ func_readはユーザキー入力を読むためのインターフェースです。
+ キーを読み込むまでブロックするインターフェースとして実装されている
+ 必要があります。
+
+ 6-2. func_write
+
+ func_writeはシェル出力を書くためのインターフェースです。
+ 書き込みが終了するまでブロックするインターフェースとして実装されている
+ 必要があります。
+
+ 6-3. func_cb
+
+ func_cbはシステムに対するユーザ要求文字列を取得するための
+ インターフェースです。
+
+7. ライセンス
+
+ * vtparse and vtparse_tableはパブリックドメインとして提供されています。
+ * ntshell, ntopt, ntlibc, text_editor, text_historyはMITライセンスです。
+
+ ===============================================================
+ The MIT license for Natural Tiny Shell (NT-Shell)
+ ===============================================================
+ Copyright (c) 2010-2011 Shinichiro Nakamura
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or
+ sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ===============================================================
+
+ よってNatural Tiny Shell (NT-Shell)は非商用、商用を問わず製品に使用する
+ ことができます。
+ しかしながら、無保証です。
+
+ 再配布する場合に、著作権文字列を取り除かないで下さい。
+
+8. 参考文献
+
+ * A parser for DEC’s ANSI-compatible video terminal
+ http://vt100.net/emu/dec_ansi_parser
+
+9. バージョン
+
+ * 2011/03/01 Version 0.0.1 初版。
+ * 2011/03/02 Version 0.0.2 ユティリティモジュールを追加。
+ * 2011/03/04 Version 0.0.3 バグ修正。
+ * 2011/04/30 Version 0.0.4 vtparseのテーブルがROMに配置されるようにした。
+ ntoptの欠落を修正した。
+ ntlibcを追加した。
+ * 2011/05/16 Version 0.0.5 入力補完機能を追加した。
+ ntshellのインターフェースを変更した。
+ * 2011/05/22 Version 0.0.6 カーソルの先頭ジャンプ機能を追加した。
+ * 2011/09/22 Version 0.0.7 ntoptインターフェースを更新した。
--- /dev/null
+source [find ./jtagkey2p.cfg]
+source [find ./lpc1768.cfg]
--- /dev/null
+#!/bin/sh
+
+#
+# gdb経由でプログラムをロードする。
+#
+
+arm-none-eabi-gdb TOPPERS-ASP_BlackTank-LPC1769.axf -x gdbcmd-progload.txt
+
--- /dev/null
+#!/usr/bin/expect
+
+#
+# telnet経由でプログラムをライトする。
+# こういうのはexpectを使えば良い。
+#
+
+set timeout 600
+spawn telnet localhost 4444
+
+expect ">"
+send "halt\n"
+
+expect ">"
+send "flash probe 0\n"
+
+expect ">"
+send "flash write_image erase TOPPERS-ASP_BlackTank-LPC1769.bin\n"
+
+expect ">"
+send "exit\n"
+
+sleep 2
+
+spawn telnet localhost 4444
+
+sleep 2
+
+expect ">"
+send "reset\n"
+
+expect ">"
+send "exit\n"
--- /dev/null
+/**
+ * @file sys_init.c
+ * @author Shinichiro Nakamura
+ * @brief システムで優先的に初期化したい処理の実装。
+ */
+
+#include <LPC17xx.h>
+#include <kernel.h>
+#include <t_syslog.h>
+
+#include "kernel_cfg.h"
+#include "sys_init.h"
+
+/**
+ * @brief 初期化ルーチン
+ * @param exinf コンフィギュレータから渡す引数。今回は利用しない
+ * @details
+ * システムで早期に初期化が必要なものに関してここに記述する。
+ * この関数はapplication.cfgの中で、ATT_INIによりシステムに
+ * 初期化関数として登録される。
+ */
+void sys_init(intptr_t exinf)
+{
+}
+
--- /dev/null
+/**
+ * @file sys_init.h
+ * @author Shinichiro Nakamura
+ * @brief システムで優先的に初期化したい処理の定義。
+ */
+
+#ifndef _SYS_INIT_H_
+#define _SYS_INIT_H_
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+void sys_init(intptr_t exinf);
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#endif /* _SYS_INIT_H_ */
+
--- /dev/null
+/**
+ * @file task_audio.c
+ * @brief オーディオDMAに同期して動くタスク
+ * @details
+ * @ref dma_intr_handler からのSEM_I2SDMA セマフォ・シグナルを受けて
+ * しかるべきデータ・バッファを特定し、信号処理を行う。
+ *
+ * なお、このタスクはシステム起動時にはインアクティブである。
+ * 明示的にアクティベートして始めて動作を開始する。
+ *
+ * 内蔵I2SペリフェラルとDMAを使って外部のオーディオ・コーデック
+ * からデータを取り込み、内部でコピーして再度オーディオ・コーデックに
+ * 出力する。内部コピーは \ref process_audio 関数で行っており
+ * 内部を書き換えることでどのようなアルゴリズムでも実装できる。
+ *
+ * audio_taskはDMA割り込みハンドラ \ref dma_intr_handler からの
+ * シグナルに同期して動作し、ピンポンバッファを使ってDMAと
+ * ソフトウェア処理の並列化を図っている。
+ *
+ * このプログラムが使用しているコーデックはTI社のTLV320AIC23Bである。
+ * 初期化データ列は \ref codec_init ルーチンから送出している。
+ *
+ * なお、LPC1768のDMAは、何らかのDMA管理機構を使ってチャンネル割り当てを
+ * すべきだが、このプログラムではその操作を省いている。
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+#include <LPC17xx.h>
+#include "kernel_cfg.h"
+#include "audio_common.h"
+#include "audio_effect.h"
+#include "i2s_subsystem.h"
+#include "i2c_subsystem.h"
+#include "codec_subsystem.h"
+#include "testpin.h"
+#include "task_audio.h"
+#include "task_display.h"
+
+#define MSG_TARGET(n) (((n) & 0xF000) >> 12)
+#define MSG_VALUE(n) (((n) & 0x0FFF) >> 0)
+
+/**
+ * \param file ソースコードのファイル名
+ * \param line ソースコードの行番号
+ * \param expr サービスコールのテキスト表現
+ * \param ercd サービスコールの結果(エラー値)
+ * \brief サービスコールのエラーのログ出力を行う補助関数
+ * \details
+ * TOPPERS/ASPのサービスコールのエラー出力を行うためのサポート関数。
+ * \ref SVC_PERROR マクロの中から使う。
+ */
+Inline void
+svc_perror(const char *file, int_t line, const char *expr, ER ercd)
+{
+ if (ercd < 0) {
+ t_perror(LOG_ERROR, file, line, expr, ercd);
+ }
+}
+
+/**
+ * \brief サービスコールのエラー出力マクロ
+ * \param expr サービスコールの式
+ * \details
+ * exprとして与えたサービスコールのソースコード上の表現と
+ * その実行結果を印字する。
+ * サービスコールに限らず値を持つ式ならなんでもよい。
+ */
+#define SVC_PERROR(expr) svc_perror(__FILE__, __LINE__, #expr, (expr))
+
+/**
+ * \brief DMAハンドラ
+ * \details
+ * このハンドラは全DMAに対して共通に呼ばれる.
+ *
+ * 呼ばれると、DMAのバッファ終了割り込みステータスを確認する。
+ * それがI2S DMAバッファの終了割り込みなら、割り込みをクリアして
+ * タスクに通知する。
+ * \todo
+ * DMAチャンネルの番号は決め打ちである。
+ * 適切なDMA管理機構を使った方式への変更が必要である。
+ */
+void dma_intr_handler(intptr_t exinf)
+{
+ i2s_dma_intr_handler();
+}
+
+/**
+ * \brief I2S用データ
+ * \details
+ * DMAのLLIやバッファなどはすべてこの変数にパッケージしている。
+ * こうすることで、グローバル空間に名前が散らかることを阻止できる。
+ */
+struct I2S_AUDIO_DATA audio_data;
+
+struct I2S_AUDIO_DATA* get_audio_data(void)
+{
+ return &audio_data;
+}
+
+void task_audio(intptr_t exinf)
+{
+ AUDIOSAMPLE *txbuf;
+ const AUDIOSAMPLE *rxbuf;
+ int index;
+ AUDIOSAMPLE lm_left, lm_right;
+ uint16_t msg;
+ effect_param_t effect_param;
+ void (*effect_func)(
+ const effect_param_t *param,
+ const AUDIOSAMPLE *in_left,
+ const AUDIOSAMPLE *in_right,
+ AUDIOSAMPLE *out_left,
+ AUDIOSAMPLE *out_right);
+
+ /*
+ * オーディオコーデックを初期化する。
+ */
+ i2c_init();
+ codec_init();
+
+ /*
+ * ペリフェラルを初期化する。
+ */
+ i2s_init();
+ i2s_dma_init(get_audio_data());
+
+ /*
+ * @todo
+ * i2s_start()を呼ぶとDMA割り込みの無限ループに陥る。
+ * 現象が発生するのはコールドスタートの時だけ。要調査。
+ */
+ i2s_start();
+
+ /*
+ * リアルタイム・ステータス用のテストピンを出力にする。
+ */
+ testpin_init();
+
+ effect_func = audio_effect_through;
+
+ while(1)
+ {
+ // 外部タスクからパラメータを取得する。
+ if (prcv_dtq(DTQ_AUDIOPARAM, (intptr_t *)&msg) == E_OK) {
+ switch (MSG_TARGET(msg)) {
+ case AUDIO_PARAM_MODE:
+ switch (MSG_VALUE(msg)) {
+ case AUDIO_VALUE_MODE_THROUGH:
+ effect_func = audio_effect_through;
+ break;
+ case AUDIO_VALUE_MODE_VOCAL_CANCEL:
+ effect_func = audio_effect_vocal_cancel;
+ break;
+ case AUDIO_VALUE_MODE_FIR:
+ effect_func = audio_effect_fir;
+ break;
+ case AUDIO_VALUE_MODE_IIR:
+ effect_func = audio_effect_iir;
+ break;
+ default:
+ syslog(LOG_NOTICE,
+ "Unknown effect mode %d.",
+ MSG_VALUE(msg));
+ break;
+ }
+ break;
+ case AUDIO_PARAM_VAR0:
+ effect_param.var0 = MSG_VALUE(msg);
+ break;
+ case AUDIO_PARAM_VAR1:
+ effect_param.var1 = MSG_VALUE(msg);
+ break;
+ case AUDIO_PARAM_VAR2:
+ effect_param.var2 = MSG_VALUE(msg);
+ break;
+ case AUDIO_PARAM_VAR3:
+ effect_param.var3 = MSG_VALUE(msg);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // DMAバッファ転送の終了を待つ。
+ wai_sem(SEM_I2SDMA);
+
+ // プログラムが使用してもよいバッファのアドレスを取得する。
+ txbuf = i2s_getTxBuf();
+ rxbuf = i2s_getRxBuf();
+
+ // 同期状態を示すためのテストピン信号を作成する。
+ testpin_tp1_write(1);
+
+ lm_left = 0;
+ lm_right = 0;
+ for (index = 0; index < AUDIOBUFSIZE; index+=2) {
+ effect_func(
+ &effect_param,
+ rxbuf + (index + 0), rxbuf + (index + 1),
+ txbuf + (index + 0), txbuf + (index + 1));
+ lm_left = (lm_left >> 1) + (*(txbuf + (index + 0)) >> 1);
+ lm_right = (lm_right >> 1) + (*(txbuf + (index + 1)) >> 1);
+ }
+
+ // 同期状態を示すためのテストピン信号を作成する
+ testpin_tp1_write(0);
+ }
+}
+
--- /dev/null
+/**
+ * @file task_audio.h
+ * @brief オーディオDMAに同期して動くタスク
+ * @param exinf コンフィギュレータがタスクに引き渡す変数。
+ * @details
+ * @ref dma_intr_handler からのSEM_I2SDMA セマフォ・シグナルを受けて
+ * しかるべきデータ・バッファを特定し、信号処理を行う。
+ *
+ * なお、このタスクはシステム起動時にはインアクティブである。
+ * 明示的にアクティベートして始めて動作を開始する。
+ */
+
+#ifndef TASK_AUDIO_H
+#define TASK_AUDIO_H
+
+#include "i2s_subsystem.h"
+
+/**
+ * @brief タスクプライオリティ。(オーディオタスク)
+ */
+#define TSKPRI_AUDIO 10
+#define TSKSTK_AUDIO STACK_SIZE
+
+/**
+ * @defgroup BLACKTANK_LPC1769_TASK_AUDIO_CLIENT
+ * @ingroup BLACKTANK_LPC1769_TASK_AUDIO
+ * @{
+ */
+
+#define AUDIO_PARAM_MODE 0 /**< @brief モードパラメータ。 */
+#define AUDIO_PARAM_VAR0 1 /**< @brief VAR0パラメータ。 */
+#define AUDIO_PARAM_VAR1 2 /**< @brief VAR1パラメータ。 */
+#define AUDIO_PARAM_VAR2 3 /**< @brief VAR2パラメータ。 */
+#define AUDIO_PARAM_VAR3 4 /**< @brief VAR3パラメータ。 */
+
+#define AUDIO_VALUE_MODE_THROUGH 0 /**< @brief モードに対する値。 */
+#define AUDIO_VALUE_MODE_VOCAL_CANCEL 1 /**< @brief モードに対する値。 */
+#define AUDIO_VALUE_MODE_FIR 2 /**< @brief モードに対する値。 */
+#define AUDIO_VALUE_MODE_IIR 3 /**< @brief モードに対する値。 */
+
+/**
+ * @brief オーディオパラメータを設定する。
+ * @details
+ * このマクロを使うとオーディオパラメータを設定することができる。
+ * マクロはタスクコンテキスト内から呼び出す事ができる。
+ * @param PARAM 設定対象パラメータ。
+ * @param VALUE 設定対象パラメータに対する設定値。
+ */
+#define TSKAPI_AUDIO_PARAM(PARAM,VALUE) \
+ snd_dtq(DTQ_AUDIOPARAM, \
+ (intptr_t)( \
+ (((PARAM) & 0x000F) << 12) \
+ | (((VALUE)& 0x0FFF) << 0)))
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup BLACKTANK_LPC1769_TASK_AUDIO
+ * @ingroup BLACKTANK_LPC1769_TASK
+ * @{
+ */
+
+void task_audio(intptr_t exinf);
+void dma_intr_handler(intptr_t exinf);
+struct I2S_AUDIO_DATA* get_audio_data(void);
+
+/**
+ * @}
+ */
+
+#endif
+
--- /dev/null
+/**
+ * @file task_display.c
+ * @author Shinichiro Nakamura
+ * @brief ディスプレイタスクの実装(task_display)
+ * @details
+ * ディスプレイタスクは有機ELディスプレイを制御するタスクである。
+ * ディスプレイの制御は以下のマクロを使って行うことができる。
+ *
+ * DISP_CLEAR(r, g, b);
+ * DISP_LINE(x1, y1, x2, y2, r, g, b);
+ * DISP_BOX(x1, y1, x2, y2, r, g, b);
+ * DISP_FILLBOX(x1, y1, x2, y2, r1, g1, b1, r2, g2, b2);
+ * DISP_TEXT(x, y, r, g, b, "text");
+ * DISP_BMPFILE("filename");
+ */
+
+#include <LPC17xx.h>
+#include <kernel.h>
+#include <t_syslog.h>
+#include <itron.h>
+
+#include "kernel_cfg.h"
+#include "task_display.h"
+#include "oled.h"
+#include "ff.h"
+#include "bmplowio.h"
+
+static const uint8_t FONT_X = 5;
+static const uint8_t FONT_Y = 7;
+static const uint16_t FONT_MIN_CODE = 0x20;
+static const uint16_t FONT_MAX_CODE = 0x7F;
+static const uint8_t font5x7_data[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, // (white space)
+ 0x00, 0x00, 0x5F, 0x00, 0x00, // !
+ 0x00, 0x07, 0x00, 0x07, 0x00, // "
+ 0x14, 0x7F, 0x14, 0x7F, 0x14, // #
+ 0x24, 0x2A, 0x7F, 0x2A, 0x12, // $
+ 0x23, 0x13, 0x08, 0x64, 0x62, // %
+ 0x36, 0x49, 0x55, 0x22, 0x50, // &
+ 0x00, 0x05, 0x03, 0x00, 0x00, // '
+ 0x00, 0x1C, 0x22, 0x41, 0x00, // (
+ 0x00, 0x41, 0x22, 0x1C, 0x00, // )
+ 0x08, 0x2A, 0x1C, 0x2A, 0x08, // *
+ 0x08, 0x08, 0x3E, 0x08, 0x08, // +
+ 0x00, 0x50, 0x30, 0x00, 0x00, // ,
+ 0x08, 0x08, 0x08, 0x08, 0x08, // -
+ 0x00, 0x60, 0x60, 0x00, 0x00, // .
+ 0x20, 0x10, 0x08, 0x04, 0x02, // /
+ 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
+ 0x00, 0x42, 0x7F, 0x40, 0x00, // 1
+ 0x42, 0x61, 0x51, 0x49, 0x46, // 2
+ 0x21, 0x41, 0x45, 0x4B, 0x31, // 3
+ 0x18, 0x14, 0x12, 0x7F, 0x10, // 4
+ 0x27, 0x45, 0x45, 0x45, 0x39, // 5
+ 0x3C, 0x4A, 0x49, 0x49, 0x30, // 6
+ 0x01, 0x71, 0x09, 0x05, 0x03, // 7
+ 0x36, 0x49, 0x49, 0x49, 0x36, // 8
+ 0x06, 0x49, 0x49, 0x29, 0x1E, // 9
+ 0x00, 0x36, 0x36, 0x00, 0x00, // :
+ 0x00, 0x56, 0x36, 0x00, 0x00, // ;
+ 0x00, 0x08, 0x14, 0x22, 0x41, // <
+ 0x14, 0x14, 0x14, 0x14, 0x14, // =
+ 0x41, 0x22, 0x14, 0x08, 0x00, // >
+ 0x02, 0x01, 0x51, 0x09, 0x06, // ?
+ 0x32, 0x49, 0x79, 0x41, 0x3E, // @
+ 0x7E, 0x11, 0x11, 0x11, 0x7E, // A
+ 0x7F, 0x49, 0x49, 0x49, 0x36, // B
+ 0x3E, 0x41, 0x41, 0x41, 0x22, // C
+ 0x7F, 0x41, 0x41, 0x22, 0x1C, // D
+ 0x7F, 0x49, 0x49, 0x49, 0x41, // E
+ 0x7F, 0x09, 0x09, 0x01, 0x01, // F
+ 0x3E, 0x41, 0x41, 0x51, 0x32, // G
+ 0x7F, 0x08, 0x08, 0x08, 0x7F, // H
+ 0x00, 0x41, 0x7F, 0x41, 0x00, // I
+ 0x20, 0x40, 0x41, 0x3F, 0x01, // J
+ 0x7F, 0x08, 0x14, 0x22, 0x41, // K
+ 0x7F, 0x40, 0x40, 0x40, 0x40, // L
+ 0x7F, 0x02, 0x04, 0x02, 0x7F, // M
+ 0x7F, 0x04, 0x08, 0x10, 0x7F, // N
+ 0x3E, 0x41, 0x41, 0x41, 0x3E, // O
+ 0x7F, 0x09, 0x09, 0x09, 0x06, // P
+ 0x3E, 0x41, 0x51, 0x21, 0x5E, // Q
+ 0x7F, 0x09, 0x19, 0x29, 0x46, // R
+ 0x46, 0x49, 0x49, 0x49, 0x31, // S
+ 0x01, 0x01, 0x7F, 0x01, 0x01, // T
+ 0x3F, 0x40, 0x40, 0x40, 0x3F, // U
+ 0x1F, 0x20, 0x40, 0x20, 0x1F, // V
+ 0x7F, 0x20, 0x18, 0x20, 0x7F, // W
+ 0x63, 0x14, 0x08, 0x14, 0x63, // X
+ 0x03, 0x04, 0x78, 0x04, 0x03, // Y
+ 0x61, 0x51, 0x49, 0x45, 0x43, // Z
+ 0x00, 0x00, 0x7F, 0x41, 0x41, // [
+ 0x02, 0x04, 0x08, 0x10, 0x20, // /
+ 0x41, 0x41, 0x7F, 0x00, 0x00, // ]
+ 0x04, 0x02, 0x01, 0x02, 0x04, // ^
+ 0x40, 0x40, 0x40, 0x40, 0x40, // _
+ 0x00, 0x01, 0x02, 0x04, 0x00, // `
+ 0x20, 0x54, 0x54, 0x54, 0x78, // a
+ 0x7F, 0x48, 0x44, 0x44, 0x38, // b
+ 0x38, 0x44, 0x44, 0x44, 0x20, // c
+ 0x38, 0x44, 0x44, 0x48, 0x7F, // d
+ 0x38, 0x54, 0x54, 0x54, 0x18, // e
+ 0x08, 0x7E, 0x09, 0x01, 0x02, // f
+ 0x08, 0x14, 0x54, 0x54, 0x3C, // g
+ 0x7F, 0x08, 0x04, 0x04, 0x78, // h
+ 0x00, 0x44, 0x7D, 0x40, 0x00, // i
+ 0x20, 0x40, 0x44, 0x3D, 0x00, // j
+ 0x00, 0x7F, 0x10, 0x28, 0x44, // k
+ 0x00, 0x41, 0x7F, 0x40, 0x00, // l
+ 0x7C, 0x04, 0x18, 0x04, 0x78, // m
+ 0x7C, 0x08, 0x04, 0x04, 0x78, // n
+ 0x38, 0x44, 0x44, 0x44, 0x38, // o
+ 0x7C, 0x14, 0x14, 0x14, 0x08, // p
+ 0x08, 0x14, 0x14, 0x18, 0x7C, // q
+ 0x7C, 0x08, 0x04, 0x04, 0x08, // r
+ 0x48, 0x54, 0x54, 0x54, 0x20, // s
+ 0x04, 0x3F, 0x44, 0x40, 0x20, // t
+ 0x3C, 0x40, 0x40, 0x20, 0x7C, // u
+ 0x1C, 0x20, 0x40, 0x20, 0x1C, // v
+ 0x3C, 0x40, 0x30, 0x40, 0x3C, // w
+ 0x44, 0x28, 0x10, 0x28, 0x44, // x
+ 0x0C, 0x50, 0x50, 0x50, 0x3C, // y
+ 0x44, 0x64, 0x54, 0x4C, 0x44, // z
+ 0x00, 0x08, 0x36, 0x41, 0x00, // {
+ 0x00, 0x00, 0x7F, 0x00, 0x00, // |
+ 0x00, 0x41, 0x36, 0x08, 0x00, // }
+ 0x08, 0x08, 0x2A, 0x1C, 0x08, // ->
+ 0x08, 0x1C, 0x2A, 0x08, 0x08 // <-
+};
+
+typedef struct {
+ FATFS fatfs[_VOLUMES];
+ DIR dir;
+ FIL fil;
+ FILINFO filinfo;
+} work_t;
+
+work_t work;
+
+void disp_clear(const uint8_t r, const uint8_t g, const uint8_t b)
+{
+ VP vp;
+ get_mpf(MPF_DISPLAY, &vp);
+ ((display_msg_t*)vp)->cmd = DISPLAY_CMD_CLEAR;
+ display_clear_t *param =
+ (display_clear_t *)&(((display_msg_t*)vp)->param);
+ param->r = r;
+ param->g = g;
+ param->b = b;
+ snd_mbx(MBX_DISPLAY, vp);
+}
+
+void disp_line(
+ const uint8_t x1,
+ const uint8_t y1,
+ const uint8_t x2,
+ const uint8_t y2,
+ const uint8_t r,
+ const uint8_t g,
+ const uint8_t b)
+{
+ VP vp;
+ get_mpf(MPF_DISPLAY, &vp);
+ ((display_msg_t*)vp)->cmd = DISPLAY_CMD_LINE;
+ display_line_t *param =
+ (display_line_t *)&(((display_msg_t*)vp)->param);
+ param->x1 = x1;
+ param->y1 = y1;
+ param->x2 = x2;
+ param->y2 = y2;
+ param->r = r;
+ param->g = g;
+ param->b = b;
+ snd_mbx(MBX_DISPLAY, vp);
+}
+
+void disp_box(
+ const uint8_t x1,
+ const uint8_t y1,
+ const uint8_t x2,
+ const uint8_t y2,
+ const uint8_t r,
+ const uint8_t g,
+ const uint8_t b)
+{
+ VP vp;
+ get_mpf(MPF_DISPLAY, &vp);
+ ((display_msg_t*)vp)->cmd = DISPLAY_CMD_BOX;
+ display_box_t *param =
+ (display_box_t *)&(((display_msg_t*)vp)->param);
+ param->x1 = x1;
+ param->y1 = y1;
+ param->x2 = x2;
+ param->y2 = y2;
+ param->r = r;
+ param->g = g;
+ param->b = b;
+ snd_mbx(MBX_DISPLAY, vp);
+}
+
+void disp_fillbox(
+ const uint8_t x1,
+ const uint8_t y1,
+ const uint8_t x2,
+ const uint8_t y2,
+ const uint8_t r1,
+ const uint8_t g1,
+ const uint8_t b1,
+ const uint8_t r2,
+ const uint8_t g2,
+ const uint8_t b2)
+{
+ VP vp;
+ get_mpf(MPF_DISPLAY, &vp);
+ ((display_msg_t*)vp)->cmd = DISPLAY_CMD_FILLBOX;
+ display_fillbox_t *param =
+ (display_fillbox_t *)&(((display_msg_t*)vp)->param);
+ param->x1 = x1;
+ param->y1 = y1;
+ param->x2 = x2;
+ param->y2 = y2;
+ param->r1 = r1;
+ param->g1 = g1;
+ param->b1 = b1;
+ param->r2 = r2;
+ param->g2 = g2;
+ param->b2 = b2;
+ snd_mbx(MBX_DISPLAY, vp);
+}
+
+void disp_text(
+ const uint8_t x,
+ const uint8_t y,
+ const uint8_t r,
+ const uint8_t g,
+ const uint8_t b,
+ const char *text)
+{
+ int i;
+ const char *strp;
+ VP vp;
+ get_mpf(MPF_DISPLAY, &vp);
+ ((display_msg_t*)vp)->cmd = DISPLAY_CMD_TEXT;
+ display_text_t *param =
+ (display_text_t *)&(((display_msg_t*)vp)->param);
+ param->x = x;
+ param->y = y;
+ param->r = r;
+ param->g = g;
+ param->b = b;
+ strp = text;
+ i = 0;
+ while (*strp) {
+ param->text[i] = *strp;
+ i++;
+ strp++;
+ }
+ param->text[i] = '\0';
+ snd_mbx(MBX_DISPLAY, vp);
+}
+
+void disp_bmpfile(const char *filename)
+{
+ int i;
+ char *strp;
+ VP vp;
+ get_mpf(MPF_DISPLAY, &vp);
+ ((display_msg_t*)vp)->cmd = DISPLAY_CMD_BMPFILE;
+ display_bmpfile_t *param =
+ (display_bmpfile_t *)&(((display_msg_t*)vp)->param);
+ strp = (char *)filename;
+ i = 0;
+ while (*strp) {
+ param->filename[i++] = *strp;
+ strp++;
+ }
+ param->filename[i++] = '\0';
+ snd_mbx(MBX_DISPLAY, vp);
+}
+
+void disp_audio_levelmeter(const int left, const int right)
+{
+ VP vp;
+ get_mpf(MPF_DISPLAY, &vp);
+ ((display_msg_t*)vp)->cmd = DISPLAY_CMD_AUDIO_LEVELMETER;
+ display_audio_levelmeter_t *param =
+ (display_audio_levelmeter_t *)&(((display_msg_t*)vp)->param);
+ param->left = left;
+ param->right = right;
+ snd_mbx(MBX_DISPLAY, vp);
+}
+
+void cmd_clear(display_clear_t *p)
+{
+ Color c;
+ c.r = p->r;
+ c.g = p->g;
+ c.b = p->b;
+
+ oled_fill_box(0, 0, OLED_X - 1, OLED_Y - 1, c, c);
+}
+
+void cmd_line(display_line_t *p)
+{
+ Color c;
+ c.r = p->r;
+ c.g = p->g;
+ c.b = p->b;
+
+ oled_draw_line(p->x1, p->y1, p->x2, p->y2, c);
+}
+
+void cmd_box(display_box_t *p)
+{
+ Color c;
+ c.r = p->r;
+ c.g = p->g;
+ c.b = p->b;
+
+ oled_draw_line(p->x1, p->y1, p->x2, p->y1, c);
+ oled_draw_line(p->x2, p->y1, p->x2, p->y2, c);
+ oled_draw_line(p->x2, p->y2, p->x1, p->y2, c);
+ oled_draw_line(p->x1, p->y2, p->x1, p->y1, c);
+}
+
+void cmd_fillbox(display_fillbox_t *p)
+{
+ Color c1, c2;
+ c1.r = p->r1;
+ c1.g = p->g1;
+ c1.b = p->b1;
+ c2.r = p->r2;
+ c2.g = p->g2;
+ c2.b = p->b2;
+
+ oled_fill_box(p->x1, p->y1, p->x2, p->y2, c1, c2);
+}
+
+void draw_char(uint8_t x, uint8_t y, char c, Color *col) {
+ int i, j;
+ if ((FONT_MIN_CODE <= c) &&(c <= FONT_MAX_CODE)) {
+ int aofs = (c - FONT_MIN_CODE) * FONT_X;
+ for (i = 0; i < FONT_X; i++) {
+ uint8_t pat = font5x7_data[aofs + i];
+ for (j = 0; j < FONT_Y; j++) {
+ if (pat & (1 << j)) {
+ oled_draw_pixel(x + i, y + j, *col);
+ }
+ }
+ }
+ } else {
+ for (i = 0; i < FONT_X; i++) {
+ uint8_t pat = (i % 2) ? 0x55 : 0xAA;
+ for (j = 0; j < FONT_Y; j++) {
+ if (pat & (1 << j)) {
+ oled_draw_pixel(x + i, y + j, *col);
+ }
+ }
+ }
+ }
+}
+
+void cmd_text(display_text_t *p)
+{
+ Color col;
+ col.r = p->r;
+ col.g = p->g;
+ col.b = p->b;
+
+ char *strp = p->text;
+ int cnt = 0;
+ while (*strp) {
+ draw_char(p->x + (FONT_X * cnt), p->y, *strp, &col);
+ strp++;
+ cnt++;
+ }
+}
+
+int ff_getc(void)
+{
+ uint8_t c;
+ UINT n;
+ FRESULT fr = f_read(&work.fil, &c, 1, &n);
+ return ((fr == FR_OK) ? c : -1);
+}
+
+void dispfunc(int x, int y, int r, int g, int b)
+{
+ Color c;
+ if ((0 <= x) && (0 <= y) && (x < OLED_X) && (y < OLED_Y)) {
+ c.r = r;
+ c.g = g;
+ c.b = b;
+ oled_draw_pixel(x, y, c);
+ }
+}
+
+void cmd_bmpfile(display_bmpfile_t *p)
+{
+ bmp_file_t bmpfile;
+ bmp_info_t bmpinfo;
+ bmp_rgbquad_t bmprgbquad;
+
+ int a = f_mount(0, &work.fatfs[0]);
+ int b = f_opendir(&work.dir, "");
+ if ((a == 0) && (b == 0)) {
+ FRESULT res = f_open(
+ &work.fil, p->filename, FA_OPEN_EXISTING|FA_READ);
+ if (res == FR_OK) {
+ bmplowio_header_read(ff_getc, &bmpfile, &bmpinfo);
+ if (have_palette(&bmpinfo)) {
+ bmplowio_palette_read(
+ ff_getc,
+ &bmprgbquad,
+ (1 << bmpinfo.biBitCount));
+ }
+ bmplowio_image_read(
+ ff_getc,
+ &bmpfile,
+ &bmpinfo,
+ dispfunc);
+ } else {
+ syslog(LOG_NOTICE, "file open failed.(%d)", res);
+ }
+ } else {
+ syslog(LOG_NOTICE, "mount failed.");
+ }
+}
+
+void cmd_audio_levelmeter(display_audio_levelmeter_t *p)
+{
+ Color c1, c2;
+ c1.r = 0xFF;
+ c1.g = 0xFF;
+ c1.b = 0xFF;
+ c2.r = 0x00;
+ c2.g = 0x00;
+ c2.b = 0x00;
+
+ static const int LVW = OLED_X;
+ static const int LVH = 2;
+ static const int LVOFSX = 0;
+ static const int LVOFSY = 10;
+
+ unsigned int PL = ((((uint32_t)p->left ) ^ 0x80000000) >> 24) - 128;
+ unsigned int PR = ((((uint32_t)p->right) ^ 0x80000000) >> 24) - 128;
+ PL = PL / 5;
+ PR = PR / 5;
+ if (PL < 0) { PL = 0; }
+ if (PR < 0) { PR = 0; }
+ if (LVW <= PL) { PL = LVW - 1; }
+ if (LVW <= PR) { PR = LVW - 1; }
+
+ /*
+ * Left side.
+ */
+ oled_fill_box(
+ LVOFSX + 0, LVOFSY + 0,
+ LVOFSX + PL - 1, LVOFSY + LVH - 1,
+ c1, c1);
+ oled_fill_box(
+ LVOFSX + PL, LVOFSY + 0,
+ LVOFSX + OLED_X - 1, LVOFSY + LVH - 1,
+ c2, c2);
+
+ /*
+ * Right side.
+ */
+ oled_fill_box(
+ LVOFSX + 0, LVOFSY + LVH,
+ LVOFSX + PR - 1, LVOFSY + LVH + LVH - 1,
+ c1, c1);
+ oled_fill_box(
+ LVOFSX + PR, LVOFSY + LVH,
+ LVOFSX + OLED_X - 1, LVOFSY + LVH + LVH - 1,
+ c2, c2);
+}
+
+void task_display(intptr_t exinf)
+{
+ display_msg_t *p;
+
+ /*
+ * OLEDを初期化する。
+ */
+ oled_init();
+ oled_clear(0, 0, OLED_X - 1, OLED_Y - 1);
+
+ while(1)
+ {
+ /*
+ * メールボックスの受信を待つ。
+ * 待つまでタスクは受信待ちとなる。
+ */
+ if (rcv_mbx(MBX_DISPLAY, (T_MSG**)&p) == E_OK) {
+ /*
+ * コマンドによってパラメータの型が決まる。
+ * コマンドによって処理関数が決まる。
+ */
+ uint8_t cmd = ((display_msg_t*)p)->cmd;
+ void* param = ((display_msg_t*)p)->param;
+ switch (cmd) {
+ case DISPLAY_CMD_CLEAR:
+ cmd_clear((display_clear_t *)param);
+ break;
+ case DISPLAY_CMD_LINE:
+ cmd_line((display_line_t *)param);
+ break;
+ case DISPLAY_CMD_BOX:
+ cmd_box((display_box_t *)param);
+ break;
+ case DISPLAY_CMD_FILLBOX:
+ cmd_fillbox((display_fillbox_t *)param);
+ break;
+ case DISPLAY_CMD_TEXT:
+ cmd_text((display_text_t *)param);
+ break;
+ case DISPLAY_CMD_BMPFILE:
+ cmd_bmpfile((display_bmpfile_t *)param);
+ break;
+ case DISPLAY_CMD_AUDIO_LEVELMETER:
+ cmd_audio_levelmeter((display_audio_levelmeter_t *)param);
+ break;
+ default:
+ syslog(LOG_NOTICE, "Unknown command number %d.", cmd);
+ break;
+ }
+ rel_mpf(MPF_DISPLAY, (VP)p);
+ }
+ }
+}
+
--- /dev/null
+/**
+ * @file task_display.h
+ * @author Shinichiro Nakamura
+ * @brief ディスプレイタスクの定義(task_display)
+ * @details
+ * ディスプレイタスクは有機ELディスプレイを制御するタスクである。
+ * ディスプレイの制御はマクロを使って行うことができる。
+ */
+
+/**
+ * @example
+ * ディスプレイへの表示は以下のマクロを使って行うことができる。
+ *
+ * @code
+ * TSKAPI_DISPLAY_CLEAR(r, g, b);
+ * TSKAPI_DISPLAY_LINE(x1, y1, x2, y2, r, g, b);
+ * TSKAPI_DISPLAY_BOX(x1, y1, x2, y2, r, g, b);
+ * TSKAPI_DISPLAY_FILLBOX(x1, y1, x2, y2, r1, g1, b1, r2, g2, b2);
+ * TSKAPI_DISPLAY_TEXT(x, y, r, g, b, "text");
+ * TSKAPI_DISPLAY_BMPFILE("filename");
+ * @endcode
+ *
+ * このマクロは、タスクコンテキスト内のどこからでも呼ぶことができる。
+ */
+
+#ifndef _TASK_DISPLAY_H_
+#define _TASK_DISPLAY_H_
+
+#include "target_test.h"
+
+/**
+ * @brief タスクプライオリティ。(ディスプレイタスク)
+ */
+#define TSKPRI_DISPLAY 11
+#define TSKSTK_DISPLAY STACK_SIZE
+
+#define DISPLAY_CMD_CLEAR 0
+#define DISPLAY_CMD_LINE 1
+#define DISPLAY_CMD_BOX 2
+#define DISPLAY_CMD_FILLBOX 3
+#define DISPLAY_CMD_TEXT 4
+#define DISPLAY_CMD_BMPFILE 5
+#define DISPLAY_CMD_AUDIO_LEVELMETER 6
+
+typedef struct {
+ T_MSG header;
+ uint8_t cmd;
+ uint8_t param[64];
+} display_msg_t;
+
+typedef struct {
+ uint8_t r;
+ uint8_t g;
+ uint8_t b;
+} display_clear_t;
+
+typedef struct {
+ uint8_t x1;
+ uint8_t y1;
+ uint8_t x2;
+ uint8_t y2;
+ uint8_t r;
+ uint8_t g;
+ uint8_t b;
+} display_line_t;
+
+typedef struct {
+ uint8_t x1;
+ uint8_t y1;
+ uint8_t x2;
+ uint8_t y2;
+ uint8_t r;
+ uint8_t g;
+ uint8_t b;
+} display_box_t;
+
+typedef struct {
+ uint8_t x1;
+ uint8_t y1;
+ uint8_t x2;
+ uint8_t y2;
+ uint8_t r1;
+ uint8_t g1;
+ uint8_t b1;
+ uint8_t r2;
+ uint8_t g2;
+ uint8_t b2;
+} display_fillbox_t;
+
+typedef struct {
+ uint8_t x;
+ uint8_t y;
+ uint8_t r;
+ uint8_t g;
+ uint8_t b;
+ char text[32];
+} display_text_t;
+
+typedef struct {
+ char filename[32];
+} display_bmpfile_t;
+
+typedef struct {
+ int left;
+ int right;
+} display_audio_levelmeter_t;
+
+/**
+ * @defgroup BLACKTANK_LPC1769_TASK_DISPLAY_CLIENT
+ * @ingroup BLACKTANK_LPC1769_TASK_DISPLAY
+ * @{
+ */
+
+void disp_clear(const uint8_t r, const uint8_t g, const uint8_t b);
+void disp_line(
+ const uint8_t x1,
+ const uint8_t y1,
+ const uint8_t x2,
+ const uint8_t y2,
+ const uint8_t r,
+ const uint8_t g,
+ const uint8_t b);
+void disp_box(
+ const uint8_t x1,
+ const uint8_t y1,
+ const uint8_t x2,
+ const uint8_t y2,
+ const uint8_t r,
+ const uint8_t g,
+ const uint8_t b);
+void disp_fillbox(
+ const uint8_t x1,
+ const uint8_t y1,
+ const uint8_t x2,
+ const uint8_t y2,
+ const uint8_t r1,
+ const uint8_t g1,
+ const uint8_t b1,
+ const uint8_t r2,
+ const uint8_t g2,
+ const uint8_t b2);
+void disp_text(
+ const uint8_t x,
+ const uint8_t y,
+ const uint8_t r,
+ const uint8_t g,
+ const uint8_t b,
+ const char *text);
+void disp_bmpfile(const char *filename);
+void disp_audio_levelmeter(const int left, const int right);
+
+#define TSKAPI_DISPLAY_CLEAR(R,G,B) \
+ disp_clear((R),(G),(B))
+#define TSKAPI_DISPLAY_LINE(X1,Y1,X2,Y2,R,G,B) \
+ disp_line((X1),(Y1),(X2),(Y2),(R),(G),(B))
+#define TSKAPI_DISPLAY_BOX(X1,Y1,X2,Y2,R,G,B) \
+ disp_box((X1),(Y1),(X2),(Y2),(R),(G),(B))
+#define TSKAPI_DISPLAY_FILLBOX(X1,Y1,X2,Y2,R1,G1,B1,R2,G2,B2) \
+ disp_fillbox((X1),(Y1),(X2),(Y2),(R1),(G1),(B1),(R2),(G2),(B2))
+#define TSKAPI_DISPLAY_TEXT(X,Y,R,G,B,TEXT) \
+ disp_text((X),(Y),(R),(G),(B),(TEXT))
+#define TSKAPI_DISPLAY_BMPFILE(FN) \
+ disp_bmpfile((FN))
+#define TSKAPI_DISPLAY_AUDIO_LEVELMETER(L,R) \
+ disp_audio_levelmeter((L),(R))
+
+/**
+ * @}
+ */
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/**
+ * @defgroup BLACKTANK_LPC1769_TASK_DISPLAY
+ * @ingroup BLACKTANK_LPC1769_TASK
+ * @{
+ */
+
+void task_display(intptr_t exinf);
+
+/**
+ * @}
+ */
+
+#endif
+
+#endif
+
--- /dev/null
+/**
+ * @file task_init.c
+ * @author Shinichiro Nakamura
+ * @brief 初期化タスクの実装(task_init)
+ * @details
+ * よくあるスプラッシュ画面を表示するタスク。
+ * このタスクは自身の処理が完了後に、本当に必要なタスクを起動する。
+ * 本当に必要なタスクを起動した後は、システムの動作をユーザに通知する
+ * だけのタスクとして動作する。
+ */
+
+#include <LPC17xx.h>
+#include <kernel.h>
+#include <t_syslog.h>
+#include <t_stdlib.h>
+
+#include "task_init.h"
+#include "kernel_cfg.h"
+#include "task_display.h"
+#include "config.h"
+
+#define TASK_START(TSKID,TSKNAME) \
+ act_tsk(TSKID); \
+ tslp_tsk(100); \
+ syslog(LOG_NOTICE, "[%d:%s]", TSKID,TSKNAME)
+
+void task_init(intptr_t exinf)
+{
+ if (TASK_AUDIO_ENABLED()) {
+ TASK_START(TASK_AUDIO, "audio");
+ }
+ TASK_START(TASK_DISPLAY, "display");
+ TASK_START(TASK_LED, "led");
+ TASK_START(TASK_MENU, "menu");
+ TASK_START(TASK_USERINPUT, "userinput");
+ TASK_START(TASK_NTSHELL, "ntshell");
+
+ int cnt = 0;
+ while (1) {
+ /*
+ * 動作を示すマーキング.
+ */
+ TSKAPI_DISPLAY_FILLBOX(90, 0, 95, 6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+ switch (cnt % 4) {
+ case 0:
+ TSKAPI_DISPLAY_TEXT(90, 0, 0xFF, 0xFF, 0xFF, "-");
+ break;
+ case 1:
+ TSKAPI_DISPLAY_TEXT(90, 0, 0xFF, 0xFF, 0xFF, "\\");
+ break;
+ case 2:
+ TSKAPI_DISPLAY_TEXT(90, 0, 0xFF, 0xFF, 0xFF, "|");
+ break;
+ case 3:
+ TSKAPI_DISPLAY_TEXT(90, 0, 0xFF, 0xFF, 0xFF, "/");
+ break;
+ }
+ cnt++;
+ tslp_tsk(100);
+ }
+}
+
--- /dev/null
+/**
+ * @file task_init.h
+ * @author Shinichiro Nakamura
+ * @brief 初期化タスクの定義(task_init)
+ * @details
+ * よくある初期化画面を表示するタスク。
+ * このタスクは自身の処理が完了後に、本当に必要なタスクを起動する。
+ * 本当に必要なタスクを起動した後は、システムの動作をユーザに通知する
+ * だけのタスクとして動作する。
+ */
+
+#ifndef TASK_INIT_H
+#define TASK_INIT_H
+
+/**
+ * @brief タスクプライオリティ。(初期化)
+ */
+#define TSKPRI_INIT 13
+#define TSKSTK_INIT STACK_SIZE
+
+/**
+ * @defgroup BLACKTANK_LPC1769_TASK_INIT
+ * @ingroup BLACKTANK_LPC1769_TASK
+ * @{
+ */
+
+void task_init(intptr_t exinf);
+
+/**
+ * @}
+ */
+
+#endif
+
--- /dev/null
+/**
+ * @file task_led.c
+ * @author Shinichiro Nakamura
+ * @brief LEDタスクの実装(task_led)
+ * @details
+ * LEDタスクはLEDの点灯を制御するタスクである。
+ * 点灯は各タスクから次のマクロのみで指示することができる。
+ * LEDMSG(target, control);
+ */
+
+#include <LPC17xx.h>
+#include <kernel.h>
+#include <t_syslog.h>
+
+#include "kernel_cfg.h"
+#include "task_led.h"
+#include "led.h"
+
+#define MSG_CONTROL(n) (((n) & 0x0080) ? 1 : 0)
+#define MSG_TARGET(n) ((n) & 0x000F)
+
+void task_led(intptr_t exinf)
+{
+ uint16_t msg;
+ led_init();
+ while(1)
+ {
+ if (rcv_dtq(DTQ_LED, (intptr_t *)&msg) == E_OK) {
+ switch (MSG_TARGET(msg)) {
+ case DBLED0:
+ led_debug_write(0, MSG_CONTROL(msg));
+ break;
+ case DBLED1:
+ led_debug_write(1, MSG_CONTROL(msg));
+ break;
+ case DBLED2:
+ led_debug_write(2, MSG_CONTROL(msg));
+ break;
+ case DBLED3:
+ led_debug_write(3, MSG_CONTROL(msg));
+ break;
+ case SWLED0:
+ led_switch_write(0, MSG_CONTROL(msg));
+ break;
+ case SWLED1:
+ led_switch_write(1, MSG_CONTROL(msg));
+ break;
+ case SWLED2:
+ led_switch_write(2, MSG_CONTROL(msg));
+ break;
+ case SWLED3:
+ led_switch_write(3, MSG_CONTROL(msg));
+ break;
+ }
+ }
+ tslp_tsk(10);
+ }
+}
+
--- /dev/null
+/**
+ * @file task_led.h
+ * @author Shinichiro Nakamura
+ * @brief LEDタスクの定義(task_led)
+ * @details
+ * LEDタスクはLEDの点灯を制御するタスクである。
+ * 点灯は各タスクからマクロで指示することができる。
+ */
+
+/**
+ * @example
+ * LEDの点灯指令は以下のマクロを使って行うことができる。
+ *
+ * @code
+ * LEDMSG(target, control);
+ * @endcode
+ *
+ * このマクロは、タスクコンテキスト内のどこからでも呼ぶことができる。
+ */
+
+#ifndef _TASK_LED_H_
+#define _TASK_LED_H_
+
+#include "target_test.h"
+
+/**
+ * @brief タスクプライオリティ。(LEDタスク)
+ */
+#define TSKPRI_LED 11
+#define TSKSTK_LED STACK_SIZE
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/**
+ * @defgroup BLACKTANK_LPC1769_TASK_LED_CLIENT
+ * @ingroup BLACKTANK_LPC1769_TASK_LED
+ * @{
+ */
+
+#define DBLED0 0 /**< デバッグ用LED0 */
+#define DBLED1 1 /**< デバッグ用LED1 */
+#define DBLED2 2 /**< デバッグ用LED2 */
+#define DBLED3 3 /**< デバッグ用LED3 */
+#define SWLED0 4 /**< スイッチ用LED0 */
+#define SWLED1 5 /**< スイッチ用LED1 */
+#define SWLED2 6 /**< スイッチ用LED2 */
+#define SWLED3 7 /**< スイッチ用LED3 */
+
+#define LEDOFF 0 /**< LEDを消灯する。 */
+#define LEDON 1 /**< LEDを点灯する。 */
+
+#define TSKAPI_LED_LEDMSG(TARGET, CONTROL) \
+ snd_dtq(DTQ_LED, (intptr_t)(((CONTROL) ? 0x80:0x00) | ((TARGET)& 0x0F)))
+/**<
+ * LEDの点灯指令を行う。
+ *
+ * @param TARGET ターゲット。
+ * @param CONTROL 制御内容。
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup BLACKTANK_LPC1769_TASK_LED
+ * @ingroup BLACKTANK_LPC1769_TASK
+ * @{
+ */
+
+void task_led(intptr_t exinf);
+
+/**
+ * @}
+ */
+
+#endif
+
+#endif
--- /dev/null
+/**
+ * @file task_menu.c
+ * @author Shinichiro Nakamura
+ * @brief メニュータスクの実装(task_menu)
+ * @details
+ * メニュータスクはユーザにシステムのサービスを提示し、
+ * ユーザからの要求をシステムに伝達する役目を果たす。
+ * ユーザからの入力はそれらを管理するタスクからの通知に依存する。
+ */
+
+#include <LPC17xx.h>
+#include <kernel.h>
+#include <t_syslog.h>
+
+#include "kernel_cfg.h"
+#include "task_menu.h"
+#include "task_led.h"
+#include "task_display.h"
+#include "task_audio.h"
+#include "oled.h"
+#include "config.h"
+
+#define MSG_DEVICE(n) (((n) & 0xF000) >> 12)
+#define MSG_VALUE(n) (((n) & 0x0FFF) >> 0)
+
+/*
+ * メニュータスクの雛形。
+ * 簡単に階層化ができる。
+ */
+
+typedef enum {
+ PAGE_TOP,
+ PAGE_100,
+ PAGE_200,
+ PAGE_300,
+ PAGE_VER
+} PAGEID;
+
+typedef enum {
+ PAGE_IN,
+ PAGE_TICK,
+ PAGE_OUT
+} ACTION;
+
+typedef struct {
+ PAGEID curr_page;
+ PAGEID next_page[4];
+ void (*func)(ACTION act);
+} menu_t;
+
+static PAGEID curr_page = PAGE_TOP;
+
+typedef struct {
+ int val[4];
+} menu_work_t;
+
+menu_work_t menu_work;
+
+#define DISP_MENUNAME(NAME) \
+ do { \
+ TSKAPI_DISPLAY_FILLBOX(0, 0, OLED_X - 1, 8, \
+ 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00); \
+ TSKAPI_DISPLAY_TEXT(0, 0, 0xFF, 0xFF, 0xFF, (NAME)); \
+ } while(0)
+
+#define DISP_MENUTAG(A,B,C,D) \
+ do { \
+ TSKAPI_DISPLAY_FILLBOX(0, 52, OLED_X - 1, OLED_Y - 1, \
+ 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00); \
+ TSKAPI_DISPLAY_TEXT(2 + (24 * 0), 52, 0xFF, 0xFF, 0xFF, (A)); \
+ TSKAPI_DISPLAY_TEXT(2 + (24 * 1), 52, 0xFF, 0xFF, 0xFF, (B)); \
+ TSKAPI_DISPLAY_TEXT(2 + (24 * 2), 52, 0xFF, 0xFF, 0xFF, (C)); \
+ TSKAPI_DISPLAY_TEXT(2 + (24 * 3), 52, 0xFF, 0xFF, 0xFF, (D)); \
+ } while(0)
+
+void page_splash(ACTION act)
+{
+ /* 他のタスクが初期化状態を表示するため
+ * このタスクでは何も表示しない。
+ */
+}
+
+void page_top(ACTION act)
+{
+ if (act == PAGE_IN) {
+ TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
+ DISP_MENUNAME("[TOP]");
+ DISP_MENUTAG("M-1", "M-2", "M-3", "VER");
+ }
+ if (act == PAGE_TICK) {
+ int i;
+ for (i = 0; i < 4; i++) {
+ static const int MAXVAL = (1023/ 32);
+ static const int XOFS = 10;
+ static const int YOFS = 18;
+ int val = MAXVAL - (menu_work.val[i] / 32);
+ TSKAPI_DISPLAY_FILLBOX(
+ XOFS + i * 20, YOFS + 0,
+ XOFS + i * 20 + 10, YOFS + val,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00);
+ TSKAPI_DISPLAY_FILLBOX(
+ XOFS + i * 20, YOFS + val,
+ XOFS + i * 20 + 10, YOFS + MAXVAL,
+ 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF);
+ }
+ if (!TASK_AUDIO_ENABLED()) {
+ TSKAPI_DISPLAY_TEXT(10, 8, 0xFF, 0xFF, 0xFF, "AUDIO DISABLED");
+ }
+ }
+ if (act == PAGE_OUT) {
+ TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
+ }
+}
+
+void page_100(ACTION act)
+{
+ if (act == PAGE_IN) {
+ TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
+ DISP_MENUNAME("[MENU-1]");
+ TSKAPI_DISPLAY_TEXT(20, 30, 0xFF, 0xFF, 0xFF, "-- MENU 1 --");
+ DISP_MENUTAG("", "", "", "RET");
+ }
+ if (act == PAGE_OUT) {
+ TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
+ }
+}
+
+void page_200(ACTION act)
+{
+ if (act == PAGE_IN) {
+ TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
+ DISP_MENUNAME("[MENU-2]");
+ TSKAPI_DISPLAY_TEXT(20, 30, 0xFF, 0xFF, 0xFF, "-- MENU 2 --");
+ DISP_MENUTAG("", "", "", "RET");
+ }
+ if (act == PAGE_OUT) {
+ TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
+ }
+}
+
+void page_300(ACTION act)
+{
+ if (act == PAGE_IN) {
+ TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
+ DISP_MENUNAME("[MENU-3]");
+ TSKAPI_DISPLAY_TEXT(20, 30, 0xFF, 0xFF, 0xFF, "-- MENU 3 --");
+ DISP_MENUTAG("", "", "", "RET");
+ }
+ if (act == PAGE_OUT) {
+ TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
+ }
+}
+
+void page_ver(ACTION act)
+{
+ if (act == PAGE_IN) {
+ TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
+ DISP_MENUNAME("[Version]");
+ TSKAPI_DISPLAY_TEXT(20, 30, 0xFF, 0xFF, 0xFF, "Preliminary");
+ DISP_MENUTAG("", "", "", "RET");
+ }
+ if (act == PAGE_OUT) {
+ TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
+ }
+}
+
+static const menu_t menu[6] = {
+ {PAGE_TOP, {PAGE_100, PAGE_200, PAGE_300, PAGE_VER}, page_top},
+ {PAGE_100, {PAGE_100, PAGE_100, PAGE_100, PAGE_TOP}, page_100},
+ {PAGE_200, {PAGE_200, PAGE_200, PAGE_200, PAGE_TOP}, page_200},
+ {PAGE_300, {PAGE_300, PAGE_300, PAGE_300, PAGE_TOP}, page_300},
+ {PAGE_VER, {PAGE_VER, PAGE_VER, PAGE_VER, PAGE_TOP}, page_ver}
+};
+
+void execute_pagefunc(PAGEID page, ACTION act)
+{
+ int i;
+ for (i = 0; i < sizeof(menu) / sizeof(menu[0]); i++) {
+ if (menu[i].curr_page == page) {
+ if (menu[i].func != NULL) {
+ menu[i].func(act);
+ return;
+ }
+ }
+ }
+}
+
+PAGEID get_next_page(PAGEID page, int sw)
+{
+ int i;
+ for (i = 0; i < sizeof(menu) / sizeof(menu[0]); i++) {
+ if (menu[i].curr_page == page) {
+ return menu[i].next_page[sw];
+ }
+ }
+ return page;
+}
+
+void splash(void)
+{
+ static const int XOFS = 5;
+ static const int YOFS = 10;
+ static const int YSTP = 12;
+
+ TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
+ TSKAPI_DISPLAY_BMPFILE("0:LOGO.BMP");
+ tslp_tsk(2000);
+
+ TSKAPI_DISPLAY_CLEAR(0x00, 0x00, 0x00);
+ TSKAPI_DISPLAY_TEXT(XOFS + 0, YOFS + YSTP * 0,
+ 0xFF, 0xFF, 0xFF, "Special thanks to");
+ TSKAPI_DISPLAY_TEXT(XOFS + 22, YOFS + YSTP * 2,
+ 0xFF, 0xFF, 0xFF, "Horie-san");
+ TSKAPI_DISPLAY_TEXT(XOFS + 20, YOFS + YSTP * 3,
+ 0xFF, 0xFF, 0xFF, "Kaneko-san");
+ tslp_tsk(2000);
+}
+
+#define SCREEN_SAVE_COUNTER_INIT 100
+
+void task_menu(intptr_t exinf)
+{
+ volatile uint16_t msg;
+ volatile uint16_t screen_save = SCREEN_SAVE_COUNTER_INIT;
+
+ splash();
+
+ execute_pagefunc(curr_page, PAGE_IN);
+ while(1)
+ {
+ /*
+ * 有機ELディスプレイは焼き付けを起こしやすい。
+ * スクリーンを保護する意味で一定時間の操作がなければ
+ * 表示を消去することにした。
+ */
+ if (screen_save == 0) {
+ /*
+ * スクリーン焼き付けを防止するための描画を実行する。
+ */
+ static uint32_t color = 0;
+ TSKAPI_DISPLAY_CLEAR(
+ (color >> 16) & 0xff,
+ (color >> 8) & 0xff,
+ (color >> 0) & 0xff);
+ color++;
+ } else {
+ /*
+ * ページにティックを与える。
+ * 各ページは自身が必要とする再描画を行うだろう。
+ */
+ execute_pagefunc(curr_page, PAGE_TICK);
+ /*
+ * スクリーンセーバ起動カウンタをデクリメントする。
+ */
+ screen_save--;
+ }
+
+ /*
+ * データキューの受信状態を見る。
+ * ここではポーリングして、データがなければスルーする。
+ */
+ while (prcv_dtq(DTQ_USERINPUT, (intptr_t *)&msg) == E_OK) {
+ /*
+ * スイッチイベントの受信。
+ */
+ if ((DEVICE_SW0 <= MSG_DEVICE(msg))
+ && (MSG_DEVICE(msg) <= DEVICE_SW3)) {
+ /*
+ * スイッチ入力がある時にはスクリーンセーバカウンタを
+ * 初期値にする。
+ */
+ if (screen_save == 0) {
+ execute_pagefunc(curr_page, PAGE_IN);
+ }
+ screen_save = SCREEN_SAVE_COUNTER_INIT;
+
+ /*
+ * スイッチがONエッジならばページの遷移処理を実行。
+ */
+ if (MSG_VALUE(msg)) {
+ PAGEID next_page = get_next_page(
+ curr_page, MSG_DEVICE(msg));
+ if (next_page != curr_page) {
+ execute_pagefunc(curr_page, PAGE_OUT);
+ curr_page = next_page;
+ execute_pagefunc(curr_page, PAGE_IN);
+ }
+ }
+ /*
+ * 押されたスイッチのLEDを点灯させる。
+ */
+ switch (MSG_DEVICE(msg)) {
+ case DEVICE_SW0:
+ TSKAPI_LED_LEDMSG(SWLED0, MSG_VALUE(msg));
+ break;
+ case DEVICE_SW1:
+ TSKAPI_LED_LEDMSG(SWLED1, MSG_VALUE(msg));
+ break;
+ case DEVICE_SW2:
+ TSKAPI_LED_LEDMSG(SWLED2, MSG_VALUE(msg));
+ break;
+ case DEVICE_SW3:
+ TSKAPI_LED_LEDMSG(SWLED3, MSG_VALUE(msg));
+ break;
+ }
+ }
+ /*
+ * ボリュームイベントの受信。
+ */
+ if ((DEVICE_VOL0 <= MSG_DEVICE(msg))
+ && (MSG_DEVICE(msg) <= DEVICE_VOL3)) {
+ /*
+ * 作業用変数に与えられたレベルを格納しておく。
+ */
+ int ch = MSG_DEVICE(msg) - DEVICE_VOL0;
+ menu_work.val[ch] = MSG_VALUE(msg);
+ /*
+ * オーディオパラメータをオーディオタスクに伝達する。
+ */
+ if (TASK_AUDIO_ENABLED()) {
+ switch (MSG_DEVICE(msg)) {
+ case DEVICE_VOL0:
+ TSKAPI_AUDIO_PARAM(
+ AUDIO_PARAM_VAR0, MSG_VALUE(msg));
+ break;
+ case DEVICE_VOL1:
+ TSKAPI_AUDIO_PARAM(
+ AUDIO_PARAM_VAR1, MSG_VALUE(msg));
+ break;
+ case DEVICE_VOL2:
+ TSKAPI_AUDIO_PARAM(
+ AUDIO_PARAM_VAR2, MSG_VALUE(msg));
+ break;
+ case DEVICE_VOL3:
+ TSKAPI_AUDIO_PARAM(
+ AUDIO_PARAM_VAR3, MSG_VALUE(msg));
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ tslp_tsk(100);
+ }
+}
+
--- /dev/null
+/**
+ * @file task_menu.h
+ * @author Shinichiro Nakamura
+ * @brief メニュータスクの定義(task_menu)
+ * @details
+ * メニュータスクはユーザにシステムのサービスを提示し、
+ * ユーザからの要求をシステムに伝達する役目を果たす。
+ * ユーザからの入力はそれらを管理するタスクからの通知に依存する。
+ */
+
+#ifndef _TASK_MENU_H_
+#define _TASK_MENU_H_
+
+#include "target_test.h"
+
+/**
+ * @brief タスクプライオリティ。(メニュータスク)
+ */
+#define TSKPRI_MENU 12
+#define TSKSTK_MENU STACK_SIZE
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/**
+ * @defgroup BLACKTANK_LPC1769_TASK_MENU_CLIENT
+ * @ingroup BLACKTANK_LPC1769_TASK_MENU
+ * @{
+ */
+
+#define DEVICE_SW0 0 /**< デバイス:スイッチ0 */
+#define DEVICE_SW1 1 /**< デバイス:スイッチ1 */
+#define DEVICE_SW2 2 /**< デバイス:スイッチ2 */
+#define DEVICE_SW3 3 /**< デバイス:スイッチ3 */
+#define DEVICE_VOL0 4 /**< デバイス:ボリューム0 */
+#define DEVICE_VOL1 5 /**< デバイス:ボリューム1 */
+#define DEVICE_VOL2 6 /**< デバイス:ボリューム2 */
+#define DEVICE_VOL3 7 /**< デバイス:ボリューム3 */
+
+/**
+ * @brief menuタスクAPI(ユーザメッセージ)の実行。
+ * @param device デバイス番号。
+ * @param value 値。
+ */
+#define TSKAPI_MENU_USERMSG(device, value) \
+ snd_dtq(DTQ_USERINPUT, \
+ (intptr_t)(((device & 0x000F) << 12) | ((value & 0x0FFF) << 0)))
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup BLACKTANK_LPC1769_TASK_MENU
+ * @ingroup BLACKTANK_LPC1769_TASK
+ * @{
+ */
+
+void task_menu(intptr_t exinf);
+
+/**
+ * @}
+ */
+
+#endif
+
+#endif
+
--- /dev/null
+/**
+ * @file task_ntshell.c
+ * @author Shinichiro Nakamura
+ * @brief ナチュラルタイニーシェルタスクの実装(task_ntshell)
+ * @details
+ * システムをコンソールから制御することのできるインターフェースタスク。
+ * 主に開発者のために提供される。
+ */
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <target_syssvc.h>
+#include <syssvc/serial.h>
+#include <logtrace/trace_config.h>
+
+#include "kernel_cfg.h"
+
+#include "task_ntshell.h"
+#include "task_led.h"
+#include "task_display.h"
+#include "task_audio.h"
+
+#include "ntshell.h"
+#include "ntopt.h"
+#include "ntlibc.h"
+#include "cmd.h"
+
+ntshell_t ntshell;
+
+int func_read(char *buf, int cnt);
+int func_write(const char *buf, int cnt);
+int func_ntopt(int argc, char **argv, void *extobj);
+int func_ntshell(const char *text);
+
+typedef struct {
+ char *command;
+ char *description;
+ void (*func)(int argc, char **argv);
+} command_table_t;
+
+const command_table_t table[] = {
+ {"taskinfo", "Task information.", cmd_taskinfo},
+ {"audio", "Audio task parameter.", cmd_audio},
+ {"lcd", "Control the LCD.", cmd_lcd},
+ {"led", "Set state of the debug purpose LED.", cmd_led},
+ {"mount", "Mount a SD card.", cmd_mount},
+ {"ls", "List contents on a SD card.", cmd_ls},
+ {"cd", "Change the current directory.", cmd_cd},
+ {"trace", "Trace the kernel conditions.", cmd_trace},
+ {"exit", "Exit the kernel.", cmd_exit},
+ {NULL, NULL, NULL}
+};
+
+void cmd_help(void) {
+ const command_table_t *p = &table[0];
+ char buf[64];
+ while (p->command != NULL) {
+ ntlibc_strcpy(buf, p->command);
+ ntlibc_strcat(buf, "\t:");
+ ntlibc_strcat(buf, p->description);
+ syslog(LOG_NOTICE, buf);
+ tslp_tsk(10);
+ p++;
+ }
+}
+
+int func_read(char *buf, int cnt)
+{
+ return serial_rea_dat(SIO_PORTID, (char_t *)buf, cnt);
+}
+
+int func_write(const char *buf, int cnt)
+{
+ return serial_wri_dat(SIO_PORTID, (const char_t *)buf, cnt);
+}
+
+int func_ntopt(int argc, char **argv, void *extobj)
+{
+ if (argc == 0) {
+ return 0;
+ }
+
+ int execnt = 0;
+ const command_table_t *p = &table[0];
+ while (p->command != NULL) {
+ if (ntlibc_strcmp((const char *)argv[0], p->command) == 0) {
+ p->func(argc, argv);
+ execnt++;
+ }
+ p++;
+ }
+ if (execnt == 0) {
+ if (argc > 0) {
+ cmd_help();
+ } else {
+ syslog(LOG_NOTICE,
+ "Found unknown command. (help: display help.)");
+ }
+ }
+
+ tslp_tsk(250);
+ return 0;
+}
+
+int func_ntshell(const char *text)
+{
+ return ntopt_parse((const char *)text, NULL, func_ntopt);
+}
+
+/**
+ * \brief メインタスク
+ * \param exinf コンフィギュレータから渡す引数。今回は利用しない
+ * \details
+ */
+void task_ntshell(intptr_t exinf)
+{
+ serial_opn_por(SIO_PORTID);
+
+ ntshell_execute(&ntshell, func_read, func_write, func_ntshell);
+}
+
--- /dev/null
+/**
+ * @file task_ntshell.h
+ * @author Shinichiro Nakamura
+ * @brief ナチュラルタイニーシェルタスクの定義(task_ntshell)
+ * @details
+ * システムをコンソールから制御することのできるインターフェースタスク。
+ * 主に開発者のために提供される。
+ */
+
+#ifndef _TASK_NTSHELL_H_
+#define _TASK_NTSHELL_H_
+
+/*
+ * ターゲット依存の定義
+ */
+#include "target_test.h"
+
+/*
+ * 各タスクの優先度の定義
+ */
+
+/**
+ * @brief タスクプライオリティ。(シェルタスク)
+ */
+#define TSKPRI_NTSHELL 14
+#define TSKSTK_NTSHELL STACK_SIZE
+
+/*
+ * 関数のプロトタイプ宣言
+ */
+#ifndef TOPPERS_MACRO_ONLY
+
+/**
+ * @defgroup BLACKTANK_LPC1769_TASK_NTSHELL
+ * @ingroup BLACKTANK_LPC1769_TASK
+ * @{
+ */
+
+void task_ntshell(intptr_t exinf);
+
+/**
+ * @}
+ */
+
+#endif /* TOPPERS_MACRO_ONLY */
+
+#endif /* _TASK_NTSHELL_H_ */
--- /dev/null
+/**
+ * @file task_userinput.c
+ * @author Shinichiro Nakamura
+ * @brief ユーザインプットタスクの実装(task_userinput)
+ * @details
+ * ユーザインプットタスクは4系統のユーザ入力の変化を観察するタスク。
+ * 変化があればデータキューを介してメニュータスクに通知を行う。
+ */
+
+#include <LPC17xx.h>
+#include <kernel.h>
+#include <t_syslog.h>
+
+#include "kernel_cfg.h"
+#include "task_userinput.h"
+#include "task_menu.h"
+#include "hid.h"
+
+void task_userinput(intptr_t exinf)
+{
+ uint16_t initdone = 0;
+ uint16_t s0prev = 0, s1prev = 0, s2prev = 0, s3prev = 0;
+ uint16_t v0prev = 0, v1prev = 0, v2prev = 0, v3prev = 0;
+ hid_init();
+ while(1)
+ {
+ /*
+ * Sense.
+ */
+ uint16_t s0curr = hid_swread(0);
+ uint16_t s1curr = hid_swread(1);
+ uint16_t s2curr = hid_swread(2);
+ uint16_t s3curr = hid_swread(3);
+ uint16_t v0curr = (uint16_t)(hid_volread(0) >> 2);
+ uint16_t v1curr = (uint16_t)(hid_volread(1) >> 2);
+ uint16_t v2curr = (uint16_t)(hid_volread(2) >> 2);
+ uint16_t v3curr = (uint16_t)(hid_volread(3) >> 2);
+
+ /*
+ * Diff.
+ */
+ if ((s0prev != s0curr) || (!initdone)) {
+ if (s0curr) {
+ TSKAPI_MENU_USERMSG(DEVICE_SW0, 1);
+ } else {
+ TSKAPI_MENU_USERMSG(DEVICE_SW0, 0);
+ }
+ }
+ if ((s1prev != s1curr) || (!initdone)) {
+ if (s1curr) {
+ TSKAPI_MENU_USERMSG(DEVICE_SW1, 1);
+ } else {
+ TSKAPI_MENU_USERMSG(DEVICE_SW1, 0);
+ }
+ }
+ if ((s2prev != s2curr) || (!initdone)) {
+ if (s2curr) {
+ TSKAPI_MENU_USERMSG(DEVICE_SW2, 1);
+ } else {
+ TSKAPI_MENU_USERMSG(DEVICE_SW2, 0);
+ }
+ }
+ if ((s3prev != s3curr) || (!initdone)) {
+ if (s3curr) {
+ TSKAPI_MENU_USERMSG(DEVICE_SW3, 1);
+ } else {
+ TSKAPI_MENU_USERMSG(DEVICE_SW3, 0);
+ }
+ }
+ if ((v0prev != v0curr) || (!initdone)) {
+ TSKAPI_MENU_USERMSG(DEVICE_VOL0, v0curr);
+ }
+ if ((v1prev != v1curr) || (!initdone)) {
+ TSKAPI_MENU_USERMSG(DEVICE_VOL1, v1curr);
+ }
+ if ((v2prev != v2curr) || (!initdone)) {
+ TSKAPI_MENU_USERMSG(DEVICE_VOL2, v2curr);
+ }
+ if ((v3prev != v3curr) || (!initdone)) {
+ TSKAPI_MENU_USERMSG(DEVICE_VOL3, v3curr);
+ }
+ initdone = 1;
+
+ /*
+ * Store.
+ */
+ s0prev = s0curr;
+ s1prev = s1curr;
+ s2prev = s2curr;
+ s3prev = s3curr;
+ v0prev = v0curr;
+ v1prev = v1curr;
+ v2prev = v2curr;
+ v3prev = v3curr;
+
+ tslp_tsk(50);
+ }
+}
+
--- /dev/null
+/**
+ * @file task_userinput.h
+ * @author Shinichiro Nakamura
+ * @brief ユーザインプットタスクの定義(task_userinput)
+ * @details
+ * ユーザインプットタスクは4系統のユーザ入力の変化を観察するタスク。
+ * 変化があればデータキューを介してメニュータスクに通知を行う。
+ */
+
+#ifndef _TASK_USERINPUT_H_
+#define _TASK_USERINPUT_H_
+
+#include "target_test.h"
+
+/**
+ * @brief タスクプライオリティ。(ユーザ入力タスク)
+ */
+#define TSKPRI_USERINPUT 12
+#define TSKSTK_USERINPUT STACK_SIZE
+
+#ifndef TOPPERS_MACRO_ONLY
+
+/**
+ * @defgroup BLACKTANK_LPC1769_TASK_USERINPUT
+ * @ingroup BLACKTANK_LPC1769_TASK
+ * @{
+ */
+
+void task_userinput(intptr_t exinf);
+
+/**
+ * @}
+ */
+
+#endif
+
+#endif
+
--- /dev/null
+/**
+ * @file testpin.c
+ * @author Shinichiro Nakamura
+ * @brief テストピン制御ライブラリの実装。
+ */
+
+#include <LPC17xx.h>
+#include "testpin.h"
+
+#define TP1_PIN_NUM 25
+#define TP2_PIN_NUM 26
+
+void testpin_init(void)
+{
+ LPC_GPIO1->FIODIR |= (1 << TP1_PIN_NUM);
+ LPC_GPIO1->FIODIR |= (1 << TP2_PIN_NUM);
+}
+
+void testpin_tp1_write(uint8_t on)
+{
+ if (on) {
+ LPC_GPIO1->FIOPIN |= (1 << TP1_PIN_NUM);
+ } else {
+ LPC_GPIO1->FIOPIN &= ~(1 << TP1_PIN_NUM);
+ }
+}
+
+void testpin_tp2_write(uint8_t on)
+{
+ if (on) {
+ LPC_GPIO1->FIOPIN |= (1 << TP2_PIN_NUM);
+ } else {
+ LPC_GPIO1->FIOPIN &= ~(1 << TP2_PIN_NUM);
+ }
+}
+
+void testpin_tp1_toggle(void)
+{
+ LPC_GPIO1->FIOPIN ^= (1 << TP1_PIN_NUM);
+}
+
+void testpin_tp2_toggle(void)
+{
+ LPC_GPIO1->FIOPIN ^= (1 << TP2_PIN_NUM);
+}
+
--- /dev/null
+/**
+ * @file testpin.h
+ * @author Shinichiro Nakamura
+ * @brief テストピン制御ライブラリの定義。
+ */
+
+#ifndef TESTPIN_H
+#define TESTPIN_H
+
+void testpin_init(void);
+void testpin_tp1_write(uint8_t on);
+void testpin_tp2_write(uint8_t on);
+void testpin_tp1_toggle(void);
+void testpin_tp2_toggle(void);
+
+#endif
+
--- /dev/null
+/**
+ * @file text_editor.c
+ * @author Shinichiro Nakamura
+ * @brief NT-Shell用テキストエディタモジュールの実装。
+ * @details
+ * 文字列の編集を論理的に扱うためのモジュール。
+ * このモジュールはビューに関して一切感知しない。
+ */
+
+/*
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell)
+ * Version 0.0.7
+ * ===============================================================
+ * Copyright (c) 2010-2011 Shinichiro Nakamura
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ * ===============================================================
+ */
+
+#include "text_editor.h"
+
+/**
+ * @brief テキストエディタを初期化する。
+ *
+ * @param p テキストエディタ構造体。
+ */
+void text_editor_init(text_editor_t *p)
+{
+ p->pos = 0;
+ p->len = 0;
+ p->buffer[p->len] = '\0';
+}
+
+/**
+ * @brief 文字を挿入する。
+ *
+ * @param p テキストエディタ構造体。
+ * @param c 文字。
+ */
+int text_editor_insert(text_editor_t *p, char c)
+{
+ if (p->len < sizeof(p->buffer) - 1) {
+ int n = p->len - p->pos + 1;
+ int i;
+ char *src = p->buffer + p->len + 0;
+ char *des = p->buffer + p->len + 1;
+ for (i = 0; i < n; i++) {
+ *des = *src;
+ des--;
+ src--;
+ }
+
+ p->buffer[p->pos] = c;
+ p->pos++;
+ p->len++;
+ p->buffer[p->len] = '\0';
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * @brief 文字を削除する。
+ *
+ * @param p テキストエディタ構造体。
+ */
+int text_editor_backspace(text_editor_t *p)
+{
+ if (0 < p->pos) {
+ int n = p->len - p->pos;
+ int i;
+ char *src = p->buffer + p->pos - 0;
+ char *des = p->buffer + p->pos - 1;
+ p->pos--;
+ p->len--;
+ for (i = 0; i < n; i++) {
+ *des = *src;
+ des++;
+ src++;
+ }
+ *(p->buffer + p->len) = '\0';
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * @brief カーソル位置を取得する。
+ *
+ * @param p テキストエディタ構造体。
+ */
+int text_editor_cursor_get_position(text_editor_t *p)
+{
+ return p->pos;
+}
+
+/**
+ * @brief カーソルを先頭に移動させる。
+ *
+ * @param p テキストエディタ構造体。
+ */
+int text_editor_cursor_head(text_editor_t *p)
+{
+ if (0 < p->pos) {
+ p->pos = 0;
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * @brief カーソルを最後尾に移動させる。
+ *
+ * @param p テキストエディタ構造体。
+ */
+int text_editor_cursor_tail(text_editor_t *p)
+{
+ if (p->pos < p->len) {
+ p->pos = p->len;
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * @brief カーソルを左へ移動させる。
+ *
+ * @param p テキストエディタ構造体。
+ */
+int text_editor_cursor_left(text_editor_t *p)
+{
+ if (0 < p->pos) {
+ p->pos--;
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * @brief カーソルを右へ移動させる。
+ *
+ * @param p テキストエディタ構造体。
+ */
+int text_editor_cursor_right(text_editor_t *p)
+{
+ if (p->pos < p->len) {
+ p->pos++;
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * @brief 文字列を設定する。
+ *
+ * @param p テキストエディタ構造体。
+ * @param buf 文字列が格納されたバッファ。
+ */
+int text_editor_set_text(text_editor_t *p, char *buf)
+{
+ char *src = buf;
+ char *des = p->buffer;
+ int n = 0;
+ while (*src) {
+ *des = *src;
+ des++;
+ src++;
+ n++;
+ if (sizeof(p->buffer) <= n - 1) {
+ break;
+ }
+ }
+ *des = '\0';
+ p->len = n;
+ p->pos = p->len;
+ return n;
+}
+
+/**
+ * @brief 文字列を取得する。
+ *
+ * @param p テキストエディタ構造体。
+ * @param buf 文字列を格納するバッファ。
+ * @param siz バッファサイズ。
+ */
+int text_editor_get_text(text_editor_t *p, char *buf, int siz)
+{
+ char *src = p->buffer;
+ char *des = buf;
+ int n = 0;
+ while (*src) {
+ *des++ = *src++;
+ n++;
+ if (siz <= n) {
+ break;
+ }
+ }
+ *des = '\0';
+ return n;
+}
+
+/**
+ * @brief 文字列を消去する。
+ *
+ * @param p テキストエディタ構造体。
+ */
+void text_editor_clear(text_editor_t *p)
+{
+ p->pos = 0;
+ p->len = 0;
+ p->buffer[p->len] = '\0';
+}
+
--- /dev/null
+/**
+ * @file text_editor.h
+ * @author Shinichiro Nakamura
+ * @brief NT-Shell用テキストエディタモジュールの定義。
+ * @details
+ * 文字列の編集を論理的に扱うためのモジュール。
+ * このモジュールはビューに関して一切感知しない。
+ */
+
+/*
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell)
+ * Version 0.0.7
+ * ===============================================================
+ * Copyright (c) 2010-2011 Shinichiro Nakamura
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ * ===============================================================
+ */
+
+#ifndef _TEXT_EDITOR_H_
+#define _TEXT_EDITOR_H_
+
+#define TEXTEDITOR_MAXLEN 64
+
+typedef struct {
+ char buffer[TEXTEDITOR_MAXLEN];
+ int pos;
+ int len;
+} text_editor_t;
+
+void text_editor_init(text_editor_t *p);
+int text_editor_insert(text_editor_t *p, char c);
+int text_editor_backspace(text_editor_t *p);
+int text_editor_cursor_get_position(text_editor_t *p);
+int text_editor_cursor_head(text_editor_t *p);
+int text_editor_cursor_tail(text_editor_t *p);
+int text_editor_cursor_left(text_editor_t *p);
+int text_editor_cursor_right(text_editor_t *p);
+int text_editor_set_text(text_editor_t *p, char *buf);
+int text_editor_get_text(text_editor_t *p, char *buf, int siz);
+void text_editor_clear(text_editor_t *p);
+
+#endif
+
--- /dev/null
+/**
+ * @file text_history.c
+ * @author Shinichiro Nakamura
+ * @brief NT-Shell用テキストヒストリモジュールの実装。
+ * @details
+ * 文字列の入力履歴を論理的に扱うためのモジュール。
+ * このモジュールはビューに関して一切感知しない。
+ */
+
+/*
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell)
+ * Version 0.0.7
+ * ===============================================================
+ * Copyright (c) 2010-2011 Shinichiro Nakamura
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ * ===============================================================
+ */
+
+#include "text_history.h"
+#include "ntlibc.h"
+
+/**
+ * @brief 初期化する。
+ *
+ * @param p テキストヒストリ構造体。
+ */
+void text_history_init(text_history_t *p)
+{
+ p->rp = 0;
+ p->wp = 0;
+ int i;
+ for (i = 0; i < sizeof(p->history); i++) {
+ p->history[i] = 0;
+ }
+}
+
+/**
+ * @brief テキストヒストリに対して書き込みを実行する。
+ *
+ * @param p テキストヒストリ構造体。
+ * @param buf バッファ。
+ */
+int text_history_write(text_history_t *p, char *buf)
+{
+ if (buf[0] == '\0') {
+ return 0;
+ }
+ char *sp = p->history + (TEXTHISTORY_MAXLEN * p->wp);
+ while (*buf) {
+ *sp = *buf;
+ sp++;
+ buf++;
+ }
+ *sp = '\0';
+ p->wp = (p->wp + 1) % TEXTHISTORY_DEPTH;
+ p->rp = p->wp;
+ return 1;
+}
+
+/**
+ * @brief テキストヒストリから読み出しを実行する。
+ * @details
+ * 得られる文字列が与えられたバッファサイズよりも大きい場合、
+ * バッファに格納される文字列は途中で途切れるものとする。
+ *
+ * @param p テキストヒストリ構造体。
+ * @param buf バッファ。
+ * @param siz バッファサイズ。
+ */
+int text_history_read(text_history_t *p, char *buf, const int siz)
+{
+ char *sp = p->history + (TEXTHISTORY_MAXLEN * p->rp);
+ int n = 0;
+ while (*sp) {
+ *buf = *sp;
+ buf++;
+ sp++;
+ n++;
+ if (siz - 1 <= n) {
+ break;
+ }
+ }
+ *buf = '\0';
+ return n;
+}
+
+/**
+ * @brief 読み出しポインタを次に進める。
+ *
+ * @param p テキストヒストリ構造体。
+ */
+int text_history_read_point_next(text_history_t *p)
+{
+ int n = (p->rp + 1) % TEXTHISTORY_DEPTH;
+ if (n != p->wp) {
+ p->rp = n;
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * @brief 読み出しポインタを前に戻す。
+ *
+ * @param p テキストヒストリ構造体。
+ */
+int text_history_read_point_prev(text_history_t *p)
+{
+ int n = (p->rp == 0) ? (TEXTHISTORY_DEPTH - 1) : (p->rp - 1);
+ if (n != p->wp) {
+ char *sp = p->history + (TEXTHISTORY_MAXLEN * n);
+ if (*sp != '\0') {
+ p->rp = n;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/**
+ * @brief 与えられたテキストで始まる文字列を探す。
+ * @details このインターフェースはテキスト入力補完のために作られた。
+ *
+ * @param p テキストヒストリオブジェクト。
+ * @param index ヒストリ中で見つかる文字列のindex個目。
+ * @param text 検索する文字列。
+ * @param buf 格納先バッファ。
+ * @param siz 格納先バッファサイズ。
+ *
+ * @retval 0 成功。
+ * @retval 0以外 失敗。
+ */
+int text_history_find(text_history_t *p,
+ const int index, const char *text,
+ char *buf, const int siz)
+{
+ const int text_len = ntlibc_strlen((const char *)text);
+ int found = 0;
+ int i;
+ for (i = 0; i < TEXTHISTORY_DEPTH; i++) {
+ int target = (p->rp + i) % TEXTHISTORY_DEPTH;
+ char *txtp = p->history + (TEXTHISTORY_MAXLEN * target);
+ const int target_len = ntlibc_strlen((const char *)txtp);
+ int comp_len = (target_len < text_len) ? target_len : text_len;
+ if ((ntlibc_strncmp(
+ (const char *)txtp,
+ (const char *)text, comp_len) == 0) && (comp_len > 0)) {
+ if (found == index) {
+ ntlibc_strcpy((char *)buf, (char *)txtp);
+ return 0;
+ }
+ found++;
+ }
+ }
+ return -1;
+}
+
--- /dev/null
+/**
+ * @file text_history.h
+ * @author Shinichiro Nakamura
+ * @brief NT-Shell用テキストヒストリモジュールの定義。
+ * @details
+ * 文字列の入力履歴を論理的に扱うためのモジュール。
+ * このモジュールはビューに関して一切感知しない。
+ */
+
+/*
+ * ===============================================================
+ * Natural Tiny Shell (NT-Shell)
+ * Version 0.0.7
+ * ===============================================================
+ * Copyright (c) 2010-2011 Shinichiro Nakamura
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ * ===============================================================
+ */
+
+#ifndef TEXT_HISTORY_H
+#define TEXT_HISTORY_H
+
+#define TEXTHISTORY_MAXLEN 64 /**< テキストヒストリあたりの最大文字列長。 */
+#define TEXTHISTORY_DEPTH 8 /**< テキストヒストリのヒストリ数。 */
+
+/**
+ * @brief テキストヒストリ構造体。
+ */
+typedef struct {
+ char history[TEXTHISTORY_MAXLEN * TEXTHISTORY_DEPTH];
+ int rp;
+ int wp;
+} text_history_t;
+
+void text_history_init(text_history_t *p);
+int text_history_write(text_history_t *p, char *buf);
+int text_history_read(text_history_t *p, char *buf, const int siz);
+int text_history_read_point_next(text_history_t *p);
+int text_history_read_point_prev(text_history_t *p);
+int text_history_find(text_history_t *p,
+ const int index, const char *text,
+ char *buf, const int siz);
+
+#endif
+
--- /dev/null
+/**
+ * @file vtparse.c
+ * @brief VTParse
+ * @details
+ * An implementation of Paul Williams' DEC compatible state machine parser
+ * This code is in the public domain.
+ * @author Joshua Haberman <joshua@reverberate.org>
+ */
+
+#include "vtparse.h"
+#include "vtparse_table.h"
+#include "ntlibc.h"
+
+void vtparse_init(vtparse_t *parser, vtparse_callback_t cb)
+{
+ parser->state = VTPARSE_STATE_GROUND;
+ parser->intermediate_chars[0] = '\0';
+ parser->num_params = 0;
+ parser->ignore_flagged = 0;
+ parser->cb = cb;
+}
+
+static void do_action(vtparse_t *parser, vtparse_action_t action, char ch)
+{
+ /* Some actions we handle internally (like parsing parameters), others
+ * we hand to our client for processing */
+
+ switch(action) {
+ case VTPARSE_ACTION_PRINT:
+ case VTPARSE_ACTION_EXECUTE:
+ case VTPARSE_ACTION_HOOK:
+ case VTPARSE_ACTION_PUT:
+ case VTPARSE_ACTION_OSC_START:
+ case VTPARSE_ACTION_OSC_PUT:
+ case VTPARSE_ACTION_OSC_END:
+ case VTPARSE_ACTION_UNHOOK:
+ case VTPARSE_ACTION_CSI_DISPATCH:
+ case VTPARSE_ACTION_ESC_DISPATCH:
+ parser->cb(parser, action, ch);
+ break;
+
+ case VTPARSE_ACTION_IGNORE:
+ /* do nothing */
+ break;
+
+ case VTPARSE_ACTION_COLLECT:
+ {
+ /* Append the character to the intermediate params */
+ int num_intermediate_chars = ntlibc_strlen((char*)parser->intermediate_chars);
+
+ if(num_intermediate_chars + 1 > MAX_INTERMEDIATE_CHARS)
+ parser->ignore_flagged = 1;
+ else
+ parser->intermediate_chars[num_intermediate_chars++] = ch;
+
+ break;
+ }
+
+ case VTPARSE_ACTION_PARAM:
+ {
+ /* process the param character */
+ if(ch == ';')
+ {
+ parser->num_params += 1;
+ parser->params[parser->num_params-1] = 0;
+ }
+ else
+ {
+ /* the character is a digit */
+ int current_param;
+
+ if(parser->num_params == 0)
+ {
+ parser->num_params = 1;
+ parser->params[0] = 0;
+ }
+
+ current_param = parser->num_params - 1;
+ parser->params[current_param] *= 10;
+ parser->params[current_param] += (ch - '0');
+ }
+
+ break;
+ }
+
+ case VTPARSE_ACTION_CLEAR:
+ parser->intermediate_chars[0] = '\0';
+ parser->num_params = 0;
+ parser->ignore_flagged = 0;
+ break;
+
+ default:
+ // Internal error: Unknown action.
+ break;
+ }
+}
+
+static void do_state_change(vtparse_t *parser, state_change_t change, char ch)
+{
+ /* A state change is an action and/or a new state to transition to. */
+
+ vtparse_state_t new_state = STATE(change);
+ vtparse_action_t action = ACTION(change);
+
+
+ if(new_state)
+ {
+ /* Perform up to three actions:
+ * 1. the exit action of the old state
+ * 2. the action associated with the transition
+ * 3. the entry actionk of the new action
+ */
+
+ vtparse_action_t exit_action = GET_EXIT_ACTIONS(parser->state);
+ vtparse_action_t entry_action = GET_ENTRY_ACTIONS(new_state);
+
+ if(exit_action)
+ do_action(parser, exit_action, 0);
+
+ if(action)
+ do_action(parser, action, ch);
+
+ if(entry_action)
+ do_action(parser, entry_action, 0);
+
+ parser->state = new_state;
+ }
+ else
+ {
+ do_action(parser, action, ch);
+ }
+}
+
+void vtparse(vtparse_t *parser, unsigned char *data, int len)
+{
+ int i;
+ for(i = 0; i < len; i++)
+ {
+ unsigned char ch = data[i];
+
+ /* If a transition is defined from the "anywhere" state, always
+ * use that. Otherwise use the transition from the current state. */
+
+ state_change_t change = GET_STATE_TABLE(VTPARSE_STATE_ANYWHERE, ch);
+
+ if(!change)
+ change = GET_STATE_TABLE(parser->state, ch);
+
+ do_state_change(parser, change, data[i]);
+ }
+}
+
--- /dev/null
+/**
+ * @file vtparse.h
+ * @brief VTParse
+ * @details
+ * An implementation of Paul Williams' DEC compatible state machine parser
+ * This code is in the public domain.
+ * @author Joshua Haberman <joshua@reverberate.org>
+ */
+
+#include "vtparse_table.h"
+
+#define MAX_INTERMEDIATE_CHARS 2
+#define ACTION(state_change) (vtparse_action_t)(state_change & 0x0F)
+#define STATE(state_change) (vtparse_state_t)(state_change >> 4)
+
+struct vtparse;
+
+typedef void (*vtparse_callback_t)(struct vtparse*, vtparse_action_t, unsigned char);
+
+typedef struct vtparse {
+ vtparse_state_t state;
+ vtparse_callback_t cb;
+ unsigned char intermediate_chars[MAX_INTERMEDIATE_CHARS+1];
+ char ignore_flagged;
+ int params[16];
+ int num_params;
+ void* user_data;
+} vtparse_t;
+
+void vtparse_init(vtparse_t *parser, vtparse_callback_t cb);
+void vtparse(vtparse_t *parser, unsigned char *data, int len);
+
--- /dev/null
+/**
+ * @file vtparse_table.c
+ * @brief VTParse
+ * @details
+ * An implementation of Paul Williams' DEC compatible state machine parser
+ * This code is in the public domain.
+ * @author Joshua Haberman <joshua@reverberate.org>
+ */
+
+#include "vtparse_table.h"
+
+static const char *ACTION_NAMES[] = {
+ "<no action>",
+ "CLEAR",
+ "COLLECT",
+ "CSI_DISPATCH",
+ "ESC_DISPATCH",
+ "EXECUTE",
+ "HOOK",
+ "IGNORE",
+ "OSC_END",
+ "OSC_PUT",
+ "OSC_START",
+ "PARAM",
+ "PRINT",
+ "PUT",
+ "UNHOOK",
+};
+
+static const char *STATE_NAMES[] = {
+ "ANYWHERE",
+ "CSI_ENTRY",
+ "CSI_IGNORE",
+ "CSI_INTERMEDIATE",
+ "CSI_PARAM",
+ "DCS_ENTRY",
+ "DCS_IGNORE",
+ "DCS_INTERMEDIATE",
+ "DCS_PARAM",
+ "DCS_PASSTHROUGH",
+ "ESCAPE",
+ "ESCAPE_INTERMEDIATE",
+ "GROUND",
+ "OSC_STRING",
+ "SOS_PM_APC_STRING",
+};
+
+static const state_change_t STATE_TABLE[15][256] = {
+ { /* VTPARSE_STATE_ANYWHERE */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+/*24 */ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+ 0,
+/*26 */ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*27 */ 0 | (VTPARSE_STATE_ESCAPE << 4),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+/*128*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*129*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*130*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*131*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*132*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*133*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*134*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*135*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*136*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*137*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*138*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*139*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*140*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*141*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*142*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*143*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*144*/ 0 | (VTPARSE_STATE_DCS_ENTRY << 4),
+/*145*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*146*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*147*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*148*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*149*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*150*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*151*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*152*/ 0 | (VTPARSE_STATE_SOS_PM_APC_STRING << 4),
+/*153*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*154*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*155*/ 0 | (VTPARSE_STATE_CSI_ENTRY << 4),
+/*156*/ VTPARSE_ACTION_EXECUTE | (VTPARSE_STATE_GROUND << 4),
+/*157*/ 0 | (VTPARSE_STATE_OSC_STRING << 4),
+/*158*/ 0 | (VTPARSE_STATE_SOS_PM_APC_STRING << 4),
+/*159*/ 0 | (VTPARSE_STATE_SOS_PM_APC_STRING << 4),
+ },
+ { /* VTPARSE_STATE_CSI_ENTRY */
+/*0 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*1 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*2 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*3 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*4 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*5 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*6 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*7 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*8 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*9 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*10 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*11 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*12 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*13 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*14 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*15 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*16 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*17 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*18 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*19 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*20 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*21 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*22 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*23 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+ 0,
+/*25 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+ 0,
+ 0,
+/*28 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*29 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*30 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*31 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*32 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*33 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*34 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*35 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*36 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*37 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*38 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*39 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*40 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*41 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*42 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*43 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*44 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*45 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*46 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*47 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*48 */ VTPARSE_ACTION_PARAM | (VTPARSE_STATE_CSI_PARAM << 4),
+/*49 */ VTPARSE_ACTION_PARAM | (VTPARSE_STATE_CSI_PARAM << 4),
+/*50 */ VTPARSE_ACTION_PARAM | (VTPARSE_STATE_CSI_PARAM << 4),
+/*51 */ VTPARSE_ACTION_PARAM | (VTPARSE_STATE_CSI_PARAM << 4),
+/*52 */ VTPARSE_ACTION_PARAM | (VTPARSE_STATE_CSI_PARAM << 4),
+/*53 */ VTPARSE_ACTION_PARAM | (VTPARSE_STATE_CSI_PARAM << 4),
+/*54 */ VTPARSE_ACTION_PARAM | (VTPARSE_STATE_CSI_PARAM << 4),
+/*55 */ VTPARSE_ACTION_PARAM | (VTPARSE_STATE_CSI_PARAM << 4),
+/*56 */ VTPARSE_ACTION_PARAM | (VTPARSE_STATE_CSI_PARAM << 4),
+/*57 */ VTPARSE_ACTION_PARAM | (VTPARSE_STATE_CSI_PARAM << 4),
+/*58 */ 0 | (VTPARSE_STATE_CSI_IGNORE << 4),
+/*59 */ VTPARSE_ACTION_PARAM | (VTPARSE_STATE_CSI_PARAM << 4),
+/*60 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_PARAM << 4),
+/*61 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_PARAM << 4),
+/*62 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_PARAM << 4),
+/*63 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_PARAM << 4),
+/*64 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*65 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*66 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*67 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*68 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*69 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*70 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*71 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*72 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*73 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*74 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*75 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*76 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*77 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*78 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*79 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*80 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*81 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*82 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*83 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*84 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*85 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*86 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*87 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*88 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*89 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*90 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*91 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*92 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*93 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*94 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*95 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*96 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*97 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*98 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*99 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*100*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*101*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*102*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*103*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*104*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*105*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*106*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*107*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*108*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*109*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*110*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*111*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*112*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*113*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*114*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*115*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*116*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*117*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*118*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*119*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*120*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*121*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*122*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*123*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*124*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*125*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*126*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*127*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+ },
+ { /* VTPARSE_STATE_CSI_IGNORE */
+/*0 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*1 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*2 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*3 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*4 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*5 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*6 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*7 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*8 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*9 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*10 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*11 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*12 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*13 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*14 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*15 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*16 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*17 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*18 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*19 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*20 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*21 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*22 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*23 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+ 0,
+/*25 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+ 0,
+ 0,
+/*28 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*29 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*30 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*31 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*32 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*33 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*34 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*35 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*36 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*37 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*38 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*39 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*40 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*41 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*42 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*43 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*44 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*45 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*46 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*47 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*48 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*49 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*50 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*51 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*52 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*53 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*54 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*55 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*56 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*57 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*58 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*59 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*60 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*61 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*62 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*63 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*64 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*65 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*66 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*67 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*68 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*69 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*70 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*71 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*72 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*73 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*74 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*75 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*76 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*77 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*78 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*79 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*80 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*81 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*82 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*83 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*84 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*85 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*86 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*87 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*88 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*89 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*90 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*91 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*92 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*93 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*94 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*95 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*96 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*97 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*98 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*99 */ 0 | (VTPARSE_STATE_GROUND << 4),
+/*100*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*101*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*102*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*103*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*104*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*105*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*106*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*107*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*108*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*109*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*110*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*111*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*112*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*113*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*114*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*115*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*116*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*117*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*118*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*119*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*120*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*121*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*122*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*123*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*124*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*125*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*126*/ 0 | (VTPARSE_STATE_GROUND << 4),
+/*127*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+ },
+ { /* VTPARSE_STATE_CSI_INTERMEDIATE */
+/*0 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*1 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*2 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*3 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*4 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*5 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*6 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*7 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*8 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*9 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*10 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*11 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*12 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*13 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*14 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*15 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*16 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*17 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*18 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*19 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*20 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*21 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*22 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*23 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+ 0,
+/*25 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+ 0,
+ 0,
+/*28 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*29 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*30 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*31 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*32 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*33 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*34 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*35 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*36 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*37 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*38 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*39 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*40 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*41 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*42 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*43 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*44 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*45 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*46 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*47 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*48 */ 0 | (VTPARSE_STATE_CSI_IGNORE << 4),
+/*49 */ 0 | (VTPARSE_STATE_CSI_IGNORE << 4),
+/*50 */ 0 | (VTPARSE_STATE_CSI_IGNORE << 4),
+/*51 */ 0 | (VTPARSE_STATE_CSI_IGNORE << 4),
+/*52 */ 0 | (VTPARSE_STATE_CSI_IGNORE << 4),
+/*53 */ 0 | (VTPARSE_STATE_CSI_IGNORE << 4),
+/*54 */ 0 | (VTPARSE_STATE_CSI_IGNORE << 4),
+/*55 */ 0 | (VTPARSE_STATE_CSI_IGNORE << 4),
+/*56 */ 0 | (VTPARSE_STATE_CSI_IGNORE << 4),
+/*57 */ 0 | (VTPARSE_STATE_CSI_IGNORE << 4),
+/*58 */ 0 | (VTPARSE_STATE_CSI_IGNORE << 4),
+/*59 */ 0 | (VTPARSE_STATE_CSI_IGNORE << 4),
+/*60 */ 0 | (VTPARSE_STATE_CSI_IGNORE << 4),
+/*61 */ 0 | (VTPARSE_STATE_CSI_IGNORE << 4),
+/*62 */ 0 | (VTPARSE_STATE_CSI_IGNORE << 4),
+/*63 */ 0 | (VTPARSE_STATE_CSI_IGNORE << 4),
+/*64 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*65 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*66 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*67 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*68 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*69 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*70 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*71 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*72 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*73 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*74 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*75 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*76 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*77 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*78 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*79 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*80 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*81 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*82 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*83 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*84 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*85 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*86 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*87 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*88 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*89 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*90 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*91 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*92 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*93 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*94 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*95 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*96 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*97 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*98 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*99 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*100*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*101*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*102*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*103*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*104*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*105*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*106*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*107*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*108*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*109*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*110*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*111*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*112*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*113*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*114*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*115*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*116*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*117*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*118*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*119*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*120*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*121*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*122*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*123*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*124*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*125*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*126*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*127*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+ },
+ { /* VTPARSE_STATE_CSI_PARAM */
+/*0 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*1 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*2 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*3 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*4 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*5 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*6 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*7 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*8 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*9 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*10 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*11 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*12 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*13 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*14 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*15 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*16 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*17 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*18 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*19 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*20 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*21 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*22 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*23 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+ 0,
+/*25 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+ 0,
+ 0,
+/*28 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*29 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*30 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*31 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*32 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*33 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*34 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*35 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*36 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*37 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*38 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*39 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*40 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*41 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*42 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*43 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*44 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*45 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*46 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*47 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_CSI_INTERMEDIATE << 4),
+/*48 */ VTPARSE_ACTION_PARAM | (0 << 4),
+/*49 */ VTPARSE_ACTION_PARAM | (0 << 4),
+/*50 */ VTPARSE_ACTION_PARAM | (0 << 4),
+/*51 */ VTPARSE_ACTION_PARAM | (0 << 4),
+/*52 */ VTPARSE_ACTION_PARAM | (0 << 4),
+/*53 */ VTPARSE_ACTION_PARAM | (0 << 4),
+/*54 */ VTPARSE_ACTION_PARAM | (0 << 4),
+/*55 */ VTPARSE_ACTION_PARAM | (0 << 4),
+/*56 */ VTPARSE_ACTION_PARAM | (0 << 4),
+/*57 */ VTPARSE_ACTION_PARAM | (0 << 4),
+/*58 */ 0 | (VTPARSE_STATE_CSI_IGNORE << 4),
+/*59 */ VTPARSE_ACTION_PARAM | (0 << 4),
+/*60 */ 0 | (VTPARSE_STATE_CSI_IGNORE << 4),
+/*61 */ 0 | (VTPARSE_STATE_CSI_IGNORE << 4),
+/*62 */ 0 | (VTPARSE_STATE_CSI_IGNORE << 4),
+/*63 */ 0 | (VTPARSE_STATE_CSI_IGNORE << 4),
+/*64 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*65 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*66 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*67 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*68 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*69 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*70 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*71 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*72 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*73 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*74 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*75 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*76 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*77 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*78 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*79 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*80 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*81 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*82 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*83 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*84 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*85 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*86 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*87 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*88 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*89 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*90 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*91 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*92 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*93 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*94 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*95 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*96 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*97 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*98 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*99 */ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*100*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*101*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*102*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*103*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*104*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*105*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*106*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*107*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*108*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*109*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*110*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*111*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*112*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*113*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*114*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*115*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*116*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*117*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*118*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*119*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*120*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*121*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*122*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*123*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*124*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*125*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*126*/ VTPARSE_ACTION_CSI_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*127*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+ },
+ { /* VTPARSE_STATE_DCS_ENTRY */
+/*0 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*1 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*2 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*3 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*4 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*5 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*6 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*7 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*8 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*9 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*10 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*11 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*12 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*13 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*14 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*15 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*16 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*17 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*18 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*19 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*20 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*21 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*22 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*23 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+ 0,
+/*25 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+ 0,
+ 0,
+/*28 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*29 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*30 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*31 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*32 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*33 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*34 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*35 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*36 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*37 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*38 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*39 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*40 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*41 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*42 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*43 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*44 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*45 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*46 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*47 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*48 */ VTPARSE_ACTION_PARAM | (VTPARSE_STATE_DCS_PARAM << 4),
+/*49 */ VTPARSE_ACTION_PARAM | (VTPARSE_STATE_DCS_PARAM << 4),
+/*50 */ VTPARSE_ACTION_PARAM | (VTPARSE_STATE_DCS_PARAM << 4),
+/*51 */ VTPARSE_ACTION_PARAM | (VTPARSE_STATE_DCS_PARAM << 4),
+/*52 */ VTPARSE_ACTION_PARAM | (VTPARSE_STATE_DCS_PARAM << 4),
+/*53 */ VTPARSE_ACTION_PARAM | (VTPARSE_STATE_DCS_PARAM << 4),
+/*54 */ VTPARSE_ACTION_PARAM | (VTPARSE_STATE_DCS_PARAM << 4),
+/*55 */ VTPARSE_ACTION_PARAM | (VTPARSE_STATE_DCS_PARAM << 4),
+/*56 */ VTPARSE_ACTION_PARAM | (VTPARSE_STATE_DCS_PARAM << 4),
+/*57 */ VTPARSE_ACTION_PARAM | (VTPARSE_STATE_DCS_PARAM << 4),
+/*58 */ 0 | (VTPARSE_STATE_DCS_IGNORE << 4),
+/*59 */ VTPARSE_ACTION_PARAM | (VTPARSE_STATE_DCS_PARAM << 4),
+/*60 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_PARAM << 4),
+/*61 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_PARAM << 4),
+/*62 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_PARAM << 4),
+/*63 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_PARAM << 4),
+/*64 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*65 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*66 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*67 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*68 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*69 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*70 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*71 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*72 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*73 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*74 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*75 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*76 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*77 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*78 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*79 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*80 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*81 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*82 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*83 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*84 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*85 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*86 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*87 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*88 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*89 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*90 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*91 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*92 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*93 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*94 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*95 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*96 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*97 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*98 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*99 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*100*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*101*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*102*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*103*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*104*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*105*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*106*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*107*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*108*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*109*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*110*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*111*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*112*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*113*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*114*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*115*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*116*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*117*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*118*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*119*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*120*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*121*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*122*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*123*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*124*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*125*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*126*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*127*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+ },
+ { /* VTPARSE_STATE_DCS_IGNORE */
+/*0 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*1 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*2 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*3 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*4 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*5 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*6 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*7 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*8 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*9 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*10 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*11 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*12 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*13 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*14 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*15 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*16 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*17 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*18 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*19 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*20 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*21 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*22 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*23 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+ 0,
+/*25 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+ 0,
+ 0,
+/*28 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*29 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*30 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*31 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*32 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*33 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*34 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*35 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*36 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*37 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*38 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*39 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*40 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*41 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*42 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*43 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*44 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*45 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*46 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*47 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*48 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*49 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*50 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*51 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*52 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*53 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*54 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*55 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*56 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*57 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*58 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*59 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*60 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*61 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*62 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*63 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*64 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*65 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*66 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*67 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*68 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*69 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*70 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*71 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*72 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*73 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*74 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*75 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*76 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*77 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*78 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*79 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*80 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*81 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*82 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*83 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*84 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*85 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*86 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*87 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*88 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*89 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*90 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*91 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*92 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*93 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*94 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*95 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*96 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*97 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*98 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*99 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*100*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*101*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*102*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*103*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*104*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*105*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*106*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*107*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*108*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*109*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*110*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*111*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*112*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*113*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*114*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*115*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*116*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*117*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*118*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*119*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*120*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*121*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*122*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*123*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*124*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*125*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*126*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*127*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+/*156*/ 0 | (VTPARSE_STATE_GROUND << 4),
+ },
+ { /* VTPARSE_STATE_DCS_INTERMEDIATE */
+/*0 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*1 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*2 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*3 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*4 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*5 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*6 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*7 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*8 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*9 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*10 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*11 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*12 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*13 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*14 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*15 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*16 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*17 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*18 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*19 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*20 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*21 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*22 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*23 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+ 0,
+/*25 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+ 0,
+ 0,
+/*28 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*29 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*30 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*31 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*32 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*33 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*34 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*35 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*36 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*37 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*38 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*39 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*40 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*41 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*42 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*43 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*44 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*45 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*46 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*47 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*48 */ 0 | (VTPARSE_STATE_DCS_IGNORE << 4),
+/*49 */ 0 | (VTPARSE_STATE_DCS_IGNORE << 4),
+/*50 */ 0 | (VTPARSE_STATE_DCS_IGNORE << 4),
+/*51 */ 0 | (VTPARSE_STATE_DCS_IGNORE << 4),
+/*52 */ 0 | (VTPARSE_STATE_DCS_IGNORE << 4),
+/*53 */ 0 | (VTPARSE_STATE_DCS_IGNORE << 4),
+/*54 */ 0 | (VTPARSE_STATE_DCS_IGNORE << 4),
+/*55 */ 0 | (VTPARSE_STATE_DCS_IGNORE << 4),
+/*56 */ 0 | (VTPARSE_STATE_DCS_IGNORE << 4),
+/*57 */ 0 | (VTPARSE_STATE_DCS_IGNORE << 4),
+/*58 */ 0 | (VTPARSE_STATE_DCS_IGNORE << 4),
+/*59 */ 0 | (VTPARSE_STATE_DCS_IGNORE << 4),
+/*60 */ 0 | (VTPARSE_STATE_DCS_IGNORE << 4),
+/*61 */ 0 | (VTPARSE_STATE_DCS_IGNORE << 4),
+/*62 */ 0 | (VTPARSE_STATE_DCS_IGNORE << 4),
+/*63 */ 0 | (VTPARSE_STATE_DCS_IGNORE << 4),
+/*64 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*65 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*66 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*67 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*68 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*69 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*70 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*71 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*72 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*73 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*74 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*75 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*76 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*77 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*78 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*79 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*80 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*81 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*82 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*83 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*84 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*85 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*86 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*87 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*88 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*89 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*90 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*91 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*92 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*93 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*94 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*95 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*96 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*97 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*98 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*99 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*100*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*101*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*102*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*103*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*104*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*105*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*106*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*107*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*108*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*109*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*110*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*111*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*112*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*113*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*114*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*115*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*116*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*117*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*118*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*119*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*120*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*121*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*122*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*123*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*124*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*125*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*126*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*127*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+ },
+ { /* VTPARSE_STATE_DCS_PARAM */
+/*0 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*1 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*2 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*3 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*4 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*5 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*6 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*7 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*8 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*9 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*10 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*11 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*12 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*13 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*14 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*15 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*16 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*17 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*18 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*19 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*20 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*21 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*22 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*23 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+ 0,
+/*25 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+ 0,
+ 0,
+/*28 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*29 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*30 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*31 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*32 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*33 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*34 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*35 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*36 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*37 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*38 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*39 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*40 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*41 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*42 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*43 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*44 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*45 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*46 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*47 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_DCS_INTERMEDIATE << 4),
+/*48 */ VTPARSE_ACTION_PARAM | (0 << 4),
+/*49 */ VTPARSE_ACTION_PARAM | (0 << 4),
+/*50 */ VTPARSE_ACTION_PARAM | (0 << 4),
+/*51 */ VTPARSE_ACTION_PARAM | (0 << 4),
+/*52 */ VTPARSE_ACTION_PARAM | (0 << 4),
+/*53 */ VTPARSE_ACTION_PARAM | (0 << 4),
+/*54 */ VTPARSE_ACTION_PARAM | (0 << 4),
+/*55 */ VTPARSE_ACTION_PARAM | (0 << 4),
+/*56 */ VTPARSE_ACTION_PARAM | (0 << 4),
+/*57 */ VTPARSE_ACTION_PARAM | (0 << 4),
+/*58 */ 0 | (VTPARSE_STATE_DCS_IGNORE << 4),
+/*59 */ VTPARSE_ACTION_PARAM | (0 << 4),
+/*60 */ 0 | (VTPARSE_STATE_DCS_IGNORE << 4),
+/*61 */ 0 | (VTPARSE_STATE_DCS_IGNORE << 4),
+/*62 */ 0 | (VTPARSE_STATE_DCS_IGNORE << 4),
+/*63 */ 0 | (VTPARSE_STATE_DCS_IGNORE << 4),
+/*64 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*65 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*66 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*67 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*68 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*69 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*70 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*71 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*72 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*73 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*74 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*75 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*76 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*77 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*78 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*79 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*80 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*81 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*82 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*83 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*84 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*85 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*86 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*87 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*88 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*89 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*90 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*91 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*92 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*93 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*94 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*95 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*96 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*97 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*98 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*99 */ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*100*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*101*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*102*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*103*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*104*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*105*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*106*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*107*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*108*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*109*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*110*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*111*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*112*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*113*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*114*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*115*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*116*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*117*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*118*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*119*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*120*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*121*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*122*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*123*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*124*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*125*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*126*/ 0 | (VTPARSE_STATE_DCS_PASSTHROUGH << 4),
+/*127*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+ },
+ { /* VTPARSE_STATE_DCS_PASSTHROUGH */
+/*0 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*1 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*2 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*3 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*4 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*5 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*6 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*7 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*8 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*9 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*10 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*11 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*12 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*13 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*14 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*15 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*16 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*17 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*18 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*19 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*20 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*21 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*22 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*23 */ VTPARSE_ACTION_PUT | (0 << 4),
+ 0,
+/*25 */ VTPARSE_ACTION_PUT | (0 << 4),
+ 0,
+ 0,
+/*28 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*29 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*30 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*31 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*32 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*33 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*34 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*35 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*36 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*37 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*38 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*39 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*40 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*41 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*42 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*43 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*44 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*45 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*46 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*47 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*48 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*49 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*50 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*51 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*52 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*53 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*54 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*55 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*56 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*57 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*58 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*59 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*60 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*61 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*62 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*63 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*64 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*65 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*66 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*67 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*68 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*69 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*70 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*71 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*72 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*73 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*74 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*75 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*76 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*77 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*78 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*79 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*80 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*81 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*82 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*83 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*84 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*85 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*86 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*87 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*88 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*89 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*90 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*91 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*92 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*93 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*94 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*95 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*96 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*97 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*98 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*99 */ VTPARSE_ACTION_PUT | (0 << 4),
+/*100*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*101*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*102*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*103*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*104*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*105*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*106*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*107*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*108*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*109*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*110*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*111*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*112*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*113*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*114*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*115*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*116*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*117*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*118*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*119*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*120*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*121*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*122*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*123*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*124*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*125*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*126*/ VTPARSE_ACTION_PUT | (0 << 4),
+/*127*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+/*156*/ 0 | (VTPARSE_STATE_GROUND << 4),
+ },
+ { /* VTPARSE_STATE_ESCAPE */
+/*0 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*1 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*2 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*3 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*4 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*5 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*6 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*7 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*8 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*9 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*10 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*11 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*12 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*13 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*14 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*15 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*16 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*17 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*18 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*19 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*20 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*21 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*22 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*23 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+ 0,
+/*25 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+ 0,
+ 0,
+/*28 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*29 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*30 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*31 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*32 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_ESCAPE_INTERMEDIATE << 4),
+/*33 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_ESCAPE_INTERMEDIATE << 4),
+/*34 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_ESCAPE_INTERMEDIATE << 4),
+/*35 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_ESCAPE_INTERMEDIATE << 4),
+/*36 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_ESCAPE_INTERMEDIATE << 4),
+/*37 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_ESCAPE_INTERMEDIATE << 4),
+/*38 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_ESCAPE_INTERMEDIATE << 4),
+/*39 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_ESCAPE_INTERMEDIATE << 4),
+/*40 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_ESCAPE_INTERMEDIATE << 4),
+/*41 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_ESCAPE_INTERMEDIATE << 4),
+/*42 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_ESCAPE_INTERMEDIATE << 4),
+/*43 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_ESCAPE_INTERMEDIATE << 4),
+/*44 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_ESCAPE_INTERMEDIATE << 4),
+/*45 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_ESCAPE_INTERMEDIATE << 4),
+/*46 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_ESCAPE_INTERMEDIATE << 4),
+/*47 */ VTPARSE_ACTION_COLLECT | (VTPARSE_STATE_ESCAPE_INTERMEDIATE << 4),
+/*48 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*49 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*50 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*51 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*52 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*53 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*54 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*55 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*56 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*57 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*58 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*59 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*60 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*61 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*62 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*63 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*64 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*65 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*66 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*67 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*68 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*69 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*70 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*71 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*72 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*73 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*74 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*75 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*76 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*77 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*78 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*79 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*80 */ 0 | (VTPARSE_STATE_DCS_ENTRY << 4),
+/*81 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*82 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*83 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*84 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*85 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*86 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*87 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*88 */ 0 | (VTPARSE_STATE_SOS_PM_APC_STRING << 4),
+/*89 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*90 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*91 */ 0 | (VTPARSE_STATE_CSI_ENTRY << 4),
+/*92 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*93 */ 0 | (VTPARSE_STATE_OSC_STRING << 4),
+/*94 */ 0 | (VTPARSE_STATE_SOS_PM_APC_STRING << 4),
+/*95 */ 0 | (VTPARSE_STATE_SOS_PM_APC_STRING << 4),
+/*96 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*97 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*98 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*99 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*100*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*101*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*102*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*103*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*104*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*105*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*106*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*107*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*108*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*109*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*110*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*111*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*112*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*113*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*114*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*115*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*116*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*117*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*118*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*119*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*120*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*121*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*122*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*123*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*124*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*125*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*126*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*127*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+ },
+ { /* VTPARSE_STATE_ESCAPE_INTERMEDIATE */
+/*0 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*1 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*2 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*3 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*4 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*5 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*6 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*7 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*8 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*9 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*10 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*11 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*12 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*13 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*14 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*15 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*16 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*17 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*18 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*19 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*20 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*21 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*22 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*23 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+ 0,
+/*25 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+ 0,
+ 0,
+/*28 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*29 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*30 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*31 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*32 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*33 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*34 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*35 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*36 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*37 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*38 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*39 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*40 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*41 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*42 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*43 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*44 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*45 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*46 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*47 */ VTPARSE_ACTION_COLLECT | (0 << 4),
+/*48 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*49 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*50 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*51 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*52 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*53 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*54 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*55 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*56 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*57 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*58 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*59 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*60 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*61 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*62 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*63 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*64 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*65 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*66 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*67 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*68 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*69 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*70 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*71 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*72 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*73 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*74 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*75 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*76 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*77 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*78 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*79 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*80 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*81 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*82 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*83 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*84 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*85 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*86 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*87 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*88 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*89 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*90 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*91 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*92 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*93 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*94 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*95 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*96 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*97 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*98 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*99 */ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*100*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*101*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*102*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*103*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*104*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*105*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*106*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*107*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*108*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*109*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*110*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*111*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*112*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*113*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*114*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*115*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*116*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*117*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*118*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*119*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*120*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*121*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*122*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*123*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*124*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*125*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*126*/ VTPARSE_ACTION_ESC_DISPATCH | (VTPARSE_STATE_GROUND << 4),
+/*127*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+ },
+ { /* VTPARSE_STATE_GROUND */
+/*0 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*1 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*2 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*3 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*4 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*5 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*6 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*7 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*8 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*9 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*10 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*11 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*12 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*13 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*14 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*15 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*16 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*17 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*18 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*19 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*20 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*21 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*22 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*23 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+ 0,
+/*25 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+ 0,
+ 0,
+/*28 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*29 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*30 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*31 */ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*32 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*33 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*34 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*35 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*36 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*37 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*38 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*39 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*40 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*41 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*42 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*43 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*44 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*45 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*46 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*47 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*48 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*49 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*50 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*51 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*52 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*53 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*54 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*55 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*56 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*57 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*58 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*59 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*60 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*61 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*62 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*63 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*64 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*65 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*66 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*67 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*68 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*69 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*70 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*71 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*72 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*73 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*74 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*75 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*76 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*77 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*78 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*79 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*80 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*81 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*82 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*83 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*84 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*85 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*86 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*87 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*88 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*89 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*90 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*91 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*92 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*93 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*94 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*95 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*96 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*97 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*98 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*99 */ VTPARSE_ACTION_PRINT | (0 << 4),
+/*100*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*101*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*102*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*103*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*104*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*105*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*106*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*107*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*108*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*109*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*110*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*111*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*112*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*113*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*114*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*115*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*116*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*117*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*118*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*119*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*120*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*121*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*122*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*123*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*124*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*125*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*126*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*127*/ VTPARSE_ACTION_PRINT | (0 << 4),
+/*128*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*129*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*130*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*131*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*132*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*133*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*134*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*135*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*136*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*137*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*138*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*139*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*140*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*141*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*142*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*143*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+ 0,
+/*145*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*146*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*147*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*148*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*149*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*150*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*151*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*152*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*153*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+/*154*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+ 0,
+/*156*/ VTPARSE_ACTION_EXECUTE | (0 << 4),
+ },
+ { /* VTPARSE_STATE_OSC_STRING */
+/*0 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*1 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*2 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*3 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*4 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*5 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*6 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*7 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*8 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*9 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*10 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*11 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*12 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*13 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*14 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*15 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*16 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*17 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*18 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*19 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*20 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*21 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*22 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*23 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+ 0,
+/*25 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+ 0,
+ 0,
+/*28 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*29 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*30 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*31 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*32 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*33 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*34 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*35 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*36 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*37 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*38 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*39 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*40 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*41 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*42 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*43 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*44 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*45 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*46 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*47 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*48 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*49 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*50 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*51 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*52 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*53 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*54 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*55 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*56 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*57 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*58 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*59 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*60 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*61 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*62 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*63 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*64 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*65 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*66 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*67 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*68 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*69 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*70 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*71 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*72 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*73 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*74 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*75 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*76 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*77 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*78 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*79 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*80 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*81 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*82 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*83 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*84 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*85 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*86 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*87 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*88 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*89 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*90 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*91 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*92 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*93 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*94 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*95 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*96 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*97 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*98 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*99 */ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*100*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*101*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*102*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*103*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*104*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*105*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*106*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*107*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*108*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*109*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*110*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*111*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*112*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*113*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*114*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*115*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*116*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*117*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*118*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*119*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*120*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*121*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*122*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*123*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*124*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*125*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*126*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+/*127*/ VTPARSE_ACTION_OSC_PUT | (0 << 4),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+/*156*/ 0 | (VTPARSE_STATE_GROUND << 4),
+ },
+ { /* VTPARSE_STATE_SOS_PM_APC_STRING */
+/*0 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*1 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*2 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*3 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*4 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*5 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*6 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*7 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*8 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*9 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*10 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*11 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*12 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*13 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*14 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*15 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*16 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*17 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*18 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*19 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*20 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*21 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*22 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*23 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+ 0,
+/*25 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+ 0,
+ 0,
+/*28 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*29 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*30 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*31 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*32 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*33 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*34 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*35 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*36 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*37 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*38 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*39 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*40 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*41 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*42 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*43 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*44 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*45 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*46 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*47 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*48 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*49 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*50 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*51 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*52 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*53 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*54 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*55 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*56 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*57 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*58 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*59 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*60 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*61 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*62 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*63 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*64 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*65 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*66 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*67 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*68 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*69 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*70 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*71 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*72 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*73 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*74 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*75 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*76 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*77 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*78 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*79 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*80 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*81 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*82 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*83 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*84 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*85 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*86 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*87 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*88 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*89 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*90 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*91 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*92 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*93 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*94 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*95 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*96 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*97 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*98 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*99 */ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*100*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*101*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*102*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*103*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*104*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*105*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*106*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*107*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*108*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*109*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*110*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*111*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*112*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*113*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*114*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*115*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*116*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*117*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*118*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*119*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*120*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*121*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*122*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*123*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*124*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*125*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*126*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+/*127*/ VTPARSE_ACTION_IGNORE | (0 << 4),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+/*156*/ 0 | (VTPARSE_STATE_GROUND << 4),
+ },
+};
+
+static const vtparse_action_t ENTRY_ACTIONS[] = {
+ (vtparse_action_t)0 /* none for ANYWHERE */,
+ VTPARSE_ACTION_CLEAR, /* CSI_ENTRY */
+ (vtparse_action_t)0 /* none for CSI_IGNORE */,
+ (vtparse_action_t)0 /* none for CSI_INTERMEDIATE */,
+ (vtparse_action_t)0 /* none for CSI_PARAM */,
+ VTPARSE_ACTION_CLEAR, /* DCS_ENTRY */
+ (vtparse_action_t)0 /* none for DCS_IGNORE */,
+ (vtparse_action_t)0 /* none for DCS_INTERMEDIATE */,
+ (vtparse_action_t)0 /* none for DCS_PARAM */,
+ VTPARSE_ACTION_HOOK, /* DCS_PASSTHROUGH */
+ VTPARSE_ACTION_CLEAR, /* ESCAPE */
+ (vtparse_action_t)0 /* none for ESCAPE_INTERMEDIATE */,
+ (vtparse_action_t)0 /* none for GROUND */,
+ VTPARSE_ACTION_OSC_START, /* OSC_STRING */
+ (vtparse_action_t)0 /* none for SOS_PM_APC_STRING */,
+};
+
+static const vtparse_action_t EXIT_ACTIONS[] = {
+ (vtparse_action_t)0 /* none for ANYWHERE */,
+ (vtparse_action_t)0 /* none for CSI_ENTRY */,
+ (vtparse_action_t)0 /* none for CSI_IGNORE */,
+ (vtparse_action_t)0 /* none for CSI_INTERMEDIATE */,
+ (vtparse_action_t)0 /* none for CSI_PARAM */,
+ (vtparse_action_t)0 /* none for DCS_ENTRY */,
+ (vtparse_action_t)0 /* none for DCS_IGNORE */,
+ (vtparse_action_t)0 /* none for DCS_INTERMEDIATE */,
+ (vtparse_action_t)0 /* none for DCS_PARAM */,
+ VTPARSE_ACTION_UNHOOK, /* DCS_PASSTHROUGH */
+ (vtparse_action_t)0 /* none for ESCAPE */,
+ (vtparse_action_t)0 /* none for ESCAPE_INTERMEDIATE */,
+ (vtparse_action_t)0 /* none for GROUND */,
+ VTPARSE_ACTION_OSC_END, /* OSC_STRING */
+ (vtparse_action_t)0 /* none for SOS_PM_APC_STRING */,
+};
+
+state_change_t GET_STATE_TABLE(const int state, const int ch)
+{
+ return STATE_TABLE[state][ch];
+}
+
+vtparse_action_t GET_ENTRY_ACTIONS(const int state)
+{
+ return ENTRY_ACTIONS[state];
+}
+
+vtparse_action_t GET_EXIT_ACTIONS(const int state)
+{
+ return EXIT_ACTIONS[state];
+}
+
+const char *GET_ACTION_NAMES(const int n)
+{
+ return ACTION_NAMES[n];
+}
+
+const char *GET_STATE_NAMES(const int n)
+{
+ return STATE_NAMES[n];
+}
+
--- /dev/null
+/**
+ * @file vtparse_table.h
+ * @brief VTParse
+ * @details
+ * An implementation of Paul Williams' DEC compatible state machine parser
+ * This code is in the public domain.
+ * @author Joshua Haberman <joshua@reverberate.org>
+ */
+
+#ifndef VTPARSE_TABLE_H
+#define VTPARSE_TABLE_H
+
+typedef enum {
+ VTPARSE_STATE_ANYWHERE = 0,
+ VTPARSE_STATE_CSI_ENTRY = 1,
+ VTPARSE_STATE_CSI_IGNORE = 2,
+ VTPARSE_STATE_CSI_INTERMEDIATE = 3,
+ VTPARSE_STATE_CSI_PARAM = 4,
+ VTPARSE_STATE_DCS_ENTRY = 5,
+ VTPARSE_STATE_DCS_IGNORE = 6,
+ VTPARSE_STATE_DCS_INTERMEDIATE = 7,
+ VTPARSE_STATE_DCS_PARAM = 8,
+ VTPARSE_STATE_DCS_PASSTHROUGH = 9,
+ VTPARSE_STATE_ESCAPE = 10,
+ VTPARSE_STATE_ESCAPE_INTERMEDIATE = 11,
+ VTPARSE_STATE_GROUND = 12,
+ VTPARSE_STATE_OSC_STRING = 13,
+ VTPARSE_STATE_SOS_PM_APC_STRING = 14,
+} vtparse_state_t;
+
+typedef enum {
+ VTPARSE_ACTION_CLEAR = 1,
+ VTPARSE_ACTION_COLLECT = 2,
+ VTPARSE_ACTION_CSI_DISPATCH = 3,
+ VTPARSE_ACTION_ESC_DISPATCH = 4,
+ VTPARSE_ACTION_EXECUTE = 5,
+ VTPARSE_ACTION_HOOK = 6,
+ VTPARSE_ACTION_IGNORE = 7,
+ VTPARSE_ACTION_OSC_END = 8,
+ VTPARSE_ACTION_OSC_PUT = 9,
+ VTPARSE_ACTION_OSC_START = 10,
+ VTPARSE_ACTION_PARAM = 11,
+ VTPARSE_ACTION_PRINT = 12,
+ VTPARSE_ACTION_PUT = 13,
+ VTPARSE_ACTION_UNHOOK = 14,
+} vtparse_action_t;
+
+typedef unsigned char state_change_t;
+
+state_change_t GET_STATE_TABLE(const int state, const int ch);
+vtparse_action_t GET_ENTRY_ACTIONS(const int state);
+vtparse_action_t GET_EXIT_ACTIONS(const int state);
+const char *GET_ACTION_NAMES(const int n);
+const char *GET_STATE_NAMES(const int n);
+
+#endif
+