HEW環境では割り込みベクタの設定を #pragma interruptで指定出来ます。
GCC では
_isr_vectors[VECT(RTC,PRD)] = rtc_irq_handler;
としたものが #pragma interrupt (rtc_irq_handler(vect=VECT(RTC,PRD)))
と出来ます。またアセンブラでは .rvector指令で
.rvector TRAP_SAVE_SR, _tn_trap_cpu_save_sr
_tn_trap_cpu_save_sr:
push.l r2
とするこで C$VECTに割り込み処理先を登録してくれます。1) tn_port_rx_gcc.S -> tn_port_rx_rxc.src
; -----------------------------------------------------------------------------
;
; TNKernel RTOS port for RX core
;
; Copyright ゥ 2011, 2012 Maxim Salov
; All rights reserved.
;
; Assembler: GCC
;
; Permission to use, copy, modify, and distribute this software in source
; and binary forms and its documentation for any purpose and without fee
; is hereby granted, provided that the above copyright notice appear
; in all copies and that both that copyright notice and this permission
; notice appear in supporting documentation.
;
; THIS SOFTWARE IS PROVIDED BY THE YURI TIOMKIN 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 YURI TIOMKIN 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.
; -----------------------------------------------------------------------------
; .section .text
;; External references
.glb _tn_curr_run_task
.glb _tn_next_task_to_run
.glb _tn_system_state
;; Public functions declared in this file
.glb _tn_startup_hardware_init
.glb _tn_startup
.glb _tn_switch_context
.glb _tn_switch_context_exit
.glb _tn_switch_context_irq_handler
.glb _tn_trap_cpu_save_sr
.glb _tn_trap_cpu_restore_sr
.glb _tn_icpu_save_sr
.glb _tn_icpu_restore_sr
.glb _tn_cpu_save_sr
.glb _tn_cpu_restore_sr
.glb _tn_start_exe
.glb _tn_chk_irq_disabled
.glb _tn_int_exit
.glb _tn_cpu_int_enable
.glb _tn_inside_int
;; Addresses and bits for SWINT
SWINTR .equ 000872E0h
SWINT .equ 1
IPR03 .equ 00087303h
SWINTPR .equ 1
IER03 .equ 00087203h
IEN3 .equ 3
IR027 .equ 0008701Bh
__stack .equ 20000h
TN_ST_STATE_RUNNING .equ 1
;; Bit definitions for PSW register
I_BIT_N .equ 16
I_BIT .equ (1 << I_BIT_N)
U_BIT_N .equ 17
U_BIT .equ (1 << U_BIT_N)
PM_BIT_N .equ 20
PM_BIT .equ (1 << PM_BIT_N)
IPL_BITS .equ 0F000000h
;; Trap numbers
TRAP_SAVE_SR .equ 10
TRAP_RESTORE_SR .equ 11
;/* ------------------------------------------------------------------------ */
.section P,CODE
;/* ------------------------------------------------------------------------ */
;/* ------------------------------------------------------------------------ */
_tn_startup_hardware_init:
pop r1 ; save return address
mov.l #__stack, r2 ; get top of RAM _\stack
mvtc r2, isp ; set ISP to top of RAM
add #-512, r2 ; reserve some space for ISP
mvtc r2, usp ; set USP
setpsw U ; switch to USP
push.l r1 ; restore return address
rts
;/* ------------------------------------------------------------------------ */
_tn_startup:
;; Enable SWINT (software interrupt), which is used to switch context
mov.l #IER03, r1
mov.l #IPR03, r2
mov.l #IR027, r3
bclr #IEN3, [r1].b ; Disable SWINT
mov.b #SWINTPR, [r2] ; Set SWINT priority to lowest
mov.b #0, [r3] ; Reset interrupt request
bset #IEN3, [r1].b ; Enable SWINT
rts
;/* ------------------------------------------------------------------------ */
_tn_start_exe:
;; Interrupts must be disabled for now, but we should not trust user :/
clrpsw I
;; Set system state to TN_ST_STATE_RUNNING
mov.l #_tn_system_state, r1
mov.l #TN_ST_STATE_RUNNING, [r1]
;; Make request for context switch
;; IMHO this step is unnecessary, since we initially switch to idle task, and additional context switch will not lead us to timer task
;; bsr _tn_switch_context
;; Reset interrupt stack pointer into initial state
mov.l #__stack, r1
mvtc r1, isp
;; Prepare for first context switch
;; Read current task pointer and write it to USP (user stack pointer)
mov.l #_tn_curr_run_task, r1
mov.l [r1], r1
mov.l [r1], r1
mvtc r1, usp
;; Restore PC and PSW from user stack and place it into interrupt stack
setpsw U
popm r1-r2
clrpsw U
pushm r1-r2
;; Read task context
setpsw U
popm r1-r15 ; Restore context of new task
;; Switch back to interrupt stack
clrpsw U
;; "Return" from interrupt. This will fetch task's address and PSW value with already enabled interrupts, user mode and user stack pointer
rte
;; We should not reach this point
?:
bra.b ?-
;/* ------------------------------------------------------------------------ */
_tn_switch_context_exit:
;; Enable interrupts
mov.l #1, r1
bsr _tn_cpu_restore_sr
;; Make request for context switch
bsr _tn_switch_context
;; We should not reach this point
?:
bra.b ?-
;/* ------------------------------------------------------------------------ */
_tn_switch_context_irq_handler_rte:
popm r1-r2
rte
.rvector 27, _tn_switch_context_irq_handler
_tn_switch_context_irq_handler:
pushm r1-r2
;; The context switching - to do or not to do, that is the question :)
mov.l #_tn_curr_run_task, r1
mov.l #_tn_next_task_to_run, r2
mov.l [r2], r2
mov.l [r1], r1 ; If both pointers reference one task - not to do
cmp r1, r2
beq.b _tn_switch_context_irq_handler_rte
;; to do
popm r1-r2
;/* -------------------------------------- */
;; Save task context
setpsw U ; Switch to the stack of previous task
pushm r1-r15 ; Save context
;; Save PC and PSW of current task (located on top of isp) into task stack (usp)
clrpsw U
popm r1-r2
setpsw U
pushm r1-r2
;; Prepare to save/switch/restore stack pointers
mov.l #_tn_curr_run_task, r1
mov.l [r1], r5 ; Read TCB address of current task
mov.l #_tn_next_task_to_run, r2
mov.l [r2], r6 ; Read TCB address of next task
;; Save current stack pointer
mvfc usp, r3
mov.l r3, [r5]
;; Set next task as current one
mov.l r6, [r1]
;; Restore stack pointer of next task
mov.l [r6], r3
mvtc r3, usp
;; Restore PC and PSW from user stack and place it into interrupt stack
setpsw U
popm r1-r2
clrpsw U
pushm r1-r2
;; Read task context
setpsw U
popm r1-r15 ; Restore context of new task
;; Switch back to interrupt stack
clrpsw U
;/* -------------------------------------- */
rte
;/* ------------------------------------------------------------------------ */
_tn_switch_context:
_tn_int_exit:
mov.l #SWINTR, r1
mov.b #SWINT, [r1] ; Trigger software interrupt
rts
;/* ------------------------------------------------------------------------ */
.rvector TRAP_SAVE_SR, _tn_trap_cpu_save_sr
_tn_trap_cpu_save_sr:
push.l r2
mov.l 8[r0], r2 ; Read PSW value from stack
mov.l r2, r1
bclr #I_BIT_N, r2 ; Reset I bit in saved PSW
mov.l r2, 8[r0] ; Store PSW value to stack
and #I_BIT, r1 ; Isolate I bit
pop r2
rte
;/* ------------------------------------------------------------------------ */
.rvector TRAP_RESTORE_SR, _tn_trap_cpu_restore_sr
_tn_trap_cpu_restore_sr:
push.l r2
mov.l 8[r0], r2 ; Read PSW value from stack
cmp #0, r1 ; Check if we need to set I bit
bmnz #I_BIT_N, r2 ; Enable/disable interrupts in saved PSW
mov.l r2, 8[r0] ; Store PSW value to stack
pop r2
rte
;/* ------------------------------------------------------------------------ */
_tn_cpu_save_sr:
int #TRAP_SAVE_SR
rts
;/* ------------------------------------------------------------------------ */
_tn_cpu_restore_sr:
int #TRAP_RESTORE_SR
rts
;/* ------------------------------------------------------------------------ */
_tn_icpu_save_sr:
mvfc psw, r1
clrpsw I
and #I_BIT, r1
rts
;/* ------------------------------------------------------------------------ */
_tn_icpu_restore_sr:
mvfc psw, r2
cmp #0, r1
bmnz #I_BIT_N, r2
mvtc r2, psw
rts
;/* ------------------------------------------------------------------------ */
_tn_chk_irq_disabled:
mvfc psw, r1
and #I_BIT, r1 ; Isolate I bit
bnot #I_BIT_N, r1 ; Invert I bit
rts
;/* ------------------------------------------------------------------------ */
_tn_cpu_int_enable:
;; This function is invoked as a starting point of tn_timer_task_func.
;; But interrupts are already enabled, because the only way there -- to
;; perform context switch, that is done in SWINT.
;; But lets implement it any way
mov.l #1, r1
bsr _tn_cpu_restore_sr
rts
;/* ------------------------------------------------------------------------ */
_tn_inside_int:
mvfc psw, r1
and #U_BIT, r1
bnot #U_BIT_N, r1
rts
;/* ------------------------------------------------------------------------ */
.end
2) tn_user.c
/*
TNKernel real-time kernel
Copyright ゥ 2011 Maxim Salov
All rights reserved.
Permission to use, copy, modify, and distribute this software in source
and binary forms and its documentation for any purpose and without fee
is hereby granted, provided that the above copyright notice appear
in all copies and that both that copyright notice and this permission
notice appear in supporting documentation.
THIS SOFTWARE IS PROVIDED BY THE YURI TIOMKIN 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 YURI TIOMKIN 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 <iodefine.h>
#include <grsakurarx63ndef.h>
#include <tn.h>
#include <tn_user.h>
#include "sci2.h"
//----------------------------------------------------------------------------
// RTC initialization routine
//----------------------------------------------------------------------------
void rtc_init(void)
{
/* For detailed description please refer to hardware manual */
SYSTEM.PRCR.WORD = 0xA503;
RTC.RCR3.BYTE = 0x0c;
SYSTEM.SOSCCR.BIT.SOSTP = 0; /* Enable SubClock circuit */
SYSTEM.PRCR.WORD = 0xA500;
RTC.RCR3.BIT.RTCEN = 1;
RTC.RCR2.BIT.START = 0;
while (0 != RTC.RCR2.BIT.START);
RTC.RCR2.BIT.RESET = 1;
while (1 == RTC.RCR2.BIT.RESET);
/* Set initial time and date */
RTC.RSECCNT.BYTE = 0;
RTC.RMINCNT.BYTE = 0;
RTC.RHRCNT.BYTE = 0;
RTC.RDAYCNT.BYTE = 0;
RTC.RWKCNT.BYTE = 0;
RTC.RMONCNT.BYTE = 0;
RTC.RYRCNT.WORD = 0x2012;
/* Set periodic interrupt */
RTC.RCR1.BYTE = 0x64;
// RTC.RCR1.BYTE = 0xc4;
// RTC.RCR1.BIT.PES = 6; /* Set periodic interrupts frequency to 256 Hz */
// RTC.RCR1.BIT.PIE = 1; /* Enable periodic interrupts */
// _isr_vectors[VECT(RTC,PRD)] = rtc_irq_handler;
IR(RTC,PRD) = 0; /* Clear interrupt flag */
IPR(RTC,PRD) = 3; /* Set priority level */
IEN(RTC,PRD) = 1; /* Enable interrupt in ICU */
RTC.RCR2.BIT.START = 1; /* Start RTC */
while (1 != RTC.RCR2.BIT.START);
}
//----------------------------------------------------------------------------
// RTC periodic interrupt
//----------------------------------------------------------------------------
#pragma interrupt (rtc_irq_handler(vect=VECT(RTC,PRD)))
//interrupt_attr
void rtc_irq_handler(void)
{
static unsigned char free_counter;
free_counter++;
if(free_counter > 63) {
LEDA6 ^= 1;
free_counter=0;
}
tn_tick_int_processing();
tn_int_exit();
}
//----------------------------------------------------------------------------
3)test.c
/*
TNKernel real-time kernel - YRDKRX62N test (RX core)
Copyright ゥ 2011 Maxim Salov
All rights reserved.
Permission to use, copy, modify, and distribute this software in source
and binary forms and its documentation for any purpose and without fee
is hereby granted, provided that the above copyright notice appear
in all copies and that both that copyright notice and this permission
notice appear in supporting documentation.
THIS SOFTWARE IS PROVIDED BY THE YURI TIOMKIN 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 YURI TIOMKIN 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.
*/
/*============================================================================
A basic test - (Hello-LED-World)
*===========================================================================*/
#include <tn.h>
#include <machine.h>
#include <iodefine.h>
#include <grsakurarx63ndef.h>
#include "tn_user.h"
#include "hwsetup.h"
#include "sci2.h"
//----------- Tasks ----------------------------------------------------------
#define TASK_0_PRIORITY 7
#define TASK_1_PRIORITY 10
#define TASK_2_PRIORITY 12
#define TASK_0_STK_SIZE 128
#define TASK_1_STK_SIZE 128
#define TASK_2_STK_SIZE 128
unsigned int task_0_stack[TASK_0_STK_SIZE];
unsigned int task_1_stack[TASK_1_STK_SIZE];
unsigned int task_2_stack[TASK_2_STK_SIZE];
TN_TCB task_0;
TN_TCB task_1;
TN_TCB task_2;
void task_0_func(void * par );
void task_1_func(void * par );
void task_2_func(void * par );
//----------------------------------------------------------------------------
void tcp_main(void);
void main (void)
{
HardwareSetup();
sci2_init();
rtc_init();
printk("\nStart System\n");
tn_start_system();
...以下略
4)Resetprg.c
/***********************************************************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. No
* other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
* applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. TO THE MAXIMUM
* EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES
* SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS
* SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability of
* this software. By using this software, you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
*
* Copyright (C) 2012 Renesas Electronics Corporation. All rights reserved.
***********************************************************************************************************************/
/***********************************************************************************************************************
* File Name : resetprg.c
* Version : 1.01
* Description : Power on reset
***********************************************************************************************************************/
/**********************************************************************************************************************
* History : DD.MM.YYYY Version Description
* : 22.04.2011 1.00 First Release
* : 21.08.2012 1.01 Change to supervisor mode
***********************************************************************************************************************/
/***********************************************************************************************************************
Includes <System Includes> , "Project Includes"
***********************************************************************************************************************/
#include <machine.h>
#include <_h_c_lib.h>
#include <stdint.h>
#include "typedefine.h"
#include "iodefine.h"
#include "sci2.h"
//#include "isr_vectors.h"
/***********************************************************************************************************************
Macro definitions
***********************************************************************************************************************/
#define PSW_init 0x00010000
#define FPSW_init 0x00000100
/***********************************************************************************************************************
Typedef definitions
***********************************************************************************************************************/
/***********************************************************************************************************************
Imported global variables and functions (from other files)
***********************************************************************************************************************/
//#ifdef __cplusplus // Use SIM I/O
//extern "C" {
//#endif
//extern void _INIT_IOLIB(void);
//extern void _CLOSEALL(void);
//#ifdef __cplusplus
//}
//#endif
//extern void srand(_UINT); // Remove the comment when you use rand()
//extern _SBYTE *_s1ptr; // Remove the comment when you use strtok()
#ifdef __cplusplus // Use Hardware Setup
extern "C" {
#endif
extern void main(void);
extern void HardwareSetup(void);
extern void tn_startup_hardware_init(void);
extern void tn_startup(void);
#ifdef __cplusplus
}
#endif
//#ifdef __cplusplus // Remove the comment when you use global class object
//extern "C" { // Sections C$INIT and C$END will be generated
//#endif
//extern void _CALL_INIT(void);
//extern void _CALL_END(void);
//#ifdef __cplusplus
//}
//#endif
#define PSW_init 0x00000000 // PSW bit pattern
#define FPSW_init 0x00000100 // FPSW bit base pattern
/***********************************************************************************************************************
Exported global variables and functions (to be accessed by other files)
***********************************************************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
void PowerON_Reset_PC(void);
#ifdef __cplusplus
}
#endif
/***********************************************************************************************************************
Private global variables and functions
***********************************************************************************************************************/
#pragma section ResetPRG
#pragma entry PowerON_Reset_PC
/***********************************************************************************************************************
* Function Name: PowerON_Reset_PC
* Description : Executes the CPU initialization processing to register
* the power-on reset vector to the exception vector table.
* This function is executed first after power-on reset.
* Arguments : None
* Return Value : None
***********************************************************************************************************************/
void PowerON_Reset_PC(void)
{
set_psw(PSW_init); // Set Ubit & Ibit for PSW
set_fpsw(FPSW_init);
set_intb(__sectop("C$VECT"));
set_isp (0x400);
tn_startup_hardware_init();
_INITSCT();
tn_startup();
main();
brk();
}
/* END of File */
5)intprg.c
省略
6 その他
http://japan.renesas.com/products/tools/middleware/c_communication/a_tcpip/tcpip_t4/index.jsp
にて公開されている無償版TCP/IP プロトコルスタックが便利です。
本家 http://www.tnkernel.com/ に Version 2.7があがっていた。
2013.07.22
0 件のコメント:
コメントを投稿