集成ymodem(暂未ceshi)

This commit is contained in:
zhangzheng
2025-03-11 19:29:59 +08:00
parent 141a6fd96b
commit 377c31cdc8
18 changed files with 1951 additions and 6 deletions

View File

@@ -15,7 +15,7 @@
* [x] TTY驱动支持
* [x] 内核二值信号量支持优先级反转(优先级继承协议)。
* [ ] FPU完整支持fastipc FPU支持
* [ ] 文件系统&网络协议栈完善自动删除支持(文件描述符自动管理库)
* [ ] 文件系统 & 网络协议栈完善自动删除支持(文件描述符自动管理库)
* [ ] 线程占用率统计
* [ ] procfs支持
* [ ] 新进程中env支持

View File

@@ -291,10 +291,6 @@ bool_t task_knl_kill(thread_t *kill_thread, bool_t is_knl)
{
// 还原栈和usp TODO: arch相关的
thread_user_pf_restore(kill_thread, (void *)arch_get_user_sp());
// umword_t *cur_pf = (umword_t *)(arch_get_user_sp()) - 8;
// cur_pf[5] = (umword_t)(thread_get_bind_task(kill_thread)->mm_space.mm_block);
// register volatile umword_t r9 asm("r9");
// r9 = (umword_t)(thread_get_bind_task(kill_thread)->mm_space.mm_block);
mpu_switch_to_task(thread_get_bind_task(kill_thread));
ref_counter_dec_and_release(&task->ref_cn, &task->kobj);
reset_ram = TRUE;

View File

@@ -18,7 +18,7 @@ static u_mutex_t mutex_lock;
static int test_cn;
static __attribute__((optimize(0))) void hard_sleep(void)
{
int i = 99999999;
volatile int i = 999999999;
while(i--);
}
static void *thread_th1(void *arg)
@@ -52,6 +52,9 @@ static void *thread_th3(void *arg)
u_mutex_unlock(&mutex_lock);
return NULL;
}
/**
* 测试优先级继承是否生效
*/
static void u_mutex_test(CuTest *tc)
{
obj_handler_t mutex_hd;

View File

@@ -5,6 +5,7 @@ add_subdirectory(tinycc-arm-thumb)
add_subdirectory(test)
add_subdirectory(test2)
add_subdirectory(vi)
add_subdirectory(Ymodem)
add_subdirectory(binutils-2.33.1)
# add_subdirectory(share_lib_test)
# add_subdirectory(share_lib_test2)

View File

@@ -0,0 +1,64 @@
cmake_minimum_required(VERSION 3.13)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ")
file(
GLOB deps
*.c
source/*.c
porting/*.c
)
add_executable(
ym.elf
${deps}
${START_SRC}
)
target_link_libraries(
ym.elf
PUBLIC
-Bstatic
${LIBC_NAME}
--whole-archive
${START_LIB}
libc_be
sys
sys_util
sys_svr
--no-whole-archive
${GCC_LIB_PATH}/libgcc.a
)
target_include_directories(
ym.elf
PUBLIC
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys/inc
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys_svr/inc
${CMAKE_CURRENT_SOURCE_DIR}/
${CMAKE_CURRENT_SOURCE_DIR}/source
${CMAKE_CURRENT_SOURCE_DIR}/porting
)
add_dependencies(
ym.elf
${START_LIB}
sys
sys_util
)
set_target_properties(
ym.elf PROPERTIES LINK_FLAGS
"-T ${CMAKE_CURRENT_LIST_DIR}/${ARCH_NAME}/link.lds ${CORTEX_M_LINK_FLAGS} --gc-section -no-dynamic-linker "
#--no-warn-rwx-segments
)
add_custom_target(
ym_dump ALL
COMMAND
${CMAKE_OBJCOPY} -O binary -S ym.elf ym.bin
COMMAND
${CMAKE_SIZE} ym.elf
COMMAND
${CMAKE_COMMAND} -E copy ym.bin ${CMAKE_SOURCE_DIR}/build/output/cpio/ym
COMMAND
cp ym.elf ${CMAKE_SOURCE_DIR}/build/output/ym.elf
)
add_dependencies(ym_dump ym.elf)

View File

@@ -0,0 +1,124 @@
ENTRY(_start_)
SECTIONS
{
.text : {
. = ALIGN(4);
__text_start__ = .;
KEEP(*(.first))
*(.text)
*(.text.*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(SORT(.rodata.*))
*(.rodata)
KEEP(*(.eh_frame*))
. = ALIGN(4);
__rel_start__ = .;
*(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
__rel_end__ = .;
}
.ARM.exidx : {
. = ALIGN(4);
__exdix_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
/* This is used by the startup in order to initialize the .data secion */
__exdix_end = .;
}
.permissions_table : {
. = ALIGN(4);
__permissions_table_start__ = .;
KEEP(*(.permissions_table))
__permissions_table_end__ = .;
}
PROVIDE(__ram_size__ = __bss_end__ - __data_start__);
.data : {
. = ALIGN(4);
__data_start__ = .;
__got_start__ = .;
*(.got)
__got_end__ = .;
. = ALIGN(4);
*(.data)
*(.data.*)
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
. = ALIGN(4);
_shell_command_start = .;
KEEP(*(shellCommand))
_shell_command_end = .;
. = ALIGN(4);
/* All data end */
__data_end__ = .;
}
PROVIDE(__heap_size__ = __heap_end__ - __heap_start__);
PROVIDE(__stack_size__ = __stack_end__ - __stack_start__);
.bss : {
. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss secion */
__bss_start__ = .;
*(.bss)
*(COMMON)
. = ALIGN(4);
__heap_start__ = .;
KEEP(*(.bss.heap))
__heap_end__ = .;
. = ALIGN(4);
__stack_start__ = .;
KEEP(*(.bss.stack))
__stack_end__ = .;
*(.bss.*)
/* This is used by the startup in order to initialize the .bss secion */
. = ALIGN(4);
__bss_end__ = .;
}
_end = .;
}

View File

@@ -0,0 +1,19 @@
#include <u_types.h>
#define HEAP_SIZE (512)
#define STACK_SIZE (1024 * 3)
#if defined(__CC_ARM)
#define HEAP_ATTR SECTION("HEAP") __attribute__((zero_init))
#define STACK_ATTR SECTION("STACK") __attribute__((zero_init))
#elif defined(__GNUC__)
#define HEAP_ATTR __attribute__((__section__(".bss.heap")))
#define STACK_ATTR __attribute__((__section__(".bss.stack")))
#elif defined(__IAR_SYSTEMS_ICC__)
#define HEAP_ATTR
#define STACK_ATTR
#endif
__attribute__((used)) HEAP_ATTR static char _____heap_____[HEAP_SIZE];
__attribute__((used)) STACK_ATTR static char _____stack_____[STACK_SIZE];
__attribute__((used)) umword_t _____mm_bitmap_____[ROUND(HEAP_SIZE, MK_PAGE_SIZE) / (sizeof(umword_t) * 8) + 1];

View File

@@ -0,0 +1,8 @@
#include "ymodem_export.h"
int main(int argv, char *argc[])
{
Ymodem_Main_Entrance();
return 0;
}

View File

@@ -0,0 +1,265 @@
/**
******************************************************************************
* @file STM32F0xx_IAP/src/common.c
* @author MCD Application Team
* @version V1.0.0
* @date 29-May-2012
* @brief Main program body
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
// #include "ymodem_port.h"
// #include "ff.h"
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <termios.h>
#include <u_types.h>
#include <unistd.h>
/** @addtogroup STM32F0xx_IAP
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/********************************************************************************
* Porting APIs
********************************************************************************/
typedef enum {
TRANS_FILE = 0,
IAP_IMAGE = 1,
} YMODEM_ACTION_E;
typedef struct {
int ymodem_tty_fd;
YMODEM_ACTION_E ymodem_action;
uint32_t ymodem_receive_supported_maxsize;
uint32_t ymodem_transmit_size;
bool_t ymodem_file_inited;
uint32_t ymodem_file_total_size;
uint32_t ymodem_file_handled_size;
int ymodem_file_handle;
// uint8_t ymodem_file_tmppath[128];
} YMODEM_DATA_T;
static YMODEM_DATA_T s_ymodem_data;
static void tty_init(void)
{
struct termios old_settings;
struct termios new_settings;
tcgetattr(STDIN_FILENO, &old_settings);
new_settings = old_settings;
new_settings.c_lflag &= ~(ICANON | ECHO); // 禁用规范模式和回显
new_settings.c_cc[VMIN] = 1; // 读取的最小字符数
new_settings.c_cc[VTIME] = 0; // 读取的超时时间以10ms为单位
tcsetattr(STDIN_FILENO, TCSANOW, &new_settings);
}
void ymodem_init(void)
{
tty_init();
memset(&s_ymodem_data, 0, sizeof(YMODEM_DATA_T));
s_ymodem_data.ymodem_tty_fd = STDIN_FILENO;
s_ymodem_data.ymodem_action = TRANS_FILE;
switch (s_ymodem_data.ymodem_action) {
case TRANS_FILE:
s_ymodem_data.ymodem_receive_supported_maxsize = 1024 * 1024 * 5;
s_ymodem_data.ymodem_transmit_size = 0;
break;
#if 0
case IAP_IMAGE:
#warning "MUST implement GOT transmit SIZE!"
s_ymodem_data.ymodem_receive_supported_maxsize = 1024 * 1024 * 5;
s_ymodem_data.ymodem_transmit_size = 0;
break;
#endif
default:
// Not supported
break;
}
}
uint32_t ymodem_get_receive_maxsize(void)
{
return s_ymodem_data.ymodem_receive_supported_maxsize;
}
uint32_t ymodem_get_transmit_size(void)
{
return s_ymodem_data.ymodem_transmit_size;
}
#include <fcntl.h>
// 0 - success ; -1 - fail
int ymodem_recv_start_cb(const char *filename, const uint32_t filesize)
{
// FRESULT fres;
int ret;
switch (s_ymodem_data.ymodem_action) {
case TRANS_FILE:
ret = open(filename, O_RDWR | O_CREAT, 0777);
if (ret < 0) {
//logd("Ymodem Start: create file(%s) fail(%d)...\n", filename, ret);
return -1;
} else {
//logd("Ymodem Start: create file(%s) ok(%d)...\n", filename, ret);
s_ymodem_data.ymodem_file_inited = TRUE;
s_ymodem_data.ymodem_file_total_size = filesize;
s_ymodem_data.ymodem_file_handled_size = 0;
s_ymodem_data.ymodem_file_handle = ret;
return 0;
}
// break;
case IAP_IMAGE:
/* erase user application area */
// FLASH_If_Erase(APPLICATION_ADDRESS);
break;
default:
// Not supported
break;
}
return -1;
}
int ymodem_recv_processing_cb(const uint8_t *buffer, const uint32_t buff_size)
{
int ret;
uint32_t to_write_size = 0;
uint32_t writted_size = 0;
switch (s_ymodem_data.ymodem_action) {
case TRANS_FILE:
to_write_size = s_ymodem_data.ymodem_file_total_size - s_ymodem_data.ymodem_file_handled_size;
to_write_size = (buff_size > to_write_size) ? to_write_size : buff_size;
ret = write(s_ymodem_data.ymodem_file_handle, buffer, to_write_size);
if (ret != to_write_size) {
//loge("Ymodem process: write file(%d - %d) fail(%d)...\n", to_write_size, writted_size, ret);
return -1;
} else {
s_ymodem_data.ymodem_file_handled_size += to_write_size;
// logi("Ymodem process: write file(%d/%d) ok(%d)...\n", s_ymodem_data.ymodem_file_handled_size,
// s_ymodem_data.ymodem_file_total_size, ret);
return 0;
}
// break;
case IAP_IMAGE:
// if (FLASH_If_Write(&flashdestination, (uint32_t*) ramsource, (uint16_t) packet_length/4) == 0)
break;
default:
// Not supported
break;
}
return -1;
}
int ymodem_recv_end_cb(void)
{
int fres;
// FILINFO fno;
switch (s_ymodem_data.ymodem_action) {
case TRANS_FILE:
if (TRUE != s_ymodem_data.ymodem_file_inited)
return -1;
fres = close(s_ymodem_data.ymodem_file_handle);
//logd("Ymodem End: close file res(%d)...\n", fres);
#if 0
fres = stat((const TCHAR *)s_ymodem_data.ymodem_file_tmppath, &fno);
if (fres != RES_OK) {
logw("Get File Status Fail(%d)...\n", fres);
} else {
logi("Get File Status ok(%d), file size(%d) Bytes...\n", fres, fno.fsize);
}
#endif
s_ymodem_data.ymodem_file_handle = -1;
s_ymodem_data.ymodem_file_total_size = 0;
s_ymodem_data.ymodem_file_handled_size = 0;
s_ymodem_data.ymodem_file_inited = FALSE;
return 0;
// break;
case IAP_IMAGE:
/* erase user application area */
// FLASH_If_Erase(APPLICATION_ADDRESS);
break;
default:
// Not supported
break;
}
return -1;
}
/**
* @brief Test to see if a key has been pressed on the HyperTerminal
* @param key: The key pressed
* @retval 1: Correct
* 0: Error
*/
uint32_t SerialKeyPressed(uint8_t *key)
{
int ret;
ret = read(STDIN_FILENO, key, 1);
if (ret < 0) {
return 0;
}
return 1;
}
// fail - 0xff; success -other value
uint8_t SerialReadByte(void)
{
int ret;
uint8_t byte;
ret = read(STDIN_FILENO, &byte, 1);
if (ret < 0) {
return 0xff;
}
return byte;
}
/**
* @brief Print a character on the HyperTerminal
* @param c: The character to be printed
* @retval None
*/
void SerialPutChar(uint8_t c)
{
write(STDIN_FILENO, &c, 1);
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,56 @@
/**
******************************************************************************
* @file STM32F0xx_IAP/inc/common.h
* @author MCD Application Team
* @version V1.0.0
* @date 29-May-2012
* @brief Header for main.c module
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
#ifndef __YMODEM_EXPORT_H__
#define __YMODEM_EXPORT_H__
/********************************************************************************
* The Public APIs *
********************************************************************************/
void Ymodem_Main_Entrance(void);
/********************************************************************************
* The Porting APIs Must Be Implemented *
********************************************************************************/
extern unsigned int SerialKeyPressed(unsigned char *key);
extern void SerialPutChar(unsigned char c);
extern unsigned char SerialReadByte(void);
extern void ymodem_init(void);
extern unsigned int ymodem_get_receive_maxsize(void);
extern unsigned int ymodem_get_transmit_size(void);
//0 - success ; -1 - fail
extern int ymodem_recv_start_cb(const char * filename, const unsigned int filesize);
extern int ymodem_recv_processing_cb(const unsigned char * buffer, const unsigned int buff_size);
extern int ymodem_recv_end_cb(void);
#endif /* __YMODEM_EXPORT_H__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,37 @@
#### About Source Code:
- source : source code Of Ymodem Protocol Implemention
```c
source --
|_____ common.h : compile system header files needed to include
|
|_____ ymodem.c : protocol implemention
|_____ ymodem.h : header file of protocol implemention
|
|_____ ymodem_util.c/.h : Tool Functions
|
|_____ ymodem_menu.c/.h : man - machine interaction menu
porting --
|
|_____ ymodem_export.h : All porting APIs should be Implemented by USER for different System or For different Usuage
|_____ ymodem_export.c : a demo implemention for porting APIs, For reference only, compile error exist
```
- porting : Porting file. porting APIs declare in ymodem_export.h, and ymodem_export.c is one implemention for Keil5/STM32. and compile errors exist
- keil : keil(v5) project, for STM32
---
#### And Attention:
- the origin source code is from Project\STM32F0xx_IAP Demo Project in ST.com
- And you may read the blog-article to known more about Ymodem: [Ymodem Procotol Porting](https://nixlong.github.io/2017/08/14/svm/Ymodem%E5%8D%8F%E8%AE%AE%E7%A7%BB%E6%A4%8D/#more)
---
By nix.long@126.com

View File

@@ -0,0 +1,8 @@
#ifndef __COMMON_H__
#define __COMMON_H__
/*System Include Files depended*/
#include "stdint.h"
#include "string.h"
#endif /*__COMMON_H__*/

View File

@@ -0,0 +1,726 @@
/**
******************************************************************************
* @file STM32F0xx_IAP/src/ymodem.c
* @author MCD Application Team
* @version V1.0.0
* @date 29-May-2012
* @brief Main program body
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
//#include "common.h"
#include "ymodem.h"
#include "ymodem_util.h"
#include "ymodem_export.h"
/** @addtogroup STM32F0xx_IAP
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
extern uint8_t FileName[];
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
* @brief Receive byte from sender
* @param c: Character
* @param timeout: Timeout
* @retval 0: Byte received
* -1: Timeout
*/
static int32_t Receive_Byte (uint8_t *c, uint32_t timeout)
{
while (timeout-- > 0)
{
if (SerialKeyPressed(c) == 1)
{
return 0;
}
}
return -1;
}
/**
* @brief Send a byte
* @param c: Character
* @retval 0: Byte sent
*/
static uint32_t Send_Byte (uint8_t c)
{
SerialPutChar(c);
return 0;
}
/**
* @brief Update CRC16 for input byte
* @param CRC input value
* @param input byte
* @retval Updated CRC value
*/
uint16_t UpdateCRC16(uint16_t crcIn, uint8_t byte)
{
uint32_t crc = crcIn;
uint32_t in = byte|0x100;
do
{
crc <<= 1;
in <<= 1;
if(in&0x100)
{
++crc;
}
if(crc&0x10000)
{
crc ^= 0x1021;
}
} while(!(in&0x10000));
return (crc&0xffffu);
}
/**
* @brief Cal CRC16 for YModem Packet
* @param data
* @param length
* @retval CRC value
*/
uint16_t Cal_CRC16(const uint8_t* data, uint32_t size)
{
uint32_t crc = 0;
const uint8_t* dataEnd = data+size;
while(data<dataEnd)
{
crc = UpdateCRC16(crc,*data++);
}
crc = UpdateCRC16(crc,0);
crc = UpdateCRC16(crc,0);
return (crc&0xffffu);
}
/**
* @brief Cal Check sum for YModem Packet
* @param data
* @param length
* @retval None
*/
uint8_t CalChecksum(const uint8_t* data, uint32_t size)
{
uint32_t sum = 0;
const uint8_t* dataEnd = data+size;
while(data < dataEnd)
{
sum += *data++;
}
return (sum&0xffu);
}
/**
* @brief Receive a packet from sender
* @param data
* @param length
* @param timeout
* 0: end of transmission
* -1: abort by sender
* >0: packet length
* @retval 0: normally return
* -1: timeout or packet error
* 1: abort by user
*/
static int32_t Receive_Packet (uint8_t *data, int32_t *length, uint32_t timeout)
{
uint16_t i, packet_size, computedcrc;
uint8_t c;
*length = 0;
if (Receive_Byte(&c, timeout) != 0)
{
return -1;
}
switch (c)
{
case SOH:
packet_size = PACKET_SIZE;
break;
case STX:
packet_size = PACKET_1K_SIZE;
break;
case EOT:
return 0;
case CA:
if ((Receive_Byte(&c, timeout) == 0) && (c == CA))
{
*length = -1;
return 0;
}
else
{
return -1;
}
case ABORT1:
case ABORT2:
return 1;
default:
return -1;
}
*data = c;
for (i = 1; i < (packet_size + PACKET_OVERHEAD); i ++)
{
if (Receive_Byte(data + i, timeout) != 0)
{
return -1;
}
}
if (data[PACKET_SEQNO_INDEX] != ((data[PACKET_SEQNO_COMP_INDEX] ^ 0xff) & 0xff))
{
return -1;
}
/* Compute the CRC */
computedcrc = Cal_CRC16(&data[PACKET_HEADER], (uint32_t)packet_size);
/* Check that received CRC match the already computed CRC value
data[packet_size+3]<<8) | data[packet_size+4] contains the received CRC
computedcrc contains the computed CRC value */
if (computedcrc != (uint16_t)((data[packet_size+3]<<8) | data[packet_size+4]))
{
/* CRC error */
return -1;
}
*length = packet_size;
return 0;
}
/**
* @brief Receive a file using the ymodem protocol
* @param buf: Address of the first byte
* @retval The size of the file
*/
int32_t Ymodem_Receive (uint8_t *buf)
{
uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD], file_size[FILE_SIZE_LENGTH], *file_ptr, *buf_ptr;
int32_t i, packet_length, session_done, file_done, packets_received, errors, session_begin, size = 0;
uint32_t flashdestination, ramsource;
uint32_t YMODEM_MAX_SIZE = ymodem_get_receive_maxsize();
flashdestination = flashdestination;
ramsource = ramsource;
#if 0
/* Initialize flashdestination variable */
flashdestination = APPLICATION_ADDRESS;
#endif
for (session_done = 0, errors = 0, session_begin = 0; ;)
{
for (packets_received = 0, file_done = 0, buf_ptr = buf; ;)
{
switch (Receive_Packet(packet_data, &packet_length, NAK_TIMEOUT))
{
case 0:
errors = 0;
switch (packet_length)
{
/* Abort by sender */
case - 1:
Send_Byte(ACK);
return 0;
/* End of transmission */
case 0:
Send_Byte(ACK);
file_done = 1;
break;
/* Normal packet */
default:
if ((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff))
{
Send_Byte(NAK);
}
else
{
if (packets_received == 0)
{
/* Filename packet */
if (packet_data[PACKET_HEADER] != 0)
{
/* Filename packet has valid data */
for (i = 0, file_ptr = packet_data + PACKET_HEADER; (*file_ptr != 0) && (i < FILE_NAME_LENGTH);)
{
FileName[i++] = *file_ptr++;
}
FileName[i++] = '\0';
for (i = 0, file_ptr ++; (*file_ptr != ' ') && (i < (FILE_SIZE_LENGTH - 1));)
{
file_size[i++] = *file_ptr++;
}
file_size[i++] = '\0';
Str2Int(file_size, &size);
/* Test the size of the image to be sent */
/* Image size is greater than Flash size */
if (size > (YMODEM_MAX_SIZE + 1))
{
/* End session */
Send_Byte(CA);
Send_Byte(CA);
return -1;
}
#if 0
/* erase user application area */
FLASH_If_Erase(APPLICATION_ADDRESS);
#else
//start fail
if(-1 == ymodem_recv_start_cb((char*)FileName, size)){
/* End session */
Send_Byte(CA);
Send_Byte(CA);
return -1;
}
#endif
Send_Byte(ACK);
Send_Byte(CRC16);
}
/* Filename packet is empty, end session */
else
{
Send_Byte(ACK);
file_done = 1;
session_done = 1;
break;
}
}
/* Data packet */
else
{
memcpy((uint8_t*)buf_ptr, (uint8_t*)packet_data + PACKET_HEADER, packet_length);
ramsource = (uint32_t)buf;
/* Write received data in Flash */
#if 0
if (FLASH_If_Write(&flashdestination, (uint32_t*) ramsource, (uint16_t) packet_length/4) == 0)
#else
if(0 == ymodem_recv_processing_cb((const uint8_t *)buf, packet_length))
#endif
{
Send_Byte(ACK);
}
else /* An error occurred while writing to Flash memory */
{
/* End session */
Send_Byte(CA);
Send_Byte(CA);
return -2;
}
}
packets_received ++;
session_begin = 1;
}
}
break;
case 1:
Send_Byte(CA);
Send_Byte(CA);
return -3;
default:
if (session_begin > 0)
{
errors ++;
}
if (errors > MAX_ERRORS)
{
Send_Byte(CA);
Send_Byte(CA);
return 0;
}
Send_Byte(CRC16);
break;
}
if (file_done != 0)
{
break;
}
}
if (session_done != 0)
{
break;
}
}
return (int32_t)size;
}
/**
* @brief check response using the ymodem protocol
* @param buf: Address of the first byte
* @retval The size of the file
*/
int32_t Ymodem_CheckResponse(uint8_t c)
{
return 0;
}
/**
* @brief Prepare the first block
* @param timeout
* @retval None
*/
void Ymodem_PrepareIntialPacket(uint8_t *data, const uint8_t* fileName, uint32_t *length)
{
uint16_t i, j;
uint8_t file_ptr[10];
/* Make first three packet */
data[0] = SOH;
data[1] = 0x00;
data[2] = 0xff;
/* Filename packet has valid data */
for (i = 0; (fileName[i] != '\0') && (i < FILE_NAME_LENGTH);i++)
{
data[i + PACKET_HEADER] = fileName[i];
}
data[i + PACKET_HEADER] = 0x00;
Int2Str (file_ptr, *length);
for (j =0, i = i + PACKET_HEADER + 1; file_ptr[j] != '\0' ; )
{
data[i++] = file_ptr[j++];
}
for (j = i; j < PACKET_SIZE + PACKET_HEADER; j++)
{
data[j] = 0;
}
}
/**
* @brief Prepare the data packet
* @param timeout
* @retval None
*/
void Ymodem_PreparePacket(uint8_t *SourceBuf, uint8_t *data, uint8_t pktNo, uint32_t sizeBlk)
{
uint16_t i, size, packetSize;
uint8_t* file_ptr;
/* Make first three packet */
packetSize = sizeBlk >= PACKET_1K_SIZE ? PACKET_1K_SIZE : PACKET_SIZE;
size = sizeBlk < packetSize ? sizeBlk :packetSize;
if (packetSize == PACKET_1K_SIZE)
{
data[0] = STX;
}
else
{
data[0] = SOH;
}
data[1] = pktNo;
data[2] = (~pktNo);
file_ptr = SourceBuf;
/* Filename packet has valid data */
for (i = PACKET_HEADER; i < size + PACKET_HEADER;i++)
{
data[i] = *file_ptr++;
}
if ( size <= packetSize)
{
for (i = size + PACKET_HEADER; i < packetSize + PACKET_HEADER; i++)
{
data[i] = 0x1A; /* EOF (0x1A) or 0x00 */
}
}
}
/**
* @brief Transmit a data packet using the ymodem protocol
* @param data
* @param length
* @retval None
*/
void Ymodem_SendPacket(uint8_t *data, uint16_t length)
{
uint16_t i;
i = 0;
while (i < length)
{
Send_Byte(data[i]);
i++;
}
}
/**
* @brief Transmit a file using the ymodem protocol
* @param buf: Address of the first byte
* @retval The size of the file
*/
uint8_t Ymodem_Transmit (uint8_t *buf, const uint8_t* sendFileName, uint32_t sizeFile)
{
uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD];
uint8_t FileName[FILE_NAME_LENGTH];
uint8_t *buf_ptr, tempCheckSum ;
uint16_t tempCRC, blkNumber;
uint8_t receivedC[2], CRC16_F = 0, i;
uint32_t errors = 0, ackReceived = 0, size = 0, pktSize;
uint32_t YMODEM_TRANSMIT_SIZE = ymodem_get_transmit_size();
for (i = 0; i < (FILE_NAME_LENGTH - 1); i++)
{
FileName[i] = sendFileName[i];
}
CRC16_F = 1;
/* Prepare first block */
Ymodem_PrepareIntialPacket(&packet_data[0], FileName, &sizeFile);
do
{
/* Send Packet */
Ymodem_SendPacket(packet_data, PACKET_SIZE + PACKET_HEADER);
/* Send CRC or Check Sum based on CRC16_F */
if (CRC16_F)
{
tempCRC = Cal_CRC16(&packet_data[3], PACKET_SIZE);
Send_Byte(tempCRC >> 8);
Send_Byte(tempCRC & 0xFF);
}
else
{
tempCheckSum = CalChecksum (&packet_data[3], PACKET_SIZE);
Send_Byte(tempCheckSum);
}
/* Wait for Ack and 'C' */
if (Receive_Byte(&receivedC[0], 1000000) == 0)
{
if (receivedC[0] == ACK)
{
/* Packet transfered correctly */
ackReceived = 1;
}
}
else
{
errors++;
}
}while (!ackReceived && (errors < 0x0A));
if (errors >= 0x0A)
{
return errors;
}
buf_ptr = buf;
size = sizeFile;
blkNumber = 0x01;
/* Here 1024 bytes package is used to send the packets */
while (size)
{
/* Prepare next packet */
Ymodem_PreparePacket(buf_ptr, &packet_data[0], blkNumber, size);
ackReceived = 0;
receivedC[0]= 0;
errors = 0;
do
{
/* Send next packet */
if (size >= PACKET_1K_SIZE)
{
pktSize = PACKET_1K_SIZE;
}
else
{
pktSize = PACKET_SIZE;
}
Ymodem_SendPacket(packet_data, pktSize + PACKET_HEADER);
/* Send CRC or Check Sum based on CRC16_F */
if (CRC16_F)
{
tempCRC = Cal_CRC16(&packet_data[3], pktSize);
Send_Byte(tempCRC >> 8);
Send_Byte(tempCRC & 0xFF);
}
else
{
tempCheckSum = CalChecksum (&packet_data[3], pktSize);
Send_Byte(tempCheckSum);
}
/* Wait for Ack */
if (Receive_Byte(&receivedC[0], 1000000) == 0)
{
if (receivedC[0] == ACK)
{
ackReceived = 1;
if (size > pktSize)
{
buf_ptr += pktSize;
size -= pktSize;
if (blkNumber == (YMODEM_TRANSMIT_SIZE/1024))
{
return 0xFF; /* error */
}
else
{
blkNumber++;
}
}
else
{
buf_ptr += pktSize;
size = 0;
}
}
}
else
{
errors++;
}
}while(!ackReceived && (errors < 0x0A));
/* Resend packet if NAK for a count of 10 else end of commuincation */
if (errors >= 0x0A)
{
return errors;
}
}
ackReceived = 0;
receivedC[0] = 0x00;
receivedC[1] = 0x00;
errors = 0;
do
{
Send_Byte(EOT);
/* Send (EOT); */
/* Wait for Ack */
receivedC[0] = SerialReadByte();
if (receivedC[0] == ACK)
{
ackReceived = 1;
}
else
{
errors++;
}
}while (!ackReceived && (errors < 0x0A));
if (errors >= 0x0A)
{
return errors;
}
/* Last packet preparation */
ackReceived = 0;
receivedC[0] = 0x00;
receivedC[1] = 0x00;
errors = 0;
packet_data[0] = SOH;
packet_data[1] = 0;
packet_data [2] = 0xFF;
for (i = PACKET_HEADER; i < (PACKET_SIZE + PACKET_HEADER); i++)
{
packet_data [i] = 0x00;
}
do
{
/* Send Packet */
Ymodem_SendPacket(packet_data, PACKET_SIZE + PACKET_HEADER);
/* Send CRC or Check Sum based on CRC16_F */
tempCRC = Cal_CRC16(&packet_data[3], PACKET_SIZE);
Send_Byte(tempCRC >> 8);
Send_Byte(tempCRC & 0xFF);
/* Wait for Ack and 'C' */
if (Receive_Byte(&receivedC[1], 1000000) == 0)
{
if (receivedC[1] == ACK)
{
/* Packet transfered correctly */
ackReceived = 1;
}
}
else
{
errors++;
}
}while (!ackReceived && (errors < 0x0A));
/* Resend packet if NAK for a count of 10 else end of commuincation */
if (errors >= 0x0A)
{
return errors;
}
receivedC[0] = 0x00;
do
{
Send_Byte(EOT);
/* Send (EOT); */
/* Wait for Ack */
if ((Receive_Byte(&receivedC[0], 1000000) == 0) && receivedC[0] == ACK)
{
ackReceived = 1;
}
else
{
errors++;
}
/* Clear Overrun flag of the USART2 */
//USART_ClearFlag(EVAL_COM1, USART_FLAG_ORE);
}while (!ackReceived && (errors < 0x0A));
if (errors >= 0x0A)
{
return errors;
}
return 0; /* file trasmitted successfully */
}
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,78 @@
/**
******************************************************************************
* @file STM32F0xx_IAP/inc/ymodem.h
* @author MCD Application Team
* @version V1.0.0
* @date 29-May-2012
* @brief Header for main.c module
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef _YMODEM_H_
#define _YMODEM_H_
#include "common.h"
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
#define PACKET_SEQNO_INDEX (1)
#define PACKET_SEQNO_COMP_INDEX (2)
#define PACKET_HEADER (3)
#define PACKET_TRAILER (2)
#define PACKET_OVERHEAD (PACKET_HEADER + PACKET_TRAILER)
#define PACKET_SIZE (128)
#define PACKET_1K_SIZE (1024)
#define FILE_NAME_LENGTH (256)
#define FILE_SIZE_LENGTH (16)
#define SOH (0x01) /* start of 128-byte data packet */
#define STX (0x02) /* start of 1024-byte data packet */
#define EOT (0x04) /* end of transmission */
#define ACK (0x06) /* acknowledge */
#define NAK (0x15) /* negative acknowledge */
#define CA (0x18) /* two of these in succession aborts transfer */
#define CRC16 (0x43) /* 'C' == 0x43, request 16-bit CRC */
#define ABORT1 (0x41) /* 'A' == 0x41, abort by user */
#define ABORT2 (0x61) /* 'a' == 0x61, abort by user */
#define NAK_TIMEOUT (5000)
#define MAX_ERRORS (5)
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
int32_t Ymodem_Receive (uint8_t *);
uint8_t Ymodem_Transmit (uint8_t *,const uint8_t* , uint32_t );
uint16_t UpdateCRC16(uint16_t crcIn, uint8_t byte);
uint16_t Cal_CRC16(const uint8_t* data, uint32_t size);
uint8_t CalChecksum(const uint8_t* data, uint32_t size);
int32_t Ymodem_CheckResponse(uint8_t c);
void Ymodem_PrepareIntialPacket(uint8_t *data, const uint8_t* fileName, uint32_t *length);
void Ymodem_PreparePacket(uint8_t *SourceBuf, uint8_t *data, uint8_t pktNo, uint32_t sizeBlk);
void Ymodem_SendPacket(uint8_t *data, uint16_t length);
#endif /* _YMODEM_H_ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,186 @@
/**
******************************************************************************
* @file STM32F0xx_IAP/src/menu.c
* @author MCD Application Team
* @version V1.0.0
* @date 29-May-2012
* @brief Main program body
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "ymodem.h"
#include "ymodem_menu.h"
#include "ymodem_util.h"
#include "ymodem_export.h"
/** @addtogroup STM32F0xx_IAP
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint32_t JumpAddress;
extern uint32_t UserMemoryMask;
uint32_t FlashProtection = 0;
uint8_t tab_1024[1024] = {0};
uint8_t FileName[FILE_NAME_LENGTH];
/* Private function prototypes -----------------------------------------------*/
void SerialDownload(void);
void SerialUpload(void);
// #warning "avoid errors"
#define APPLICATION_ADDRESS 0x08000000
#define USER_FLASH_SIZE 1024
/* Private functions ---------------------------------------------------------*/
/**
* @brief Download a file via serial port
* @param None
* @retval None
*/
void SerialDownload(void)
{
uint8_t Number[10] = {0};
int32_t Size = 0;
SerialPutString("Waiting for the file to be sent ... (press 'a' to abort)\n\r");
Size = Ymodem_Receive(&tab_1024[0]);
ymodem_recv_end_cb();
if (Size > 0)
{
SerialPutString("\n\n\r Download File Successfully!\n\r--------------------------------\r\n Name: ");
SerialPutString(FileName);
Int2Str(Number, Size);
SerialPutString("\n\r Size: ");
SerialPutString(Number);
SerialPutString(" Bytes\r\n");
SerialPutString("--------------------------------\n");
}
else if (Size == -1)
{
SerialPutString("\n\n\rThe file size is higher than the allowed space memory!\n\r");
}
else if (Size == -2)
{
SerialPutString("\n\n\rVerification failed!\n\r");
}
else if (Size == -3)
{
SerialPutString("\r\n\nAborted by user.\n\r");
}
else
{
SerialPutString("\n\rFailed to receive the file!\n\r");
}
}
#if 0
/**
* @brief Upload a file via serial port.
* @param None
* @retval None
*/
void SerialUpload(void)
{
uint8_t status = 0 ;
SerialPutString("\n\n\rSelect Receive File\n\r");
if (GetKey() == CRC16)
{
/* Transmit the flash image through ymodem protocol */
status = Ymodem_Transmit((uint8_t*)APPLICATION_ADDRESS, (const uint8_t*)"UploadedFlashImage.bin", USER_FLASH_SIZE);
if (status != 0)
{
SerialPutString("\n\rError Occurred while Transmitting File\n\r");
}
else
{
SerialPutString("\n\rFile uploaded successfully \n\r");
}
}
}
#endif
/**
* @brief Display the Main Menu on HyperTerminal
* @param None
* @retval None
*/
void Ymodem_Main_Entrance(void)
{
uint8_t key = 0;
ymodem_init();
SerialPutString("\r\n======================================================================");
SerialPutString("\r\n= (C) COPYRIGHT 2012 STMicroelectronics =");
SerialPutString("\r\n= =");
SerialPutString("\r\n= MKRTOS In-Application Programming Application (Version 1.0.0) =");
SerialPutString("\r\n= =");
SerialPutString("\r\n= By MCD Application Team =");
SerialPutString("\r\n======================================================================");
SerialPutString("\r\n\r\n");
while (1)
{
SerialPutString("\r\n================== Ymodem Menu =========================\r\n\n");
SerialPutString(" Download File from PC to Board ------- 1\r\n\n");
// SerialPutString(" Upload File from Board to PC ------- 2\r\n\n");
SerialPutString(" Exit Y-modem ------- 2\r\n\n");
SerialPutString("==========================================================\r\n\n");
/* Receive key */
key = GetKey();
if (key == 0x31)
{
/* Download user application in the Flash */
SerialDownload();
}
#if 0
else if (key == 0x32)
{
/* Upload user application from the Flash */
SerialUpload();
}
#endif
else if (key == 0x32) /* execute the new program */
{
SerialPutString("Exit Y-modem ....\r\n");
break;
}
else
{
SerialPutString("Invalid Number ! ==> The number should be either 1, 2 or 3\r");
}
}
}
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,43 @@
/**
******************************************************************************
* @file STM32F0xx_IAP/inc/menu.h
* @author MCD Application Team
* @version V1.0.0
* @date 29-May-2012
* @brief Header for main.c module
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MENU_H
#define __MENU_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
#endif /* __MENU_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,264 @@
/**
******************************************************************************
* @file STM32F0xx_IAP/src/common.c
* @author MCD Application Team
* @version V1.0.0
* @date 29-May-2012
* @brief Main program body
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "ymodem_util.h"
#include "ymodem_export.h"
/********************************************************************************
* ANSI-C APIs
********************************************************************************/
/**
* @brief Get a key from the HyperTerminal
* @param None
* @retval The Key Pressed
*/
uint8_t GetKey(void)
{
uint8_t key = 0;
/* Waiting for user input */
while (1)
{
if (SerialKeyPressed((uint8_t*)&key)) break;
}
return key;
}
/**
* @brief Convert an Integer to a string
* @param str: The string
* @param intnum: The intger to be converted
* @retval None
*/
void Int2Str(uint8_t* str, int32_t intnum)
{
uint32_t i, Div = 1000000000, j = 0, Status = 0;
for (i = 0; i < 10; i++)
{
str[j++] = (intnum / Div) + 48;
intnum = intnum % Div;
Div /= 10;
if ((str[j-1] == '0') & (Status == 0))
{
j = 0;
}
else
{
Status++;
}
}
}
/**
* @brief Convert a string to an integer
* @param inputstr: The string to be converted
* @param intnum: The intger value
* @retval 1: Correct
* 0: Error
*/
uint32_t Str2Int(uint8_t *inputstr, int32_t *intnum)
{
uint32_t i = 0, res = 0;
uint32_t val = 0;
if (inputstr[0] == '0' && (inputstr[1] == 'x' || inputstr[1] == 'X'))
{
if (inputstr[2] == '\0')
{
return 0;
}
for (i = 2; i < 11; i++)
{
if (inputstr[i] == '\0')
{
*intnum = val;
/* return 1; */
res = 1;
break;
}
if (ISVALIDHEX(inputstr[i]))
{
val = (val << 4) + CONVERTHEX(inputstr[i]);
}
else
{
/* return 0, Invalid input */
res = 0;
break;
}
}
/* over 8 digit hex --invalid */
if (i >= 11)
{
res = 0;
}
}
else /* max 10-digit decimal input */
{
for (i = 0;i < 11;i++)
{
if (inputstr[i] == '\0')
{
*intnum = val;
/* return 1 */
res = 1;
break;
}
else if ((inputstr[i] == 'k' || inputstr[i] == 'K') && (i > 0))
{
val = val << 10;
*intnum = val;
res = 1;
break;
}
else if ((inputstr[i] == 'm' || inputstr[i] == 'M') && (i > 0))
{
val = val << 20;
*intnum = val;
res = 1;
break;
}
else if (ISVALIDDEC(inputstr[i]))
{
val = val * 10 + CONVERTDEC(inputstr[i]);
}
else
{
/* return 0, Invalid input */
res = 0;
break;
}
}
/* Over 10 digit decimal --invalid */
if (i >= 11)
{
res = 0;
}
}
return res;
}
/**
* @brief Get an integer from the HyperTerminal
* @param num: The inetger
* @retval 1: Correct
* 0: Error
*/
uint32_t GetIntegerInput(int32_t * num)
{
uint8_t inputstr[16];
while (1)
{
GetInputString(inputstr);
if (inputstr[0] == '\0') continue;
if ((inputstr[0] == 'a' || inputstr[0] == 'A') && inputstr[1] == '\0')
{
SerialPutString("User Cancelled \r\n");
return 0;
}
if (Str2Int(inputstr, num) == 0)
{
SerialPutString("Error, Input again: \r\n");
}
else
{
return 1;
}
}
}
/**
* @brief Print a string on the HyperTerminal
* @param s: The string to be printed
* @retval None
*/
void Serial_PutString(uint8_t *s)
{
while (*s != '\0')
{
SerialPutChar(*s);
s++;
}
}
/**
* @brief Get Input string from the HyperTerminal
* @param buffP: The input string
* @retval None
*/
void GetInputString (uint8_t * buffP)
{
uint32_t bytes_read = 0;
uint8_t c = 0;
do
{
c = GetKey();
if (c == '\r')
break;
if (c == '\b') /* Backspace */
{
if (bytes_read > 0)
{
SerialPutString("\b \b");
bytes_read --;
}
continue;
}
if (bytes_read >= CMD_STRING_SIZE )
{
SerialPutString("Command string size overflow\r\n");
bytes_read = 0;
continue;
}
if (c >= 0x20 && c <= 0x7E)
{
buffP[bytes_read++] = c;
SerialPutChar(c);
}
}
while (1);
SerialPutString(("\n\r"));
buffP[bytes_read] = '\0';
}
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,67 @@
/**
******************************************************************************
* @file STM32F0xx_IAP/inc/common.h
* @author MCD Application Team
* @version V1.0.0
* @date 29-May-2012
* @brief Header for main.c module
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __YMODEM_UTIL_H__
#define __YMODEM_UTIL_H__
/* Includes ------------------------------------------------------------------*/
#include "common.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Constants used by Serial Command Line Mode */
#define CMD_STRING_SIZE 128
/* Exported macro ------------------------------------------------------------*/
/* Common routines */
#define IS_AF(c) ((c >= 'A') && (c <= 'F'))
#define IS_af(c) ((c >= 'a') && (c <= 'f'))
#define IS_09(c) ((c >= '0') && (c <= '9'))
#define ISVALIDHEX(c) IS_AF(c) || IS_af(c) || IS_09(c)
#define ISVALIDDEC(c) IS_09(c)
#define CONVERTDEC(c) (c - '0')
#define CONVERTHEX_alpha(c) (IS_AF(c) ? (c - 'A'+10) : (c - 'a'+10))
#define CONVERTHEX(c) (IS_09(c) ? (c - '0') : CONVERTHEX_alpha(c))
#define SerialPutString(x) Serial_PutString((uint8_t*)(x))
/* Exported functions ------------------------------------------------------- */
void Int2Str(uint8_t* str,int32_t intnum);
uint32_t Str2Int(uint8_t *inputstr,int32_t *intnum);
uint32_t GetIntegerInput(int32_t * num);
uint8_t GetKey(void);
void SerialPutChar(uint8_t c);
void Serial_PutString(uint8_t *s);
void GetInputString(uint8_t * buffP);
#endif /* __YMODEM_UTIL_H__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/