【AT-START-F437测评】THREADX + FILEX
THREADX 作为世界第一梯队的RTOS,如今已归微软旗下,拥有者诸多安全认证:
航空领域 – ED-12B, DO-178B, ED-109, ED-278
医学领域 – IEC-60601, IEC-62304, ISO-14971, FDA 510(k)
工业领域– IEC-61508, and others
运输领域 – CENELEC EN50128, 49CFR236, IEC-61508
该RTOS虽然不是完全免版税,但也有这个趋势,至少在STM32、NXP、瑞萨芯片上已经可以免费使用了。
FILEX做为THREADX的配套组件之一,同样拥有如上安全认证。
这几天拿AT32F437评估板测试THREADX和FILEX,记录一下使用情况。
=========================================================
首先是THREADX,不得不说微软的移植工作做的非常细致,各种常见内核都已做好适配,使用时只需要添加官方移植好的M4文件就可以。
如下图所示部分选择port/cortex_m4下的文件即可。
其中 tx_initialize_low_level.S 文件内的时钟需要配置一下:
- SYSTEM_CLOCK = 288000000
- SYSTICK_CYCLES = ((SYSTEM_CLOCK / 500) -1)
AT32F437主频288MHz,上面配置系统TICK为2ms。
THREADX这么一点配置基本就可以跑起来了。
==========================================================
FILEX需要移植一个文件,主要用来实现USB DISK的读写操作,USB 读写参考AT32官方例程即可。
移植内容如下:
- #include <string.h>
- #include "usbh_user.h"
- #include "bsp.h"
- #include "tx_api.h"
- #include "fx_api.h"
- #include "usb_core.h"
- #include "usbh_msc_class.h"
- #include "common.h"
- /* Handle for USB Host */
- extern otg_core_type otg_core_struct;
- UINT _fx_partition_offset_calculate(void *partition_sector, UINT partition, ULONG *partition_start, ULONG *partition_size);
- static uint8_t sector_read(void *buff, uint32_t sec_site, uint32_t amount);
- static uint8_t sector_write(void *buff, uint32_t sec_site, uint32_t amount);
- /**
- * [url=home.php?mod=space&uid=247401]@brief[/url] This function is the entry point to the STM32 SDIO disk driver. */
- /* It relies on the STM32 peripheral library from ST.
- * @param None
- * @retval None
- */
- VOID fx_udisk_driver(FX_MEDIA *media_ptr)
- {
- int32_t status;
- ULONG partition_start;
- ULONG partition_size;
- /* before performing any operation, check the status of the SDMMC */
- if(usbh_msc_is_ready(&otg_core_struct.host, 0) != MSC_OK)
- {
- media_ptr->fx_media_driver_status = FX_IO_ERROR;
- return;
- }
- /* Process the driver request specified in the media control block. */
- switch (media_ptr->fx_media_driver_request)
- {
- case FX_DRIVER_INIT:
- {
- if(usbh_msc_is_ready(&otg_core_struct.host, 0) == MSC_OK)
- {
- media_ptr->fx_media_driver_status = FX_SUCCESS;
- }
- else
- {
- media_ptr->fx_media_driver_status = FX_IO_ERROR;
- }
- break;
- }
- case FX_DRIVER_UNINIT:
- {
- /* Successful driver request. */
- media_ptr->fx_media_driver_status = FX_SUCCESS;
- break;
- }
- case FX_DRIVER_READ:
- {
- status = sector_read(
- media_ptr->fx_media_driver_buffer,
- media_ptr->fx_media_driver_logical_sector + media_ptr->fx_media_hidden_sectors,
- media_ptr->fx_media_driver_sectors
- );
- if (status == 0)
- media_ptr->fx_media_driver_status = FX_SUCCESS;
- else
- media_ptr->fx_media_driver_status = FX_IO_ERROR;
- break;
- }
- case FX_DRIVER_WRITE:
- {
- status = sector_write(
- media_ptr->fx_media_driver_buffer,
- media_ptr->fx_media_driver_logical_sector + media_ptr->fx_media_hidden_sectors,
- media_ptr->fx_media_driver_sectors
- );
- if (status == 0)
- media_ptr->fx_media_driver_status = FX_SUCCESS;
- else
- media_ptr->fx_media_driver_status = FX_IO_ERROR;
- break;
- }
- case FX_DRIVER_FLUSH:
- {
- /* Return driver success. */
- media_ptr->fx_media_driver_status = FX_SUCCESS;
- break;
- }
- case FX_DRIVER_ABORT:
- {
- /* Return driver success. */
- media_ptr->fx_media_driver_status = FX_SUCCESS;
- break;
- }
- case FX_DRIVER_BOOT_READ:
- {
- status = sector_read(
- media_ptr->fx_media_driver_buffer,
- 0,
- 1);
- if (status == 0)
- {
- media_ptr->fx_media_driver_status = FX_SUCCESS;
- }
- else
- {
- media_ptr->fx_media_driver_status = FX_IO_ERROR;
- break;
- }
- /* Check if the sector 0 is the actual boot sector, otherwise calculate the offset into it.
- Please note that this should belong to higher level of MW to do this check and it is here
- as a temporary work solution */
- partition_start = 0;
- status = _fx_partition_offset_calculate(media_ptr->fx_media_driver_buffer, 0,
- &partition_start, &partition_size);
- /* Check partition read error. */
- if (status)
- {
- /* Unsuccessful driver request. */
- media_ptr->fx_media_driver_status = FX_IO_ERROR;
- return;
- }
- /* Now determine if there is a partition... */
- if (partition_start)
- {
- /* Yes, now lets read the actual boot record. */
- status = sector_read(
- media_ptr->fx_media_driver_buffer,
- partition_start,
- 1);
- /* Check status of SDIO Read. */
- if (status != 0)
- {
- /* Unsuccessful driver request. */
- media_ptr->fx_media_driver_status = FX_IO_ERROR;
- return;
- }
- }
- /* Successful driver request. */
- media_ptr->fx_media_driver_status = FX_SUCCESS;
- break;
- }
- case FX_DRIVER_BOOT_WRITE:
- {
- status = sector_write(
- media_ptr->fx_media_driver_buffer,
- 0,
- 1
- );
- if (status == 0)
- media_ptr->fx_media_driver_status = FX_SUCCESS;
- else
- media_ptr->fx_media_driver_status = FX_IO_ERROR;
- break;
- }
- default:
- {
- media_ptr->fx_media_driver_status = FX_IO_ERROR;
- break;
- }
- }
- }
- uint8_t sector_read(void *buff, uint32_t sec_site, uint32_t count)
- {
- usb_sts_type status;
-
- status = usbh_msc_read(&otg_core_struct.host, sec_site, count, buff, 0);
-
- if(status == USB_OK)
- return 0;
-
- return 1;
- }
- uint8_t sector_write(void *buff, uint32_t sec_site, uint32_t count)
- {
- usb_sts_type status;
- status = usbh_msc_write(&otg_core_struct.host, sec_site, count, (uint8_t *)buff, 0);
-
- if(status == USB_OK)
- return 0;
-
- return 1;
- }
应用测试代码比较多,不贴在这里了,感兴趣的小伙伴可以从贴尾链接下载代码测试。
下面是测试结果:
烧录程序运行后,插入U盘开始U盘操作。串口显示内容如下:
U盘操作完后接入电脑,多出两个文件是本测试程序创建的:
一个CSV表格,一个PDF文件。
表格文件内容:
PDF文件比较长,截取一部分如下:
这就完了,微软出品的软件确实比较容易上手。系统默认配置,底层移植量非常少就能跑起来。后面可以细致研究OS和文件系统的各个API用法了。
代码托管在GITEE:
https://toscode.gitee.com/aple_sun/at32f437-start-threadx
|