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开发板;
- DB9 RS232串口线1根;
- USB转TTL串口线1根;
- DC5V电源1个;
- 开发板配套烧录器或Jlink 1个。
- OneOS 源码包(OneOS-V2.2.0.zip)
- OneOS-Cube(OneOS-Cube-V1.3.5)
- OK1061-S开发板资料
- NXP程序配置软件:MCUXpresso Config Tools
- CODESYS IDE软件安装包
- MDK环境:笔者这里推荐使用的是MDK V5.31.0.0
下面来一张,本期板卡实例颜值担当OK1061-S开发板的板卡全貌:
CODESYS RUNTIME
默认工程程序代码是一个通用示例代码,并非完全为CODESYS所定制工程,需要我们用户在通用工程的基础上做一些适配调整;
首先需要通过OneOS BSP模板创建一个基础工程,方法如下:
进入\OneOS-V2.2.0\projects目录下鼠标右键打开OneOS-Cube
在创建完基础工程过后,进入上面新建的基础工程目录:imxrt1061-forlinx,并通过menuconfig进行配置一些外设以及参数配置:
- 修改console串口为lpuart1;
- 关闭HAL下的Ethernet网卡;
- 关闭lwip组件;
- 使能CoDeSys组件并根据工程实际情况修改配置参数;
- 使用命令scons --ide=mdk5 生成工程。
如果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.cstatic 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运行起来了。不着急,马上就是见证奇迹的时候啦~~
Step1 录入设备信息 运行CODESYS V3.5 IDE程序,通过工具->设备存储库把OneOS提供的标准PLC设备描述文件进行安装;只有这样,IDE才能认识我们的设备呢!
话不多说,新建一个标准工程;
这里我们对网关进行一下小小的配置,帮助IDE找到我们设备吧,若不能正常发现设备,则重复查看RUNTIME心跳一节,确认LPUART3所对应的串口已被关闭;
好啦,到这里一切都已准备就绪,通往CODESYS IDE编程的大门已被打开。这里我们简单编写几行代码,测试一下编译、下载和设备的运行情况。刚上车的乘客请坐稳扶好,我们粗发啦;
PLC代码如下:
PROGRAM PLC_PRGVAR 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, OneOS技术分享