mirror of
https://gitee.com/Vancouver2017/luban-lite-t3e-pro.git
synced 2025-12-15 10:58:54 +00:00
v1.0.3
This commit is contained in:
@@ -2,10 +2,7 @@ Import('AIC_ROOT')
|
||||
Import('PRJ_KERNEL')
|
||||
from building import *
|
||||
|
||||
if GetDepend('KERNEL_RTTHREAD') == True:
|
||||
src = Glob('*.c')
|
||||
else:
|
||||
src = []
|
||||
src = Glob('*.c')
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
CPPPATH = [cwd + '/../include/', ]
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
* Authors: Mingfeng.Li <mingfeng.li@artinchip.com>
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#if defined(RT_USING_FINSH) && defined(AIC_AXICFG_DRV)
|
||||
#include <rtthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -4,22 +4,29 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <rtconfig.h>
|
||||
#ifdef RT_USING_FINSH
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <finsh.h>
|
||||
#include "aic_osal.h"
|
||||
#include "aic_common.h"
|
||||
|
||||
#define printf rt_kprintf
|
||||
#ifdef AIC_CONSOLE_BARE_DRV
|
||||
#include "console.h"
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_FINSH
|
||||
#include <rtconfig.h>
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <finsh.h>
|
||||
|
||||
#define printf rt_kprintf
|
||||
#define THREAD_NAME_LEN 64
|
||||
|
||||
struct memtest_para {
|
||||
u32 address;
|
||||
u32 size;
|
||||
char thread_name[64];
|
||||
char thread_name[THREAD_NAME_LEN];
|
||||
bool auto_addr;
|
||||
};
|
||||
|
||||
@@ -118,11 +125,11 @@ static void memtest_thread(void *arg)
|
||||
goto memtest_thread_err;
|
||||
}
|
||||
para.address = (long)malloc_addr;
|
||||
memset(para.thread_name, 0, 64);
|
||||
memset(para.thread_name, 0, THREAD_NAME_LEN);
|
||||
}
|
||||
sprintf(para.thread_name, "memtest_0x%x-0x%x, size=0x%x", para.address,
|
||||
para.address + para.size, para.size);
|
||||
printf("memtest,address: 0x%08X size: 0x%08X\r\n", para.address, para.size);
|
||||
snprintf(para.thread_name, THREAD_NAME_LEN, "memtest_0x%x-0x%x, size=0x%x",
|
||||
para.address, para.address + para.size, para.size);
|
||||
printf("memtest address 0x%08X, size 0x%08X\r\n", para.address, para.size);
|
||||
|
||||
do {
|
||||
loop_times++;
|
||||
@@ -150,7 +157,7 @@ static void cmd_mem_test(int argc, char **argv)
|
||||
u32 address = 0;
|
||||
u32 size = 0;
|
||||
rt_thread_t thid;
|
||||
char thread_name[32] = { 0 };
|
||||
char thread_name[THREAD_NAME_LEN] = { 0 };
|
||||
struct memtest_para para;
|
||||
memset(¶, 0, sizeof(struct memtest_para));
|
||||
char *str_tmp;
|
||||
@@ -165,14 +172,15 @@ static void cmd_mem_test(int argc, char **argv)
|
||||
if (argc == 2) {
|
||||
para.auto_addr = 1;
|
||||
size = strtol(argv[1], &str_tmp, 16);
|
||||
sprintf(thread_name, "memtest_auto_addr-0x%x", size);
|
||||
snprintf(thread_name, THREAD_NAME_LEN, "memtest_auto_addr-0x%x", size);
|
||||
} else if (argc == 3) {
|
||||
address = strtol(argv[1], &str_tmp, 16);
|
||||
size = strtol(argv[2], &str_tmp, 16);
|
||||
para.address = address;
|
||||
sprintf(thread_name, "memtest_0x%x-0x%x", address, address + size);
|
||||
snprintf(thread_name, THREAD_NAME_LEN, "memtest_0x%x-0x%x",
|
||||
address, address + size);
|
||||
}
|
||||
sprintf(para.thread_name, "%s", thread_name);
|
||||
snprintf(para.thread_name, THREAD_NAME_LEN, "%s", thread_name);
|
||||
para.size = size;
|
||||
|
||||
thid = aicos_thread_create(thread_name, 4096, 10, memtest_thread, ¶);
|
||||
@@ -188,3 +196,158 @@ static void cmd_mem_test(int argc, char **argv)
|
||||
MSH_CMD_EXPORT_ALIAS(cmd_mem_test, mem_test, memory test: mem_test address_hex size_hex);
|
||||
|
||||
#endif /* RT_USING_FINSH */
|
||||
|
||||
static int cmd_test_cache(int argc, char **argv)
|
||||
{
|
||||
u32 addr = 0, len = 0;
|
||||
|
||||
if (argc != 4) {
|
||||
printf("Invalid argument. Usage: \n");
|
||||
printf(" %s [i/c/f] [Phy addr] [len]\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
addr = strtol(argv[2], NULL, 16);
|
||||
len = atoi(argv[3]);
|
||||
switch (argv[1][0]) {
|
||||
case 'i':
|
||||
printf("Invalid Cache 0x%08x, len %d\n", addr, len);
|
||||
aicos_dcache_invalid_range((void *)(ptr_t)addr, len);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf("Clean Cache 0x%08x, len %d\n", addr, len);
|
||||
aicos_dcache_clean_range((void *)(ptr_t)addr, len);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
printf("Clean and invalid Cache 0x%08x, len %d\n", addr, len);
|
||||
aicos_dcache_clean_invalid_range((void *)(ptr_t)addr, len);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Invalid Cache operation: %s\n", argv[1]);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#ifdef RT_USING_FINSH
|
||||
MSH_CMD_EXPORT_ALIAS(cmd_test_cache, test_cache, Cache operation test);
|
||||
#endif
|
||||
#ifdef AIC_CONSOLE_BARE_DRV
|
||||
CONSOLE_CMD(test_cache, cmd_test_cache, "Cache operation test");
|
||||
#endif
|
||||
|
||||
static char *show_size(u32 size)
|
||||
{
|
||||
static char str[32] = "";
|
||||
|
||||
memset(str, 0, 32);
|
||||
if (size >= 0x100000) {
|
||||
if ((size >> 10) % 0x400)
|
||||
snprintf(str, 32, "%d MB %d KB", size >> 20, (size >> 10) % 0x400);
|
||||
else
|
||||
snprintf(str, 32, "%d MB", size >> 20);
|
||||
} else if (size >= 0x400) {
|
||||
snprintf(str, 32, "%d KB", size >> 10);
|
||||
} else {
|
||||
snprintf(str, 32, "%d B", size);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
#define PRINT_MEM_ITEM(name, s, e) \
|
||||
do { \
|
||||
int size = (int)(ptr_t)&e - (int)(ptr_t)&s; \
|
||||
if (size) \
|
||||
printf("%-16s 0x%08X 0x%08X 0x%08X (%s)\n", name, \
|
||||
(int)(ptr_t)&s, (int)(ptr_t)&e, size, show_size(size)); \
|
||||
else \
|
||||
printf("%-16s %10d %10d %10d \n", name, 0, 0, 0); \
|
||||
} while (0)
|
||||
|
||||
#define PRINT_MEM_ITEM_EX(name, s, e) \
|
||||
do { \
|
||||
extern int s, e; \
|
||||
PRINT_MEM_ITEM(name, s, e); \
|
||||
} while (0)
|
||||
|
||||
static int cmd_meminfo(int argc, char **argv)
|
||||
{
|
||||
printf("--------------------------------------------------------------\n");
|
||||
printf("Name Start End Size \n");
|
||||
printf("---------------- ---------- ---------- -----------------------\n");
|
||||
|
||||
#ifdef AIC_DRAM_TOTAL_SIZE
|
||||
PRINT_MEM_ITEM_EX("DRAM Total", __dram_start, __dram_end);
|
||||
#endif
|
||||
#ifdef AIC_DRAM_CMA_EN
|
||||
PRINT_MEM_ITEM("DRAM CMA Heap", __dram_cma_heap_start, __dram_cma_heap_end);
|
||||
#endif
|
||||
|
||||
/* Ignore the baremetal mode,
|
||||
because the link script is so simple that some label are undefined */
|
||||
#ifndef KERNEL_BAREMETAL
|
||||
|
||||
#ifdef AIC_TCM_EN
|
||||
PRINT_MEM_ITEM_EX("iTCM Total", __itcm_start, __itcm_end);
|
||||
PRINT_MEM_ITEM("iTCM Heap", __itcm_heap_start, __itcm_heap_end);
|
||||
PRINT_MEM_ITEM_EX("dTCM Total", __dtcm_start, __dtcm_end);
|
||||
PRINT_MEM_ITEM("dTCM Heap", __dtcm_heap_start, __dtcm_heap_end);
|
||||
#endif
|
||||
|
||||
#ifdef AIC_SRAM_TOTAL_SIZE
|
||||
PRINT_MEM_ITEM_EX("SRAM S0 Total", __sram_s0_start, __sram_s0_end);
|
||||
PRINT_MEM_ITEM_EX("SRAM S1 SW", __sram_s1_sw_start, __sram_s1_sw_end);
|
||||
PRINT_MEM_ITEM_EX("SRAM S1 CMA", __sram_s1_cma_start, __sram_s1_cma_end);
|
||||
#endif
|
||||
|
||||
#ifdef AIC_SRAM_SIZE
|
||||
#if (CONFIG_AIC_SRAM_SW_SIZE != 0)
|
||||
PRINT_MEM_ITEM("SRAM SW Heap", __sram_sw_heap_start, __sram_sw_heap_end);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef AIC_SRAM1_SW_EN
|
||||
PRINT_MEM_ITEM("SRAM1 SW Heap",
|
||||
__sram_s1_sw_heap_start, __sram_s1_sw_heap_end);
|
||||
#endif
|
||||
#ifdef AIC_SRAM1_CMA_EN
|
||||
PRINT_MEM_ITEM("SRAM1 CMA Heap",
|
||||
__sram_s1_cma_heap_start, __sram_s1_cma_heap_end);
|
||||
#endif
|
||||
|
||||
#ifdef AIC_PSRAM_SIZE
|
||||
PRINT_MEM_ITEM_EX("PSRAM Total", __psram_start, __psram_end);
|
||||
#endif
|
||||
#ifdef AIC_PSRAM_SW_EN
|
||||
PRINT_MEM_ITEM_EX("PSRAM SW", __psram_sw_start, __psram_sw_end);
|
||||
PRINT_MEM_ITEM("PSRAM SW Heap",
|
||||
__psram_sw_heap_start, __psram_sw_heap_end);
|
||||
#endif
|
||||
#ifdef AIC_PSRAM_CMA_EN
|
||||
PRINT_MEM_ITEM_EX("PSRAM CMA", __psram_cma_start, __psram_cma_end);
|
||||
PRINT_MEM_ITEM("PSRAM CMA Heap",
|
||||
__psram_cma_heap_start, __psram_cma_heap_end);
|
||||
#endif
|
||||
|
||||
#ifdef AIC_DRAM_CMA_EN
|
||||
PRINT_MEM_ITEM("CMA Heap", __cma_heap_start, __cma_heap_end);
|
||||
#endif
|
||||
|
||||
#endif // end of ifndef KERNEL_BAREMETAL
|
||||
|
||||
PRINT_MEM_ITEM("Heap", __heap_start, __heap_end);
|
||||
PRINT_MEM_ITEM_EX("Text section", __stext, __etext);
|
||||
PRINT_MEM_ITEM_EX("RO Data section", __srodata, __erodata);
|
||||
PRINT_MEM_ITEM_EX("Data section", __sdata, __edata);
|
||||
PRINT_MEM_ITEM_EX("BSS section", __sbss, __ebss);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#ifdef RT_USING_FINSH
|
||||
MSH_CMD_EXPORT_ALIAS(cmd_meminfo, meminfo, Show the memory information);
|
||||
#endif
|
||||
#ifdef AIC_CONSOLE_BARE_DRV
|
||||
CONSOLE_CMD(meminfo, cmd_meminfo, "Show the memory information");
|
||||
#endif
|
||||
|
||||
@@ -14,6 +14,19 @@
|
||||
#include <rtconfig.h>
|
||||
#include <aic_common.h>
|
||||
|
||||
/* Common malloc align */
|
||||
typedef void *(*aicos_malloc1_t)(size_t);
|
||||
typedef void (*aicos_free1_t)(void *);
|
||||
typedef void *(*aicos_malloc2_t)(unsigned int, size_t);
|
||||
typedef void (*aicos_free2_t)(unsigned int, void *);
|
||||
|
||||
void *_aicos_malloc_align_(size_t size, size_t align, unsigned int type, void *func);
|
||||
void _aicos_free_align_(void *ptr, unsigned int type, void *func);
|
||||
|
||||
/* Irq */
|
||||
void aicos_irq_enter(void);
|
||||
void aicos_irq_exit(void);
|
||||
|
||||
/* New define */
|
||||
typedef void *aicos_thread_t;
|
||||
typedef void (*aic_thread_entry_t)(void *argument);
|
||||
@@ -22,13 +35,6 @@ typedef void *aicos_mutex_t;
|
||||
typedef void *aicos_event_t;
|
||||
typedef void *aicos_queue_t;
|
||||
|
||||
typedef struct {
|
||||
int item_size;
|
||||
int depth;
|
||||
void *buf;
|
||||
void *q;
|
||||
} osal_queue_def_t;
|
||||
|
||||
#if defined(KERNEL_RTTHREAD)
|
||||
#include "aic_osal_rtthread.h"
|
||||
#elif defined(KERNEL_FREERTOS)
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <csi_core.h>
|
||||
#include <aic_errno.h>
|
||||
#include <aic_tlsf.h>
|
||||
#include <aic_time.h>
|
||||
@@ -236,24 +238,132 @@ static inline int aicos_event_send(aicos_event_t event, uint32_t set)
|
||||
//--------------------------------------------------------------------+
|
||||
// Queue API
|
||||
//--------------------------------------------------------------------+
|
||||
static inline aicos_queue_t aicos_queue_create(uint32_t item_size, uint32_t queue_size) {return NULL;}
|
||||
static inline void aicos_queue_delete(aicos_queue_t queue) {}
|
||||
static inline int aicos_queue_send(aicos_queue_t queue, void const *buff) {return -1;}
|
||||
static inline int aicos_queue_receive(aicos_queue_t queue, void *buff, uint32_t msec) {return -1;}
|
||||
static inline int aicos_queue_empty(aicos_queue_t queue) {return 0;}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short depth; /* max items */
|
||||
unsigned short item_size; /* size of each item */
|
||||
volatile unsigned short wr_idx; /* write pointer */
|
||||
volatile unsigned short rd_idx; /* read pointer */
|
||||
unsigned char buffer[0]; /* data buffer */
|
||||
}osal_queue_def_t;
|
||||
|
||||
typedef osal_queue_def_t* osal_queue_t;
|
||||
|
||||
/* ringbuffer */
|
||||
#define RB_DATA_COUNT(w, r, max) (((w)>=(r)) ? ((w)-(r)) : ((max)-(r)+(w)))
|
||||
#define RB_IS_FULL(w, r, max) (RB_DATA_COUNT(w,r,max) >= ((max)-1))
|
||||
#define RB_INC_POINTER(p, max) p = ((p)+1)%(max)
|
||||
|
||||
static inline aicos_queue_t aicos_queue_create(uint32_t item_size, uint32_t queue_size)
|
||||
{
|
||||
osal_queue_t q;
|
||||
|
||||
q = aicos_malloc(0, sizeof(osal_queue_def_t) + item_size*queue_size);
|
||||
if (NULL == q)
|
||||
return NULL;
|
||||
|
||||
q->item_size = item_size;
|
||||
q->depth = queue_size;
|
||||
q->rd_idx = 0;
|
||||
q->wr_idx = 0;
|
||||
|
||||
return (aicos_queue_t)q;
|
||||
}
|
||||
|
||||
static inline void aicos_queue_delete(aicos_queue_t queue)
|
||||
{
|
||||
aicos_free(0, queue);
|
||||
}
|
||||
|
||||
static inline int aicos_queue_send(aicos_queue_t queue, void const *buff)
|
||||
{
|
||||
osal_queue_t q = (aicos_queue_t)queue;
|
||||
|
||||
if (!buff)
|
||||
return -EINVAL;
|
||||
|
||||
if (RB_IS_FULL(q->wr_idx, q->rd_idx, q->depth))
|
||||
return -EAGAIN;
|
||||
|
||||
memcpy(q->buffer + q->wr_idx*q->item_size, buff, q->item_size);
|
||||
|
||||
RB_INC_POINTER(q->wr_idx, q->depth);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int aicos_queue_receive(aicos_queue_t queue, void *buff, uint32_t msec)
|
||||
{
|
||||
osal_queue_t q = (aicos_queue_t)queue;
|
||||
u64 s_us = 0;
|
||||
u64 e_us = 0;
|
||||
|
||||
if (!buff)
|
||||
return -EINVAL;
|
||||
|
||||
if (RB_DATA_COUNT(q->wr_idx, q->rd_idx, q->depth)) {
|
||||
memcpy(buff, q->buffer + q->rd_idx*q->item_size, q->item_size);
|
||||
RB_INC_POINTER(q->rd_idx, q->depth);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (msec == 0) {
|
||||
return -EAGAIN;
|
||||
} else if (msec == AICOS_WAIT_FOREVER) {
|
||||
while (!RB_DATA_COUNT(q->wr_idx, q->rd_idx, q->depth)) { }
|
||||
} else {
|
||||
s_us = aic_get_time_us();
|
||||
while (!RB_DATA_COUNT(q->wr_idx, q->rd_idx, q->depth)) {
|
||||
e_us = aic_get_time_us();
|
||||
if (((e_us-s_us) / 1000) >= msec)
|
||||
return -ETIME;
|
||||
}
|
||||
}
|
||||
|
||||
if (RB_DATA_COUNT(q->wr_idx, q->rd_idx, q->depth)) {
|
||||
memcpy(buff, q->buffer + q->rd_idx*q->item_size, q->item_size);
|
||||
RB_INC_POINTER(q->rd_idx, q->depth);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline int aicos_queue_empty(aicos_queue_t queue)
|
||||
{
|
||||
osal_queue_t q = (aicos_queue_t)queue;
|
||||
|
||||
return !RB_DATA_COUNT(q->wr_idx, q->rd_idx, q->depth);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Critical API
|
||||
//--------------------------------------------------------------------+
|
||||
static inline size_t aicos_enter_critical_section(void) {return -1;}
|
||||
static inline void aicos_leave_critical_section(size_t flag) {}
|
||||
static inline size_t aicos_enter_critical_section(void)
|
||||
{
|
||||
return (size_t)csi_irq_save();;
|
||||
}
|
||||
static inline void aicos_leave_critical_section(size_t flag)
|
||||
{
|
||||
csi_irq_restore(flag);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Sleep API
|
||||
//--------------------------------------------------------------------+
|
||||
static inline void aicos_msleep(uint32_t delay) {}
|
||||
|
||||
static inline void aicos_msleep(uint32_t delay)
|
||||
{
|
||||
u64 s_us = 0;
|
||||
u64 e_us = 0;
|
||||
|
||||
s_us = aic_get_time_us();
|
||||
while (1) {
|
||||
e_us = aic_get_time_us();
|
||||
if (((e_us-s_us) / 1000) >= delay)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -16,6 +16,17 @@
|
||||
#include <timers.h>
|
||||
#include <event_groups.h>
|
||||
#include <aic_errno.h>
|
||||
#include <aic_tlsf.h>
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Interrupt Define
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
extern unsigned int g_aicos_irq_nested_cnt;
|
||||
static inline int aicos_in_irq(void)
|
||||
{
|
||||
return g_aicos_irq_nested_cnt;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Timeout Define
|
||||
@@ -284,17 +295,33 @@ static inline void aicos_msleep(uint32_t delay)
|
||||
static inline void *aicos_malloc(unsigned int mem_type, size_t size)
|
||||
{
|
||||
if (mem_type == MEM_DEFAULT)
|
||||
return rt_malloc(size);
|
||||
return pvPortMalloc(size);
|
||||
else
|
||||
return aic_memheap_malloc(mem_type, size);
|
||||
return aic_tlsf_malloc(mem_type, size);
|
||||
}
|
||||
|
||||
static inline void aicos_free(unsigned int mem_type, void *mem)
|
||||
{
|
||||
if (mem_type == MEM_DEFAULT)
|
||||
rt_free(mem);
|
||||
vPortFree(mem);
|
||||
else
|
||||
aic_memheap_free(mem_type, mem);
|
||||
aic_tlsf_free(mem_type, mem);
|
||||
}
|
||||
|
||||
static inline void *aicos_malloc_align(uint32_t mem_type, size_t size, size_t align)
|
||||
{
|
||||
if (mem_type == MEM_DEFAULT)
|
||||
return _aicos_malloc_align_(size, align, 0xFFFF, (void *)pvPortMalloc);
|
||||
else
|
||||
return aic_tlsf_malloc_align(mem_type, size, align);
|
||||
}
|
||||
|
||||
static inline void aicos_free_align(uint32_t mem_type, void *mem)
|
||||
{
|
||||
if (mem_type == MEM_DEFAULT)
|
||||
_aicos_free_align_(mem, 0xFFFF, (void *)vPortFree);
|
||||
else
|
||||
aic_tlsf_free_align(mem_type, mem);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -51,7 +51,6 @@ typedef enum irqreturn irqreturn_t;
|
||||
typedef irqreturn_t (*irq_handler_t)(int, void *);
|
||||
typedef irqreturn_t (*pin_irq_handler_t)(void *);
|
||||
|
||||
|
||||
static inline int aicos_request_irq(unsigned int irq, irq_handler_t handler, unsigned int flags,
|
||||
const char *name, void *data)
|
||||
{
|
||||
@@ -71,12 +70,6 @@ static inline void aicos_irq_disable(unsigned int irq)
|
||||
drv_irq_disable(irq);
|
||||
}
|
||||
|
||||
extern unsigned int g_aicos_irq_nested_cnt;
|
||||
static inline int aicos_in_irq(void)
|
||||
{
|
||||
return g_aicos_irq_nested_cnt;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Cache API
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
@@ -160,6 +160,13 @@ static inline int aicos_event_send(aicos_event_t event, uint32_t set)
|
||||
// Queue API
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
typedef struct {
|
||||
int item_size;
|
||||
int depth;
|
||||
void *buf;
|
||||
void *q;
|
||||
} osal_queue_def_t;
|
||||
|
||||
static inline aicos_queue_t aicos_queue_create(uint32_t item_size, uint32_t queue_size)
|
||||
{
|
||||
osal_queue_def_t *p_queue_def;
|
||||
|
||||
@@ -246,20 +246,18 @@ static inline void aicos_free(unsigned int mem_type, void *mem)
|
||||
|
||||
static inline void *aicos_malloc_align(uint32_t mem_type, size_t size, size_t align)
|
||||
{
|
||||
/* Only support MEM_DEFAULT type by now */
|
||||
if (mem_type != MEM_DEFAULT)
|
||||
return NULL;
|
||||
|
||||
return rt_malloc_align(size, align);
|
||||
if (mem_type == MEM_DEFAULT)
|
||||
return rt_malloc_align(size, align);
|
||||
else
|
||||
return _aicos_malloc_align_(size, align, mem_type, (void *)aic_memheap_malloc);
|
||||
}
|
||||
|
||||
static inline void aicos_free_align(uint32_t mem_type, void *mem)
|
||||
{
|
||||
/* Only support MEM_DEFAULT type by now */
|
||||
if (mem_type != MEM_DEFAULT)
|
||||
return;
|
||||
|
||||
rt_free_align(mem);
|
||||
if (mem_type == MEM_DEFAULT)
|
||||
rt_free_align(mem);
|
||||
else
|
||||
_aicos_free_align_(mem, mem_type, (void *)aic_memheap_free);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <aic_core.h>
|
||||
|
||||
|
||||
unsigned long g_aicos_irq_state = 0;
|
||||
unsigned int g_aicos_irq_nested_cnt = 0;
|
||||
|
||||
@@ -16,3 +20,64 @@ void aicos_irq_exit(void)
|
||||
{
|
||||
g_aicos_irq_nested_cnt--;
|
||||
}
|
||||
|
||||
void *_aicos_malloc_align_(size_t size, size_t align, unsigned int type, void *func)
|
||||
{
|
||||
void *ptr;
|
||||
void *align_ptr;
|
||||
int uintptr_size;
|
||||
size_t align_size;
|
||||
|
||||
/* sizeof pointer */
|
||||
uintptr_size = sizeof(void*);
|
||||
uintptr_size -= 1;
|
||||
|
||||
/* align the alignment size to uintptr size byte */
|
||||
align = ((align + uintptr_size) & ~uintptr_size);
|
||||
|
||||
/* get total aligned size */
|
||||
align_size = ((size + uintptr_size) & ~uintptr_size) + align;
|
||||
/* allocate memory block from heap */
|
||||
if (type >= MAX_MEM_REGION) {
|
||||
aicos_malloc1_t func1 = (aicos_malloc1_t)func;
|
||||
ptr = (*func1)(align_size);
|
||||
} else {
|
||||
aicos_malloc2_t func2 = (aicos_malloc2_t)func;
|
||||
ptr = (*func2)(type, align_size);
|
||||
}
|
||||
if (ptr != NULL)
|
||||
{
|
||||
/* the allocated memory block is aligned */
|
||||
if (((unsigned long)ptr & (align - 1)) == 0)
|
||||
{
|
||||
align_ptr = (void *)((unsigned long)ptr + align);
|
||||
}
|
||||
else
|
||||
{
|
||||
align_ptr = (void *)(((unsigned long)ptr + (align - 1)) & ~(align - 1));
|
||||
}
|
||||
|
||||
/* set the pointer before alignment pointer to the real pointer */
|
||||
*((unsigned long *)((unsigned long)align_ptr - sizeof(void *))) = (unsigned long)ptr;
|
||||
|
||||
ptr = align_ptr;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void _aicos_free_align_(void *ptr, unsigned int type, void *func)
|
||||
{
|
||||
void *real_ptr;
|
||||
|
||||
/* NULL check */
|
||||
if (ptr == NULL) return;
|
||||
real_ptr = (void *) * (unsigned long *)((unsigned long)ptr - sizeof(void *));
|
||||
if (type >= MAX_MEM_REGION) {
|
||||
aicos_free1_t func1 = (aicos_free1_t)func;
|
||||
(*func1)(real_ptr);
|
||||
} else {
|
||||
aicos_free2_t func2 = (aicos_free2_t)func;
|
||||
(*func2)(type, real_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,5 +12,40 @@ config DRIVER_BARE_DRV_EN
|
||||
bool
|
||||
default y
|
||||
|
||||
if ! AIC_BOOTLOADER
|
||||
config AIC_BAREMETAL_CONSOLE_UART
|
||||
int "Baremetal console UART ID"
|
||||
range 0 8
|
||||
default 0
|
||||
endif
|
||||
|
||||
config ARCH_RISCV
|
||||
bool
|
||||
|
||||
config ARCH_RISCV_FPU
|
||||
bool
|
||||
|
||||
config ARCH_RISCV_FPU_S
|
||||
select ARCH_RISCV_FPU
|
||||
bool
|
||||
|
||||
config ARCH_RISCV_FPU_D
|
||||
select ARCH_RISCV_FPU
|
||||
bool
|
||||
|
||||
config ARCH_RISCV32
|
||||
select ARCH_RISCV
|
||||
bool
|
||||
|
||||
config ARCH_RISCV64
|
||||
select ARCH_RISCV
|
||||
select ARCH_CPU_64BIT
|
||||
bool
|
||||
|
||||
config ARCH_CSKY
|
||||
bool
|
||||
|
||||
source "kernel/freertos/Kconfig.kernel"
|
||||
|
||||
endmenu
|
||||
|
||||
|
||||
298
kernel/freertos/Kconfig.kernel
Normal file
298
kernel/freertos/Kconfig.kernel
Normal file
@@ -0,0 +1,298 @@
|
||||
menu "FreeRTOS Kernel"
|
||||
|
||||
menu "Tasks"
|
||||
|
||||
config FREERTOS_PREEMPTIVE_EN
|
||||
bool "Enable Preemptive"
|
||||
default y
|
||||
|
||||
config FREERTOS_TICK_RATE_HZ
|
||||
int "Frequency of the RTOS tick interrupt (Hz)"
|
||||
default 500
|
||||
---help---
|
||||
The tick interrupt is used to measure time. Therefore a higher tick frequency means time can
|
||||
be measured to a higher resolution. However, a high tick frequency also means that the RTOS
|
||||
kernel will use more CPU time so be less efficient. The RTOS demo applications all use a tick
|
||||
rate of 1000Hz. This is used to test the RTOS kernel and is higher than would normally be
|
||||
required.
|
||||
More than one task can share the same priority. The RTOS scheduler will share processor time
|
||||
between tasks of the same priority by switching between the tasks during each RTOS tick. A high
|
||||
tick rate frequency will therefore also have the effect of reducing the 'time slice' given to
|
||||
each task.
|
||||
|
||||
config FREERTOS_MAX_PRIORITIES
|
||||
int "Number of available priorities"
|
||||
default 200
|
||||
---help---
|
||||
Any number of tasks can share the same priority. Co-routines are prioritised separately -
|
||||
see configMAX_CO_ROUTINE_PRIORITIES.
|
||||
Each available priority consumes RAM within the RTOS kernel so this value should not
|
||||
be set any higher than actually required by your application.
|
||||
|
||||
config FREERTOS_MINIMAL_STACK_SIZE
|
||||
int "IDLE task stack size (words)"
|
||||
default 1024
|
||||
---help---
|
||||
The size of the stack used by the idle task. Generally this should not be reduced from
|
||||
the value set in the FreeRTOSConfig.h file provided with the demo application for the port
|
||||
you are using.
|
||||
Like the stack size parameter to the xTaskCreate() function, the stack size is specified
|
||||
in words, not bytes. If each item placed on the stack is 32-bits, then a stack size of 100
|
||||
means 400 bytes (each 32-bit stack item consuming 4 bytes).
|
||||
|
||||
config FREERTOS_MAX_TASK_NAME_LEN
|
||||
int "Maximum task name length"
|
||||
default 12
|
||||
---help---
|
||||
The maximum permissible length of the descriptive name given to a task when the task is
|
||||
created. The length is specified in the number of characters including the NULL termination
|
||||
byte.
|
||||
|
||||
config FREERTOS_IDLE_SHOULD_YIELD
|
||||
bool "Idle task should yield"
|
||||
depends on FREERTOS_PREEMPTIVE_EN
|
||||
default y
|
||||
---help---
|
||||
Tasks that share the same priority will time slice. Assuming none of the tasks get preempted,
|
||||
it might be assumed that each task of at a given priority will be allocated an equal amount
|
||||
of processing time - and if the shared priority is above the idle priority then this is indeed
|
||||
the case.
|
||||
When tasks share the idle priority the behaviour can be slightly different. When
|
||||
configIDLE_SHOULD_YIELD is set to 1 the idle task will yield immediately should any other task
|
||||
at the idle priority be ready to run.
|
||||
|
||||
menuconfig FREERTOS_USE_TASK_NOTIFICATIONS
|
||||
bool "Use task notifications"
|
||||
default y
|
||||
---help---
|
||||
Setting configUSE_TASK_NOTIFICATIONS to 1 (or leaving configUSE_TASK_NOTIFICATIONS undefined)
|
||||
will include direct to task notification functionality and its associated API in the build.
|
||||
Setting configUSE_TASK_NOTIFICATIONS to 0 will exclude direct to task notification functionality
|
||||
and its associated API from the build.
|
||||
Each task consumes 8 additional bytes of RAM when direct to task notifications are included in
|
||||
the build.
|
||||
|
||||
if FREERTOS_USE_TASK_NOTIFICATIONS
|
||||
config FREERTOS_USE_TASK_NOTIFICATION_ARRAY_ENTRIES
|
||||
int "Task notifications arry entries"
|
||||
default 3
|
||||
endif
|
||||
|
||||
config FREERTOS_USE_TIME_SLICING
|
||||
bool "Use time slicing"
|
||||
default y
|
||||
depends on FREERTOS_USE_QUEUE_SETS
|
||||
---help---
|
||||
By default (if configUSE_TIME_SLICING is not defined, or if configUSE_TIME_SLICING is defined as
|
||||
1) FreeRTOS uses prioritised preemptive scheduling with time slicing. That means the RTOS scheduler
|
||||
will always run the highest priority task that is in the Ready state, and will switch between tasks
|
||||
of equal priority on every RTOS tick interrupt. If configUSE_TIME_SLICING is set to 0 then the RTOS
|
||||
scheduler will still run the highest priority task that is in the Ready state, but will not switch
|
||||
between tasks of equal priority just because a tick interrupt has occurred.
|
||||
|
||||
config FREERTOS_NUM_THREAD_LOCAL_STORAGE_POINTERS
|
||||
int "Number of pointers in TLS"
|
||||
default 4
|
||||
---help---
|
||||
Sets the number of indexes in each task's thread local storage array.
|
||||
|
||||
config FREERTOS_MAIN_THREAD_STACK_SIZE
|
||||
int "Set main thread stack size"
|
||||
default 8096
|
||||
|
||||
config FREERTOS_MAIN_THREAD_PRIORITY
|
||||
int "Set main thread priority"
|
||||
default 32
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Hooks"
|
||||
|
||||
config FREERTOS_USE_IDLE_HOOK
|
||||
bool "Use idle hook"
|
||||
default n
|
||||
---help---
|
||||
Set to use idle hook or clear to omit it
|
||||
|
||||
config FREERTOS_USE_TICK_HOOK
|
||||
bool "Use tick hook"
|
||||
default n
|
||||
---help---
|
||||
Set if you wish to use a tick hook, or clear to omit an tick hook
|
||||
|
||||
config FREERTOS_USE_CHECK_STACK_OVERFLOW_HOOK
|
||||
bool "Use check stack overflow hook"
|
||||
default y
|
||||
---help---
|
||||
Check stack overflow
|
||||
|
||||
config FREERTOS_USE_MALLOC_FAILED_HOOK
|
||||
bool "Use malloc-failed hook"
|
||||
default y
|
||||
---help---
|
||||
The kernel uses a call to pvPortMalloc() to allocate memory from the heap each time a
|
||||
task, queue or semaphore is created. The official FreeRTOS download includes four sample
|
||||
memory allocation schemes for this purpose. The schemes are implemented in the heap_1.c,
|
||||
heap_2.c, heap_3.c, heap_4.c and heap_5.c source files respectively. configUSE_MALLOC_FAILED_HOOK
|
||||
is only relevant when one of these three sample schemes is being used. The malloc() failed
|
||||
hook function is a hook (or callback) function that, if defined and configured, will be
|
||||
called if pvPortMalloc() ever returns NULL. NULL will be returned only if there is
|
||||
insufficient FreeRTOS heap memory remaining for the requested allocation to succeed.
|
||||
If configUSE_MALLOC_FAILED_HOOK is set to 1 then the application must define a malloc()
|
||||
failed hook function. If configUSE_MALLOC_FAILED_HOOK is set to 0 then the malloc() failed
|
||||
hook function will not be called, even if one is defined. Malloc() failed hook functions
|
||||
must have the name and prototype shown below.
|
||||
void vApplicationMallocFailedHook( void );
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Primitives"
|
||||
|
||||
config FREERTOS_USE_MUTEXES
|
||||
bool "Mutexes"
|
||||
default y
|
||||
---help---
|
||||
Set to 1 to include mutex functionality in the build, or 0 to omit mutex functionality from the
|
||||
build. Readers should familiarise themselves with the differences between mutexes and binary semaphores
|
||||
in relation to the FreeRTOS functionality.
|
||||
|
||||
config FREERTOS_USE_RECURSIVE_MUTEXES
|
||||
bool "Recursive mutexes"
|
||||
default n
|
||||
depends on FREERTOS_USE_MUTEXES
|
||||
---help---
|
||||
Set to 1 to include recursive mutex functionality in the build, or 0 to omit recursive mutex
|
||||
functionality from the build.
|
||||
|
||||
config FREERTOS_USE_COUNTING_SEMAPHORES
|
||||
bool "Counting semaphores"
|
||||
default y
|
||||
---help---
|
||||
Set to 1 to include counting semaphore functionality in the build, or 0 to omit counting semaphore
|
||||
functionality from the build.
|
||||
|
||||
config FREERTOS_USE_ALTERNATIVE_API
|
||||
bool "Alternative queue API"
|
||||
default n
|
||||
---help---
|
||||
Set to 1 to include the 'alternative' queue functions in the build, or 0 to omit the 'alternative'
|
||||
queue functions from the build. The alternative API is described within the queue.h header file. The
|
||||
alternative API is deprecated and should not be used in new designs.
|
||||
|
||||
config FREERTOS_USE_QUEUE_SETS
|
||||
bool "Queue sets"
|
||||
default n
|
||||
---help---
|
||||
Set to 1 to include queue set functionality (the ability to block, or pend, on multiple queues and
|
||||
semaphores), or 0 to omit queue set functionality.
|
||||
|
||||
menuconfig FREERTOS_USE_CO_ROUTINES
|
||||
bool "Co-routines"
|
||||
default n
|
||||
---help---
|
||||
Set to 1 to include co-routine functionality in the build, or 0 to omit co-routine functionality
|
||||
from the build. To include co-routines croutine.c must be included in the project.
|
||||
|
||||
if FREERTOS_USE_CO_ROUTINES
|
||||
|
||||
config FREERTOS_MAX_CO_ROUTINE_PRIORITIES
|
||||
int "Number of co-routine priorities"
|
||||
default 2
|
||||
---help---
|
||||
The number of priorities available to the application co-routines. Any number of co-routines can
|
||||
share the same priority.
|
||||
|
||||
endif
|
||||
|
||||
menuconfig FREERTOS_USE_TIMERS
|
||||
bool "Timers"
|
||||
default y
|
||||
---help---
|
||||
Set to 1 to include software timer functionality, or 0 to omit software timer functionality
|
||||
|
||||
if FREERTOS_USE_TIMERS
|
||||
|
||||
config FREERTOS_TIMER_TASK_PRIORITY
|
||||
int "Timer service task priority"
|
||||
default 1
|
||||
---help---
|
||||
Sets the priority of the software timer service/daemon task
|
||||
|
||||
config FREERTOS_TIMER_QUEUE_LENGTH
|
||||
int "Timer queue length"
|
||||
default 36
|
||||
---help---
|
||||
Sets the length of the software timer command queue
|
||||
|
||||
config FREERTOS_TIMER_TASK_STACK_DEPTH
|
||||
int "Timer task stack depth"
|
||||
default FREERTOS_MINIMAL_STACK_SIZE
|
||||
---help---
|
||||
Sets the stack depth allocated to the software timer service/daemon task
|
||||
|
||||
endif
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Libraries"
|
||||
|
||||
config FREERTOS_USE_NEWLIB_REENTRANT
|
||||
bool "Re-entrant newlib support"
|
||||
default n
|
||||
---help---
|
||||
If configUSE_NEWLIB_REENTRANT is set to 1 then a newlib reent structure will be allocated for each
|
||||
created task.
|
||||
|
||||
config FREERTOS_ENABLE_BACKWARD_COMPATIBILITY
|
||||
bool "Enable backward compatibility"
|
||||
default y
|
||||
---help---
|
||||
The FreeRTOS.h header file includes a set of #define macros that map the names of data types used
|
||||
in versions of FreeRTOS prior to version 8.0.0 to the names used in FreeRTOS version 8.0.0. The macros
|
||||
allow application code to update the version of FreeRTOS they are built against from a pre 8.0.0
|
||||
version to a post 8.0.0 version without modification. Setting configENABLE_BACKWARD_COMPATIBILITY to
|
||||
0 in FreeRTOSConfig.h excludes the macors from the build, and in so doing allowing validation that
|
||||
no pre version 8.0.0 names are being used
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Debug"
|
||||
|
||||
config FREERTOS_USE_TRACE_FACILITY
|
||||
bool "Enable trace facility"
|
||||
default n
|
||||
---help---
|
||||
Set to 1 if you wish to include additional structure members and functions to assist with execution
|
||||
visualisation and tracing.
|
||||
|
||||
config FREERTOS_USE_STATS_FORMATTING_FUNCTIONS
|
||||
bool "Include vTaskList() and vTaskGetRunTimeStats()"
|
||||
default n
|
||||
depends on FREERTOS_USE_TRACE_FACILITY
|
||||
---help---
|
||||
Includes vTaskList() and vTaskGetRunTimeStats() to the build.
|
||||
|
||||
config FREERTOS_QUEUE_REGISTRY_SIZE
|
||||
int "Queue registry size"
|
||||
default 10
|
||||
---help---
|
||||
The queue registry has two purposes, both of which are associated with RTOS kernel aware debugging:
|
||||
1. It allows a textual name to be associated with a queue for easy queue identification within a
|
||||
debugging GUI.
|
||||
2. It contains the information required by a debugger to locate each registered queue and semaphore.
|
||||
The queue registry has no purpose unless you are using a RTOS kernel aware debugger.
|
||||
configQUEUE_REGISTRY_SIZE defines the maximum number of queues and semaphores that can be registered.
|
||||
Only those queues and semaphores that you want to view using a RTOS kernel aware debugger need be
|
||||
registered. See the API reference documentation for vQueueAddToRegistry() and vQueueUnregisterQueue()
|
||||
for more information.
|
||||
|
||||
config FREERTOS_GENERATE_RUN_TIME_STATS
|
||||
bool "Generate run time stats"
|
||||
default n
|
||||
---help---
|
||||
The Run Time Stats page describes the use of this parameter.
|
||||
|
||||
endmenu
|
||||
|
||||
endmenu
|
||||
|
||||
18
kernel/freertos/SConscript
Normal file
18
kernel/freertos/SConscript
Normal file
@@ -0,0 +1,18 @@
|
||||
Import('PRJ_KERNEL')
|
||||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
path = [cwd + '/include']
|
||||
path += [cwd + '/portable/GCC/RISC-V']
|
||||
path += [cwd + '/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions']
|
||||
|
||||
src = Glob('*.c')
|
||||
src += Glob('portable/MemMang/heap_5.c')
|
||||
src += Glob('portable/GCC/RISC-V/*.c')
|
||||
src += Glob('portable/GCC/RISC-V/*.S')
|
||||
|
||||
CPPDEFINES = []
|
||||
|
||||
group = DefineGroup('freertos', src, depend = ['KERNEL_FREERTOS'], CPPPATH = path, CPPDEFINES = CPPDEFINES)
|
||||
|
||||
Return('group')
|
||||
76
kernel/freertos/entry.c
Normal file
76
kernel/freertos/entry.c
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Artinchip Technology Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
#include <aic_core.h>
|
||||
#include <board.h>
|
||||
#include <aic_tlsf.h>
|
||||
|
||||
#ifndef FREERTOS_MAIN_THREAD_STACK_SIZE
|
||||
#define MAIN_TASK_STACK_SIZE 8192
|
||||
#else
|
||||
#define MAIN_TASK_STACK_SIZE FREERTOS_MAIN_THREAD_STACK_SIZE
|
||||
#endif
|
||||
|
||||
#ifndef FREERTOS_MAIN_THREAD_PRIORITY
|
||||
#define MAIN_TASK_PRI 32
|
||||
#else
|
||||
#define MAIN_TASK_PRI FREERTOS_MAIN_THREAD_PRIORITY
|
||||
#endif
|
||||
|
||||
extern void aic_board_sysclk_init(void);
|
||||
extern void aic_board_pinmux_init(void);
|
||||
extern int main(void);
|
||||
|
||||
HeapRegion_t xHeapRegions[] =
|
||||
{
|
||||
{ NULL, 0},
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
int freertos_heap_init (void)
|
||||
{
|
||||
xHeapRegions[0].pucStartAddress = ( uint8_t * )(&__heap_start);
|
||||
xHeapRegions[0].xSizeInBytes = (size_t)(&__heap_end) - (size_t)(&__heap_start);
|
||||
vPortDefineHeapRegions( xHeapRegions );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aic_hw_board_init(void)
|
||||
{
|
||||
freertos_heap_init();
|
||||
#ifdef TLSF_MEM_HEAP
|
||||
aic_tlsf_heap_init();
|
||||
#endif
|
||||
aic_board_sysclk_init();
|
||||
aic_board_pinmux_init();
|
||||
}
|
||||
|
||||
int entry(void)
|
||||
{
|
||||
TaskHandle_t xHandle;
|
||||
BaseType_t ret;
|
||||
|
||||
/* hw&heap init */
|
||||
aic_hw_board_init();
|
||||
|
||||
/* kernel init */
|
||||
|
||||
/* init task */
|
||||
ret = xTaskCreate((TaskFunction_t)main, "main", MAIN_TASK_STACK_SIZE/sizeof(StackType_t), NULL, configMAX_PRIORITIES-1-MAIN_TASK_PRI, &xHandle);
|
||||
if (ret != pdPASS) {
|
||||
printf("FreeRTOS create init main task fail.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* kernel start */
|
||||
vTaskStartScheduler();
|
||||
return 0;
|
||||
}
|
||||
281
kernel/freertos/include/FreeRTOSConfig.h
Normal file
281
kernel/freertos/include/FreeRTOSConfig.h
Normal file
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd.
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* If you are: *
|
||||
* *
|
||||
* + New to FreeRTOS, *
|
||||
* + Wanting to learn FreeRTOS or multitasking in general quickly *
|
||||
* + Looking for basic training, *
|
||||
* + Wanting to improve your FreeRTOS skills and productivity *
|
||||
* *
|
||||
* then take a look at the FreeRTOS eBook *
|
||||
* *
|
||||
* "Using the FreeRTOS Real Time Kernel - a Practical Guide" *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
* A pdf reference manual is also available. Both are usually delivered *
|
||||
* to your inbox within 20 minutes to two hours when purchased between 8am *
|
||||
* and 8pm GMT (although please allow up to 24 hours in case of *
|
||||
* exceptional circumstances). Thank you for your support! *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
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 exception 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. See the GNU General Public License for
|
||||
more details. You should have received a copy of the GNU General Public
|
||||
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||
by writing to Richard Barry, contact details for whom are available on the
|
||||
FreeRTOS WEB site.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
|
||||
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||
contact details.
|
||||
|
||||
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||
critical systems.
|
||||
|
||||
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||
licensing and training services.
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_CONFIG_H
|
||||
#define FREERTOS_CONFIG_H
|
||||
#include <stdio.h>
|
||||
#include <rtconfig.h>
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Application specific definitions.
|
||||
*
|
||||
* These definitions should be adjusted for your particular hardware and
|
||||
* application requirements.
|
||||
*
|
||||
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||
*
|
||||
* See http://www.freertos.org/a00110.html.
|
||||
*----------------------------------------------------------*/
|
||||
#define configMTIME_BASE_ADDRESS ( ( 0xE0000000UL ) + 0xBFF8UL )
|
||||
#define configMTIMECMP_BASE_ADDRESS ( ( 0xE0000000UL ) + 0x4000UL )
|
||||
|
||||
#define portasmHANDLE_INTERRUPT Default_IRQHandler
|
||||
|
||||
#ifdef FREERTOS_PREEMPTIVE_EN
|
||||
#define configUSE_PREEMPTION 1
|
||||
#else
|
||||
#define configUSE_PREEMPTION 0
|
||||
#endif
|
||||
#ifdef AIC_CLK_CPU_FREQ
|
||||
#define configCPU_CLOCK_HZ ( ( unsigned long ) AIC_CLK_CPU_FREQ )
|
||||
#else
|
||||
#define configCPU_CLOCK_HZ ( ( unsigned long ) 200000000 )
|
||||
#endif
|
||||
#ifdef FREERTOS_TICK_RATE_HZ
|
||||
#define configTICK_RATE_HZ FREERTOS_TICK_RATE_HZ
|
||||
#else
|
||||
#define configTICK_RATE_HZ 200
|
||||
#endif
|
||||
#ifdef FREERTOS_MAX_PRIORITIES
|
||||
#define configMAX_PRIORITIES FREERTOS_MAX_PRIORITIES
|
||||
#else
|
||||
#define configMAX_PRIORITIES 200
|
||||
#endif
|
||||
#ifdef FREERTOS_MINIMAL_STACK_SIZE
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) FREERTOS_MINIMAL_STACK_SIZE )
|
||||
#else
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) (256*4) )
|
||||
#endif
|
||||
#ifdef FREERTOS_MAX_TASK_NAME_LEN
|
||||
#define configMAX_TASK_NAME_LEN ( FREERTOS_MAX_TASK_NAME_LEN )
|
||||
#else
|
||||
#define configMAX_TASK_NAME_LEN ( 12 )
|
||||
#endif
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#ifdef FREERTOS_IDLE_SHOULD_YIELD
|
||||
#define configIDLE_SHOULD_YIELD 1
|
||||
#else
|
||||
#define configIDLE_SHOULD_YIELD 0
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_TASK_NOTIFICATIONS
|
||||
#define configUSE_TASK_NOTIFICATIONS 1
|
||||
#else
|
||||
#define configUSE_TASK_NOTIFICATIONS 0
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_TASK_NOTIFICATION_ARRAY_ENTRIES
|
||||
#define configTASK_NOTIFICATION_ARRAY_ENTRIES FREERTOS_USE_TASK_NOTIFICATION_ARRAY_ENTRIES
|
||||
#else
|
||||
#define configTASK_NOTIFICATION_ARRAY_ENTRIES 3
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_MUTEXES
|
||||
#define configUSE_MUTEXES 1
|
||||
#ifdef FREERTOS_USE_RECURSIVE_MUTEXES
|
||||
#define configUSE_RECURSIVE_MUTEXES 1
|
||||
#else
|
||||
#define configUSE_RECURSIVE_MUTEXES 0
|
||||
#endif
|
||||
#else
|
||||
#define configUSE_MUTEXES 0
|
||||
#define configUSE_RECURSIVE_MUTEXES 0
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_COUNTING_SEMAPHORES
|
||||
#define configUSE_COUNTING_SEMAPHORES 1
|
||||
#else
|
||||
#define configUSE_COUNTING_SEMAPHORES 0
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_ALTERNATIVE_API
|
||||
#define configUSE_ALTERNATIVE_API 1 /* Deprecated! */
|
||||
#else
|
||||
#define configUSE_ALTERNATIVE_API 0 /* Deprecated! */
|
||||
#endif
|
||||
#ifdef FREERTOS_QUEUE_REGISTRY_SIZE
|
||||
#define configQUEUE_REGISTRY_SIZE FREERTOS_QUEUE_REGISTRY_SIZE
|
||||
#else
|
||||
#define configQUEUE_REGISTRY_SIZE 10
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_QUEUE_SETS
|
||||
#define configUSE_QUEUE_SETS 1
|
||||
#else
|
||||
#define configUSE_QUEUE_SETS 0
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_TIME_SLICING
|
||||
#define configUSE_TIME_SLICING 1
|
||||
#else
|
||||
#define configUSE_TIME_SLICING 0
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_NEWLIB_REENTRANT
|
||||
#define configUSE_NEWLIB_REENTRANT 1
|
||||
#else
|
||||
#define configUSE_NEWLIB_REENTRANT 0
|
||||
#endif
|
||||
#ifdef FREERTOS_ENABLE_BACKWARD_COMPATIBILITY
|
||||
#define configENABLE_BACKWARD_COMPATIBILITY 1
|
||||
#else
|
||||
#define configENABLE_BACKWARD_COMPATIBILITY 0
|
||||
#endif
|
||||
#ifdef FREERTOS_NUM_THREAD_LOCAL_STORAGE_POINTERS
|
||||
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS FREERTOS_NUM_THREAD_LOCAL_STORAGE_POINTERS
|
||||
#else
|
||||
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 4
|
||||
#endif
|
||||
//#define configSTACK_DEPTH_TYPE uint16_t
|
||||
//#define configMESSAGE_BUFFER_LENGTH_TYPE size_t
|
||||
|
||||
/* Memory allocation related definitions. */
|
||||
#define configSUPPORT_STATIC_ALLOCATION 0
|
||||
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) (24576 * 4))
|
||||
#define configAPPLICATION_ALLOCATED_HEAP 0
|
||||
|
||||
/* Hook function related definitions. */
|
||||
#ifdef FREERTOS_USE_IDLE_HOOK
|
||||
#define configUSE_IDLE_HOOK 1
|
||||
#else
|
||||
#define configUSE_IDLE_HOOK 0
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_TICK_HOOK
|
||||
#define configUSE_TICK_HOOK 1
|
||||
#else
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_CHECK_STACK_OVERFLOW_HOOK
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 1
|
||||
#else
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 0
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_MALLOC_FAILED_HOOK
|
||||
#define configUSE_MALLOC_FAILED_HOOK 1
|
||||
#else
|
||||
#define configUSE_MALLOC_FAILED_HOOK 0
|
||||
#endif
|
||||
#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
|
||||
|
||||
/* Run time and task stats gathering related definitions. */
|
||||
#ifdef FREERTOS_GENERATE_RUN_TIME_STATS
|
||||
#define configGENERATE_RUN_TIME_STATS 1
|
||||
#else
|
||||
#define configGENERATE_RUN_TIME_STATS 0
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_TRACE_FACILITY
|
||||
#define configUSE_TRACE_FACILITY 1
|
||||
#else
|
||||
#define configUSE_TRACE_FACILITY 0
|
||||
#endif
|
||||
#ifdef FREERTOS_USE_STATS_FORMATTING_FUNCTIONS
|
||||
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
|
||||
#else
|
||||
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
|
||||
#endif
|
||||
|
||||
/* Co-routine related definitions. */
|
||||
#ifdef FREERTOS_USE_CO_ROUTINES
|
||||
#define configUSE_CO_ROUTINES 1
|
||||
#else
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#endif
|
||||
#ifdef FREERTOS_MAX_CO_ROUTINE_PRIORITIES
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES FREERTOS_MAX_CO_ROUTINE_PRIORITIES
|
||||
#else
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES 2
|
||||
#endif
|
||||
|
||||
|
||||
/* Software timer related definitions. */
|
||||
#ifdef FREERTOS_USE_TIMERS
|
||||
#define configUSE_TIMERS 1
|
||||
#else
|
||||
#define configUSE_TIMERS 0
|
||||
#endif
|
||||
#ifdef FREERTOS_TIMER_TASK_PRIORITY
|
||||
#define configTIMER_TASK_PRIORITY FREERTOS_TIMER_TASK_PRIORITY
|
||||
#else
|
||||
#define configTIMER_TASK_PRIORITY 1
|
||||
#endif
|
||||
#ifdef FREERTOS_TIMER_QUEUE_LENGTH
|
||||
#define configTIMER_QUEUE_LENGTH FREERTOS_TIMER_QUEUE_LENGTH
|
||||
#else
|
||||
#define configTIMER_QUEUE_LENGTH 36
|
||||
#endif
|
||||
#ifdef FREERTOS_TIMER_TASK_STACK_DEPTH
|
||||
#define configTIMER_TASK_STACK_DEPTH FREERTOS_TIMER_TASK_STACK_DEPTH
|
||||
#else
|
||||
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
|
||||
#endif
|
||||
|
||||
/* Interrupt nesting behaviour configuration. */
|
||||
#define configKERNEL_INTERRUPT_PRIORITY ( ( unsigned char ) 7 << ( unsigned char ) 5 ) /* Priority 7, or 255 as only the top three bits are implemented. This is the lowest priority. */
|
||||
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( ( unsigned char ) 5 << ( unsigned char ) 5 ) /* Priority 5, or 160 as only the top three bits are implemented. */
|
||||
|
||||
/* Set the following definitions to 1 to include the API function, or zero
|
||||
to exclude the API function. */
|
||||
|
||||
#define INCLUDE_vTaskPrioritySet 1
|
||||
#define INCLUDE_uxTaskPriorityGet 1
|
||||
#define INCLUDE_vTaskDelete 1
|
||||
#define INCLUDE_vTaskSuspend 1
|
||||
#define INCLUDE_vTaskDelayUntil 1
|
||||
#define INCLUDE_vTaskDelay 1
|
||||
#define INCLUDE_xTaskGetSchedulerState 1
|
||||
#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark 0
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark2 0
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 0
|
||||
#define INCLUDE_eTaskGetState 1
|
||||
#define INCLUDE_xSemaphoreGetMutexHolder 1
|
||||
#define INCLUDE_xTimerPendFunctionCall 1
|
||||
#define INCLUDE_xTaskAbortDelay 0
|
||||
#define INCLUDE_xTaskGetHandle 0
|
||||
#define INCLUDE_xTaskResumeFromISR 1
|
||||
|
||||
#endif /* FREERTOS_CONFIG_H */
|
||||
@@ -74,8 +74,8 @@ interrupt stack after the scheduler has started. */
|
||||
the ISR stack. */
|
||||
#define portISR_STACK_FILL_BYTE 0xee
|
||||
#else
|
||||
extern const uint32_t __freertos_irq_stack_top[];
|
||||
const StackType_t xISRStackTop = ( StackType_t ) __freertos_irq_stack_top;
|
||||
extern const uint32_t g_top_irqstack[];
|
||||
const StackType_t xISRStackTop = ( StackType_t ) g_top_irqstack;
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -87,12 +87,14 @@ void vPortSetupTimerInterrupt( void ) __attribute__(( weak ));
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if 0
|
||||
/* Used to program the machine timer compare register. */
|
||||
uint64_t ullNextTime = 0ULL;
|
||||
const uint64_t *pullNextTime = &ullNextTime;
|
||||
const size_t uxTimerIncrementsForOneTick = ( size_t ) ( ( configCPU_CLOCK_HZ ) / ( configTICK_RATE_HZ ) ); /* Assumes increment won't go over 32-bits. */
|
||||
uint32_t const ullMachineTimerCompareRegisterBase = configMTIMECMP_BASE_ADDRESS;
|
||||
volatile uint64_t * pullMachineTimerCompareRegister = NULL;
|
||||
#endif
|
||||
|
||||
/* Set configCHECK_FOR_STACK_OVERFLOW to 3 to add ISR stack checking to task
|
||||
stack checking. A problem in the ISR stack will trigger an assert, not call the
|
||||
@@ -114,9 +116,18 @@ task stack, not the ISR stack). */
|
||||
#define portCHECK_ISR_STACK()
|
||||
#endif /* configCHECK_FOR_STACK_OVERFLOW > 2 */
|
||||
|
||||
/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). This
|
||||
will be set to 0 prior to the first task being started. */
|
||||
portLONG ulCriticalNesting = 0x9999UL;
|
||||
|
||||
/* Used to record one tack want to swtich task after enter critical area, we need know it
|
||||
* and implement task switch after exit critical area */
|
||||
portLONG pendsvflag = 0;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 )
|
||||
#if 0
|
||||
//#if( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 )
|
||||
|
||||
void vPortSetupTimerInterrupt( void )
|
||||
{
|
||||
@@ -151,6 +162,8 @@ BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
extern void xPortStartFirstTask( void );
|
||||
|
||||
ulCriticalNesting = 0UL;
|
||||
|
||||
#if( configASSERT_DEFINED == 1 )
|
||||
{
|
||||
volatile uint32_t mtvec = 0;
|
||||
@@ -173,6 +186,7 @@ extern void xPortStartFirstTask( void );
|
||||
}
|
||||
#endif /* configASSERT_DEFINED */
|
||||
|
||||
#if 0
|
||||
/* If there is a CLINT then it is ok to use the default implementation
|
||||
in this file, otherwise vPortSetupTimerInterrupt() must be implemented to
|
||||
configure whichever clock is to be used to generate the tick interrupt. */
|
||||
@@ -191,6 +205,7 @@ extern void xPortStartFirstTask( void );
|
||||
__asm volatile( "csrs mie, %0" :: "r"(0x800) );
|
||||
}
|
||||
#endif /* ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 ) */
|
||||
#endif
|
||||
|
||||
xPortStartFirstTask();
|
||||
|
||||
@@ -206,7 +221,64 @@ void vPortEndScheduler( void )
|
||||
for( ;; );
|
||||
}
|
||||
|
||||
void vTaskEnterCritical( void )
|
||||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
ulCriticalNesting ++;
|
||||
}
|
||||
|
||||
void vTaskExitCritical( void )
|
||||
{
|
||||
if (ulCriticalNesting == 0) {
|
||||
while(1);
|
||||
}
|
||||
|
||||
ulCriticalNesting --;
|
||||
if (ulCriticalNesting == 0)
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
|
||||
if (pendsvflag)
|
||||
{
|
||||
pendsvflag = 0;
|
||||
portYIELD();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if configUSE_PREEMPTION == 0
|
||||
void xPortSysTickHandler( void )
|
||||
{
|
||||
portLONG ulDummy;
|
||||
|
||||
ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
xTaskIncrementTick();
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
|
||||
}
|
||||
|
||||
#else
|
||||
void xPortSysTickHandler( void )
|
||||
{
|
||||
portLONG ulDummy;
|
||||
|
||||
ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||
{
|
||||
if (xTaskIncrementTick() != pdFALSE)
|
||||
{
|
||||
portYIELD_FROM_ISR(pdTRUE);
|
||||
}
|
||||
}
|
||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
|
||||
}
|
||||
#endif
|
||||
|
||||
__attribute__((weak)) void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName )
|
||||
{
|
||||
for(;;);
|
||||
}
|
||||
|
||||
__attribute__((weak)) void vApplicationMallocFailedHook( void )
|
||||
{
|
||||
for(;;);
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,9 @@
|
||||
* registers.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "cpuport.h"
|
||||
|
||||
#if __riscv_xlen == 64
|
||||
#define portWORD_SIZE 8
|
||||
#define store_x sd
|
||||
@@ -67,6 +70,16 @@
|
||||
#error Assembler did not define __riscv_xlen
|
||||
#endif
|
||||
|
||||
#if defined(__riscv_d)
|
||||
#define portFWORD_SIZE 8
|
||||
#define store_f fsd
|
||||
#define load_f fld
|
||||
#elif defined(__riscv_f)
|
||||
#define store_f fsw
|
||||
#define load_f flw
|
||||
#define portFWORD_SIZE 4
|
||||
#endif
|
||||
|
||||
#include "freertos_risc_v_chip_specific_extensions.h"
|
||||
|
||||
/* Check the freertos_risc_v_chip_specific_extensions.h and/or command line
|
||||
@@ -85,10 +98,6 @@ definitions. */
|
||||
#error freertos_risc_v_chip_specific_extensions.h must define portasmHAS_MTIME to either 1 (MTIME clock present) or 0 (MTIME clock not present). See https://www.FreeRTOS.org/Using-FreeRTOS-on-RISC-V.html
|
||||
#endif
|
||||
|
||||
#ifndef portasmHANDLE_INTERRUPT
|
||||
#error portasmHANDLE_INTERRUPT must be defined to the function to be called to handle external/peripheral interrupts. portasmHANDLE_INTERRUPT can be defined on the assembler command line or in the appropriate freertos_risc_v_chip_specific_extensions.h header file. https://www.FreeRTOS.org/Using-FreeRTOS-on-RISC-V.html
|
||||
#endif
|
||||
|
||||
#ifndef portasmHAS_SIFIVE_CLINT
|
||||
#define portasmHAS_SIFIVE_CLINT 0
|
||||
#endif
|
||||
@@ -98,9 +107,18 @@ registers must be saved by the portasmSAVE_ADDITIONAL_REGISTERS and
|
||||
portasmRESTORE_ADDITIONAL_REGISTERS macros - which can be defined in a chip
|
||||
specific version of freertos_risc_v_chip_specific_extensions.h. See the notes
|
||||
at the top of this file. */
|
||||
#if defined(__riscv_p)
|
||||
#define portCONTEXT_SIZE ( 31 * portWORD_SIZE )
|
||||
#else
|
||||
#define portCONTEXT_SIZE ( 30 * portWORD_SIZE )
|
||||
#endif
|
||||
#if defined(__riscv_d) || defined(__riscv_f)
|
||||
#define FLOAT_REG_NUM 32
|
||||
#define portFCONTEXT_SIZE ( FLOAT_REG_NUM * portFWORD_SIZE )
|
||||
#endif
|
||||
|
||||
.global xPortStartFirstTask
|
||||
.global PendSV_Handler
|
||||
.global freertos_risc_v_trap_handler
|
||||
.global pxPortInitialiseStack
|
||||
.extern pxCurrentTCB
|
||||
@@ -116,9 +134,75 @@ at the top of this file. */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Functions: vPortYield
|
||||
*/
|
||||
.global vPortYield
|
||||
.type vPortYield, %function
|
||||
vPortYield:
|
||||
li t0, TSPEND_ADDR
|
||||
lb t1, (t0)
|
||||
li t2, 0x01
|
||||
or t1, t1, t2
|
||||
sb t1, (t0)
|
||||
|
||||
/* make sure wite instruction is complete */
|
||||
fence
|
||||
lb t1, (t0)
|
||||
fence
|
||||
#ifdef __riscv_xthead
|
||||
sync.i
|
||||
#else
|
||||
.long 0x01a0000b
|
||||
#endif
|
||||
|
||||
ret
|
||||
|
||||
.align 8
|
||||
.func
|
||||
PendSV_Handler:
|
||||
freertos_risc_v_trap_handler:
|
||||
#ifdef CONFIG_THEAD_EXT_SPSWAPEN
|
||||
csrrw sp, mscratch, sp
|
||||
#endif
|
||||
|
||||
// portasmSAVE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to save any registers unique to the RISC-V implementation. */
|
||||
#if defined(__riscv_d) || defined(__riscv_f)
|
||||
addi sp, sp, -portFCONTEXT_SIZE
|
||||
store_f f0, 0 * portFWORD_SIZE( sp )
|
||||
store_f f1, 1 * portFWORD_SIZE( sp )
|
||||
store_f f2, 2 * portFWORD_SIZE( sp )
|
||||
store_f f3, 3 * portFWORD_SIZE( sp )
|
||||
store_f f4, 4 * portFWORD_SIZE( sp )
|
||||
store_f f5, 5 * portFWORD_SIZE( sp )
|
||||
store_f f6, 6 * portFWORD_SIZE( sp )
|
||||
store_f f7, 7 * portFWORD_SIZE( sp )
|
||||
store_f f8, 8 * portFWORD_SIZE( sp )
|
||||
store_f f9, 9 * portFWORD_SIZE( sp )
|
||||
store_f f10, 10 * portFWORD_SIZE( sp )
|
||||
store_f f11, 11 * portFWORD_SIZE( sp )
|
||||
store_f f12, 12 * portFWORD_SIZE( sp )
|
||||
store_f f13, 13 * portFWORD_SIZE( sp )
|
||||
store_f f14, 14 * portFWORD_SIZE( sp )
|
||||
store_f f15, 15 * portFWORD_SIZE( sp )
|
||||
store_f f16, 16 * portFWORD_SIZE( sp )
|
||||
store_f f17, 17 * portFWORD_SIZE( sp )
|
||||
store_f f18, 18 * portFWORD_SIZE( sp )
|
||||
store_f f19, 19 * portFWORD_SIZE( sp )
|
||||
store_f f20, 20 * portFWORD_SIZE( sp )
|
||||
store_f f21, 21 * portFWORD_SIZE( sp )
|
||||
store_f f22, 22 * portFWORD_SIZE( sp )
|
||||
store_f f23, 23 * portFWORD_SIZE( sp )
|
||||
store_f f24, 24 * portFWORD_SIZE( sp )
|
||||
store_f f25, 25 * portFWORD_SIZE( sp )
|
||||
store_f f26, 26 * portFWORD_SIZE( sp )
|
||||
store_f f27, 27 * portFWORD_SIZE( sp )
|
||||
store_f f28, 28 * portFWORD_SIZE( sp )
|
||||
store_f f29, 29 * portFWORD_SIZE( sp )
|
||||
store_f f30, 30 * portFWORD_SIZE( sp )
|
||||
store_f f31, 31 * portFWORD_SIZE( sp )
|
||||
#endif
|
||||
|
||||
addi sp, sp, -portCONTEXT_SIZE
|
||||
store_x x1, 1 * portWORD_SIZE( sp )
|
||||
store_x x5, 2 * portWORD_SIZE( sp )
|
||||
@@ -152,101 +236,30 @@ freertos_risc_v_trap_handler:
|
||||
csrr t0, mstatus /* Required for MPIE bit. */
|
||||
store_x t0, 29 * portWORD_SIZE( sp )
|
||||
|
||||
portasmSAVE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to save any registers unique to the RISC-V implementation. */
|
||||
#if defined(__riscv_p)
|
||||
csrr t0, vxsat
|
||||
store_x t0, 30 * portWORD_SIZE( sp )
|
||||
#endif
|
||||
|
||||
csrr a1, mepc
|
||||
store_x a1, 0( sp ) /* Save updated exception return address. */
|
||||
|
||||
load_x t0, pxCurrentTCB /* Load pxCurrentTCB. */
|
||||
store_x sp, 0( t0 ) /* Write sp to first TCB member. */
|
||||
|
||||
csrr a0, mcause
|
||||
csrr a1, mepc
|
||||
|
||||
test_if_asynchronous:
|
||||
srli a2, a0, __riscv_xlen - 1 /* MSB of mcause is 1 if handing an asynchronous interrupt - shift to LSB to clear other bits. */
|
||||
beq a2, x0, handle_synchronous /* Branch past interrupt handing if not asynchronous. */
|
||||
store_x a1, 0( sp ) /* Asynch so save unmodified exception return address. */
|
||||
|
||||
handle_asynchronous:
|
||||
|
||||
#if( portasmHAS_MTIME != 0 )
|
||||
|
||||
test_if_mtimer: /* If there is a CLINT then the mtimer is used to generate the tick interrupt. */
|
||||
|
||||
addi t0, x0, 1
|
||||
|
||||
slli t0, t0, __riscv_xlen - 1 /* LSB is already set, shift into MSB. Shift 31 on 32-bit or 63 on 64-bit cores. */
|
||||
addi t1, t0, 7 /* 0x8000[]0007 == machine timer interrupt. */
|
||||
bne a0, t1, test_if_external_interrupt
|
||||
|
||||
load_x t0, pullMachineTimerCompareRegister /* Load address of compare register into t0. */
|
||||
load_x t1, pullNextTime /* Load the address of ullNextTime into t1. */
|
||||
|
||||
#if( __riscv_xlen == 32 )
|
||||
|
||||
/* Update the 64-bit mtimer compare match value in two 32-bit writes. */
|
||||
li t4, -1
|
||||
lw t2, 0(t1) /* Load the low word of ullNextTime into t2. */
|
||||
lw t3, 4(t1) /* Load the high word of ullNextTime into t3. */
|
||||
sw t4, 0(t0) /* Low word no smaller than old value to start with - will be overwritten below. */
|
||||
sw t3, 4(t0) /* Store high word of ullNextTime into compare register. No smaller than new value. */
|
||||
sw t2, 0(t0) /* Store low word of ullNextTime into compare register. */
|
||||
lw t0, uxTimerIncrementsForOneTick /* Load the value of ullTimerIncrementForOneTick into t0 (could this be optimized by storing in an array next to pullNextTime?). */
|
||||
add t4, t0, t2 /* Add the low word of ullNextTime to the timer increments for one tick (assumes timer increment for one tick fits in 32-bits). */
|
||||
sltu t5, t4, t2 /* See if the sum of low words overflowed (what about the zero case?). */
|
||||
add t6, t3, t5 /* Add overflow to high word of ullNextTime. */
|
||||
sw t4, 0(t1) /* Store new low word of ullNextTime. */
|
||||
sw t6, 4(t1) /* Store new high word of ullNextTime. */
|
||||
|
||||
#endif /* __riscv_xlen == 32 */
|
||||
|
||||
#if( __riscv_xlen == 64 )
|
||||
|
||||
/* Update the 64-bit mtimer compare match value. */
|
||||
ld t2, 0(t1) /* Load ullNextTime into t2. */
|
||||
sd t2, 0(t0) /* Store ullNextTime into compare register. */
|
||||
ld t0, uxTimerIncrementsForOneTick /* Load the value of ullTimerIncrementForOneTick into t0 (could this be optimized by storing in an array next to pullNextTime?). */
|
||||
add t4, t0, t2 /* Add ullNextTime to the timer increments for one tick. */
|
||||
sd t4, 0(t1) /* Store ullNextTime. */
|
||||
|
||||
#endif /* __riscv_xlen == 64 */
|
||||
|
||||
load_x sp, xISRStackTop /* Switch to ISR stack before function call. */
|
||||
jal xTaskIncrementTick
|
||||
beqz a0, processed_source /* Don't switch context if incrementing tick didn't unblock a task. */
|
||||
jal vTaskSwitchContext
|
||||
j processed_source
|
||||
|
||||
test_if_external_interrupt: /* If there is a CLINT and the mtimer interrupt is not pending then check to see if an external interrupt is pending. */
|
||||
addi t1, t1, 4 /* 0x80000007 + 4 = 0x8000000b == Machine external interrupt. */
|
||||
bne a0, t1, as_yet_unhandled /* Something as yet unhandled. */
|
||||
|
||||
#endif /* portasmHAS_MTIME */
|
||||
|
||||
load_x sp, xISRStackTop /* Switch to ISR stack before function call. */
|
||||
jal portasmHANDLE_INTERRUPT /* Jump to the interrupt handler if there is no CLINT or if there is a CLINT and it has been determined that an external interrupt is pending. */
|
||||
j processed_source
|
||||
|
||||
handle_synchronous:
|
||||
addi a1, a1, 4 /* Synchronous so updated exception return address to the instruction after the instruction that generated the exeption. */
|
||||
store_x a1, 0( sp ) /* Save updated exception return address. */
|
||||
|
||||
test_if_environment_call:
|
||||
li t0, 11 /* 11 == environment call. */
|
||||
bne a0, t0, is_exception /* Not an M environment call, so some other exception. */
|
||||
load_x sp, xISRStackTop /* Switch to ISR stack before function call. */
|
||||
jal vTaskSwitchContext
|
||||
j processed_source
|
||||
|
||||
is_exception:
|
||||
csrr t0, mcause /* For viewing in the debugger only. */
|
||||
csrr t1, mepc /* For viewing in the debugger only */
|
||||
csrr t2, mstatus
|
||||
j is_exception /* No other exceptions handled yet. */
|
||||
#ifdef TSPEND_NEED_CLEAR
|
||||
/* clear software interrupt */
|
||||
li t0, TSPEND_ADDR
|
||||
li t1, 0x0
|
||||
sw t1, (t0)
|
||||
/* make sure wite instruction is complete */
|
||||
fence
|
||||
lb t1, (t0)
|
||||
#endif
|
||||
|
||||
as_yet_unhandled:
|
||||
csrr t0, mcause /* For viewing in the debugger only. */
|
||||
j as_yet_unhandled
|
||||
|
||||
processed_source:
|
||||
load_x t1, pxCurrentTCB /* Load pxCurrentTCB. */
|
||||
load_x sp, 0( t1 ) /* Read sp from first TCB member. */
|
||||
|
||||
@@ -254,7 +267,10 @@ processed_source:
|
||||
load_x t0, 0( sp )
|
||||
csrw mepc, t0
|
||||
|
||||
portasmRESTORE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to restore any registers unique to the RISC-V implementation. */
|
||||
#if defined(__riscv_p)
|
||||
load_x t0, 30( sp )
|
||||
csrw vxsat, t0
|
||||
#endif
|
||||
|
||||
/* Load mstatus with the interrupt enable bits used by the task. */
|
||||
load_x t0, 29 * portWORD_SIZE( sp )
|
||||
@@ -290,6 +306,46 @@ processed_source:
|
||||
load_x x31, 28 * portWORD_SIZE( sp ) /* t6 */
|
||||
addi sp, sp, portCONTEXT_SIZE
|
||||
|
||||
//portasmRESTORE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to restore any registers unique to the RISC-V implementation. */
|
||||
#if defined(__riscv_d) || defined(__riscv_f)
|
||||
load_f f0, 0 * portFWORD_SIZE( sp )
|
||||
load_f f1, 1 * portFWORD_SIZE( sp )
|
||||
load_f f2, 2 * portFWORD_SIZE( sp )
|
||||
load_f f3, 3 * portFWORD_SIZE( sp )
|
||||
load_f f4, 4 * portFWORD_SIZE( sp )
|
||||
load_f f5, 5 * portFWORD_SIZE( sp )
|
||||
load_f f6, 6 * portFWORD_SIZE( sp )
|
||||
load_f f7, 7 * portFWORD_SIZE( sp )
|
||||
load_f f8, 8 * portFWORD_SIZE( sp )
|
||||
load_f f9, 9 * portFWORD_SIZE( sp )
|
||||
load_f f10, 10 * portFWORD_SIZE( sp )
|
||||
load_f f11, 11 * portFWORD_SIZE( sp )
|
||||
load_f f12, 12 * portFWORD_SIZE( sp )
|
||||
load_f f13, 13 * portFWORD_SIZE( sp )
|
||||
load_f f14, 14 * portFWORD_SIZE( sp )
|
||||
load_f f15, 15 * portFWORD_SIZE( sp )
|
||||
load_f f16, 16 * portFWORD_SIZE( sp )
|
||||
load_f f17, 17 * portFWORD_SIZE( sp )
|
||||
load_f f18, 18 * portFWORD_SIZE( sp )
|
||||
load_f f19, 19 * portFWORD_SIZE( sp )
|
||||
load_f f20, 20 * portFWORD_SIZE( sp )
|
||||
load_f f21, 21 * portFWORD_SIZE( sp )
|
||||
load_f f22, 22 * portFWORD_SIZE( sp )
|
||||
load_f f23, 23 * portFWORD_SIZE( sp )
|
||||
load_f f24, 24 * portFWORD_SIZE( sp )
|
||||
load_f f25, 25 * portFWORD_SIZE( sp )
|
||||
load_f f26, 26 * portFWORD_SIZE( sp )
|
||||
load_f f27, 27 * portFWORD_SIZE( sp )
|
||||
load_f f28, 28 * portFWORD_SIZE( sp )
|
||||
load_f f29, 29 * portFWORD_SIZE( sp )
|
||||
load_f f30, 30 * portFWORD_SIZE( sp )
|
||||
load_f f31, 31 * portFWORD_SIZE( sp )
|
||||
addi sp, sp, portFCONTEXT_SIZE
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_THEAD_EXT_SPSWAPEN
|
||||
csrrw sp, mscratch, sp
|
||||
#endif
|
||||
mret
|
||||
.endfunc
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -298,20 +354,15 @@ processed_source:
|
||||
.func
|
||||
xPortStartFirstTask:
|
||||
|
||||
#if( portasmHAS_SIFIVE_CLINT != 0 )
|
||||
/* If there is a clint then interrupts can branch directly to the FreeRTOS
|
||||
trap handler. Otherwise the interrupt controller will need to be configured
|
||||
outside of this file. */
|
||||
la t0, freertos_risc_v_trap_handler
|
||||
csrw mtvec, t0
|
||||
#endif /* portasmHAS_CLILNT */
|
||||
|
||||
load_x sp, pxCurrentTCB /* Load pxCurrentTCB. */
|
||||
load_x sp, 0( sp ) /* Read sp from first TCB member. */
|
||||
|
||||
load_x x1, 0( sp ) /* Note for starting the scheduler the exception return address is used as the function return address. */
|
||||
load_x x1, 0( sp ) /* Note for starting the scheduler the exception return address is used as the function return address. */
|
||||
|
||||
portasmRESTORE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to restore any registers unique to the RISC-V implementation. */
|
||||
#if defined(__riscv_p)
|
||||
load_x t0, 30( sp )
|
||||
csrw vxsat, t0
|
||||
#endif
|
||||
|
||||
load_x x6, 3 * portWORD_SIZE( sp ) /* t1 */
|
||||
load_x x7, 4 * portWORD_SIZE( sp ) /* t2 */
|
||||
@@ -346,6 +397,43 @@ xPortStartFirstTask:
|
||||
load_x x5, 2 * portWORD_SIZE( sp ) /* Initial x5 (t0) value. */
|
||||
|
||||
addi sp, sp, portCONTEXT_SIZE
|
||||
|
||||
//portasmRESTORE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to restore any registers unique to the RISC-V implementation. */
|
||||
#if defined(__riscv_d) || defined(__riscv_f)
|
||||
load_f f0, 0 * portFWORD_SIZE( sp )
|
||||
load_f f1, 1 * portFWORD_SIZE( sp )
|
||||
load_f f2, 2 * portFWORD_SIZE( sp )
|
||||
load_f f3, 3 * portFWORD_SIZE( sp )
|
||||
load_f f4, 4 * portFWORD_SIZE( sp )
|
||||
load_f f5, 5 * portFWORD_SIZE( sp )
|
||||
load_f f6, 6 * portFWORD_SIZE( sp )
|
||||
load_f f7, 7 * portFWORD_SIZE( sp )
|
||||
load_f f8, 8 * portFWORD_SIZE( sp )
|
||||
load_f f9, 9 * portFWORD_SIZE( sp )
|
||||
load_f f10, 10 * portFWORD_SIZE( sp )
|
||||
load_f f11, 11 * portFWORD_SIZE( sp )
|
||||
load_f f12, 12 * portFWORD_SIZE( sp )
|
||||
load_f f13, 13 * portFWORD_SIZE( sp )
|
||||
load_f f14, 14 * portFWORD_SIZE( sp )
|
||||
load_f f15, 15 * portFWORD_SIZE( sp )
|
||||
load_f f16, 16 * portFWORD_SIZE( sp )
|
||||
load_f f17, 17 * portFWORD_SIZE( sp )
|
||||
load_f f18, 18 * portFWORD_SIZE( sp )
|
||||
load_f f19, 19 * portFWORD_SIZE( sp )
|
||||
load_f f20, 20 * portFWORD_SIZE( sp )
|
||||
load_f f21, 21 * portFWORD_SIZE( sp )
|
||||
load_f f22, 22 * portFWORD_SIZE( sp )
|
||||
load_f f23, 23 * portFWORD_SIZE( sp )
|
||||
load_f f24, 24 * portFWORD_SIZE( sp )
|
||||
load_f f25, 25 * portFWORD_SIZE( sp )
|
||||
load_f f26, 26 * portFWORD_SIZE( sp )
|
||||
load_f f27, 27 * portFWORD_SIZE( sp )
|
||||
load_f f28, 28 * portFWORD_SIZE( sp )
|
||||
load_f f29, 29 * portFWORD_SIZE( sp )
|
||||
load_f f30, 30 * portFWORD_SIZE( sp )
|
||||
load_f f31, 31 * portFWORD_SIZE( sp )
|
||||
addi sp, sp, portFCONTEXT_SIZE
|
||||
#endif
|
||||
ret
|
||||
.endfunc
|
||||
/*-----------------------------------------------------------*/
|
||||
@@ -415,6 +503,22 @@ xPortStartFirstTask:
|
||||
.align 8
|
||||
.func
|
||||
pxPortInitialiseStack:
|
||||
#if defined(__riscv_d) || defined(__riscv_f)
|
||||
addi t0, x0, FLOAT_REG_NUM /* The number of float registers. */
|
||||
chip_float_stack_frame: /* First add any float registers to the stack frame being created. */
|
||||
beq t0, x0, 1f /* No more float registers to save. */
|
||||
addi a0, a0, -portFWORD_SIZE /* Make space for float register. */
|
||||
store_f f0, 0(a0) /* Give the float register an initial value of zero. */
|
||||
addi t0, t0, -1 /* Decrement the count of float registers remaining. */
|
||||
j chip_float_stack_frame /* Until no more float registers. */
|
||||
1:
|
||||
#endif
|
||||
|
||||
#if defined(__riscv_p)
|
||||
csrr t0, vxsat
|
||||
addi a0, a0, -portWORD_SIZE
|
||||
store_x t0, 0(a0) /* vxsat onto the stack. */
|
||||
#endif
|
||||
|
||||
csrr t0, mstatus /* Obtain current mstatus value. */
|
||||
andi t0, t0, ~0x8 /* Ensure interrupts are disabled when the stack is restored within an ISR. Required when a task is created after the schedulre has been started, otherwise interrupts would be disabled anyway. */
|
||||
@@ -428,14 +532,7 @@ pxPortInitialiseStack:
|
||||
store_x a2, 0(a0) /* Task parameters (pvParameters parameter) goes into register X10/a0 on the stack. */
|
||||
addi a0, a0, -(6 * portWORD_SIZE) /* Space for registers x5-x9. */
|
||||
store_x x0, 0(a0) /* Return address onto the stack, could be portTASK_RETURN_ADDRESS */
|
||||
addi t0, x0, portasmADDITIONAL_CONTEXT_SIZE /* The number of chip specific additional registers. */
|
||||
chip_specific_stack_frame: /* First add any chip specific registers to the stack frame being created. */
|
||||
beq t0, x0, 1f /* No more chip specific registers to save. */
|
||||
addi a0, a0, -portWORD_SIZE /* Make space for chip specific register. */
|
||||
store_x x0, 0(a0) /* Give the chip specific register an initial value of zero. */
|
||||
addi t0, t0, -1 /* Decrement the count of chip specific registers remaining. */
|
||||
j chip_specific_stack_frame /* Until no more chip specific registers. */
|
||||
1:
|
||||
|
||||
addi a0, a0, -portWORD_SIZE
|
||||
store_x a1, 0(a0) /* mret value (pxCode parameter) onto the stack. */
|
||||
ret
|
||||
|
||||
@@ -90,15 +90,16 @@ not need to be guarded with a critical section. */
|
||||
|
||||
|
||||
/* Scheduler utilities. */
|
||||
extern void vPortYield( void );
|
||||
extern void vTaskSwitchContext( void );
|
||||
#define portYIELD() __asm volatile( "ecall" );
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vTaskSwitchContext()
|
||||
#define portYIELD() vPortYield()
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portYIELD()
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Critical section management. */
|
||||
#define portCRITICAL_NESTING_IN_TCB 1
|
||||
#define portCRITICAL_NESTING_IN_TCB 0
|
||||
extern void vTaskEnterCritical( void );
|
||||
extern void vTaskExitCritical( void );
|
||||
|
||||
@@ -113,7 +114,7 @@ extern void vTaskExitCritical( void );
|
||||
|
||||
/* Architecture specific optimisations. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#endif
|
||||
|
||||
#if( configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 )
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include <dfs_fs.h>
|
||||
#include <dfs_file.h>
|
||||
#include <dfs_elm.h>
|
||||
|
||||
static rt_device_t disk[FF_VOLUMES] = {0};
|
||||
|
||||
@@ -147,12 +148,12 @@ int dfs_elm_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *d
|
||||
|
||||
/* open the root directory to test whether the fatfs is valid */
|
||||
result = f_opendir(dir, drive);
|
||||
rt_free(dir);
|
||||
if (result != FR_OK)
|
||||
goto __err;
|
||||
|
||||
/* mount succeed! */
|
||||
fs->data = fat;
|
||||
rt_free(dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -955,7 +956,7 @@ DWORD get_fattime(void)
|
||||
(DWORD)tm_now.tm_mday << 16 |
|
||||
(DWORD)tm_now.tm_hour << 11 |
|
||||
(DWORD)tm_now.tm_min << 5 |
|
||||
(DWORD)tm_now.tm_sec / 2 ;
|
||||
(DWORD)tm_now.tm_sec / 2;
|
||||
|
||||
return fat_time;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ struct rt_adc_ops
|
||||
rt_uint32_t channel);
|
||||
rt_uint32_t (*get_irq_count)(struct rt_adc_device *device,
|
||||
rt_uint32_t channel);
|
||||
rt_uint32_t (*get_obtaining_data_mode)(struct rt_adc_device *device,
|
||||
rt_uint32_t channel);
|
||||
#endif
|
||||
rt_uint8_t (*get_resolution)(struct rt_adc_device *device);
|
||||
rt_int16_t (*get_vref) (struct rt_adc_device *device);
|
||||
@@ -47,6 +49,7 @@ typedef enum
|
||||
RT_ADC_CMD_IRQ_COUNT = RT_DEVICE_CTRL_BASE(ADC) + 5,
|
||||
RT_ADC_CMD_GET_DMA_DATA = RT_DEVICE_CTRL_BASE(ADC) + 6,
|
||||
RT_ADC_CMD_CONFIG_DMA = RT_DEVICE_CTRL_BASE(ADC) + 7,
|
||||
RT_ADC_CMD_OBTAIN_DATA_MODE = RT_DEVICE_CTRL_BASE(ADC) + 8,
|
||||
#endif
|
||||
} rt_adc_cmd_t;
|
||||
|
||||
|
||||
@@ -48,6 +48,8 @@ struct rt_mtd_nand_device {
|
||||
const struct rt_mtd_nand_driver_ops *ops;
|
||||
|
||||
void *priv;
|
||||
|
||||
rt_uint8_t attr;
|
||||
};
|
||||
typedef struct rt_mtd_nand_device *rt_mtd_nand_t;
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#define PWM_CMD_SET_FIFO (RT_DEVICE_CTRL_BASE(PWM) + 8)
|
||||
#define PWM_CMD_SET_FIFO_NUM (RT_DEVICE_CTRL_BASE(PWM) + 9)
|
||||
#define PWM_CMD_GET_FIFO (RT_DEVICE_CTRL_BASE(PWM) + 10)
|
||||
#define PWM_CMD_SET_PUL (RT_DEVICE_CTRL_BASE(PWM) + 11)
|
||||
|
||||
struct rt_pwm_configuration
|
||||
{
|
||||
@@ -37,6 +38,10 @@ struct rt_pwm_configuration
|
||||
*/
|
||||
rt_bool_t complementary;
|
||||
|
||||
#if defined(AIC_PWM_DRV) || defined(AIC_EPWM_DRV)
|
||||
rt_uint32_t irq_mode;
|
||||
rt_uint32_t pul_cnt;
|
||||
#endif
|
||||
#ifdef AIC_XPWM_DRV
|
||||
rt_uint32_t pulse_cnt; /* 0:PWM mode, 1-n:XPWM pulse cnt */
|
||||
rt_uint32_t fifo_num;
|
||||
@@ -67,6 +72,9 @@ rt_err_t rt_device_pwm_register(struct rt_device_pwm *device, const char *name,
|
||||
|
||||
rt_err_t rt_pwm_enable(struct rt_device_pwm *device, int channel);
|
||||
rt_err_t rt_pwm_disable(struct rt_device_pwm *device, int channel);
|
||||
#if defined(AIC_PWM_DRV) || defined(AIC_EPWM_DRV)
|
||||
rt_err_t rt_pwm_set_pul(struct rt_device_pwm *device, int channel, rt_uint32_t irq_mode, rt_uint32_t period, rt_uint32_t pulse, rt_uint32_t pul_cnt);
|
||||
#endif
|
||||
#ifdef AIC_XPWM_DRV
|
||||
rt_err_t rt_pwm_set(struct rt_device_pwm *device, int channel, rt_uint32_t period, rt_uint32_t pulse, rt_uint32_t pulse_cnt);
|
||||
#else
|
||||
|
||||
@@ -48,6 +48,9 @@ extern "C" {
|
||||
#define RT_TOUCH_CTRL_POWER_ON (RT_DEVICE_CTRL_BASE(Touch) + 8) /* Touch Power On */
|
||||
#define RT_TOUCH_CTRL_POWER_OFF (RT_DEVICE_CTRL_BASE(Touch) + 9) /* Touch Power Off */
|
||||
#define RT_TOUCH_CTRL_GET_STATUS (RT_DEVICE_CTRL_BASE(Touch) + 10) /* Get Touch Power Status */
|
||||
#ifdef AIC_RTP_DRV
|
||||
#define RT_TOUCH_CTRL_PDEB_VALID_CHECK (RT_DEVICE_CTRL_BASE(Touch) + 11) /* Determine if the pdeb value is valid*/
|
||||
#endif
|
||||
|
||||
/* Touch event */
|
||||
#define RT_TOUCH_EVENT_NONE (0) /* Touch none */
|
||||
|
||||
@@ -78,6 +78,10 @@ static rt_err_t _adc_control(rt_device_t dev, int cmd, void *args)
|
||||
{
|
||||
return adc->ops->get_irq_count(adc, (rt_uint32_t)(long)args);
|
||||
}
|
||||
else if (cmd == RT_ADC_CMD_OBTAIN_DATA_MODE && adc->ops->get_obtaining_data_mode)
|
||||
{
|
||||
return adc->ops->get_obtaining_data_mode(adc, (rt_uint32_t)(long)args);
|
||||
}
|
||||
#endif
|
||||
else if (cmd == RT_ADC_CMD_GET_VREF && adc->ops->get_vref && args)
|
||||
{
|
||||
|
||||
@@ -309,6 +309,29 @@ rt_err_t rt_pwm_get(struct rt_device_pwm *device, struct rt_pwm_configuration *c
|
||||
return result;
|
||||
}
|
||||
|
||||
#if defined(AIC_PWM_DRV) || defined(AIC_EPWM_DRV)
|
||||
rt_err_t rt_pwm_set_pul(struct rt_device_pwm *device, int channel, rt_uint32_t irq_mode, rt_uint32_t period, rt_uint32_t pulse, rt_uint32_t pul_cnt)
|
||||
{
|
||||
rt_err_t result = RT_EOK;
|
||||
struct rt_pwm_configuration configuration = {0};
|
||||
|
||||
if (!device)
|
||||
{
|
||||
return -RT_EIO;
|
||||
}
|
||||
|
||||
configuration.channel = (channel > 0) ? (channel) : (-channel);
|
||||
configuration.irq_mode = irq_mode;
|
||||
configuration.period = period;
|
||||
configuration.pulse = pulse;
|
||||
configuration.pul_cnt = pul_cnt;
|
||||
result = rt_device_control(&device->parent, PWM_CMD_SET_PUL, &configuration);
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_FINSH
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -415,6 +438,21 @@ static int pwm(int argc, char **argv)
|
||||
rt_kprintf("Get info of device: [%s] error.\n", pwm_device);
|
||||
}
|
||||
}
|
||||
#if defined(AIC_PWM_DRV) || defined(AIC_EPWM_DRV)
|
||||
else if (!strcmp(argv[1], "set_pul"))
|
||||
{
|
||||
if(argc == 7)
|
||||
{
|
||||
result = rt_pwm_set_pul(pwm_device, atoi(argv[2]), atoi(argv[3]), atoi(argv[4]), atoi(argv[5]), atoi(argv[6]));
|
||||
rt_kprintf("pwm pul set on %s at channel %d\n",pwm_device,atoi(argv[2]));
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_kprintf("Set pul of device: [%s] error\n", pwm_device);
|
||||
rt_kprintf("Usage: pwm set_pul <channel> <irq_mode> <period> <pulse> <pulse cnt>\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if (!strcmp(argv[1], "set"))
|
||||
{
|
||||
#ifdef AIC_XPWM_DRV
|
||||
@@ -533,10 +571,13 @@ static int pwm(int argc, char **argv)
|
||||
else
|
||||
{
|
||||
rt_kprintf("Usage: \n");
|
||||
rt_kprintf("pwm probe <device name> - probe pwm by name\n");
|
||||
rt_kprintf("pwm enable <channel> - enable pwm channel\n");
|
||||
rt_kprintf("pwm disable <channel> - disable pwm channel\n");
|
||||
rt_kprintf("pwm get <channel> - get pwm channel info\n");
|
||||
rt_kprintf("pwm probe <device name> - probe pwm by name\n");
|
||||
rt_kprintf("pwm enable <channel> - enable pwm channel\n");
|
||||
rt_kprintf("pwm disable <channel> - disable pwm channel\n");
|
||||
rt_kprintf("pwm get <channel> - get pwm channel info\n");
|
||||
#if defined(AIC_PWM_DRV) || defined(AIC_EPWM_DRV)
|
||||
rt_kprintf("pwm set_pul <channel> <irq_mode> <period> <pulse> <pulse cnt> - set pwm pulse\n");
|
||||
#endif
|
||||
#ifdef AIC_XPWM_DRV
|
||||
rt_kprintf("pwm set <channel> <period> <pulse> <pulse cnt> - set pwm channel info\n");
|
||||
rt_kprintf("pwm set_fifo_num <channel> <fifo_num> - set xpwm fifo count\n");
|
||||
@@ -546,7 +587,7 @@ static int pwm(int argc, char **argv)
|
||||
rt_kprintf("pwm dma_test <channel> <loop_times> - xpwm dma test\n");
|
||||
#endif
|
||||
#else
|
||||
rt_kprintf("pwm set <channel> <period> <pulse> - set pwm channel info\n");
|
||||
rt_kprintf("pwm set <channel> <period> <pulse> - set pwm channel info\n");
|
||||
#endif
|
||||
result = - RT_ERROR;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <dfs_fs.h>
|
||||
#include <disk_part.h>
|
||||
|
||||
#include <drivers/mmcsd_core.h>
|
||||
|
||||
@@ -340,7 +341,7 @@ static rt_int32_t mmcsd_set_blksize(struct rt_mmcsd_card *card)
|
||||
}
|
||||
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
const static struct rt_device_ops mmcsd_blk_ops =
|
||||
static const struct rt_device_ops mmcsd_blk_ops =
|
||||
{
|
||||
rt_mmcsd_init,
|
||||
rt_mmcsd_open,
|
||||
@@ -421,6 +422,28 @@ static struct mmcsd_blk_device * rt_mmcsd_create_blkdev(struct rt_mmcsd_card *ca
|
||||
return blk_dev;
|
||||
}
|
||||
|
||||
static unsigned long mmcsd_write(struct blk_desc *blk_dev, u64 start,
|
||||
u64 blkcnt, void *buffer)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = rt_mmcsd_req_blk(blk_dev->priv, start, buffer, blkcnt, 1);
|
||||
if (err == RT_EOK)
|
||||
return blkcnt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long mmcsd_read(struct blk_desc *blk_dev, u64 start, u64 blkcnt,
|
||||
const void *buffer)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = rt_mmcsd_req_blk(blk_dev->priv, start, (void *)buffer, blkcnt, 0);
|
||||
if (err == RT_EOK)
|
||||
return blkcnt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card)
|
||||
{
|
||||
rt_int32_t err = 0;
|
||||
@@ -456,29 +479,40 @@ rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card)
|
||||
/* Initial blk_device link-list. */
|
||||
rt_list_init(&card->blk_devices);
|
||||
|
||||
for (i = 0; i < RT_MMCSD_MAX_PARTITION; i++)
|
||||
{
|
||||
/* Get the first partition */
|
||||
status = dfs_filesystem_get_partition(&part, sector, i);
|
||||
if (status == RT_EOK)
|
||||
{
|
||||
struct aic_partition *parts, *p;
|
||||
struct blk_desc dev_desc;
|
||||
struct disk_blk_ops ops;
|
||||
|
||||
ops.blk_write = mmcsd_write;
|
||||
ops.blk_read = mmcsd_read;
|
||||
aic_disk_part_set_ops(&ops);
|
||||
dev_desc.blksz = card->card_blksize;
|
||||
dev_desc.lba_count = card->card_capacity * (1024 / card->card_blksize);
|
||||
dev_desc.priv = card;
|
||||
parts = aic_disk_get_parts(&dev_desc);
|
||||
p = parts;
|
||||
i = 0;
|
||||
while (p) {
|
||||
/* Given name is with allocated host id and its partition index. */
|
||||
if (card->card_type == CARD_TYPE_MMC)
|
||||
rt_snprintf(dname, sizeof(dname), "mmc%dp%d", host_id, i);
|
||||
else
|
||||
rt_snprintf(dname, sizeof(dname), "sd%dp%d", host_id, i);
|
||||
part.type = 0;
|
||||
part.offset = p->start / card->card_blksize;
|
||||
part.size = p->size / card->card_blksize;
|
||||
blk_dev = rt_mmcsd_create_blkdev(card, (const char*)dname, &part);
|
||||
if ( blk_dev == RT_NULL )
|
||||
{
|
||||
err = -RT_ENOMEM;
|
||||
aic_part_free(parts);
|
||||
goto exit_rt_mmcsd_blk_probe;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
p = p->next;
|
||||
i++;
|
||||
}
|
||||
if (parts)
|
||||
aic_part_free(parts);
|
||||
|
||||
/* Always create the super node, given name is with allocated host id. */
|
||||
if (card->card_type == CARD_TYPE_MMC)
|
||||
|
||||
@@ -605,6 +605,9 @@ static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag)
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
serial = (struct rt_serial_device *)dev;
|
||||
|
||||
/* this device has more reference count */
|
||||
if (dev->ref_count > 0) return RT_EOK;
|
||||
|
||||
LOG_D("open serial device: 0x%08x with open flag: 0x%04x",
|
||||
dev, oflag);
|
||||
/* check device flag with the open flag */
|
||||
@@ -751,7 +754,7 @@ static rt_err_t rt_serial_close(struct rt_device *dev)
|
||||
serial = (struct rt_serial_device *)dev;
|
||||
|
||||
/* this device has more reference count */
|
||||
if (dev->ref_count > 1) return RT_EOK;
|
||||
if (dev->ref_count > 0) return RT_EOK;
|
||||
|
||||
if (dev->open_flag & RT_DEVICE_FLAG_INT_RX)
|
||||
{
|
||||
@@ -834,7 +837,6 @@ static rt_err_t rt_serial_close(struct rt_device *dev)
|
||||
#endif /* RT_SERIAL_USING_DMA */
|
||||
|
||||
serial->ops->control(serial, RT_DEVICE_CTRL_CLOSE, RT_NULL);
|
||||
dev->flag &= ~RT_DEVICE_FLAG_ACTIVATED;
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ if GetDepend(['RT_WLAN_CFG_ENABLE']):
|
||||
if GetDepend(['RT_WLAN_WORK_THREAD_ENABLE']):
|
||||
src += ['wlan_workqueue.c']
|
||||
|
||||
group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_WIFI'], CPPPATH = CPPPATH)
|
||||
mycflags = (' -w')
|
||||
group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_WIFI'], CPPPATH
|
||||
= CPPPATH, LOCAL_CFLAGS = mycflags)
|
||||
|
||||
Return('group')
|
||||
|
||||
@@ -17,11 +17,14 @@
|
||||
#include <string.h>
|
||||
|
||||
/* ========================== block device ======================== */
|
||||
struct fal_blk_device
|
||||
{
|
||||
struct fal_blk_device {
|
||||
struct rt_device parent;
|
||||
struct rt_device_blk_geometry geometry;
|
||||
const struct fal_partition *fal_part;
|
||||
#ifdef AIC_FATFS_ENABLE_WRITE_IN_SPINOR
|
||||
rt_uint32_t length;
|
||||
rt_uint8_t *buf;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* RT-Thread device interface */
|
||||
@@ -47,12 +50,13 @@ static rt_err_t blk_dev_control(rt_device_t dev, rt_uint8_t cmd, void *args)
|
||||
|
||||
memcpy(geometry, &part->geometry, sizeof(struct rt_device_blk_geometry));
|
||||
}
|
||||
#ifndef FAL_BLK_DEVICE_RDONLY
|
||||
else if (cmd == RT_DEVICE_CTRL_BLK_ERASE)
|
||||
{
|
||||
rt_uint32_t *addrs = (rt_uint32_t *) args, start_addr = addrs[0], end_addr = addrs[1], phy_start_addr;
|
||||
rt_size_t phy_size;
|
||||
|
||||
log_d("start_addr = %d end_addr = %d.\n", start_addr, end_addr);
|
||||
|
||||
if (addrs == RT_NULL || start_addr > end_addr)
|
||||
{
|
||||
return -RT_ERROR;
|
||||
@@ -71,7 +75,6 @@ static rt_err_t blk_dev_control(rt_device_t dev, rt_uint8_t cmd, void *args)
|
||||
return -RT_ERROR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
@@ -99,33 +102,55 @@ static rt_size_t blk_dev_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_si
|
||||
|
||||
static rt_size_t blk_dev_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
|
||||
{
|
||||
#ifndef AIC_FATFS_ENABLE_WRITE_IN_SPINOR
|
||||
log_e("This config only supports read!\n");
|
||||
return size;
|
||||
#else
|
||||
int ret = 0;
|
||||
struct fal_blk_device *part;
|
||||
rt_off_t phy_pos;
|
||||
rt_size_t phy_size;
|
||||
rt_off_t phy_pos, buf_pos;
|
||||
rt_size_t phy_size, buf_size;
|
||||
rt_uint32_t align_sector = 0;
|
||||
rt_uint8_t align_cnt = 0;
|
||||
|
||||
part = (struct fal_blk_device*) dev;
|
||||
assert(part != RT_NULL);
|
||||
|
||||
/* change the block device's logic address to physical address */
|
||||
phy_pos = pos * part->geometry.bytes_per_sector;
|
||||
phy_size = size * part->geometry.bytes_per_sector;
|
||||
align_sector = pos - pos % 8;
|
||||
align_cnt = pos % 8 + size;
|
||||
align_cnt = (align_cnt + 7) / 8 * 8;
|
||||
|
||||
if (dev->flag & RT_DEVICE_FLAG_RDONLY) {
|
||||
log_e("The block device read only.\n");
|
||||
return size;
|
||||
}
|
||||
log_d("pos = %ld size = %d!\n", pos, size);
|
||||
log_d("align_sector = %ld align_cnt = %d!\n", align_sector, align_cnt);
|
||||
|
||||
ret = fal_partition_erase(part->fal_part, phy_pos, phy_size);
|
||||
phy_pos = align_sector * part->geometry.bytes_per_sector;
|
||||
phy_size = align_cnt * part->geometry.bytes_per_sector;
|
||||
buf_pos = pos % 8 * part->geometry.bytes_per_sector;
|
||||
buf_size = size * part->geometry.bytes_per_sector;
|
||||
|
||||
if (ret == (int) phy_size)
|
||||
{
|
||||
ret = fal_partition_write(part->fal_part, phy_pos, buffer, phy_size);
|
||||
}
|
||||
memset(part->buf, 0xFF, part->length);
|
||||
|
||||
ret = fal_partition_read(part->fal_part, phy_pos, part->buf, phy_size);
|
||||
if (ret != (int) phy_size)
|
||||
{
|
||||
ret = 0;
|
||||
log_e("fal partition read data size failed!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
rt_memcpy(part->buf + buf_pos, buffer, buf_size);
|
||||
|
||||
ret = fal_partition_erase(part->fal_part, phy_pos, phy_size);
|
||||
if (ret != (int) phy_size)
|
||||
{
|
||||
log_e("fal partition erase data size failed!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = fal_partition_write(part->fal_part, phy_pos, part->buf, phy_size);
|
||||
if (ret != (int) phy_size)
|
||||
{
|
||||
log_e("fal partition write data size failed!\n");
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -133,11 +158,12 @@ static rt_size_t blk_dev_write(rt_device_t dev, rt_off_t pos, const void* buffer
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
const static struct rt_device_ops blk_dev_ops =
|
||||
{
|
||||
static const struct rt_device_ops blk_dev_ops = {
|
||||
RT_NULL,
|
||||
RT_NULL,
|
||||
RT_NULL,
|
||||
@@ -177,20 +203,23 @@ struct rt_device *fal_blk_device_create(const char *parition_name)
|
||||
blk_dev = (struct fal_blk_device*) rt_malloc(sizeof(struct fal_blk_device));
|
||||
if (blk_dev)
|
||||
{
|
||||
#ifdef AIC_FATFS_ENABLE_WRITE_IN_SPINOR
|
||||
blk_dev->length = AIC_USING_FS_IMAGE_TYPE_FATFS_CLUSTER_SIZE * 512 * 2;
|
||||
blk_dev->buf = (uint8_t *)rt_malloc(blk_dev->length);
|
||||
if (!blk_dev->buf) {
|
||||
log_e("Error: no memory for create SPI NOR block buf");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
blk_dev->fal_part = fal_part;
|
||||
|
||||
#ifdef FAL_BLK_DEVICE_RDONLY
|
||||
/*To solve the problem of space waste when the sector is set to 4096*/
|
||||
/*bytes_per_sector and block_size must set to 512,
|
||||
the fatfs partition info can be recognized normally*/
|
||||
blk_dev->geometry.bytes_per_sector = 512;
|
||||
blk_dev->geometry.block_size = blk_dev->geometry.bytes_per_sector;
|
||||
blk_dev->geometry.sector_count = fal_part->len / blk_dev->geometry.bytes_per_sector;
|
||||
#else
|
||||
blk_dev->geometry.bytes_per_sector = fal_flash->blk_size;
|
||||
blk_dev->geometry.block_size = fal_flash->blk_size;
|
||||
blk_dev->geometry.sector_count = fal_part->len / fal_flash->blk_size;
|
||||
#endif
|
||||
|
||||
/* register device */
|
||||
blk_dev->parent.type = RT_Device_Class_Block;
|
||||
@@ -211,11 +240,8 @@ struct rt_device *fal_blk_device_create(const char *parition_name)
|
||||
|
||||
rt_sprintf(str, "blk_%s", fal_part->name);
|
||||
log_d("The FAL block device (%s) created successfully", str);
|
||||
#ifdef FAL_BLK_DEVICE_RDONLY
|
||||
rt_device_register(RT_DEVICE(blk_dev), str, RT_DEVICE_FLAG_RDONLY | RT_DEVICE_FLAG_STANDALONE);
|
||||
#else
|
||||
|
||||
rt_device_register(RT_DEVICE(blk_dev), str, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -409,8 +435,7 @@ static rt_size_t char_dev_write(rt_device_t dev, rt_off_t pos, const void *buffe
|
||||
}
|
||||
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
const static struct rt_device_ops char_dev_ops =
|
||||
{
|
||||
static const struct rt_device_ops char_dev_ops = {
|
||||
RT_NULL,
|
||||
RT_NULL,
|
||||
RT_NULL,
|
||||
@@ -952,7 +977,7 @@ static void fal(uint8_t argc, char **argv) {
|
||||
}
|
||||
}
|
||||
}
|
||||
MSH_CMD_EXPORT(fal, FAL (Flash Abstraction Layer) operate.);
|
||||
MSH_CMD_EXPORT(fal, FAL (Flash Abstraction Layer) operate);
|
||||
|
||||
#endif /* defined(RT_USING_FINSH) && defined(FINSH_USING_MSH) */
|
||||
#endif /* RT_VER_NUM */
|
||||
|
||||
@@ -69,6 +69,8 @@ static const short __spm[13] =
|
||||
ALIGN(4) static const char *days = "Sun Mon Tue Wed Thu Fri Sat ";
|
||||
ALIGN(4) static const char *months = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ";
|
||||
|
||||
extern uint64_t aic_get_time_us(void);
|
||||
|
||||
static int __isleap(int year)
|
||||
{
|
||||
/* every fourth year is a leap year except for century years that are
|
||||
@@ -618,8 +620,15 @@ RTM_EXPORT(clock_getres);
|
||||
int clock_gettime(clockid_t clockid, struct timespec *tp)
|
||||
{
|
||||
#ifndef RT_USING_RTC
|
||||
RTC_LOG_WARNING
|
||||
return -1;
|
||||
uint64_t us = 0;
|
||||
rt_base_t level;
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
us = aic_get_time_us();
|
||||
tp->tv_sec = us / (1000*1000);
|
||||
tp->tv_nsec = (us % (1000*1000))*1000;
|
||||
rt_hw_interrupt_enable(level);
|
||||
return 0;
|
||||
#else
|
||||
int ret = 0;
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ rt_err_t dlmodule_load_shared_object(struct rt_dlmodule* module, void *module_pt
|
||||
if (phdr[index].p_vaddr > vend_addr + 16)
|
||||
{
|
||||
/* There should not be too much padding in the object files. */
|
||||
LOG_W("warning: too much padding before segment %d", index);
|
||||
LOG_D("warning: too much padding before segment %d", index);
|
||||
}
|
||||
|
||||
vend_addr = phdr[index].p_vaddr + phdr[index].p_memsz;
|
||||
@@ -94,6 +94,7 @@ rt_err_t dlmodule_load_shared_object(struct rt_dlmodule* module, void *module_pt
|
||||
module->nref = 0;
|
||||
|
||||
/* allocate module space */
|
||||
module_size = ALIGN_UP(module_size, CACHE_LINE_SIZE);
|
||||
module->mem_space = rt_malloc_align(module_size, CACHE_LINE_SIZE);
|
||||
if (module->mem_space == RT_NULL)
|
||||
{
|
||||
@@ -311,6 +312,7 @@ rt_err_t dlmodule_load_relocated_object(struct rt_dlmodule* module, void *module
|
||||
module->vstart_addr = 0;
|
||||
|
||||
/* allocate module space */
|
||||
module_size = ALIGN_UP(module_size, CACHE_LINE_SIZE);
|
||||
module->mem_space = rt_malloc_align(module_size, CACHE_LINE_SIZE);
|
||||
if (module->mem_space == RT_NULL)
|
||||
{
|
||||
|
||||
@@ -146,6 +146,7 @@ static void _dlmodule_thread_entry(void* parameter)
|
||||
{
|
||||
int argc = 0;
|
||||
char *argv[RT_MODULE_ARG_MAX];
|
||||
int ret = 0;
|
||||
|
||||
struct rt_dlmodule *module = (struct rt_dlmodule*)parameter;
|
||||
|
||||
@@ -168,10 +169,11 @@ static void _dlmodule_thread_entry(void* parameter)
|
||||
module->cmd_line);
|
||||
|
||||
if (module->entry_addr)
|
||||
module->entry_addr(argc, argv);
|
||||
ret = module->entry_addr(argc, argv);
|
||||
|
||||
__exit:
|
||||
_dlmodule_exit();
|
||||
if (ret != RT_DLMODULE_DEAMON)
|
||||
_dlmodule_exit();
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -505,6 +507,8 @@ struct rt_dlmodule* dlmodule_load(const char* filename)
|
||||
/* increase module reference count */
|
||||
module->nref ++;
|
||||
|
||||
LOG_I("Module: load %s to 0x%lx succeed.", filename, module->mem_space);
|
||||
|
||||
/* deal with cache */
|
||||
#ifdef RT_USING_CACHE
|
||||
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, module->mem_space, module->mem_size);
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#define RT_DLMODULE_STAT_CLOSING 0x02
|
||||
#define RT_DLMODULE_STAT_CLOSED 0x03
|
||||
|
||||
#define RT_DLMODULE_DEAMON 0xDEA305
|
||||
|
||||
struct rt_dlmodule;
|
||||
typedef void* rt_addr_t;
|
||||
|
||||
|
||||
@@ -31,6 +31,16 @@ vPortYield:
|
||||
or t1, t1, t2
|
||||
sb t1, (t0)
|
||||
|
||||
/* make sure wite instruction is complete */
|
||||
fence
|
||||
lw t1, (t0)
|
||||
fence
|
||||
#ifdef __riscv_xthead
|
||||
sync.is
|
||||
#else
|
||||
.long 0x01b0000b
|
||||
#endif
|
||||
|
||||
ret
|
||||
|
||||
/*
|
||||
@@ -67,7 +77,11 @@ rt_hw_context_switch_to:
|
||||
fence
|
||||
lw t1, (t0)
|
||||
fence
|
||||
#ifdef __riscv_xthead
|
||||
sync.is
|
||||
#else
|
||||
.long 0x01b0000b
|
||||
#endif
|
||||
|
||||
/* enable global interrup */
|
||||
csrsi mstatus, 8
|
||||
@@ -120,7 +134,11 @@ rt_hw_context_switch_interrupt:
|
||||
fence
|
||||
lw t1, (t0)
|
||||
fence
|
||||
#ifdef __riscv_xthead
|
||||
sync.is
|
||||
#else
|
||||
.long 0x01b0000b
|
||||
#endif
|
||||
|
||||
LOAD t0, 0 * REGBYTES(sp)
|
||||
LOAD t1, 1 * REGBYTES(sp)
|
||||
|
||||
@@ -31,6 +31,16 @@ vPortYield:
|
||||
or t1, t1, t2
|
||||
sb t1, (t0)
|
||||
|
||||
/* make sure wite instruction is complete */
|
||||
fence
|
||||
lb t1, (t0)
|
||||
fence
|
||||
#ifdef __riscv_xthead
|
||||
sync.i
|
||||
#else
|
||||
.long 0x01a0000b
|
||||
#endif
|
||||
|
||||
ret
|
||||
|
||||
/*
|
||||
@@ -75,7 +85,11 @@ rt_hw_context_switch_to:
|
||||
fence
|
||||
lb t1, (t0)
|
||||
fence
|
||||
#ifdef __riscv_xthead
|
||||
sync.i
|
||||
#else
|
||||
.long 0x01a0000b
|
||||
#endif
|
||||
|
||||
/* enable global interrup */
|
||||
csrsi mstatus, 8
|
||||
@@ -130,7 +144,11 @@ rt_hw_context_switch_interrupt:
|
||||
fence
|
||||
lb t1, (t0)
|
||||
fence
|
||||
#ifdef __riscv_xthead
|
||||
sync.i
|
||||
#else
|
||||
.long 0x01a0000b
|
||||
#endif
|
||||
|
||||
LOAD t0, 0 * REGBYTES(sp)
|
||||
LOAD t1, 1 * REGBYTES(sp)
|
||||
|
||||
@@ -1255,7 +1255,7 @@ rt_device_t rt_console_set_device(const char *name)
|
||||
}
|
||||
|
||||
/* set new console device */
|
||||
rt_device_open(new_device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_STREAM);
|
||||
rt_device_open(new_device, RT_DEVICE_FLAG_INT_RX | RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_STREAM);
|
||||
_console_device = new_device;
|
||||
}
|
||||
|
||||
|
||||
@@ -328,6 +328,13 @@ def TargetEclipse(env, sdk=False, prj_name=None):
|
||||
shutil.copytree(src_d, des_d)
|
||||
elif platform.system() == 'Windows':
|
||||
shutil.copytree('\\\\?\\' + src_d, '\\\\?\\' + des_d)
|
||||
# copy post_build.bat
|
||||
print('Copy post_build bat file...')
|
||||
src_d = os.path.join(prj_out_dir, 'post_build.bat')
|
||||
des_d = os.path.join(prj_eclipse_dir, 'tools')
|
||||
src_d = os.path.normpath(src_d)
|
||||
des_d = os.path.normpath(des_d)
|
||||
shutil.copy(src_d, des_d)
|
||||
# copy toolchain
|
||||
print('Copy toolchain file...')
|
||||
src_d = os.path.join(aic_root, 'toolchain')
|
||||
@@ -433,5 +440,54 @@ def TargetEclipse(env, sdk=False, prj_name=None):
|
||||
with open(des_f, 'w') as f:
|
||||
f.write(template_prefs_str)
|
||||
|
||||
# (2.3) write to 'post_build.bat'
|
||||
prj_chip = os.environ["PRJ_CHIP"]
|
||||
if sdk:
|
||||
src = os.path.join(prj_eclipse_dir, './tools/post_build.bat')
|
||||
else:
|
||||
src = os.path.join(prj_out_dir, './post_build.bat')
|
||||
if os.path.exists(src):
|
||||
post_build = None
|
||||
with open(src, 'r') as f:
|
||||
post_build = f.read()
|
||||
if sdk and post_build:
|
||||
post_build = post_build.replace(r';', '\n')
|
||||
des = prj_eclipse_dir + '/Debug/' + prj_chip
|
||||
post_build = post_build.replace(r'${ProjDirPath}/Debug/${ProjName}', des)
|
||||
des = prj_eclipse_dir + '/toolchain/bin/riscv64-unknown-elf-'
|
||||
post_build = post_build.replace(r'riscv64-unknown-elf-', des)
|
||||
des = prj_eclipse_dir + '/toolchain/riscv64-unknown-elf/bin/objcopy.exe'
|
||||
post_build = post_build.replace(r'${cross_prefix}${cross_objcopy}${cross_suffix}', des)
|
||||
des = prj_eclipse_dir + '/Debug/' + prj_chip
|
||||
post_build = post_build.replace(r'${ProjName}', des)
|
||||
des = prj_eclipse_dir
|
||||
post_build = post_build.replace(r'${ProjDirPath}', des)
|
||||
elif post_build:
|
||||
post_build = post_build.replace(r';', '\n')
|
||||
des = aic_root + '/toolchain/riscv64-unknown-elf/bin/objcopy.exe'
|
||||
post_build = post_build.replace(r'${cross_prefix}${cross_objcopy}${cross_suffix}', des)
|
||||
des = aic_root + '/tools/env/tools/Python39'
|
||||
post_build = post_build.replace(r'${ProjDirPath}/tools/Python39', des)
|
||||
des = aic_root + '/tools/env/tools/bin'
|
||||
post_build = post_build.replace(r'${ProjDirPath}/tools/bin', des)
|
||||
des = aic_root + '/' + prj_out_dir + prj_chip + '.elf'
|
||||
post_build = post_build.replace(r'${ProjDirPath}/Debug/${ProjName}.elf', des)
|
||||
des = aic_root + '/' + prj_out_dir
|
||||
post_build = post_build.replace(r'${ProjDirPath}/Debug/', des)
|
||||
des = aic_root + '/toolchain/bin/riscv64-unknown-elf-'
|
||||
post_build = post_build.replace(r'riscv64-unknown-elf-', des)
|
||||
post_build = post_build.replace(r'${ProjDirPath}', aic_root)
|
||||
des = aic_root + '/' + prj_out_dir + prj_chip + '.elf'
|
||||
post_build = post_build.replace(r'${ProjName}.elf', des)
|
||||
des = aic_root + '/' + prj_out_dir + prj_chip + '.bin'
|
||||
post_build = post_build.replace(r'${ProjName}.bin', des)
|
||||
with open(src, 'w') as f:
|
||||
if post_build:
|
||||
f.write(post_build)
|
||||
else:
|
||||
print("post_build.bat is invaild")
|
||||
else:
|
||||
print("post_build.bat is invaild")
|
||||
|
||||
print('done!')
|
||||
exit(0)
|
||||
|
||||
@@ -314,15 +314,11 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [
|
||||
prj_kernel = env['PRJ_KERNEL']
|
||||
prj_app = env['PRJ_APP']
|
||||
# generate .Kconfig.prj
|
||||
if prj_kernel == 'baremetal':
|
||||
app_os = 'baremetal'
|
||||
else:
|
||||
app_os = 'os'
|
||||
with open(".Kconfig.prj", "w") as f:
|
||||
f.write('source "bsp/artinchip/sys/{}/Kconfig.chip"\n'.format(prj_chip))
|
||||
f.write('source "target/{}/{}/Kconfig.board"\n'.format(prj_chip, prj_board))
|
||||
f.write('source "kernel/{}/Kconfig"\n'.format(prj_kernel))
|
||||
f.write('source "application/{}/{}/Kconfig"\n'.format(app_os, prj_app))
|
||||
f.write('source "application/{}/{}/Kconfig"\n'.format(prj_kernel, prj_app))
|
||||
if prj_kernel == 'rt-thread':
|
||||
f.write('source "$PKGS_DIR/Kconfig"\n')
|
||||
# call menuconfig
|
||||
|
||||
Reference in New Issue
Block a user