Wiznet makers

ssekim

Published November 14, 2023 ©

57 UCC

29 VAR

0 Contests

0 Followers

0 Following

Original Link

STM32 W5500 OTA功能 - bootloader及app的設計和實現

A bootloader that supports OTA with W5500.

COMPONENTS
PROJECT DESCRIPTION
 
u-boot, which is mainly used on Linux, began supporting TCP about a year ago. However, it is not easy to support networks in embedded bootloaders.

Advantages of Bootloader with TCP/IP Support

Developing a bootloader with TCP/IP support offers several advantages:

Firmware Management via Network:

  • TCP/IP facilitates efficient firmware updates through network connections.
  • It enables streamlined management and updates of firmware located remotely.

Remote Monitoring:

  • Utilizing TCP/IP features in the bootloader allows for remote monitoring and debugging of devices.
  • Real-time access to logs, sensor data, and device status is possible remotely.

Challenges in Implementing TCP/IP in General Bootloaders

Code Size:

  • Bootloaders are primarily designed for firmware updates and booting processes, necessitating a small code size.
  • TCP/IP stacks are complex and require a substantial codebase, making integration into small bootloaders challenging.

Memory Constraints:

  • Bootloaders often operate within limited memory space.
  • TCP/IP stacks consume significant memory, posing difficulties in fitting them into constrained bootloader environments.

Feasibility of Developing a TCP/IP-enabled Bootloader with W5500

Built-in TCP/IP:

  • W5500 embeds a hardware-based TCP/IP stack, offering convenient features that might be challenging to implement with additional software.
  • Leveraging the built-in stack enables the integration of TCP/IP functionality into bootloaders with minimal code and memory footprint.

Implementation with Minimal Memory and Code:

  • Using W5500's hardware stack allows developers to minimize code size and memory usage in the bootloader.
  • Hardware stacks are generally more efficient and support faster data transmission compared to software implementations.

Developing a TCP/IP-enabled bootloader with W5500 not only streamlines network-based firmware management and remote monitoring but also ensures efficient operation in environments with limited memory resources.

 

Bootloader Test Code

typedef  void (*pFunction)(void);
pFunction Jump_To_Bootloader;
uint32_t JumpAddress;

void func_jump2bootloader(void)
{
	if (((*(__IO uint32_t*)FLASH_BASE_ADDR) & 0x2FFC0000 ) == 0x20000000)
	{
		__disable_irq();
		JumpAddress = *(__IO uint32_t*) (FLASH_BASE_ADDR + 4);
    Jump_To_Bootloader = (pFunction) JumpAddress;
		__set_MSP(*(__IO uint32_t*) FLASH_BASE_ADDR);
    Jump_To_Bootloader();
	}
}

void func_led_onoff_cross(void);
void func_led_onoff_sametime(void);

void func_custom_http_downloading_file_save(u8 state, u8 pageno, u8* cache, u32 len_cache_cont)//pageno start from 1
{
//	func_usart2_dma_send_bytes(cache, len_cache_cont);
	if(state == 0)//downloading
	{
		//write FLASH Backup file content
		func_flash_write_datas(FLASH_APPBACKUP_ADDR + (pageno-1)*2048, (u16*)cache, SIZE_DOWNLOAD_CACHE/2);
	}
	else if(state == 1)//done
	{
		//write FLASH Backup file content
		func_flash_write_datas(FLASH_APPBACKUP_ADDR + (pageno-1)*2048, (u16*)cache, (len_cache_cont%2) == 0 ? (len_cache_cont/2) : (len_cache_cont/2+1));
		
		//write FLASH Record
		{
			u16 arrs[4];
			u32 downloadsize = (pageno-1)*SIZE_DOWNLOAD_CACHE + len_cache_cont;
			arrs[0] = 2;
			arrs[1] = 0xFFFF;
			arrs[2] = downloadsize >> 16;
			arrs[3] = (u16)downloadsize;
			func_flash_write_datas(FLASH_RECORD_ADDR, arrs, 4);			
		}
	}
}

u8 buf[2048];

int main()
{
	u8 state_k1_init;
	
	u8 mac[6]={0, };
	DHCP_Get dhcp_get;
	
	//FIXME your file server ip
	u8 srv_ip[] = {192, 168, 1, 109};
	u16 srv_port = 8888;
	
	NVIC_SetVectorTable(NVIC_VectTab_FLASH, (FLASH_APPCODE_ADDR - FLASH_BASE_ADDR));
	
	init_led();
	init_switchkeys();
	
	init_system_spi();
	func_w5500_reset();	
	
//	init_hardware_usart2_dma(115200);
	
	getMacByLockCode(mac);
	setSHAR(mac);
	
	sysinit(txsize, rxsize);
	setRTR(2000);
  setRCR(3);
	
	state_k1_init = func_get_switchkey1();
	
	//USART DMA problem: 2 bytes missing
//	func_usart2_dma_send_bytes(mac, 2);
//	delay_ms(100);
	
	//hook
	init_hooks_http_download_file_save(func_custom_http_downloading_file_save);
	
	//DHCP
	for(;func_dhcp_get_ip_sub_gw(buf, sizeof(buf), 1, mac, &dhcp_get, 500) != 0;);	
	if(func_dhcp_get_ip_sub_gw(buf, sizeof(buf), 1, mac, &dhcp_get, 500) == 0)
	{
		setSUBR(dhcp_get.sub);
		setGAR(dhcp_get.gw);
		setSIPR(dhcp_get.lip);
		close(1);
	}
	
	for(;;)
	{
		if(state_k1_init != func_get_switchkey1())
		{
			u8 res;
			//downlaod bin file and reboot
			memset(buf, 0 , sizeof(buf));
			res = func_http_get_download_file(0, srv_ip, srv_port, "/file/APP_Download.bin_1.1.8", 5000, buf, sizeof(buf));
			if(res == 0)
			{
				//jump to bootloader
				func_jump2bootloader();
			}
			state_k1_init = func_get_switchkey1();
		}
//		func_led_onoff_cross();
		func_led_onoff_sametime();
		
	}
	
}
Documents
Comments Write