LiteOS系统--快速烧写.bin文件到norflash相应位置

xiaoxiao2025-10-10  7

华为LiteOS系统因OS和app代码是通过接口app_init衔接在一块的,所以在开发调试中每次进行修改后都需要重新烧写flash,这样其实很麻烦,所以干脆写了个工具辅助进行文件传输,使用TCP协议,代码分为设备端和linux主机端,

注意在LiteOS系统调用的app_init()函数里边,注册如下命令:

osCmdReg(CMD_TYPE_EX, "WriteNorFlash",1, (CMD_CBK_FUNC)write_file_to_nor_flash); osCmdReg(CMD_TYPE_EX, "RecvWriteNor",0, (CMD_CBK_FUNC)receive_and_write_file_to_nor_flash);

 

用来在命令行下通过输入命令“WriteNorFlash” 或者“RecvWriteNor”直接调用如下函数写入或接收写入.bin文件到指定Norflash位置:

设备端代码 .c  和 .h文件:

 其中擦写的起始地址和大小可通过宏来改变:

#define FLASH_START_ADDRESS 0x100000   //liteOS写OS和app的起始地址 #define ERRASE_SIZE   (7*1024*1024)           //擦除7M大小的空间

#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <unistd.h> #include "write_file_to_flash.h" #include "spinor.h" #include <stdlib.h>//不加会报隐式声明与内建函数'exit'不兼容 #include <sys/socket.h> #include <netinet/in.h>//因用了地址 /******************************************************************* 手动烧写文件到norflash, 从设备文件系统中读取一个系统文件(ipc8.bin)烧到norflash的系统位置, ********************************************************************/ //argv[1]:要读取的源文件 int write_file_to_nor_flash(int argc,char**argv) { char need_help = !strcmp(argv[0],"-h")||!strcmp(argv[0],"-help"); if(argc < 1||need_help) { printf("usage: WriteNorFlash [inputfile]\n\ Atteion : inputfile need absolute path\n\ eg : WriteNorFlash /jffs0/ipc18.bin \n"); return 0; } //printf("argv[0] = %s \n",argv[0]); int read_file = open((const char *)argv[0], O_RDONLY); if( read_file < 0) { perror("open read_file error !\n"); return -1; } /*分配缓存空间*/ char * read_buffer = (char*)malloc(ERRASE_SIZE); if(NULL == read_buffer) { perror("malloc failed !\n"); return -1; } memset(read_buffer,0,ERRASE_SIZE); /*读取文件至缓存空间*/ unsigned long size = read(read_file,read_buffer,ERRASE_SIZE); printf("read size = %d bytes\n",size); /*擦除NorFlash*/ printf("erase NorFlash......\n"); int ret = hispinor_erase(FLASH_START_ADDRESS, ERRASE_SIZE); /*写NorFlash*/ printf("write NorFlash......\n"); ret = hispinor_write(read_buffer, FLASH_START_ADDRESS, size); if(0 == ret) { printf("write NroFlash success ,write(%d)bytes!\n",size); } else { perror("write NroFlash failed !\n"); } free(read_buffer); close(read_file); return 0; } /******************************************************************* 功能:接收文件到内存并直接烧写到norflash (TCP传输): 专门烧写系统文件(ipc18.bin)用,提高开发调试速度,比ftp传输文件 再烧写的方式要快,因接收的数据不保存成文件,而是直接从内存写入norflash 使用:配合客户端程序 send_and_write_file_to_norflash 使用 1.设备端运行命令“RecvWriteNor”(会调用该函数)等待接收数据; 2.虚拟机(linux主机)下运行客户端程序 send_and_write_file_to_norflash 格式:send_and_write_file_to_norflash [file name] [deviceIP] eg: ./send_and_write_file_to_norflash ipc18.bin 192.168.3.82 注意:目前没有加入文件校验机制 *******************************************************************/ #define portnum 5555 //端口有可能端口被占用,可以改端口才能通 int receive_and_write_file_to_nor_flash(int argc,char**argv) { char need_help = !strcmp(argv[0],"-h")||!strcmp(argv[0],"-help"); if(argc !=0||need_help) { printf("usage: RecvWriteNor\n\ Atteion : need to be used in conjunction with client process: send_and_write_file_to_norflash]\n\ eg : \n\ board: RecvWriteNor\n\ linux computer: send_and_write_file_to_norflash [file name] [deviceIP]\n"); return 0; } int sockfd; int new_fd;//建立连接后会返回一个新的fd struct sockaddr_in sever_addr; //服务器的IP地址 struct sockaddr_in client_addr; //客户机的IP地址 char *buffer = (char*)malloc(ERRASE_SIZE); if(NULL == buffer) { perror("malloc failed!\n"); return -1; } char *p_buffer = buffer; memset(buffer,0,ERRASE_SIZE); int nbyte; int checkListen; unsigned int filesize = 0; unsigned int countbytes = 0; /***为了消除accept函数第3个参数的类型不匹配问题的警告***********/ int sockaddr_size = sizeof(struct sockaddr); /******************************************************/ //1.创建套接字 if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1) { printf("create socket error!\n"); return -1; } printf("create socket success!\n"); //2.1设置要绑定的服务器地址 bzero(&sever_addr,sizeof(struct sockaddr_in)); sever_addr.sin_family = AF_INET; sever_addr.sin_port = htons(portnum);//将主机字节序转换成网络字节序 sever_addr.sin_addr.s_addr = htonl(INADDR_ANY);//绑定任意的IP地址,要和网络上所有的IP地址通讯 //2.2绑定地址 if(bind(sockfd,(struct sockaddr*)&sever_addr,sizeof(struct sockaddr)) < 0) { printf("bind socket error!\n"); return -1; } printf("bind socket success!\n"); //3.监听端口 printf("into listen portnum(%d)......!\n",portnum); checkListen = listen(sockfd,5); if(checkListen < 0) { perror("socket listen error!\n"); return -1; } do { //4.等待连接 new_fd = accept(sockfd,(struct sockaddr*)(&client_addr),(socklen_t *)(&sockaddr_size)); if(new_fd<0) { printf("accept eror!\n"); return -1; } printf("sever get connection from %s\n",inet_ntoa(client_addr.sin_addr.s_addr)); //5.接收文件大小信息 recv(new_fd,&filesize,sizeof(filesize),0); printf("receive file size = %ld bytes\n",filesize); if(filesize <= 0)return -1; //5.1接收数据 while(1) { if(countbytes >= filesize)break; nbyte = recv(new_fd,p_buffer+countbytes,filesize - countbytes,0); countbytes = countbytes + nbyte; //printf("countbytes = %d bytes...\n",countbytes); } printf("success ! server received (%d)bytes!\n",countbytes); }while(0); /*****debug code ***/ #if 0 int tmp_file = open("/jffs0/tmp.bin", O_RDWR| O_CREAT,0660); if( tmp_file < 0) { perror("open read_file error !\n"); return -1; } printf("open read_file success !\n"); //debug printf("receive:%s \n",buffer); unsigned int tmp_ret = write(tmp_file, buffer, countbytes); if(tmp_ret < 0) { perror("write file error!\n"); return -1; } printf("write file success! write size(%ld)bytes! \n",tmp_ret); #endif /*******************/ #if 1 /*擦除NorFlash*/ if(countbytes != filesize) { printf("countbytes != filesize\n"); return -1; } printf("erase NorFlash......\n"); int ret = hispinor_erase(FLASH_START_ADDRESS, ERRASE_SIZE); /*写NorFlash*/ printf("write NorFlash......\n"); ret = hispinor_write(buffer, FLASH_START_ADDRESS,countbytes); if(0 == ret) { printf("write NroFlash success ,write(%d)bytes!\n",countbytes); } else { perror("write NroFlash failed !\n"); } #endif close(new_fd); close(sockfd); free(buffer); return 0; } #ifndef WRITE_FILE_TO_FLASH_H #define WRITE_FILE_TO_FLASH_H #define FLASH_START_ADDRESS 0x100000 //liteOS写OS和app的起始地址 #define ERRASE_SIZE (7*1024*1024) //擦除7M大小的空间 int write_file_to_nor_flash(int argc,char**argv); int receive_and_write_file_to_nor_flash(int argc,char**argv); #endif

linux主机端代码:

/************************************************************************ *文件名:send_and_write_file_to_norflash.c *创建者:spy_007 *创见时间:2018/10/11 *文件说明: 功能:发送文件到给设备:client端程序 专门烧写系统文件(ipc18.bin)用,提高开发调试速度,比ftp传输文件 再烧写的方式要快,因接收的数据不保存成文件,而是直接从内存写入norflash 使用:配合设备端(服务端)命令 “RecvWriteNor” 使用 1.设备端运行命令“RecvWriteNor”等待接收数据; 2.虚拟机(linux主机)下运行客户端程序 send_and_write_file_to_norflash 格式:send_and_write_file_to_norflash [file name] [deviceIP] eg: ./send_and_write_file_to_norflash ipc18.bin 192.168.3.82 注意:目前没有加入文件校验机制 ************************************************************************/ #include<stdlib.h>//不加会报隐式声明与内建函数'exit'不兼容 #include<stdio.h> #include<sys/socket.h> #include<string.h> #include<netinet/in.h>//因用了地址 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> //3333是主机字节序 #define portnum 5555 #define ERRASE_SIZE (7*1024*1024) //文件缓存空间大小 int main(int argc,char**argv) { if(argc < 3) { printf("usage:%s [filename] [device ip]\n",argv[0]); return -1; } int sockfd,checkConnect; struct sockaddr_in sever_addr; //服务器的IP地址 //1.创建套接字 if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1) { printf("create socket error!\n"); exit(1); } //2.1设置需要连接的服务器地址 bzero(&sever_addr,sizeof(struct sockaddr_in)); sever_addr.sin_family = AF_INET; sever_addr.sin_port = htons(portnum);//host to net (short) 先要将主机字节序转换成网络字节序 sever_addr.sin_addr.s_addr = inet_addr(argv[2]);//绑定IP地址 //2.2连接服务器 checkConnect = connect(sockfd,(struct sockaddr*)(&sever_addr),sizeof(struct sockaddr)); if(checkConnect < 0) { printf("connect error!\n"); exit(1); } /*分配缓存空间*/ char * read_buffer = (char*)malloc(ERRASE_SIZE); if(NULL == read_buffer) { perror("malloc failed !\n"); return -1; } memset(read_buffer,0,ERRASE_SIZE); //打开文件 int read_file = open((const char *)argv[1], O_RDONLY); if( read_file < 0) { printf("open %s error !\n",argv[1]); return -1; } /*读取文件至缓存空间*/ unsigned int size = read(read_file,read_buffer,ERRASE_SIZE); printf("read size = %d bytes\n",size); //发送文件大小信息 unsigned int size_bak = size; printf("sizeof(unsigned long) = %d\n",sizeof(unsigned long)); if(send(sockfd,&size_bak,sizeof(size_bak),0) < 0) { perror("send file size failed!\n"); return -1; } printf("send file size success!\n"); //3.发送数据到服务器 int countbytes = 0; int sendbytes = 0; usleep(100); while(1) { if(0 == size) break; while(1) { sendbytes = send(sockfd,read_buffer + countbytes,size,0); if(sendbytes < 0) { perror("send failed!\n"); return -1; } break; } countbytes = countbytes + sendbytes; printf("countbytes = %d\n",countbytes); size = size - countbytes; usleep(100); } printf("success send(%ld)bytes!\n",countbytes); //4.关闭连接 close(sockfd); free(read_buffer); return 0; }

这里就举例其中一个命令“RecvWriteNor”的使用:

设备端先输入命令进入监听模式:

之后linux端运行: ./send_and_write_file_to_norflash ipc18.bin 192.XXX.XXX.XXX

设备端将自动接收文件并写入到Norflash对应地址处(注意 IP得在同一网段且互相能ping通)。

success!

转载请注明原文地址: https://www.6miu.com/read-5037672.html

最新回复(0)