402 lines
10 KiB
C
402 lines
10 KiB
C
/* Copyright (2017) Baidu Inc. All rights reserved.
|
|
*
|
|
* File: duerapp_system_info.c
|
|
* Auth: Zhong Shuai(zhongshuai@baidu.com)
|
|
* Desc: Provide the information about the system
|
|
*/
|
|
|
|
#include "lightduer_system_info.h"
|
|
#include "lightduer_statistics.h"
|
|
#include <string.h>
|
|
|
|
#include "lightduer_mutex.h"
|
|
#include "lightduer_types.h"
|
|
#include "lightduer_timers.h"
|
|
#include "lightduer_log.h"
|
|
#include "lightduer_memory.h"
|
|
#include "lightduer_lib.h"
|
|
#include "lightduer_timestamp.h"
|
|
#include "fs/fs.h"
|
|
#include "wifi/wifi_connect.h"
|
|
|
|
extern u32 get_free_heap_size(void);
|
|
extern int storage_device_ready(void);
|
|
|
|
__attribute__((weak)) u32 get_free_heap_size(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
#define DUER_GET_FREE_HEAP_SIZE() get_free_heap_size()
|
|
|
|
#define DELAY_TIEM (5 * 1000)
|
|
|
|
extern int duer_system_info_init(void);
|
|
|
|
volatile static uint32_t s_peak = 0;
|
|
volatile static uint32_t s_trough = (~0x0);
|
|
volatile static uint32_t s_sum = 0;
|
|
volatile static uint32_t s_counts = 0;
|
|
volatile static duer_mutex_t s_lock_sys_info = NULL;
|
|
static duer_timer_handler s_timer;
|
|
|
|
extern duer_system_static_info_t g_system_static_info;
|
|
|
|
static void calculate_system_info(void *arg)
|
|
{
|
|
int ret = DUER_OK;
|
|
uint32_t free_heap_size = 0;
|
|
|
|
free_heap_size = DUER_GET_FREE_HEAP_SIZE() / 1024;
|
|
|
|
ret = duer_mutex_lock(s_lock_sys_info);
|
|
if (ret != DUER_OK) {
|
|
DUER_LOGE("Lock sys info failed");
|
|
return;
|
|
}
|
|
|
|
if (free_heap_size > s_peak) {
|
|
s_peak = free_heap_size;
|
|
}
|
|
|
|
if (free_heap_size < s_trough) {
|
|
s_trough = free_heap_size;
|
|
}
|
|
|
|
s_sum += free_heap_size;
|
|
s_counts++;
|
|
|
|
ret = duer_mutex_unlock(s_lock_sys_info);
|
|
if (ret != DUER_OK) {
|
|
DUER_LOGE("Unlock sys info failed");
|
|
}
|
|
}
|
|
|
|
static int duer_init_system_info_module(void)
|
|
{
|
|
int ret = 0;
|
|
|
|
if (s_lock_sys_info) {
|
|
return DUER_OK;
|
|
}
|
|
|
|
s_lock_sys_info = duer_mutex_create();
|
|
if (!s_lock_sys_info) {
|
|
DUER_LOGE("Create lock failed");
|
|
|
|
return DUER_ERR_FAILED;
|
|
}
|
|
|
|
s_timer = duer_timer_acquire(calculate_system_info, NULL, DUER_TIMER_PERIODIC);
|
|
|
|
ret = duer_timer_start(s_timer, DELAY_TIEM);
|
|
if (ret != DUER_OK) {
|
|
DUER_LOGE("Start timer failed");
|
|
|
|
ret = DUER_ERR_FAILED;
|
|
}
|
|
|
|
return DUER_OK;
|
|
}
|
|
|
|
static int duer_get_system_static_info(duer_system_static_info_t *info)
|
|
{
|
|
if (info == NULL) {
|
|
DUER_LOGE("Sys Info: Argument Error");
|
|
return DUER_ERR_INVALID_PARAMETER;
|
|
}
|
|
|
|
memcpy(info, &g_system_static_info, sizeof(*info));
|
|
|
|
return DUER_OK;
|
|
}
|
|
|
|
static int duer_get_system_dynamic_info(duer_system_dynamic_info_t *info)
|
|
{
|
|
unsigned long num_of_tasks = 0;
|
|
|
|
num_of_tasks = os_tasks_num_query();
|
|
info->total_task = num_of_tasks;
|
|
|
|
#if 0 //(configUSE_TRACE_FACILITY == 1)
|
|
uint32_t run_time = 0;
|
|
UBaseType_t task_array_size = 0;
|
|
TaskStatus_t *task_status_array = NULL;
|
|
|
|
task_status_array = DUER_MALLOC(num_of_tasks * sizeof(TaskStatus_t));
|
|
|
|
task_array_size = uxTaskGetSystemState(task_status_array, num_of_tasks, &run_time);
|
|
|
|
info->system_up_time = run_time;
|
|
info->running_task = task_array_size;
|
|
|
|
DUER_FREE(task_status_array);
|
|
#else
|
|
|
|
info->system_up_time = duer_timestamp();
|
|
|
|
#endif
|
|
|
|
return DUER_OK;
|
|
}
|
|
|
|
static int duer_free_system_dynamic_info(duer_system_dynamic_info_t *info)
|
|
{
|
|
return DUER_OK;
|
|
}
|
|
|
|
static int duer_get_memory_info(duer_memory_info_t *mem_info)
|
|
{
|
|
int ret = DUER_OK;
|
|
|
|
mem_info->total_memory_size = g_system_static_info.ram_size;
|
|
|
|
calculate_system_info(NULL);
|
|
|
|
ret = duer_mutex_lock(s_lock_sys_info);
|
|
if (ret != DUER_OK) {
|
|
DUER_LOGE("Lock sys info failed");
|
|
return ret;
|
|
}
|
|
|
|
mem_info->memory_type = RAM;
|
|
mem_info->peak = s_peak;
|
|
mem_info->trough = s_trough;
|
|
if (s_counts > 0) {
|
|
mem_info->average = 1.0f * s_sum / s_counts;
|
|
} else {
|
|
DUER_LOGE("No memory info was measured!!!");
|
|
}
|
|
|
|
s_peak = 0;
|
|
s_trough = ~0;
|
|
s_sum = 0;
|
|
s_counts = 0;
|
|
|
|
ret = duer_mutex_unlock(s_lock_sys_info);
|
|
if (ret != DUER_OK) {
|
|
DUER_LOGE("Unlock sys info failed");
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int duer_get_disk_info(duer_disk_info_t **disk_info)
|
|
{
|
|
duer_disk_info_t *info = NULL;
|
|
duer_disk_info_t *sd_info = NULL;
|
|
struct vfs_partition *part = NULL;
|
|
u32 space = 0;
|
|
|
|
if (disk_info == NULL) {
|
|
return DUER_ERR_INVALID_PARAMETER;
|
|
}
|
|
|
|
/**
|
|
* TODU: You SHOULD impliment this function for obtain the partition remain size.
|
|
*
|
|
* Follow is a demo
|
|
*
|
|
* =====================================
|
|
* info = DUER_MALLOC(sizeof(*info));
|
|
* if (info == NULL) {
|
|
* DUER_LOGE("Malloc failed");
|
|
*
|
|
* return DUER_ERR_FAILED;
|
|
* }
|
|
*
|
|
* memset(info, 0, sizeof(*info));
|
|
*
|
|
* strncpy(info->partition_name, "Flash", PARTITION_NAME_LEN);
|
|
*
|
|
* info->total_size = xxx_get_flash_total_size();
|
|
* info->used_size = xxx_get_flash_used_size();
|
|
* info->available_size = xxx_get_flash_available();
|
|
* info->next = NULL; // If you have another patitions, linked to the next.
|
|
*/
|
|
|
|
*disk_info = info;
|
|
|
|
#if 0
|
|
info = DUER_MALLOC(sizeof(*info));
|
|
if (info == NULL) {
|
|
DUER_LOGE("Malloc failed");
|
|
|
|
return DUER_ERR_FAILED;
|
|
}
|
|
|
|
memset(info, 0, sizeof(*info));
|
|
|
|
strncpy(info->partition_name, "Flash", PARTITION_NAME_LEN);
|
|
|
|
part = fget_partition("mnt/spiflash/C/");
|
|
if (part) {
|
|
info->total_size = g_system_static_info.rom_size;
|
|
fget_free_space("mnt/spiflash/C/", &space);
|
|
info->used_size = part->total_size / 1024;
|
|
info->available_size = info->total_size - info->used_size;
|
|
info->unilization = 100 * info->available_size / info->total_size;
|
|
}
|
|
|
|
info->next = NULL; // If you have another patitions, linked to the next.
|
|
|
|
*disk_info = info;
|
|
|
|
if (storage_device_ready()) {
|
|
sd_info = DUER_MALLOC(sizeof(*sd_info));
|
|
if (sd_info == NULL) {
|
|
DUER_LOGE("Malloc failed");
|
|
return DUER_OK;
|
|
}
|
|
|
|
memset(sd_info, 0, sizeof(*sd_info));
|
|
|
|
strncpy(sd_info->partition_name, "SD", PARTITION_NAME_LEN);
|
|
|
|
part = fget_partition(CONFIG_ROOT_PATH);
|
|
if (part) {
|
|
sd_info->total_size = part->total_size / 1024;
|
|
fget_free_space(CONFIG_ROOT_PATH, &space);
|
|
sd_info->used_size = (part->total_size - space) / 1024;
|
|
sd_info->available_size = space / 1024;
|
|
sd_info->unilization = 100 * sd_info->available_size / sd_info->total_size;
|
|
}
|
|
|
|
info->next = sd_info;
|
|
sd_info->next = NULL;
|
|
}
|
|
#endif
|
|
|
|
return DUER_OK;
|
|
}
|
|
|
|
static int duer_free_disk_info(duer_disk_info_t *disk_info)
|
|
{
|
|
duer_disk_info_t *temp = NULL;
|
|
while (disk_info != NULL) {
|
|
temp = disk_info;
|
|
disk_info = temp->next;
|
|
DUER_FREE(temp);
|
|
}
|
|
|
|
return DUER_OK;
|
|
}
|
|
|
|
static int get_network_info(duer_network_info_t *network_info)
|
|
{
|
|
if (network_info == NULL) {
|
|
return DUER_ERR_INVALID_PARAMETER;
|
|
}
|
|
|
|
/**
|
|
* TODU: You SHOULD impliment this function for obtain the network information.
|
|
*
|
|
* Follow is a demo
|
|
*
|
|
* =====================================
|
|
*
|
|
* network_info->wireless->link = xxx_get_rssi();
|
|
* network_info->wireless->level = xxx_get_signal_strength;
|
|
* network_info->wireless->noise = xxx_get_noise();
|
|
*
|
|
* network_info->network_type = WIFI_TYPE;
|
|
* strncpy(network_info->hw_address, xxx_get_mac_address(), HW_ADDRESS_LEN);
|
|
* strncpy(network_info->ipv4_address, xxx_get_ipaddr(), IPV4_ADDRESS_LEN);
|
|
* strncpy(network_info->wireless.bssid, xxx_get_ipaddr(), BSSID_LEN);
|
|
* network_info->mtu = xxx_get_mtu();
|
|
* network_info->transmitted_packets = xxx_get_tx_packets();
|
|
* network_info->received_packets = xxx_get_rx_packets();
|
|
*
|
|
* return DUER_OK;
|
|
*/
|
|
|
|
u8 mac_addr[6];
|
|
char *p;
|
|
|
|
wifi_get_mac(mac_addr);
|
|
|
|
struct wifi_mode_info info;
|
|
info.mode = STA_MODE;
|
|
wifi_get_mode_cur_info(&info);
|
|
|
|
network_info->network_type = WIFI_TYPE;
|
|
p = network_info->hw_address;
|
|
DUER_SNPRINTF(network_info->wireless.ssid, SSID_LEN + 1, "%s", info.ssid);
|
|
for (int i = 0; i < 6; i++) {
|
|
*(p++) = *((char *)"0123456789ABCDEF" + ((mac_addr[i] >> 4) & 0x0f));
|
|
*(p++) = *((char *)"0123456789ABCDEF" + (mac_addr[i] & 0x0f));
|
|
*(p++) = ':';
|
|
}
|
|
*(--p) = '\0';
|
|
#if 0
|
|
/* DUER_SNPRINTF(network_info->wireless.bssid, BSSID_LEN + 1, "%02x:%02x:%02x:%02x:%02x:%02x", */
|
|
|
|
DUER_SNPRINTF(network_info->hw_address, HW_ADDRESS_LEN + 1, "%02x:%02x:%02x:%02x:%02x:%02x",
|
|
mac_addr[0], mac_addr[1], mac_addr[2],
|
|
mac_addr[3], mac_addr[4], mac_addr[5]);
|
|
#endif
|
|
network_info->wireless.link = wifi_get_rssi();
|
|
|
|
return DUER_OK;
|
|
}
|
|
|
|
static int duer_free_network_info(duer_network_info_t *network_info)
|
|
{
|
|
return DUER_OK;
|
|
}
|
|
|
|
static duer_system_info_ops_t s_system_info_ops = {
|
|
.init = duer_init_system_info_module,
|
|
.get_system_static_info = duer_get_system_static_info,
|
|
.get_system_dynamic_info = duer_get_system_dynamic_info,
|
|
.free_system_dynamic_info = duer_free_system_dynamic_info,
|
|
.get_memory_info = duer_get_memory_info,
|
|
.get_disk_info = duer_get_disk_info,
|
|
.free_disk_info = duer_free_disk_info,
|
|
.get_network_info = get_network_info,
|
|
.free_network_info = duer_free_network_info,
|
|
};
|
|
|
|
int duer_statistics_initialize(void)
|
|
{
|
|
int ret = DUER_OK;
|
|
|
|
ret = duer_system_info_register_system_info_ops(&s_system_info_ops);
|
|
if (ret != DUER_OK) {
|
|
DUER_LOGE("Sys Info: Register system info ops failed ret: %d", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = duer_init_system_info();
|
|
if (ret != DUER_OK) {
|
|
DUER_LOGE("Sys Info: Init system info failed ret: %d", ret);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
#ifndef DISABLE_REPORT_SYSTEM_INFO
|
|
int duer_statistics_finalize(void)
|
|
{
|
|
int ret = DUER_OK;
|
|
|
|
if (s_timer != NULL) {
|
|
duer_timer_stop(s_timer);
|
|
duer_timer_release(s_timer);
|
|
s_timer = NULL;
|
|
}
|
|
|
|
if (s_lock_sys_info) {
|
|
duer_mutex_destroy(s_lock_sys_info);
|
|
s_lock_sys_info = NULL;
|
|
}
|
|
|
|
ret = duer_uninit_system_info();
|
|
if (ret != DUER_OK) {
|
|
DUER_LOGE("Sys Info: uninit system info failed ret: %d", ret);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
#endif
|