mirror of
https://github.com/kelvinlawson/atomthreads.git
synced 2026-01-11 18:33:16 +01:00
Initial port of MIPS architecture.
Completely untested. Shouldn't be merged to master. Signed-off-by: Himanshu Chauhan <hschauhan@nulltrace.org>
This commit is contained in:
1161
ports/mips/Doxyfile
Normal file
1161
ports/mips/Doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
107
ports/mips/Makefile
Normal file
107
ports/mips/Makefile
Normal file
@@ -0,0 +1,107 @@
|
||||
############
|
||||
# Settings #
|
||||
############
|
||||
|
||||
# Build all test applications:
|
||||
# make
|
||||
#
|
||||
# Program a test application using UISP (appname => test app e.g. sems1):
|
||||
# make program app=appname
|
||||
|
||||
# Location of build tools and atomthreads sources
|
||||
KERNEL_DIR=../../kernel
|
||||
TESTS_DIR=../../tests
|
||||
CC=mips-linux-gnu-gcc
|
||||
OBJCOPY=mips-linux-gnu-objcopy
|
||||
|
||||
# Enable stack-checking. WARNING: the full automated test suite currently
|
||||
# requires a little over 1KB RAM with stack-checking enabled. If you are
|
||||
# using a device with 1KB internal SRAM and no external SRAM then you
|
||||
# must disable stack-checking to run all of the automated tests.
|
||||
#STACK_CHECK=true
|
||||
|
||||
# Directory for built objects
|
||||
BUILD_DIR=build
|
||||
|
||||
# Port/application object files
|
||||
APP_OBJECTS = atomport.o test-main.o
|
||||
APP_ASM_OBJECTS = atomport-asm.o atomport-entry.o
|
||||
|
||||
# Kernel object files
|
||||
KERNEL_OBJECTS = atomkernel.o atomsem.o atommutex.o atomtimer.o atomqueue.o
|
||||
|
||||
# Collection of built objects (excluding test applications)
|
||||
ALL_OBJECTS = $(APP_OBJECTS) $(APP_ASM_OBJECTS) $(KERNEL_OBJECTS)
|
||||
BUILT_OBJECTS = $(patsubst %,$(BUILD_DIR)/%,$(ALL_OBJECTS))
|
||||
|
||||
# Test object files (dealt with separately as only one per application build)
|
||||
TEST_OBJECTS = $(notdir $(patsubst %.c,%.o,$(wildcard $(TESTS_DIR)/*.c)))
|
||||
|
||||
# Target application filenames (.elf and .hex) for each test object
|
||||
TEST_ELFS = $(patsubst %.o,%.elf,$(TEST_OBJECTS))
|
||||
TEST_HEXS = $(patsubst %.o,%.hex,$(TEST_OBJECTS))
|
||||
|
||||
# Search build/output directory for dependencies
|
||||
vpath %.o ./$(BUILD_DIR)
|
||||
vpath %.elf ./$(BUILD_DIR)
|
||||
vpath %.hex ./$(BUILD_DIR)
|
||||
|
||||
# GCC flags
|
||||
CFLAGS=-g -Wall -Werror
|
||||
|
||||
# Enable stack-checking (disable if not required)
|
||||
ifeq ($(STACK_CHECK),true)
|
||||
CFLAGS += -DATOM_STACK_CHECKING
|
||||
endif
|
||||
|
||||
|
||||
#################
|
||||
# Build targets #
|
||||
#################
|
||||
|
||||
# All tests
|
||||
all: $(BUILD_DIR) $(TEST_HEXS) Makefile
|
||||
|
||||
# Make build/output directory
|
||||
$(BUILD_DIR):
|
||||
mkdir $(BUILD_DIR)
|
||||
|
||||
# Test HEX files (one application build for each test)
|
||||
$(TEST_HEXS): %.hex: %.elf
|
||||
@echo Building $@
|
||||
$(OBJCOPY) -j .text -j .data -O ihex $(BUILD_DIR)/$< $(BUILD_DIR)/$@
|
||||
|
||||
# Test ELF files (one application build for each test)
|
||||
$(TEST_ELFS): %.elf: %.o $(KERNEL_OBJECTS) $(APP_OBJECTS) $(APP_ASM_OBJECTS)
|
||||
$(CC) $(CFLAGS) $(BUILD_DIR)/$(notdir $<) $(BUILT_OBJECTS) --output $(BUILD_DIR)/$@ -Wl,-Map,$(BUILD_DIR)/$(basename $@).map
|
||||
|
||||
# Kernel objects builder
|
||||
$(KERNEL_OBJECTS): %.o: $(KERNEL_DIR)/%.c
|
||||
$(CC) -c $(CFLAGS) -I. $< -o $(BUILD_DIR)/$(notdir $@)
|
||||
|
||||
# Test objects builder
|
||||
$(TEST_OBJECTS): %.o: $(TESTS_DIR)/%.c
|
||||
$(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@)
|
||||
|
||||
# Application C objects builder
|
||||
$(APP_OBJECTS): %.o: ./%.c
|
||||
$(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) -I$(TESTS_DIR) $< -o $(BUILD_DIR)/$(notdir $@)
|
||||
|
||||
# Application asm objects builder
|
||||
$(APP_ASM_OBJECTS): %.o: ./%.s
|
||||
$(CC) -c $(CFLAGS) -x assembler-with-cpp -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@)
|
||||
|
||||
# .lst file builder
|
||||
%.lst: %.c
|
||||
$(CC) $(CFLAGS) -I. -I$(KERNEL_DIR) -I$(TESTS_DIR) -Wa,-al $< > $@
|
||||
|
||||
# Clean
|
||||
clean:
|
||||
rm -f *.o *.elf *.map *.hex *.bin *.lst
|
||||
rm -rf doxygen-kernel
|
||||
rm -rf doxygen-avr
|
||||
rm -rf build
|
||||
|
||||
doxygen:
|
||||
doxygen $(KERNEL_DIR)/Doxyfile
|
||||
doxygen ./Doxyfile
|
||||
97
ports/mips/atomport-asm.s
Normal file
97
ports/mips/atomport-asm.s
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Atomthreads Project. All rights reserved.
|
||||
*
|
||||
* 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. No personal names or organizations' names associated with the
|
||||
* Atomthreads project may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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.
|
||||
*/
|
||||
|
||||
#include <atomport-private.h>
|
||||
|
||||
.section .text
|
||||
|
||||
/**
|
||||
* Function that performs the contextSwitch. Whether its a voluntary release
|
||||
* of CPU by thread or a pre-emption, under both conditions this function is
|
||||
* called. The signature is as follows:
|
||||
*
|
||||
* archContextSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb)
|
||||
*/
|
||||
.globl archContextSwitch
|
||||
archContextSwitch:
|
||||
lw k0, 0(a0) /* assume that sp_save_ptr is always at base of ATOM_TCB */
|
||||
lw k1, 0(a1)
|
||||
|
||||
sw s0, (s0_IDX * 4)(a0)
|
||||
sw s1, (s1_IDX * 4)(a0)
|
||||
sw s2, (s2_IDX * 4)(a0)
|
||||
sw s3, (s3_IDX * 4)(a0)
|
||||
sw s4, (s4_IDX * 4)(a0)
|
||||
sw s5, (s5_IDX * 4)(a0)
|
||||
sw s6, (s6_IDX * 4)(a0)
|
||||
sw s7, (s7_IDX * 4)(a0)
|
||||
sw s8, (s8_IDX * 4)(a0)
|
||||
sw sp, (sp_IDX * 4)(a0)
|
||||
sw gp, (gp_IDX * 4)(a0)
|
||||
|
||||
lw s0, (s0_IDX * 4)(a1)
|
||||
lw s1, (s1_IDX * 4)(a1)
|
||||
lw s2, (s2_IDX * 4)(a1)
|
||||
lw s3, (s3_IDX * 4)(a1)
|
||||
lw s4, (s4_IDX * 4)(a1)
|
||||
lw s5, (s5_IDX * 4)(a1)
|
||||
lw s6, (s6_IDX * 4)(a1)
|
||||
lw s7, (s7_IDX * 4)(a1)
|
||||
lw s8, (s8_IDX * 4)(a1)
|
||||
lw sp, (sp_IDX * 4)(a1)
|
||||
lw gp, (gp_IDX * 4)(a1)
|
||||
|
||||
j ra
|
||||
nop
|
||||
|
||||
/**
|
||||
* archFirstThreadRestore(ATOM_TCB *new_tcb)
|
||||
*
|
||||
* This function is responsible for restoring and starting the first
|
||||
* thread the OS runs. It expects to find the thread context exactly
|
||||
* as it would be if a context save had previously taken place on it.
|
||||
* The only real difference between this and the archContextSwitch()
|
||||
* routine is that there is no previous thread for which context must
|
||||
* be saved.
|
||||
*
|
||||
* The final action this function must do is to restore interrupts.
|
||||
*/
|
||||
.globl archFirstThreadRestore
|
||||
archFirstThreadRestore:
|
||||
move k0, a0 /* save the copy of tcb pointer in k0 */
|
||||
lw k1, 0(k0) /* Assume that sp_save_ptr is always at base of ATOM_TCB */
|
||||
lw a0, (a0_IDX * 4)(k1)
|
||||
lw sp, (sp_IDX * 4)(k1)
|
||||
lw s8, (s8_IDX * 4)(k1)
|
||||
lw k0, (ra_IDX * 4)(k1)
|
||||
mtc0 k0, CP0_EPC
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
eret
|
||||
230
ports/mips/atomport-entry.s
Normal file
230
ports/mips/atomport-entry.s
Normal file
@@ -0,0 +1,230 @@
|
||||
/**
|
||||
* Copyright (c) 2010 Himanshu Chauhan.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* @file start.S
|
||||
* @version 0.1
|
||||
* @author Himanshu Chauhan (hschauhan@nulltrace.org)
|
||||
* @brief 24Kc startup file.
|
||||
*/
|
||||
|
||||
#include "atomport-private.h"
|
||||
|
||||
.extern _stack_start
|
||||
.section .start.text,"ax",@progbits
|
||||
|
||||
EXCEPTION_VECTOR(_tlbmiss, 0x00, _handle_tlbmiss)
|
||||
EXCEPTION_VECTOR(_cache_error, 0x100, _handle_cache_error)
|
||||
EXCEPTION_VECTOR(_general_exception, 0x180, _handle_general_exception)
|
||||
/* FIXME: We don't need this when in EIC mode. */
|
||||
EXCEPTION_VECTOR(_interrupts, 0x200, _handle_interrupt)
|
||||
|
||||
LEAF(_start)
|
||||
mtc0 ZERO, CP0_CONTEXT
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
/* globally disable interrupts until we are prepared. */
|
||||
disable_global_interrupts
|
||||
|
||||
/* clear CPU timer counters. We don't want surprises. */
|
||||
mtc0 ZERO, CP0_COMPARE
|
||||
mtc0 ZERO, CP0_COUNT
|
||||
|
||||
/* Read number of tlb entries from config register */
|
||||
bal num_tlb_entries
|
||||
nop
|
||||
|
||||
/* initialize tlb */
|
||||
bal tlb_init
|
||||
move A0, V0
|
||||
|
||||
la SP, _stack_start /* setup the stack (bss segment) */
|
||||
la T0, cpu_init
|
||||
j T0 /* Call the C- code now */
|
||||
nop
|
||||
|
||||
1: b 1b /* we should not come here whatsoever */
|
||||
END(_start)
|
||||
|
||||
/*
|
||||
* Read config 1 register and return the number
|
||||
* of TLB entries in this CPU.
|
||||
*/
|
||||
LEAF(num_tlb_entries)
|
||||
mfc0 A1, CP0_CONFIG1
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
srl V0, A1, 25
|
||||
and V0, V0, 0x3F
|
||||
jr RA
|
||||
nop
|
||||
END(num_tlb_entries)
|
||||
|
||||
/**
|
||||
* tlb_init
|
||||
* Initialize the TLB to a power-up state, guaranteeing that all entries
|
||||
* are unique and invalid.
|
||||
* Arguments:
|
||||
* a0 = Maximum TLB index (from MMUSize field of C0_Config1)
|
||||
* Returns:
|
||||
* No value
|
||||
* Restrictions:
|
||||
* This routine must be called in unmapped space
|
||||
* Algorithm:
|
||||
* va = kseg0_base;
|
||||
* for (entry = max_TLB_index ; entry >= 0, entry--) {
|
||||
* while (TLB_Probe_Hit(va)) {
|
||||
* va += Page_Size;
|
||||
* }
|
||||
* TLB_Write(entry, va, 0, 0, 0);
|
||||
* }
|
||||
*/
|
||||
LEAF(tlb_init)
|
||||
/* Clear PageMask, EntryLo0 and EntryLo1 so that valid bits are off, PFN values
|
||||
* are zero, and the default page size is used.
|
||||
*/
|
||||
mtc0 ZERO, CP0_ENTRYLO0
|
||||
/* Clear out PFN and valid bits */
|
||||
mtc0 ZERO, CP0_ENTRYLO1
|
||||
mtc0 ZERO, CP0_PAGEMASK
|
||||
/* Clear out mask register */
|
||||
/* Start with the base address of kseg0 for the VA part of the TLB */
|
||||
li T0, 0x80000000
|
||||
/*
|
||||
* Write the VA candidate to EntryHi and probe the TLB to see if if is
|
||||
* already there. If it is, a write to the TLB may cause a machine
|
||||
* check, so just increment the VA candidate by one page and try again.
|
||||
*/
|
||||
10:
|
||||
mtc0 T0, CP0_ENTRYHI
|
||||
/* Write VA candidate */
|
||||
tlbp_write_hazard
|
||||
/* Clear EntryHi hazard (ssnop/ehb in R1/2) */
|
||||
tlbp
|
||||
/* Probe the TLB to check for a match */
|
||||
tlbp_read_hazard
|
||||
/* Clear Index hazard (ssnop/ehb in R1/2) */
|
||||
mfc0 T1, CP0_INDEX
|
||||
addiu T0, (1 << S_EntryHiVPN2)
|
||||
/* Read back flag to check for match */
|
||||
bgez T1, 10b
|
||||
nop
|
||||
/* Add 1 to VPN index in va */
|
||||
/*
|
||||
* A write of the VPN candidate will be unique, so write this entry
|
||||
* into the next index, decrement the index, and continue until the
|
||||
* index goes negative (thereby writing all TLB entries)
|
||||
*/
|
||||
mtc0 A0, CP0_INDEX
|
||||
/* Use this as next TLB index */
|
||||
tlbw_write_hazard
|
||||
/* Clear Index hazard (ssnop/ehb in R1/2) */
|
||||
tlbwi
|
||||
/* Write the TLB entry */
|
||||
/* Branch if more TLB entries to do */
|
||||
addiu A0, A0, -1
|
||||
bne A0, ZERO, 10b
|
||||
nop
|
||||
|
||||
/* Decrement the TLB index */
|
||||
/*
|
||||
* Clear Index and EntryHi simply to leave the state constant for all
|
||||
* returns
|
||||
*/
|
||||
mtc0 ZERO, CP0_INDEX
|
||||
mtc0 ZERO, CP0_ENTRYHI
|
||||
jr RA
|
||||
/* Return to caller */
|
||||
nop
|
||||
END(tlb_init)
|
||||
|
||||
.extern vmm_cpu_handle_pagefault
|
||||
|
||||
LEAF(_handle_tlbmiss)
|
||||
disable_global_interrupts
|
||||
move K0, SP
|
||||
SAVE_INT_CONTEXT(_int_stack)
|
||||
move A0, SP
|
||||
bal vmm_cpu_handle_pagefault
|
||||
nop
|
||||
enable_global_interrupts
|
||||
eret
|
||||
END(_handle_tlbmiss)
|
||||
|
||||
.extern generic_int_handler
|
||||
.extern _int_stack
|
||||
.extern vmm_regs_dump
|
||||
LEAF(_handle_interrupt)
|
||||
disable_global_interrupts
|
||||
SAVE_INT_CONTEXT(_int_stack)
|
||||
move A0, SP
|
||||
bal generic_int_handler
|
||||
nop
|
||||
RESTORE_INT_CONTEXT(SP)
|
||||
enable_global_interrupts
|
||||
eret
|
||||
END(_handle_interrupt)
|
||||
|
||||
LEAF(_handle_cache_error)
|
||||
b _handle_cache_error
|
||||
nop
|
||||
END(_handle_cache_error)
|
||||
|
||||
LEAF(_handle_general_exception)
|
||||
//move K0, SP
|
||||
//SAVE_INT_CONTEXT(_int_stack)
|
||||
//bal vmm_regs_dump
|
||||
//move A0, SP
|
||||
|
||||
b _handle_general_exception
|
||||
nop
|
||||
END(_handle_general_exception)
|
||||
|
||||
/**
|
||||
* A0 -> Contains virtual address.
|
||||
* A1 -> Contains physical address.
|
||||
* A2 -> TLB index: If -1 select automatically.
|
||||
*/
|
||||
.globl create_tlb_entry
|
||||
LEAF(create_tlb_entry)
|
||||
mtc0 A2, CP0_INDEX /* load the tlb index to be programmed. */
|
||||
srl A0, A0, 12 /* get the VPN */
|
||||
sll A0, A0, 12
|
||||
nop
|
||||
mtc0 A0, CP0_ENTRYHI /* load VPN in entry hi */
|
||||
addi T0, A1, 0x1000 /* next PFN for entry lo1 in T0 */
|
||||
srl A1, A1, 12 /* get the PFN */
|
||||
sll A1, A1, 6 /* get the PFN */
|
||||
srl T0, T0, 12
|
||||
sll T0, T0, 6
|
||||
ori A1, A1, 0x7 /* mark the page writable, global and valid */
|
||||
mtc0 A1, CP0_ENTRYLO0
|
||||
ori T0, T0, 0x7 /* mark the next physical page writable, global and valid */
|
||||
nop
|
||||
nop
|
||||
mtc0 T0, CP0_ENTRYLO1
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
tlbwi
|
||||
ehb
|
||||
j RA
|
||||
nop
|
||||
END(create_tlb_entry)
|
||||
148
ports/mips/atomport-private.h
Normal file
148
ports/mips/atomport-private.h
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Atomthreads Project. All rights reserved.
|
||||
*
|
||||
* 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. No personal names or organizations' names associated with the
|
||||
* Atomthreads project may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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.
|
||||
*/
|
||||
|
||||
#ifndef __ATOMPORT_PRIVATE_H_
|
||||
#define __ATOMPORT_PRIVATE_H_
|
||||
|
||||
#define zero $0
|
||||
#define at $1
|
||||
#define v0 $2
|
||||
#define v1 $3
|
||||
#define a0 $4
|
||||
#define a1 $5
|
||||
#define a2 $6
|
||||
#define a3 $7
|
||||
#define t0 $8
|
||||
#define t1 $9
|
||||
#define t2 $10
|
||||
#define t3 $11
|
||||
#define t4 $12
|
||||
#define t5 $13
|
||||
#define t6 $14
|
||||
#define t7 $15
|
||||
#define t8 $24
|
||||
#define t9 $25
|
||||
#define s0 $16
|
||||
#define s1 $17
|
||||
#define s2 $18
|
||||
#define s3 $19
|
||||
#define s4 $20
|
||||
#define s5 $21
|
||||
#define s6 $22
|
||||
#define s7 $23
|
||||
#define k0 $26
|
||||
#define k1 $27
|
||||
#define gp $28
|
||||
#define sp $29
|
||||
#define s8 $30
|
||||
#define fp $30
|
||||
#define ra $31
|
||||
|
||||
#define NUM_REGISTERS 32
|
||||
#define WORD_SIZE 4
|
||||
|
||||
#define v0_IDX 0
|
||||
#define v1_IDX 1
|
||||
#define a0_IDX 2
|
||||
#define a1_IDX 3
|
||||
#define a2_IDX 4
|
||||
#define a3_IDX 5
|
||||
#define t0_IDX 6
|
||||
#define t1_IDX 7
|
||||
#define t2_IDX 8
|
||||
#define t3_IDX 9
|
||||
#define t4_IDX 10
|
||||
#define t5_IDX 11
|
||||
#define t6_IDX 12
|
||||
#define t7_IDX 13
|
||||
#define s0_IDX 14
|
||||
#define s1_IDX 15
|
||||
#define s2_IDX 16
|
||||
#define s3_IDX 17
|
||||
#define s4_IDX 18
|
||||
#define s5_IDX 19
|
||||
#define s6_IDX 20
|
||||
#define s7_IDX 21
|
||||
#define t8_IDX 22
|
||||
#define t9_IDX 23
|
||||
#define sp_IDX 24
|
||||
#define gp_IDX 25
|
||||
#define s8_IDX 26
|
||||
#define ra_IDX 27
|
||||
#define k0_IDX 28
|
||||
#define k1_IDX 29
|
||||
#define at_IDX 30
|
||||
#define zero_IDX 31
|
||||
|
||||
#define CP0_INDEX $0
|
||||
#define CP0_RANDOM $1
|
||||
#define CP0_ENTRYLO0 $2
|
||||
#define CP0_ENTRYLO1 $3
|
||||
#define CP0_CONTEXT $4
|
||||
#define CP0_PAGEMASK $5
|
||||
#define CP0_WIRED $6
|
||||
#define CP0_HWRENA $7
|
||||
#define CP0_BADVADDR $8
|
||||
#define CP0_COUNT $9
|
||||
#define CP0_ENTRYHI $10
|
||||
#define CP0_COMPARE $11
|
||||
#define CP0_STATUS $12
|
||||
#define CP0_INTCTL $12,1
|
||||
#define CP0_SRSCTL $12,2
|
||||
#define CP0_SRSMAP $12,3
|
||||
#define CP0_CAUSE $13
|
||||
#define CP0_EPC $14
|
||||
#define CP0_PRID $15
|
||||
#define CP0_EBASE $15,1
|
||||
#define CP0_CONFIG $16
|
||||
#define CP0_CONFIG1 $16,1
|
||||
#define CP0_CONFIG2 $16,2
|
||||
#define CP0_CONFIG3 $16,3
|
||||
#define CP0_LLADDR $17
|
||||
#define CP0_WATCHLO $18
|
||||
#define CP0_WATCHHI $19
|
||||
#define CP0_DEBUG $23
|
||||
#define CP0_DEPC $24
|
||||
#define CP0_PERFCTL $25,0
|
||||
#define CP0_PERFCNT $25,1
|
||||
#define CP0_ECC $26
|
||||
#define CP0_CACHEERR $27
|
||||
#define CP0_TAGLO $28
|
||||
#define CP0_DATALO $28,1
|
||||
#define CP0_TAGHI $29
|
||||
#define CP0_DATAHI $29,1
|
||||
#define CP0_ERRORPC $30
|
||||
|
||||
#define SAVE_REG(addr, reg, val) \
|
||||
sw reg, (reg ## _IDX * WORD_SIZE)(addr)
|
||||
|
||||
#define LOAD_REG(addr, reg, val) \
|
||||
lw reg, (reg ## _IDX * WORD_SIZE)(addr)
|
||||
|
||||
#endif /* __ATOMPORT_PRIVATE_H_ */
|
||||
48
ports/mips/atomport-tests.h
Normal file
48
ports/mips/atomport-tests.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Himanshu Chauhan. All rights reserved.
|
||||
*
|
||||
* 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. No personal names or organizations' names associated with the
|
||||
* Atomthreads project may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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.
|
||||
*/
|
||||
|
||||
#ifndef __ATOM_PORT_TESTS_H
|
||||
#define __ATOM_PORT_TESTS_H
|
||||
|
||||
/* Include Atomthreads kernel API */
|
||||
#include "atom.h"
|
||||
|
||||
/* Logger macro for viewing test results */
|
||||
/* FIXME: Add uart out routine once uart is supported */
|
||||
#define ATOMLOG(x)
|
||||
#define _STR(x)
|
||||
|
||||
/* Default thread stack size (in bytes) */
|
||||
#define TEST_THREAD_STACK_SIZE 128
|
||||
|
||||
/* Uncomment to enable logging of stack usage to UART */
|
||||
/* #define TESTS_LOG_STACK_USAGE */
|
||||
|
||||
#endif /* __ATOM_PORT_TESTS_H */
|
||||
|
||||
42
ports/mips/atomport-types.h
Normal file
42
ports/mips/atomport-types.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Himanshu Chauhan. All rights reserved.
|
||||
*
|
||||
* 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. No personal names or organizations' names associated with the
|
||||
* Atomthreads project may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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.
|
||||
*/
|
||||
|
||||
#ifndef __ATOMPORT_TYPES_H
|
||||
#define __ATOMPORT_TYPES_H
|
||||
|
||||
typedef signed int int32_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned char uint8_t;
|
||||
|
||||
#define UINT32 uint32_t
|
||||
|
||||
#endif /* __ATOMPORT_TYPES_H */
|
||||
75
ports/mips/atomport.c
Normal file
75
ports/mips/atomport.c
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Himanshu Chauhan for Atomthreads Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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. No personal names or organizations' names associated with the
|
||||
* Atomthreads project may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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.
|
||||
*/
|
||||
|
||||
#include <atom.h>
|
||||
#include <atomport-private.h>
|
||||
#include <atomport.h>
|
||||
|
||||
/**
|
||||
* This function initialises each thread's stack during creation, before the
|
||||
* thread is first run. New threads are scheduled in using the same
|
||||
* context-switch function used for threads which were previously scheduled
|
||||
* out, therefore this function should set up a stack context which looks
|
||||
* much like a thread which has been scheduled out and had its context saved.
|
||||
* We fill part of the stack with those registers which are involved in the
|
||||
* context switch, including appropriate stack or register contents to cause
|
||||
* the thread to branch to its entry point function when it is scheduled in.
|
||||
*
|
||||
* Interrupts should also be enabled whenever a thread is restored, hence
|
||||
* ports may wish to explicitly include the interrupt-enable register here
|
||||
* which will be restored when the thread is scheduled in. Other methods
|
||||
* can be used to enable interrupts, however, without explicitly storing
|
||||
* it in the thread's context.
|
||||
*/
|
||||
void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top,
|
||||
void (*entry_point)(UINT32),
|
||||
UINT32 entry_param)
|
||||
{
|
||||
|
||||
#define STORE_VAL(base, reg, val) \
|
||||
*((uint32_t *)(base + ((reg ## _IDX) * WORD_SIZE))) = (uint32_t)val
|
||||
|
||||
void *stack_start = (stack_top - (WORD_SIZE * NUM_REGISTERS));
|
||||
|
||||
tcb_ptr->sp_save_ptr = stack_start;
|
||||
|
||||
STORE_VAL(stack_start, sp, stack_start);
|
||||
STORE_VAL(stack_start, s8, stack_start);
|
||||
STORE_VAL(stack_start, s1, 0);
|
||||
STORE_VAL(stack_start, s2, 0);
|
||||
STORE_VAL(stack_start, s3, 0);
|
||||
STORE_VAL(stack_start, s4, 0);
|
||||
STORE_VAL(stack_start, s5, 0);
|
||||
STORE_VAL(stack_start, s6, 0);
|
||||
STORE_VAL(stack_start, s7, 0);
|
||||
STORE_VAL(stack_start, ra, entry_point);
|
||||
STORE_VAL(stack_start, a0, entry_param);
|
||||
}
|
||||
|
||||
53
ports/mips/atomport.h
Normal file
53
ports/mips/atomport.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Himanshu Chauhan. All rights reserved.
|
||||
*
|
||||
* 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. No personal names or organizations' names associated with the
|
||||
* Atomthreads project may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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.
|
||||
*/
|
||||
|
||||
#ifndef __ATOM_PORT_H
|
||||
#define __ATOM_PORT_H
|
||||
|
||||
#include "atomport-types.h"
|
||||
|
||||
/* Required number of system ticks per second (normally 100 for 10ms tick) */
|
||||
#define SYSTEM_TICKS_PER_SEC 100
|
||||
|
||||
/**
|
||||
* Architecture-specific types.
|
||||
* Most of these are available from stdint.h on this platform, which is
|
||||
* included above.
|
||||
*/
|
||||
#define POINTER void *
|
||||
|
||||
/* Critical region protection */
|
||||
#define CRITICAL_STORE
|
||||
#define CRITICAL_START() __asm__ __volatile__("di $0\n\t")
|
||||
#define CRITICAL_END() __asm__ __volatile__("ei $0\n\t");
|
||||
|
||||
/* Uncomment to enable stack-checking */
|
||||
/* #define ATOM_STACK_CHECKING */
|
||||
|
||||
#endif /* __ATOM_PORT_H */
|
||||
297
ports/mips/tests-main.c
Normal file
297
ports/mips/tests-main.c
Normal file
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Kelvin Lawson. All rights reserved.
|
||||
*
|
||||
* 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. No personal names or organizations' names associated with the
|
||||
* Atomthreads project may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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.
|
||||
*/
|
||||
|
||||
#include "atom.h"
|
||||
#include "atomport-private.h"
|
||||
#include "atomtests.h"
|
||||
#include "atomtimer.h"
|
||||
|
||||
/* Constants */
|
||||
|
||||
/*
|
||||
* Idle thread stack size
|
||||
*
|
||||
* This needs to be large enough to handle any interrupt handlers
|
||||
* and callbacks called by interrupt handlers (e.g. user-created
|
||||
* timer callbacks) as well as the saving of all context when
|
||||
* switching away from this thread.
|
||||
*
|
||||
* In this case, the idle stack is allocated on the BSS via the
|
||||
* idle_thread_stack[] byte array.
|
||||
*/
|
||||
#define IDLE_STACK_SIZE_BYTES 128
|
||||
|
||||
|
||||
/*
|
||||
* Main thread stack size
|
||||
*
|
||||
* Note that this is not a required OS kernel thread - you will replace
|
||||
* this with your own application thread.
|
||||
*
|
||||
* In this case the Main thread is responsible for calling out to the
|
||||
* test routines. Once a test routine has finished, the test status is
|
||||
* printed out on the UART and the thread remains running in a loop
|
||||
* flashing a LED.
|
||||
*
|
||||
* The Main thread stack generally needs to be larger than the idle
|
||||
* thread stack, as not only does it need to store interrupt handler
|
||||
* stack saves and context switch saves, but the application main thread
|
||||
* will generally be carrying out more nested function calls and require
|
||||
* stack for application code local variables etc.
|
||||
*
|
||||
* With all OS tests implemented to date on the AVR, the Main thread
|
||||
* stack has not exceeded 198 bytes. To allow all tests to run we set
|
||||
* a minimum main thread stack size of 204 bytes. This may increase in
|
||||
* future as the codebase changes but for the time being is enough to
|
||||
* cope with all of the automated tests.
|
||||
*/
|
||||
#define MAIN_STACK_SIZE_BYTES 204
|
||||
|
||||
|
||||
/*
|
||||
* Startup code stack
|
||||
*
|
||||
* Some stack space is required at initial startup for running the main()
|
||||
* routine. This stack space is only temporarily required at first bootup
|
||||
* and is no longer required as soon as the OS is started. By default
|
||||
* GCC sets this to the top of RAM (RAMEND) and it grows down from there.
|
||||
* Because we only need this temporarily, though, it would be wasteful to
|
||||
* set aside a region at the top of RAM which is not used during runtime.
|
||||
*
|
||||
* What we do here is to reuse part of the idle thread's stack during
|
||||
* initial startup. As soon as we enter the main() routine we move the
|
||||
* stack pointer to half-way down the idle thread's stack. This is used
|
||||
* temporarily while calls are made to atomOSInit(), atomThreadCreate()
|
||||
* and atomOSStart(). Once the OS is started this stack area is no
|
||||
* longer required, and can be used for its original purpose (for the
|
||||
* idle thread's stack).
|
||||
*
|
||||
* This does mean, however, that we cannot monitor the stack usage of the
|
||||
* idle thread. Stack usage is monitored by prefilling the stack with a
|
||||
* known value, and we are obliterating some of that prefilled area by
|
||||
* using it as our startup stack, so we cannot use the stack-checking API
|
||||
* to get a true picture of idle thread stack usage. If you wish to
|
||||
* monitor idle thread stack usage for your applications then you are
|
||||
* free to use a different region for the startup stack (e.g. set aside
|
||||
* an area permanently, or place it somewhere you know you can reuse
|
||||
* later in the application). For the time being, this method gives us a
|
||||
* simple way of reducing the memory consumption without having to add
|
||||
* any special AVR-specific considerations to the automated test
|
||||
* applications.
|
||||
*
|
||||
* This optimisation was required to allow some of the larger automated
|
||||
* test modules to run on devices with 1KB of RAM. You should avoid doing
|
||||
* this if you can afford to set aside 64 bytes or so, or if you are
|
||||
* writing your own applications in which you have further control over
|
||||
* where data is located.
|
||||
*/
|
||||
|
||||
|
||||
/* Local data */
|
||||
|
||||
/* Application threads' TCBs */
|
||||
static ATOM_TCB main_tcb;
|
||||
|
||||
/* Main thread's stack area */
|
||||
static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES];
|
||||
|
||||
/* Idle thread's stack area */
|
||||
static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES];
|
||||
|
||||
/* STDIO stream */
|
||||
static FILE uart_stdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
static void main_thread_func (uint32_t data);
|
||||
|
||||
|
||||
/**
|
||||
* \b main
|
||||
*
|
||||
* Program entry point.
|
||||
*
|
||||
* Sets up the AVR hardware resources (system tick timer interrupt) necessary
|
||||
* for the OS to be started. Creates an application thread and starts the OS.
|
||||
*/
|
||||
|
||||
int main ( void )
|
||||
{
|
||||
int8_t status;
|
||||
|
||||
/**
|
||||
* Reuse part of the idle thread's stack for the stack required
|
||||
* during this startup function.
|
||||
*/
|
||||
SP = (int)&idle_thread_stack[(IDLE_STACK_SIZE_BYTES/2) - 1];
|
||||
|
||||
/**
|
||||
* Note: to protect OS structures and data during initialisation,
|
||||
* interrupts must remain disabled until the first thread
|
||||
* has been restored. They are reenabled at the very end of
|
||||
* the first thread restore, at which point it is safe for a
|
||||
* reschedule to take place.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Initialise the OS before creating our threads.
|
||||
*
|
||||
* Note that we tell the OS that the idle stack is half its actual
|
||||
* size. This prevents it prefilling the bottom half with known
|
||||
* values for stack-checkig purposes, which we cannot allow because
|
||||
* we are temporarily using it for our own stack. The remainder will
|
||||
* still be available once the OS is started, this only prevents the
|
||||
* OS from prefilling it.
|
||||
*
|
||||
* If you are not reusing the idle thread's stack during startup then
|
||||
* you should pass in the correct size here.
|
||||
*/
|
||||
status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES - 1], (IDLE_STACK_SIZE_BYTES/2));
|
||||
if (status == ATOM_OK)
|
||||
{
|
||||
/* Enable the system tick timer */
|
||||
avrInitSystemTickTimer();
|
||||
|
||||
/* Create an application thread */
|
||||
status = atomThreadCreate(&main_tcb,
|
||||
TEST_THREAD_PRIO, main_thread_func, 0,
|
||||
&main_thread_stack[MAIN_STACK_SIZE_BYTES - 1],
|
||||
MAIN_STACK_SIZE_BYTES);
|
||||
if (status == ATOM_OK)
|
||||
{
|
||||
/**
|
||||
* First application thread successfully created. It is
|
||||
* now possible to start the OS. Execution will not return
|
||||
* from atomOSStart(), which will restore the context of
|
||||
* our application thread and start executing it.
|
||||
*
|
||||
* Note that interrupts are still disabled at this point.
|
||||
* They will be enabled as we restore and execute our first
|
||||
* thread in archFirstThreadRestore().
|
||||
*/
|
||||
atomOSStart();
|
||||
}
|
||||
}
|
||||
|
||||
while (1)
|
||||
;
|
||||
|
||||
/* There was an error starting the OS if we reach here */
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \b main_thread_func
|
||||
*
|
||||
* Entry point for main application thread.
|
||||
*
|
||||
* This is the first thread that will be executed when the OS is started.
|
||||
*
|
||||
* @param[in] data Unused (optional thread entry parameter)
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static void main_thread_func (uint32_t data)
|
||||
{
|
||||
uint32_t test_status;
|
||||
int sleep_ticks;
|
||||
|
||||
/* Enable all LEDs (STK500-specific) */
|
||||
DDRB = 0xFF;
|
||||
PORTB = 0xFF;
|
||||
|
||||
/* Initialise UART (9600bps) */
|
||||
if (uart_init(9600) != 0)
|
||||
{
|
||||
/* Error initialising UART */
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect stdout via the UART. Note that the UART write routine
|
||||
* is protected via a semaphore, so the OS must be started before
|
||||
* use of the UART.
|
||||
*/
|
||||
stdout = &uart_stdout;
|
||||
|
||||
/* Put a message out on the UART */
|
||||
printf_P(PSTR("Go\n"));
|
||||
|
||||
/* Start test. All tests use the same start API. */
|
||||
test_status = test_start();
|
||||
|
||||
/* Check main thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
if (test_status == 0)
|
||||
{
|
||||
uint32_t used_bytes, free_bytes;
|
||||
|
||||
/* Check idle thread stack usage */
|
||||
if (atomThreadStackCheck (&main_tcb, &used_bytes, &free_bytes) == ATOM_OK)
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
printf_P (PSTR("Main stack overflow\n"));
|
||||
test_status++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
printf_P (PSTR("MainUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Log final status */
|
||||
if (test_status == 0)
|
||||
{
|
||||
printf_P (PSTR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf_P (PSTR("Fail(%d)\n"), test_status);
|
||||
}
|
||||
|
||||
/* Flash LED once per second if passed, very quickly if failed */
|
||||
sleep_ticks = (test_status == 0) ? SYSTEM_TICKS_PER_SEC : (SYSTEM_TICKS_PER_SEC/8);
|
||||
|
||||
/* Test finished, flash slowly for pass, fast for fail */
|
||||
while (1)
|
||||
{
|
||||
/* Toggle a LED (STK500-specific) */
|
||||
PORTB ^= (1 << 7);
|
||||
|
||||
/* Sleep then toggle LED again */
|
||||
atomTimerDelay(sleep_ticks);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user