Merge branch 'wang_weigen_master' of https://git.trustie.net/xuos/xiuos into develop
This commit is contained in:
commit
2fcb4ad3ad
|
@ -1,2 +1,3 @@
|
|||
*.vscode
|
||||
*.o
|
||||
.DS_Store
|
|
@ -1,4 +1,7 @@
|
|||
menu "knowing app"
|
||||
source "$APP_DIR/Applications/knowing_app/mnist/Kconfig"
|
||||
source "$APP_DIR/Applications/knowing_app/face_detect/Kconfig"
|
||||
source "$APP_DIR/Applications/knowing_app/instrusion_detect/Kconfig"
|
||||
source "$APP_DIR/Applications/knowing_app/helmet_detect/Kconfig"
|
||||
source "$APP_DIR/Applications/knowing_app/iris_ml_demo/Kconfig"
|
||||
endmenu
|
||||
|
|
|
@ -4,4 +4,5 @@ config FACE_DETECT
|
|||
depends on DRV_USING_OV2640
|
||||
depends on USING_KPU_POSTPROCESSING
|
||||
depends on USING_YOLOV2
|
||||
select LIB_USING_CJSON
|
||||
default n
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
# Face detection demo
|
||||
|
||||
### A face object detection task demo. Running MobileNet-yolo on K210-based edge devices.
|
||||
|
||||
---
|
||||
|
||||
## Training
|
||||
|
||||
kmodel from [GitHub](https://github.com/kendryte/kendryte-standalone-demo/blob/develop/face_detect/detect.kmodel).
|
||||
|
||||
## Deployment
|
||||
|
||||
### compile and burn
|
||||
|
||||
Use `(scons --)menuconfig` in bsp folder *(Ubiquitous/RT_Thread/bsp/k210)*, open:
|
||||
|
||||
- More Drivers --> ov2640 driver
|
||||
- Board Drivers Config --> Enable LCD on SPI0
|
||||
- Board Drivers Config --> Enable SDCARD (spi1(ss0))
|
||||
- Board Drivers Config --> Enable DVP(camera)
|
||||
- RT-Thread Components --> POSIX layer and C standard library --> Enable pthreads APIs
|
||||
- APP_Framework --> Framework --> support knowing framework --> kpu model postprocessing --> yolov2 region layer
|
||||
- APP_Framework --> Applications --> knowing app --> enable apps/face detect
|
||||
|
||||
`scons -j(n)` to compile and burn in by *kflash*.
|
||||
|
||||
### json config and kmodel
|
||||
|
||||
Copy json config for deployment o SD card */kmodel*. Example config file is *detect.json* in this directory. Copy final kmodel to SD card */kmodel* either.
|
||||
|
||||
---
|
||||
|
||||
## Run
|
||||
|
||||
In serial terminal, `face_detect` to start a detection thread, `face_detect_delete` to stop it. Detection results can be found in output.
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"net_input_size": [
|
||||
240,
|
||||
320
|
||||
],
|
||||
"net_output_shape": [
|
||||
20,
|
||||
15,
|
||||
30
|
||||
],
|
||||
"sensor_output_size": [
|
||||
240,
|
||||
320
|
||||
],
|
||||
"anchors": [
|
||||
1.889,
|
||||
2.5245,
|
||||
2.9465,
|
||||
3.94056,
|
||||
3.99987,
|
||||
5.3658,
|
||||
5.155437,
|
||||
6.92275,
|
||||
6.718375,
|
||||
9.01025
|
||||
],
|
||||
"kmodel_path": "/kmodel/detect.kmodel",
|
||||
"kmodel_size": 388776,
|
||||
"obj_thresh": [
|
||||
0.7
|
||||
],
|
||||
"labels": [
|
||||
"face"
|
||||
],
|
||||
"nms_thresh": 0.3
|
||||
}
|
Binary file not shown.
|
@ -1,100 +1,230 @@
|
|||
#include <transform.h>
|
||||
#include"region_layer.h"
|
||||
#define SHOW_RGB_BUF_SIZE (320*240*2)
|
||||
#define AI_KPU_RGB_BUF_SIZE (320*240*3)
|
||||
#define KMODEL_SIZE (388776) //face model size
|
||||
#ifdef LIB_USING_CJSON
|
||||
#include <cJSON.h>
|
||||
#endif
|
||||
#include "region_layer.h"
|
||||
#define ANCHOR_NUM 5
|
||||
#define KPUIMAGEWIDTH (320)
|
||||
#define KPUIMAGEHEIGHT (240)
|
||||
#define STACK_SIZE (128 * 1024)
|
||||
#define JSON_FILE_PATH "/kmodel/detect.json"
|
||||
#define JSON_BUFFER_SIZE (4 * 1024)
|
||||
|
||||
// params from json
|
||||
static float anchor[ANCHOR_NUM * 2] = {};
|
||||
static int net_output_shape[3] = {};
|
||||
static int net_input_size[2] = {};
|
||||
static int sensor_output_size[2] = {};
|
||||
static char kmodel_path[127] = "";
|
||||
static int kmodel_size = 0;
|
||||
static float obj_thresh[20] = {};
|
||||
static float nms_thresh = 0.0;
|
||||
static char labels[20][32] = {};
|
||||
static int class_num = 0;
|
||||
|
||||
static float anchor[ANCHOR_NUM * 2] = {1.889,2.5245, 2.9465,3.94056, 3.99987,5.3658, 5.155437,6.92275, 6.718375,9.01025};
|
||||
|
||||
|
||||
#define THREAD_PRIORITY_FACE_D (11)
|
||||
static pthread_t facetid = 0;
|
||||
static void* thread_face_detcet_entry(void *parameter);
|
||||
#define THREAD_PRIORITY_FACE_D (11)
|
||||
static pthread_t facetid = 0;
|
||||
static void *thread_face_detcet_entry(void *parameter);
|
||||
static int g_fd = 0;
|
||||
static int kmodel_fd = 0;
|
||||
static int if_exit = 0;
|
||||
static unsigned char * showbuffer = NULL ;
|
||||
static unsigned char * kpurgbbuffer = NULL ;
|
||||
static int if_exit = 0;
|
||||
static unsigned char *showbuffer = NULL;
|
||||
static unsigned char *kpurgbbuffer = NULL;
|
||||
|
||||
static _ioctl_shoot_para shoot_para_t = {0};
|
||||
unsigned char * model_data = NULL; //kpu data load memory
|
||||
unsigned char *model_data_align = NULL;
|
||||
unsigned char *model_data = NULL; // kpu data load memory
|
||||
unsigned char *model_data_align = NULL;
|
||||
|
||||
kpu_model_context_t face_detect_task;
|
||||
static region_layer_t face_detect_rl;
|
||||
static obj_info_t face_detect_info;
|
||||
volatile uint32_t g_ai_done_flag;
|
||||
|
||||
static void ai_done(void *ctx)
|
||||
static void ai_done(void *ctx) { g_ai_done_flag = 1; }
|
||||
|
||||
static void param_parse()
|
||||
{
|
||||
g_ai_done_flag = 1;
|
||||
int fin;
|
||||
char buffer[JSON_BUFFER_SIZE] = "";
|
||||
// char *buffer;
|
||||
// if (NULL != (buffer = (char*)malloc(JSON_BUFFER_SIZE * sizeof(char)))) {
|
||||
// memset(buffer, 0, JSON_BUFFER_SIZE * sizeof(char));
|
||||
// } else {
|
||||
// printf("Json buffer malloc failed!");
|
||||
// exit(-1);
|
||||
// }
|
||||
int array_size;
|
||||
cJSON *json_obj;
|
||||
cJSON *json_item;
|
||||
cJSON *json_array_item;
|
||||
|
||||
fin = open(JSON_FILE_PATH, O_RDONLY);
|
||||
if (!fin) {
|
||||
printf("Error open file %s", JSON_FILE_PATH);
|
||||
exit(-1);
|
||||
}
|
||||
read(fin, buffer, sizeof(buffer));
|
||||
close(fin);
|
||||
|
||||
// read json string
|
||||
json_obj = cJSON_Parse(buffer);
|
||||
// free(buffer);
|
||||
char *json_print_str = cJSON_Print(json_obj);
|
||||
printf("Json file content: \n%s\n", json_print_str);
|
||||
cJSON_free(json_print_str);
|
||||
// get anchors
|
||||
json_item = cJSON_GetObjectItem(json_obj, "anchors");
|
||||
array_size = cJSON_GetArraySize(json_item);
|
||||
if (ANCHOR_NUM * 2 != array_size) {
|
||||
printf("Expect anchor size: %d, got %d in json file", ANCHOR_NUM * 2, array_size);
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("Got %d anchors from json file\n", ANCHOR_NUM);
|
||||
}
|
||||
for (int i = 0; i < ANCHOR_NUM * 2; i++) {
|
||||
json_array_item = cJSON_GetArrayItem(json_item, i);
|
||||
anchor[i] = json_array_item->valuedouble;
|
||||
printf("%d: %f\n", i, anchor[i]);
|
||||
}
|
||||
// net_input_size
|
||||
json_item = cJSON_GetObjectItem(json_obj, "net_input_size");
|
||||
array_size = cJSON_GetArraySize(json_item);
|
||||
if (2 != array_size) {
|
||||
printf("Expect net_input_size: %d, got %d in json file", 2, array_size);
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("Got %d net_input_size from json file\n", 2);
|
||||
}
|
||||
for (int i = 0; i < 2; i++) {
|
||||
json_array_item = cJSON_GetArrayItem(json_item, i);
|
||||
net_input_size[i] = json_array_item->valueint;
|
||||
printf("%d: %d\n", i, net_input_size[i]);
|
||||
}
|
||||
// net_output_shape
|
||||
json_item = cJSON_GetObjectItem(json_obj, "net_output_shape");
|
||||
array_size = cJSON_GetArraySize(json_item);
|
||||
if (3 != array_size) {
|
||||
printf("Expect net_output_shape: %d, got %d in json file", 3, array_size);
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("Got %d net_output_shape from json file\n", 3);
|
||||
}
|
||||
for (int i = 0; i < 3; i++) {
|
||||
json_array_item = cJSON_GetArrayItem(json_item, i);
|
||||
net_output_shape[i] = json_array_item->valueint;
|
||||
printf("%d: %d\n", i, net_output_shape[i]);
|
||||
}
|
||||
// sensor_output_size
|
||||
json_item = cJSON_GetObjectItem(json_obj, "sensor_output_size");
|
||||
array_size = cJSON_GetArraySize(json_item);
|
||||
if (2 != array_size) {
|
||||
printf("Expect sensor_output_size: %d, got %d in json file", 2, array_size);
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("Got %d sensor_output_size from json file\n", 2);
|
||||
}
|
||||
for (int i = 0; i < 2; i++) {
|
||||
json_array_item = cJSON_GetArrayItem(json_item, i);
|
||||
sensor_output_size[i] = json_array_item->valueint;
|
||||
printf("%d: %d\n", i, sensor_output_size[i]);
|
||||
}
|
||||
// kmodel_path
|
||||
json_item = cJSON_GetObjectItem(json_obj, "kmodel_path");
|
||||
memcpy(kmodel_path, json_item->valuestring, strlen(json_item->valuestring));
|
||||
printf("Got kmodel_path: %s\n", kmodel_path);
|
||||
// kmodel_size
|
||||
json_item = cJSON_GetObjectItem(json_obj, "kmodel_size");
|
||||
kmodel_size = json_item->valueint;
|
||||
printf("Got kmodel_size: %d\n", kmodel_size);
|
||||
// labels
|
||||
json_item = cJSON_GetObjectItem(json_obj, "labels");
|
||||
class_num = cJSON_GetArraySize(json_item);
|
||||
if (0 >= class_num) {
|
||||
printf("No labels!");
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("Got %d labels\n", class_num);
|
||||
}
|
||||
for (int i = 0; i < class_num; i++) {
|
||||
json_array_item = cJSON_GetArrayItem(json_item, i);
|
||||
memcpy(labels[i], json_array_item->valuestring, strlen(json_array_item->valuestring));
|
||||
printf("%d: %s\n", i, labels[i]);
|
||||
}
|
||||
// obj_thresh
|
||||
json_item = cJSON_GetObjectItem(json_obj, "obj_thresh");
|
||||
array_size = cJSON_GetArraySize(json_item);
|
||||
if (class_num != array_size) {
|
||||
printf("label number and thresh number mismatch! label number : %d, obj thresh number %d", class_num, array_size);
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("Got %d obj_thresh\n", array_size);
|
||||
}
|
||||
for (int i = 0; i < array_size; i++) {
|
||||
json_array_item = cJSON_GetArrayItem(json_item, i);
|
||||
obj_thresh[i] = json_array_item->valuedouble;
|
||||
printf("%d: %f\n", i, obj_thresh[i]);
|
||||
}
|
||||
// nms_thresh
|
||||
json_item = cJSON_GetObjectItem(json_obj, "nms_thresh");
|
||||
nms_thresh = json_item->valuedouble;
|
||||
printf("Got nms_thresh: %f\n", nms_thresh);
|
||||
|
||||
cJSON_Delete(json_obj);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void face_detect()
|
||||
{
|
||||
int ret = 0;
|
||||
int result = 0;
|
||||
int size = 0;
|
||||
g_fd = open("/dev/ov2640",O_RDONLY);
|
||||
if(g_fd < 0)
|
||||
{
|
||||
param_parse();
|
||||
g_fd = open("/dev/ov2640", O_RDONLY);
|
||||
if (g_fd < 0) {
|
||||
printf("open ov2640 fail !!");
|
||||
return;
|
||||
}
|
||||
showbuffer = (unsigned char*)malloc(SHOW_RGB_BUF_SIZE);
|
||||
if(NULL ==showbuffer)
|
||||
{
|
||||
_ioctl_set_dvp_reso set_dvp_reso = {sensor_output_size[1], sensor_output_size[0]};
|
||||
ioctl(g_fd, IOCTRL_CAMERA_SET_DVP_RESO, &set_dvp_reso);
|
||||
showbuffer = (unsigned char *)malloc(sensor_output_size[0] * sensor_output_size[1] * 2);
|
||||
if (NULL == showbuffer) {
|
||||
close(g_fd);
|
||||
printf("showbuffer apply memory fail !!");
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
kpurgbbuffer = (unsigned char*)malloc(AI_KPU_RGB_BUF_SIZE);
|
||||
if(NULL ==kpurgbbuffer)
|
||||
{
|
||||
kpurgbbuffer = (unsigned char *)malloc(net_input_size[0] * net_input_size[1] * 3);
|
||||
if (NULL == kpurgbbuffer) {
|
||||
close(g_fd);
|
||||
free(showbuffer);
|
||||
printf("kpurgbbuffer apply memory fail !!");
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
model_data = (unsigned char *)malloc(KMODEL_SIZE + 255);
|
||||
if(NULL ==model_data)
|
||||
{
|
||||
model_data = (unsigned char *)malloc(kmodel_size + 255);
|
||||
if (NULL == model_data) {
|
||||
free(showbuffer);
|
||||
free(kpurgbbuffer);
|
||||
close(g_fd);
|
||||
printf("model_data apply memory fail !!");
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
memset(model_data,0,KMODEL_SIZE + 255);
|
||||
memset(showbuffer,0,SHOW_RGB_BUF_SIZE);
|
||||
memset(kpurgbbuffer,0,AI_KPU_RGB_BUF_SIZE);
|
||||
memset(model_data, 0, kmodel_size + 255);
|
||||
memset(showbuffer, 0, sensor_output_size[0] * sensor_output_size[1] * 2);
|
||||
memset(kpurgbbuffer, 0, net_input_size[0] * net_input_size[1] * 3);
|
||||
shoot_para_t.pdata = (unsigned int *)(showbuffer);
|
||||
shoot_para_t.length = SHOW_RGB_BUF_SIZE;
|
||||
shoot_para_t.length = (size_t)(sensor_output_size[0] * sensor_output_size[1] * 2);
|
||||
/*
|
||||
load memory
|
||||
*/
|
||||
kmodel_fd = open("/kmodel/detect.kmodel",O_RDONLY);
|
||||
if(kmodel_fd <0)
|
||||
{
|
||||
printf("open kmodel fail");
|
||||
close(g_fd);
|
||||
free(showbuffer);
|
||||
free(kpurgbbuffer);
|
||||
free(model_data);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
size = read(kmodel_fd, model_data, KMODEL_SIZE);
|
||||
if(size != KMODEL_SIZE)
|
||||
{
|
||||
printf("read kmodel error size %d\n",size);
|
||||
kmodel_fd = open(kmodel_path, O_RDONLY);
|
||||
if (kmodel_fd < 0) {
|
||||
printf("open kmodel fail");
|
||||
close(g_fd);
|
||||
free(showbuffer);
|
||||
free(kpurgbbuffer);
|
||||
free(model_data);
|
||||
return;
|
||||
} else {
|
||||
size = read(kmodel_fd, model_data, kmodel_size);
|
||||
if (size != kmodel_size) {
|
||||
printf("read kmodel error size %d\n", size);
|
||||
close(g_fd);
|
||||
close(kmodel_fd);
|
||||
free(showbuffer);
|
||||
|
@ -102,17 +232,14 @@ void face_detect()
|
|||
free(model_data);
|
||||
return;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("read kmodel success \n");
|
||||
}
|
||||
|
||||
} else {
|
||||
printf("read kmodel success \n");
|
||||
}
|
||||
}
|
||||
unsigned char *model_data_align = (unsigned char *)(((unsigned int)model_data+255)&(~255));
|
||||
dvp_set_ai_addr((uint32_t)kpurgbbuffer, (uint32_t)(kpurgbbuffer + 320 * 240), (uint32_t)(kpurgbbuffer + 320 * 240 * 2));
|
||||
if (kpu_load_kmodel(&face_detect_task, model_data_align) != 0)
|
||||
{
|
||||
unsigned char *model_data_align = (unsigned char *)(((unsigned int)model_data + 255) & (~255));
|
||||
dvp_set_ai_addr((uint32_t)kpurgbbuffer, (uint32_t)(kpurgbbuffer + net_input_size[0] * net_input_size[1]),
|
||||
(uint32_t)(kpurgbbuffer + net_input_size[0] * net_input_size[1] * 2));
|
||||
if (kpu_load_kmodel(&face_detect_task, model_data_align) != 0) {
|
||||
printf("\nmodel init error\n");
|
||||
close(g_fd);
|
||||
close(kmodel_fd);
|
||||
|
@ -123,46 +250,46 @@ void face_detect()
|
|||
}
|
||||
face_detect_rl.anchor_number = ANCHOR_NUM;
|
||||
face_detect_rl.anchor = anchor;
|
||||
face_detect_rl.threshold = 0.7;
|
||||
face_detect_rl.nms_value = 0.3;
|
||||
result = region_layer_init(&face_detect_rl, 20, 15, 30, KPUIMAGEWIDTH, KPUIMAGEHEIGHT);
|
||||
printf("region_layer_init result %d \n\r",result);
|
||||
size_t stack_size = 32*1024;
|
||||
pthread_attr_t attr; /* 线程属性 */
|
||||
struct sched_param prio; /* 线程优先级 */
|
||||
prio.sched_priority = 8; /* 优先级设置为 8 */
|
||||
pthread_attr_init(&attr); /* 先使用默认值初始化属性 */
|
||||
pthread_attr_setschedparam(&attr,&prio); /* 修改属性对应的优先级 */
|
||||
face_detect_rl.threshold = malloc(class_num * sizeof(float));
|
||||
for (int idx = 0; idx < class_num; idx++) {
|
||||
face_detect_rl.threshold[idx] = obj_thresh[idx];
|
||||
}
|
||||
face_detect_rl.nms_value = nms_thresh;
|
||||
result = region_layer_init(&face_detect_rl, net_output_shape[0], net_output_shape[1], net_output_shape[2],
|
||||
net_input_size[1], net_input_size[0]);
|
||||
printf("region_layer_init result %d \n\r", result);
|
||||
size_t stack_size = STACK_SIZE;
|
||||
pthread_attr_t attr; /* 线程属性 */
|
||||
struct sched_param prio; /* 线程优先级 */
|
||||
prio.sched_priority = 8; /* 优先级设置为 8 */
|
||||
pthread_attr_init(&attr); /* 先使用默认值初始化属性 */
|
||||
pthread_attr_setschedparam(&attr, &prio); /* 修改属性对应的优先级 */
|
||||
pthread_attr_setstacksize(&attr, stack_size);
|
||||
|
||||
/* 创建线程 1, 属性为 attr,入口函数是 thread_entry,入口函数参数是 1 */
|
||||
result = pthread_create(&facetid,&attr,thread_face_detcet_entry,NULL);
|
||||
if (0 == result)
|
||||
{
|
||||
result = pthread_create(&facetid, &attr, thread_face_detcet_entry, NULL);
|
||||
if (0 == result) {
|
||||
printf("thread_face_detcet_entry successfully!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("thread_face_detcet_entry failed! error code is %d\n",result);
|
||||
} else {
|
||||
printf("thread_face_detcet_entry failed! error code is %d\n", result);
|
||||
close(g_fd);
|
||||
}
|
||||
}
|
||||
#ifdef __RT_THREAD_H__
|
||||
MSH_CMD_EXPORT(face_detect,face detect task);
|
||||
MSH_CMD_EXPORT(face_detect, face detect task);
|
||||
#endif
|
||||
static void* thread_face_detcet_entry(void *parameter)
|
||||
|
||||
static void *thread_face_detcet_entry(void *parameter)
|
||||
{
|
||||
extern void lcd_draw_picture(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint32_t *ptr);
|
||||
extern void lcd_draw_picture(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint32_t * ptr);
|
||||
printf("thread_face_detcet_entry start!\n");
|
||||
int ret = 0;
|
||||
//sysctl_enable_irq();
|
||||
while(1)
|
||||
{
|
||||
//memset(showbuffer,0,320*240*2);
|
||||
// sysctl_enable_irq();
|
||||
while (1) {
|
||||
// memset(showbuffer,0,320*240*2);
|
||||
g_ai_done_flag = 0;
|
||||
ret = ioctl(g_fd,IOCTRL_CAMERA_START_SHOT,&shoot_para_t);
|
||||
if(RT_ERROR == ret)
|
||||
{
|
||||
ret = ioctl(g_fd, IOCTRL_CAMERA_START_SHOT, &shoot_para_t);
|
||||
if (RT_ERROR == ret) {
|
||||
printf("ov2640 can't wait event flag");
|
||||
rt_free(showbuffer);
|
||||
close(g_fd);
|
||||
|
@ -170,84 +297,77 @@ static void* thread_face_detcet_entry(void *parameter)
|
|||
return NULL;
|
||||
}
|
||||
kpu_run_kmodel(&face_detect_task, kpurgbbuffer, DMAC_CHANNEL5, ai_done, NULL);
|
||||
while(!g_ai_done_flag);
|
||||
while (!g_ai_done_flag)
|
||||
;
|
||||
float *output;
|
||||
size_t output_size;
|
||||
kpu_get_output(&face_detect_task, 0, (uint8_t **)&output, &output_size);
|
||||
face_detect_rl.input = output;
|
||||
region_layer_run(&face_detect_rl, &face_detect_info);
|
||||
/* display result */
|
||||
#ifdef BSP_USING_LCD
|
||||
for (int face_cnt = 0; face_cnt < face_detect_info.obj_number; face_cnt++)
|
||||
{
|
||||
draw_edge((uint32_t *)showbuffer, &face_detect_info, face_cnt, 0xF800);
|
||||
/* display result */
|
||||
#ifdef BSP_USING_LCD
|
||||
for (int face_cnt = 0; face_cnt < face_detect_info.obj_number; face_cnt++) {
|
||||
draw_edge((uint32_t *)showbuffer, &face_detect_info, face_cnt, 0xF800, (uint16_t)sensor_output_size[1],
|
||||
(uint16_t)sensor_output_size[0]);
|
||||
printf("%d: (%d, %d, %d, %d) cls: %s conf: %f\t", face_cnt, face_detect_info.obj[face_cnt].x1,
|
||||
face_detect_info.obj[face_cnt].y1, face_detect_info.obj[face_cnt].x2, face_detect_info.obj[face_cnt].y2,
|
||||
labels[face_detect_info.obj[face_cnt].class_id], face_detect_info.obj[face_cnt].prob);
|
||||
}
|
||||
if (0 != face_detect_info.obj_number) printf("\n");
|
||||
lcd_draw_picture(0, 0, (uint16_t)sensor_output_size[1], (uint16_t)sensor_output_size[0], (unsigned int *)showbuffer);
|
||||
#endif
|
||||
usleep(1);
|
||||
if (1 == if_exit) {
|
||||
if_exit = 0;
|
||||
printf("thread_face_detcet_entry exit");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
lcd_draw_picture(0, 0, 320, 240, (unsigned int*)showbuffer);
|
||||
#endif
|
||||
usleep(1);
|
||||
if(1 == if_exit)
|
||||
{
|
||||
if_exit = 0;
|
||||
printf("thread_face_detcet_entry exit");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void face_detect_delete()
|
||||
{
|
||||
if(showbuffer != NULL)
|
||||
{
|
||||
if (showbuffer != NULL) {
|
||||
int ret = 0;
|
||||
close(g_fd);
|
||||
close(kmodel_fd);
|
||||
free(showbuffer);
|
||||
free(kpurgbbuffer);
|
||||
free(model_data);
|
||||
printf("face detect task cancel!!! ret %d ",ret);
|
||||
printf("face detect task cancel!!! ret %d ", ret);
|
||||
if_exit = 1;
|
||||
}
|
||||
|
||||
}
|
||||
#ifdef __RT_THREAD_H__
|
||||
MSH_CMD_EXPORT(face_detect_delete,face detect task delete);
|
||||
MSH_CMD_EXPORT(face_detect_delete, face detect task delete);
|
||||
#endif
|
||||
void kmodel_load(unsigned char * model_data)
|
||||
|
||||
void kmodel_load(unsigned char *model_data)
|
||||
{
|
||||
int kmodel_fd = 0;
|
||||
int size = 0;
|
||||
kmodel_fd = open("/kmodel/detect.kmodel",O_RDONLY);
|
||||
kmodel_fd = open(kmodel_path, O_RDONLY);
|
||||
|
||||
model_data = (unsigned char *)malloc(KMODEL_SIZE + 255);
|
||||
if(NULL ==model_data)
|
||||
{
|
||||
model_data = (unsigned char *)malloc(kmodel_size + 255);
|
||||
if (NULL == model_data) {
|
||||
printf("model_data apply memory fail !!");
|
||||
return ;
|
||||
return;
|
||||
}
|
||||
memset(model_data,0,KMODEL_SIZE + 255);
|
||||
memset(model_data, 0, kmodel_size + 255);
|
||||
|
||||
if (kmodel_fd>= 0)
|
||||
{
|
||||
size = read(kmodel_fd, model_data, KMODEL_SIZE);
|
||||
if(size != KMODEL_SIZE)
|
||||
{
|
||||
printf("read kmodel error size %d\n",size);
|
||||
if (kmodel_fd >= 0) {
|
||||
size = read(kmodel_fd, model_data, kmodel_size);
|
||||
if (size != kmodel_size) {
|
||||
printf("read kmodel error size %d\n", size);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("read kmodel success");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
printf("read kmodel success");
|
||||
}
|
||||
} else {
|
||||
free(model_data);
|
||||
printf("open kmodel fail");
|
||||
}
|
||||
|
||||
}
|
||||
#ifdef __RT_THREAD_H__
|
||||
MSH_CMD_EXPORT(kmodel_load,kmodel load memory);
|
||||
MSH_CMD_EXPORT(kmodel_load, kmodel load memory);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
config HELMET_DETECT
|
||||
bool "enable apps/helmet detect"
|
||||
depends on BOARD_K210_EVB
|
||||
depends on DRV_USING_OV2640
|
||||
depends on USING_KPU_POSTPROCESSING
|
||||
depends on USING_YOLOV2
|
||||
select LIB_USING_CJSON
|
||||
default n
|
|
@ -0,0 +1,167 @@
|
|||
# Helmet detection demo
|
||||
|
||||
### A helmet and head without helmet object detection task demo. Running MobileNet-yolo on K210-based edge devices.
|
||||
|
||||
---
|
||||
|
||||
## Training
|
||||
|
||||
### Enviroment preparation
|
||||
|
||||
Model generated by [aXeleRate](https://forgeplus.trustie.net/projects/yangtuo250/aXeleRate) and converted to kmodel by [nncase](https://github.com/kendryte/nncase/tree/v0.1.0-rc5).
|
||||
|
||||
```shell
|
||||
# master branch for MobileNetv1-yolov2 and unstable branch to test MobileNetv1(v2)-yolov2(v3)
|
||||
git clone https://git.trustie.net/yangtuo250/aXeleRate.git (-b unstable)
|
||||
cd aXeleRate
|
||||
pip install -r requirments.txt && pip install -e .
|
||||
```
|
||||
|
||||
### training config setting
|
||||
|
||||
Example [config](https://forgeplus.trustie.net/projects/yangtuo250/aXeleRate/tree/master/configs/detector.json), some hyper-parameters:
|
||||
|
||||
- architecture: backbone, MobileNet7_5 for default, MobileNet1_0(α = 1.0) and above cannot run on K210 because of OOM on feature map in master branch. For unstable branch MobileNetV2_1_0 is OK.
|
||||
|
||||
- input_size: fixed model input size, single integer for height equals to width, otherwise a list([height, width]).
|
||||
- anchors: yolov2 anchor(for master) or anchor scaled to 1.0(for unstable), can be generate by [darknet](https://github.com/AlexeyAB/darknet).
|
||||
- labels: labels of all classes.
|
||||
- train(valid)_image(annot)_folder: path of images and annoations for training and validation.
|
||||
- saved_folder: path for trainig result storage(models, checkpoints, logs ...).
|
||||
|
||||
Mine config for unstable:
|
||||
```json
|
||||
{
|
||||
"model": {
|
||||
"type": "Detector",
|
||||
"architecture": "MobileNetV2_1_0",
|
||||
"input_size": [
|
||||
224,
|
||||
320
|
||||
],
|
||||
"anchors": [
|
||||
[
|
||||
[
|
||||
0.1043,
|
||||
0.1560
|
||||
],
|
||||
[
|
||||
0.0839,
|
||||
0.3036
|
||||
],
|
||||
[
|
||||
0.1109,
|
||||
0.3923
|
||||
],
|
||||
[
|
||||
0.1378,
|
||||
0.5244
|
||||
],
|
||||
[
|
||||
0.2049,
|
||||
0.6673
|
||||
]
|
||||
]
|
||||
],
|
||||
"labels": [
|
||||
"human"
|
||||
],
|
||||
"obj_thresh": 0.5,
|
||||
"iou_thresh": 0.45,
|
||||
"coord_scale": 1.0,
|
||||
"class_scale": 0.0,
|
||||
"object_scale": 5.0,
|
||||
"no_object_scale": 3.0
|
||||
},
|
||||
"weights": {
|
||||
"full": "",
|
||||
"backend": ""
|
||||
},
|
||||
"train": {
|
||||
"actual_epoch": 2000,
|
||||
"train_image_folder": "mydata/human/Images/train",
|
||||
"train_annot_folder": "mydata/human/Annotations/train",
|
||||
"train_times": 2,
|
||||
"valid_image_folder": "mydata/human/Images/val",
|
||||
"valid_annot_folder": "mydata/human/Annotations/val",
|
||||
"valid_times": 1,
|
||||
"valid_metric": "precision",
|
||||
"batch_size": 32,
|
||||
"learning_rate": 2e-5,
|
||||
"saved_folder": "mydata/human/results",
|
||||
"first_trainable_layer": "",
|
||||
"augmentation": true,
|
||||
"is_only_detect": false,
|
||||
"validation_freq": 5,
|
||||
"quantize": false,
|
||||
"class_weights": [1.0]
|
||||
},
|
||||
"converter": {
|
||||
"type": [
|
||||
"k210"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
*(For more detailed config usage, please refer to original aXeleRate repo.)*
|
||||
|
||||
### data preparation
|
||||
|
||||
Please refer to [VOC format](https://towardsdatascience.com/coco-data-format-for-object-detection-a4c5eaf518c5), path as config above.
|
||||
|
||||
### train it!
|
||||
|
||||
```shell
|
||||
python -m aXeleRate.train -c PATH_TO_YOUR_CONFIG
|
||||
```
|
||||
|
||||
### model convert
|
||||
|
||||
Please refer to [nncase repo](https://github.com/kendryte/nncase/tree/v0.1.0-rc5).
|
||||
|
||||
---
|
||||
|
||||
## Deployment
|
||||
|
||||
### compile and burn
|
||||
|
||||
Use `(scons --)menuconfig` in bsp folder *(Ubiquitous/RT_Thread/bsp/k210)*, open:
|
||||
|
||||
- More Drivers --> ov2640 driver
|
||||
- Board Drivers Config --> Enable LCD on SPI0
|
||||
- Board Drivers Config --> Enable SDCARD (spi1(ss0))
|
||||
- Board Drivers Config --> Enable DVP(camera)
|
||||
- RT-Thread Components --> POSIX layer and C standard library --> Enable pthreads APIs
|
||||
- APP_Framework --> Framework --> support knowing framework --> kpu model postprocessing --> yolov2 region layer
|
||||
- APP_Framework --> Applications --> knowing app --> enable apps/helmet detect
|
||||
|
||||
`scons -j(n)` to compile and burn in by *kflash*.
|
||||
|
||||
### json config and kmodel
|
||||
|
||||
Copy json config for deployment o SD card */kmodel*. Example config file is *helmet.json* in this directory. Something to be modified:
|
||||
|
||||
- net_input_size: same as *input_size* in training config file, but array only.
|
||||
- net_output_shape: final feature map size, can be found in **nncase** output.
|
||||
- sensor_output_size: image height and width from camera.
|
||||
- kmodel_size: kmodel size shown in file system.
|
||||
- anchors: same as *anchor* in training config file(multi-dimention anchors flatten to 1 dim).
|
||||
- labels: same as *label* in training config file.
|
||||
- obj_thresh: array, object threshold of each label.
|
||||
- nms_thresh: NMS threshold of boxes.
|
||||
|
||||
Copy final kmodel to SD card */kmodel* either.
|
||||
|
||||
---
|
||||
|
||||
## Run
|
||||
|
||||
In serial terminal, `helmet_detect` to start a detection thread, `helmet_detect_delete` to stop it. Detection results can be found in output.
|
||||
|
||||
---
|
||||
|
||||
## TODO
|
||||
|
||||
- [ ] Fix LCD real-time result display.
|
||||
- [ ] Test more object detection backbone and algorithm(like yolox).
|
|
@ -0,0 +1,9 @@
|
|||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = Glob('*.c') + Glob('*.cpp')
|
||||
CPPPATH = [cwd]
|
||||
|
||||
group = DefineGroup('Applications', src, depend = ['HELMET_DETECT'], LOCAL_CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"net_input_size": [
|
||||
256,
|
||||
256
|
||||
],
|
||||
"net_output_shape": [
|
||||
8,
|
||||
8,
|
||||
35
|
||||
],
|
||||
"sensor_output_size": [
|
||||
256,
|
||||
256
|
||||
],
|
||||
"anchors": [
|
||||
0.1384,
|
||||
0.276,
|
||||
0.308,
|
||||
0.504,
|
||||
0.5792,
|
||||
0.8952,
|
||||
1.072,
|
||||
1.6184,
|
||||
2.1128,
|
||||
3.184
|
||||
],
|
||||
"kmodel_path": "/kmodel/helmet.kmodel",
|
||||
"kmodel_size": 2714044,
|
||||
"obj_thresh": [
|
||||
0.7,
|
||||
0.9
|
||||
],
|
||||
"labels": [
|
||||
"head",
|
||||
"helmet"
|
||||
],
|
||||
"nms_thresh": 0.45
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,380 @@
|
|||
#include <transform.h>
|
||||
#ifdef LIB_USING_CJSON
|
||||
#include <cJSON.h>
|
||||
#endif
|
||||
#include "region_layer.h"
|
||||
#define ANCHOR_NUM 5
|
||||
#define STACK_SIZE (128 * 1024)
|
||||
#define JSON_FILE_PATH "/kmodel/helmet.json"
|
||||
#define JSON_BUFFER_SIZE (4 * 1024)
|
||||
|
||||
// params from json
|
||||
static float anchor[ANCHOR_NUM * 2] = {};
|
||||
static int net_output_shape[3] = {};
|
||||
static int net_input_size[2] = {};
|
||||
static int sensor_output_size[2] = {};
|
||||
static char kmodel_path[127] = "";
|
||||
static int kmodel_size = 0;
|
||||
static float obj_thresh[20] = {};
|
||||
static float nms_thresh = 0.0;
|
||||
static char labels[20][32] = {};
|
||||
static int class_num = 0;
|
||||
|
||||
#define THREAD_PRIORITY_HELMET_D (11)
|
||||
static pthread_t helmettid = 0;
|
||||
static void *thread_helmet_detect_entry(void *parameter);
|
||||
static int g_fd = 0;
|
||||
static int kmodel_fd = 0;
|
||||
static int if_exit = 0;
|
||||
static unsigned char *showbuffer = NULL;
|
||||
static unsigned char *kpurgbbuffer = NULL;
|
||||
|
||||
static _ioctl_shoot_para shoot_para_t = {0};
|
||||
unsigned char *model_data = NULL; // kpu data load memory
|
||||
unsigned char *model_data_align = NULL;
|
||||
|
||||
kpu_model_context_t helmet_detect_task;
|
||||
static region_layer_t helmet_detect_rl;
|
||||
static obj_info_t helmet_detect_info;
|
||||
volatile uint32_t g_ai_done_flag;
|
||||
|
||||
static void ai_done(void *ctx) { g_ai_done_flag = 1; }
|
||||
|
||||
static void param_parse()
|
||||
{
|
||||
int fin;
|
||||
char buffer[JSON_BUFFER_SIZE] = "";
|
||||
// char *buffer;
|
||||
// if (NULL != (buffer = (char*)malloc(JSON_BUFFER_SIZE * sizeof(char)))) {
|
||||
// memset(buffer, 0, JSON_BUFFER_SIZE * sizeof(char));
|
||||
// } else {
|
||||
// printf("Json buffer malloc failed!");
|
||||
// exit(-1);
|
||||
// }
|
||||
int array_size;
|
||||
cJSON *json_obj;
|
||||
cJSON *json_item;
|
||||
cJSON *json_array_item;
|
||||
|
||||
fin = open(JSON_FILE_PATH, O_RDONLY);
|
||||
if (!fin) {
|
||||
printf("Error open file %s", JSON_FILE_PATH);
|
||||
exit(-1);
|
||||
}
|
||||
read(fin, buffer, sizeof(buffer));
|
||||
close(fin);
|
||||
|
||||
// read json string
|
||||
json_obj = cJSON_Parse(buffer);
|
||||
// free(buffer);
|
||||
char *json_print_str = cJSON_Print(json_obj);
|
||||
printf("Json file content: \n%s\n", json_print_str);
|
||||
cJSON_free(json_print_str);
|
||||
// get anchors
|
||||
json_item = cJSON_GetObjectItem(json_obj, "anchors");
|
||||
array_size = cJSON_GetArraySize(json_item);
|
||||
if (ANCHOR_NUM * 2 != array_size) {
|
||||
printf("Expect anchor size: %d, got %d in json file", ANCHOR_NUM * 2, array_size);
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("Got %d anchors from json file\n", ANCHOR_NUM);
|
||||
}
|
||||
for (int i = 0; i < ANCHOR_NUM * 2; i++) {
|
||||
json_array_item = cJSON_GetArrayItem(json_item, i);
|
||||
anchor[i] = json_array_item->valuedouble;
|
||||
printf("%d: %f\n", i, anchor[i]);
|
||||
}
|
||||
// net_input_size
|
||||
json_item = cJSON_GetObjectItem(json_obj, "net_input_size");
|
||||
array_size = cJSON_GetArraySize(json_item);
|
||||
if (2 != array_size) {
|
||||
printf("Expect net_input_size: %d, got %d in json file", 2, array_size);
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("Got %d net_input_size from json file\n", 2);
|
||||
}
|
||||
for (int i = 0; i < 2; i++) {
|
||||
json_array_item = cJSON_GetArrayItem(json_item, i);
|
||||
net_input_size[i] = json_array_item->valueint;
|
||||
printf("%d: %d\n", i, net_input_size[i]);
|
||||
}
|
||||
// net_output_shape
|
||||
json_item = cJSON_GetObjectItem(json_obj, "net_output_shape");
|
||||
array_size = cJSON_GetArraySize(json_item);
|
||||
if (3 != array_size) {
|
||||
printf("Expect net_output_shape: %d, got %d in json file", 3, array_size);
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("Got %d net_output_shape from json file\n", 3);
|
||||
}
|
||||
for (int i = 0; i < 3; i++) {
|
||||
json_array_item = cJSON_GetArrayItem(json_item, i);
|
||||
net_output_shape[i] = json_array_item->valueint;
|
||||
printf("%d: %d\n", i, net_output_shape[i]);
|
||||
}
|
||||
// sensor_output_size
|
||||
json_item = cJSON_GetObjectItem(json_obj, "sensor_output_size");
|
||||
array_size = cJSON_GetArraySize(json_item);
|
||||
if (2 != array_size) {
|
||||
printf("Expect sensor_output_size: %d, got %d in json file", 2, array_size);
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("Got %d sensor_output_size from json file\n", 2);
|
||||
}
|
||||
for (int i = 0; i < 2; i++) {
|
||||
json_array_item = cJSON_GetArrayItem(json_item, i);
|
||||
sensor_output_size[i] = json_array_item->valueint;
|
||||
printf("%d: %d\n", i, sensor_output_size[i]);
|
||||
}
|
||||
// kmodel_path
|
||||
json_item = cJSON_GetObjectItem(json_obj, "kmodel_path");
|
||||
memcpy(kmodel_path, json_item->valuestring, strlen(json_item->valuestring));
|
||||
printf("Got kmodel_path: %s\n", kmodel_path);
|
||||
// kmodel_size
|
||||
json_item = cJSON_GetObjectItem(json_obj, "kmodel_size");
|
||||
kmodel_size = json_item->valueint;
|
||||
printf("Got kmodel_size: %d\n", kmodel_size);
|
||||
// labels
|
||||
json_item = cJSON_GetObjectItem(json_obj, "labels");
|
||||
class_num = cJSON_GetArraySize(json_item);
|
||||
if (0 >= class_num) {
|
||||
printf("No labels!");
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("Got %d labels\n", class_num);
|
||||
}
|
||||
for (int i = 0; i < class_num; i++) {
|
||||
json_array_item = cJSON_GetArrayItem(json_item, i);
|
||||
memcpy(labels[i], json_array_item->valuestring, strlen(json_array_item->valuestring));
|
||||
printf("%d: %s\n", i, labels[i]);
|
||||
}
|
||||
// obj_thresh
|
||||
json_item = cJSON_GetObjectItem(json_obj, "obj_thresh");
|
||||
array_size = cJSON_GetArraySize(json_item);
|
||||
if (class_num != array_size) {
|
||||
printf("label number and thresh number mismatch! label number : %d, obj thresh number %d", class_num, array_size);
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("Got %d obj_thresh\n", array_size);
|
||||
}
|
||||
for (int i = 0; i < array_size; i++) {
|
||||
json_array_item = cJSON_GetArrayItem(json_item, i);
|
||||
obj_thresh[i] = json_array_item->valuedouble;
|
||||
printf("%d: %f\n", i, obj_thresh[i]);
|
||||
}
|
||||
// nms_thresh
|
||||
json_item = cJSON_GetObjectItem(json_obj, "nms_thresh");
|
||||
nms_thresh = json_item->valuedouble;
|
||||
printf("Got nms_thresh: %f\n", nms_thresh);
|
||||
|
||||
cJSON_Delete(json_obj);
|
||||
return;
|
||||
}
|
||||
|
||||
void helmet_detect()
|
||||
{
|
||||
int ret = 0;
|
||||
int result = 0;
|
||||
int size = 0;
|
||||
param_parse();
|
||||
g_fd = open("/dev/ov2640", O_RDONLY);
|
||||
if (g_fd < 0) {
|
||||
printf("open ov2640 fail !!");
|
||||
return;
|
||||
}
|
||||
_ioctl_set_dvp_reso set_dvp_reso = {sensor_output_size[1], sensor_output_size[0]};
|
||||
ioctl(g_fd, IOCTRL_CAMERA_SET_DVP_RESO, &set_dvp_reso);
|
||||
showbuffer = (unsigned char *)malloc(sensor_output_size[0] * sensor_output_size[1] * 2);
|
||||
if (NULL == showbuffer) {
|
||||
close(g_fd);
|
||||
printf("showbuffer apply memory fail !!");
|
||||
return;
|
||||
}
|
||||
kpurgbbuffer = (unsigned char *)malloc(net_input_size[0] * net_input_size[1] * 3);
|
||||
if (NULL == kpurgbbuffer) {
|
||||
close(g_fd);
|
||||
free(showbuffer);
|
||||
printf("kpurgbbuffer apply memory fail !!");
|
||||
return;
|
||||
}
|
||||
model_data = (unsigned char *)malloc(kmodel_size + 255);
|
||||
if (NULL == model_data) {
|
||||
free(showbuffer);
|
||||
free(kpurgbbuffer);
|
||||
close(g_fd);
|
||||
printf("model_data apply memory fail !!");
|
||||
return;
|
||||
}
|
||||
memset(model_data, 0, kmodel_size + 255);
|
||||
memset(showbuffer, 0, sensor_output_size[0] * sensor_output_size[1] * 2);
|
||||
memset(kpurgbbuffer, 127, net_input_size[0] * net_input_size[1] * 3);
|
||||
shoot_para_t.pdata = (unsigned int *)(showbuffer);
|
||||
shoot_para_t.length = (size_t)(sensor_output_size[0] * sensor_output_size[1] * 2);
|
||||
/*
|
||||
load memory
|
||||
*/
|
||||
kmodel_fd = open(kmodel_path, O_RDONLY);
|
||||
if (kmodel_fd < 0) {
|
||||
printf("open kmodel fail");
|
||||
close(g_fd);
|
||||
free(showbuffer);
|
||||
free(kpurgbbuffer);
|
||||
free(model_data);
|
||||
return;
|
||||
} else {
|
||||
size = read(kmodel_fd, model_data, kmodel_size);
|
||||
if (size != kmodel_size) {
|
||||
printf("read kmodel error size %d\n", size);
|
||||
close(g_fd);
|
||||
close(kmodel_fd);
|
||||
free(showbuffer);
|
||||
free(kpurgbbuffer);
|
||||
free(model_data);
|
||||
return;
|
||||
|
||||
} else {
|
||||
printf("read kmodel success \n");
|
||||
}
|
||||
}
|
||||
unsigned char *model_data_align = (unsigned char *)(((unsigned int)model_data + 255) & (~255));
|
||||
dvp_set_ai_addr((uint32_t)(kpurgbbuffer + net_input_size[1] * (net_input_size[0] - sensor_output_size[0])),
|
||||
(uint32_t)(kpurgbbuffer + net_input_size[1] * (net_input_size[0] - sensor_output_size[0]) +
|
||||
net_input_size[0] * net_input_size[1]),
|
||||
(uint32_t)(kpurgbbuffer + net_input_size[0] * net_input_size[1] * 2 +
|
||||
net_input_size[1] * (net_input_size[0] - sensor_output_size[0])));
|
||||
if (kpu_load_kmodel(&helmet_detect_task, model_data_align) != 0) {
|
||||
printf("\nmodel init error\n");
|
||||
close(g_fd);
|
||||
close(kmodel_fd);
|
||||
free(showbuffer);
|
||||
free(kpurgbbuffer);
|
||||
free(model_data);
|
||||
return;
|
||||
}
|
||||
helmet_detect_rl.anchor_number = ANCHOR_NUM;
|
||||
helmet_detect_rl.anchor = anchor;
|
||||
helmet_detect_rl.threshold = malloc(class_num * sizeof(float));
|
||||
for (int idx = 0; idx < class_num; idx++) {
|
||||
helmet_detect_rl.threshold[idx] = obj_thresh[idx];
|
||||
}
|
||||
helmet_detect_rl.nms_value = nms_thresh;
|
||||
result = region_layer_init(&helmet_detect_rl, net_output_shape[0], net_output_shape[1], net_output_shape[2],
|
||||
net_input_size[1], net_input_size[0]);
|
||||
printf("region_layer_init result %d \n\r", result);
|
||||
size_t stack_size = STACK_SIZE;
|
||||
pthread_attr_t attr; /* 线程属性 */
|
||||
struct sched_param prio; /* 线程优先级 */
|
||||
prio.sched_priority = 8; /* 优先级设置为 8 */
|
||||
pthread_attr_init(&attr); /* 先使用默认值初始化属性 */
|
||||
pthread_attr_setschedparam(&attr, &prio); /* 修改属性对应的优先级 */
|
||||
pthread_attr_setstacksize(&attr, stack_size);
|
||||
|
||||
/* 创建线程 1, 属性为 attr,入口函数是 thread_entry,入口函数参数是 1 */
|
||||
result = pthread_create(&helmettid, &attr, thread_helmet_detect_entry, NULL);
|
||||
if (0 == result) {
|
||||
printf("thread_helmet_detect_entry successfully!\n");
|
||||
} else {
|
||||
printf("thread_helmet_detect_entry failed! error code is %d\n", result);
|
||||
close(g_fd);
|
||||
}
|
||||
}
|
||||
#ifdef __RT_THREAD_H__
|
||||
MSH_CMD_EXPORT(helmet_detect, helmet detect task);
|
||||
#endif
|
||||
|
||||
static void *thread_helmet_detect_entry(void *parameter)
|
||||
{
|
||||
extern void lcd_draw_picture(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint32_t * ptr);
|
||||
printf("thread_helmet_detect_entry start!\n");
|
||||
int ret = 0;
|
||||
// sysctl_enable_irq();
|
||||
while (1) {
|
||||
// memset(showbuffer,0,320*240*2);
|
||||
g_ai_done_flag = 0;
|
||||
ret = ioctl(g_fd, IOCTRL_CAMERA_START_SHOT, &shoot_para_t);
|
||||
if (RT_ERROR == ret) {
|
||||
printf("ov2640 can't wait event flag");
|
||||
rt_free(showbuffer);
|
||||
close(g_fd);
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
kpu_run_kmodel(&helmet_detect_task, kpurgbbuffer, DMAC_CHANNEL5, ai_done, NULL);
|
||||
while (!g_ai_done_flag)
|
||||
;
|
||||
float *output;
|
||||
size_t output_size;
|
||||
kpu_get_output(&helmet_detect_task, 0, (uint8_t **)&output, &output_size);
|
||||
helmet_detect_rl.input = output;
|
||||
region_layer_run(&helmet_detect_rl, &helmet_detect_info);
|
||||
/* display result */
|
||||
#ifdef BSP_USING_LCD
|
||||
for (int helmet_cnt = 0; helmet_cnt < helmet_detect_info.obj_number; helmet_cnt++) {
|
||||
// draw_edge((uint32_t *)showbuffer, &helmet_detect_info, helmet_cnt, 0xF800,
|
||||
// (uint16_t)sensor_output_size[1],
|
||||
// (uint16_t)sensor_output_size[0]);
|
||||
printf("%d: (%d, %d, %d, %d) cls: %s conf: %f\t", helmet_cnt, helmet_detect_info.obj[helmet_cnt].x1,
|
||||
helmet_detect_info.obj[helmet_cnt].y1, helmet_detect_info.obj[helmet_cnt].x2,
|
||||
helmet_detect_info.obj[helmet_cnt].y2, labels[helmet_detect_info.obj[helmet_cnt].class_id],
|
||||
helmet_detect_info.obj[helmet_cnt].prob);
|
||||
}
|
||||
if (0 != helmet_detect_info.obj_number) {
|
||||
printf("\n");
|
||||
}
|
||||
lcd_draw_picture(0, 0, (uint16_t)sensor_output_size[1], (uint16_t)sensor_output_size[0], (unsigned int *)showbuffer);
|
||||
#endif
|
||||
usleep(1);
|
||||
if (1 == if_exit) {
|
||||
if_exit = 0;
|
||||
printf("thread_helmet_detect_entry exit");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void helmet_detect_delete()
|
||||
{
|
||||
if (showbuffer != NULL) {
|
||||
int ret = 0;
|
||||
close(g_fd);
|
||||
close(kmodel_fd);
|
||||
free(showbuffer);
|
||||
free(kpurgbbuffer);
|
||||
free(model_data);
|
||||
printf("helmet detect task cancel!!! ret %d ", ret);
|
||||
if_exit = 1;
|
||||
}
|
||||
}
|
||||
#ifdef __RT_THREAD_H__
|
||||
MSH_CMD_EXPORT(helmet_detect_delete, helmet detect task delete);
|
||||
#endif
|
||||
|
||||
void kmodel_load(unsigned char *model_data)
|
||||
{
|
||||
int kmodel_fd = 0;
|
||||
int size = 0;
|
||||
kmodel_fd = open(kmodel_path, O_RDONLY);
|
||||
|
||||
model_data = (unsigned char *)malloc(kmodel_size + 255);
|
||||
if (NULL == model_data) {
|
||||
printf("model_data apply memory fail !!");
|
||||
return;
|
||||
}
|
||||
memset(model_data, 0, kmodel_size + 255);
|
||||
|
||||
if (kmodel_fd >= 0) {
|
||||
size = read(kmodel_fd, model_data, kmodel_size);
|
||||
if (size != kmodel_size) {
|
||||
printf("read kmodel error size %d\n", size);
|
||||
|
||||
} else {
|
||||
printf("read kmodel success");
|
||||
}
|
||||
} else {
|
||||
free(model_data);
|
||||
printf("open kmodel fail");
|
||||
}
|
||||
}
|
||||
#ifdef __RT_THREAD_H__
|
||||
MSH_CMD_EXPORT(kmodel_load, kmodel load memory);
|
||||
#endif
|
|
@ -0,0 +1,8 @@
|
|||
config INSTRUSION_DETECT
|
||||
bool "enable apps/instrusion detect"
|
||||
depends on BOARD_K210_EVB
|
||||
depends on DRV_USING_OV2640
|
||||
depends on USING_KPU_POSTPROCESSING
|
||||
depends on USING_YOLOV2
|
||||
select LIB_USING_CJSON
|
||||
default n
|
|
@ -0,0 +1,5 @@
|
|||
# Instrusion detect demo
|
||||
|
||||
### A human object detection task demo. Running MobileNet-yolo on K210-based edge devices.
|
||||
|
||||
***Training, deployment and running, please see helmet_detect***
|
|
@ -0,0 +1,9 @@
|
|||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = Glob('*.c') + Glob('*.cpp')
|
||||
CPPPATH = [cwd]
|
||||
|
||||
group = DefineGroup('Applications', src, depend = ['INSTRUSION_DETECT'], LOCAL_CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"net_input_size": [
|
||||
224,
|
||||
320
|
||||
],
|
||||
"net_output_shape": [
|
||||
10,
|
||||
7,
|
||||
30
|
||||
],
|
||||
"sensor_output_size": [
|
||||
240,
|
||||
320
|
||||
],
|
||||
"anchors": [
|
||||
1.043,
|
||||
1.092,
|
||||
0.839,
|
||||
2.1252,
|
||||
1.109,
|
||||
2.7461,
|
||||
1.378,
|
||||
3.6708,
|
||||
2.049,
|
||||
4.6711
|
||||
],
|
||||
"kmodel_path": "/kmodel/human.kmodel",
|
||||
"kmodel_size": 2713236,
|
||||
"obj_thresh": [
|
||||
0.55
|
||||
],
|
||||
"labels": [
|
||||
"human"
|
||||
],
|
||||
"nms_thresh": 0.35
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,380 @@
|
|||
#include <transform.h>
|
||||
#ifdef LIB_USING_CJSON
|
||||
#include <cJSON.h>
|
||||
#endif
|
||||
#include "region_layer.h"
|
||||
#define ANCHOR_NUM 5
|
||||
#define STACK_SIZE (128 * 1024)
|
||||
#define JSON_FILE_PATH "/kmodel/human.json"
|
||||
#define JSON_BUFFER_SIZE (4 * 1024)
|
||||
|
||||
// params from json
|
||||
static float anchor[ANCHOR_NUM * 2] = {};
|
||||
static int net_output_shape[3] = {};
|
||||
static int net_input_size[2] = {};
|
||||
static int sensor_output_size[2] = {};
|
||||
static char kmodel_path[127] = "";
|
||||
static int kmodel_size = 0;
|
||||
static float obj_thresh[20] = {};
|
||||
static float nms_thresh = 0.0;
|
||||
static char labels[20][32] = {};
|
||||
static int class_num = 0;
|
||||
|
||||
#define THREAD_PRIORITY_HUMAN_D (11)
|
||||
static pthread_t instrusiontid = 0;
|
||||
static void *thread_instrusion_detect_entry(void *parameter);
|
||||
static int g_fd = 0;
|
||||
static int kmodel_fd = 0;
|
||||
static int if_exit = 0;
|
||||
static unsigned char *showbuffer = NULL;
|
||||
static unsigned char *kpurgbbuffer = NULL;
|
||||
|
||||
static _ioctl_shoot_para shoot_para_t = {0};
|
||||
unsigned char *model_data = NULL; // kpu data load memory
|
||||
unsigned char *model_data_align = NULL;
|
||||
|
||||
kpu_model_context_t instrusion_detect_task;
|
||||
static region_layer_t instrusion_detect_rl;
|
||||
static obj_info_t instrusion_detect_info;
|
||||
volatile uint32_t g_ai_done_flag;
|
||||
|
||||
static void ai_done(void *ctx) { g_ai_done_flag = 1; }
|
||||
|
||||
static void param_parse()
|
||||
{
|
||||
int fin;
|
||||
char buffer[JSON_BUFFER_SIZE] = "";
|
||||
// char *buffer;
|
||||
// if (NULL != (buffer = (char*)malloc(JSON_BUFFER_SIZE * sizeof(char)))) {
|
||||
// memset(buffer, 0, JSON_BUFFER_SIZE * sizeof(char));
|
||||
// } else {
|
||||
// printf("Json buffer malloc failed!");
|
||||
// exit(-1);
|
||||
// }
|
||||
int array_size;
|
||||
cJSON *json_obj;
|
||||
cJSON *json_item;
|
||||
cJSON *json_array_item;
|
||||
|
||||
fin = open(JSON_FILE_PATH, O_RDONLY);
|
||||
if (!fin) {
|
||||
printf("Error open file %s", JSON_FILE_PATH);
|
||||
exit(-1);
|
||||
}
|
||||
read(fin, buffer, sizeof(buffer));
|
||||
close(fin);
|
||||
|
||||
// read json string
|
||||
json_obj = cJSON_Parse(buffer);
|
||||
// free(buffer);
|
||||
char *json_print_str = cJSON_Print(json_obj);
|
||||
printf("Json file content: \n%s\n", json_print_str);
|
||||
cJSON_free(json_print_str);
|
||||
// get anchors
|
||||
json_item = cJSON_GetObjectItem(json_obj, "anchors");
|
||||
array_size = cJSON_GetArraySize(json_item);
|
||||
if (ANCHOR_NUM * 2 != array_size) {
|
||||
printf("Expect anchor size: %d, got %d in json file", ANCHOR_NUM * 2, array_size);
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("Got %d anchors from json file\n", ANCHOR_NUM);
|
||||
}
|
||||
for (int i = 0; i < ANCHOR_NUM * 2; i++) {
|
||||
json_array_item = cJSON_GetArrayItem(json_item, i);
|
||||
anchor[i] = json_array_item->valuedouble;
|
||||
printf("%d: %f\n", i, anchor[i]);
|
||||
}
|
||||
// net_input_size
|
||||
json_item = cJSON_GetObjectItem(json_obj, "net_input_size");
|
||||
array_size = cJSON_GetArraySize(json_item);
|
||||
if (2 != array_size) {
|
||||
printf("Expect net_input_size: %d, got %d in json file", 2, array_size);
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("Got %d net_input_size from json file\n", 2);
|
||||
}
|
||||
for (int i = 0; i < 2; i++) {
|
||||
json_array_item = cJSON_GetArrayItem(json_item, i);
|
||||
net_input_size[i] = json_array_item->valueint;
|
||||
printf("%d: %d\n", i, net_input_size[i]);
|
||||
}
|
||||
// net_output_shape
|
||||
json_item = cJSON_GetObjectItem(json_obj, "net_output_shape");
|
||||
array_size = cJSON_GetArraySize(json_item);
|
||||
if (3 != array_size) {
|
||||
printf("Expect net_output_shape: %d, got %d in json file", 3, array_size);
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("Got %d net_output_shape from json file\n", 3);
|
||||
}
|
||||
for (int i = 0; i < 3; i++) {
|
||||
json_array_item = cJSON_GetArrayItem(json_item, i);
|
||||
net_output_shape[i] = json_array_item->valueint;
|
||||
printf("%d: %d\n", i, net_output_shape[i]);
|
||||
}
|
||||
// sensor_output_size
|
||||
json_item = cJSON_GetObjectItem(json_obj, "sensor_output_size");
|
||||
array_size = cJSON_GetArraySize(json_item);
|
||||
if (2 != array_size) {
|
||||
printf("Expect sensor_output_size: %d, got %d in json file", 2, array_size);
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("Got %d sensor_output_size from json file\n", 2);
|
||||
}
|
||||
for (int i = 0; i < 2; i++) {
|
||||
json_array_item = cJSON_GetArrayItem(json_item, i);
|
||||
sensor_output_size[i] = json_array_item->valueint;
|
||||
printf("%d: %d\n", i, sensor_output_size[i]);
|
||||
}
|
||||
// kmodel_path
|
||||
json_item = cJSON_GetObjectItem(json_obj, "kmodel_path");
|
||||
memcpy(kmodel_path, json_item->valuestring, strlen(json_item->valuestring));
|
||||
printf("Got kmodel_path: %s\n", kmodel_path);
|
||||
// kmodel_size
|
||||
json_item = cJSON_GetObjectItem(json_obj, "kmodel_size");
|
||||
kmodel_size = json_item->valueint;
|
||||
printf("Got kmodel_size: %d\n", kmodel_size);
|
||||
// labels
|
||||
json_item = cJSON_GetObjectItem(json_obj, "labels");
|
||||
class_num = cJSON_GetArraySize(json_item);
|
||||
if (0 >= class_num) {
|
||||
printf("No labels!");
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("Got %d labels\n", class_num);
|
||||
}
|
||||
for (int i = 0; i < class_num; i++) {
|
||||
json_array_item = cJSON_GetArrayItem(json_item, i);
|
||||
memcpy(labels[i], json_array_item->valuestring, strlen(json_array_item->valuestring));
|
||||
printf("%d: %s\n", i, labels[i]);
|
||||
}
|
||||
// obj_thresh
|
||||
json_item = cJSON_GetObjectItem(json_obj, "obj_thresh");
|
||||
array_size = cJSON_GetArraySize(json_item);
|
||||
if (class_num != array_size) {
|
||||
printf("label number and thresh number mismatch! label number : %d, obj thresh number %d", class_num, array_size);
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("Got %d obj_thresh\n", array_size);
|
||||
}
|
||||
for (int i = 0; i < array_size; i++) {
|
||||
json_array_item = cJSON_GetArrayItem(json_item, i);
|
||||
obj_thresh[i] = json_array_item->valuedouble;
|
||||
printf("%d: %f\n", i, obj_thresh[i]);
|
||||
}
|
||||
// nms_thresh
|
||||
json_item = cJSON_GetObjectItem(json_obj, "nms_thresh");
|
||||
nms_thresh = json_item->valuedouble;
|
||||
printf("Got nms_thresh: %f\n", nms_thresh);
|
||||
|
||||
cJSON_Delete(json_obj);
|
||||
return;
|
||||
}
|
||||
|
||||
void instrusion_detect()
|
||||
{
|
||||
int ret = 0;
|
||||
int result = 0;
|
||||
int size = 0;
|
||||
param_parse();
|
||||
g_fd = open("/dev/ov2640", O_RDONLY);
|
||||
if (g_fd < 0) {
|
||||
printf("open ov2640 fail !!");
|
||||
return;
|
||||
}
|
||||
_ioctl_set_dvp_reso set_dvp_reso = {sensor_output_size[1], sensor_output_size[0]};
|
||||
ioctl(g_fd, IOCTRL_CAMERA_SET_DVP_RESO, &set_dvp_reso);
|
||||
showbuffer = (unsigned char *)malloc(sensor_output_size[0] * sensor_output_size[1] * 2);
|
||||
if (NULL == showbuffer) {
|
||||
close(g_fd);
|
||||
printf("showbuffer apply memory fail !!");
|
||||
return;
|
||||
}
|
||||
kpurgbbuffer = (unsigned char *)malloc(net_input_size[0] * net_input_size[1] * 3);
|
||||
if (NULL == kpurgbbuffer) {
|
||||
close(g_fd);
|
||||
free(showbuffer);
|
||||
printf("kpurgbbuffer apply memory fail !!");
|
||||
return;
|
||||
}
|
||||
model_data = (unsigned char *)malloc(kmodel_size + 255);
|
||||
if (NULL == model_data) {
|
||||
free(showbuffer);
|
||||
free(kpurgbbuffer);
|
||||
close(g_fd);
|
||||
printf("model_data apply memory fail !!");
|
||||
return;
|
||||
}
|
||||
memset(model_data, 0, kmodel_size + 255);
|
||||
memset(showbuffer, 0, sensor_output_size[0] * sensor_output_size[1] * 2);
|
||||
memset(kpurgbbuffer, 127, net_input_size[0] * net_input_size[1] * 3);
|
||||
shoot_para_t.pdata = (unsigned int *)(showbuffer);
|
||||
shoot_para_t.length = (size_t)(sensor_output_size[0] * sensor_output_size[1] * 2);
|
||||
/*
|
||||
load memory
|
||||
*/
|
||||
kmodel_fd = open(kmodel_path, O_RDONLY);
|
||||
if (kmodel_fd < 0) {
|
||||
printf("open kmodel fail");
|
||||
close(g_fd);
|
||||
free(showbuffer);
|
||||
free(kpurgbbuffer);
|
||||
free(model_data);
|
||||
return;
|
||||
} else {
|
||||
size = read(kmodel_fd, model_data, kmodel_size);
|
||||
if (size != kmodel_size) {
|
||||
printf("read kmodel error size %d\n", size);
|
||||
close(g_fd);
|
||||
close(kmodel_fd);
|
||||
free(showbuffer);
|
||||
free(kpurgbbuffer);
|
||||
free(model_data);
|
||||
return;
|
||||
|
||||
} else {
|
||||
printf("read kmodel success \n");
|
||||
}
|
||||
}
|
||||
unsigned char *model_data_align = (unsigned char *)(((unsigned int)model_data + 255) & (~255));
|
||||
dvp_set_ai_addr((uint32_t)(kpurgbbuffer + net_input_size[1] * (net_input_size[0] - sensor_output_size[0])),
|
||||
(uint32_t)(kpurgbbuffer + net_input_size[1] * (net_input_size[0] - sensor_output_size[0]) +
|
||||
net_input_size[0] * net_input_size[1]),
|
||||
(uint32_t)(kpurgbbuffer + net_input_size[0] * net_input_size[1] * 2 +
|
||||
net_input_size[1] * (net_input_size[0] - sensor_output_size[0])));
|
||||
if (kpu_load_kmodel(&instrusion_detect_task, model_data_align) != 0) {
|
||||
printf("\nmodel init error\n");
|
||||
close(g_fd);
|
||||
close(kmodel_fd);
|
||||
free(showbuffer);
|
||||
free(kpurgbbuffer);
|
||||
free(model_data);
|
||||
return;
|
||||
}
|
||||
instrusion_detect_rl.anchor_number = ANCHOR_NUM;
|
||||
instrusion_detect_rl.anchor = anchor;
|
||||
instrusion_detect_rl.threshold = malloc(class_num * sizeof(float));
|
||||
for (int idx = 0; idx < class_num; idx++) {
|
||||
instrusion_detect_rl.threshold[idx] = obj_thresh[idx];
|
||||
}
|
||||
instrusion_detect_rl.nms_value = nms_thresh;
|
||||
result = region_layer_init(&instrusion_detect_rl, net_output_shape[0], net_output_shape[1], net_output_shape[2],
|
||||
net_input_size[1], net_input_size[0]);
|
||||
printf("region_layer_init result %d \n\r", result);
|
||||
size_t stack_size = STACK_SIZE;
|
||||
pthread_attr_t attr; /* 线程属性 */
|
||||
struct sched_param prio; /* 线程优先级 */
|
||||
prio.sched_priority = 8; /* 优先级设置为 8 */
|
||||
pthread_attr_init(&attr); /* 先使用默认值初始化属性 */
|
||||
pthread_attr_setschedparam(&attr, &prio); /* 修改属性对应的优先级 */
|
||||
pthread_attr_setstacksize(&attr, stack_size);
|
||||
|
||||
/* 创建线程 1, 属性为 attr,入口函数是 thread_entry,入口函数参数是 1 */
|
||||
result = pthread_create(&instrusiontid, &attr, thread_instrusion_detect_entry, NULL);
|
||||
if (0 == result) {
|
||||
printf("thread_instrusion_detect_entry successfully!\n");
|
||||
} else {
|
||||
printf("thread_instrusion_detect_entry failed! error code is %d\n", result);
|
||||
close(g_fd);
|
||||
}
|
||||
}
|
||||
#ifdef __RT_THREAD_H__
|
||||
MSH_CMD_EXPORT(instrusion_detect, instrusion detect task);
|
||||
#endif
|
||||
|
||||
static void *thread_instrusion_detect_entry(void *parameter)
|
||||
{
|
||||
extern void lcd_draw_picture(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint32_t * ptr);
|
||||
printf("thread_instrusion_detect_entry start!\n");
|
||||
int ret = 0;
|
||||
// sysctl_enable_irq();
|
||||
while (1) {
|
||||
// memset(showbuffer,0,320*240*2);
|
||||
g_ai_done_flag = 0;
|
||||
ret = ioctl(g_fd, IOCTRL_CAMERA_START_SHOT, &shoot_para_t);
|
||||
if (RT_ERROR == ret) {
|
||||
printf("ov2640 can't wait event flag");
|
||||
rt_free(showbuffer);
|
||||
close(g_fd);
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
kpu_run_kmodel(&instrusion_detect_task, kpurgbbuffer, DMAC_CHANNEL5, ai_done, NULL);
|
||||
while (!g_ai_done_flag)
|
||||
;
|
||||
float *output;
|
||||
size_t output_size;
|
||||
kpu_get_output(&instrusion_detect_task, 0, (uint8_t **)&output, &output_size);
|
||||
instrusion_detect_rl.input = output;
|
||||
region_layer_run(&instrusion_detect_rl, &instrusion_detect_info);
|
||||
/* display result */
|
||||
#ifdef BSP_USING_LCD
|
||||
for (int instrusion_cnt = 0; instrusion_cnt < instrusion_detect_info.obj_number; instrusion_cnt++) {
|
||||
// draw_edge((uint32_t *)showbuffer, &instrusion_detect_info, instrusion_cnt, 0xF800,
|
||||
// (uint16_t)sensor_output_size[1],
|
||||
// (uint16_t)sensor_output_size[0]);
|
||||
printf("%d: (%d, %d, %d, %d) cls: %s conf: %f\t", instrusion_cnt, instrusion_detect_info.obj[instrusion_cnt].x1,
|
||||
instrusion_detect_info.obj[instrusion_cnt].y1, instrusion_detect_info.obj[instrusion_cnt].x2,
|
||||
instrusion_detect_info.obj[instrusion_cnt].y2, labels[instrusion_detect_info.obj[instrusion_cnt].class_id],
|
||||
instrusion_detect_info.obj[instrusion_cnt].prob);
|
||||
}
|
||||
if (0 != instrusion_detect_info.obj_number) {
|
||||
printf("\n");
|
||||
}
|
||||
lcd_draw_picture(0, 0, (uint16_t)sensor_output_size[1], (uint16_t)sensor_output_size[0], (unsigned int *)showbuffer);
|
||||
#endif
|
||||
usleep(1);
|
||||
if (1 == if_exit) {
|
||||
if_exit = 0;
|
||||
printf("thread_instrusion_detect_entry exit");
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void instrusion_detect_delete()
|
||||
{
|
||||
if (showbuffer != NULL) {
|
||||
int ret = 0;
|
||||
close(g_fd);
|
||||
close(kmodel_fd);
|
||||
free(showbuffer);
|
||||
free(kpurgbbuffer);
|
||||
free(model_data);
|
||||
printf("instrusion detect task cancel!!! ret %d ", ret);
|
||||
if_exit = 1;
|
||||
}
|
||||
}
|
||||
#ifdef __RT_THREAD_H__
|
||||
MSH_CMD_EXPORT(instrusion_detect_delete, instrusion detect task delete);
|
||||
#endif
|
||||
|
||||
void kmodel_load(unsigned char *model_data)
|
||||
{
|
||||
int kmodel_fd = 0;
|
||||
int size = 0;
|
||||
kmodel_fd = open(kmodel_path, O_RDONLY);
|
||||
|
||||
model_data = (unsigned char *)malloc(kmodel_size + 255);
|
||||
if (NULL == model_data) {
|
||||
printf("model_data apply memory fail !!");
|
||||
return;
|
||||
}
|
||||
memset(model_data, 0, kmodel_size + 255);
|
||||
|
||||
if (kmodel_fd >= 0) {
|
||||
size = read(kmodel_fd, model_data, kmodel_size);
|
||||
if (size != kmodel_size) {
|
||||
printf("read kmodel error size %d\n", size);
|
||||
|
||||
} else {
|
||||
printf("read kmodel success");
|
||||
}
|
||||
} else {
|
||||
free(model_data);
|
||||
printf("open kmodel fail");
|
||||
}
|
||||
}
|
||||
#ifdef __RT_THREAD_H__
|
||||
MSH_CMD_EXPORT(kmodel_load, kmodel load memory);
|
||||
#endif
|
|
@ -0,0 +1,57 @@
|
|||
#include <stdarg.h>
|
||||
|
||||
/**
|
||||
* Predict class for features vector
|
||||
*/
|
||||
int predict(float *x)
|
||||
{
|
||||
if (x[2] <= 2.449999988079071) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
else {
|
||||
if (x[3] <= 1.75) {
|
||||
if (x[2] <= 4.950000047683716) {
|
||||
if (x[3] <= 1.6500000357627869) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
else {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
if (x[3] <= 1.550000011920929) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
else {
|
||||
if (x[2] <= 5.450000047683716) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
else {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
if (x[2] <= 4.8500001430511475) {
|
||||
if (x[1] <= 3.100000023841858) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
config IRIS_ML_DEMO
|
||||
bool "enable apps/iris ml demo"
|
||||
default n
|
|
@ -0,0 +1,41 @@
|
|||
#include <stdarg.h>
|
||||
|
||||
/**
|
||||
* Compute dot product
|
||||
*/
|
||||
float dot(float *x, ...)
|
||||
{
|
||||
va_list w;
|
||||
va_start(w, 4);
|
||||
float dot = 0.0;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
const float wi = va_arg(w, double);
|
||||
dot += x[i] * wi;
|
||||
}
|
||||
|
||||
return dot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Predict class for features vector
|
||||
*/
|
||||
int predict(float *x)
|
||||
{
|
||||
float votes[3] = {0.0f};
|
||||
votes[0] = dot(x, -0.423405592418, 0.967388282125, -2.517050233286, -1.079182996654) + 9.84868307535428;
|
||||
votes[1] = dot(x, 0.534517184386, -0.321908835083, -0.206465997471, -0.944448257908) + 2.238120068472271;
|
||||
votes[2] = dot(x, -0.111111591968, -0.645479447042, 2.723516230758, 2.023631254562) + -12.086803143826813;
|
||||
// return argmax of votes
|
||||
int classIdx = 0;
|
||||
float maxVotes = votes[0];
|
||||
|
||||
for (int i = 1; i < 3; i++) {
|
||||
if (votes[i] > maxVotes) {
|
||||
classIdx = i;
|
||||
maxVotes = votes[i];
|
||||
}
|
||||
}
|
||||
|
||||
return classIdx;
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
# Machine learning demo using iris dataset
|
||||
|
||||
### Classification task demo, tested on stm32f4 and k210-based edge devices. Training on iris dataset by *Decision Tree classifier*, *Support Vector Machine classifier* and *Logistic Regression classifier*.
|
||||
|
||||
---
|
||||
|
||||
## Training
|
||||
|
||||
Model generated by [Sklearn](https://scikit-learn.org/stable/) and converted to C language by [micromlgen](https://forgeplus.trustie.net/projects/yangtuo250/micromlgen).
|
||||
|
||||
### Enviroment preparation
|
||||
|
||||
```shell
|
||||
pip install scikit-learn
|
||||
git clone https://git.trustie.net/yangtuo250/micromlgen.git -b C
|
||||
cd micromlgen && pip install -e .
|
||||
```
|
||||
|
||||
### Train it!
|
||||
|
||||
```python
|
||||
# load iris dataset
|
||||
from sklearn.datasets import load_iris
|
||||
X, y = load_iris(return_X_y=True)
|
||||
|
||||
# train SVC classifier and convert
|
||||
clf = SVC(kernel='linear', gamma=0.001).fit(X, y)
|
||||
print(port(clf, cplusplus=False, platform=platforms.STM32F4))
|
||||
|
||||
# train logistic regression classifier and convert
|
||||
clf = LogisticRegression(max_iter=1000).fit(X, y)
|
||||
print(port(clf, cplusplus=False, platform=platforms.STM32F4))
|
||||
|
||||
# train decision tree classifier and convert
|
||||
clf = DecisionTreeClassifier().fit(X, y)
|
||||
print(port(clf, cplusplus=False, platform=platforms.STM32F4)
|
||||
```
|
||||
Copy each content generated by print to a single C language file.
|
||||
|
||||
---
|
||||
|
||||
## Deployment
|
||||
|
||||
### compile and burn
|
||||
|
||||
Use `(scons --)menuconfig` in *bsp folder(Ubiquitous/RT_Thread/bsp/k210(or stm32f407-atk-coreboard))*, open **APP_Framwork --> Applications --> knowing app --> enable apps/iris ml demo** to enable this app. `scons -j(n)` to compile and burn in by *st-flash(for ARM)* or *kflash(for k210)*.
|
||||
|
||||
### testing set
|
||||
|
||||
Copy *iris.csv* to SD card */csv/iris.csv*.
|
||||
|
||||
---
|
||||
|
||||
## Run
|
||||
|
||||
In serial terminal:
|
||||
- `iris_SVC_predict` for SVC prediction
|
||||
- `iris_DecisonTree_predict` for decision tree prediction
|
||||
- `iris_LogisticRegression_predict` for logistic regression prediction
|
||||
|
||||
Example output:
|
||||
|
||||
```shell
|
||||
data 1: 5.1000 3.5000 1.4000 0.2000 result: 0
|
||||
data 2: 6.4000 3.2000 4.5000 1.5000 result: 1
|
||||
data 3: 5.8000 2.7000 5.1000 1.9000 result: 2
|
||||
data 4: 7.7000 3.8000 6.7000 2.2000 result: 2
|
||||
data 5: 5.5000 2.6000 4.4000 1.2000 result: 1
|
||||
data 6: 5.1000 3.8000 1.9000 0.4000 result: 0
|
||||
data 7: 5.8000 2.7000 3.9000 1.2000 result: 1
|
||||
```
|
|
@ -0,0 +1,9 @@
|
|||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = Glob('*.c') + Glob('*.cpp')
|
||||
CPPPATH = [cwd]
|
||||
|
||||
group = DefineGroup('Applications', src, depend = ['IRIS_ML_DEMO'], LOCAL_CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
* SVC model trained by iris dataset
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
|
||||
/**
|
||||
* Compute kernel between feature vector and support vector.
|
||||
* Kernel type: linear
|
||||
*/
|
||||
float compute_kernel(float *x, ...)
|
||||
{
|
||||
va_list w;
|
||||
va_start(w, 4);
|
||||
float kernel = 0.0;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
kernel += x[i] * va_arg(w, double);
|
||||
}
|
||||
|
||||
return kernel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Predict class for features vector
|
||||
*/
|
||||
int predict(float *x)
|
||||
{
|
||||
float kernels[27] = {0};
|
||||
float decisions[3] = {0};
|
||||
int votes[3] = {0};
|
||||
kernels[0] = compute_kernel(x, 5.1, 3.3, 1.7, 0.5);
|
||||
kernels[1] = compute_kernel(x, 4.8, 3.4, 1.9, 0.2);
|
||||
kernels[2] = compute_kernel(x, 4.5, 2.3, 1.3, 0.3);
|
||||
kernels[3] = compute_kernel(x, 6.9, 3.1, 4.9, 1.5);
|
||||
kernels[4] = compute_kernel(x, 6.3, 3.3, 4.7, 1.6);
|
||||
kernels[5] = compute_kernel(x, 6.1, 2.9, 4.7, 1.4);
|
||||
kernels[6] = compute_kernel(x, 5.6, 3.0, 4.5, 1.5);
|
||||
kernels[7] = compute_kernel(x, 6.2, 2.2, 4.5, 1.5);
|
||||
kernels[8] = compute_kernel(x, 5.9, 3.2, 4.8, 1.8);
|
||||
kernels[9] = compute_kernel(x, 6.3, 2.5, 4.9, 1.5);
|
||||
kernels[10] = compute_kernel(x, 6.8, 2.8, 4.8, 1.4);
|
||||
kernels[11] = compute_kernel(x, 6.7, 3.0, 5.0, 1.7);
|
||||
kernels[12] = compute_kernel(x, 6.0, 2.7, 5.1, 1.6);
|
||||
kernels[13] = compute_kernel(x, 5.4, 3.0, 4.5, 1.5);
|
||||
kernels[14] = compute_kernel(x, 5.1, 2.5, 3.0, 1.1);
|
||||
kernels[15] = compute_kernel(x, 4.9, 2.5, 4.5, 1.7);
|
||||
kernels[16] = compute_kernel(x, 6.5, 3.2, 5.1, 2.0);
|
||||
kernels[17] = compute_kernel(x, 6.0, 2.2, 5.0, 1.5);
|
||||
kernels[18] = compute_kernel(x, 6.3, 2.7, 4.9, 1.8);
|
||||
kernels[19] = compute_kernel(x, 6.2, 2.8, 4.8, 1.8);
|
||||
kernels[20] = compute_kernel(x, 6.1, 3.0, 4.9, 1.8);
|
||||
kernels[21] = compute_kernel(x, 7.2, 3.0, 5.8, 1.6);
|
||||
kernels[22] = compute_kernel(x, 6.3, 2.8, 5.1, 1.5);
|
||||
kernels[23] = compute_kernel(x, 6.0, 3.0, 4.8, 1.8);
|
||||
kernels[24] = compute_kernel(x, 6.3, 2.5, 5.0, 1.9);
|
||||
kernels[25] = compute_kernel(x, 6.5, 3.0, 5.2, 2.0);
|
||||
kernels[26] = compute_kernel(x, 5.9, 3.0, 5.1, 1.8);
|
||||
decisions[0] = 1.452844496978 + kernels[0] * 0.67075289031 + kernels[2] * 0.077097563476 + kernels[14] * -0.747850453786;
|
||||
decisions[1] = 1.507713125178 + kernels[0] * 0.043820415076 + kernels[1] * 0.159872086718 + kernels[15] * -0.203692501794;
|
||||
decisions[2] = 6.78097118511 + kernels[3] + kernels[4] + kernels[5] + kernels[6] + kernels[7] + kernels[8] + kernels[9] +
|
||||
kernels[10] * 0.243261886421 + kernels[11] + kernels[12] + kernels[13] - kernels[15] - kernels[16] -
|
||||
kernels[17] - kernels[18] - kernels[19] - kernels[20] + kernels[21] * -0.437859817863 - kernels[22] -
|
||||
kernels[23] + kernels[24] * -0.645105347981 + kernels[25] * -0.160296720576 - kernels[26];
|
||||
votes[decisions[0] > 0 ? 0 : 1] += 1;
|
||||
votes[decisions[1] > 0 ? 0 : 2] += 1;
|
||||
votes[decisions[2] > 0 ? 1 : 2] += 1;
|
||||
int val = votes[0];
|
||||
int idx = 0;
|
||||
|
||||
for (int i = 1; i < 3; i++) {
|
||||
if (votes[i] > val) {
|
||||
val = votes[i];
|
||||
idx = i;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
5.1,3.5,1.4,0.2
|
||||
6.4,3.2,4.5,1.5
|
||||
5.8,2.7,5.1,1.9
|
||||
7.7,3.8,6.7,2.2
|
||||
5.5,2.6,4.4,1.2
|
||||
5.1,3.8,1.9,0.4
|
||||
5.8,2.7,3.9,1.2
|
|
|
@ -0,0 +1,98 @@
|
|||
#include <string.h>
|
||||
#include <transform.h>
|
||||
|
||||
#define FEATURE_NUM 4
|
||||
#define CSV_PATH "/csv/iris.csv"
|
||||
#define CSV_BUFFER_SIZE (1 * 1024)
|
||||
|
||||
static float data[10][FEATURE_NUM] = {};
|
||||
static int data_len = 0;
|
||||
|
||||
void simple_CSV_read()
|
||||
{
|
||||
int fin;
|
||||
int col = 0;
|
||||
char buffer[CSV_BUFFER_SIZE] = "";
|
||||
char *tmp = "";
|
||||
char *delim = ",\n ";
|
||||
|
||||
fin = open(CSV_PATH, O_RDONLY);
|
||||
if (!fin) {
|
||||
printf("Error open file %s", CSV_PATH);
|
||||
exit(-1);
|
||||
}
|
||||
read(fin, buffer, sizeof(buffer));
|
||||
close(fin);
|
||||
|
||||
data_len = 0;
|
||||
for (tmp = strtok(buffer, delim); tmp && *tmp; col++, tmp = strtok(NULL, delim)) {
|
||||
if (0 == col % FEATURE_NUM) {
|
||||
// printf("\n");
|
||||
data_len++;
|
||||
col = 0;
|
||||
}
|
||||
data[data_len - 1][col] = atof(tmp);
|
||||
// printf("%.4f ", data[data_len - 1][col]);
|
||||
}
|
||||
// printf("\n");
|
||||
}
|
||||
|
||||
void iris_SVC_predict()
|
||||
{
|
||||
#include "SVCModel.h"
|
||||
int result;
|
||||
|
||||
simple_CSV_read();
|
||||
|
||||
for (int i = 0; i < data_len; i++) {
|
||||
result = predict(data[i]);
|
||||
printf("data %d: ", i + 1);
|
||||
for (int j = 0; j < FEATURE_NUM; j++) {
|
||||
printf("%.4f ", data[i][j]);
|
||||
}
|
||||
printf("result: %d\n", result);
|
||||
}
|
||||
}
|
||||
#ifdef __RT_THREAD_H__
|
||||
MSH_CMD_EXPORT(iris_SVC_predict, iris predict by SVC);
|
||||
#endif
|
||||
|
||||
void iris_DecisonTree_predict()
|
||||
{
|
||||
#include "DecisionTreeClassifierModel.h"
|
||||
int result;
|
||||
|
||||
simple_CSV_read();
|
||||
|
||||
for (int i = 0; i < data_len; i++) {
|
||||
result = predict(data[i]);
|
||||
printf("data %d: ", i + 1);
|
||||
for (int j = 0; j < FEATURE_NUM; j++) {
|
||||
printf("%.4f ", data[i][j]);
|
||||
}
|
||||
printf("result: %d\n", result);
|
||||
}
|
||||
}
|
||||
#ifdef __RT_THREAD_H__
|
||||
MSH_CMD_EXPORT(iris_DecisonTree_predict, iris predict by decison tree classifier);
|
||||
#endif
|
||||
|
||||
void iris_LogisticRegression_predict()
|
||||
{
|
||||
#include "LogisticRegressionModel.h"
|
||||
int result;
|
||||
|
||||
simple_CSV_read();
|
||||
|
||||
for (int i = 0; i < data_len; i++) {
|
||||
result = predict(data[i]);
|
||||
printf("data %d: ", i + 1);
|
||||
for (int j = 0; j < FEATURE_NUM; j++) {
|
||||
printf("%.4f ", data[i][j]);
|
||||
}
|
||||
printf("result: %d\n", result);
|
||||
}
|
||||
}
|
||||
#ifdef __RT_THREAD_H__
|
||||
MSH_CMD_EXPORT(iris_LogisticRegression_predict, iris predict by logistic regression);
|
||||
#endif
|
|
@ -9,7 +9,7 @@ if ADD_XIUOS_FETURES
|
|||
|
||||
config ADAPTER_EC200T_PIN_DRIVER
|
||||
string "EC200T device pin driver path"
|
||||
default "/dev/pin"
|
||||
default "/dev/pin_dev"
|
||||
|
||||
config ADAPTER_EC200T_DRIVER_EXTUART
|
||||
bool "Using extra uart to support 4G"
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
|
||||
#include <adapter.h>
|
||||
#include <at_agent.h>
|
||||
|
||||
static void Ec200tPowerSet(void)
|
||||
{
|
||||
|
@ -50,8 +51,6 @@ static void Ec200tPowerSet(void)
|
|||
|
||||
static int Ec200tOpen(struct Adapter *adapter)
|
||||
{
|
||||
uint8_t ec200t_cmd[64];
|
||||
|
||||
/*step1: open ec200t serial port*/
|
||||
adapter->fd = PrivOpen(ADAPTER_EC200T_DRIVER, O_RDWR);
|
||||
if (adapter->fd < 0) {
|
||||
|
@ -59,43 +58,43 @@ static int Ec200tOpen(struct Adapter *adapter)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/*step2: serial write "+++", quit transparent mode*/
|
||||
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
||||
strcpy(ec200t_cmd, "+++");
|
||||
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
||||
/*step2: init AT agent*/
|
||||
if (!adapter->agent) {
|
||||
char *agent_name = "4G_uart_client";
|
||||
if (EOK != InitATAgent(agent_name, adapter->fd, 512)) {
|
||||
printf("at agent init failed !\n");
|
||||
return -1;
|
||||
}
|
||||
ATAgentType at_agent = GetATAgent(agent_name);
|
||||
|
||||
/*step3: serial write "AT+CCID", get SIM ID*/
|
||||
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
||||
strcpy(ec200t_cmd, "AT+CCID\r\n");
|
||||
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
||||
adapter->agent = at_agent;
|
||||
}
|
||||
|
||||
/*step3: serial write "+++", quit transparent mode*/
|
||||
ATOrderSend(adapter->agent, REPLY_TIME_OUT, NULL, "+++");
|
||||
|
||||
/*step4: serial write "AT+CCID", get SIM ID*/
|
||||
ATOrderSend(adapter->agent, REPLY_TIME_OUT, NULL, "AT+CCID\r\n");
|
||||
|
||||
PrivTaskDelay(2500);
|
||||
|
||||
/*step4: serial write "AT+CPIN?", check SIM status*/
|
||||
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
||||
strcpy(ec200t_cmd, "AT+CPIN?\r\n");
|
||||
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
||||
/*step5: serial write "AT+CPIN?", check SIM status*/
|
||||
ATOrderSend(adapter->agent, REPLY_TIME_OUT, NULL, "AT+CPIN?\r\n");
|
||||
|
||||
PrivTaskDelay(2500);
|
||||
|
||||
/*step5: serial write "AT+CREG?", check whether registered to GSM net*/
|
||||
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
||||
strcpy(ec200t_cmd, "AT+CREG?\r\n");
|
||||
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
||||
/*step6: serial write "AT+CREG?", check whether registered to GSM net*/
|
||||
ATOrderSend(adapter->agent, REPLY_TIME_OUT, NULL, "AT+CREG?\r\n");
|
||||
|
||||
PrivTaskDelay(2500);
|
||||
|
||||
/*step6: serial write "AT+QICLOSE", close socket connect before open socket*/
|
||||
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
||||
strcpy(ec200t_cmd, "AT+QICLOSE=0\r\n");
|
||||
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
||||
/*step7: serial write "AT+QICLOSE", close socket connect before open socket*/
|
||||
ATOrderSend(adapter->agent, REPLY_TIME_OUT, NULL, "AT+QICLOSE=0\r\n");
|
||||
|
||||
PrivTaskDelay(2500);
|
||||
|
||||
/*step7: serial write "AT+QIDEACT", close TCP net before open socket*/
|
||||
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
||||
strcpy(ec200t_cmd, "AT+QIDEACT=1\r\n");
|
||||
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
||||
/*step8: serial write "AT+QIDEACT", close TCP net before open socket*/
|
||||
ATOrderSend(adapter->agent, REPLY_TIME_OUT, NULL, "AT+QIDEACT=1\r\n");
|
||||
|
||||
PrivTaskDelay(2500);
|
||||
|
||||
|
@ -106,24 +105,21 @@ static int Ec200tOpen(struct Adapter *adapter)
|
|||
|
||||
static int Ec200tClose(struct Adapter *adapter)
|
||||
{
|
||||
uint8_t ec200t_cmd[64];
|
||||
if (!adapter->agent) {
|
||||
printf("Ec200tClose AT agent NULL\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*step1: serial write "+++", quit transparent mode*/
|
||||
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
||||
strcpy(ec200t_cmd, "+++");
|
||||
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
||||
ATOrderSend(adapter->agent, REPLY_TIME_OUT, NULL, "+++");
|
||||
|
||||
/*step2: serial write "AT+QICLOSE", close socket connect before open socket*/
|
||||
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
||||
strcpy(ec200t_cmd, "AT+QICLOSE=0\r\n");
|
||||
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
||||
ATOrderSend(adapter->agent, REPLY_TIME_OUT, NULL, "AT+QICLOSE=0\r\n");
|
||||
|
||||
PrivTaskDelay(2500);
|
||||
|
||||
/*step3: serial write "AT+QIDEACT", close TCP net before open socket*/
|
||||
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
||||
strcpy(ec200t_cmd, "AT+QIDEACT=1\r\n");
|
||||
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
||||
ATOrderSend(adapter->agent, REPLY_TIME_OUT, NULL, "AT+QIDEACT=1\r\n");
|
||||
|
||||
PrivTaskDelay(2500);
|
||||
|
||||
|
@ -167,7 +163,7 @@ static int Ec200tIoctl(struct Adapter *adapter, int cmd, void *args)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int Ec200tConnect(struct Adapter *adapter, const char *ip, const char *port, enum IpType ip_type)
|
||||
static int Ec200tConnect(struct Adapter *adapter, enum NetRoleType net_role, const char *ip, const char *port, enum IpType ip_type)
|
||||
{
|
||||
uint8_t ec200t_cmd[64];
|
||||
|
||||
|
@ -180,14 +176,12 @@ static int Ec200tConnect(struct Adapter *adapter, const char *ip, const char *po
|
|||
strcpy(ec200t_cmd, "AT+QICSGP=1,2,\"CMNET\",\"\",\"\",1\r\n");
|
||||
}
|
||||
|
||||
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
||||
ATOrderSend(adapter->agent, REPLY_TIME_OUT, NULL, ec200t_cmd);
|
||||
|
||||
PrivTaskDelay(2500);
|
||||
|
||||
/*step2: serial write "AT+QIACT", open TCP net*/
|
||||
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
||||
strcpy(ec200t_cmd, "AT+QIACT=1\r\n");
|
||||
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
||||
ATOrderSend(adapter->agent, REPLY_TIME_OUT, NULL, "AT+QIACT=1\r\n");
|
||||
|
||||
PrivTaskDelay(2500);
|
||||
|
||||
|
@ -200,7 +194,7 @@ static int Ec200tConnect(struct Adapter *adapter, const char *ip, const char *po
|
|||
strcat(ec200t_cmd, ",0,2\r\n");
|
||||
|
||||
ADAPTER_DEBUG("Ec200t connect AT CMD :%s\n", ec200t_cmd);
|
||||
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
||||
ATOrderSend(adapter->agent, REPLY_TIME_OUT, NULL, ec200t_cmd);
|
||||
|
||||
ADAPTER_DEBUG("Ec200t connect TCP done\n");
|
||||
|
||||
|
@ -224,14 +218,10 @@ static int Ec200tDisconnect(struct Adapter *adapter)
|
|||
uint8_t ec200t_cmd[64];
|
||||
|
||||
/*step1: serial write "+++", quit transparent mode*/
|
||||
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
||||
strcpy(ec200t_cmd, "+++");
|
||||
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
||||
ATOrderSend(adapter->agent, REPLY_TIME_OUT, NULL, "+++");
|
||||
|
||||
/*step2: serial write "AT+QICLOSE", close socket connect before open socket*/
|
||||
memset(ec200t_cmd, 0, sizeof(ec200t_cmd));
|
||||
strcpy(ec200t_cmd, "AT+QICLOSE=0\r\n");
|
||||
PrivWrite(adapter->fd, ec200t_cmd, strlen(ec200t_cmd));
|
||||
ATOrderSend(adapter->agent, REPLY_TIME_OUT, NULL, "AT+QICLOSE=0\r\n");
|
||||
|
||||
PrivTaskDelay(2500);
|
||||
|
||||
|
@ -245,6 +235,13 @@ static const struct IpProtocolDone ec200t_done =
|
|||
.open = Ec200tOpen,
|
||||
.close = Ec200tClose,
|
||||
.ioctl = Ec200tIoctl,
|
||||
.setup = NULL,
|
||||
.setdown = NULL,
|
||||
.setaddr = NULL,
|
||||
.setdns = NULL,
|
||||
.setdhcp = NULL,
|
||||
.ping = NULL,
|
||||
.netstat = NULL,
|
||||
.connect = Ec200tConnect,
|
||||
.send = Ec200tSend,
|
||||
.recv = Ec200tRecv,
|
||||
|
|
|
@ -51,7 +51,6 @@ int Adapter4GInit(void)
|
|||
|
||||
struct Adapter *adapter = malloc(sizeof(struct Adapter));
|
||||
if (!adapter) {
|
||||
printf("Adapter4GInit malloc error\n");
|
||||
free(adapter);
|
||||
return -1;
|
||||
}
|
||||
|
@ -80,11 +79,32 @@ int Adapter4GInit(void)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/******************TEST*********************/
|
||||
static int Adapter4GTest(void)
|
||||
/******************4G TEST*********************/
|
||||
int Adapter4GTest(void)
|
||||
{
|
||||
int ret = 0;
|
||||
const char *send_msg = "SendHeart";
|
||||
char recv_msg[128];
|
||||
int baud_rate = BAUD_RATE_115200;
|
||||
|
||||
struct Adapter* adapter = AdapterDeviceFindByName(ADAPTER_4G_NAME);
|
||||
|
||||
return ret;
|
||||
#ifdef ADAPTER_EC200T
|
||||
//Using DSD server to test 4G Socket connection
|
||||
uint8 server_addr[64] = "115.238.53.61";
|
||||
uint8 server_port[64] = "33333";
|
||||
|
||||
AdapterDeviceOpen(adapter);
|
||||
AdapterDeviceControl(adapter, OPE_INT, &baud_rate);
|
||||
|
||||
AdapterDeviceConnect(adapter, CLIENT, server_addr, server_port, IPV4);
|
||||
|
||||
while (1) {
|
||||
AdapterDeviceSend(adapter, send_msg, strlen(send_msg));
|
||||
AdapterDeviceRecv(adapter, recv_msg, 128);
|
||||
printf("4G recv msg %s\n", recv_msg);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0)|SHELL_CMD_DISABLE_RETURN, Adapter4GTest, Adapter4GTest, show adapter 4G information);
|
||||
|
|
|
@ -446,6 +446,11 @@ int AdapterDeviceDisconnect(struct Adapter *adapter)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Set up to net
|
||||
* @param adapter - adapter device pointer
|
||||
* @return success: 0 , failure: other
|
||||
*/
|
||||
int AdapterDeviceSetUp(struct Adapter *adapter)
|
||||
{
|
||||
if (!adapter)
|
||||
|
@ -501,6 +506,11 @@ int AdapterDeviceSetUp(struct Adapter *adapter)
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Set down from net
|
||||
* @param adapter - adapter device pointer
|
||||
* @return success: 0 , failure: other
|
||||
*/
|
||||
int AdapterDeviceSetDown(struct Adapter *adapter)
|
||||
{
|
||||
if (!adapter)
|
||||
|
@ -556,6 +566,14 @@ int AdapterDeviceSetDown(struct Adapter *adapter)
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Set ip/gateway/netmask address
|
||||
* @param adapter - adapter device pointer
|
||||
* @param ip - ip address
|
||||
* @param gateway - gateway address
|
||||
* @param netmast - netmast address
|
||||
* @return success: 0 , failure: other
|
||||
*/
|
||||
int AdapterDeviceSetAddr(struct Adapter *adapter, const char *ip, const char *gateway, const char *netmask)
|
||||
{
|
||||
if (!adapter)
|
||||
|
@ -611,6 +629,135 @@ int AdapterDeviceSetAddr(struct Adapter *adapter, const char *ip, const char *ga
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Set dns function
|
||||
* @param adapter - adapter device pointer
|
||||
* @param dns_addr - dns address
|
||||
* @param dns_count - dns count
|
||||
* @return success: 0 , failure: other
|
||||
*/
|
||||
int AdapterDeviceSetDns(struct Adapter *adapter, const char *dns_addr, uint8 dns_count)
|
||||
{
|
||||
if (!adapter)
|
||||
return -1;
|
||||
|
||||
int result = 0;
|
||||
|
||||
struct IpProtocolDone *ip_done = NULL;
|
||||
struct PrivProtocolDone *priv_done = NULL;
|
||||
|
||||
switch (adapter->net_protocol)
|
||||
{
|
||||
case PRIVATE_PROTOCOL:
|
||||
priv_done = (struct PrivProtocolDone *)adapter->done;
|
||||
if (NULL == priv_done->setdns)
|
||||
return 0;
|
||||
|
||||
result = priv_done->setdns(adapter, dns_addr, dns_count);
|
||||
if (0 == result) {
|
||||
printf("Device %s setdns success.\n", adapter->name);
|
||||
adapter->adapter_status = INSTALL;
|
||||
} else {
|
||||
if (adapter->fd) {
|
||||
PrivClose(adapter->fd);
|
||||
adapter->fd = 0;
|
||||
}
|
||||
printf("Device %s setdns failed(%d).\n", adapter->name, result);
|
||||
}
|
||||
break;
|
||||
|
||||
case IP_PROTOCOL:
|
||||
ip_done = (struct IpProtocolDone *)adapter->done;
|
||||
if (NULL == ip_done->setdns)
|
||||
return 0;
|
||||
|
||||
result = ip_done->setdns(adapter, dns_addr, dns_count);
|
||||
if (0 == result) {
|
||||
printf("Device %s setdns success.\n", adapter->name);
|
||||
adapter->adapter_status = INSTALL;
|
||||
} else {
|
||||
if (adapter->fd) {
|
||||
PrivClose(adapter->fd);
|
||||
adapter->fd = 0;
|
||||
}
|
||||
printf("Device %s setdns failed(%d).\n", adapter->name, result);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Set DHCP function
|
||||
* @param adapter - adapter device pointer
|
||||
* @param enable - enable DHCP or not
|
||||
* @return success: 0 , failure: other
|
||||
*/
|
||||
int AdapterDeviceSetDhcp(struct Adapter *adapter, int enable)
|
||||
{
|
||||
if (!adapter)
|
||||
return -1;
|
||||
|
||||
int result = 0;
|
||||
|
||||
struct IpProtocolDone *ip_done = NULL;
|
||||
struct PrivProtocolDone *priv_done = NULL;
|
||||
|
||||
switch (adapter->net_protocol)
|
||||
{
|
||||
case PRIVATE_PROTOCOL:
|
||||
priv_done = (struct PrivProtocolDone *)adapter->done;
|
||||
if (NULL == priv_done->setdhcp)
|
||||
return 0;
|
||||
|
||||
result = priv_done->setdhcp(adapter, enable);
|
||||
if (0 == result) {
|
||||
printf("Device %s setdhcp success.\n", adapter->name);
|
||||
adapter->adapter_status = INSTALL;
|
||||
} else {
|
||||
if (adapter->fd) {
|
||||
PrivClose(adapter->fd);
|
||||
adapter->fd = 0;
|
||||
}
|
||||
printf("Device %s setdhcp failed(%d).\n", adapter->name, result);
|
||||
}
|
||||
break;
|
||||
|
||||
case IP_PROTOCOL:
|
||||
ip_done = (struct IpProtocolDone *)adapter->done;
|
||||
if (NULL == ip_done->setdhcp)
|
||||
return 0;
|
||||
|
||||
result = ip_done->setdhcp(adapter, enable);
|
||||
if (0 == result) {
|
||||
printf("Device %s setdhcp success.\n", adapter->name);
|
||||
adapter->adapter_status = INSTALL;
|
||||
} else {
|
||||
if (adapter->fd) {
|
||||
PrivClose(adapter->fd);
|
||||
adapter->fd = 0;
|
||||
}
|
||||
printf("Device %s setdhcp failed(%d).\n", adapter->name, result);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: ping function
|
||||
* @param adapter - adapter device pointer
|
||||
* @param destination - the destination ip address
|
||||
* @return success: 0 , failure: other
|
||||
*/
|
||||
int AdapterDevicePing(struct Adapter *adapter, const char *destination)
|
||||
{
|
||||
if (!adapter)
|
||||
|
@ -666,6 +813,11 @@ int AdapterDevicePing(struct Adapter *adapter, const char *destination)
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Show the net status
|
||||
* @param adapter - adapter device pointer
|
||||
* @return success: 0 , failure: other
|
||||
*/
|
||||
int AdapterDeviceNetstat(struct Adapter *adapter)
|
||||
{
|
||||
if (!adapter)
|
||||
|
|
|
@ -59,8 +59,6 @@ struct AdapterProductInfo;
|
|||
typedef struct Adapter *AdapterType;
|
||||
typedef struct AdapterProductInfo *AdapterProductInfoType;
|
||||
|
||||
#define ADAPTER_WIFI_NAME "wifi"
|
||||
|
||||
struct Socket
|
||||
{
|
||||
int id;
|
||||
|
@ -90,6 +88,8 @@ enum NetRoleType
|
|||
{
|
||||
CLIENT = 1,
|
||||
SERVER,
|
||||
MASTER,
|
||||
SLAVE,
|
||||
ROLE_NONE,
|
||||
};
|
||||
|
||||
|
@ -210,12 +210,25 @@ int AdapterDeviceJoin(struct Adapter *adapter, const char *priv_net_group);
|
|||
/*Adapter disconnect from ip net or private net group*/
|
||||
int AdapterDeviceDisconnect(struct Adapter *adapter);
|
||||
|
||||
/*Set up to net*/
|
||||
int AdapterDeviceSetUp(struct Adapter *adapter);
|
||||
|
||||
/*Set down from net*/
|
||||
int AdapterDeviceSetDown(struct Adapter *adapter);
|
||||
|
||||
/*Set ip/gateway/netmask address*/
|
||||
int AdapterDeviceSetAddr(struct Adapter *adapter, const char *ip, const char *gateway, const char *netmask);
|
||||
|
||||
/**/
|
||||
int AdapterDeviceSetDns(struct Adapter *adapter, const char *dns_addr, uint8 dns_count);
|
||||
|
||||
/**/
|
||||
int AdapterDeviceSetDhcp(struct Adapter *adapter, int enable);
|
||||
|
||||
/*ping function*/
|
||||
int AdapterDevicePing(struct Adapter *adapter, const char *destination);
|
||||
|
||||
/*Show the net status*/
|
||||
int AdapterDeviceNetstat(struct Adapter *adapter);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
config ADAPTER_BLUETOOTH_HC08
|
||||
string "HC08 adapter name"
|
||||
default "hc08"
|
||||
|
||||
if ADD_XIUOS_FETURES
|
||||
config ADAPTER_HC08_DRIVER_EXTUART
|
||||
bool "Using extra uart to support bluetooth"
|
||||
default n
|
||||
|
||||
config ADAPTER_HC08_DRIVER
|
||||
string "HC08 device uart driver path"
|
||||
default "/dev/uart4_dev4"
|
||||
depends on !ADAPTER_HC08_DRIVER_EXTUART
|
||||
|
||||
if ADAPTER_HC08_DRIVER_EXTUART
|
||||
config ADAPTER_HC08_DRIVER
|
||||
string "HC08 device extra uart driver path"
|
||||
default "/dev/extuart_dev7"
|
||||
|
||||
config ADAPTER_HC08_DRIVER_EXT_PORT
|
||||
int "if HC08 device using extuart, choose port"
|
||||
default "7"
|
||||
endif
|
||||
endif
|
||||
|
||||
if ADD_NUTTX_FETURES
|
||||
|
||||
endif
|
||||
|
||||
if ADD_RTTHREAD_FETURES
|
||||
|
||||
endif
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := hc08.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file hc08.c
|
||||
* @brief Implement the connection Bluetooth adapter function, using HC08 device
|
||||
* @version 1.1
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.07.12
|
||||
*/
|
||||
|
||||
#include <adapter.h>
|
||||
#include <at_agent.h>
|
||||
|
||||
static int rx_sem;
|
||||
static sem_t *hc08_sem;
|
||||
static pthread_t hc08_recv_thread;
|
||||
|
||||
void Hc08RecvThreadEntry(void *parameter)
|
||||
{
|
||||
|
||||
while (1)
|
||||
{
|
||||
PrivRead(adapter->fd, buf, len);
|
||||
|
||||
UserSemaphoreAbandon(rx_sem);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static int Hc08Open(struct Adapter *adapter)
|
||||
{
|
||||
if (INSTALL == adapter->adapter_status) {
|
||||
printf("Hc08 has already been open\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*step1: open hc08 serial port*/
|
||||
adapter->fd = PrivOpen(ADAPTER_HC08_DRIVER, O_RDWR);
|
||||
if (adapter->fd < 0) {
|
||||
printf("Hc08Open get serial %s fd error\n", ADAPTER_HC08_DRIVER);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*step2: init AT agent*/
|
||||
if (!adapter->agent) {
|
||||
char *agent_name = "bluetooth_uart_client";
|
||||
if (EOK != InitATAgent(agent_name, adapter->fd, 512)) {
|
||||
printf("at agent init failed !\n");
|
||||
return -1;
|
||||
}
|
||||
ATAgentType at_agent = GetATAgent(agent_name);
|
||||
|
||||
adapter->agent = at_agent;
|
||||
}
|
||||
|
||||
/*step3: create bluetooth receive task*/
|
||||
PrivSemaphoreCreate(hc08_sem, 0, rx_sem);
|
||||
|
||||
PrivTaskCreate(&hc08_recv_thread, NULL, Hc08RecvThreadEntry, NULL);
|
||||
|
||||
ADAPTER_DEBUG("Hc08 open done\n");
|
||||
}
|
||||
|
||||
static int Hc08Close(struct Adapter *adapter)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Hc08Ioctl(struct Adapter *adapter, int cmd, void *args)
|
||||
{
|
||||
if (OPE_INT != cmd) {
|
||||
printf("Hc08Ioctl only support OPE_INT, do not support %d\n", cmd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t baud_rate = *((uint32_t *)args);
|
||||
|
||||
struct SerialDataCfg serial_cfg;
|
||||
memset(&serial_cfg, 0 ,sizeof(struct SerialDataCfg));
|
||||
serial_cfg.serial_baud_rate = baud_rate;
|
||||
serial_cfg.serial_data_bits = DATA_BITS_8;
|
||||
serial_cfg.serial_stop_bits = STOP_BITS_1;
|
||||
serial_cfg.serial_buffer_size = SERIAL_RB_BUFSZ;
|
||||
serial_cfg.serial_parity_mode = PARITY_NONE;
|
||||
serial_cfg.serial_bit_order = STOP_BITS_1;
|
||||
serial_cfg.serial_invert_mode = NRZ_NORMAL;
|
||||
#ifdef ADAPTER_HC08_DRIVER_EXT_PORT
|
||||
serial_cfg.ext_uart_no = ADAPTER_HC08_DRIVER_EXT_PORT;
|
||||
serial_cfg.port_configure = PORT_CFG_INIT;
|
||||
#endif
|
||||
|
||||
struct PrivIoctlCfg ioctl_cfg;
|
||||
ioctl_cfg.ioctl_driver_type = SERIAL_TYPE;
|
||||
ioctl_cfg.args = &serial_cfg;
|
||||
PrivIoctl(adapter->fd, OPE_INT, &ioctl_cfg);
|
||||
|
||||
ADAPTER_DEBUG("Hc08 ioctl done\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Hc08SetAddr(struct Adapter *adapter, const char *ip, const char *gateway, const char *netmask)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static int Hc08Connect(struct Adapter *adapter, enum NetRoleType net_role, const char *ip, const char *port, enum IpType ip_type)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static int Hc08Send(struct Adapter *adapter, const void *buf, size_t len)
|
||||
{
|
||||
PrivWrite(adapter->fd, buf, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Hc08Recv(struct Adapter *adapter, void *buf, size_t len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Hc08Disconnect(struct Adapter *adapter)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static const struct IpProtocolDone hc08_done =
|
||||
{
|
||||
.open = Hc08Open,
|
||||
.close = Hc08Close,
|
||||
.ioctl = Hc08Ioctl,
|
||||
.setup = NULL,
|
||||
.setdown = NULL,
|
||||
.setaddr = Hc08SetAddr,
|
||||
.setdns = NULL,
|
||||
.setdhcp = NULL,
|
||||
.ping = NULL,
|
||||
.netstat = NULL,
|
||||
.connect = Hc08Connect,
|
||||
.send = Hc08Send,
|
||||
.recv = Hc08Recv,
|
||||
.disconnect = Hc08Disconnect,
|
||||
};
|
||||
|
||||
AdapterProductInfoType Hc08Attach(struct Adapter *adapter)
|
||||
{
|
||||
struct AdapterProductInfo *product_info = malloc(sizeof(struct AdapterProductInfo));
|
||||
if (!product_info) {
|
||||
printf("Hc08Attach malloc product_info error\n");
|
||||
free(product_info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
product_info->model_name = ADAPTER_BLUETOOTH_HC08;
|
||||
|
||||
product_info->model_done = (void *)&hc08_done;
|
||||
|
||||
return product_info;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
config ADAPTER_BLUETOOTH
|
||||
bool "Using bluetooth adapter function"
|
||||
default y
|
||||
|
||||
if ADAPTER_BLUETOOTH
|
||||
config ADAPTER_HC08
|
||||
bool "Using bluetooth adapter device HC08"
|
||||
default y
|
||||
|
||||
if ADAPTER_HC08
|
||||
source "$APP_DIR/Framework/connection/bluetooth/HC08/Kconfig"
|
||||
endif
|
||||
|
||||
endif
|
|
@ -1,3 +1,7 @@
|
|||
SRC_FILES := adapter_bluetooth.c
|
||||
|
||||
ifeq ($(CONFIG_ADAPTER_HC08),y)
|
||||
SRC_DIR += HC08
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
|
@ -48,8 +48,6 @@ static int Hfa21InitAtCmd(ATAgentType at_agent)
|
|||
*/
|
||||
static int Hfa21Open(struct Adapter *adapter)
|
||||
{
|
||||
uint8_t hfa21_cmd[64];
|
||||
|
||||
/*step1: open ec200t serial port*/
|
||||
adapter->fd = PrivOpen(ADAPTER_HFA21_DRIVER, O_RDWR);
|
||||
if (adapter->fd < 0) {
|
||||
|
@ -58,14 +56,16 @@ static int Hfa21Open(struct Adapter *adapter)
|
|||
}
|
||||
|
||||
/*step2: init AT agent*/
|
||||
char *agent_name = "uart3_client";
|
||||
if (InitATAgent(agent_name, adapter->fd, 512)) {
|
||||
printf("at agent init failed !\n");
|
||||
return -1;
|
||||
}
|
||||
ATAgentType at_agent = GetATAgent(agent_name);
|
||||
if (!adapter->agent) {
|
||||
char *agent_name = "wifi_uart_client";
|
||||
if (EOK != InitATAgent(agent_name, adapter->fd, 512)) {
|
||||
printf("at agent init failed !\n");
|
||||
return -1;
|
||||
}
|
||||
ATAgentType at_agent = GetATAgent(agent_name);
|
||||
|
||||
adapter->agent = at_agent;
|
||||
adapter->agent = at_agent;
|
||||
}
|
||||
|
||||
ADAPTER_DEBUG("Hfa21 open done\n");
|
||||
|
||||
|
@ -195,7 +195,7 @@ static int Hfa21SetDown(struct Adapter *adapter)
|
|||
}
|
||||
|
||||
/**
|
||||
* @description: set wifi ip/gatewy/netmask address(in sta mode)
|
||||
* @description: set wifi ip/gateway/netmask address(in sta mode)
|
||||
* @param adapter - wifi device pointer
|
||||
* @param ip - ip address
|
||||
* @param gateway - gateway address
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
extern AdapterProductInfoType Hfa21Attach(struct Adapter *adapter);
|
||||
#endif
|
||||
|
||||
#define ADAPTER_WIFI_NAME "wifi"
|
||||
|
||||
static int AdapterWifiRegister(struct Adapter *adapter)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -151,15 +153,13 @@ int AdapterWifiTest(void)
|
|||
|
||||
const char *wifi_msg = "LiuKai Test";
|
||||
int len = strlen(wifi_msg);
|
||||
for(int i=0;i<10;++i)
|
||||
{
|
||||
for(int i = 0;i < 10; ++i) {
|
||||
AdapterDeviceSend(adapter, wifi_msg, len);
|
||||
PrivTaskDelay(4000);
|
||||
}
|
||||
|
||||
char wifi_recv_msg[128];
|
||||
while (1)
|
||||
{
|
||||
while (1) {
|
||||
AdapterDeviceRecv(adapter, wifi_recv_msg, 128);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
# KPU(K210) YOLOv2 region layer
|
||||
|
||||
## Introduction
|
||||
|
||||
KPU(k210) accelerate most of CNN network layers, but do not support some of operators of YOLOv2 region layer. Such layers and operators will run on MCU instead.
|
||||
YOLOv2 region layer accept feature map(shape w\*h\*c) and return final detection boxes.
|
||||
|
||||
## Usage
|
||||
|
||||
Use `(scons --)menuconfig` in bsp folder *(Ubiquitous/RT_Thread/bsp/k210)*, open *APP_Framework --> Framework --> support knowing framework --> kpu model postprocessing --> yolov2 region layer*.
|
|
@ -1,31 +1,33 @@
|
|||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include "region_layer.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct {
|
||||
float x;
|
||||
float y;
|
||||
float w;
|
||||
float h;
|
||||
} box_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
int index;
|
||||
int class;
|
||||
float **probs;
|
||||
} sortable_box_t;
|
||||
|
||||
|
||||
int region_layer_init(region_layer_t *rl, int width, int height, int channels, int origin_width, int origin_height)
|
||||
{
|
||||
int flag = 0;
|
||||
|
||||
rl->coords = 4;
|
||||
rl->image_width = 320;
|
||||
rl->image_height = 240;
|
||||
/* As no more parameter adding to this function,
|
||||
image width(height) is regarded as net input shape as well as image capture from sensor.
|
||||
If net input did not match sensor input, `dvp_set_image_size` function can set sensor output shape.
|
||||
*/
|
||||
rl->image_width = origin_width;
|
||||
rl->image_height = origin_height;
|
||||
|
||||
rl->classes = channels / 5 - 5;
|
||||
rl->net_width = origin_width;
|
||||
|
@ -36,31 +38,26 @@ int region_layer_init(region_layer_t *rl, int width, int height, int channels, i
|
|||
rl->output_number = (rl->boxes_number * (rl->classes + rl->coords + 1));
|
||||
|
||||
rl->output = malloc(rl->output_number * sizeof(float));
|
||||
if (rl->output == NULL)
|
||||
{
|
||||
if (rl->output == NULL) {
|
||||
flag = -1;
|
||||
goto malloc_error;
|
||||
}
|
||||
rl->boxes = malloc(rl->boxes_number * sizeof(box_t));
|
||||
if (rl->boxes == NULL)
|
||||
{
|
||||
if (rl->boxes == NULL) {
|
||||
flag = -2;
|
||||
goto malloc_error;
|
||||
}
|
||||
rl->probs_buf = malloc(rl->boxes_number * (rl->classes + 1) * sizeof(float));
|
||||
if (rl->probs_buf == NULL)
|
||||
{
|
||||
if (rl->probs_buf == NULL) {
|
||||
flag = -3;
|
||||
goto malloc_error;
|
||||
}
|
||||
rl->probs = malloc(rl->boxes_number * sizeof(float *));
|
||||
if (rl->probs == NULL)
|
||||
{
|
||||
if (rl->probs == NULL) {
|
||||
flag = -4;
|
||||
goto malloc_error;
|
||||
}
|
||||
for (uint32_t i = 0; i < rl->boxes_number; i++)
|
||||
rl->probs[i] = &(rl->probs_buf[i * (rl->classes + 1)]);
|
||||
for (uint32_t i = 0; i < rl->boxes_number; i++) rl->probs[i] = &(rl->probs_buf[i * (rl->classes + 1)]);
|
||||
return 0;
|
||||
malloc_error:
|
||||
free(rl->output);
|
||||
|
@ -78,24 +75,20 @@ void region_layer_deinit(region_layer_t *rl)
|
|||
free(rl->probs);
|
||||
}
|
||||
|
||||
static inline float sigmoid(float x)
|
||||
{
|
||||
return 1.f / (1.f + expf(-x));
|
||||
}
|
||||
static inline float sigmoid(float x) { return 1.f / (1.f + expf(-x)); }
|
||||
|
||||
static void activate_array(region_layer_t *rl, int index, int n)
|
||||
{
|
||||
float *output = &rl->output[index];
|
||||
float *input = &rl->input[index];
|
||||
|
||||
for (int i = 0; i < n; ++i)
|
||||
output[i] = sigmoid(input[i]);
|
||||
for (int i = 0; i < n; ++i) output[i] = sigmoid(input[i]);
|
||||
}
|
||||
|
||||
static int entry_index(region_layer_t *rl, int location, int entry)
|
||||
{
|
||||
int wh = rl->layer_width * rl->layer_height;
|
||||
int n = location / wh;
|
||||
int n = location / wh;
|
||||
int loc = location % wh;
|
||||
|
||||
return n * wh * (rl->coords + rl->classes + 1) + entry * wh + loc;
|
||||
|
@ -109,10 +102,8 @@ static void softmax(region_layer_t *rl, float *input, int n, int stride, float *
|
|||
float sum = 0;
|
||||
float largest_i = input[0];
|
||||
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
if (input[i * stride] > largest_i)
|
||||
largest_i = input[i * stride];
|
||||
for (i = 0; i < n; ++i) {
|
||||
if (input[i * stride] > largest_i) largest_i = input[i * stride];
|
||||
}
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
|
@ -121,17 +112,16 @@ static void softmax(region_layer_t *rl, float *input, int n, int stride, float *
|
|||
sum += e;
|
||||
output[i * stride] = e;
|
||||
}
|
||||
for (i = 0; i < n; ++i)
|
||||
output[i * stride] /= sum;
|
||||
for (i = 0; i < n; ++i) output[i * stride] /= sum;
|
||||
}
|
||||
|
||||
static void softmax_cpu(region_layer_t *rl, float *input, int n, int batch, int batch_offset, int groups, int stride, float *output)
|
||||
static void softmax_cpu(region_layer_t *rl, float *input, int n, int batch, int batch_offset, int groups, int stride,
|
||||
float *output)
|
||||
{
|
||||
int g, b;
|
||||
|
||||
for (b = 0; b < batch; ++b) {
|
||||
for (g = 0; g < groups; ++g)
|
||||
softmax(rl, input + b * batch_offset + g, n, stride, output + b * batch_offset + g);
|
||||
for (g = 0; g < groups; ++g) softmax(rl, input + b * batch_offset + g, n, stride, output + b * batch_offset + g);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,11 +129,9 @@ static void forward_region_layer(region_layer_t *rl)
|
|||
{
|
||||
int index;
|
||||
|
||||
for (index = 0; index < rl->output_number; index++)
|
||||
rl->output[index] = rl->input[index];
|
||||
for (index = 0; index < rl->output_number; index++) rl->output[index] = rl->input[index];
|
||||
|
||||
for (int n = 0; n < rl->anchor_number; ++n)
|
||||
{
|
||||
for (int n = 0; n < rl->anchor_number; ++n) {
|
||||
index = entry_index(rl, n * rl->layer_width * rl->layer_height, 0);
|
||||
activate_array(rl, index, 2 * rl->layer_width * rl->layer_height);
|
||||
index = entry_index(rl, n * rl->layer_width * rl->layer_height, 4);
|
||||
|
@ -151,9 +139,8 @@ static void forward_region_layer(region_layer_t *rl)
|
|||
}
|
||||
|
||||
index = entry_index(rl, 0, rl->coords + 1);
|
||||
softmax_cpu(rl, rl->input + index, rl->classes, rl->anchor_number,
|
||||
rl->output_number / rl->anchor_number, rl->layer_width * rl->layer_height,
|
||||
rl->layer_width * rl->layer_height, rl->output + index);
|
||||
softmax_cpu(rl, rl->input + index, rl->classes, rl->anchor_number, rl->output_number / rl->anchor_number,
|
||||
rl->layer_width * rl->layer_height, rl->layer_width * rl->layer_height, rl->output + index);
|
||||
}
|
||||
|
||||
static void correct_region_boxes(region_layer_t *rl, box_t *boxes)
|
||||
|
@ -166,8 +153,7 @@ static void correct_region_boxes(region_layer_t *rl, box_t *boxes)
|
|||
int new_w = 0;
|
||||
int new_h = 0;
|
||||
|
||||
if (((float)net_width / image_width) <
|
||||
((float)net_height / image_height)) {
|
||||
if (((float)net_width / image_width) < ((float)net_height / image_height)) {
|
||||
new_w = net_width;
|
||||
new_h = (image_height * net_width) / image_width;
|
||||
} else {
|
||||
|
@ -177,10 +163,8 @@ static void correct_region_boxes(region_layer_t *rl, box_t *boxes)
|
|||
for (int i = 0; i < boxes_number; ++i) {
|
||||
box_t b = boxes[i];
|
||||
|
||||
b.x = (b.x - (net_width - new_w) / 2. / net_width) /
|
||||
((float)new_w / net_width);
|
||||
b.y = (b.y - (net_height - new_h) / 2. / net_height) /
|
||||
((float)new_h / net_height);
|
||||
b.x = (b.x - (net_width - new_w) / 2. / net_width) / ((float)new_w / net_width);
|
||||
b.y = (b.y - (net_height - new_h) / 2. / net_height) / ((float)new_h / net_height);
|
||||
b.w *= (float)net_width / new_w;
|
||||
b.h *= (float)net_height / new_h;
|
||||
boxes[i] = b;
|
||||
|
@ -205,36 +189,31 @@ static void get_region_boxes(region_layer_t *rl, float *predictions, float **pro
|
|||
uint32_t anchor_number = rl->anchor_number;
|
||||
uint32_t classes = rl->classes;
|
||||
uint32_t coords = rl->coords;
|
||||
float threshold = rl->threshold;
|
||||
float *threshold = rl->threshold;
|
||||
|
||||
for (int i = 0; i < layer_width * layer_height; ++i)
|
||||
{
|
||||
for (int i = 0; i < layer_width * layer_height; ++i) {
|
||||
int row = i / layer_width;
|
||||
int col = i % layer_width;
|
||||
|
||||
for (int n = 0; n < anchor_number; ++n)
|
||||
{
|
||||
for (int n = 0; n < anchor_number; ++n) {
|
||||
int index = n * layer_width * layer_height + i;
|
||||
|
||||
for (int j = 0; j < classes; ++j)
|
||||
probs[index][j] = 0;
|
||||
for (int j = 0; j < classes; ++j) probs[index][j] = 0;
|
||||
int obj_index = entry_index(rl, n * layer_width * layer_height + i, coords);
|
||||
int box_index = entry_index(rl, n * layer_width * layer_height + i, 0);
|
||||
float scale = predictions[obj_index];
|
||||
float scale = predictions[obj_index];
|
||||
|
||||
boxes[index] = get_region_box(predictions, rl->anchor, n, box_index, col, row,
|
||||
layer_width, layer_height, layer_width * layer_height);
|
||||
boxes[index] = get_region_box(predictions, rl->anchor, n, box_index, col, row, layer_width, layer_height,
|
||||
layer_width * layer_height);
|
||||
|
||||
float max = 0;
|
||||
|
||||
for (int j = 0; j < classes; ++j)
|
||||
{
|
||||
for (int j = 0; j < classes; ++j) {
|
||||
int class_index = entry_index(rl, n * layer_width * layer_height + i, coords + 1 + j);
|
||||
float prob = scale * predictions[class_index];
|
||||
|
||||
probs[index][j] = (prob > threshold) ? prob : 0;
|
||||
if (prob > max)
|
||||
max = prob;
|
||||
probs[index][j] = (prob > threshold[j]) ? prob : 0;
|
||||
if (prob > max) max = prob;
|
||||
}
|
||||
probs[index][classes] = max;
|
||||
}
|
||||
|
@ -257,11 +236,11 @@ static int nms_comparator(void *pa, void *pb)
|
|||
|
||||
static float overlap(float x1, float w1, float x2, float w2)
|
||||
{
|
||||
float l1 = x1 - w1/2;
|
||||
float l2 = x2 - w2/2;
|
||||
float l1 = x1 - w1 / 2;
|
||||
float l2 = x2 - w2 / 2;
|
||||
float left = l1 > l2 ? l1 : l2;
|
||||
float r1 = x1 + w1/2;
|
||||
float r2 = x2 + w2/2;
|
||||
float r1 = x1 + w1 / 2;
|
||||
float r2 = x2 + w2 / 2;
|
||||
float right = r1 < r2 ? r1 : r2;
|
||||
|
||||
return right - left;
|
||||
|
@ -272,8 +251,7 @@ static float box_intersection(box_t a, box_t b)
|
|||
float w = overlap(a.x, a.w, b.x, b.w);
|
||||
float h = overlap(a.y, a.h, b.y, b.h);
|
||||
|
||||
if (w < 0 || h < 0)
|
||||
return 0;
|
||||
if (w < 0 || h < 0) return 0;
|
||||
return w * h;
|
||||
}
|
||||
|
||||
|
@ -285,10 +263,7 @@ static float box_union(box_t a, box_t b)
|
|||
return u;
|
||||
}
|
||||
|
||||
static float box_iou(box_t a, box_t b)
|
||||
{
|
||||
return box_intersection(a, b) / box_union(a, b);
|
||||
}
|
||||
static float box_iou(box_t a, box_t b) { return box_intersection(a, b) / box_union(a, b); }
|
||||
|
||||
static void do_nms_sort(region_layer_t *rl, box_t *boxes, float **probs)
|
||||
{
|
||||
|
@ -298,30 +273,23 @@ static void do_nms_sort(region_layer_t *rl, box_t *boxes, float **probs)
|
|||
int i, j, k;
|
||||
sortable_box_t s[boxes_number];
|
||||
|
||||
for (i = 0; i < boxes_number; ++i)
|
||||
{
|
||||
for (i = 0; i < boxes_number; ++i) {
|
||||
s[i].index = i;
|
||||
s[i].class = 0;
|
||||
s[i].probs = probs;
|
||||
}
|
||||
|
||||
for (k = 0; k < classes; ++k)
|
||||
{
|
||||
for (i = 0; i < boxes_number; ++i)
|
||||
s[i].class = k;
|
||||
for (k = 0; k < classes; ++k) {
|
||||
for (i = 0; i < boxes_number; ++i) s[i].class = k;
|
||||
qsort(s, boxes_number, sizeof(sortable_box_t), nms_comparator);
|
||||
for (i = 0; i < boxes_number; ++i)
|
||||
{
|
||||
if (probs[s[i].index][k] == 0)
|
||||
continue;
|
||||
for (i = 0; i < boxes_number; ++i) {
|
||||
if (probs[s[i].index][k] == 0) continue;
|
||||
box_t a = boxes[s[i].index];
|
||||
|
||||
for (j = i + 1; j < boxes_number; ++j)
|
||||
{
|
||||
for (j = i + 1; j < boxes_number; ++j) {
|
||||
box_t b = boxes[s[j].index];
|
||||
|
||||
if (box_iou(a, b) > nms_value)
|
||||
probs[s[j].index][k] = 0;
|
||||
if (box_iou(a, b) > nms_value) probs[s[j].index][k] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -332,11 +300,9 @@ static int max_index(float *a, int n)
|
|||
int i, max_i = 0;
|
||||
float max = a[0];
|
||||
|
||||
for (i = 1; i < n; ++i)
|
||||
{
|
||||
if (a[i] > max)
|
||||
{
|
||||
max = a[i];
|
||||
for (i = 1; i < n; ++i) {
|
||||
if (a[i] > max) {
|
||||
max = a[i];
|
||||
max_i = i;
|
||||
}
|
||||
}
|
||||
|
@ -349,16 +315,14 @@ static void region_layer_output(region_layer_t *rl, obj_info_t *obj_info)
|
|||
uint32_t image_width = rl->image_width;
|
||||
uint32_t image_height = rl->image_height;
|
||||
uint32_t boxes_number = rl->boxes_number;
|
||||
float threshold = rl->threshold;
|
||||
float *threshold = rl->threshold;
|
||||
box_t *boxes = (box_t *)rl->boxes;
|
||||
|
||||
for (int i = 0; i < rl->boxes_number; ++i)
|
||||
{
|
||||
int class = max_index(rl->probs[i], rl->classes);
|
||||
for (int i = 0; i < rl->boxes_number; ++i) {
|
||||
int class = max_index(rl->probs[i], rl->classes);
|
||||
float prob = rl->probs[i][class];
|
||||
|
||||
if (prob > threshold)
|
||||
{
|
||||
if (prob > threshold[class]) {
|
||||
box_t *b = boxes + i;
|
||||
obj_info->obj[obj_number].x1 = b->x * image_width - (b->w * image_width / 2);
|
||||
obj_info->obj[obj_number].y1 = b->y * image_height - (b->h * image_height / 2);
|
||||
|
@ -380,7 +344,8 @@ void region_layer_run(region_layer_t *rl, obj_info_t *obj_info)
|
|||
region_layer_output(rl, obj_info);
|
||||
}
|
||||
|
||||
void draw_edge(uint32_t *gram, obj_info_t *obj_info, uint32_t index, uint16_t color)
|
||||
void draw_edge(uint32_t *gram, obj_info_t *obj_info, uint32_t index, uint16_t color, uint16_t image_width,
|
||||
uint16_t image_height)
|
||||
{
|
||||
uint32_t data = ((uint32_t)color << 16) | (uint32_t)color;
|
||||
uint32_t *addr1, *addr2, *addr3, *addr4, x1, y1, x2, y2;
|
||||
|
@ -390,48 +355,41 @@ void draw_edge(uint32_t *gram, obj_info_t *obj_info, uint32_t index, uint16_t co
|
|||
x2 = obj_info->obj[index].x2;
|
||||
y2 = obj_info->obj[index].y2;
|
||||
|
||||
if (x1 <= 0)
|
||||
x1 = 1;
|
||||
if (x2 >= 319)
|
||||
x2 = 318;
|
||||
if (y1 <= 0)
|
||||
y1 = 1;
|
||||
if (y2 >= 239)
|
||||
y2 = 238;
|
||||
if (x1 <= 0) x1 = 1;
|
||||
if (x2 >= image_width - 1) x2 = image_width - 2;
|
||||
if (y1 <= 0) y1 = 1;
|
||||
if (y2 >= image_height - 1) y2 = image_height - 2;
|
||||
|
||||
addr1 = gram + (320 * y1 + x1) / 2;
|
||||
addr2 = gram + (320 * y1 + x2 - 8) / 2;
|
||||
addr3 = gram + (320 * (y2 - 1) + x1) / 2;
|
||||
addr4 = gram + (320 * (y2 - 1) + x2 - 8) / 2;
|
||||
for (uint32_t i = 0; i < 4; i++)
|
||||
{
|
||||
addr1 = gram + (image_width * y1 + x1) / 2;
|
||||
addr2 = gram + (image_width * y1 + x2 - 8) / 2;
|
||||
addr3 = gram + (image_width * (y2 - 1) + x1) / 2;
|
||||
addr4 = gram + (image_width * (y2 - 1) + x2 - 8) / 2;
|
||||
for (uint32_t i = 0; i < 4; i++) {
|
||||
*addr1 = data;
|
||||
*(addr1 + 160) = data;
|
||||
*(addr1 + image_width / 2) = data;
|
||||
*addr2 = data;
|
||||
*(addr2 + 160) = data;
|
||||
*(addr2 + image_width / 2) = data;
|
||||
*addr3 = data;
|
||||
*(addr3 + 160) = data;
|
||||
*(addr3 + image_width / 2) = data;
|
||||
*addr4 = data;
|
||||
*(addr4 + 160) = data;
|
||||
*(addr4 + image_width / 2) = data;
|
||||
addr1++;
|
||||
addr2++;
|
||||
addr3++;
|
||||
addr4++;
|
||||
}
|
||||
addr1 = gram + (320 * y1 + x1) / 2;
|
||||
addr2 = gram + (320 * y1 + x2 - 2) / 2;
|
||||
addr3 = gram + (320 * (y2 - 8) + x1) / 2;
|
||||
addr4 = gram + (320 * (y2 - 8) + x2 - 2) / 2;
|
||||
for (uint32_t i = 0; i < 8; i++)
|
||||
{
|
||||
addr1 = gram + (image_width * y1 + x1) / 2;
|
||||
addr2 = gram + (image_width * y1 + x2 - 2) / 2;
|
||||
addr3 = gram + (image_width * (y2 - 8) + x1) / 2;
|
||||
addr4 = gram + (image_width * (y2 - 8) + x2 - 2) / 2;
|
||||
for (uint32_t i = 0; i < 8; i++) {
|
||||
*addr1 = data;
|
||||
*addr2 = data;
|
||||
*addr3 = data;
|
||||
*addr4 = data;
|
||||
addr1 += 160;
|
||||
addr2 += 160;
|
||||
addr3 += 160;
|
||||
addr4 += 160;
|
||||
addr1 += image_width / 2;
|
||||
addr2 += image_width / 2;
|
||||
addr3 += image_width / 2;
|
||||
addr4 += image_width / 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
float threshold;
|
||||
float *threshold;
|
||||
float nms_value;
|
||||
uint32_t coords;
|
||||
uint32_t anchor_number;
|
||||
|
@ -44,6 +44,6 @@ typedef struct
|
|||
int region_layer_init(region_layer_t *rl, int width, int height, int channels, int origin_width, int origin_height);
|
||||
void region_layer_deinit(region_layer_t *rl);
|
||||
void region_layer_run(region_layer_t *rl, obj_info_t *obj_info);
|
||||
void draw_edge(uint32_t *gram, obj_info_t *obj_info, uint32_t index, uint16_t color);
|
||||
void draw_edge(uint32_t *gram, obj_info_t *obj_info, uint32_t index, uint16_t color, uint16_t image_width, uint16_t image_height);
|
||||
|
||||
#endif // _REGION_LAYER
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
menu "app lib"
|
||||
menu "lib"
|
||||
|
||||
choice
|
||||
prompt "chose a kind of lib for app"
|
||||
|
@ -10,5 +10,5 @@ menu "app lib"
|
|||
config APP_SELECT_OTHER_LIB
|
||||
bool "app select other lib"
|
||||
endchoice
|
||||
|
||||
source "$APP_DIR/lib/cJSON/Kconfig"
|
||||
endmenu
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
import os
|
||||
Import('RTT_ROOT')
|
||||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
objs = []
|
||||
list = os.listdir(cwd)
|
||||
|
||||
for d in list:
|
||||
path = os.path.join(cwd, d)
|
||||
if os.path.isfile(os.path.join(path, 'SConscript')):
|
||||
objs = objs + SConscript(os.path.join(path, 'SConscript'))
|
||||
|
||||
Return('objs')
|
|
@ -0,0 +1,3 @@
|
|||
menuconfig LIB_USING_CJSON
|
||||
bool "USING cJSON"
|
||||
default n
|
|
@ -0,0 +1,10 @@
|
|||
from building import *
|
||||
import os
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
|
||||
src = Glob('*.c')
|
||||
|
||||
group = DefineGroup('cjson', src, depend = ['LIB_USING_CJSON'], CPPPATH = [cwd])
|
||||
|
||||
Return('group')
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,293 @@
|
|||
/*
|
||||
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef cJSON__h
|
||||
#define cJSON__h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
|
||||
#define __WINDOWS__
|
||||
#endif
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
|
||||
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options:
|
||||
|
||||
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
|
||||
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
|
||||
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
|
||||
|
||||
For *nix builds that support visibility attribute, you can define similar behavior by
|
||||
|
||||
setting default visibility to hidden by adding
|
||||
-fvisibility=hidden (for gcc)
|
||||
or
|
||||
-xldscope=hidden (for sun cc)
|
||||
to CFLAGS
|
||||
|
||||
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
|
||||
|
||||
*/
|
||||
|
||||
#define CJSON_CDECL __cdecl
|
||||
#define CJSON_STDCALL __stdcall
|
||||
|
||||
/* export symbols by default, this is necessary for copy pasting the C and header file */
|
||||
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_EXPORT_SYMBOLS
|
||||
#endif
|
||||
|
||||
#if defined(CJSON_HIDE_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) type CJSON_STDCALL
|
||||
#elif defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
|
||||
#elif defined(CJSON_IMPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
|
||||
#endif
|
||||
#else /* !__WINDOWS__ */
|
||||
#define CJSON_CDECL
|
||||
#define CJSON_STDCALL
|
||||
|
||||
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
|
||||
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
|
||||
#else
|
||||
#define CJSON_PUBLIC(type) type
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* project version */
|
||||
#define CJSON_VERSION_MAJOR 1
|
||||
#define CJSON_VERSION_MINOR 7
|
||||
#define CJSON_VERSION_PATCH 14
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* cJSON Types: */
|
||||
#define cJSON_Invalid (0)
|
||||
#define cJSON_False (1 << 0)
|
||||
#define cJSON_True (1 << 1)
|
||||
#define cJSON_NULL (1 << 2)
|
||||
#define cJSON_Number (1 << 3)
|
||||
#define cJSON_String (1 << 4)
|
||||
#define cJSON_Array (1 << 5)
|
||||
#define cJSON_Object (1 << 6)
|
||||
#define cJSON_Raw (1 << 7) /* raw json */
|
||||
|
||||
#define cJSON_IsReference 256
|
||||
#define cJSON_StringIsConst 512
|
||||
|
||||
/* The cJSON structure: */
|
||||
typedef struct cJSON
|
||||
{
|
||||
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
||||
struct cJSON *next;
|
||||
struct cJSON *prev;
|
||||
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||
struct cJSON *child;
|
||||
|
||||
/* The type of the item, as above. */
|
||||
int type;
|
||||
|
||||
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
|
||||
char *valuestring;
|
||||
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
|
||||
int valueint;
|
||||
/* The item's number, if type==cJSON_Number */
|
||||
double valuedouble;
|
||||
|
||||
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||
char *string;
|
||||
} cJSON;
|
||||
|
||||
typedef struct cJSON_Hooks
|
||||
{
|
||||
/* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
|
||||
void *(CJSON_CDECL *malloc_fn)(size_t sz);
|
||||
void (CJSON_CDECL *free_fn)(void *ptr);
|
||||
} cJSON_Hooks;
|
||||
|
||||
typedef int cJSON_bool;
|
||||
|
||||
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
|
||||
* This is to prevent stack overflows. */
|
||||
#ifndef CJSON_NESTING_LIMIT
|
||||
#define CJSON_NESTING_LIMIT 1000
|
||||
#endif
|
||||
|
||||
/* returns the version of cJSON as a string */
|
||||
CJSON_PUBLIC(const char*) cJSON_Version(void);
|
||||
|
||||
/* Supply malloc, realloc and free functions to cJSON */
|
||||
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||
|
||||
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
|
||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length);
|
||||
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||
|
||||
/* Render a cJSON entity to text for transfer/storage. */
|
||||
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
||||
/* Render a cJSON entity to text for transfer/storage without any formatting. */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
|
||||
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
|
||||
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
|
||||
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
|
||||
/* Delete a cJSON entity and all subentities. */
|
||||
CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);
|
||||
|
||||
/* Returns the number of items in an array (or object). */
|
||||
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
|
||||
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
|
||||
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
|
||||
|
||||
/* Check item type and return its value */
|
||||
CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item);
|
||||
CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item);
|
||||
|
||||
/* These functions check the type of an item */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
|
||||
|
||||
/* These calls create a cJSON item of the appropriate type. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
||||
/* raw json */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
||||
|
||||
/* Create a string where valuestring references a string so
|
||||
* it will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
|
||||
/* Create an object/array that only references it's elements so
|
||||
* they will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
|
||||
|
||||
/* These utilities create an Array of count items.
|
||||
* The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count);
|
||||
|
||||
/* Append item to the specified array/object. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
||||
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
|
||||
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
|
||||
* writing to `item->string` */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
|
||||
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
||||
|
||||
/* Remove/Detach items from Arrays/Objects. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
|
||||
/* Update array items. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
|
||||
|
||||
/* Duplicate a cJSON item */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
|
||||
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
|
||||
* need to be released. With recurse!=0, it will duplicate any children connected to the item.
|
||||
* The item->next and ->prev pointers are always zero on return from Duplicate. */
|
||||
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
|
||||
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
|
||||
|
||||
/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
|
||||
* The input pointer json cannot point to a read-only address area, such as a string constant,
|
||||
* but should point to a readable and writable adress area. */
|
||||
CJSON_PUBLIC(void) cJSON_Minify(char *json);
|
||||
|
||||
/* Helper functions for creating and adding items to an object at the same time.
|
||||
* They return the added item or NULL on failure. */
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
|
||||
|
||||
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
|
||||
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
|
||||
/* helper for the cJSON_SetNumberValue macro */
|
||||
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
||||
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
|
||||
/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */
|
||||
CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
|
||||
|
||||
/* Macro for iterating over an array or object */
|
||||
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
|
||||
|
||||
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
|
||||
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
|
||||
CJSON_PUBLIC(void) cJSON_free(void *object);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -237,7 +237,8 @@ CONFIG_RT_WLAN_WORKQUEUE_THREAD_PRIO=15
|
|||
# POSIX layer and C standard library
|
||||
#
|
||||
CONFIG_RT_USING_LIBC=y
|
||||
# CONFIG_RT_USING_PTHREADS is not set
|
||||
CONFIG_RT_USING_PTHREADS=y
|
||||
CONFIG_PTHREAD_NUM_MAX=8
|
||||
CONFIG_RT_USING_POSIX=y
|
||||
# CONFIG_RT_USING_POSIX_MMAP is not set
|
||||
# CONFIG_RT_USING_POSIX_TERMIOS is not set
|
||||
|
@ -379,9 +380,27 @@ CONFIG_BSP_SPI1_USING_SS1=y
|
|||
CONFIG_BSP_SPI1_SS1_PIN=8
|
||||
# CONFIG_BSP_SPI1_USING_SS2 is not set
|
||||
# CONFIG_BSP_SPI1_USING_SS3 is not set
|
||||
# CONFIG_BSP_USING_LCD is not set
|
||||
CONFIG_BSP_USING_LCD=y
|
||||
CONFIG_BSP_LCD_CS_PIN=36
|
||||
CONFIG_BSP_LCD_WR_PIN=39
|
||||
CONFIG_BSP_LCD_DC_PIN=38
|
||||
CONFIG_BSP_LCD_RST_PIN=37
|
||||
CONFIG_BSP_LCD_X_MAX=240
|
||||
CONFIG_BSP_LCD_Y_MAX=320
|
||||
CONFIG_BSP_USING_SDCARD=y
|
||||
# CONFIG_BSP_USING_DVP is not set
|
||||
CONFIG_BSP_USING_DVP=y
|
||||
|
||||
#
|
||||
# The default pin assignment is based on the Maix Duino K210 development board
|
||||
#
|
||||
CONFIG_BSP_DVP_SCCB_SDA_PIN=40
|
||||
CONFIG_BSP_DVP_SCCB_SCLK_PIN=41
|
||||
CONFIG_BSP_DVP_CMOS_RST_PIN=42
|
||||
CONFIG_BSP_DVP_CMOS_VSYNC_PIN=43
|
||||
CONFIG_BSP_DVP_CMOS_PWDN_PIN=44
|
||||
CONFIG_BSP_DVP_CMOS_XCLK_PIN=46
|
||||
CONFIG_BSP_DVP_CMOS_PCLK_PIN=47
|
||||
CONFIG_BSP_DVP_CMOS_HREF_PIN=45
|
||||
|
||||
#
|
||||
# Kendryte SDK Config
|
||||
|
@ -392,7 +411,7 @@ CONFIG_PKG_KENDRYTE_SDK_VERNUM=0x0055
|
|||
# More Drivers
|
||||
#
|
||||
# CONFIG_PKG_USING_RW007 is not set
|
||||
# CONFIG_DRV_USING_OV2640 is not set
|
||||
CONFIG_DRV_USING_OV2640=y
|
||||
|
||||
#
|
||||
# APP_Framework
|
||||
|
@ -424,7 +443,7 @@ CONFIG_MAIN_KTASK_STACK_SIZE=1024
|
|||
#
|
||||
# knowing app
|
||||
#
|
||||
# CONFIG_APPLICATION_KNOWING is not set
|
||||
CONFIG_FACE_DETECT=y
|
||||
|
||||
#
|
||||
# sensor app
|
||||
|
@ -438,9 +457,17 @@ CONFIG_TRANSFORM_LAYER_ATTRIUBUTE=y
|
|||
CONFIG_ADD_XIUOS_FETURES=y
|
||||
# CONFIG_ADD_NUTTX_FETURES is not set
|
||||
# CONFIG_ADD_RTTHREAD_FETURES is not set
|
||||
# CONFIG_SUPPORT_SENSOR_FRAMEWORK is not set
|
||||
CONFIG_SUPPORT_SENSOR_FRAMEWORK=y
|
||||
# CONFIG_SENSOR_CO2 is not set
|
||||
# CONFIG_SENSOR_PM is not set
|
||||
# CONFIG_SENSOR_VOICE is not set
|
||||
# CONFIG_SENSOR_TEMPERATURE is not set
|
||||
# CONFIG_SENSOR_HUMIDITY is not set
|
||||
# CONFIG_SUPPORT_CONNECTION_FRAMEWORK is not set
|
||||
CONFIG_SUPPORT_KNOWING_FRAMEWORK=y
|
||||
# CONFIG_USING_TENSORFLOWLITEMICRO is not set
|
||||
CONFIG_USING_KPU_POSTPROCESSING=y
|
||||
CONFIG_USING_YOLOV2=y
|
||||
# CONFIG_SUPPORT_CONTROL_FRAMEWORK is not set
|
||||
|
||||
#
|
||||
|
|
|
@ -0,0 +1,228 @@
|
|||
# this
|
||||
*.old
|
||||
*.dblite
|
||||
cconfig.h
|
||||
*.bin
|
||||
*.map
|
||||
# rtconfig.h
|
||||
# .config
|
||||
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.con
|
|
@ -59,6 +59,7 @@ objs.extend(SConscript(os.getcwd() + '/../../../../APP_Framework/Framework/SCons
|
|||
# include APP_Framework/Applications
|
||||
objs.extend(SConscript(os.getcwd() + '/../../../../APP_Framework/Applications/SConscript'))
|
||||
|
||||
|
||||
# include APP_Framework/lib
|
||||
objs.extend(SConscript(os.getcwd() + '/../../../../APP_Framework/lib/SConscript'))
|
||||
# make a building
|
||||
DoBuilding(TARGET, objs)
|
||||
|
|
|
@ -67,7 +67,7 @@ static rt_err_t rt_dvp_init(rt_device_t dev)
|
|||
dvp_set_output_enable(0, 1);
|
||||
dvp_set_output_enable(1, 1);
|
||||
dvp_set_image_format(DVP_CFG_RGB_FORMAT);////////////////
|
||||
dvp_set_image_size(320, 240);
|
||||
dvp_set_image_size(320, 240); // default
|
||||
dvp_config_interrupt(DVP_CFG_FINISH_INT_ENABLE, 0);
|
||||
dvp_disable_auto();
|
||||
plic_set_priority(IRQN_DVP_INTERRUPT, 1);
|
||||
|
|
|
@ -160,6 +160,8 @@
|
|||
/* POSIX layer and C standard library */
|
||||
|
||||
#define RT_USING_LIBC
|
||||
#define RT_USING_PTHREADS
|
||||
#define PTHREAD_NUM_MAX 8
|
||||
#define RT_USING_POSIX
|
||||
#define RT_LIBC_FIXED_TIMEZONE 8
|
||||
|
||||
|
@ -254,7 +256,26 @@
|
|||
#define BSP_SPI1_SS0_PIN 29
|
||||
#define BSP_SPI1_USING_SS1
|
||||
#define BSP_SPI1_SS1_PIN 8
|
||||
#define BSP_USING_LCD
|
||||
#define BSP_LCD_CS_PIN 36
|
||||
#define BSP_LCD_WR_PIN 39
|
||||
#define BSP_LCD_DC_PIN 38
|
||||
#define BSP_LCD_RST_PIN 37
|
||||
#define BSP_LCD_X_MAX 240
|
||||
#define BSP_LCD_Y_MAX 320
|
||||
#define BSP_USING_SDCARD
|
||||
#define BSP_USING_DVP
|
||||
|
||||
/* The default pin assignment is based on the Maix Duino K210 development board */
|
||||
|
||||
#define BSP_DVP_SCCB_SDA_PIN 40
|
||||
#define BSP_DVP_SCCB_SCLK_PIN 41
|
||||
#define BSP_DVP_CMOS_RST_PIN 42
|
||||
#define BSP_DVP_CMOS_VSYNC_PIN 43
|
||||
#define BSP_DVP_CMOS_PWDN_PIN 44
|
||||
#define BSP_DVP_CMOS_XCLK_PIN 46
|
||||
#define BSP_DVP_CMOS_PCLK_PIN 47
|
||||
#define BSP_DVP_CMOS_HREF_PIN 45
|
||||
|
||||
/* Kendryte SDK Config */
|
||||
|
||||
|
@ -262,6 +283,7 @@
|
|||
|
||||
/* More Drivers */
|
||||
|
||||
#define DRV_USING_OV2640
|
||||
|
||||
/* APP_Framework */
|
||||
|
||||
|
@ -281,6 +303,7 @@
|
|||
|
||||
/* knowing app */
|
||||
|
||||
#define FACE_DETECT
|
||||
|
||||
/* sensor app */
|
||||
|
||||
|
@ -289,7 +312,10 @@
|
|||
|
||||
#define TRANSFORM_LAYER_ATTRIUBUTE
|
||||
#define ADD_XIUOS_FETURES
|
||||
#define SUPPORT_SENSOR_FRAMEWORK
|
||||
#define SUPPORT_KNOWING_FRAMEWORK
|
||||
#define USING_KPU_POSTPROCESSING
|
||||
#define USING_YOLOV2
|
||||
|
||||
/* app lib */
|
||||
|
||||
|
|
|
@ -356,6 +356,7 @@ CONFIG_MAIN_KTASK_STACK_SIZE=1024
|
|||
#
|
||||
# knowing app
|
||||
#
|
||||
CONFIG_IRIS_ML_DEMO=y
|
||||
|
||||
#
|
||||
# sensor app
|
||||
|
@ -378,10 +379,13 @@ CONFIG_SUPPORT_SENSOR_FRAMEWORK=y
|
|||
# CONFIG_SUPPORT_CONNECTION_FRAMEWORK is not set
|
||||
CONFIG_SUPPORT_KNOWING_FRAMEWORK=y
|
||||
# CONFIG_USING_TENSORFLOWLITEMICRO is not set
|
||||
CONFIG_USING_KPU_POSTPROCESSING=y
|
||||
# CONFIG_USING_YOLOV2 is not set
|
||||
# CONFIG_SUPPORT_CONTROL_FRAMEWORK is not set
|
||||
|
||||
#
|
||||
# app lib
|
||||
# lib
|
||||
#
|
||||
CONFIG_APP_SELECT_NEWLIB=y
|
||||
# CONFIG_APP_SELECT_OTHER_LIB is not set
|
||||
# CONFIG_LIB_USING_CJSON is not set
|
||||
|
|
|
@ -1,30 +1,19 @@
|
|||
*.pyc
|
||||
# this
|
||||
*.map
|
||||
*.dblite
|
||||
*.elf
|
||||
*.bin
|
||||
*.hex
|
||||
*.axf
|
||||
*.exe
|
||||
*.pdb
|
||||
*.idb
|
||||
*.ilk
|
||||
*.old
|
||||
*~
|
||||
*.o
|
||||
*.obj
|
||||
*.out
|
||||
*.bak
|
||||
*.dep
|
||||
*.lib
|
||||
*.i
|
||||
*.d
|
||||
.DS_Stor*
|
||||
*.uimg
|
||||
GPATH
|
||||
GRTAGS
|
||||
GTAGS
|
||||
.vscode
|
||||
JLinkLog.txt
|
||||
JLinkSettings.ini
|
||||
DebugConfig/
|
||||
|
@ -32,3 +21,223 @@ RTE/
|
|||
settings/
|
||||
*.uvguix*
|
||||
cconfig.h
|
||||
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.con
|
||||
|
|
|
@ -81,6 +81,7 @@ objs.extend(SConscript(os.getcwd() + '/../../../../APP_Framework/Framework/SCons
|
|||
|
||||
# include APP_Framework/Applications
|
||||
objs.extend(SConscript(os.getcwd() + '/../../../../APP_Framework/Applications/SConscript'))
|
||||
|
||||
# include APP_Framework/lib
|
||||
objs.extend(SConscript(os.getcwd() + '/../../../../APP_Framework/lib/SConscript'))
|
||||
# make a building
|
||||
DoBuilding(TARGET, objs)
|
||||
|
|
|
@ -201,6 +201,8 @@
|
|||
|
||||
/* knowing app */
|
||||
|
||||
#define IRIS_ML_DEMO
|
||||
|
||||
/* sensor app */
|
||||
|
||||
|
||||
|
@ -210,8 +212,9 @@
|
|||
#define ADD_XIUOS_FETURES
|
||||
#define SUPPORT_SENSOR_FRAMEWORK
|
||||
#define SUPPORT_KNOWING_FRAMEWORK
|
||||
#define USING_KPU_POSTPROCESSING
|
||||
|
||||
/* app lib */
|
||||
/* lib */
|
||||
|
||||
#define APP_SELECT_NEWLIB
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ if os.getenv('RTT_ROOT'):
|
|||
# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR
|
||||
if CROSS_TOOL == 'gcc':
|
||||
PLATFORM = 'gcc'
|
||||
EXEC_PATH = r'/usr/local/Cellar/gcc-arm-none-eabi/20180627/bin'
|
||||
EXEC_PATH = r'/opt/gcc-arm-none-eabi-7-2018-q2-update/bin'
|
||||
elif CROSS_TOOL == 'keil':
|
||||
PLATFORM = 'armcc'
|
||||
EXEC_PATH = r'C:/Keil_v5'
|
||||
|
|
|
@ -1467,20 +1467,31 @@ static rt_err_t rt_ov2640_control(rt_device_t dev, int cmd, void *args)
|
|||
{
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
rt_err_t ret = RT_EOK;
|
||||
if(cmd < IOCTRL_CAMERA_START_SHOT || cmd > IOCTRL_CAMERA_SET_EXPOSURE)
|
||||
if(cmd < IOCTRL_CAMERA_SET_DVP_RESO || cmd > IOCTRL_CAMERA_SET_EXPOSURE)
|
||||
{
|
||||
LOG_E("CMD value should be 22 ~29");
|
||||
return RT_ERROR;
|
||||
}
|
||||
|
||||
int value = 0;
|
||||
_ioctl_shoot_para shoot_para = {0};
|
||||
|
||||
#ifdef BOARD_K210_EVB
|
||||
_ioctl_set_dvp_reso set_dvp_reso = {0};
|
||||
#endif
|
||||
if(IOCTRL_CAMERA_START_SHOT == cmd)
|
||||
{
|
||||
shoot_para = *((_ioctl_shoot_para*)args);
|
||||
ret = rt_ov2640_start_shoot(shoot_para.pdata,shoot_para.length);
|
||||
return ret;
|
||||
}
|
||||
#ifdef BOARD_K210_EVB
|
||||
else if(IOCTRL_CAMERA_SET_DVP_RESO == cmd)
|
||||
{
|
||||
set_dvp_reso =*((_ioctl_set_dvp_reso*)args);
|
||||
dvp_set_image_size(set_dvp_reso.width, set_dvp_reso.height);
|
||||
return RT_EOK;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
value = *((int*)args);
|
||||
|
|
|
@ -123,9 +123,9 @@ extern "C" {
|
|||
#define OV2640_SENSOR_HISTO_LOW 0x61
|
||||
#define OV2640_SENSOR_HISTO_HIGH 0x62
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef BOARD_K210_EVB
|
||||
#define IOCTRL_CAMERA_SET_DVP_RESO (21) // set dev resolution
|
||||
#endif
|
||||
|
||||
#define IOCTRL_CAMERA_START_SHOT (22) // start shoot
|
||||
#define IOCTRL_CAMERA_SET_RESO (23) //set resolution
|
||||
|
@ -136,6 +136,14 @@ extern "C" {
|
|||
#define IOCTRL_CAMERA_SET_EFFECT (28) //set effect
|
||||
#define IOCTRL_CAMERA_SET_EXPOSURE (29) //set auto exposure
|
||||
|
||||
#ifdef BOARD_K210_EVB
|
||||
typedef struct
|
||||
{
|
||||
uint32_t width; // width The width of image
|
||||
uint32_t height; // height The height of image
|
||||
}_ioctl_set_dvp_reso;
|
||||
#endif
|
||||
|
||||
|
||||
struct camera_device
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue