#include #ifdef CONFIG_AT_USR #include "FreeRTOS.h" #include "task.h" #include "semphr.h" #include "freertos_pmu.h" #include "at_cmd/log_service.h" #include "at_cmd/atcmd_wifi.h" #include #include "tcpip.h" #include #include #include #include "tcm_heap.h" #include "rtl8195a/rtl_libc.h" #include "flash_api.h" #include "sleep_ex_api.h" #include "lwip/tcp_impl.h" extern char str_rom_57ch3Dch0A[]; // "=========================================================\n" 57 #define printf rtl_printf // DiagPrintf /* RAM/TCM/Heaps info */ extern void ShowMemInfo(void); /* void ShowMemInfo(void) { printf("\nCLK CPU\t\t%d Hz\nRAM heap\t%d bytes\nTCM heap\t%d bytes\n", HalGetCpuClk(), xPortGetFreeHeapSize(), tcm_heap_freeSpace()); } */ //------------------------------------------------------------------------------ // Mem, Tasks info //------------------------------------------------------------------------------ void fATST(int argc, char *argv[]) { (void) argc; (void) argv; ShowMemInfo(); #if CONFIG_DEBUG_LOG > 1 extern int min_free_heap_size; printf("\nMin free heap size %d bytes\n", min_free_heap_size); #endif #if 0 //CONFIG_DEBUG_LOG > 1 dump_mem_block_list(); tcm_heap_dump(); #endif printf("\n"); #if (configGENERATE_RUN_TIME_STATS == 1) char *cBuffer = pvPortMalloc(512); if(cBuffer != NULL) { vTaskGetRunTimeStats((char *)cBuffer); printf("%s", cBuffer); } vPortFree(cBuffer); #endif #if defined(configUSE_TRACE_FACILITY) && (configUSE_TRACE_FACILITY == 1) && (configUSE_STATS_FORMATTING_FUNCTIONS == 1) { char * pcWriteBuffer = malloc(1024); if(pcWriteBuffer) { vTaskList((char*)pcWriteBuffer); printf("\nTask List:\n"); printf(&str_rom_57ch3Dch0A[7]); // "==========================================\n" printf("Name\t Status Priority HighWaterMark TaskNumber\n%s\n", pcWriteBuffer); free(pcWriteBuffer); } } #endif } /*------------------------------------------------------------------------------------- Копирует данные из области align(4) (flash, registers, ...) в область align(1) (ram) --------------------------------------------------------------------------------------*/ extern void copy_align4_to_align1(unsigned char * pd, void * ps, unsigned int len); /* static void copy_align4_to_align1(unsigned char * pd, void * ps, unsigned int len) { union { unsigned char uc[4]; unsigned int ud; }tmp; unsigned int *p = (unsigned int *)((unsigned int)ps & (~3)); unsigned int xlen = (unsigned int)ps & 3; // unsigned int size = len; if(xlen) { tmp.ud = *p++; while (len) { len--; *pd++ = tmp.uc[xlen++]; if(xlen & 4) break; } } xlen = len >> 2; while(xlen) { tmp.ud = *p++; *pd++ = tmp.uc[0]; *pd++ = tmp.uc[1]; *pd++ = tmp.uc[2]; *pd++ = tmp.uc[3]; xlen--; } if(len & 3) { tmp.ud = *p; pd[0] = tmp.uc[0]; if(len & 2) { pd[1] = tmp.uc[1]; if(len & 1) { pd[2] = tmp.uc[2]; } } } // return size; } */ /* * int print_hex_dump(uint8_t *buf, int len, unsigned char k) */ int print_hex_dump(uint8_t *buf, int len, unsigned char k) { uint32_t ss[2]; ss[0] = 0x78323025; // "%02x" ss[1] = k; // ","...'\0' uint8_t * ptr = buf; int result = 0; while (len--) { if (len == 0) ss[1] = 0; result += printf((uint8_t *) &ss, *ptr++); } return result; } extern char str_rom_hex_addr[]; // in *.ld "[Addr] .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F\n" void dump_bytes(uint32 addr, int size) { uint8 buf[17]; int symbs_line = sizeof(buf)-1; printf(str_rom_hex_addr); while (size) { if (symbs_line > size) symbs_line = size; printf("%08X ", addr); copy_align4_to_align1(buf, (void *) addr, symbs_line); print_hex_dump(buf, symbs_line, ' '); int i; for(i = 0 ; i < symbs_line ; i++) { if(buf[i] < 0x20 || buf[i] > 0x7E) { buf[i] = '.'; } } buf[symbs_line] = 0; i = (sizeof(buf)-1) - symbs_line; while(i--) printf(" "); printf(" %s\r\n", buf); addr += symbs_line; size -= symbs_line; } } //------------------------------------------------------------------------------ // Dump byte register //------------------------------------------------------------------------------ extern uint32_t Strtoul( IN const uint8_t *nptr, IN uint8_t **endptr, IN uint32_t base ); static void fATSB(int argc, char *argv[]) { int size = 16; uint32 addr = Strtoul(argv[1],0,16); if (argc > 2) { size = Strtoul(argv[2],0,10); if (size <= 0 || size > 16384) size = 16; } if(addr + size > SPI_FLASH_BASE) { flash_turnon(); dump_bytes(addr, size); SpicDisableRtl8195A(); } else { dump_bytes(addr, size); } } extern uint32_t CmdDumpWord(IN uint16_t argc, IN uint8_t *argv[]); extern uint32_t CmdWriteWord(IN uint16_t argc, IN uint8_t *argv[]); //------------------------------------------------------------------------------ // Dump dword register //------------------------------------------------------------------------------ static void fATSD(int argc, char *argv[]) { /* if (argc > 2) { int size = Strtoul(argv[2],0,10); if (size <= 0 || size > 16384) argv[2] = "16"; } */ CmdDumpWord(argc-1, (unsigned char**)(argv+1)); } //------------------------------------------------------------------------------ // Write dword register //------------------------------------------------------------------------------ static void fATSW(int argc, char *argv[]) { CmdWriteWord(argc-1, (unsigned char**)(argv+1)); } /* Get one byte from the 4-byte address */ #define ip4_addr1(ipaddr) (((uint8_t*)(ipaddr))[0]) #define ip4_addr2(ipaddr) (((uint8_t*)(ipaddr))[1]) #define ip4_addr3(ipaddr) (((uint8_t*)(ipaddr))[2]) #define ip4_addr4(ipaddr) (((uint8_t*)(ipaddr))[3]) /* These are cast to uint16_t, with the intent that they are often arguments * to printf using the U16_F format from cc.h. */ #define ip4_addr1_16(ipaddr) ((uint16_t)ip4_addr1(ipaddr)) #define ip4_addr2_16(ipaddr) ((uint16_t)ip4_addr2(ipaddr)) #define ip4_addr3_16(ipaddr) ((uint16_t)ip4_addr3(ipaddr)) #define ip4_addr4_16(ipaddr) ((uint16_t)ip4_addr4(ipaddr)) #define IP2STR(ipaddr) ip4_addr1_16(ipaddr), \ ip4_addr2_16(ipaddr), \ ip4_addr3_16(ipaddr), \ ip4_addr4_16(ipaddr) #define IPSTR "%d.%d.%d.%d" extern const char * const tcp_state_str[]; /* static const char * const tcp_state_str[] = { "CLOSED", "LISTEN", "SYN_SENT", "SYN_RCVD", "ESTABLISHED", "FIN_WAIT_1", "FIN_WAIT_2", "CLOSE_WAIT", "CLOSING", "LAST_ACK", "TIME_WAIT" }; */ /****************************************************************************** * FunctionName : debug * Parameters : * Returns : *******************************************************************************/ void print_udp_pcb(void) { struct udp_pcb *pcb; bool prt_none = true; rtl_printf("UDP pcbs:\n"); for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { rtl_printf("flg:%02x\t" IPSTR ":%d\t" IPSTR ":%d\trecv:%p\n", pcb->flags, IP2STR(&pcb->local_ip), pcb->local_port, IP2STR(&pcb->remote_ip), pcb->remote_port, pcb->recv ); prt_none = false; }; if(prt_none) rtl_printf("none\n"); } /****************************************************************************** * FunctionName : debug * Parameters : * Returns : *******************************************************************************/ void print_tcp_pcb(void) { struct tcp_pcb *pcb; rtl_printf("Active PCB states:\n"); bool prt_none = true; for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { rtl_printf("Port %d|%d\tflg:%02x\ttmr:%p\t%s\n", pcb->local_port, pcb->remote_port, pcb->flags, pcb->tmr, tcp_state_str[pcb->state]); prt_none = false; }; if(prt_none) rtl_printf("none\n"); rtl_printf("Listen PCB states:\n"); prt_none = true; for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) { rtl_printf("Port %d|%d\tflg:%02x\ttmr:%p\t%s\n", pcb->local_port, pcb->remote_port, pcb->flags, pcb->tmr, tcp_state_str[pcb->state]); prt_none = false; }; if(prt_none) rtl_printf("none\n"); rtl_printf("TIME-WAIT PCB states:\n"); prt_none = true; for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { rtl_printf("Port %d|%d\tflg:%02x\ttmr:%p \t%s\n", pcb->local_port, pcb->remote_port, pcb->flags, pcb->tmr, tcp_state_str[pcb->state]); prt_none = false; }; if(prt_none) rtl_printf("none\n"); } /****************************************************************************** * FunctionName : debug * Parameters : * Returns : *******************************************************************************/ static void fATLW(int argc, char *argv[]) // Info Lwip { (void) argc; (void) argv; print_udp_pcb(); print_tcp_pcb(); } //------------------------------------------------------------------------------ // GPIO Info //------------------------------------------------------------------------------ static void fATGI(int argc, char *argv[]) { (void) argc; (void) argv; int i; for (i = 0; i < _PORT_MAX; i++) printf("Port %c state: 0x%04x\n", i + 'A', GPIOState[i]); } //------------------------------------------------------------------------------ // Deep sleep //------------------------------------------------------------------------------ static void fATDS(int argc, char *argv[]) { uint32 sleep_ms = 10000; if(argc > 1) sleep_ms = atoi(argv[1]); #if 0 // WakeUp PB_1 if(argc > 2) { printf("%u ms waiting low level on PB_1 before launching Deep-Sleep...\n", sleep_ms); // turn off log uart HalDeinitLogUart(); // sys_log_uart_off(); // initialize wakeup pin gpio_t gpio_wake; gpio_init(&gpio_wake, PB_1); gpio_dir(&gpio_wake, PIN_INPUT); gpio_mode(&gpio_wake, PullDown); TickType_t sttime = xTaskGetTickCount(); do { if(gpio_read(&gpio_wake) == 0) { // Enter deep sleep... Wait give rising edge at PB_1 to wakeup system. deepsleep_ex(DSLEEP_WAKEUP_BY_GPIO, 0); }; vTaskDelay(1); } while(xTaskGetTickCount() - sttime < sleep_ms); HalInitLogUart(); // sys_log_uart_on(); printf("No set pin low in deep sleep!\n"); } else { printf("Deep-Sleep %u ms\n", sleep_ms); HalLogUartWaitTxFifoEmpty(); // Enter deep sleep... Wait timer ms deepsleep_ex(DSLEEP_WAKEUP_BY_TIMER, sleep_ms); } #else HalLogUartWaitTxFifoEmpty(); deepsleep_ex(DSLEEP_WAKEUP_BY_TIMER, sleep_ms); #endif } /*------------------------------------------------------------------------------ * power saving mode *----------------------------------------------------------------------------*/ static void fATSP(int argc, char *argv[]) { if(argc > 2) { switch (argv[1][0]) { case 'a': // acquire { acquire_wakelock(atoi(argv[2])); break; } case 'r': // release { release_wakelock(atoi(argv[2])); break; } }; }; printf("WakeLock Status %d\n", pmu_get_wakelock_status()); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ MON_RAM_TAB_SECTION COMMAND_TABLE console_commands_at[] = { {"ATST", 0, fATST, ": Memory info"}, {"ATLW", 0, fATLW, ": LwIP Info"}, {"ATGI", 0, fATGI, ": GPIO Info"}, {"ATSB", 1, fATSB, "=[,COUNT(dec)]: Dump byte register"}, {"ATSD", 1, fATSD, "=[,COUNT(dec)]: Dump dword register"}, {"ATSW", 2, fATSW, "=,: Set register"}, {"ATDS", 0, fATDS, "=[TIME(ms)]: Deep sleep"}, {"ATSP", 0, fATSP, "=,: Power"} }; #endif //#ifdef CONFIG_AT_USR