Further work on Pinecil compile

This commit is contained in:
Ben V. Brown
2020-08-18 18:58:00 +10:00
parent 3560f6c5c1
commit 2becaa5eab
22 changed files with 1214 additions and 1260 deletions

View File

@@ -12,7 +12,8 @@ SemaphoreHandle_t FRToSI2C::I2CSemaphore;
StaticSemaphore_t FRToSI2C::xSemaphoreBuffer;
#define FLAG_TIMEOUT 1000
void FRToSI2C::CpltCallback() {
void FRToSI2C::CpltCallback()
{
//TODO
}
@@ -20,28 +21,31 @@ void FRToSI2C::CpltCallback() {
*
* @param obj The I2C object
*/
int i2c_start() {
int i2c_start()
{
int timeout;
/* clear I2C_FLAG_AERR Flag */
i2c_flag_clear(I2C0, I2C_FLAG_AERR);
/* wait until I2C_FLAG_I2CBSY flag is reset */
timeout = FLAG_TIMEOUT
;
while ((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) == SET) {
if ((timeout--) == 0) {
timeout = FLAG_TIMEOUT;
while ((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) == SET)
{
if ((timeout--) == 0)
{
return (int) -1;
return (int)-1;
}
}
/* ensure the i2c has been stopped */
timeout = FLAG_TIMEOUT
;
while ((I2C_CTL0(I2C0) & I2C_CTL0_STOP) == I2C_CTL0_STOP) {
if ((timeout--) == 0) {
return (int) -1;
timeout = FLAG_TIMEOUT;
while ((I2C_CTL0(I2C0) & I2C_CTL0_STOP) == I2C_CTL0_STOP)
{
if ((timeout--) == 0)
{
return (int)-1;
}
}
@@ -49,30 +53,34 @@ int i2c_start() {
i2c_start_on_bus(I2C0);
/* ensure the i2c has been started successfully */
timeout = FLAG_TIMEOUT
;
while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET) {
if ((timeout--) == 0) {
return (int) -1;
timeout = FLAG_TIMEOUT;
while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET)
{
if ((timeout--) == 0)
{
return (int)-1;
}
}
return (int) 0;
return (int)0;
}
/** Send STOP command
*
* @param obj The I2C object
*/
int i2c_stop() {
int i2c_stop()
{
/* generate a STOP condition */
i2c_stop_on_bus(I2C0);
/* wait for STOP bit reset */
int timeout = FLAG_TIMEOUT;
while ((I2C_CTL0(I2C0) & I2C_CTL0_STOP)) {
if ((timeout--) == 0) {
while ((I2C_CTL0(I2C0) & I2C_CTL0_STOP))
{
if ((timeout--) == 0)
{
return -1;
}
}
@@ -86,26 +94,32 @@ int i2c_stop() {
* @param last Acknoledge
* @return The read byte
*/
int i2c_byte_read(int last) {
int i2c_byte_read(int last)
{
int timeout;
if (last) {
if (last)
{
/* disable acknowledge */
i2c_ack_config(I2C0, I2C_ACK_DISABLE);
} else {
}
else
{
/* enable acknowledge */
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
}
/* wait until the byte is received */
timeout = FLAG_TIMEOUT;
while ((i2c_flag_get(I2C0, I2C_FLAG_RBNE)) == RESET) {
if ((timeout--) == 0) {
while ((i2c_flag_get(I2C0, I2C_FLAG_RBNE)) == RESET)
{
if ((timeout--) == 0)
{
return -1;
}
}
return (int) i2c_data_receive(I2C0);
return (int)i2c_data_receive(I2C0);
}
/** Write one byte
@@ -114,15 +128,17 @@ int i2c_byte_read(int last) {
* @param data Byte to be written
* @return 0 if NAK was received, 1 if ACK was received, 2 for timeout.
*/
int i2c_byte_write(int data) {
int i2c_byte_write(int data)
{
int timeout;
i2c_data_transmit(I2C0, data);
/* wait until the byte is transmitted */
timeout = FLAG_TIMEOUT;
while (((i2c_flag_get(I2C0, I2C_FLAG_TBE)) == RESET)
|| ((i2c_flag_get(I2C0, I2C_FLAG_BTC)) == RESET)) {
if ((timeout--) == 0) {
while (((i2c_flag_get(I2C0, I2C_FLAG_TBE)) == RESET) || ((i2c_flag_get(I2C0, I2C_FLAG_BTC)) == RESET))
{
if ((timeout--) == 0)
{
return 2;
}
}
@@ -131,7 +147,8 @@ int i2c_byte_write(int data) {
}
bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
uint8_t *pData, uint16_t Size) {
uint8_t *pData, uint16_t Size)
{
if (!lock())
return false;
@@ -140,13 +157,18 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
/* wait until I2C_FLAG_I2CBSY flag is reset */
timeout = FLAG_TIMEOUT;
while ((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) == SET) {
if ((timeout--) == 0) {
while ((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) == SET)
{
if ((timeout--) == 0)
{
i2c_stop();
unlock();
return false;
} else {
if (timeout % 5 == 0) {
}
else
{
if (timeout % 5 == 0)
{
i2c_stop();
}
}
@@ -155,10 +177,11 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
i2c_start_on_bus(I2C0);
/* ensure the i2c has been started successfully */
timeout = FLAG_TIMEOUT
;
while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET) {
if ((timeout--) == 0) {
timeout = FLAG_TIMEOUT;
while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET)
{
if ((timeout--) == 0)
{
i2c_stop();
unlock();
return false;
@@ -170,9 +193,11 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
timeout = 0;
/* wait until I2C_FLAG_ADDSEND flag is set */
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) {
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND))
{
timeout++;
if (timeout > 100000) {
if (timeout > 100000)
{
i2c_stop();
unlock();
return false;
@@ -180,7 +205,8 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
}
bool no_ack = i2c_flag_get(I2C0, I2C_FLAG_AERR);
no_ack |= i2c_flag_get(I2C0, I2C_FLAG_BERR);
if (no_ack) {
if (no_ack)
{
i2c_stop();
unlock();
return false;
@@ -190,21 +216,23 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
int status = i2c_byte_write(MemAddress);
no_ack |= i2c_flag_get(I2C0, I2C_FLAG_BERR);
no_ack |= i2c_flag_get(I2C0, I2C_FLAG_LOSTARB);
if (status == 2 || no_ack) {
if (status == 2 || no_ack)
{
i2c_stop();
unlock();
return false;
}
//////////////////////////// //Restart into read
//////////////////////////// //Restart into read
/* generate a START condition */
i2c_start_on_bus(I2C0);
/* ensure the i2c has been started successfully */
timeout = FLAG_TIMEOUT
;
while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET) {
if ((timeout--) == 0) {
timeout = FLAG_TIMEOUT;
while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET)
{
if ((timeout--) == 0)
{
i2c_stop();
unlock();
return false;
@@ -216,9 +244,11 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
timeout = 0;
/* wait until I2C_FLAG_ADDSEND flag is set */
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) {
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND))
{
timeout++;
if (timeout > 100000) {
if (timeout > 100000)
{
i2c_stop();
unlock();
return false;
@@ -228,13 +258,15 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
/* clear ADDSEND */
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
no_ack = i2c_flag_get(I2C0, I2C_FLAG_AERR);
if (no_ack) {
if (no_ack)
{
i2c_stop();
unlock();
return false;
}
for (count = 0; count < Size; count++) {
pData[count] = i2c_byte_read(count == (Size - 1));
for (count = 0; count < Size; count++)
{
pData[count] = i2c_byte_read(count == (uint32_t)(Size - 1));
}
/* if not sequential write, then send stop */
@@ -243,17 +275,20 @@ bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
unlock();
return true;
}
void FRToSI2C::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data) {
void FRToSI2C::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data)
{
Mem_Write(address, reg, &data, 1);
}
uint8_t FRToSI2C::I2C_RegisterRead(uint8_t add, uint8_t reg) {
uint8_t FRToSI2C::I2C_RegisterRead(uint8_t add, uint8_t reg)
{
uint8_t temp = 0;
Mem_Read(add, reg, &temp, 1);
return temp;
}
void FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
uint8_t *pData, uint16_t Size) {
uint8_t *pData, uint16_t Size)
{
if (!lock())
return;
@@ -261,15 +296,19 @@ void FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
int timeout = 0;
/* wait until I2C_FLAG_I2CBSY flag is reset */
timeout = FLAG_TIMEOUT
;
while ((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) == SET) {
if ((timeout--) == 0) {
timeout = FLAG_TIMEOUT;
while ((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) == SET)
{
if ((timeout--) == 0)
{
i2c_stop();
unlock();
return;
} else {
if (timeout % 5 == 0) {
}
else
{
if (timeout % 5 == 0)
{
i2c_stop();
}
}
@@ -278,10 +317,11 @@ void FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
i2c_start_on_bus(I2C0);
/* ensure the i2c has been started successfully */
timeout = FLAG_TIMEOUT
;
while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET) {
if ((timeout--) == 0) {
timeout = FLAG_TIMEOUT;
while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET)
{
if ((timeout--) == 0)
{
i2c_stop();
unlock();
return;
@@ -293,9 +333,11 @@ void FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
timeout = 0;
/* wait until I2C_FLAG_ADDSEND flag is set */
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) {
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND))
{
timeout++;
if (timeout > 100000) {
if (timeout > 100000)
{
i2c_stop();
unlock();
return;
@@ -305,9 +347,11 @@ void FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
/* clear ADDSEND */
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
int status = i2c_byte_write(MemAddress);
for (count = 0; count < Size; count++) {
for (count = 0; count < Size; count++)
{
status = i2c_byte_write(pData[count]);
if (status != 1) {
if (status != 1)
{
i2c_stop();
unlock();
return;
@@ -320,7 +364,8 @@ void FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
unlock();
}
void FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
void FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size)
{
if (!lock())
return;
uint32_t count = 0;
@@ -328,13 +373,18 @@ void FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
/* wait until I2C_FLAG_I2CBSY flag is reset */
timeout = FLAG_TIMEOUT;
while ((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) == SET) {
if ((timeout--) == 0) {
while ((i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) == SET)
{
if ((timeout--) == 0)
{
i2c_stop();
unlock();
return;
} else {
if (timeout % 5 == 0) {
}
else
{
if (timeout % 5 == 0)
{
i2c_stop();
}
}
@@ -343,10 +393,11 @@ void FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
i2c_start_on_bus(I2C0);
/* ensure the i2c has been started successfully */
timeout = FLAG_TIMEOUT
;
while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET) {
if ((timeout--) == 0) {
timeout = FLAG_TIMEOUT;
while ((i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) == RESET)
{
if ((timeout--) == 0)
{
i2c_stop();
unlock();
return;
@@ -358,9 +409,11 @@ void FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
timeout = 0;
/* wait until I2C_FLAG_ADDSEND flag is set */
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) {
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND))
{
timeout++;
if (timeout > 100000) {
if (timeout > 100000)
{
i2c_stop();
unlock();
return;
@@ -370,9 +423,11 @@ void FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
/* clear ADDSEND */
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
for (count = 0; count < Size; count++) {
for (count = 0; count < Size; count++)
{
int status = i2c_byte_write(pData[count]);
if (status != 1) {
if (status != 1)
{
i2c_stop();
unlock();
return;
@@ -385,7 +440,8 @@ void FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
unlock();
}
bool FRToSI2C::probe(uint16_t DevAddress) {
bool FRToSI2C::probe(uint16_t DevAddress)
{
if (!lock())
return false;
i2c_start();
@@ -393,14 +449,16 @@ bool FRToSI2C::probe(uint16_t DevAddress) {
i2c_master_addressing(I2C0, DevAddress, I2C_TRANSMITTER);
/* wait until ADDSEND bit is set */
int timeout = FLAG_TIMEOUT;
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) {
if (i2c_flag_get(I2C0, I2C_FLAG_AERR)
|| i2c_flag_get(I2C0, I2C_FLAG_BERR)) {
while (!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND))
{
if (i2c_flag_get(I2C0, I2C_FLAG_AERR) || i2c_flag_get(I2C0, I2C_FLAG_BERR))
{
i2c_stop();
unlock();
return false;
}
if (timeout-- == 0) {
if (timeout-- == 0)
{
i2c_stop();
unlock();
return false;
@@ -422,17 +480,20 @@ bool FRToSI2C::probe(uint16_t DevAddress) {
return !no_ack;
}
void FRToSI2C::I2C_Unstick() {
void FRToSI2C::I2C_Unstick()
{
unstick_I2C();
}
bool FRToSI2C::lock() {
bool FRToSI2C::lock()
{
if (I2CSemaphore == nullptr)
return true;
return xSemaphoreTake(I2CSemaphore,1000) == pdTRUE;
return xSemaphoreTake(I2CSemaphore, 1000) == pdTRUE;
}
void FRToSI2C::unlock() {
void FRToSI2C::unlock()
{
if (I2CSemaphore == nullptr)
return;
xSemaphoreGive(I2CSemaphore);

View File

@@ -0,0 +1,27 @@
/*
* Model_Config.h
*
* Created on: 25 Jul 2020
* Author: Ralim
*/
#ifndef BSP_MINIWARE_MODEL_CONFIG_H_
#define BSP_MINIWARE_MODEL_CONFIG_H_
/*
* Lookup for mapping features <-> Models
*/
#if defined(MODEL_Pinecil) > 1
#error "Multiple models defined!"
#elif defined(MODEL_Pinecil) == 0
#error "No model defined!"
#endif
#ifdef MODEL_Pinecil
#define ACCEL_LIS
#define TEMP_TMP36
#define POW_QC
#define POW_PD
#endif
#endif /* BSP_MINIWARE_MODEL_CONFIG_H_ */

View File

@@ -1,3 +1,4 @@
#include "FreeRTOSConfig.h"
#include "FreeRTOS.h"
#include "task.h"
#include "portmacro.h"
@@ -6,36 +7,32 @@
#include "riscv_encoding.h"
#include "n200_timer.h"
#include "n200_eclic.h"
/* Standard Includes */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
/* Each task maintains its own interrupt status in the critical nesting variable. */
UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
#if USER_MODE_TASKS
#ifdef __riscv_flen
unsigned long MSTATUS_INIT = (MSTATUS_MPIE | (0x1 << 13));
unsigned long MSTATUS_INIT = (MSTATUS_MPIE | (0x1 << 13));
#else
unsigned long MSTATUS_INIT = (MSTATUS_MPIE);
unsigned long MSTATUS_INIT = (MSTATUS_MPIE);
#endif
#else
#ifdef __riscv_flen
unsigned long MSTATUS_INIT = (MSTATUS_MPP | MSTATUS_MPIE | (0x1 << 13));
unsigned long MSTATUS_INIT = (MSTATUS_MPP | MSTATUS_MPIE | (0x1 << 13));
#else
unsigned long MSTATUS_INIT = (MSTATUS_MPP | MSTATUS_MPIE);
unsigned long MSTATUS_INIT = (MSTATUS_MPP | MSTATUS_MPIE);
#endif
#endif
/*
* Used to catch tasks that attempt to return from their implementing function.
*/
static void prvTaskExitError( void );
static void prvTaskExitError(void);
/**
* @brief System Call Trap
@@ -47,52 +44,51 @@ static void prvTaskExitError( void );
*/
unsigned long ulSynchTrap(unsigned long mcause, unsigned long sp, unsigned long arg1)
{
switch(mcause&0X00000fff)
switch (mcause & 0X00000fff)
{
//on User and Machine ECALL, handler the request
case 8:
case 11:
//on User and Machine ECALL, handler the request
case 8:
case 11:
{
if (arg1 == IRQ_DISABLE)
{
if(arg1==IRQ_DISABLE)
{
//zero out mstatus.mpie
clear_csr(mstatus,MSTATUS_MPIE);
}
else if(arg1==IRQ_ENABLE)
{
//set mstatus.mpie
set_csr(mstatus,MSTATUS_MPIE);
}
else if(arg1==PORT_YIELD)
{
//always yield from machine mode
//fix up mepc on sync trap
unsigned long epc = read_csr(mepc);
vPortYield_from_ulSynchTrap(sp,epc+4);
}
else if(arg1==PORT_YIELD_TO_RA)
{
vPortYield_from_ulSynchTrap(sp,(*(unsigned long*)(sp+1*sizeof(sp))));
}
break;
//zero out mstatus.mpie
clear_csr(mstatus, MSTATUS_MPIE);
}
default:
else if (arg1 == IRQ_ENABLE)
{
/* 异常处理 */
extern uintptr_t handle_trap(uintptr_t mcause, uintptr_t sp);
handle_trap(mcause,sp);
//set mstatus.mpie
set_csr(mstatus, MSTATUS_MPIE);
}
else if (arg1 == PORT_YIELD)
{
//always yield from machine mode
//fix up mepc on sync trap
unsigned long epc = read_csr(mepc);
vPortYield_from_ulSynchTrap(sp, epc + 4);
}
else if (arg1 == PORT_YIELD_TO_RA)
{
vPortYield_from_ulSynchTrap(sp, (*(unsigned long *)(sp + 1 * sizeof(sp))));
}
break;
}
default:
{
/* 异常处理 */
extern uintptr_t handle_trap(uintptr_t mcause, uintptr_t sp);
handle_trap(mcause, sp);
}
}
//fix mepc and return
unsigned long epc = read_csr(mepc);
write_csr(mepc,epc+4);
write_csr(mepc, epc + 4);
return sp;
}
/*-----------------------------------------------------------*/
/**
* @brief 设置触发软中断
* @note 目的是在软中断内进行任务上下文切换
@@ -100,24 +96,22 @@ unsigned long ulSynchTrap(unsigned long mcause, unsigned long sp, unsigned long
*/
void vPortSetMSIPInt(void)
{
*(volatile uint8_t *) (TIMER_CTRL_ADDR + TIMER_MSIP) |=0x01;
*(volatile uint8_t *)(TIMER_CTRL_ADDR + TIMER_MSIP) |= 0x01;
__asm volatile("fence");
__asm volatile("fence.i");
}
/*-----------------------------------------------------------*/
/**
* @brief 清除软中断
*
*/
void vPortClearMSIPInt(void)
{
*(volatile uint8_t *) (TIMER_CTRL_ADDR + TIMER_MSIP) &= ~0x01;
*(volatile uint8_t *)(TIMER_CTRL_ADDR + TIMER_MSIP) &= ~0x01;
}
/*-----------------------------------------------------------*/
/**
* @brief 执行任务上下文切换,在portasm.S中被调用
*
@@ -125,23 +119,22 @@ void vPortClearMSIPInt(void)
* @param arg1
* @return unsigned long sp地址
*/
unsigned long taskswitch( unsigned long sp, unsigned long arg1)
unsigned long taskswitch(unsigned long sp, unsigned long arg1)
{
//always yield from machine mode
//fix up mepc on
unsigned long epc = read_csr(mepc);
vPortYield(sp,epc); //never returns
vPortYield(sp, epc); //never returns
return sp;
}
/*-----------------------------------------------------------*/
/**
* @brief 调研freertos内建函数vTaskSwitchContext,在portasm.S中被调用
*
*/
void vDoTaskSwitchContext( void )
void vDoTaskSwitchContext(void)
{
portDISABLE_INTERRUPTS();
vTaskSwitchContext();
@@ -149,45 +142,42 @@ void vDoTaskSwitchContext( void )
}
/*-----------------------------------------------------------*/
/**
* @brief 进入临界段
*
*/
void vPortEnterCritical( void )
void vPortEnterCritical(void)
{
#if USER_MODE_TASKS
ECALL(IRQ_DISABLE);
#else
portDISABLE_INTERRUPTS();
#endif
#if USER_MODE_TASKS
ECALL(IRQ_DISABLE);
#else
portDISABLE_INTERRUPTS();
#endif
uxCriticalNesting++;
}
/*-----------------------------------------------------------*/
/**
* @brief 退出临界段
*
*/
void vPortExitCritical( void )
void vPortExitCritical(void)
{
configASSERT( uxCriticalNesting );
configASSERT(uxCriticalNesting);
uxCriticalNesting--;
if( uxCriticalNesting == 0 )
if (uxCriticalNesting == 0)
{
#if USER_MODE_TASKS
ECALL(IRQ_ENABLE);
#else
portENABLE_INTERRUPTS();
#endif
#if USER_MODE_TASKS
ECALL(IRQ_ENABLE);
#else
portENABLE_INTERRUPTS();
#endif
}
return;
}
/*-----------------------------------------------------------*/
/**
* @brief Clear current interrupt mask and set given mask
*
@@ -195,11 +185,10 @@ void vPortExitCritical( void )
*/
void vPortClearInterruptMask(int int_mask)
{
eclic_set_mth (int_mask);
eclic_set_mth(int_mask);
}
/*-----------------------------------------------------------*/
/**
* @brief Set interrupt mask and return current interrupt enable register
*
@@ -207,15 +196,14 @@ void vPortClearInterruptMask(int int_mask)
*/
int xPortSetInterruptMask(void)
{
int int_mask=0;
int_mask=eclic_get_mth();
int int_mask = 0;
int_mask = eclic_get_mth();
portDISABLE_INTERRUPTS();
return int_mask;
}
/*-----------------------------------------------------------*/
/**
* @brief 初始化任务栈帧
*
@@ -224,30 +212,30 @@ int xPortSetInterruptMask(void)
* @param pvParameters 任务参数
* @return StackType_t* 完成初始化后的栈顶
*/
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
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. */
#ifdef __riscv_flen
pxTopOfStack -= 32; /* 浮点寄存器 */
pxTopOfStack -= 32; /* 浮点寄存器 */
#endif
pxTopOfStack--;
*pxTopOfStack = 0xb8000000; /* CSR_MCAUSE */
*pxTopOfStack = 0xb8000000; /* CSR_MCAUSE */
pxTopOfStack--;
*pxTopOfStack = 0x40; /* CSR_SUBM */
*pxTopOfStack = 0x40; /* CSR_SUBM */
pxTopOfStack--;
*pxTopOfStack = (portSTACK_TYPE)pxCode; /* Start address */
*pxTopOfStack = (portSTACK_TYPE)pxCode; /* Start address */
pxTopOfStack--;
*pxTopOfStack = MSTATUS_INIT; /* CSR_MSTATUS */
*pxTopOfStack = MSTATUS_INIT; /* CSR_MSTATUS */
pxTopOfStack -= 22;
*pxTopOfStack = (portSTACK_TYPE)pvParameters; /* Register a0 */
*pxTopOfStack = (portSTACK_TYPE)pvParameters; /* Register a0 */
pxTopOfStack -=9;
pxTopOfStack -= 9;
*pxTopOfStack = (portSTACK_TYPE)prvTaskExitError; /* Register ra */
pxTopOfStack--;
@@ -255,25 +243,24 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
}
/*-----------------------------------------------------------*/
/**
* @brief 任务退出函数
*
*/
void prvTaskExitError( void )
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 );
configASSERT(uxCriticalNesting == ~0UL);
portDISABLE_INTERRUPTS();
for( ;; );
for (;;)
;
}
/*-----------------------------------------------------------*/
/**
* @brief tick中断
* @note 由于该中断配置为向量模式则中断到来会调用portasm.S的MTIME_HANDLER,进行栈帧保存之后该函数会调用vPortSysTickHandler
@@ -281,39 +268,38 @@ void prvTaskExitError( void )
*/
void vPortSysTickHandler(void)
{
volatile uint64_t * mtime = (uint64_t*) (TIMER_CTRL_ADDR + TIMER_MTIME);
volatile uint64_t * mtimecmp = (uint64_t*) (TIMER_CTRL_ADDR + TIMER_MTIMECMP);
volatile uint64_t *mtime = (uint64_t *)(TIMER_CTRL_ADDR + TIMER_MTIME);
volatile uint64_t *mtimecmp = (uint64_t *)(TIMER_CTRL_ADDR + TIMER_MTIMECMP);
UBaseType_t uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
#if CONFIG_SYSTEMVIEW_EN
#if CONFIG_SYSTEMVIEW_EN
traceISR_ENTER();
#endif
#endif
uint64_t now = *mtime;
now += (configRTC_CLOCK_HZ / configTICK_RATE_HZ);
*mtimecmp = now;
/* 调用freertos的tick增加接口 */
if( xTaskIncrementTick() != pdFALSE )
if (xTaskIncrementTick() != pdFALSE)
{
#if CONFIG_SYSTEMVIEW_EN
#if CONFIG_SYSTEMVIEW_EN
traceISR_EXIT_TO_SCHEDULER();
#endif
#endif
portYIELD();
}
#if CONFIG_SYSTEMVIEW_EN
#if CONFIG_SYSTEMVIEW_EN
else
{
traceISR_EXIT();
}
#endif
#endif
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus);
}
/*-----------------------------------------------------------*/
/**
* @brief 初始化tick
*
@@ -321,21 +307,20 @@ void vPortSysTickHandler(void)
void vPortSetupTimer(void)
{
/* 内核timer定时器使用64位的计数器来实现 */
volatile uint64_t * mtime = (uint64_t*) (TIMER_CTRL_ADDR + TIMER_MTIME);
volatile uint64_t * mtimecmp = (uint64_t*) (TIMER_CTRL_ADDR + TIMER_MTIMECMP);
volatile uint64_t *mtime = (uint64_t *)(TIMER_CTRL_ADDR + TIMER_MTIME);
volatile uint64_t *mtimecmp = (uint64_t *)(TIMER_CTRL_ADDR + TIMER_MTIMECMP);
portENTER_CRITICAL();
uint64_t now = *mtime;
now += (configRTC_CLOCK_HZ / configTICK_RATE_HZ);
*mtimecmp = now;
uint64_t now = *mtime;
now += (configRTC_CLOCK_HZ / configTICK_RATE_HZ);
*mtimecmp = now;
portEXIT_CRITICAL();
eclic_set_vmode(CLIC_INT_TMR);
eclic_irq_enable(CLIC_INT_TMR,configKERNEL_INTERRUPT_PRIORITY>>configPRIO_BITS,0);
eclic_irq_enable(CLIC_INT_TMR, configKERNEL_INTERRUPT_PRIORITY >> configPRIO_BITS, 0);
}
/*-----------------------------------------------------------*/
/**
* @brief 初始化软中断
*
@@ -343,11 +328,10 @@ void vPortSetupTimer(void)
void vPortSetupMSIP(void)
{
eclic_set_vmode(CLIC_INT_SFT);
eclic_irq_enable(CLIC_INT_SFT,configKERNEL_INTERRUPT_PRIORITY>>configPRIO_BITS,0);
eclic_irq_enable(CLIC_INT_SFT, configKERNEL_INTERRUPT_PRIORITY >> configPRIO_BITS, 0);
}
/*-----------------------------------------------------------*/
/**
* @brief 调度启动前的初始化准备
*

View File

@@ -1,14 +1,13 @@
#ifndef PORTMACRO_H
#define PORTMACRO_H
#ifndef PINE_PORTMACRO_H
#define PINE_PORTMACRO_H
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
#include "riscv_encoding.h"
/*-----------------------------------------------------------
* Port specific definitions.
*
@@ -20,123 +19,128 @@ extern "C" {
*/
/* Type definitions. */
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
#define portCHAR char
#define portFLOAT float
#define portDOUBLE double
#define portLONG long
#define portSHORT short
#define portSTACK_TYPE uint32_t
#define portBASE_TYPE long
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
#if( configUSE_16_BIT_TICKS == 1 )
#if (configUSE_16_BIT_TICKS == 1)
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#define portMAX_DELAY (TickType_t)0xffff
#else
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
typedef uint32_t TickType_t;
#define portMAX_DELAY (TickType_t)0xffffffffUL
#endif
/*-----------------------------------------------------------*/
/* Architecture specifics. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
/*-----------------------------------------------------------*/
/* Architecture specifics. */
extern void vPortYield(unsigned long,unsigned long);
extern void vPortYield_from_ulSynchTrap(unsigned long,unsigned long);
extern int xPortSetInterruptMask(void);
extern void vPortClearInterruptMask( int uxSavedStatusValue );
#define portSTACK_GROWTH (-1)
#define portTICK_PERIOD_MS ((TickType_t)1000 / configTICK_RATE_HZ)
#define portBYTE_ALIGNMENT 8
/*-----------------------------------------------------------*/
/* Architecture specifics. */
extern void vPortYield(unsigned long, unsigned long);
extern void vPortYield_from_ulSynchTrap(unsigned long, unsigned long);
extern int xPortSetInterruptMask(void);
extern void vPortClearInterruptMask(int uxSavedStatusValue);
/*-----------------------------------------------------------*/
/*System Calls */
/*-----------------------------------------------------------*/
//ecall macro used to store argument in a3
#define ECALL(arg) ({ \
register uintptr_t a2 asm ("a2") = (uintptr_t)(arg); \
asm volatile ("ecall" \
: "+r" (a2) \
: \
: "memory"); \
a2; \
#define ECALL(arg) ({ \
register uintptr_t a2 asm("a2") = (uintptr_t)(arg); \
asm volatile("ecall" \
: "+r"(a2) \
: \
: "memory"); \
a2; \
})
extern void vPortSetMSIPInt(void);
extern void vPortSetMSIPInt(void);
#define port_MSIPSET_BIT vPortSetMSIPInt()
#define IRQ_DISABLE 20
#define IRQ_ENABLE 30
#define PORT_YIELD 40
#define PORT_YIELD_TO_RA 50
#define IRQ_DISABLE 20
#define IRQ_ENABLE 30
#define PORT_YIELD 40
#define PORT_YIELD_TO_RA 50
/*-----------------------------------------------------------*/
/* Scheduler utilities. */
/* the return after the ECALL is VERY important */
//#define portYIELD() ECALL(PORT_YIELD);
#define portYIELD() port_MSIPSET_BIT;
#if CONFIG_SYSTEMVIEW_EN
#define portEND_SWITCHING_ISR(xSwitchRequired) { if( xSwitchRequired != pdFALSE) { traceISR_EXIT_TO_SCHEDULER(); portYIELD(); } else {traceISR_EXIT(); } }
#ifdef CONFIG_SYSTEMVIEW_EN
#define portEND_SWITCHING_ISR(xSwitchRequired) \
{ \
if (xSwitchRequired != pdFALSE) \
{ \
traceISR_EXIT_TO_SCHEDULER(); \
portYIELD(); \
} \
else \
{ \
traceISR_EXIT(); \
} \
}
#else
#define portEND_SWITCHING_ISR(xSwitchRequired) if( xSwitchRequired != pdFALSE) portYIELD()
#define portEND_SWITCHING_ISR(xSwitchRequired) \
if (xSwitchRequired != pdFALSE) \
portYIELD()
#endif
#define portYIELD_FROM_ISR(x) portEND_SWITCHING_ISR(x)
#define portYIELD_FROM_ISR(x) portEND_SWITCHING_ISR(x)
/* Critical section management. */
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
extern void eclic_set_mth (uint8_t mth);
#define portDISABLE_INTERRUPTS() \
{ \
eclic_set_mth((configMAX_SYSCALL_INTERRUPT_PRIORITY)|0x1f); \
__asm volatile("fence"); \
__asm volatile("fence.i"); \
}
#define portENABLE_INTERRUPTS() eclic_set_mth(0)
#define portSET_INTERRUPT_MASK_FROM_ISR() xPortSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) vPortClearInterruptMask( uxSavedStatusValue )
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
/* Critical section management. */
extern void vPortEnterCritical(void);
extern void vPortExitCritical(void);
extern void eclic_set_mth(uint8_t mth);
#define portDISABLE_INTERRUPTS() \
{ \
eclic_set_mth((configMAX_SYSCALL_INTERRUPT_PRIORITY) | 0x1f); \
__asm volatile("fence"); \
__asm volatile("fence.i"); \
}
#define portENABLE_INTERRUPTS() eclic_set_mth(0)
#define portSET_INTERRUPT_MASK_FROM_ISR() xPortSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedStatusValue) vPortClearInterruptMask(uxSavedStatusValue)
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. These are
not necessary for to use this port. They are defined so the common demo files
(which build with all the ports) will build. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION_PROTO(vFunction, pvParameters) void vFunction(void *pvParameters)
#define portTASK_FUNCTION(vFunction, pvParameters) void vFunction(void *pvParameters)
/*-----------------------------------------------------------*/
/* Tickless idle/low power functionality. */
#ifndef portSUPPRESS_TICKS_AND_SLEEP
extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
extern void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime);
#define portSUPPRESS_TICKS_AND_SLEEP(xExpectedIdleTime) vPortSuppressTicksAndSleep(xExpectedIdleTime)
#endif
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
#define portINLINE __inline
#define portINLINE __inline
#ifndef portFORCE_INLINE
#define portFORCE_INLINE inline __attribute__(( always_inline))
#define portFORCE_INLINE inline __attribute__((always_inline))
#endif
#ifdef __cplusplus
}
#endif
#endif /* PORTMACRO_H */

View File

@@ -1,176 +0,0 @@
OUTPUT_ARCH( "riscv" )
ENTRY( _start )
MEMORY
{
/* Run in FLASH */
flash (rxai!w) : ORIGIN = 0x08000000, LENGTH = 128k
ram (wxa!ri) : ORIGIN = 0x20000000, LENGTH = 32K
/* Run in RAM */
/* flash (rxai!w) : ORIGIN = 0x20000000, LENGTH = 24k
ram (wxa!ri) : ORIGIN = 0x20006000, LENGTH = 8K
*/
}
SECTIONS
{
__stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
.init :
{
KEEP (*(SORT_NONE(.init)))
} >flash AT>flash
.ilalign :
{
. = ALIGN(4);
PROVIDE( _ilm_lma = . );
} >flash AT>flash
.ialign :
{
PROVIDE( _ilm = . );
} >flash AT>flash
.text :
{
*(.rodata .rodata.*)
*(.text.unlikely .text.unlikely.*)
*(.text.startup .text.startup.*)
*(.text .text.*)
*(.gnu.linkonce.t.*)
} >flash AT>flash
.fini :
{
KEEP (*(SORT_NONE(.fini)))
} >flash AT>flash
. = ALIGN(4);
PROVIDE (__etext = .);
PROVIDE (_etext = .);/*0x80022c8*/
PROVIDE (etext = .);/*0x80022c8*/
PROVIDE( _eilm = . );
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >flash AT>flash
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
} >flash AT>flash
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
} >flash AT>flash
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
} >flash AT>flash
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >flash AT>flash
. = ALIGN(4);
PROVIDE( _eilm = . );
.lalign :
{
. = ALIGN(4);
PROVIDE( _data_lma = . );
} >flash AT>flash
.dalign :
{
. = ALIGN(4);
PROVIDE( _data = . );
} >ram AT>flash
.data :
{
*(.rdata)
*(.gnu.linkonce.r.*)
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800);
*(.sdata .sdata.*)
*(.gnu.linkonce.s.*)
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
} >ram AT>flash
. = ALIGN(4);
PROVIDE( _edata = . );
PROVIDE( edata = . );
PROVIDE( _fbss = . ); /*0X200052A0 0X200002A0*/
PROVIDE( __bss_start = . );
.bss :
{
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
} >ram AT>ram
. = ALIGN(8);
PROVIDE( _end = . ); /*0X2000,0340*/
PROVIDE( end = . );
PROVIDE( heap_start = . );
.stack ORIGIN(ram) + LENGTH(ram) - __stack_size :
{
PROVIDE( heap_end = . );
. = __stack_size;
PROVIDE( _sp = . );
} >ram AT>ram
}