*(字符型 *)addr=data;

本文探讨了在调试NANDFLASH代码时遇到的内存映射问题,特别是如何通过指针操作实现对特定地址的数据写入。通过示例说明了如何设置数据对齐方式并进行内存写入。

今天在调试NAND FLASH代码的时候,对映射地址赋值的时候,碰到指针的问题,脑子又不清醒。

例:

 

我起初还以为是什么指针的指针。

后来根据别人代码和自己的理解,脑子清醒点了,这个问题以前碰到过。

这句话的意思,先将地址0x70000000存取的数据的对齐方式设为unsigned char型(即8位对齐)然后对地址为0x70000000写入数据0x90

. ├── bin │ ├── common.o │ ├── epoll_serv │ ├── epoll_serv.o │ ├── process_serv │ ├── process_serv.o │ ├── pthread_serv │ └── pthread_serv.o ├── include │ └── common.h ├── Makefile ├── src │ ├── common.c │ ├── epoll_serv.c │ ├── process_serv.c │ └── pthread_serv.c └── web ├── About.html ├── Contact.html ├── css │ ├── reset.css │ ├── style.css │ └── style_mobile.css ├── data │ └── contact.json ├── images │ ├── About_baby.png │ ├── About_ball.png │ ├── About_be.png │ ├── About_bird.png │ ├── About_content.png │ ├── About_message.png │ ├── About_@.png │ ├── body.png │ ├── footer_baby.png │ ├── footer_ball.png │ ├── footer_be.png │ ├── footer_bird.png │ ├── footer_message.png │ ├── footer_@.png │ ├── footer.png │ ├── header.png │ └── Thumbs.db ├── img │ ├── 1.jpg │ ├── 2.jpg │ ├── 3.jpg │ ├── 4.jpg │ ├── 5.jpg │ ├── 6.jpg │ └── Thumbs.db ├── Index.html ├── js │ ├── action.js │ └── jquery-1.9.1.min.js ├── test.html └── Work.html 以上是我的文件目录数,web文件里面的内容是实验提供的, ├── include │ └── common.h ├── Makefile ├── src │ ├── common.c │ ├── epoll_serv.c │ ├── process_serv.c │ └── pthread_serv.c 这几个是我自己写的,代码如下: common.h #ifndef __COMMON_H__ #define __COMMON_H__ #define _XOPEN_SOURCE 700 // 消除sigaction相关报错 #include <stdio.h> // 标准输入输出 #include <stdlib.h> // 标准库函数 #include <string.h> // 字符串处理 #include <unistd.h> // UNIX标准函数 #include <sys/socket.h> // 套接字接口 #include <netinet/in.h> // 网络地址结构 #include <arpa/inet.h> // 地址转换函数 #include <fcntl.h> // 文件控制 #include <sys/stat.h> // 文件状态 #include <sys/sendfile.h> // 高效文件传输 #include <sys/types.h> // 系统类型 #include <dirent.h> // 目录操作 #include <errno.h> // 错误码 #include <regex.h> // 正则表达式 #include <sys/wait.h> // 关闭子进程 #include <signal.h> // 信号处理 #include <sys/epoll.h> // epoll I/O多路复用 #include <pthread.h> // 多线程头文件 #include <semaphore.h> // 信号量 #define PORT 80 // 监听端口 #define MAX_EVENTS 1024 // epoll最大事件数 #define BUFFER_SIZE 4096 // 请求缓冲区大小 #define ROOT_DIR "./web" // Web根目录,根据执行可执行文件的路径来设置 #define MAX_MATCHES 30 // 最大匹配数 /* 根据文件扩展名获取MIME类型 */ const char *get_mime_type(const char *path); /* 发送HTTP响应 */ void send_response(int fd, int status, const char *status_msg, const char *content_type, const char *body, int body_len); /* 发送文件内容 */ void send_file(int fd, const char *path); /* 处理GET请求 */ void handle_get_request(int fd, const char *path); /* 处理POST请求 */ void handle_post_request(int fd, const char *path, const char *body, int body_len); /* 处理HTTP请求 */ void handle_request(int fd, const char *request); #endif process_serv.c #include "common.h" #define WORKER_PROCESSES 1 /* 工作进程数量 */ /* 信号处理函数,用于销毁子进程 */ void read_childproc(int sig) { /* 入参检查*/ if (sig < 0) { return; } pid_t pid; int status; while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { if (WIFEXITED(status)) { printf("Normal removed proc id: %d\n", pid); } else { printf("Abnormal removed proc id: %d\n", pid); } } } /* 进程工作 */ void worker_process(int server_fd) { /* 入参检查*/ if (server_fd <= 2) { return; } while (1) { struct sockaddr_in client_addr; socklen_t addrlen = sizeof(client_addr); int client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &addrlen); if (client_fd < 0) { if (errno == EINTR) continue; /* 被信号中断,重试 */ perror("accept"); continue; } printf("[Worker %d] New connection: %s:%d\n", getpid(), inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); /* 读取请求 */ char buffer[BUFFER_SIZE]; ssize_t bytes_read = read(client_fd, buffer, BUFFER_SIZE - 1); if (bytes_read <= 0) { close(client_fd); continue; } buffer[bytes_read] = '\0'; fprintf(stdout, "======buffer======\n%s============\nclient_fd:%d\n", buffer, client_fd); /* 处理请求 */ handle_request(client_fd, buffer); /* 关闭连接 */ close(client_fd); } } /** * 主函数:设置服务器并创建工作进程 */ int main() { int server_fd; struct sockaddr_in addr; socklen_t addrlen = sizeof(addr); /* 创建套接字 */ if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket failed"); exit(EXIT_FAILURE); } /* 设置套接字选项(允许地址重用) */ int opt = 1; if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { perror("setsockopt failed"); close(server_fd); exit(EXIT_FAILURE); } /* 绑定地址 */ memset(&addr, 0, addrlen); addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons(PORT); if (bind(server_fd, (struct sockaddr *)&addr, addrlen) < 0) { perror("bind failed"); close(server_fd); exit(EXIT_FAILURE); } /* 开始监听 */ if (listen(server_fd, SOMAXCONN) < 0) { perror("listen failed"); close(server_fd); exit(EXIT_FAILURE); } printf("Web server running on port %d...\n", PORT); printf("Root directory: %s\n", ROOT_DIR); /* 设置信号处理 */ struct sigaction act; act.sa_handler = read_childproc; sigemptyset(&act.sa_mask); act.sa_flags = SA_NOCLDSTOP | SA_RESTART; /* 注册信号 */ if (sigaction(SIGCHLD, &act, 0) < 0) { perror("sigaction failed"); close(server_fd); exit(EXIT_FAILURE); } /* 创建工作进程 */ for (int i = 0; i < WORKER_PROCESSES; i++) { pid_t pid = fork(); if (pid == 0) { /* 子进程 */ worker_process(server_fd); exit(EXIT_SUCCESS); } else if (pid < 0) { perror("fork failed"); exit(EXIT_FAILURE); } } /* 主进程等待 */ while (1) { pause(); /* 等待信号 */ } close(server_fd); return 0; } epoll_serv.c #include "common.h" /* 客户端数据结构 */ typedef struct { int fd; /* 客户端套接字描述符 */ char buffer[BUFFER_SIZE]; /* 请求数据缓冲区 */ int buffer_len; /* 当前缓冲区数据长度 */ int status; /* 客户端状态(0:等待,1:读取中,2:写入中) */ } client_data; /** * 工作进程函数(处理客户端连接) */ void worker_process(int server_fd) { /* 入参检查*/ if (server_fd <= 2) { return; } while (1) { struct sockaddr_in client_addr; socklen_t addrlen = sizeof(client_addr); int client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &addrlen); if (client_fd < 0) { if (errno == EINTR) continue; /* 被信号中断,重试 */ perror("accept"); continue; } printf("[Worker %d] New connection: %s:%d\n", getpid(), inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); /* 读取请求 */ char buffer[BUFFER_SIZE]; ssize_t bytes_read = read(client_fd, buffer, BUFFER_SIZE - 1); if (bytes_read <= 0) { close(client_fd); continue; } buffer[bytes_read] = '\0'; fprintf(stdout, "======buffer======\n%s============\n", buffer); /* 处理请求 */ handle_request(client_fd, buffer); /* 关闭连接 */ close(client_fd); } } /** * 主函数:设置服务器并运行事件循环 */ int main() { int server_fd, epoll_fd; struct sockaddr_in addr; socklen_t addrlen = sizeof(addr); /* 1. 创建服务器套接字 */ if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket failed"); exit(EXIT_FAILURE); } /* 设置套接字选项(允许地址重用) */ int opt = 1; if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { perror("setsockopt failed"); close(server_fd); exit(EXIT_FAILURE); } /* 2. 配置服务器地址 */ addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; /* 监听所有网络接口 */ addr.sin_port = htons(PORT); /* 监听端口 */ /* 3. 绑定套接字 */ if (bind(server_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("bind failed"); close(server_fd); exit(EXIT_FAILURE); } /* 4. 开始监听 */ if (listen(server_fd, SOMAXCONN) < 0) { perror("listen failed"); close(server_fd); exit(EXIT_FAILURE); } printf("Web server running on port %d...\n", PORT); printf("Root directory: %s\n", ROOT_DIR); /* 5. 创建epoll实例 */ if ((epoll_fd = epoll_create1(0)) < 0) { perror("epoll_create1 failed"); close(server_fd); exit(EXIT_FAILURE); } /* 6. 添加服务器套接字到epoll */ struct epoll_event ev; ev.events = EPOLLIN; /* 监听读事件 */ ev.data.fd = server_fd; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, &ev) < 0) { perror("epoll_ctl failed"); close(server_fd); close(epoll_fd); exit(EXIT_FAILURE); } printf("Web server running on port %d...\n", PORT); printf("Root directory: %s\n", ROOT_DIR); /* 7. 分配客户端数据存储空间 */ struct epoll_event events[MAX_EVENTS]; client_data *clients = calloc(MAX_EVENTS, sizeof(client_data)); /* 8. 主事件循环 */ while (1) { /* 等待事件发生 */ int nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1); /* 一直等到事件发生 */ if (nfds < 0) { perror("epoll_wait"); continue; } /* 处理所有就绪事件 */ for (int i = 0; i < nfds; i++) { int fd = events[i].data.fd; /* 处理新连接 */ if (fd == server_fd) { /* 接受新连接 */ int client_fd = accept(server_fd, (struct sockaddr *)&addr, &addrlen); if (client_fd < 0) { perror("accept"); continue; } /* 设置非阻塞模式 */ fcntl(client_fd, F_SETFL, fcntl(client_fd, F_GETFL, 0) | O_NONBLOCK); /* 添加新客户端到epoll */ ev.events = EPOLLIN | EPOLLET; /* 边缘触发模式 */ ev.data.fd = client_fd; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &ev) < 0) { perror("epoll_ctl client"); close(client_fd); } /* 初始化客户端数据 */ clients[client_fd].fd = client_fd; clients[client_fd].buffer_len = 0; clients[client_fd].status = 0; printf("New connection: %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); } else { /* 处理现有客户端数据 */ client_data *client = &clients[fd]; /* 读取客户端数据 */ int bytes_read = read(fd, client->buffer + client->buffer_len, BUFFER_SIZE - client->buffer_len); if (bytes_read <= 0) { /* 连接关闭或错误 */ epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL); close(fd); memset(client, 0, sizeof(client_data)); continue; } /* 更新缓冲区 */ client->buffer_len += bytes_read; client->buffer[client->buffer_len] = '\0'; /* 检查是否收到完整HTTP请求(以空行结束) */ if (strstr(client->buffer, "\r\n\r\n") != NULL) { /* 处理请求 */ handle_request(fd, client->buffer); /* 重置缓冲区 */ client->buffer_len = 0; memset(client->buffer, 0, BUFFER_SIZE); } } } } /* 清理资源(实际不会执行到这里) */ free(clients); close(server_fd); close(epoll_fd); return 0; } pthread.c #include "common.h" #include <pthread.h> #include <errno.h> /* 线程工作函数 */ void *worker_pthread(void *arg) { /* 入参检查*/ if (NULL == arg) { return NULL; } /* 从参数中获取客户端文件描述符 */ int client_fd = *(int *)arg; free(arg); /* 释放动态分配的内存 */ printf("------------------------- work process ----------------------------\n"); char buffer[BUFFER_SIZE]; ssize_t bytes_read = read(client_fd, buffer, BUFFER_SIZE - 1); if (bytes_read < 0) { perror("read error"); close(client_fd); return NULL; } buffer[bytes_read] = '\0'; /* 确保字符串正确终止 */ /* 修复格式字符串:参数顺序应与格式匹配 */ fprintf(stdout, "======buffer======\nclient_fd:%d\t\n%s============\n", client_fd, buffer); /* ======buffer====== client_fd:5 GET /images/footer.png HTTP/1.1 Host: localhost User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0 Accept: Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: http://localhost/css/style_mobile.css Connection: keep-alive ============ */ /* 处理请求 */ if (strlen(buffer) > 0) { handle_request(client_fd, buffer); } /* 关闭连接 */ close(client_fd); printf("______________________________________________________\n"); return NULL; } /** * 主函数:设置服务器并创建回收线程 */ int main() { int server_fd; struct sockaddr_in addr, client_addr; socklen_t client_len = sizeof(client_addr); /* 创建套接字 */ if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket creation failed"); exit(EXIT_FAILURE); } /* 设置套接字选项(允许地址重用) */ int opt = 1; if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { perror("setsockopt failed"); close(server_fd); exit(EXIT_FAILURE); } /* 绑定地址 */ memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons(PORT); if (bind(server_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("bind failed"); close(server_fd); exit(EXIT_FAILURE); } /* 开始监听 */ if (listen(server_fd, SOMAXCONN) < 0) { perror("listen failed"); close(server_fd); exit(EXIT_FAILURE); } printf("Web server running on port %d...\n", PORT); printf("Root directory: %s\n", ROOT_DIR); while (1) { /* 接受新连接 */ int client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_len); if (client_fd < 0) { perror("accept failed"); continue; } /* 动态分配内存传递client_fd(避免线程间竞争) */ int *client_ptr = malloc(sizeof(int)); if (!client_ptr) { perror("malloc failed"); close(client_fd); continue; } *client_ptr = client_fd; /* 创建新线程处理连接 */ pthread_t t_id; if (pthread_create(&t_id, NULL, worker_pthread, client_ptr) != 0) { perror("pthread_create failed"); free(client_ptr); close(client_fd); continue; } /* 分离线程(自动回收资源) */ pthread_detach(t_id); printf("New connection: %s:%d (thread %lu)\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), (unsigned long)t_id); } close(server_fd); return 0; } 实验要求如下,帮我写一个实验报告
08-16
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #include <pthread.h> #include <sys/stat.h> #include <fcntl.h> #define PORT 8080 /* 服务器监听端口 */ #define BUFFER_SIZE 4096 /* 缓冲区大小 */ #define WEB_ROOT "/mydisk/test/webserver/web" /* 网站根目录 */ /** * @brief 根据文件路径获取文件类型和连接类型 * * 该函数根据给定的文件路径提取文件的扩展名,并根据扩展名确定文件的连接类型。 * * @param filePath 文件路径,C风格字符串 * @param file_extension 用于存储文件扩展名的缓冲区,C风格字符串 * @param connect_type 用于存储文件连接类型的缓冲区,C风格字符串 */ void getContentType(const char *filePath, char *connect_type) { // 查找文件名中的最后一个点字符,用于提取扩展名 const char *dot_position = strrchr(filePath, '.'); char file_extension[10] = {0}; if (dot_position != NULL) { // 扩展名是从点后开始的 strcpy(file_extension, dot_position + 1); } else { // 如果没有点字符,说明没有扩展名 strcpy(file_extension, ""); } if(strcmp(file_extension, "html") == 0) { strcpy(connect_type, "text/html"); } else if(strcmp(file_extension, "jpg") == 0) { strcpy(connect_type, "image/jpeg"); } else if(strcmp(file_extension, "png") == 0) { strcpy(connect_type, "image/png"); } else if(strcmp(file_extension, "css") == 0) { strcpy(connect_type, "text/css"); } else if(strcmp(file_extension, "js") == 0){ strcpy(connect_type, "text/javascript"); } else{ strcpy(connect_type, "text/plain"); } } void *handle_client(void *arg) { int client_socket = *((int *)arg); /* 获取客户端的socket */ free(arg); /* 释放参数内存 */ char buffer[BUFFER_SIZE]; /* 缓冲区 */ ssize_t bytes_read = read(client_socket, buffer, BUFFER_SIZE); /* 读取的字节数 */ if (bytes_read < 0) { perror("读取数据失败"); close(client_socket); return NULL; } buffer[bytes_read] = '\0'; /* 添加字符串结束符 */ /* 解析HTTP请求 */ char *saveptr; char *method = strtok_r(buffer, " ", &saveptr); char *path = strtok_r(NULL, " ", &saveptr); printf("Buffer:%s , Method: %s, Path: %s\n", buffer, method, path); if (method == NULL || path == NULL) { perror("解析HTTP请求失败"); close(client_socket); return NULL; } /* 构建本地文件路径 */ char file_path[BUFFER_SIZE]; if (strcmp(path, "/") == 0) { snprintf(file_path, sizeof(file_path), "%s/Index.html", WEB_ROOT); /* 默认首页 */ } else { snprintf(file_path, sizeof(file_path), "%s%s", WEB_ROOT, path); } printf("File_Path:%s\n", file_path); /* 检查文件是否存在 */ struct stat file_stat; if (stat(file_path, &file_stat) == -1 || S_ISDIR(file_stat.st_mode)) { char path[BUFFER_SIZE]; getcwd(path, sizeof(path)); printf("%s\n", path); printf("path:%d, access:%d ,stat:%d, s_isdir:%d\r\n", access(file_path, F_OK), access(file_path, R_OK / W_OK), stat(file_path, &file_stat) == -1, S_ISDIR(file_stat.st_mode)); char response[] = "HTTP/1.1 404 Not Found\r\n" "Content-Type: text/html\r\n" "Content-Length: %ld\r\n\r\n" "<html><body><h1>404 Not Found</h1></body></html>\r\n"; write(client_socket, response, strlen(response)); printf("回答是:%s", response); } else { /* 读取文件内容并发送 */ int file_fd = open(file_path, O_RDONLY); if (file_fd == -1) { perror("打开文件失败"); close(client_socket); return NULL; } char response[BUFFER_SIZE]; char content_type[20] = {0}; getContentType(file_path, content_type); snprintf(response, sizeof(response), "HTTP/1.1 200 OK\r\n" "Content-Type: %s\r\n" "Content-Length: %ld\r\n\r\n", content_type, file_stat.st_size); write(client_socket, response, strlen(response)); printf("回答是:%s", response); char file_buffer[BUFFER_SIZE]; ssize_t bytes_written; while ((bytes_written = read(file_fd, file_buffer, BUFFER_SIZE)) > 0) { write(client_socket, file_buffer, bytes_written); } close(client_socket); } close(client_socket); return NULL; } int main() { /* 创建服务器 */ int server_socket = socket(AF_INET, SOCK_STREAM, 0); /* TCP套接字*/ if (server_socket == -1) { perror("创建套接字失败"); exit(EXIT_FAILURE); } /* 配置服务器地址 */ struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; /* IPv4地址 */ server_addr.sin_port = htons(PORT); server_addr.sin_addr.s_addr = INADDR_ANY; /* 监听所有地址 */ /* 绑定地址 */ if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) { perror("绑定套接字失败"); close(server_socket); exit(EXIT_FAILURE); } /* 开始监听 */ if (listen(server_socket, 15) == -1) { perror("监听套接字失败"); close(server_socket); exit(EXIT_FAILURE); } while (1) { struct sockaddr_in client_addr; socklen_t client_addr_size = sizeof(client_addr); int *client_socket = malloc(sizeof(int)); /* 客户端socket */ if (client_socket == NULL) { perror("内存分配失败"); continue; } else { *client_socket = -1; } /* 接受新连接 */ *client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_addr_size); if (*client_socket == -1) { perror("接受连接失败"); free(client_socket); continue; } else { printf("接受连接成功,客户端地址:%s\n", inet_ntoa(client_addr.sin_addr)); } /* 创建新线程处理客户端 */ pthread_t thread_id; if (pthread_create(&thread_id, NULL, handle_client, (void *)client_socket) != 0) { perror("创建线程失败"); close(*client_socket); free(client_socket); } /* 创建线程处理客户端 */ pthread_detach(thread_id); /* 使线程分离,自动回收资源,避免资源泄露 */ } close(server_socket); return 0; } 根据我上面的webserver的多线程实现,给出对应的多进程实现和IO多路复用实现,并给出三种方案的优缺点分析,如何测试性能
08-16
/*************************************************************************** * @file power_data.c * @brief * **************************************************************************** * @attention * * Created on: 2025-05-12 * Author: YL Monitor Software group * **************************************************************************** * @description * 功率部件的数据缓存处理模块 * * ****************************************************************************/ /************************ Includes *************************/ /************************ 宏指令 *************************/ #include "power_data.h" #include "main.h" /************************ Private types *************************/ /************************ Private constants *************************/ /************************ 功能结构体 *************************/ typedef enum{ CACHE_L1_LOADING = 0xA1,/*正在加载数据*/ CACHE_L1_READY = 0xA2,/*数据就绪*/ CACHE_L1_SENT = 0xA2,/*数据已上传至LEVEL2*/ }ENUM_CACHE_L1_STATUS; typedef enum{ CACHE_L2_SENDING = 0x55,/*数据待上传*/ CACHE_L2_SENT = 0xAA,/*数据已上传*/ }ENUM_CACHE_L2_STATUS; /************************ Private macros *************************/ /************************ Private variables *************************/ /************************ 私有变量 *************************/ #if !SERIAL1_DMARx_ENABLE //禁用DMA1读取 0 /* 一级数据缓存:用于功率部件接收数据的实时缓存 */ uint8_t power1_data_cache_L1[POWER_DEVICE_DATA_SIZE] = {0}; static SemaphoreHandle_t mutex_RW_Power1_L1 = NULL; /* 一级缓存当前数据写入位置 */ static uint16_t power1_L1_wPos = 0; /* 一级数据缓存状态 */ static uint16_t power1_L1_status = CACHE_L1_LOADING; #endif #if !SERIAL2_DMARx_ENABLE //禁用DMA2读取 0 /* 一级数据缓存:用于功率部件接收数据的实时缓存 */ uint8_t power2_data_cache_L1[POWER_DEVICE_DATA_SIZE] = {0}; static SemaphoreHandle_t mutex_RW_Power2_L1 = NULL; /* 一级缓存当前数据写入位置 */ static uint16_t power2_L1_wPos = 0; /* 一级数据缓存状态 */ static uint16_t power2_L1_status = CACHE_L1_LOADING; #endif /* 二级数据缓存:用于系统状态监控 */ static uint8_t power1_data_cache_L2[POWER_DEVICE_DATA_SIZE] = {0}; static uint8_t power2_data_cache_L2[POWER_DEVICE_DATA_SIZE] = {0}; static SemaphoreHandle_t mutex_RW_Power1_L2 = NULL; static SemaphoreHandle_t mutex_RW_Power2_L2 = NULL; /* 二级数据缓存状态 */ static uint8_t power1_L2_status = CACHE_L2_SENDING; static uint8_t power2_L2_status = CACHE_L2_SENDING; /************************ Functions *************************/ /************************ 功能函数 *************************/ /************************************************************ * @funName : MD_SwInitPowerData * @Input : NULL * * @Output : ***************** * @Description : 数据缓存模块软件资源初始化 * * ***************** * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/5/12 * *************************************************************/ void MD_SwInitPowerData(void) { #if !SERIAL1_DMARx_ENABLE if(NULL == mutex_RW_Power1_L1) { mutex_RW_Power1_L1 = xSemaphoreCreateBinary(); /* 数据读写互斥量创建失败 */ if(NULL == mutex_RW_Power1_L1) { } else { /* 释放数据读写互斥量 */ xSemaphoreGive(mutex_RW_Power1_L1); } } #endif #if SERIAL2_DMARx_ENABLE #else if(NULL == mutex_RW_Power2_L1) { mutex_RW_Power2_L1 = xSemaphoreCreateBinary(); /* 数据读写互斥量创建失败 */ if(NULL == mutex_RW_Power2_L1) { } else { /* 释放数据读写互斥量 */ xSemaphoreGive(mutex_RW_Power2_L1); } } #endif if(NULL == mutex_RW_Power1_L2) { mutex_RW_Power1_L2 = xSemaphoreCreateBinary(); /* 数据读写互斥量创建失败 */ if(NULL == mutex_RW_Power1_L2) { } else { /* 释放数据读写互斥量 */ xSemaphoreGive(mutex_RW_Power1_L2); } } if(NULL == mutex_RW_Power2_L2) { mutex_RW_Power2_L2 = xSemaphoreCreateBinary(); /* 数据读写互斥量创建失败 */ if(NULL == mutex_RW_Power2_L2) { } else { /* 释放数据读写互斥量 */ xSemaphoreGive(mutex_RW_Power2_L2); } } } /************************************************************ * @funName : MD_UpdatePowerL2 * @Input : device-功率部件序号 * * @Output : ***************** * @Description : 更新功率部件二级缓存数据 * * ***************** * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/5/12 * *************************************************************/ void MD_UpdatePowerL2(const uint8_t device) { switch(device) { case POWER_DEVICE_1: { #if SERIAL1_DMARx_ENABLE if(BSP_GetRecvSize4Serial1() >= POWER_DEVICE_DATA_SIZE) { uint8_t rbuf[POWER_DEVICE_DATA_SIZE] = {0}; uint16_t rlen = 0; BSP_Recv4Serial1(rbuf, &rlen); if(rlen >= POWER_DEVICE_DATA_SIZE){ portBASE_TYPE xRecvWoken = pdFALSE; xSemaphoreTakeFromISR(mutex_RW_Power1_L2, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); memcpy((uint8_t*)power1_data_cache_L2, (uint8_t*)rbuf, POWER_DEVICE_DATA_SIZE); power1_L2_status = CACHE_L2_SENDING;/* 待发送 */ xRecvWoken = pdFALSE; xSemaphoreGiveFromISR(mutex_RW_Power1_L2, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); } } #else if(CACHE_L1_READY == power1_L1_status) { portBASE_TYPE xRecvWoken = pdFALSE; xSemaphoreTakeFromISR(mutex_RW_Power1_L2, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); memcpy((uint8_t*)power1_data_cache_L2, (uint8_t*)power1_data_cache_L1, POWER_DEVICE_DATA_SIZE); power1_L1_status = CACHE_L1_SENT; power1_L2_status = CACHE_L2_SENDING;/* 待发送 */ xRecvWoken = pdFALSE; xSemaphoreGiveFromISR(mutex_RW_Power1_L2, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); } #endif }break; case POWER_DEVICE_2: { #if SERIAL2_DMARx_ENABLE if(BSP_GetRecvSize4Serial2() >= POWER_DEVICE_DATA_SIZE) { uint8_t rbuf[POWER_DEVICE_DATA_SIZE] = {0}; uint16_t rlen = 0; BSP_Recv4Serial2(rbuf, &rlen); if(rlen >= POWER_DEVICE_DATA_SIZE){ portBASE_TYPE xRecvWoken = pdFALSE; xSemaphoreTakeFromISR(mutex_RW_Power2_L2, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); memcpy((uint8_t*)power2_data_cache_L2, (uint8_t*)rbuf, POWER_DEVICE_DATA_SIZE); power2_L2_status = CACHE_L2_SENDING;/* 待发送 */ xRecvWoken = pdFALSE; xSemaphoreGiveFromISR(mutex_RW_Power2_L2, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); } } #else if(CACHE_L1_READY == power2_L1_status) { portBASE_TYPE xRecvWoken = pdFALSE; xSemaphoreTakeFromISR(mutex_RW_Power2_L2, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); memcpy((uint8_t*)power2_data_cache_L2, (uint8_t*)power2_data_cache_L1, POWER_DEVICE_DATA_SIZE); power1_L1_status = CACHE_L1_SENT; power2_L2_status = CACHE_L2_SENDING;/* 待发送 */ xRecvWoken = pdFALSE; xSemaphoreGiveFromISR(mutex_RW_Power2_L2, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); } #endif }break; } } /************************************************************ * @funName : MD_UpdatePowerL1 * @Input : device-功率部件序号 * bFirst-是否为第一个数据 * wbuf-数据 * wlen-数据长度 * * @Output : ***************** * @Description : 更新功率部件一级缓存数据 * * ***************** * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/5/12 * *************************************************************/ //static uint8_t byte = 0; void MD_UpdatePowerL1(const uint8_t device, const bool bFirst, const uint8_t* wbuf, const uint16_t wlen) { uint16_t len = wlen; if(wlen <= 0) { return; } switch(device) { case POWER_DEVICE_1: { #if SERIAL1_DMARx_ENABLE #else if(bFirst) { power1_L1_status = CACHE_L1_LOADING; power1_L1_wPos = 0; memset((uint8_t*)power1_data_cache_L1, 0, POWER_DEVICE_DATA_SIZE); } if(len > POWER_DEVICE_DATA_SIZE - power1_L1_wPos) { len = POWER_DEVICE_DATA_SIZE - power1_L1_wPos; } portBASE_TYPE xRecvWoken = pdFALSE; xSemaphoreTakeFromISR(mutex_RW_Power1_L1, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); memcpy((uint8_t*)&power1_data_cache_L1[power1_L1_wPos], wbuf, len); power1_L1_wPos += len; xRecvWoken = pdFALSE; xSemaphoreGiveFromISR(mutex_RW_Power1_L1, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); if(POWER_DEVICE_DATA_SIZE <= power1_L1_wPos) { power1_L1_status = CACHE_L1_READY; } #endif }break; case POWER_DEVICE_2: { #if SERIAL2_DMARx_ENABLE #else if(bFirst) { power2_L1_status = CACHE_L1_LOADING; power2_L1_wPos = 0; memset((uint8_t*)power2_data_cache_L1, 0, POWER_DEVICE_DATA_SIZE); } if(len > POWER_DEVICE_DATA_SIZE - power2_L1_wPos) { len = POWER_DEVICE_DATA_SIZE - power2_L1_wPos; } portBASE_TYPE xRecvWoken = pdFALSE; xSemaphoreTakeFromISR(mutex_RW_Power2_L1, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); memcpy((uint8_t*)&power2_data_cache_L1[power2_L1_wPos], wbuf, len); power2_L1_wPos += len; xRecvWoken = pdFALSE; xSemaphoreGiveFromISR(mutex_RW_Power2_L1, &xRecvWoken); portYIELD_FROM_ISR(xRecvWoken); if(POWER_DEVICE_DATA_SIZE <= power2_L1_wPos) { power2_L1_status = CACHE_L1_READY; } #endif }break; } } /********************功率部件一级缓存数据********************/ /************************************************************ * @funName : MD_ReadPowerL2 * @Input : device-功率部件序号 * rbuf-数据输出缓存 * pos-数据读取位置 * rlen-数据读取长度 * * @Output : ***************** * @Description : 获取功率部件二级缓存数据 * * ***************** * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/5/13 * *************************************************************/ bool MD_ReadPowerL2(const uint8_t device, uint8_t *rbuf, const uint16_t pos, const uint16_t rlen) { if(rlen > POWER_DEVICE_DATA_SIZE || pos >= POWER_DEVICE_DATA_SIZE || POWER_DEVICE_DATA_SIZE - pos < rlen) { return false; } switch(device) { case POWER_DEVICE_1: { xSemaphoreTake(mutex_RW_Power1_L2, portMAX_DELAY); memcpy(rbuf, (uint8_t*)&power1_data_cache_L2[pos], rlen); xSemaphoreGive(mutex_RW_Power1_L2); }break; case POWER_DEVICE_2: { xSemaphoreTake(mutex_RW_Power2_L2, portMAX_DELAY); memcpy(rbuf, (uint8_t*)&power2_data_cache_L2[pos], rlen); xSemaphoreGive(mutex_RW_Power2_L2); }break; } return true; } /************************************************************ * @funName : MD_GetPowerL2 * @Input : device-功率部件序号 * rbuf-数据缓存地址 * * @Output : ***************** * @Description : 获取功率部件二级缓存地址 * * ***************** * @Athor : YL Software Group * @Version : V0.0.0 * @Data : 2025/5/13 * *************************************************************/ uint8_t* MD_GetPowerL2(const uint8_t device) { uint8_t* addr = NULL; switch(device) { case POWER_DEVICE_1: { xSemaphoreTake(mutex_RW_Power1_L2, portMAX_DELAY); if(CACHE_L2_SENDING != power1_L2_status) { addr = NULL; } else { power1_L2_status = CACHE_L2_SENT; addr = power1_data_cache_L2; } xSemaphoreGive(mutex_RW_Power1_L2); }break; case POWER_DEVICE_2: { xSemaphoreTake(mutex_RW_Power2_L2, portMAX_DELAY); if(CACHE_L2_SENDING != power2_L2_status) { addr = NULL; } else{ power2_L2_status = CACHE_L2_SENT; addr = power2_data_cache_L2; } xSemaphoreGive(mutex_RW_Power1_L2); }break; } return addr; } /************************ End of file *************************/ /*************************************************************************** * @file fw_data.h * @brief This file contains the macros & function about real data for framework & App. * **************************************************************************** * @attention * * Created on: 2025-05-30 * Author: YL Monitor Software group * **************************************************************************** * @description * * * ****************************************************************************/ #ifndef __FW_DATA_H_ #define __FW_DATA_H_ #ifdef __cplusplus extern "C" { #endif /************************ Includes *************************/ #include "main.h" /************************ Exportd types ********************/ typedef struct{ uint8_t byte_H; uint8_t byte_L; }Power_Bits16; typedef struct{ uint8_t byte0; uint8_t byte1; uint8_t byte2; uint8_t byte3; }Power_Bits32; /* 功率部件系统参数 */ typedef struct{ /* word 0 */ Power_Bits16 Reserved0; //0-预留 /* word 1 */ Power_Bits16 SYSCTRL; //1-系统控制 /* word 2 */ Power_Bits16 Flag; //2-系统状态标志 /* word 3 */ Power_Bits16 ProtectHard_PROHARD; //3-硬件保护标志 /* word 4 */ Power_Bits16 ProtectSoft_PROSOFT; //4-软件保护标志 /* word 5 */ Power_Bits16 ProtectDrive_PRODRIVE; //5-驱动保护标志 /* word 6 */ Power_Bits16 ProtectComm_PROCOMM; //6-通信保护标志 /* word 7 */ Power_Bits16 INVCTRL; //7-逆变器控制 /* word 8 */ Power_Bits16 Reserved8; //预留 /* word 9 */ Power_Bits16 Reserved9; //预留 /* word 10 */ Power_Bits16 Reserved10; //预留 /* word 11 */ Power_Bits32 GPADAT_H; //GPIO0~31状态 /* word 12 */ Power_Bits32 GPADAT_L; //GPIO0~31状态 /* word 13*/ Power_Bits32 GPBDAT_H; //GPIO32~63状态 /* word 14 */ Power_Bits32 GPBDAT_L; //GPIO32~63状态 /* word 15 */ Power_Bits32 GPCDAT_H; //GPIO64~87状态 /* word 16 */ Power_Bits32 GPCDAT_L; //GPIO64~87状态 /* word 17 */ Power_Bits16 Reserved17; //预留 /* word 18 */ Power_Bits16 Reserved18; //预留 /* word 19 */ Power_Bits16 Reserved19; //预留 /* word 20 */ Power_Bits16 OSC_CLK_FRQ; //外部晶振频率 /* word 21 */ Power_Bits16 SYS_CLK_FRQ; //系统时钟频率 /* word 22 */ Power_Bits16 SYS_TICK; //定时器时钟基准 /* word 23 */ Power_Bits16 SET_F_PWM; //开关频率 /* word 24 */ Power_Bits16 Reserved24; //预留 /* word 25 */ Power_Bits16 SysMode; //工作模式 /* word 26 */ Power_Bits16 SysState; //工作状态 /* word 27 */ Power_Bits16 SysStartMode; //启动方式 /* word 28*/ Power_Bits16 SysStartStopControl; //启停控制指令来源 /* word 29*/ Power_Bits16 SysCommandSource; //系统频率指令来源 /* word 30*/ Power_Bits16 ModID; //模块编号 /* word 31*/ Power_Bits16 SETUP_UOUT; //电压设定值 /* word 32*/ Power_Bits16 SETUP_IOUT; //电流设定值 /* word 33*/ Power_Bits16 SETUP_FREQ; //频率设定值 /* word 34*/ Power_Bits16 SOFTSTART_TIME; //软件起动时间 /* word 35*/ Power_Bits16 STEP_UOUT; //电压步长 /* word 36*/ Power_Bits16 STEP_IOUT; //电流步长 /* word 37*/ Power_Bits16 STEP_FREQ; //频率步长 /* word 38 */ Power_Bits16 STEP_ANGLE; //相角步长 /* word 39 */ Power_Bits16 POINTCYCLE; //周波点数 /* word 40 */ Power_Bits16 REF_UOUT; //电压给定值 /* word 41 */ Power_Bits16 REF_IOUT; //电流给定值 /* word 42 */ Power_Bits16 REF_FREQ; //频率给定值 /* word 43 */ Power_Bits16 REF_ANGLE; //实时相角 /* word 44 */ Power_Bits16 KPWMA; //A相调制系数 /* word 45 */ Power_Bits16 KPWMB; //B相调制系数 /* word 46 */ Power_Bits16 KPWMC; //C相调制系数 /* word 47 */ Power_Bits16 Effective_Uin; //输入电压有效值 /* word 48 */ Power_Bits16 Effective_Iin; //输入电流有效值 /* word 49 */ Power_Bits16 Effective_Udc; //直流母线电压有效值 /* word 50 */ Power_Bits16 Effective_Uout1; //A相输出电压有效值 /* word 51 */ Power_Bits16 Effective_Uout2; //B相输出电压有效值 /* word 52 */ Power_Bits16 Effective_Uout3; //C相输出电压有效值 /* word 53 */ Power_Bits16 Effective_Iout1; //A相输出电流有效值 /* word 54 */ Power_Bits16 Effective_Iout2; //B相输出电流有效值 /* word 55 */ Power_Bits16 Effective_Iout3; //C相输出电流有效值 /* word 56 */ Power_Bits16 Effective_IL1; //A相电感电流有效值 /* word 57 */ Power_Bits16 Effective_IL2; //B相电感电流有效值 /* word 58 */ Power_Bits16 Effective_IL3; //C相电感电流有效值 /* word 59 */ Power_Bits16 Effective_UinC; //备用电源电压有效值 /* word 60 */ Power_Bits16 Effective_UoutSet; //输出电压设定值(模拟) /* word 61 */ Power_Bits16 Effective_IoutSet; //输出电流设定值(模拟) /* word 62 */ Power_Bits16 Reserved62; //预留 /* word 63 */ Power_Bits16 Effective_FreqSet; //输出电压频率设定值(模拟) /* word 64 */ Power_Bits16 PIDU1_hReference; //PIDU1给定值 /* word 65 */ Power_Bits16 PIDI1_hPresentFeedback; //PIDI1反馈值 /* word 66 */ Power_Bits16 PIDI1_hReference; //PIDI1输出值 /* word 67 */ Power_Bits16 PIDU1_hKp_Gain; //PIDU1参数kp /* word 68*/ Power_Bits16 PIDU1_hKi_Gain; //PIDU1参数ki /* word 69*/ Power_Bits16 PIDU1_hKd_Gain; //PIDU1参数kd /* word 70*/ Power_Bits32 PIDU1_wLower_Limit_Integral; //PIDU1积分下限值 /* word 71*/ Power_Bits32 PIDU1_wUpper_Limit_Integral; //PIDU1积分上限值 /* word 72*/ Power_Bits16 PIDU1_hLower_Limit_Output; //PIDU1输出下限值 /* word 73*/ Power_Bits16 PIDU1_hUpper_Limit_Output; //PIDU1输出上限值 /* word 74*/ Power_Bits16 PIDU2_hReference; //PIDU2给定值 /* word 75*/ Power_Bits16 PIDU2_hPresentFeedback; //PIDU2反馈值 /* word 76*/ Power_Bits16 PIDI2_hReference; //PIDI2输出值 /* word 77*/ Power_Bits16 PIDU2_hKp_Gain; //PIDU2参数kp /* word 78*/ Power_Bits16 PIDU2_hKi_Gain; //PIDU2参数ki /* word 79*/ Power_Bits16 PIDU2_hKd_Gain; //PIDU2参数kd /* word 80*/ Power_Bits32 PIDU2_wLower_Limit_Integral; //PIDU2积分下限值 /* word 81*/ Power_Bits32 PIDU2_wUpper_Limit_Integral; //PIDU2积分上限值 /* word 82*/ Power_Bits16 PIDU2_hLower_Limit_Output; //PIDU2输出下限值 /* word 83*/ Power_Bits16 PIDU2_hUpper_Limit_Output; //PIDU2输出上限值 /* word 84 */ Power_Bits16 PIDI1hReference; //PIDI1给定值 /* word 85 */ Power_Bits16 PIDI1hPresentFeedback; //PIDI1反馈值 /* word 86 */ Power_Bits16 iParkUref_Ds; //PIDI1输出值 /* word 87 */ Power_Bits16 PIDI1_hKp_Gain; //PIDI1参数kp /* word 88*/ Power_Bits16 PIDI1_hKi_Gain; //PIDI1参数ki /* word 89*/ Power_Bits16 PIDI1_hKd_Gain; //PIDI1参数kd /* word 90*/ Power_Bits32 PIDI1_wLower_Limit_Integral; //PIDI1积分下限值 /* word 91*/ Power_Bits32 PIDI1_wUpper_Limit_Integral; //PIDI1积分上限值 /* word 92*/ Power_Bits16 PIDI1_hLower_Limit_Output; //PIDI1输出下限值 /* word 93*/ Power_Bits16 PIDI1_hUpper_Limit_Output; //PIDI1输出上限值 /* word 94 */ Power_Bits16 PIDI2hReference; //PIDI2给定值 /* word 95 */ Power_Bits16 PIDI2_hPresentFeedback; //PIDI2反馈值 /* word 96 */ Power_Bits16 iParkUref_Qs; //输出值 /* word 97 */ Power_Bits16 PIDI2_hKp_Gain; //PIDI2参数kp /* word 98*/ Power_Bits16 PIDI2_hKi_Gain; //PIDI2参数ki /* word 99*/ Power_Bits16 PIDI2_hKd_Gain; //PIDI2参数kd /* word 100*/ Power_Bits32 PIDI2_wLower_Limit_Integral; //PIDI2积分下限值 /* word 101*/ Power_Bits32 PIDI2_wUpper_Limit_Integral; //PIDI2积分上限值 /* word 102*/ Power_Bits16 PIDI2_hLower_Limit_Output; //PIDI2输出下限值 /* word 103*/ Power_Bits16 PIDI2_hUpper_Limit_Output; //PIDI2输出上限值 /* word 104 */ Power_Bits16 PIDPARA_hReference; //PIDPARA给定值 /* word 105 */ Power_Bits16 PIDPARA_hPresentFeedback; //PIDPARA反馈值 /* word 106 */ Power_Bits16 Reserved106; //PIDPARA输出值 /* word 107 */ Power_Bits16 PIDPARA_hKp_Gain; //PIDPARA参数kp /* word 108*/ Power_Bits16 PIDPARA_hKi_Gain; //PIDPARA参数ki /* word 109*/ Power_Bits16 PIDPARA_hKd_Gain; //PIDPARA参数kd /* word 110*/ Power_Bits32 PIDPARA_wLower_Limit_Integral;//PIDPARA积分下限值 /* word 111*/ Power_Bits32 PIDPARA_wUpper_Limit_Integral;//PIDPARA积分上限值 /* word 112*/ Power_Bits16 PIDPARA_hLower_Limit_Output; //PIDPARA输出下限值 /* word 113*/ Power_Bits16 PIDPARA_hUpper_Limit_Output; //PIDPARA输出上限值 /* word 114 */ Power_Bits16 PIDPLL_hReference; //PIDPLL给定值 /* word 115 */ Power_Bits16 PIDPLL_hPresentFeedback; //PIDPLL反馈值 /* word 116 */ Power_Bits16 Reserved116; //PIDPLL输出值 /* word 117 */ Power_Bits16 PIDPLL_hKp_Gain; //PIDPLL参数kp /* word 118*/ Power_Bits16 PIDPLL_hKi_Gain; //PIDPLL参数ki /* word 119*/ Power_Bits16 PIDPLL_hKd_Gain; //PIDPLL参数kd /* word 120*/ Power_Bits32 PIDPLL_wLower_Limit_Integral; //PIDPLL积分下限值 /* word 121*/ Power_Bits32 PIDPLL_wUpper_Limit_Integral; //PIDPLL积分上限值 /* word 122*/ Power_Bits16 PIDPLL_hLower_Limit_Output; //PIDPLL输出下限值 /* word 123*/ Power_Bits16 PIDPLL_hUpper_Limit_Output; //PIDPLL输出上限值 /* word 124 */ Power_Bits16 Reserved124; //输出变压器变比 /* word 125 */ Power_Bits16 Reserved125; //变压器等效电抗 /* word 126 */ Power_Bits16 Reserved126; //变压器等效电阻 /* word 127 */ Power_Bits16 Reserved127; //预留 /* word 128 */ Power_Bits16 FdOverUin_ValLimitHi; //输入过压保护值 /* word 129 */ Power_Bits16 FdUnderUin_ValLimitHi; //输入欠压保护值 /* word 130 */ Power_Bits16 FdOverIin_ValLimitHi; //输入过流保护值 /* word 131 */ Power_Bits16 FdOverUo1_ValLimitHi; //输出过压保护值 /* word 132 */ Power_Bits16 FdOverIo1_ValLimitHi; //输出过流保护值 /* word 133 */ Power_Bits16 FdOverIL1_ValLimitHi; //电感过流保护值 /* word 134 */ Power_Bits16 Reserved134; //短路保护电压动作值 /* word 135 */ Power_Bits16 Reserved135; //短路保护电流动作值 /* word 136 */ Power_Bits16 Reserved136; //短路保护电压返回值 /* word 137 */ Power_Bits16 Reserved137; //短路保护电流返回值 /* word 138 */ Power_Bits16 Reserved138; //短路运行时间 /* word 139 */ Power_Bits16 Reserved139; //110%过载保护限值 /* word 140 */ Power_Bits16 Reserved140; //110%过载保护时间 /* word 141 */ Power_Bits16 Reserved141; //110%过载保护倒计时 /* word 142 */ Power_Bits16 Reserved142; //120%过载保护限值 /* word 143 */ Power_Bits16 Reserved143; //120%过载保护时间 /* word 144 */ Power_Bits16 Reserved144; //120%过载保护倒计时 /* word 145 预留*/ Power_Bits16 Reserved145; /* word 146 AD结果寄存器数据(CH0)*/ Power_Bits16 AdcRegs_ADCRESULT0; /* word 147 */ Power_Bits16 AdcRegs_ADCRESULT1; //AD结果寄存器数据(CH1) /* word 148 */ Power_Bits16 AdcRegs_ADCRESULT2; //AD结果寄存器数据(CH2) /* word 149 */ Power_Bits16 AdcRegs_ADCRESULT3; //AD结果寄存器数据(CH3) /* word 150 */ Power_Bits16 AdcRegs_ADCRESULT4; //AD结果寄存器数据(CH4) /* word 151 */ Power_Bits16 AdcRegs_ADCRESULT5; //AD结果寄存器数据(CH5) /* word 152 */ Power_Bits16 AdcRegs_ADCRESULT6; //AD结果寄存器数据(CH6) /* word 153 */ Power_Bits16 AdcRegs_ADCRESULT7; //AD结果寄存器数据(CH7) /* word 154 */ Power_Bits16 AdcRegs_ADCRESULT8; //AD结果寄存器数据(CH8) /* word 155 */ Power_Bits16 AdcRegs_ADCRESULT9; //AD结果寄存器数据(CH9) /* word 156 */ Power_Bits16 AdcRegs_ADCRESULT10; //AD结果寄存器数据(CH10) /* word 157 */ Power_Bits16 AdcRegs_ADCRESULT11; //AD结果寄存器数据(CH11) /* word 158 */ Power_Bits16 AdcRegs_ADCRESULT12; //AD结果寄存器数据(CH12) /* word 159 */ Power_Bits16 AdcRegs_ADCRESULT13; //AD结果寄存器数据(CH13) /* word 160 */ Power_Bits16 AdcRegs_ADCRESULT14; //AD结果寄存器数据(CH14) /* word 161 */ Power_Bits16 AdcRegs_ADCRESULT15; //AD结果寄存器数据(CH15) /* word 162 预留*/ Power_Bits16 Reserved162; /* word 163 预留*/ Power_Bits16 Reserved163; /* word 164 预留*/ Power_Bits16 Reserved164; /* word 165 预留*/ Power_Bits16 Reserved165; /* word 166 预留*/ Power_Bits16 Reserved166; /* word 167 预留*/ Power_Bits16 Reserved167; /* word 168 预留*/ Power_Bits16 Reserved168; /* word 169预留 */ Power_Bits16 Reserved169; /* word 170 预留*/ Power_Bits16 Reserved170; /* word 171 预留*/ Power_Bits16 Reserved171; /* word 172 预留*/ Power_Bits16 Reserved172; /* word 173 预留*/ Power_Bits16 Reserved173; /* word 174 预留*/ Power_Bits16 Reserved174; /* word 175 预留*/ Power_Bits16 Reserved175; /* word 176 预留*/ Power_Bits16 Reserved176; /* word 177 预留*/ Power_Bits16 Reserved177; /* word 178 预留*/ Power_Bits16 Reserved178; /* word 179 预留*/ Power_Bits16 Reserved179; /* word 180 输入电压传感器采样范围*/ Power_Bits16 PEAK_UIN_SENSOR; /* word 181 输入电流传感器采样范围*/ Power_Bits16 PEAK_IIN_SENSOR; /* word 182 输出电压传感器采样范围*/ Power_Bits16 PEAK_UO_SENSOR; /* word 183 输出电流传感器采样范围*/ Power_Bits16 PEAK_IO_SENSOR; /* word 184 电感电流传感器采样范围*/ Power_Bits16 PEAK_IL_SENSOR; /* word 185 预留*/ Power_Bits16 Reserved185; /* word 186 预留*/ Power_Bits16 Reserved186; /* word 187 预留*/ Power_Bits16 Reserved187; /* word 188 预留*/ Power_Bits16 Reserved188; /* word 189 预留*/ Power_Bits16 Reserved189; /* word 190 通道选择*/ Power_Bits16 ChannelSelect; /* word 191 预留*/ Power_Bits16 Reserved191; /* word 192 预留*/ Power_Bits16 Reserved192; /* word 193 地址偏移量*/ Power_Bits16 AddressOffset; /* word 194 预留*/ Power_Bits16 Reserved194; /* word 195 预留*/ Power_Bits16 Reserved195; /* word 196 预留*/ Power_Bits16 Reserved196; /* word 197 预留*/ Power_Bits16 Reserved197; /* word 198 预留*/ Power_Bits16 Reserved198; /* word 199 网络通讯协议控制*/ Power_Bits16 Modbus_Control_ModbusCtrl; }Power_System_Type; STM32F105 power_data.c程序的二级缓存的400字节的数据准确的赋值给fw_data.h程序中的Power_System_Type结构体中,然后调用结构体的某一个数据,需要频繁访问结构体中的某个字段,可以将其缓存到局部变量中,减少多次访问互斥锁的开销,用标准库写出详细代码和注释
06-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值