blob: f5c2ece3132690e88a2888bfe0e4b736007faae3 [file] [log] [blame]
#! /usr/bin/env python
#
# sysgen.py - System Generator
#
#
# Copyright (c) 2015, Wind River Systems, Inc.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1) Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2) Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# 3) Neither the name of Wind River Systems nor the names of its contributors
# may be used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# Required arguments:
# - name of VPF file
# Generates:
# - kernel_main.c file
# - microkernel_objects.h file
# - vxmicro.h file
import os
import sys
# input-related variables
num_kargs = 0
num_timers = 0
task_list = [ ]
event_list = [ ]
mutex_list = [ ]
sema_list = [ ]
fifo_list = [ ]
pipe_list = [ ]
mbx_list = [ ]
map_list = [ ]
pool_list = [ ]
driver_list = [ ]
group_dictionary = { }
group_key_list = [ ]
# output-related variables
kernel_main_c_data = ""
vxmicro_h_data = ""
micro_objs_h_data = ""
def get_output_dir():
if len(sys.argv) > 2:
return sys.argv[2]
else:
return ""
output_dir = get_output_dir()
# Parse VPF file
def vpf_parse():
global num_kargs
global num_timers
# open file for reading
with open(sys.argv[1], 'r') as infile:
# read file contents
data = infile.read()
# create list of the lines, breaking at line boundaries
my_list = data.splitlines()
# process each line
for line in my_list:
words = line.split()
if (len(words) == 0) :
continue # ignore blank line
if (words[0][0] == "%") :
continue # ignore comment line
if (words[0] == "CONFIG") :
num_kargs = int(words[1])
num_timers = int(words[2])
continue
if (words[0] == "TASK") :
task_list.append( (words[1], int(words[2]), words[3],
int(words[4]), words[5]) )
continue
if (words[0] == "TASKGROUP") :
if group_dictionary.has_key(words[1]) :
continue # ignore re-definition of a task group
group_bitmask = 1 << len(group_dictionary)
group_dictionary[words[1]] = group_bitmask
group_key_list.append( words[1] )
continue
if (words[0] == "EVENT") :
event_list.append( (words[1], words[2]) )
continue
if (words[0] == "SEMA") :
sema_list.append( (words[1], ) )
continue
if (words[0] == "MUTEX") :
mutex_list.append( (words[1], ) )
continue
if (words[0] == "FIFO") :
fifo_list.append( (words[1], int(words[2]), int(words[3])) )
continue
if (words[0] == "PIPE") :
pipe_list.append( (words[1], int(words[2])) )
continue
if (words[0] == "MAILBOX") :
mbx_list.append( (words[1], ) )
continue
if (words[0] == "MAP") :
map_list.append( (words[1], int(words[2]), int(words[3])) )
continue
if (words[0] == "POOL") :
pool_list.append( (words[1], int(words[2]), int(words[3]),
int(words[4])) )
continue
if (words[0] == "TIMERDRIVER") :
start_quote = line.find("'")
end_quote = line.rfind("'")
driver_list.append( line[start_quote+1:end_quote] )
continue
if (words[0] == "USERDRIVER") :
start_quote = line.find("'")
end_quote = line.rfind("'")
driver_list.append( line[start_quote+1:end_quote] )
continue
print "UNRECOGNIZED INPUT LINE"
print words # display any unrecognized line
# Generate miscellaneous global variables
kernel_main_c_filename_str = \
"/* kernel_main.c - microkernel mainline and kernel objects */\n\n"
do_not_edit_warning = \
"\n\n\n/* THIS FILE IS AUTOGENERATED -- DO NOT MODIFY! */\n\n\n"
copyright = \
"/*\n" + \
" * Copyright (c) 2015 Wind River Systems, Inc.\n" + \
" *\n" + \
" * Redistribution and use in source and binary forms, with or without\n" + \
" * modification, are permitted provided that the following conditions are met:\n" + \
" *\n" + \
" * 1) Redistributions of source code must retain the above copyright notice,\n" + \
" * this list of conditions and the following disclaimer.\n" + \
" *\n" + \
" * 2) Redistributions in binary form must reproduce the above copyright notice,\n" + \
" * this list of conditions and the following disclaimer in the documentation\n" + \
" * and/or other materials provided with the distribution.\n" + \
" *\n" + \
" * 3) Neither the name of Wind River Systems nor the names of its contributors\n" + \
" * may be used to endorse or promote products derived from this software without\n" + \
" * specific prior written permission.\n" + \
" *\n" + \
" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n" + \
" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n" + \
" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n" + \
" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\n" + \
" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n" + \
" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n" + \
" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n" + \
" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n" + \
" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n" + \
" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n" + \
" * POSSIBILITY OF SUCH DAMAGE.\n" + \
" */\n"
def kernel_main_c_general():
kernel_main_c_out(
kernel_main_c_filename_str +
copyright +
do_not_edit_warning +
"\n" +
"#include <microkernel.h>\n" +
"#include <k_boot.h>\n" +
"#include <toolchain.h>\n" +
"#include <sections.h>\n" +
"#include <vxmicro.h>")
kernel_main_c_out("\nconst knode_t K_ThisNode = 0x00010000;")
kernel_main_c_out("\nchar __noinit _minik_stack[CONFIG_MICROKERNEL_SERVER_STACK_SIZE];")
kernel_main_c_out("int K_StackSize = CONFIG_MICROKERNEL_SERVER_STACK_SIZE;")
# Generate command packet variables
def kernel_main_c_kargs():
# command packets
kernel_main_c_out("\n" +
"struct k_args K_ArgsBlocks[%s] =\n" % (num_kargs) +
"{\n" +
" {NULL, NULL, 0, 0, 0, (K_COMM) UNDEFINED},")
for i in range(1, num_kargs-1):
kernel_main_c_out(
" {&K_ArgsBlocks[%d], NULL, 0, 0, 0, (K_COMM) UNDEFINED}," %
(i-1))
kernel_main_c_out(
" {&K_ArgsBlocks[%d], NULL, 0, 0, 0, (K_COMM) UNDEFINED}" %
(num_kargs-2) +
"\n};")
# linked list of free command packets
kernel_main_c_out("\n" +
"struct nano_lifo K_ArgsFree = " +
"{(void *) &K_ArgsBlocks[%d], NULL};" % (num_kargs-1))
# Generate timer system variables
def kernel_main_c_timers():
# timer descriptors
kernel_main_c_out("\n" +
"K_TIMER K_TimerBlocks[%d] =\n" % (num_timers) +
"{\n" +
" {NULL, NULL, 0, 0, (struct k_args *)0xffffffff},")
for i in range(1, num_timers-1):
kernel_main_c_out(
" {&K_TimerBlocks[%d], NULL, 0, 0, (struct k_args *)0xffffffff}," % (i-1))
kernel_main_c_out(
" {&K_TimerBlocks[%d], NULL, 0, 0, (struct k_args *)0xffffffff}\n" % (num_timers-2) +
"};")
# linked list of free timers
kernel_main_c_out("\n" +
"struct nano_lifo K_TimerFree = " +
"{(void *) &K_TimerBlocks[%d], NULL};" % (num_timers-1))
# Generate task variables
def kernel_main_c_tasks():
total_tasks = len(task_list) + 1
# task global variables
kernel_main_c_out("int K_TaskCount = %d;" % (total_tasks - 1));
# task stack areas
kernel_main_c_out("");
for task in task_list:
kernel_main_c_out("char __noinit __%s_stack[%d];" % (task[0], task[3]))
# task descriptors (including one for idle task)
kernel_main_c_out("\n" +
"struct k_proc K_TaskList[%d] =\n" % (total_tasks) +
"{")
ident = 0x00010000
for task in task_list:
prio = task[1]
entry = task[2]
size = task[3]
stack = "__" + task[0] + "_stack"
# create bitmask of group(s) task belongs to
group_bitmask = 0
group_set = task[4][1:len(task[4])-1] # drop [] surrounding groups
if (group_set != ""):
group_list = group_set.split(',')
for group in group_list:
group_bitmask |= group_dictionary[group]
# invert bitmask to convert SYS indication to non-SYS indication
#
# NOTE: There actually is no SYS group; instead, there is a non-SYS
# group that all tasks belong to unless they specify the 'SYS' name.
# This approach allows the kernel to easily suspend all non-SYS tasks
# during debugging, while minimizing the number of task entries that
# have to explicitly indicate their SYS/non-SYS status.
group_bitmask ^= group_dictionary['SYS']
kernel_main_c_out(
" {NULL, NULL, %d, %#010x, " % (prio, ident) +
"0x00000001, %#010x,\n" % (group_bitmask) +
"%s, %s, %d, (taskabortfunction)NULL}," % (entry, stack, size))
ident += 1
kernel_main_c_out(" {NULL, NULL, 63, 0x00000000, " +
"0x00000000, 0x00000000,\n" +
"(taskstartfunction)NULL, NULL, 0, (taskabortfunction)NULL}")
kernel_main_c_out("};")
# currently scheduled task (idle task)
kernel_main_c_out("\n" +
"struct k_proc * K_Task = &K_TaskList[%d];" % (total_tasks - 1))
# Generate task scheduling variables
def kernel_main_c_priorities():
num_prios = 64
total_tasks = len(task_list) + 1
# priority queue descriptors (lowest priority queue contains idle task)
kernel_main_c_out("\n" +
"struct k_tqhd K_PrioList[%d] =\n" % (num_prios) +
"{")
for i in range(1, num_prios):
kernel_main_c_out(" {NULL, (struct k_proc *)&K_PrioList[%d]}," % (i-1))
kernel_main_c_out(
" {&K_TaskList[%d], &K_TaskList[%d]}\n" %
(total_tasks - 1, total_tasks - 1) +
"};")
# active priority queue (idle task's queue)
kernel_main_c_out("\n" +
"struct k_tqhd * K_Prio = &K_PrioList[%d];" % (num_prios-1))
# Generate event variables
def kernel_main_c_events():
total_events = 4 + len(event_list)
# event descriptors
kernel_main_c_out("\n" +
"struct evstr EVENTS[%d] =\n" % (total_events) +
"{")
# pre-defined events
kernel_main_c_out(
" {0, (kevent_handler_t)K_ticker, (struct k_args *)NULL, 0},\n" +
" {0, (kevent_handler_t)NULL, (struct k_args *)NULL, 0},\n" +
" {0, (kevent_handler_t)NULL, (struct k_args *)NULL, 0},\n" +
" {0, (kevent_handler_t)NULL, (struct k_args *)NULL, 0},"
)
# project-specific events
for event in event_list:
kernel_main_c_out(
" {0, (kevent_handler_t)%s, (struct k_args *)NULL, 0}," %
(event[1]))
kernel_main_c_out("};")
# number of events
kernel_main_c_out("\n" +
"const int K_max_eventnr = %d;" % (total_events))
# event object identifiers
kernel_main_c_out("")
for event_name in event_list:
kernel_main_c_out(
"const kevent_t %s_objId = %s;" %
(event_name[0], event_name[0]))
# Generate mutex variables
def kernel_main_c_mutexes():
total_mutexes = len(mutex_list)
if (total_mutexes == 0) :
kernel_main_c_out("\nstruct mutex_struct * K_MutexList = NULL;");
return
# mutex descriptors
kernel_main_c_out("\n" +
"struct mutex_struct K_MutexList[%s] =\n" % (total_mutexes) +
"{")
for mutex in mutex_list:
kernel_main_c_out(" {ANYTASK, 64, 64, 0, NULL, 0, 0},")
kernel_main_c_out("};")
kernel_main_c_out("")
# mutex object identifiers
for mutex in mutex_list:
name = mutex[0]
kernel_main_c_out("const kmutex_t %s_objId = %s;" % (name, name))
# Generate semaphore variables
def kernel_main_c_semas():
total_semas = len(sema_list)
if (total_semas == 0) :
kernel_main_c_out("\nstruct sem_struct * K_SemList = NULL;");
return
# semaphore descriptors
kernel_main_c_out("\n" +
"struct sem_struct K_SemList[%s] =\n" % (total_semas) +
"{")
for semaphore in sema_list:
kernel_main_c_out(" {NULL, 0, 0},")
kernel_main_c_out("};")
# Generate FIFO variables
def kernel_main_c_fifos():
total_fifos = len(fifo_list)
if (total_fifos == 0) :
kernel_main_c_out("\nstruct que_struct * K_QueList = NULL;");
return
# FIFO buffers
kernel_main_c_out("")
for fifo in fifo_list:
kernel_main_c_out(
"char __noinit __%s_buffer[%d];" % (fifo[0], fifo[1] * fifo[2]))
# FIFO descriptors
kernel_main_c_out("\n" +
"struct que_struct K_QueList[%s] =\n" % (total_fifos) +
"{"
)
for fifo in fifo_list:
depth = fifo[1]
width = fifo[2]
buffer = "__" + fifo[0] + "_buffer"
kernel_main_c_out(
" {%d, %d, %s, %s + (%d * %d),\n" %
(depth, width, buffer, buffer, depth, width) +
"%s, %s, NULL, 0, 0, 0}," %
(buffer, buffer))
kernel_main_c_out("};")
# Generate pipe variables
def kernel_main_c_pipes():
total_pipes = len(pipe_list)
# pipe global variables
kernel_main_c_out("int K_PipeCount = %d;" % (total_pipes));
if (total_pipes == 0) :
kernel_main_c_out("\nstruct pipe_struct * K_PipeList = NULL;");
return
# pipe buffers
kernel_main_c_out("")
for pipe in pipe_list:
kernel_main_c_out("char __noinit __%s_buffer[%d];" % (pipe[0], pipe[1]))
# pipe descriptors
kernel_main_c_out("\n" +
"struct pipe_struct K_PipeList[%d] =\n" % (total_pipes) +
"{")
for pipe in pipe_list:
size = pipe[1]
buffer = "__" + pipe[0] + "_buffer"
kernel_main_c_out(" {%d, %s}," % (size, buffer))
kernel_main_c_out("};")
# pipe variables [should probably be eliminated]
kernel_main_c_out("\n" +
"PFN_CHANNEL_RW pHS_Channel_Put = (PFN_CHANNEL_RW)NULL;\n" +
"PFN_CHANNEL_RW pHS_Channel_PutW = (PFN_CHANNEL_RW)NULL;\n" +
"PFN_CHANNEL_RWT pHS_Channel_PutWT = (PFN_CHANNEL_RWT)NULL;\n" +
"PFN_CHANNEL_RW pHS_Channel_Get = (PFN_CHANNEL_RW)NULL;\n" +
"PFN_CHANNEL_RW pHS_Channel_GetW = (PFN_CHANNEL_RW)NULL;\n" +
"PFN_CHANNEL_RWT pHS_Channel_GetWT = (PFN_CHANNEL_RWT)NULL;\n" +
"PFN_CHANNEL_RWT pKS_Channel_PutWT = _task_pipe_put;\n" +
"PFN_CHANNEL_RWT pKS_Channel_GetWT = _task_pipe_get;")
# Generate mailbox variables
def kernel_main_c_mailboxes():
total_mbxs = len(mbx_list)
if (total_mbxs == 0) :
kernel_main_c_out("\nstruct mbx_struct * K_MbxList = NULL;");
return
# mailbox descriptors
kernel_main_c_out("\n" +
"struct mbx_struct K_MbxList[%d] =\n" % (total_mbxs) +
"{")
for mbx in mbx_list:
kernel_main_c_out(" {NULL, NULL, 0},")
kernel_main_c_out("};")
# Generate memory map variables
def kernel_main_c_maps():
total_maps = len(map_list)
# map global variables
kernel_main_c_out("int K_MapCount = %d;" % (total_maps));
if (total_maps == 0) :
kernel_main_c_out("\nstruct map_struct * K_MapList = NULL;");
return
# memory map buffers
kernel_main_c_out("")
for map in map_list:
blocks = map[1]
block_size = map[2]
kernel_main_c_out("char __noinit __MAP_%s_buffer[%d];" %
(map[0], blocks * block_size))
# memory map descriptors
kernel_main_c_out("\nstruct map_struct K_MapList[%d] =\n{" % (total_maps))
for map in map_list:
blocks = map[1]
block_size = map[2]
kernel_main_c_out(" { %d, %d, __MAP_%s_buffer }," %
(blocks, block_size, map[0]))
kernel_main_c_out("};")
# Generate memory pool variables
def kernel_main_c_pools():
total_pools = len(pool_list)
# pool global variables
kernel_main_c_out("\nint K_PoolCount = %d;" % (total_pools));
if (total_pools == 0) :
kernel_main_c_out("\nstruct pool_struct * K_PoolList = NULL;");
return
# start accumulating memory pool descriptor info
pool_descriptors = "\nstruct pool_struct K_PoolList[%d] =\n{\n" % \
(total_pools)
ident = 0x00010000
for pool in pool_list:
kernel_main_c_out("")
# create local variables relating to current pool
min_block_size = pool[1]
max_block_size = pool[2]
num_maximal_blocks = pool[3]
total_memory = max_block_size * num_maximal_blocks
buffer = "__" + pool[0] + "_buffer"
frag_table = "fragtab_%#010x" % ident
# determine block sizes used by pool (including actual minimum size)
frag_size_list = [ max_block_size ]
while (ident != 0) : # loop forever
min_block_size_actual = frag_size_list[len(frag_size_list)-1]
min_block_size_proposed = min_block_size_actual / 4
if (min_block_size_proposed < min_block_size) :
break
frag_size_list.append(min_block_size_proposed)
frag_levels = len(frag_size_list)
# determine size of block status arrays
# - largest size gets special handling
# - remainder of algorithm is a complete mystery ...
block_status_sizes = [ (num_maximal_blocks + 3) / 4 ]
block_status_size_to_use = num_maximal_blocks
for index in range(1, frag_levels):
block_status_sizes.append(block_status_size_to_use)
block_status_size_to_use *= 4
# generate block status areas
for index in range(0, frag_levels):
kernel_main_c_out("struct block_stat blockstatus_%#010x_%d[%d];" %
(ident, index, block_status_sizes[index]))
# generate memory pool fragmentation descriptor
kernel_main_c_out("\nstruct pool_block %s[%d] =\n{" %
(frag_table, frag_levels))
for index in range(0, frag_levels):
kernel_main_c_out(" { %d, %d, blockstatus_%#010x_%d}," %
(frag_size_list[index], block_status_sizes[index], ident, index))
kernel_main_c_out("};\n")
# generate memory pool buffer
kernel_main_c_out("char __noinit %s[%d];" % (buffer, total_memory))
# append memory pool descriptor info
pool_descriptors += " {%d, %d, 2, %d, %d, %d, NULL, %s, %s},\n" % \
(max_block_size, min_block_size_actual, total_memory,
num_maximal_blocks, frag_levels, frag_table, buffer)
ident += 1
# generate memory pool descriptor info
pool_descriptors += "};"
kernel_main_c_out(pool_descriptors)
# Generate kernel services function table
def kernel_main_c_kernel_services():
# initialize table with info for all possible kernel services
func_table = [
"/* 0 */ K_nop,", # required
"/* 1 */ K_mvdreq,", # required
"/* 2 */ (kernelfunc) NULL,", # unused
"/* 3 */ (kernelfunc) NULL,", # unused
"/* 4 */ K_offload,", # required
"/* 5 */ K_workload,", # required
"/* 6 */ K_signals,", # depends on semaphores
"/* 7 */ K_signalm,", # depends on semaphores
"/* 8 */ K_resets,", # depends on semaphores
"/* 9 */ K_resetm,", # depends on semaphores
"/* 10 */ K_waitsreq,", # depends on semaphores
"/* 11 */ K_waitsrpl,", # depends on semaphores
"/* 12 */ K_waitsrpl,", # depends on semaphores and timers
"/* 13 */ K_waitmany,", # depends on semaphores
"/* 14 */ K_waitmreq,", # depends on semaphores
"/* 15 */ K_waitmrdy,", # depends on semaphores
"/* 16 */ K_waitmcan,", # depends on semaphores
"/* 17 */ K_waitmacc,", # depends on semaphores
"/* 18 */ K_waitmend,", # depends on semaphores
"/* 19 */ K_waitmtmo,", # depends on semaphores and timers
"/* 20 */ K_inqsema,", # depends on semaphores
"/* 21 */ K_lockreq,", # depends on mutexes
"/* 22 */ K_lockrpl,", # depends on mutexes
"/* 23 */ K_lockrpl,", # depends on mutexes and timers
"/* 24 */ K_unlock,", # depends on mutexes
"/* 25 */ K_enqreq,", # depends on FIFOs
"/* 26 */ K_enqrpl,", # depends on FIFOs
"/* 27 */ K_enqrpl,", # depends on FIFOs and timers
"/* 28 */ K_deqreq,", # depends on FIFOs
"/* 29 */ K_deqrpl,", # depends on FIFOs
"/* 30 */ K_deqrpl,", # depends on FIFOs and timers
"/* 31 */ K_queue,", # depends on FIFOs
"/* 32 */ K_sendreq,", # depends on mailboxes
"/* 33 */ K_sendrpl,", # depends on mailboxes and timers
"/* 34 */ K_sendack,", # depends on mailboxes
"/* 35 */ K_senddata,", # depends on mailboxes
"/* 36 */ K_recvreq,", # depends on mailboxes
"/* 37 */ K_recvrpl,", # depends on mailboxes and timers
"/* 38 */ K_recvack,", # depends on mailboxes
"/* 39 */ K_recvdata,", # depends on mailboxes
"/* 40 */ K_elapse,", # required
"/* 41 */ K_sleep,", # depends on timers
"/* 42 */ K_wakeup,", # depends on timers
"/* 43 */ K_taskop,", # required
"/* 44 */ K_groupop,", # required
"/* 45 */ K_set_prio,", # required
"/* 46 */ K_yield,", # required
"/* 47 */ K_alloc,", # depends on memory maps
"/* 48 */ K_dealloc,", # depends on memory maps
"/* 49 */ K_alloc_timer,", # depends on timers
"/* 50 */ K_dealloc_timer,", # depends on timers
"/* 51 */ K_start_timer,", # depends on timers
"/* 52 */ K_stop_timer,", # depends on timers
"/* 53 */ K_alloctmo,", # depends on memory maps [and timers?]
"/* 54 */ (kernelfunc) NULL,", # unused
"/* 55 */ (kernelfunc) NULL,", # unused
"/* 56 */ (kernelfunc) NULL,", # unused
"/* 57 */ (kernelfunc) NULL,", # unused
"/* 58 */ K_event_test,", # required
"/* 59 */ K_event_set_handler,", # required
"/* 60 */ K_event_signal,", # required
"/* 61 */ K_GetBlock,", # depends on memory pools
"/* 62 */ K_RelBlock,", # depends on memory pools
"/* 63 */ K_GetBlock_Waiters,", # depends on memory pools
"/* 64 */ K_gtbltmo,", # depends on memory pools
"/* 65 */ K_Defrag,", # depends on memory pools
"/* 66 */ (kernelfunc) NULL,", # unused
"/* 67 */ (kernelfunc) NULL,", # unused
"/* 68 */ (kernelfunc) NULL,", # unused
"/* 69 */ (kernelfunc) NULL,", # unused
"/* 70 */ (kernelfunc) NULL,", # unused
"/* 71 */ (kernelfunc) NULL,", # unused
"/* 72 */ K_ChSendReq,", # depends on pipes
"/* 73 */ K_ChSendTmo,", # depends on pipes
"/* 74 */ K_ChSendRpl,", # depends on pipes
"/* 75 */ K_ChSendAck,", # depends on pipes
"/* 76 */ K_ChRecvReq,", # depends on pipes
"/* 77 */ K_ChRecvTmo,", # depends on pipes
"/* 78 */ K_ChRecvRpl,", # depends on pipes
"/* 79 */ K_ChRecvAck,", # depends on pipes
"/* 80 */ K_ChMovedAck,", # depends on pipes
"/* 81 */ K_eventtesttmo" # required
]
# eliminate table entries for kernel services that project doesn't utilize
# (note: some entries can be eliminated for more than one reason)
if (len(sema_list) == 0):
func_table[6] = "/* 6 */ (kernelfunc) NULL,"
func_table[7] = "/* 7 */ (kernelfunc) NULL,"
func_table[8] = "/* 8 */ (kernelfunc) NULL,"
func_table[9] = "/* 9 */ (kernelfunc) NULL,"
func_table[10] = "/* 10 */ (kernelfunc) NULL,"
func_table[11] = "/* 11 */ (kernelfunc) NULL,"
func_table[12] = "/* 12 */ (kernelfunc) NULL,"
func_table[13] = "/* 13 */ (kernelfunc) NULL,"
func_table[14] = "/* 14 */ (kernelfunc) NULL,"
func_table[15] = "/* 15 */ (kernelfunc) NULL,"
func_table[16] = "/* 16 */ (kernelfunc) NULL,"
func_table[17] = "/* 17 */ (kernelfunc) NULL,"
func_table[18] = "/* 18 */ (kernelfunc) NULL,"
func_table[19] = "/* 19 */ (kernelfunc) NULL,"
func_table[20] = "/* 20 */ (kernelfunc) NULL,"
if (len(mutex_list) == 0):
func_table[21] = "/* 21 */ (kernelfunc) NULL,"
func_table[22] = "/* 22 */ (kernelfunc) NULL,"
func_table[23] = "/* 23 */ (kernelfunc) NULL,"
func_table[24] = "/* 24 */ (kernelfunc) NULL,"
if (len(fifo_list) == 0):
func_table[25] = "/* 25 */ (kernelfunc) NULL,"
func_table[26] = "/* 26 */ (kernelfunc) NULL,"
func_table[27] = "/* 27 */ (kernelfunc) NULL,"
func_table[28] = "/* 28 */ (kernelfunc) NULL,"
func_table[29] = "/* 29 */ (kernelfunc) NULL,"
func_table[30] = "/* 30 */ (kernelfunc) NULL,"
func_table[31] = "/* 31 */ (kernelfunc) NULL,"
if (len(mbx_list) == 0):
func_table[32] = "/* 32 */ (kernelfunc) NULL,"
func_table[33] = "/* 33 */ (kernelfunc) NULL,"
func_table[34] = "/* 34 */ (kernelfunc) NULL,"
func_table[35] = "/* 35 */ (kernelfunc) NULL,"
func_table[36] = "/* 36 */ (kernelfunc) NULL,"
func_table[37] = "/* 37 */ (kernelfunc) NULL,"
func_table[38] = "/* 38 */ (kernelfunc) NULL,"
func_table[39] = "/* 39 */ (kernelfunc) NULL,"
if (len(map_list) == 0):
func_table[47] = "/* 47 */ (kernelfunc) NULL,"
func_table[48] = "/* 48 */ (kernelfunc) NULL,"
func_table[53] = "/* 53 */ (kernelfunc) NULL,"
if (len(pool_list) == 0):
func_table[61] = "/* 61 */ (kernelfunc) NULL,"
func_table[62] = "/* 62 */ (kernelfunc) NULL,"
func_table[63] = "/* 63 */ (kernelfunc) NULL,"
func_table[64] = "/* 64 */ (kernelfunc) NULL,"
func_table[65] = "/* 65 */ (kernelfunc) NULL,"
if (len(pipe_list) == 0):
func_table[72] = "/* 72 */ (kernelfunc) NULL,"
func_table[73] = "/* 73 */ (kernelfunc) NULL,"
func_table[74] = "/* 74 */ (kernelfunc) NULL,"
func_table[75] = "/* 75 */ (kernelfunc) NULL,"
func_table[76] = "/* 76 */ (kernelfunc) NULL,"
func_table[77] = "/* 77 */ (kernelfunc) NULL,"
func_table[78] = "/* 78 */ (kernelfunc) NULL,"
func_table[79] = "/* 79 */ (kernelfunc) NULL,"
func_table[80] = "/* 80 */ (kernelfunc) NULL,"
if (num_timers == 0):
func_table[12] = "/* 12 */ (kernelfunc) NULL,"
func_table[19] = "/* 19 */ (kernelfunc) NULL,"
func_table[23] = "/* 23 */ (kernelfunc) NULL,"
func_table[27] = "/* 27 */ (kernelfunc) NULL,"
func_table[30] = "/* 30 */ (kernelfunc) NULL,"
func_table[33] = "/* 33 */ (kernelfunc) NULL,"
func_table[37] = "/* 37 */ (kernelfunc) NULL,"
func_table[41] = "/* 41 */ (kernelfunc) NULL,"
func_table[42] = "/* 42 */ (kernelfunc) NULL,"
func_table[49] = "/* 49 */ (kernelfunc) NULL,"
func_table[50] = "/* 50 */ (kernelfunc) NULL,"
func_table[51] = "/* 51 */ (kernelfunc) NULL,"
func_table[52] = "/* 52 */ (kernelfunc) NULL,"
# generate function table
kernel_main_c_out("\n" +
"const kernelfunc _minik_func[82] =\n" +
"{")
for func in func_table:
kernel_main_c_out(" " + func)
kernel_main_c_out("};")
# Generate driver initialization routine
def kernel_main_c_driver_init():
kernel_main_c_out("\n" +
"void init_drivers(void)\n" +
"{")
for driver_call in driver_list:
kernel_main_c_out(" " + driver_call + ";")
kernel_main_c_out("}")
# Generate node initialization routine
def kernel_main_c_node_init():
kernel_main_c_out("\n" +
"void init_node(void)\n{")
if (len(pipe_list) > 0) :
kernel_main_c_out(" InitPipe();")
if (len(map_list) > 0) :
kernel_main_c_out(" InitMap();")
if (len(pool_list) > 0) :
kernel_main_c_out(" InitPools();")
kernel_main_c_out("}")
# Generate main() routine
def kernel_main_c_main():
kernel_main_c_out("\n" +
"void main(void)\n" +
"{\n" +
" kernel_init();\n" +
" task_group_start(EXE);\n" +
" kernel_idle();\n" +
"}")
# Append a string to kernel_main.c
def kernel_main_c_out(string):
global kernel_main_c_data
kernel_main_c_data += string + "\n"
def write_file(filename, contents):
f = open(filename, 'w') # overwrites it if it already exists
f.write(contents)
f.close()
# Generate kernel_main.c file
def kernel_main_c_generate():
global kernel_main_c_data
# create file contents
kernel_main_c_general()
kernel_main_c_kargs()
kernel_main_c_timers()
kernel_main_c_tasks()
kernel_main_c_priorities()
kernel_main_c_events()
kernel_main_c_mutexes()
kernel_main_c_semas()
kernel_main_c_fifos()
kernel_main_c_pipes()
kernel_main_c_mailboxes()
kernel_main_c_maps()
kernel_main_c_pools()
kernel_main_c_kernel_services()
kernel_main_c_driver_init()
kernel_main_c_node_init()
kernel_main_c_main()
write_file(output_dir + 'kernel_main.c', kernel_main_c_data)
# Generate microkernel_objects.h file
micro_objs_h_filename_str = \
"/* microkernel_objects.h - microkernel objects */\n\n"
micro_objs_h_include_guard = "_MICROKERNEL_OBJECTS__H_"
micro_objs_h_header_include_guard_str = \
"#ifndef " + micro_objs_h_include_guard + "\n" \
"#define " + micro_objs_h_include_guard + "\n\n"
def generate_micro_objs_h_header():
global micro_objs_h_data
micro_objs_h_data += \
micro_objs_h_filename_str + \
copyright + \
do_not_edit_warning + \
micro_objs_h_header_include_guard_str
micro_objs_h_footer_include_guard_str = \
"\n#endif /* " + micro_objs_h_include_guard + " */\n"
def generate_micro_objs_h_footer():
global micro_objs_h_data
micro_objs_h_data += \
micro_objs_h_footer_include_guard_str
def generate_taskgroup_line(taskgroup, group_id):
global micro_objs_h_data
micro_objs_h_data += \
"#define " + taskgroup + " 0x%8.8x\n" % group_id
def generate_micro_objs_h_taskgroups():
for group in group_key_list:
generate_taskgroup_line(group, group_dictionary[group])
def generate_micro_objs_h_nodes():
global micro_objs_h_data
micro_objs_h_data += \
"\n#define NODE1 0x00010000\n\n"
def generate_obj_id_line(name, obj_id):
return "#define " + name + " 0x0001%4.4x\n" % obj_id
def generate_obj_id_lines(obj_types):
data = ""
for obj_type in obj_types:
for obj in obj_type[0]:
data += generate_obj_id_line(str(obj[0]), obj_type[1])
obj_type[1] += 1
if obj_type[1] > 0:
data += "\n"
return data
def generate_micro_objs_h_obj_ids():
global micro_objs_h_data
obj_types = [
[task_list, 0],
[mutex_list, 0],
[sema_list, 0],
[fifo_list, 0],
[pipe_list, 0],
[mbx_list, 0],
[pool_list, 0],
]
micro_objs_h_data += generate_obj_id_lines(obj_types)
def generate_micro_objs_h_misc():
global micro_objs_h_data
micro_objs_h_data += "\n" + \
"#define TICKFREQ 1000\n" + \
"#define DATALEN 32768\n" + \
"#define CEILING_PRIO 5\n" + \
"#define KERNEL_PRIO 0\n" + \
"#define DRIVER_PRIO 1\n" + \
"#define TICKTIME 1000\n"
def micro_objs_h_generate():
generate_micro_objs_h_header()
generate_micro_objs_h_taskgroups()
generate_micro_objs_h_nodes()
generate_micro_objs_h_obj_ids()
generate_micro_objs_h_misc() # XXX - remove when ready
generate_micro_objs_h_footer()
write_file(output_dir + 'microkernel_objects.h', micro_objs_h_data)
vxmicro_h_filename_str = \
"/* vxmicro.h - microkernel master header file */\n\n"
vxmicro_h_include_guard = "_VXMICRO__H_"
vxmicro_h_header_include_guard_str = \
"#ifndef " + vxmicro_h_include_guard + "\n" \
"#define " + vxmicro_h_include_guard + "\n\n"
def generate_vxmicro_h_header():
global vxmicro_h_data
vxmicro_h_data += \
vxmicro_h_filename_str + \
copyright + \
do_not_edit_warning + \
vxmicro_h_header_include_guard_str + \
"#include <microkernel.h>\n" + \
"#include <microkernel_objects.h>\n"
def generate_vxmicro_h_misc():
global vxmicro_h_data
vxmicro_h_data += "\n" + \
"extern const int K_max_eventnr;\n" + \
"extern struct evstr EVENTS[];\n\n"
def generate_vxmicro_h_obj_ids():
global vxmicro_h_data
base_event = 4 # events start at 4
event_id = base_event
for event in event_list:
vxmicro_h_data += "#define %s %u\n" % (str(event[0]), event_id)
event_id += 1
if event_id > base_event:
vxmicro_h_data += "\n"
obj_types = [
[map_list, 0],
]
vxmicro_h_data += generate_obj_id_lines(obj_types)
vxmicro_h_footer_include_guard_str = \
"\n#endif /* " + vxmicro_h_include_guard + " */\n"
def generate_vxmicro_h_task_entry_points():
global vxmicro_h_data
for task in task_list:
vxmicro_h_data += "extern void %s(void);\n" % task[2]
def generate_vxmicro_h_footer():
global vxmicro_h_data
vxmicro_h_data += \
vxmicro_h_footer_include_guard_str
# Generate vxmicro.h file
def vxmicro_h_generate():
generate_vxmicro_h_header()
generate_vxmicro_h_misc()
generate_vxmicro_h_obj_ids()
generate_vxmicro_h_task_entry_points()
generate_vxmicro_h_footer()
write_file(output_dir + 'vxmicro.h', vxmicro_h_data)
# System generator mainline
vpf_parse()
kernel_main_c_generate()
vxmicro_h_generate()
micro_objs_h_generate()