Merge pull request 'merge code' (#29) from prepare_for_master into develop
|
@ -35,5 +35,9 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
|
||||||
SRC_DIR += control_app
|
SRC_DIR += control_app
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_APP_USING_WEBNET),y)
|
||||||
|
SRC_DIR += webnet
|
||||||
|
endif
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
include $(KERNEL_ROOT)/compiler.mk
|
||||||
endif
|
endif
|
|
@ -1,5 +1,5 @@
|
||||||
menuconfig APP_USING_WEBNET
|
menuconfig APP_USING_WEBNET
|
||||||
bool "WebNet: A lightweight, customizable, embeddable Web Server for RT-Thread"
|
bool "WebNet: A lightweight, customizable, embeddable Web Server for XiUOS"
|
||||||
default n
|
default n
|
||||||
if APP_USING_WEBNET
|
if APP_USING_WEBNET
|
||||||
|
|
||||||
|
@ -25,31 +25,31 @@ if APP_USING_WEBNET
|
||||||
|
|
||||||
config WEBNET_USING_LOG
|
config WEBNET_USING_LOG
|
||||||
bool "LOG: Enable output log support"
|
bool "LOG: Enable output log support"
|
||||||
default n
|
default y
|
||||||
|
|
||||||
config WEBNET_USING_AUTH
|
config WEBNET_USING_AUTH
|
||||||
bool "AUTH: Enable basic HTTP authentication support"
|
bool "AUTH: Enable basic HTTP authentication support"
|
||||||
default n
|
default y
|
||||||
|
|
||||||
config WEBNET_USING_CGI
|
config WEBNET_USING_CGI
|
||||||
bool "CGI: Enable Common Gateway Interface support"
|
bool "CGI: Enable Common Gateway Interface support"
|
||||||
default n
|
default y
|
||||||
|
|
||||||
config WEBNET_USING_ASP
|
config WEBNET_USING_ASP
|
||||||
bool "ASP: Enable Active Server Pages support"
|
bool "ASP: Enable Active Server Pages support"
|
||||||
default n
|
default y
|
||||||
|
|
||||||
config WEBNET_USING_SSI
|
config WEBNET_USING_SSI
|
||||||
bool "SSI: Enable Server Side Includes support"
|
bool "SSI: Enable Server Side Includes support"
|
||||||
default n
|
default y
|
||||||
|
|
||||||
config WEBNET_USING_INDEX
|
config WEBNET_USING_INDEX
|
||||||
bool "INDEX: Enable list all the file in the directory support"
|
bool "INDEX: Enable list all the file in the directory support"
|
||||||
default n
|
default y
|
||||||
|
|
||||||
config WEBNET_USING_ALIAS
|
config WEBNET_USING_ALIAS
|
||||||
bool "ALIAS: Enable alias support"
|
bool "ALIAS: Enable alias support"
|
||||||
default n
|
default y
|
||||||
|
|
||||||
config WEBNET_USING_DAV
|
config WEBNET_USING_DAV
|
||||||
bool "DAV: Enable Web-based Distributed Authoring and Versioning support"
|
bool "DAV: Enable Web-based Distributed Authoring and Versioning support"
|
||||||
|
@ -57,7 +57,7 @@ if APP_USING_WEBNET
|
||||||
|
|
||||||
config WEBNET_USING_UPLOAD
|
config WEBNET_USING_UPLOAD
|
||||||
bool "UPLOAD: Enable upload file support"
|
bool "UPLOAD: Enable upload file support"
|
||||||
default n
|
default y
|
||||||
|
|
||||||
config WEBNET_USING_GZIP
|
config WEBNET_USING_GZIP
|
||||||
bool "GZIP: Enable compressed file support by GZIP"
|
bool "GZIP: Enable compressed file support by GZIP"
|
||||||
|
@ -65,11 +65,10 @@ if APP_USING_WEBNET
|
||||||
|
|
||||||
config WEBNET_CACHE_LEVEL
|
config WEBNET_CACHE_LEVEL
|
||||||
int "CACHE: Configure cache level(0:disable 1:use Last-Modified 2:use Cache-Control)"
|
int "CACHE: Configure cache level(0:disable 1:use Last-Modified 2:use Cache-Control)"
|
||||||
default 0
|
default 2
|
||||||
range 0 2
|
range 0 2
|
||||||
|
|
||||||
if WEBNET_CACHE_LEVEL = 2
|
if WEBNET_CACHE_LEVEL = 2
|
||||||
|
|
||||||
config WEBNET_CACHE_MAX_AGE
|
config WEBNET_CACHE_MAX_AGE
|
||||||
int "Cache-Control time in seconds"
|
int "Cache-Control time in seconds"
|
||||||
default 1800
|
default 1800
|
||||||
|
@ -80,7 +79,7 @@ if APP_USING_WEBNET
|
||||||
|
|
||||||
config WEBNET_USING_SAMPLES
|
config WEBNET_USING_SAMPLES
|
||||||
bool "Enable webnet samples"
|
bool "Enable webnet samples"
|
||||||
default n
|
default y
|
||||||
select WEBNET_USING_ASP
|
select WEBNET_USING_ASP
|
||||||
select WEBNET_USING_AUTH
|
select WEBNET_USING_AUTH
|
||||||
select WEBNET_USING_CGI
|
select WEBNET_USING_CGI
|
||||||
|
|
|
@ -237,3 +237,10 @@ void PrivTaskexitCritical()
|
||||||
{
|
{
|
||||||
rt_exit_critical();
|
rt_exit_critical();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************tick**********************/
|
||||||
|
#ifdef APP_USING_WEBNET
|
||||||
|
int PriGetTick(){
|
||||||
|
return rt_tick_get()/RT_TICK_PER_SECOND;
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -239,6 +239,10 @@ void PrivTaskenterCritical();
|
||||||
void PrivTaskexitCritical();
|
void PrivTaskexitCritical();
|
||||||
|
|
||||||
|
|
||||||
|
/*********************tick**********************/
|
||||||
|
#ifdef APP_USING_WEBNET
|
||||||
|
int PriGetTick();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,3 +204,24 @@ void PrivFree(void *pointer)
|
||||||
UserFree(pointer);
|
UserFree(pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*********************massage queue***********************/
|
||||||
|
mqd_t PrivMqueueSend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio)
|
||||||
|
{
|
||||||
|
return mq_send(mqdes, msg_ptr, msg_len, msg_prio);
|
||||||
|
}
|
||||||
|
|
||||||
|
mqd_t PrivMqueueCreate(const char *name, int oflag, mode_t mode, struct mq_attr *attr)
|
||||||
|
{
|
||||||
|
return mq_open(name, oflag, mode, attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PrivMqueueReceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio)
|
||||||
|
{
|
||||||
|
return mq_receive(mqdes, msg_ptr, msg_len, msg_prio);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************tick**********************/
|
||||||
|
int PriGetTick(){
|
||||||
|
return CurrentTicksGain() / TICK_PER_SECOND;
|
||||||
|
}
|
|
@ -29,6 +29,16 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <user_api.h>
|
#include <user_api.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
|
||||||
|
#ifdef APP_USING_WEBNET
|
||||||
|
#include "sys_arch.h"
|
||||||
|
#include <lwip/sockets.h>
|
||||||
|
#include "lwip/sys.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <iot-vfs_posix.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -93,6 +103,14 @@ extern "C" {
|
||||||
#define SERIAL_RB_BUFSZ 128
|
#define SERIAL_RB_BUFSZ 128
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef APP_USING_WEBNET
|
||||||
|
|
||||||
|
#define bool _Bool
|
||||||
|
#define FALSE 0
|
||||||
|
#define TRUE 1
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
struct PinDevIrq
|
struct PinDevIrq
|
||||||
{
|
{
|
||||||
int irq_mode;//< RISING/FALLING/HIGH/LOW
|
int irq_mode;//< RISING/FALLING/HIGH/LOW
|
||||||
|
@ -295,6 +313,16 @@ void *PrivRealloc(void *pointer, size_t size);
|
||||||
void *PrivCalloc(size_t count, size_t size);
|
void *PrivCalloc(size_t count, size_t size);
|
||||||
void PrivFree(void *pointer);
|
void PrivFree(void *pointer);
|
||||||
|
|
||||||
|
/*********************massage queue***********************/
|
||||||
|
|
||||||
|
mqd_t PrivMqueueSend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio);
|
||||||
|
mqd_t PrivMqueueCreate(const char *name, int oflag, mode_t mode,struct mq_attr *attr);
|
||||||
|
int PrivMqueueReceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio);
|
||||||
|
|
||||||
|
|
||||||
|
/*********************tick**********************/
|
||||||
|
int PriGetTick();
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,19 @@ typedef int pid_t;
|
||||||
#define SCHED_RR 2
|
#define SCHED_RR 2
|
||||||
#define SCHED_IDLE 5
|
#define SCHED_IDLE 5
|
||||||
|
|
||||||
|
/*from rt added by zy*/
|
||||||
|
#define DEFAULT_STACK_SIZE 4096
|
||||||
|
#define DEFAULT_PRIORITY KTASK_PRIORITY_MAX / 2
|
||||||
|
#define PTHREAD_CREATE_JOINABLE 0x00
|
||||||
|
#define PTHREAD_INHERIT_SCHED 1
|
||||||
|
|
||||||
|
/* function in pthread.c */
|
||||||
|
/*support webnet*/
|
||||||
|
int pthread_attr_init(pthread_attr_t *attr);
|
||||||
|
int pthread_attr_setschedparam(pthread_attr_t *attr,
|
||||||
|
struct sched_param const *param);
|
||||||
|
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stack_size);
|
||||||
|
|
||||||
/* function in pthread.c */
|
/* function in pthread.c */
|
||||||
int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void));
|
int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void));
|
||||||
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||||
|
|
|
@ -21,6 +21,45 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "include/pthread.h"
|
#include "include/pthread.h"
|
||||||
|
#include <assert.h>
|
||||||
|
const pthread_attr_t pthread_default_attr =
|
||||||
|
{
|
||||||
|
0, /* stack base */
|
||||||
|
0,
|
||||||
|
DEFAULT_STACK_SIZE, /* stack size */
|
||||||
|
0,
|
||||||
|
PTHREAD_INHERIT_SCHED, /* Inherit parent prio/policy */
|
||||||
|
SCHED_FIFO, /* scheduler policy */
|
||||||
|
{
|
||||||
|
DEFAULT_PRIORITY, /* scheduler priority */
|
||||||
|
},
|
||||||
|
4096,
|
||||||
|
PTHREAD_CREATE_JOINABLE, /* detach state */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int pthread_attr_init(pthread_attr_t *attr)
|
||||||
|
{
|
||||||
|
assert(attr != NULL);
|
||||||
|
*attr = pthread_default_attr;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pthread_attr_setschedparam(pthread_attr_t *attr,
|
||||||
|
struct sched_param const *param)
|
||||||
|
{
|
||||||
|
assert(attr != NULL);
|
||||||
|
assert(param != NULL);
|
||||||
|
attr->schedparam.sched_priority = param->sched_priority;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stack_size)
|
||||||
|
{
|
||||||
|
assert(attr != NULL);
|
||||||
|
attr->stacksize = stack_size;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||||
void *(*start_routine)(void *), void *arg)
|
void *(*start_routine)(void *), void *arg)
|
||||||
|
|
|
@ -11,4 +11,27 @@ config HC32F4A0_BOARD
|
||||||
---help---
|
---help---
|
||||||
Select if you are using the HC32F4A0 base board with the HC32F4A0.
|
Select if you are using the HC32F4A0 base board with the HC32F4A0.
|
||||||
|
|
||||||
|
config HC32_ROMFS
|
||||||
|
bool "Automount baked-in ROMFS image"
|
||||||
|
default n
|
||||||
|
depends on FS_ROMFS
|
||||||
|
---help---
|
||||||
|
Select HC32_ROMFS_IMAGEFILE, HC32_ROMFS_DEV_MINOR, HC32_ROMFS_MOUNTPOINT
|
||||||
|
|
||||||
|
config HC32_ROMFS_DEV_MINOR
|
||||||
|
int "Minor for the block device backing the data"
|
||||||
|
depends on HC32_ROMFS
|
||||||
|
default 64
|
||||||
|
|
||||||
|
config HC32_ROMFS_MOUNTPOINT
|
||||||
|
string "Mountpoint of the custom romfs image"
|
||||||
|
depends on HC32_ROMFS
|
||||||
|
default "/rom"
|
||||||
|
|
||||||
|
config HC32_ROMFS_IMAGEFILE
|
||||||
|
string "ROMFS image file to include into build"
|
||||||
|
depends on HC32_ROMFS
|
||||||
|
default "../../../../../rom.img"
|
||||||
|
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -57,38 +57,42 @@
|
||||||
/* for lowputc device output */
|
/* for lowputc device output */
|
||||||
|
|
||||||
/* UART RX/TX Port/Pin definition */
|
/* UART RX/TX Port/Pin definition */
|
||||||
#define LP_RX_PORT (GPIO_PORT_H) /* PH6: USART6_RX */
|
#define DBG_RX_PORT (GPIO_PORT_H) /* PH6: USART6_RX */
|
||||||
#define LP_RX_PIN (GPIO_PIN_06)
|
#define DBG_RX_PIN (GPIO_PIN_06)
|
||||||
#define LP_RX_GPIO_FUNC (GPIO_FUNC_37_USART6_RX)
|
#define DBG_RX_GPIO_FUNC (GPIO_FUNC_37_USART6_RX)
|
||||||
|
|
||||||
#define LP_TX_PORT (GPIO_PORT_E) /* PE6: USART6_TX */
|
#define DBG_TX_PORT (GPIO_PORT_E) /* PE6: USART6_TX */
|
||||||
#define LP_TX_PIN (GPIO_PIN_06)
|
#define DBG_TX_PIN (GPIO_PIN_06)
|
||||||
#define LP_TX_GPIO_FUNC (GPIO_FUNC_36_USART6_TX)
|
#define DBG_TX_GPIO_FUNC (GPIO_FUNC_36_USART6_TX)
|
||||||
|
|
||||||
/* UART unit definition */
|
/* UART unit definition */
|
||||||
#define LP_UNIT (M4_USART6)
|
#define DBG_UNIT (M4_USART6)
|
||||||
#define LP_FUNCTION_CLK_GATE (PWC_FCG3_USART6)
|
#define DBG_BAUDRATE (115200UL)
|
||||||
|
#define DBG_FUNCTION_CLK_GATE (PWC_FCG3_USART6)
|
||||||
|
|
||||||
/* UART unit interrupt definition */
|
/* UART unit interrupt definition */
|
||||||
#define LP_UNIT_ERR_INT_SRC (INT_USART6_EI)
|
#define DBG_UNIT_ERR_INT_SRC (INT_USART6_EI)
|
||||||
#define LP_UNIT_ERR_INT_IRQn (Int015_IRQn + HC32_IRQ_FIRST)
|
#define DBG_UNIT_ERR_INT_IRQn (Int010_IRQn)
|
||||||
|
|
||||||
#define LP_UNIT_RX_INT_SRC (INT_USART6_RI)
|
#define DBG_UNIT_RX_INT_SRC (INT_USART6_RI)
|
||||||
#define LP_UNIT_RX_INT_IRQn (Int103_IRQn + HC32_IRQ_FIRST)
|
#define DBG_UNIT_RX_INT_IRQn (Int011_IRQn)
|
||||||
|
|
||||||
#define LP_UNIT_TX_INT_SRC (INT_USART6_TI)
|
#define DBG_RXTO_INT_SRC (INT_USART6_RTO)
|
||||||
#define LP_UNIT_TX_INT_IRQn (Int102_IRQn + HC32_IRQ_FIRST)
|
#define DBG_RXTO_INT_IRQn (Int012_IRQn)
|
||||||
|
|
||||||
#define LP_UNIT_TCI_INT_SRC (INT_USART6_TCI)
|
#define DBG_UNIT_TX_INT_SRC (INT_USART6_TI)
|
||||||
#define LP_UNIT_TCI_INT_IRQn (Int099_IRQn + HC32_IRQ_FIRST)
|
#define DBG_UNIT_TX_INT_IRQn (Int013_IRQn)
|
||||||
|
|
||||||
|
#define DBG_UNIT_TCI_INT_SRC (INT_USART6_TCI)
|
||||||
|
#define DBG_UNIT_TCI_INT_IRQn (Int014_IRQn)
|
||||||
|
|
||||||
/* printf device s*/
|
/* printf device s*/
|
||||||
#define BSP_PRINTF_DEVICE LP_UNIT
|
#define BSP_PRINTF_DEVICE DBG_UNIT
|
||||||
#define BSP_PRINTF_BAUDRATE (115200)
|
#define BSP_PRINTF_BAUDRATE DBG_BAUDRATE
|
||||||
|
|
||||||
#define BSP_PRINTF_PORT LP_TX_PORT
|
#define BSP_PRINTF_PORT DBG_TX_PORT
|
||||||
|
|
||||||
#define BSP_PRINTF_PIN LP_TX_PIN
|
#define BSP_PRINTF_PIN DBG_TX_PIN
|
||||||
#define BSP_PRINTF_PORT_FUNC LP_TX_GPIO_FUNC
|
#define BSP_PRINTF_PORT_FUNC DBG_TX_GPIO_FUNC
|
||||||
|
|
||||||
#endif /* __BOARDS_ARM_HC32_HC32F4A0_INCLUDE_BOARD_H */
|
#endif /* __BOARDS_ARM_HC32_HC32F4A0_INCLUDE_BOARD_H */
|
||||||
|
|
|
@ -41,7 +41,7 @@ USER_LIBGCC = "${shell "$(CC)" $(ARCHCPUFLAGS) -print-libgcc-file-name}"
|
||||||
|
|
||||||
# Source files
|
# Source files
|
||||||
|
|
||||||
CSRCS = stm32_userspace.c
|
CSRCS = hc32_userspace.c
|
||||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||||
OBJS = $(COBJS)
|
OBJS = $(COBJS)
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
# error "CONFIG_NUTTX_USERSPACE not defined"
|
# error "CONFIG_NUTTX_USERSPACE not defined"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_NUTTX_USERSPACE != 0x20060000
|
#if CONFIG_NUTTX_USERSPACE != 0x20062000
|
||||||
# error "CONFIG_NUTTX_USERSPACE must be 0x20060000 to match memory.ld"
|
# error "CONFIG_NUTTX_USERSPACE must be 0x20060000 to match memory.ld"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* boards/arm/stm32/aiit-arm32-board/scripts/gnu-elf.ld
|
* boards/arm/hc32/hc32f4a0/scripts/gnu-elf.ld
|
||||||
*
|
*
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* boards/arm/stm32/aiit-arm32-board/scripts/kernel-space.ld
|
* boards/arm/hc32/hc32f4a0/scripts/kernel-space.ld
|
||||||
*
|
*
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
* For MPU support, the kernel-mode NuttX section is assumed to be 128Kb of
|
* For MPU support, the kernel-mode NuttX section is assumed to be 128Kb of
|
||||||
* FLASH and 4Kb of SRAM. That is an excessive amount for the kernel which
|
* FLASH and 4Kb of SRAM. That is an excessive amount for the kernel which
|
||||||
* should fit into 64KB and, of course, can be optimized as needed (See
|
* should fit into 64KB and, of course, can be optimized as needed (See
|
||||||
* also boards/arm/stm32/aiit-arm32-board/scripts/kernel-space.ld). Allowing the
|
* also boards/arm/hc32/hc32f4a0/scripts/kernel-space.ld). Allowing the
|
||||||
* additional does permit addition debug instrumentation to be added to the
|
* additional does permit addition debug instrumentation to be added to the
|
||||||
* kernel space without overflowing the partition.
|
* kernel space without overflowing the partition.
|
||||||
*
|
*
|
||||||
|
@ -73,13 +73,13 @@ MEMORY
|
||||||
{
|
{
|
||||||
/* 2Mb FLASH */
|
/* 2Mb FLASH */
|
||||||
|
|
||||||
kflash (rx) : ORIGIN = 0x00000000, LENGTH = 2M
|
kflash (rx) : ORIGIN = 0x00000000, LENGTH = 64K
|
||||||
uflash (rx) : ORIGIN = 0x00200000, LENGTH = 128K
|
uflash (rx) : ORIGIN = 0x00010000, LENGTH = 1M
|
||||||
xflash (rx) : ORIGIN = 0x00220000, LENGTH = 768K
|
xflash (rx) : ORIGIN = 0x00110000, LENGTH = 128K
|
||||||
|
|
||||||
/* 512Kb of contiguous SRAM */
|
/* 512Kb of contiguous SRAM */
|
||||||
|
|
||||||
ksram (rwx) : ORIGIN = 0x1FFE0000, LENGTH = 512K
|
ksram (rwx) : ORIGIN = 0x1FFE0000, LENGTH = 64K
|
||||||
usram (rwx) : ORIGIN = 0x20060000, LENGTH = 4K
|
usram (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 448K
|
||||||
xsram (rwx) : ORIGIN = 0x20062000, LENGTH = 4K
|
xsram (rwx) : ORIGIN = 0x20070000, LENGTH = 4K
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,16 +48,16 @@ SECTIONS
|
||||||
_sinit = ABSOLUTE(.);
|
_sinit = ABSOLUTE(.);
|
||||||
*(.init_array .init_array.*)
|
*(.init_array .init_array.*)
|
||||||
_einit = ABSOLUTE(.);
|
_einit = ABSOLUTE(.);
|
||||||
} > kflash
|
} > uflash
|
||||||
|
|
||||||
.ARM.extab : {
|
.ARM.extab : {
|
||||||
*(.ARM.extab*)
|
*(.ARM.extab*)
|
||||||
} > kflash
|
} > uflash
|
||||||
|
|
||||||
__exidx_start = ABSOLUTE(.);
|
__exidx_start = ABSOLUTE(.);
|
||||||
.ARM.exidx : {
|
.ARM.exidx : {
|
||||||
*(.ARM.exidx*)
|
*(.ARM.exidx*)
|
||||||
} > kflash
|
} > uflash
|
||||||
|
|
||||||
__exidx_end = ABSOLUTE(.);
|
__exidx_end = ABSOLUTE(.);
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ SECTIONS
|
||||||
CONSTRUCTORS
|
CONSTRUCTORS
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
_edata = ABSOLUTE(.);
|
_edata = ABSOLUTE(.);
|
||||||
} > ksram AT > kflash
|
} > usram AT > uflash
|
||||||
|
|
||||||
.bss : {
|
.bss : {
|
||||||
_sbss = ABSOLUTE(.);
|
_sbss = ABSOLUTE(.);
|
||||||
|
@ -79,7 +79,7 @@ SECTIONS
|
||||||
*(COMMON)
|
*(COMMON)
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
_ebss = ABSOLUTE(.);
|
_ebss = ABSOLUTE(.);
|
||||||
} > ksram
|
} > usram
|
||||||
|
|
||||||
/* Stabs debugging sections */
|
/* Stabs debugging sections */
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,10 @@ ifeq ($(CONFIG_ARCH_LEDS),y)
|
||||||
CSRCS +=
|
CSRCS +=
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_STM32_ROMFS),y)
|
||||||
|
CSRCS += hc32_romfs_initialize.c
|
||||||
|
endif
|
||||||
|
|
||||||
DEPPATH += --dep-path board
|
DEPPATH += --dep-path board
|
||||||
VPATH += :board
|
VPATH += :board
|
||||||
CFLAGS += $(shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board)
|
CFLAGS += $(shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board)
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
extern int hc32_bringup(void);
|
extern int hc32_bringup(void);
|
||||||
|
extern int hc32_spidev_initialized;
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: hc32_boardinitialize
|
* Name: hc32_boardinitialize
|
||||||
|
@ -52,57 +53,57 @@ extern int hc32_bringup(void);
|
||||||
|
|
||||||
void hc32_boardinitialize(void)
|
void hc32_boardinitialize(void)
|
||||||
{
|
{
|
||||||
//#ifdef CONFIG_SCHED_CRITMONITOR
|
#ifdef CONFIG_SCHED_CRITMONITOR
|
||||||
// /* Enable ITM and DWT resources, if not left enabled by debugger. */
|
/* Enable ITM and DWT resources, if not left enabled by debugger. */
|
||||||
//
|
|
||||||
// modifyreg32(NVIC_DEMCR, 0, NVIC_DEMCR_TRCENA);
|
modifyreg32(NVIC_DEMCR, 0, NVIC_DEMCR_TRCENA);
|
||||||
//
|
|
||||||
// /* Make sure the high speed cycle counter is running. It will be started
|
/* Make sure the high speed cycle counter is running. It will be started
|
||||||
// * automatically only if a debugger is connected.
|
* automatically only if a debugger is connected.
|
||||||
// */
|
*/
|
||||||
//
|
|
||||||
// putreg32(0xc5acce55, ITM_LAR);
|
putreg32(0xc5acce55, ITM_LAR);
|
||||||
// modifyreg32(DWT_CTRL, 0, DWT_CTRL_CYCCNTENA_MASK);
|
modifyreg32(DWT_CTRL, 0, DWT_CTRL_CYCCNTENA_MASK);
|
||||||
//#endif
|
#endif
|
||||||
//
|
|
||||||
//#if defined(CONFIG_HC32_SPI1) || defined(CONFIG_HC32_SPI2) || defined(CONFIG_HC32_SPI3)
|
#if defined(CONFIG_HC32_SPI1) || defined(CONFIG_HC32_SPI2) || defined(CONFIG_HC32_SPI3)
|
||||||
// /* Configure SPI chip selects if 1) SPI is not disabled, and 2) the weak
|
/* Configure SPI chip selects if 1) SPI is not disabled, and 2) the weak
|
||||||
// * function hc32_spidev_initialize() has been brought into the link.
|
* function hc32_spidev_initialize() has been brought into the link.
|
||||||
// */
|
*/
|
||||||
//
|
|
||||||
// if (hc32_spidev_initialize)
|
if (hc32_spidev_initialized)
|
||||||
// {
|
{
|
||||||
// hc32_spidev_initialize();
|
hc32_spidev_initialize();
|
||||||
// }
|
}
|
||||||
//#endif
|
#endif
|
||||||
//
|
|
||||||
//#ifdef CONFIG_HC32_OTGFS
|
#ifdef CONFIG_HC32_OTGFS
|
||||||
// /* Initialize USB if the 1) OTG FS controller is in the configuration and
|
/* Initialize USB if the 1) OTG FS controller is in the configuration and
|
||||||
// * 2) disabled, and 3) the weak function hc32_usbinitialize() has been
|
* 2) disabled, and 3) the weak function hc32_usbinitialize() has been
|
||||||
// * brought into the build. Presumably either CONFIG_USBDEV or
|
* brought into the build. Presumably either CONFIG_USBDEV or
|
||||||
// * CONFIG_USBHOST is also selected.
|
* CONFIG_USBHOST is also selected.
|
||||||
// */
|
*/
|
||||||
//
|
|
||||||
// if (hc32_usbinitialize)
|
if (hc32_usbinitialize)
|
||||||
// {
|
{
|
||||||
// hc32_usbinitialize();
|
hc32_usbinitialize();
|
||||||
// }
|
}
|
||||||
//#endif
|
#endif
|
||||||
//
|
|
||||||
//#ifdef HAVE_NETMONITOR
|
#ifdef HAVE_NETMONITOR
|
||||||
// /* Configure board resources to support networking. */
|
/* Configure board resources to support networking. */
|
||||||
//
|
|
||||||
// if (hc32_netinitialize)
|
if (hc32_netinitialize)
|
||||||
// {
|
{
|
||||||
// hc32_netinitialize();
|
hc32_netinitialize();
|
||||||
// }
|
}
|
||||||
//#endif
|
#endif
|
||||||
//
|
|
||||||
//#ifdef CONFIG_ARCH_LEDS
|
#ifdef CONFIG_ARCH_LEDS
|
||||||
// /* Configure on-board LEDs if LED support has been selected. */
|
/* Configure on-board LEDs if LED support has been selected. */
|
||||||
//
|
|
||||||
// board_autoled_initialize();
|
board_autoled_initialize();
|
||||||
//#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
|
|
||||||
#include <nuttx/fs/fs.h>
|
#include <nuttx/fs/fs.h>
|
||||||
|
|
||||||
|
#include <hc32_common.h>
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: hc32_bringup
|
* Name: hc32_bringup
|
||||||
*
|
*
|
||||||
|
@ -48,6 +50,27 @@
|
||||||
int hc32_bringup(void)
|
int hc32_bringup(void)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
#ifdef CONFIG_FS_PROCFS
|
||||||
|
/* Mount the procfs file system */
|
||||||
|
|
||||||
|
ret = nx_mount(NULL, HC32_PROCFS_MOUNTPOINT, "procfs", 0, NULL);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
serr("ERROR: Failed to mount procfs at %s: %d\n",
|
||||||
|
HC32_PROCFS_MOUNTPOINT, ret);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_HC32_ROMFS
|
||||||
|
ret = hc32_romfs_initialize();
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
serr("ERROR: Failed to mount romfs at %s: %d\n",
|
||||||
|
CONFIG_HC32_ROMFS_MOUNTPOINT, ret);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
printf("start %s\n", __func__);
|
printf("start %s\n", __func__);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
/****************************************************************************
|
||||||
|
* boards/arm/hc32/hc32f4a0/src/hc32_romfs.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Tomasz Wozniak. All rights reserved.
|
||||||
|
* Author: Tomasz Wozniak <t.wozniak@samsung.com>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __BOARDS_ARM_HC32_HC32F4A0_SRC_HC32_ROMFS_H
|
||||||
|
#define __BOARDS_ARM_HC32_HC32F4A0_SRC_HC32_ROMFS_H
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_HC32_ROMFS
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define ROMFS_SECTOR_SIZE 64
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: stm32_romfs_initialize
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Registers built-in ROMFS image as block device and mounts it.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) on success, a negated errno value on error.
|
||||||
|
*
|
||||||
|
* Assumptions/Limitations:
|
||||||
|
* Memory addresses [&romfs_data_begin .. &romfs_data_begin) should contain
|
||||||
|
* ROMFS volume data, as included in the assembly snippet above (l. 84).
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int hc32_romfs_initialize(void);
|
||||||
|
|
||||||
|
#endif /* CONFIG_STM32_ROMFS */
|
||||||
|
|
||||||
|
#endif /* __BOARDS_ARM_HC32_HC32F4A0_SRC_HC32_ROMFS_H */
|
|
@ -0,0 +1,158 @@
|
||||||
|
/****************************************************************************
|
||||||
|
* boards/arm/hc32/hc32f4a0/src/hc32_romfs_initialize.c
|
||||||
|
* This file provides contents of an optional ROMFS volume, mounted at boot.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Tomasz Wozniak. All rights reserved.
|
||||||
|
* Author: Tomasz Wozniak <t.wozniak@samsung.com>
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <sys/mount.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <debug.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <nuttx/fs/fs.h>
|
||||||
|
#include <nuttx/drivers/ramdisk.h>
|
||||||
|
#include "hc32_romfs.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef CONFIG_HC32_ROMFS
|
||||||
|
# error "CONFIG_HC32_ROMFS must be defined"
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifndef CONFIG_HC32_ROMFS_IMAGEFILE
|
||||||
|
# error "CONFIG_HC32_ROMFS_IMAGEFILE must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_HC32_ROMFS_DEV_MINOR
|
||||||
|
# error "CONFIG_HC32_ROMFS_DEV_MINOR must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_HC32_ROMFS_MOUNTPOINT
|
||||||
|
# error "CONFIG_HC32_ROMFS_MOUNTPOINT must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define NSECTORS(size) (((size) + ROMFS_SECTOR_SIZE - 1)/ROMFS_SECTOR_SIZE)
|
||||||
|
|
||||||
|
#define STR2(m) #m
|
||||||
|
#define STR(m) STR2(m)
|
||||||
|
|
||||||
|
#define MKMOUNT_DEVNAME(m) "/dev/ram" STR(m)
|
||||||
|
#define MOUNT_DEVNAME MKMOUNT_DEVNAME(CONFIG_HC32_ROMFS_DEV_MINOR)
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
__asm__ (
|
||||||
|
".section .rodata\n"
|
||||||
|
".balign 16\n"
|
||||||
|
".globl romfs_data_begin\n"
|
||||||
|
"romfs_data_begin:\n"
|
||||||
|
".incbin " STR(CONFIG_HC32_ROMFS_IMAGEFILE) "\n"\
|
||||||
|
\
|
||||||
|
".balign " STR(ROMFS_SECTOR_SIZE) "\n"
|
||||||
|
".globl romfs_data_end\n"
|
||||||
|
"romfs_data_end:\n"
|
||||||
|
".globl romfs_data_size\n"
|
||||||
|
"romfs_data_size:\n"
|
||||||
|
".word romfs_data_end - romfs_data_begin\n"
|
||||||
|
".previous\n");
|
||||||
|
|
||||||
|
extern const char romfs_data_begin;
|
||||||
|
extern const char romfs_data_end;
|
||||||
|
extern const int romfs_data_size;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: hc32_romfs_initialize
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Registers the aboveincluded binary file as block device.
|
||||||
|
* Then mounts the block device as ROMFS filesystems.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero (OK) on success, a negated errno value on error.
|
||||||
|
*
|
||||||
|
* Assumptions/Limitations:
|
||||||
|
* Memory addresses [&romfs_data_begin .. &romfs_data_begin) should contain
|
||||||
|
* ROMFS volume data, as included in the assembly snippet above (l. 84).
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int hc32_romfs_initialize(void)
|
||||||
|
{
|
||||||
|
uintptr_t romfs_data_len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Create a ROM disk for the /etc filesystem */
|
||||||
|
|
||||||
|
romfs_data_len = (uintptr_t)&romfs_data_end - (uintptr_t)&romfs_data_begin;
|
||||||
|
|
||||||
|
ret = romdisk_register(CONFIG_HC32_ROMFS_DEV_MINOR, &romfs_data_begin,
|
||||||
|
NSECTORS(romfs_data_len), ROMFS_SECTOR_SIZE);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
ferr("ERROR: romdisk_register failed: %d\n", -ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mount the file system */
|
||||||
|
|
||||||
|
finfo("Mounting ROMFS filesystem at target=%s with source=%s\n",
|
||||||
|
CONFIG_HC32_ROMFS_MOUNTPOINT, MOUNT_DEVNAME);
|
||||||
|
|
||||||
|
ret = nx_mount(MOUNT_DEVNAME, CONFIG_HC32_ROMFS_MOUNTPOINT,
|
||||||
|
"romfs", MS_RDONLY, NULL);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
ferr("ERROR: nx_mount(%s,%s,romfs) failed: %d\n",
|
||||||
|
MOUNT_DEVNAME, CONFIG_HC32_ROMFS_MOUNTPOINT, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_HC32_ROMFS */
|
|
@ -172,3 +172,26 @@ config HC32_UART8
|
||||||
|
|
||||||
endmenu # HC32 U[S]ART Selection
|
endmenu # HC32 U[S]ART Selection
|
||||||
|
|
||||||
|
config HC32_SPI1
|
||||||
|
bool "SPI1"
|
||||||
|
default n
|
||||||
|
select SPI
|
||||||
|
select HC32_SPI
|
||||||
|
|
||||||
|
config HC32_SPI2
|
||||||
|
bool "SPI2"
|
||||||
|
default n
|
||||||
|
depends on HC32_HAVE_SPI2
|
||||||
|
select SPI
|
||||||
|
select HC32_SPI
|
||||||
|
|
||||||
|
|
||||||
|
config HC32_SPI
|
||||||
|
bool
|
||||||
|
|
||||||
|
config HC32_I2C
|
||||||
|
bool
|
||||||
|
|
||||||
|
config HC32_CAN
|
||||||
|
bool
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,6 @@ CMN_ASRCS += arm_lazyexception.S
|
||||||
else
|
else
|
||||||
CMN_ASRCS += arm_exception.S
|
CMN_ASRCS += arm_exception.S
|
||||||
endif
|
endif
|
||||||
CMN_CSRCS += arm_vectors.c
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_ARCH_RAMVECTORS),y)
|
ifeq ($(CONFIG_ARCH_RAMVECTORS),y)
|
||||||
CMN_CSRCS += arm_ramvec_initialize.c arm_ramvec_attach.c
|
CMN_CSRCS += arm_ramvec_initialize.c arm_ramvec_attach.c
|
||||||
|
@ -77,12 +76,19 @@ ifeq ($(CONFIG_SCHED_THREAD_LOCAL),y)
|
||||||
CMN_CSRCS += arm_tls.c
|
CMN_CSRCS += arm_tls.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
CMN_CSRCS += hc32_vectors.c
|
||||||
|
|
||||||
CHIP_CSRCS = hc32_allocateheap.c hc32_gpio.c
|
CHIP_CSRCS = hc32_allocateheap.c hc32_gpio.c
|
||||||
CHIP_CSRCS += hc32_irq.c hc32_idle.c hc32_mpuinit.c
|
CHIP_CSRCS += hc32_irq.c hc32_idle.c hc32_mpuinit.c
|
||||||
CHIP_CSRCS += hc32_rcc.c hc32_start.c hc32_serial.c
|
CHIP_CSRCS += hc32_rcc.c hc32_start.c hc32_serial.c
|
||||||
CHIP_CSRCS += hc32_pm.c hc32_timerisr.c hc32_lowputc.c
|
CHIP_CSRCS += hc32_pm.c hc32_timerisr.c hc32_lowputc.c
|
||||||
|
CHIP_CSRCS += hc32_console.c
|
||||||
|
|
||||||
CHIP_CSRCS += hc32f4a0_clk.c hc32f4a0_efm.c hc32f4a0_gpio.c
|
CHIP_CSRCS += hc32f4a0_clk.c hc32f4a0_efm.c hc32f4a0_gpio.c
|
||||||
CHIP_CSRCS += hc32f4a0_interrupts.c hc32f4a0_usart.c hc32f4a0_utility.c
|
CHIP_CSRCS += hc32f4a0_interrupts.c hc32f4a0_usart.c hc32f4a0_utility.c
|
||||||
CHIP_CSRCS += hc32f4a0_sram.c hc32f4a0_pwc.c
|
CHIP_CSRCS += hc32f4a0_sram.c hc32f4a0_pwc.c
|
||||||
|
|
||||||
|
CHIP_CSRCS += hc32f4a0_spi.c
|
||||||
|
|
||||||
|
CHIP_CSRCS += hc32_spiflash.c hc32_spi.c
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ extern "C"
|
||||||
#define DDL_RTC_ENABLE (DDL_OFF)
|
#define DDL_RTC_ENABLE (DDL_OFF)
|
||||||
#define DDL_SDIOC_ENABLE (DDL_OFF)
|
#define DDL_SDIOC_ENABLE (DDL_OFF)
|
||||||
#define DDL_SMC_ENABLE (DDL_OFF)
|
#define DDL_SMC_ENABLE (DDL_OFF)
|
||||||
#define DDL_SPI_ENABLE (DDL_OFF)
|
#define DDL_SPI_ENABLE (DDL_ON)
|
||||||
#define DDL_SRAM_ENABLE (DDL_ON)
|
#define DDL_SRAM_ENABLE (DDL_ON)
|
||||||
#define DDL_SWDT_ENABLE (DDL_OFF)
|
#define DDL_SWDT_ENABLE (DDL_OFF)
|
||||||
#define DDL_TMR0_ENABLE (DDL_OFF)
|
#define DDL_TMR0_ENABLE (DDL_OFF)
|
||||||
|
@ -134,7 +134,7 @@ extern "C"
|
||||||
#define BSP_OV5640_ENABLE (BSP_OFF)
|
#define BSP_OV5640_ENABLE (BSP_OFF)
|
||||||
#define BSP_S29GL064N90TFI03_ENABLE (BSP_OFF)
|
#define BSP_S29GL064N90TFI03_ENABLE (BSP_OFF)
|
||||||
#define BSP_TCA9539_ENABLE (BSP_OFF)
|
#define BSP_TCA9539_ENABLE (BSP_OFF)
|
||||||
#define BSP_W25QXX_ENABLE (BSP_ON)
|
#define BSP_W25QXX_ENABLE (BSP_OFF)
|
||||||
#define BSP_WM8731_ENABLE (BSP_OFF)
|
#define BSP_WM8731_ENABLE (BSP_OFF)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -90,13 +90,13 @@
|
||||||
|
|
||||||
/* Set the end of system SRAM */
|
/* Set the end of system SRAM */
|
||||||
|
|
||||||
#define SRAM1_END 0x20073880
|
#define SRAM1_END 0x1FFF0000
|
||||||
|
|
||||||
|
|
||||||
/* Set the range of CCM SRAM as well (although we may not use it) */
|
/* Set the range of CCM SRAM as well (although we may not use it) */
|
||||||
|
|
||||||
#define SRAM2_START 0x1FE00000
|
#define SRAM2_START 0x1FFF0000
|
||||||
#define SRAM2_END 0x20073880
|
#define SRAM2_END 0x20070000
|
||||||
|
|
||||||
|
|
||||||
/* There are 4 possible SRAM configurations:
|
/* There are 4 possible SRAM configurations:
|
||||||
|
|
|
@ -37,6 +37,15 @@ extern "C"
|
||||||
#define HC32F4A0 1
|
#define HC32F4A0 1
|
||||||
#define USE_DDL_DRIVER 1
|
#define USE_DDL_DRIVER 1
|
||||||
|
|
||||||
|
#ifdef CONFIG_FS_PROCFS
|
||||||
|
# ifdef CONFIG_NSH_PROC_MOUNTPOINT
|
||||||
|
# define HC32_PROCFS_MOUNTPOINT CONFIG_NSH_PROC_MOUNTPOINT
|
||||||
|
# else
|
||||||
|
# define HC32_PROCFS_MOUNTPOINT "/proc"
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define getreg32(a) (*(volatile uint32_t *)(a))
|
#define getreg32(a) (*(volatile uint32_t *)(a))
|
||||||
#define putreg32(v,a) (*(volatile uint32_t *)(a) = (v))
|
#define putreg32(v,a) (*(volatile uint32_t *)(a) = (v))
|
||||||
#define getreg16(a) (*(volatile uint16_t *)(a))
|
#define getreg16(a) (*(volatile uint16_t *)(a))
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <arch/board/board.h>
|
||||||
|
#include "chip.h"
|
||||||
|
#include "hc32_uart.h"
|
||||||
|
#include "hc32_spi.h"
|
||||||
|
|
||||||
|
void hc32_test_console(void)
|
||||||
|
{
|
||||||
|
char *dev_str = "/dev/console";
|
||||||
|
char *test_chr = "test";
|
||||||
|
int fd = 0, ret;
|
||||||
|
|
||||||
|
fd = open(dev_str, 0x6);
|
||||||
|
hc32_print("%s: open <%s> ret = %d\n", __func__, dev_str, fd);
|
||||||
|
ret = write(fd, test_chr, strlen(test_chr));
|
||||||
|
hc32_print("%s: open %d ret %d\n", __func__, fd, ret);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hc32_console_handle(char *buf)
|
||||||
|
{
|
||||||
|
if(strncmp(buf, "console", 7) == 0)
|
||||||
|
{
|
||||||
|
hc32_test_console();
|
||||||
|
}
|
||||||
|
else if(strncmp(buf, "spi", 7) == 0)
|
||||||
|
{
|
||||||
|
hc32_print("start flash test ...\n");
|
||||||
|
hc32_spiflash_test();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
#ifndef __HC32_CONSOLE_H_
|
||||||
|
#define __HC32_CONSOLE_H_
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <nuttx/irq.h>
|
||||||
|
#include <nuttx/arch.h>
|
||||||
|
#include <nuttx/fs/ioctl.h>
|
||||||
|
#include <nuttx/serial/serial.h>
|
||||||
|
#include <nuttx/power/pm.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_SERIAL_TERMIOS
|
||||||
|
# include <termios.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <arch/board/board.h>
|
||||||
|
#include "chip.h"
|
||||||
|
#include "hc32_uart.h"
|
||||||
|
#include "hc32_rcc.h"
|
||||||
|
#include "hc32_gpio.h"
|
||||||
|
#include "arm_internal.h"
|
||||||
|
#include "hc32f4a0.h"
|
||||||
|
#include "hc32f4a0_usart.h"
|
||||||
|
#include "hc32f4a0_gpio.h"
|
||||||
|
#include "hc32f4a0_interrupts.h"
|
||||||
|
#include "hc32f4a0_sram.h"
|
||||||
|
#include "hc32f4a0_pwc.h"
|
||||||
|
#include "hc32f4a0_efm.h"
|
||||||
|
|
||||||
|
void hc32_console_handle(char *buf);
|
||||||
|
|
||||||
|
#endif
|
|
@ -119,7 +119,7 @@ void hc32_gpioinit(void)
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: hc32_configgpio (for the HC32F10xxx family)
|
* Name: hc32_configgpio (for the HC32F4A0)
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int hc32_configgpio(uint32_t cfgset)
|
int hc32_configgpio(uint32_t cfgset)
|
||||||
|
|
|
@ -152,6 +152,12 @@ static void up_idlepm(void)
|
||||||
|
|
||||||
void up_idle(void)
|
void up_idle(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#if defined (CONFIG_HC32F4A0_BOARD)
|
||||||
|
extern void hc32_uart_handle(void);
|
||||||
|
hc32_uart_handle();
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS)
|
#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS)
|
||||||
/* If the system is idle and there are no timer interrupts, then process
|
/* If the system is idle and there are no timer interrupts, then process
|
||||||
* "fake" timer interrupts. Hopefully, something will wake up.
|
* "fake" timer interrupts. Hopefully, something will wake up.
|
||||||
|
|
|
@ -37,34 +37,12 @@
|
||||||
#include "hc32_lowputc.h"
|
#include "hc32_lowputc.h"
|
||||||
#include "hc32f4a0_usart.h"
|
#include "hc32f4a0_usart.h"
|
||||||
#include "hc32_ddl.h"
|
#include "hc32_ddl.h"
|
||||||
|
#include "hc32_uart.h"
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* UART multiple processor ID definition */
|
|
||||||
#define UART_MASTER_STATION_ID (0x20U)
|
|
||||||
#define UART_SLAVE_STATION_ID (0x21U)
|
|
||||||
|
|
||||||
/* Ring buffer size */
|
|
||||||
#define IS_RING_BUFFER_EMPTY(x) (0U == ((x)->u16UsedSize))
|
|
||||||
|
|
||||||
/* Multi-processor silence mode */
|
|
||||||
#define LP_UART_NORMAL_MODE (0U)
|
|
||||||
#define LP_UART_SILENCE_MODE (1U)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Ring buffer structure definition
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t u16Capacity;
|
|
||||||
__IO uint16_t u16UsedSize;
|
|
||||||
uint16_t u16InIdx;
|
|
||||||
uint16_t u16OutIdx;
|
|
||||||
uint8_t au8Buf[50];
|
|
||||||
} stc_ring_buffer_t;
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -81,212 +59,10 @@ typedef struct
|
||||||
* Private Data
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static uint8_t m_u8UartSilenceMode = LP_UART_NORMAL_MODE;
|
|
||||||
|
|
||||||
static stc_ring_buffer_t m_stcRingBuf = {
|
|
||||||
.u16InIdx = 0U,
|
|
||||||
.u16OutIdx = 0U,
|
|
||||||
.u16UsedSize = 0U,
|
|
||||||
.u16Capacity = sizeof (m_stcRingBuf.au8Buf),
|
|
||||||
};
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set silence mode.
|
|
||||||
* @param [in] u8Mode Silence mode
|
|
||||||
* This parameter can be one of the following values:
|
|
||||||
* @arg LP_UART_SILENCE_MODE: UART silence mode
|
|
||||||
* @arg LP_UART_NORMAL_MODE: UART normal mode
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void UsartSetSilenceMode(uint8_t u8Mode)
|
|
||||||
{
|
|
||||||
m_u8UartSilenceMode = u8Mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get silence mode.
|
|
||||||
* @param [in] None
|
|
||||||
* @retval Returned value can be one of the following values:
|
|
||||||
* @arg LP_UART_SILENCE_MODE: UART silence mode
|
|
||||||
* @arg LP_UART_NORMAL_MODE: UART normal mode
|
|
||||||
*/
|
|
||||||
static uint8_t UsartGetSilenceMode(void)
|
|
||||||
{
|
|
||||||
return m_u8UartSilenceMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Instal IRQ handler.
|
|
||||||
* @param [in] pstcConfig Pointer to struct @ref stc_irq_signin_config_t
|
|
||||||
* @param [in] u32Priority Interrupt priority
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void InstalIrqHandler(const stc_irq_signin_config_t *pstcConfig,
|
|
||||||
uint32_t u32Priority)
|
|
||||||
{
|
|
||||||
if (NULL != pstcConfig)
|
|
||||||
{
|
|
||||||
(void)INTC_IrqSignIn(pstcConfig);
|
|
||||||
NVIC_ClearPendingIRQ(pstcConfig->enIRQn);
|
|
||||||
NVIC_SetPriority(pstcConfig->enIRQn, u32Priority);
|
|
||||||
NVIC_EnableIRQ(pstcConfig->enIRQn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Write ring buffer.
|
|
||||||
* @param [in] pstcBuffer Pointer to a @ref stc_ring_buffer_t structure
|
|
||||||
* @param [in] pu8Data Pointer to data buffer to read
|
|
||||||
* @retval An en_result_t enumeration value:
|
|
||||||
* - Ok: Write success.
|
|
||||||
* - ErrorNotReady: Buffer is empty.
|
|
||||||
*/
|
|
||||||
static en_result_t RingBufRead(stc_ring_buffer_t *pstcBuffer, uint8_t *pu8Data)
|
|
||||||
{
|
|
||||||
en_result_t enRet = Ok;
|
|
||||||
|
|
||||||
if (pstcBuffer->u16UsedSize == 0U)
|
|
||||||
{
|
|
||||||
enRet = ErrorNotReady;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*pu8Data = pstcBuffer->au8Buf[pstcBuffer->u16OutIdx++];
|
|
||||||
pstcBuffer->u16OutIdx %= pstcBuffer->u16Capacity;
|
|
||||||
pstcBuffer->u16UsedSize--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return enRet;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief UART TX Empty IRQ callback.
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void USART_TxEmpty_IrqCallback(void)
|
|
||||||
{
|
|
||||||
uint8_t u8Data = 0U;
|
|
||||||
en_flag_status_t enFlag = USART_GetStatus(LP_UNIT, USART_FLAG_TXE);
|
|
||||||
en_functional_state_t enState = USART_GetFuncState(LP_UNIT, USART_INT_TXE);
|
|
||||||
|
|
||||||
if ((Set == enFlag) && (Enable == enState))
|
|
||||||
{
|
|
||||||
USART_SendId(LP_UNIT, UART_SLAVE_STATION_ID);
|
|
||||||
|
|
||||||
while (Reset == USART_GetStatus(LP_UNIT, USART_FLAG_TC)) /* Wait Tx data register empty */
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Ok == RingBufRead(&m_stcRingBuf, &u8Data))
|
|
||||||
{
|
|
||||||
USART_SendData(LP_UNIT, (uint16_t)u8Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IS_RING_BUFFER_EMPTY(&m_stcRingBuf))
|
|
||||||
{
|
|
||||||
USART_FuncCmd(LP_UNIT, USART_INT_TXE, Disable);
|
|
||||||
USART_FuncCmd(LP_UNIT, USART_INT_TC, Enable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief UART TX Complete IRQ callback.
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void USART_TxComplete_IrqCallback(void)
|
|
||||||
{
|
|
||||||
en_flag_status_t enFlag = USART_GetStatus(LP_UNIT, USART_FLAG_TC);
|
|
||||||
en_functional_state_t enState = USART_GetFuncState(LP_UNIT, USART_INT_TC);
|
|
||||||
|
|
||||||
if ((Set == enFlag) && (Enable == enState))
|
|
||||||
{
|
|
||||||
/* Disable TX function */
|
|
||||||
USART_FuncCmd(LP_UNIT, (USART_TX | USART_RX | USART_INT_TC), Disable);
|
|
||||||
|
|
||||||
/* Enable RX function */
|
|
||||||
USART_FuncCmd(LP_UNIT, (USART_RX | USART_INT_RX), Enable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Write ring buffer.
|
|
||||||
* @param [in] pstcBuffer Pointer to a @ref stc_ring_buffer_t structure
|
|
||||||
* @param [in] u8Data Data to write
|
|
||||||
* @retval An en_result_t enumeration value:
|
|
||||||
* - Ok: Write success.
|
|
||||||
* - ErrorBufferFull: Buffer is full.
|
|
||||||
*/
|
|
||||||
static en_result_t write_ring_buf(stc_ring_buffer_t *pstcBuffer, uint8_t u8Data)
|
|
||||||
{
|
|
||||||
en_result_t enRet = Ok;
|
|
||||||
|
|
||||||
if (pstcBuffer->u16UsedSize >= pstcBuffer->u16Capacity)
|
|
||||||
{
|
|
||||||
enRet = ErrorBufferFull;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pstcBuffer->au8Buf[pstcBuffer->u16InIdx++] = u8Data;
|
|
||||||
pstcBuffer->u16InIdx %= pstcBuffer->u16Capacity;
|
|
||||||
pstcBuffer->u16UsedSize++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return enRet;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief UART RX IRQ callback.
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void USART_Rx_IrqCallback(void)
|
|
||||||
{
|
|
||||||
uint8_t u8RxData;
|
|
||||||
en_flag_status_t enFlag = USART_GetStatus(LP_UNIT, USART_FLAG_RXNE);
|
|
||||||
en_functional_state_t enState = USART_GetFuncState(LP_UNIT, USART_INT_RX);
|
|
||||||
|
|
||||||
if ((Set == enFlag) && (Enable == enState))
|
|
||||||
{
|
|
||||||
u8RxData = (uint8_t)USART_RecData(LP_UNIT);
|
|
||||||
|
|
||||||
if ((Reset == USART_GetStatus(LP_UNIT, USART_FLAG_MPB)) &&
|
|
||||||
(LP_UART_NORMAL_MODE == UsartGetSilenceMode()))
|
|
||||||
{
|
|
||||||
write_ring_buf(&m_stcRingBuf, u8RxData);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (UART_MASTER_STATION_ID != u8RxData)
|
|
||||||
{
|
|
||||||
USART_SilenceCmd(LP_UNIT, Enable);
|
|
||||||
UsartSetSilenceMode(LP_UART_SILENCE_MODE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UsartSetSilenceMode(LP_UART_NORMAL_MODE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief UART RX Error IRQ callback.
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void USART_RxErr_IrqCallback(void)
|
|
||||||
{
|
|
||||||
USART_ClearStatus(LP_UNIT, (USART_CLEAR_FLAG_FE | USART_CLEAR_FLAG_PE | USART_CLEAR_FLAG_ORE));
|
|
||||||
}
|
|
||||||
|
|
||||||
void hc32_unlock(void)
|
void hc32_unlock(void)
|
||||||
{
|
{
|
||||||
/* Unlock GPIO register: PSPCR, PCCR, PINAER, PCRxy, PFSRxy */
|
/* Unlock GPIO register: PSPCR, PCCR, PINAER, PCRxy, PFSRxy */
|
||||||
|
@ -342,30 +118,19 @@ void hc32_print_portinit(void)
|
||||||
|
|
||||||
void arm_lowputc(char ch)
|
void arm_lowputc(char ch)
|
||||||
{
|
{
|
||||||
while(Set != USART_GetStatus(LP_UNIT, USART_FLAG_TXE));
|
while(Set != USART_GetStatus(DBG_UNIT, USART_FLAG_TXE));
|
||||||
USART_SendData(LP_UNIT, ch);
|
USART_SendData(DBG_UNIT, ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: hc32_lowsetup
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This performs basic initialization of the USART used for the serial
|
|
||||||
* console. Its purpose is to get the console output available as soon
|
|
||||||
* as possible.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
void hc32_lowsetup(void)
|
void hc32_lowsetup(void)
|
||||||
{
|
{
|
||||||
stc_irq_signin_config_t stcIrqSigninCfg;
|
const stc_usart_uart_init_t stcUartInit = {
|
||||||
const stc_usart_multiprocessor_init_t stcUartMultiProcessorInit = {
|
.u32Baudrate = BSP_PRINTF_BAUDRATE,
|
||||||
.u32Baudrate = 115200UL,
|
|
||||||
.u32BitDirection = USART_LSB,
|
.u32BitDirection = USART_LSB,
|
||||||
.u32StopBit = USART_STOPBIT_1BIT,
|
.u32StopBit = USART_STOPBIT_1BIT,
|
||||||
|
.u32Parity = USART_PARITY_NONE,
|
||||||
.u32DataWidth = USART_DATA_LENGTH_8BIT,
|
.u32DataWidth = USART_DATA_LENGTH_8BIT,
|
||||||
.u32ClkMode = USART_INTERNCLK_NONE_OUTPUT,
|
.u32ClkMode = USART_INTERNCLK_OUTPUT,
|
||||||
.u32PclkDiv = USART_PCLK_DIV64,
|
.u32PclkDiv = USART_PCLK_DIV64,
|
||||||
.u32OversamplingBits = USART_OVERSAMPLING_8BIT,
|
.u32OversamplingBits = USART_OVERSAMPLING_8BIT,
|
||||||
.u32NoiseFilterState = USART_NOISE_FILTER_DISABLE,
|
.u32NoiseFilterState = USART_NOISE_FILTER_DISABLE,
|
||||||
|
@ -380,42 +145,18 @@ void hc32_lowsetup(void)
|
||||||
DDL_PrintfInit(BSP_PRINTF_DEVICE, BSP_PRINTF_BAUDRATE, hc32_print_portinit);
|
DDL_PrintfInit(BSP_PRINTF_DEVICE, BSP_PRINTF_BAUDRATE, hc32_print_portinit);
|
||||||
|
|
||||||
/* Configure USART RX/TX pin. */
|
/* Configure USART RX/TX pin. */
|
||||||
GPIO_SetFunc(LP_RX_PORT, LP_RX_PIN, LP_RX_GPIO_FUNC, PIN_SUBFUNC_DISABLE);
|
GPIO_SetFunc(DBG_RX_PORT, DBG_RX_PIN, DBG_RX_GPIO_FUNC, PIN_SUBFUNC_DISABLE);
|
||||||
GPIO_SetFunc(LP_TX_PORT, LP_TX_PIN, LP_TX_GPIO_FUNC, PIN_SUBFUNC_DISABLE);
|
GPIO_SetFunc(DBG_TX_PORT, DBG_TX_PIN, DBG_TX_GPIO_FUNC, PIN_SUBFUNC_DISABLE);
|
||||||
|
|
||||||
hc32_lock();
|
hc32_lock();
|
||||||
|
|
||||||
/* Enable peripheral clock */
|
/* Enable peripheral clock */
|
||||||
PWC_Fcg3PeriphClockCmd(LP_FUNCTION_CLK_GATE, Enable);
|
PWC_Fcg3PeriphClockCmd(DBG_FUNCTION_CLK_GATE, Enable);
|
||||||
|
|
||||||
/* Set silence mode */
|
|
||||||
UsartSetSilenceMode(LP_UART_SILENCE_MODE);
|
|
||||||
|
|
||||||
/* Initialize UART function. */
|
/* Initialize UART function. */
|
||||||
(void)USART_MultiProcessorInit(LP_UNIT, &stcUartMultiProcessorInit);
|
if (Ok != USART_UartInit(DBG_UNIT, &stcUartInit))
|
||||||
|
{
|
||||||
/* Register error IRQ handler && configure NVIC. */
|
for (;;);
|
||||||
stcIrqSigninCfg.enIRQn = LP_UNIT_ERR_INT_IRQn;
|
}
|
||||||
stcIrqSigninCfg.enIntSrc = LP_UNIT_ERR_INT_SRC;
|
|
||||||
stcIrqSigninCfg.pfnCallback = &USART_RxErr_IrqCallback;
|
|
||||||
InstalIrqHandler(&stcIrqSigninCfg, DDL_IRQ_PRIORITY_DEFAULT);
|
|
||||||
|
|
||||||
/* Register RX IRQ handler && configure NVIC. */
|
|
||||||
stcIrqSigninCfg.enIRQn = LP_UNIT_RX_INT_IRQn;
|
|
||||||
stcIrqSigninCfg.enIntSrc = LP_UNIT_RX_INT_SRC;
|
|
||||||
stcIrqSigninCfg.pfnCallback = &USART_Rx_IrqCallback;
|
|
||||||
InstalIrqHandler(&stcIrqSigninCfg, DDL_IRQ_PRIORITY_00);
|
|
||||||
|
|
||||||
/* Register TX IRQ handler && configure NVIC. */
|
|
||||||
stcIrqSigninCfg.enIRQn = LP_UNIT_TX_INT_IRQn;
|
|
||||||
stcIrqSigninCfg.enIntSrc = LP_UNIT_TX_INT_SRC;
|
|
||||||
stcIrqSigninCfg.pfnCallback = &USART_TxEmpty_IrqCallback;
|
|
||||||
InstalIrqHandler(&stcIrqSigninCfg, DDL_IRQ_PRIORITY_DEFAULT);
|
|
||||||
|
|
||||||
/* Register TC IRQ handler && configure NVIC. */
|
|
||||||
stcIrqSigninCfg.enIRQn = LP_UNIT_TCI_INT_IRQn;
|
|
||||||
stcIrqSigninCfg.enIntSrc = LP_UNIT_TCI_INT_SRC;
|
|
||||||
stcIrqSigninCfg.pfnCallback = &USART_TxComplete_IrqCallback;
|
|
||||||
InstalIrqHandler(&stcIrqSigninCfg, DDL_IRQ_PRIORITY_DEFAULT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
189
Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_spi.c
Executable file
|
@ -0,0 +1,189 @@
|
||||||
|
/**
|
||||||
|
*******************************************************************************
|
||||||
|
* @file arch/arm/src/hc32/hc32_spi.c
|
||||||
|
* @brief SPI write read flash API for the Device Driver Library.
|
||||||
|
@verbatim
|
||||||
|
Change Logs:
|
||||||
|
Date Author Notes
|
||||||
|
2020-06-12 Wangmin First version
|
||||||
|
2020-10-13 Wangmin Modify spelling mistake
|
||||||
|
@endverbatim
|
||||||
|
*******************************************************************************
|
||||||
|
* Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software component is licensed by HDSC under BSD 3-Clause license
|
||||||
|
* (the "License"); You may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at:
|
||||||
|
* opensource.org/licenses/BSD-3-Clause
|
||||||
|
*
|
||||||
|
*******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Include files
|
||||||
|
******************************************************************************/
|
||||||
|
#include "hc32_ddl.h"
|
||||||
|
#include "hc32_spi.h"
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Local type definitions ('typedef')
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Local pre-processor symbols/macros ('#define')
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Global variable definitions (declared in header file with 'extern')
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Local function prototypes ('static')
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Local variable definitions ('static')
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Function implementation - global ('extern') and local ('static')
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief MCU Peripheral registers write unprotected.
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
* @note Comment/uncomment each API depending on APP requires.
|
||||||
|
*/
|
||||||
|
static void Peripheral_WE(void)
|
||||||
|
{
|
||||||
|
/* Unlock GPIO register: PSPCR, PCCR, PINAER, PCRxy, PFSRxy */
|
||||||
|
GPIO_Unlock();
|
||||||
|
/* Unlock PWC register: FCG0 */
|
||||||
|
PWC_FCG0_Unlock();
|
||||||
|
/* Unlock PWC, CLK, PVD registers, @ref PWC_REG_Write_Unlock_Code for details */
|
||||||
|
PWC_Unlock(PWC_UNLOCK_CODE_0 | PWC_UNLOCK_CODE_1 | PWC_UNLOCK_CODE_2);
|
||||||
|
/* Unlock SRAM register: WTCR */
|
||||||
|
SRAM_WTCR_Unlock();
|
||||||
|
/* Unlock SRAM register: CKCR */
|
||||||
|
//SRAM_CKCR_Unlock();
|
||||||
|
/* Unlock all EFM registers */
|
||||||
|
EFM_Unlock();
|
||||||
|
/* Unlock EFM register: FWMC */
|
||||||
|
//EFM_FWMC_Unlock();
|
||||||
|
/* Unlock EFM OTP write protect registers */
|
||||||
|
//EFM_OTP_WP_Unlock();
|
||||||
|
/* Unlock all MPU registers */
|
||||||
|
// MPU_Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief MCU Peripheral registers write protected.
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
* @note Comment/uncomment each API depending on APP requires.
|
||||||
|
*/
|
||||||
|
static __attribute__((unused)) void Peripheral_WP(void)
|
||||||
|
{
|
||||||
|
/* Lock GPIO register: PSPCR, PCCR, PINAER, PCRxy, PFSRxy */
|
||||||
|
GPIO_Lock();
|
||||||
|
/* Lock PWC register: FCG0 */
|
||||||
|
PWC_FCG0_Lock();
|
||||||
|
/* Lock PWC, CLK, PVD registers, @ref PWC_REG_Write_Unlock_Code for details */
|
||||||
|
PWC_Lock(PWC_UNLOCK_CODE_0 | PWC_UNLOCK_CODE_1 | PWC_UNLOCK_CODE_2);
|
||||||
|
/* Lock SRAM register: WTCR */
|
||||||
|
SRAM_WTCR_Lock();
|
||||||
|
/* Lock SRAM register: CKCR */
|
||||||
|
//SRAM_CKCR_Lock();
|
||||||
|
/* Lock EFM OTP write protect registers */
|
||||||
|
//EFM_OTP_WP_Lock();
|
||||||
|
/* Lock EFM register: FWMC */
|
||||||
|
//EFM_FWMC_Lock();
|
||||||
|
/* Lock all EFM registers */
|
||||||
|
EFM_Lock();
|
||||||
|
/* Lock all MPU registers */
|
||||||
|
// MPU_Lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configure SPI peripheral function
|
||||||
|
*
|
||||||
|
* @param [in] None
|
||||||
|
*
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
static void Spi_Config(void)
|
||||||
|
{
|
||||||
|
stc_spi_init_t stcSpiInit;
|
||||||
|
stc_spi_delay_t stcSpiDelayCfg;
|
||||||
|
|
||||||
|
/* Clear initialize structure */
|
||||||
|
(void)SPI_StructInit(&stcSpiInit);
|
||||||
|
(void)SPI_DelayStructInit(&stcSpiDelayCfg);
|
||||||
|
|
||||||
|
/* Configure peripheral clock */
|
||||||
|
PWC_Fcg1PeriphClockCmd(SPI_UNIT_CLOCK, Enable);
|
||||||
|
|
||||||
|
/* SPI De-initialize */
|
||||||
|
SPI_DeInit(SPI_UNIT);
|
||||||
|
|
||||||
|
/* Configuration SPI structure */
|
||||||
|
stcSpiInit.u32WireMode = SPI_WIRE_3;
|
||||||
|
stcSpiInit.u32TransMode = SPI_FULL_DUPLEX;
|
||||||
|
stcSpiInit.u32MasterSlave = SPI_MASTER;
|
||||||
|
stcSpiInit.u32SuspMode = SPI_COM_SUSP_FUNC_OFF;
|
||||||
|
stcSpiInit.u32Modfe = SPI_MODFE_DISABLE;
|
||||||
|
stcSpiInit.u32Parity = SPI_PARITY_INVALID;
|
||||||
|
stcSpiInit.u32SpiMode = SPI_MODE_0;
|
||||||
|
stcSpiInit.u32BaudRatePrescaler = SPI_BR_PCLK1_DIV256;
|
||||||
|
stcSpiInit.u32DataBits = SPI_DATA_SIZE_8BIT;
|
||||||
|
stcSpiInit.u32FirstBit = SPI_FIRST_MSB;
|
||||||
|
(void)SPI_Init(SPI_UNIT, &stcSpiInit);
|
||||||
|
|
||||||
|
stcSpiDelayCfg.u32IntervalDelay = SPI_INTERVAL_TIME_8SCK_2PCLK1;
|
||||||
|
stcSpiDelayCfg.u32ReleaseDelay = SPI_RELEASE_TIME_8SCK;
|
||||||
|
stcSpiDelayCfg.u32SetupDelay = SPI_SETUP_TIME_1SCK;
|
||||||
|
(void)SPI_DelayTimeCfg(SPI_UNIT, &stcSpiDelayCfg);
|
||||||
|
|
||||||
|
SPI_FunctionCmd(SPI_UNIT, Enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int hc32_spi_init(void)
|
||||||
|
{
|
||||||
|
stc_gpio_init_t stcGpioCfg;
|
||||||
|
|
||||||
|
Peripheral_WE();
|
||||||
|
|
||||||
|
/* Port configurate */
|
||||||
|
(void)GPIO_StructInit(&stcGpioCfg);
|
||||||
|
|
||||||
|
/* High driving capacity for output pin. */
|
||||||
|
stcGpioCfg.u16PinDir = PIN_DIR_OUT;
|
||||||
|
stcGpioCfg.u16PinDrv = PIN_DRV_HIGH;
|
||||||
|
stcGpioCfg.u16PinState = PIN_STATE_SET;
|
||||||
|
(void)GPIO_Init(SPI_NSS_PORT, SPI_NSS_PIN, &stcGpioCfg);
|
||||||
|
|
||||||
|
(void)GPIO_StructInit(&stcGpioCfg);
|
||||||
|
stcGpioCfg.u16PinDrv = PIN_DRV_HIGH;
|
||||||
|
(void)GPIO_Init(SPI_SCK_PORT, SPI_SCK_PIN, &stcGpioCfg);
|
||||||
|
(void)GPIO_Init(SPI_MOSI_PORT, SPI_MOSI_PIN, &stcGpioCfg);
|
||||||
|
|
||||||
|
/* CMOS input for input pin */
|
||||||
|
stcGpioCfg.u16PinDrv = PIN_DRV_LOW;
|
||||||
|
stcGpioCfg.u16PinIType = PIN_ITYPE_CMOS;
|
||||||
|
(void)GPIO_Init(SPI_MISO_PORT, SPI_MISO_PIN, &stcGpioCfg);
|
||||||
|
|
||||||
|
/* Configure SPI Port function for master */
|
||||||
|
GPIO_SetFunc(SPI_SCK_PORT, SPI_SCK_PIN, SPI_SCK_FUNC, PIN_SUBFUNC_DISABLE);
|
||||||
|
GPIO_SetFunc(SPI_MOSI_PORT, SPI_MOSI_PIN, SPI_MOSI_FUNC, PIN_SUBFUNC_DISABLE);
|
||||||
|
GPIO_SetFunc(SPI_MISO_PORT, SPI_MISO_PIN, SPI_MISO_FUNC, PIN_SUBFUNC_DISABLE);
|
||||||
|
|
||||||
|
/* Configure SPI for SPI flash */
|
||||||
|
Spi_Config();
|
||||||
|
|
||||||
|
Peripheral_WP();
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
/**
|
||||||
|
*******************************************************************************
|
||||||
|
* @file arch/arm/src/hc32/hc32_spi.h
|
||||||
|
* @brief SPI write read flash API for the Device Driver Library.
|
||||||
|
@verbatim
|
||||||
|
Change Logs:
|
||||||
|
Date Author Notes
|
||||||
|
2020-06-12 Wangmin First version
|
||||||
|
2020-10-13 Wangmin Modify spelling mistake
|
||||||
|
@endverbatim
|
||||||
|
*******************************************************************************
|
||||||
|
* Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software component is licensed by HDSC under BSD 3-Clause license
|
||||||
|
* (the "License"); You may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at:
|
||||||
|
* opensource.org/licenses/BSD-3-Clause
|
||||||
|
*
|
||||||
|
*******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Include files
|
||||||
|
******************************************************************************/
|
||||||
|
#include "hc32_ddl.h"
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Local type definitions ('typedef')
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Local pre-processor symbols/macros ('#define')
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/* SPI unit and clock definition */
|
||||||
|
#define SPI_UNIT (M4_SPI1)
|
||||||
|
#define SPI_UNIT_CLOCK (PWC_FCG1_SPI1)
|
||||||
|
|
||||||
|
/* SPI port definition for master */
|
||||||
|
#define SPI_NSS_PORT (GPIO_PORT_C)
|
||||||
|
#define SPI_NSS_PIN (GPIO_PIN_07)
|
||||||
|
|
||||||
|
#define SPI_SCK_PORT (GPIO_PORT_C)
|
||||||
|
#define SPI_SCK_PIN (GPIO_PIN_06)
|
||||||
|
#define SPI_SCK_FUNC (GPIO_FUNC_40_SPI1_SCK)
|
||||||
|
|
||||||
|
#define SPI_MOSI_PORT (GPIO_PORT_D)
|
||||||
|
#define SPI_MOSI_PIN (GPIO_PIN_08)
|
||||||
|
#define SPI_MOSI_FUNC (GPIO_FUNC_41_SPI1_MOSI)
|
||||||
|
|
||||||
|
#define SPI_MISO_PORT (GPIO_PORT_D)
|
||||||
|
#define SPI_MISO_PIN (GPIO_PIN_09)
|
||||||
|
#define SPI_MISO_FUNC (GPIO_FUNC_42_SPI1_MISO)
|
||||||
|
|
||||||
|
/* NSS pin control */
|
||||||
|
#define SPI_NSS_HIGH() (GPIO_SetPins(SPI_NSS_PORT, SPI_NSS_PIN))
|
||||||
|
#define SPI_NSS_LOW() (GPIO_ResetPins(SPI_NSS_PORT, SPI_NSS_PIN))
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Global variable definitions (declared in header file with 'extern')
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Local function prototypes ('static')
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Local variable definitions ('static')
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Function implementation - global ('extern') and local ('static')
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
int hc32_spi_init(void);
|
||||||
|
void hc32_spiflash_test(void);
|
||||||
|
|
|
@ -0,0 +1,350 @@
|
||||||
|
/**
|
||||||
|
*******************************************************************************
|
||||||
|
* @file arch/arm/src/hc32/hc32_spiflash.c
|
||||||
|
* @brief SPI write read flash API for the Device Driver Library.
|
||||||
|
@verbatim
|
||||||
|
Change Logs:
|
||||||
|
Date Author Notes
|
||||||
|
2020-06-12 Wangmin First version
|
||||||
|
2020-10-13 Wangmin Modify spelling mistake
|
||||||
|
@endverbatim
|
||||||
|
*******************************************************************************
|
||||||
|
* Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software component is licensed by HDSC under BSD 3-Clause license
|
||||||
|
* (the "License"); You may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at:
|
||||||
|
* opensource.org/licenses/BSD-3-Clause
|
||||||
|
*
|
||||||
|
*******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Include files
|
||||||
|
******************************************************************************/
|
||||||
|
#include "hc32_ddl.h"
|
||||||
|
#include "hc32_spi.h"
|
||||||
|
#include "hc32_uart.h"
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Local type definitions ('typedef')
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Local pre-processor symbols/macros ('#define')
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/* FLASH parameters */
|
||||||
|
#define FLASH_PAGE_SIZE (0x100U)
|
||||||
|
#define FLASH_SECTOR_SIZE (0x1000U)
|
||||||
|
#define FLASH_MAX_ADDR (0x800000UL)
|
||||||
|
#define FLASH_DUMMY_BYTE_VALUE (0xffU)
|
||||||
|
#define FLASH_BUSY_BIT_MASK (0x01U)
|
||||||
|
|
||||||
|
/* FLASH instruction */
|
||||||
|
#define FLASH_INSTR_WRITE_ENABLE (0x06U)
|
||||||
|
#define FLASH_INSTR_PAGE_PROGRAM (0x02U)
|
||||||
|
#define FLASH_INSTR_STANDARD_READ (0x03U)
|
||||||
|
#define FLASH_INSTR_ERASE_4KB_SECTOR (0x20U)
|
||||||
|
#define FLASH_INSTR_READ_SR1 (0x05U)
|
||||||
|
#define FLASH_READ_MANUFACTURER_ID (0x90U)
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Global variable definitions (declared in header file with 'extern')
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Local function prototypes ('static')
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Local variable definitions ('static')
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Function implementation - global ('extern') and local ('static')
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SPI flash write byte function
|
||||||
|
*
|
||||||
|
* @param [in] u8Data SPI write data to flash
|
||||||
|
*
|
||||||
|
* @retval uint8_t SPI receive data from flash
|
||||||
|
*/
|
||||||
|
static uint8_t SpiFlash_WriteReadByte(uint8_t u8Data)
|
||||||
|
{
|
||||||
|
uint8_t u8Byte;
|
||||||
|
|
||||||
|
/* Wait tx buffer empty */
|
||||||
|
while (Reset == SPI_GetStatus(SPI_UNIT, SPI_FLAG_TX_BUFFER_EMPTY))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
/* Send data */
|
||||||
|
SPI_WriteDataReg(SPI_UNIT, (uint32_t)u8Data);
|
||||||
|
|
||||||
|
/* Wait rx buffer full */
|
||||||
|
while (Reset == SPI_GetStatus(SPI_UNIT, SPI_FLAG_RX_BUFFER_FULL))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
/* Receive data */
|
||||||
|
u8Byte = (uint8_t)SPI_ReadDataReg(SPI_UNIT);
|
||||||
|
|
||||||
|
return u8Byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SPI flash write enable function
|
||||||
|
*
|
||||||
|
* @param [in] None
|
||||||
|
*
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
static void SpiFlash_WriteEnable(void)
|
||||||
|
{
|
||||||
|
SPI_NSS_LOW();
|
||||||
|
(void)SpiFlash_WriteReadByte(FLASH_INSTR_WRITE_ENABLE);
|
||||||
|
SPI_NSS_HIGH();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SPI flash wait for write operation end function
|
||||||
|
*
|
||||||
|
* @param [in] None
|
||||||
|
*
|
||||||
|
* @retval Ok Flash internal operation finish
|
||||||
|
* @retval ErrorTimeout Flash internal operation timeout
|
||||||
|
*/
|
||||||
|
static en_result_t SpiFlash_WaitForWriteEnd(void)
|
||||||
|
{
|
||||||
|
en_result_t enRet = Ok;
|
||||||
|
uint8_t u8Status;
|
||||||
|
uint32_t u32Timeout;
|
||||||
|
stc_clk_freq_t stcClkFreq;
|
||||||
|
|
||||||
|
(void)CLK_GetClockFreq(&stcClkFreq);
|
||||||
|
u32Timeout = stcClkFreq.sysclkFreq / 1000U;
|
||||||
|
SPI_NSS_LOW();
|
||||||
|
(void)SpiFlash_WriteReadByte(FLASH_INSTR_READ_SR1);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
u8Status = SpiFlash_WriteReadByte(FLASH_DUMMY_BYTE_VALUE);
|
||||||
|
u32Timeout--;
|
||||||
|
} while ((u32Timeout != 0UL) &&
|
||||||
|
((u8Status & FLASH_BUSY_BIT_MASK) == FLASH_BUSY_BIT_MASK));
|
||||||
|
|
||||||
|
if (FLASH_BUSY_BIT_MASK == u8Status)
|
||||||
|
{
|
||||||
|
enRet = ErrorTimeout;
|
||||||
|
}
|
||||||
|
SPI_NSS_HIGH();
|
||||||
|
|
||||||
|
return enRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SPI flash page write program function
|
||||||
|
*
|
||||||
|
* @param [in] u32Addr Valid flash address
|
||||||
|
* @param [in] pData Pointer to send data buffer
|
||||||
|
* @param [in] len Send data length
|
||||||
|
*
|
||||||
|
* @retval Error Page write program failed
|
||||||
|
* @retval Ok Page write program success
|
||||||
|
*/
|
||||||
|
static en_result_t SpiFlash_WritePage(uint32_t u32Addr, const uint8_t pData[], uint16_t len)
|
||||||
|
{
|
||||||
|
en_result_t enRet;
|
||||||
|
uint16_t u16Index = 0U;
|
||||||
|
|
||||||
|
if ((u32Addr > FLASH_MAX_ADDR) || (NULL == pData) || (len > FLASH_PAGE_SIZE))
|
||||||
|
{
|
||||||
|
enRet = Error;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SpiFlash_WriteEnable();
|
||||||
|
/* Send data to flash */
|
||||||
|
SPI_NSS_LOW();
|
||||||
|
(void)SpiFlash_WriteReadByte(FLASH_INSTR_PAGE_PROGRAM);
|
||||||
|
(void)SpiFlash_WriteReadByte((uint8_t)((u32Addr & 0xFF0000UL) >> 16U));
|
||||||
|
(void)SpiFlash_WriteReadByte((uint8_t)((u32Addr & 0xFF00U) >> 8U));
|
||||||
|
(void)SpiFlash_WriteReadByte((uint8_t)(u32Addr & 0xFFU));
|
||||||
|
while (0U != (len--))
|
||||||
|
{
|
||||||
|
(void)SpiFlash_WriteReadByte(pData[u16Index]);
|
||||||
|
u16Index++;
|
||||||
|
}
|
||||||
|
SPI_NSS_HIGH();
|
||||||
|
/* Wait for flash idle */
|
||||||
|
enRet = SpiFlash_WaitForWriteEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
return enRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SPI flash read data function
|
||||||
|
*
|
||||||
|
* @param [in] u32Addr Valid flash address
|
||||||
|
* @param [out] pData Pointer to receive data buffer
|
||||||
|
*
|
||||||
|
* @param [in] len Read data length
|
||||||
|
*
|
||||||
|
* @retval Error Read data program failed
|
||||||
|
* @retval Ok Read data program success
|
||||||
|
*/
|
||||||
|
static en_result_t SpiFlash_ReadData(uint32_t u32Addr, uint8_t pData[], uint16_t len)
|
||||||
|
{
|
||||||
|
en_result_t enRet = Ok;
|
||||||
|
uint16_t u16Index = 0U;
|
||||||
|
|
||||||
|
if ((u32Addr > FLASH_MAX_ADDR) || (NULL == pData))
|
||||||
|
{
|
||||||
|
enRet = Error;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SpiFlash_WriteEnable();
|
||||||
|
/* Send data to flash */
|
||||||
|
SPI_NSS_LOW();
|
||||||
|
(void)SpiFlash_WriteReadByte(FLASH_INSTR_STANDARD_READ);
|
||||||
|
(void)SpiFlash_WriteReadByte((uint8_t)((u32Addr & 0xFF0000UL) >> 16U));
|
||||||
|
(void)SpiFlash_WriteReadByte((uint8_t)((u32Addr & 0xFF00U) >> 8U));
|
||||||
|
(void)SpiFlash_WriteReadByte((uint8_t)(u32Addr & 0xFFU));
|
||||||
|
while (0U != (len--))
|
||||||
|
{
|
||||||
|
pData[u16Index] = SpiFlash_WriteReadByte(FLASH_DUMMY_BYTE_VALUE);
|
||||||
|
u16Index++;
|
||||||
|
}
|
||||||
|
SPI_NSS_HIGH();
|
||||||
|
}
|
||||||
|
|
||||||
|
return enRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SPI flash read ID for test
|
||||||
|
*
|
||||||
|
* @param [in] None
|
||||||
|
*
|
||||||
|
* @retval uint8_t Flash ID
|
||||||
|
*/
|
||||||
|
static uint8_t SpiFlash_ReadID(void)
|
||||||
|
{
|
||||||
|
uint8_t u8IdRead;
|
||||||
|
SPI_NSS_LOW();
|
||||||
|
(void)SpiFlash_WriteReadByte(FLASH_READ_MANUFACTURER_ID);
|
||||||
|
(void)SpiFlash_WriteReadByte((uint8_t)0x00U);
|
||||||
|
(void)SpiFlash_WriteReadByte((uint8_t)0x00U);
|
||||||
|
(void)SpiFlash_WriteReadByte((uint8_t)0x00U);
|
||||||
|
u8IdRead = SpiFlash_WriteReadByte(FLASH_DUMMY_BYTE_VALUE);
|
||||||
|
SPI_NSS_HIGH();
|
||||||
|
return u8IdRead;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SPI flash erase 4Kb sector function
|
||||||
|
*
|
||||||
|
* @param [in] u32Addr Valid flash address
|
||||||
|
*
|
||||||
|
* @retval Error Sector erase failed
|
||||||
|
* @retval Ok Sector erase success
|
||||||
|
*/
|
||||||
|
static en_result_t SpiFlash_Erase4KbSector(uint32_t u32Addr)
|
||||||
|
{
|
||||||
|
en_result_t enRet;
|
||||||
|
|
||||||
|
if (u32Addr >= FLASH_MAX_ADDR)
|
||||||
|
{
|
||||||
|
enRet = Error;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SpiFlash_WriteEnable();
|
||||||
|
/* Send instruction to flash */
|
||||||
|
SPI_NSS_LOW();
|
||||||
|
(void)SpiFlash_WriteReadByte(FLASH_INSTR_ERASE_4KB_SECTOR);
|
||||||
|
(void)SpiFlash_WriteReadByte((uint8_t)((u32Addr & 0xFF0000UL) >> 16U));
|
||||||
|
(void)SpiFlash_WriteReadByte((uint8_t)((u32Addr & 0xFF00U) >> 8U));
|
||||||
|
(void)SpiFlash_WriteReadByte((uint8_t)(u32Addr & 0xFFU));
|
||||||
|
//SPI_GetStatus(const M4_SPI_TypeDef *SPIx, uint32_t u32Flag) //todo
|
||||||
|
SPI_NSS_HIGH();
|
||||||
|
/* Wait for flash idle */
|
||||||
|
enRet = SpiFlash_WaitForWriteEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
return enRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Main function of spi_master_base project
|
||||||
|
* @param None
|
||||||
|
* @retval int32_t return value, if needed
|
||||||
|
*/
|
||||||
|
|
||||||
|
void hc32_spiflash_test(void)
|
||||||
|
{
|
||||||
|
uint32_t flashAddr = 0UL;
|
||||||
|
uint16_t bufferLen;
|
||||||
|
char txBuffer[] = "SPI read and write flash example: Welcome to use HDSC micro chip";
|
||||||
|
char rxBuffer[128];
|
||||||
|
uint8_t flash_id = 0;
|
||||||
|
|
||||||
|
hc32_spi_init();
|
||||||
|
|
||||||
|
/* Get tx buffer length */
|
||||||
|
bufferLen = (uint16_t)sizeof(txBuffer);
|
||||||
|
|
||||||
|
flash_id = SpiFlash_ReadID();
|
||||||
|
hc32_print("SPI Flash id: %#x\n", flash_id);
|
||||||
|
|
||||||
|
(void)memset(rxBuffer, 0L, sizeof(rxBuffer));
|
||||||
|
/* Erase sector */
|
||||||
|
(void)SpiFlash_Erase4KbSector(flashAddr);
|
||||||
|
/* Write data to flash */
|
||||||
|
(void)SpiFlash_WritePage(flashAddr, (uint8_t*)&txBuffer[0], bufferLen);
|
||||||
|
/* Read data from flash */
|
||||||
|
(void)SpiFlash_ReadData(flashAddr, (uint8_t*)&rxBuffer[0], bufferLen);
|
||||||
|
|
||||||
|
/* Compare txBuffer and rxBuffer */
|
||||||
|
if (memcmp(txBuffer, rxBuffer, (uint32_t)bufferLen) != 0)
|
||||||
|
{
|
||||||
|
hc32_print("spi failed!!!\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hc32_print("spi ok!!!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Flash address offset */
|
||||||
|
flashAddr += FLASH_SECTOR_SIZE;
|
||||||
|
if (flashAddr >= FLASH_MAX_ADDR)
|
||||||
|
{
|
||||||
|
flashAddr = 0U;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int hc32_spidev_initialized = 1;
|
||||||
|
|
||||||
|
void hc32_spidev_initialize(void)
|
||||||
|
{
|
||||||
|
hc32_spi_init();
|
||||||
|
hc32_spidev_initialized = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* EOF (not truncated)
|
||||||
|
******************************************************************************/
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
#include <nuttx/serial/serial.h>
|
#include <nuttx/serial/serial.h>
|
||||||
|
|
||||||
#include "chip.h"
|
#include "chip.h"
|
||||||
|
|
||||||
#define CONSOLE_UART 6
|
#define CONSOLE_UART 6
|
||||||
|
@ -43,9 +42,35 @@
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* Make sure that we have not enabled more U[S]ARTs than are supported by the
|
typedef enum en_uart_state
|
||||||
* device.
|
{
|
||||||
|
UART_STATE_IDLE = 0U, /*!< No data */
|
||||||
|
UART_STATE_RXEND = 1U, /*!< UART RX End */
|
||||||
|
} uart_state_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Ring buffer structure definition
|
||||||
*/
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint16_t u16Capacity;
|
||||||
|
volatile uint16_t u16UsedSize;
|
||||||
|
uint16_t u16InIdx;
|
||||||
|
uint16_t u16OutIdx;
|
||||||
|
uint8_t au8Buf[50];
|
||||||
|
} uart_ring_buffer_t;
|
||||||
|
|
||||||
|
|
||||||
|
/* UART multiple processor ID definition */
|
||||||
|
#define UART_MASTER_STATION_ID (0x20U)
|
||||||
|
#define UART_SLAVE_STATION_ID (0x21U)
|
||||||
|
|
||||||
|
/* Ring buffer size */
|
||||||
|
#define IS_RING_BUFFER_EMPTY(x) (0U == ((x)->u16UsedSize))
|
||||||
|
|
||||||
|
/* Multi-processor silence mode */
|
||||||
|
#define DBG_UART_NORMAL_MODE (0U)
|
||||||
|
#define DBG_UART_SILENCE_MODE (1U)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Types
|
* Public Types
|
||||||
|
@ -80,7 +105,9 @@ extern "C"
|
||||||
|
|
||||||
FAR uart_dev_t *hc32_serial_get_uart(int uart_num);
|
FAR uart_dev_t *hc32_serial_get_uart(int uart_num);
|
||||||
|
|
||||||
void hc32_print(const char *fmt, ...);
|
int hc32_print(const char *fmt, ...);
|
||||||
|
|
||||||
|
void hc32_console_handle(char *buf);
|
||||||
|
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
|
|
|
@ -0,0 +1,266 @@
|
||||||
|
/****************************************************************************
|
||||||
|
* arch/arm/src/armv7-m/arm_vectors.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Michael Smith. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include "chip.h"
|
||||||
|
#include "arm_internal.h"
|
||||||
|
#include "hc32f4a0_interrupts.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define IDLE_STACK ((unsigned)&_ebss+CONFIG_IDLETHREAD_STACKSIZE)
|
||||||
|
|
||||||
|
#ifndef ARMV7M_PERIPHERAL_INTERRUPTS
|
||||||
|
# error ARMV7M_PERIPHERAL_INTERRUPTS must be defined to the number of I/O interrupts to be supported
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* Chip-specific entrypoint */
|
||||||
|
|
||||||
|
extern void __start(void);
|
||||||
|
|
||||||
|
/* Common exception entrypoint */
|
||||||
|
|
||||||
|
extern void exception_common(void);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* The v7m vector table consists of an array of function pointers, with the
|
||||||
|
* first slot (vector zero) used to hold the initial stack pointer.
|
||||||
|
*
|
||||||
|
* As all exceptions (interrupts) are routed via exception_common, we just
|
||||||
|
* need to fill this array with pointers to it.
|
||||||
|
*
|
||||||
|
* Note that the [ ... ] designated initializer is a GCC extension.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
unsigned _vectors[] locate_data(".vectors") =
|
||||||
|
{
|
||||||
|
/* Initial stack */
|
||||||
|
|
||||||
|
IDLE_STACK,
|
||||||
|
|
||||||
|
/* Reset exception handler */
|
||||||
|
|
||||||
|
(unsigned)&__start,
|
||||||
|
|
||||||
|
/* Vectors 2 - n point directly at the generic handler */
|
||||||
|
|
||||||
|
[2 ... (15 + ARMV7M_PERIPHERAL_INTERRUPTS)] = (unsigned)&exception_common
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
unsigned _vectors[] locate_data(".vectors") =
|
||||||
|
{
|
||||||
|
/* Initial stack */
|
||||||
|
|
||||||
|
IDLE_STACK,
|
||||||
|
|
||||||
|
/* Reset exception handler */
|
||||||
|
|
||||||
|
(unsigned)&__start,
|
||||||
|
(unsigned)&NMI_Handler,
|
||||||
|
(unsigned)&HardFault_Handler,
|
||||||
|
(unsigned)&MemManage_Handler,
|
||||||
|
(unsigned)&BusFault_Handler,
|
||||||
|
(unsigned)&UsageFault_Handler,
|
||||||
|
(unsigned)&exception_common,
|
||||||
|
(unsigned)&exception_common,
|
||||||
|
(unsigned)&exception_common,
|
||||||
|
(unsigned)&exception_common,
|
||||||
|
(unsigned)&SVC_Handler, /* SVC */
|
||||||
|
(unsigned)&DebugMon_Handler, /* DebugMon */
|
||||||
|
(unsigned)&exception_common,
|
||||||
|
(unsigned)&PendSV_Handler,
|
||||||
|
(unsigned)&SysTick_Handler, /* SysTick */
|
||||||
|
(unsigned)&IRQ000_Handler,
|
||||||
|
(unsigned)&IRQ001_Handler,
|
||||||
|
(unsigned)&IRQ002_Handler,
|
||||||
|
(unsigned)&IRQ003_Handler,
|
||||||
|
(unsigned)&IRQ004_Handler,
|
||||||
|
(unsigned)&IRQ005_Handler,
|
||||||
|
(unsigned)&IRQ006_Handler,
|
||||||
|
(unsigned)&IRQ007_Handler,
|
||||||
|
(unsigned)&IRQ008_Handler,
|
||||||
|
(unsigned)&IRQ009_Handler,
|
||||||
|
(unsigned)&IRQ010_Handler,
|
||||||
|
(unsigned)&IRQ011_Handler,
|
||||||
|
(unsigned)&IRQ012_Handler,
|
||||||
|
(unsigned)&IRQ013_Handler,
|
||||||
|
(unsigned)&IRQ014_Handler,
|
||||||
|
(unsigned)&IRQ015_Handler,
|
||||||
|
(unsigned)&IRQ016_Handler,
|
||||||
|
(unsigned)&IRQ017_Handler,
|
||||||
|
(unsigned)&IRQ018_Handler,
|
||||||
|
(unsigned)&IRQ019_Handler,
|
||||||
|
(unsigned)&IRQ020_Handler,
|
||||||
|
(unsigned)&IRQ021_Handler,
|
||||||
|
(unsigned)&IRQ022_Handler,
|
||||||
|
(unsigned)&IRQ023_Handler,
|
||||||
|
(unsigned)&IRQ024_Handler,
|
||||||
|
(unsigned)&IRQ025_Handler,
|
||||||
|
(unsigned)&IRQ026_Handler,
|
||||||
|
(unsigned)&IRQ027_Handler,
|
||||||
|
(unsigned)&IRQ028_Handler,
|
||||||
|
(unsigned)&IRQ029_Handler,
|
||||||
|
(unsigned)&IRQ030_Handler,
|
||||||
|
(unsigned)&IRQ031_Handler,
|
||||||
|
(unsigned)&IRQ032_Handler,
|
||||||
|
(unsigned)&IRQ033_Handler,
|
||||||
|
(unsigned)&IRQ034_Handler,
|
||||||
|
(unsigned)&IRQ035_Handler,
|
||||||
|
(unsigned)&IRQ036_Handler,
|
||||||
|
(unsigned)&IRQ037_Handler,
|
||||||
|
(unsigned)&IRQ038_Handler,
|
||||||
|
(unsigned)&IRQ039_Handler,
|
||||||
|
(unsigned)&IRQ040_Handler,
|
||||||
|
(unsigned)&IRQ041_Handler,
|
||||||
|
(unsigned)&IRQ042_Handler,
|
||||||
|
(unsigned)&IRQ043_Handler,
|
||||||
|
(unsigned)&IRQ044_Handler,
|
||||||
|
(unsigned)&IRQ045_Handler,
|
||||||
|
(unsigned)&IRQ046_Handler,
|
||||||
|
(unsigned)&IRQ047_Handler,
|
||||||
|
(unsigned)&IRQ048_Handler,
|
||||||
|
(unsigned)&IRQ049_Handler,
|
||||||
|
(unsigned)&IRQ050_Handler,
|
||||||
|
(unsigned)&IRQ051_Handler,
|
||||||
|
(unsigned)&IRQ052_Handler,
|
||||||
|
(unsigned)&IRQ053_Handler,
|
||||||
|
(unsigned)&IRQ054_Handler,
|
||||||
|
(unsigned)&IRQ055_Handler,
|
||||||
|
(unsigned)&IRQ056_Handler,
|
||||||
|
(unsigned)&IRQ057_Handler,
|
||||||
|
(unsigned)&IRQ058_Handler,
|
||||||
|
(unsigned)&IRQ059_Handler,
|
||||||
|
(unsigned)&IRQ060_Handler,
|
||||||
|
(unsigned)&IRQ061_Handler,
|
||||||
|
(unsigned)&IRQ062_Handler,
|
||||||
|
(unsigned)&IRQ063_Handler,
|
||||||
|
(unsigned)&IRQ064_Handler,
|
||||||
|
(unsigned)&IRQ065_Handler,
|
||||||
|
(unsigned)&IRQ066_Handler,
|
||||||
|
(unsigned)&IRQ067_Handler,
|
||||||
|
(unsigned)&IRQ068_Handler,
|
||||||
|
(unsigned)&IRQ069_Handler,
|
||||||
|
(unsigned)&IRQ070_Handler,
|
||||||
|
(unsigned)&IRQ071_Handler,
|
||||||
|
(unsigned)&IRQ072_Handler,
|
||||||
|
(unsigned)&IRQ073_Handler,
|
||||||
|
(unsigned)&IRQ074_Handler,
|
||||||
|
(unsigned)&IRQ075_Handler,
|
||||||
|
(unsigned)&IRQ076_Handler,
|
||||||
|
(unsigned)&IRQ077_Handler,
|
||||||
|
(unsigned)&IRQ078_Handler,
|
||||||
|
(unsigned)&IRQ079_Handler,
|
||||||
|
(unsigned)&IRQ080_Handler,
|
||||||
|
(unsigned)&IRQ081_Handler,
|
||||||
|
(unsigned)&IRQ082_Handler,
|
||||||
|
(unsigned)&IRQ083_Handler,
|
||||||
|
(unsigned)&IRQ084_Handler,
|
||||||
|
(unsigned)&IRQ085_Handler,
|
||||||
|
(unsigned)&IRQ086_Handler,
|
||||||
|
(unsigned)&IRQ087_Handler,
|
||||||
|
(unsigned)&IRQ088_Handler,
|
||||||
|
(unsigned)&IRQ089_Handler,
|
||||||
|
(unsigned)&IRQ090_Handler,
|
||||||
|
(unsigned)&IRQ091_Handler,
|
||||||
|
(unsigned)&IRQ092_Handler,
|
||||||
|
(unsigned)&IRQ093_Handler,
|
||||||
|
(unsigned)&IRQ094_Handler,
|
||||||
|
(unsigned)&IRQ095_Handler,
|
||||||
|
(unsigned)&IRQ096_Handler,
|
||||||
|
(unsigned)&IRQ097_Handler,
|
||||||
|
(unsigned)&IRQ098_Handler,
|
||||||
|
(unsigned)&IRQ099_Handler,
|
||||||
|
(unsigned)&IRQ100_Handler,
|
||||||
|
(unsigned)&IRQ101_Handler,
|
||||||
|
(unsigned)&IRQ102_Handler,
|
||||||
|
(unsigned)&IRQ103_Handler,
|
||||||
|
(unsigned)&IRQ104_Handler,
|
||||||
|
(unsigned)&IRQ105_Handler,
|
||||||
|
(unsigned)&IRQ106_Handler,
|
||||||
|
(unsigned)&IRQ107_Handler,
|
||||||
|
(unsigned)&IRQ108_Handler,
|
||||||
|
(unsigned)&IRQ109_Handler,
|
||||||
|
(unsigned)&IRQ110_Handler,
|
||||||
|
(unsigned)&IRQ111_Handler,
|
||||||
|
(unsigned)&IRQ112_Handler,
|
||||||
|
(unsigned)&IRQ113_Handler,
|
||||||
|
(unsigned)&IRQ114_Handler,
|
||||||
|
(unsigned)&IRQ115_Handler,
|
||||||
|
(unsigned)&IRQ116_Handler,
|
||||||
|
(unsigned)&IRQ117_Handler,
|
||||||
|
(unsigned)&IRQ118_Handler,
|
||||||
|
(unsigned)&IRQ119_Handler,
|
||||||
|
(unsigned)&IRQ120_Handler,
|
||||||
|
(unsigned)&IRQ121_Handler,
|
||||||
|
(unsigned)&IRQ122_Handler,
|
||||||
|
(unsigned)&IRQ123_Handler,
|
||||||
|
(unsigned)&IRQ124_Handler,
|
||||||
|
(unsigned)&IRQ125_Handler,
|
||||||
|
(unsigned)&IRQ126_Handler,
|
||||||
|
(unsigned)&IRQ127_Handler,
|
||||||
|
(unsigned)&IRQ128_Handler,
|
||||||
|
(unsigned)&IRQ129_Handler,
|
||||||
|
(unsigned)&IRQ130_Handler,
|
||||||
|
(unsigned)&IRQ131_Handler,
|
||||||
|
(unsigned)&IRQ132_Handler,
|
||||||
|
(unsigned)&IRQ133_Handler,
|
||||||
|
(unsigned)&IRQ134_Handler,
|
||||||
|
(unsigned)&IRQ135_Handler,
|
||||||
|
(unsigned)&IRQ136_Handler,
|
||||||
|
(unsigned)&IRQ137_Handler,
|
||||||
|
(unsigned)&IRQ138_Handler,
|
||||||
|
(unsigned)&IRQ139_Handler,
|
||||||
|
(unsigned)&IRQ140_Handler,
|
||||||
|
(unsigned)&IRQ141_Handler,
|
||||||
|
(unsigned)&IRQ142_Handler,
|
||||||
|
(unsigned)&IRQ143_Handler
|
||||||
|
|
||||||
|
// [2 ... (15 + ARMV7M_PERIPHERAL_INTERRUPTS)] = (unsigned)&exception_common
|
||||||
|
};
|
||||||
|
#endif
|
|
@ -137,6 +137,8 @@ typedef struct
|
||||||
#define GPIO_PORT_SHIFT 16
|
#define GPIO_PORT_SHIFT 16
|
||||||
|
|
||||||
#define GPIO_PINSET(_port, _pin) ((uint32_t)(_port << GPIO_PORT_SHIFT) | _pin)
|
#define GPIO_PINSET(_port, _pin) ((uint32_t)(_port << GPIO_PORT_SHIFT) | _pin)
|
||||||
|
#define GPIO_PIN(_pinset) ((_pinset >> GPIO_PIN_SHIFT) & GPIO_PIN_MASK)
|
||||||
|
#define GPIO_PORT(_pinset) ((_pinset >> GPIO_PORT_SHIFT) & GPIO_PORT_MASK)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
|
|
1095
Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32f4a0_spi.c
Executable file
|
@ -0,0 +1,446 @@
|
||||||
|
/**
|
||||||
|
*******************************************************************************
|
||||||
|
* @file hc32f4a0_spi.h
|
||||||
|
* @brief This file contains all the functions prototypes of the SPI driver
|
||||||
|
* library.
|
||||||
|
@verbatim
|
||||||
|
Change Logs:
|
||||||
|
Date Author Notes
|
||||||
|
2020-06-12 Wangmin First version
|
||||||
|
@endverbatim
|
||||||
|
*******************************************************************************
|
||||||
|
* Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software component is licensed by HDSC under BSD 3-Clause license
|
||||||
|
* (the "License"); You may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at:
|
||||||
|
* opensource.org/licenses/BSD-3-Clause
|
||||||
|
*
|
||||||
|
*******************************************************************************
|
||||||
|
*/
|
||||||
|
#ifndef __HC32F4A0_SPI_H__
|
||||||
|
#define __HC32F4A0_SPI_H__
|
||||||
|
|
||||||
|
/* C binding of definitions if building with C++ compiler */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Include files
|
||||||
|
******************************************************************************/
|
||||||
|
#include "hc32_common.h"
|
||||||
|
#include "ddl_config.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup HC32F4A0_DDL_Driver
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup DDL_SPI
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if (DDL_SPI_ENABLE == DDL_ON)
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Global type definitions ('typedef')
|
||||||
|
******************************************************************************/
|
||||||
|
/**
|
||||||
|
* @defgroup SPI_Global_Types SPI Global Types
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Structure definition of SPI initialization.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t u32WireMode; /*!< SPI wire mode, 3 wire mode or 4 wire mode.
|
||||||
|
This parameter can be a value of @ref SPI_Wire_Mode_Define */
|
||||||
|
uint32_t u32TransMode; /*!< SPI transfer mode, send only or full duplex.
|
||||||
|
This parameter can be a value of @ref SPI_Transfer_Mode_Define */
|
||||||
|
uint32_t u32MasterSlave; /*!< SPI master/slave mode.
|
||||||
|
This parameter can be a value of @ref SPI_Master_Slave_Mode_Define */
|
||||||
|
uint32_t u32SuspMode; /*!< SPI communication suspend function.
|
||||||
|
This parameter can be a value of @ref SPI_Communication_Suspend_Function_Define */
|
||||||
|
uint32_t u32Modfe; /*!< SPI mode fault detect command.
|
||||||
|
This parameter can be a value of @ref SPI_Mode_Fault_Dectet_Command_Define */
|
||||||
|
uint32_t u32Parity; /*!< SPI parity check selection.
|
||||||
|
This parameter can be a value of @ref SPI_Parity_Check_Define */
|
||||||
|
uint32_t u32SpiMode; /*!< SPI mode.
|
||||||
|
This parameter can be a value of @ref SPI_Mode_Define */
|
||||||
|
uint32_t u32BaudRatePrescaler; /*!< SPI baud rate prescaler.
|
||||||
|
This parameter can be a value of @ref SPI_Baud_Rate_Prescaler_Define */
|
||||||
|
uint32_t u32DataBits; /*!< SPI data bits, 4 bits ~ 32 bits.
|
||||||
|
This parameter can be a value of @ref SPI_Data_Size_Define */
|
||||||
|
uint32_t u32FirstBit; /*!< MSB first or LSB first.
|
||||||
|
This parameter can be a value of @ref SPI_First_Bit_Define */
|
||||||
|
uint32_t u32FrameLevel; /*!< SPI frame level, SPI_FRAME_1 ~ SPI_FRAME_4.
|
||||||
|
This parameter can be a value of @ref SPI_Frame_Level_Define */
|
||||||
|
} stc_spi_init_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Structure definition of SPI delay time configuration.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t u32IntervalDelay; /*!< SPI interval time delay (Next access delay time)
|
||||||
|
This parameter can be a value of @ref SPI_Interval_Delay_Time_define */
|
||||||
|
uint32_t u32ReleaseDelay; /*!< SPI release time delay (SCK invalid delay time)
|
||||||
|
This parameter can be a value of @ref SPI_Release_Delay_Time_define */
|
||||||
|
uint32_t u32SetupDelay; /*!< SPI Setup time delay (SCK valid delay time) define
|
||||||
|
This parameter can be a value of @ref SPI_Setup_Delay_Time_define */
|
||||||
|
} stc_spi_delay_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Global pre-processor symbols/macros ('#define')
|
||||||
|
******************************************************************************/
|
||||||
|
/**
|
||||||
|
* @defgroup SPI_Global_Macros SPI Global Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup SPI_Wire_Mode_Define SPI wire mode define
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SPI_WIRE_4 (0UL)
|
||||||
|
#define SPI_WIRE_3 (SPI_CR1_SPIMDS)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup SPI_Transfer_Mode_Define SPI transfer mode define
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SPI_FULL_DUPLEX (0UL) /*!< Full duplex. */
|
||||||
|
#define SPI_SEND_ONLY (SPI_CR1_TXMDS) /*!< Send only. */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup SPI_Master_Slave_Mode_Define SPI master slave mode define
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SPI_SLAVE (0UL)
|
||||||
|
#define SPI_MASTER (SPI_CR1_MSTR)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup SPI_Loopback_Selection_Define SPI loopback selection define
|
||||||
|
* @note Loopback mode is mainly used for parity self-diagnosis in 4-wire full-duplex mode.
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SPI_SPLPBK_INVALID (0UL)
|
||||||
|
#define SPI_SPLPBK_MOSI_INVERT (SPI_CR1_SPLPBK) /*!< MISO data is the inverse of the data output by MOSI. */
|
||||||
|
#define SPI_SPLPBK_MOSI (SPI_CR1_SPLPBK2) /*!< MISO data is the data output by MOSI. */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup SPI_Communication_Suspend_Function_Define SPI communication suspend function define
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SPI_COM_SUSP_FUNC_OFF (0UL)
|
||||||
|
#define SPI_COM_SUSP_FUNC_ON (SPI_CR1_CSUSPE)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup SPI_Interrupt_Type_Define SPI interrupt type define
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SPI_INT_ERROR (SPI_CR1_EIE) /*!< Including overload, underload and parity error. */
|
||||||
|
#define SPI_INT_TX_BUFFER_EMPTY (SPI_CR1_TXIE)
|
||||||
|
#define SPI_INT_RX_BUFFER_FULL (SPI_CR1_RXIE)
|
||||||
|
#define SPI_INT_IDLE (SPI_CR1_IDIE)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup SPI_Mode_Fault_Dectet_Command_Define SPI mode fault dectect command define
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SPI_MODFE_DISABLE (0UL) /*!< Disable mode fault detection. */
|
||||||
|
#define SPI_MODFE_ENABLE (SPI_CR1_MODFE) /*!< Enable mode fault detection. */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup SPI_Parity_Check_Error_Self_Diagnosis_Define SPI parity check error self diagnosis define
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SPI_PATE_DISABLE (0UL) /*!< Disable self diagnosis of parity check. */
|
||||||
|
#define SPI_PATE_ENABLE (SPI_CR1_PATE) /*!< Enable self diagnosis of parity check. */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup SPI_Parity_Check_Define SPI parity check mode define
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SPI_PARITY_INVALID (0UL) /*!< Parity check invalid. */
|
||||||
|
#define SPI_PARITY_EVEN (SPI_CR1_PAE) /*!< Parity check selection even parity. */
|
||||||
|
#define SPI_PARITY_ODD (SPI_CR1_PAE | SPI_CR1_PAOE) /*!< Parity check selection odd parity. */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup SPI_Interval_Delay_Time_define SPI interval time delay (Next access delay time) define
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SPI_INTERVAL_TIME_1SCK_2PCLK1 (0UL)
|
||||||
|
#define SPI_INTERVAL_TIME_2SCK_2PCLK1 (SPI_CFG1_MIDI_0)
|
||||||
|
#define SPI_INTERVAL_TIME_3SCK_2PCLK1 (SPI_CFG1_MIDI_1)
|
||||||
|
#define SPI_INTERVAL_TIME_4SCK_2PCLK1 (SPI_CFG1_MIDI_1 | SPI_CFG1_MIDI_0)
|
||||||
|
#define SPI_INTERVAL_TIME_5SCK_2PCLK1 (SPI_CFG1_MIDI_2)
|
||||||
|
#define SPI_INTERVAL_TIME_6SCK_2PCLK1 (SPI_CFG1_MIDI_2 | SPI_CFG1_MIDI_0)
|
||||||
|
#define SPI_INTERVAL_TIME_7SCK_2PCLK1 (SPI_CFG1_MIDI_2 | SPI_CFG1_MIDI_1)
|
||||||
|
#define SPI_INTERVAL_TIME_8SCK_2PCLK1 (SPI_CFG1_MIDI_2 | SPI_CFG1_MIDI_1 | SPI_CFG1_MIDI_0)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup SPI_Release_Delay_Time_define SPI release time delay (SCK invalid delay time) define
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SPI_RELEASE_TIME_1SCK (0UL)
|
||||||
|
#define SPI_RELEASE_TIME_2SCK (SPI_CFG1_MSSDL_0)
|
||||||
|
#define SPI_RELEASE_TIME_3SCK (SPI_CFG1_MSSDL_1)
|
||||||
|
#define SPI_RELEASE_TIME_4SCK (SPI_CFG1_MSSDL_1 | SPI_CFG1_MSSDL_0)
|
||||||
|
#define SPI_RELEASE_TIME_5SCK (SPI_CFG1_MSSDL_2)
|
||||||
|
#define SPI_RELEASE_TIME_6SCK (SPI_CFG1_MSSDL_2 | SPI_CFG1_MSSDL_0)
|
||||||
|
#define SPI_RELEASE_TIME_7SCK (SPI_CFG1_MSSDL_2 | SPI_CFG1_MSSDL_1)
|
||||||
|
#define SPI_RELEASE_TIME_8SCK (SPI_CFG1_MSSDL_2 | SPI_CFG1_MSSDL_1 | SPI_CFG1_MSSDL_0)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup SPI_Setup_Delay_Time_define SPI Setup time delay (SCK valid delay time) define
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SPI_SETUP_TIME_1SCK (0UL)
|
||||||
|
#define SPI_SETUP_TIME_2SCK (SPI_CFG1_MSSI_0)
|
||||||
|
#define SPI_SETUP_TIME_3SCK (SPI_CFG1_MSSI_1)
|
||||||
|
#define SPI_SETUP_TIME_4SCK (SPI_CFG1_MSSI_1 | SPI_CFG1_MSSI_0)
|
||||||
|
#define SPI_SETUP_TIME_5SCK (SPI_CFG1_MSSI_2)
|
||||||
|
#define SPI_SETUP_TIME_6SCK (SPI_CFG1_MSSI_2 | SPI_CFG1_MSSI_0)
|
||||||
|
#define SPI_SETUP_TIME_7SCK (SPI_CFG1_MSSI_2 | SPI_CFG1_MSSI_1)
|
||||||
|
#define SPI_SETUP_TIME_8SCK (SPI_CFG1_MSSI_2 | SPI_CFG1_MSSI_1 | SPI_CFG1_MSSI_0)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup SPI_SS_Pin_Define SPI SSx define
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SPI_PIN_SS0 (SPI_CFG1_SS0PV)
|
||||||
|
#define SPI_PIN_SS1 (SPI_CFG1_SS1PV)
|
||||||
|
#define SPI_PIN_SS2 (SPI_CFG1_SS2PV)
|
||||||
|
#define SPI_PIN_SS3 (SPI_CFG1_SS3PV)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup SPI_SS_Active_Level_Define SPI SSx Active Level define
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SPI_SS_ACTIVE_LOW (0UL) /*!< SS pin active low. */
|
||||||
|
#define SPI_SS_ACTIVE_HIGH (1UL) /*!< SS pin active high. */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup SPI_Read_Target_Buffer_Define SPI read data register target buffer define
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SPI_RD_TARGET_RD_BUF (0UL) /*!< Read RX buffer. */
|
||||||
|
#define SPI_RD_TARGET_WR_BUF (SPI_CFG1_SPRDTD) /*!< Read TX buffer. */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup SPI_Frame_Level_Define SPI data frame level define, The Data in the
|
||||||
|
* SPI_DR register will be send to TX_BUFF after
|
||||||
|
* enough data frame write to the SPI_DR
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SPI_FRAME_1 (0UL) /*!< Data 1 frame */
|
||||||
|
#define SPI_FRAME_2 (SPI_CFG1_FTHLV_0) /*!< Data 2 frame.*/
|
||||||
|
#define SPI_FRAME_3 (SPI_CFG1_FTHLV_1) /*!< Data 3 frame.*/
|
||||||
|
#define SPI_FRAME_4 (SPI_CFG1_FTHLV_0 | SPI_CFG1_FTHLV_1) /*!< Data 4 frame.*/
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup SPI_Mode_Define SPI Mode define
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/* SCK pin output low in idle state; MOSI/MISO pin data valid in odd edge , MOSI/MISO pin data change in even edge */
|
||||||
|
#define SPI_MODE_0 (0UL)
|
||||||
|
/* SCK pin output low in idle state; MOSI/MISO pin data valid in even edge , MOSI/MISO pin data change in odd edge */
|
||||||
|
#define SPI_MODE_1 (SPI_CFG2_CPHA)
|
||||||
|
/* SCK pin output high in idle state; MOSI/MISO pin data valid in odd edge , MOSI/MISO pin data change in even edge */
|
||||||
|
#define SPI_MODE_2 (SPI_CFG2_CPOL)
|
||||||
|
/* SCK pin output high in idle state; MOSI/MISO pin data valid in even edge , MOSI/MISO pin data change in odd edge */
|
||||||
|
#define SPI_MODE_3 (SPI_CFG2_CPOL | SPI_CFG2_CPHA)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup SPI_Baud_Rate_Prescaler_Define SPI baudrate prescaler define
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SPI_BR_PCLK1_DIV2 (0UL) /*!< SPI baud rate is the pclk1 divided by 2. */
|
||||||
|
#define SPI_BR_PCLK1_DIV4 (SPI_CFG2_MBR_0) /*!< SPI baud rate is the pclk1 clock divided by 4. */
|
||||||
|
#define SPI_BR_PCLK1_DIV8 (SPI_CFG2_MBR_1) /*!< SPI baud rate is the pclk1 clock divided by 8. */
|
||||||
|
#define SPI_BR_PCLK1_DIV16 (SPI_CFG2_MBR_1 | SPI_CFG2_MBR_0) /*!< SPI baud rate is the pclk1 clock divided by 16. */
|
||||||
|
#define SPI_BR_PCLK1_DIV32 (SPI_CFG2_MBR_2) /*!< SPI baud rate is the pclk1 clock divided by 32. */
|
||||||
|
#define SPI_BR_PCLK1_DIV64 (SPI_CFG2_MBR_2 | SPI_CFG2_MBR_0) /*!< SPI baud rate is the pclk1 clock divided by 64. */
|
||||||
|
#define SPI_BR_PCLK1_DIV128 (SPI_CFG2_MBR_2 | SPI_CFG2_MBR_1) /*!< SPI baud rate is the pclk1 clock divided by 128. */
|
||||||
|
#define SPI_BR_PCLK1_DIV256 (SPI_CFG2_MBR_2 | SPI_CFG2_MBR_1 | SPI_CFG2_MBR_0) /*!< SPI baud rate is the pclk1 divided by 256. */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup SPI_Data_Size_Define SPI data size define
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SPI_DATA_SIZE_4BIT (0UL)
|
||||||
|
#define SPI_DATA_SIZE_5BIT (SPI_CFG2_DSIZE_0)
|
||||||
|
#define SPI_DATA_SIZE_6BIT (SPI_CFG2_DSIZE_1)
|
||||||
|
#define SPI_DATA_SIZE_7BIT (SPI_CFG2_DSIZE_0 | SPI_CFG2_DSIZE_1)
|
||||||
|
#define SPI_DATA_SIZE_8BIT (SPI_CFG2_DSIZE_2)
|
||||||
|
#define SPI_DATA_SIZE_9BIT (SPI_CFG2_DSIZE_2 | SPI_CFG2_DSIZE_0)
|
||||||
|
#define SPI_DATA_SIZE_10BIT (SPI_CFG2_DSIZE_2 | SPI_CFG2_DSIZE_1)
|
||||||
|
#define SPI_DATA_SIZE_11BIT (SPI_CFG2_DSIZE_2 | SPI_CFG2_DSIZE_1 | SPI_CFG2_DSIZE_0)
|
||||||
|
#define SPI_DATA_SIZE_12BIT (SPI_CFG2_DSIZE_3)
|
||||||
|
#define SPI_DATA_SIZE_13BIT (SPI_CFG2_DSIZE_3 | SPI_CFG2_DSIZE_0)
|
||||||
|
#define SPI_DATA_SIZE_14BIT (SPI_CFG2_DSIZE_3 | SPI_CFG2_DSIZE_1)
|
||||||
|
#define SPI_DATA_SIZE_15BIT (SPI_CFG2_DSIZE_3 | SPI_CFG2_DSIZE_1 | SPI_CFG2_DSIZE_0)
|
||||||
|
#define SPI_DATA_SIZE_16BIT (SPI_CFG2_DSIZE_3 | SPI_CFG2_DSIZE_2)
|
||||||
|
#define SPI_DATA_SIZE_20BIT (SPI_CFG2_DSIZE_3 | SPI_CFG2_DSIZE_2 | SPI_CFG2_DSIZE_0)
|
||||||
|
#define SPI_DATA_SIZE_24BIT (SPI_CFG2_DSIZE_3 | SPI_CFG2_DSIZE_2 | SPI_CFG2_DSIZE_1)
|
||||||
|
#define SPI_DATA_SIZE_32BIT (SPI_CFG2_DSIZE_3 | SPI_CFG2_DSIZE_2 | SPI_CFG2_DSIZE_1 | SPI_CFG2_DSIZE_0)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup SPI_First_Bit_Define SPI first bit define
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SPI_FIRST_MSB (0UL)
|
||||||
|
#define SPI_FIRST_LSB (SPI_CFG2_LSBF)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup SPI_State_Flag_Define SPI state flag define
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SPI_FLAG_OVERLOAD (SPI_SR_OVRERF)
|
||||||
|
#define SPI_FLAG_IDLE (SPI_SR_IDLNF)
|
||||||
|
#define SPI_FLAG_MODE_FAULT (SPI_SR_MODFERF)
|
||||||
|
#define SPI_FLAG_PARITY_ERROR (SPI_SR_PERF)
|
||||||
|
#define SPI_FLAG_UNDERLOAD (SPI_SR_UDRERF)
|
||||||
|
#define SPI_FLAG_TX_BUFFER_EMPTY (SPI_SR_TDEF) /*!< This flag is set when the data in the data register \
|
||||||
|
is copied into the shift register, but the transmission \
|
||||||
|
of the data bit may not have been completed. */
|
||||||
|
#define SPI_FLAG_RX_BUFFER_FULL (SPI_SR_RDFF) /*!< When this flag is set, it indicates that a data was received. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Global variable definitions ('extern')
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
Global function prototypes (definition in C source)
|
||||||
|
******************************************************************************/
|
||||||
|
/**
|
||||||
|
* @addtogroup SPI_Global_Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
en_result_t SPI_StructInit(stc_spi_init_t *pstcInit);
|
||||||
|
en_result_t SPI_DelayStructInit(stc_spi_delay_t *pstcDelayCfg);
|
||||||
|
|
||||||
|
en_result_t SPI_Init(M4_SPI_TypeDef *SPIx, const stc_spi_init_t *pstcInit);
|
||||||
|
void SPI_DeInit(M4_SPI_TypeDef *SPIx);
|
||||||
|
|
||||||
|
void SPI_IntCmd(M4_SPI_TypeDef *SPIx, uint32_t u32IntType, en_functional_state_t enNewState);
|
||||||
|
void SPI_FunctionCmd(M4_SPI_TypeDef *SPIx, en_functional_state_t enNewState);
|
||||||
|
|
||||||
|
void SPI_WriteDataReg(M4_SPI_TypeDef *SPIx, uint32_t u32Data);
|
||||||
|
uint32_t SPI_ReadDataReg(const M4_SPI_TypeDef *SPIx);
|
||||||
|
|
||||||
|
en_flag_status_t SPI_GetStatus(const M4_SPI_TypeDef *SPIx, uint32_t u32Flag);
|
||||||
|
void SPI_ClearFlag(M4_SPI_TypeDef *SPIx, uint32_t u32Flag);
|
||||||
|
|
||||||
|
void SPI_LoopbackModeCfg(M4_SPI_TypeDef *SPIx, uint32_t u32Mode);
|
||||||
|
void SPI_PateCmd(M4_SPI_TypeDef *SPIx, en_functional_state_t enNewState);
|
||||||
|
en_result_t SPI_DelayTimeCfg(M4_SPI_TypeDef *SPIx, const stc_spi_delay_t *pstcDelayCfg);
|
||||||
|
void SPI_SSValidLevelCfg(M4_SPI_TypeDef *SPIx, uint32_t u32SSPin, en_functional_state_t enNewState);
|
||||||
|
void SPI_SSPinSel(M4_SPI_TypeDef *SPIx, uint32_t u32SSPin);
|
||||||
|
void SPI_ReadBufCfg(M4_SPI_TypeDef *SPIx, uint32_t u32ReadBuf);
|
||||||
|
|
||||||
|
en_result_t SPI_Transmit(M4_SPI_TypeDef *SPIx, const void *pvTxBuf, uint32_t u32TxLength);
|
||||||
|
en_result_t SPI_Receive(M4_SPI_TypeDef *SPIx, void *pvRxBuf, uint32_t u32RxLength);
|
||||||
|
en_result_t SPI_TransmitReceive(M4_SPI_TypeDef *SPIx, const void *pvTxBuf, void *pvRxBuf, uint32_t u32Length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /* DDL_SPI_ENABLE */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __HC32F4A0_SPI_H__ */
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* EOF (not truncated)
|
||||||
|
******************************************************************************/
|
|
@ -1,575 +0,0 @@
|
||||||
/**
|
|
||||||
*******************************************************************************
|
|
||||||
* @file w25qxx.c
|
|
||||||
* @brief This midware file provides firmware functions to W25QXX group spi flash.
|
|
||||||
@verbatim
|
|
||||||
Change Logs:
|
|
||||||
Date Author Notes
|
|
||||||
2020-06-12 Wangmin First version
|
|
||||||
2020-08-31 Wangmin Modify for MISRAC2012
|
|
||||||
@endverbatim
|
|
||||||
*******************************************************************************
|
|
||||||
* Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
|
|
||||||
*
|
|
||||||
* This software component is licensed by HDSC under BSD 3-Clause license
|
|
||||||
* (the "License"); You may not use this file except in compliance with the
|
|
||||||
* License. You may obtain a copy of the License at:
|
|
||||||
* opensource.org/licenses/BSD-3-Clause
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Include files
|
|
||||||
******************************************************************************/
|
|
||||||
#include "w25qxx.h"
|
|
||||||
#include "ev_hc32f4a0_lqfp176_w25qxx.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @addtogroup BSP
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @addtogroup Components
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @defgroup W25QXX Flash Driver for W25QXX
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if (BSP_W25QXX_ENABLE == BSP_ON)
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Local type definitions ('typedef')
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Local pre-processor symbols/macros ('#define')
|
|
||||||
******************************************************************************/
|
|
||||||
/**
|
|
||||||
* @defgroup W25QXX_Local_Macros W25QXX Local Macros
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
#define W25Q_BIT_0 (1UL << 0U)
|
|
||||||
#define W25Q_BIT_1 (1UL << 1U)
|
|
||||||
#define W25Q_BIT_2 (1UL << 2U)
|
|
||||||
#define W25Q_BIT_3 (1UL << 3U)
|
|
||||||
#define W25Q_BIT_4 (1UL << 4U)
|
|
||||||
#define W25Q_BIT_5 (1UL << 5U)
|
|
||||||
#define W25Q_BIT_6 (1UL << 6U)
|
|
||||||
#define W25Q_BIT_7 (1UL << 7U)
|
|
||||||
#define W25Q_BIT_8 (1UL << 8U)
|
|
||||||
#define W25Q_BIT_9 (1UL << 9U)
|
|
||||||
#define W25Q_BIT_10 (1UL << 10U)
|
|
||||||
#define W25Q_BIT_11 (1UL << 11U)
|
|
||||||
#define W25Q_BIT_12 (1UL << 12U)
|
|
||||||
#define W25Q_BIT_13 (1UL << 13U)
|
|
||||||
#define W25Q_BIT_14 (1UL << 14U)
|
|
||||||
#define W25Q_BIT_15 (1UL << 15U)
|
|
||||||
|
|
||||||
#define W25Q_ST_BUSY ((uint16_t)W25Q_BIT_0)
|
|
||||||
#define W25Q_ST_WEL ((uint16_t)W25Q_BIT_1) /*<! Write enable latch. */
|
|
||||||
|
|
||||||
#define LOAD_CMD(a, cmd, addr) do { \
|
|
||||||
(a)[0U] = (cmd); \
|
|
||||||
(a)[1U] = (uint8_t)((addr) >> 16U); \
|
|
||||||
(a)[2U] = (uint8_t)((addr) >> 8U); \
|
|
||||||
(a)[3U] = (uint8_t)(addr); \
|
|
||||||
} while (0U)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Global variable definitions (declared in header file with 'extern')
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Local function prototypes ('static')
|
|
||||||
******************************************************************************/
|
|
||||||
/**
|
|
||||||
* @defgroup W25QXX_Local_Functions W25QXX Local Functions
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
static void W25QXX_WriteCmd(uint8_t u8Cmd, const uint8_t *pu8CmdData, uint32_t u32CmdDataLength);
|
|
||||||
static void W25QXX_ReadCmd(uint8_t u8Cmd, uint8_t *pu8CmdData, uint32_t u32CmdDataLength,
|
|
||||||
uint8_t *pu8Info, uint8_t u8InfoLength);
|
|
||||||
|
|
||||||
static void W25QXX_Wt(uint8_t u8Cmd, uint32_t u32Address, const uint8_t *pu8Data, uint32_t u32DataLength);
|
|
||||||
static void W25QXX_Rd(uint8_t u8Cmd, uint32_t u32Address, uint8_t *pu8Data, uint32_t u32DataLength);
|
|
||||||
|
|
||||||
static void W25QXX_WaitBusy(void);
|
|
||||||
|
|
||||||
static void W25QXX_WriteEnable(void);
|
|
||||||
static void W25QXX_WriteDisable(void);
|
|
||||||
|
|
||||||
static void W25QXX_WritePage(uint32_t u32Address, const uint8_t *pu8Data, uint32_t u32DataLength);
|
|
||||||
|
|
||||||
static void W25QXX_Write_NoCheck(const uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite);
|
|
||||||
static void W25QXX_WriteCmd(uint8_t u8Cmd, const uint8_t *pu8CmdData, uint32_t u32CmdDataLength);
|
|
||||||
static void W25QXX_ReadCmd(uint8_t u8Cmd, uint8_t *pu8CmdData, uint32_t u32CmdDataLength,
|
|
||||||
uint8_t *pu8Info, uint8_t u8InfoLength);
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Local variable definitions ('static')
|
|
||||||
******************************************************************************/
|
|
||||||
static uint8_t W25QXX_BUFFER[4096U];
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Function implementation - global ('extern') and local ('static')
|
|
||||||
******************************************************************************/
|
|
||||||
/**
|
|
||||||
* @defgroup W25QXX_Global_Functions W25QXX Global Functions
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initializes W25QXX.
|
|
||||||
* @param [out] pstcW25qxx Pointer to a stc_w25qxx_t structure which contains the information of the SPI flash.
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void W25QXX_Init(stc_w25qxx_t *pstcW25qxx)
|
|
||||||
{
|
|
||||||
BSP_W25Q_SPI_Init();
|
|
||||||
|
|
||||||
if (pstcW25qxx != NULL)
|
|
||||||
{
|
|
||||||
/* Read Flash ID */
|
|
||||||
pstcW25qxx->u16ManId = W25QXX_ReadManDeviceId();
|
|
||||||
|
|
||||||
switch (pstcW25qxx->u16ManId)
|
|
||||||
{
|
|
||||||
case W25Q64:
|
|
||||||
pstcW25qxx->u32PageCount = 32768UL; /* W25Q64 contains 32768 pages. */
|
|
||||||
pstcW25qxx->u32SectorCount = 2048U; /* W25Q64 contains 2048 sectors. */
|
|
||||||
pstcW25qxx->u32BlockCount32k = 0U; /* DO NOT support 32K block. */
|
|
||||||
pstcW25qxx->u32BlockCount64k = 128U;
|
|
||||||
pstcW25qxx->u32CapacityInBytes = pstcW25qxx->u32PageCount * W25Q_SIZE_PAGE;
|
|
||||||
pstcW25qxx->u32CapacityInKB = pstcW25qxx->u32CapacityInBytes * W25Q_SIZE_1K;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Read manufacturer device ID.
|
|
||||||
* @param None
|
|
||||||
* @retval 16 bit manufacturer device ID.
|
|
||||||
*/
|
|
||||||
uint16_t W25QXX_ReadManDeviceId(void)
|
|
||||||
{
|
|
||||||
uint8_t au8TempId[2U];
|
|
||||||
uint8_t au8Dummy[3U] = {0U};
|
|
||||||
uint16_t u16ManID;
|
|
||||||
|
|
||||||
W25QXX_ReadCmd(W25Q_MANUFACTURER_DEVICE_ID, au8Dummy, 3U, au8TempId, 2U);
|
|
||||||
|
|
||||||
u16ManID = (uint16_t)au8TempId[0U] << 8U;
|
|
||||||
u16ManID |= au8TempId[1U];
|
|
||||||
|
|
||||||
return u16ManID;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Read unique ID.
|
|
||||||
* @param [out] pu8UniqueId Pointer to a buffer the 64 bit unique ID to be stored.
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void W25QXX_ReadUniqueId(uint8_t *pu8UniqueId)
|
|
||||||
{
|
|
||||||
uint8_t au8Dummy[4U] = {0U};
|
|
||||||
|
|
||||||
W25QXX_ReadCmd(W25Q_READ_UNIQUE_ID, au8Dummy, 4U, pu8UniqueId, 8U);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief W25QXX read status register.
|
|
||||||
* @param None
|
|
||||||
* @retval 16 bit W25QXX status.
|
|
||||||
*/
|
|
||||||
uint16_t W25QXX_ReadStatus(void)
|
|
||||||
{
|
|
||||||
uint8_t u8TempStatus;
|
|
||||||
uint16_t u16RetStatus;
|
|
||||||
|
|
||||||
W25QXX_ReadCmd(W25Q_READ_STATUS_REG_2, NULL, 0U, &u8TempStatus, 1U);
|
|
||||||
|
|
||||||
u16RetStatus = u8TempStatus;
|
|
||||||
|
|
||||||
W25QXX_ReadCmd(W25Q_READ_STATUS_REG_1, NULL, 0U, &u8TempStatus, 1U);
|
|
||||||
|
|
||||||
u16RetStatus <<= 8U;
|
|
||||||
u16RetStatus |= u8TempStatus;
|
|
||||||
|
|
||||||
return u16RetStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief W25QXX write status register
|
|
||||||
* @param [in] u16Status Specified status.
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void W25QXX_WriteStatus(uint16_t u16Status)
|
|
||||||
{
|
|
||||||
uint8_t au8Data[2U];
|
|
||||||
|
|
||||||
au8Data[0U] = (uint8_t)u16Status;
|
|
||||||
au8Data[1U] = (uint8_t)(u16Status >> 8U);
|
|
||||||
|
|
||||||
W25QXX_WriteCmd(W25Q_WRITE_STATUS_REG, au8Data, 2U);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief W25QXX power down.
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void W25QXX_PowerDown(void)
|
|
||||||
{
|
|
||||||
W25QXX_WriteCmd(W25Q_POWER_DOWN, NULL, 0U);
|
|
||||||
|
|
||||||
W25QXX_DELAY_MS(1U);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief W25QXX release power down.
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void W25QXX_ReleasePowerDown(void)
|
|
||||||
{
|
|
||||||
W25QXX_WriteCmd(W25Q_RELEASE_POWER_DOWN, NULL, 0U);
|
|
||||||
|
|
||||||
W25QXX_DELAY_MS(1U);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief W25QXX chip ease.
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void W25QXX_EraseChip(void)
|
|
||||||
{
|
|
||||||
W25QXX_WriteEnable();
|
|
||||||
W25QXX_WaitBusy();
|
|
||||||
W25QXX_WriteCmd(W25Q_CHIP_ERASE, NULL, 0U);
|
|
||||||
W25QXX_WaitBusy();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief W25QXX sector ease.
|
|
||||||
* @param [in] u32SectorAddress The address of the specified sector.
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void W25QXX_EraseSector(uint32_t u32SectorAddress)
|
|
||||||
{
|
|
||||||
u32SectorAddress *= W25Q_SIZE_SECTOR;
|
|
||||||
|
|
||||||
W25QXX_WriteEnable();
|
|
||||||
W25QXX_WaitBusy();
|
|
||||||
|
|
||||||
W25QXX_Wt(W25Q_SECTOR_ERASE, u32SectorAddress, NULL, 0U);
|
|
||||||
|
|
||||||
W25QXX_WaitBusy();
|
|
||||||
W25QXX_WriteDisable();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief W25QXX block ease.
|
|
||||||
* @param [in] u32BlockAddress The address of the specified block.
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void W25QXX_EraseBlock(uint32_t u32BlockAddress)
|
|
||||||
{
|
|
||||||
W25QXX_Wt(W25Q_BLOCK_ERASE_64K, u32BlockAddress, NULL, 0U);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief W25QXX flash write
|
|
||||||
* @param [in] pBuffer Data buffer to be written
|
|
||||||
* @param [in] WriteAddr Address to be written
|
|
||||||
* @param [in] NumByteToWrite Number to be written, (MAX. 65535)
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void W25QXX_Write_NoCheck(const uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
|
|
||||||
{
|
|
||||||
uint32_t pageremain;
|
|
||||||
uint32_t u32BufAdrTmp = (uint32_t)pBuffer;
|
|
||||||
pageremain = 256U - WriteAddr % 256U;
|
|
||||||
if (NumByteToWrite <= pageremain)
|
|
||||||
{
|
|
||||||
pageremain = NumByteToWrite;
|
|
||||||
}
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
W25QXX_WritePage(WriteAddr, (uint8_t *)u32BufAdrTmp, pageremain);
|
|
||||||
if (NumByteToWrite == (uint16_t)pageremain)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else //NumByteToWrite>pageremain
|
|
||||||
{
|
|
||||||
u32BufAdrTmp += pageremain;
|
|
||||||
WriteAddr += pageremain;
|
|
||||||
|
|
||||||
NumByteToWrite -= (uint16_t)pageremain;
|
|
||||||
if (NumByteToWrite > 256U)
|
|
||||||
{
|
|
||||||
pageremain = 256U;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pageremain = (uint32_t)NumByteToWrite;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief W25QXX write data.
|
|
||||||
* @param [in] u32Address The start address of the data to be written.
|
|
||||||
* @param [in] pu8WriteBuf The pointer to the buffer contains the data to be written.
|
|
||||||
* @param [in] u32NumByteToWrite Buffer size in bytes.
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void W25QXX_WriteData(uint32_t u32Address, const uint8_t *pu8WriteBuf, uint32_t u32NumByteToWrite)
|
|
||||||
{
|
|
||||||
uint32_t secpos;
|
|
||||||
uint16_t secoff;
|
|
||||||
uint16_t secremain;
|
|
||||||
uint16_t i;
|
|
||||||
uint8_t *pW25QXX_BUF;
|
|
||||||
pW25QXX_BUF = W25QXX_BUFFER;
|
|
||||||
uint32_t u32WriteBufAddr = (uint32_t)&pu8WriteBuf;
|
|
||||||
|
|
||||||
secpos = u32Address / 4096U;
|
|
||||||
secoff = (uint16_t)(u32Address % 4096U);
|
|
||||||
secremain = 4096U - secoff;
|
|
||||||
|
|
||||||
if (u32NumByteToWrite <= secremain)
|
|
||||||
{
|
|
||||||
secremain = (uint16_t)u32NumByteToWrite;
|
|
||||||
}
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
W25QXX_ReadData(secpos * 4096U, pW25QXX_BUF, 4096U); // read one sector content
|
|
||||||
for (i = 0U; i < secremain; i++) // check if blank sector
|
|
||||||
{
|
|
||||||
if (pW25QXX_BUF[secoff + i] != (uint8_t)0xFFU)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i < secremain)
|
|
||||||
{
|
|
||||||
W25QXX_EraseSector(secpos); // not blank, need erase
|
|
||||||
for (i = 0U; i < secremain; i++) // backup first
|
|
||||||
{
|
|
||||||
pW25QXX_BUF[i + secoff] = pu8WriteBuf[i];
|
|
||||||
}
|
|
||||||
W25QXX_Write_NoCheck(pW25QXX_BUF, secpos * 4096U, 4096U); // write back after erase
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
W25QXX_Write_NoCheck((const uint8_t *)u32WriteBufAddr, u32Address, secremain);
|
|
||||||
}
|
|
||||||
if (u32NumByteToWrite == secremain)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
secpos++; // next sector
|
|
||||||
secoff = 0U;
|
|
||||||
|
|
||||||
u32WriteBufAddr += secremain;
|
|
||||||
u32Address += secremain;
|
|
||||||
u32NumByteToWrite -= secremain;
|
|
||||||
if (u32NumByteToWrite > 4096U)
|
|
||||||
{
|
|
||||||
secremain = 4096U;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
secremain = (uint16_t)u32NumByteToWrite;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief W25QXX read data.
|
|
||||||
* @param [in] u32Address The start address of the data to be read.
|
|
||||||
* @param [in] pu8ReadBuf The pointer to the buffer contains the data to be stored.
|
|
||||||
* @param [in] u32NumByteToRead Buffer size in bytes.
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void W25QXX_ReadData(uint32_t u32Address, uint8_t *pu8ReadBuf, uint32_t u32NumByteToRead)
|
|
||||||
{
|
|
||||||
W25QXX_Rd(W25Q_READ_DATA, u32Address, pu8ReadBuf, u32NumByteToRead);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @addtogroup W25QXX_Local_Functions W25QXX Local Functions
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief W25QXX write command.
|
|
||||||
* @param [in] u8Cmd Command of W25QXX.
|
|
||||||
* @param [in] pu8CmdData Pointer to a buffer that contains the data following the command.
|
|
||||||
* @param [in] u32CmdDataLength The length of the command data in bytes.
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void W25QXX_WriteCmd(uint8_t u8Cmd, const uint8_t *pu8CmdData, uint32_t u32CmdDataLength)
|
|
||||||
{
|
|
||||||
W25Q_CS_ACTIVE();
|
|
||||||
(void)BSP_W25Q_SPI_Transmit(&u8Cmd, 1U);
|
|
||||||
(void)BSP_W25Q_SPI_Transmit(pu8CmdData, u32CmdDataLength);
|
|
||||||
W25Q_CS_INACTIVE();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief W25QXX read command.
|
|
||||||
* @param [in] u8Cmd Command of W25QXX.
|
|
||||||
* @param [in] pu8CmdData Pointer to a buffer that contains the data following the command.
|
|
||||||
* @param [in] u32CmdDataLength The length of the command data in bytes.
|
|
||||||
* @param [in] pu8Info The information of the command.
|
|
||||||
* @param [in] u8InfoLength The length of the information.
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void W25QXX_ReadCmd(uint8_t u8Cmd, uint8_t *pu8CmdData, uint32_t u32CmdDataLength,
|
|
||||||
uint8_t *pu8Info, uint8_t u8InfoLength)
|
|
||||||
{
|
|
||||||
W25Q_CS_ACTIVE();
|
|
||||||
(void)BSP_W25Q_SPI_Transmit(&u8Cmd, 1U);
|
|
||||||
(void)BSP_W25Q_SPI_Transmit(pu8CmdData, u32CmdDataLength);
|
|
||||||
(void)BSP_W25Q_SPI_Receive(pu8Info, (uint32_t)u8InfoLength);
|
|
||||||
W25Q_CS_INACTIVE();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief W25QXX write data.
|
|
||||||
* @param [in] u8Cmd Command of W25QXX.
|
|
||||||
* @param [in] u32Address The start address of the data to be written.
|
|
||||||
* @param [in] pu8Data The data to be written.
|
|
||||||
* @param [in] u32DataLength The length of the data in bytes.
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void W25QXX_Wt(uint8_t u8Cmd, uint32_t u32Address, const uint8_t *pu8Data, uint32_t u32DataLength)
|
|
||||||
{
|
|
||||||
uint8_t au8Cmd[4U];
|
|
||||||
|
|
||||||
LOAD_CMD(au8Cmd, u8Cmd, u32Address);
|
|
||||||
|
|
||||||
W25Q_CS_ACTIVE();
|
|
||||||
(void)BSP_W25Q_SPI_Transmit(au8Cmd, 4U);
|
|
||||||
(void)BSP_W25Q_SPI_Transmit(pu8Data, u32DataLength);
|
|
||||||
W25Q_CS_INACTIVE();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief W25QXX read data.
|
|
||||||
* @param [in] u8Cmd Command of W25QXX.
|
|
||||||
* @param [in] u32Address The start address of the data to be written.
|
|
||||||
* @param [in] pu8Data The data to be stored.
|
|
||||||
* @param [in] u32DataLength The length of the data in bytes.
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void W25QXX_Rd(uint8_t u8Cmd, uint32_t u32Address, uint8_t *pu8Data, uint32_t u32DataLength)
|
|
||||||
{
|
|
||||||
uint8_t au8Cmd[4U];
|
|
||||||
|
|
||||||
LOAD_CMD(au8Cmd, u8Cmd, u32Address);
|
|
||||||
|
|
||||||
W25Q_CS_ACTIVE();
|
|
||||||
(void)BSP_W25Q_SPI_Transmit(au8Cmd, 4U);
|
|
||||||
(void)BSP_W25Q_SPI_Receive(pu8Data, u32DataLength);
|
|
||||||
W25Q_CS_INACTIVE();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief W25QXX Write enable.
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void W25QXX_WriteEnable(void)
|
|
||||||
{
|
|
||||||
W25QXX_WriteCmd(W25Q_WRITE_ENABLE, NULL, 0U);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief W25QXX Write disable.
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void W25QXX_WriteDisable(void)
|
|
||||||
{
|
|
||||||
W25QXX_WriteCmd(W25Q_WRITE_DISABLE, NULL, 0U);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Wait while W25QXX is busy.
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void W25QXX_WaitBusy(void)
|
|
||||||
{
|
|
||||||
while ((W25QXX_ReadStatus() & W25Q_ST_BUSY) == W25Q_ST_BUSY)
|
|
||||||
{
|
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief W25QXX page program.
|
|
||||||
* @param [in] u32Address Start address of the page.
|
|
||||||
* @param [in] pu8Data Pointer to a buffer that contains the data to be written.
|
|
||||||
* @param [in] u32DataLength Size of the buffer in bytes.
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void W25QXX_WritePage(uint32_t u32Address, const uint8_t *pu8Data, uint32_t u32DataLength)
|
|
||||||
{
|
|
||||||
W25QXX_WriteEnable();
|
|
||||||
W25QXX_Wt(W25Q_PAGE_PROGRAM, u32Address, pu8Data, u32DataLength);
|
|
||||||
W25QXX_WaitBusy();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif /* BSP_W25QXX_ENABLE */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* EOF (not truncated)
|
|
||||||
******************************************************************************/
|
|
|
@ -1,197 +0,0 @@
|
||||||
/**
|
|
||||||
*******************************************************************************
|
|
||||||
* @file w25qxx.h
|
|
||||||
* @brief This file provides firmware functions to W25QXX group spi flash.
|
|
||||||
@verbatim
|
|
||||||
Change Logs:
|
|
||||||
Date Author Notes
|
|
||||||
2020-06-12 Wangmin First version
|
|
||||||
@endverbatim
|
|
||||||
*******************************************************************************
|
|
||||||
* Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
|
|
||||||
*
|
|
||||||
* This software component is licensed by HDSC under BSD 3-Clause license
|
|
||||||
* (the "License"); You may not use this file except in compliance with the
|
|
||||||
* License. You may obtain a copy of the License at:
|
|
||||||
* opensource.org/licenses/BSD-3-Clause
|
|
||||||
*
|
|
||||||
*******************************************************************************
|
|
||||||
*/
|
|
||||||
#ifndef __W25QXX_H__
|
|
||||||
#define __W25QXX_H__
|
|
||||||
|
|
||||||
/* C binding of definitions if building with C++ compiler */
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Include files
|
|
||||||
******************************************************************************/
|
|
||||||
#include "hc32_common.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @addtogroup BSP
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @addtogroup Components
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @addtogroup W25QXX
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if (BSP_W25QXX_ENABLE == BSP_ON)
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Global type definitions ('typedef')
|
|
||||||
******************************************************************************/
|
|
||||||
/**
|
|
||||||
* @defgroup W25QXX_Global_Types W25QXX Global Types
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Structure definition of W25QXX information.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t u16ManId; /*!< Manufacturer device ID. */
|
|
||||||
uint8_t au8UniqueId[8U]; /*!< 64 bit unique ID number. */
|
|
||||||
uint32_t u32PageCount;
|
|
||||||
uint32_t u32SectorCount;
|
|
||||||
uint32_t u32BlockCount32k;
|
|
||||||
uint32_t u32BlockCount64k;
|
|
||||||
uint32_t u32CapacityInBytes;
|
|
||||||
uint32_t u32CapacityInKB;
|
|
||||||
} stc_w25qxx_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Global pre-processor symbols/macros ('#define')
|
|
||||||
******************************************************************************/
|
|
||||||
/**
|
|
||||||
* @defgroup W25QXX_Global_Macros W25QXX Global Macros
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup W25QXX_ID W25QXX ID
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
#define W25Q80 (0xEF13U)
|
|
||||||
#define W25Q16 (0xEF14U)
|
|
||||||
#define W25Q32 (0xEF15U)
|
|
||||||
#define W25Q64 (0xEF16U)
|
|
||||||
#define W25Q128 (0xEF17U)
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup W25QXX_Command W25QXX Command
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
#define W25Q_WRITE_ENABLE ((uint8_t)0x06U)
|
|
||||||
#define W25Q_VOLATILE_SR_WRITE_ENABLE ((uint8_t)0x50U)
|
|
||||||
#define W25Q_WRITE_DISABLE ((uint8_t)0x04U)
|
|
||||||
#define W25Q_READ_STATUS_REG_1 ((uint8_t)0x05U)
|
|
||||||
#define W25Q_READ_STATUS_REG_2 ((uint8_t)0x35U)
|
|
||||||
#define W25Q_WRITE_STATUS_REG ((uint8_t)0x01U)
|
|
||||||
#define W25Q_PAGE_PROGRAM ((uint8_t)0x02U)
|
|
||||||
#define W25Q_SECTOR_ERASE ((uint8_t)0x20U)
|
|
||||||
#define W25Q_BLOCK_ERASE_32K ((uint8_t)0x52U)
|
|
||||||
#define W25Q_BLOCK_ERASE_64K ((uint8_t)0xD8U)
|
|
||||||
#define W25Q_CHIP_ERASE ((uint8_t)0xC7U)
|
|
||||||
#define W25Q_ERASE_PROGRAM_SUSPEND ((uint8_t)0x75U)
|
|
||||||
#define W25Q_ERASE_PROGRAM_RESUME ((uint8_t)0x7AU)
|
|
||||||
#define W25Q_POWER_DOWN ((uint8_t)0xB9U)
|
|
||||||
#define W25Q_READ_DATA ((uint8_t)0x03U)
|
|
||||||
#define W25Q_FAST_READ ((uint8_t)0x0BU)
|
|
||||||
#define W25Q_DEVICE_ID ((uint8_t)0xABU)
|
|
||||||
#define W25Q_RELEASE_POWER_DOWN (W25Q_DEVICE_ID)
|
|
||||||
#define W25Q_MANUFACTURER_DEVICE_ID ((uint8_t)0x90U)
|
|
||||||
#define W25Q_JEDEC_ID ((uint8_t)0x9FU)
|
|
||||||
#define W25Q_READ_UNIQUE_ID ((uint8_t)0x4BU)
|
|
||||||
#define W25Q_READ_SFDP_REG ((uint8_t)0x5AU)
|
|
||||||
#define W25Q_REASE_SECURITY_REG ((uint8_t)0x44U)
|
|
||||||
#define W25Q_PROGRAM_SECURITY_REG ((uint8_t)0x42U)
|
|
||||||
#define W25Q_READ_SECURITY_REG ((uint8_t)0x48U)
|
|
||||||
#define W25Q_ENABLE_QPI ((uint8_t)0x38U)
|
|
||||||
#define W25Q_ENABLE_RESET ((uint8_t)0x66U)
|
|
||||||
#define W25Q_RESET ((uint8_t)0x99U)
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define W25Q_SIZE_1K (1024U) /*!< 1KB */
|
|
||||||
#define W25Q_SIZE_PAGE (256U) /*!< 256B/page */
|
|
||||||
#define W25Q_SIZE_SECTOR (W25Q_SIZE_1K * 4U) /*!< 4KB/sector */
|
|
||||||
#define W25Q_SIZE_BLOCK (W25Q_SIZE_1K * 64U) /*!< 64KB/block */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Global variable definitions ('extern')
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
Global function prototypes (definition in C source)
|
|
||||||
******************************************************************************/
|
|
||||||
/**
|
|
||||||
* @addtogroup W25QXX_Global_Functions W25QXX Global Functions
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
void W25QXX_Init(stc_w25qxx_t *pstcW25qxx);
|
|
||||||
uint16_t W25QXX_ReadManDeviceId(void);
|
|
||||||
void W25QXX_ReadUniqueId(uint8_t *pu8UniqueId);
|
|
||||||
|
|
||||||
uint16_t W25QXX_ReadStatus(void);
|
|
||||||
void W25QXX_WriteStatus(uint16_t u16Status);
|
|
||||||
void W25QXX_PowerDown(void);
|
|
||||||
void W25QXX_ReleasePowerDown(void);
|
|
||||||
|
|
||||||
void W25QXX_EraseChip(void);
|
|
||||||
void W25QXX_EraseSector(uint32_t u32SectorAddress);
|
|
||||||
void W25QXX_EraseBlock(uint32_t u32BlockAddress);
|
|
||||||
|
|
||||||
void W25QXX_WriteData(uint32_t u32Address, const uint8_t *pu8WriteBuf, uint32_t u32NumByteToWrite);
|
|
||||||
void W25QXX_ReadData(uint32_t u32Address, uint8_t *pu8ReadBuf, uint32_t u32NumByteToRead);
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* BSP_W25QXX_ENABLE */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __W25QXX_H__ */
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* EOF (not truncated)
|
|
||||||
******************************************************************************/
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
menu "TableStorage"
|
||||||
|
|
||||||
|
config TABLE_STORAGE
|
||||||
|
bool "Using Table storage system"
|
||||||
|
default n
|
||||||
|
|
||||||
|
if TABLE_STORAGE
|
||||||
|
|
||||||
|
config TABLE_STORAGE_BASIC
|
||||||
|
bool "Enable TableStorage Basic"
|
||||||
|
default y
|
||||||
|
|
||||||
|
config TABLE_STORAGE_QUERY
|
||||||
|
bool "[System-level] Enable TableStorage Buffer"
|
||||||
|
default n
|
||||||
|
|
||||||
|
config TABLE_STORAGE_CACHE
|
||||||
|
bool "[System-level] Enable TableStorage Prefetcher"
|
||||||
|
default n
|
||||||
|
|
||||||
|
config TABLE_STORAGE_PREFETCH
|
||||||
|
bool "[Table-level] Enable TableStorage Query Cache"
|
||||||
|
default n
|
||||||
|
|
||||||
|
config TABLE_STORAGE_SECOND_INDEX
|
||||||
|
bool "[Table-level] Enable TableStorage Second Index"
|
||||||
|
default n
|
||||||
|
|
||||||
|
config TABLE_STORAGE_TRANSACTION
|
||||||
|
bool "(Other) Enable TableStorage Transaction"
|
||||||
|
default n
|
||||||
|
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
endmenu
|
|
@ -0,0 +1,153 @@
|
||||||
|
## README
|
||||||
|
|
||||||
|
TableStorage是一款面向泛在操作系统的轻量级表存储原型系统。TableStorage专注于泛在操作系统场景下结构化数据的存储,与传统的多层堆叠式软件栈(数据库 + 文件系统)不同,TableStorage避免过度分层,从存储全栈角度,进行跨层(数据库的存储引擎 + 文件系统)的设计,主要包含以下三个属性
|
||||||
|
|
||||||
|
- 低冗余:去除文件抽象并直接将“表”存储到设备中, 避免功能冗余和不必要的软件开销
|
||||||
|
- 兼容性:提供一组通用的API 以支持表级的存取操作,与传统数据库中的读写操作兼容
|
||||||
|
- 可集成:支持组件的深度集成,具体来说, 可以集成事务和执行引擎以满足复杂的事务和查询处理需求
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### 开发板
|
||||||
|
|
||||||
|
- K210最小系统板(Max bit)
|
||||||
|
|
||||||
|
- SD卡配置
|
||||||
|
|
||||||
|
| 引脚 | 作用 | RW007板子 |
|
||||||
|
| :----------------: | :-------: | :-------: |
|
||||||
|
| io 27(印丝标注SCK) | SPI1_SCK | SCK |
|
||||||
|
| io 26(印丝标注SO) | SPI1_MISO | MISO |
|
||||||
|
| io 28(印丝标注SI) | SPI1_MOSI | MOSI |
|
||||||
|
| io 29 | CS/BOOT1 | CS |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### 编译说明
|
||||||
|
|
||||||
|
- 环境搭建
|
||||||
|
|
||||||
|
- 参考https://gitlink.org.cn/xuos/xiuos/tree/prepare_for_master/Ubiquitous%2FXiZi_IIoT%2Fboard%2Fkd233下的**开发环境搭建**小节,搭建好XiUOS的开发环境
|
||||||
|
|
||||||
|
- 参考https://gitlink.org.cn/xuos/xiuos/tree/prepare_for_master/Ubiquitous%2FRT-Thread_Fusion_XiUOS%2Faiit_board%2Fk210搭建好XiUOS-RTThread的开发环境
|
||||||
|
|
||||||
|
- 配置XiUOS-RTThread基本环境
|
||||||
|
|
||||||
|
- SD卡的配置:按照上表SD卡引脚说明配置
|
||||||
|
|
||||||
|
<img src="pic/image-20221123215723700.png" alt="image-20221123215723700" style="zoom: 33%;" />
|
||||||
|
|
||||||
|
- 其他推荐配置
|
||||||
|
|
||||||
|
<img src="pic/image-20221123215509060.png" alt="image-20221123215509060" style="zoom: 50%;" />
|
||||||
|
|
||||||
|
- (可选)如果编译时,出现定时器错误,则可以选择使用软件定时器
|
||||||
|
|
||||||
|
<img src="pic/image-20221123215939427.png" alt="image-20221123215939427" style="zoom: 33%;" />
|
||||||
|
|
||||||
|
- 配置TableStorage
|
||||||
|
|
||||||
|
```shell
|
||||||
|
scons --menuconfig
|
||||||
|
```
|
||||||
|
|
||||||
|
- 若不开启TableStorage组件,则自动在SD卡上使用FATFS
|
||||||
|
|
||||||
|
- 若开启TableStorage组件,则在SD卡上使用TableStorage,默认打开了Enable TableStorage Basic模块(注:当前版本仅支持Basic模块)
|
||||||
|
|
||||||
|
<img src="pic/image-20221123213344406.png" alt="image-20221123213344406" style="zoom: 33%;" />
|
||||||
|
|
||||||
|
- 执行 scons 编译,若编译正确无误,在当前文件夹下生成rtthread.elf、rtthread.bin。其中rtthread.bin需要烧写到设备中进行运行
|
||||||
|
|
||||||
|
- 烧录及运行结果图
|
||||||
|
|
||||||
|
```shell
|
||||||
|
sudo kflash -t rtthread.bin -p /dev/ttyUSB0
|
||||||
|
```
|
||||||
|
|
||||||
|
- 烧录并运行无误,则
|
||||||
|
|
||||||
|
<img src="pic/image-20221123215143184.png" alt="image-20221123215143184" style="zoom: 33%;" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### 调试
|
||||||
|
|
||||||
|
- 修改k210/rtconfig.py中的BUILD选项来配置debug模式,并重新编译
|
||||||
|
|
||||||
|
- 安装openocd(下载ubuntu版本64位),
|
||||||
|
|
||||||
|
- 下载地址:[Releases · kendryte/openocd-kendryte (github.com)](https://github.com/kendryte/openocd-kendryte/releases),推荐下载地址为:http://101.36.126.201:8011/kendryte-openocd-0.2.3-ubuntu64.tar.gz
|
||||||
|
|
||||||
|
- 安装
|
||||||
|
|
||||||
|
```shell
|
||||||
|
sudo apt install libusb-dev libftdi-dev libhidapi-dev
|
||||||
|
sudo mv kendryte-openocd-0.2.3-ubuntu64.tar.gz /opt
|
||||||
|
cd /opt
|
||||||
|
sudo tar -zxvf kendryte-openocd-0.2.3-ubuntu64.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
- 修改配置文件
|
||||||
|
|
||||||
|
sudo vim /opt/kendryte-openocd/tcl/k210.cfg,并复制以下内容
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# SiPEED USB-JTAG/TTL
|
||||||
|
interface ftdi
|
||||||
|
ftdi_device_desc "Dual RS232"
|
||||||
|
ftdi_vid_pid 0x0403 0x6010
|
||||||
|
ftdi_layout_init 0x0508 0x0f1b
|
||||||
|
ftdi_layout_signal nTRST -data 0x0200 -noe 0x0100
|
||||||
|
ftdi_layout_signal nSRST -data 0x0800 -noe 0x0400
|
||||||
|
|
||||||
|
jtag_rclk 3000
|
||||||
|
|
||||||
|
# server port
|
||||||
|
gdb_port 9999
|
||||||
|
telnet_port 4444
|
||||||
|
|
||||||
|
# add cpu target
|
||||||
|
set _CHIPNAME riscv
|
||||||
|
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x04e4796b
|
||||||
|
|
||||||
|
set _TARGETNAME $_CHIPNAME.cpu
|
||||||
|
target create $_TARGETNAME riscv -chain-position $_TARGETNAME
|
||||||
|
|
||||||
|
# command
|
||||||
|
init
|
||||||
|
if {[ info exists pulse_srst]} {
|
||||||
|
ftdi_set_signal nSRST 0
|
||||||
|
ftdi_set_signal nSRST 1
|
||||||
|
ftdi_set_signal nSRST z
|
||||||
|
}
|
||||||
|
halt
|
||||||
|
```
|
||||||
|
|
||||||
|
- 调试器和Max bit开发板的硬件连线
|
||||||
|
|
||||||
|
<img src="pic/image-20221123220234259.png" alt="image-20221123220234259" style="zoom: 33%;" />
|
||||||
|
|
||||||
|
- 启动调试器
|
||||||
|
|
||||||
|
```shell
|
||||||
|
sudo /opt/kendryte-openocd/bin/openocd -f /opt/kendryte-openocd/tcl/k210.cfg
|
||||||
|
```
|
||||||
|
|
||||||
|
<img src="pic/image-20221123221828637.png" alt="image-20221123221828637" style="zoom: 33%;" />
|
||||||
|
|
||||||
|
- 在Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210目录下,连接调试器
|
||||||
|
|
||||||
|
```shell
|
||||||
|
/opt/xpack-riscv-none-embed-gcc-10.2.0-1.2/bin/riscv-none-embed-gdb rtthread.elf --eval-command="target remote 127.0.0.1:9999"
|
||||||
|
```
|
||||||
|
|
||||||
|
- gdb终端调试
|
||||||
|
|
||||||
|
<img src="pic/image-20221123222125802.png" alt="image-20221123222125802" style="zoom: 33%;" />
|
||||||
|
|
||||||
|
<img src="pic/image-20221123223127817.png" alt="image-20221123223127817" style="zoom:33%;" />
|
||||||
|
|
||||||
|
- vscode调试
|
||||||
|
|
||||||
|
<img src="pic/image-20221123225705614.png" alt="image-20221123225705614" style="zoom:33%;" />
|
|
@ -0,0 +1,26 @@
|
||||||
|
from building import *
|
||||||
|
|
||||||
|
# get current directory
|
||||||
|
cwd = GetCurrentDir()
|
||||||
|
|
||||||
|
# the set of source files associated with this SConscript file.
|
||||||
|
src = Glob('src/common/*.cc')
|
||||||
|
src += Glob('src/execution/*.cc')
|
||||||
|
src += Glob('src/storage/*.cc')
|
||||||
|
|
||||||
|
# compile optional modules
|
||||||
|
if GetDepend(['TABLE_STORAGE_CACHE']):
|
||||||
|
src += ['src/modules/prefetcher.cc']
|
||||||
|
if GetDepend(['TABLE_STORAGE_CACHE']):
|
||||||
|
src += ['src/modules/queryCache.cc']
|
||||||
|
if GetDepend(['TABLE_STORAGE_CACHE']):
|
||||||
|
src += ['src/modules/buffer.cc']
|
||||||
|
if GetDepend(['TABLE_STORAGE_CACHE']):
|
||||||
|
src += ['src/modules/secondIndex.cc']
|
||||||
|
|
||||||
|
# include path
|
||||||
|
path = [cwd + '/include']
|
||||||
|
|
||||||
|
group = DefineGroup('TableStorage', src, depend = ['TABLE_STORAGE'], CPPPATH = path)
|
||||||
|
|
||||||
|
Return('group')
|
|
@ -0,0 +1,35 @@
|
||||||
|
/**
|
||||||
|
* @file BufferItem.h
|
||||||
|
* @brief BufferItem
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BUFFERITEM_H
|
||||||
|
#define BUFFERITEM_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
class BufferItem {
|
||||||
|
public:
|
||||||
|
BufferItem(uint64_t tableID);
|
||||||
|
|
||||||
|
virtual ~BufferItem();
|
||||||
|
|
||||||
|
// virtual void flush() const = 0;
|
||||||
|
|
||||||
|
uint64_t getTableID() { return tableID; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint64_t tableID;
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(BufferItem);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LightTable
|
||||||
|
|
||||||
|
#endif // BUFFERITEM_H
|
|
@ -0,0 +1,144 @@
|
||||||
|
/**
|
||||||
|
* @file Common.h
|
||||||
|
* @brief parameter configuration
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
#ifndef COMMON_H
|
||||||
|
#define COMMON_H
|
||||||
|
|
||||||
|
#include <rtconfig.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
#define YCSB_TEST
|
||||||
|
|
||||||
|
extern int cacheReadNum;
|
||||||
|
extern int cacheWriteNum;
|
||||||
|
|
||||||
|
extern std::chrono::steady_clock::time_point start_time;
|
||||||
|
extern std::chrono::steady_clock::time_point end_time;
|
||||||
|
extern double diff_sdcard_read;
|
||||||
|
extern double diff_sdcard_write;
|
||||||
|
|
||||||
|
#define SYSTEM_MAX_CORES 0
|
||||||
|
#define SYSTEM_MAX_IO_QUEUES 8
|
||||||
|
|
||||||
|
#ifndef YCSB_TEST
|
||||||
|
#define NETWORK_MESSAGE_DATA_MAX_SIZE 4088
|
||||||
|
#define NETWORK_TRANSMIT_MAX_SIZE 4096
|
||||||
|
#else
|
||||||
|
#define NETWORK_MESSAGE_DATA_MAX_SIZE 51192
|
||||||
|
#define NETWORK_TRANSMIT_MAX_SIZE 51200
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SDCARD_TEST_WRITE_BLOCKID 200
|
||||||
|
#define SDCARD_TEST_READ_BLOCKID 1000
|
||||||
|
#define SDCARD_TEST_NUM 10000
|
||||||
|
|
||||||
|
#define HASH_BUCKET_SIZE 50
|
||||||
|
#define CACHE_SIZE 500
|
||||||
|
|
||||||
|
#define SEGMENT_TYPE_SMALL_BITMAP_SIZE 32768
|
||||||
|
#define SEGMENT_TYPE_MEDIUM_BITMAP_SIZE 4096
|
||||||
|
#ifndef YCSB_TEST
|
||||||
|
#define SEGMENT_TYPE_BIG_BITMAP_SIZE 512
|
||||||
|
#else
|
||||||
|
#define SEGMENT_TYPE_BIG_BITMAP_SIZE 512
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SEGMENT_TYPE_SMALL_START 64
|
||||||
|
#define SEGMENT_TYPE_MEDIUM_START 2097216
|
||||||
|
#define SEGMENT_TYPE_BIG_START 6291528
|
||||||
|
|
||||||
|
#define SEGMENT_TYPE_SMALL_CELL_SIZE 4096
|
||||||
|
#define SEGMENT_TYPE_MEDIUM_CELL_SIZE 65536
|
||||||
|
#ifndef YCSB_TEST
|
||||||
|
#define SEGMENT_TYPE_BIG_CELL_SIZE 2097152
|
||||||
|
#else
|
||||||
|
#define SEGMENT_TYPE_BIG_CELL_SIZE 65536000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PREFETCH_BLOCK_SERIALIZED_LENGTH 33
|
||||||
|
|
||||||
|
#define MAX_BRANCH_COUNT 4
|
||||||
|
|
||||||
|
#define PRELOAD_BLOCK_COUNT 10
|
||||||
|
#define PRELOAD_CHECK_INTERVAL_US 50
|
||||||
|
|
||||||
|
#define BLOCK_SIZE 512
|
||||||
|
|
||||||
|
#ifndef YCSB_TEST
|
||||||
|
#define BUFFER_SIZE 200
|
||||||
|
#else
|
||||||
|
#define BUFFER_SIZE 300000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CACHED_PAGE_COUNT 100
|
||||||
|
|
||||||
|
#define ROOTTABLE_TUPLE_SIZE sizeof(RootTable::TableTuple)
|
||||||
|
|
||||||
|
#define TABLE_ID_SIZE sizeof(uint64_t)
|
||||||
|
|
||||||
|
#define SYSTEM_TABLE_COUNT 1
|
||||||
|
#define ROOTTABLE_TABLE_ID 1
|
||||||
|
#define ROOTTABLE_SEGMENT_ID 1
|
||||||
|
#define ROOTTABLE_FIRST_BLOCK_ID 14680164
|
||||||
|
|
||||||
|
#define TABLE1_META_BLOCKID 1000
|
||||||
|
#define TABLE1_META_LOG_BLOCKID 10000
|
||||||
|
#define TABLE1_INDEX_BLOCKID 2000
|
||||||
|
#define TABLE1_INDEX_LOG_BLOCKID 20000
|
||||||
|
#define TABLE1_DATA_LOG_BLOCKID 30000
|
||||||
|
#define META_ENTRY_NUM 8
|
||||||
|
#define META_ENTRY_SIZE 64
|
||||||
|
#define BUFFER_MAX 4096
|
||||||
|
#define COMMON_TABLE_START_ID 101
|
||||||
|
#define YCSB_TABLE_ID 100
|
||||||
|
#define TABLE_NAME_LENGTH 32
|
||||||
|
#define PRIMARY_KEY_LENGTH 128
|
||||||
|
#define FILE_PATH_LENGTH 1024
|
||||||
|
#define FILE_NAME_LENGTH 128
|
||||||
|
#define USER_NAME_LENGTH 32
|
||||||
|
#define COLUMN_NAME_LENGTH 128
|
||||||
|
#define COLUMN_TYPE_NAME_LENGTH 32
|
||||||
|
|
||||||
|
#define PREFETCH_BLOCK_SERIALIZED_LENGTH 33
|
||||||
|
#define ROWMAP_SERIALIZED_LENGTH 42
|
||||||
|
#define SCHEMA_ENTRY_SERIALIZED_LENGTH 181
|
||||||
|
|
||||||
|
#define MAX_META_LENGTH 2048
|
||||||
|
|
||||||
|
#define MAX_PATH_LENGTH 128
|
||||||
|
const char METAPATH[MAX_PATH_LENGTH] = "../../data";
|
||||||
|
|
||||||
|
struct timespec diff(struct timespec start, struct timespec end);
|
||||||
|
|
||||||
|
class Queue {
|
||||||
|
public:
|
||||||
|
#ifdef IO_PROFILING
|
||||||
|
static struct timespec accumulate_io_times();
|
||||||
|
static struct timespec accumulate_io_submit_times();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IO_PROFILING
|
||||||
|
static std::queue<struct timespec> io_times;
|
||||||
|
static std::queue<struct timespec> io_submit_times;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
// A macro to disallow the copy constructor and operator= functions
|
||||||
|
#ifndef DISALLOW_COPY_AND_ASSIGN
|
||||||
|
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
||||||
|
TypeName(const TypeName &) = delete; \
|
||||||
|
TypeName &operator=(const TypeName &) = delete;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace LightTable
|
||||||
|
|
||||||
|
#endif // COMMON_H
|
|
@ -0,0 +1,35 @@
|
||||||
|
/**
|
||||||
|
* @file CommonTable.h
|
||||||
|
* @brief CommonTable
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COMMONTABLE_H
|
||||||
|
#define COMMONTABLE_H
|
||||||
|
|
||||||
|
#include "Table.h"
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
class CommonTable : public Table {
|
||||||
|
public:
|
||||||
|
CommonTable(uint64_t tableID, const char *tableName, uint64_t firstBlockID,
|
||||||
|
uint64_t segmentID, SegmentType segmentType,
|
||||||
|
std::vector<Schema::SchemaEntry> schemaEntrys,
|
||||||
|
bool usePrimaryKeyIndex = false);
|
||||||
|
|
||||||
|
CommonTable(uint64_t tableID, const char *tableName, uint64_t firstBlockID,
|
||||||
|
uint64_t segmentID, SegmentType segmentType,
|
||||||
|
bool usePrimaryKeyIndex = false);
|
||||||
|
|
||||||
|
friend class MetaHandle;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(CommonTable);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LightTable
|
||||||
|
|
||||||
|
#endif // COMMONTABLE_H
|
|
@ -0,0 +1,61 @@
|
||||||
|
/**
|
||||||
|
* @file Driver.h
|
||||||
|
* @brief driver
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
#ifndef DRIVER_H
|
||||||
|
#define DRIVER_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Error.h"
|
||||||
|
|
||||||
|
// #include <mutex>
|
||||||
|
// #include <pthread.h>
|
||||||
|
// #include <condition_variable>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
uint32_t MakeTableStorage(const char *device_name);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
class Driver {
|
||||||
|
public:
|
||||||
|
static uint32_t driver_init(const char *device_name);
|
||||||
|
|
||||||
|
static void driver_cleanup(const char *device_name);
|
||||||
|
|
||||||
|
static uint32_t driver_read(uint8_t *buf, uint64_t blockID);
|
||||||
|
|
||||||
|
static uint32_t driver_write(uint8_t *buf, uint64_t blockID);
|
||||||
|
|
||||||
|
static uint32_t read(uint8_t *buf, uint64_t blockID);
|
||||||
|
|
||||||
|
static uint32_t write(uint8_t *buf, uint64_t blockID);
|
||||||
|
|
||||||
|
Driver(){};
|
||||||
|
|
||||||
|
#ifdef TABLE_STORAGE_CACHE
|
||||||
|
static BlockCache *blkCache;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LightTable
|
||||||
|
|
||||||
|
#endif // DRIVER_H
|
|
@ -0,0 +1,62 @@
|
||||||
|
/**
|
||||||
|
* @file Error.h
|
||||||
|
* @brief error number
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ERROR_H
|
||||||
|
#define ERROR_H
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
enum ErrorCode {
|
||||||
|
SUCCESS = 0,
|
||||||
|
ERROR_TABLE = 1,
|
||||||
|
SEGMENT_TYPE_ERROR = 2,
|
||||||
|
SEGMENT_STATUS_ERROR = 3,
|
||||||
|
SEGMENT_IS_EXHAUSTED = 4,
|
||||||
|
BUCKET_ITEM_NOT_FOUND = 5,
|
||||||
|
ADD_BUCKET_ITEM_ERROR = 6,
|
||||||
|
PREFETCH_BLOCK_NOT_FOUND = 7,
|
||||||
|
GET_AVAILABLE_BLOCK_ERROR = 8,
|
||||||
|
BLOCK_OCCUPIED = 9,
|
||||||
|
ADD_ROW_MAP_ENTRY_ERROR = 10,
|
||||||
|
ROW_MAP_ENTRY_NOT_FOUND = 11,
|
||||||
|
ADD_SCHEMA_ENTRY_ERROR = 12,
|
||||||
|
SCHEMA_ENTRY_NOT_FOUND = 13,
|
||||||
|
COLUMN_ITEM_NOT_FOUND = 14,
|
||||||
|
COLUMN_ID_NOT_CONTINUOUS = 15,
|
||||||
|
DELETE_PARIMARY_KEY_COLUMN = 16,
|
||||||
|
TABLE_NOT_FOUND = 17,
|
||||||
|
TABLE_TUPLE_NOT_FOUND = 18,
|
||||||
|
ADD_TABLE_TUPLE_ERROR = 19,
|
||||||
|
BUFFER_EMPTY = 20,
|
||||||
|
TYPE_INVALID = 21,
|
||||||
|
ROWLOCATION_INVALID = 22,
|
||||||
|
CREATE_SOCKET_ERROR = 23,
|
||||||
|
INET_PTON_ERROR = 24,
|
||||||
|
BIND_SOCKET_ERROR = 25,
|
||||||
|
LISTEN_SOCKET_ERROR = 26,
|
||||||
|
ACCEPT_SOCKET_ERROR = 27,
|
||||||
|
CONNECT_SOCKET_ERROR = 28,
|
||||||
|
SEND_MESSAGE_ERROR = 29,
|
||||||
|
EVENT_TYPE_NOT_DEFINED = 30,
|
||||||
|
SCHEMA_NOT_EXIST = 31,
|
||||||
|
OPEN_META_FILE_ERROR = 32,
|
||||||
|
INVALID_META_FILE = 33,
|
||||||
|
INVALID_MEMORY_BLOCK_ID = 34,
|
||||||
|
UPDATE_TUPLE_ERROR = 35,
|
||||||
|
INVALID_PAGE_ID = 36,
|
||||||
|
ADD_QUERY_CACHE_ERROR = 37,
|
||||||
|
TRIE_LEAF_EXIST = 38,
|
||||||
|
TRIE_LEAF_NOT_EXIST = 39,
|
||||||
|
TRIE_LEAF_NOT_FOUND = 40,
|
||||||
|
INVALID_SCAN_RANGE = 41,
|
||||||
|
INVALID_PRELOAD_TASK = 42,
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LightTable
|
||||||
|
|
||||||
|
#endif // ERROR_H
|
|
@ -0,0 +1,59 @@
|
||||||
|
/**
|
||||||
|
* @file HashBucket.h
|
||||||
|
* @brief HashBucket
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HASHBUCKET_H
|
||||||
|
#define HASHBUCKET_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
// #include <pthread.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <map>
|
||||||
|
#include <iostream>
|
||||||
|
#include <utility>
|
||||||
|
// #include <mutex>
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Error.h"
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
typedef struct rowLocation {
|
||||||
|
uint64_t blockID;
|
||||||
|
uint64_t rowOffset;
|
||||||
|
} RowLocation;
|
||||||
|
|
||||||
|
class HashBucket {
|
||||||
|
public:
|
||||||
|
HashBucket();
|
||||||
|
|
||||||
|
uint32_t addBucketItem(uint64_t key, RowLocation rowLocation);
|
||||||
|
|
||||||
|
uint32_t deleteBucketItem(uint64_t key);
|
||||||
|
|
||||||
|
uint32_t updateRowLocation(uint64_t key, RowLocation rowLocation);
|
||||||
|
|
||||||
|
uint32_t getRowLocation(uint64_t key, RowLocation &rowLocation);
|
||||||
|
|
||||||
|
uint64_t getBucketSize();
|
||||||
|
|
||||||
|
uint32_t setBucketSize(uint64_t bucketSize);
|
||||||
|
|
||||||
|
uint32_t getAllBucketItems(std::map<uint64_t, RowLocation> &bucketItems);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<uint64_t, RowLocation> bucketItems;
|
||||||
|
uint64_t bucketSize;
|
||||||
|
// pthread_mutex_t mtx;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(HashBucket);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LightTable
|
||||||
|
|
||||||
|
#endif // HASHBUCKET_H
|
|
@ -0,0 +1,63 @@
|
||||||
|
/**
|
||||||
|
* @file HashTable.h
|
||||||
|
* @brief HashTable
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HASHTABLE_H
|
||||||
|
#define HASHTABLE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "HashBucket.h"
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
class HashTable {
|
||||||
|
public:
|
||||||
|
HashTable();
|
||||||
|
|
||||||
|
~HashTable();
|
||||||
|
|
||||||
|
uint64_t getMapKey(const char *primaryKey);
|
||||||
|
|
||||||
|
uint32_t hashToBucket(uint64_t key);
|
||||||
|
|
||||||
|
uint32_t getRowLocation(uint32_t bucketID, uint64_t key,
|
||||||
|
RowLocation &rowLocation);
|
||||||
|
|
||||||
|
uint32_t addItem(uint32_t bucketID, uint64_t key, RowLocation rowLocation);
|
||||||
|
|
||||||
|
uint32_t deleteItem(uint32_t bucketID, uint64_t key);
|
||||||
|
|
||||||
|
uint32_t updateItem(uint32_t bucketID, uint64_t key, RowLocation rowLocation);
|
||||||
|
|
||||||
|
uint64_t getItemCount();
|
||||||
|
|
||||||
|
uint32_t getAllBuckets(std::vector<HashBucket *> &buckets);
|
||||||
|
uint32_t refreshRowLocations(uint64_t blockID, uint64_t deleteOffset,
|
||||||
|
uint64_t rowSize,
|
||||||
|
std::map<uint64_t, RowLocation> &locationItems);
|
||||||
|
|
||||||
|
uint32_t clear();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<HashBucket *> buckets;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(HashTable);
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend class MetaHandle;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LightTable
|
||||||
|
|
||||||
|
#endif // HASHTABLE_H
|
|
@ -0,0 +1,101 @@
|
||||||
|
/**
|
||||||
|
* @file PrefetchBlockManager.h
|
||||||
|
* @brief PrefetchBlockManager
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PREFETCHBLOCKMANAGER_H
|
||||||
|
#define PREFETCHBLOCKMANAGER_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
// #include <pthread.h>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <chrono>
|
||||||
|
#include <utility>
|
||||||
|
// #include <mutex>
|
||||||
|
|
||||||
|
#include "Error.h"
|
||||||
|
#include "Common.h"
|
||||||
|
#include "SegmentManager.h"
|
||||||
|
|
||||||
|
namespace LightTable
|
||||||
|
{
|
||||||
|
|
||||||
|
enum PrefetchBlockStatus
|
||||||
|
{
|
||||||
|
PREFETCH_BLOCK_STATUS_IDLE = 0,
|
||||||
|
PREFETCH_BLOCK_STATUS_BUSY,
|
||||||
|
};
|
||||||
|
|
||||||
|
class PrefetchBlockManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef struct prefetchBlockManagerEntry
|
||||||
|
{
|
||||||
|
uint64_t blockID;
|
||||||
|
uint64_t currentOffset;
|
||||||
|
bool isOccupied;
|
||||||
|
bool isCached;
|
||||||
|
uint64_t pageID;
|
||||||
|
}PrefetchBlockManagerEntry;
|
||||||
|
|
||||||
|
PrefetchBlockManager(uint64_t firstBlockID, uint64_t segmentID,
|
||||||
|
SegmentType segmentType);
|
||||||
|
|
||||||
|
~PrefetchBlockManager();
|
||||||
|
|
||||||
|
uint64_t blockAllocate(uint64_t rowSize);
|
||||||
|
|
||||||
|
uint64_t getNextBlock();
|
||||||
|
|
||||||
|
uint32_t setBlockState(uint64_t blockID, bool isOccupied);
|
||||||
|
|
||||||
|
uint32_t setOffset(uint64_t blockID, uint64_t currentOffset);
|
||||||
|
|
||||||
|
uint32_t getOffset(uint64_t blockID, uint64_t ¤tOffset);
|
||||||
|
|
||||||
|
uint32_t advanceOffset(uint64_t blockID, uint64_t rowSize);
|
||||||
|
|
||||||
|
uint32_t isOccupied(uint64_t blockID, bool &status);
|
||||||
|
|
||||||
|
uint32_t getPrefetchBlockEntry(uint64_t blockID,
|
||||||
|
PrefetchBlockManagerEntry &entry);
|
||||||
|
|
||||||
|
uint32_t getAllPrefetchBlockEntrys(std::map<uint64_t,
|
||||||
|
PrefetchBlockManagerEntry> &entrys);
|
||||||
|
|
||||||
|
uint32_t lockBlock(uint64_t blockID);
|
||||||
|
|
||||||
|
uint32_t unlockBlock(uint64_t blockID);
|
||||||
|
|
||||||
|
uint32_t setIsCached(uint64_t blockID, bool isCached, uint64_t pageID);
|
||||||
|
|
||||||
|
bool isCached(uint64_t blockID, uint64_t &pageID);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<uint64_t, PrefetchBlockManagerEntry> prefetchBlocks;
|
||||||
|
|
||||||
|
const uint64_t segmentID;
|
||||||
|
const SegmentType segmentType;
|
||||||
|
const uint64_t firstBlockID;
|
||||||
|
uint64_t blockCount;
|
||||||
|
uint64_t currentID;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(PrefetchBlockManager);
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend class QueryCache;
|
||||||
|
friend class MetaHandle;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LightTable
|
||||||
|
|
||||||
|
#endif // PREFETCHBLOCKMANAGER_H
|
|
@ -0,0 +1,57 @@
|
||||||
|
/**
|
||||||
|
* @file RWLock.h
|
||||||
|
* @brief RWLock
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
#ifndef RWLOCK_H
|
||||||
|
#define RWLOCK_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
using version_lock_t = uint8_t;
|
||||||
|
#define LOAD_ORDER std::memory_order_acquire
|
||||||
|
#define STORE_ORDER std::memory_order_release
|
||||||
|
|
||||||
|
static_assert(sizeof(version_lock_t) == 1, "Lock must be 1 byte.");
|
||||||
|
static constexpr version_lock_t CLIENT_BIT = 0b10000000;
|
||||||
|
static constexpr version_lock_t NO_CLIENT_BIT = 0b01111111;
|
||||||
|
static constexpr version_lock_t USED_BIT = 0b01000000;
|
||||||
|
static constexpr version_lock_t UNLOCKED_BIT = 0b11111110;
|
||||||
|
|
||||||
|
#define IS_LOCKED(lock) ((lock)&1)
|
||||||
|
|
||||||
|
class RWLock {
|
||||||
|
std::atomic<version_lock_t> version_lock;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool lock(const bool blocking = true) {
|
||||||
|
version_lock_t lock_value = version_lock.load(LOAD_ORDER);
|
||||||
|
// Compare and swap until we are the thread to set the lock bit
|
||||||
|
lock_value &= UNLOCKED_BIT;
|
||||||
|
while (!version_lock.compare_exchange_weak(lock_value, lock_value + 1)) {
|
||||||
|
lock_value &= UNLOCKED_BIT;
|
||||||
|
if (!blocking) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void unlock() {
|
||||||
|
const version_lock_t current_version = version_lock.load(LOAD_ORDER);
|
||||||
|
version_lock_t new_version = (current_version + 1) % USED_BIT;
|
||||||
|
new_version |= USED_BIT;
|
||||||
|
new_version |= (current_version & CLIENT_BIT);
|
||||||
|
version_lock.store(new_version, STORE_ORDER);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace LightTable
|
||||||
|
|
||||||
|
#endif // HASHTABLE_H
|
|
@ -0,0 +1,75 @@
|
||||||
|
/**
|
||||||
|
* @file RootTable.h
|
||||||
|
* @brief RootTable
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ROOTTABLE_H
|
||||||
|
#define ROOTTABLE_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "SystemTable.h"
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
class Buffer;
|
||||||
|
|
||||||
|
class RootTable : public SystemTable {
|
||||||
|
public:
|
||||||
|
typedef struct tableTuple {
|
||||||
|
uint64_t tableID;
|
||||||
|
char tableName[TABLE_NAME_LENGTH];
|
||||||
|
uint64_t firstBlockID;
|
||||||
|
uint64_t segmentID;
|
||||||
|
SegmentType segmentType;
|
||||||
|
char user[USER_NAME_LENGTH];
|
||||||
|
struct tm time;
|
||||||
|
} TableTuple;
|
||||||
|
|
||||||
|
RootTable(std::vector<Schema::SchemaEntry> schemaEntrys,
|
||||||
|
bool usePrimaryKeyIndex)
|
||||||
|
: SystemTable(ROOTTABLE_TABLE_ID, "RootTable", ROOTTABLE_FIRST_BLOCK_ID,
|
||||||
|
ROOTTABLE_SEGMENT_ID, SEGMENT_TYPE_BIG, schemaEntrys,
|
||||||
|
usePrimaryKeyIndex) {}
|
||||||
|
|
||||||
|
RootTable(bool usePrimaryKeyIndex = false);
|
||||||
|
|
||||||
|
uint32_t tableNameToTableID(const char *tableName, uint64_t &tableID);
|
||||||
|
|
||||||
|
uint32_t deleteTableInfo(uint64_t tableID);
|
||||||
|
|
||||||
|
uint32_t appendTableInfo(TableTuple tableTuple);
|
||||||
|
|
||||||
|
uint32_t getTableInfo(uint64_t tableID, TableTuple &tableTupleResult);
|
||||||
|
|
||||||
|
uint32_t modifyTableInfo(uint64_t tableID, TableTuple tableTuple);
|
||||||
|
|
||||||
|
uint32_t getTableTuple(uint64_t tableID, TableTuple &tableTuple);
|
||||||
|
|
||||||
|
uint32_t serializeRow(const TableTuple tableTuple, uint8_t *buf);
|
||||||
|
|
||||||
|
uint32_t deserializeRow(const uint8_t *buf, TableTuple *tableTuple);
|
||||||
|
|
||||||
|
uint64_t getTableCount();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<uint64_t, TableTuple> tableTupleMap;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(RootTable);
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend class MetaHandle;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LightTable
|
||||||
|
|
||||||
|
#endif // ROOTTABLE_H
|
|
@ -0,0 +1,57 @@
|
||||||
|
/**
|
||||||
|
* @file RowMap.h
|
||||||
|
* @brief
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ROWMAP_H
|
||||||
|
#define ROWMAP_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Error.h"
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
class RowMap {
|
||||||
|
public:
|
||||||
|
typedef struct rowMapEntry {
|
||||||
|
uint64_t key;
|
||||||
|
uint64_t blockID;
|
||||||
|
uint64_t rowOffset;
|
||||||
|
} RowMapEntry;
|
||||||
|
|
||||||
|
RowMap();
|
||||||
|
|
||||||
|
uint32_t appendEntry(uint64_t key, uint64_t blockID, uint64_t rowOffset);
|
||||||
|
|
||||||
|
uint32_t deleteEntry(uint64_t key);
|
||||||
|
|
||||||
|
uint32_t alterEntry(uint64_t key, uint64_t blockID, uint64_t rowOffset);
|
||||||
|
|
||||||
|
uint32_t queryEntry(uint64_t key, RowMapEntry &rowMapEntry);
|
||||||
|
|
||||||
|
uint32_t queryAllEntry(std::map<uint64_t, RowMapEntry> &allRowMapEntrys);
|
||||||
|
|
||||||
|
uint64_t getRowCount();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<uint64_t, RowMapEntry> rowMapEntrys;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(RowMap);
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend class MetaHandle;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LightTable
|
||||||
|
|
||||||
|
#endif // ROWMAP_H
|
|
@ -0,0 +1,92 @@
|
||||||
|
/**
|
||||||
|
* @file Schema.h
|
||||||
|
* @brief table schema
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SCHEMA_H
|
||||||
|
#define SCHEMA_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Error.h"
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
class Schema {
|
||||||
|
public:
|
||||||
|
typedef struct schemaEntry {
|
||||||
|
uint64_t columnID;
|
||||||
|
char columnName[COLUMN_NAME_LENGTH];
|
||||||
|
char type[COLUMN_TYPE_NAME_LENGTH];
|
||||||
|
uint32_t length;
|
||||||
|
bool isPrimaryKey;
|
||||||
|
bool isEmpty;
|
||||||
|
|
||||||
|
schemaEntry &operator=(schemaEntry &another) {
|
||||||
|
this->columnID = another.columnID;
|
||||||
|
memcpy(this->columnName, another.columnName, COLUMN_NAME_LENGTH);
|
||||||
|
memcpy(this->type, another.type, COLUMN_TYPE_NAME_LENGTH);
|
||||||
|
this->length = another.length;
|
||||||
|
this->isPrimaryKey = another.isPrimaryKey;
|
||||||
|
this->isEmpty = another.isEmpty;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
} SchemaEntry;
|
||||||
|
|
||||||
|
Schema();
|
||||||
|
|
||||||
|
Schema(std::vector<SchemaEntry> schemaEntrys);
|
||||||
|
|
||||||
|
uint32_t appendEntry(SchemaEntry &schemaEntry);
|
||||||
|
|
||||||
|
uint32_t deleteEntry(uint64_t columnID);
|
||||||
|
|
||||||
|
uint32_t alterEntry(uint64_t columnID, SchemaEntry schemaEntry);
|
||||||
|
|
||||||
|
uint32_t getColumnID(const char *columnName, uint64_t &columnID);
|
||||||
|
|
||||||
|
uint32_t queryEntry(uint64_t columnID, Schema::SchemaEntry &schemaEntry);
|
||||||
|
|
||||||
|
uint32_t queryAllEntry(std::map<uint64_t, SchemaEntry> &allSchemaEntrys);
|
||||||
|
|
||||||
|
uint64_t getEntrySize();
|
||||||
|
|
||||||
|
void setEntrySize(uint64_t entrySize);
|
||||||
|
|
||||||
|
uint32_t getPrimaryKeyLength();
|
||||||
|
|
||||||
|
uint64_t getColumnCount();
|
||||||
|
|
||||||
|
void setColumnCount(uint64_t columnCount);
|
||||||
|
|
||||||
|
Schema::SchemaEntry &getPrimaryKeySchema();
|
||||||
|
|
||||||
|
uint32_t drop();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<uint64_t, SchemaEntry> schemaEntrys;
|
||||||
|
SchemaEntry primaryKeySchema;
|
||||||
|
uint64_t columnCount;
|
||||||
|
uint64_t entrySize;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(Schema);
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend class MetaHandle;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LightTable
|
||||||
|
|
||||||
|
#endif // SCHEMA_H
|
|
@ -0,0 +1,59 @@
|
||||||
|
/**
|
||||||
|
* @file SegmentManager.h
|
||||||
|
* @brief SegmentManager
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SEGMENTMANAGER_H
|
||||||
|
#define SEGMENTMANAGER_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Error.h"
|
||||||
|
#include "Driver.h"
|
||||||
|
#include "Common.h"
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
enum SegmentType {
|
||||||
|
SEGMENT_TYPE_SMALL = 101,
|
||||||
|
SEGMENT_TYPE_MEDIUM,
|
||||||
|
SEGMENT_TYPE_BIG,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SegmentStatus {
|
||||||
|
SEGMENT_STATUS_IDLE = 0,
|
||||||
|
SEGMENT_STATUS_BUSY,
|
||||||
|
};
|
||||||
|
|
||||||
|
class SegmentManager {
|
||||||
|
public:
|
||||||
|
SegmentManager();
|
||||||
|
~SegmentManager();
|
||||||
|
|
||||||
|
uint32_t setBitmap(SegmentType segmentType, uint64_t segmentID,
|
||||||
|
SegmentStatus segmentStatus);
|
||||||
|
|
||||||
|
uint32_t getIdleSegment(SegmentType segmentType, uint64_t &segmentID,
|
||||||
|
uint64_t &firstBlockID);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t setBit(uint64_t segmentID, uint8_t *buf, uint64_t segmentStart,
|
||||||
|
SegmentStatus segmentStatus);
|
||||||
|
|
||||||
|
uint32_t findFirstIdle(uint8_t *buf, uint64_t segmentNum,
|
||||||
|
uint64_t &segmentID);
|
||||||
|
|
||||||
|
uint8_t *bigBitmap;
|
||||||
|
uint8_t *mediumBitmap;
|
||||||
|
uint8_t *smallBitmap;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(SegmentManager);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LightTable
|
||||||
|
|
||||||
|
#endif // SEGMENTMANAGER_H
|
|
@ -0,0 +1,33 @@
|
||||||
|
/**
|
||||||
|
* @file SystemTable.h
|
||||||
|
* @brief SystemTable
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SYSTEMTABLE_H
|
||||||
|
#define SYSTEMTABLE_H
|
||||||
|
|
||||||
|
#include "Table.h"
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
class SystemTable : public Table {
|
||||||
|
public:
|
||||||
|
SystemTable(uint64_t tableID, const char *tableName, uint64_t firstBlockID,
|
||||||
|
uint64_t segmentID, SegmentType segmentType,
|
||||||
|
std::vector<Schema::SchemaEntry> schemaEntrys,
|
||||||
|
bool usePrimaryKeyIndex);
|
||||||
|
|
||||||
|
SystemTable(uint64_t tableID, const char *tableName, uint64_t firstBlockID,
|
||||||
|
uint64_t segmentID, SegmentType segmentType,
|
||||||
|
bool usePrimaryKeyIndex);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(SystemTable);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LightTable
|
||||||
|
|
||||||
|
#endif // SYSTEMTABLE_H
|
|
@ -0,0 +1,147 @@
|
||||||
|
/**
|
||||||
|
* @file Table.h
|
||||||
|
* @brief Table
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TABLE_H
|
||||||
|
#define TABLE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <ctime>
|
||||||
|
#include <iostream>
|
||||||
|
#include <queue>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "HashTable.h"
|
||||||
|
#include "RowMap.h"
|
||||||
|
#include "Schema.h"
|
||||||
|
#include "Driver.h"
|
||||||
|
#include "UndoLogEntry.h"
|
||||||
|
#include "SegmentManager.h"
|
||||||
|
#include "PrefetchBlockManager.h"
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
#ifdef TABLE_STORAGE_SECOND_INDEX
|
||||||
|
// TODO: second index
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class Buffer;
|
||||||
|
|
||||||
|
class Table {
|
||||||
|
typedef struct currentLocation {
|
||||||
|
uint64_t blockID;
|
||||||
|
int32_t emptySlotNum;
|
||||||
|
} currentLocation;
|
||||||
|
|
||||||
|
typedef struct metaLogEntry {
|
||||||
|
uint64_t tableID;
|
||||||
|
uint64_t tupleNum;
|
||||||
|
std::time_t t;
|
||||||
|
} metaLogEntry;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Table(uint64_t tableID, const char *tableName, uint64_t firstBlockID,
|
||||||
|
uint64_t segmentID, SegmentType segmentType,
|
||||||
|
std::vector<Schema::SchemaEntry> schemaEntrys,
|
||||||
|
bool usePrimaryKeyIndex = false);
|
||||||
|
|
||||||
|
Table(uint64_t tableID, const char *tableName, uint64_t firstBlockID,
|
||||||
|
uint64_t segmentID, SegmentType segmentType,
|
||||||
|
bool usePrimaryKeyIndex = false);
|
||||||
|
|
||||||
|
uint32_t drop();
|
||||||
|
|
||||||
|
uint32_t truncate();
|
||||||
|
|
||||||
|
uint32_t insertRow(const uint8_t *rowData);
|
||||||
|
|
||||||
|
uint32_t insertRow_logging(const uint8_t *rowData);
|
||||||
|
|
||||||
|
uint32_t deleteRow(const char *primaryKey);
|
||||||
|
|
||||||
|
uint32_t updateRow(const char *primaryKey, const uint8_t *rowData);
|
||||||
|
|
||||||
|
uint32_t updateColumnItem(const char *primaryKey, const char *columnName,
|
||||||
|
const uint8_t *columnData);
|
||||||
|
|
||||||
|
uint32_t updateColumnItem_logging(const char *primaryKey,
|
||||||
|
const char *columnName,
|
||||||
|
const uint8_t *columnData);
|
||||||
|
|
||||||
|
uint32_t selectRow(const char *primaryKey, uint8_t *rowData);
|
||||||
|
|
||||||
|
uint32_t selectColumnItem(const char *primaryKey, const char *columnName,
|
||||||
|
uint8_t *columnData);
|
||||||
|
|
||||||
|
uint64_t getRowCount();
|
||||||
|
|
||||||
|
uint64_t getTableID();
|
||||||
|
|
||||||
|
char *getTableName();
|
||||||
|
|
||||||
|
uint32_t setTableID(uint64_t tableID);
|
||||||
|
|
||||||
|
uint32_t setTableName(const char *tableName);
|
||||||
|
|
||||||
|
Schema &getSchema();
|
||||||
|
|
||||||
|
HashTable &getHashTable();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint32_t getColumnID(const char *columnName, uint64_t &columnID);
|
||||||
|
|
||||||
|
uint32_t parsePrimaryKey(const uint8_t *rowData, char *primaryKeyData);
|
||||||
|
|
||||||
|
uint32_t locateRow(const char *primaryKey, RowLocation &rowLocation);
|
||||||
|
|
||||||
|
uint32_t getRowFromBlock(const char *primaryKey, uint8_t *rowData,
|
||||||
|
const uint8_t *blockData,
|
||||||
|
const RowLocation rowLocation);
|
||||||
|
|
||||||
|
uint32_t selectRow(const char *primaryKey, uint8_t *rowData,
|
||||||
|
RowLocation &rowLocation);
|
||||||
|
|
||||||
|
uint32_t deleteRowData(uint64_t key, RowLocation rowLocation);
|
||||||
|
|
||||||
|
uint32_t getColumnOffset(const char *columnName, uint64_t &columnID,
|
||||||
|
uint32_t &columnLength, uint64_t &offset);
|
||||||
|
|
||||||
|
uint64_t tableID;
|
||||||
|
char tableName[TABLE_NAME_LENGTH];
|
||||||
|
Schema schema;
|
||||||
|
RowMap rowMap;
|
||||||
|
HashTable hashTable;
|
||||||
|
bool usePrimaryKeyIndex;
|
||||||
|
uint64_t tupleNum;
|
||||||
|
std::time_t t;
|
||||||
|
currentLocation indexLocation;
|
||||||
|
currentLocation metaLogLocation;
|
||||||
|
currentLocation indexLogLocation;
|
||||||
|
currentLocation dataLogLocation;
|
||||||
|
uint8_t indexData[BLOCK_SIZE];
|
||||||
|
uint8_t metaData[BLOCK_SIZE];
|
||||||
|
uint8_t metaLog[BLOCK_SIZE];
|
||||||
|
uint8_t indexLog[BLOCK_SIZE];
|
||||||
|
uint8_t dataLog[BLOCK_SIZE];
|
||||||
|
PrefetchBlockManager prefetchBlockManager;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(Table);
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend class DaemonProcess;
|
||||||
|
friend class MetaHandle;
|
||||||
|
friend class QueryCache;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LightTable
|
||||||
|
|
||||||
|
#endif // TABLE_H
|
|
@ -0,0 +1,145 @@
|
||||||
|
/**
|
||||||
|
* @file TableStorage.h
|
||||||
|
* @brief TableStorage
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DAEMONPROCESS_H
|
||||||
|
#define DAEMONPROCESS_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <map>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
// #include <sys/types.h>
|
||||||
|
// #include <sys/socket.h>
|
||||||
|
// #include <arpa/inet.h>
|
||||||
|
// #include <netinet/in.h>
|
||||||
|
// #include <netinet/tcp.h>
|
||||||
|
|
||||||
|
#include "RootTable.h"
|
||||||
|
#include "SegmentManager.h"
|
||||||
|
#include "Common.h"
|
||||||
|
#include "CommonTable.h"
|
||||||
|
#include "Error.h"
|
||||||
|
#include "Driver.h"
|
||||||
|
#include "Table.h"
|
||||||
|
|
||||||
|
#define TABLE_DEBUG_ENABLE
|
||||||
|
#define PROJECT_NAME "TanleStorage"
|
||||||
|
|
||||||
|
#ifndef TABLE_PRINT
|
||||||
|
#define TABLE_PRINT(...) printf(__VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
#define TABLE_LOG_PREFIX1() \
|
||||||
|
TABLE_PRINT("[\e[1;34m%s\033[0m] \e[1;31m%s\033[0m", PROJECT_NAME, \
|
||||||
|
__FUNCTION__)
|
||||||
|
#define TABLE_LOG_PREFIX2() TABLE_PRINT(" ")
|
||||||
|
#define TABLE_LOG_PREFIX() \
|
||||||
|
TABLE_LOG_PREFIX1(); \
|
||||||
|
TABLE_LOG_PREFIX2()
|
||||||
|
|
||||||
|
#ifdef TABLE_DEBUG_ENABLE
|
||||||
|
#define TABLE_DEBUG(...) \
|
||||||
|
TABLE_LOG_PREFIX(); \
|
||||||
|
TABLE_PRINT("(\e[1;32m%s:%d\033[0m) ", __FILE__, __LINE__); \
|
||||||
|
TABLE_PRINT(__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define TABLE_DEBUG(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
enum EventType {
|
||||||
|
CREATE_TABLE_EVENT = 10001,
|
||||||
|
INSERT_ROW_EVENT,
|
||||||
|
DELETE_ROW_EVENT,
|
||||||
|
SELECT_ROW_EVENT,
|
||||||
|
#ifdef YCSB_TEST
|
||||||
|
SCAN_EVENT,
|
||||||
|
#endif
|
||||||
|
UPDATE_ROW_EVENT,
|
||||||
|
#ifdef YCSB_TEST
|
||||||
|
UPDATE_COLUMNS_EVENT,
|
||||||
|
#endif
|
||||||
|
DROP_TABLE_EVENT,
|
||||||
|
RESPOND_CLIENT_REQUEST,
|
||||||
|
STOP_SERVICE_EVENT,
|
||||||
|
#ifdef YCSB_TEST
|
||||||
|
UNKNOWN_EVENT,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct message {
|
||||||
|
uint32_t size;
|
||||||
|
EventType eventType;
|
||||||
|
uint8_t data[NETWORK_MESSAGE_DATA_MAX_SIZE];
|
||||||
|
} Message;
|
||||||
|
|
||||||
|
class TableStorage {
|
||||||
|
public:
|
||||||
|
static TableStorage *getInstance(const char *ipAddress,
|
||||||
|
const uint32_t portNum,
|
||||||
|
const char *path = METAPATH) {
|
||||||
|
static TableStorage *daemonProcess;
|
||||||
|
|
||||||
|
// To determine whether the first call.
|
||||||
|
if (daemonProcess == NULL) {
|
||||||
|
daemonProcess = new TableStorage(ipAddress, portNum, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return daemonProcess;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t createTable(const char *tableName, SegmentType segmentType,
|
||||||
|
std::vector<Schema::SchemaEntry> &schema);
|
||||||
|
|
||||||
|
uint32_t dropTable(const char *tableName);
|
||||||
|
|
||||||
|
uint32_t insertTuple(const char *tableName, const uint8_t *row);
|
||||||
|
|
||||||
|
uint32_t deleteTuple(const char *tableName, const char *primaryKey);
|
||||||
|
|
||||||
|
uint32_t updateTuple(const char *tableName, const char *primaryKey,
|
||||||
|
const char *columnName, const uint8_t *value);
|
||||||
|
|
||||||
|
uint32_t selectTuple(const char *tableName, const char *primaryKey,
|
||||||
|
uint8_t *row);
|
||||||
|
|
||||||
|
uint32_t initTableStorage();
|
||||||
|
uint32_t closeTableStorage();
|
||||||
|
|
||||||
|
private:
|
||||||
|
TableStorage(const char *ipAddress, const uint32_t portNum, const char *path);
|
||||||
|
~TableStorage();
|
||||||
|
|
||||||
|
RootTable *rootTable;
|
||||||
|
std::map<uint64_t, Table *> tableMap;
|
||||||
|
SegmentManager *segmentManager;
|
||||||
|
const char *LightTableIPAddress;
|
||||||
|
const uint32_t LightTablePortNum;
|
||||||
|
|
||||||
|
// int32_t socketfd;
|
||||||
|
// MetaHandle metaHandle;
|
||||||
|
// Buffer *buf;
|
||||||
|
// QueryCache *queryCache;
|
||||||
|
// BlockPreload *blockPreload;
|
||||||
|
|
||||||
|
friend class Benchmark;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LightTable
|
||||||
|
|
||||||
|
#endif // DAEMONPROCESS_H
|
|
@ -0,0 +1,81 @@
|
||||||
|
/**
|
||||||
|
* @file ThreadSafeQueue.h
|
||||||
|
* @brief ThreadSafeQueue
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
template <class object>
|
||||||
|
class ThreadSafeQueue {
|
||||||
|
private:
|
||||||
|
pthread_mutex_t m_lock;
|
||||||
|
int m_front;
|
||||||
|
int m_rear;
|
||||||
|
object m_data[BUFFER_SIZE];
|
||||||
|
|
||||||
|
public:
|
||||||
|
ThreadSafeQueue() : m_front(0), m_rear(0) {
|
||||||
|
pthread_mutex_init(&m_lock, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EnQueue(object data) {
|
||||||
|
pthread_mutex_lock(&m_lock);
|
||||||
|
if (isFull()) {
|
||||||
|
// cout<<"The queue is full!"<<endl;
|
||||||
|
pthread_mutex_unlock(&m_lock);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_data[m_rear] = data;
|
||||||
|
m_rear = (m_rear + 1) % BUFFER_SIZE;
|
||||||
|
pthread_mutex_unlock(&m_lock);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeQueue(object& data) {
|
||||||
|
pthread_mutex_lock(&m_lock);
|
||||||
|
if (isEmpty()) {
|
||||||
|
pthread_mutex_unlock(&m_lock);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
data = m_data[m_front];
|
||||||
|
m_front = (m_front + 1) % BUFFER_SIZE;
|
||||||
|
pthread_mutex_unlock(&m_lock);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool top(object& data) {
|
||||||
|
pthread_mutex_lock(&m_lock);
|
||||||
|
if (isEmpty()) {
|
||||||
|
pthread_mutex_unlock(&m_lock);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
data = m_data[m_front];
|
||||||
|
pthread_mutex_unlock(&m_lock);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isFull() {
|
||||||
|
if ((m_rear + 1) % BUFFER_SIZE == m_front) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isEmpty() {
|
||||||
|
if (m_rear == m_front) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
~ThreadSafeQueue() { pthread_mutex_destroy(&m_lock); }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LightTable
|
|
@ -0,0 +1,49 @@
|
||||||
|
/**
|
||||||
|
* @file UndoLogEntry.h
|
||||||
|
* @brief UndoLogEntry
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UNDOLOGENTRY_H
|
||||||
|
#define UNDOLOGENTRY_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "BufferItem.h"
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Error.h"
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
class UndoLogEntry : public BufferItem {
|
||||||
|
public:
|
||||||
|
UndoLogEntry(uint64_t tableID, const char *primaryKey, uint64_t keySize,
|
||||||
|
char *tuple, uint64_t tupleSize, uint64_t blockID,
|
||||||
|
uint64_t offset);
|
||||||
|
|
||||||
|
static bool getIsExpired(UndoLogEntry *logEntry);
|
||||||
|
void expireUndoLog();
|
||||||
|
|
||||||
|
uint32_t getTuple(uint64_t tableID, const char *primaryKey, char *tuple,
|
||||||
|
uint64_t &blockID, uint64_t &offset);
|
||||||
|
|
||||||
|
char *getPrimaryKey();
|
||||||
|
|
||||||
|
~UndoLogEntry();
|
||||||
|
|
||||||
|
private:
|
||||||
|
char *tuple;
|
||||||
|
char *primaryKey;
|
||||||
|
uint64_t blockID;
|
||||||
|
uint64_t offset;
|
||||||
|
uint64_t tupleSize;
|
||||||
|
uint64_t keySize;
|
||||||
|
bool isExpired;
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(UndoLogEntry);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LightTable
|
||||||
|
|
||||||
|
#endif // UNDOLOGENTRY_H
|
|
@ -0,0 +1,41 @@
|
||||||
|
/**
|
||||||
|
* @file integer.h
|
||||||
|
* @brief integer
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _FF_INTEGER
|
||||||
|
#define _FF_INTEGER
|
||||||
|
|
||||||
|
#ifdef _WIN32 /* FatFs development platform */
|
||||||
|
|
||||||
|
#include <tchar.h>
|
||||||
|
#include <windows.h>
|
||||||
|
typedef unsigned __int64 QWORD;
|
||||||
|
|
||||||
|
#else /* Embedded platform */
|
||||||
|
|
||||||
|
/* These types MUST be 16-bit or 32-bit */
|
||||||
|
typedef int INT;
|
||||||
|
typedef unsigned int UINT;
|
||||||
|
|
||||||
|
/* This type MUST be 8-bit */
|
||||||
|
typedef unsigned char BYTE;
|
||||||
|
|
||||||
|
/* These types MUST be 16-bit */
|
||||||
|
typedef short SHORT;
|
||||||
|
typedef unsigned short WORD;
|
||||||
|
typedef unsigned short WCHAR;
|
||||||
|
|
||||||
|
/* These types MUST be 32-bit */
|
||||||
|
typedef long LONG;
|
||||||
|
typedef unsigned long DWORD;
|
||||||
|
|
||||||
|
/* This type MUST be 64-bit (Remove this for C89 compatibility) */
|
||||||
|
typedef unsigned long long QWORD;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
After Width: | Height: | Size: 72 KiB |
After Width: | Height: | Size: 132 KiB |
After Width: | Height: | Size: 56 KiB |
After Width: | Height: | Size: 92 KiB |
After Width: | Height: | Size: 149 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 77 KiB |
After Width: | Height: | Size: 177 KiB |
After Width: | Height: | Size: 227 KiB |
After Width: | Height: | Size: 144 KiB |
|
@ -0,0 +1,80 @@
|
||||||
|
/**
|
||||||
|
* @file Common.cc
|
||||||
|
* @brief Common
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
int cacheReadNum = 0;
|
||||||
|
int cacheWriteNum = 0;
|
||||||
|
|
||||||
|
std::chrono::steady_clock::time_point start_time =
|
||||||
|
std::chrono::steady_clock::now();
|
||||||
|
std::chrono::steady_clock::time_point end_time =
|
||||||
|
std::chrono::steady_clock::now();
|
||||||
|
double diff_sdcard_read = 0.0;
|
||||||
|
double diff_sdcard_write = 0.0;
|
||||||
|
|
||||||
|
struct timespec diff(struct timespec start, struct timespec end) {
|
||||||
|
struct timespec temp;
|
||||||
|
if ((end.tv_nsec - start.tv_nsec) < 0) {
|
||||||
|
temp.tv_sec = end.tv_sec - start.tv_sec - 1;
|
||||||
|
temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
|
||||||
|
} else {
|
||||||
|
temp.tv_sec = end.tv_sec - start.tv_sec;
|
||||||
|
temp.tv_nsec = end.tv_nsec - start.tv_nsec;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef IO_PROFILING
|
||||||
|
std::queue<struct timespec> Queue::io_times;
|
||||||
|
std::queue<struct timespec> Queue::io_submit_times;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IO_PROFILING
|
||||||
|
struct timespec Queue::accumulate_io_times() {
|
||||||
|
struct timespec sum;
|
||||||
|
sum.tv_sec = 0;
|
||||||
|
sum.tv_nsec = 0;
|
||||||
|
|
||||||
|
while (!io_times.empty()) {
|
||||||
|
sum.tv_sec += io_times.front().tv_sec;
|
||||||
|
if (1000000000 <= sum.tv_nsec + io_times.front().tv_nsec) {
|
||||||
|
sum.tv_sec++;
|
||||||
|
sum.tv_nsec = sum.tv_nsec + io_times.front().tv_nsec - 1000000000;
|
||||||
|
} else {
|
||||||
|
sum.tv_nsec += io_times.front().tv_nsec;
|
||||||
|
}
|
||||||
|
io_times.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct timespec Queue::accumulate_io_submit_times() {
|
||||||
|
struct timespec sum;
|
||||||
|
sum.tv_sec = 0;
|
||||||
|
sum.tv_nsec = 0;
|
||||||
|
|
||||||
|
while (!io_submit_times.empty()) {
|
||||||
|
sum.tv_sec += io_submit_times.front().tv_sec;
|
||||||
|
if (1000000000 <= sum.tv_nsec + io_submit_times.front().tv_nsec) {
|
||||||
|
sum.tv_sec++;
|
||||||
|
sum.tv_nsec = sum.tv_nsec + io_submit_times.front().tv_nsec - 1000000000;
|
||||||
|
} else {
|
||||||
|
sum.tv_nsec += io_submit_times.front().tv_nsec;
|
||||||
|
}
|
||||||
|
io_submit_times.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace LightTable
|
|
@ -0,0 +1,92 @@
|
||||||
|
/**
|
||||||
|
* @file Driver.cc
|
||||||
|
* @brief Driver
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Driver.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "ff.h"
|
||||||
|
#include "ffconf.h"
|
||||||
|
|
||||||
|
#include <diskio.h>
|
||||||
|
#include <rtdef.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Definitions of physical drive number for each drive */
|
||||||
|
#define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */
|
||||||
|
#define DEV_MMC 1 /* Example: Map MMC/SD card to physical drive 1 */
|
||||||
|
#define DEV_USB 2 /* Example: Map USB MSD to physical drive 2 */
|
||||||
|
|
||||||
|
static rt_device_t disk[FF_VOLUMES] = {0};
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
uint32_t Driver::write(uint8_t *buf, uint64_t blockID) {
|
||||||
|
rt_size_t result;
|
||||||
|
rt_device_t device = disk[0];
|
||||||
|
|
||||||
|
#ifdef TABLE_STORAGE_CACHE
|
||||||
|
// TODO: cache
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (rt_device_write(device, blockID, buf, 1) == 1)
|
||||||
|
return RES_OK;
|
||||||
|
else
|
||||||
|
return RES_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Driver::read(uint8_t *buf, uint64_t blockID) {
|
||||||
|
rt_size_t result;
|
||||||
|
rt_device_t device = disk[0];
|
||||||
|
|
||||||
|
#ifdef TABLE_STORAGE_CACHE
|
||||||
|
// TODO: cache
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (rt_device_read(device, blockID, buf, 1) == 1) {
|
||||||
|
return RES_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RES_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Driver::driver_cleanup(const char *device_name) {
|
||||||
|
/* clean device */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Driver::driver_init(const char *device_name) {
|
||||||
|
/* init device */
|
||||||
|
/* note: initialization of the device is done at the MakeTableStorage*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // namespace LightTable
|
||||||
|
|
||||||
|
uint32_t MakeTableStorage(const char *device_name) {
|
||||||
|
rt_device_t dev_id;
|
||||||
|
|
||||||
|
/* open specific device */
|
||||||
|
if (device_name == NULL) {
|
||||||
|
/* which is a non-device filesystem mount */
|
||||||
|
dev_id = NULL;
|
||||||
|
} else if ((dev_id = rt_device_find(device_name)) == NULL) {
|
||||||
|
/* no this device */
|
||||||
|
rt_set_errno(-ENODEV);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open device, but do not check the status of device */
|
||||||
|
if (dev_id != NULL) {
|
||||||
|
if (rt_device_open(dev_id, RT_DEVICE_OFLAG_RDWR) != RT_EOK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
disk[0] = dev_id;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
ifndef LIGHTTABLE_DIR
|
||||||
|
LIGHTTABLE_DIR = ../..
|
||||||
|
endif
|
||||||
|
|
||||||
|
SRC_FILES := $(wildcard *.cc)
|
||||||
|
INCLUDE_DIR = -I$(LIGHTTABLE_DIR)/src -I. -I$(LIGHTTABLE_DIR)/spdk/include
|
||||||
|
|
||||||
|
SOURCE_FOR_CC = $(foreach source_file_1, $(SOURCES),$(filter %.cc, $(source_file_1)))
|
||||||
|
|
||||||
|
CXXFLAGS += -Werror -fno-omit-frame-pointer -Wall -Wextra -Wno-unused-parameter \
|
||||||
|
-Wno-missing-field-initializers -Wmissing-declarations -fno-strict-aliasing \
|
||||||
|
$(INCLUDE_DIR) -Wformat -Wformat-security -D_GNU_SOURCE \
|
||||||
|
-fPIC -fno-stack-protector -fno-common -DNDEBUG -U_FORTIFY_SOURCE \
|
||||||
|
-D_FORTIFY_SOURCE=2 -std=c++11
|
||||||
|
|
||||||
|
CXXFLAGS += -DYCSB_TEST
|
||||||
|
|
||||||
|
CXXFLAGS += -Wl,-z,relro,-z,now -Wl,-z,noexecstack -lpthread -Wl,-z,relro,-z,now \
|
||||||
|
-Wl,-z,noexecstack \
|
||||||
|
-Wl,--whole-archive -Wl,--no-whole-archive
|
||||||
|
|
||||||
|
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,17 @@
|
||||||
|
/**
|
||||||
|
* @file BufferItem.cc
|
||||||
|
* @brief BufferItem
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "BufferItem.h"
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
BufferItem::BufferItem(uint64_t tableID) : tableID(tableID) {}
|
||||||
|
|
||||||
|
BufferItem::~BufferItem() {}
|
||||||
|
|
||||||
|
} // namespace LightTable
|
|
@ -0,0 +1,23 @@
|
||||||
|
ifndef LIGHTTABLE_DIR
|
||||||
|
LIGHTTABLE_DIR = ../..
|
||||||
|
endif
|
||||||
|
|
||||||
|
SRC_FILES := $(wildcard *.cc)
|
||||||
|
INCLUDE_DIR = -I$(LIGHTTABLE_DIR)/src -I.
|
||||||
|
|
||||||
|
SOURCE_FOR_CC = $(foreach source_file_1, $(SOURCES),$(filter %.cc, $(source_file_1)))
|
||||||
|
|
||||||
|
CXXFLAGS += -Werror -fno-omit-frame-pointer -Wall -Wextra -Wno-unused-parameter \
|
||||||
|
-Wno-missing-field-initializers -Wmissing-declarations -fno-strict-aliasing \
|
||||||
|
$(INCLUDE_DIR) -Wformat -Wformat-security -D_GNU_SOURCE \
|
||||||
|
-fPIC -fno-stack-protector -fno-common -DNDEBUG -U_FORTIFY_SOURCE \
|
||||||
|
-D_FORTIFY_SOURCE=2 -std=c++11
|
||||||
|
|
||||||
|
CXXFLAGS += -DYCSB_TEST
|
||||||
|
|
||||||
|
CXXFLAGS += -Wl,-z,relro,-z,now -Wl,-z,noexecstack -lpthread -Wl,-z,relro,-z,now \
|
||||||
|
-Wl,-z,noexecstack \
|
||||||
|
-Wl,--whole-archive -Wl,--no-whole-archive
|
||||||
|
|
||||||
|
|
||||||
|
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,184 @@
|
||||||
|
/**
|
||||||
|
* @file TableStorage.cc
|
||||||
|
* @brief TableStorage
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TableStorage.h"
|
||||||
|
|
||||||
|
// #include "ThreadPool.h"
|
||||||
|
// #include "Buffer.h"
|
||||||
|
|
||||||
|
// static struct timespec time1, time2, time3;
|
||||||
|
// static uint32_t coreNum = 0;
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
TableStorage::TableStorage(const char *ipAddress, const uint32_t portNum,
|
||||||
|
const char *path)
|
||||||
|
: // metaHandle(path),
|
||||||
|
LightTableIPAddress(ipAddress),
|
||||||
|
LightTablePortNum(portNum) {
|
||||||
|
|
||||||
|
segmentManager = new SegmentManager();
|
||||||
|
rootTable = new RootTable();
|
||||||
|
|
||||||
|
std::cout << "INIT TableStorage SUCCESS" << "\n";
|
||||||
|
// threadPool = ThreadPool::getInstance(SYSTEM_MAX_CORES);
|
||||||
|
// buf = Buffer::getInstance();
|
||||||
|
// queryCache = QueryCache::getInstance(&tableMap);
|
||||||
|
// blockPreload = BlockPreload::getInstance();
|
||||||
|
// blockPreload->setParameters(queryCache);
|
||||||
|
// buf->setParameters(&metaHandle, rootTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t TableStorage::createTable(const char *tableName,
|
||||||
|
SegmentType segmentType,
|
||||||
|
std::vector<Schema::SchemaEntry> &schema) {
|
||||||
|
uint64_t segmentID = 0;
|
||||||
|
uint64_t firstBlockID = 0;
|
||||||
|
uint64_t tableID =
|
||||||
|
tableMap.size() + COMMON_TABLE_START_ID - SYSTEM_TABLE_COUNT;
|
||||||
|
uint32_t err =
|
||||||
|
segmentManager->getIdleSegment(segmentType, segmentID, firstBlockID);
|
||||||
|
if (err != SUCCESS) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
CommonTable *commonTable = new CommonTable(tableID, tableName, firstBlockID,
|
||||||
|
segmentID, segmentType, schema);
|
||||||
|
std::pair<std::map<uint64_t, Table *>::iterator, bool> ret;
|
||||||
|
ret = tableMap.insert(std::pair<uint64_t, Table *>(tableID, commonTable));
|
||||||
|
if (false == ret.second) {
|
||||||
|
return ERROR_TABLE;
|
||||||
|
}
|
||||||
|
time_t timeNow = time(NULL);
|
||||||
|
struct tm *now = localtime(&timeNow);
|
||||||
|
RootTable::TableTuple tuple;
|
||||||
|
tuple.tableID = tableID;
|
||||||
|
memcpy(tuple.tableName, tableName, TABLE_NAME_LENGTH);
|
||||||
|
tuple.firstBlockID = firstBlockID;
|
||||||
|
tuple.segmentType = segmentType;
|
||||||
|
tuple.segmentID = segmentID;
|
||||||
|
memcpy(tuple.user, "user", 5);
|
||||||
|
tuple.time = *now;
|
||||||
|
err = rootTable->appendTableInfo(tuple);
|
||||||
|
|
||||||
|
if (err == SUCCESS) std::cout << "create table: " << tableName << std::endl;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t TableStorage::dropTable(const char *tableName) {
|
||||||
|
uint64_t tableID = 0;
|
||||||
|
uint32_t result = rootTable->tableNameToTableID(tableName, tableID);
|
||||||
|
if (SUCCESS != result) return result;
|
||||||
|
|
||||||
|
std::map<uint64_t, Table *>::iterator iter = tableMap.find(tableID);
|
||||||
|
Table *commonTable = iter->second;
|
||||||
|
commonTable->drop();
|
||||||
|
tableMap.erase(tableID);
|
||||||
|
result = rootTable->deleteTableInfo(tableID);
|
||||||
|
|
||||||
|
if (result == SUCCESS) std::cout << "drop table: " << tableName << std::endl;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t TableStorage::insertTuple(const char *tableName, const uint8_t *row) {
|
||||||
|
uint64_t tableID = 0;
|
||||||
|
uint32_t result = 0;
|
||||||
|
|
||||||
|
#ifndef SDCARD_TEST
|
||||||
|
result = rootTable->tableNameToTableID(tableName, tableID);
|
||||||
|
if (SUCCESS != result) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
tableID = YCSB_TABLE_ID;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::map<uint64_t, Table *>::iterator iter = tableMap.find(tableID);
|
||||||
|
Table *commonTable = iter->second;
|
||||||
|
|
||||||
|
#ifndef TABLE_STORAGE_LOGGING
|
||||||
|
result = commonTable->insertRow(row);
|
||||||
|
#else
|
||||||
|
result = commonTable->insertRow_logging(row);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t TableStorage::deleteTuple(const char *tableName,
|
||||||
|
const char *primaryKey) {
|
||||||
|
uint64_t tableID = 0;
|
||||||
|
uint32_t result = rootTable->tableNameToTableID(tableName, tableID);
|
||||||
|
if (SUCCESS != result) return result;
|
||||||
|
|
||||||
|
std::map<uint64_t, Table *>::iterator iter = tableMap.find(tableID);
|
||||||
|
Table *commonTable = iter->second;
|
||||||
|
result = commonTable->deleteRow(primaryKey);
|
||||||
|
|
||||||
|
if (result == SUCCESS)
|
||||||
|
std::cout << "delete a tuple in " << tableName << " success!" << std::endl;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t TableStorage::updateTuple(const char *tableName,
|
||||||
|
const char *primaryKey,
|
||||||
|
const char *columnName,
|
||||||
|
const uint8_t *value) {
|
||||||
|
uint64_t tableID = 0;
|
||||||
|
uint32_t result = rootTable->tableNameToTableID(tableName, tableID);
|
||||||
|
if (SUCCESS != result) return result;
|
||||||
|
|
||||||
|
std::map<uint64_t, Table *>::iterator iter = tableMap.find(tableID);
|
||||||
|
Table *commonTable = iter->second;
|
||||||
|
|
||||||
|
#ifndef TABLE_STORAGE_LOGGING
|
||||||
|
result = commonTable->updateColumnItem(primaryKey, columnName, value);
|
||||||
|
#else
|
||||||
|
result = commonTable->updateColumnItem_logging(primaryKey, columnName, value);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t TableStorage::selectTuple(const char *tableName,
|
||||||
|
const char *primaryKey, uint8_t *row) {
|
||||||
|
uint64_t tableID = 0;
|
||||||
|
uint32_t result = 0;
|
||||||
|
|
||||||
|
#ifndef SDCARD_TEST
|
||||||
|
result = rootTable->tableNameToTableID(tableName, tableID);
|
||||||
|
if (SUCCESS != result) return result;
|
||||||
|
#else
|
||||||
|
tableID = YCSB_TABLE_ID;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::map<uint64_t, Table *>::iterator iter = tableMap.find(tableID);
|
||||||
|
Table *commonTable = iter->second;
|
||||||
|
result = commonTable->selectRow(primaryKey, row);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t TableStorage::initTableStorage() {
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t TableStorage::closeTableStorage() {
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
TableStorage::~TableStorage() {
|
||||||
|
for (auto ite = tableMap.begin(); ite != tableMap.end(); ++ite)
|
||||||
|
delete (ite->second);
|
||||||
|
tableMap.clear();
|
||||||
|
delete (rootTable);
|
||||||
|
delete (segmentManager);
|
||||||
|
std::cout << "close TableStorage success!\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace LightTable
|
|
@ -0,0 +1,54 @@
|
||||||
|
/**
|
||||||
|
* @file UndoLogEntry.cc
|
||||||
|
* @brief UndoLogEntry
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "UndoLogEntry.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
UndoLogEntry::UndoLogEntry(uint64_t tableID, const char *primaryKey,
|
||||||
|
uint64_t keySize, char *tuple, uint64_t tupleSize,
|
||||||
|
uint64_t blockID, uint64_t offset)
|
||||||
|
: BufferItem(tableID),
|
||||||
|
blockID(blockID),
|
||||||
|
offset(offset),
|
||||||
|
tupleSize(tupleSize),
|
||||||
|
keySize(keySize),
|
||||||
|
isExpired(false) {
|
||||||
|
memcpy(this->tuple, tuple, tupleSize);
|
||||||
|
memcpy(this->primaryKey, primaryKey, keySize);
|
||||||
|
}
|
||||||
|
|
||||||
|
UndoLogEntry::~UndoLogEntry() {
|
||||||
|
delete[] primaryKey;
|
||||||
|
delete[] tuple;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t UndoLogEntry::getTuple(uint64_t tableID, const char *primaryKey,
|
||||||
|
char *tuple, uint64_t &blockID,
|
||||||
|
uint64_t &offset) {
|
||||||
|
if (this->tableID != tableID || strcmp(this->primaryKey, primaryKey) != 0) {
|
||||||
|
return ERROR_TABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(tuple, this->tuple, tupleSize);
|
||||||
|
blockID = this->blockID;
|
||||||
|
offset = this->offset;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UndoLogEntry::expireUndoLog() { isExpired = true; }
|
||||||
|
|
||||||
|
char *UndoLogEntry::getPrimaryKey() { return this->primaryKey; }
|
||||||
|
|
||||||
|
bool UndoLogEntry::getIsExpired(UndoLogEntry *logEntry) {
|
||||||
|
return logEntry->isExpired;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace LightTable
|
|
@ -0,0 +1,31 @@
|
||||||
|
/**
|
||||||
|
* @file CommonTable.cc
|
||||||
|
* @brief CommonTable
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "CommonTable.h"
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
CommonTable::CommonTable(uint64_t tableID, const char *tableName,
|
||||||
|
uint64_t firstBlockID, uint64_t segmentID,
|
||||||
|
SegmentType segmentType,
|
||||||
|
std::vector<Schema::SchemaEntry> schemaEntrys,
|
||||||
|
bool usePrimaryKeyIndex)
|
||||||
|
: Table(tableID, tableName, firstBlockID, segmentID, segmentType,
|
||||||
|
schemaEntrys, usePrimaryKeyIndex)
|
||||||
|
|
||||||
|
{}
|
||||||
|
|
||||||
|
CommonTable::CommonTable(uint64_t tableID, const char *tableName,
|
||||||
|
uint64_t firstBlockID, uint64_t segmentID,
|
||||||
|
SegmentType segmentType, bool usePrimaryKeyIndex)
|
||||||
|
: Table(tableID, tableName, firstBlockID, segmentID, segmentType,
|
||||||
|
usePrimaryKeyIndex)
|
||||||
|
|
||||||
|
{}
|
||||||
|
|
||||||
|
} // namespace LightTable
|
|
@ -0,0 +1,77 @@
|
||||||
|
/**
|
||||||
|
* @file HashBucket.cc
|
||||||
|
* @brief HashBucket
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "HashBucket.h"
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
HashBucket::HashBucket() : bucketSize(0) {}
|
||||||
|
|
||||||
|
uint32_t HashBucket::addBucketItem(uint64_t key, RowLocation rowLocation) {
|
||||||
|
std::pair<std::map<uint64_t, RowLocation>::iterator, bool> ret;
|
||||||
|
// std::unique_lock<std::mutex> lck(mtx);
|
||||||
|
// pthread_mutex_lock(&mtx);
|
||||||
|
ret = bucketItems.insert(std::pair<uint64_t, RowLocation>(key, rowLocation));
|
||||||
|
// lck.unlock();
|
||||||
|
// pthread_mutex_unlock(&mtx);
|
||||||
|
if (ret.second == false) {
|
||||||
|
return ADD_BUCKET_ITEM_ERROR;
|
||||||
|
}
|
||||||
|
bucketSize++;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t HashBucket::deleteBucketItem(uint64_t key) {
|
||||||
|
if (bucketItems.erase(key) == 1) {
|
||||||
|
bucketSize--;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
return BUCKET_ITEM_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t HashBucket::updateRowLocation(uint64_t key, RowLocation rowLocation) {
|
||||||
|
std::map<uint64_t, RowLocation>::iterator iter;
|
||||||
|
iter = bucketItems.find(key);
|
||||||
|
|
||||||
|
if (iter != bucketItems.end()) {
|
||||||
|
(iter->second).blockID = rowLocation.blockID;
|
||||||
|
(iter->second).rowOffset = rowLocation.rowOffset;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
return BUCKET_ITEM_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t HashBucket::getRowLocation(uint64_t key, RowLocation &rowLocation) {
|
||||||
|
std::map<uint64_t, RowLocation>::iterator iter;
|
||||||
|
iter = bucketItems.find(key);
|
||||||
|
|
||||||
|
if (iter != bucketItems.end()) {
|
||||||
|
rowLocation.blockID = (iter->second).blockID;
|
||||||
|
rowLocation.rowOffset = (iter->second).rowOffset;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
rowLocation.blockID = 0;
|
||||||
|
rowLocation.rowOffset = 0;
|
||||||
|
return BUCKET_ITEM_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t HashBucket::getBucketSize() { return bucketSize; }
|
||||||
|
|
||||||
|
uint32_t HashBucket::setBucketSize(uint64_t bucketSize) {
|
||||||
|
this->bucketSize = bucketSize;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t HashBucket::getAllBucketItems(
|
||||||
|
std::map<uint64_t, RowLocation> &bucketItems) {
|
||||||
|
bucketItems = this->bucketItems;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace LightTable
|
|
@ -0,0 +1,113 @@
|
||||||
|
/**
|
||||||
|
* @file HashTable.cc
|
||||||
|
* @brief HashTable
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "HashTable.h"
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
HashTable::HashTable() {
|
||||||
|
buckets.reserve(HASH_BUCKET_SIZE);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < HASH_BUCKET_SIZE; i++) {
|
||||||
|
HashBucket *tempBucket = new HashBucket();
|
||||||
|
buckets.push_back(tempBucket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HashTable::~HashTable() {
|
||||||
|
std::vector<HashBucket *>::iterator iter = buckets.begin();
|
||||||
|
while (iter != buckets.end()) {
|
||||||
|
iter = buckets.erase(iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t HashTable::getMapKey(const char *primaryKey) {
|
||||||
|
const std::string str = primaryKey;
|
||||||
|
|
||||||
|
uint64_t BitsInUnsignedInt = (uint64_t)(4 * 8);
|
||||||
|
uint64_t ThreeQuarters = (uint64_t)((BitsInUnsignedInt * 3) / 4);
|
||||||
|
uint64_t OneEighth = (uint64_t)(BitsInUnsignedInt / 8);
|
||||||
|
uint64_t HighBits = (uint64_t)(0xFFFFFFFF) << (BitsInUnsignedInt - OneEighth);
|
||||||
|
uint64_t hash = 0;
|
||||||
|
uint64_t test = 0;
|
||||||
|
for (uint32_t i = 0; i < str.length(); i++) {
|
||||||
|
hash = (hash << OneEighth) + str[i];
|
||||||
|
if ((test = hash & HighBits) != 0) {
|
||||||
|
hash = ((hash ^ (test >> ThreeQuarters)) & (~HighBits));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t HashTable::hashToBucket(uint64_t key) {
|
||||||
|
return key % HASH_BUCKET_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t HashTable::getRowLocation(uint32_t bucketID, uint64_t key,
|
||||||
|
RowLocation &rowLocation) {
|
||||||
|
return buckets[bucketID]->getRowLocation(key, rowLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t HashTable::addItem(uint32_t bucketID, uint64_t key,
|
||||||
|
RowLocation rowLocation) {
|
||||||
|
return buckets[bucketID]->addBucketItem(key, rowLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t HashTable::deleteItem(uint32_t bucketID, uint64_t key) {
|
||||||
|
return buckets[bucketID]->deleteBucketItem(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t HashTable::updateItem(uint32_t bucketID, uint64_t key,
|
||||||
|
RowLocation rowLocation) {
|
||||||
|
return buckets[bucketID]->updateRowLocation(key, rowLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t HashTable::getItemCount() {
|
||||||
|
if (buckets.size() == 0) {
|
||||||
|
return buckets.size();
|
||||||
|
}
|
||||||
|
uint64_t itemCount = 0;
|
||||||
|
for (uint32_t i = 0; i < HASH_BUCKET_SIZE; i++) {
|
||||||
|
itemCount += buckets[i]->getBucketSize();
|
||||||
|
}
|
||||||
|
return itemCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t HashTable::getAllBuckets(std::vector<HashBucket *> &buckets) {
|
||||||
|
buckets = this->buckets;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t HashTable::refreshRowLocations(
|
||||||
|
uint64_t blockID, uint64_t deleteOffset, uint64_t rowSize,
|
||||||
|
std::map<uint64_t, RowLocation> &locationItems) {
|
||||||
|
for (uint32_t i = 0; i < HASH_BUCKET_SIZE; i++) {
|
||||||
|
std::map<uint64_t, RowLocation> bucketItems;
|
||||||
|
buckets[i]->getAllBucketItems(bucketItems);
|
||||||
|
std::map<uint64_t, RowLocation>::iterator iter = bucketItems.begin();
|
||||||
|
while (iter != bucketItems.end()) {
|
||||||
|
if ((iter->second).blockID == blockID &&
|
||||||
|
(iter->second).rowOffset > deleteOffset) {
|
||||||
|
(iter->second).rowOffset -= rowSize;
|
||||||
|
locationItems.insert(
|
||||||
|
std::pair<uint64_t, RowLocation>(iter->first, iter->second));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t HashTable::clear() {
|
||||||
|
std::vector<HashBucket *>::iterator iter = buckets.begin();
|
||||||
|
while (iter != buckets.end()) {
|
||||||
|
iter = buckets.erase(iter);
|
||||||
|
}
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace LightTable
|
|
@ -0,0 +1,23 @@
|
||||||
|
ifndef LIGHTTABLE_DIR
|
||||||
|
LIGHTTABLE_DIR = ../..
|
||||||
|
endif
|
||||||
|
|
||||||
|
SRC_FILES := $(wildcard *.cc)
|
||||||
|
INCLUDE_DIR = -I$(LIGHTTABLE_DIR)/src -I. -I$(LIGHTTABLE_DIR)/spdk/include -I/opt/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.1-20190425-1021/riscv-none-embed/include/c++/8.2.0
|
||||||
|
|
||||||
|
SOURCE_FOR_CC = $(foreach source_file_1, $(SOURCES),$(filter %.cc, $(source_file_1)))
|
||||||
|
|
||||||
|
CXXFLAGS += -fno-omit-frame-pointer \
|
||||||
|
-Wno-missing-field-initializers -Wmissing-declarations -fno-strict-aliasing \
|
||||||
|
$(INCLUDE_DIR) -Wformat -Wformat-security -D_GNU_SOURCE \
|
||||||
|
-fPIC -fno-stack-protector -fno-common -DNDEBUG -U_FORTIFY_SOURCE \
|
||||||
|
-D_FORTIFY_SOURCE=2 -std=c++11
|
||||||
|
|
||||||
|
CXXFLAGS += -DYCSB_TEST
|
||||||
|
|
||||||
|
CXXFLAGS += -Wl,-z,relro,-z,now -Wl,-z,noexecstack -lpthread -Wl,-z,relro,-z,now \
|
||||||
|
-Wl,-z,noexecstack \
|
||||||
|
-Wl,--whole-archive -Wl,--no-whole-archive -lrt
|
||||||
|
|
||||||
|
|
||||||
|
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,267 @@
|
||||||
|
/**
|
||||||
|
* @file PrefetchBlockManager.cc
|
||||||
|
* @brief PrefetchBlockManager
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "PrefetchBlockManager.h"
|
||||||
|
|
||||||
|
namespace LightTable
|
||||||
|
{
|
||||||
|
|
||||||
|
PrefetchBlockManager::PrefetchBlockManager(uint64_t firstBlockID,
|
||||||
|
uint64_t segmentID,
|
||||||
|
SegmentType segmentType)
|
||||||
|
: segmentID(segmentID), segmentType(segmentType), firstBlockID(firstBlockID), currentID(0)
|
||||||
|
{
|
||||||
|
uint32_t num = 0;
|
||||||
|
|
||||||
|
switch (segmentType)
|
||||||
|
{
|
||||||
|
case SEGMENT_TYPE_SMALL:
|
||||||
|
num = SEGMENT_TYPE_SMALL_CELL_SIZE / BLOCK_SIZE;
|
||||||
|
break;
|
||||||
|
case SEGMENT_TYPE_MEDIUM:
|
||||||
|
num = SEGMENT_TYPE_MEDIUM_CELL_SIZE / BLOCK_SIZE;
|
||||||
|
break;
|
||||||
|
case SEGMENT_TYPE_BIG:
|
||||||
|
num = SEGMENT_TYPE_BIG_CELL_SIZE / BLOCK_SIZE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockCount = num;
|
||||||
|
|
||||||
|
#ifndef YCSB_TEST
|
||||||
|
while (num--)
|
||||||
|
{
|
||||||
|
PrefetchBlockManagerEntry *entry = new PrefetchBlockManagerEntry();
|
||||||
|
entry->blockID = firstBlockID + num;
|
||||||
|
entry->currentOffset = 0;
|
||||||
|
entry->isOccupied = PREFETCH_BLOCK_STATUS_IDLE;
|
||||||
|
prefetchBlocks.insert(std::pair<uint64_t, PrefetchBlockManagerEntry>(entry->blockID, *entry));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
PrefetchBlockManager::~PrefetchBlockManager()
|
||||||
|
{
|
||||||
|
prefetchBlocks.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t
|
||||||
|
PrefetchBlockManager::getNextBlock()
|
||||||
|
{
|
||||||
|
uint32_t count = blockCount - currentID;
|
||||||
|
if (count <= 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
currentID++;
|
||||||
|
return currentID + firstBlockID - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t
|
||||||
|
PrefetchBlockManager::blockAllocate(uint64_t rowSize)
|
||||||
|
{
|
||||||
|
if (blockCount == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// struct timespec time;
|
||||||
|
// clock_gettime(CLOCK_REALTIME, &time);
|
||||||
|
srand((unsigned)time(NULL));
|
||||||
|
std::map<uint64_t, PrefetchBlockManagerEntry>::iterator iter;
|
||||||
|
uint32_t count = blockCount - currentID;
|
||||||
|
|
||||||
|
while (count--)
|
||||||
|
{
|
||||||
|
uint64_t blockID = currentID + firstBlockID;
|
||||||
|
iter = prefetchBlocks.find(blockID);
|
||||||
|
|
||||||
|
if (!iter->second.isOccupied)
|
||||||
|
{
|
||||||
|
if (rowSize < (BLOCK_SIZE - iter->second.currentOffset))
|
||||||
|
{
|
||||||
|
iter->second.isOccupied = PREFETCH_BLOCK_STATUS_BUSY;
|
||||||
|
return blockID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currentID++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
PrefetchBlockManager::setBlockState(uint64_t blockID, bool isOccupied)
|
||||||
|
{
|
||||||
|
std::map<uint64_t, PrefetchBlockManagerEntry>::iterator iter;
|
||||||
|
iter = prefetchBlocks.find(blockID);
|
||||||
|
|
||||||
|
if (iter != prefetchBlocks.end())
|
||||||
|
{
|
||||||
|
iter->second.isOccupied = isOccupied;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return PREFETCH_BLOCK_NOT_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
PrefetchBlockManager::setOffset(uint64_t blockID, uint64_t currentOffset)
|
||||||
|
{
|
||||||
|
std::map<uint64_t, PrefetchBlockManagerEntry>::iterator iter;
|
||||||
|
iter = prefetchBlocks.find(blockID);
|
||||||
|
|
||||||
|
if (iter != prefetchBlocks.end())
|
||||||
|
{
|
||||||
|
iter->second.currentOffset = currentOffset;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return PREFETCH_BLOCK_NOT_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
PrefetchBlockManager::getOffset(uint64_t blockID, uint64_t ¤tOffset)
|
||||||
|
{
|
||||||
|
std::map<uint64_t, PrefetchBlockManagerEntry>::iterator iter;
|
||||||
|
iter = prefetchBlocks.find(blockID);
|
||||||
|
|
||||||
|
if (iter != prefetchBlocks.end())
|
||||||
|
{
|
||||||
|
currentOffset = iter->second.currentOffset;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return PREFETCH_BLOCK_NOT_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
PrefetchBlockManager::advanceOffset(uint64_t blockID, uint64_t rowSize)
|
||||||
|
{
|
||||||
|
std::map<uint64_t, PrefetchBlockManagerEntry>::iterator iter;
|
||||||
|
iter = prefetchBlocks.find(blockID);
|
||||||
|
|
||||||
|
if (iter != prefetchBlocks.end())
|
||||||
|
{
|
||||||
|
iter->second.currentOffset += rowSize;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return PREFETCH_BLOCK_NOT_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
PrefetchBlockManager::isOccupied(uint64_t blockID, bool &status)
|
||||||
|
{
|
||||||
|
std::map<uint64_t, PrefetchBlockManagerEntry>::iterator iter;
|
||||||
|
iter = prefetchBlocks.find(blockID);
|
||||||
|
|
||||||
|
if (iter != prefetchBlocks.end())
|
||||||
|
{
|
||||||
|
status = iter->second.isOccupied;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return PREFETCH_BLOCK_NOT_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
PrefetchBlockManager::getPrefetchBlockEntry(uint64_t blockID,
|
||||||
|
PrefetchBlockManagerEntry &entry)
|
||||||
|
{
|
||||||
|
entry = prefetchBlocks[blockID];
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
PrefetchBlockManager::getAllPrefetchBlockEntrys(std::map<uint64_t,
|
||||||
|
PrefetchBlockManagerEntry> &entrys)
|
||||||
|
{
|
||||||
|
entrys = prefetchBlocks;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
PrefetchBlockManager::lockBlock(uint64_t blockID)
|
||||||
|
{
|
||||||
|
std::map<uint64_t, PrefetchBlockManagerEntry>::iterator iter;
|
||||||
|
iter = prefetchBlocks.find(blockID);
|
||||||
|
if (iter != prefetchBlocks.end())
|
||||||
|
{
|
||||||
|
if (iter->second.isOccupied == PREFETCH_BLOCK_STATUS_BUSY)
|
||||||
|
{
|
||||||
|
return BLOCK_OCCUPIED;
|
||||||
|
}
|
||||||
|
iter->second.isOccupied = PREFETCH_BLOCK_STATUS_BUSY;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
return PREFETCH_BLOCK_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
PrefetchBlockManager::unlockBlock(uint64_t blockID)
|
||||||
|
{
|
||||||
|
std::map<uint64_t, PrefetchBlockManagerEntry>::iterator iter;
|
||||||
|
iter = prefetchBlocks.find(blockID);
|
||||||
|
if (iter != prefetchBlocks.end())
|
||||||
|
{
|
||||||
|
if (iter->second.isOccupied == PREFETCH_BLOCK_STATUS_BUSY)
|
||||||
|
{
|
||||||
|
iter->second.isOccupied = PREFETCH_BLOCK_STATUS_IDLE;
|
||||||
|
}
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
return PREFETCH_BLOCK_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
PrefetchBlockManager::isCached(uint64_t blockID, uint64_t &pageID)
|
||||||
|
{
|
||||||
|
std::map<uint64_t, PrefetchBlockManagerEntry>::iterator iter;
|
||||||
|
iter = prefetchBlocks.find(blockID);
|
||||||
|
|
||||||
|
if (iter != prefetchBlocks.end() && iter->second.isCached)
|
||||||
|
{
|
||||||
|
pageID = iter->second.pageID;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
PrefetchBlockManager::setIsCached(uint64_t blockID, bool isCached, uint64_t pageID)
|
||||||
|
{
|
||||||
|
std::map<uint64_t, PrefetchBlockManagerEntry>::iterator iter;
|
||||||
|
iter = prefetchBlocks.find(blockID);
|
||||||
|
|
||||||
|
if (iter != prefetchBlocks.end())
|
||||||
|
{
|
||||||
|
iter->second.isCached = isCached;
|
||||||
|
if (isCached)
|
||||||
|
{
|
||||||
|
iter->second.pageID = pageID;
|
||||||
|
}
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
return PREFETCH_BLOCK_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace LightTable
|
|
@ -0,0 +1,244 @@
|
||||||
|
/**
|
||||||
|
* @file RootTable.cc
|
||||||
|
* @brief RootTable
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "RootTable.h"
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
RootTable::RootTable(bool usePrimaryKeyIndex)
|
||||||
|
: SystemTable(ROOTTABLE_TABLE_ID, "RootTable", ROOTTABLE_FIRST_BLOCK_ID,
|
||||||
|
ROOTTABLE_SEGMENT_ID, SEGMENT_TYPE_SMALL,
|
||||||
|
usePrimaryKeyIndex) {
|
||||||
|
Schema::SchemaEntry entry1 = {1, "tableID", "uint64_t", 8, true, false};
|
||||||
|
schema.appendEntry(entry1);
|
||||||
|
Schema::SchemaEntry entry2 = {2, "tableName", "string", TABLE_NAME_LENGTH,
|
||||||
|
false, false};
|
||||||
|
schema.appendEntry(entry2);
|
||||||
|
Schema::SchemaEntry entry3 = {3, "firstBlockID", "uint64_t", 8, false, false};
|
||||||
|
schema.appendEntry(entry3);
|
||||||
|
Schema::SchemaEntry entry4 = {4, "segmentID", "uint64_t", 8, false, false};
|
||||||
|
schema.appendEntry(entry4);
|
||||||
|
Schema::SchemaEntry entry5 = {5, "segmentType", "uint32_t", 4, false, false};
|
||||||
|
schema.appendEntry(entry5);
|
||||||
|
Schema::SchemaEntry entry6 = {6, "user", "string", USER_NAME_LENGTH,
|
||||||
|
false, true};
|
||||||
|
schema.appendEntry(entry6);
|
||||||
|
Schema::SchemaEntry entry7 = {7, "time", "time", 60, false, false};
|
||||||
|
schema.appendEntry(entry7);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t RootTable::tableNameToTableID(const char *tableName,
|
||||||
|
uint64_t &tableID) {
|
||||||
|
std::map<uint64_t, TableTuple>::iterator iter = tableTupleMap.begin();
|
||||||
|
|
||||||
|
while (iter != tableTupleMap.end()) {
|
||||||
|
if (0 == strncmp(tableName, iter->second.tableName, TABLE_NAME_LENGTH)) {
|
||||||
|
tableID = iter->second.tableID;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
iter++;
|
||||||
|
}
|
||||||
|
return TABLE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t RootTable::deleteTableInfo(uint64_t tableID) {
|
||||||
|
uint32_t ret = SUCCESS;
|
||||||
|
|
||||||
|
RowLocation rowLocation;
|
||||||
|
uint32_t bucketID = hashTable.hashToBucket(tableID);
|
||||||
|
ret = hashTable.getRowLocation(bucketID, tableID, rowLocation);
|
||||||
|
|
||||||
|
uint64_t deleteBlockID = rowLocation.blockID;
|
||||||
|
uint64_t deleteRowOffset = rowLocation.rowOffset;
|
||||||
|
char *hashTableMetaData = new char[ROWMAP_SERIALIZED_LENGTH];
|
||||||
|
uint32_t size = 0;
|
||||||
|
|
||||||
|
while (prefetchBlockManager.lockBlock(rowLocation.blockID) != SUCCESS)
|
||||||
|
;
|
||||||
|
uint64_t currentOffset = 0;
|
||||||
|
ret = prefetchBlockManager.getOffset(rowLocation.blockID, currentOffset);
|
||||||
|
if (ret != SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rowLocation.rowOffset + schema.getEntrySize() != currentOffset) {
|
||||||
|
// RowBufferItem::Tuple item;
|
||||||
|
// uint8_t str[ROOTTABLE_TUPLE_SIZE];
|
||||||
|
// memcpy(str, &tableTupleMap[tableID], sizeof(tableTupleMap[tableID]));
|
||||||
|
// item.blockID = rowLocation.blockID;
|
||||||
|
// item.rowOffset = rowLocation.rowOffset;
|
||||||
|
// item.isDelete = true;
|
||||||
|
// RowBufferItem *rowBufferItem = new RowBufferItem(item);
|
||||||
|
// buf->append(rowBufferItem);
|
||||||
|
|
||||||
|
std::map<uint64_t, RowLocation> locationItems;
|
||||||
|
hashTable.refreshRowLocations(deleteBlockID, deleteRowOffset,
|
||||||
|
schema.getEntrySize(), locationItems);
|
||||||
|
// std::map<uint64_t, RowLocation>::iterator iter = locationItems.begin();
|
||||||
|
// while (iter != locationItems.end()) {
|
||||||
|
// MetaHandle::serialize(std::pair<uint64_t, RowLocation>(iter->first,
|
||||||
|
// iter->second), tableID, hashTableMetaData, size);
|
||||||
|
// MetaBufferItem *nextMeta= new MetaBufferItem(tableID, hashTableMetaData,
|
||||||
|
// size); buf->append(nextMeta);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
hashTable.deleteItem(bucketID, tableID);
|
||||||
|
rowLocation.blockID = 0;
|
||||||
|
// MetaHandle::serialize(std::pair<uint64_t, RowLocation>(tableID,
|
||||||
|
// rowLocation),
|
||||||
|
// ROOTTABLE_TABLE_ID, hashTableMetaData, size);
|
||||||
|
// MetaBufferItem *hashTableMeta= new MetaBufferItem(ROOTTABLE_TABLE_ID,
|
||||||
|
// hashTableMetaData, size);
|
||||||
|
// buf->append(hashTableMeta);
|
||||||
|
|
||||||
|
uint64_t newOffset = currentOffset - schema.getEntrySize();
|
||||||
|
prefetchBlockManager.setOffset(deleteBlockID, newOffset);
|
||||||
|
|
||||||
|
PrefetchBlockManager::PrefetchBlockManagerEntry blockEntry;
|
||||||
|
prefetchBlockManager.unlockBlock(deleteBlockID);
|
||||||
|
prefetchBlockManager.getPrefetchBlockEntry(deleteBlockID, blockEntry);
|
||||||
|
// char *pbmData = new char[PREFETCH_BLOCK_SERIALIZED_LENGTH];
|
||||||
|
// MetaHandle::serialize(blockEntry, ROOTTABLE_TABLE_ID, pbmData, size);
|
||||||
|
// MetaBufferItem *pbmMeta = new MetaBufferItem(ROOTTABLE_TABLE_ID, pbmData,
|
||||||
|
// size); buf->append(pbmMeta);
|
||||||
|
|
||||||
|
if (tableTupleMap.erase(tableID) == 1) {
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
return ERROR_TABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t RootTable::appendTableInfo(TableTuple tableTuple) {
|
||||||
|
uint32_t err = SUCCESS;
|
||||||
|
|
||||||
|
tableTupleMap.insert(
|
||||||
|
std::pair<uint64_t, TableTuple>(tableTuple.tableID, tableTuple));
|
||||||
|
|
||||||
|
uint64_t blockID = 0;
|
||||||
|
uint64_t blockOffset = 0;
|
||||||
|
blockID = prefetchBlockManager.blockAllocate(schema.getEntrySize());
|
||||||
|
err = prefetchBlockManager.getOffset(blockID, blockOffset);
|
||||||
|
|
||||||
|
if (err != SUCCESS) {
|
||||||
|
// TODO allocate new seg
|
||||||
|
return GET_AVAILABLE_BLOCK_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RowBufferItem::Tuple item;
|
||||||
|
// uint8_t str[ROOTTABLE_TUPLE_SIZE];
|
||||||
|
// memcpy(str, &tableTuple, sizeof(tableTuple));
|
||||||
|
// item.row = str;
|
||||||
|
// item.blockID = blockID;
|
||||||
|
// item.rowOffset = blockOffset;
|
||||||
|
// item.isDelete = false;
|
||||||
|
// RowBufferItem *rowBufferItem = new RowBufferItem(item);
|
||||||
|
// buf->append(rowBufferItem);
|
||||||
|
|
||||||
|
uint32_t bucketID = hashTable.hashToBucket(tableTuple.tableID);
|
||||||
|
RowLocation rowLocation = {blockID, blockOffset};
|
||||||
|
err = hashTable.addItem(bucketID, tableTuple.tableID, rowLocation);
|
||||||
|
|
||||||
|
if (err != SUCCESS) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// uint32_t size = 0;
|
||||||
|
// char *hashTableMetaData = new char[ROWMAP_SERIALIZED_LENGTH];
|
||||||
|
// MetaHandle::serialize(std::pair<uint64_t, RowLocation>(tableTuple.tableID,
|
||||||
|
// rowLocation), tableID, hashTableMetaData, size);
|
||||||
|
// MetaBufferItem *hashTableMeta = new MetaBufferItem(tableID,
|
||||||
|
// hashTableMetaData,
|
||||||
|
// size);
|
||||||
|
// buf->append(hashTableMeta);
|
||||||
|
|
||||||
|
err = prefetchBlockManager.advanceOffset(blockID, schema.getEntrySize());
|
||||||
|
prefetchBlockManager.setBlockState(blockID, PREFETCH_BLOCK_STATUS_IDLE);
|
||||||
|
|
||||||
|
// PrefetchBlockManager::PrefetchBlockManagerEntry blockEntry;
|
||||||
|
// prefetchBlockManager.getPrefetchBlockEntry(blockID, blockEntry);
|
||||||
|
// char *pbmData = new char[PREFETCH_BLOCK_SERIALIZED_LENGTH];
|
||||||
|
// MetaHandle::serialize(blockEntry, tableID, pbmData, size);
|
||||||
|
// MetaBufferItem *pbmMeta = new MetaBufferItem(tableID, pbmData, size);
|
||||||
|
// buf->append(pbmMeta);
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t RootTable::getTableInfo(uint64_t tableID,
|
||||||
|
TableTuple &tableTupleResult) {
|
||||||
|
std::map<uint64_t, TableTuple>::iterator iter;
|
||||||
|
iter = tableTupleMap.find(tableID);
|
||||||
|
|
||||||
|
if (iter != tableTupleMap.end()) {
|
||||||
|
tableTupleResult = iter->second;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
tableTupleResult.tableID = 0;
|
||||||
|
return TABLE_TUPLE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t RootTable::modifyTableInfo(uint64_t tableID, TableTuple tableTuple) {
|
||||||
|
uint32_t ret = SUCCESS;
|
||||||
|
std::map<uint64_t, TableTuple>::iterator iter;
|
||||||
|
iter = tableTupleMap.find(tableID);
|
||||||
|
|
||||||
|
if (iter != tableTupleMap.end()) {
|
||||||
|
iter->second = tableTuple;
|
||||||
|
|
||||||
|
uint32_t bucketID = hashTable.hashToBucket(tableID);
|
||||||
|
RowLocation rowLocation;
|
||||||
|
ret = hashTable.getRowLocation(bucketID, tableID, rowLocation);
|
||||||
|
if (ret != SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
// RowBufferItem::Tuple item;
|
||||||
|
// uint8_t str[ROOTTABLE_TUPLE_SIZE];
|
||||||
|
// memcpy(str, &tableTuple, sizeof(tableTuple));
|
||||||
|
// item.row = str;
|
||||||
|
// item.blockID = rowLocation.blockID;
|
||||||
|
// item.rowOffset = rowLocation.rowOffset;
|
||||||
|
// item.isDelete = false;
|
||||||
|
// RowBufferItem *rowBufferItem = new RowBufferItem(item);
|
||||||
|
// buf->append(rowBufferItem);
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
return TABLE_TUPLE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t RootTable::getTableTuple(uint64_t tableID, TableTuple &tableTuple) {
|
||||||
|
std::map<uint64_t, TableTuple>::iterator iter;
|
||||||
|
iter = tableTupleMap.find(tableID);
|
||||||
|
if (iter != tableTupleMap.end()) {
|
||||||
|
tableTuple = iter->second;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
return TABLE_TUPLE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t RootTable::serializeRow(const TableTuple tableTuple, uint8_t *buf) {
|
||||||
|
memcpy(buf, &tableTuple, ROOTTABLE_TUPLE_SIZE);
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t RootTable::deserializeRow(const uint8_t *buf,
|
||||||
|
TableTuple *tableTupleResult) {
|
||||||
|
if (buf != NULL) {
|
||||||
|
memcpy(tableTupleResult, buf, ROOTTABLE_TUPLE_SIZE);
|
||||||
|
if (tableTupleResult->tableID != 0) {
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return BUFFER_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t RootTable::getTableCount() { return tableTupleMap.size(); }
|
||||||
|
|
||||||
|
} // namespace LightTable
|
|
@ -0,0 +1,77 @@
|
||||||
|
/**
|
||||||
|
* @file RowMap.cc
|
||||||
|
* @brief RowMap
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "RowMap.h"
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
RowMap::RowMap() {}
|
||||||
|
|
||||||
|
uint32_t RowMap::appendEntry(uint64_t key, uint64_t blockID,
|
||||||
|
uint64_t rowOffset) {
|
||||||
|
std::pair<std::map<uint64_t, RowMapEntry>::iterator, bool> ret;
|
||||||
|
RowMapEntry rowMapEntry = {key, blockID, rowOffset};
|
||||||
|
|
||||||
|
ret = rowMapEntrys.insert(std::pair<uint64_t, RowMapEntry>(key, rowMapEntry));
|
||||||
|
|
||||||
|
if (ret.second == false) {
|
||||||
|
return ADD_ROW_MAP_ENTRY_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t RowMap::deleteEntry(uint64_t key) {
|
||||||
|
if (rowMapEntrys.erase(key) == 1) {
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
return ROW_MAP_ENTRY_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t RowMap::alterEntry(uint64_t key, uint64_t blockID,
|
||||||
|
uint64_t rowOffset) {
|
||||||
|
std::map<uint64_t, RowMapEntry>::iterator iter;
|
||||||
|
iter = rowMapEntrys.find(key);
|
||||||
|
|
||||||
|
if (iter != rowMapEntrys.end()) {
|
||||||
|
(iter->second).key = key;
|
||||||
|
(iter->second).blockID = blockID;
|
||||||
|
(iter->second).rowOffset = rowOffset;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ROW_MAP_ENTRY_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t RowMap::queryEntry(uint64_t key, RowMapEntry &rowMapEntry) {
|
||||||
|
std::map<uint64_t, RowMapEntry>::iterator iter;
|
||||||
|
iter = rowMapEntrys.find(key);
|
||||||
|
|
||||||
|
if (iter != rowMapEntrys.end()) {
|
||||||
|
rowMapEntry = iter->second;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
rowMapEntry.key = key;
|
||||||
|
rowMapEntry.blockID = 0;
|
||||||
|
rowMapEntry.rowOffset = 0;
|
||||||
|
return ROW_MAP_ENTRY_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t RowMap::queryAllEntry(
|
||||||
|
std::map<uint64_t, RowMapEntry> &allRowMapEntrys) {
|
||||||
|
if (rowMapEntrys.empty() == false) {
|
||||||
|
allRowMapEntrys = rowMapEntrys;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
return ROW_MAP_ENTRY_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t RowMap::getRowCount() { return rowMapEntrys.size(); }
|
||||||
|
|
||||||
|
} // namespace LightTable
|
|
@ -0,0 +1,166 @@
|
||||||
|
/**
|
||||||
|
* @file Schema.cc
|
||||||
|
* @brief table schema
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Schema.h"
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
Schema::Schema() {
|
||||||
|
primaryKeySchema.columnID = 1;
|
||||||
|
primaryKeySchema.isPrimaryKey = true;
|
||||||
|
columnCount = 0;
|
||||||
|
entrySize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Schema::Schema(std::vector<SchemaEntry> schemaEntrys) {
|
||||||
|
columnCount = 0;
|
||||||
|
entrySize = 0;
|
||||||
|
primaryKeySchema.columnID = 1;
|
||||||
|
primaryKeySchema.isPrimaryKey = true;
|
||||||
|
std::vector<SchemaEntry>::iterator iter = schemaEntrys.begin();
|
||||||
|
while (iter != schemaEntrys.end()) {
|
||||||
|
appendEntry(*iter);
|
||||||
|
iter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Schema::appendEntry(SchemaEntry &schemaEntry) {
|
||||||
|
if (schemaEntry.columnID != columnCount + 1) {
|
||||||
|
return COLUMN_ID_NOT_CONTINUOUS;
|
||||||
|
}
|
||||||
|
std::pair<std::map<uint64_t, SchemaEntry>::iterator, bool> ret;
|
||||||
|
ret = schemaEntrys.insert(std::pair<uint64_t, Schema::SchemaEntry>(
|
||||||
|
schemaEntry.columnID, schemaEntry));
|
||||||
|
|
||||||
|
if (ret.second == false) {
|
||||||
|
return ADD_SCHEMA_ENTRY_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (schemaEntry.isPrimaryKey) {
|
||||||
|
primaryKeySchema = schemaEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
columnCount++;
|
||||||
|
entrySize = entrySize + schemaEntry.length;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Schema::deleteEntry(uint64_t columnID) {
|
||||||
|
if (columnID == primaryKeySchema.columnID) {
|
||||||
|
return DELETE_PARIMARY_KEY_COLUMN;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t newColumnID = columnID;
|
||||||
|
SchemaEntry schemaEntry;
|
||||||
|
|
||||||
|
std::map<uint64_t, SchemaEntry>::iterator iter;
|
||||||
|
iter = schemaEntrys.find(columnID);
|
||||||
|
if (iter != schemaEntrys.end()) {
|
||||||
|
schemaEntry = iter->second;
|
||||||
|
schemaEntrys.erase(iter);
|
||||||
|
entrySize = entrySize - schemaEntry.length;
|
||||||
|
columnCount--;
|
||||||
|
|
||||||
|
if (columnCount > 0) {
|
||||||
|
iter = schemaEntrys.find(newColumnID + 1);
|
||||||
|
|
||||||
|
while (iter != schemaEntrys.end()) {
|
||||||
|
schemaEntry = iter->second;
|
||||||
|
schemaEntry.columnID = newColumnID;
|
||||||
|
|
||||||
|
schemaEntrys.insert(
|
||||||
|
std::pair<uint64_t, Schema::SchemaEntry>(newColumnID, schemaEntry));
|
||||||
|
|
||||||
|
schemaEntrys.erase(iter);
|
||||||
|
newColumnID++;
|
||||||
|
iter = schemaEntrys.find(newColumnID + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
return SCHEMA_ENTRY_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Schema::alterEntry(uint64_t columnID, SchemaEntry schemaEntry) {
|
||||||
|
if (schemaEntry.columnID != columnID) {
|
||||||
|
return COLUMN_ID_NOT_CONTINUOUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<uint64_t, SchemaEntry>::iterator iter;
|
||||||
|
iter = schemaEntrys.find(columnID);
|
||||||
|
|
||||||
|
entrySize = entrySize - (iter->second).length;
|
||||||
|
|
||||||
|
if (iter != schemaEntrys.end()) {
|
||||||
|
iter->second = schemaEntry;
|
||||||
|
primaryKeySchema = schemaEntry;
|
||||||
|
entrySize = entrySize + (iter->second).length;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
return SCHEMA_ENTRY_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Schema::getColumnID(const char *columnName, uint64_t &columnID) {
|
||||||
|
std::map<uint64_t, SchemaEntry>::iterator iter = schemaEntrys.begin();
|
||||||
|
while (iter != schemaEntrys.end()) {
|
||||||
|
if (strncmp(iter->second.columnName, columnName, iter->second.length) ==
|
||||||
|
0) {
|
||||||
|
columnID = (iter->second).columnID;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
iter++;
|
||||||
|
}
|
||||||
|
return COLUMN_ITEM_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Schema::queryEntry(uint64_t columnID,
|
||||||
|
Schema::SchemaEntry &schemaEntry) {
|
||||||
|
std::map<uint64_t, SchemaEntry>::iterator iter;
|
||||||
|
iter = schemaEntrys.find(columnID);
|
||||||
|
|
||||||
|
if (iter != schemaEntrys.end()) {
|
||||||
|
schemaEntry = iter->second;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
schemaEntry.columnID = 0;
|
||||||
|
return SCHEMA_ENTRY_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Schema::queryAllEntry(
|
||||||
|
std::map<uint64_t, SchemaEntry> &allSchemaEntrys) {
|
||||||
|
allSchemaEntrys = schemaEntrys;
|
||||||
|
if (schemaEntrys.empty() == false) {
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
return SCHEMA_ENTRY_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t Schema::getEntrySize() { return entrySize; }
|
||||||
|
|
||||||
|
void Schema::setEntrySize(uint64_t entrySize) { this->entrySize = entrySize; }
|
||||||
|
|
||||||
|
uint64_t Schema::getColumnCount() { return columnCount; }
|
||||||
|
|
||||||
|
void Schema::setColumnCount(uint64_t columnCount) {
|
||||||
|
this->columnCount = columnCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Schema::getPrimaryKeyLength() { return primaryKeySchema.length; }
|
||||||
|
|
||||||
|
Schema::SchemaEntry &Schema::getPrimaryKeySchema() { return primaryKeySchema; }
|
||||||
|
|
||||||
|
uint32_t Schema::drop() {
|
||||||
|
schemaEntrys.clear();
|
||||||
|
primaryKeySchema.length = 0;
|
||||||
|
columnCount = 0;
|
||||||
|
entrySize = 0;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace LightTable
|
|
@ -0,0 +1,180 @@
|
||||||
|
/**
|
||||||
|
* @file SegmentManager.cc
|
||||||
|
* @brief SegmentManager
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "SegmentManager.h"
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
SegmentManager::SegmentManager() {
|
||||||
|
int blockID, num = 0;
|
||||||
|
|
||||||
|
smallBitmap = new uint8_t[SEGMENT_TYPE_SMALL_BITMAP_SIZE];
|
||||||
|
mediumBitmap = new uint8_t[SEGMENT_TYPE_MEDIUM_BITMAP_SIZE];
|
||||||
|
bigBitmap = new uint8_t[SEGMENT_TYPE_BIG_BITMAP_SIZE];
|
||||||
|
|
||||||
|
#ifdef YCSB_TEST
|
||||||
|
blockID = SEGMENT_TYPE_BIG_START;
|
||||||
|
while (num < SEGMENT_TYPE_BIG_BITMAP_SIZE) {
|
||||||
|
Driver::read(bigBitmap + num, blockID);
|
||||||
|
num += BLOCK_SIZE;
|
||||||
|
blockID++;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
num = 0;
|
||||||
|
blockID = SEGMENT_TYPE_SMALL_START;
|
||||||
|
while (num < SEGMENT_TYPE_SMALL_BITMAP_SIZE) {
|
||||||
|
Driver::read(smallBitmap + num, blockID);
|
||||||
|
num += BLOCK_SIZE;
|
||||||
|
blockID++;
|
||||||
|
}
|
||||||
|
|
||||||
|
num = 0;
|
||||||
|
blockID = SEGMENT_TYPE_MEDIUM_START;
|
||||||
|
while (num < SEGMENT_TYPE_MEDIUM_BITMAP_SIZE) {
|
||||||
|
Driver::read(mediumBitmap + num, blockID);
|
||||||
|
num += BLOCK_SIZE;
|
||||||
|
blockID++;
|
||||||
|
}
|
||||||
|
|
||||||
|
num = 0;
|
||||||
|
blockID = SEGMENT_TYPE_BIG_START;
|
||||||
|
while (num < SEGMENT_TYPE_BIG_BITMAP_SIZE) {
|
||||||
|
Driver::read(mediumBitmap + num, blockID);
|
||||||
|
num += BLOCK_SIZE;
|
||||||
|
blockID++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
SegmentManager::~SegmentManager() {
|
||||||
|
delete[] smallBitmap;
|
||||||
|
delete[] mediumBitmap;
|
||||||
|
delete[] bigBitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t SegmentManager::setBitmap(SegmentType segmentType, uint64_t segmentID,
|
||||||
|
SegmentStatus segmentStatus) {
|
||||||
|
switch (segmentType) {
|
||||||
|
case SEGMENT_TYPE_SMALL:
|
||||||
|
return setBit(segmentID, smallBitmap, SEGMENT_TYPE_SMALL_START,
|
||||||
|
segmentStatus);
|
||||||
|
|
||||||
|
case SEGMENT_TYPE_MEDIUM:
|
||||||
|
return setBit(segmentID, mediumBitmap, SEGMENT_TYPE_MEDIUM_START,
|
||||||
|
segmentStatus);
|
||||||
|
|
||||||
|
case SEGMENT_TYPE_BIG:
|
||||||
|
return setBit(segmentID, bigBitmap, SEGMENT_TYPE_BIG_START,
|
||||||
|
segmentStatus);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return SEGMENT_TYPE_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t SegmentManager::getIdleSegment(SegmentType segmentType,
|
||||||
|
uint64_t &segmentID,
|
||||||
|
uint64_t &firstBlockID) {
|
||||||
|
uint32_t stateCode;
|
||||||
|
|
||||||
|
switch (segmentType) {
|
||||||
|
case SEGMENT_TYPE_SMALL:
|
||||||
|
stateCode =
|
||||||
|
findFirstIdle(smallBitmap, SEGMENT_TYPE_SMALL_BITMAP_SIZE, segmentID);
|
||||||
|
|
||||||
|
if (stateCode != SUCCESS) return stateCode;
|
||||||
|
|
||||||
|
firstBlockID = SEGMENT_TYPE_SMALL_START +
|
||||||
|
(SEGMENT_TYPE_SMALL_CELL_SIZE / BLOCK_SIZE) * segmentID;
|
||||||
|
|
||||||
|
return setBit(segmentID, smallBitmap, SEGMENT_TYPE_SMALL_START,
|
||||||
|
SEGMENT_STATUS_BUSY);
|
||||||
|
|
||||||
|
case SEGMENT_TYPE_MEDIUM:
|
||||||
|
stateCode = findFirstIdle(mediumBitmap, SEGMENT_TYPE_MEDIUM_BITMAP_SIZE,
|
||||||
|
segmentID);
|
||||||
|
|
||||||
|
if (stateCode != SUCCESS) return stateCode;
|
||||||
|
|
||||||
|
firstBlockID = SEGMENT_TYPE_MEDIUM_START +
|
||||||
|
(SEGMENT_TYPE_MEDIUM_CELL_SIZE / BLOCK_SIZE) * segmentID;
|
||||||
|
|
||||||
|
return setBit(segmentID, mediumBitmap, SEGMENT_TYPE_MEDIUM_START,
|
||||||
|
SEGMENT_STATUS_BUSY);
|
||||||
|
|
||||||
|
case SEGMENT_TYPE_BIG:
|
||||||
|
stateCode =
|
||||||
|
findFirstIdle(bigBitmap, SEGMENT_TYPE_BIG_BITMAP_SIZE, segmentID);
|
||||||
|
|
||||||
|
if (stateCode != SUCCESS) return stateCode;
|
||||||
|
|
||||||
|
firstBlockID = SEGMENT_TYPE_BIG_START +
|
||||||
|
(SEGMENT_TYPE_BIG_CELL_SIZE / BLOCK_SIZE) * segmentID;
|
||||||
|
|
||||||
|
return setBit(segmentID, bigBitmap, SEGMENT_TYPE_BIG_START,
|
||||||
|
SEGMENT_STATUS_BUSY);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return SEGMENT_TYPE_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t SegmentManager::setBit(uint64_t segmentID, uint8_t *buf,
|
||||||
|
uint64_t segmentStart,
|
||||||
|
SegmentStatus segmentStatus) {
|
||||||
|
uint32_t integer, remainder;
|
||||||
|
uint8_t tmp = 1;
|
||||||
|
|
||||||
|
integer = segmentID / 8;
|
||||||
|
remainder = segmentID % 8;
|
||||||
|
|
||||||
|
tmp = tmp << remainder;
|
||||||
|
if (segmentStatus == SEGMENT_STATUS_BUSY) {
|
||||||
|
buf[integer] |= tmp;
|
||||||
|
} else if (segmentStatus == SEGMENT_STATUS_IDLE) {
|
||||||
|
buf[integer] &= ~tmp;
|
||||||
|
} else {
|
||||||
|
return SEGMENT_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t num = integer / BLOCK_SIZE;
|
||||||
|
uint64_t blockID = num + segmentStart;
|
||||||
|
|
||||||
|
Driver::write(buf + num * BLOCK_SIZE, blockID);
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t SegmentManager::findFirstIdle(uint8_t *buf, uint64_t segmentNum,
|
||||||
|
uint64_t &segmentID) {
|
||||||
|
uint64_t num, place;
|
||||||
|
uint8_t res, tmp, isfound;
|
||||||
|
|
||||||
|
for (isfound = num = 0; num < segmentNum; num++) {
|
||||||
|
for (place = 0; place < 8; place++) {
|
||||||
|
tmp = 0x01 << place;
|
||||||
|
tmp = tmp & buf[num];
|
||||||
|
res = (tmp >> place);
|
||||||
|
if (res == 0) {
|
||||||
|
isfound = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isfound == 1) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isfound == 0) {
|
||||||
|
return SEGMENT_IS_EXHAUSTED;
|
||||||
|
}
|
||||||
|
segmentID = num * 8 + place;
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace LightTable
|
|
@ -0,0 +1,31 @@
|
||||||
|
/**
|
||||||
|
* @file SystemTable.cc
|
||||||
|
* @brief SystemTable
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "SystemTable.h"
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
SystemTable::SystemTable(uint64_t tableID, const char *tableName,
|
||||||
|
uint64_t firstBlockID, uint64_t segmentID,
|
||||||
|
SegmentType segmentType,
|
||||||
|
std::vector<Schema::SchemaEntry> schemaEntrys,
|
||||||
|
bool usePrimaryKeyIndex)
|
||||||
|
: Table(tableID, tableName, firstBlockID, segmentID, segmentType,
|
||||||
|
schemaEntrys, usePrimaryKeyIndex)
|
||||||
|
|
||||||
|
{}
|
||||||
|
|
||||||
|
SystemTable::SystemTable(uint64_t tableID, const char *tableName,
|
||||||
|
uint64_t firstBlockID, uint64_t segmentID,
|
||||||
|
SegmentType segmentType, bool usePrimaryKeyIndex)
|
||||||
|
: Table(tableID, tableName, firstBlockID, segmentID, segmentType,
|
||||||
|
usePrimaryKeyIndex)
|
||||||
|
|
||||||
|
{}
|
||||||
|
|
||||||
|
} // namespace LightTable
|
|
@ -0,0 +1,639 @@
|
||||||
|
/**
|
||||||
|
* @file Table.cc
|
||||||
|
* @brief Table
|
||||||
|
* @version 0.1
|
||||||
|
* @author SYS Lab
|
||||||
|
* @date 2022.11.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Table.h"
|
||||||
|
|
||||||
|
namespace LightTable {
|
||||||
|
|
||||||
|
Table::Table(uint64_t tableID, const char *tableName, uint64_t firstBlockID,
|
||||||
|
uint64_t segmentID, SegmentType segmentType,
|
||||||
|
std::vector<Schema::SchemaEntry> schemaEntrys,
|
||||||
|
bool usePrimaryKeyIndex)
|
||||||
|
: prefetchBlockManager(firstBlockID, segmentID, segmentType),
|
||||||
|
schema(schemaEntrys),
|
||||||
|
rowMap(),
|
||||||
|
tupleNum(0),
|
||||||
|
t(time(0)),
|
||||||
|
indexLocation{TABLE1_INDEX_BLOCKID, META_ENTRY_NUM},
|
||||||
|
metaLogLocation{TABLE1_META_LOG_BLOCKID, META_ENTRY_NUM},
|
||||||
|
indexLogLocation{TABLE1_INDEX_LOG_BLOCKID, META_ENTRY_NUM},
|
||||||
|
dataLogLocation{TABLE1_DATA_LOG_BLOCKID, META_ENTRY_NUM} {
|
||||||
|
this->tableID = tableID;
|
||||||
|
memcpy(this->tableName, tableName, sizeof(tableName) + 1);
|
||||||
|
this->usePrimaryKeyIndex = usePrimaryKeyIndex;
|
||||||
|
std::map<uint64_t, Schema::SchemaEntry> allSchemaEntrys;
|
||||||
|
schema.queryAllEntry(allSchemaEntrys);
|
||||||
|
}
|
||||||
|
|
||||||
|
Table::Table(uint64_t tableID, const char *tableName, uint64_t firstBlockID,
|
||||||
|
uint64_t segmentID, SegmentType segmentType,
|
||||||
|
bool usePrimaryKeyIndex)
|
||||||
|
: prefetchBlockManager(firstBlockID, segmentID, segmentType),
|
||||||
|
schema(),
|
||||||
|
rowMap() {
|
||||||
|
this->tableID = tableID;
|
||||||
|
memcpy(this->tableName, tableName, sizeof(tableName) + 1);
|
||||||
|
// this->buf = buf;
|
||||||
|
// this->queryCache = queryCache;
|
||||||
|
// this->blockPreload = blockPreload;
|
||||||
|
this->usePrimaryKeyIndex = usePrimaryKeyIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Table::drop() {
|
||||||
|
uint32_t ret = SUCCESS;
|
||||||
|
|
||||||
|
ret = truncate();
|
||||||
|
if (ret != SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
schema.drop();
|
||||||
|
|
||||||
|
// std::map<uint64_t, Schema::SchemaEntry> allSchemaEntrys;
|
||||||
|
// schema.queryAllEntry(allSchemaEntrys);
|
||||||
|
// uint64_t columnCount = allSchemaEntrys.size();
|
||||||
|
// uint64_t length = 10 + columnCount * (SCHEMA_ENTRY_SERIALIZED_LENGTH + 1);
|
||||||
|
// char *schemaData = new char[length];
|
||||||
|
// uint32_t size = 0;
|
||||||
|
// MetaHandle::serialize(allSchemaEntrys, tableID, schemaData, size);
|
||||||
|
// MetaBufferItem *schemaMetaItem = new MetaBufferItem(tableID, schemaData,
|
||||||
|
// size); buf->append(schemaMetaItem); delete[] schemaData;
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// uint32_t Table::truncate() {
|
||||||
|
// uint32_t size = 0;
|
||||||
|
// char *pbmData;
|
||||||
|
// MetaBufferItem *pbmMeta;
|
||||||
|
// char *hashTableData;
|
||||||
|
// MetaBufferItem *hashTableMeta;
|
||||||
|
// std::map<uint64_t, PrefetchBlockManager::PrefetchBlockManagerEntry> entrys;
|
||||||
|
// prefetchBlockManager.getAllPrefetchBlockEntrys(entrys);
|
||||||
|
// std::map<uint64_t, PrefetchBlockManager::PrefetchBlockManagerEntry>::iterator
|
||||||
|
// pbmIter = entrys.begin();
|
||||||
|
// while (pbmIter != entrys.end()) {
|
||||||
|
// prefetchBlockManager.lockBlock(pbmIter->first);
|
||||||
|
// prefetchBlockManager.setOffset(pbmIter->first, 0);
|
||||||
|
// prefetchBlockManager.unlockBlock(pbmIter->first);
|
||||||
|
// pbmData = new char[PREFETCH_BLOCK_SERIALIZED_LENGTH];
|
||||||
|
// MetaHandle::serialize(pbmIter->second, tableID, pbmData, size);
|
||||||
|
// pbmMeta = new MetaBufferItem(tableID, pbmData, size);
|
||||||
|
// // buf->append(pbmMeta);
|
||||||
|
// pbmIter++;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// std::vector<HashBucket *> buckets;
|
||||||
|
// hashTable.getAllBuckets(buckets);
|
||||||
|
// for (uint32_t i = 0; i < buckets.size(); i++) {
|
||||||
|
// std::map<uint64_t, RowLocation> bucketItems;
|
||||||
|
// buckets[i]->getAllBucketItems(bucketItems);
|
||||||
|
// std::map<uint64_t, RowLocation>::iterator itemIter;
|
||||||
|
// itemIter = bucketItems.begin();
|
||||||
|
// while (itemIter != bucketItems.end()) {
|
||||||
|
// itemIter->second.blockID = 0;
|
||||||
|
// hashTableData = new char[ROWMAP_SERIALIZED_LENGTH];
|
||||||
|
// MetaHandle::serialize(
|
||||||
|
// std::pair<uint64_t, RowLocation>(itemIter->first, itemIter->second),
|
||||||
|
// tableID, hashTableData, size);
|
||||||
|
// hashTableMeta = new MetaBufferItem(tableID, hashTableData, size);
|
||||||
|
// // buf->append(hashTableMeta);
|
||||||
|
// itemIter = bucketItems.erase(itemIter);
|
||||||
|
// itemIter++;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return SUCCESS;
|
||||||
|
// }
|
||||||
|
|
||||||
|
uint32_t Table::parsePrimaryKey(const uint8_t *rowData, char *primaryKeyData) {
|
||||||
|
if (strncmp(schema.getPrimaryKeySchema().type, "uint64_t", 8) == 0) {
|
||||||
|
uint64_t primaryKeyI64 = 0;
|
||||||
|
memcpy(&primaryKeyI64, rowData, schema.getPrimaryKeySchema().length);
|
||||||
|
sprintf(primaryKeyData, "%ld", primaryKeyI64);
|
||||||
|
} else if (strncmp(schema.getPrimaryKeySchema().type, "string", 6) == 0) {
|
||||||
|
memcpy(primaryKeyData, rowData, schema.getPrimaryKeySchema().length);
|
||||||
|
} else {
|
||||||
|
return TYPE_INVALID;
|
||||||
|
}
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Table::insertRow(const uint8_t *rowData) {
|
||||||
|
uint32_t ret = SUCCESS;
|
||||||
|
uint64_t blockID = 0;
|
||||||
|
uint64_t blockOffset = 0;
|
||||||
|
uint8_t blockData[BLOCK_SIZE];
|
||||||
|
tupleNum++;
|
||||||
|
t = time(0);
|
||||||
|
|
||||||
|
#ifndef YCSB_TEST
|
||||||
|
blockID = prefetchBlockManager.blockAllocate(schema.getEntrySize());
|
||||||
|
while (blockID == 0) {
|
||||||
|
blockID = prefetchBlockManager.blockAllocate(schema.getEntrySize());
|
||||||
|
}
|
||||||
|
ret = prefetchBlockManager.getOffset(blockID, blockOffset);
|
||||||
|
if (ret != SUCCESS) {
|
||||||
|
// TODO allocate new seg
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
blockID = prefetchBlockManager.getNextBlock();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (blockOffset != 0) {
|
||||||
|
Driver::read(blockData, blockID);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(blockData + blockOffset, rowData, schema.getEntrySize());
|
||||||
|
#ifdef SDCARD_TEST
|
||||||
|
start_time = std::chrono::steady_clock::now();
|
||||||
|
#endif
|
||||||
|
Driver::write(blockData, blockID);
|
||||||
|
#ifdef SDCARD_TEST
|
||||||
|
for (int i = 0; i < SDCARD_TEST_NUM; ++i)
|
||||||
|
Driver::write(blockData, SDCARD_TEST_WRITE_BLOCKID + 100 * i);
|
||||||
|
end_time = std::chrono::steady_clock::now();
|
||||||
|
diff_sdcard_write = std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
|
end_time - start_time)
|
||||||
|
.count();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char *primaryKeyData = new char[schema.getPrimaryKeySchema().length];
|
||||||
|
ret = parsePrimaryKey(rowData, primaryKeyData);
|
||||||
|
if (ret != SUCCESS) {
|
||||||
|
delete[] primaryKeyData;
|
||||||
|
prefetchBlockManager.unlockBlock(blockID);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t key = hashTable.getMapKey(primaryKeyData);
|
||||||
|
uint32_t bucketID = hashTable.hashToBucket(key);
|
||||||
|
RowLocation rowLocation = {blockID, blockOffset};
|
||||||
|
ret = hashTable.addItem(bucketID, key, rowLocation);
|
||||||
|
|
||||||
|
if (ret != SUCCESS) {
|
||||||
|
delete[] primaryKeyData;
|
||||||
|
prefetchBlockManager.unlockBlock(blockID);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TABLE_STORAGE_SECOND_INDEX
|
||||||
|
ret = secondaryIndex.insert(primaryKeyData,
|
||||||
|
schema.getPrimaryKeySchema().length, rowLocation);
|
||||||
|
if (ret != SUCCESS) {
|
||||||
|
delete[] primaryKeyData;
|
||||||
|
prefetchBlockManager.unlockBlock(blockID);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef YCSB_TEST
|
||||||
|
ret = prefetchBlockManager.advanceOffset(blockID, schema.getEntrySize());
|
||||||
|
prefetchBlockManager.setBlockState(blockID, PREFETCH_BLOCK_STATUS_IDLE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
delete[] primaryKeyData;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Table::insertRow_logging(const uint8_t *rowData) {
|
||||||
|
uint32_t ret = SUCCESS;
|
||||||
|
uint64_t blockID = 0;
|
||||||
|
uint64_t blockOffset = 0;
|
||||||
|
|
||||||
|
tupleNum++;
|
||||||
|
t = time(0);
|
||||||
|
|
||||||
|
char *primaryKeyData = new char[schema.getPrimaryKeySchema().length];
|
||||||
|
ret = parsePrimaryKey(rowData, primaryKeyData);
|
||||||
|
if (ret != SUCCESS) {
|
||||||
|
delete[] primaryKeyData;
|
||||||
|
prefetchBlockManager.unlockBlock(blockID);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t key = hashTable.getMapKey(primaryKeyData);
|
||||||
|
uint32_t bucketID = hashTable.hashToBucket(key);
|
||||||
|
RowLocation rowLocation = {blockID, blockOffset};
|
||||||
|
|
||||||
|
ret = hashTable.addItem(bucketID, key, rowLocation);
|
||||||
|
if (ret != SUCCESS) {
|
||||||
|
delete[] primaryKeyData;
|
||||||
|
prefetchBlockManager.unlockBlock(blockID);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
metaLogEntry metaEntry{.tableID = tableID, .tupleNum = tupleNum, .t = t};
|
||||||
|
|
||||||
|
if (metaLogLocation.emptySlotNum != 0) {
|
||||||
|
memcpy(metaLog + (META_ENTRY_SIZE *
|
||||||
|
(META_ENTRY_NUM - metaLogLocation.emptySlotNum)),
|
||||||
|
&metaEntry, sizeof(metaLogEntry));
|
||||||
|
} else {
|
||||||
|
metaLogLocation.blockID++;
|
||||||
|
metaLogLocation.emptySlotNum = META_ENTRY_NUM;
|
||||||
|
memset(metaLog, 0, BLOCK_SIZE);
|
||||||
|
memcpy(metaLog, &metaEntry, sizeof(metaLogEntry));
|
||||||
|
}
|
||||||
|
Driver::write(metaLog, metaLogLocation.blockID);
|
||||||
|
metaLogLocation.emptySlotNum--;
|
||||||
|
|
||||||
|
uint32_t size = 0;
|
||||||
|
char *hashTableMetaData = new char[ROWMAP_SERIALIZED_LENGTH];
|
||||||
|
// MetaHandle::serialize(std::pair<uint64_t, RowLocation>(key, rowLocation),
|
||||||
|
// tableID, hashTableMetaData, size);
|
||||||
|
// MetaBufferItem *hashTableMeta =
|
||||||
|
// new MetaBufferItem(tableID, hashTableMetaData, size);
|
||||||
|
// if (indexLogLocation.emptySlotNum != 0) {
|
||||||
|
// memcpy(indexLog + (META_ENTRY_SIZE *
|
||||||
|
// (META_ENTRY_NUM - indexLogLocation.emptySlotNum)),
|
||||||
|
// hashTableMeta->metaItem,
|
||||||
|
// META_ENTRY_SIZE > hashTableMeta->metaItemSize
|
||||||
|
// ? hashTableMeta->metaItemSize
|
||||||
|
// : META_ENTRY_SIZE);
|
||||||
|
// } else {
|
||||||
|
// indexLogLocation.blockID++;
|
||||||
|
// indexLogLocation.emptySlotNum = META_ENTRY_NUM;
|
||||||
|
// memset(indexLog, 0, BLOCK_SIZE);
|
||||||
|
// memcpy(indexLog, hashTableMeta->metaItem,
|
||||||
|
// META_ENTRY_SIZE > hashTableMeta->metaItemSize
|
||||||
|
// ? hashTableMeta->metaItemSize
|
||||||
|
// : META_ENTRY_SIZE);
|
||||||
|
// }
|
||||||
|
Driver::write(indexLog, indexLogLocation.blockID);
|
||||||
|
indexLogLocation.emptySlotNum--;
|
||||||
|
|
||||||
|
memcpy(metaData, &tupleNum, 8);
|
||||||
|
memcpy(metaData + 8, &t, sizeof(std::time_t));
|
||||||
|
Driver::write(metaData, TABLE1_META_BLOCKID);
|
||||||
|
|
||||||
|
// if (indexLocation.emptySlotNum != 0) {
|
||||||
|
// memcpy(indexData + (META_ENTRY_SIZE *
|
||||||
|
// (META_ENTRY_NUM - indexLocation.emptySlotNum)),
|
||||||
|
// hashTableMeta->metaItem,
|
||||||
|
// META_ENTRY_SIZE > hashTableMeta->metaItemSize
|
||||||
|
// ? hashTableMeta->metaItemSize
|
||||||
|
// : META_ENTRY_SIZE);
|
||||||
|
// } else {
|
||||||
|
// indexLocation.blockID++;
|
||||||
|
// indexLocation.emptySlotNum = META_ENTRY_NUM;
|
||||||
|
// memset(indexData, 0, BLOCK_SIZE);
|
||||||
|
// memcpy(indexData, hashTableMeta->metaItem,
|
||||||
|
// META_ENTRY_SIZE > hashTableMeta->metaItemSize
|
||||||
|
// ? hashTableMeta->metaItemSize
|
||||||
|
// : META_ENTRY_SIZE);
|
||||||
|
// }
|
||||||
|
Driver::write(indexData, indexLocation.blockID);
|
||||||
|
indexLocation.emptySlotNum--;
|
||||||
|
|
||||||
|
uint8_t blockData[BLOCK_SIZE];
|
||||||
|
blockID = dataLogLocation.blockID;
|
||||||
|
memcpy(blockData, rowData, schema.getEntrySize());
|
||||||
|
Driver::write(blockData, blockID);
|
||||||
|
dataLogLocation.blockID++;
|
||||||
|
|
||||||
|
blockID = prefetchBlockManager.getNextBlock();
|
||||||
|
if (blockOffset != 0) {
|
||||||
|
Driver::read(blockData, blockID);
|
||||||
|
}
|
||||||
|
memcpy(blockData + blockOffset, rowData, schema.getEntrySize());
|
||||||
|
Driver::write(blockData, blockID);
|
||||||
|
|
||||||
|
delete[] hashTableMetaData;
|
||||||
|
// delete hashTableMeta;
|
||||||
|
delete[] primaryKeyData;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Table::deleteRow(const char *primaryKey) {
|
||||||
|
uint32_t ret = SUCCESS;
|
||||||
|
|
||||||
|
RowLocation rowLocation;
|
||||||
|
ret = locateRow(primaryKey, rowLocation);
|
||||||
|
if (ret != SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
uint64_t deleteBlockID = rowLocation.blockID;
|
||||||
|
uint64_t deleteRowOffset = rowLocation.rowOffset;
|
||||||
|
|
||||||
|
while (prefetchBlockManager.lockBlock(rowLocation.blockID) != SUCCESS)
|
||||||
|
;
|
||||||
|
uint64_t currentOffset = 0;
|
||||||
|
ret = prefetchBlockManager.getOffset(rowLocation.blockID, currentOffset);
|
||||||
|
uint64_t key = hashTable.getMapKey(primaryKey);
|
||||||
|
|
||||||
|
if (rowLocation.rowOffset + schema.getEntrySize() != currentOffset) {
|
||||||
|
ret = deleteRowData(key, rowLocation);
|
||||||
|
if (ret != SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t size = 0;
|
||||||
|
uint32_t bucketID = hashTable.hashToBucket(key);
|
||||||
|
hashTable.deleteItem(bucketID, key);
|
||||||
|
char *hashTableMetaData = new char[ROWMAP_SERIALIZED_LENGTH];
|
||||||
|
rowLocation.blockID = 0;
|
||||||
|
// MetaHandle::serialize(std::pair<uint64_t, RowLocation>(key, rowLocation),
|
||||||
|
// tableID, hashTableMetaData, size);
|
||||||
|
// MetaBufferItem *hashTableMeta= new MetaBufferItem(tableID,
|
||||||
|
// hashTableMetaData,
|
||||||
|
// size);
|
||||||
|
// buf->append(hashTableMeta);
|
||||||
|
|
||||||
|
if (deleteRowOffset + schema.getEntrySize() != currentOffset) {
|
||||||
|
std::map<uint64_t, RowLocation> locationItems;
|
||||||
|
hashTable.refreshRowLocations(deleteBlockID, deleteRowOffset,
|
||||||
|
schema.getEntrySize(), locationItems);
|
||||||
|
// std::map<uint64_t, RowLocation>::iterator iter = locationItems.begin();
|
||||||
|
// while (iter != locationItems.end()) {
|
||||||
|
// MetaHandle::serialize(std::pair<uint64_t, RowLocation>(iter->first,
|
||||||
|
// iter->second), tableID, hashTableMetaData,
|
||||||
|
// size);
|
||||||
|
// MetaBufferItem *nextMeta= new MetaBufferItem(tableID,
|
||||||
|
// hashTableMetaData,
|
||||||
|
// size);
|
||||||
|
// buf->append(nextMeta);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t newOffset = currentOffset - schema.getEntrySize();
|
||||||
|
prefetchBlockManager.setOffset(deleteBlockID, newOffset);
|
||||||
|
prefetchBlockManager.unlockBlock(deleteBlockID);
|
||||||
|
PrefetchBlockManager::PrefetchBlockManagerEntry blockEntry;
|
||||||
|
prefetchBlockManager.getPrefetchBlockEntry(deleteBlockID, blockEntry);
|
||||||
|
// char *pbmData = new char[PREFETCH_BLOCK_SERIALIZED_LENGTH];
|
||||||
|
// MetaHandle::serialize(blockEntry, tableID, pbmData, size);
|
||||||
|
// MetaBufferItem *pbmMeta = new MetaBufferItem(tableID, pbmData, size);
|
||||||
|
// buf->append(pbmMeta);
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Table::deleteRowData(uint64_t key, RowLocation rowLocation) {
|
||||||
|
uint8_t blockData[BLOCK_SIZE];
|
||||||
|
Driver::read(blockData, rowLocation.blockID);
|
||||||
|
|
||||||
|
uint64_t start = rowLocation.rowOffset;
|
||||||
|
uint64_t nextRow = start + schema.getEntrySize();
|
||||||
|
memcpy(blockData + start, blockData + nextRow, BLOCK_SIZE - nextRow);
|
||||||
|
|
||||||
|
Driver::write(blockData, rowLocation.blockID);
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Table::updateRow(const char *primaryKey, const uint8_t *rowData) {
|
||||||
|
uint32_t ret = SUCCESS;
|
||||||
|
|
||||||
|
RowLocation rowLocation;
|
||||||
|
ret = locateRow(primaryKey, rowLocation);
|
||||||
|
if (ret == BUCKET_ITEM_NOT_FOUND) {
|
||||||
|
return insertRow(rowData);
|
||||||
|
} else if (ret != SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t blockData[BLOCK_SIZE];
|
||||||
|
|
||||||
|
while (prefetchBlockManager.lockBlock(rowLocation.blockID) != SUCCESS)
|
||||||
|
;
|
||||||
|
Driver::read(blockData, rowLocation.blockID);
|
||||||
|
|
||||||
|
// char *undoTuple = new char[schema.getEntrySize()];
|
||||||
|
// memcpy(undoTuple, blockData+rowLocation.rowOffset, schema.getEntrySize());
|
||||||
|
// UndoLogEntry *logEntry = new UndoLogEntry(this->tableID, primaryKey,
|
||||||
|
// schema.getPrimaryKeyLength(),
|
||||||
|
// undoTuple, schema.getEntrySize(),
|
||||||
|
// rowLocation.blockID, rowLocation.rowOffset);
|
||||||
|
// buf->append(logEntry);
|
||||||
|
|
||||||
|
memcpy(blockData + rowLocation.rowOffset, rowData, schema.getEntrySize());
|
||||||
|
|
||||||
|
if (SUCCESS != Driver::write(blockData, rowLocation.blockID)) {
|
||||||
|
// memcpy(blockData + rowLocation.rowOffset, undoTuple,
|
||||||
|
// schema.getEntrySize());
|
||||||
|
// ret = UPDATE_TUPLE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// logEntry->expireUndoLog();
|
||||||
|
prefetchBlockManager.unlockBlock(rowLocation.blockID);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Table::locateRow(const char *primaryKey, RowLocation &rowLocation) {
|
||||||
|
uint32_t ret = SUCCESS;
|
||||||
|
|
||||||
|
uint64_t key = hashTable.getMapKey(primaryKey);
|
||||||
|
uint32_t bucketID = hashTable.hashToBucket(key);
|
||||||
|
|
||||||
|
ret = hashTable.getRowLocation(bucketID, key, rowLocation);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Table::selectRow(const char *primaryKey, uint8_t *rowData) {
|
||||||
|
RowLocation rowLocation;
|
||||||
|
return selectRow(primaryKey, rowData, rowLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Table::selectRow(const char *primaryKey, uint8_t *rowData,
|
||||||
|
RowLocation &rowLocation) {
|
||||||
|
uint32_t ret = SUCCESS;
|
||||||
|
uint8_t blockData[BLOCK_SIZE];
|
||||||
|
|
||||||
|
ret = locateRow(primaryKey, rowLocation);
|
||||||
|
if (ret != SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef YCSB_TEST
|
||||||
|
while (prefetchBlockManager.lockBlock(rowLocation.blockID) != SUCCESS)
|
||||||
|
;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SDCARD_TEST
|
||||||
|
start_time = std::chrono::steady_clock::now();
|
||||||
|
#endif
|
||||||
|
Driver::read(blockData, rowLocation.blockID);
|
||||||
|
#ifdef SDCARD_TEST
|
||||||
|
for (int i = 0; i < SDCARD_TEST_NUM; ++i)
|
||||||
|
Driver::read(blockData, SDCARD_TEST_READ_BLOCKID + 100 * i);
|
||||||
|
end_time = std::chrono::steady_clock::now();
|
||||||
|
diff_sdcard_read = (std::chrono::duration_cast<std::chrono::microseconds>(
|
||||||
|
end_time - start_time)
|
||||||
|
.count());
|
||||||
|
#endif
|
||||||
|
#ifndef YCSB_TEST
|
||||||
|
prefetchBlockManager.unlockBlock(rowLocation.blockID);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ret = getRowFromBlock(primaryKey, rowData, blockData, rowLocation);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Table::getRowFromBlock(const char *primaryKey, uint8_t *rowData,
|
||||||
|
const uint8_t *blockData,
|
||||||
|
const RowLocation rowLocation) {
|
||||||
|
uint32_t ret = SUCCESS;
|
||||||
|
|
||||||
|
char *primaryKeyData = new char[schema.getPrimaryKeySchema().length];
|
||||||
|
if (rowLocation.rowOffset + schema.getEntrySize() > BLOCK_SIZE) {
|
||||||
|
delete[] primaryKeyData;
|
||||||
|
return ROWLOCATION_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = parsePrimaryKey(blockData + rowLocation.rowOffset, primaryKeyData);
|
||||||
|
if (ret != SUCCESS) {
|
||||||
|
delete[] primaryKeyData;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp(primaryKeyData, primaryKey,
|
||||||
|
schema.getPrimaryKeySchema().length) != 0) {
|
||||||
|
delete[] primaryKeyData;
|
||||||
|
return ERROR_TABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(rowData, blockData + rowLocation.rowOffset, schema.getEntrySize());
|
||||||
|
|
||||||
|
delete[] primaryKeyData;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Table::selectColumnItem(const char *primaryKey, const char *columnName,
|
||||||
|
uint8_t *columnData) {
|
||||||
|
uint32_t ret = SUCCESS;
|
||||||
|
|
||||||
|
uint8_t *rowData = new uint8_t[schema.getEntrySize()];
|
||||||
|
RowLocation rowLocation;
|
||||||
|
ret = selectRow(primaryKey, rowData, rowLocation);
|
||||||
|
if (ret != SUCCESS) {
|
||||||
|
delete[] rowData;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t columnOffset = 0;
|
||||||
|
uint64_t columnID = 0;
|
||||||
|
uint32_t columnLength = 0;
|
||||||
|
ret = getColumnOffset(columnName, columnID, columnLength, columnOffset);
|
||||||
|
|
||||||
|
memcpy(columnData, rowData + columnOffset, columnLength);
|
||||||
|
|
||||||
|
delete[] rowData;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Table::updateColumnItem(const char *primaryKey, const char *columnName,
|
||||||
|
const uint8_t *columnData) {
|
||||||
|
uint32_t ret = SUCCESS;
|
||||||
|
|
||||||
|
uint8_t *blockData = new uint8_t[BLOCK_SIZE];
|
||||||
|
RowLocation rowLocation;
|
||||||
|
ret = locateRow(primaryKey, rowLocation);
|
||||||
|
if (ret != SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef YCSB_TEST
|
||||||
|
while (prefetchBlockManager.lockBlock(rowLocation.blockID) != SUCCESS)
|
||||||
|
;
|
||||||
|
#endif
|
||||||
|
Driver::read(blockData, rowLocation.blockID);
|
||||||
|
|
||||||
|
// char *undoTuple = new char[schema.getEntrySize()];
|
||||||
|
// memcpy(undoTuple, blockData+rowLocation.rowOffset, schema.getEntrySize());
|
||||||
|
// UndoLogEntry *logEntry = new UndoLogEntry(this->tableID, primaryKey,
|
||||||
|
// schema.getPrimaryKeyLength(),
|
||||||
|
// undoTuple, schema.getEntrySize(),
|
||||||
|
// rowLocation.blockID, rowLocation.rowOffset);
|
||||||
|
// buf->append(logEntry);
|
||||||
|
|
||||||
|
uint64_t columnOffset, columnID;
|
||||||
|
uint32_t columnLength;
|
||||||
|
ret = getColumnOffset(columnName, columnID, columnLength, columnOffset);
|
||||||
|
|
||||||
|
uint64_t columnStart = rowLocation.rowOffset + columnOffset;
|
||||||
|
memcpy(blockData + columnStart, columnData, columnLength);
|
||||||
|
|
||||||
|
if (SUCCESS != Driver::write(blockData, rowLocation.blockID)) {
|
||||||
|
// memcpy(blockData + rowLocation.rowOffset, undoTuple,
|
||||||
|
// schema.getEntrySize());
|
||||||
|
// ret = UPDATE_TUPLE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// logEntry->expireUndoLog();
|
||||||
|
#ifndef YCSB_TEST
|
||||||
|
prefetchBlockManager.unlockBlock(rowLocation.blockID);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
delete[] blockData;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Table::updateColumnItem_logging(const char *primaryKey,
|
||||||
|
const char *columnName,
|
||||||
|
const uint8_t *columnData) {
|
||||||
|
// TODO
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Table::getColumnOffset(const char *columnName, uint64_t &columnID,
|
||||||
|
uint32_t &columnLength, uint64_t &offset) {
|
||||||
|
uint32_t ret = SUCCESS;
|
||||||
|
offset = 0;
|
||||||
|
columnID = 0;
|
||||||
|
columnLength = 0;
|
||||||
|
|
||||||
|
ret = getColumnID(columnName, columnID);
|
||||||
|
if (ret != SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<uint64_t, Schema::SchemaEntry> schemaEntrys;
|
||||||
|
ret = schema.queryAllEntry(schemaEntrys);
|
||||||
|
if (ret != SUCCESS) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
columnLength = schemaEntrys[columnID].length;
|
||||||
|
for (uint64_t i = 1; i < columnID; i++) {
|
||||||
|
offset += schemaEntrys[i].length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t Table::getRowCount() { return hashTable.getItemCount(); }
|
||||||
|
|
||||||
|
uint64_t Table::getTableID() { return tableID; }
|
||||||
|
|
||||||
|
char *Table::getTableName() { return tableName; }
|
||||||
|
|
||||||
|
uint32_t Table::setTableID(uint64_t tableID) {
|
||||||
|
this->tableID = tableID;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Table::setTableName(const char *tableName) {
|
||||||
|
memcpy(this->tableName, tableName, sizeof(tableName) + 1);
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Table::getColumnID(const char *columnName, uint64_t &columnID) {
|
||||||
|
return schema.getColumnID(columnName, columnID);
|
||||||
|
}
|
||||||
|
|
||||||
|
Schema &Table::getSchema() { return schema; }
|
||||||
|
|
||||||
|
HashTable &Table::getHashTable() { return hashTable; }
|
||||||
|
|
||||||
|
} // namespace LightTable
|
|
@ -0,0 +1,3 @@
|
||||||
|
menuconfig APP_USING_NETDEV
|
||||||
|
bool "Enable network interface device"
|
||||||
|
default y
|
|
@ -0,0 +1,3 @@
|
||||||
|
SRC_DIR := src
|
||||||
|
|
||||||
|
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2015-02-17 Bernard First version
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file inet.h
|
||||||
|
* @brief using in webnet
|
||||||
|
* @version 2.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-09-15
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __INET_H__
|
||||||
|
#define __INET_H__
|
||||||
|
|
||||||
|
#include <netdev_ipaddr.h>
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,213 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2019-03-18 ChenYong First version
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file netdev.h
|
||||||
|
* @brief Structure and function declarations of device and ipaddr
|
||||||
|
* @version 2.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-09-15
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __NETDEV_H__
|
||||||
|
#define __NETDEV_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <transform.h>
|
||||||
|
#include "netdev_ipaddr.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#define netdev_container_of(ptr, type, member) ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
|
||||||
|
#define netdev_slist_entry(node, type, member) netdev_container_of(node, type, member)
|
||||||
|
#define netdev_list_entry(node, type, member) netdev_container_of(node, type, member)
|
||||||
|
|
||||||
|
/* the maximum of all used hardware address lengths */
|
||||||
|
#ifndef NETDEV_HWADDR_MAX_LEN
|
||||||
|
#define NETDEV_HWADDR_MAX_LEN 8U
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* the maximum of dns server number supported */
|
||||||
|
#ifndef NETDEV_DNS_SERVERS_NUM
|
||||||
|
#define NETDEV_DNS_SERVERS_NUM 2U
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if NETDEV_IPV6
|
||||||
|
/* the maximum of dns server number supported */
|
||||||
|
#ifndef NETDEV_IPV6_NUM_ADDRESSES
|
||||||
|
#define NETDEV_IPV6_NUM_ADDRESSES 3U
|
||||||
|
#endif
|
||||||
|
#endif /* NETDEV_IPV6 */
|
||||||
|
|
||||||
|
/* whether the network interface device is 'up' (set by the network interface driver or application) */
|
||||||
|
#define NETDEV_FLAG_UP 0x01U
|
||||||
|
/* if set, the network interface device has broadcast capability, only supported in the 'lwIP' stack */
|
||||||
|
#define NETDEV_FLAG_BROADCAST 0x02U
|
||||||
|
/* if set, the network interface device has an active link (set by the network interface driver) */
|
||||||
|
#define NETDEV_FLAG_LINK_UP 0x04U
|
||||||
|
/* if set, the network interface device is an ethernet device using ARP, only supported in the 'lwIP' stack */
|
||||||
|
#define NETDEV_FLAG_ETHARP 0x08U
|
||||||
|
/* if set, the network interface device is an ethernet device, only supported in the 'lwIP' stack */
|
||||||
|
#define NETDEV_FLAG_ETHERNET 0x10U
|
||||||
|
/* if set, the network interface device has IGMP capability, only supported in the 'lwIP' stack */
|
||||||
|
#define NETDEV_FLAG_IGMP 0x20U
|
||||||
|
/* if set, the network interface device has MLD6 capability, only supported in the 'lwIP' stack */
|
||||||
|
#define NETDEV_FLAG_MLD6 0x40U
|
||||||
|
/* if set, the network interface device connected to internet successfully (set by the network interface driver) */
|
||||||
|
#define NETDEV_FLAG_INTERNET_UP 0x80U
|
||||||
|
/* if set, the network interface device has DHCP capability (set by the network interface device driver or application) */
|
||||||
|
#define NETDEV_FLAG_DHCP 0x100U
|
||||||
|
|
||||||
|
enum netdev_cb_type
|
||||||
|
{
|
||||||
|
NETDEV_CB_ADDR_IP, /* IP address */
|
||||||
|
NETDEV_CB_ADDR_NETMASK, /* subnet mask */
|
||||||
|
NETDEV_CB_ADDR_GATEWAY, /* netmask */
|
||||||
|
NETDEV_CB_ADDR_DNS_SERVER, /* dns server */
|
||||||
|
NETDEV_CB_STATUS_UP, /* changed to 'up' */
|
||||||
|
NETDEV_CB_STATUS_DOWN, /* changed to 'down' */
|
||||||
|
NETDEV_CB_STATUS_LINK_UP, /* changed to 'link up' */
|
||||||
|
NETDEV_CB_STATUS_LINK_DOWN, /* changed to 'link down' */
|
||||||
|
NETDEV_CB_STATUS_INTERNET_UP, /* changed to 'internet up' */
|
||||||
|
NETDEV_CB_STATUS_INTERNET_DOWN, /* changed to 'internet down' */
|
||||||
|
NETDEV_CB_STATUS_DHCP_ENABLE, /* enable DHCP capability */
|
||||||
|
NETDEV_CB_STATUS_DHCP_DISABLE, /* disable DHCP capability */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct netdev;
|
||||||
|
|
||||||
|
/* function prototype for network interface device status or address change callback functions */
|
||||||
|
typedef void (*netdev_callback_fn )(struct netdev *netdev, enum netdev_cb_type type);
|
||||||
|
|
||||||
|
struct netdev_ops;
|
||||||
|
|
||||||
|
/* network interface device object */
|
||||||
|
struct netdev_slist_node
|
||||||
|
{
|
||||||
|
struct netdev_slist_node *next; /**< point to next node. */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct netdev_slist_node netdev_slist_t; /**< Type for single list. */
|
||||||
|
|
||||||
|
|
||||||
|
#define NETDEV_NAME_MAX 8
|
||||||
|
struct netdev
|
||||||
|
{
|
||||||
|
netdev_slist_t list;//
|
||||||
|
|
||||||
|
char name[NETDEV_NAME_MAX]; /* network interface device name */
|
||||||
|
ip_addr_t ip_addr; /* IP address */
|
||||||
|
ip_addr_t netmask; /* subnet mask */
|
||||||
|
ip_addr_t gw; /* gateway */
|
||||||
|
#if NETDEV_IPV6
|
||||||
|
ip_addr_t ip6_addr[NETDEV_IPV6_NUM_ADDRESSES]; /* array of IPv6 addresses */
|
||||||
|
#endif /* NETDEV_IPV6 */
|
||||||
|
ip_addr_t dns_servers[NETDEV_DNS_SERVERS_NUM]; /* DNS server */
|
||||||
|
uint8_t hwaddr_len; /* hardware address length */
|
||||||
|
uint8_t hwaddr[NETDEV_HWADDR_MAX_LEN]; /* hardware address */
|
||||||
|
|
||||||
|
uint16_t flags; /* network interface device status flag */
|
||||||
|
uint16_t mtu; /* maximum transfer unit (in bytes) */
|
||||||
|
const struct netdev_ops *ops; /* network interface device operations */
|
||||||
|
|
||||||
|
netdev_callback_fn status_callback; /* network interface device flags change callback */
|
||||||
|
netdev_callback_fn addr_callback; /* network interface device address information change callback */
|
||||||
|
|
||||||
|
|
||||||
|
void *user_data; /* user-specific data */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The list of network interface device */
|
||||||
|
extern struct netdev *netdev_list;
|
||||||
|
/* The default network interface device */
|
||||||
|
extern struct netdev *netdev_default;
|
||||||
|
|
||||||
|
/* The network interface device ping response object */
|
||||||
|
struct netdev_ping_resp
|
||||||
|
{
|
||||||
|
ip_addr_t ip_addr; /* response IP address */
|
||||||
|
uint16_t data_len; /* response data length */
|
||||||
|
uint16_t ttl; /* time to live */
|
||||||
|
uint32_t ticks; /* response time, unit tick */
|
||||||
|
void *user_data; /* user-specific data */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The network interface device operations */
|
||||||
|
struct netdev_ops
|
||||||
|
{
|
||||||
|
/* set network interface device hardware status operations */
|
||||||
|
int (*set_up)(struct netdev *netdev);
|
||||||
|
int (*set_down)(struct netdev *netdev);
|
||||||
|
|
||||||
|
/* set network interface device address information operations */
|
||||||
|
int (*set_addr_info)(struct netdev *netdev, ip_addr_t *ip_addr, ip_addr_t *netmask, ip_addr_t *gw);
|
||||||
|
int (*set_dns_server)(struct netdev *netdev, uint8_t dns_num, ip_addr_t *dns_server);
|
||||||
|
int (*set_dhcp)(struct netdev *netdev, _Bool is_enabled);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* set default network interface device in current network stack*/
|
||||||
|
int (*set_default)(struct netdev *netdev);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The network interface device registered and unregistered*/
|
||||||
|
int netdev_register(struct netdev *netdev, const char *name, void *user_data);
|
||||||
|
int netdev_unregister(struct netdev *netdev);
|
||||||
|
|
||||||
|
/* Get network interface device object */
|
||||||
|
struct netdev *netdev_get_first_by_flags(uint16_t flags);
|
||||||
|
struct netdev *netdev_get_by_ipaddr(ip_addr_t *ip_addr);
|
||||||
|
struct netdev *netdev_get_by_name(const char *name);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Set default network interface device in list */
|
||||||
|
void netdev_set_default(struct netdev *netdev);
|
||||||
|
|
||||||
|
/* Set network interface device status */
|
||||||
|
int netdev_set_up(struct netdev *netdev);
|
||||||
|
int netdev_set_down(struct netdev *netdev);
|
||||||
|
int netdev_dhcp_enabled(struct netdev *netdev, _Bool is_enabled);
|
||||||
|
|
||||||
|
/* Get network interface device status */
|
||||||
|
#define netdev_is_up(netdev) (((netdev)->flags & NETDEV_FLAG_UP) ? (uint8_t)1 : (uint8_t)0)
|
||||||
|
#define netdev_is_link_up(netdev) (((netdev)->flags & NETDEV_FLAG_LINK_UP) ? (uint8_t)1 : (uint8_t)0)
|
||||||
|
#define netdev_is_internet_up(netdev) (((netdev)->flags & NETDEV_FLAG_INTERNET_UP) ? (uint8_t)1 : (uint8_t)0)
|
||||||
|
#define netdev_is_dhcp_enabled(netdev) (((netdev)->flags & NETDEV_FLAG_DHCP) ? (uint8_t)1 : (uint8_t)0)
|
||||||
|
|
||||||
|
/* Set network interface device address */
|
||||||
|
int netdev_set_ipaddr(struct netdev *netdev, const ip_addr_t *ipaddr);
|
||||||
|
int netdev_set_netmask(struct netdev *netdev, const ip_addr_t *netmask);
|
||||||
|
int netdev_set_gw(struct netdev *netdev, const ip_addr_t *gw);
|
||||||
|
int netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server);
|
||||||
|
|
||||||
|
/* Set network interface device callback, it can be called when the status or address changed */
|
||||||
|
void netdev_set_status_callback(struct netdev *netdev, netdev_callback_fn status_callback);
|
||||||
|
void netdev_set_addr_callback(struct netdev *netdev, netdev_callback_fn addr_callback);
|
||||||
|
|
||||||
|
/* Set network interface device status and address, this function can only be called in the network interface device driver */
|
||||||
|
void netdev_low_level_set_ipaddr(struct netdev *netdev, const ip_addr_t *ipaddr);
|
||||||
|
void netdev_low_level_set_netmask(struct netdev *netdev, const ip_addr_t *netmask);
|
||||||
|
void netdev_low_level_set_gw(struct netdev *netdev, const ip_addr_t *gw);
|
||||||
|
void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server);
|
||||||
|
void netdev_low_level_set_status(struct netdev *netdev, _Bool is_up);
|
||||||
|
void netdev_low_level_set_link_status(struct netdev *netdev, _Bool is_up);
|
||||||
|
void netdev_low_level_set_internet_status(struct netdev *netdev, _Bool is_up);
|
||||||
|
void netdev_low_level_set_dhcp_status(struct netdev *netdev, _Bool is_enable);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __NETDEV_H__ */
|
|
@ -0,0 +1,259 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2018-05-18 ChenYong First version
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file netdev_ipaddr.h
|
||||||
|
* @brief Structure and function declarations of device and ipaddr
|
||||||
|
* @version 2.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-09-15
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**modified:
|
||||||
|
*
|
||||||
|
* delete some functions already in lwip
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __NETDEV_IPADDR_H__
|
||||||
|
#define __NETDEV_IPADDR_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if NETDEV_IPV4
|
||||||
|
/** IPv4 only: set the IP address given as an u32_t */
|
||||||
|
#define ip4_addr_set_u32(dest_ipaddr, src_u32) ((dest_ipaddr)->addr = (src_u32))
|
||||||
|
/** IPv4 only: get the IP address as an u32_t */
|
||||||
|
#define ip4_addr_get_u32(src_ipaddr) ((src_ipaddr)->addr)
|
||||||
|
|
||||||
|
#define IP4ADDR_STRLEN_MAX 16
|
||||||
|
#endif /* NETIF_IPV4 */
|
||||||
|
|
||||||
|
#define PP_NTOHS(x) PP_HTONS(x)
|
||||||
|
#define PP_NTOHL(x) PP_HTONL(x)
|
||||||
|
|
||||||
|
/* If your port already typedef's in_addr_t, define IN_ADDR_T_DEFINED
|
||||||
|
to prevent this code from redefining it. */
|
||||||
|
#if !defined(in_addr_t) && !defined(IN_ADDR_T_DEFINED)
|
||||||
|
typedef uint32_t in_addr_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if NETDEV_IPV4
|
||||||
|
struct in_addr
|
||||||
|
{
|
||||||
|
in_addr_t s_addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct ip4_addr
|
||||||
|
{
|
||||||
|
uint32_t addr;
|
||||||
|
} ip4_addr_t;
|
||||||
|
|
||||||
|
/** 255.255.255.255 */
|
||||||
|
#define IPADDR_NONE ((uint32_t)0xffffffffUL)
|
||||||
|
/** 127.0.0.1 */
|
||||||
|
#define IPADDR_LOOPBACK ((uint32_t)0x7f000001UL)
|
||||||
|
/** 0.0.0.0 */
|
||||||
|
#define IPADDR_ANY ((uint32_t)0x00000000UL)
|
||||||
|
/** 255.255.255.255 */
|
||||||
|
#define IPADDR_BROADCAST ((uint32_t)0xffffffffUL)
|
||||||
|
|
||||||
|
/** 255.255.255.255 */
|
||||||
|
#define INADDR_NONE IPADDR_NONE
|
||||||
|
/** 127.0.0.1 */
|
||||||
|
#define INADDR_LOOPBACK IPADDR_LOOPBACK
|
||||||
|
/** 0.0.0.0 */
|
||||||
|
#define INADDR_ANY IPADDR_ANY
|
||||||
|
/** 255.255.255.255 */
|
||||||
|
#define INADDR_BROADCAST IPADDR_BROADCAST
|
||||||
|
|
||||||
|
#define IPADDR_BROADCAST_STRING "255.255.255.255"
|
||||||
|
|
||||||
|
/** Copy IP address - faster than ip4_addr_set: no NULL check */
|
||||||
|
#define ip4_addr_copy(dest, src) ((dest).addr = (src).addr)
|
||||||
|
#define ip4_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr)
|
||||||
|
/** Safely copy one IP address to another (src may be NULL) */
|
||||||
|
#define ip4_addr_set(dest, src) ((dest)->addr = ((src) == NULL ? 0 : (src)->addr))
|
||||||
|
/** Set complete address to zero */
|
||||||
|
#define ip4_addr_set_zero(ipaddr) ((ipaddr)->addr = 0)
|
||||||
|
/** Set address to IPADDR_ANY (no need for htonl()) */
|
||||||
|
#define ip4_addr_set_any(ipaddr) ((ipaddr)->addr = IPADDR_ANY)
|
||||||
|
#define ip4_addr_isany_val(ipaddr) ((ipaddr).addr == IPADDR_ANY)
|
||||||
|
#define ip4_addr_isany(ipaddr) ((ipaddr) == NULL || ip4_addr_isany_val(*(ipaddr)))
|
||||||
|
|
||||||
|
in_addr_t netdev_ipaddr_addr(const char *cp);
|
||||||
|
int netdev_ip4addr_aton(const char *cp, ip4_addr_t *addr);
|
||||||
|
char *netdev_ip4addr_ntoa(const ip4_addr_t *addr);
|
||||||
|
char *netdev_ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen);
|
||||||
|
#endif /* NETIF_IPV4 */
|
||||||
|
|
||||||
|
#if NETDEV_IPV6
|
||||||
|
struct in6_addr
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint32_t u32_addr[4];
|
||||||
|
uint8_t u8_addr[16];
|
||||||
|
} un;
|
||||||
|
#define s6_addr un.u8_addr
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct ip6_addr
|
||||||
|
{
|
||||||
|
uint32_t addr[4];
|
||||||
|
#ifdef NETDEV_IPV6_SCOPES
|
||||||
|
uint8_t zone;
|
||||||
|
#endif /* NETDEV_IPV6_SCOPES */
|
||||||
|
} ip6_addr_t;
|
||||||
|
|
||||||
|
/** This macro can be used to initialize a variable of type struct in6_addr
|
||||||
|
to the IPv6 wildcard address. */
|
||||||
|
#define IN6ADDR_ANY_INIT {{{0,0,0,0}}}
|
||||||
|
/** This macro can be used to initialize a variable of type struct in6_addr
|
||||||
|
to the IPv6 loopback address. */
|
||||||
|
#define IN6ADDR_LOOPBACK_INIT {{{0,0,0,PP_HTONL(1)}}}
|
||||||
|
|
||||||
|
/** This variable is initialized by the system to contain the wildcard IPv6 address.
|
||||||
|
*/
|
||||||
|
extern const struct in6_addr in6addr_any;
|
||||||
|
|
||||||
|
#define ip6_addr_cmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \
|
||||||
|
((addr1)->addr[1] == (addr2)->addr[1]) && \
|
||||||
|
((addr1)->addr[2] == (addr2)->addr[2]) && \
|
||||||
|
((addr1)->addr[3] == (addr2)->addr[3]))
|
||||||
|
/** Copy IPv6 address - faster than ip6_addr_set: no NULL check */
|
||||||
|
#define ip6_addr_copy(dest, src) do{(dest).addr[0] = (src).addr[0]; \
|
||||||
|
(dest).addr[1] = (src).addr[1]; \
|
||||||
|
(dest).addr[2] = (src).addr[2]; \
|
||||||
|
(dest).addr[3] = (src).addr[3];}while(0)
|
||||||
|
/** Safely copy one IPv6 address to another (src may be NULL) */
|
||||||
|
#define ip6_addr_set(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : (src)->addr[0]; \
|
||||||
|
(dest)->addr[1] = (src) == NULL ? 0 : (src)->addr[1]; \
|
||||||
|
(dest)->addr[2] = (src) == NULL ? 0 : (src)->addr[2]; \
|
||||||
|
(dest)->addr[3] = (src) == NULL ? 0 : (src)->addr[3];}while(0)
|
||||||
|
/** Set complete address to zero */
|
||||||
|
#define ip6_addr_set_zero(ip6addr) do{(ip6addr)->addr[0] = 0; \
|
||||||
|
(ip6addr)->addr[1] = 0; \
|
||||||
|
(ip6addr)->addr[2] = 0; \
|
||||||
|
(ip6addr)->addr[3] = 0;}while(0)
|
||||||
|
/** Set address to ipv6 'any' (no need for lwip_htonl()) */
|
||||||
|
#define ip6_addr_set_any(ip6addr) ip6_addr_set_zero(ip6addr)
|
||||||
|
#define ip6_addr_isany_val(ip6addr) (((ip6addr).addr[0] == 0) && \
|
||||||
|
((ip6addr).addr[1] == 0) && \
|
||||||
|
((ip6addr).addr[2] == 0) && \
|
||||||
|
((ip6addr).addr[3] == 0))
|
||||||
|
#define ip6_addr_isany(ip6addr) (((ip6addr) == NULL) || ip6_addr_isany_val(*(ip6addr)))
|
||||||
|
|
||||||
|
int netdev_ip6addr_aton(const char *cp, ip6_addr_t *addr);
|
||||||
|
char *netdev_ip6addr_ntoa(const ip6_addr_t *addr);
|
||||||
|
char *netdev_ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen);
|
||||||
|
#endif /* NETIF_IPV6 */
|
||||||
|
|
||||||
|
#if NETDEV_IPV4 && NETDEV_IPV6
|
||||||
|
/* A union struct for both IP version's addresses */
|
||||||
|
typedef struct _ip_addr
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
ip6_addr_t ip6;
|
||||||
|
ip4_addr_t ip4;
|
||||||
|
} u_addr;
|
||||||
|
/** @ref netdev_ip_addr_type */
|
||||||
|
uint8_t type;
|
||||||
|
} ip_addr_t;
|
||||||
|
|
||||||
|
#define IP_SET_TYPE_VAL(ipaddr, iptype) do { (ipaddr).type = (iptype); }while(0)
|
||||||
|
#define IP_SET_TYPE(ipaddr, iptype) do { if((ipaddr) != NULL) { IP_SET_TYPE_VAL(*(ipaddr), iptype); }}while(0)
|
||||||
|
#define IP_GET_TYPE(ipaddr) ((ipaddr)->type)
|
||||||
|
|
||||||
|
#define IP_IS_V4_VAL(ipaddr) (IP_GET_TYPE(&ipaddr) == IPADDR_TYPE_V4)
|
||||||
|
#define IP_IS_V6_VAL(ipaddr) (IP_GET_TYPE(&ipaddr) == IPADDR_TYPE_V6)
|
||||||
|
#define IP_IS_V4(ipaddr) (((ipaddr) == NULL) || IP_IS_V4_VAL(*(ipaddr)))
|
||||||
|
#define IP_IS_V6(ipaddr) (((ipaddr) != NULL) && IP_IS_V6_VAL(*(ipaddr)))
|
||||||
|
|
||||||
|
/** Convert generic ip address to specific protocol version */
|
||||||
|
#define ip_2_ip6(ipaddr) (&((ipaddr)->u_addr.ip6))
|
||||||
|
/** Convert generic ip address to specific protocol version */
|
||||||
|
#define ip_2_ip4(ipaddr) (&((ipaddr)->u_addr.ip4))
|
||||||
|
|
||||||
|
#define ip_addr_copy(dest, src) do{ IP_SET_TYPE_VAL(dest, IP_GET_TYPE(&src)); if(IP_IS_V6_VAL(src)){ \
|
||||||
|
ip6_addr_copy(*ip_2_ip6(&(dest)), *ip_2_ip6(&(src))); }else{ \
|
||||||
|
ip4_addr_copy(*ip_2_ip4(&(dest)), *ip_2_ip4(&(src))); }}while(0)
|
||||||
|
#define ip_addr_cmp(addr1, addr2) ((IP_GET_TYPE(addr1) != IP_GET_TYPE(addr2)) ? 0 : (IP_IS_V6_VAL(*(addr1)) ? \
|
||||||
|
ip6_addr_cmp(ip_2_ip6(addr1), ip_2_ip6(addr2)) : \
|
||||||
|
ip4_addr_cmp(ip_2_ip4(addr1), ip_2_ip4(addr2))))
|
||||||
|
#define ip_addr_set(dest, src) do{ IP_SET_TYPE(dest, IP_GET_TYPE(src)); if(IP_IS_V6(src)){ \
|
||||||
|
ip6_addr_set(ip_2_ip6(dest), ip_2_ip6(src)); }else{ \
|
||||||
|
ip4_addr_set(ip_2_ip4(dest), ip_2_ip4(src)); }}while(0)
|
||||||
|
#define ip_addr_set_zero(ipaddr) do{ ip6_addr_set_zero(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, 0); }while(0)
|
||||||
|
#define ip_addr_set_any(is_ipv6, ipaddr) do{ if(is_ipv6){ \
|
||||||
|
ip6_addr_set_any(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V6); }else{ \
|
||||||
|
ip4_addr_set_any(ip_2_ip4(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); }}while(0)
|
||||||
|
|
||||||
|
#define ip_addr_isany_val(ipaddr) ((IP_IS_V6_VAL(ipaddr)) ? \
|
||||||
|
ip6_addr_isany_val(*ip_2_ip6(&(ipaddr))) : \
|
||||||
|
ip4_addr_isany_val(*ip_2_ip4(&(ipaddr))))
|
||||||
|
#define ip_addr_isany(ipaddr) ((IP_IS_V6(ipaddr)) ? \
|
||||||
|
ip6_addr_isany(ip_2_ip6(ipaddr)) : \
|
||||||
|
ip4_addr_isany(ip_2_ip4(ipaddr)))
|
||||||
|
|
||||||
|
/* directly map this to the lwip internal functions */
|
||||||
|
#define inet_addr(cp) netdev_ipaddr_addr(cp)
|
||||||
|
#define inet_aton(cp, addr) ((IP_IS_V6_VAL(*addr)) ? \
|
||||||
|
netdev_ip6addr_aton(cp, ip_2_ip6(addr)) : \
|
||||||
|
netdev_ip4addr_aton(cp, ip_2_ip4(addr)))
|
||||||
|
#define inet_ntoa(addr) ((IP_IS_V6_VAL(addr)) ? \
|
||||||
|
netdev_ip6addr_ntoa(ip_2_ip6(&addr)) : \
|
||||||
|
netdev_ip4addr_ntoa(ip_2_ip4(&addr)))
|
||||||
|
#define inet_ntoa_r(addr, buf, buflen) ((IP_IS_V6_VAL(addr)) ? \
|
||||||
|
netdev_ip6addr_ntoa_r(ip_2_ip6(&addr), buf, buflen) : \
|
||||||
|
netdev_ip4addr_ntoa_r(ip_2_ip4(&addr), buf, buflen))
|
||||||
|
#elif NETDEV_IPV4 /* NETDEV_IPV4 */
|
||||||
|
|
||||||
|
typedef ip4_addr_t ip_addr_t;
|
||||||
|
|
||||||
|
#define IP_SET_TYPE_VAL(ipaddr, iptype)
|
||||||
|
#define IP_SET_TYPE(ipaddr, iptype)
|
||||||
|
#define IP_GET_TYPE(ipaddr) IPADDR_TYPE_V4
|
||||||
|
|
||||||
|
#define ip_addr_copy(dest, src) ip4_addr_copy(dest, src)
|
||||||
|
#define ip_addr_cmp(addr1, addr2) ip4_addr_cmp(addr1, addr2)
|
||||||
|
#define ip_addr_set(dest, src) ip4_addr_set(dest, src)
|
||||||
|
#define ip_addr_set_zero(ipaddr) ip4_addr_set_zero(ipaddr)
|
||||||
|
#define ip_addr_set_any(is_ipv6, ipaddr) ip4_addr_set_any(ipaddr)
|
||||||
|
#define ip_addr_isany_val(ipaddr) ip4_addr_isany_val(ipaddr)
|
||||||
|
#define ip_addr_isany(ipaddr) ip4_addr_isany(ipaddr)
|
||||||
|
|
||||||
|
/* directly map this to the lwip internal functions */
|
||||||
|
#define inet_addr(cp) netdev_ipaddr_addr(cp)
|
||||||
|
#define inet_aton(cp, addr) netdev_ip4addr_aton(cp,(ip4_addr_t*)addr)
|
||||||
|
#define inet_ntoa(addr) netdev_ip4addr_ntoa((const ip4_addr_t*)&(addr))
|
||||||
|
#define inet_ntoa_r(addr, buf, buflen) netdev_ip4addr_ntoa_r((const ip4_addr_t*)&(addr), buf, buflen)
|
||||||
|
#else /* NETDEV_IPV6 */
|
||||||
|
|
||||||
|
//typedef ip6_addr_t ip_addr_t;
|
||||||
|
|
||||||
|
#define IP_SET_TYPE_VAL(ipaddr, iptype)
|
||||||
|
#define IP_SET_TYPE(ipaddr, iptype)
|
||||||
|
#endif /* NTDEV_IPV4 && NTDEV_IPV6 */
|
||||||
|
|
||||||
|
|
||||||
|
const char *netdev_inet_ntop(int af, const void *src, char *dst, int32_t size);
|
||||||
|
int netdev_inet_pton(int af, const char *src, void *dst);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __NETDEV_IPADDR_H__ */
|
|
@ -0,0 +1,3 @@
|
||||||
|
SRC_FILES := netdev.c netdev_ipaddr.c
|
||||||
|
|
||||||
|
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,834 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2022-03-18 ChenYong First version
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file netdev.c
|
||||||
|
* @brief functions of getting device address
|
||||||
|
* @version 2.0
|
||||||
|
* @author AIIT XUOS Lab
|
||||||
|
* @date 2022-09-15
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <transform.h>
|
||||||
|
|
||||||
|
#include "../include/netdev_ipaddr.h"
|
||||||
|
#include "../include/netdev.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define DBG_TAG "netdev"
|
||||||
|
#define DBG_LVL DBG_INFO
|
||||||
|
|
||||||
|
|
||||||
|
/* The list of network interface device */
|
||||||
|
struct netdev *netdev_list = NULL;
|
||||||
|
/* The default network interface device */
|
||||||
|
struct netdev *netdev_default = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* following four functions are basic operations on linked lists
|
||||||
|
*/
|
||||||
|
void netdev_slist_init(netdev_slist_t *l)
|
||||||
|
{
|
||||||
|
l->next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void netdev_slist_append(netdev_slist_t *l, netdev_slist_t *n)
|
||||||
|
{
|
||||||
|
struct netdev_slist_node *node;
|
||||||
|
|
||||||
|
node = l;
|
||||||
|
while (node->next) node = node->next;
|
||||||
|
|
||||||
|
/* append the node to the tail */
|
||||||
|
node->next = n;
|
||||||
|
n->next = NULL;
|
||||||
|
}
|
||||||
|
netdev_slist_t *netdev_slist_next(netdev_slist_t *n)
|
||||||
|
{
|
||||||
|
return n->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
netdev_slist_t *netdev_slist_remove(netdev_slist_t *l, netdev_slist_t *n)
|
||||||
|
{
|
||||||
|
/* remove slist head */
|
||||||
|
struct netdev_slist_node *node = l;
|
||||||
|
while (node->next && node->next != n) node = node->next;
|
||||||
|
|
||||||
|
/* remove node */
|
||||||
|
if (node->next != (netdev_slist_t *)0) node->next = node->next->next;
|
||||||
|
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will register network interface device and
|
||||||
|
* add it to network interface device list.
|
||||||
|
*
|
||||||
|
* @param netdev the network interface device object
|
||||||
|
* @param name the network interface device name
|
||||||
|
* @param user_data user-specific data
|
||||||
|
*
|
||||||
|
* @return 0: registered successfully
|
||||||
|
* -1: registered failed
|
||||||
|
*/
|
||||||
|
|
||||||
|
int netdev_register(struct netdev *netdev, const char *name, void *user_data)
|
||||||
|
{
|
||||||
|
long level;
|
||||||
|
uint16_t flags_mask;
|
||||||
|
uint16_t index;
|
||||||
|
|
||||||
|
assert(netdev);
|
||||||
|
assert(name);
|
||||||
|
|
||||||
|
/* clean network interface device */
|
||||||
|
flags_mask = NETDEV_FLAG_UP | NETDEV_FLAG_LINK_UP | NETDEV_FLAG_INTERNET_UP | NETDEV_FLAG_DHCP;
|
||||||
|
netdev->flags &= ~flags_mask;
|
||||||
|
|
||||||
|
ip_addr_set_zero(&(netdev->ip_addr));
|
||||||
|
ip_addr_set_zero(&(netdev->netmask));
|
||||||
|
ip_addr_set_zero(&(netdev->gw));
|
||||||
|
|
||||||
|
IP_SET_TYPE_VAL(netdev->ip_addr, IPADDR_TYPE_V4);
|
||||||
|
IP_SET_TYPE_VAL(netdev->netmask, IPADDR_TYPE_V4);
|
||||||
|
IP_SET_TYPE_VAL(netdev->gw, IPADDR_TYPE_V4);
|
||||||
|
#if NETDEV_IPV6
|
||||||
|
for (index = 0; index < NETDEV_IPV6_NUM_ADDRESSES; index++)
|
||||||
|
{
|
||||||
|
ip_addr_set_zero(&(netdev->ip6_addr[index]));
|
||||||
|
IP_SET_TYPE_VAL(netdev->ip_addr, IPADDR_TYPE_V6);
|
||||||
|
}
|
||||||
|
#endif /* NETDEV_IPV6 */
|
||||||
|
for (index = 0; index < NETDEV_DNS_SERVERS_NUM; index++)
|
||||||
|
{
|
||||||
|
ip_addr_set_zero(&(netdev->dns_servers[index]));
|
||||||
|
IP_SET_TYPE_VAL(netdev->ip_addr, IPADDR_TYPE_V4);
|
||||||
|
}
|
||||||
|
netdev->status_callback = NULL;
|
||||||
|
netdev->addr_callback = NULL;
|
||||||
|
|
||||||
|
if(strlen(name) > NETDEV_NAME_MAX)
|
||||||
|
{
|
||||||
|
char netdev_name[NETDEV_NAME_MAX + 1] = {0};
|
||||||
|
|
||||||
|
strncpy(netdev_name, name, NETDEV_NAME_MAX);
|
||||||
|
printf("netdev name[%s] length is so long that have been cut into [%s].", name, netdev_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fill network interface device */
|
||||||
|
strncpy(netdev->name, name, NETDEV_NAME_MAX);
|
||||||
|
netdev->user_data = user_data;
|
||||||
|
|
||||||
|
/* initialize current network interface device single list */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
netdev_slist_init(&(netdev->list));
|
||||||
|
|
||||||
|
level = CriticalAreaLock();
|
||||||
|
|
||||||
|
if (netdev_list == NULL)
|
||||||
|
{
|
||||||
|
netdev_list = netdev;
|
||||||
|
netdev_default = netdev;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* tail insertion */
|
||||||
|
netdev_slist_append(&(netdev_list->list), &(netdev->list));
|
||||||
|
}
|
||||||
|
|
||||||
|
CriticalAreaUnLock(level);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will unregister network interface device and
|
||||||
|
* delete it from network interface device list.
|
||||||
|
*
|
||||||
|
* @param netdev the network interface device object
|
||||||
|
*
|
||||||
|
* @return 0: unregistered successfully
|
||||||
|
* -1: unregistered failed
|
||||||
|
*/
|
||||||
|
int netdev_unregister(struct netdev *netdev)
|
||||||
|
{
|
||||||
|
long level;
|
||||||
|
netdev_slist_t *node = NULL;
|
||||||
|
struct netdev *cur_netdev = NULL;
|
||||||
|
|
||||||
|
assert(netdev);
|
||||||
|
|
||||||
|
if (netdev_list == NULL)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
level = CriticalAreaLock();
|
||||||
|
|
||||||
|
for (node = &(netdev_list->list); node; node = netdev_slist_next(node))
|
||||||
|
{
|
||||||
|
cur_netdev = netdev_slist_entry(node, struct netdev, list);
|
||||||
|
if (cur_netdev == netdev)
|
||||||
|
{
|
||||||
|
/* find this network interface device in network interface device list */
|
||||||
|
if (netdev_list == netdev && netdev_slist_next(&netdev_list->list) == NULL)
|
||||||
|
{
|
||||||
|
netdev_list = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
netdev_slist_remove(&(netdev_list->list), &(cur_netdev->list));
|
||||||
|
}
|
||||||
|
if (netdev_default == netdev)
|
||||||
|
{
|
||||||
|
netdev_default = netdev_list;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CriticalAreaUnLock(level);
|
||||||
|
|
||||||
|
if (cur_netdev == netdev)
|
||||||
|
{
|
||||||
|
|
||||||
|
memset(netdev, 0, sizeof(*netdev));
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will get the first network interface device
|
||||||
|
* with the flags in network interface device list.
|
||||||
|
*
|
||||||
|
* @param flags the network interface device flags
|
||||||
|
*
|
||||||
|
* @return != NULL: network interface device object
|
||||||
|
* NULL: get failed
|
||||||
|
*/
|
||||||
|
struct netdev *netdev_get_first_by_flags(uint16_t flags)
|
||||||
|
{
|
||||||
|
long level;
|
||||||
|
netdev_slist_t *node = NULL;
|
||||||
|
struct netdev *netdev = NULL;
|
||||||
|
|
||||||
|
if (netdev_list == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
level = CriticalAreaLock();
|
||||||
|
|
||||||
|
for (node = &(netdev_list->list); node; node = netdev_slist_next(node))
|
||||||
|
{
|
||||||
|
netdev = netdev_slist_entry(node, struct netdev, list);
|
||||||
|
if (netdev && (netdev->flags & flags) != 0)
|
||||||
|
{
|
||||||
|
CriticalAreaUnLock(level);
|
||||||
|
return netdev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CriticalAreaUnLock(level);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will get the first network interface device
|
||||||
|
* in network interface device list by IP address.
|
||||||
|
*
|
||||||
|
* @param addr the network interface device IP address
|
||||||
|
*
|
||||||
|
* @return != NULL: network interface device object
|
||||||
|
* NULL: get failed
|
||||||
|
*/
|
||||||
|
struct netdev *netdev_get_by_ipaddr(ip_addr_t *ip_addr)
|
||||||
|
{
|
||||||
|
long level;
|
||||||
|
netdev_slist_t *node = NULL;
|
||||||
|
struct netdev *netdev = NULL;
|
||||||
|
|
||||||
|
if (netdev_list == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
level = CriticalAreaLock();
|
||||||
|
|
||||||
|
for (node = &(netdev_list->list); node; node = netdev_slist_next(node))
|
||||||
|
{
|
||||||
|
netdev = netdev_slist_entry(node, struct netdev, list);
|
||||||
|
if (netdev && ip_addr_cmp(&(netdev->ip_addr), ip_addr))
|
||||||
|
{
|
||||||
|
CriticalAreaUnLock(level);
|
||||||
|
return netdev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CriticalAreaUnLock(level);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will get network interface device
|
||||||
|
* in network interface device list by netdev name.
|
||||||
|
*
|
||||||
|
* @param name the network interface device name
|
||||||
|
*
|
||||||
|
* @return != NULL: network interface device object
|
||||||
|
* NULL: get failed
|
||||||
|
*/
|
||||||
|
struct netdev *netdev_get_by_name(const char *name)
|
||||||
|
{
|
||||||
|
long level;
|
||||||
|
netdev_slist_t *node = NULL;
|
||||||
|
struct netdev *netdev = NULL;
|
||||||
|
|
||||||
|
if (netdev_list == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
level = CriticalAreaLock();
|
||||||
|
|
||||||
|
for (node = &(netdev_list->list); node; node = netdev_slist_next(node))
|
||||||
|
{
|
||||||
|
netdev = netdev_slist_entry(node, struct netdev, list);
|
||||||
|
if (netdev && (strncmp(netdev->name, name, strlen(netdev->name) < NETDEV_NAME_MAX ? strlen(netdev->name) : NETDEV_NAME_MAX) == 0))
|
||||||
|
{
|
||||||
|
CriticalAreaUnLock(level);
|
||||||
|
return netdev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CriticalAreaUnLock(level);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will set default network interface device.
|
||||||
|
*
|
||||||
|
* @param netdev the network interface device to change
|
||||||
|
*/
|
||||||
|
void netdev_set_default(struct netdev *netdev)
|
||||||
|
{
|
||||||
|
if (netdev)
|
||||||
|
{
|
||||||
|
netdev_default = netdev;
|
||||||
|
|
||||||
|
if (netdev->ops->set_default)
|
||||||
|
{
|
||||||
|
/* set default network interface device in the current network stack */
|
||||||
|
netdev->ops->set_default(netdev);
|
||||||
|
}
|
||||||
|
printf("Setting default network interface device name(%s) successfully.", netdev->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will enable network interface device .
|
||||||
|
*
|
||||||
|
* @param netdev the network interface device to change
|
||||||
|
*
|
||||||
|
* @return 0: set status successfully
|
||||||
|
* -1: set status failed
|
||||||
|
*/
|
||||||
|
int netdev_set_up(struct netdev *netdev)
|
||||||
|
{
|
||||||
|
assert(netdev);
|
||||||
|
|
||||||
|
if (!netdev->ops || !netdev->ops->set_up)
|
||||||
|
{
|
||||||
|
printf("The network interface device(%s) not support to set status.", netdev->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* network interface device status flags check */
|
||||||
|
if (netdev_is_up(netdev))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* execute enable network interface device operations by network interface device driver */
|
||||||
|
return netdev->ops->set_up(netdev);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This function will disable network interface device.
|
||||||
|
*
|
||||||
|
* @param netdev the network interface device to change
|
||||||
|
*
|
||||||
|
* @return 0: set status successfully
|
||||||
|
* -1: set sttaus failed
|
||||||
|
*/
|
||||||
|
int netdev_set_down(struct netdev *netdev)
|
||||||
|
{
|
||||||
|
assert(netdev);
|
||||||
|
|
||||||
|
if (!netdev->ops || !netdev->ops->set_down)
|
||||||
|
{
|
||||||
|
printf("The network interface device(%s) not support to set status.", netdev->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* network interface device status flags check */
|
||||||
|
if (!netdev_is_up(netdev))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* execute disable network interface device operations by network interface driver */
|
||||||
|
return netdev->ops->set_down(netdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will control network interface device DHCP capability enable or disable.
|
||||||
|
*
|
||||||
|
* @param netdev the network interface device device to change
|
||||||
|
* @param is_enable the new DHCP status
|
||||||
|
*
|
||||||
|
* @return 0: set DHCP status successfully
|
||||||
|
* -1: set DHCP status failed
|
||||||
|
*/
|
||||||
|
int netdev_dhcp_enabled(struct netdev *netdev, _Bool is_enabled)
|
||||||
|
{
|
||||||
|
assert(netdev);
|
||||||
|
|
||||||
|
if (!netdev->ops || !netdev->ops->set_dhcp)
|
||||||
|
{
|
||||||
|
printf("The network interface device(%s) not support to set DHCP status.", netdev->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* network interface device DHCP flags check */
|
||||||
|
if (netdev_is_dhcp_enabled(netdev) == is_enabled)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* execute network interface device DHCP capability control operations */
|
||||||
|
return netdev->ops->set_dhcp(netdev, is_enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will set network interface device IP address.
|
||||||
|
*
|
||||||
|
* @param netdev the network interface device to change
|
||||||
|
* @param ipaddr the new IP address
|
||||||
|
*
|
||||||
|
* @return 0: set IP address successfully
|
||||||
|
* -1: set IP address failed
|
||||||
|
*/
|
||||||
|
int netdev_set_ipaddr(struct netdev *netdev, const ip_addr_t *ip_addr)
|
||||||
|
{
|
||||||
|
assert(netdev);
|
||||||
|
assert(ip_addr);
|
||||||
|
|
||||||
|
if (!netdev->ops || !netdev->ops->set_addr_info)
|
||||||
|
{
|
||||||
|
printf("The network interface device(%s) not support to set IP address.", netdev->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (netdev_is_dhcp_enabled(netdev))
|
||||||
|
{
|
||||||
|
printf("The network interface device(%s) DHCP capability is enable, not support set IP address.", netdev->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* execute network interface device set IP address operations */
|
||||||
|
return netdev->ops->set_addr_info(netdev, (ip_addr_t *)ip_addr, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will set network interface device netmask address.
|
||||||
|
*
|
||||||
|
* @param netdev the network interface device to change
|
||||||
|
* @param netmask the new netmask address
|
||||||
|
*
|
||||||
|
* @return 0: set netmask address successfully
|
||||||
|
* -1: set netmask address failed
|
||||||
|
*/
|
||||||
|
int netdev_set_netmask(struct netdev *netdev, const ip_addr_t *netmask)
|
||||||
|
{
|
||||||
|
assert(netdev);
|
||||||
|
assert(netmask);
|
||||||
|
|
||||||
|
if (!netdev->ops || !netdev->ops->set_addr_info)
|
||||||
|
{
|
||||||
|
printf("The network interface device(%s) not support to set netmask address.", netdev->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (netdev_is_dhcp_enabled(netdev))
|
||||||
|
{
|
||||||
|
printf("The network interface device(%s) DHCP capability is enable, not support set netmask address.", netdev->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* execute network interface device set netmask address operations */
|
||||||
|
return netdev->ops->set_addr_info(netdev, NULL, (ip_addr_t *)netmask, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will set network interface device gateway address.
|
||||||
|
*
|
||||||
|
* @param netdev the network interface device to change
|
||||||
|
* @param gateway the new gateway address
|
||||||
|
*
|
||||||
|
* @return 0: set gateway address successfully
|
||||||
|
* -1: set gateway address failed
|
||||||
|
*/
|
||||||
|
int netdev_set_gw(struct netdev *netdev, const ip_addr_t *gw)
|
||||||
|
{
|
||||||
|
assert(netdev);
|
||||||
|
assert(gw);
|
||||||
|
|
||||||
|
if (!netdev->ops || !netdev->ops->set_addr_info)
|
||||||
|
{
|
||||||
|
printf("The network interface device(%s) not support to set gateway address.", netdev->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (netdev_is_dhcp_enabled(netdev))
|
||||||
|
{
|
||||||
|
printf("The network interface device(%s) DHCP capability is enable, not support set gateway address.", netdev->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* execute network interface device set gateway address operations */
|
||||||
|
return netdev->ops->set_addr_info(netdev, NULL, NULL, (ip_addr_t *)gw);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will set network interface device DNS server address.
|
||||||
|
*
|
||||||
|
* @param netdev the network interface device to change
|
||||||
|
* @param dns_server the new DNS server address
|
||||||
|
*
|
||||||
|
* @return 0: set netmask address successfully
|
||||||
|
* -1: set netmask address failed
|
||||||
|
*/
|
||||||
|
int netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server)
|
||||||
|
{
|
||||||
|
assert(netdev);
|
||||||
|
assert(dns_server);
|
||||||
|
|
||||||
|
if (dns_num >= NETDEV_DNS_SERVERS_NUM)
|
||||||
|
{
|
||||||
|
printf("The number of DNS servers(%d) set exceeds the maximum number(%d).", dns_num + 1, NETDEV_DNS_SERVERS_NUM);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!netdev->ops || !netdev->ops->set_dns_server)
|
||||||
|
{
|
||||||
|
printf("The network interface device(%s) not support to set DNS server address.", netdev->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* execute network interface device set DNS server address operations */
|
||||||
|
return netdev->ops->set_dns_server(netdev, dns_num, (ip_addr_t *)dns_server);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will set callback to be called when the network interface device status has been changed.
|
||||||
|
*
|
||||||
|
* @param netdev the network interface device to change
|
||||||
|
* @param status_callback the callback be called when the status has been changed.
|
||||||
|
*/
|
||||||
|
void netdev_set_status_callback(struct netdev *netdev, netdev_callback_fn status_callback)
|
||||||
|
{
|
||||||
|
assert(netdev);
|
||||||
|
assert(status_callback);
|
||||||
|
|
||||||
|
netdev->status_callback = status_callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will set callback to be called when the network interface device address has been changed.
|
||||||
|
*
|
||||||
|
* @param netdev the network interface device to change
|
||||||
|
* @param addr_callback the callback be called when the address has been changed.
|
||||||
|
*/
|
||||||
|
void netdev_set_addr_callback(struct netdev *netdev, netdev_callback_fn addr_callback)
|
||||||
|
{
|
||||||
|
assert(netdev);
|
||||||
|
assert(addr_callback);
|
||||||
|
|
||||||
|
netdev->addr_callback = addr_callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will set network interface device IP address.
|
||||||
|
* @NOTE it can only be called in the network interface device driver.
|
||||||
|
*
|
||||||
|
* @param netdev the network interface device to change
|
||||||
|
* @param ipaddr the new IP address
|
||||||
|
*/
|
||||||
|
void netdev_low_level_set_ipaddr(struct netdev *netdev, const ip_addr_t *ip_addr)
|
||||||
|
{
|
||||||
|
assert(ip_addr);
|
||||||
|
|
||||||
|
if (netdev && ip_addr_cmp(&(netdev->ip_addr), ip_addr) == 0)
|
||||||
|
{
|
||||||
|
ip_addr_copy(netdev->ip_addr, *ip_addr);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* execute IP address change callback function */
|
||||||
|
if (netdev->addr_callback)
|
||||||
|
{
|
||||||
|
netdev->addr_callback(netdev, NETDEV_CB_ADDR_IP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will set network interface device netmask address.
|
||||||
|
* @NOTE it can only be called in the network interface device driver.
|
||||||
|
*
|
||||||
|
* @param netdev the network interface device to change
|
||||||
|
* @param netmask the new netmask address
|
||||||
|
*/
|
||||||
|
void netdev_low_level_set_netmask(struct netdev *netdev, const ip_addr_t *netmask)
|
||||||
|
{
|
||||||
|
assert(netmask);
|
||||||
|
|
||||||
|
if (netdev && ip_addr_cmp(&(netdev->netmask), netmask) == 0)
|
||||||
|
{
|
||||||
|
ip_addr_copy(netdev->netmask, *netmask);
|
||||||
|
|
||||||
|
/* execute netmask address change callback function */
|
||||||
|
if (netdev->addr_callback)
|
||||||
|
{
|
||||||
|
netdev->addr_callback(netdev, NETDEV_CB_ADDR_NETMASK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will set network interface device gateway address.
|
||||||
|
* @NOTE it can only be called in the network interface device driver.
|
||||||
|
*
|
||||||
|
* @param netdev the network interface device to change
|
||||||
|
* @param gateway the new gateway address
|
||||||
|
*/
|
||||||
|
void netdev_low_level_set_gw(struct netdev *netdev, const ip_addr_t *gw)
|
||||||
|
{
|
||||||
|
assert(gw);
|
||||||
|
|
||||||
|
if (netdev && ip_addr_cmp(&(netdev->gw), gw) == 0)
|
||||||
|
{
|
||||||
|
ip_addr_copy(netdev->gw, *gw);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* execute gateway address change callback function */
|
||||||
|
if (netdev->addr_callback)
|
||||||
|
{
|
||||||
|
netdev->addr_callback(netdev, NETDEV_CB_ADDR_GATEWAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will set network interface device DNS server address.
|
||||||
|
* @NOTE it can only be called in the network interface device driver.
|
||||||
|
*
|
||||||
|
* @param netdev the network interface device to change
|
||||||
|
* @param dns_server the new DNS server address
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server)
|
||||||
|
{
|
||||||
|
unsigned int index;
|
||||||
|
|
||||||
|
assert(dns_server);
|
||||||
|
|
||||||
|
if (netdev == NULL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* check DNS servers is exist */
|
||||||
|
for (index = 0; index < NETDEV_DNS_SERVERS_NUM; index++)
|
||||||
|
{
|
||||||
|
if (ip_addr_cmp(&(netdev->dns_servers[index]), dns_server))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dns_num < NETDEV_DNS_SERVERS_NUM)
|
||||||
|
{
|
||||||
|
ip_addr_copy(netdev->dns_servers[dns_num], *dns_server);
|
||||||
|
|
||||||
|
/* execute DNS servers address change callback function */
|
||||||
|
if (netdev->addr_callback)
|
||||||
|
{
|
||||||
|
netdev->addr_callback(netdev, NETDEV_CB_ADDR_DNS_SERVER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef NETDEV_USING_AUTO_DEFAULT
|
||||||
|
/* Change to the first link_up network interface device automatically */
|
||||||
|
static void netdev_auto_change_default(struct netdev *netdev)
|
||||||
|
{
|
||||||
|
struct netdev *new_netdev = NULL;
|
||||||
|
|
||||||
|
if (memcmp(netdev, netdev_default, sizeof(struct netdev)) == 0)
|
||||||
|
{
|
||||||
|
new_netdev = netdev_get_first_by_flags(NETDEV_FLAG_LINK_UP);
|
||||||
|
if (new_netdev)
|
||||||
|
{
|
||||||
|
netdev_set_default(new_netdev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* NETDEV_USING_AUTO_DEFAULT */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will set network interface device status.
|
||||||
|
* @NOTE it can only be called in the network interface device driver.
|
||||||
|
*
|
||||||
|
* @param netdev the network interface device to change
|
||||||
|
* @param is_up the new status
|
||||||
|
*/
|
||||||
|
void netdev_low_level_set_status(struct netdev *netdev, _Bool is_up)
|
||||||
|
{
|
||||||
|
if (netdev && netdev_is_up(netdev) != is_up)
|
||||||
|
{
|
||||||
|
if (is_up)
|
||||||
|
{
|
||||||
|
netdev->flags |= NETDEV_FLAG_UP;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
netdev->flags &= ~NETDEV_FLAG_UP;
|
||||||
|
|
||||||
|
#ifdef NETDEV_USING_AUTO_DEFAULT
|
||||||
|
/* change to the first link_up network interface device automatically */
|
||||||
|
netdev_auto_change_default(netdev);
|
||||||
|
#endif /* NETDEV_USING_AUTO_DEFAULT */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* execute network interface device status change callback function */
|
||||||
|
if (netdev->status_callback)
|
||||||
|
{
|
||||||
|
netdev->status_callback(netdev, is_up ? NETDEV_CB_STATUS_UP : NETDEV_CB_STATUS_DOWN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will set network interface device active link status.
|
||||||
|
* @NOTE it can only be called in the network interface device driver.
|
||||||
|
*
|
||||||
|
* @param netdev the network interface device to change
|
||||||
|
* @param is_up the new link status
|
||||||
|
*/
|
||||||
|
void netdev_low_level_set_link_status(struct netdev *netdev, _Bool is_up)
|
||||||
|
{
|
||||||
|
if (netdev && netdev_is_link_up(netdev) != is_up)
|
||||||
|
{
|
||||||
|
if (is_up)
|
||||||
|
{
|
||||||
|
netdev->flags |= NETDEV_FLAG_LINK_UP;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
netdev->flags &= ~NETDEV_FLAG_LINK_UP;
|
||||||
|
|
||||||
|
/* set network interface device flags to internet down */
|
||||||
|
netdev->flags &= ~NETDEV_FLAG_INTERNET_UP;
|
||||||
|
|
||||||
|
#ifdef NETDEV_USING_AUTO_DEFAULT
|
||||||
|
/* change to the first link_up network interface device automatically */
|
||||||
|
netdev_auto_change_default(netdev);
|
||||||
|
#endif /* NETDEV_USING_AUTO_DEFAULT */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* execute link status change callback function */
|
||||||
|
if (netdev->status_callback)
|
||||||
|
{
|
||||||
|
netdev->status_callback(netdev, is_up ? NETDEV_CB_STATUS_LINK_UP : NETDEV_CB_STATUS_LINK_DOWN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will set network interface device active internet status.
|
||||||
|
* @NOTE it can only be called in the network interface device driver.
|
||||||
|
*
|
||||||
|
* @param netdev the network interface device to change
|
||||||
|
* @param is_up the new internet status
|
||||||
|
*/
|
||||||
|
void netdev_low_level_set_internet_status(struct netdev *netdev, _Bool is_up)
|
||||||
|
{
|
||||||
|
if (netdev && netdev_is_internet_up(netdev) != is_up)
|
||||||
|
{
|
||||||
|
if (is_up)
|
||||||
|
{
|
||||||
|
netdev->flags |= NETDEV_FLAG_INTERNET_UP;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
netdev->flags &= ~NETDEV_FLAG_INTERNET_UP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* execute network interface device status change callback function */
|
||||||
|
if (netdev->status_callback)
|
||||||
|
{
|
||||||
|
netdev->status_callback(netdev, is_up ? NETDEV_CB_STATUS_INTERNET_UP : NETDEV_CB_STATUS_INTERNET_DOWN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will set network interface device DHCP status.
|
||||||
|
* @NOTE it can only be called in the network interface device driver.
|
||||||
|
*
|
||||||
|
* @param netdev the network interface device to change
|
||||||
|
* @param is_up the new DHCP status
|
||||||
|
*/
|
||||||
|
void netdev_low_level_set_dhcp_status(struct netdev *netdev, _Bool is_enable)
|
||||||
|
{
|
||||||
|
if (netdev && netdev_is_dhcp_enabled(netdev) != is_enable)
|
||||||
|
{
|
||||||
|
if (is_enable)
|
||||||
|
{
|
||||||
|
netdev->flags |= NETDEV_FLAG_DHCP;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
netdev->flags &= ~NETDEV_FLAG_DHCP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* execute DHCP status change callback function */
|
||||||
|
if (netdev->status_callback)
|
||||||
|
{
|
||||||
|
netdev->status_callback(netdev, is_enable ? NETDEV_CB_STATUS_DHCP_ENABLE : NETDEV_CB_STATUS_DHCP_DISABLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|