OneOS 是中国移动针对物联网领域推出的轻量级操作系统,具有可裁剪、 跨平台、低功耗、高安全等特点,支持 ARM Cortex-A 和 Cortex-M、MIPS、RISC-V 等主流芯片架构,兼容 POSIX、CMSIS 等标准接口,支持 Javascript、MicroPython 等高级语言开发模式,提供图形化开发工具,能够有效提升开发效率、降低开发 成本,帮助用户快速开发稳定可靠、安全易用的物联网应用。
目前,OneOS 联合 CODESYS推出基于 OneOS 的PLC 编程规范开发套件,融合OneOS 特色组件,支持一站式配置和裁剪,支持 EtherCAT、CANopen 等多种工业现场总线协议栈,支持多种运动控制算法,支持基于优先级的任务调度,搭建了嵌入式设备与工业控制的桥梁,为工业打开了更加庞大丰富的蓝海市场。下面让我们一起看看OneOS+CODESYS是如何工作的吧~
CODESYS软件分三层架构,可用下图来表示,对于每一层的详细介绍,感兴趣的朋友可以上CODESYS官网进行查看。
OneOS接管的是CODESYS三层架构中的设备硬件层;OneOS+CODESYS 实现了IEC61131-3多种标准编程语言的支持,满足用户高实时性、高可靠以及高安全的运行要求。
OneOS+CODESYS首发来咯。准备好了吗?各位!Let's go!
下面来一张,本期板卡实例颜值担当OK1061-S开发板的板卡全貌:
默认工程程序代码是一个通用示例代码,并非完全为CODESYS所定制工程,需要我们用户在通用工程的基础上做一些适配调整;
首先需要通过OneOS BSP模板创建一个基础工程,方法如下:
进入\OneOS-V2.2.0\projects目录下鼠标右键打开OneOS-Cube
在创建完基础工程过后,进入上面新建的基础工程目录:imxrt1061-forlinx,并通过menuconfig进行配置一些外设以及参数配置:
如果PLC代码运行RAM区的Cache被使能,会导致PLC程序反复下载时宕机;所以我们需要手动关闭该RAM对应的Cache。
//CoDeSysAutoLoad.c
/* Code/Data Area Config */
#define CODESYS_CODE_BASE_ADDR 0x20200000 /* Code area base address */
#define CODESYS_CODE_SIZE 0x40000 /* Code area size(>40k) range 0x10000 0xA0000,default 0xA0000 */
#define CODESYS_DATA_BASE_ADDR 0x20240000 /* Data area base address */
#define CODESYS_DATA_SIZE 0x20000 /* Data area size(>30k) , range 0x7800 0xA0000,default 0xA0000 */
//board.c line 110
/* Region 7 setting: Memory with Normal type, not shareable, outer/inner write back */
MPU->RBAR = ARM_MPU_RBAR(7, 0x20200000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_512KB);
OneOS在适配CODESYS Runtime时底层存储时,运用的fal接口;fal分区可通过menuconfig进行修改,用户需要查看具体定义可以在oneos_config.h查看到具体定义。
#define CODESYS_FAL_NAME_CODE "user"
#define CODESYS_FAL_NAME_FILE "CoDeSysApp"
用户分区适用的名称需要和fal_cfg.c的系统分区表的分区名称所对应,否则会在运行过程中触发找不到对应存储区的断言;板卡默认分区表如下:
//fal_cfg.c
static fal_part_info_t fal_part_info[] =
{
/* part, flash, addr, size, lock */
{ IMXRT_FLASH_APP_NAME, "onchip_flash", IMXRT_FLASH_APP_START, IMXRT_FLASH_APP_SIZE, FAL_PART_INFO_FLAGS_LOCKED},
{ IMXRT_FLASH_USER_NAME, "onchip_flash", IMXRT_FLASH_USER_START, IMXRT_FLASH_USER_SIZE, FAL_PART_INFO_FLAGS_UNLOCKED},
{IMXRT_FLASH_CODESYS_NAME, "onchip_flash", IMXRT_FLASH_CODESYS_START, IMXRT_FLASH_CODESYS_SIZE, FAL_PART_INFO_FLAGS_UNLOCKED},
#ifdef BSP_USING_I2C_AT24CXX
{ "at24", "at24cxx_eeprom", 0, BSP_AT24CXX_SIZE, FAL_PART_INFO_FLAGS_UNLOCKED},
#endif
};
各分区的默认参数信息在board_memory.h 中进行了定义,用户一般不需要修改;
//board_memory.h
#define IMXRT_FLASH_APP_NAME "app"
#define IMXRT_FLASH_APP_START (0)
#define IMXRT_FLASH_APP_SIZE (1 * 1024 * 1024)
#define IMXRT_FLASH_USER_NAME "user"
#define IMXRT_FLASH_USER_START IMXRT_FLASH_APP_START + IMXRT_FLASH_APP_SIZE
#define IMXRT_FLASH_USER_SIZE (1 * 1024 * 1024)
#define IMXRT_FLASH_CODESYS_NAME "CoDeSysApp"
#define IMXRT_FLASH_CODESYS_START IMXRT_FLASH_USER_START + IMXRT_FLASH_USER_SIZE
#define IMXRT_FLASH_CODESYS_SIZE (1 * 1024 * 1024)
具体参考步骤如下:
如果用户需要支持按键强制清除CODESYS的CODE区和DATA区应定义此按键,同时应在runtime启动前调用fal删除相应的存储区;
#define CODESYS_APP_DELETE_KEY GET_PIN(5, 0) /* WAKEUP */
#define CODESYS_APP_DELETE_KEY_DEFAULT_LEVEL PIN_HIGH
删除CODE存储区示例代码如下,DATA区的删除用户可以参照以下代码进行编写:
if (codesys_app_delete_check())
{
fal_part = fal_part_find(plc_board_config()->SysFlash.code_part);
if (fal_part == NULL)
{
LOG_E(TAG, "flash %s mount faild", plc_board_config()->SysFlash.code_part);
}
OS_ASSERT(fal_part);
erase_size = 0;
LOG_I(TAG, "erase App...");
while(erase_size < fal_part->info->size)
{
result = fal_part_erase(fal_part, erase_size, fal_part->flash->block_size);
if(result < 0)
{
break;
}
erase_size += result;
printf("#");
}
}
把上面修改好的工程进行编译并下载到开发板中,开发板接线图如下;
查看设备运行日志
通过RS232串口线把板卡的LPUART1连接到电脑,通过串口终端可以查看设备运行日志,默认配置配置为:115200,8,1,none,none:
[2] E/drv.usdhc: cannot detect card! [_usdhc_detectinit][248]
==================== FAL partition table ====================
| name | flash_dev | offset | length |
-------------------------------------------------------------
| app | onchip_flash | 0x00000000 | 0x00100000 |
| user | onchip_flash | 0x00100000 | 0x00100000 |
| CoDeSysApp | onchip_flash | 0x00200000 | 0x00100000 |
| at24 | at24cxx_eeprom | 0x00000000 | 0x00000100 |
=============================================================
[7] I/CoDeSys.Main: {"LibName":"CoDeSys_Lib_V3.5.17.10","Board":"OK1061-S","Kernel":"OneOS-V2.1.0","Version":"1.0.1","CompilerVer":"6140002","Data":"Dec 9 2021","Time":"15:58:55","Author":"OneOS Team"} [codesys_runtime_entry][116]
[9] I/plc: code & data area init ok. [SysMemOSHookFunction][83]
[9] I/plc: flash1(CoDeSysApp) init ok. [SysFlashInit][148]
[10] I/plc: flash2(user) init ok. [SysFlashInit][148]
[11] W/plc: byNet:0 Register Failed. [Phy_CanMiniDriver_Setup][339]
[12] I/plc: byNet:1 bind device can2. [CMD_Setup][101]
[12] I/plc: byNet:1 Register OK. [Phy_CanMiniDriver_Setup][335]
sh />
如上日志中byNet:0 Register Failed.实为板卡can1设备没有注册只注册了can2所导致,解决此warning可以设备注册can1即可消除;用户可以忽略不管;
查看RUNTIME心跳
通过USB转TTL线缆把LPUART3连接到电脑,并打开串口查看软件,配置信息如下:
如果RUNTIME已正常运行,通过串口软件可以查看到5秒1个的心跳输出:
当用户查看到此心跳时,说明设备已运行了RUNTIME;确保串口查看软件已关闭此串口,则可以出发进入下一站啦,此时是不是还有点小激动呢?哈哈~
通过上面的一些列准备,终于把我们的CODESYS RUNTIME运行起来了。不着急,马上就是见证奇迹的时候啦~~
运行CODESYS V3.5 IDE程序,通过工具->设备存储库把OneOS提供的标准PLC设备描述文件进行安装;只有这样,IDE才能认识我们的设备呢!
话不多说,新建一个标准工程;
这里我们对网关进行一下小小的配置,帮助IDE找到我们设备吧,若不能正常发现设备,则重复查看RUNTIME心跳一节,确认LPUART3所对应的串口已被关闭;
好啦,到这里一切都已准备就绪,通往CODESYS IDE编程的大门已被打开。这里我们简单编写几行代码,测试一下编译、下载和设备的运行情况。刚上车的乘客请坐稳扶好,我们粗发啦;
PLC代码如下:
PROGRAM PLC_PRG
VAR
a,b:INT;//定义a,b两个int型变量
END_VAR
a := a + 1;
IF a MOD 10 = 0
THEN
b := b + 10;
END_IF
程序大意:a自加1,a遇10的整数倍b加10;
最后最后,关于OneOS+CODESYS的更多用法,用户可移步OneOS学院查看更多资讯和在线应用课程。
本文已完结