mirror of
https://gitee.com/Lamdonn/varch.git
synced 2025-12-06 08:46:42 +08:00
Add cpul, date and unitt
This commit is contained in:
parent
ca9bdaad24
commit
a2125c2b9f
10
README.en.md
10
README.en.md
@ -2,6 +2,11 @@
|
||||
|
||||

|
||||
|
||||
[](https://gitee.com/Lamdonn/varch)
|
||||
[](LICENSE)
|
||||
[](Lamdonn@163.com)
|
||||

|
||||
|
||||
## Introduction
|
||||
|
||||
[中文版](README.md)
|
||||
@ -30,6 +35,7 @@ It has the characteristics of **simplicity, universality, and efficiency**, with
|
||||
| valloc | 01.00.00 | [link](/doc/valloc.md) | [path](./source/01_general) | Dynamic memory usage testing tool
|
||||
| vlog | 01.01.00 | [link](/doc/vlog.md) | [path](./source/01_general) | Log output module
|
||||
| intl | 01.00.00 | [link](/doc/intl.md) | [path](./source/01_general) | Large integer arithmetic module
|
||||
| date | 01.00.00 | [link](/doc/date.md) | [path](./source/01_general) | Date calculation module, calculating date differences, printing calendars, etc
|
||||
| vctype | 01.00.00 | [link](/doc/vctype.md) | [path](./source/02_vstd) | Similar to the C standard library ctype
|
||||
| vmath | 01.00.00 | [link](/doc/vmath.md) | [path](./source/02_vstd) | Similar to the C standard library math
|
||||
| vmem | 01.00.00 | [link](/doc/vmem.md) | [path](./source/02_vstd) | Simple implementation of memory pool
|
||||
@ -62,6 +68,10 @@ It has the characteristics of **simplicity, universality, and efficiency**, with
|
||||
| json | 01.00.00 | [link](/doc/json.md) | [path](./source/05_parser) | JSON file parsing generator
|
||||
| txls | 01.00.00 | [link](/doc/txls.md) | [path](./source/05_parser) | TXLS file parsing generator
|
||||
| xml | 01.00.00 | [link](/doc/xml.md) | [path](./source/05_parser) | XML file parsing generator
|
||||
| ramt | 01.00.00 | [link](/doc/ramt.md) | [path](./source/06_performance) | RAM test module
|
||||
| romt | 01.00.00 | [link](/doc/romt.md) | [path](./source/06_performance) | ROM test module
|
||||
| cpul | 01.00.00 | [link](/doc/cpul.md) | [path](./source/06_performance) | CPU load test module, including obtaining and increasing load
|
||||
| unitt | 01.00.00 | [link](/doc/unitt.md) | [path](./source/06_performance) | Simple unit test module
|
||||
|
||||
## Usage
|
||||
|
||||
|
||||
10
README.md
10
README.md
@ -2,6 +2,11 @@
|
||||
|
||||

|
||||
|
||||
[](https://gitee.com/Lamdonn/varch)
|
||||
[](LICENSE)
|
||||
[](Lamdonn@163.com)
|
||||

|
||||
|
||||
## 介绍
|
||||
|
||||
[English version](README.en.md)
|
||||
@ -30,6 +35,7 @@ varch(we-architecture,意为我们的框架库)是嵌入式C语言常用
|
||||
| valloc | 01.00.00 | [link](/doc/valloc.md) | [path](./source/01_general) | 动态内存使用测试工具
|
||||
| vlog | 01.01.00 | [link](/doc/vlog.md) | [path](./source/01_general) | 日志输出模块
|
||||
| intl | 01.00.00 | [link](/doc/intl.md) | [path](./source/01_general) | 大型整数运算模块
|
||||
| date | 01.00.00 | [link](/doc/date.md) | [path](./source/01_general) | 日期计算模块,计算日期差、打印日历等
|
||||
| vctype | 01.00.00 | [link](/doc/vctype.md) | [path](./source/02_vstd) | 类似于C标准库ctype
|
||||
| vmath | 01.00.00 | [link](/doc/vmath.md) | [path](./source/02_vstd) | 类似于C标准库math
|
||||
| vmem | 01.00.00 | [link](/doc/vmem.md) | [path](./source/02_vstd) | 内存池的简单实现
|
||||
@ -62,6 +68,10 @@ varch(we-architecture,意为我们的框架库)是嵌入式C语言常用
|
||||
| json | 01.00.00 | [link](/doc/json.md) | [path](./source/05_parser) | JSON文件解析生成器
|
||||
| txls | 01.00.00 | [link](/doc/txls.md) | [path](./source/05_parser) | TXLS文件解析生成器
|
||||
| xml | 01.00.00 | [link](/doc/xml.md) | [path](./source/05_parser) | XML文件解析生成器
|
||||
| ramt | 01.00.00 | [link](/doc/ramt.md) | [path](./source/06_performance) | RAM测试模块
|
||||
| romt | 01.00.00 | [link](/doc/romt.md) | [path](./source/06_performance) | ROM测试模块
|
||||
| cpul | 01.00.00 | [link](/doc/cpul.md) | [path](./source/06_performance) | CPU负载测试模块,包含获取和增加负载
|
||||
| unitt | 01.00.00 | [link](/doc/unitt.md) | [path](./source/06_performance) | 简易的单元测试模块
|
||||
|
||||
## 使用说明
|
||||
|
||||
|
||||
8
makefile
8
makefile
@ -58,6 +58,12 @@ include $(TESTSPACE)/test.mk
|
||||
TESTSRC += $(APPLICATION_PATH)/main.c
|
||||
TESTSRC += $(TEST_SRC)
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
UNAME := Windows
|
||||
else
|
||||
UNAME := $(shell uname -s)
|
||||
endif
|
||||
|
||||
##################################################################################
|
||||
### recipes
|
||||
##################################################################################
|
||||
@ -79,7 +85,7 @@ LIBP ?= /usr
|
||||
|
||||
# link
|
||||
${TARP}:$(OBJS)
|
||||
mkdir -p $(dir $@)
|
||||
@ mkdir -p $(dir $@)
|
||||
@ $(CC) $(CFLAG) $(OBJS) -o $(TARP) $(LIBS)
|
||||
|
||||
# compile
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
#include "init.h"
|
||||
#if defined(_WIN32)
|
||||
#include <conio.h>
|
||||
#include <windows.h>
|
||||
#elif defined(__unix)
|
||||
#include <termios.h>
|
||||
#endif
|
||||
@ -39,9 +40,9 @@ static int kbhit(void)
|
||||
if (ch != EOF)
|
||||
{
|
||||
ungetc(ch, stdin);
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -67,8 +68,8 @@ static int into(int argc, char *argv[])
|
||||
|
||||
static void console_main(void)
|
||||
{
|
||||
int c;
|
||||
if (!kbhit())
|
||||
int c = 0;
|
||||
if (kbhit())
|
||||
{
|
||||
c = getchar();
|
||||
#if CONSOLE_DEBUG == 1
|
||||
@ -124,6 +125,7 @@ void console_init(void)
|
||||
if (!console_task) return;
|
||||
|
||||
printf("console init! task<%d>!\r\n", console_task);
|
||||
printf("Press `Enter` to enter the console, input `cmd -h` to get help!\r\n");
|
||||
|
||||
/* Export into command */
|
||||
command_export("into", into);
|
||||
|
||||
234
source/01_general/date.c
Normal file
234
source/01_general/date.c
Normal file
@ -0,0 +1,234 @@
|
||||
/*********************************************************************************************************
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* file description
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* \file date.c
|
||||
* \unit date
|
||||
* \brief This is a simple date calculate module for C language
|
||||
* \author Lamdonn
|
||||
* \version v1.0.0
|
||||
* \license GPL-2.0
|
||||
* \copyright Copyright (C) 2023 Lamdonn.
|
||||
********************************************************************************************************/
|
||||
#include "date.h"
|
||||
|
||||
// TODO: 1582.10.04 - 1582.10.15
|
||||
|
||||
/**
|
||||
* \brief Check if a year is a leap year.
|
||||
* \param[in] year: The year to check.
|
||||
* \return 1 if the year is a leap year, 0 otherwise.
|
||||
*/
|
||||
uint8_t date_isleap(uint16_t year)
|
||||
{
|
||||
return (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the number of days in a century.
|
||||
* \param[in] century: The century to evaluate.
|
||||
* \return Number of days in the given century.
|
||||
*/
|
||||
uint32_t date_century_days(uint16_t century)
|
||||
{
|
||||
if (century == 0) return 0u; // No days in century 0
|
||||
return (century % 4 == 0) ? 36525u : 36524u; // 25 leap years in 400 years
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the number of days in a year.
|
||||
* \param[in] year: The year to evaluate.
|
||||
* \return Number of days in the given year.
|
||||
*/
|
||||
uint32_t date_year_days(uint16_t year)
|
||||
{
|
||||
if (year == 0) return 0u; // No days in year 0
|
||||
return date_isleap(year) ? 366u : 365u;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the number of days in a month of a given year.
|
||||
* \param[in] year: The year of the month.
|
||||
* \param[in] month: The month to evaluate (1-12).
|
||||
* \return Number of days in the specified month of the specified year.
|
||||
*/
|
||||
uint32_t date_month_days(uint16_t year, uint8_t month)
|
||||
{
|
||||
if (year == 0) return 0; // No valid month days for year 0
|
||||
switch (month)
|
||||
{
|
||||
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
|
||||
return 31; // Months with 31 days
|
||||
case 4: case 6: case 9: case 11:
|
||||
return 30; // Months with 30 days
|
||||
case 2:
|
||||
return date_isleap(year) ? 29 : 28; // February days depending on leap year
|
||||
default:
|
||||
return 0; // Invalid month
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Validate a date.
|
||||
* \param[in] date: The date structure to validate.
|
||||
* \return 1 if the date is valid, 0 otherwise.
|
||||
*/
|
||||
uint8_t date_isvalid(DATE date)
|
||||
{
|
||||
if (date.year == 0 || date.month == 0 || date.day == 0) return 0; // Year, month or day 0 is not valid
|
||||
return (date_month_days(date.year, date.month) >= date.day);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Calculate the total number of days from a given date to a base date.
|
||||
* \param[in] date: The date to calculate the total days for.
|
||||
* \return Total number of days from a base date to the given date, 0 if invalid.
|
||||
*/
|
||||
uint32_t date_current_days(DATE date)
|
||||
{
|
||||
uint32_t days = 0;
|
||||
uint16_t year = 1;
|
||||
uint8_t month = 1;
|
||||
|
||||
// Validate the input date; return 0 if invalid
|
||||
if (!date_isvalid(date)) return 0;
|
||||
|
||||
// Count days for complete centuries
|
||||
for ( ; year + 2000 <= date.year; year += 2000) days += 730485u;
|
||||
// Count days for complete centuries within the current century
|
||||
for ( ; year + 100 <= date.year; year += 100) days += date_century_days((year / 100) + 1);
|
||||
// Count days for complete years within the current century
|
||||
for ( ; year + 1 <= date.year; year++) days += date_year_days(year);
|
||||
// Count days for completed months in the current year
|
||||
for ( ; month < date.month; month++) days += date_month_days(date.year, month);
|
||||
// Add the days of the current month
|
||||
days += date.day;
|
||||
|
||||
return days;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the week number of a given date based on the total days.
|
||||
* \param[in] date: The date to evaluate.
|
||||
* \return The week number [1, 7] for the specified date (Mon | Tue | Wed | Thu | Fri | Sat | Sun), 0 if invalid.
|
||||
*/
|
||||
uint32_t date_get_week(DATE date)
|
||||
{
|
||||
#define bias 0 // Adjust to week start
|
||||
uint32_t days = date_current_days(date);
|
||||
uint32_t week = 0;
|
||||
|
||||
// If days is 0, return 0 indicating invalid date
|
||||
if (days == 0) return 0;
|
||||
|
||||
week = (days + bias) % 7;
|
||||
if (week == 0) week = 7;
|
||||
|
||||
return week;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Calculate the difference in days between two dates.
|
||||
* \param[in] date1: The first date.
|
||||
* \param[in] date2: The second date.
|
||||
* \return The difference in days between the two dates. Returns 0 if either date is invalid.
|
||||
*/
|
||||
int32_t date_diff_days(DATE date1, DATE date2)
|
||||
{
|
||||
uint32_t days1 = date_current_days(date1);
|
||||
uint32_t days2 = date_current_days(date2); // Corrected to use date2
|
||||
|
||||
// Return 0 if either date is invalid
|
||||
if (days1 == 0 || days2 == 0) return 0;
|
||||
|
||||
return (int32_t)(days1 - days2);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert a number of days to a DATE structure.
|
||||
* \param[in] days: The number of days to convert.
|
||||
* \return A DATE structure representing the converted days.
|
||||
*/
|
||||
DATE date_from_days(uint32_t days)
|
||||
{
|
||||
DATE date = {1, 1, 1}; // Initialize to base date (1/1/1)
|
||||
uint32_t tdays = 0;
|
||||
|
||||
// Return zero date if days are 0
|
||||
if (days == 0) return DATE(0,0,0);
|
||||
|
||||
// Convert days to years
|
||||
for ( ; days > 730485; days -= 730485) date.year += 2000;
|
||||
for ( ; days > (tdays = date_century_days((date.year / 100) + 1)); days -= tdays) date.year += 100;
|
||||
for ( ; days > (tdays = date_year_days(date.year)); days -= tdays) date.year++;
|
||||
for ( ; days > (tdays = date_month_days(date.year, date.month)); days -= tdays) date.month++;
|
||||
date.day = days;
|
||||
|
||||
return date;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Offset a date by a certain number of days.
|
||||
* \param[in] date: The date to offset.
|
||||
* \param[in] days: The number of days to offset (can be negative).
|
||||
* \return A new DATE structure after applying the offset, or a zero date if invalid.
|
||||
*/
|
||||
DATE date_offset(DATE date, int32_t days)
|
||||
{
|
||||
if (!date_isvalid(date)) return DATE(0,0,0); // Return zero date if invalid
|
||||
return date_from_days(date_current_days(date) + days);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Show the calendar for a specific month and year.
|
||||
* \param[in] year: The year of the calendar to show.
|
||||
* \param[in] month: The month of the calendar to show.
|
||||
*/
|
||||
void date_show(uint16_t year, uint8_t month)
|
||||
{
|
||||
DATE date = {year, month, 1};
|
||||
uint32_t days;
|
||||
uint32_t tday = 1;
|
||||
uint32_t week = 0;
|
||||
int len = 0;
|
||||
|
||||
days = date_month_days(year, month);
|
||||
if (days == 0)
|
||||
{
|
||||
printf("[ERROR] Invalid date!\r\n");
|
||||
return; // Exit if the date is invalid
|
||||
}
|
||||
|
||||
week = date_get_week(date) % 7; // Get the starting day of the week
|
||||
|
||||
// Print the calendar header
|
||||
printf("+-----------------------------------------+\r\n");
|
||||
len = printf("| %04d/%02d", year, month); while (len++ < 42) printf(" "); printf("|\r\n");
|
||||
printf("+-----------------------------------------+\r\n");
|
||||
printf("| Sun | Mon | Tue | Wed | Thu | Fri | Sat |\r\n");
|
||||
printf("+-----------------------------------------+\r\n");
|
||||
|
||||
// Print the days of the month
|
||||
while (tday <= days)
|
||||
{
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
if (i == 0) printf("|"); // Start of the week
|
||||
|
||||
if (i == week && tday <= days)
|
||||
{
|
||||
printf(" %3u |", tday); // Print the current day
|
||||
tday++;
|
||||
week = (week + 1) % 7; // Move to the next week day
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" |"); // Empty space for days not in the current month
|
||||
}
|
||||
|
||||
if (i == 6) printf("\r\n"); // End of the week
|
||||
}
|
||||
}
|
||||
|
||||
printf("+-----------------------------------------+\r\n"); // End of the calendar
|
||||
}
|
||||
120
source/01_general/date.h
Normal file
120
source/01_general/date.h
Normal file
@ -0,0 +1,120 @@
|
||||
/*********************************************************************************************************
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* file description
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* \file date.h
|
||||
* \unit date
|
||||
* \brief This is a simple date calculate module for C language
|
||||
* \author Lamdonn
|
||||
* \version v1.0.0
|
||||
* \license GPL-2.0
|
||||
* \copyright Copyright (C) 2023 Lamdonn.
|
||||
********************************************************************************************************/
|
||||
#ifndef __date_H
|
||||
#define __date_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Version infomation */
|
||||
|
||||
#define DATE_V_MAJOR 1
|
||||
#define DATE_V_MINOR 0
|
||||
#define DATE_V_PATCH 0
|
||||
|
||||
typedef struct {
|
||||
uint16_t year; /**< Year component of the date */
|
||||
uint8_t month; /**< Month component of the date */
|
||||
uint8_t day; /**< Day component of the date */
|
||||
} DATE;
|
||||
|
||||
/**
|
||||
* \brief Macro to create a DATE structure instance.
|
||||
* \param[in] y: Year component of the date.
|
||||
* \param[in] m: Month component of the date (1-12).
|
||||
* \param[in] d: Day component of the date (1-31 depending on the month).
|
||||
* \return A DATE structure initialized with the specified year, month, and day.
|
||||
*/
|
||||
#define DATE(y, m, d) (DATE){.year=(y), .month=(m), .day=(d)}
|
||||
|
||||
/**
|
||||
* \brief Check if a year is a leap year.
|
||||
* \param[in] year: The year to check.
|
||||
* \return 1 if the year is a leap year, 0 otherwise.
|
||||
*/
|
||||
uint8_t date_isleap(uint16_t year);
|
||||
|
||||
/**
|
||||
* \brief Validate a date.
|
||||
* \param[in] date: The date structure to validate.
|
||||
* \return 1 if the date is valid, 0 otherwise.
|
||||
*/
|
||||
uint8_t date_isvalid(DATE date);
|
||||
|
||||
/**
|
||||
* \brief Get the number of days in a century.
|
||||
* \param[in] century: The century to evaluate.
|
||||
* \return Number of days in the given century.
|
||||
*/
|
||||
uint32_t date_century_days(uint16_t century);
|
||||
|
||||
/**
|
||||
* \brief Get the number of days in a year.
|
||||
* \param[in] year: The year to evaluate.
|
||||
* \return Number of days in the given year.
|
||||
*/
|
||||
uint32_t date_year_days(uint16_t year);
|
||||
|
||||
/**
|
||||
* \brief Get the number of days in a month of a given year.
|
||||
* \param[in] year: The year of the month.
|
||||
* \param[in] month: The month to evaluate (1-12).
|
||||
* \return Number of days in the specified month of the specified year.
|
||||
*/
|
||||
uint32_t date_month_days(uint16_t year, uint8_t month);
|
||||
|
||||
/**
|
||||
* \brief Get the week number of a given date based on the total days.
|
||||
* \param[in] date: The date to evaluate.
|
||||
* \return The week number [1, 7] for the specified date (Mon | Tue | Wed | Thu | Fri | Sat | Sun), 0 if invalid.
|
||||
*/
|
||||
uint32_t date_get_week(DATE date);
|
||||
|
||||
/**
|
||||
* \brief Calculate the total number of days from a given date to a base date.
|
||||
* \param[in] date: The date to calculate the total days for.
|
||||
* \return Total number of days from a base date to the given date, 0 if invalid.
|
||||
*/
|
||||
uint32_t date_current_days(DATE date);
|
||||
|
||||
/**
|
||||
* \brief Calculate the difference in days between two dates.
|
||||
* \param[in] date1: The first date.
|
||||
* \param[in] date2: The second date.
|
||||
* \return The difference in days between the two dates. Returns 0 if either date is invalid.
|
||||
*/
|
||||
int32_t date_diff_days(DATE date1, DATE date2);
|
||||
|
||||
/**
|
||||
* \brief Convert a number of days to a DATE structure.
|
||||
* \param[in] days: The number of days to convert.
|
||||
* \return A DATE structure representing the converted days.
|
||||
*/
|
||||
DATE date_from_days(uint32_t days);
|
||||
|
||||
/**
|
||||
* \brief Offset a date by a certain number of days.
|
||||
* \param[in] date: The date to offset.
|
||||
* \param[in] days: The number of days to offset (can be negative).
|
||||
* \return A new DATE structure after applying the offset, or a zero date if invalid.
|
||||
*/
|
||||
DATE date_offset(DATE date, int32_t days);
|
||||
|
||||
/**
|
||||
* \brief Show the calendar for a specific month and year.
|
||||
* \param[in] year: The year of the calendar to show.
|
||||
* \param[in] month: The month of the calendar to show.
|
||||
*/
|
||||
void date_show(uint16_t year, uint8_t month);
|
||||
|
||||
#endif
|
||||
211
source/06_performance/cpul.c
Normal file
211
source/06_performance/cpul.c
Normal file
@ -0,0 +1,211 @@
|
||||
/*********************************************************************************************************
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* file description
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* \file cpul.c
|
||||
* \unit cpul
|
||||
* \brief This is a simple cpuload module for C language
|
||||
* \author Lamdonn
|
||||
* \version v1.0.0
|
||||
* \license GPL-2.0
|
||||
* \copyright Copyright (C) 2023 Lamdonn.
|
||||
********************************************************************************************************/
|
||||
#include "cpul.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// Buffer for CRC calculation, initialized with some values
|
||||
uint8_t calbuffer[CPUL_GEN_BSIZE] = {'A', 'B', 0};
|
||||
|
||||
/**
|
||||
* \brief Adjust the refined load based on current and target loads.
|
||||
*
|
||||
* This function controls the refined load adjustment by comparing
|
||||
* the current load with the target load and modifying the refined
|
||||
* load accordingly.
|
||||
*
|
||||
* \param[in] cpul: Pointer to the CPUL instance.
|
||||
* \return Returns the adjusted refined load value.
|
||||
*/
|
||||
static uint32_t controller(CPUL *cpul)
|
||||
{
|
||||
// If the current load is less than the target load
|
||||
if (cpul->ctrl.cload < cpul->ctrl.tload)
|
||||
{
|
||||
// If adding resolution to refined load does not exceed its current value
|
||||
if (cpul->ctrl.refine + cpul->resolution > cpul->ctrl.refine)
|
||||
{
|
||||
// Increase the refined load by the resolution value
|
||||
cpul->ctrl.refine += cpul->resolution;
|
||||
}
|
||||
}
|
||||
// If the current load is greater than target load + 1
|
||||
else if (cpul->ctrl.cload > (cpul->ctrl.tload + 1))
|
||||
{
|
||||
// If the refined load is greater than or equal to the resolution
|
||||
if (cpul->ctrl.refine >= cpul->resolution)
|
||||
{
|
||||
// Decrease the refined load by the resolution value
|
||||
cpul->ctrl.refine -= cpul->resolution;
|
||||
}
|
||||
}
|
||||
|
||||
return cpul->ctrl.refine; // Return the adjusted refined load
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Calculate CRC8 checksum.
|
||||
*
|
||||
* This function computes the CRC8 checksum for a given data buffer.
|
||||
* It iterates through each byte of data and processes it to generate
|
||||
* the CRC value.
|
||||
*
|
||||
* \param[in] data: Pointer to the data buffer.
|
||||
* \param[in] len: Length of the data buffer.
|
||||
* \return Returns the calculated CRC8 value.
|
||||
*/
|
||||
static uint8_t crc8(uint8_t *data, uint32_t len)
|
||||
{
|
||||
uint8_t i; // Loop index for bit processing
|
||||
uint8_t crc = 0; // Initialize CRC value to 0
|
||||
while (len--) // Process each byte in the data buffer
|
||||
{
|
||||
crc ^= *data++; // XOR the current byte with the CRC value
|
||||
for (i = 0; i < 8; i++) // Process each bit of the byte
|
||||
{
|
||||
if (crc & 0x80) // If the highest bit of CRC is set
|
||||
crc = (crc << 1) ^ 0x07; // Shift left and XOR with the polynomial
|
||||
else
|
||||
crc <<= 1; // Just shift left if the highest bit is not set
|
||||
}
|
||||
}
|
||||
return crc; // Return the calculated CRC8 value
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Update the granularity of the load control.
|
||||
*
|
||||
* This function updates the calbuffer values based on the refined load
|
||||
* using CRC8 checksum for each iteration specified by the input parameter.
|
||||
*
|
||||
* \param[in] input: Number of iterations to update the buffer.
|
||||
* \return none.
|
||||
*/
|
||||
static void granularity(uint32_t input)
|
||||
{
|
||||
// Loop through the specified number of iterations
|
||||
for (uint32_t i = 0; i < input; i++)
|
||||
{
|
||||
// Update calbuffer with a CRC8 value calculated from the current buffer
|
||||
calbuffer[calbuffer[0] % sizeof(calbuffer)] = crc8(calbuffer, sizeof(calbuffer));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Initialize the CPUL instance.
|
||||
*
|
||||
* This function initializes the CPUL structure to default values
|
||||
* and checks for valid pointers.
|
||||
*
|
||||
* \param[in] cpul: Pointer to the CPUL instance.
|
||||
* \return Returns CPUL_E_OK on success, otherwise an error code.
|
||||
*/
|
||||
int cpul_init(CPUL *cpul)
|
||||
{
|
||||
// Check if the cpul pointer is valid
|
||||
if (!cpul) return CPUL_E_INVALID;
|
||||
// Check if the raw function pointer is valid
|
||||
if (!cpul->raw) return CPUL_E_RAW;
|
||||
|
||||
cpul->ctrl.cload = 0xFFFF; // Set current load to untested value
|
||||
cpul->ctrl.tload = 0; // Default target load to zero (no load increase)
|
||||
cpul->ctrl.refine = 0; // Initialize refined load
|
||||
|
||||
return CPUL_E_OK; // Initialization successful
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the current CPU load.
|
||||
*
|
||||
* This function retrieves the current load from the CPUL instance
|
||||
* and checks for validity of parameters and state.
|
||||
*
|
||||
* \param[in] cpul: Pointer to the CPUL instance.
|
||||
* \param[out] load: Pointer to store the current load value.
|
||||
* \return Returns CPUL_E_OK on success, otherwise an error code.
|
||||
*/
|
||||
int cpul_get(CPUL *cpul, uint16_t *load)
|
||||
{
|
||||
// Check if the cpul pointer is valid
|
||||
if (!cpul) return CPUL_E_INVALID;
|
||||
// Check if the raw function pointer is valid
|
||||
if (!cpul->raw) return CPUL_E_RAW;
|
||||
// Check if the load parameter is valid
|
||||
if (!load) return CPUL_E_PARA;
|
||||
|
||||
// If current load is still untested, return an error
|
||||
if (cpul->ctrl.cload == 0xFFFF) return CPUL_E_NTEST;
|
||||
// Check if the current load exceeds the maximum allowed value
|
||||
if (cpul->ctrl.cload > 10000) return CPUL_E_OVER;
|
||||
|
||||
*load = cpul->ctrl.cload; // Retrieve the current load value
|
||||
|
||||
return CPUL_E_OK; // Success
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the target CPU load.
|
||||
*
|
||||
* This function sets the target load for the CPUL instance and checks for valid parameters.
|
||||
*
|
||||
* \param[in] cpul: Pointer to the CPUL instance.
|
||||
* \param[in] load: Target load value to set.
|
||||
* \return Returns CPUL_E_OK on success, otherwise an error code.
|
||||
*/
|
||||
int cpul_set(CPUL *cpul, uint16_t load)
|
||||
{
|
||||
// Check if the cpul pointer is valid
|
||||
if (!cpul) return CPUL_E_INVALID;
|
||||
// Check if the raw function pointer is valid
|
||||
if (!cpul->raw) return CPUL_E_RAW;
|
||||
// Check if the load parameter is zero
|
||||
if (!load) return CPUL_E_PARA;
|
||||
|
||||
// Check if the load exceeds the maximum allowed value
|
||||
if (load > 10000) return CPUL_E_OVER;
|
||||
|
||||
cpul->ctrl.tload = load; // Set the target load
|
||||
|
||||
return CPUL_E_OK; // Success
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Execute a CPUL management task.
|
||||
*
|
||||
* This function executes a task to manage the CPU load based on
|
||||
* the current and target load values.
|
||||
*
|
||||
* \param[in] cpul: Pointer to the CPUL instance.
|
||||
* \return Returns CPUL_E_OK on success, otherwise an error code.
|
||||
*/
|
||||
int cpul_task(CPUL *cpul)
|
||||
{
|
||||
// Check if the cpul pointer is valid
|
||||
if (!cpul) return CPUL_E_INVALID;
|
||||
// Check if the raw function pointer is valid
|
||||
if (!cpul->raw) return CPUL_E_RAW;
|
||||
|
||||
// Call the raw function to get the current load value
|
||||
cpul->ctrl.cload = cpul->raw(cpul->coreid);
|
||||
|
||||
// If the target load is not zero, perform load management
|
||||
if (cpul->ctrl.tload != 0)
|
||||
{
|
||||
// Adjust the refined load based on current and target load
|
||||
cpul->ctrl.refine = controller(cpul);
|
||||
// Update granularity based on the refined load
|
||||
granularity(cpul->ctrl.refine);
|
||||
}
|
||||
|
||||
return CPUL_E_OK; // Success
|
||||
}
|
||||
100
source/06_performance/cpul.h
Normal file
100
source/06_performance/cpul.h
Normal file
@ -0,0 +1,100 @@
|
||||
/*********************************************************************************************************
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* file description
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* \file cpul.h
|
||||
* \unit cpul
|
||||
* \brief This is a simple cpuload module for C language
|
||||
* \author Lamdonn
|
||||
* \version v1.0.0
|
||||
* \license GPL-2.0
|
||||
* \copyright Copyright (C) 2023 Lamdonn.
|
||||
********************************************************************************************************/
|
||||
#ifndef __cpul_H
|
||||
#define __cpul_H
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
/* Version infomation */
|
||||
#define CPUL_V_MAJOR 0
|
||||
#define CPUL_V_MINOR 1
|
||||
#define CPUL_V_PATcH 0
|
||||
|
||||
#define CPUL_GEN_BSIZE 4
|
||||
|
||||
#define CPUL_E_OK 0 // Success
|
||||
#define CPUL_E_INVALID 1 // Invalid `CPUL` pointer
|
||||
#define CPUL_E_RAW 2 // Invalid raw function
|
||||
#define CPUL_E_PARA 3 // Invalid parameter
|
||||
#define CPUL_E_NTEST 4 // CPUL load testing has not started
|
||||
#define CPUL_E_OVER 5 // CPUL load exceeds range
|
||||
|
||||
typedef uint16_t (*cpul_raw_t)(uint8_t coreid); // Type definition for the raw CPUL load function
|
||||
|
||||
/**
|
||||
* \brief Structure to control CPUL load parameters.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t refine; ///< Refined load value
|
||||
uint16_t cload; ///< Current load value
|
||||
uint16_t tload; ///< Target load value
|
||||
} CPUL_CTRL;
|
||||
|
||||
/**
|
||||
* \brief Structure to represent a CPU Load Manager.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t coreid; ///< Core ID
|
||||
cpul_raw_t raw; ///< Pointer to the raw CPUL load function
|
||||
uint32_t resolution; ///< Resolution of the load control
|
||||
CPUL_CTRL ctrl; ///< Control structure for CPUL management
|
||||
} CPUL;
|
||||
|
||||
/**
|
||||
* \brief Initialize the CPUL instance.
|
||||
*
|
||||
* This function initializes the CPUL structure to default values
|
||||
* and checks for valid pointers.
|
||||
*
|
||||
* \param[in] cpul: Pointer to the CPUL instance.
|
||||
* \return Returns CPUL_E_OK on success, otherwise an error code.
|
||||
*/
|
||||
int cpul_init(CPUL *cpul);
|
||||
|
||||
/**
|
||||
* \brief Get the current CPU load.
|
||||
*
|
||||
* This function retrieves the current load from the CPUL instance
|
||||
* and checks for validity of parameters and state.
|
||||
*
|
||||
* \param[in] cpul: Pointer to the CPUL instance.
|
||||
* \param[out] load: Pointer to store the current load value.
|
||||
* \return Returns CPUL_E_OK on success, otherwise an error code.
|
||||
*/
|
||||
int cpul_get(CPUL *cpul, uint16_t *load);
|
||||
|
||||
/**
|
||||
* \brief Set the target CPU load.
|
||||
*
|
||||
* This function sets the target load for the CPUL instance and checks for valid parameters.
|
||||
*
|
||||
* \param[in] cpul: Pointer to the CPUL instance.
|
||||
* \param[in] load: Target load value to set.
|
||||
* \return Returns CPUL_E_OK on success, otherwise an error code.
|
||||
*/
|
||||
int cpul_set(CPUL *cpul, uint16_t load);
|
||||
|
||||
/**
|
||||
* \brief Execute a CPUL management task.
|
||||
*
|
||||
* This function executes a task to manage the CPU load based on
|
||||
* the current and target load values.
|
||||
*
|
||||
* \param[in] cpul: Pointer to the CPUL instance.
|
||||
* \return Returns CPUL_E_OK on success, otherwise an error code.
|
||||
*/
|
||||
int cpul_task(CPUL *cpul);
|
||||
|
||||
#endif
|
||||
306
source/06_performance/unitt.c
Normal file
306
source/06_performance/unitt.c
Normal file
@ -0,0 +1,306 @@
|
||||
/*********************************************************************************************************
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* file description
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* \file unitt.c
|
||||
* \unit unitt
|
||||
* \brief This is a simple unit test module for C language
|
||||
* \author Lamdonn
|
||||
* \version v1.0.0
|
||||
* \license GPL-2.0
|
||||
* \copyright Copyright (C) 2023 Lamdonn.
|
||||
********************************************************************************************************/
|
||||
#include "unitt.h"
|
||||
|
||||
/**
|
||||
* \brief Assert that a condition is true.
|
||||
*
|
||||
* This function checks if the given condition is true. If it is false,
|
||||
* it outputs an assertion failure message and returns a failure code.
|
||||
*
|
||||
* \param[in] condition: The condition to evaluate.
|
||||
* \param[in] message: The message to display if the assertion fails.
|
||||
* \return Returns UNITT_E_OK if the assertion passes, otherwise UNITT_E_FAIL.
|
||||
*/
|
||||
int unitt_det_true(int condition, const char* message)
|
||||
{
|
||||
if (!condition)
|
||||
{
|
||||
fprintf(stderr, "Assertion Failed: %s\n", message);
|
||||
return UNITT_E_FAIL;
|
||||
}
|
||||
|
||||
return UNITT_E_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Assert that a condition is false.
|
||||
*
|
||||
* This function checks if the given condition is false. If it is true,
|
||||
* it outputs an assertion failure message and returns a failure code.
|
||||
*
|
||||
* \param[in] condition: The condition to evaluate.
|
||||
* \param[in] message: The message to display if the assertion fails.
|
||||
* \return Returns UNITT_E_OK if the assertion passes, otherwise UNITT_E_FAIL.
|
||||
*/
|
||||
int unitt_det_false(int condition, const char* message)
|
||||
{
|
||||
if (condition)
|
||||
{
|
||||
fprintf(stderr, "Assertion Failed: %s\n", message);
|
||||
return UNITT_E_FAIL;
|
||||
}
|
||||
|
||||
return UNITT_E_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Assert that two integers are equal.
|
||||
*
|
||||
* This function checks whether the expected and actual values are equal.
|
||||
* If they are not equal, it outputs an assertion failure message with
|
||||
* both values and returns a failure code.
|
||||
*
|
||||
* \param[in] expected: The expected value.
|
||||
* \param[in] actual: The actual value.
|
||||
* \param[in] message: The message to display if the assertion fails.
|
||||
* \return Returns UNITT_E_OK if the assertion passes, otherwise UNITT_E_FAIL.
|
||||
*/
|
||||
int unitt_det_equal(int expected, int actual, const char* message)
|
||||
{
|
||||
if (expected != actual)
|
||||
{
|
||||
fprintf(stderr, "Assertion Failed: %s (Expected: %d, Actual: %d)\n", message, expected, actual);
|
||||
return UNITT_E_FAIL;
|
||||
}
|
||||
|
||||
return UNITT_E_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Assert that two integers are not equal.
|
||||
*
|
||||
* This function checks whether the expected and actual values are not equal.
|
||||
* If they are equal, it outputs an assertion failure message and returns a failure code.
|
||||
*
|
||||
* \param[in] expected: The expected value.
|
||||
* \param[in] actual: The actual value.
|
||||
* \param[in] message: The message to display if the assertion fails.
|
||||
* \return Returns UNITT_E_OK if the assertion passes, otherwise UNITT_E_FAIL.
|
||||
*/
|
||||
int unitt_det_nequal(int expected, int actual, const char* message)
|
||||
{
|
||||
if (expected == actual)
|
||||
{
|
||||
fprintf(stderr, "Assertion Failed: %s (Expected not equal to Actual)\n", message);
|
||||
return UNITT_E_FAIL;
|
||||
}
|
||||
|
||||
return UNITT_E_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Assert that a pointer is NULL.
|
||||
*
|
||||
* This function checks whether the given pointer is NULL. If it is not NULL,
|
||||
* it outputs an assertion failure message with the pointer's value and returns a failure code.
|
||||
*
|
||||
* \param[in] pointer: The pointer to evaluate.
|
||||
* \param[in] message: The message to display if the assertion fails.
|
||||
* \return Returns UNITT_E_OK if the assertion passes, otherwise UNITT_E_FAIL.
|
||||
*/
|
||||
int unitt_det_null(void* pointer, const char* message)
|
||||
{
|
||||
if (pointer != NULL)
|
||||
{
|
||||
fprintf(stderr, "Assertion Failed: %s (Expected NULL, Actual: %p)\n", message, pointer);
|
||||
return UNITT_E_FAIL;
|
||||
}
|
||||
|
||||
return UNITT_E_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Assert that a pointer is not NULL.
|
||||
*
|
||||
* This function checks whether the given pointer is not NULL. If it is NULL,
|
||||
* it outputs an assertion failure message and returns a failure code.
|
||||
*
|
||||
* \param[in] pointer: The pointer to evaluate.
|
||||
* \param[in] message: The message to display if the assertion fails.
|
||||
* \return Returns UNITT_E_OK if the assertion passes, otherwise UNITT_E_FAIL.
|
||||
*/
|
||||
int unitt_det_nnull(void* pointer, const char* message)
|
||||
{
|
||||
if (pointer == NULL)
|
||||
{
|
||||
fprintf(stderr, "Assertion Failed: %s (Expected non-NULL, Actual: NULL)\n", message);
|
||||
return UNITT_E_FAIL;
|
||||
}
|
||||
|
||||
return UNITT_E_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Assert that two floats are approximately equal.
|
||||
*
|
||||
* This function checks whether the expected and actual float values are approximately equal
|
||||
* within a given epsilon range. If they are not, it outputs an assertion failure message
|
||||
* with both values and returns a failure code.
|
||||
*
|
||||
* \param[in] expected: The expected float value.
|
||||
* \param[in] actual: The actual float value.
|
||||
* \param[in] epsilon: The acceptable difference between the two values.
|
||||
* \param[in] message: The message to display if the assertion fails.
|
||||
* \return Returns UNITT_E_OK if the assertion passes, otherwise UNITT_E_FAIL.
|
||||
*/
|
||||
int unitt_det_float(float expected, float actual, float epsilon, const char* message)
|
||||
{
|
||||
if (fabs(expected - actual) > epsilon)
|
||||
{
|
||||
fprintf(stderr, "Assertion Failed: %s (Expected: %.6f, Actual: %.6f)\n", message, expected, actual);
|
||||
return UNITT_E_FAIL;
|
||||
}
|
||||
|
||||
return UNITT_E_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Assert that two strings are equal.
|
||||
*
|
||||
* This function checks whether the expected and actual strings are equal.
|
||||
* If they are not equal, it outputs an assertion failure message with both strings
|
||||
* and returns a failure code.
|
||||
*
|
||||
* \param[in] expected: The expected string.
|
||||
* \param[in] actual: The actual string.
|
||||
* \param[in] message: The message to display if the assertion fails.
|
||||
* \return Returns UNITT_E_OK if the assertion passes, otherwise UNITT_E_FAIL.
|
||||
*/
|
||||
int unitt_det_string(const char* expected, const char* actual, const char* message)
|
||||
{
|
||||
if (strcmp(expected, actual) != 0)
|
||||
{
|
||||
fprintf(stderr, "Assertion Failed: %s (Expected: '%s', Actual: '%s')\n", message, expected, actual);
|
||||
return UNITT_E_FAIL;
|
||||
}
|
||||
|
||||
return UNITT_E_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Handle a test failure.
|
||||
*
|
||||
* This function is called when a test fails. It outputs the name of the failed test.
|
||||
*
|
||||
* \param[in] name: The name of the failed test.
|
||||
* \return Returns UNITT_E_OK.
|
||||
*/
|
||||
int unitt_fail_handle(const char* name)
|
||||
{
|
||||
printf("Failure in test: %s\n", name);
|
||||
return UNITT_E_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Execute a test suite.
|
||||
*
|
||||
* This function runs all the test cases within the provided test suites.
|
||||
* It measures the execution time for each test and outputs a summary report.
|
||||
*
|
||||
* \param[in] suites: Array of test suites to execute.
|
||||
* \param[in] count: Number of test suites in the array.
|
||||
* \param[in] failcb: Callback function to handle test failures.
|
||||
* \param[in] specific: Specific test name to execute (NULL for all).
|
||||
* \param[in] filename: Output filename for results (NULL for stdout).
|
||||
* \return none.
|
||||
*/
|
||||
void unitt_execute(UNITT* suites, uint32_t count, unitt_failcb_t failcb, const char* specific, const char* filename)
|
||||
{
|
||||
UNITT* suite = NULL;
|
||||
UNITT_TCASE* tcase = NULL;
|
||||
uint64_t cstart = 0, cend = 0; // Record the start and end time of the test
|
||||
|
||||
FILE* output = stdout; // Default output to standard output
|
||||
if (filename != NULL)
|
||||
{
|
||||
output = fopen(filename, "w");
|
||||
if (output == NULL)
|
||||
{
|
||||
perror("Failed to open output file");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate over each test suite
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
suite = &suites[i];
|
||||
|
||||
fprintf(output, "Running test suite: %s\n", suite->name);
|
||||
|
||||
// Iterate over each test case
|
||||
for (int j = 0; j < suite->count; j++)
|
||||
{
|
||||
tcase = &suite->tests[j];
|
||||
|
||||
if (specific && strcmp(tcase->name, specific) != 0)
|
||||
{
|
||||
continue; // Skip non-matching tests
|
||||
}
|
||||
|
||||
// Execute setup function before the test
|
||||
if (tcase->setup) tcase->setup();
|
||||
|
||||
// Record start time
|
||||
if (suite->clock) cstart = suite->clock();
|
||||
|
||||
// Execute test function
|
||||
if (UNITT_E_OK == tcase->func())
|
||||
{
|
||||
tcase->passed++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (failcb) failcb(tcase->name);
|
||||
}
|
||||
|
||||
// Record end time
|
||||
if (suite->clock) cend = suite->clock();
|
||||
|
||||
// Accumulate the time taken for the test
|
||||
if (suite->clock) tcase->time += (cend - cstart);
|
||||
|
||||
// Execute teardown function after the test
|
||||
if (tcase->teardown) tcase->teardown();
|
||||
|
||||
tcase->tested++;
|
||||
}
|
||||
}
|
||||
|
||||
// Output summary of the tests
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
suite = &suites[i];
|
||||
|
||||
fprintf(output, "Test suite `%s` report: \r\n", suite->name);
|
||||
|
||||
// Iterate over each test case
|
||||
for (int j = 0; j < suite->count; j++)
|
||||
{
|
||||
tcase = &suite->tests[j];
|
||||
|
||||
fprintf(output, "[%s] Summary: tested %u, passed %u, time %llu us.\r\n",
|
||||
tcase->name,
|
||||
tcase->tested,
|
||||
tcase->passed,
|
||||
tcase->time
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (filename != NULL)
|
||||
{
|
||||
fclose(output);
|
||||
}
|
||||
}
|
||||
184
source/06_performance/unitt.h
Normal file
184
source/06_performance/unitt.h
Normal file
@ -0,0 +1,184 @@
|
||||
/*********************************************************************************************************
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* file description
|
||||
* ------------------------------------------------------------------------------------------------------
|
||||
* \file unitt.h
|
||||
* \unit unitt
|
||||
* \brief This is a simple unit test module for C language
|
||||
* \author Lamdonn
|
||||
* \version v1.0.0
|
||||
* \license GPL-2.0
|
||||
* \copyright Copyright (C) 2023 Lamdonn.
|
||||
********************************************************************************************************/
|
||||
#ifndef __unitt_H
|
||||
#define __unitt_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Version infomation */
|
||||
#define UNITT_V_MAJOR 0
|
||||
#define UNITT_V_MINOR 1
|
||||
#define UNITT_V_PATcH 0
|
||||
|
||||
// Type definition for a clock function
|
||||
typedef uint64_t (*unitt_clock_t)();
|
||||
|
||||
// Type definition for a test function
|
||||
typedef int (*unitt_func_t)();
|
||||
|
||||
// Type definition for a setup function before the test
|
||||
typedef int (*unitt_setup_t)();
|
||||
|
||||
// Type definition for a teardown function after the test
|
||||
typedef int (*unitt_teardown_t)();
|
||||
|
||||
// Type definition for a failure callback function
|
||||
typedef int (*unitt_failcb_t)(const char* name);
|
||||
|
||||
// Type definition for a random input generation function
|
||||
typedef int (*unitt_randin_t)();
|
||||
|
||||
/**
|
||||
* \brief Structure representing a test case
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
const char* name; ///< Name of the test
|
||||
unitt_func_t func; ///< Pointer to the test function
|
||||
unitt_setup_t setup; ///< Pointer to the setup function
|
||||
unitt_teardown_t teardown; ///< Pointer to the teardown function
|
||||
unitt_randin_t random_input; ///< Pointer to the random input generation function
|
||||
uint32_t tested; ///< Count of tests executed
|
||||
uint32_t passed; ///< Count of tests passed
|
||||
uint64_t time; ///< Total time taken for the test
|
||||
} UNITT_TCASE;
|
||||
|
||||
/**
|
||||
* \brief Structure representing a test suite
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
const char* name; ///< Name of the test suite
|
||||
UNITT_TCASE* tests; ///< Array of test cases
|
||||
uint32_t count; ///< Number of test cases
|
||||
unitt_clock_t clock; ///< Pointer to the clock function for measuring time
|
||||
} UNITT;
|
||||
|
||||
#define UNITT_E_OK (0) // Success return code
|
||||
#define UNITT_E_FAIL (-1) // Failure return code
|
||||
|
||||
/**
|
||||
* \brief Assert that a condition is true
|
||||
* \param[in] condition: The condition to evaluate
|
||||
* \param[in] message: The message to display if the assertion fails
|
||||
* \return Returns UNITT_E_OK if the assertion passes, otherwise UNITT_E_FAIL
|
||||
*/
|
||||
int unitt_det_true(int condition, const char* message);
|
||||
|
||||
/**
|
||||
* \brief Assert that a condition is false
|
||||
* \param[in] condition: The condition to evaluate
|
||||
* \param[in] message: The message to display if the assertion fails
|
||||
* \return Returns UNITT_E_OK if the assertion passes, otherwise UNITT_E_FAIL
|
||||
*/
|
||||
int unitt_det_false(int condition, const char* message);
|
||||
|
||||
/**
|
||||
* \brief Assert that two integers are equal
|
||||
* \param[in] expected: The expected value
|
||||
* \param[in] actual: The actual value
|
||||
* \param[in] message: The message to display if the assertion fails
|
||||
* \return Returns UNITT_E_OK if the assertion passes, otherwise UNITT_E_FAIL
|
||||
*/
|
||||
int unitt_det_equal(int expected, int actual, const char* message);
|
||||
|
||||
/**
|
||||
* \brief Assert that two integers are not equal
|
||||
* \param[in] expected: The expected value
|
||||
* \param[in] actual: The actual value
|
||||
* \param[in] message: The message to display if the assertion fails
|
||||
* \return Returns UNITT_E_OK if the assertion passes, otherwise UNITT_E_FAIL
|
||||
*/
|
||||
int unitt_det_nequal(int expected, int actual, const char* message);
|
||||
|
||||
/**
|
||||
* \brief Assert that a pointer is NULL
|
||||
* \param[in] pointer: The pointer to evaluate
|
||||
* \param[in] message: The message to display if the assertion fails
|
||||
* \return Returns UNITT_E_OK if the assertion passes, otherwise UNITT_E_FAIL
|
||||
*/
|
||||
int unitt_det_null(void* pointer, const char* message);
|
||||
|
||||
/**
|
||||
* \brief Assert that a pointer is not NULL
|
||||
* \param[in] pointer: The pointer to evaluate
|
||||
* \param[in] message: The message to display if the assertion fails
|
||||
* \return Returns UNITT_E_OK if the assertion passes, otherwise UNITT_E_FAIL
|
||||
*/
|
||||
int unitt_det_nnull(void* pointer, const char* message);
|
||||
|
||||
/**
|
||||
* \brief Assert that two floats are approximately equal
|
||||
* \param[in] expected: The expected float value
|
||||
* \param[in] actual: The actual float value
|
||||
* \param[in] epsilon: The acceptable difference between the two values
|
||||
* \param[in] message: The message to display if the assertion fails
|
||||
* \return Returns UNITT_E_OK if the assertion passes, otherwise UNITT_E_FAIL
|
||||
*/
|
||||
int unitt_det_float(float expected, float actual, float epsilon, const char* message);
|
||||
|
||||
/**
|
||||
* \brief Assert that two strings are equal
|
||||
* \param[in] expected: The expected string
|
||||
* \param[in] actual: The actual string
|
||||
* \param[in] message: The message to display if the assertion fails
|
||||
* \return Returns UNITT_E_OK if the assertion passes, otherwise UNITT_E_FAIL
|
||||
*/
|
||||
int unitt_det_string(const char* expected, const char* actual, const char* message);
|
||||
|
||||
/**
|
||||
* \brief Handle a test failure
|
||||
* \param[in] name: The name of the failed test
|
||||
* \return Returns UNITT_E_OK
|
||||
*/
|
||||
int unitt_fail_handle(const char* name);
|
||||
|
||||
/**
|
||||
* \brief Execute a test suite
|
||||
* \param[in] suites: Array of test suites to execute
|
||||
* \param[in] count: Number of test suites in the array
|
||||
* \param[in] failcb: Callback function to handle test failures
|
||||
* \param[in] specific: Specific test name to execute (NULL for all)
|
||||
* \param[in] filename: Output filename for results (NULL for stdout)
|
||||
* \return none
|
||||
*/
|
||||
void unitt_execute(UNITT* suites, uint32_t count, unitt_failcb_t failcb, const char* specific, const char* filename);
|
||||
|
||||
/**
|
||||
* \brief Macro to define a test case
|
||||
* \param name: Name of the test case
|
||||
*/
|
||||
#define UNITT_TCASE(name) { #name, name, NULL, NULL, NULL, 0, 0, 0 }
|
||||
|
||||
/**
|
||||
* \brief Macro to execute a set of test cases
|
||||
* \param suites: Array of test cases to execute
|
||||
*/
|
||||
#define UNITT_EXE(suites) unitt_execute((suites), sizeof(suites) / sizeof(suites[0]), unitt_fail_handle, 0, 0)
|
||||
|
||||
/**
|
||||
* \brief Macro to execute a set of test cases with additional parameters
|
||||
* \param suites: Array of test cases to execute
|
||||
* \param count: Number of test cases
|
||||
* \param mode: Execution mode
|
||||
* \param specific: Specific test name to execute
|
||||
* \param output: Output filename for results
|
||||
*/
|
||||
#define UNITT_EXE2(suites, count, mode, specific, output) unitt_execute(suites, count, unitt_fail_handle, specific, output)
|
||||
|
||||
#endif // __unit_H
|
||||
@ -45,6 +45,11 @@ TEST_INC =
|
||||
# TEST_SRC += $(TESTSPACE)/test_sList.c
|
||||
# TEST_SRC += $(TESTSPACE)/test_dList.c
|
||||
# TEST_SRC += $(TESTSPACE)/test_cQueue.c
|
||||
TEST_SRC += $(TESTSPACE)/test_intl.c
|
||||
# TEST_SRC += $(TESTSPACE)/test_intl.c
|
||||
# TEST_SRC += $(TESTSPACE)/test_ramt.c
|
||||
# TEST_SRC += $(TESTSPACE)/test_cpul.c
|
||||
# TEST_SRC += $(TESTSPACE)/test_date.c
|
||||
TEST_SRC += $(TESTSPACE)/test_unitt.c
|
||||
|
||||
|
||||
export TEST_SRC TEST_INC
|
||||
|
||||
200
test/test_cpul.c
Normal file
200
test/test_cpul.c
Normal file
@ -0,0 +1,200 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sched.h>
|
||||
#include "init.h"
|
||||
#include "cpul.h"
|
||||
|
||||
#define CORE_NUM_MAX 32
|
||||
#define LINE_BUFFER_SIZE 1024
|
||||
|
||||
/**
|
||||
* Structure for recording CPU counters in stat
|
||||
*/
|
||||
typedef struct {
|
||||
uint64_t user; /**< Time spent in user mode */
|
||||
uint64_t nice; /**< Time spent in low-priority user mode */
|
||||
uint64_t system; /**< Time spent in system mode */
|
||||
uint64_t idle; /**< Time spent waiting for tasks */
|
||||
uint64_t iowait; /**< Time spent waiting for I/O to complete */
|
||||
uint64_t irq; /**< Time spent processing interrupts */
|
||||
uint64_t softirq; /**< Time spent processing soft interrupts */
|
||||
uint64_t steal; /**< Time spent by other OS in virtual environment */
|
||||
uint64_t guest; /**< Time spent running guest OS */
|
||||
uint64_t guest_nice; /**< Time spent running low priority guest OS */
|
||||
} cputime_t;
|
||||
|
||||
static uint16_t loadTable[CORE_NUM_MAX] = {0};
|
||||
|
||||
static cputime_t read_stat(int coreid)
|
||||
{
|
||||
cputime_t work;
|
||||
FILE *file;
|
||||
char line[LINE_BUFFER_SIZE];
|
||||
|
||||
file = fopen("/proc/stat", "rb");
|
||||
if (file == NULL) {
|
||||
}
|
||||
|
||||
if (fgets(line, sizeof(line), file) == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (sscanf(line, "cpu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
|
||||
&work.user,
|
||||
&work.nice,
|
||||
&work.system,
|
||||
&work.idle,
|
||||
&work.iowait,
|
||||
&work.irq,
|
||||
&work.softirq,
|
||||
&work.steal,
|
||||
&work.guest,
|
||||
&work.guest_nice) < 4) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (coreid > 0)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < coreid; i++)
|
||||
{
|
||||
if (fgets(line, sizeof(line), file) == NULL)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (sscanf(line, "cpu%*u %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
|
||||
&work.user,
|
||||
&work.nice,
|
||||
&work.system,
|
||||
&work.idle,
|
||||
&work.iowait,
|
||||
&work.irq,
|
||||
&work.softirq,
|
||||
&work.steal,
|
||||
&work.guest,
|
||||
&work.guest_nice) < 4)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
error:
|
||||
fclose(file);
|
||||
return work;
|
||||
}
|
||||
|
||||
void *loadupdate_entry(void *ptr)
|
||||
{
|
||||
const int coreNum = *(int *)ptr;
|
||||
cputime_t before[coreNum], after[coreNum], diff[coreNum];
|
||||
int i = 0;
|
||||
|
||||
while(1)
|
||||
{
|
||||
/* Calcul real time load */
|
||||
for (i = 0; i < coreNum; i++) before[i] = read_stat(i);
|
||||
usleep(1000000);
|
||||
for (i = 0; i < coreNum; i++) after[i] = read_stat(i);
|
||||
|
||||
for (i = 0; i < coreNum; i++)
|
||||
{
|
||||
if (after[i].user > before[i].user && after[i].idle > before[i].idle)
|
||||
{
|
||||
diff[i].user = after[i].user - before[i].user;
|
||||
diff[i].idle = after[i].idle - before[i].idle;
|
||||
loadTable[i] = (uint16_t)(((float)(diff[i].user) / (float)(diff[i].user + diff[i].idle)) * 10000);
|
||||
}
|
||||
else
|
||||
{
|
||||
loadTable[i] = 0;
|
||||
}
|
||||
|
||||
// printf("[core%d] load %d\r\n", i, loadTable[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t cpul_raw(uint8_t coreid)
|
||||
{
|
||||
if (coreid >= CORE_NUM_MAX) return 0xFFFF;
|
||||
return (uint16_t)(loadTable[coreid]);
|
||||
}
|
||||
|
||||
void *loadgen_entry(void *ptr)
|
||||
{
|
||||
#define PERIOD 10
|
||||
const int coreid = *(int *)ptr;
|
||||
CPUL cpul;
|
||||
int ret = 0;
|
||||
uint32_t count = 0;
|
||||
uint16_t load = 0;
|
||||
|
||||
cpul.coreid = coreid;
|
||||
cpul.resolution = 10;
|
||||
cpul.raw = cpul_raw;
|
||||
ret = cpul_init(&cpul);
|
||||
|
||||
ret = cpul_set(&cpul, 5000);
|
||||
|
||||
while(1)
|
||||
{
|
||||
count += PERIOD;
|
||||
if (count >= 25200000) count = 0;
|
||||
|
||||
if (count % 1000 == 0)
|
||||
{
|
||||
ret = cpul_get(&cpul, &load);
|
||||
printf("cpul_get<%d> %2d.%02d%%, %d, %d\r\n", coreid, (uint16_t)(load / 100), load % 100, cpul.ctrl.tload, cpul.ctrl.refine);
|
||||
}
|
||||
|
||||
cpul_task(&cpul);
|
||||
usleep(1000 * PERIOD);
|
||||
}
|
||||
}
|
||||
|
||||
static void test(void)
|
||||
{
|
||||
int num_cpus = sysconf(_SC_NPROCESSORS_CONF);
|
||||
pthread_t thread_update, thread_gen[num_cpus];
|
||||
int coreid[num_cpus];
|
||||
int ret;
|
||||
|
||||
printf("Number of CPUs: %d\n", num_cpus);
|
||||
|
||||
ret = pthread_create(&thread_update, NULL, &loadupdate_entry, &num_cpus);
|
||||
if (ret != 0) {
|
||||
printf("pthread_create failed!\n");
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_cpus; i++)
|
||||
{
|
||||
coreid[i] = i;
|
||||
ret = pthread_create(&thread_gen[i], NULL, &loadgen_entry, &coreid[i]);
|
||||
if (ret != 0) {
|
||||
printf("pthread_create failed!\n");
|
||||
}
|
||||
cpu_set_t cpuset;
|
||||
CPU_ZERO(&cpuset);
|
||||
CPU_SET(i, &cpuset);
|
||||
sched_setaffinity(thread_gen[i], sizeof(cpu_set_t), &cpuset);
|
||||
}
|
||||
|
||||
pthread_join(thread_update, NULL);
|
||||
for (int i = 0; i < num_cpus; i++)
|
||||
{
|
||||
pthread_join(thread_gen[i], NULL);
|
||||
}
|
||||
}
|
||||
init_export_app(test);
|
||||
69
test/test_date.c
Normal file
69
test/test_date.c
Normal file
@ -0,0 +1,69 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "init.h"
|
||||
#include "date.h"
|
||||
|
||||
#if 0
|
||||
static int century_days(int century)
|
||||
{
|
||||
int days = 0;
|
||||
int year = (century - 1) * 100 + 1;
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
days += date_year_days(year + i);
|
||||
}
|
||||
|
||||
return days;
|
||||
}
|
||||
|
||||
static int thousand2_days(int base)
|
||||
{
|
||||
int days = 0;
|
||||
|
||||
for (int i = 0; i < 2000; i++)
|
||||
{
|
||||
days += date_year_days(base + i);
|
||||
}
|
||||
|
||||
return days;
|
||||
}
|
||||
|
||||
static int thousand3_days(int base)
|
||||
{
|
||||
int days = 0;
|
||||
int century = (base / 100) + 1;
|
||||
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
// days += century_days(century + i);
|
||||
days += date_century_days(century + i);
|
||||
}
|
||||
|
||||
return days;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void test(void)
|
||||
{
|
||||
printf("month days %d\r\n", date_month_days(2024, 11));
|
||||
printf("date_isleap %d\r\n", date_isleap(1582));
|
||||
// printf("date_current_days %d\r\n", date_current_days(DATE(1,1,1)));
|
||||
// printf("date_current_days %d\r\n", date_current_days(DATE(2000,12,31)));
|
||||
// printf("date_current_days %d\r\n", date_current_days(DATE(2001,1,1)));
|
||||
// printf("date_current_days %d\r\n", date_current_days(DATE(2024,11,9)));
|
||||
printf("date_get_week %d\r\n", date_get_week(DATE(2024,11,11)));
|
||||
|
||||
printf("date_diff_days %d\r\n", date_diff_days(DATE(2018,3,14), DATE(2024,11,10)));
|
||||
|
||||
// DATE date = date_from_days(date_current_days(DATE(2024,11,30)));
|
||||
DATE date = date_offset(DATE(2024,11,30), -1);
|
||||
|
||||
printf("%d.%d.%d\r\n", date.year,date.month,date.day);
|
||||
|
||||
date_show(1998,7);
|
||||
date_show(2024,11);
|
||||
date_show(2224,11);
|
||||
}
|
||||
init_export_app(test);
|
||||
43
test/test_ramt.c
Normal file
43
test/test_ramt.c
Normal file
@ -0,0 +1,43 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "init.h"
|
||||
#include "tool.h"
|
||||
#include "ramt.h"
|
||||
#include "kern.h"
|
||||
|
||||
#define TASK_PERIOD 5 // ms
|
||||
|
||||
static uint8_t buffer[128];
|
||||
static RAMT ramt_object;
|
||||
|
||||
static void test_task(void)
|
||||
{
|
||||
static int count = 0;
|
||||
|
||||
count += TASK_PERIOD;
|
||||
|
||||
ramt_task(&ramt_object);
|
||||
|
||||
if (count % 1000 == 0)
|
||||
{
|
||||
printf("result %08X\r\n", ramt_result(&ramt_object));
|
||||
}
|
||||
}
|
||||
|
||||
static void test_ramt(void)
|
||||
{
|
||||
task_t task;
|
||||
|
||||
printf("ramt test!\r\n");
|
||||
|
||||
ramt_object.base = (void *)buffer;
|
||||
ramt_object.size = sizeof(buffer);
|
||||
ramt_init(&ramt_object);
|
||||
|
||||
ramt_start(&ramt_object, RAMT_MODE_NORMAL, 0xFFFFFFFF);
|
||||
|
||||
task = task_create(TASK_PERIOD, test_task);
|
||||
printf("task <%d>\r\n", task);
|
||||
}
|
||||
init_export_app(test_ramt);
|
||||
182
test/test_unitt.c
Normal file
182
test/test_unitt.c
Normal file
@ -0,0 +1,182 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include "init.h"
|
||||
#include "unitt.h"
|
||||
#include "kern.h"
|
||||
|
||||
#if 0
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <psapi.h> // -lPsapi
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
void get_memory_usage(int* resident_set_size, int* virtual_memory_size)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
PROCESS_MEMORY_COUNTERS pmc;
|
||||
if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) {
|
||||
*resident_set_size = pmc.WorkingSetSize / 1024; // 转换为KB
|
||||
*virtual_memory_size = pmc.PagefileUsage / 1024; // 转换为KB
|
||||
} else {
|
||||
*resident_set_size = 0;
|
||||
*virtual_memory_size = 0;
|
||||
}
|
||||
#else
|
||||
FILE* file = fopen("/proc/self/statm", "r");
|
||||
if (file) {
|
||||
fscanf(file, "%d %d", resident_set_size, virtual_memory_size);
|
||||
fclose(file);
|
||||
} else {
|
||||
*resident_set_size = 0;
|
||||
*virtual_memory_size = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#define SINGLE_TCOUNT 1000
|
||||
|
||||
uint64_t unitt_clock(void)
|
||||
{
|
||||
struct timeval mstime;
|
||||
uint64_t us = 0;
|
||||
gettimeofday(&mstime, NULL);
|
||||
us = mstime.tv_sec * 1000000 + mstime.tv_usec;
|
||||
return us;
|
||||
}
|
||||
|
||||
// 计算两个整数的和
|
||||
int unit_add(int a, int b)
|
||||
{
|
||||
return a + b;
|
||||
}
|
||||
|
||||
// 计算两个整数的差
|
||||
int unit_subtract(int a, int b)
|
||||
{
|
||||
return a - b;
|
||||
}
|
||||
|
||||
// 计算两个整数的乘积
|
||||
int unit_multiply(int a, int b)
|
||||
{
|
||||
return a * b;
|
||||
}
|
||||
|
||||
// 计算两个整数的商
|
||||
float unit_divide(int a, int b)
|
||||
{
|
||||
if (b == 0)
|
||||
{
|
||||
return 0; // 简单处理,真实应用中应更严格处理
|
||||
}
|
||||
return (float)a / (float)b;
|
||||
}
|
||||
|
||||
// 测试前的初始化函数
|
||||
int setup()
|
||||
{
|
||||
// 初始化代码(如果需要)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 测试后的清理函数
|
||||
int teardown()
|
||||
{
|
||||
// 清理代码(如果需要)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 随机输入生成函数
|
||||
int random_input()
|
||||
{
|
||||
return rand() % 100; // 生成0到99之间的随机整数
|
||||
}
|
||||
|
||||
// 测试加法函数,使用随机输入
|
||||
int test_add()
|
||||
{
|
||||
// 进行10次随机测试
|
||||
for (int i = 0; i < SINGLE_TCOUNT; i++)
|
||||
{
|
||||
int a = random_input();
|
||||
int b = random_input();
|
||||
if (UNITT_E_FAIL == unitt_det_equal(unit_add(a, b), a + b, "Random addition failed")) return UNITT_E_FAIL;
|
||||
}
|
||||
|
||||
return UNITT_E_OK;
|
||||
}
|
||||
|
||||
// 测试减法函数,使用随机输入
|
||||
int test_subtract()
|
||||
{
|
||||
// 进行10次随机测试
|
||||
for (int i = 0; i < SINGLE_TCOUNT; i++)
|
||||
{
|
||||
int a = random_input();
|
||||
int b = random_input();
|
||||
if (UNITT_E_FAIL == unitt_det_equal(unit_subtract(a, b), a - b, "Random subtraction failed")) return UNITT_E_FAIL;
|
||||
}
|
||||
|
||||
return UNITT_E_OK;
|
||||
}
|
||||
|
||||
// 测试乘法函数,使用随机输入
|
||||
int test_multiply()
|
||||
{
|
||||
// 进行10次随机测试
|
||||
for (int i = 0; i < SINGLE_TCOUNT; i++)
|
||||
{
|
||||
int a = random_input();
|
||||
int b = random_input();
|
||||
if (UNITT_E_FAIL == unitt_det_equal(unit_multiply(a, b), a * b, "Random multiplication failed")) return UNITT_E_FAIL;
|
||||
}
|
||||
|
||||
return UNITT_E_OK;
|
||||
}
|
||||
|
||||
// 测试除法函数,使用随机输入
|
||||
int test_divide()
|
||||
{
|
||||
// 进行10次随机测试
|
||||
for (int i = 0; i < SINGLE_TCOUNT; i++)
|
||||
{
|
||||
int a = random_input();
|
||||
int b = random_input();
|
||||
if (b != 0)
|
||||
{
|
||||
if (UNITT_E_FAIL == unitt_det_float(unit_divide(a, b), (float)a / (float)b, 0.00001, "Random division failed")) return UNITT_E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
return UNITT_E_OK;
|
||||
}
|
||||
|
||||
void unit_main()
|
||||
{
|
||||
static UNITT_TCASE math_tests[] = {
|
||||
UNITT_TCASE(test_add),
|
||||
UNITT_TCASE(test_subtract),
|
||||
UNITT_TCASE(test_multiply),
|
||||
UNITT_TCASE(test_divide),
|
||||
};
|
||||
|
||||
static UNITT suites[] = {
|
||||
{ "Math Suite", math_tests, sizeof(math_tests) / sizeof(math_tests[0]) , unitt_clock },
|
||||
};
|
||||
|
||||
UNITT_EXE(suites);
|
||||
}
|
||||
|
||||
static void test(void)
|
||||
{
|
||||
srand((unsigned int)time(NULL)); // 初始化随机数种子
|
||||
|
||||
// unit_main();
|
||||
printf("create task %d\r\n", task_create(1000, unit_main));
|
||||
}
|
||||
init_export_app(test);
|
||||
Loading…
x
Reference in New Issue
Block a user