diff --git a/prj/TCPClient/Ld/Link.ld b/prj/TCPClient/Ld/Link.ld index 8583664..6e31bc0 100644 --- a/prj/TCPClient/Ld/Link.ld +++ b/prj/TCPClient/Ld/Link.ld @@ -1 +1,168 @@ -ENTRY( _start ) __stack_size = 2048; PROVIDE( _stack_size = __stack_size ); MEMORY { FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 192K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K } SECTIONS { .init : { _sinit = .; . = ALIGN(4); KEEP(*(SORT_NONE(.init))) . = ALIGN(4); _einit = .; } >FLASH AT>FLASH .vector : { *(.vector); . = ALIGN(64); } >FLASH AT>FLASH .text : { . = ALIGN(4); *(.text) *(.text.*) *(.rodata) *(.rodata*) *(.gnu.linkonce.t.*) . = ALIGN(4); } >FLASH AT>FLASH .fini : { KEEP(*(SORT_NONE(.fini))) . = ALIGN(4); } >FLASH AT>FLASH PROVIDE( _etext = . ); PROVIDE( _eitcm = . ); .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH AT>FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH AT>FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH AT>FLASH .ctors : { /* gcc uses crtbegin.o to find the start of the constructors, so we make sure it is first. Because this is a wildcard, it doesn't matter if the user does not actually link against crtbegin.o; the linker won't look for a file to match a wildcard. The wildcard also means that it doesn't matter which directory crtbegin.o is in. */ KEEP (*crtbegin.o(.ctors)) KEEP (*crtbegin?.o(.ctors)) /* We don't want to include the .ctor section from the crtend.o file until after the sorted ctors. The .ctor section from the crtend file contains the end of ctors marker and it must be last */ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) } >FLASH AT>FLASH .dtors : { KEEP (*crtbegin.o(.dtors)) KEEP (*crtbegin?.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) } >FLASH AT>FLASH .dalign : { . = ALIGN(4); PROVIDE(_data_vma = .); } >RAM AT>FLASH .dlalign : { . = ALIGN(4); PROVIDE(_data_lma = .); } >FLASH AT>FLASH .data : { *(.gnu.linkonce.r.*) *(.data .data.*) *(.gnu.linkonce.d.*) . = ALIGN(8); PROVIDE( __global_pointer$ = . + 0x800 ); *(.sdata .sdata.*) *(.sdata2.*) *(.gnu.linkonce.s.*) . = ALIGN(8); *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*) . = ALIGN(4); PROVIDE( _edata = .); } >RAM AT>FLASH .bss : { . = ALIGN(4); PROVIDE( _sbss = .); *(.sbss*) *(.gnu.linkonce.sb.*) *(.bss*) *(.gnu.linkonce.b.*) *(COMMON*) . = ALIGN(4); PROVIDE( _ebss = .); } >RAM AT>FLASH PROVIDE( _end = _ebss); PROVIDE( end = . ); .stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size : { PROVIDE( _heap_end = . ); . = ALIGN(4); PROVIDE(_susrstack = . ); . = . + __stack_size; PROVIDE( _eusrstack = .); } >RAM } \ No newline at end of file +ENTRY( _start ) + +__stack_size = 2048; + +PROVIDE( _stack_size = __stack_size ); + + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 128K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K +} + + +SECTIONS +{ + + .init : + { + _sinit = .; + . = ALIGN(4); + KEEP(*(SORT_NONE(.init))) + . = ALIGN(4); + _einit = .; + } >FLASH AT>FLASH + + .vector : + { + *(.vector); + . = ALIGN(64); + } >FLASH AT>FLASH + + .text : + { + . = ALIGN(4); + *(.text) + *(.text.*) + *(.rodata) + *(.rodata*) + *(.gnu.linkonce.t.*) + . = ALIGN(4); + } >FLASH AT>FLASH + + .fini : + { + KEEP(*(SORT_NONE(.fini))) + . = ALIGN(4); + } >FLASH AT>FLASH + + PROVIDE( _etext = . ); + PROVIDE( _eitcm = . ); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH AT>FLASH + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH AT>FLASH + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH AT>FLASH + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >FLASH AT>FLASH + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >FLASH AT>FLASH + + .dalign : + { + . = ALIGN(4); + PROVIDE(_data_vma = .); + } >RAM AT>FLASH + + .dlalign : + { + . = ALIGN(4); + PROVIDE(_data_lma = .); + } >FLASH AT>FLASH + + .data : + { + *(.gnu.linkonce.r.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.sdata2.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + . = ALIGN(4); + PROVIDE( _edata = .); + } >RAM AT>FLASH + + .bss : + { + . = ALIGN(4); + PROVIDE( _sbss = .); + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss*) + *(.gnu.linkonce.b.*) + *(COMMON*) + . = ALIGN(4); + PROVIDE( _ebss = .); + } >RAM AT>FLASH + + PROVIDE( _end = _ebss); + PROVIDE( end = . ); + + .stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = ALIGN(4); + PROVIDE(_susrstack = . ); + . = . + __stack_size; + PROVIDE( _eusrstack = .); + __freertos_irq_stack_top = .; + } >RAM + +} + + + diff --git a/prj/TCPClient/User/ch32v30x_it.c b/prj/TCPClient/User/ch32v30x_it.c index 9b58158..0021b7e 100644 --- a/prj/TCPClient/User/ch32v30x_it.c +++ b/prj/TCPClient/User/ch32v30x_it.c @@ -11,8 +11,6 @@ *******************************************************************************/ #include "eth_driver.h" #include "ch32v30x_it.h" -#include "FreeRTOS.h" -#include "task.h" void NMI_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast"))); void HardFault_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast"))); @@ -91,19 +89,8 @@ void ETH_IRQHandler(void) */ void TIM2_IRQHandler(void) { - static uint8_t wchnet_divider = 0; - - /* 2ms tick for FreeRTOS (configTICK_RATE_HZ = 500) */ - sys_tick_ms += 2; - xPortSysTickHandler(); - - /* Software divider: call WCHNET_TimeIsr every 5 ticks = 10ms */ - if (++wchnet_divider >= 5) - { - wchnet_divider = 0; - WCHNET_TimeIsr(WCHNETTIMERPERIOD); - } - + sys_tick_ms += WCHNETTIMERPERIOD; + WCHNET_TimeIsr(WCHNETTIMERPERIOD); TIM_ClearITPendingBit(TIM2, TIM_IT_Update); } diff --git a/prj/TCPClient/User/main.c b/prj/TCPClient/User/main.c index 56dc3cd..c8ee851 100644 --- a/prj/TCPClient/User/main.c +++ b/prj/TCPClient/User/main.c @@ -75,6 +75,41 @@ void OnDetectionResult(uint32_t frameNumber, uint8_t resultStatus) #define KEEPALIVE_ENABLE 1 +/* ============================================================ + * FLASH / SRAM 分配配置 (Option Bytes RAM_CODE_MOD[2:0]) + * 修改后需复位才生效 + * ============================================================ */ +typedef enum { + FLASH_192_SRAM_128 = 0, /* 00x 默认 */ + FLASH_224_SRAM_96, /* 01x */ + FLASH_256_SRAM_64, /* 10x */ + FLASH_128_SRAM_192, /* 110 */ + FLASH_288_SRAM_32 /* 111 */ +} FLASH_SRAM_DEFIN; + +static void Config_Flash_SRAM(FLASH_SRAM_DEFIN mode) +{ + uint8_t UserByte = FLASH_GetUserOptionByte() & 0xFF; + uint8_t newByte = UserByte & ~0xE0; /* clear bits [7:5] */ + + switch (mode) { + case FLASH_192_SRAM_128: break; /* 000 */ + case FLASH_224_SRAM_96: newByte |= 0x40; break; /* 010 */ + case FLASH_256_SRAM_64: newByte |= 0x80; break; /* 100 */ + case FLASH_128_SRAM_192: newByte |= 0xC0; break; /* 110 */ + case FLASH_288_SRAM_32: newByte |= 0xE0; break; /* 111 */ + default: return; + } + + if (newByte == UserByte) return; /* already configured */ + + FLASH_Unlock(); + FLASH_ProgramOptionByteData(0x1FFFF802, newByte); + FLASH_Lock(); + printf("Flash/SRAM config changed to %d, resetting...\r\n", mode); + NVIC_SystemReset(); +} + u8 MACAddr[6]; u8 IPAddr[4] = {192, 168, 1, 10}; u8 GWIPAddr[4] = {192, 168, 1, 1}; @@ -96,8 +131,7 @@ void TIM2_Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure = {0}; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); - /* 2ms period: matches configTICK_RATE_HZ = 500 */ - TIM_TimeBaseStructure.TIM_Period = 2000 - 1; + TIM_TimeBaseStructure.TIM_Period = WCHNETTIMERPERIOD * 1000 - 1; TIM_TimeBaseStructure.TIM_Prescaler = SystemCoreClock / 1000000 - 1; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; @@ -226,6 +260,8 @@ int main(void) Delay_Init(); USART_Printf_Init(115200); printf("TCPClient Test\r\nSystemClk:%d\r\n", SystemCoreClock); + printf("UserByte: %02x\r\n", FLASH_GetUserOptionByte() & 0xFF); + Config_Flash_SRAM(FLASH_128_SRAM_192); printf("net version:%x\n", WCHNET_GetVer()); if (WCHNET_LIB_VER != WCHNET_GetVer()) printf("version error.\n");