|

楼主 |
发表于 2017-12-12 17:29:12
|
显示全部楼层
34.6 实验例程说明(RTX)
34.6.1 STM32F407开发板实验
配套例子:
V5-1048_RL-TCPnet实验_SMTP邮件发送(RTX)
实验目的:
1. 学习RL-TCPnet的SMTP邮件发送。
实验内容:
1. 用户务必将网线接到能够联网的路由器或者交换机上面测试,因为DNS域名解析和SMTP发送邮件需要连接网络才行。
2. 由于126,163和QQ邮箱的通信都做了加密,所以RL-TCPnet的SMTP无法进行邮箱通信。当前测试新浪邮箱还可以使用,所以大家使用前务必要注册新浪邮箱。根据注册的新浪邮箱,SMTP_uif.c文件开头代码中的发送邮箱、接收邮箱、用户名、用户密码和邮件主题是需要用户填写的。
#define MAIL_FROM "baiyongbin_2006@sina.cn" 发送邮箱
#define RCPT_TO "baiyongbin_2006@sina.cn" 接收邮箱
#define SMTP_USER "baiyongbin_2006@sina.cn" 发送邮箱的用户名
#define SMTP_PASSWORD "xxxxxxxxx" 发送邮箱的密码
#define MAIL_SUBJECT "安富莱电子" 邮件主题
3. 邮件发送的具体操作步骤,务必看本章节配套教程的使用说明。
4. 我们这里实现邮件的自收发,也就是开发板的SMTP Client登录新浪邮箱,然后自己给自己发邮件。发送后,大家可以在电脑端或者手机端登录邮箱,并查看邮箱的内容。
5. 按下按键K2将启动邮件发送。
实验操作:
详见本章节34.5小节。
配置向导文件设置(Net_Config.c):
详见本章节34.3小节。
调试文件设置(Net_Debug.c):
详见本章节34.4小节。
RTX配置:
RTX配置向导详情如下:
Task Configuration
(1)Number of concurrent running tasks
允许创建6个任务,实际创建了如下5个任务:
AppTaskUserIF任务 :按键消息处理。
AppTaskLED任务 :LED闪烁。
AppTaskMsgPro任务 :按键检测。
AppTaskTCPMain任务:RL-TCPnet测试任务。
AppTaskStart任务 :启动任务,也是最高优先级任务,这里实现RL-TCPnet的时间基准更新。
(2)Number of tasks with user-provided stack
创建的5个任务都是采用自定义堆栈方式。
(3)Run in privileged mode
设置任务运行在非特权级模式。
RTX任务调试信息:
程序设计:
任务栈大小分配:
staticuint64_t AppTaskUserIFStk[1024/8]; /* 任务栈 */
staticuint64_t AppTaskLEDStk[1024/8]; /* 任务栈 */
staticuint64_t AppTaskMsgProStk[1024/8]; /* 任务栈 */
staticuint64_t AppTaskTCPMainStk[2048/8]; /* 任务栈 */
staticuint64_t AppTaskStartStk[1024/8]; /* 任务栈 */
将任务栈定义成uint64_t类型可以保证任务栈是8字节对齐的,8字节对齐的含义就是数组的首地址对8求余等于0。如果不做8字节对齐的话,部分C语言库函数、浮点运算和uint64_t类型数据运算会出问题。
系统栈大小分配:
RTX初始化:
- /*
- *********************************************************************************************************
- * 函 数 名: main
- * 功能说明: 标准c程序入口。
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- int main (void)
- {
- /* 初始化外设 */
- bsp_Init();
-
- /* 创建启动任务 */
- os_sys_init_user (AppTaskStart, /* 任务函数 */
- 5, /* 任务优先级 */
- &AppTaskStartStk, /* 任务栈 */
- sizeof(AppTaskStartStk)); /* 任务栈大小,单位字节数 */
- while(1);
- }
复制代码 硬件外设初始化
硬件外设的初始化是在 bsp.c 文件实现:
- /*
- *********************************************************************************************************
- * 函 数 名: bsp_Init
- * 功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void bsp_Init(void)
- {
- /*
- 由于ST固件库的启动文件已经执行了CPU系统时钟的初始化,所以不必再次重复配置系统时钟。
- 启动文件配置了CPU主时钟频率、内部Flash访问速度和可选的外部SRAM FSMC初始化。
-
- 系统时钟缺省配置为168MHz,如果需要更改,可以修改 system_stm32f4xx.c 文件
- */
- /* 优先级分组设置为4,可配置0-15级抢占式优先级,0级子优先级,即不存在子优先级。*/
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
-
- bsp_InitDWT(); /* 初始化DWT */
- bsp_InitUart(); /* 初始化串口 */
- bsp_InitKey(); /* 初始化按键变量(必须在 bsp_InitTimer() 之前调用) */
- bsp_InitLed(); /* 初始LED指示灯端口 */
- }
复制代码 RTX任务创建:
- /*
- *********************************************************************************************************
- * 函 数 名: AppTaskCreate
- * 功能说明: 创建应用任务
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void AppTaskCreate (void)
- {
- HandleTaskUserIF = os_tsk_create_user(AppTaskUserIF, /* 任务函数 */
- 1, /* 任务优先级 */
- &AppTaskUserIFStk, /* 任务栈 */
- sizeof(AppTaskUserIFStk)); /* 任务栈大小,单位字节数 */
-
- HandleTaskLED = os_tsk_create_user(AppTaskLED, /* 任务函数 */
- 2, /* 任务优先级 */
- &AppTaskLEDStk, /* 任务栈 */
- sizeof(AppTaskLEDStk)); /* 任务栈大小,单位字节数 */
-
- HandleTaskMsgPro = os_tsk_create_user(AppTaskMsgPro, /* 任务函数 */
- 3, /* 任务优先级 */
- &AppTaskMsgProStk, /* 任务栈 */
- sizeof(AppTaskMsgProStk)); /* 任务栈大小,单位字节数 */
-
- HandleTaskTCPMain = os_tsk_create_user(AppTaskTCPMain, /* 任务函数 */
- 4, /* 任务优先级 */
- &AppTaskTCPMainStk, /* 任务栈 */
- sizeof(AppTaskTCPMainStk)); /* 任务栈大小,单位字节数 */
- }
复制代码 五个RTX任务的实现:
RL-TCPnet功能测试
这里专门创建了一个app_tcpnet_lib.c文件用于RL-TCPnet功能的测试,此文件主要实现网络主函数main_TcpNet的调用和邮件的发送。
- #include "includes.h"
-
-
-
- /*
- *********************************************************************************************************
- * 用于本文件的调试
- *********************************************************************************************************
- */
- #if 1
- #define printf_debug printf
- #else
- #define printf_debug(...)
- #endif
-
-
- /*
- *********************************************************************************************************
- * 变量
- *********************************************************************************************************
- */
- char const *hosts[4] =
- {
- "smtp.sina.cn",
- "smtp.126.com",
- "smtp.qq.com",
- "smtp.163.com",
- };
-
- U8 srv_ip[4];
- U8 dns_flag = 0;
-
-
- /*
- *********************************************************************************************************
- * 函 数 名: dns_cbfunc
- * 功能说明: 函数get_host_by_name的回调函数。
- * 形 参: event 事件类型
- * ip 如果事件类型是DNS_EVT_SUCCESS,此指针变量指向返回的IP地址缓冲区。
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void dns_cbfunc (unsigned char event, unsigned char *ip)
- {
- switch (event)
- {
- /* 成功解析地址 */
- case DNS_EVT_SUCCESS:
- printf_debug("DNS解析出邮箱服务器IP地址 : %d.%d.%d.%d\\n",ip[0],ip[1],ip[2],ip[3]);
-
- srv_ip[0] = ip[0];
- srv_ip[1] = ip[1];
- srv_ip[2] = ip[2];
- srv_ip[3] = ip[3];
- dns_flag = 1;
- break;
-
- /* DNS记录数据库中不存在此地址 */
- case DNS_EVT_NONAME:
- printf_debug("Host Name does not exist in DNS record database.\\n");
- break;
-
- /* 允许的DNS解析重试次数已经用完,仍无法解析,时间超时 */
- case DNS_EVT_TIMEOUT:
- printf_debug("DNS Resolver Timeout expired, Host Address not resolved.\\n");
- break;
-
- /* DNS协议错误,收到无效或者被损坏的回复 */
- case DNS_EVT_ERROR:
- printf_debug("DNS Resolver Protocol Error, Host Address not resolved.\\n");
- return;
- }
- }
-
- /*
- *********************************************************************************************************
- * 函 数 名: smtp_cback
- * 功能说明: 函数smtp_connect的回调函数。
- * 形 参: event 事件类型
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void smtp_cback(U8 event)
- {
- switch (event)
- {
- /* 邮件发送成功 */
- case SMTP_EVT_SUCCESS:
- printf_debug ("Email successfully sent\\r\\n");
- break;
-
- /* 超时,邮件未发送成功 */
- case SMTP_EVT_TIMEOUT:
- printf_debug ("Mail Server timeout.\\r\\n");
- break;
-
- /* 邮件发送失败 */
- case SMTP_EVT_ERROR:
- printf_debug ("Error sending email.\\r\\n");
- break;
- }
- }
-
- /*
- *********************************************************************************************************
- * 函 数 名: TCPnetTest
- * 功能说明: TCPent测试函数。
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void TCPnetTest(void)
- {
- OS_RESULT xResult;
-
- while (1)
- {
- os_evt_wait_or(0x0003, 0xFFFF);
-
- /* 如果接受到按键K2按下的消息,解析smtp.sina.cn的IP地址 */
- xResult = os_evt_get ();
- if(xResult == KEY2_BIT1)
- {
- get_host_by_name ((U8 *)hosts[0], dns_cbfunc);
- }
-
- /* 解析出IP地址后,发送邮件 */
- if(dns_flag == 1)
- {
- smtp_connect ((U8 *)&srv_ip, 25, smtp_cback);
- dns_flag = 0;
- }
-
- while (main_TcpNet() == __TRUE);
- }
- }
复制代码 SMTP用户接口文件的实现
KEIL官网有提供SMTP的接口文件,名为SMTP_uif.c文件。我们就是在这个文件上修改。具体修改后的代码如下:
- #include <Net_Config.h>
- #include <string.h>
- #include <stdio.h>
-
- /* Email definitions */
- #define MAIL_FROM "baiyongbin_2006@sina.cn"
- #define RCPT_TO "baiyongbin_2006@sina.cn"
- #define SMTP_USER "baiyongbin_2006@sina.cn"
- #define SMTP_PASSWORD "xxxxxxxxx"
- #define MAIL_SUBJECT "安富莱电子"
-
-
- #define MSG_HEADER \\
- "Hello,大家好!\\r\\n\\r\\n" \\
- "这是一封来自STM32-V6开发板发出的邮件,运行的RL-TCPnet小型协议栈\\r\\n" \\
- "在这里祝福大家身体健康,万事如意\\r\\n\\r\\n" \\
- "--------------------------------------------------------------\\r\\n"
-
- #define MSG_FOOTER \\
- "--------------------------------------------------------------\\r\\n"\\
- "此致敬礼\\r\\n\\r\\n" \\
- "安富莱电子"
-
-
- /* My structure of SMTP U32 storage variable. This variable is private and */
- /* is not altered by SMTP Client. It is only set to zero when smtp_cbfunc() */
- /* is called for the first time. */
- typedef struct {
- U8 id;
- U16 idx;
- } MY_BUF;
- #define MYBUF(p) ((MY_BUF *)p)
-
- /* Net_Config.c */
- extern struct sys_cfg sys_config;
- #define lhost_name sys_config.HostName
-
- /*----------------------------------------------------------------------------
- * SMTP CallBack Functions
- *---------------------------------------------------------------------------*/
-
- /*--------------------------- smtp_cbfunc -----------------------------------*/
-
- U16 smtp_cbfunc (U8 code, U8 *buf, U16 buflen, U32 *pvar) {
- /* This function is called by the SMTP client to get email parameters and */
- /* data. It returns the number of bytes written to the output buffer. */
- /* Hi-bit of return value (len is or-ed with 0x8000) is a repeat flag the */
- /* SMTP client. If this bit is set to 1, the system will call this func */
- /* again with parameter 'pvar' pointing to a 4-byte buffer. This buffer */
- /* can be used for storing different status variables for this function. */
- /* It is set to 0 by SMTP client on first call and is not altered by SMTP */
- /* client for repeated calls. This function should NEVER write more than */
- /* 'buflen' bytes to the buffer. */
- /* Parameters: */
- /* code - function code with following values: */
- /* 0 - Username: - for SMTP authentication if requested */
- /* 1 - Password: - for SMTP authentication if requested */
- /* 2 - 'From : ' - get email address of the sender */
- /* 3 - 'To : ' - get email address of recipient */
- /* 4 - 'Subject: ' - get subject of email */
- /* 5 - 'Data : ' - get email data in plain ascii format */
- /* buf - SMTP transmit buffer */
- /* buflen - length of this buffer (500-1400 bytes - depends on MSS) */
- /* pvar - pointer to local storage buffer used for repeated loops */
- /* This is a U32 variable - size is 4 bytes. Value is: */
- /* - on 1st call = 0 */
- /* - 2nd call = as set by this function on first call */
- U32 len = 0;
-
- switch (code) {
- case 0:
- /* Enter Username for SMTP Server authentication. */
- len = str_copy (buf, SMTP_USER);
- break;
-
- case 1:
- /* Enter Password for SMTP Server authentication. */
- len = str_copy (buf, SMTP_PASSWORD);
- break;
-
- case 2:
- /* Enter email address of the sender. */
- len = str_copy (buf, MAIL_FROM);
- break;
-
- case 3:
- /* Enter email address of the recipient. */
- len = str_copy (buf, RCPT_TO);
- break;
-
- case 4:
- /* Enter email subject. */
- len = str_copy (buf, MAIL_SUBJECT);
- break;
-
- case 5:
- /* Enter email data. */
- switch (MYBUF(pvar)->id) {
- case 0:
- /* First call, enter an email header text. */
- len = sprintf ((char *)buf, MSG_HEADER);
- MYBUF(pvar)->id = 1;
- MYBUF(pvar)->idx = 1;
- goto rep;
-
- case 1:
- /* Add email message body. */
- /* Let's use as much of the buffer as possible. */
- /* This will produce less packets and speedup the transfer. */
- len = sprintf ((char *)(buf), "%d. ",MYBUF(pvar)->idx);
-
- len += str_copy (buf+len, "用户可以在这里添加数据\\n");
- if (++MYBUF(pvar)->idx > 5)
- {
- MYBUF(pvar)->id = 2;
- }
- /* Request a repeated call, bit 15 is a repeat flag. */
- rep: len |= 0x8000;
- break;
-
- case 2:
- /* Last one, add a footer text to this email. */
- len = str_copy (buf, MSG_FOOTER);
- break;
- }
- }
- return ((U16)len);
- }
-
-
- /*--------------------------- smtp_accept_auth ------------------------------*/
-
- BOOL smtp_accept_auth (U8 *srv_ip) {
- /* SMTP server with address 'srv_ip' is asking for user authentication. */
- /* Return value: __TRUE = use the authentication */
- /* __FALSE = do not use the authentication */
-
- /* Accept the authentication. */
- return (__TRUE);
- }
-
- /*----------------------------------------------------------------------------
- * end of file
- *---------------------------------------------------------------------------*/
复制代码
34.6.2 STM32F429开发板实验
配套例子:
V6-1048_RL-TCPnet实验_SMTP邮件发送(RTX)
实验目的:
1. 学习RL-TCPnet的SMTP邮件发送。
实验内容:
1. 用户务必将网线接到能够联网的路由器或者交换机上面测试,因为DNS域名解析和SMTP发送邮件需要连接网络才行。
2. 由于126,163和QQ邮箱的通信都做了加密,所以RL-TCPnet的SMTP无法进行邮箱通信。当前测试新浪邮箱还可以使用,所以大家使用前务必要注册新浪邮箱。根据注册的新浪邮箱,SMTP_uif.c文件开头代码中的发送邮箱、接收邮箱、用户名、用户密码和邮件主题是需要用户填写的。
#define MAIL_FROM "baiyongbin_2006@sina.cn" 发送邮箱
#define RCPT_TO "baiyongbin_2006@sina.cn" 接收邮箱
#define SMTP_USER "baiyongbin_2006@sina.cn" 发送邮箱的用户名
#define SMTP_PASSWORD "xxxxxxxxx" 发送邮箱的密码
#define MAIL_SUBJECT "安富莱电子" 邮件主题
3. 邮件发送的具体操作步骤,务必看本章节配套教程的使用说明。
4. 我们这里实现邮件的自收发,也就是开发板的SMTP Client登录新浪邮箱,然后自己给自己发邮件。发送后,大家可以在电脑端或者手机端登录邮箱,并查看邮箱的内容。
5. 按下按键K2将启动邮件发送。
实验操作:
详见本章节34.5小节。
配置向导文件设置(Net_Config.c):
详见本章节34.3小节。
调试文件设置(Net_Debug.c):
详见本章节34.4小节。
RTX配置:
RTX配置向导详情如下:
Task Configuration
(1)Number of concurrent running tasks
允许创建6个任务,实际创建了如下5个任务:
AppTaskUserIF任务 :按键消息处理。
AppTaskLED任务 :LED闪烁。
AppTaskMsgPro任务 :按键检测。
AppTaskTCPMain任务:RL-TCPnet测试任务。
AppTaskStart任务 :启动任务,也是最高优先级任务,这里实现RL-TCPnet的时间基准更新。
(2)Number of tasks with user-provided stack
创建的5个任务都是采用自定义堆栈方式。
(3)Run in privileged mode
设置任务运行在非特权级模式。
RTX任务调试信息:
程序设计:
任务栈大小分配:
staticuint64_t AppTaskUserIFStk[1024/8]; /* 任务栈 */
staticuint64_t AppTaskLEDStk[1024/8]; /* 任务栈 */
staticuint64_t AppTaskMsgProStk[1024/8]; /* 任务栈 */
staticuint64_t AppTaskTCPMainStk[2048/8]; /* 任务栈 */
staticuint64_t AppTaskStartStk[1024/8]; /* 任务栈 */
将任务栈定义成uint64_t类型可以保证任务栈是8字节对齐的,8字节对齐的含义就是数组的首地址对8求余等于0。如果不做8字节对齐的话,部分C语言库函数、浮点运算和uint64_t类型数据运算会出问题。
系统栈大小分配:
RTX初始化:
- /*
- *********************************************************************************************************
- * 函 数 名: main
- * 功能说明: 标准c程序入口。
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- int main (void)
- {
- /* 初始化外设 */
- bsp_Init();
-
- /* 创建启动任务 */
- os_sys_init_user (AppTaskStart, /* 任务函数 */
- 5, /* 任务优先级 */
- &AppTaskStartStk, /* 任务栈 */
- sizeof(AppTaskStartStk)); /* 任务栈大小,单位字节数 */
- while(1);
- }
复制代码 硬件外设初始化
硬件外设的初始化是在 bsp.c 文件实现:
- /*
- *********************************************************************************************************
- * 函 数 名: bsp_Init
- * 功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void bsp_Init(void)
- {
- /*
- 由于ST固件库的启动文件已经执行了CPU系统时钟的初始化,所以不必再次重复配置系统时钟。
- 启动文件配置了CPU主时钟频率、内部Flash访问速度和可选的外部SRAM FSMC初始化。
-
- 系统时钟缺省配置为168MHz,如果需要更改,可以修改 system_stm32f4xx.c 文件
- */
- /* 优先级分组设置为4,可配置0-15级抢占式优先级,0级子优先级,即不存在子优先级。*/
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
-
- SystemCoreClockUpdate(); /* 根据PLL配置更新系统时钟频率变量 SystemCoreClock */
-
- bsp_InitDWT(); /* 初始化DWT */
- bsp_InitUart(); /* 初始化串口 */
- bsp_InitKey(); /* 初始化按键变量(必须在 bsp_InitTimer() 之前调用) */
-
- bsp_InitExtIO(); /* FMC总线上扩展了32位输出IO, 操作LED等外设必须初始化 */
- bsp_InitLed(); /* 初始LED指示灯端口 */
- }
复制代码 RTX任务创建:
- /*
- *********************************************************************************************************
- * 函 数 名: AppTaskCreate
- * 功能说明: 创建应用任务
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void AppTaskCreate (void)
- {
- HandleTaskUserIF = os_tsk_create_user(AppTaskUserIF, /* 任务函数 */
- 1, /* 任务优先级 */
- &AppTaskUserIFStk, /* 任务栈 */
- sizeof(AppTaskUserIFStk)); /* 任务栈大小,单位字节数 */
-
- HandleTaskLED = os_tsk_create_user(AppTaskLED, /* 任务函数 */
- 2, /* 任务优先级 */
- &AppTaskLEDStk, /* 任务栈 */
- sizeof(AppTaskLEDStk)); /* 任务栈大小,单位字节数 */
-
- HandleTaskMsgPro = os_tsk_create_user(AppTaskMsgPro, /* 任务函数 */
- 3, /* 任务优先级 */
- &AppTaskMsgProStk, /* 任务栈 */
- sizeof(AppTaskMsgProStk)); /* 任务栈大小,单位字节数 */
-
- HandleTaskTCPMain = os_tsk_create_user(AppTaskTCPMain, /* 任务函数 */
- 4, /* 任务优先级 */
- &AppTaskTCPMainStk, /* 任务栈 */
- sizeof(AppTaskTCPMainStk)); /* 任务栈大小,单位字节数 */
- }
复制代码 五个RTX任务的实现:
RL-TCPnet功能测试
这里专门创建了一个app_tcpnet_lib.c文件用于RL-TCPnet功能的测试,此文件主要实现网络主函数main_TcpNet的调用和邮件的发送。
- #include "includes.h"
-
-
-
- /*
- *********************************************************************************************************
- * 用于本文件的调试
- *********************************************************************************************************
- */
- #if 1
- #define printf_debug printf
- #else
- #define printf_debug(...)
- #endif
-
-
- /*
- *********************************************************************************************************
- * 变量
- *********************************************************************************************************
- */
- char const *hosts[4] =
- {
- "smtp.sina.cn",
- "smtp.126.com",
- "smtp.qq.com",
- "smtp.163.com",
- };
-
- U8 srv_ip[4];
- U8 dns_flag = 0;
-
-
- /*
- *********************************************************************************************************
- * 函 数 名: dns_cbfunc
- * 功能说明: 函数get_host_by_name的回调函数。
- * 形 参: event 事件类型
- * ip 如果事件类型是DNS_EVT_SUCCESS,此指针变量指向返回的IP地址缓冲区。
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void dns_cbfunc (unsigned char event, unsigned char *ip)
- {
- switch (event)
- {
- /* 成功解析地址 */
- case DNS_EVT_SUCCESS:
- printf_debug("DNS解析出邮箱服务器IP地址 : %d.%d.%d.%d\\n",ip[0],ip[1],ip[2],ip[3]);
-
- srv_ip[0] = ip[0];
- srv_ip[1] = ip[1];
- srv_ip[2] = ip[2];
- srv_ip[3] = ip[3];
- dns_flag = 1;
- break;
-
- /* DNS记录数据库中不存在此地址 */
- case DNS_EVT_NONAME:
- printf_debug("Host Name does not exist in DNS record database.\\n");
- break;
-
- /* 允许的DNS解析重试次数已经用完,仍无法解析,时间超时 */
- case DNS_EVT_TIMEOUT:
- printf_debug("DNS Resolver Timeout expired, Host Address not resolved.\\n");
- break;
-
- /* DNS协议错误,收到无效或者被损坏的回复 */
- case DNS_EVT_ERROR:
- printf_debug("DNS Resolver Protocol Error, Host Address not resolved.\\n");
- return;
- }
- }
-
- /*
- *********************************************************************************************************
- * 函 数 名: smtp_cback
- * 功能说明: 函数smtp_connect的回调函数。
- * 形 参: event 事件类型
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void smtp_cback(U8 event)
- {
- switch (event)
- {
- /* 邮件发送成功 */
- case SMTP_EVT_SUCCESS:
- printf_debug ("Email successfully sent\\r\\n");
- break;
-
- /* 超时,邮件未发送成功 */
- case SMTP_EVT_TIMEOUT:
- printf_debug ("Mail Server timeout.\\r\\n");
- break;
-
- /* 邮件发送失败 */
- case SMTP_EVT_ERROR:
- printf_debug ("Error sending email.\\r\\n");
- break;
- }
- }
-
- /*
- *********************************************************************************************************
- * 函 数 名: TCPnetTest
- * 功能说明: TCPent测试函数。
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void TCPnetTest(void)
- {
- OS_RESULT xResult;
-
- while (1)
- {
- os_evt_wait_or(0x0003, 0xFFFF);
-
- /* 如果接受到按键K2按下的消息,解析smtp.sina.cn的IP地址 */
- xResult = os_evt_get ();
- if(xResult == KEY2_BIT1)
- {
- get_host_by_name ((U8 *)hosts[0], dns_cbfunc);
- }
-
- /* 解析出IP地址后,发送邮件 */
- if(dns_flag == 1)
- {
- smtp_connect ((U8 *)&srv_ip, 25, smtp_cback);
- dns_flag = 0;
- }
-
- while (main_TcpNet() == __TRUE);
- }
- }
复制代码 SMTP用户接口文件的实现
KEIL官网有提供SMTP的接口文件,名为SMTP_uif.c文件。我们就是在这个文件上修改。具体修改后的代码如下:
- #include <Net_Config.h>
- #include <string.h>
- #include <stdio.h>
-
- /* Email definitions */
- #define MAIL_FROM "baiyongbin_2006@sina.cn"
- #define RCPT_TO "baiyongbin_2006@sina.cn"
- #define SMTP_USER "baiyongbin_2006@sina.cn"
- #define SMTP_PASSWORD "xxxxxxxxx"
- #define MAIL_SUBJECT "安富莱电子"
-
-
- #define MSG_HEADER \\
- "Hello,大家好!\\r\\n\\r\\n" \\
- "这是一封来自STM32-V6开发板发出的邮件,运行的RL-TCPnet小型协议栈\\r\\n" \\
- "在这里祝福大家身体健康,万事如意\\r\\n\\r\\n" \\
- "--------------------------------------------------------------\\r\\n"
-
- #define MSG_FOOTER \\
- "--------------------------------------------------------------\\r\\n"\\
- "此致敬礼\\r\\n\\r\\n" \\
- "安富莱电子"
-
-
- /* My structure of SMTP U32 storage variable. This variable is private and */
- /* is not altered by SMTP Client. It is only set to zero when smtp_cbfunc() */
- /* is called for the first time. */
- typedef struct {
- U8 id;
- U16 idx;
- } MY_BUF;
- #define MYBUF(p) ((MY_BUF *)p)
-
- /* Net_Config.c */
- extern struct sys_cfg sys_config;
- #define lhost_name sys_config.HostName
-
- /*----------------------------------------------------------------------------
- * SMTP CallBack Functions
- *---------------------------------------------------------------------------*/
-
- /*--------------------------- smtp_cbfunc -----------------------------------*/
-
- U16 smtp_cbfunc (U8 code, U8 *buf, U16 buflen, U32 *pvar) {
- /* This function is called by the SMTP client to get email parameters and */
- /* data. It returns the number of bytes written to the output buffer. */
- /* Hi-bit of return value (len is or-ed with 0x8000) is a repeat flag the */
- /* SMTP client. If this bit is set to 1, the system will call this func */
- /* again with parameter 'pvar' pointing to a 4-byte buffer. This buffer */
- /* can be used for storing different status variables for this function. */
- /* It is set to 0 by SMTP client on first call and is not altered by SMTP */
- /* client for repeated calls. This function should NEVER write more than */
- /* 'buflen' bytes to the buffer. */
- /* Parameters: */
- /* code - function code with following values: */
- /* 0 - Username: - for SMTP authentication if requested */
- /* 1 - Password: - for SMTP authentication if requested */
- /* 2 - 'From : ' - get email address of the sender */
- /* 3 - 'To : ' - get email address of recipient */
- /* 4 - 'Subject: ' - get subject of email */
- /* 5 - 'Data : ' - get email data in plain ascii format */
- /* buf - SMTP transmit buffer */
- /* buflen - length of this buffer (500-1400 bytes - depends on MSS) */
- /* pvar - pointer to local storage buffer used for repeated loops */
- /* This is a U32 variable - size is 4 bytes. Value is: */
- /* - on 1st call = 0 */
- /* - 2nd call = as set by this function on first call */
- U32 len = 0;
-
- switch (code) {
- case 0:
- /* Enter Username for SMTP Server authentication. */
- len = str_copy (buf, SMTP_USER);
- break;
-
- case 1:
- /* Enter Password for SMTP Server authentication. */
- len = str_copy (buf, SMTP_PASSWORD);
- break;
-
- case 2:
- /* Enter email address of the sender. */
- len = str_copy (buf, MAIL_FROM);
- break;
-
- case 3:
- /* Enter email address of the recipient. */
- len = str_copy (buf, RCPT_TO);
- break;
-
- case 4:
- /* Enter email subject. */
- len = str_copy (buf, MAIL_SUBJECT);
- break;
-
- case 5:
- /* Enter email data. */
- switch (MYBUF(pvar)->id) {
- case 0:
- /* First call, enter an email header text. */
- len = sprintf ((char *)buf, MSG_HEADER);
- MYBUF(pvar)->id = 1;
- MYBUF(pvar)->idx = 1;
- goto rep;
-
- case 1:
- /* Add email message body. */
- /* Let's use as much of the buffer as possible. */
- /* This will produce less packets and speedup the transfer. */
- len = sprintf ((char *)(buf), "%d. ",MYBUF(pvar)->idx);
-
- len += str_copy (buf+len, "用户可以在这里添加数据\\n");
- if (++MYBUF(pvar)->idx > 5)
- {
- MYBUF(pvar)->id = 2;
- }
- /* Request a repeated call, bit 15 is a repeat flag. */
- rep: len |= 0x8000;
- break;
-
- case 2:
- /* Last one, add a footer text to this email. */
- len = str_copy (buf, MSG_FOOTER);
- break;
- }
- }
- return ((U16)len);
- }
-
-
- /*--------------------------- smtp_accept_auth ------------------------------*/
-
- BOOL smtp_accept_auth (U8 *srv_ip) {
- /* SMTP server with address 'srv_ip' is asking for user authentication. */
- /* Return value: __TRUE = use the authentication */
- /* __FALSE = do not use the authentication */
-
- /* Accept the authentication. */
- return (__TRUE);
- }
-
- /*----------------------------------------------------------------------------
- * end of file
- *---------------------------------------------------------------------------*/
复制代码 |
|