├── README.md ├── Zdx_Library.c ├── Zdx_Library.h ├── common.h └── errcode.h /README.md: -------------------------------------------------------------------------------- 1 | # Zdx_Library 2 | 裸机环境上实用的库 3 | 4 | 目录 5 | 6 | 1. TASK 任务调度 7 | 8 | 2. QUEUE 队列管理 9 | 10 | 3. RING_REDIS 环形缓存 11 | 12 | 4. MEMORY 内存管理 13 | 14 | 5. TIME 时间转换 15 | 16 | ## 1. TASK 任务调度:#define ZDX_TASK ## 17 | 18 | 无RTOS(裸机环境)下实现分时调度法,非常适用于单片机环境下的一般应用场景 19 | 20 | RTOS优点不用多说了,但对于一些简单的业务需求,移植一个操作系统又显得非常麻烦,且非常占用系统资源。 21 | 22 | 通常的做法是在一个大while下执行各个业务函数,通过多个定时器去控制各个函数的执行周期,利用几个全局变量关联各个模块功能。 23 | 24 | 但这样的做法在多轮开发下,会造成 代码非常臃肿,模块关系混乱,不利于阅读。 25 | 26 | 为了解决这个问题,手动码了一个简单的多任务调度,封装成接口供大家使用! 27 | 28 | 实现方式:创建任务时,设定好任务的调度周期和任务函数,通过定时器来计算任务是否达到执行周期,在主循环上执行任务函数。 29 | 30 | **优点:** 31 | 32 | 1、占用代码量超小 33 | 34 | 2、移植超简单 35 | 36 | 3、程序架构清晰、模块化 37 | 38 | **管理方式:** 39 | 40 | 1、链表形式(推荐),任务数量无限,通过修改宏TASK_MODE_SELECT为TASK_MODE_LINKED进行条件编译 41 | 42 | 2、数组形式,任务数量由宏定义TASK_AMOUNT_MAX决定,通过修改宏TASK_MODE_SELECT为TASK_MODE_ARRAY进行条件编译 43 | 44 | **接口说明:** 45 | 46 | 1、Task_create 创建一个任务,需要传入任务函数指针和执行周期 47 | 48 | 2、Task_cancel 取消一个任务 49 | 50 | 3、Task_reckon_time 任务计数,通常放在1mS的定时器中断中执行 51 | 52 | 4、Task_scheduling 任务调度,主函数上循环调用即可 53 | 54 | 55 | 例: 56 | ```c 57 | //任务句柄变量 58 | task_t gTestHandle,gLedHandle,gRtcHandle; 59 | 60 | void main(void) 61 | { 62 | Drive_init();//时钟、外设、IO 初始化 63 | Time_init();//设定1mS中断一次的定时器 64 | 65 | Task_create(&gTestHandle,"test_task_1",Task_1_fun,NULL,5);//创建一个Task_1_fun 任务 5mS执行一次 66 | Task_create(&gLedHandle,"test_led",Led_fun,NULL,100);//创建一个Led_fun 任务 100mS执行一次 67 | Task_create(&gRtcHandle,"test_RTC",RTC_fun,NULL,1000);//创建RTC_fun 任务 1000mS执行一次 68 | 69 | start_time();//启动定时器 70 | 71 | while(1) 72 | { 73 | Task_scheduling(); //死循环,任务调度 74 | } 75 | } 76 | 77 | //定时器中断回调函数 1mS一次中断 78 | void CallBack_time_it(void) 79 | { 80 | Task_reckon_time();//任务周期计算 81 | } 82 | ``` 83 | 84 | 85 | 86 | 87 | ## 2. QUEUE 队列管理:#define ZDX_QUEUE ## 88 | 89 | 使用方法:根据业务场景,修改宏定义QUEUE_DATA_LEN_MAX和QUEUE_AMOUNT_MAX ,创建静态或动态的队列缓存。 90 | 91 | **接口说明:** 92 | 93 | Queue_init:队列初始化 94 | 95 | Queue_add:入队 96 | 97 | Queue_del:出队 98 | 99 | Queue_get:读取队列头数据 100 | 101 | 102 | 103 | 104 | ## 3. RING_REDIS 环形缓存:#define ZDX_RING_REDIS ## 105 | 106 | 107 | 一、环形缓冲区的特性 108 | 109 | 1、先进先出 110 | 2、当缓冲区被使用完,且又有新的数据需要存储时,丢掉历史最久的数据,保存最新数据 111 | 现实中的存储介质都是线性的,因此我们需要做一下处理,才能在功能上实现环形缓冲区 112 | ![](https://img-blog.csdn.net/20180823161741219?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21hb3dlbnRhbzA0MTY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70) 113 | 114 | 115 | ![](https://img-blog.csdn.net/20180823161009879?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21hb3dlbnRhbzA0MTY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70) 116 | 117 | 118 | 119 | 120 | ## 4. MEMORY 内存管理:#define ZDX_MEMORY ## 121 | 122 | 编写支持对其分配的malloc和free函数,分配内存时,malloc函数返回的地址必须能被2的n次方整除。 123 | 124 | 125 | void* aligned_malloc(size_t required_bytes, size_t alignment) 126 | void aligned_free(void* r) 127 | 128 | 内存模型: 129 | ![](https://img-blog.csdnimg.cn/202103131542419.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3ODMwNzU3,size_16,color_FFFFFF,t_70) 130 | 131 | 132 | 133 | ## 5. TIME 时间转换:#define TIME_CONVERSION ## 134 | 135 | **接口说明:** 136 | 137 | 1.Time_strTimeToUtime 时间格式转化成时间戳 138 | 139 | 2.Time_uTimeToStrTime 时间戳转换成时间格式结构体 140 | 141 | 3.Time_checkFormatIsLegal 判断时间是否合法 -------------------------------------------------------------------------------- /Zdx_Library.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file Zdx_Library.h 4 | * @brief 裸机下常用库 5 | * @version V1.1 6 | * @author 周大侠 7 | * @email zzzdaxia@qq.com 8 | * @date 2022-09-16 10:52:04 9 | ****************************************************************************** 10 | * @remark 11 | Default encoding UTF-8 12 | ****************************************************************************** 13 | */ 14 | #include "Zdx_Library.h" 15 | 16 | 17 | #ifdef ZDX_TASK 18 | // 无操作系统下的分时调度 19 | 20 | #if (TASK_MODE_SELECT == TASK_MODE_LINKED) 21 | 22 | volatile static Sys_Task Sys_TaskMange = {0, NULL, NULL}; 23 | 24 | /******************************************************** 25 | * @Description:创建一个任务 26 | * @Arguments : 27 | pTaskHandle[IN] 任务控制块指针 28 | sTaskName[IN] 任务名称,指向ASCII字符串的指针 29 | pRoutine[IN] 任务函数 30 | par[IN] 传递给任务函数的参数指针 31 | uPeriod[IN] 任务调度周期-毫秒 32 | * @Returns : 33 | 0 创建成功 34 | -1 创建失败,参数错误 35 | * @author : 周大侠 2022-09-15 15:32:04 36 | *******************************************************/ 37 | int Task_create(task_t* pTaskHandle, char* sTaskName, 38 | void* (*pRoutine)(void*), void* par, uint32_t uPeriod) 39 | { 40 | if(NULL == pTaskHandle || NULL == pRoutine || NULL == sTaskName) 41 | { 42 | DEBUG_OUT("Unable to add task,parameter error!\n"); 43 | return -1; 44 | } 45 | 46 | pTaskHandle->taskInfo.uPeriod = uPeriod; 47 | pTaskHandle->taskInfo.uCnt = 0; 48 | pTaskHandle->taskInfo.Task_func = pRoutine; 49 | pTaskHandle->taskInfo.par = par; 50 | pTaskHandle->taskInfo.status = TASK_IDLE; 51 | strncpy((char*)&pTaskHandle->taskInfo.name,sTaskName,TASK_NAME_LEN_MAX-1); 52 | pTaskHandle->nextTask = NULL; 53 | 54 | if(NULL != Sys_TaskMange.taskHead) 55 | { 56 | task_t* tailNode; 57 | 58 | tailNode = Sys_TaskMange.taskHead; 59 | for(;NULL != tailNode->nextTask;tailNode = tailNode->nextTask); 60 | tailNode->nextTask = pTaskHandle; 61 | } 62 | else 63 | { 64 | Sys_TaskMange.taskHead = pTaskHandle; 65 | } 66 | Sys_TaskMange.taskSum++; 67 | 68 | return 0; 69 | } 70 | 71 | /******************************************************** 72 | * @Description:删除一个任务 73 | * @Arguments : 74 | pTaskHandle[IN] 要删除的任务的控制块指针,NULL为当前任务 75 | * @Returns : 76 | 0:成功 77 | -1 无任务 78 | -2 未找到需要删除的任务 79 | * @author : 周大侠 2022-09-15 15:33:06 80 | *******************************************************/ 81 | int Task_cancel(task_t* pTaskHandle) 82 | { 83 | if(NULL == pTaskHandle)//结束当前任务 84 | { 85 | pTaskHandle = Sys_TaskMange.taskNow; 86 | } 87 | 88 | if(NULL == Sys_TaskMange.taskHead || NULL == pTaskHandle || 1 > Sys_TaskMange.taskSum) 89 | { 90 | DEBUG_OUT("Unable to cancel task,parameter error!\n"); 91 | return -1; 92 | } 93 | 94 | if(Sys_TaskMange.taskHead == pTaskHandle) 95 | { 96 | Sys_TaskMange.taskHead = pTaskHandle->nextTask; 97 | pTaskHandle->nextTask = NULL; 98 | pTaskHandle->taskInfo.status = TASK_DEL; 99 | Sys_TaskMange.taskSum--; 100 | } 101 | else 102 | { 103 | task_t* taskNode = Sys_TaskMange.taskHead; 104 | 105 | for(; NULL != taskNode->nextTask; taskNode = taskNode->nextTask) 106 | { 107 | if(taskNode->nextTask == pTaskHandle) 108 | { 109 | taskNode->nextTask = pTaskHandle->nextTask; 110 | pTaskHandle->nextTask = NULL; 111 | pTaskHandle->taskInfo.status = TASK_DEL; 112 | Sys_TaskMange.taskSum--; 113 | return 0; 114 | } 115 | } 116 | } 117 | DEBUG_OUT("Unable to find the task of cancel!\n"); 118 | return -2; 119 | } 120 | 121 | /******************************************************** 122 | * @Description:任务计时 123 | * @Arguments :无 124 | * @Returns :无 125 | * @author : 周大侠 2022-09-14 16:27:02 126 | * @remark :需要定时器1mS 调用一次 127 | *******************************************************/ 128 | void Task_reckon_time(void) 129 | { 130 | task_t* taskNode = Sys_TaskMange.taskHead; 131 | 132 | for(; NULL != taskNode; taskNode = taskNode->nextTask) 133 | { 134 | if(TASK_IDLE == taskNode->taskInfo.status) 135 | { 136 | taskNode->taskInfo.uCnt++; 137 | if(taskNode->taskInfo.uCnt >= taskNode->taskInfo.uPeriod) 138 | { 139 | taskNode->taskInfo.uCnt = 0; 140 | taskNode->taskInfo.status = TASK_READY; 141 | } 142 | } 143 | } 144 | } 145 | 146 | /******************************************************** 147 | * @Description:任务调度 148 | * @Arguments :无 149 | * @Returns :无 150 | * @author : 周大侠 2022-09-14 16:27:11 151 | *******************************************************/ 152 | void Task_scheduling (void) 153 | { 154 | task_t* taskNode = Sys_TaskMange.taskHead; 155 | 156 | for(; NULL != taskNode; taskNode = taskNode->nextTask) 157 | { 158 | if(TASK_READY == taskNode->taskInfo.status && NULL != taskNode->taskInfo.Task_func) 159 | { 160 | taskNode->taskInfo.status = TASK_RESUME; 161 | Sys_TaskMange.taskNow = taskNode; 162 | taskNode->taskInfo.Task_func(taskNode->taskInfo.par); 163 | Sys_TaskMange.taskNow = NULL; 164 | if(TASK_RESUME == taskNode->taskInfo.status) 165 | taskNode->taskInfo.status = TASK_IDLE; 166 | } 167 | } 168 | } 169 | 170 | #elif (TASK_MODE_SELECT == TASK_MODE_ARRAY) 171 | 172 | volatile static Sys_Task Sys_TaskMange = {0, 0,{0}}; 173 | 174 | /******************************************************** 175 | * @Description:创建一个任务 176 | * @Arguments : 177 | pTaskHandle[OUT]任务控制块指针 178 | sTaskName[IN] 任务名称,指向ASCII字符串的指针 179 | pRoutine[IN] 任务函数 180 | par[IN] 传递给任务函数的参数指针 181 | uPeriod[IN] 任务调度周期-毫秒 182 | * @Returns : 183 | 0 创建成功 184 | -1 创建失败,参数错误 185 | -2 创建失败,任务池已满 186 | * @author : 周大侠 2022-09-15 15:32:04 187 | *******************************************************/ 188 | 189 | int Task_create(task_t* pTaskHandle, char* sTaskName, 190 | void* (*pRoutine)(void*), void* par, uint32_t uPeriod) 191 | { 192 | uint16_t i = 0; 193 | 194 | if(NULL == pTaskHandle || NULL == pRoutine || NULL == sTaskName) 195 | { 196 | DEBUG_OUT("Unable to add task,parameter error!\n"); 197 | return -1; 198 | } 199 | 200 | for(i = 0; i < TASK_AMOUNT_MAX; i++) 201 | { 202 | if(NULL == Sys_TaskMange.taskList[i].Task_func) 203 | { 204 | Sys_TaskMange.taskList[i].uPeriod = uPeriod; 205 | Sys_TaskMange.taskList[i].uCnt = 0; 206 | Sys_TaskMange.taskList[i].Task_func = pRoutine; 207 | Sys_TaskMange.taskList[i].par = par; 208 | Sys_TaskMange.taskList[i].status = TASK_IDLE; 209 | strncpy((char*)&Sys_TaskMange.taskList[i].name,sTaskName,TASK_NAME_LEN_MAX-1); 210 | *pTaskHandle = i; 211 | Sys_TaskMange.taskSum++; 212 | return 0; 213 | } 214 | } 215 | 216 | DEBUG_OUT("The task pool is full and the failure is created!\n"); 217 | return -2; 218 | } 219 | 220 | /******************************************************** 221 | * @Description:删除一个任务 222 | * @Arguments : 223 | pTaskHandle[IN] 要删除的任务的控制块指针,NULL为当前任务 224 | * @Returns : 225 | 0:成功 226 | -1 超出任务池 227 | * @author : 周大侠 2022-09-15 15:33:06 228 | *******************************************************/ 229 | 230 | int Task_cancel(task_t* pTaskHandle) 231 | { 232 | task_t delTask; 233 | 234 | if(NULL == pTaskHandle)//结束当前线程 235 | delTask = Sys_TaskMange.taskNow; 236 | else 237 | delTask = *pTaskHandle; 238 | 239 | if(delTask < TASK_AMOUNT_MAX) 240 | { 241 | memset((char*)&Sys_TaskMange.taskList[delTask],00,sizeof(ScmTask_Info)); 242 | Sys_TaskMange.taskList[delTask].status = TASK_DEL; 243 | Sys_TaskMange.taskSum--; 244 | return 0; 245 | } 246 | else 247 | return -1; 248 | } 249 | 250 | /******************************************************** 251 | * @Description:任务计时 252 | * @Arguments :无 253 | * @Returns :无 254 | * @author : 周大侠 2022-09-14 16:27:02 255 | * @remark :需要定时器1mS 调用一次 256 | *******************************************************/ 257 | void Task_reckon_time(void) 258 | { 259 | task_t i = 0; 260 | 261 | for(i = 0 ;i < TASK_AMOUNT_MAX;i++) 262 | { 263 | if(TASK_IDLE == Sys_TaskMange.taskList[i].status && NULL != Sys_TaskMange.taskList[i].Task_func) 264 | { 265 | Sys_TaskMange.taskList[i].uCnt++; 266 | if(Sys_TaskMange.taskList[i].uCnt >= Sys_TaskMange.taskList[i].uPeriod) 267 | { 268 | Sys_TaskMange.taskList[i].uCnt = 0; 269 | Sys_TaskMange.taskList[i].status = TASK_READY; 270 | } 271 | } 272 | } 273 | } 274 | 275 | /******************************************************** 276 | * @Description:任务调度 277 | * @Arguments :无 278 | * @Returns :无 279 | * @author : 周大侠 2022-09-14 16:27:11 280 | *******************************************************/ 281 | void Task_scheduling (void) 282 | { 283 | task_t i = 0; 284 | 285 | for(i = 0 ;i < TASK_AMOUNT_MAX;i++) 286 | { 287 | if(TASK_READY == Sys_TaskMange.taskList[i].status && NULL != Sys_TaskMange.taskList[i].Task_func) 288 | { 289 | Sys_TaskMange.taskNow = i; 290 | Sys_TaskMange.taskList[i].status = TASK_RESUME; 291 | Sys_TaskMange.taskList[i].Task_func(Sys_TaskMange.taskList[i].par); 292 | if(TASK_RESUME == Sys_TaskMange.taskList[i].status) 293 | Sys_TaskMange.taskList[i].status = TASK_IDLE; 294 | } 295 | } 296 | } 297 | #endif//#if(TASK_MODE_SELECT == xxx) 298 | 299 | #endif//#ifdef ZDX_TASK 300 | 301 | 302 | 303 | #ifdef ZDX_QUEUE 304 | 305 | //队列管理 306 | /******************************************************** 307 | * @Description:队列初始化 308 | * @Arguments : 309 | p_Queue:[IN]队列句柄 310 | * @Returns : 311 | -1 fall 312 | 0 succeed 313 | * @author : 周大侠 314 | *******************************************************/ 315 | int Queue_init(ScmQueue_info *p_Queue) 316 | { 317 | if(NULL != p_Queue) 318 | { 319 | memset((char*)p_Queue,00,sizeof(ScmQueue_info)); 320 | //p_Queue->clock init 321 | return 0; 322 | } 323 | return -1; 324 | } 325 | 326 | /******************************************************** 327 | * @Description:队列-入队 328 | * @Arguments : 329 | p_Queue:[IN]队列句柄 330 | pData: [IN]:数据指针 331 | uSize: [IN]:数据大小 332 | * @Returns : 333 | -1 fall 334 | 0 succeed 335 | * @author : 周大侠 336 | *******************************************************/ 337 | int Queue_add(ScmQueue_info *p_Queue, void* pData, uint32_t uSize) 338 | { 339 | uint32_t point_to_end = 0; 340 | int result = 0; 341 | 342 | //xSemaphoreTake( p_Queue->clock, portMAX_DELAY ); 343 | if(p_Queue->Queue_sum < QUEUE_AMOUNT_MAX && NULL != pData && uSize <= QUEUE_DATA_LEN_MAX) 344 | { 345 | point_to_end = p_Queue->Queue_new + p_Queue->Queue_sum; 346 | point_to_end = (point_to_end >= QUEUE_AMOUNT_MAX) ? ( point_to_end - QUEUE_AMOUNT_MAX) : (point_to_end); 347 | 348 | memcpy(&p_Queue->List[point_to_end].data[0],(uint8_t*)pData,uSize); 349 | p_Queue->List[point_to_end].len = uSize; 350 | p_Queue->Queue_sum++; 351 | } 352 | else 353 | { 354 | DEBUG_OUT("Queue_add fill.\n"); 355 | result = -1; 356 | } 357 | //xSemaphoreGive( p_Queue->clock ); 358 | 359 | return result; 360 | } 361 | 362 | /******************************************************** 363 | * @Description:队列-出队 364 | * @Arguments : 365 | p_Queue:[IN]队列句柄 366 | * @Returns : 367 | -1 fall 368 | 0 succeed 369 | * @author : 周大侠 370 | * @notice : 移除一个头部成员 371 | *******************************************************/ 372 | int Queue_del(ScmQueue_info *p_Queue) 373 | { 374 | uint32_t point_to_head = p_Queue->Queue_new; 375 | int result = 0; 376 | 377 | //xSemaphoreTake( p_Queue->clock, portMAX_DELAY ); 378 | if(p_Queue->Queue_new < QUEUE_AMOUNT_MAX && p_Queue->Queue_sum >= 1) 379 | { 380 | //memset(&p_Queue->List[p_Queue->Queue_new].data[0],00,QUEUE_DATA_LEN_MAX); 381 | p_Queue->List[p_Queue->Queue_new].len = 0; 382 | p_Queue->Queue_sum--; 383 | if(p_Queue->Queue_sum > 0) 384 | { 385 | point_to_head++; 386 | (point_to_head >= QUEUE_AMOUNT_MAX) ? ( point_to_head = 0) : (point_to_head); 387 | p_Queue->Queue_new = point_to_head; 388 | } 389 | } 390 | else 391 | { 392 | DEBUG_OUT("FUN Queue_del err.\n"); 393 | result = -1; 394 | } 395 | //xSemaphoreGive( p_Queue->clock ); 396 | 397 | return result; 398 | } 399 | 400 | /******************************************************** 401 | * @Description:队列-读取队列头成员 402 | * @Arguments : 403 | p_Queue: [IN]队列句柄 404 | pData[OUT]: 存放头部成员数据的指针 405 | * @Returns : 406 | [OUT]数据大小 407 | * @author : 周大侠 408 | *******************************************************/ 409 | uint32_t Queue_get(ScmQueue_info *p_Queue, char** pData) 410 | { 411 | uint32_t len = 0; 412 | 413 | //xSemaphoreTake( p_Queue->clock, portMAX_DELAY ); 414 | if(NULL != p_Queue && NULL != pData) 415 | { 416 | if(0 < p_Queue->Queue_sum) 417 | { 418 | *pData = (char*)p_Queue->List[p_Queue->Queue_new].data; 419 | len = p_Queue->List[p_Queue->Queue_new].len; 420 | } 421 | else 422 | { 423 | *pData = NULL; 424 | len = 0; 425 | } 426 | } 427 | //xSemaphoreGive( p_Queue->clock ) 428 | 429 | return len; 430 | } 431 | 432 | 433 | #endif 434 | 435 | 436 | #ifdef ZDX_RING_REDIS 437 | //环形缓存 438 | 439 | /******************************************************** 440 | * @Description: 初始化环形缓冲区 441 | * @Arguments : 442 | pRing 环形缓冲区结构指针 443 | size 设置环形缓冲区大小 444 | * @Returns : 445 | 0 成功 446 | -1 失败 447 | *******************************************************/ 448 | int initRingbuffer(ScmRingBuff* pRing ,uint32_t size) 449 | { 450 | int result = -1; 451 | 452 | if(NULL != pRing) 453 | { 454 | if(pRing->pHead == NULL) 455 | { 456 | pRing->pHead = (char*) malloc(size); 457 | if(NULL != pRing->pHead) 458 | { 459 | pRing->pValid = pRing->pValidTail = pRing->pHead; 460 | pRing->pTail = pRing->pHead + size; 461 | pRing->validLen = 0; 462 | pRing->RingSize = size; 463 | //pRing->clock init 464 | result = 0; 465 | } 466 | } 467 | } 468 | return result; 469 | } 470 | 471 | /******************************************************** 472 | * @Description: 向缓冲区写入数据 473 | * @Arguments : 474 | pRing 环形缓冲区结构指针 475 | buffer 写入的数据指针 476 | addLen 写入的数据长度 477 | * @Returns : 478 | 0 成功 479 | -1:缓冲区没有初始化 480 | -2:写入长度过大 481 | *******************************************************/ 482 | int wirteRingbuffer(ScmRingBuff* pRing,char* buffer,uint32_t addLen) 483 | { 484 | int result = -1; 485 | 486 | if(NULL != pRing && NULL != buffer) 487 | { 488 | //xSemaphoreTake( pRing->clock, portMAX_DELAY ); 489 | if(NULL != pRing->pHead && NULL != pRing->pTail && NULL != pRing->pValid && NULL != pRing->pValidTail) 490 | { 491 | if(addLen <= pRing->RingSize) 492 | { 493 | //将要存入的数据copy到pValidTail处 494 | if(pRing->pValidTail + addLen > pRing->pTail)//需要分成两段copy 495 | { 496 | uint32_t len1 = pRing->pTail - pRing->pValidTail; 497 | uint32_t len2 = addLen - len1; 498 | memcpy( pRing->pValidTail, buffer, len1); 499 | memcpy( pRing->pHead, buffer + len1, len2); 500 | pRing->pValidTail = pRing->pHead + len2;//新的有效数据区结尾指针 501 | } 502 | else 503 | { 504 | memcpy( pRing->pValidTail, buffer, addLen); 505 | pRing->pValidTail += addLen;//新的有效数据区结尾指针 506 | } 507 | 508 | //需重新计算已使用区的起始位置 509 | if(pRing->validLen + addLen > pRing->RingSize) 510 | { 511 | int moveLen = pRing->validLen + addLen - pRing->RingSize;//有效指针将要移动的长度 512 | if(pRing->pValid + moveLen > pRing->pTail)//需要分成两段计算 513 | { 514 | uint32_t len1 = pRing->pTail - pRing->pValid; 515 | uint32_t len2 = moveLen - len1; 516 | pRing->pValid = pRing->pHead + len2; 517 | } 518 | else 519 | { 520 | pRing->pValid = pRing->pValid + moveLen; 521 | } 522 | 523 | pRing->validLen = pRing->RingSize; 524 | } 525 | else 526 | { 527 | pRing->validLen += addLen; 528 | } 529 | result = 0; 530 | } 531 | else 532 | result = -2; 533 | } 534 | //xSemaphoreGive( pRing->clock ); 535 | } 536 | return result; 537 | } 538 | 539 | /******************************************************** 540 | * @Description: 向缓冲区读出数据 541 | * @Arguments : 542 | pRing 环形缓冲区结构指针 543 | buffer 接收数据缓存 544 | len 将要接收的数据长度 545 | * @Returns : 546 | 大于0 实际读取的长度 547 | -1:缓冲区没有初始化 548 | *******************************************************/ 549 | int readRingbuffer(ScmRingBuff* pRing,char* buffer,uint32_t len) 550 | { 551 | int result = -1; 552 | 553 | if(NULL != pRing && NULL != buffer) 554 | { 555 | //xSemaphoreTake( pRing->clock, portMAX_DELAY ); 556 | if(NULL != pRing->pHead && NULL != pRing->pTail && NULL != pRing->pValid && NULL != pRing->pValidTail) 557 | { 558 | if(0 < pRing->validLen) 559 | { 560 | if( len >= pRing->validLen) 561 | len = pRing->validLen; 562 | 563 | if(pRing->pValid + len > pRing->pTail)//需要分成两段copy 564 | { 565 | uint32_t len1 = pRing->pTail - pRing->pValid; 566 | uint32_t len2 = len - len1; 567 | memcpy( buffer, pRing->pValid, len1);//第一段 568 | memcpy( buffer+len1, pRing->pHead, len2);//第二段,绕到整个存储区的开头 569 | 570 | //注释此语句,则读取的数据不会被清除 571 | pRing->pValid = pRing->pHead + len2;//更新已使用缓冲区的起始 572 | } 573 | else 574 | { 575 | memcpy( buffer, pRing->pValid, len); 576 | //注释此语句,则读取的数据不会被清除 577 | pRing->pValid = pRing->pValid +len;//更新已使用缓冲区的起始 578 | } 579 | //注释此语句,则读取的数据不会被清除 580 | pRing->validLen -= len;//更新已使用缓冲区的长度 581 | result = len; 582 | } 583 | else 584 | result = 0; 585 | } 586 | //xSemaphoreGive( pRing->clock ); 587 | 588 | } 589 | return result; 590 | } 591 | 592 | /******************************************************** 593 | * @Description: 释放环形缓冲区 594 | * @Arguments : 595 | pRing 环形缓冲区结构指针 596 | * @Returns : 597 | 0 成功 598 | -1 失败 599 | *******************************************************/ 600 | int releaseRingbuffer(ScmRingBuff* pRing) 601 | { 602 | int result = -1; 603 | 604 | if(NULL != pRing && NULL != pRing->pHead) 605 | { 606 | //xSemaphoreTake( pRing->clock, portMAX_DELAY ); 607 | free(pRing->pHead); 608 | //xSemaphoreGive( pRing->clock ); 609 | memset((char*)pRing,00,sizeof(ScmRingBuff)); 610 | result = 0; 611 | } 612 | return result; 613 | } 614 | 615 | #endif 616 | 617 | 618 | #ifdef ZDX_MEMORY 619 | 620 | /******************************************************** 621 | * @Description:字节对齐 malloc 622 | * @Arguments : 623 | required_bytes 要申请内存字节大小 (Byte) 624 | alignment 字节对齐值 必须为2的n次方 625 | * @Returns : 626 | 0 申请失败 627 | 其它:得到的地址 628 | * @author : 周大侠 2021-3-13 11:28:07 629 | *******************************************************/ 630 | void* aligned_malloc(size_t required_bytes, size_t alignment) 631 | { 632 | void* res = NULL; 633 | size_t offset = alignment - 1 + sizeof(void*);//需要增加调整空间和存放实际地址的空间 634 | void* p = (void*)malloc(required_bytes+offset);// p 为实际malloc的地址 635 | 636 | if (NULL != p) 637 | { 638 | res = (void*)(((size_t )(p)+offset)&~(alignment-1));//a &~(b-1) 可以理解为b在a范围中的最大整数倍的值 ,b必须为2的n次方,如:100&~(8-1) = 96 639 | void** tmp = (void**)res;//tmp是一个存放指针数据的地址 640 | tmp[-1] = p;//地址的前一个位置存放指针p 641 | } 642 | 643 | return res; 644 | } 645 | 646 | /******************************************************** 647 | * @Description:字节对齐的 内存释放 648 | * @Arguments : 649 | r 要释放的地址值 650 | * @Returns : 651 | * @author : 周大侠 2021-3-13 11:28:07 652 | *******************************************************/ 653 | void aligned_free(void* r) 654 | { 655 | if (r != NULL) 656 | { 657 | void** tmp = (void**)r; 658 | free(tmp[-1]); 659 | } 660 | } 661 | 662 | #endif 663 | 664 | #ifdef TIME_CONVERSION 665 | 666 | /******************************************************** 667 | * @Description:闰年判断 668 | * @Arguments : 669 | year[IN] 判断的年份 670 | * @Returns : 671 | 0:平年 672 | 1: 闰年 673 | * @author : 周大侠 2022-8-1 20:19:29 674 | *******************************************************/ 675 | static uint8_t Time_checkLeapYear(uint16_t uYear) 676 | { 677 | return (((uYear) % 4) == 0 && (((uYear) % 100) != 0 || ((uYear) % 400) == 0)); 678 | } 679 | 680 | /******************************************************** 681 | * @Description:时间格式转化成时间戳 682 | * @Arguments : 683 | pStrTime[IN] 时间结构体 684 | * @Returns : 685 | 从1970年起的时间戳 686 | * @author : 周大侠 2022-8-1 20:19:29 687 | *******************************************************/ 688 | uint32_t Time_strTimeToUtime(TimeStruct* pStrTime) 689 | { 690 | const uint16_t mon_yday[2][12] = 691 | { 692 | {0,31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, 693 | {0,31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}, 694 | }; 695 | uint32_t ret; 696 | int i = 0; 697 | 698 | if(NULL == pStrTime || 0 == pStrTime->day || 699 | 0 == pStrTime->month || 12 < pStrTime->month || 1970 > pStrTime->year ) 700 | { 701 | return 0; 702 | } 703 | 704 | // 以平年时间计算的秒数 705 | ret = (pStrTime->year - 1970) * 365 * 24 * 3600; 706 | ret += (mon_yday[Time_checkLeapYear(pStrTime->year)][pStrTime->month - 1] + pStrTime->day - 1) * 24 * 3600; 707 | ret += pStrTime->hour * 3600 + pStrTime->minte * 60 + pStrTime->second; 708 | // 加上闰年的秒数 709 | for(i = 1970; i < pStrTime->year; i++) 710 | { 711 | if(Time_checkLeapYear(i)) 712 | { 713 | ret += 24 * 3600; 714 | } 715 | } 716 | if(ret > 4107715199U)//2100-02-29 23:59:59 717 | { 718 | ret += 24 * 3600; 719 | } 720 | return(ret); 721 | } 722 | 723 | /******************************************************** 724 | * @Description:时间戳转换成时间格式结构体 725 | * @Arguments : 726 | uTime[IN] 时间戳 727 | pStrTime[OUT] 输出的时间结构体指针 728 | * @Returns : 729 | NULL 730 | * @author : 周大侠 2022-8-1 20:19:29 731 | *******************************************************/ 732 | void Time_uTimeToStrTime(uint32_t uTime, TimeStruct* pStrTime) 733 | { 734 | const char Days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 735 | 736 | uint32_t Pass4year; 737 | int hours_per_year; 738 | 739 | pStrTime->msec = 0; 740 | //取秒时间 741 | pStrTime->second=(int)(uTime % 60); 742 | uTime /= 60; 743 | //取分钟时间 744 | pStrTime->minte=(int)(uTime % 60); 745 | uTime /= 60; 746 | //取过去多少个四年,每四年有 1461*24 小时 747 | Pass4year = uTime / (1461L * 24L); 748 | //计算年份 749 | pStrTime->year=(Pass4year << 2) + 1970; 750 | //四年中剩下的小时数 751 | uTime %= 1461L * 24L; 752 | //校正闰年影响的年份,计算一年中剩下的小时数 753 | while(1) 754 | { 755 | //一年的小时数 756 | hours_per_year = 365 * 24; 757 | //判断闰年,是闰年,一年则多24小时,即一天 758 | if ((pStrTime->year & 3) == 0) hours_per_year += 24; 759 | 760 | if (uTime < hours_per_year) break; 761 | 762 | pStrTime->year++; 763 | uTime -= hours_per_year; 764 | } 765 | //小时数 766 | pStrTime->hour=(int)(uTime % 24); 767 | //一年中剩下的天数 768 | uTime /= 24; 769 | //假定为闰年 770 | uTime++; 771 | //校正闰年的误差,计算月份,日期 772 | if((pStrTime->year & 3) == 0) 773 | { 774 | if (uTime > 60) 775 | { 776 | uTime--; 777 | } 778 | else 779 | { 780 | if (uTime == 60) 781 | { 782 | pStrTime->month = 2; 783 | pStrTime->day = 29; 784 | return ; 785 | } 786 | } 787 | } 788 | //计算月日 789 | for (pStrTime->month = 1; Days[pStrTime->month - 1] < uTime;pStrTime->month++) 790 | { 791 | uTime -= Days[pStrTime->month - 1]; 792 | } 793 | 794 | pStrTime->day = (uint8_t)(uTime); 795 | 796 | return; 797 | } 798 | 799 | /******************************************************** 800 | * @Description:判断时间是否合法 801 | * @Arguments : 802 | year[IN] 年 803 | month[IN] 月 804 | day[IN] 日 805 | hour[IN] 时 806 | minte[IN] 分 807 | second[IN]秒 808 | * @Returns : 809 | 0 :合法 810 | 其它:非法 811 | * @author : 周大侠 2022-8-1 20:19:29 812 | *******************************************************/ 813 | int Time_checkFormatIsLegal(uint16_t year, uint8_t month, uint8_t day, 814 | uint8_t hour, uint8_t minte, uint8_t second) 815 | { 816 | if ((year < 1970) || (year > 2100) || (month == 0) || (month > 12) || 817 | (day == 0) || (hour > 24) || (minte > 59) || (second > 59)) //数值非法 818 | { 819 | return -1; 820 | } 821 | 822 | switch (month) //日数是否超限 823 | { 824 | case 1: 825 | case 3: 826 | case 5: 827 | case 7: 828 | case 8: 829 | case 10: 830 | case 12: if (day > 31) return 0;break; //一个月31天 831 | case 4: 832 | case 6: 833 | case 9: 834 | case 11: if (day > 30) return 0;break; //一个月30天 835 | case 2: 836 | if (((year % 4) == 0 && (year % 100) != 0) || ((year % 400) == 0)) //是否是闰年 837 | { 838 | if (day > 29) //闰年2月29天 839 | return -1; 840 | break; 841 | } 842 | else 843 | { 844 | if (day > 28) //非闰年2月28天 845 | return -1; 846 | break; 847 | } 848 | } 849 | return 0; 850 | } 851 | 852 | #endif -------------------------------------------------------------------------------- /Zdx_Library.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file Zdx_Library.h 4 | * @brief 裸机下常用库头文件 5 | * @version V1.1 6 | * @author 周大侠 7 | * @email zzzdaxia@qq.com 8 | * @date 2022-09-16 10:51:48 9 | ****************************************************************************** 10 | * @remark 11 | Default encoding UTF-8 12 | ****************************************************************************** 13 | */ 14 | #ifndef _ZDX_LIBRARY_H_ 15 | #define _ZDX_LIBRARY_H_ 16 | 17 | /*----------------------------------------------------------------------------- 18 | * Include file 19 | -----------------------------------------------------------------------------*/ 20 | #include 21 | #include 22 | #include 23 | #include "common.h" 24 | 25 | 26 | //任务调度 27 | #define ZDX_TASK 28 | 29 | //队列管理 30 | #define ZDX_QUEUE 31 | 32 | //环形缓存 33 | #define ZDX_RING_REDIS 34 | 35 | //内存管理 36 | #define ZDX_MEMORY 37 | 38 | //时间转换 39 | #define TIME_CONVERSION 40 | 41 | 42 | #define DEBUG_OUT(...) //printf 43 | 44 | 45 | /*----------------------------------------------------------------------------- 46 | * 任务调度 47 | -----------------------------------------------------------------------------*/ 48 | #ifdef ZDX_TASK 49 | 50 | #define TASK_MODE_LINKED 1 //链表形式,无限任务 51 | #define TASK_MODE_ARRAY 0 //数组形式,任务数由宏决定 52 | 53 | #define TASK_MODE_SELECT TASK_MODE_LINKED 54 | #define TASK_NAME_LEN_MAX (10U) // 任务名最大长度 55 | 56 | typedef enum 57 | { 58 | TASK_IDLE = 0,//空闲 59 | TASK_RESUME,//运行态 60 | TASK_READY,//准备态 61 | TASK_DEL,//删除态 62 | }cmTask_status;//任务状态 63 | 64 | typedef struct 65 | { 66 | uint32_t uPeriod;//任务执行周期 67 | uint32_t uCnt;//任务计数值 68 | void* (*Task_func)(void*);//任务函数指针 69 | void* par ;//任务函数参数 70 | cmTask_status status;// 任务状态 71 | char name[TASK_NAME_LEN_MAX]; 72 | }ScmTask_Info;//任务信息 73 | 74 | #if (TASK_MODE_SELECT == TASK_MODE_LINKED) 75 | 76 | typedef struct ScmTask_Node 77 | { 78 | ScmTask_Info taskInfo; 79 | struct ScmTask_Node* nextTask; 80 | }task_t;//任务控制块 81 | 82 | typedef struct 83 | { 84 | uint32_t taskSum; 85 | task_t* taskNow; 86 | task_t* taskHead; 87 | }Sys_Task; 88 | 89 | #elif (TASK_MODE_SELECT == TASK_MODE_ARRAY) 90 | 91 | #define TASK_AMOUNT_MAX (20U)//最大任务数量 92 | typedef uint16_t task_t;//任务控制块 93 | 94 | typedef struct 95 | { 96 | task_t taskSum; 97 | task_t taskNow; 98 | ScmTask_Info taskList[TASK_AMOUNT_MAX]; 99 | }Sys_Task;//任务表 100 | 101 | #else 102 | #error "Please select the correct task pattern!" 103 | #endif//#if(TASK_MODE_SELECT == xxx) 104 | 105 | int Task_create(task_t* pTaskHandle, char* sTaskName, 106 | void* (*pRoutine)(void*), void* par, uint32_t uPeriod); 107 | int Task_cancel(task_t* pTaskHandle); 108 | void Task_reckon_time(void); 109 | void Task_scheduling (void); 110 | 111 | #endif 112 | 113 | /*----------------------------------------------------------------------------- 114 | * 队列管理 115 | -----------------------------------------------------------------------------*/ 116 | #ifdef ZDX_QUEUE 117 | 118 | #define QUEUE_DATA_LEN_MAX (128U) //队列数据最大长度 119 | #define QUEUE_AMOUNT_MAX (32U) //队列最大长度 120 | 121 | 122 | typedef struct 123 | { 124 | char data[QUEUE_DATA_LEN_MAX]; 125 | uint32_t len; 126 | }ScmQueue_data; 127 | 128 | typedef struct 129 | { 130 | //mutex_t clock; //互斥锁 131 | uint32_t Queue_sum; 132 | uint32_t Queue_new; 133 | ScmQueue_data List[QUEUE_AMOUNT_MAX]; 134 | }ScmQueue_info; 135 | 136 | 137 | //队列管理 138 | int Queue_init(ScmQueue_info *p_Queue); 139 | int Queue_add(ScmQueue_info *p_Queue, void* pData, uint32_t uSize); 140 | int Queue_del(ScmQueue_info *p_Queue); 141 | uint32_t Queue_get(ScmQueue_info *p_Queue, char** pData); 142 | 143 | #endif 144 | 145 | /*----------------------------------------------------------------------------- 146 | * 环形缓存 147 | -----------------------------------------------------------------------------*/ 148 | #ifdef ZDX_RING_REDIS 149 | 150 | typedef struct 151 | { 152 | //mutex_t clock; //互斥锁 153 | uint32_t validLen;//已使用的数据长度 154 | uint32_t RingSize;//缓冲区总大小 155 | char* pHead;//环形存储区的首地址 156 | char* pTail;//环形存储区的结尾地址 157 | char* pValid;//已使用的缓冲区的首地址 158 | char* pValidTail;//已使用的缓冲区的尾地址 159 | }ScmRingBuff; 160 | 161 | int initRingbuffer(ScmRingBuff* pRing ,uint32_t size); 162 | int wirteRingbuffer(ScmRingBuff* pRing,char* buffer,uint32_t addLen); 163 | int readRingbuffer(ScmRingBuff* pRing,char* buffer,uint32_t len); 164 | int releaseRingbuffer(ScmRingBuff* pRing); 165 | 166 | #endif 167 | 168 | /*----------------------------------------------------------------------------- 169 | * 内存管理 170 | -----------------------------------------------------------------------------*/ 171 | #ifdef ZDX_MEMORY 172 | 173 | void* aligned_malloc(size_t required_bytes, size_t alignment); 174 | void aligned_free(void* r); 175 | 176 | #endif 177 | 178 | /*----------------------------------------------------------------------------- 179 | * 时间转换 180 | -----------------------------------------------------------------------------*/ 181 | #ifdef TIME_CONVERSION 182 | 183 | typedef struct 184 | { 185 | uint16_t year; //[1970,2100] 186 | uint8_t month; //[1,12] 187 | uint8_t day; //[1,31] 188 | uint8_t hour; //[0,23] 189 | uint8_t minte; //[0,59] 190 | uint8_t second;//[0,59] 191 | uint16_t msec; //[0,999] 192 | }TimeStruct; 193 | 194 | uint32_t Time_strTimeToUtime(TimeStruct* pStrTime); 195 | void Time_uTimeToStrTime(uint32_t uTime, TimeStruct* pStrTime); 196 | int Time_checkFormatIsLegal(uint16_t year, uint8_t month, uint8_t day, 197 | uint8_t hour, uint8_t minte, uint8_t second); 198 | #endif 199 | 200 | #endif 201 | 202 | -------------------------------------------------------------------------------- /common.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file common.h 4 | * @brief 常用宏定义 5 | * @version V1.0 6 | * @author 周大侠 7 | * @email zzzdaxia@qq.com 8 | * @date 2022-09-16 10:29:16 9 | ****************************************************************************** 10 | * @remark 11 | Default encoding UTF-8 12 | ****************************************************************************** 13 | */ 14 | #ifndef _COMMON_H_ 15 | #define _COMMON_H_ 16 | 17 | 18 | #define HARDWARE_VERSION "VER123T" 19 | #define SOFTWARE_VERSION "220916_ZDX" 20 | #if (TEST_MODE ) || ( OPEN_WATCH_DOG) 21 | #define PHASE_VERSION "_Test"; 22 | #else 23 | #define PHASE_VERSION "_Beta"; 24 | #endif 25 | #define VERSION_NAME_MAX_SIZE 32U 26 | //版本号 = 硬件版本号 + 软件版本号 + 阶段版本号 27 | //const char SysVersion[VERSION_NAME_MAX_SIZE] = HARDWARE_VERSION SOFTWARE_VERSION PHASE_VERSION; 28 | 29 | //typedef signed long long int64_t; 30 | typedef unsigned long long uint64_t; 31 | typedef unsigned long size_t; 32 | typedef signed int int32_t; 33 | typedef unsigned int uint32_t; 34 | typedef signed short int16_t; 35 | typedef unsigned short uint16_t; 36 | typedef signed char int8_t; 37 | typedef unsigned char uint8_t; 38 | 39 | #ifndef TRUE 40 | #define TRUE (1) 41 | #define FALSE (0) 42 | #endif 43 | 44 | //宏求大小 45 | #define MY_SIZEOF(_T_) ((uint32_t)((typeof(_T_)*)0 + 1)) 46 | 47 | //求结构体成员偏移值 48 | #define OFFSETOF(TYPE, MEMBER) ((long)(&(((TYPE *)0)->MEMBER))) 49 | 50 | //求数组成员个数 51 | #define ARRAY_LEN(ARRAY_NAME) \ 52 | (sizeof(ARRAY_NAME) / sizeof(ARRAY_NAME[0])) 53 | 54 | //获取数组结尾地址, 注意类型 55 | #define GET_ARRAY_TAIL_ADDR(ARRAY_NAME) \ 56 | ((void*)((char*)(&(ARRAY_NAME) + 1 ) - 1)) 57 | 58 | //获取数组最后一个元素地址 59 | #define GET_ARRAY_LAST_ELEMENT_ADDR(ARRAY_NAME,_TYPE_) \ 60 | (((_TYPE_*)(&(ARRAY_NAME) + 1 ) - 1)) 61 | 62 | //求整形差,避免溢出 63 | #define UINT32DIFF(start, end) \ 64 | (((end) >= (start))? ((end) - (start)) : ((uint32_t)(-1) - (start) + (end))) 65 | 66 | 67 | #define SET_BIT(_Val_,_Bit_) ((_Val_) |= (1 << (_Bit_))) 68 | #define CLEAN_BIT(_Val_,_Bit_) ((_Val_) &= (~(1 << (_Bit_)))) 69 | #define GET_BIT(_Val_,_Bit_) (((_Val_) >> (_Bit_)) & 0x0001) 70 | 71 | #define BigLittleSwap16(_16t_) ((((uint16_t)(_16t_) & 0xff00) >> 8) | \ 72 | (((uint16_t)(_16t_) & 0x00ff) << 8)) 73 | 74 | #define BigLittleSwap32(_32t_) ((((uint32_t)(_32t_) & 0xff000000) >> 24) | \ 75 | (((uint32_t)(_32t_) & 0x00ff0000) >> 8) | \ 76 | (((uint32_t)(_32t_) & 0x0000ff00) << 8) | \ 77 | (((uint32_t)(_32t_) & 0x000000ff) << 24)) 78 | 79 | #define TEST_TASK_PERIOD (10U) 80 | #define TEST_TASK_DELAY_MS(_ms_) (((_ms_) > TEST_TASK_PERIOD) ? ((_ms_) / TEST_TASK_PERIOD -1) : 0) 81 | 82 | #endif 83 | 84 | -------------------------------------------------------------------------------- /errcode.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file errcode.h 4 | * @brief 错误码定义 5 | * @version V1.0 6 | * @author 周大侠 7 | * @email zzzdaxia@qq.com 8 | * @date 2022-09-16 10:27:19 9 | ****************************************************************************** 10 | * @remark 11 | Default encoding UTF-8 12 | ****************************************************************************** 13 | */ 14 | #ifndef _ERRCODE_H_ 15 | #define _ERRCODE_H_ 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | /** 22 | * Error codes 23 | * Usage: return negative value with errcode, such as 'return -ERR_NOT_PERMIT' 24 | */ 25 | typedef enum 26 | { 27 | /* System errors */ 28 | SUCCESS = 0, /* Success */ 29 | ERR_NOT_PERMIT, /* Operation not permitted */ 30 | ERR_LONG_PARAM, /* Parameter too long */ 31 | ERR_DEVICE_BUSY, /* Device or resource busy */ 32 | ERR_NO_DEVICE, /* No such device */ 33 | ERR_INVAL_PARAM, /* Invalid external user parmeter */ 34 | ERR_INVAL_ARGU, /* Invalid internal function argument */ 35 | ERR_BUF_FULL, /* Buffer is full */ 36 | ERR_BUF_EMPTY, /* Buffer is empty */ 37 | ERR_BUF_OVERFLOW, /* Buffer is overflow */ 38 | ERR_BUF_BUSY, /* Buffer is in busy (in writing or reading) */ 39 | ERR_BUF_IDLE, /* Buffer is in idle */ 40 | ERR_NOT_IMPLEMENTED, /* Function not implemented */ 41 | ERR_NO_DATA, /* No data available */ 42 | ERR_VAL_OVERFLOW, /* Value overflow */ 43 | ERR_VAL_UNDERFLOW, /* Value underflow */ 44 | ERR_PROTO_NOT_SUPPORT, /* Protocol not supported */ 45 | ERR_NO_MEMORY, /* No memory */ 46 | ERR_ALREADY_INITIALIZED, /* Already initialized */ 47 | ERR_NOT_INITIALIZED, /* Not initialized */ 48 | ERR_FEATURE_NOT_SUPPORT, /* Feature not supported */ 49 | ERR_TIMEOUT, /* Timeout */ 50 | ERR_NO_MORE, /* No more */ 51 | ERR_VERSION_MISMATCH, /* Version mismatch */ 52 | ERR_NOT_READY, /* Not ready yet */ 53 | ERR_INVALID_MODE, /* Invalid mode */ 54 | ERR_UPGRADE_FAILED, /* Upgrade failed */ 55 | ERR_REPEAT_MESSAGE, /* Repeat message */ 56 | 57 | /* Length errors */ 58 | ERR_FRAME_LEN, /* Frame length error */ 59 | ERR_PACKET_LEN, /* Packet length error */ 60 | ERR_APPDATA_LEN, /* Application data length error */ 61 | 62 | /* Format errors */ 63 | ERR_FRAME_FORMAT, /* Frame format error */ 64 | ERR_PACKET_FORMAT, /* Packet format error */ 65 | ERR_APPDATA_FORMAT, /* Application data format error */ 66 | 67 | /* Data validation */ 68 | ERR_DUPLICATE_DATA, /* Duplicate data */ 69 | ERR_FILLED_DATA, /* Filled data */ 70 | ERR_CRC, /* CRC checking failed */ 71 | ERR_XOR, /* XOR checking failed */ 72 | ERR_SUM, /* Sum checking failed */ 73 | ERR_2_OUTOF_3, /* 2 out of 3 checking failed */ 74 | ERR_NOT_2BYTES_ALIGN_ADDR, /* Not 2-bytes aligned address */ 75 | ERR_NOT_4BYTES_ALIGN_ADDR, /* Not 4-bytes aligned address */ 76 | 77 | /* Hardware errors */ 78 | ERR_SPI_SEND, /* SPI sending error */ 79 | ERR_SPI_RECV, /* SPI receiving error */ 80 | ERR_I2C_SEND, /* I2C sending error */ 81 | ERR_I2C_RECV, /* I2C receiving error */ 82 | ERR_UART_SEND, /* UART sending error */ 83 | ERR_UART_RECV, /* UART receiving error */ 84 | ERR_CAN_SEND, /* CAN sending error */ 85 | ERR_CAN_RECV, /* CAN receiving error */ 86 | ERR_CAN_NODE, /* CAN node unknown error */ 87 | ERR_CAN_FRAME_SEQ, /* CAN frame sequence error */ 88 | ERR_FIFO_WRITE, /* FIFO writing error */ 89 | ERR_FIFO_READ, /* FIFO reading error */ 90 | ERR_NAND_ERASE, /* NAND erasing error */ 91 | ERR_NAND_WRITE, /* NAND writing error */ 92 | ERR_NAND_READ, /* NAND reading error */ 93 | ERR_FERAM_WRITE, /* FeRAM writing error */ 94 | ERR_FERAM_READ, /* FeRAM reading error */ 95 | 96 | /* 'ERR_CODE_MAX' should always be the last */ 97 | ERR_CODE_MAX 98 | } errCode; 99 | 100 | #ifdef __cplusplus 101 | } 102 | #endif 103 | 104 | #endif 105 | --------------------------------------------------------------------------------