|
- #include "main.h"
- #include "sys.h"
- #include "delay.h"
- #include "usart.h"
- #include "led.h"
- #include "usmart.h"
- #include "malloc.h"
- #include "mpu.h"
- #include "lan8720.h"
- #include "lwip/netif.h"
- #include "lwip_comm.h"
- #include "lwipopts.h"
- #include "includes.h"
- #include "stmflash.h"
- #include "lwip/opt.h"
- #include "lwip/lwip_sys.h"
- #include "lwip/api.h"
- #include "lwip/sockets.h"
- #define TCP_CLIENT_RX_BUFSIZE 2000 //接收缓冲区长度
- #define REMOTE_PORT 6666 //定义远端主机的IP地址
- #define LWIP_SEND_DATA 0X80 //定义有数据发送
- void SystemClock_Config(void);
- void MX_GPIO_Init(void);
- int read_progress();
- INT8U tcp_client_init(void);
- OS_EVENT *PREVENT; //发送eth信号量
- OS_EVENT *MAIL; //邮箱
- INT8U err; //错误地址
- struct netconn *tcp_clientconn=NULL; //TCP CLIENT网络连接结构体
- u8 tcp_client_flag; //TCP客户端数据发送标志位
- u8 eth_send=0;
- u8 xc_send[4]={0};
- u32 bufff=0; //大存
- u8 sml_buf[1024]={0}; //小存
- u32 *qq = (u32*)&sml_buf;
- int chunchucishu=0; //写flash次数 //要与flash存储进度挂钩 //最多28
- u32 W_head_Addr=0x0803FC00; //每加了0x400才起作用
- u32 W_tail_Addr=0x081FFFF4; //往上减
- int Progress=0;
- u16_t server_port;
- ip_addr_t server_ipaddr;
-
- //START任务
- //任务优先级
- #define START_TASK_PRIO 10
- //任务堆栈大小
- #define START_STK_SIZE 128
- //任务堆栈
- OS_STK START_TASK_STK[START_STK_SIZE];
- //任务函数
- void start_task(void *pdata);
-
- //ORDER任务
- //任务优先级
- #define ORDER_TASK_PRIO 2
- //任务堆栈大小
- #define ORDER_STK_SIZE 512
- //任务堆栈
- OS_STK ORDER_TASK_STK[ORDER_STK_SIZE];
- //任务函数
- void order_task(void *pdata);
-
- //TCP客户端任务
- #define TCPCLIENT_PRIO 6
- //任务堆栈大小
- #define TCPCLIENT_STK_SIZE 512
- //任务堆栈
- OS_STK TCPCLIENT_TASK_STK[TCPCLIENT_STK_SIZE];
- //tcp客户端任务函数
- static void tcp_client_thread(void *arg);
-
- //ETH发送任务
- //任务优先级
- #define ETH_SEND_TASK_PRIO 8
- //任务堆栈大小
- #define ETH_SEND_STK_SIZE 128
- //任务堆栈
- OS_STK ETH_SEND_TASK_STK[ETH_SEND_STK_SIZE];
- //任务函数
- void eth_send_task();
-
- int connect_chack();
- void write_flash();
- void ethsend(u8 eth_sendd);
-
-
- int main(void)
- {
- Write_Through(); //开启强制透写!
- MPU_Memory_Protection(); //保护相关存储区域
- Cache_Enable(); //打开L1-Cache
-
- HAL_Init();
- SystemClock_Config();
- delay_init(216); //延时初始化
- MX_GPIO_Init();
- MX_USART1_UART_Init();
- HAL_UART_Receive_IT(&huart1,ð_send,1);
- // server_port = REMOTE_PORT;
- // IP4_ADDR(&server_ipaddr, lwipdev.remoteip[0],lwipdev.remoteip[1], lwipdev.remoteip[2],lwipdev.remoteip[3]);
-
-
- // ersae_all();
- // STMFLASH_Write(0x081FFFFC,&bufff[0],1); //完成标志写入flash
- if(STMFLASH_ReadWord(0x081FFFFC) != 0xFFFFFFFF)ersae_all();//如果最后一个地址里面被写了数据,代表之前文件已经传完,擦除空间
- // else Progress = read_progress();//查后面的,存到第几个包了,记录一下,一会接着要
- LED0_Toggle();
- OSInit(); //UCOS初始化
- while(lwip_comm_init()); //lwip初始化
- while(tcp_client_init()); //初始化tcp_server(创建tcp_server程)
- printf("客户端创建成功!\r\n");
- OSTaskCreate(start_task,(void*)0,(OS_STK*)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO);
- OSStart(); //开启UCOS
- }
-
-
-
- //tcp客户端任务函数
- static void tcp_client_thread(void *arg)
- {
- OS_CPU_SR cpu_sr;
- u32 data_len = 0;
- struct pbuf *q;
- struct netbuf *recvbuf;
- err_t recv_err;
- // static ip_addr_t server_ipaddr,loca_ipaddr;
- // static u16_t server_port,loca_port;
-
- LWIP_UNUSED_ARG(arg);
- // server_port = REMOTE_PORT;
- // IP4_ADDR(&server_ipaddr, lwipdev.remoteip[0],lwipdev.remoteip[1], lwipdev.remoteip[2],lwipdev.remoteip[3]);
-
- while (1)
- {
- if(connect_chack() == 1)
- {
- while(1)
- { /*recv_err = netconn_recv(tcp_clientconn,&recvbuf)*/
- /*recv( tcp_clientconn->socket, &recvbuf, 1024, 0)*/
- if((recv_err = netconn_recv(tcp_clientconn,&recvbuf)) == ERR_OK) //接收到数据
- {
- OS_ENTER_CRITICAL(); //关中断
- memset(sml_buf,0,TCP_CLIENT_RX_BUFSIZE); //数据接收缓冲区清零
- for(q=recvbuf->p;q!=NULL;q=q->next) //遍历完整个pbuf链表
- {
- //判断要拷贝到TCP_CLIENT_RX_BUFSIZE中的数据是否大于TCP_CLIENT_RX_BUFSIZE的剩余空间,如果大于
- //的话就只拷贝TCP_CLIENT_RX_BUFSIZE中剩余长度的数据,否则的话就拷贝所有的数据
- if(q->len > (TCP_CLIENT_RX_BUFSIZE-data_len)) memcpy(sml_buf+data_len,q->payload,(TCP_CLIENT_RX_BUFSIZE-data_len));//拷贝数据
- else memcpy(sml_buf+data_len,q->payload,q->len);
- data_len += q->len;
- if(data_len > TCP_CLIENT_RX_BUFSIZE) break; //超出TCP客户端接收数组,跳出
- }
- OS_EXIT_CRITICAL(); //开中断
-
- if((data_len<10)&&(sml_buf[0]==0x6F)&&(sml_buf[1]==0x76)&&(sml_buf[2]==0x65)&&(sml_buf[3]==0x72))
- { //如果接到结束符
- ethsend(0x35);
- data_len=0; //复制完成后data_len要清零。
- netbuf_delete(recvbuf);
-
- while(1) //等服务器发校验数目
- {
- if((recv_err = netconn_recv(tcp_clientconn,&recvbuf)) == ERR_OK) //接收到数据
- {
- OS_ENTER_CRITICAL(); //关中断
- memset(sml_buf,0,TCP_CLIENT_RX_BUFSIZE); //数据接收缓冲区清零
- for(q=recvbuf->p;q!=NULL;q=q->next) //遍历完整个pbuf链表
- {
- //判断要拷贝到TCP_CLIENT_RX_BUFSIZE中的数据是否大于TCP_CLIENT_RX_BUFSIZE的剩余空间,如果大于
- //的话就只拷贝TCP_CLIENT_RX_BUFSIZE中剩余长度的数据,否则的话就拷贝所有的数据
- if(q->len > (TCP_CLIENT_RX_BUFSIZE-data_len)) memcpy(sml_buf+data_len,q->payload,(TCP_CLIENT_RX_BUFSIZE-data_len));//拷贝数据
- else memcpy(sml_buf+data_len,q->payload,q->len);
- data_len += q->len;
- if(data_len > TCP_CLIENT_RX_BUFSIZE) break; //超出TCP客户端接收数组,跳出
- }
- OS_EXIT_CRITICAL(); //开中断
- data_len=0; //复制完成后data_len要清零。
- netbuf_delete(recvbuf);
- break;
- }
- }
- int a=(int)sml_buf[0]*256+(int)sml_buf[1];
- if(a == chunchucishu+Progress)//成功
- {
- ethsend(0x36); //回馈传输成功信息
- // chunchucishu=0;
- STMFLASH_Write(0x081FFFFC,&bufff,1); //完成标志写入flash
- netconn_close(tcp_clientconn);
- netconn_delete(tcp_clientconn);
- printf("服务器%d.%d.%d.%d断开连接\r\n",lwipdev.remoteip[0],lwipdev.remoteip[1], lwipdev.remoteip[2],lwipdev.remoteip[3]);
- break;
- }
- else //失败
- {
- ethsend(0x37);
- // chunchucishu=0;
- STMFLASH_Write(0x081FFFFC,&bufff,1);//传输失败也要写东西
- netconn_close(tcp_clientconn);
- netconn_delete(tcp_clientconn);
- printf("服务器%d.%d.%d.%d断开连接\r\n",lwipdev.remoteip[0],lwipdev.remoteip[1], lwipdev.remoteip[2],lwipdev.remoteip[3]);
- break;
- }
- }
- else //如果不是结束符,正常工作
- {
- data_len=0; //复制完成后data_len要清零。
- netbuf_delete(recvbuf);
- W_head_Addr += 0x400;
- write_flash();
- }
- }
- else if(recv_err == ERR_CLSD) //关闭连接
- {
- netconn_close(tcp_clientconn);
- netconn_delete(tcp_clientconn);
- printf("服务器%d.%d.%d.%d断开连接\r\n",lwipdev.remoteip[0],lwipdev.remoteip[1], lwipdev.remoteip[2],lwipdev.remoteip[3]);
- break;
- }
-
- }
- }
- }
- }
-
- int read_progress()
- {
- u32 addr = 0x081FFFF4;
- int a=0;
- while(STMFLASH_ReadWord(addr)!=0xFFFFFFFF)
- {
- a++;
- addr-=4;
- }
- return a;
- }
-
- void write_flash()
- {
- chunchucishu++;
- // if(STMFLASH_ReadWord(W_tail_Addr)==0XFFFFFFFF)
- STMFLASH_Write(W_tail_Addr,qq,1); //先把坑占了,先声明这个坑我要用了
- W_tail_Addr-=4;
- STMFLASH_Write(W_head_Addr,qq,256); //再用这个坑
- ethsend(0x34);
- }
-
- int connect_chack()
- {
- err_t err;
-
- static ip_addr_t loca_ipaddr;
- static u16_t loca_port;
- tcp_clientconn=netconn_new(NETCONN_TCP); //创建一个TCP链接
- server_port = REMOTE_PORT;
- IP4_ADDR(&server_ipaddr, lwipdev.remoteip[0],lwipdev.remoteip[1], lwipdev.remoteip[2],lwipdev.remoteip[3]);
-
- err = netconn_connect(tcp_clientconn,&server_ipaddr,server_port);//连接服务器
- if(err != ERR_OK)
- {
- netconn_delete(tcp_clientconn); //返回值不等于ERR_OK,删除tcp_clientconn连接
- return 0;
- }
- else //处理新连接的数据
- {
- // struct netbuf *recvbuf;
- tcp_clientconn->recv_timeout = 10;
- netconn_getaddr(tcp_clientconn,&loca_ipaddr,&loca_port,1); //获取本地IP主机IP地址和端口号
- printf("连接上服务器%d.%d.%d.%d,本机端口号为:%d\r\n",lwipdev.remoteip[0],lwipdev.remoteip[1], lwipdev.remoteip[2],lwipdev.remoteip[3],loca_port);
-
- if((STMFLASH_ReadWord(0x081FFFF8) != 0xFFFFFFFF)&&(STMFLASH_ReadWord(0x081FFFFC) == 0xFFFFFFFF))
- {
- Progress = read_progress();
- xc_send[0]=0x30;
- xc_send[1]=(u8)STMFLASH_ReadWord(0x081FFFF8);
- xc_send[2]=Progress/256;
- xc_send[3]=Progress%256;
- netconn_write(tcp_clientconn ,&xc_send,4,NETCONN_COPY);
- W_tail_Addr = 0x081FFFF4 - 4*Progress;
- W_head_Addr = 0x0803FC00 + 0x400*Progress;
- printf("要续传了\n");
- }
- return 1;
- }
- }
-
- void USART1_IRQHandler()
- {
- OSIntEnter();
- HAL_UART_Receive_IT(&huart1,ð_send,1);
-
- OSMboxPost(MAIL,ð_send); //往邮箱MAIL里面发intrpt的地址
-
- // if(eth_send==0xca)caca=1;
- // else OSSemPost(PREVENT);
- HAL_UART_IRQHandler(&huart1);
- __HAL_UART_ENABLE_IT(&huart1, UART_IT_ERR);
- __HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);
- OSIntExit();
- }
-
- void ethsend(u8 eth_sendd)
- {
- err = netconn_write(tcp_clientconn ,ð_sendd,1,NETCONN_COPY); //发送串口收到的指令
- if(err != ERR_OK)
- {
- printf("发送失败\r\n");
- }
- else printf("发送成功%d\r\n",eth_sendd);
- tcp_client_flag &= ~LWIP_SEND_DATA;
- }
-
-
- void order_task(void *pdata)
- {
- static void *M_num; //接收邮箱数据
- static char num = 0;
- while(1)
- {
- M_num = OSMboxPend(MAIL,0,&err); //获取邮箱里面数据的地址
- if(M_num != NULL)
- {
- num = *(char*)M_num;
- if(num == 0xca) //恢复如初
- {
- LED0_Toggle();
- chunchucishu=0;
- W_head_Addr=0x0803FC00; //每加了0x400才起作用
- W_tail_Addr=0x081FFFF4; //往上减
- Progress=0;
- ersae_all();
- LED0_Toggle();
- }
- else if((num == 0x31)||(num == 0x32)||(num == 0x33))
- {
- eth_send = num;
- OSSemPost(PREVENT);
- // if(STMFLASH_ReadWord(0x081FFFF8) == 0xFFFFFFFF)
- // {
- u32 a;
- a=(u32)num;
- STMFLASH_Write(0x081FFFF8,&a,1);//记录文件序号
- // }
-
- }
- else if((num == 0x38)||(num == 0x39)||(num == 0x3a))
- {
- eth_send = num;
- OSSemPost(PREVENT);
- }
- else if(num == 0x22)
- {
- printf("连接结果是%d",connect_chack());
- }
- else if(num == 0x11)
- {
- Progress = read_progress();
- xc_send[0]=0x30;
- xc_send[1]=(u8)STMFLASH_ReadWord(0x081FFFF8);
- xc_send[2]=Progress/256;
- xc_send[3]=Progress%256;
- netconn_write(tcp_clientconn ,&xc_send,4,NETCONN_COPY);
- W_tail_Addr = 0x081FFFF4 - 4*Progress;
- W_head_Addr = 0x0803FC00 + 0x400*Progress;
- chunchucishu=0;
- printf("要续传了\n");
- }
- }
- OSTimeDlyHMSM(0,0,0,500); //延时500ms
- }
- }
- //ETH发送任务
- void eth_send_task(void *pdata)
- {
- while(1)
- {
- OSSemPend(PREVENT,0,&err); //申请信号量
- err = netconn_write(tcp_clientconn ,ð_send,1,NETCONN_COPY); //发送串口收到的指令
- if(err != ERR_OK)
- {
- printf("发送失败\r\n");
- }
- else printf("发送成功%d\r\n",eth_send);
- tcp_client_flag &= ~LWIP_SEND_DATA;
-
-
- OSTimeDlyHMSM(0,0,0,500); //延时500ms
- }
- }
-
-
-
- //创建TCP客户端线程
- //返回值:0 TCP客户端创建成功
- // 其他 TCP客户端创建失败
- INT8U tcp_client_init(void)
- {
- INT8U res;
- OS_CPU_SR cpu_sr;
-
- OS_ENTER_CRITICAL(); //关中断
-
- OSTaskCreate(eth_send_task,(void*)0,(OS_STK*)Ð_SEND_TASK_STK[ETH_SEND_STK_SIZE-1],ETH_SEND_TASK_PRIO); //显示任务
-
- res = OSTaskCreate(tcp_client_thread,(void*)0,(OS_STK*)&TCPCLIENT_TASK_STK[TCPCLIENT_STK_SIZE-1],TCPCLIENT_PRIO); //创建TCP客户端线程
- PREVENT = OSSemCreate(1); //创建信号量
- // W_FLASH = OSSemCreate(1); //创建信号量
- OSSemPend(PREVENT,0,&err);
- // OSSemPend(W_FLASH,0,&err);
- OS_EXIT_CRITICAL(); //开中断
-
- return res;
- }
-
- /* USER CODE BEGIN 4 */
- //start任务
- void start_task(void *pdata)
- {
- OS_CPU_SR cpu_sr;
- pdata = pdata ;
- static INT8U mbox; //邮箱
- OSStatInit(); //初始化统计任务
- OS_ENTER_CRITICAL(); //关中断
-
- OSTaskCreate(order_task,(void*)0,(OS_STK*)&ORDER_TASK_STK[ORDER_STK_SIZE-1],ORDER_TASK_PRIO);//创建ORDER任务
- // OSTaskCreate(write_flash,(void*)0,(OS_STK*)&FLASH_TASK_STK[FLASH_STK_SIZE-1],FLASH_TASK_PRIO);//创建LED任务
- MAIL = OSMboxCreate((void*)mbox); //创建邮箱
- OSTaskSuspend(OS_PRIO_SELF); //挂起start_task任务
- OS_EXIT_CRITICAL(); //开中断
- }
-
-
- /**
- * @brief System Clock Configuration
- * @retval None
- */
- void SystemClock_Config(void)
- {
- RCC_OscInitTypeDef RCC_OscInitStruct = {0};
- RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
-
- /** Configure the main internal regulator output voltage
- */
- __HAL_RCC_PWR_CLK_ENABLE();
- __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
- /** Initializes the RCC Oscillators according to the specified parameters
- * in the RCC_OscInitTypeDef structure.
- */
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
- RCC_OscInitStruct.HSEState = RCC_HSE_ON;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
- RCC_OscInitStruct.PLL.PLLM = 6;
- RCC_OscInitStruct.PLL.PLLN = 216;
- RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
- RCC_OscInitStruct.PLL.PLLQ = 2;
- if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
- {
- Error_Handler();
- }
- /** Activate the Over-Drive mode
- */
- if (HAL_PWREx_EnableOverDrive() != HAL_OK)
- {
- Error_Handler();
- }
- /** Initializes the CPU, AHB and APB buses clocks
- */
- RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
- |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
- RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
- RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
- RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
- RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
-
- if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7) != HAL_OK)
- {
- Error_Handler();
- }
- }
-
- /* USER CODE END 4 */
-
- /**
- * @brief This function is executed in case of error occurrence.
- * @retval None
- */
- void Error_Handler(void)
- {
- /* USER CODE BEGIN Error_Handler_Debug */
- /* User can add his own implementation to report the HAL error return state */
- __disable_irq();
- while (1)
- {
- }
- /* USER CODE END Error_Handler_Debug */
- }
-
- #ifdef USE_FULL_ASSERT
- /**
- * @brief Reports the name of the source file and the source line number
- * where the assert_param error has occurred.
- * @param file: pointer to the source file name
- * @param line: assert_param error line source number
- * @retval None
- */
- void assert_failed(uint8_t *file, uint32_t line)
- {
- /* USER CODE BEGIN 6 */
- /* User can add his own implementation to report the file name and line number,
- ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
- /* USER CODE END 6 */
- }
- #endif /* USE_FULL_ASSERT */
- void MX_GPIO_Init(void)
- {
-
- GPIO_InitTypeDef GPIO_InitStruct = {0};
-
- /* GPIO Ports Clock Enable */
- __HAL_RCC_GPIOA_CLK_ENABLE();
- __HAL_RCC_GPIOH_CLK_ENABLE();
- __HAL_RCC_GPIOF_CLK_ENABLE();
- __HAL_RCC_GPIOB_CLK_ENABLE();
-
- /*Configure GPIO pin Output Level */
- HAL_GPIO_WritePin(GPIOF, GPIO_PIN_7|GPIO_PIN_6|GPIO_PIN_8, GPIO_PIN_SET);
-
- /*Configure GPIO pins : PF7 PF6 PF8 */
- GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_6|GPIO_PIN_8;
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
- HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
-
- }
- /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|