stm32移植rtthread_stm32加密协处理器[通俗易懂]

stm32移植rtthread_stm32加密协处理器[通俗易懂]文章目录写在前面源码下载准备工作开始搬运分析总结写在前面注意本文以分析为主,主要讲解实现过程和注意点,并非从零开始标题虽然是移植,但是完全参考官方提供的一份例程,即Azure_RTOS_6.0_

写在前面

注意本文以分析为主,主要讲解实现过程和注意点,并非从零开始

标题虽然是移植,但是完全参考官方提供的一份例程,即Azure_RTOS_6.0_STM32F746G-DISCO_STM32CubeIDE_Samples_2020_05_29.zip,其主控是STM32F746G,我用的是STM32F407,不过差别不大。
目前已经能够成功ping通网络,但是ping不了大包,测试出来大概包长度只能到1470字节左右,此仅为个人笔记,所以可能存在不妥或者理解错误的地方,后续我会不断完善并更正此文章。

源码下载

先下载例程和next(非netxduo,不过估计没有什么差别)的源码,下载链接参考前一篇文章的链接,并且MDK工程也是基于前一篇文章移植过后作为模板,可在前一篇文章文末链接获得。

准备工作

移植前最好先使用一个裸机程序测试下你的网卡能否正常工作,我的phy是LAN8720A,用的STM32F407自带的MAC控制器,这个过程很简单,只要寄存器地址设置正确,复位引脚的状态正确,就基本上没什么问题了,如果接上网线后能够看到接口的灯闪烁就可以继续后面的步骤了。
有一个注意点就是如果配置phy芯片模式为自动协商,在单片机上电时如果没接网线,那么即使后面再接上,网口灯也不会闪烁,这是因为HAL库网络初始化的时候如果没检测到link up则会超时退出,后面配置phy模式为自动协商的操作也就没有执行,解决方案就是在初始化的后面添加上这个配置:

	/* init phy reset pin */
	eth_phy_init_reset_gpio();
	/* reset phy */
	eth_phy_hard_reset();
	
	HAL_ETH_Init(&heth);

	/*开启自动协商*/
	HAL_ETH_WritePHYRegister(&heth, PHY_BCR, PHY_AUTONEGOTIATION);
	
	PRINTF("phy id:%08x\r\n",eth_read_phy_id());

开始搬运

  • 添加netx的源码到工程中
    需要netx\common文件夹的内容
    需要netx\netx\ports\cortex_m4文件夹的内容
    netx\addons文件夹暂时没用,可以不添加

编译后如果报错__builtin_bswap16未定义,需要手动实现,也可直接拷贝例程nxd目录nx_port.h文件内的实现,这个是用于大小端交换的:

netx\ports\cortex_m4\gnu\inc\nx_port.h

/* Define macros that swap the endian for little endian ports. */
#ifdef NX_LITTLE_ENDIAN

/* for __builtin_bswap16 */
#include <stdint.h>
typedef uint16_t __u16;
#define __builtin_bswap16(x) __constant_swab16(x)
#define __constant_swab16(x) ((__u16)( \ (((__u16)(x) & (__u16)0x00ffU) << 8) | \ (((__u16)(x) & (__u16)0xff00U) >> 8)))

#define NX_CHANGE_ULONG_ENDIAN(arg) (arg) = __builtin_bswap32(arg)
#define NX_CHANGE_USHORT_ENDIAN(arg) (arg) = __builtin_bswap16(arg)
  • 拷贝例程中nxd目录nx_port.h内的配置宏
netx\ports\cortex_m4\gnu\inc\nx_port.h

/*失能错误检查*/
#define NX_DISABLE_ERROR_CHECKING
/*发送ACK之前接收TCP包的数量*/
#define NX_TCP_ACK_EVERY_N_PACKETS 2
/*失能接收包的大小检查*/
#define NX_DISABLE_RX_SIZE_CHECKING
/*失能ARP信息收集*/
#define NX_DISABLE_ARP_INFO
/*失能IP信息收集*/
#define NX_DISABLE_IP_INFO
/*失能ICMP信息收集*/
#define NX_DISABLE_ICMP_INFO
/*失能IGMPv2支持*/
#define NX_DISABLE_IGMPV2
/*失能IGMP信息收集*/
#define NX_DISABLE_IGMP_INFO
/*失能packet pool信息收集*/
#define NX_DISABLE_PACKET_INFO
/*失能RARP信息收集*/
#define NX_DISABLE_RARP_INFO
/*失能TCP信息收集*/
#define NX_DISABLE_TCP_INFO
/*失能UDP信息收集*/
#define NX_DISABLE_UDP_INFO
/*失能更多的回调钩子,BSD封装层使用,默认失能*/
#define NX_DISABLE_EXTENDED_NOTIFY_SUPPORT
  • 拷贝例程中nxd目录nx_driver_stm32f746.c和nx_driver_stm32f746.h文件到工程中
  • 编译工程,根据报错信息,去掉一些无用的内容
  • 添加测试程序
    将例程中sample_netx_duo_ping目录内sample_netx_duo_ping.c文件的内容添加到tx_application_define函数中。

分析

几个重要的数据结构:

// 用来管理数据包内存池
NX_PACKET_POOL
// IP实例
NX_IP
// 接口
NX_INTERFACE
// 数据包
NX_PACKET

几个重要的函数:

// 创建数据包内存池
nx_packet_pool_create
// 创建一个IP实例
nx_ip_create
// 留给用户的一个回调函数,用来实现底层的移植
VOID nx_driver_entry(NX_IP_DRIVER *driver_req_ptr)

大致流程如下,我们主要的工作就是要根据各种命令实现底层的这一部分驱动代码:
stm32移植rtthread_stm32加密协处理器[通俗易懂]

VOID nx_driver_entry(NX_IP_DRIVER *driver_req_ptr)
{ 
   
	/* Default to successful return. */
	driver_req_ptr -> nx_ip_driver_status =  NX_SUCCESS;
	
	/* Process according to the driver request type in the IP control block. */
	switch (driver_req_ptr -> nx_ip_driver_command)
	{ 
   
		case NX_LINK_INTERFACE_ATTACH:
			{ 
   
				/* Process link interface attach requests. */
				_nx_driver_interface_attach(driver_req_ptr);
				break;
			}
    case NX_LINK_INITIALIZE:
			{ 
   
				/* Process link initialize requests. */
				_nx_driver_initialize(driver_req_ptr);
				break;
			}
    case NX_LINK_ENABLE:
			{ 
   
				/* Process link enable requests. */
				_nx_driver_enable(driver_req_ptr);
				break;
			}
    case NX_LINK_DISABLE:
			{ 
   
				/* Process link disable requests. */
				_nx_driver_disable(driver_req_ptr);
				break;
			}
    case NX_LINK_ARP_SEND:
    case NX_LINK_ARP_RESPONSE_SEND:
    case NX_LINK_PACKET_BROADCAST:
    case NX_LINK_RARP_SEND:
    case NX_LINK_PACKET_SEND:
			{ 
   
				/* Process packet send requests. */
				_nx_driver_packet_send(driver_req_ptr);
				break;
			}
    case NX_LINK_MULTICAST_JOIN:
			{ 
   
				/* Process multicast join requests. */
				_nx_driver_multicast_join(driver_req_ptr);
				break;
			}
    case NX_LINK_MULTICAST_LEAVE:
			{ 
   
				/* Process multicast leave requests. */
				_nx_driver_multicast_leave(driver_req_ptr);
				break;
			}
    case NX_LINK_GET_STATUS:
			{ 
   
				/* Process get status requests. */
				_nx_driver_get_status(driver_req_ptr);
				break;
			}
#ifdef NX_DRIVER_ENABLE_DEFERRED
    case NX_LINK_DEFERRED_PROCESSING:
			{ 
   
				/* Process driver deferred requests. */

				/* Process a device driver function on behave of the IP thread. */
				_nx_driver_deferred_processing(driver_req_ptr);

				break;
			}
#endif
    case NX_LINK_GET_SPEED:
			{ 
   
				break;
			}
    case NX_LINK_GET_DUPLEX_TYPE:
			{ 
   
				break;
			}
    case NX_LINK_GET_ERROR_COUNT:
			{ 
   
				break;
			}
    case NX_LINK_GET_RX_COUNT:
			{ 
   
				break;
			}
    case NX_LINK_GET_TX_COUNT:
			{ 
   
				break;
			}
    case NX_LINK_GET_ALLOC_ERRORS:
			{ 
   
				break;
			}
    case NX_LINK_UNINITIALIZE:
			{ 
   
				break;
			}
    default:
			/* Invalid driver request. */

			/* Return the unhandled command status. */
			driver_req_ptr -> nx_ip_driver_status =  NX_UNHANDLED_COMMAND;

			/* Default to successful return. */
			driver_req_ptr -> nx_ip_driver_status =  NX_DRIVER_ERROR;
	}
}

贴张效果图:
stm32移植rtthread_stm32加密协处理器[通俗易懂]
这是一个单实例例程,也就是单网口的情况,如果是多网口的话可以参考源码src目录里面的nx_ram_network_driver.c文件,这是官方提供的一个给用户参考的移植文件

总结

总体来说,个人觉得官方的这份例程不太容易理解,就NX_INTERFACE数据结构来说,其是在nx_ip_create函数执行时填充一部分,用户移植时填充一部分,还有一部分是netx运行时反馈信息;然后在底层的实现中,还需要用户来操作这些数据结构的内容,移植非常不便,全程几乎没使用HAL库的API,但是有些代码和一些API的内容又极为相似,要是ST官方能够出一份移植文档就好了。
本文的源码工程可在我的代码仓库获取,已对移植部分代码大部分内容进行了注释。

参考文档:
LAN8720A数据手册
以太网帧结构
官方用户指导文档

欢迎扫码关注我的微信公众号
漫长当下

今天的文章stm32移植rtthread_stm32加密协处理器[通俗易懂]分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/86249.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注