266 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			266 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
    FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.
 | 
						|
    All rights reserved
 | 
						|
 | 
						|
    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
 | 
						|
 | 
						|
    This file is part of the FreeRTOS distribution and was contributed
 | 
						|
    to the project by Technolution B.V. (www.technolution.nl,
 | 
						|
    freertos-riscv@technolution.eu) under the terms of the FreeRTOS
 | 
						|
    contributors license.
 | 
						|
 | 
						|
    FreeRTOS is free software; you can redistribute it and/or modify it under
 | 
						|
    the terms of the GNU General Public License (version 2) as published by the
 | 
						|
    Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
 | 
						|
 | 
						|
    ***************************************************************************
 | 
						|
    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
 | 
						|
    >>!   distribute a combined work that includes FreeRTOS without being   !<<
 | 
						|
    >>!   obliged to provide the source code for proprietary components     !<<
 | 
						|
    >>!   outside of the FreeRTOS kernel.                                   !<<
 | 
						|
    ***************************************************************************
 | 
						|
 | 
						|
    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
						|
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
						|
    FOR A PARTICULAR PURPOSE.  Full license text is available on the following
 | 
						|
    link: http://www.freertos.org/a00114.html
 | 
						|
 | 
						|
    ***************************************************************************
 | 
						|
     *                                                                       *
 | 
						|
     *    FreeRTOS provides completely free yet professionally developed,    *
 | 
						|
     *    robust, strictly quality controlled, supported, and cross          *
 | 
						|
     *    platform software that is more than just the market leader, it     *
 | 
						|
     *    is the industry's de facto standard.                               *
 | 
						|
     *                                                                       *
 | 
						|
     *    Help yourself get started quickly while simultaneously helping     *
 | 
						|
     *    to support the FreeRTOS project by purchasing a FreeRTOS           *
 | 
						|
     *    tutorial book, reference manual, or both:                          *
 | 
						|
     *    http://www.FreeRTOS.org/Documentation                              *
 | 
						|
     *                                                                       *
 | 
						|
    ***************************************************************************
 | 
						|
 | 
						|
    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
 | 
						|
    the FAQ page "My application does not run, what could be wrong?".  Have you
 | 
						|
    defined configASSERT()?
 | 
						|
 | 
						|
    http://www.FreeRTOS.org/support - In return for receiving this top quality
 | 
						|
    embedded software for free we request you assist our global community by
 | 
						|
    participating in the support forum.
 | 
						|
 | 
						|
    http://www.FreeRTOS.org/training - Investing in training allows your team to
 | 
						|
    be as productive as possible as early as possible.  Now you can receive
 | 
						|
    FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
 | 
						|
    Ltd, and the world's leading authority on the world's leading RTOS.
 | 
						|
 | 
						|
    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
 | 
						|
    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
 | 
						|
    compatible FAT file system, and our tiny thread aware UDP/IP stack.
 | 
						|
 | 
						|
    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
 | 
						|
    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
 | 
						|
 | 
						|
    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
 | 
						|
    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
 | 
						|
    licenses offer ticketed support, indemnification and commercial middleware.
 | 
						|
 | 
						|
    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
 | 
						|
    engineered and independently SIL3 certified version for use in safety and
 | 
						|
    mission critical applications that require provable dependability.
 | 
						|
 | 
						|
    1 tab == 4 spaces!
 | 
						|
*/
 | 
						|
 | 
						|
/*-----------------------------------------------------------
 | 
						|
 * Implementation of functions defined in portable.h for the RISC-V port.
 | 
						|
 *----------------------------------------------------------*/
 | 
						|
 | 
						|
/* Scheduler includes. */
 | 
						|
#include "FreeRTOS.h"
 | 
						|
#include "task.h"
 | 
						|
#include "portmacro.h"
 | 
						|
#include <stdio.h>
 | 
						|
 | 
						|
#define TIMER (*(uint64_t *)0x40004000)
 | 
						|
#define TIMER_CMP (*(uint64_t *)0x40004008)
 | 
						|
#define TRACE (*(unsigned char *)0x40000000)
 | 
						|
 | 
						|
 | 
						|
/* A variable is used to keep track of the critical section nesting.  This
 | 
						|
variable has to be stored as part of the task context and must be initialised to
 | 
						|
a non zero value to ensure interrupts don't inadvertently become unmasked before
 | 
						|
the scheduler starts.  As it is stored as part of the task context it will
 | 
						|
automatically be set to 0 when the first task is started. */
 | 
						|
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
 | 
						|
 | 
						|
/* Contains context when starting scheduler, save all 31 registers */
 | 
						|
#ifdef __gracefulExit
 | 
						|
BaseType_t xStartContext[31] = {0};
 | 
						|
#endif
 | 
						|
 | 
						|
/*
 | 
						|
 * Handler for timer interrupt
 | 
						|
 */
 | 
						|
void vPortSysTickHandler( void );
 | 
						|
 | 
						|
/*
 | 
						|
 * Setup the timer to generate the tick interrupts.
 | 
						|
 */
 | 
						|
void vPortSetupTimer( void );
 | 
						|
 | 
						|
/*
 | 
						|
 * Set the next interval for the timer
 | 
						|
 */
 | 
						|
static void prvSetNextTimerInterrupt( void );
 | 
						|
 | 
						|
/*
 | 
						|
 * Used to catch tasks that attempt to return from their implementing function.
 | 
						|
 */
 | 
						|
static void prvTaskExitError( void );
 | 
						|
 | 
						|
 | 
						|
int _write(int file, const char *ptr, int len) {
 | 
						|
  int x;
 | 
						|
 | 
						|
  for (x = 0; x < len; x++) {
 | 
						|
    TRACE =  *ptr++;
 | 
						|
  }
 | 
						|
 | 
						|
  return (len);
 | 
						|
}
 | 
						|
 | 
						|
int _read(int file, char* ptr, int len) {
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
int _close(int fd){
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
int _fstat_r(int fd) {
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
int _lseek_r(struct _reent *ptr, FILE *fp, long offset, int whence){
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
int _isatty_r(struct _reent *ptr, int fd) {
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
void register_timer_isr() {
 | 
						|
  printf("Registering ISR\n");
 | 
						|
  asm volatile("la t0, TIMER_CMP_INT \n csrw mtvec, t0");
 | 
						|
  asm volatile("li t1, 0x888 \n csrw mie, t1");
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-----------------------------------------------------------*/
 | 
						|
 | 
						|
/* Sets the next timer interrupt
 | 
						|
 * Reads previous timer compare register, and adds tickrate */
 | 
						|
static void prvSetNextTimerInterrupt(void)
 | 
						|
{
 | 
						|
#if 0
 | 
						|
	__asm volatile("csrr t0,mtimecmp");
 | 
						|
	__asm volatile("add t0,t0,%0" :: "r"(configTICK_CLOCK_HZ / configTICK_RATE_HZ));
 | 
						|
	__asm volatile("csrw mtimecmp,t0");
 | 
						|
#endif
 | 
						|
	volatile uint32_t timer_value;
 | 
						|
	timer_value = TIMER;
 | 
						|
// 	timer_value += configTICK_CLOCK_HZ / configTICK_RATE_HZ;
 | 
						|
	timer_value += 10000 - 620;    // timer set to 100 Hz and corrected
 | 
						|
	TIMER_CMP = timer_value;
 | 
						|
  // printf("ISR\n");
 | 
						|
}
 | 
						|
/*-----------------------------------------------------------*/
 | 
						|
 | 
						|
/* Sets and enable the timer interrupt */
 | 
						|
void vPortSetupTimer(void)
 | 
						|
{
 | 
						|
 | 
						|
#if 0
 | 
						|
	__asm volatile("csrr t0,mtime");
 | 
						|
	__asm volatile("add t0,t0,%0"::"r"(configTICK_CLOCK_HZ / configTICK_RATE_HZ));
 | 
						|
	__asm volatile("csrw mtimecmp,t0");
 | 
						|
 | 
						|
	/* Enable timer interupt */
 | 
						|
	__asm volatile("csrs mie,%0"::"r"(0x80));
 | 
						|
#endif
 | 
						|
 | 
						|
        volatile uint32_t timer_value;
 | 
						|
        
 | 
						|
        register_timer_isr();
 | 
						|
        
 | 
						|
        timer_value = TIMER;
 | 
						|
        // timer_value += configTICK_CLOCK_HZ / configTICK_RATE_HZ;
 | 
						|
	timer_value += 10000 - 620;        // timer set to 100 Hz and corrected
 | 
						|
        TIMER_CMP = timer_value;
 | 
						|
}
 | 
						|
/*-----------------------------------------------------------*/
 | 
						|
 | 
						|
void prvTaskExitError( void )
 | 
						|
{
 | 
						|
	/* A function that implements a task must not exit or attempt to return to
 | 
						|
	its caller as there is nothing to return to.  If a task wants to exit it
 | 
						|
	should instead call vTaskDelete( NULL ).
 | 
						|
 | 
						|
	Artificially force an assert() to be triggered if configASSERT() is
 | 
						|
	defined, then stop here so application writers can catch the error. */
 | 
						|
	configASSERT( uxCriticalNesting == ~0UL );
 | 
						|
	portDISABLE_INTERRUPTS();
 | 
						|
	for( ;; );
 | 
						|
}
 | 
						|
/*-----------------------------------------------------------*/
 | 
						|
 | 
						|
/* Clear current interrupt mask and set given mask */
 | 
						|
void vPortClearInterruptMask(int mask)
 | 
						|
{
 | 
						|
	__asm volatile("csrw mie, %0"::"r"(mask));
 | 
						|
}
 | 
						|
/*-----------------------------------------------------------*/
 | 
						|
 | 
						|
/* Set interrupt mask and return current interrupt enable register */
 | 
						|
int vPortSetInterruptMask(void)
 | 
						|
{
 | 
						|
	int ret;
 | 
						|
	__asm volatile("csrr %0,mie":"=r"(ret));
 | 
						|
	__asm volatile("csrc mie,%0"::"i"(7));
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
/*-----------------------------------------------------------*/
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * See header file for description.
 | 
						|
 */
 | 
						|
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
 | 
						|
{
 | 
						|
	/* Simulate the stack frame as it would be created by a context switch
 | 
						|
	interrupt. */
 | 
						|
	register int *tp asm("x3");
 | 
						|
	pxTopOfStack--;
 | 
						|
	*pxTopOfStack = (portSTACK_TYPE)pxCode;			/* Start address */
 | 
						|
	pxTopOfStack -= 22;
 | 
						|
	*pxTopOfStack = (portSTACK_TYPE)pvParameters;	/* Register a0 */
 | 
						|
	pxTopOfStack -= 6;
 | 
						|
	*pxTopOfStack = (portSTACK_TYPE)tp; /* Register thread pointer */
 | 
						|
	pxTopOfStack -= 3;
 | 
						|
	*pxTopOfStack = (portSTACK_TYPE)prvTaskExitError; /* Register ra */
 | 
						|
 | 
						|
	return pxTopOfStack;
 | 
						|
}
 | 
						|
/*-----------------------------------------------------------*/
 | 
						|
 | 
						|
void vPortSysTickHandler( void )
 | 
						|
{
 | 
						|
	prvSetNextTimerInterrupt();
 | 
						|
 | 
						|
	/* Increment the RTOS tick. */
 | 
						|
	if( xTaskIncrementTick() != pdFALSE )
 | 
						|
	{
 | 
						|
		vTaskSwitchContext();
 | 
						|
	}
 | 
						|
}
 | 
						|
/*-----------------------------------------------------------*/
 |