Merge branch 'prepare_for_master' of https://gitlink.org.cn/xuos/xiuos into develop

This commit is contained in:
wgzAIIT 2023-05-12 14:01:47 +08:00
commit 7629077769
93 changed files with 3498 additions and 712 deletions

View File

@ -18,10 +18,10 @@
* @date: 2022/1/7
*/
#ifdef ADD_XIZI_FETURES
#include <stdio.h>
#include <string.h>
#include <transform.h>
#ifdef ADD_XIZI_FETURES
void TestAdc(void)
{

View File

@ -18,11 +18,10 @@
* @date: 2022/12/7
*/
#ifdef ADD_XIZI_FETURES
#include <stdio.h>
#include <string.h>
#include <transform.h>
#ifdef ADD_XIZI_FETURES
static uint16_t image_buff[384000];

View File

@ -17,10 +17,10 @@
* @author: AIIT XUOS Lab
* @date: 2023/2/17
*/
#ifdef ADD_XIZI_FETURES
#include <stdio.h>
#include <string.h>
#include <transform.h>
#ifdef ADD_XIZI_FETURES
void TestCAN(void)

View File

@ -17,10 +17,10 @@
* @author: AIIT XUOS Lab
* @date: 2022/1/11
*/
#ifdef ADD_XIZI_FETURES
#include <stdio.h>
#include <string.h>
#include <transform.h>
#ifdef ADD_XIZI_FETURES
void TestDac(void)
{

View File

@ -17,10 +17,10 @@
* @author: AIIT XUOS Lab
* @date: 2022/12/17
*/
#ifdef ADD_XIZI_FETURES
#include <stdio.h>
#include <string.h>
#include <transform.h>
#ifdef ADD_XIZI_FETURES
#include <socket.h>

View File

@ -17,10 +17,10 @@
* @author: AIIT XUOS Lab
* @date: 2022/12/17
*/
#ifdef ADD_XIZI_FETURES
#include <stdio.h>
#include <string.h>
#include <transform.h>
#ifdef ADD_XIZI_FETURES
void TestFlash(void)
{

View File

@ -17,10 +17,10 @@
* @author: AIIT XUOS Lab
* @date: 2022/11/17
*/
#ifdef ADD_XIZI_FETURES
#include <stdio.h>
#include <string.h>
#include <transform.h>
#ifdef ADD_XIZI_FETURES
#define MAX_READ_LENGTH 1000

View File

@ -17,19 +17,24 @@
* @author: AIIT XUOS Lab
* @date: 2022/12/17
*/
#ifdef ADD_XIZI_FETURES
#include <stdio.h>
#include <string.h>
#include <transform.h>
#ifdef ADD_XIZI_FETURES
#ifdef BOARD_EDU_RISCV64_EVB
#define BSP_LED_PIN 29
#define BSP_KEY_PIN 31
#elif defined BOARD_HC32F4A0_EVB
#define BSP_LED_PIN 134
#define BSP_KEY_PIN 176
#endif
#define NULL_PARAMETER 0
void TestGpio(void)
{
int pin_fd = PrivOpen(GPIO_DEV_DRIVER, O_RDWR);
if(pin_fd<0){
if(pin_fd < 0) {
printf("open pin fd error:%d\n",pin_fd);
return;
}
@ -51,8 +56,8 @@ void TestGpio(void)
}
//config key pin in board
parameter.pin = BSP_KEY_PIN;
parameter.mode = GPIO_CFG_INPUT;
parameter.pin = BSP_KEY_PIN;
parameter.mode = GPIO_CFG_INPUT;
if (0 != PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg)) {
printf("ioctl pin fd error %d\n", pin_fd);
@ -68,7 +73,7 @@ void TestGpio(void)
//recycle read pin and write pin until key break
while(1){
if(0>PrivRead(pin_fd,&pin_key,NULL_PARAMETER)){
if(0 > PrivRead(pin_fd, &pin_key, NULL_PARAMETER)) {
printf("read pin fd error %d\n", pin_fd);
PrivClose(pin_fd);
return;
@ -81,12 +86,11 @@ void TestGpio(void)
pin_led.val = GPIO_LOW;
}
if(0>PrivWrite(pin_fd,&pin_led,NULL_PARAMETER)){
printf("write pin fd error %d\n", pin_fd);
PrivClose(pin_fd);
return;
}
if(0 > PrivWrite(pin_fd, &pin_led, NULL_PARAMETER)) {
printf("write pin fd error %d\n", pin_fd);
PrivClose(pin_fd);
return;
}
}
}

View File

@ -17,10 +17,10 @@
* @author: AIIT XUOS Lab
* @date: 2022/12/17
*/
#ifdef ADD_XIZI_FETURES
#include <stdio.h>
#include <string.h>
#include <transform.h>
#ifdef ADD_XIZI_FETURES
#define BSP_LED_PIN 134
#define NULL_PARAMETER 0

View File

@ -17,10 +17,10 @@
* @author: AIIT XUOS Lab
* @date: 2022/12/17
*/
#ifdef ADD_XIZI_FETURES
#include <stdio.h>
#include <string.h>
#include <transform.h>
#ifdef ADD_XIZI_FETURES
#define I2C_SLAVE_ADDRESS 0x0012U

View File

@ -17,10 +17,10 @@
* @author: AIIT XUOS Lab
* @date: 2022/12/17
*/
#ifdef ADD_XIZI_FETURES
#include <stdio.h>
#include <string.h>
#include <transform.h>
#ifdef ADD_XIZI_FETURES
#define GRAPHIC_CTRL_RECT_UPDATE 0x00
#define LCD_STRING_TYPE 0

View File

@ -17,10 +17,10 @@
* @author: AIIT XUOS Lab
* @date: 2022/12/17
*/
#ifdef ADD_XIZI_FETURES
#include <stdio.h>
#include <string.h>
#include <transform.h>
#ifdef ADD_XIZI_FETURES
#define NULL_PARAMETER 0
#define E220_CFG_LENGTH

View File

@ -17,10 +17,10 @@
* @author: AIIT XUOS Lab
* @date: 2022/12/17
*/
#ifdef ADD_XIZI_FETURES
#include <stdio.h>
#include <string.h>
#include <transform.h>
#ifdef ADD_XIZI_FETURES
#define BSP_485_DIR_PIN 24

View File

@ -17,10 +17,10 @@
* @author: AIIT XUOS Lab
* @date: 2022/12/17
*/
#ifdef ADD_XIZI_FETURES
#include <stdio.h>
#include <string.h>
#include <transform.h>
#ifdef ADD_XIZI_FETURES
void TestRTC(int argc,char *argv[])
{

View File

@ -48,7 +48,7 @@ void TestTouch(void)
#define LCD_DOT_TYPE 1
#define LCD_SIZE 320
#elif ADD_XIZI_FETURES
#elif defined ADD_XIZI_FETURES
void TestTouch(void)
{

View File

@ -17,10 +17,10 @@
* @author: AIIT XUOS Lab
* @date: 2022/12/17
*/
#ifdef ADD_XIZI_FETURES
#include <stdio.h>
#include <string.h>
#include <transform.h>
#ifdef ADD_XIZI_FETURES
void TestWDT(int argc, char *agrv[])
{

View File

@ -1,3 +1,3 @@
SRC_DIR := advantech beckhoff br delta mitsubishi omron schneider siemens ge xinje
SRC_DIR := advantech beckhoff br delta mitsubishi omron schneider siemens ge xinje inovance
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,3 +1,3 @@
SRC_FILES := br_x20cp0410.c br_x20cp1381.c br_x20cp1586.c
SRC_FILES := br_x20cp0410.c br_x20cp1381.c br_x20cp1586.c br_ppc2100.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,23 @@
# 贝加莱 PPC2100通信测试
[TOC]
## 通信接线及参数设置
* 网口
* 通过ETH1 RJ45 网口连接
* 网口参数IP192.168.250.26 Port502
* 测试的协议:Modbus TCP
## 存储区
- 贝加莱PLC与其他PLC不同没有明确类似MD等这样的存储区的概念Modbus地址取决于库函数中结构体变量索引。
## 通信测试
- 共测试BOOLINT16INT32FLOAT,DOUBLE 共五种类型数据。
- 测试BOOL型变量用功能码01测其他类型变量用功能码03。
-

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2022 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file br_ppc2100.c
* @brief PLC BR PPC2100 app
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.5.8
*/
#include <control.h>
extern int Adapter4GActive(void);
void ControlBrTest_PPC2100(void)
{
int i, j = 0;
int read_data_length = 0;
uint8_t read_data[128] = {0};
#ifdef CONNECTION_ADAPTER_4G
Adapter4GActive();
#endif
ControlProtocolType modbus_tcp_protocol = ControlProtocolFind();
if (NULL == modbus_tcp_protocol) {
printf("%s get modbus tcp protocol %p failed\n", __func__, modbus_tcp_protocol);
return;
}
printf("%s get modbus tcp protocol %p successfull\n", __func__, modbus_tcp_protocol);
if (CONTROL_REGISTERED == modbus_tcp_protocol->protocol_status) {
ControlProtocolOpen(modbus_tcp_protocol);
for (;;) {
read_data_length = ControlProtocolRead(modbus_tcp_protocol, read_data, sizeof(read_data));
printf("%s read [%d] modbus tcp data %d using receipe file\n", __func__, i, read_data_length);
if (read_data_length) {
for (j = 0; j < read_data_length; j ++) {
printf("j %d data 0x%x\n", j, read_data[j]);
}
}
i++;
memset(read_data, 0, sizeof(read_data));
PrivTaskDelay(10000);
}
//ControlProtocolClose(modbus_tcp_protocol);
}
}
PRIV_SHELL_CMD_FUNCTION(ControlBrTest_PPC2100, Delta ppc2100 Demo, PRIV_SHELL_CMD_MAIN_ATTR);

View File

@ -0,0 +1,93 @@
{
"device_id": 1,
"device_name": "BR_PPC2100",
"communication_type": 0,
"socket_config": {
"plc_ip": "192.168.250.26",
"local_ip": "192.168.250.233",
"gateway": "192.168.250.1",
"netmask": "255.255.254.0",
"port": 502
},
"protocol_type": 2,
"read_period": 2000,
"read_item_list": [
{
"value_name": "motorrun",
"value_type": 1,
"function_code": 2,
"start_address": 0,
"quantity": 1
},
{
"value_name": "motorstop",
"value_type": 1,
"function_code": 2,
"start_address": 1,
"quantity": 1
},
{
"value_name": "valueopen",
"value_type": 1,
"function_code": 1,
"start_address": 100,
"quantity": 1
},
{
"value_name": "valueclose",
"value_type": 1,
"function_code": 1,
"start_address": 101,
"quantity": 1
},
{
"value_name": "step",
"value_type": 3,
"function_code": 4,
"start_address": 100,
"quantity": 1
},
{
"value_name": "temperature",
"value_type": 9,
"function_code": 4,
"start_address": 101,
"quantity": 2
},
{
"value_name": "status",
"value_type": 4,
"function_code": 4,
"start_address": 103,
"quantity": 2
},
{
"value_name": "mode",
"value_type": 3,
"function_code": 3,
"start_address": 200,
"quantity": 1
},
{
"value_name": "setTemperature",
"value_type": 9,
"function_code": 3,
"start_address": 201,
"quantity": 2
},
{
"value_name": "setConuter",
"value_type": 4,
"function_code": 3,
"start_address": 203,
"quantity": 2
},
{
"value_name": "LrealTest",
"value_type": 8,
"function_code": 3,
"start_address": 205,
"quantity": 4
}
]
}

View File

@ -0,0 +1,22 @@
# 台达 DVP通信测试
[TOC]
## 通信接线及参数设置
* 网口
* 通过自带 RJ45 网口连接
* 网口参数IP192.168.250.27 Port502
* 测试的协议:Modbus TCP
## 存储区
- 含MDXY。台达PLC中 各存储区地址和Modbus地址有明确的对应表详见台达DVP协议解析测试文档。
## 通信测试
- 共测试BOOLINT16INT32FLOAT 共四种类型数据。
- 测试D区M区和Y区。

View File

@ -0,0 +1,80 @@
{
"device_id": 1,
"device_name": "DELTA_DVP",
"communication_type": 0,
"socket_config": {
"plc_ip": "192.168.250.27",
"local_ip": "192.168.250.233",
"gateway": "192.168.250.1",
"netmask": "255.255.254.0",
"port": 502
},
"protocol_type": 2,
"read_period": 2000,
"read_item_list": [
{
"value_name": "M20",
"value_type": 1,
"function_code": 1,
"start_address": 2068,
"quantity": 1
},
{
"value_name": "M100",
"value_type": 1,
"function_code": 1,
"start_address":2148,
"quantity": 1
},
{
"value_name": "Y10",
"value_type": 1,
"function_code": 1,
"start_address": 1288,
"quantity": 1
},
{
"value_name": "D200",
"value_type": 3,
"function_code": 3,
"start_address":4296,
"quantity": 1
},
{
"value_name": "D201",
"value_type": 3,
"function_code": 3,
"start_address": 4297,
"quantity": 1
},
{
"value_name": "D220",
"value_type": 4,
"function_code": 3,
"start_address": 4316,
"quantity": 2
},
{
"value_name": "D222",
"value_type": 4,
"function_code": 3,
"start_address": 4318,
"quantity": 2
},
{
"value_name": "D300",
"value_type": 9,
"function_code": 3,
"start_address": 4396,
"quantity": 2
},
{
"value_name": "D302",
"value_type": 9,
"function_code": 3,
"start_address": 4398,
"quantity": 2
}
]
}

View File

@ -1,3 +1,3 @@
SRC_FILES := ge_versamax001.c
SRC_FILES := ge_versamax001.c ge_cpe100.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,57 @@
---
typora-copy-images-to: upload
---
# 艾默生原GE 通信测试
[TOC]
## 小型VersaMAX CPU001测试
### 通信接线及参数设置
* 串口
* COM2为15孔D型 RS485。波特率19200数据位8位停止位1位校验偶校验。接线按下图典型双线接法。
![ge_versamax_serial](./img/ge_versamax_serial.png)
### 存储区
- 存储区 IQAIR区。其他内存区如MAQ不能直接访问要通过程序转换访问。
### 通信测试
- 共测试BOOLINT16FLOAT共三种类型数据。
- 测试R区及Q区数据。
- R区数据测试用功能码03以字为单位读取。配方中start_address字段为PLC地址直接减1。
- Q区数据测试用功能码01以位为单位读取。配方中start_address字段为PLC地址直接减1。
## 中型PLC CPE100通信测试
### 通信接线及参数设置
- 网口
- 网口RJ45参数 IP192.168.250.28 端口号502
### 存储区
- 存储区 IQAIR区。其他内存区如MAQ不能直接访问要通过程序转换访问。
### 通信测试
- 共测试BOOLINT16INT32FLOATDOUBLE共五种类型数据。
- 测试R区及Q区数据。
- R区数据测试用功能码03以字为单位读取。配方中start_address字段为PLC地址直接减1。
- Q区数据测试用功能码01以位为单位读取。配方中start_address字段为PLC地址直接减1。

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2022 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file ge_cpe100.c
* @brief PLC GE Versamax app
* @version 3.0
* @author AIIT XUOS Lab
* @date 2022.9.27
*/
#include <control.h>
extern int Adapter4GActive(void);
void ControlGecpe100Test(void)
{
int i, j = 0;
int read_data_length = 0;
uint8_t read_data[128] = {0};
#ifdef CONNECTION_ADAPTER_4G
Adapter4GActive();
#endif
ControlProtocolType modbus_tcp_protocol = ControlProtocolFind();
if (NULL == modbus_tcp_protocol) {
printf("%s get modbus tcp protocol %p failed\n", __func__, modbus_tcp_protocol);
return;
}
printf("%s get modbus tcp protocol %p successfull\n", __func__, modbus_tcp_protocol);
if (CONTROL_REGISTERED == modbus_tcp_protocol->protocol_status) {
ControlProtocolOpen(modbus_tcp_protocol);
for (;;) {
read_data_length = ControlProtocolRead(modbus_tcp_protocol, read_data, sizeof(read_data));
printf("%s read [%d] modbus tcp data %d using receipe file\n", __func__, i, read_data_length);
if (read_data_length) {
for (j = 0; j < read_data_length; j ++) {
printf("j %d data 0x%x\n", j, read_data[j]);
}
}
i++;
memset(read_data, 0, sizeof(read_data));
PrivTaskDelay(10000);
}
//ControlProtocolClose(modbus_tcp_protocol);
}
}
PRIV_SHELL_CMD_FUNCTION(ControlGecpe100Test, ge cpe100 Demo, PRIV_SHELL_CMD_MAIN_ATTR);

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

View File

@ -0,0 +1,73 @@
{
"device_id": 1,
"device_name": "GE_CPE100_TCP",
"communication_type": 0,
"socket_config": {
"plc_ip": "192.168.250.28",
"local_ip": "192.168.250.233",
"gateway": "192.168.250.1",
"netmask": "255.255.254.0",
"port": 502
},
"protocol_type": 2,
"read_period": 2000,
"read_item_list": [
{
"value_name": "Q001",
"value_type": 1,
"function_code": 1,
"start_address": 0,
"quantity": 1
},
{
"value_name": "Q010",
"value_type": 1,
"function_code": 1,
"start_address":9,
"quantity": 1
},
{
"value_name": "Q066",
"value_type": 1,
"function_code": 1,
"start_address": 65,
"quantity": 1
},
{
"value_name": "Q100",
"value_type": 1,
"function_code": 1,
"start_address":99,
"quantity": 1
},
{
"value_name": "R11",
"value_type": 3,
"function_code": 3,
"start_address": 10,
"quantity": 1
},
{
"value_name": "R12",
"value_type": 9,
"function_code": 3,
"start_address": 11,
"quantity": 2
},
{
"value_name": "R14",
"value_type": 8,
"function_code": 3,
"start_address": 13,
"quantity": 4
},
{
"value_name": "R18",
"value_type": 4,
"function_code": 3,
"start_address": 17,
"quantity": 2
}
]
}

View File

@ -0,0 +1,58 @@
{
"device_id": 1,
"device_name": "GE_VersaMAX_RTU",
"communication_type": 1,
"serial_config": {
"station": 1,
"baud_rate": 19200,
"data_bits": 8,
"stop_bits": 1,
"check_mode": 2
},
"protocol_type": 3,
"read_period": 2000,
"read_item_list": [
{
"value_name": "Q001",
"value_type": 1,
"function_code": 1,
"start_address": 0,
"quantity": 1
},
{
"value_name": "Q010",
"value_type": 1,
"function_code": 1,
"start_address": 9,
"quantity": 1
},
{
"value_name": "Q066",
"value_type": 1,
"function_code": 1,
"start_address": 65,
"quantity": 1
},
{
"value_name": "Q100",
"value_type": 1,
"function_code": 1,
"start_address": 99,
"quantity": 1
},
{
"value_name": "R11",
"value_type": 3,
"function_code": 3,
"start_address": 10,
"quantity": 1
},
{
"value_name": "R12",
"value_type": 9,
"function_code": 3,
"start_address": 11,
"quantity": 2
}
]
}

View File

@ -0,0 +1,3 @@
SRC_FILES := inovance_am401_cpu1608tn_ethernet.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,26 @@
# INOVANCE AM4011608TN通信测试
[TOC]
## 通信接线及参数设置
* 网口
* CN3 EtherNET,Mosbus TCP协议IP192.168.250.50Port502
* 串口
* CN1 RS485AM401只支持一路串口AM600可支持两路串口。AM401接线pin1:485-pin2:485+。波特率9600数据位8位停止位1位校验偶校验
## 存储区
- 存储区 IQM区。
## 通信测试
1共测试BOOLINT16INT32FLOAT共四种类型数据。
2测试M区及Q区数据。
3M区数据测试用功能码03以字为单位读取。如读MX0.3,则读取MW0然后按位拆解。如读MW100则配方文件中起始地址则直接写100即可。如读MDx则配方文件中起始地址应为2*x这是汇川的地址编码规则决定如MD200则对应400。
4Q区数据测试用功能码01以位为单位读取。如读QX.Y则配方文件中起始地址为X*8+Y如读QWQD等则需按位进行读取后然后组合得到。

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2022 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file inovance_am401_cpu1608tn_ethernet.c
* @brief PLC inovance am401 app
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.4.25
*/
#include <control.h>
extern int Adapter4GActive(void);
void ControlInovanceam401EthernetTest(void)
{
int i, j = 0;
int read_data_length = 0;
uint8_t read_data[128] = {0};
#ifdef CONNECTION_ADAPTER_4G
Adapter4GActive();
#endif
ControlProtocolType modbus_tcp_protocol = ControlProtocolFind();
if (NULL == modbus_tcp_protocol) {
printf("%s get modbus tcp protocol %p failed\n", __func__, modbus_tcp_protocol);
return;
}
printf("%s get modbus tcp protocol %p successfull\n", __func__, modbus_tcp_protocol);
if (CONTROL_REGISTERED == modbus_tcp_protocol->protocol_status) {
ControlProtocolOpen(modbus_tcp_protocol);
for (;;) {
read_data_length = ControlProtocolRead(modbus_tcp_protocol, read_data, sizeof(read_data));
printf("%s read [%d] modbus tcp data %d using receipe file\n", __func__, i, read_data_length);
if (read_data_length) {
for (j = 0; j < read_data_length; j ++) {
printf("j %d data 0x%x\n", j, read_data[j]);
}
}
i++;
memset(read_data, 0, sizeof(read_data));
PrivTaskDelay(10000);
}
//ControlProtocolClose(modbus_tcp_protocol);
}
}
PRIV_SHELL_CMD_FUNCTION(ControlInovanceam401EthernetTest, inovance am401 ethernet Demo, PRIV_SHELL_CMD_MAIN_ATTR);

View File

@ -0,0 +1,80 @@
{
"device_id": 1,
"device_name": "INOVANCE_AM401_TCP",
"communication_type": 0,
"socket_config": {
"plc_ip": "192.168.250.50",
"local_ip": "192.168.250.233",
"gateway": "192.168.250.1",
"netmask": "255.255.254.0",
"port": 502
},
"protocol_type": 2,
"read_period": 2000,
"read_item_list": [
{
"value_name": "q00",
"value_type": 1,
"function_code": 1,
"start_address": 0,
"quantity": 1
},
{
"value_name": "q01",
"value_type": 1,
"function_code": 1,
"start_address":1,
"quantity": 1
},
{
"value_name": "q10",
"value_type": 1,
"function_code": 1,
"start_address": 8,
"quantity": 1
},
{
"value_name": "mw100",
"value_type": 3,
"function_code": 3,
"start_address": 100,
"quantity": 1
},
{
"value_name": "mw101",
"value_type": 3,
"function_code": 3,
"start_address": 101,
"quantity": 1
},
{
"value_name": "md200",
"value_type": 4,
"function_code": 3,
"start_address": 400,
"quantity": 2
},
{
"value_name": "md201",
"value_type": 4,
"function_code": 3,
"start_address": 402,
"quantity": 2
},
{
"value_name": "md300",
"value_type": 9,
"function_code": 3,
"start_address": 600,
"quantity": 2
},
{
"value_name": "md301",
"value_type": 9,
"function_code": 3,
"start_address": 602,
"quantity": 2
}
]
}

View File

@ -0,0 +1,24 @@
# 三菱 FX2N通信测试
[TOC]
## 通信接线及参数设置
* 串口
* FX2N自带8针圆口422用于程序的下载。全系列不支持网口且需购买串口拓展模块FX2N-485-BD用于通信测试。
* 接线RDA和SDA短接引出ARDB与SDB短接引出B。
* 串口模块支持MC-1C协议通信速率9600数据位7bit停止位1bit校验偶校验
## 存储区
- 存储区 IQMD区。
## 通信测试
- 共测试BOOLINT16FLOAT共三种类型数据。
- 测试M区及D区数据。

View File

@ -0,0 +1,331 @@
{
"device_id": 769,
"device_name": "S01",
"communication_type": 1,
"serial_config": {
"station": 1,
"baud_rate": 9600,
"data_bits": 7,
"stop_bits": 1,
"check_mode": 3
},
"protocol_type": 9,
"read_period": 1000,
"read_item_list": [
{
"value_name": "启动",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "0",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
},
{
"value_name": "停止",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "1",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
},
{
"value_name": "使能",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "2",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
},
{
"value_name": "回零",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "3",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
},
{
"value_name": "急停",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "4",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
},
{
"value_name": "正限位",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "5",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
},
{
"value_name": "负限位",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "6",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
},
{
"value_name": "自动运行中",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "20",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
},
{
"value_name": "故障",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "21",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
},
{
"value_name": "待机",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "22",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
},
{
"value_name": "手动模式",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "23",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
},
{
"value_name": "自动模式",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "24",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
},
{
"value_name": "运行方向",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "25",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
},
{
"value_name": "复位",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "26",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
},
{
"value_name": "备用1",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "27",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
},
{
"value_name": "产量",
"value_type": 3,
"device_code": "D",
"head_device_number_string": "0",
"device_points_count": 1,
"command_type": 1,
"monitoring_timer": 100
},
{
"value_name": "整型1",
"value_type": 3,
"device_code": "D",
"head_device_number_string": "1",
"device_points_count": 1,
"command_type": 1,
"monitoring_timer": 100
},
{
"value_name": "整型2",
"value_type": 3,
"device_code": "D",
"head_device_number_string": "2",
"device_points_count": 1,
"command_type": 1,
"monitoring_timer": 100
},
{
"value_name": "整型3",
"value_type": 3,
"device_code": "D",
"head_device_number_string": "3",
"device_points_count": 1,
"command_type": 1,
"monitoring_timer": 100
},
{
"value_name": "整型4",
"value_type": 3,
"device_code": "D",
"head_device_number_string": "4",
"device_points_count": 1,
"command_type": 1,
"monitoring_timer": 100
},
{
"value_name": "整型5",
"value_type": 3,
"device_code": "D",
"head_device_number_string": "5",
"device_points_count": 1,
"command_type": 1,
"monitoring_timer": 100
},
{
"value_name": "整型6",
"value_type": 3,
"device_code": "D",
"head_device_number_string": "50",
"device_points_count": 1,
"command_type": 1,
"monitoring_timer": 100
},
{
"value_name": "整型7",
"value_type": 3,
"device_code": "D",
"head_device_number_string": "51",
"device_points_count": 1,
"command_type": 1,
"monitoring_timer": 100
},
{
"value_name": "整型8",
"value_type": 3,
"device_code": "D",
"head_device_number_string": "52",
"device_points_count": 1,
"command_type": 1,
"monitoring_timer": 100
},
{
"value_name": "整型9",
"value_type": 3,
"device_code": "D",
"head_device_number_string": "53",
"device_points_count": 1,
"command_type": 1,
"monitoring_timer": 100
},
{
"value_name": "速度",
"value_type": 9,
"device_code": "D",
"head_device_number_string": "200",
"device_points_count": 2,
"command_type": 1,
"monitoring_timer": 100
},
{
"value_name": "加速度",
"value_type": 9,
"device_code": "D",
"head_device_number_string": "202",
"device_points_count": 2,
"command_type": 1,
"monitoring_timer": 100
},
{
"value_name": "减速度",
"value_type": 9,
"device_code": "D",
"head_device_number_string": "204",
"device_points_count": 2,
"command_type": 1,
"monitoring_timer": 100
},
{
"value_name": "起始位置",
"value_type": 9,
"device_code": "D",
"head_device_number_string": "206",
"device_points_count": 2,
"command_type": 1,
"monitoring_timer": 100
},
{
"value_name": "终点位置",
"value_type": 9,
"device_code": "D",
"head_device_number_string": "208",
"device_points_count": 2,
"command_type": 1,
"monitoring_timer": 100
},
{
"value_name": "张力值",
"value_type": 9,
"device_code": "D",
"head_device_number_string": "300",
"device_points_count": 2,
"command_type": 1,
"monitoring_timer": 100
},
{
"value_name": "浮点型1",
"value_type": 9,
"device_code": "D",
"head_device_number_string": "302",
"device_points_count": 2,
"command_type": 1,
"monitoring_timer": 100
},
{
"value_name": "浮点型2",
"value_type": 9,
"device_code": "D",
"head_device_number_string": "304",
"device_points_count": 2,
"command_type": 1,
"monitoring_timer": 100
},
{
"value_name": "浮点型3",
"value_type": 9,
"device_code": "D",
"head_device_number_string": "306",
"device_points_count": 2,
"command_type": 1,
"monitoring_timer": 100
},
{
"value_name": "浮点型4",
"value_type": 9,
"device_code": "D",
"head_device_number_string": "308",
"device_points_count": 2,
"command_type": 1,
"monitoring_timer": 100
}
]
}

View File

@ -0,0 +1,70 @@
# OMRON_CP1L通信测试
[TOC]
## 通信接线及参数设置
* 本体无接口增加CP1W-CIF41网络板卡
* FINS协议PLC IP192.168.250.31Port9600
## 存储区
- 存储区 WD区。
## JSON配方设计
* 共测试BOOLINT16共2种类型数据,以下为JSON文件解释。
- ```json
{
"device_id": 1, //设备ID默认是1此参数无效
"device_name": "CP1L", //设备名称,自定义
"communication_type": 0, //通讯协议类型 0是以太网1是串口
"socket_config": { //以太网配置
"plc_ip": "192.168.250.31", //PLC的IP地址
"local_ip": "192.168.250.233", //矽达通IP地址设定
"gateway": "192.168.250.1", //矽达通的网关地址设定
"netmask": "255.255.255.0", //矽达通子网掩码设定
"port": 9600 //端口号设定
},
"protocol_type": 5, //通讯协议5代表FINS协议
"read_period": 100, //交互周期ms
"read_item_list": [
{
"value_name": "停止", //变量名称,自定义
"value_type": 1, //变量类型BOOL = 1,INT8 = 2,INT16,INT32,UINT8,UINT16,UINT32,DOUBLE,FLOAT = 9
"area_char": "W", //变量功能块
"data_type": 0, //数据传输类型BOOL = 0,WORD = 1
"start_address": 100, //起始地址
"bit_address": 1, //BOOL地址偏移位采集变量地址是W100.1
"data_length": 1 //BOOL长度默认是1代表读取1个BOOL长度
},
{
"value_name": "转速", //变量名称,自定义
"value_type": 3, //变量类型BOOL = 1,INT8 = 2,INT16,INT32,UINT8,UINT16,UINT32,DOUBLE,FLOAT = 9
"area_char": "D", //变量功能块
"data_type": 1, //数据传输类型BOOL = 0,WORD = 1
"start_address": 101, //起始地址
"bit_address": 0, //以WORD采集方式时此参数无效采集变量地址是D101
"data_length": 1 //WORD长度默认是1代表读取1个WORD长度2个字节
}
]
}
```
## 通信测试
(1) 新增1个通信demo命名为omron_cp1l.c
(2) 复制样例代码程序到omron_cp1l.c文件中
(3) void **ControlOmronCP1LTest**(void) 更改函数名;
(4) PRIV_SHELL_CMD_FUNCTION(**ControlOmronCP1LTest**, **Omron Plc Cp1l Demo**, PRIV_SHELL_CMD_MAIN_ATTR);更改测试指令;
(5) 剪裁配置完成后,用过烧写器下载至矽达通中,重启后完成测试。

View File

@ -11,10 +11,39 @@
*/
/**
* @file omron_cj2m.c
* @brief PLC OMRON CJ2M app
* @file omron_cp1h.c
* @brief PLC OMRON CP1H app
* @version 3.0
* @author AIIT XUOS Lab
* @date 2022.9.27
* @date 2023.4.1
*/
#include <control.h>
void ControlOmronCP1HTest(void)
{
int i = 0;
uint16_t read_data_length = 0;
uint8_t read_data[1024] = {0};
ControlProtocolType fins_protocol = ControlProtocolFind();
if (NULL == fins_protocol) {
printf("%s get fins protocol %p failed\n", __func__, fins_protocol);
return;
}
printf("%s get fins protocol %p successfull\n", __func__, fins_protocol);
if (CONTROL_REGISTERED == fins_protocol->protocol_status) {
ControlProtocolOpen(fins_protocol);
for (;;) {
read_data_length = ControlProtocolRead(fins_protocol, read_data, sizeof(read_data));
printf("%s read [%d] fins data %d using receipe file\n", __func__, i, read_data_length);
i++;
PrivTaskDelay(100000);
}
//ControlProtocolClose(fins_protocol);
}
}
PRIV_SHELL_CMD_FUNCTION(ControlOmronCP1HTest, Omron Plc Cp1h Demo, PRIV_SHELL_CMD_MAIN_ATTR);

View File

@ -45,4 +45,4 @@ void ControlOmronCP1LTest(void)
//ControlProtocolClose(fins_protocol);
}
}
PRIV_SHELL_CMD_FUNCTION(ControlOmronCP1LTest, Omron Plc FINS Demo, PRIV_SHELL_CMD_MAIN_ATTR);
PRIV_SHELL_CMD_FUNCTION(ControlOmronCP1LTest, Omron Plc Cp1l Demo, PRIV_SHELL_CMD_MAIN_ATTR);

View File

@ -18,6 +18,34 @@
* @date 2022.9.27
*/
#include <control.h>
void ControlOmronNX102Test(void)
{
int i = 0;
uint16_t read_data_length = 0;
uint8_t read_data[1024] = {0};
ControlProtocolType fins_protocol = ControlProtocolFind();
if (NULL == fins_protocol) {
printf("%s get fins protocol %p failed\n", __func__, fins_protocol);
return;
}
printf("%s get fins protocol %p successfull\n", __func__, fins_protocol);
if (CONTROL_REGISTERED == fins_protocol->protocol_status) {
ControlProtocolOpen(fins_protocol);
for (;;) {
read_data_length = ControlProtocolRead(fins_protocol, read_data, sizeof(read_data));
printf("%s read [%d] fins data %d using receipe file\n", __func__, i, read_data_length);
i++;
PrivTaskDelay(10000);
}
// ControlProtocolClose(fins_protocol);
}
}
PRIV_SHELL_CMD_FUNCTION(ControlOmronNX102Test, Omron Plc FINS Demo, PRIV_SHELL_CMD_MAIN_ATTR);

View File

@ -0,0 +1,70 @@
{
"device_id": 1,
"device_name": "CP1H",
"communication_type": 0,
"socket_config": {
"plc_ip": "192.168.250.46",
"local_ip": "192.168.250.233",
"gateway": "192.168.250.1",
"netmask": "255.255.255.0",
"port": 9600
},
"protocol_type": 5,
"read_period": 100,
"read_item_list": [
{
"value_name": "启动",
"value_type": 1,
"area_char": "W",
"data_type": 0,
"start_address": 10,
"bit_address": 0,
"data_length": 1
},
{
"value_name": "停止",
"value_type": 1,
"area_char": "W",
"data_type": 0,
"start_address": 10,
"bit_address": 1,
"data_length": 1
},
{
"value_name": "暂停",
"value_type": 1,
"area_char": "W",
"data_type": 0,
"start_address": 10,
"bit_address": 2,
"data_length": 1
},
{
"value_name": "整型1",
"value_type": 3,
"area_char": "D",
"data_type": 1,
"start_address": 100,
"bit_address": 0,
"data_length": 1
},
{
"value_name": "整型2",
"value_type": 3,
"area_char": "D",
"data_type": 1,
"start_address": 101,
"bit_address": 0,
"data_length": 1
},
{
"value_name": "浮点",
"value_type": 9,
"area_char": "D",
"data_type": 1,
"start_address": 110,
"bit_address": 0,
"data_length": 2
}
]
}

View File

@ -0,0 +1,52 @@
{
"device_id": 1,
"device_name": "CP1L",
"communication_type": 0,
"socket_config": {
"plc_ip": "192.168.250.31",
"local_ip": "192.168.250.233",
"gateway": "192.168.250.1",
"netmask": "255.255.255.0",
"port": 9600
},
"protocol_type": 5,
"read_period": 100,
"read_item_list": [
{
"value_name": "启动",
"value_type": 1,
"area_char": "W",
"data_type": 0,
"start_address": 100,
"bit_address": 0,
"data_length": 1
},
{
"value_name": "停止",
"value_type": 1,
"area_char": "W",
"data_type": 0,
"start_address": 100,
"bit_address": 1,
"data_length": 1
},
{
"value_name": "转速",
"value_type": 3,
"area_char": "D",
"data_type": 1,
"start_address": 101,
"bit_address": 0,
"data_length": 1
},
{
"value_name": "产量",
"value_type": 3,
"area_char": "D",
"data_type": 1,
"start_address": 102,
"bit_address": 0,
"data_length": 1
}
]
}

View File

@ -19,9 +19,6 @@
*/
#include <control.h>
extern int Adapter4GActive(void);
void ControlM241Test(void)
{
int i, j = 0;

View File

@ -0,0 +1,79 @@
# SIEMENS - S7-1512通信测试
[TOC]
## 通信接线及参数设置
* 本体以太网口
* S7协议PLC IP192.168.250.2Port102
## 存储区
- 存储区 QDB区。
## JSON配方设计
* 共测试BOOLINT16共2种类型数据,以下为JSON文件解释。
- ```json
{
"device_id": 1, //设备ID默认是1此参数无效
"device_name": "S7-1512", //设备名称,自定义
"communication_type": 0, //通讯协议类型 0是以太网1是串口
"socket_config": { //以太网配置
"plc_ip": "192.168.250.2", //PLC的IP地址
"local_ip": "192.168.250.233", //矽达通IP地址设定
"gateway": "192.168.250.1", //矽达通的网关地址设定
"netmask": "255.255.255.0", //矽达通子网掩码设定
"port": 102 //端口号设定
},
"protocol_type": 1, //通讯协议5代表FINS协议
"read_period": 100, //交互周期ms
"read_item_list": [
{
"value_name": "布尔1", //变量名称,自定义
"value_type": 1, //变量类型BOOL = 1,INT8 = 2,INT16,INT32,UINT8,UINT16,UINT32,DOUBLE,FLOAT = 9
"area": "Q", //变量功能块
"wordlen": "Bit", //变量字长类型,有Bit Byte Word DWord Real Counter Timer
"db_number": 1, //如为DB区填写对应的DB块编号,如不是DB区无效
"start": 1, //BOOL地址偏移位采集变量地址是Q0.1
"amount": 1 //BOOL长度默认是1代表读取1个BOOL长度
},
{
"value_name": "整型", //变量名称,自定义
"value_type": 3, //变量类型BOOL = 1,INT8 = 2,INT16,INT32,UINT8,UINT16,UINT32,DOUBLE,FLOAT = 9
"area": "DB", //变量功能块
"wordlen": "Word", //变量字长类型,有Bit Byte Word DWord Real Counter Timer
"db_number": 18, //如为DB区即DB18块
"start": 2, //Word地址偏移位采集变量地址是DB18.DBW2
"amount": 1 //Word长度默认是1代表读取1个WORD长度2个字节
},
{
"value_name": "浮点数", //变量名称,自定义
"value_type": 9, //变量类型BOOL = 1,INT8 = 2,INT16,INT32,UINT8,UINT16,UINT32,DOUBLE,FLOAT = 9
"area": "DB", //变量功能块
"wordlen": "Real", //变量字长类型,有Bit Byte Word DWord Real Counter Timer
"db_number": 18, //如为DB区即DB18块
"start": 18, //Real地址偏移位采集变量地址是DB18.DBD18
"amount": 1 //Real长度默认是1代表读取1个Real长度4个字节
}
]
}
```
## 通信测试
(1) 新增1个通信demo命名为simens_s7_1500.c
(2) 复制样例代码程序到simens_s7_1500.c文件中
(3) void **ControlS71500Test**(void)更改函数名;
(4) PRIV_SHELL_CMD_FUNCTION(**ControlS71500Test, Siemens Plc S7_1512 Demo**, PRIV_SHELL_CMD_MAIN_ATTR);更改测试指令;
(5) 剪裁配置完成后,用过烧写器下载至矽达通中,重启后完成测试。

View File

@ -15,9 +15,6 @@
* @brief PLC SIEMENS S7-1200 app
* @version 3.0
* @author AIIT XUOS Lab
* @date 2022.9.27
* @date 2023.3.27
*/

View File

@ -15,9 +15,31 @@
* @brief PLC SIEMENS S7-1500 app
* @version 3.0
* @author AIIT XUOS Lab
* @date 2022.9.27
* @date 2023.3.27
*/
#include <control.h>
void ControlS71500Test(void)
{
int i = 0;
uint16_t read_data_length = 0;
uint8_t read_data[1024] = {0};
ControlProtocolType s7_protocol = ControlProtocolFind();
if (NULL == s7_protocol) {
printf("%s get s7 protocol %p failed\n", __func__, s7_protocol);
return;
}
printf("%s get s7 protocol %p successfull\n", __func__, s7_protocol);
if (CONTROL_REGISTERED == s7_protocol->protocol_status) {
ControlProtocolOpen(s7_protocol);
for (;;) {
read_data_length = ControlProtocolRead(s7_protocol, read_data, sizeof(read_data));
printf("%s read [%d] s7 data %d using receipe file\n", __func__, i, read_data_length);
i++;
memset(read_data, 0, sizeof(read_data));
PrivTaskDelay(10000);
}
}
}
PRIV_SHELL_CMD_FUNCTION(ControlS71500Test, Siemens Plc S7_1512 Demo, PRIV_SHELL_CMD_MAIN_ATTR);

View File

@ -11,13 +11,10 @@
*/
/**
* @file siemens_s7_200_smart.c
* @brief PLC SIEMENS S7-200 SMART app
* @file siemens_s7_200 smart.c
* @brief PLC SIEMENS S7-200 smart app
* @version 3.0
* @author AIIT XUOS Lab
* @date 2022.9.27
* @date 2023.3.27
*/

View File

@ -15,9 +15,6 @@
* @brief PLC SIEMENS S7-300 app
* @version 3.0
* @author AIIT XUOS Lab
* @date 2022.9.27
* @date 2023.3.27
*/

View File

@ -0,0 +1,70 @@
{
"device_id": 1,
"device_name": "S7-1512",
"communication_type": 0,
"socket_config": {
"plc_ip": "192.168.250.2",
"local_ip": "192.168.250.233",
"gateway": "192.168.250.252",
"netmask": "255.255.255.0",
"port": 102
},
"protocol_type": 1,
"read_period": 100,
"read_item_list": [
{
"value_name": "布尔1",
"value_type": 1,
"area": "Q",
"wordlen": "Bit",
"db_number": 1,
"start": 1,
"amount": 1
},
{
"value_name": "布尔2",
"value_type": 1,
"area": "Q",
"wordlen": "Bit",
"db_number": 1,
"start": 2,
"amount": 1
},
{
"value_name": "布尔3",
"value_type": 1,
"area": "Q",
"wordlen": "Bit",
"db_number": 1,
"start": 3,
"amount": 1
},
{
"value_name": "布尔4",
"value_type": 1,
"area": "Q",
"wordlen": "Bit",
"db_number": 1,
"start": 4,
"amount": 1
},
{
"value_name": "整型",
"value_type": 3,
"area": "DB",
"wordlen": "Word",
"db_number": 18,
"start": 2,
"amount": 1
},
{
"value_name": "浮点数",
"value_type": 9,
"area": "DB",
"wordlen": "Real",
"db_number": 18,
"start": 18,
"amount": 1
}
]
}

View File

@ -1,3 +1,3 @@
SRC_FILES := xsdh-60a32-e.c xdh-60t4-e.c
SRC_FILES := xdh_60t4_e.c xsdh_60a32_e.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,184 @@
{
"device_id": 1,
"device_name": "OP01",
"communication_type": 0,
"socket_config": {
"plc_ip": "192.168.250.32",
"local_ip": "192.168.250.233",
"gateway": "192.168.250.1",
"netmask": "255.255.255.0",
"port": 502
},
"protocol_type": 2,
"read_period": 100,
"read_item_list": [
{
"value_name": "M19",
"value_type": 1,
"function_code": 5,
"start_address": 19,
"quantity": 1
},
{
"value_name": "M20",
"value_type": 1,
"function_code": 5,
"start_address":20,
"quantity": 1
},
{
"value_name": "D500",
"value_type": 4,
"function_code": 6,
"start_address": 500,
"quantity": 1
},
{
"value_name": "D501",
"value_type": 4,
"function_code": 6,
"start_address": 501,
"quantity": 1
},
{
"value_name": "D502",
"value_type": 4,
"function_code": 6,
"start_address": 502,
"quantity": 1
},
{
"value_name": "D503",
"value_type": 4,
"function_code": 6,
"start_address": 503,
"quantity": 1
},
{
"value_name": "D504",
"value_type": 4,
"function_code": 6,
"start_address": 504,
"quantity": 1
},
{
"value_name": "M22",
"value_type": 1,
"function_code": 5,
"start_address": 22,
"quantity": 1
},
{
"value_name": "D505",
"value_type": 4,
"function_code": 6,
"start_address": 505,
"quantity": 1
},
{
"value_name": "D506",
"value_type": 4,
"function_code": 6,
"start_address": 506,
"quantity": 1
},
{
"value_name": "D507",
"value_type": 4,
"function_code": 6,
"start_address": 507,
"quantity": 1
},
{
"value_name": "D508",
"value_type": 4,
"function_code": 6,
"start_address": 508,
"quantity": 1
},
{
"value_name": "D509",
"value_type": 4,
"function_code": 6,
"start_address": 509,
"quantity": 1
},
{
"value_name": "D510",
"value_type": 4,
"function_code": 6,
"start_address": 510,
"quantity": 1
},
{
"value_name": "D511",
"value_type": 4,
"function_code": 6,
"start_address": 511,
"quantity": 1
},
{
"value_name": "M23",
"value_type": 1,
"function_code": 5,
"start_address": 23,
"quantity": 1
},
{
"value_name": "M24",
"value_type": 1,
"function_code": 5,
"start_address":24,
"quantity": 1
},
{
"value_name": "M25",
"value_type": 1,
"function_code": 5,
"start_address": 25,
"quantity": 1
},
{
"value_name": "M26",
"value_type": 1,
"function_code": 5,
"start_address": 26,
"quantity": 1
},
{
"value_name": "M29",
"value_type": 1,
"function_code": 5,
"start_address": 29,
"quantity": 1
},
{
"value_name": "D513",
"value_type": 4,
"function_code": 3,
"start_address": 513,
"quantity": 1
},
{
"value_name": "D515",
"value_type": 4,
"function_code": 3,
"start_address": 515,
"quantity": 1
},
{
"value_name": "M27",
"value_type": 1,
"function_code": 1,
"start_address":27,
"quantity": 1
},
{
"value_name": "M28",
"value_type": 1,
"function_code": 1,
"start_address":28,
"quantity": 1
}
]
}

View File

@ -0,0 +1,93 @@
{
"device_id": 255,
"device_name": "GJ2",
"communication_type": 0,
"socket_config": {
"plc_ip": "192.168.250.45",
"local_ip": "192.168.250.233",
"gateway": "192.168.250.1",
"netmask": "255.255.255.0",
"port": 502
},
"protocol_type": 2,
"read_period": 100,
"read_item_list": [
{
"value_name": "QX40.0",
"value_type": 1,
"function_code": 1,
"start_address":0,
"quantity": 1
},
{
"value_name": "QX40.1",
"value_type": 1,
"function_code": 1,
"start_address": 1,
"quantity": 1
},
{
"value_name": "QX40.2",
"value_type": 1,
"function_code": 1,
"start_address": 2,
"quantity": 1
},
{
"value_name": "QX40.3",
"value_type": 1,
"function_code": 1,
"start_address":3,
"quantity": 1
},
{
"value_name": "QX40.4",
"value_type": 1,
"function_code": 1,
"start_address": 4,
"quantity": 1
},
{
"value_name": "QW0",
"value_type": 3,
"function_code": 3,
"start_address": 0,
"quantity": 2
},
{
"value_name": "QW1",
"value_type": 3,
"function_code": 3,
"start_address": 1,
"quantity": 2
},
{
"value_name": "QW2",
"value_type": 3,
"function_code": 3,
"start_address": 2,
"quantity": 2
},
{
"value_name": "QW3",
"value_type": 3,
"function_code": 3,
"start_address": 3,
"quantity": 2
},
{
"value_name": "QW10",
"value_type": 3,
"function_code": 4,
"start_address": 0,
"quantity": 2
},
{
"value_name": "QW11",
"value_type": 3,
"function_code": 4,
"start_address": 1,
"quantity": 2
}
]
}

View File

@ -1,20 +0,0 @@
/*
* Copyright (c) 2022 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file mitsubishi_fx3u.c
* @brief PLC MITSUBISHI FX3U app
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.2.1
*/

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2022 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file xdh-60t4-e.c
* @brief PLC XINJE XDH-60T4-E app
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.4.5
*/
#include <control.h>
void ControlXDHTest(void)
{
int i, j = 0;
int read_data_length = 0;
uint8_t read_data[128] = {0};
ControlProtocolType modbus_tcp_protocol = ControlProtocolFind();
if (NULL == modbus_tcp_protocol) {
printf("%s get modbus tcp protocol %p failed\n", __func__, modbus_tcp_protocol);
return;
}
printf("%s get modbus tcp protocol %p successfull\n", __func__, modbus_tcp_protocol);
if (CONTROL_REGISTERED == modbus_tcp_protocol->protocol_status) {
ControlProtocolOpen(modbus_tcp_protocol);
for (;;) {
read_data_length = ControlProtocolRead(modbus_tcp_protocol, read_data, sizeof(read_data));
printf("%s read [%d] modbus tcp data %d using receipe file\n", __func__, i, read_data_length);
if (read_data_length) {
for (j = 0; j < read_data_length; j ++) {
printf("j %d data 0x%x\n", j, read_data[j]);
}
}
i++;
memset(read_data, 0, sizeof(read_data));
PrivTaskDelay(10000);
}
//ControlProtocolClose(modbus_tcp_protocol);
}
}
PRIV_SHELL_CMD_FUNCTION(ControlXDHTest, Xinje Plc XDH_60T4_E Demo, PRIV_SHELL_CMD_MAIN_ATTR);

View File

@ -1,19 +0,0 @@
/*
* Copyright (c) 2022 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file mitsubishi_fx3u.c
* @brief PLC MITSUBISHI FX3U app
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.3.1
*/

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2022 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file xsdh-60a32-e.c
* @brief PLC XINJE XSDH-60A32-E app
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.3.28
*/
#include <control.h>
void ControlXSDHTest(void)
{
int i, j = 0;
int read_data_length = 0;
uint8_t read_data[128] = {0};
ControlProtocolType modbus_tcp_protocol = ControlProtocolFind();
if (NULL == modbus_tcp_protocol) {
printf("%s get modbus tcp protocol %p failed\n", __func__, modbus_tcp_protocol);
return;
}
printf("%s get modbus tcp protocol %p successfull\n", __func__, modbus_tcp_protocol);
if (CONTROL_REGISTERED == modbus_tcp_protocol->protocol_status) {
ControlProtocolOpen(modbus_tcp_protocol);
for (;;) {
read_data_length = ControlProtocolRead(modbus_tcp_protocol, read_data, sizeof(read_data));
printf("%s read [%d] modbus tcp data %d using receipe file\n", __func__, i, read_data_length);
if (read_data_length) {
for (j = 0; j < read_data_length; j ++) {
printf("j %d data 0x%x\n", j, read_data[j]);
}
}
i++;
memset(read_data, 0, sizeof(read_data));
PrivTaskDelay(10000);
}
//ControlProtocolClose(modbus_tcp_protocol);
}
}
PRIV_SHELL_CMD_FUNCTION(ControlXSDHTest, Xinje Plc XSDH_60A32_E Demo, PRIV_SHELL_CMD_MAIN_ATTR);

View File

@ -27,7 +27,7 @@
extern "C" {
#endif
#define MODBUS_TCP_UNIT_ID 0x01
#define MODBUS_TCP_READ_CMD_LENGTH 0x0C
#define MODBUS_TCP_WRITE_SINGLE_CMD_LENGTH 0x0C

View File

@ -225,7 +225,7 @@ static int ModbusTcpInitialDataInfo(ModbusTcpReadItem *p_read_item, uint16_t ind
p_base_data_info->p_command[5] = 0x09;
}
p_base_data_info->p_command[6] = MODBUS_TCP_UNIT_ID;
p_base_data_info->p_command[6] = control_protocol->recipe->device_id;
p_base_data_info->p_command[7] = function_code;
p_base_data_info->p_command[8] = start_address >> 8;
p_base_data_info->p_command[9] = start_address;

View File

@ -23,6 +23,7 @@ endif
config CONTROL_PROTOCOL_S7
bool "Using s7 control protocol"
default n
select CONTROL_USING_SOCKET
if CONTROL_PROTOCOL_S7
source "$APP_DIR/Framework/control/plc_protocol/s7/Kconfig"
endif

View File

@ -329,7 +329,11 @@ void *ReceivePlcDataTask(void *parameter)
/*read all variable item data, put them into circular_area*/
if (i == control_protocol->recipe->read_item_count) {
printf("%s get %d item %d length\n", __func__, i, data_length);
// for(int i = 0; i < data_length; i++){
// printf("%x\n",fins_data[i]);
// }
CircularAreaAppWrite(circular_area, fins_data, data_length, 0);
printf("%s\n",fins_data);
}
/*read data every single 'read_period' ms*/

View File

@ -0,0 +1,408 @@
/*
* Copyright (c) 2022 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#ifndef snap7_h
#define snap7_h
//---------------------------------------------------------------------------
# include <stdint.h>
# include <unistd.h>
//******************************************************************************
// COMMON
//******************************************************************************
// Exact length types regardless of platform/processor
typedef uint8_t byte;
typedef uint16_t word;
typedef uint32_t longword;
typedef byte* pbyte;
typedef word* pword;
typedef uintptr_t S7Object; // multi platform/processor object reference
// DON'T CONFUSE IT WITH AN OLE OBJECT, IT'S SIMPLY
// AN INTEGER VALUE (32 OR 64 BIT) USED AS HANDLE.
#ifndef __cplusplus
typedef struct
{
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
}tm;
typedef int bool;
#define false 0;
#define true 1;
#endif
static const int errLibInvalidParam = -1;
static const int errLibInvalidObject = -2;
// CPU status
#define S7CpuStatusUnknown 0x00
#define S7CpuStatusRun 0x08
#define S7CpuStatusStop 0x04
// ISO Errors
static const longword errIsoConnect = 0x00010000; // Connection error
static const longword errIsoDisconnect = 0x00020000; // Disconnect error
static const longword errIsoInvalidPDU = 0x00030000; // Bad format
static const longword errIsoInvalidDataSize = 0x00040000; // Bad Datasize passed to send/recv buffer is invalid
static const longword errIsoNullPointer = 0x00050000; // Null passed as pointer
static const longword errIsoShortPacket = 0x00060000; // A short packet received
static const longword errIsoTooManyFragments = 0x00070000; // Too many packets without EoT flag
static const longword errIsoPduOverflow = 0x00080000; // The sum of fragments data exceded maximum packet size
static const longword errIsoSendPacket = 0x00090000; // An error occurred during send
static const longword errIsoRecvPacket = 0x000A0000; // An error occurred during recv
static const longword errIsoInvalidParams = 0x000B0000; // Invalid TSAP params
static const longword errIsoResvd_1 = 0x000C0000; // Unassigned
static const longword errIsoResvd_2 = 0x000D0000; // Unassigned
static const longword errIsoResvd_3 = 0x000E0000; // Unassigned
static const longword errIsoResvd_4 = 0x000F0000; // Unassigned
// Tag Struct
typedef struct {
int Area;
int DBNumber;
int Start;
int Size;
int WordLen;
}TS7Tag, * PS7Tag;
//------------------------------------------------------------------------------
// PARAMS LIST
//------------------------------------------------------------------------------
static const int p_u16_LocalPort = 1;
static const int p_u16_RemotePort = 2;
static const int p_i32_PingTimeout = 3;
static const int p_i32_SendTimeout = 4;
static const int p_i32_RecvTimeout = 5;
static const int p_i32_WorkInterval = 6;
static const int p_u16_SrcRef = 7;
static const int p_u16_DstRef = 8;
static const int p_u16_SrcTSap = 9;
static const int p_i32_PDURequest = 10;
static const int p_i32_MaxClients = 11;
static const int p_i32_BSendTimeout = 12;
static const int p_i32_BRecvTimeout = 13;
static const int p_u32_RecoveryTime = 14;
static const int p_u32_KeepAliveTime = 15;
// Client/Partner Job status
static const int JobComplete = 0;
static const int JobPending = 1;
//******************************************************************************
// CLIENT
//******************************************************************************
// Error codes
static const longword errNegotiatingPDU = 0x00100000;
static const longword errCliInvalidParams = 0x00200000;
static const longword errCliJobPending = 0x00300000;
static const longword errCliTooManyItems = 0x00400000;
static const longword errCliInvalidWordLen = 0x00500000;
static const longword errCliPartialDataWritten = 0x00600000;
static const longword errCliSizeOverPDU = 0x00700000;
static const longword errCliInvalidPlcAnswer = 0x00800000;
static const longword errCliAddressOutOfRange = 0x00900000;
static const longword errCliInvalidTransportSize = 0x00A00000;
static const longword errCliWriteDataSizeMismatch = 0x00B00000;
static const longword errCliItemNotAvailable = 0x00C00000;
static const longword errCliInvalidValue = 0x00D00000;
static const longword errCliCannotStartPLC = 0x00E00000;
static const longword errCliAlreadyRun = 0x00F00000;
static const longword errCliCannotStopPLC = 0x01000000;
static const longword errCliCannotCopyRamToRom = 0x01100000;
static const longword errCliCannotCompress = 0x01200000;
static const longword errCliAlreadyStop = 0x01300000;
static const longword errCliFunNotAvailable = 0x01400000;
static const longword errCliUploadSequenceFailed = 0x01500000;
static const longword errCliInvalidDataSizeRecvd = 0x01600000;
static const longword errCliInvalidBlockType = 0x01700000;
static const longword errCliInvalidBlockNumber = 0x01800000;
static const longword errCliInvalidBlockSize = 0x01900000;
static const longword errCliDownloadSequenceFailed = 0x01A00000;
static const longword errCliInsertRefused = 0x01B00000;
static const longword errCliDeleteRefused = 0x01C00000;
static const longword errCliNeedPassword = 0x01D00000;
static const longword errCliInvalidPassword = 0x01E00000;
static const longword errCliNoPasswordToSetOrClear = 0x01F00000;
static const longword errCliJobTimeout = 0x02000000;
static const longword errCliPartialDataRead = 0x02100000;
static const longword errCliBufferTooSmall = 0x02200000;
static const longword errCliFunctionRefused = 0x02300000;
static const longword errCliDestroying = 0x02400000;
static const longword errCliInvalidParamNumber = 0x02500000;
static const longword errCliCannotChangeParam = 0x02600000;
static const int MaxVars = 20; // Max vars that can be transferred with MultiRead/MultiWrite
// Client Connection Type
static const word CONNTYPE_PG = 0x0001; // Connect to the PLC as a PG
static const word CONNTYPE_OP = 0x0002; // Connect to the PLC as an OP
static const word CONNTYPE_BASIC = 0x0003; // Basic connection
// Area ID
static const byte S7AreaPE = 0x81;
static const byte S7AreaPA = 0x82;
static const byte S7AreaMK = 0x83;
static const byte S7AreaDB = 0x84;
static const byte S7AreaCT = 0x1C;
static const byte S7AreaTM = 0x1D;
// Word Length
static const int S7WLBit = 0x01;
static const int S7WLByte = 0x02;
static const int S7WLWord = 0x04;
static const int S7WLDWord = 0x06;
static const int S7WLReal = 0x08;
static const int S7WLCounter = 0x1C;
static const int S7WLTimer = 0x1D;
// Block type
static const byte Block_OB = 0x38;
static const byte Block_DB = 0x41;
static const byte Block_SDB = 0x42;
static const byte Block_FC = 0x43;
static const byte Block_SFC = 0x44;
static const byte Block_FB = 0x45;
static const byte Block_SFB = 0x46;
// Sub Block Type
static const byte SubBlk_OB = 0x08;
static const byte SubBlk_DB = 0x0A;
static const byte SubBlk_SDB = 0x0B;
static const byte SubBlk_FC = 0x0C;
static const byte SubBlk_SFC = 0x0D;
static const byte SubBlk_FB = 0x0E;
static const byte SubBlk_SFB = 0x0F;
// Block languages
static const byte BlockLangAWL = 0x01;
static const byte BlockLangKOP = 0x02;
static const byte BlockLangFUP = 0x03;
static const byte BlockLangSCL = 0x04;
static const byte BlockLangDB = 0x05;
static const byte BlockLangGRAPH = 0x06;
// Read/Write Multivars
typedef struct {
int Area;
int WordLen;
int Result;
int DBNumber;
int Start;
int Amount;
void* pdata;
} TS7DataItem, * PS7DataItem;
//typedef int TS7ResultItems[MaxVars];
//typedef TS7ResultItems *PS7ResultItems;
// List Blocks
typedef struct {
int OBCount;
int FBCount;
int FCCount;
int SFBCount;
int SFCCount;
int DBCount;
int SDBCount;
} TS7BlocksList, * PS7BlocksList;
// Blocks info
typedef struct {
int BlkType; // Block Type (OB, DB)
int BlkNumber; // Block number
int BlkLang; // Block Language
int BlkFlags; // Block flags
int MC7Size; // The real size in bytes
int LoadSize; // Load memory size
int LocalData; // Local data
int SBBLength; // SBB Length
int CheckSum; // Checksum
int Version; // Block version
// Chars info
char CodeDate[11]; // Code date
char IntfDate[11]; // Interface date
char Author[9]; // Author
char Family[9]; // Family
char Header[9]; // Header
} TS7BlockInfo, * PS7BlockInfo;
typedef word TS7BlocksOfType[0x2000];
typedef TS7BlocksOfType* PS7BlocksOfType;
// Order code
typedef struct {
char Code[21];
byte V1;
byte V2;
byte V3;
} TS7OrderCode, * PS7OrderCode;
// CPU Info
typedef struct {
char ModuleTypeName[33];
char SerialNumber[25];
char ASName[25];
char Copyright[27];
char ModuleName[25];
} TS7CpuInfo, * PS7CpuInfo;
// CP Info
typedef struct {
int MaxPduLengt;
int MaxConnections;
int MaxMpiRate;
int MaxBusRate;
} TS7CpInfo, * PS7CpInfo;
// See §33.1 of "System Software for S7-300/400 System and Standard Functions"
// and see SFC51 description too
typedef struct {
word LENTHDR;
word N_DR;
} SZL_HEADER, * PSZL_HEADER;
typedef struct {
SZL_HEADER Header;
byte Data[0x4000 - 4];
} TS7SZL, * PS7SZL;
// SZL List of available SZL IDs : same as SZL but List items are big-endian adjusted
typedef struct {
SZL_HEADER Header;
word List[0x2000 - 2];
} TS7SZLList, * PS7SZLList;
// See §33.19 of "System Software for S7-300/400 System and Standard Functions"
typedef struct {
word sch_schal;
word sch_par;
word sch_rel;
word bart_sch;
word anl_sch;
} TS7Protection, * PS7Protection;
// Client completion callback
typedef void (*pfn_CliCompletion) (void* usrPtr, int opCode, int opResult);
//------------------------------------------------------------------------------
// Import prototypes
//------------------------------------------------------------------------------
S7Object Cli_Create();
void Cli_Destroy(S7Object* Client);
int Cli_ConnectTo(S7Object Client, const char* Address, int Rack, int Slot);
int Cli_SetConnectionParams(S7Object Client, const char* Address, word LocalTSAP, word RemoteTSAP);
int Cli_SetConnectionType(S7Object Client, word ConnectionType);
int Cli_Connect(S7Object Client);
int Cli_Disconnect(S7Object Client);
int Cli_GetParam(S7Object Client, int ParamNumber, void* pValue);
int Cli_SetParam(S7Object Client, int ParamNumber, void* pValue);
int Cli_SetAsCallback(S7Object Client, pfn_CliCompletion pCompletion, void* usrPtr);
// Data I/O main functions
int Cli_ReadArea(S7Object Client, int Area, int DBNumber, int Start, int Amount, int WordLen, void* pUsrData);
int Cli_WriteArea(S7Object Client, int Area, int DBNumber, int Start, int Amount, int WordLen, void* pUsrData);
int Cli_ReadMultiVars(S7Object Client, PS7DataItem Item, int ItemsCount);
int Cli_WriteMultiVars(S7Object Client, PS7DataItem Item, int ItemsCount);
// Data I/O Lean functions
int Cli_DBRead(S7Object Client, int DBNumber, int Start, int Size, void* pUsrData);
int Cli_DBWrite(S7Object Client, int DBNumber, int Start, int Size, void* pUsrData);
int Cli_MBRead(S7Object Client, int Start, int Size, void* pUsrData);
int Cli_MBWrite(S7Object Client, int Start, int Size, void* pUsrData);
int Cli_EBRead(S7Object Client, int Start, int Size, void* pUsrData);
int Cli_EBWrite(S7Object Client, int Start, int Size, void* pUsrData);
int Cli_ABRead(S7Object Client, int Start, int Size, void* pUsrData);
int Cli_ABWrite(S7Object Client, int Start, int Size, void* pUsrData);
int Cli_TMRead(S7Object Client, int Start, int Amount, void* pUsrData);
int Cli_TMWrite(S7Object Client, int Start, int Amount, void* pUsrData);
int Cli_CTRead(S7Object Client, int Start, int Amount, void* pUsrData);
int Cli_CTWrite(S7Object Client, int Start, int Amount, void* pUsrData);
// Directory functions
int Cli_ListBlocks(S7Object Client, TS7BlocksList* pUsrData);
int Cli_GetAgBlockInfo(S7Object Client, int BlockType, int BlockNum, TS7BlockInfo* pUsrData);
int Cli_GetPgBlockInfo(S7Object Client, void* pBlock, TS7BlockInfo* pUsrData, int Size);
int Cli_ListBlocksOfType(S7Object Client, int BlockType, TS7BlocksOfType* pUsrData, int* ItemsCount);
// Blocks functions
int Cli_Upload(S7Object Client, int BlockType, int BlockNum, void* pUsrData, int* Size);
int Cli_FullUpload(S7Object Client, int BlockType, int BlockNum, void* pUsrData, int* Size);
int Cli_Download(S7Object Client, int BlockNum, void* pUsrData, int Size);
int Cli_Delete(S7Object Client, int BlockType, int BlockNum);
int Cli_DBGet(S7Object Client, int DBNumber, void* pUsrData, int* Size);
int Cli_DBFill(S7Object Client, int DBNumber, int FillChar);
// Date/Time functions
int Cli_GetPlcDateTime(S7Object Client, tm* DateTime);
int Cli_SetPlcDateTime(S7Object Client, tm* DateTime);
int Cli_SetPlcSystemDateTime(S7Object Client);
// System Info functions
int Cli_GetOrderCode(S7Object Client, TS7OrderCode* pUsrData);
int Cli_GetCpuInfo(S7Object Client, TS7CpuInfo* pUsrData);
int Cli_GetCpInfo(S7Object Client, TS7CpInfo* pUsrData);
int Cli_ReadSZL(S7Object Client, int ID, int Index, TS7SZL* pUsrData, int* Size);
int Cli_ReadSZLList(S7Object Client, TS7SZLList* pUsrData, int* ItemsCount);
// Control functions
int Cli_PlcHotStart(S7Object Client);
int Cli_PlcColdStart(S7Object Client);
int Cli_PlcStop(S7Object Client);
int Cli_CopyRamToRom(S7Object Client, int Timeout);
int Cli_Compress(S7Object Client, int Timeout);
int Cli_GetPlcStatus(S7Object Client, int* Status);
// Security functions
int Cli_GetProtection(S7Object Client, TS7Protection* pUsrData);
int Cli_SetSessionPassword(S7Object Client, char* Password);
int Cli_ClearSessionPassword(S7Object Client);
// Low level
int Cli_IsoExchangeBuffer(S7Object Client, void* pUsrData, int* Size);
// Misc
int Cli_GetExecTime(S7Object Client, int* Time);
int Cli_GetLastError(S7Object Client, int* LastError);
int Cli_GetPduLength(S7Object Client, int* Requested, int* Negotiated);
int Cli_ErrorText(int Error, char* Text, int TextLen);
// 1.1.0
int Cli_GetConnected(S7Object Client, int* Connected);
//------------------------------------------------------------------------------
// Async functions
//------------------------------------------------------------------------------
int Cli_AsReadArea(S7Object Client, int Area, int DBNumber, int Start, int Amount, int WordLen, void* pUsrData);
int Cli_AsWriteArea(S7Object Client, int Area, int DBNumber, int Start, int Amount, int WordLen, void* pUsrData);
int Cli_AsDBRead(S7Object Client, int DBNumber, int Start, int Size, void* pUsrData);
int Cli_AsDBWrite(S7Object Client, int DBNumber, int Start, int Size, void* pUsrData);
int Cli_AsMBRead(S7Object Client, int Start, int Size, void* pUsrData);
int Cli_AsMBWrite(S7Object Client, int Start, int Size, void* pUsrData);
int Cli_AsEBRead(S7Object Client, int Start, int Size, void* pUsrData);
int Cli_AsEBWrite(S7Object Client, int Start, int Size, void* pUsrData);
int Cli_AsABRead(S7Object Client, int Start, int Size, void* pUsrData);
int Cli_AsABWrite(S7Object Client, int Start, int Size, void* pUsrData);
int Cli_AsTMRead(S7Object Client, int Start, int Amount, void* pUsrData);
int Cli_AsTMWrite(S7Object Client, int Start, int Amount, void* pUsrData);
int Cli_AsCTRead(S7Object Client, int Start, int Amount, void* pUsrData);
int Cli_AsCTWrite(S7Object Client, int Start, int Amount, void* pUsrData);
int Cli_AsListBlocksOfType(S7Object Client, int BlockType, TS7BlocksOfType* pUsrData, int* ItemsCount);
int Cli_AsReadSZL(S7Object Client, int ID, int Index, TS7SZL* pUsrData, int* Size);
int Cli_AsReadSZLList(S7Object Client, TS7SZLList* pUsrData, int* ItemsCount);
int Cli_AsUpload(S7Object Client, int BlockType, int BlockNum, void* pUsrData, int* Size);
int Cli_AsFullUpload(S7Object Client, int BlockType, int BlockNum, void* pUsrData, int* Size);
int Cli_AsDownload(S7Object Client, int BlockNum, void* pUsrData, int Size);
int Cli_AsCopyRamToRom(S7Object Client, int Timeout);
int Cli_AsCompress(S7Object Client, int Timeout);
int Cli_AsDBGet(S7Object Client, int DBNumber, void* pUsrData, int* Size);
int Cli_AsDBFill(S7Object Client, int DBNumber, int FillChar);
int Cli_CheckAsCompletion(S7Object Client, int* opResult);
int Cli_WaitAsCompletion(S7Object Client, int Timeout);
#endif // snap7_h

View File

@ -16,4 +16,27 @@
* @version 3.0
* @author AIIT XUOS Lab
* @date 2022-10-08
*/
*/
#ifndef S7_H
#define S7_H
#include <control_def.h>
#include "libs7.h"
#define BASE_PLC_RECV_BUFF_SIZE 1024
ControlProtocolType control_protocol;
int8_t ReadPlcDataByRecipe(struct ControlRecipe *p_recipe);
void voidpush(uint8_t *datastack,uint8_t* args,uint16_t length);
static uint8_t GetUniformValueTypeMemorySize(UniformValueType uniform_value_type);
typedef struct
{
TS7DataItem data_info;
UniformValueType value_type;
char value_name[20];
}S7ReadItem;
#endif

View File

@ -1,4 +1,2 @@
SRC_FILES :=
SRC_FILES := libs7.a s7.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,242 @@
/*
* Copyright (c) 2022 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file s7.c
* @brief plc protocol s7
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023-4-14
*/
#include <s7.h>
/**
* @description: S7 Receive Plc Data Task
* @param parameter - parameter pointer
* @return
*/
void *ReceivePlcDataTask(void *parameter)
{
printf("%s %d\n", __func__, __LINE__);
ReadPlcDataByRecipe(control_protocol->recipe);
}
/**
* @description: S7 Protocol Open
* @param control_protocol - control protocol pointer
* @return success : 0 error
*/
int S7Open(struct ControlProtocol *control_protocol)
{
ControlProtocolOpenDef(control_protocol);
return 0;
}
/**
* @description: S7 Protocol Close
* @param control_protocol - control protocol pointer
* @return success : 0 error
*/
int S7Close(struct ControlProtocol *control_protocol)
{
ControlProtocolCloseDef();
return 0;
}
/**
* @description: S7 Protocol Read Data
* @param control_protocol - control protocol pointer
* @param buf - read data buffer pointer
* @param len - read data length
* @return success : data length error : 0
*/
int S7Read(struct ControlProtocol *control_protocol, void *buf, size_t len)
{
struct CircularAreaApp *circular_area = (struct CircularAreaApp *)control_protocol->args;
return CircularAreaAppRead(circular_area, buf, len);
}
static struct ControlDone s7_protocol_done =
{
._open = S7Open,
._close = S7Close,
._read = S7Read,
._write = NULL,
._ioctl = NULL,
};
/**
* @description: Push Data Onto a Stack One By One
* @param datastack - data stack pointer
* @param args - data pointer
* @param length - data length
* @return
*/
void PushDataIntoStack(uint8_t *datastack,uint8_t* args,uint16_t length)
{
static int index = 8;
for(int i =0; i < length; i ++) {
datastack[index] = args[i];
index++;
if(index >= control_protocol->recipe->protocol_data.data_length){
index = 8;
}
}
}
/**
* @description: Read PLC Data By Recipe
* @param p_recipe - recipe pointer
* @return success : 0 error : -1
*/
int8_t ReadPlcDataByRecipe(struct ControlRecipe *p_recipe)
{
uint16_t data_length = control_protocol->recipe->protocol_data.data_length;
uint8_t *s7_data = control_protocol->recipe->protocol_data.data;
struct CircularAreaApp *circular_area = (struct CircularAreaApp *)control_protocol->args;
S7Object s7_plc = {0};
char plc_ip_string[15] = {0};
s7_plc = Cli_Create();
sprintf(plc_ip_string, "%u.%u.%u.%u",
p_recipe->socket_config.plc_ip[0],
p_recipe->socket_config.plc_ip[1],
p_recipe->socket_config.plc_ip[2],
p_recipe->socket_config.plc_ip[3]);
int16_t read_item_count = p_recipe->read_item_count;
uint8_t *p_read_item = (uint8_t *)(p_recipe->read_item);
while (1) {
int8_t error = 0;
while (!error) {
uint16_t i = 0;
for (i = 0; i < read_item_count; i ++) {
int is_connected = 0;
Cli_GetConnected(s7_plc, &is_connected);
while (!is_connected) {
if (Cli_ConnectTo(s7_plc, plc_ip_string, 0, 1) != 0) {
PrivTaskDelay(1000);
} else {
break;
}
}
TS7DataItem data_info = ((S7ReadItem*)p_read_item + i)->data_info;
Cli_ReadMultiVars(s7_plc, &data_info, 1);
uint16_t Size = GetValueTypeMemorySize(((S7ReadItem*)p_read_item + i)->value_type);
ControlPrintfList("S7 RECV", data_info.pdata,Size);
PushDataIntoStack(s7_data,data_info.pdata,Size);
PrivTaskDelay(100);
}
/*read all variable item data, put them into circular_area*/
if (i == read_item_count) {
printf("%s get %d item %d length\n", __func__, i, data_length);
CircularAreaAppWrite(circular_area, s7_data, data_length, 0);
}
}
}
return 0;
}
/**
* @description: S7 Protocol read item Init
* @param p_read_item - read item pointer
* @param read_item_json - read item json pointer
* @param p_data - unused
* @return success : 0 error : -1
*/
static uint8_t InitialS7ReadItem(S7ReadItem* p_read_item, cJSON* read_item_json, uint8_t* p_data)
{
p_read_item->value_type = cJSON_GetObjectItem(read_item_json, "value_type")->valueint;
strncpy(p_read_item->value_name, cJSON_GetObjectItem(read_item_json, "value_name")->valuestring, 20);
TS7DataItem* p_data_info = &(p_read_item->data_info);
p_data_info->Amount = cJSON_GetObjectItem(read_item_json, "amount")->valueint;
p_data_info->Start = cJSON_GetObjectItem(read_item_json, "start")->valueint;
p_data_info->DBNumber = cJSON_GetObjectItem(read_item_json, "db_number")->valueint;
char* area_valuestring = cJSON_GetObjectItem(read_item_json, "area")->valuestring;
if (strcmp(area_valuestring, "I") == 0)
p_data_info->Area = S7AreaPE;
else if (strcmp(area_valuestring, "Q") == 0)
p_data_info->Area = S7AreaPA;
else if (strcmp(area_valuestring, "M") == 0)
p_data_info->Area = S7AreaMK;
else if (strcmp(area_valuestring, "DB") == 0)
p_data_info->Area = S7AreaDB;
else if (strcmp(area_valuestring, "C") == 0)
p_data_info->Area = S7AreaCT;
else if (strcmp(area_valuestring, "T") == 0)
p_data_info->Area = S7AreaTM;
char* wordlen_valuestring = cJSON_GetObjectItem(read_item_json, "wordlen")->valuestring;
if (strcmp(wordlen_valuestring, "Bit") == 0)
p_data_info->WordLen = S7WLBit;
else if (strcmp(wordlen_valuestring, "Byte") == 0)
p_data_info->WordLen = S7WLByte;
else if (strcmp(wordlen_valuestring, "Word") == 0)
p_data_info->WordLen = S7WLWord;
else if (strcmp(wordlen_valuestring, "DWord") == 0)
p_data_info->WordLen = S7WLDWord;
else if (strcmp(wordlen_valuestring, "Real") == 0)
p_data_info->WordLen = S7WLReal;
else if (strcmp(wordlen_valuestring, "Counter") == 0)
p_data_info->WordLen = S7WLCounter;
else if (strcmp(wordlen_valuestring, "Timer") == 0)
p_data_info->WordLen = S7WLTimer;
p_data_info->pdata = p_data;
printf("value_type is %d, amount is %d, start is %04d, db_number is %d, area is 0x%03x, wordlen is %d.\n",
p_read_item->value_type, p_data_info->Amount, p_data_info->Start, p_data_info->DBNumber,
p_data_info->Area, p_data_info->WordLen);
return GetValueTypeMemorySize(p_read_item->value_type);
}
/**
* @description: S7 Protocol Cmd Generate
* @param p_recipe - recipe pointer
* @param protocol_format_info - protocol format info pointer
* @return success : 0 error : -1
*/
int S7ProtocolFormatCmd(struct ControlRecipe *p_recipe, ProtocolFormatInfo *protocol_format_info)
{
int ret = 0;
uint8_t *S7_plc_read_data = PrivMalloc(p_recipe->protocol_data.data_length);
uint16_t S7_plc_read_data_index = 8;
cJSON *read_single_item_json = protocol_format_info->read_single_item_json;
int i = protocol_format_info->read_item_index;
if (0 == i)
p_recipe->read_item = PrivMalloc(sizeof(S7ReadItem) * p_recipe->read_item_count);
S7_plc_read_data_index += InitialS7ReadItem((S7ReadItem *)(p_recipe->read_item) + i,
read_single_item_json, S7_plc_read_data + S7_plc_read_data_index);
if (S7_plc_read_data_index == 8) {
ret = -1;
printf("%s read %d item failed!\n", __func__, i);
}
return ret;
}
/**
* @description: S7 Protocol Init
* @param p_recipe - recipe pointer
* @return success : 0 error : -1
*/
int S7ProtocolInit(struct ControlRecipe *p_recipe)
{
p_recipe->read_item = PrivMalloc(sizeof(S7ReadItem) * p_recipe->read_item_count);
if (NULL == p_recipe->read_item) {
PrivFree(p_recipe->read_item);
return -1;
}
memset(p_recipe->read_item, 0, sizeof(S7ReadItem));
p_recipe->ControlProtocolFormatCmd = S7ProtocolFormatCmd;
p_recipe->done = &s7_protocol_done;
return 0;
}

View File

@ -0,0 +1,88 @@
{
"device_id": 1,
"device_name": "demo",
"communication_type": 0,
"socket_config": {
"plc_ip": "192.168.250.2",
"local_ip": "192.168.250.233",
"gateway": "192.168.250.252",
"netmask": "255.255.255.0",
"port": 102
},
"protocol_type": 1,
"read_period": 100,
"read_item_list": [
{
"value_name": "浮点数",
"value_type": 9,
"area": "DB",
"wordlen": "Real",
"db_number": 18,
"start": 18,
"amount": 1
},
{
"value_name": "整型1",
"value_type": 3,
"area": "M",
"wordlen": "WORD",
"db_number": 1,
"start": 100,
"amount": 1
},
{
"value_name": "整型2",
"value_type": 3,
"area": "M",
"wordlen": "WORD",
"db_number": 1,
"start": 102,
"amount": 1
},
{
"value_name": "布尔1",
"value_type": 1,
"area": "Q",
"wordlen": "Bit",
"db_number": 1,
"start": 1,
"amount": 1
},
{
"value_name": "布尔2",
"value_type": 1,
"area": "Q",
"wordlen": "Bit",
"db_number": 1,
"start": 2,
"amount": 1
},
{
"value_name": "布尔3",
"value_type": 1,
"area": "Q",
"wordlen": "Bit",
"db_number": 1,
"start": 3,
"amount": 1
},
{
"value_name": "布尔4",
"value_type": 1,
"area": "Q",
"wordlen": "Bit",
"db_number": 1,
"start": 4,
"amount": 1
},
{
"value_name": "整型3",
"value_type": 3,
"area": "DB",
"wordlen": "Word",
"db_number": 18,
"start": 2,
"amount": 1
}
]
}

View File

@ -21,8 +21,6 @@
#include <control.h>
#include <control_def.h>
ControlProtocolType control_protocol;
/**
* @description: Control Framework Find certain Protocol
* @param void
@ -292,6 +290,8 @@ int ControlFrameworkInit(void)
PrivFree(control_protocol);
goto _out;
}
printf("%u %u\n",control_protocol->recipe->total_data_length,control_protocol->recipe->device_id);
printf("%s ControlPeripheralInit done\n", __func__);

View File

@ -24,10 +24,13 @@
#include <transform.h>
#include <list.h>
#ifdef __cplusplus
extern "C" {
#endif
struct ControlProtocol;
typedef struct ControlProtocol *ControlProtocolType;
@ -108,6 +111,9 @@ int ControlProtocolWrite(struct ControlProtocol *control_protocol, const void *b
/*Control Framework Protocol Ioctl*/
int ControlProtocolIoctl(struct ControlProtocol *control_protocol, int cmd, void *args);
/*Control Framework new certain Protocol*/
ControlProtocolType control_protocol;
#ifdef __cplusplus
}
#endif

View File

@ -45,6 +45,10 @@ extern int ModbusTcpProtocolInit(struct ControlRecipe *p_recipe);
extern int ModbusUartProtocolInit(struct ControlRecipe *p_recipe);
#endif
#ifdef CONTROL_PROTOCOL_S7
extern int S7ProtocolInit(struct ControlRecipe *p_recipe);
#endif
/*
CONTROL FRAMEWORK READ DATA FORMAT:
| HEAD |device_id|read data length|read item count| data |
@ -80,6 +84,9 @@ static struct ControlProtocolInitParam protocol_init[] =
#ifdef CONTROL_PROTOCOL_MODBUS_UART
{ PROTOCOL_MODBUS_UART, ModbusUartProtocolInit },
#endif
#ifdef CONTROL_PROTOCOL_S7
{ PROTOCOL_S7, S7ProtocolInit },
#endif
{ PROTOCOL_END, NULL },
};
@ -445,30 +452,24 @@ void RecipeReadVariableItem(struct ControlRecipe *p_recipe, cJSON *p_recipe_file
p_recipe->protocol_data.data = PrivMalloc(CONTROL_DATA_HEAD_LENGTH + p_recipe->total_data_length);
p_recipe->protocol_data.data_length = CONTROL_DATA_HEAD_LENGTH + p_recipe->total_data_length;
memset(p_recipe->protocol_data.data, 0, p_recipe->protocol_data.data_length);
protocol_format_info.p_read_item_data = p_recipe->protocol_data.data + CONTROL_DATA_HEAD_LENGTH;
/*Init The Control Protocol*/
ControlProtocolInitDesc(p_recipe, protocol_init);
/*Format Data Header, Reference "CONTROL FRAMEWORK READ DATA FORMAT"*/
FormatDataHeader(p_recipe);
uint16_t read_item_count = p_recipe->read_item_count;
for (i = 0; i < read_item_count; i ++) {
cJSON *read_single_item_json = cJSON_GetArrayItem(read_item_list_json, i);
protocol_format_info.read_single_item_json = read_single_item_json;
protocol_format_info.read_item_index = i;
/*Format Protocol Cmd By Analyze Variable Item One By One*/
ret = p_recipe->ControlProtocolFormatCmd(p_recipe, &protocol_format_info);
if (ret < 0) {
printf("%s read %d item failed!\n", __func__, i);
continue;
if (ret < 0) {
printf("%s read %d item failed!\n", __func__, i);
continue;
}
}
}
}

View File

@ -44,6 +44,7 @@ extern "C" {
} \
}while (0)
typedef enum
{
UNIFORM_BOOL = 1,

View File

@ -5,4 +5,6 @@ source "$KERNEL_DIR/lib/Kconfig"
source "$KERNEL_DIR/fs/Kconfig"
source "$KERNEL_DIR/tool/Kconfig"
source "$KERNEL_DIR/../../APP_Framework/Kconfig"

View File

@ -101,7 +101,7 @@ Reset_Handler:
strlt r0, [r1], #4
blt .LoopCopy1
ldr r0,=BootLoaderJumpApp
ldr r0,=ota_entry
blx r0
#else /* APP */
cpsid i /* Mask interrupts */

View File

@ -1,11 +1,11 @@
export CROSS_COMPILE ?=/usr/bin/arm-none-eabi-
export CFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g -fgnu89-inline -Wa,-mimplicit-it=thumb -Werror
export AFLAGS := -c -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -x assembler-with-cpp -Wa,-mimplicit-it=thumb -gdwarf-2
export LFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi_hc32f4a0.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link.lds
export CXXFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g -Werror
export CFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g -fgnu89-inline -Wa,-mimplicit-it=thumb -Werror
export AFLAGS := -c -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -x assembler-with-cpp -Wa,-mimplicit-it=thumb -gdwarf-2
export LFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi_hc32f4a0.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link.lds
export CXXFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g -Werror
export APPLFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi_app.map,-cref,-u, -T $(BSP_ROOT)/link_userspace.lds
export APPLFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi_app.map,-cref,-u, -T $(BSP_ROOT)/link_userspace.lds
export DEFINES := -DHAVE_CCONFIG_H -DHC32F4A0 -DUSE_DDL_DRIVER -DHAVE_SIGINFO

View File

@ -40,22 +40,6 @@ menu "xidatong-arm32 feature"
int "stack size for interrupt"
default 4096
config BSP_USING_OTA
bool "xidatong arm32 support OTA function"
default n
if BSP_USING_OTA
choice
prompt "compile bootloader bin or application bin."
default MCUBOOT_BOOTLOADER
config MCUBOOT_BOOTLOADER
bool "config as bootloader."
config MCUBOOT_APPLICATION
bool "config as application."
endchoice
endif
menu "config board peripheral"
config MOUNT_SDCARD
bool

View File

@ -64,8 +64,8 @@ Modification:
#include <connect_wdt.h>
#endif
#ifdef BSP_USING_OTA
#include <imxrt_ota.h>
#ifdef TOOL_USING_OTA
#include <ota.h>
#endif
#ifdef BSP_USING_SEMC
@ -365,49 +365,6 @@ struct InitSequenceDesc _board_init[] =
{ " NONE ",NONE },
};
#ifdef BSP_USING_OTA
static void OtaCmd(void)
{
int32_t size;
ota_info_t ota_info;
FLASH_Init();
UartConfig();
memcpy(&ota_info, (const void *)FLAG_FLAH_ADDRESS,sizeof(ota_info_t));
ota_info.status = OTA_STATUS_DOWNLOADING;
UpdateOTAFlag(&ota_info);
size = SerialDownload(DOWN_FLAH_ADDRESS);
ota_info.status = OTA_STATUS_DOWNLOADED;
UpdateOTAFlag(&ota_info);
if(size > 0)
{
ota_info.down.size = size;
ota_info.down.crc32= calculate_crc32(DOWN_FLAH_ADDRESS, size);
ota_info.down.version = ota_info.os.version + 1;
strncpy(ota_info.down.description, "OTA Test!",sizeof(ota_info.down.description));
ota_info.status = OTA_STATUS_READY;
strncpy(ota_info.error_message, "No error message!",sizeof(ota_info.error_message));
UpdateOTAFlag(&ota_info);
}
else
{
ota_info.status = OTA_STATUS_ERROR;
strncpy(ota_info.error_message, "Failed to download firmware to download partition!",sizeof(ota_info.error_message));
UpdateOTAFlag(&ota_info);
}
FLASH_DeInit();
__set_FAULTMASK(1);
NVIC_SystemReset();
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),ota, OtaCmd, ota function);
#endif
/**
* This function will initial imxrt1050 board.
*/
@ -456,9 +413,8 @@ void InitBoardHardware()
KPrintf("board init done.\n");
KPrintf("start kernel...\n");
#ifdef BSP_USING_OTA
FLASH_Init();
//跳转成功将对应跳转失败标志清零
FLASH_DeInit();
#ifdef TOOL_USING_OTA
//跳转成功设置lastjumpflag为JUMP_SUCCESS_FLAG
app_clear_jumpflag();
#endif
}

View File

@ -4,8 +4,8 @@ ifeq ($(CONFIG_BSP_USING_SDIO),y)
SRC_FILES += fsl_usdhc.c
endif
ifeq ($(CONFIG_BSP_USING_OTA),y)
SRC_FILES += fsl_romapi.c flash.c mcuboot.c common.c ymodem.c imxrt_ota.c
ifeq ($(CONFIG_TOOL_USING_OTA),y)
SRC_FILES += fsl_romapi.c flash.c mcuboot.c common.c ymodem.c
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -14,7 +14,6 @@
*/
#include <stdio.h>
#include <xs_base.h>
#include "flash.h"
#include "MIMXRT1052.h"
@ -58,11 +57,11 @@ static const lookuptable_t FlashLookupTable={
/*******************************************************************************
* : Flexspi_Nor_Wait_Busy
* : FlexSPI NOR Flash忙碌状态结束
* : instance:FlexSPI实例号
baseAddr:Flash地址(32bit)
* : kStatus_Success
* : Flexspi_Nor_Wait_Busy
* : FlexSPI NOR Flash忙碌状态结束
* : instance:FlexSPI实例号
baseAddr:Flash地址(32bit)
* : kStatus_Success
*******************************************************************************/
static status_t Flexspi_Nor_Wait_Busy(uint32_t instance, uint32_t baseAddr)
{
@ -101,11 +100,11 @@ static status_t Flexspi_Nor_Wait_Busy(uint32_t instance, uint32_t baseAddr)
/*******************************************************************************
* : Flexspi_Nor_Write_Enable
* : 使 FlexSPI NOR Flash的写入操作
* : instance:FlexSPI实例号
baseAddr:Flash地址(32bit)
* : kStatus_Success
* : Flexspi_Nor_Write_Enable
* : 使 FlexSPI NOR Flash的写入操作
* : instance:FlexSPI实例号
baseAddr:Flash地址(32bit)
* : kStatus_Success
*******************************************************************************/
static status_t Flexspi_Nor_Write_Enable(uint32_t instance, uint32_t baseAddr)
{
@ -125,12 +124,12 @@ static status_t Flexspi_Nor_Write_Enable(uint32_t instance, uint32_t baseAddr)
/*******************************************************************************
* : flexspi_clock_config
* : FlexSPI模块的时钟
* : instance:FlexSPI实例号
freq:FlexSPI时钟频率
sampleClkMode:FlexSPI时钟的采样时钟模式,SDR或DDR模式
* : kStatus_Success
* : flexspi_clock_config
* : FlexSPI模块的时钟
* : instance:FlexSPI实例号
freq:FlexSPI时钟频率
sampleClkMode:FlexSPI时钟的采样时钟模式,SDR或DDR模式
* : kStatus_Success
*******************************************************************************/
static void flexspi_clock_config(uint32_t instance, uint32_t freq, uint32_t sampleClkMode)
{
@ -210,10 +209,10 @@ static void flexspi_clock_config(uint32_t instance, uint32_t freq, uint32_t samp
/*******************************************************************************
* : flexspi_clock_gate_enable
* : FlexSPI模块的时钟门控
* :
* :
* : flexspi_clock_gate_enable
* : FlexSPI模块的时钟门控
* :
* :
*******************************************************************************/
static void flexspi_clock_gate_enable(void)
{
@ -222,10 +221,10 @@ static void flexspi_clock_gate_enable(void)
/*******************************************************************************
* : flexspi_clock_gate_disable
* : FlexSPI模块的时钟门控
* :
* :
* : flexspi_clock_gate_disable
* : FlexSPI模块的时钟门控
* :
* :
*******************************************************************************/
static void flexspi_clock_gate_disable(void)
{
@ -234,12 +233,12 @@ static void flexspi_clock_gate_disable(void)
/*******************************************************************************
* : flexspi_get_clock
* : FlexSPI时钟频率
* : instance:FlexSPI实例号
type:
freq:
* : kStatus_Success
* : flexspi_get_clock
* : FlexSPI时钟频率
* : instance:FlexSPI实例号
type:
freq:
* : kStatus_Success
*******************************************************************************/
static status_t flexspi_get_clock(uint32_t instance, flexspi_clock_type_t type, uint32_t *freq)
{
@ -291,13 +290,13 @@ static status_t flexspi_get_clock(uint32_t instance, flexspi_clock_type_t type,
/*******************************************************************************
* : flexspi_get_ticks
* : FlexSPI时钟周期数
* : ticks:
intervalNs:ns
freq:FlexSPI时钟频率MHz
unit:,,ns为单位
* : kStatus_Success
* : flexspi_get_ticks
* : FlexSPI时钟周期数
* : ticks:
intervalNs:ns
freq:FlexSPI时钟频率MHz
unit:,,ns为单位
* : kStatus_Success
*******************************************************************************/
static status_t flexspi_get_ticks(uint32_t *ticks, uint32_t intervalNs, uint32_t freq, uint32_t unit)
{
@ -330,11 +329,11 @@ static status_t flexspi_get_ticks(uint32_t *ticks, uint32_t intervalNs, uint32_t
/*******************************************************************************
* : flexspi_configure_dll
* : FLEXSPI存储器的DLL()
* : instance:FLEXSPI实例号
config:
* : kStatus_Success
* : flexspi_configure_dll
* : FLEXSPI存储器的DLL()
* : instance:FLEXSPI实例号
config:
* : kStatus_Success
*******************************************************************************/
static status_t flexspi_configure_dll(uint32_t instance, flexspi_mem_config_t *config)
{
@ -473,11 +472,11 @@ static status_t flexspi_configure_dll(uint32_t instance, flexspi_mem_config_t *c
/*******************************************************************************
* : flexspi_config_mcr1
* : FlexSPI模块的MCR1寄存器
* : instance:FLEXSPI实例号
onfig指向FlexSPI存储器配置结构体的指针
* : kStatus_Success
* : flexspi_config_mcr1
* : FlexSPI模块的MCR1寄存器
* : instance:FLEXSPI实例号
onfig指向FlexSPI存储器配置结构体的指针
* : kStatus_Success
*******************************************************************************/
static status_t flexspi_config_mcr1(uint32_t instance, flexspi_mem_config_t *config)
{
@ -513,10 +512,10 @@ static status_t flexspi_config_mcr1(uint32_t instance, flexspi_mem_config_t *con
/*******************************************************************************
* : FLASH_GetSectorSize
* :
* :
* : ,HYPER FLASH为64K字节,NOR FLASH为4K字节
* : FLASH_GetSectorSize
* :
* :
* : ,HYPER FLASH为64K字节,NOR FLASH为4K字节
*******************************************************************************/
uint32_t FLASH_GetSectorSize(void)
{
@ -529,10 +528,10 @@ uint32_t FLASH_GetSectorSize(void)
/*******************************************************************************
* : FLASH_GetProgramCmd
* :
* :
* : ,HYPER FLASH为512字节,NOR FLASH为256字节
* : FLASH_GetProgramCmd
* :
* :
* : ,HYPER FLASH为512字节,NOR FLASH为256字节
*******************************************************************************/
uint32_t FLASH_GetProgramCmd(void)
{
@ -548,10 +547,10 @@ uint32_t FLASH_GetProgramCmd(void)
/*******************************************************************************
* : FLASH_Init
* : Flash接口初始化,Flash相关操作前进行调用
* :
* :
* : FLASH_Init
* : Flash接口初始化,Flash相关操作前进行调用
* :
* :
*******************************************************************************/
void FLASH_Init(void)
{
@ -567,10 +566,10 @@ void FLASH_Init(void)
/*******************************************************************************
* : FLASH_DeInit
* : Flash接口反初始化Flash相关操作后进行调用
* :
* :
* : FLASH_DeInit
* : Flash接口反初始化Flash相关操作后进行调用
* :
* :
*******************************************************************************/
void FLASH_DeInit(void)
{
@ -583,11 +582,11 @@ void FLASH_DeInit(void)
/*******************************************************************************
* : FLASH_EraseSector
* : Flash扇区
* : addr:
* : None
* : :30ms~200/400ms
* : FLASH_EraseSector
* : Flash扇区
* : addr:
* : None
* : :30ms~200/400ms
*******************************************************************************/
uint8_t FLASH_EraseSector(uint32_t addr)
{
@ -613,13 +612,13 @@ uint8_t FLASH_EraseSector(uint32_t addr)
/*******************************************************************************
* : FLASH_WritePage
* : Flash一个页
* : addr:
buf:
len:(256)
* : kStatus_Success
* : 256
* : FLASH_WritePage
* : Flash一个页
* : addr:
buf:
len:(256)
* : kStatus_Success
* : 256
*******************************************************************************/
uint8_t FLASH_WritePage(uint32_t addr, const uint32_t *buf, uint32_t len)
{
@ -648,12 +647,12 @@ uint8_t FLASH_WritePage(uint32_t addr, const uint32_t *buf, uint32_t len)
/*******************************************************************************
* : FLASH_Read
* : Flash内容
* : addr:
buf:
len:
* : kStatus_Success
* : FLASH_Read
* : Flash内容
* : addr:
buf:
len:
* : kStatus_Success
*******************************************************************************/
status_t FLASH_Read(uint32_t addr, uint32_t *buf, uint32_t len)
{
@ -680,12 +679,12 @@ status_t FLASH_Read(uint32_t addr, uint32_t *buf, uint32_t len)
/*******************************************************************************
* : flash_erase
* : Flash指定长度的空间
* : addr:
byte_cnt:,4k字节为最小擦除单位
* : kStatus_Success
* : 4k字节的4k字节
* : flash_erase
* : Flash指定长度的空间
* : addr:
byte_cnt:,4k字节为最小擦除单位
* : kStatus_Success
* : 4k字节的4k字节
*******************************************************************************/
status_t flash_erase(uint32_t start_addr, uint32_t byte_cnt)
{
@ -707,12 +706,12 @@ status_t flash_erase(uint32_t start_addr, uint32_t byte_cnt)
/*******************************************************************************
* : flash_write
* : flash起始地址写入指定长度的数据
* : addr:
buf:
byte_cnt:
* : kStatus_Success
* : flash_write
* : flash起始地址写入指定长度的数据
* : addr:
buf:
byte_cnt:
* : kStatus_Success
*******************************************************************************/
status_t flash_write(uint32_t start_addr, uint8_t *buf, uint32_t byte_cnt)
{
@ -736,12 +735,12 @@ status_t flash_write(uint32_t start_addr, uint8_t *buf, uint32_t byte_cnt)
/*******************************************************************************
* : flash_read
* : Flash内容
* : addr:
buf:
len:
* : kStatus_Success
* : flash_read
* : Flash内容
* : addr:
buf:
len:
* : kStatus_Success
*******************************************************************************/
status_t flash_read(uint32_t addr, uint8_t *buf, uint32_t len)
{
@ -768,12 +767,12 @@ status_t flash_read(uint32_t addr, uint8_t *buf, uint32_t len)
/*******************************************************************************
* : flash_copy
* : flash数据在分区之间的拷贝
* : srcAddr:flash的起始地址
dstAddr:flash的起始地址;
imageSize:flash空间大小,
* : kStatus_Success
* : flash_copy
* : flash数据在分区之间的拷贝
* : srcAddr:flash的起始地址
dstAddr:flash的起始地址;
imageSize:flash空间大小,
* : kStatus_Success
*******************************************************************************/
status_t flash_copy(uint32_t srcAddr,uint32_t dstAddr, uint32_t imageSize)
{
@ -834,11 +833,11 @@ status_t flash_copy(uint32_t srcAddr,uint32_t dstAddr, uint32_t imageSize)
/*******************************************************************************
* : NOR_FLASH_Erase
* : Flash指定长度的空间,imageSize
* : addr:
imageSize:
* : None
* : NOR_FLASH_Erase
* : Flash指定长度的空间,imageSize
* : addr:
imageSize:
* : None
*******************************************************************************/
status_t NOR_FLASH_Erase(uint32_t app_base_addr,uint32_t imageSize)
{
@ -860,13 +859,13 @@ status_t NOR_FLASH_Erase(uint32_t app_base_addr,uint32_t imageSize)
/*******************************************************************************
* : NorFlash_Write_PageProgram
* : Flash指定长度的数据
* : pBuffer:
WriteAddr:
NumByteToWrite:(256)
* : kStatus_Success
* : 256
* : NorFlash_Write_PageProgram
* : Flash指定长度的数据
* : pBuffer:
WriteAddr:
NumByteToWrite:(256)
* : kStatus_Success
* : 256
*******************************************************************************/
void NorFlash_Write_PageProgram(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
{
@ -883,24 +882,24 @@ void NorFlash_Write_PageProgram(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t Num
/*******************************************************************************
* : NorFlash_Write_NoCheck
* : W25QXX从指定地址开始指定长度的数据
* : pBuffer:
WriteAddr:(24bit)
NumByteToWrite:(65535)
* :
* : 0XFF,0XFF处写入的数据将失败!
,,!
* : NorFlash_Write_NoCheck
* : W25QXX从指定地址开始指定长度的数据
* : pBuffer:
WriteAddr:(24bit)
NumByteToWrite:(65535)
* :
* : 0XFF,0XFF处写入的数据将失败!
,,!
*******************************************************************************/
void NorFlash_Write_NoCheck(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
{
uint16_t pageRemain;
pageRemain = 256 - WriteAddr%256;//单页剩余的字节数
pageRemain = 256 - WriteAddr%256;//单页剩余的字节数
if(NumByteToWrite <= pageRemain)
{
pageRemain = NumByteToWrite;//不大于256个字节
pageRemain = NumByteToWrite;//不大于256个字节
}
while(1)
@ -908,21 +907,21 @@ void NorFlash_Write_NoCheck(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByte
NorFlash_Write_PageProgram(pBuffer,WriteAddr,pageRemain);
if(NumByteToWrite == pageRemain)
{
break;//写入结束了
break;//写入结束了
}
else //NumByteToWrite>pageRemain
{
pBuffer += pageRemain;
WriteAddr += pageRemain;
NumByteToWrite -= pageRemain;//减去已经写入了的字节数
NumByteToWrite -= pageRemain;//减去已经写入了的字节数
if(NumByteToWrite > 256)
{
pageRemain = 256;//一次可以写入256个字节
pageRemain = 256;//一次可以写入256个字节
}
else
{
pageRemain = NumByteToWrite;//不够256个字节了
pageRemain = NumByteToWrite;//不够256个字节了
}
}
}
@ -930,13 +929,13 @@ void NorFlash_Write_NoCheck(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByte
/*******************************************************************************
* : NorFlash_Write
* : W25QXX在指定地址开始写入指定长度的数据
* : pBuffer:
WriteAddr:(24bit)
NumByteToWrite:(65535)
* : None
* :
* : NorFlash_Write
* : W25QXX在指定地址开始写入指定长度的数据
* : pBuffer:
WriteAddr:(24bit)
NumByteToWrite:(65535)
* : None
* :
*******************************************************************************/
void NorFlash_Write(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
{
@ -946,61 +945,61 @@ void NorFlash_Write(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
uint16_t i;
uint8_t *NorFlash_BUF = 0;
NorFlash_BUF = NorFlash_BUFFER;//RAM缓冲区4K
NorFlash_BUF = NorFlash_BUFFER;//RAM缓冲区4K
WriteAddr &= 0x0FFFFFFF;
secPos = WriteAddr/SECTOR_SIZE;//扇区地址
secOff = WriteAddr%SECTOR_SIZE;//在扇区内的偏移
secRemain = SECTOR_SIZE - secOff;//扇区剩余空间大小
secPos = WriteAddr/SECTOR_SIZE;//扇区地址
secOff = WriteAddr%SECTOR_SIZE;//在扇区内的偏移
secRemain = SECTOR_SIZE - secOff;//扇区剩余空间大小
if(NumByteToWrite <= secRemain)
{
secRemain = NumByteToWrite;//不大于4096个字节
secRemain = NumByteToWrite;//不大于4096个字节
}
while(1)
{
FLASH_Read(FLASH_BASE + secPos*SECTOR_SIZE, (void *)NorFlash_BUF, SECTOR_SIZE);//读出整个扇区的内容
for(i=0;i<secRemain;i++)//校验数据
FLASH_Read(CHIP_FLAH_BASE + secPos*SECTOR_SIZE, (void *)NorFlash_BUF, SECTOR_SIZE);//读出整个扇区的内容
for(i=0;i<secRemain;i++)//校验数据
{
if(NorFlash_BUF[secOff+i] != 0xFF)
{
break;//需要擦除
break;//需要擦除
}
}
if(i < secRemain)//需要擦除
if(i < secRemain)//需要擦除
{
FLASH_EraseSector(FLASH_BASE + secPos*SECTOR_SIZE);
for(i=0;i<secRemain;i++)//复制
FLASH_EraseSector(CHIP_FLAH_BASE + secPos*SECTOR_SIZE);
for(i=0;i<secRemain;i++)//复制
{
NorFlash_BUF[i+secOff] = pBuffer[i];
}
NorFlash_Write_NoCheck(NorFlash_BUF,FLASH_BASE + secPos*SECTOR_SIZE,SECTOR_SIZE);//写入整个扇区
NorFlash_Write_NoCheck(NorFlash_BUF,CHIP_FLAH_BASE + secPos*SECTOR_SIZE,SECTOR_SIZE);//写入整个扇区
}
else
{
NorFlash_Write_NoCheck(pBuffer,FLASH_BASE + WriteAddr,secRemain);//写已经擦除了的,直接写入扇区剩余区间.
NorFlash_Write_NoCheck(pBuffer,CHIP_FLAH_BASE + WriteAddr,secRemain);//写已经擦除了的,直接写入扇区剩余区间.
}
if(NumByteToWrite == secRemain)
{
break;//写入结束了
break;//写入结束了
}
else//写入未结束
else//写入未结束
{
secPos++;//扇区地址增1
secOff=0;//偏移位置为0
secPos++;//扇区地址增1
secOff=0;//偏移位置为0
pBuffer += secRemain;//指针偏移
WriteAddr += secRemain;//写地址偏移
NumByteToWrite -= secRemain;//字节数递减
pBuffer += secRemain;//指针偏移
WriteAddr += secRemain;//写地址偏移
NumByteToWrite -= secRemain;//字节数递减
if(NumByteToWrite > SECTOR_SIZE)
{
secRemain = SECTOR_SIZE;//下一个扇区还是写不完
secRemain = SECTOR_SIZE;//下一个扇区还是写不完
}
else
{
secRemain = NumByteToWrite;//下一个扇区可以写完了
secRemain = NumByteToWrite;//下一个扇区可以写完了
}
}
}
@ -1008,12 +1007,12 @@ void NorFlash_Write(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
/*******************************************************************************
* : NOR_FLASH_Write
* : W25QXX在指定地址开始写入指定长度的数据
* : FlashAddress:Flash地址的指针
Data:
DataLength:
* : 0
* : NOR_FLASH_Write
* : W25QXX在指定地址开始写入指定长度的数据
* : FlashAddress:Flash地址的指针
Data:
DataLength:
* : 0
*******************************************************************************/
#ifndef USE_HIGHT_SPEED_TRANS
uint32_t NOR_FLASH_Write(uint32_t* FlashAddress, uint8_t* Data ,uint16_t DataLength)

View File

@ -1,224 +0,0 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file: imxrt_ota.c
* @brief: file imxrt_ota.c
* @version: 1.0
* @author: AIIT XUOS Lab
* @date: 2023/3/24
*/
#include <stdio.h>
#include <time.h>
#include <string.h>
#include "flash.h"
#include "common.h"
#include "imxrt_ota.h"
static const uint32_t crc32tab[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
/*******************************************************************************
* : calculate_crc32
* : Flash内存地址范围中数据的CRC32校验和
* : addr:Flash地址的起始位置
len:CRC32的数据长度
* : CRC32值
*******************************************************************************/
uint32_t calculate_crc32(uint32_t addr, uint32_t len)
{
uint32_t crc = 0xFFFFFFFF;
uint8_t byte = 0xFF;
for(uint32_t i = 0; i < len; i++)
{
byte = *((volatile uint8_t *)(addr + i));
crc = crc32tab[(crc ^ byte) & 0xff] ^ (crc >> 8);
}
return crc^0xFFFFFFFF;
}
/*******************************************************************************
* : UpdateOTAFlag
* : OTA Flag区域的信息app里进行调用
* : ptr:ota_info_t结构体指针,OTA升级相关信息
* : kStatus_Success
*******************************************************************************/
status_t UpdateOTAFlag(ota_info_t *ptr)
{
status_t status;
status = flash_erase(FLAG_FLAH_ADDRESS,sizeof(ota_info_t));
if(status != kStatus_Success)
{
return status;
}
status = flash_write(FLAG_FLAH_ADDRESS,(void *)ptr,sizeof(ota_info_t));
return status;
}
/*******************************************************************************
* : UpdateApplication
* : bootloader里进行调用,Flash中Flag分区中的信息决定是否进行版本更新
* :
* :
* : app分区
*******************************************************************************/
void UpdateApplication(void)
{
status_t status;
ota_info_t ota_info; // 定义OTA信息结构体
// 从Flash中读取OTA信息
memcpy(&ota_info, (const void *)FLAG_FLAH_ADDRESS,sizeof(ota_info_t));
// 如果OTA升级状态为准备状态且APP分区与download分区版本不同,才可以进行升级
if((ota_info.status == OTA_STATUS_READY) && (ota_info.os.crc32 != ota_info.down.crc32))
{
Serial_PutString("\r\n------Start to update the app!------\r\n");
// 校验downlad分区固件CRC
if(calculate_crc32(DOWN_FLAH_ADDRESS, ota_info.down.size) == ota_info.down.crc32)
{
ota_info.status = OTA_STATUS_UPDATING;
UpdateOTAFlag(&ota_info);
// 1.如果CRC校验通过,开始升级,逐字节拷贝Flash,先备份当前XiUOS System分区内容
status = flash_copy(XIUOS_FLAH_ADDRESS, BAKUP_FLAH_ADDRESS, ota_info.os.size);
if((status == kStatus_Success) &&(calculate_crc32(BAKUP_FLAH_ADDRESS, ota_info.os.size) == ota_info.os.crc32))
{
Serial_PutString("\r\n------Backup app success!------\r\n");
ota_info.bak.size = ota_info.os.size;
ota_info.bak.crc32 = ota_info.os.crc32;
ota_info.bak.version = ota_info.os.version;
strncpy(ota_info.bak.description, ota_info.os.description, sizeof(ota_info.os.description));
UpdateOTAFlag(&ota_info);
}
else
{
Serial_PutString("\r\n------Backup app failed!------\r\n");
ota_info.status = OTA_STATUS_ERROR;
strncpy(ota_info.error_message, "Backup app failed!",sizeof(ota_info.error_message));
UpdateOTAFlag(&ota_info);
goto finish;
}
// 2.拷贝download分区到XiUOS System分区
status = flash_copy(DOWN_FLAH_ADDRESS, XIUOS_FLAH_ADDRESS, ota_info.down.size);
if((status == kStatus_Success) &&(calculate_crc32(XIUOS_FLAH_ADDRESS, ota_info.down.size) == ota_info.down.crc32))
{
Serial_PutString("\r\n------The download partition is copied successfully!------\r\n");
ota_info.os.size = ota_info.down.size;
ota_info.os.crc32 = ota_info.down.crc32;
ota_info.os.version = ota_info.down.version;
strncpy(ota_info.os.description, ota_info.down.description, sizeof(ota_info.down.description));
ota_info.status == OTA_STATUS_IDLE; // 拷贝download分区到XiUOS System分区成功,将OTA升级状态设置为IDLE
UpdateOTAFlag(&ota_info);
}
else
{
Serial_PutString("\r\n------The download partition copy failed!------\r\n");
ota_info.status = OTA_STATUS_ERROR;
strncpy(ota_info.error_message, "The download partition copy failed!",sizeof(ota_info.error_message));
UpdateOTAFlag(&ota_info);
goto finish;
}
Serial_PutString("\r\n------Update completed!------\r\n");
goto finish;
}
else
{
// 如果download分区CRC校验失败升级失败
Serial_PutString("\r\n------Download Firmware CRC check failed!------\r\n");
ota_info.status = OTA_STATUS_ERROR;
strncpy(ota_info.error_message, "Download Firmware CRC check failed!",sizeof(ota_info.error_message));
UpdateOTAFlag(&ota_info);
goto finish;
}
}
else
{
Serial_PutString("\r\n------No need to update the app!------\r\n");
goto finish;
}
finish:
return;
}

View File

@ -15,112 +15,46 @@
#include <stdint.h>
#include <xs_base.h>
#include "imxrt_ota.h"
#include "common.h"
#include "mcuboot.h"
#include "flash.h"
#ifdef MCUBOOT_BOOTLOADER
extern void ImxrtMsDelay(uint32 ms);
#ifdef TOOL_USING_OTA
static void InitialVersion(void)
void mcuboot_bord_init(void)
{
int32_t size;
ota_info_t ota_info;
memset(&ota_info, 0, sizeof(ota_info_t));
size = SerialDownload(XIUOS_FLAH_ADDRESS);
if(size > 0)
{
ota_info.os.size = size;
ota_info.os.crc32 = calculate_crc32(XIUOS_FLAH_ADDRESS, size);
ota_info.os.version = 0x1;
strncpy(ota_info.os.description, "This is the initial firmware for the device!", sizeof(ota_info.os.description));
UpdateOTAFlag(&ota_info);
}
}
void jump_to_application(void)
{
SCB->VTOR = (uint32_t)XIUOS_FLAH_ADDRESS;
asm volatile("LDR R0, = 0x60100000");
asm volatile("LDR R0, [R0]");
asm volatile("MOV SP, R0");
asm volatile("LDR R0, = 0x60100000+4");
asm volatile("LDR R0, [R0]");
asm volatile("BX R0");
}
void BootLoaderJumpApp(void)
{
uint8_t ch1, ch2;
uint32_t ret;
ota_info_t ota_info;
uint32_t timeout = 500;
BOARD_ConfigMPU();
BOARD_InitPins();
BOARD_BootClockRUN();
UartConfig();
SysTick_Config(SystemCoreClock / TICK_PER_SECOND);
}
Serial_PutString("Please press 'space' key into menu in 5s !!!\r\n");
void mcuboot_reset(void)
{
__set_FAULTMASK(1);
NVIC_SystemReset();
}
void mcuboot_jump(void)
{
uint32_t addr = XIUOS_FLAH_ADDRESS;
SCB->VTOR = addr;
asm volatile("LDR R0, %0" : : "m"(addr));
asm volatile("LDR R0, [R0]");
asm volatile("MOV SP, R0");
while(timeout)
{
ret = (SerialKeyPressed((uint8_t*)&ch1));
if(ret) break;
timeout--;
ImxrtMsDelay(10);
}
addr += 4;
asm volatile("LDR R0, %0" : : "m"(addr));
asm volatile("LDR R0, [R0]");
asm volatile("BX R0");
}
while(1)
{
if((ret)&&(ch1 == 0x20))
{
Serial_PutString("\r\nPlease slecet:");
Serial_PutString("\r\n 1:run app");
Serial_PutString("\r\n 2:update app");
Serial_PutString("\r\n 3:reboot \r\n");
extern void ImxrtMsDelay(uint32 ms);
ch2 = GetKey();
switch(ch2)
{
case 0x31:
jump_to_application();
break;
case 0x32:
FLASH_Init();
memcpy(&ota_info, (const void *)FLAG_FLAH_ADDRESS,sizeof(ota_info_t));
/* 此时APP分区还没有有效的固件,需要在bootloader下通过iap烧写出厂固件 */
if((ota_info.os.size > APP_FLASH_SIZE) || (calculate_crc32(XIUOS_FLAH_ADDRESS, ota_info.os.size) != ota_info.os.crc32))
{
Serial_PutString("\r\nNeed to flash initial firmware!\r\n");
InitialVersion();
}
else
{
UpdateApplication();
}
FLASH_DeInit();
jump_to_application();
break;
case 0x33:
__set_FAULTMASK(1);
NVIC_SystemReset();
default:
break;
}
}
else
{
jump_to_application();
}
}
void mcuboot_delay(uint32_t ms)
{
ImxrtMsDelay(ms);
}
#endif

View File

@ -17,7 +17,7 @@
* @author: AIIT XUOS Lab
* @date: 2023/3/24
*/
#include <xs_base.h>
#include "ymodem.h"
#include "string.h"
#include "flash.h"

View File

@ -6,7 +6,7 @@
*/
/**
* @file fsl_flash.h
* @file flash.h
* @brief support flexspi norflash function
* @version 2.0
* @author AIIT XUOS Lab
@ -16,25 +16,19 @@
#ifndef __FLASH_H__
#define __FLASH_H__
#include <xs_base.h>
#include <stdint.h>
#include "fsl_romapi.h"
#define USE_HIGHT_SPEED_TRANS 1
#define FLASH_BASE 0x60000000
#define SECTOR_SIZE 0x1000
#define FLASH_PAGE_SIZE 256
#define APP_FLASH_SIZE 0x100000 //Application package size is limited to 1M
#define FLEXSPI_WAIT_TIMEOUT_NS (500000000UL) //FlexSPI timeout value, 500ms
#define FLEXSPI_FREQ_1GHz (1000000000UL)
#define FREQ_1MHz (1000000UL)
#define FLEXSPI_DLLCR_DEFAULT (0x100UL)
#define XIUOS_FLAH_ADDRESS 0x60100000
#define BAKUP_FLAH_ADDRESS 0x60300000
#define DOWN_FLAH_ADDRESS 0x60500000
#define FLAG_FLAH_ADDRESS 0x60700000
enum
{
kFlexSpiDelayCellUnit_Min = 75, // 75ps

View File

@ -22,8 +22,12 @@
#include "fsl_iomuxc.h"
#include "fsl_gpio.h"
#include "fsl_lpuart.h"
#include "common.h"
void jump_to_application(void);
void mcuboot_bord_init(void);
void mcuboot_reset(void);
void mcuboot_jump(void);
void mcuboot_delay(uint32_t ms);
#endif

View File

@ -555,6 +555,11 @@ KERNELPATHS +=-I$(KERNEL_ROOT)/tool/shell/letter-shell \
-I$(KERNEL_ROOT)/tool/shell/letter-shell/file_ext #
endif
ifeq ($(CONFIG_TOOL_USING_OTA), y)
KERNELPATHS +=-I$(KERNEL_ROOT)/tool/bootloader/flash \
-I$(KERNEL_ROOT)/tool/bootloader/ota #
endif
ifeq ($(CONFIG_FS_LWEXT4),y)
KERNELPATHS += -I$(KERNEL_ROOT)/fs/lwext4/lwext4_submodule/blockdev/xiuos #
KERNELPATHS += -I$(KERNEL_ROOT)/fs/lwext4/lwext4_submodule/include #

View File

@ -0,0 +1,5 @@
menu "Tool feature"
source "$KERNEL_DIR/tool/bootloader/Kconfig"
endmenu

View File

@ -4,4 +4,8 @@ ifeq ($(CONFIG_TOOL_SHELL),y)
SRC_DIR += shell
endif
ifeq ($(CONFIG_TOOL_USING_OTA),y)
SRC_DIR += bootloader
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,48 @@
menu "OTA function"
menuconfig TOOL_USING_OTA
bool "Enable support OTA function"
default n
if TOOL_USING_OTA
choice
prompt "Compile bootloader bin or application bin."
default MCUBOOT_BOOTLOADER
config MCUBOOT_BOOTLOADER
bool "Config as bootloader."
config MCUBOOT_APPLICATION
bool "Config as application."
endchoice
menu "Flash area address and size configuration."
config CHIP_FLAH_BASE
hex "Flash base address of the chip."
default 0x60000000
config XIUOS_FLAH_ADDRESS
hex "Flash area address of the XiUOS system."
default 0x60100000
config BAKUP_FLAH_ADDRESS
hex "Flash area address of the backup firmware."
default 0x60300000
config DOWN_FLAH_ADDRESS
hex "Flash area address of the downloaded firmware."
default 0x60500000
config FLAG_FLAH_ADDRESS
hex "Flash area address of the OTA information."
default 0x60700000
config APP_FLASH_SIZE
hex "Application package size,the default size is limited to 1M."
default 0x00100000
endmenu
endif
endmenu

View File

@ -0,0 +1,4 @@
SRC_DIR :=
SRC_DIR += flash ota
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,3 @@
SRC_FILES := flash_ops.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,47 @@
/*
* Copyright 2018-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file flash_ops.h
* @brief support flash function
* @version 2.0
* @author AIIT XUOS Lab
* @date 2023-04-03
*/
#ifndef __FLASH_OPS_H__
#define __FLASH_OPS_H__
#include <flash.h>
typedef struct
{
/* board init function*/
void (*board_init)(void);
void (*serial_init)(void);
void (*print_string)(uint8_t *s);
/* flash Driver operation */
void (*flash_init)(void);
void (*flash_deinit)(void);
/* flash operation */
status_t (*op_flash_erase)(uint32_t start_addr, uint32_t byte_cnt);
status_t (*op_flash_write)(uint32_t start_addr, uint8_t *buf, uint32_t byte_cnt);
status_t (*op_flash_read)(uint32_t addr, uint8_t *buf, uint32_t len);
status_t (*op_flash_copy)(uint32_t srcAddr,uint32_t dstAddr, uint32_t imageSize);
/* Burn the initialization version */
int32_t (*download_by_serial)(const uint32_t addr);
/* system operation */
void(*op_reset)(void);
void(*op_jump)(void);
void(*op_delay)(uint32_t ms);
}mcuboot_t;
#endif

View File

@ -0,0 +1,3 @@
SRC_FILES := ota.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,441 @@
/*
* Copyright 2018-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file ota.c
* @brief file ota.c
* @version 2.0
* @author AIIT XUOS Lab
* @date 2023-04-03
*/
#include "shell.h"
#include "xsconfig.h"
#include "mcuboot.h"
#include "ymodem.h"
#include "ota.h"
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
static uint32_t calculate_crc32(uint32_t addr, uint32_t len);
static void UpdateApplication(void);
static void InitialVersion(void);
static void BackupVersion(void);
static void BootLoaderJumpApp(void);
static status_t UpdateOTAFlag(ota_info_t *ptr);
#ifdef MCUBOOT_APPLICATION
static void app_ota(void);
#endif
/****************************************************************************
* Private Data
****************************************************************************/
static const mcuboot_t mcuboot =
{
mcuboot_bord_init,
UartConfig,
Serial_PutString,
FLASH_Init,
FLASH_DeInit,
flash_erase,
flash_write,
flash_read,
flash_copy,
SerialDownload,
mcuboot_reset,
mcuboot_jump,
mcuboot_delay
};
static const uint32_t crc32tab[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
/*******************************************************************************
* : calculate_crc32
* : Flash内存地址范围中数据的CRC32校验和
* : addr:Flash地址的起始位置
len:CRC32的数据长度
* : CRC32值
*******************************************************************************/
static uint32_t calculate_crc32(uint32_t addr, uint32_t len)
{
uint32_t crc = 0xFFFFFFFF;
uint8_t byte = 0xFF;
for(uint32_t i = 0; i < len; i++)
{
byte = *((volatile uint8_t *)(addr + i));
crc = crc32tab[(crc ^ byte) & 0xff] ^ (crc >> 8);
}
return crc^0xFFFFFFFF;
}
/*******************************************************************************
* : UpdateApplication
* : bootloader里进行调用,Flash中Flag分区中的信息决定是否进行版本更新
* :
* :
* : app分区
*******************************************************************************/
static void UpdateApplication(void)
{
status_t status;
ota_info_t ota_info; // 定义OTA信息结构体
// 从Flash中读取OTA信息
mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t));
// 如果OTA升级状态为准备状态且APP分区与download分区版本不同,才可以进行升级
if((ota_info.status == OTA_STATUS_READY) && (ota_info.os.crc32 != ota_info.down.crc32))
{
mcuboot.print_string("\r\n------Start to update the app!------\r\n");
// 校验downlad分区固件CRC
if(calculate_crc32(DOWN_FLAH_ADDRESS, ota_info.down.size) == ota_info.down.crc32)
{
ota_info.status = OTA_STATUS_UPDATING;
UpdateOTAFlag(&ota_info);
// 1.如果CRC校验通过,开始升级,逐字节拷贝Flash,先备份当前XiUOS System分区内容
status = mcuboot.op_flash_copy(XIUOS_FLAH_ADDRESS, BAKUP_FLAH_ADDRESS, ota_info.os.size);
if((status == kStatus_Success) &&(calculate_crc32(BAKUP_FLAH_ADDRESS, ota_info.os.size) == ota_info.os.crc32))
{
mcuboot.print_string("\r\n------Backup app success!------\r\n");
ota_info.bak.size = ota_info.os.size;
ota_info.bak.crc32 = ota_info.os.crc32;
ota_info.bak.version = ota_info.os.version;
strncpy(ota_info.bak.description, ota_info.os.description, sizeof(ota_info.os.description));
UpdateOTAFlag(&ota_info);;
}
else
{
mcuboot.print_string("\r\n------Backup app failed!------\r\n");
ota_info.status = OTA_STATUS_ERROR;
strncpy(ota_info.error_message, "Backup app failed!",sizeof(ota_info.error_message));
UpdateOTAFlag(&ota_info);;
goto finish;
}
// 2.拷贝download分区到XiUOS System分区
status = mcuboot.op_flash_copy(DOWN_FLAH_ADDRESS, XIUOS_FLAH_ADDRESS, ota_info.down.size);
if((status == kStatus_Success) &&(calculate_crc32(XIUOS_FLAH_ADDRESS, ota_info.down.size) == ota_info.down.crc32))
{
mcuboot.print_string("\r\n------The download partition is copied successfully!------\r\n");
ota_info.os.size = ota_info.down.size;
ota_info.os.crc32 = ota_info.down.crc32;
ota_info.os.version = ota_info.down.version;
strncpy(ota_info.os.description, ota_info.down.description, sizeof(ota_info.down.description));
ota_info.status == OTA_STATUS_IDLE; // 拷贝download分区到XiUOS System分区成功,将OTA升级状态设置为IDLE
UpdateOTAFlag(&ota_info);;
}
else
{
mcuboot.print_string("\r\n------The download partition copy failed!------\r\n");
ota_info.status = OTA_STATUS_ERROR;
strncpy(ota_info.error_message, "The download partition copy failed!",sizeof(ota_info.error_message));
UpdateOTAFlag(&ota_info);;
goto finish;
}
mcuboot.print_string("\r\n------Update completed!------\r\n");
goto finish;
}
else
{
// 如果download分区CRC校验失败升级失败
mcuboot.print_string("\r\n------Download Firmware CRC check failed!------\r\n");
ota_info.status = OTA_STATUS_ERROR;
strncpy(ota_info.error_message, "Download Firmware CRC check failed!",sizeof(ota_info.error_message));
UpdateOTAFlag(&ota_info);;
goto finish;
}
}
else
{
mcuboot.print_string("\r\n------No need to update the app!------\r\n");
goto finish;
}
finish:
return;
}
/*******************************************************************************
* : InitialVersion
* : APP分区的初始化版本,0x1
* :
* :
*******************************************************************************/
static void InitialVersion(void)
{
int32_t size;
ota_info_t ota_info;
memset(&ota_info, 0, sizeof(ota_info_t));
size = mcuboot.download_by_serial(XIUOS_FLAH_ADDRESS);
if(size > 0)
{
ota_info.os.size = size;
ota_info.os.crc32 = calculate_crc32(XIUOS_FLAH_ADDRESS, size);
ota_info.os.version = 0x1;
strncpy(ota_info.os.description, "This is the initial firmware for the device!", sizeof(ota_info.os.description));
UpdateOTAFlag(&ota_info);
}
}
/*******************************************************************************
* : BackupVersion
* : 退,APP存在bug导致无法跳转需调用此函数进行版本回退
* :
* :
*******************************************************************************/
static void BackupVersion(void)
{
status_t status;
ota_info_t ota_info;
mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t));
ota_info.status = OTA_STATUS_BACKUP;
UpdateOTAFlag(&ota_info);
status = mcuboot.op_flash_copy(BAKUP_FLAH_ADDRESS, XIUOS_FLAH_ADDRESS, ota_info.bak.size);
if((status == kStatus_Success) &&(calculate_crc32(XIUOS_FLAH_ADDRESS, ota_info.bak.size) == ota_info.bak.crc32))
{
mcuboot.print_string("\r\n------Backup app version success!------\r\n");
ota_info.os.size = ota_info.bak.size;
ota_info.os.crc32 = ota_info.bak.crc32;
ota_info.os.version = ota_info.bak.version;
strncpy(ota_info.os.description, ota_info.bak.description, sizeof(ota_info.bak.description));
UpdateOTAFlag(&ota_info);
}
else
{
mcuboot.print_string("\r\n------Backup app version failed!------\r\n");
ota_info.status = OTA_STATUS_ERROR;
strncpy(ota_info.error_message, "Backup app version failed!",sizeof(ota_info.error_message));
UpdateOTAFlag(&ota_info);
}
}
/*******************************************************************************
* : BootLoaderJumpApp
* : ,BAKUP分区进行恢复
* :
* :
*******************************************************************************/
static void BootLoaderJumpApp(void)
{
ota_info_t ota_info;
mcuboot.flash_init();
mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t));
if(ota_info.lastjumpflag == JUMP_FAILED_FLAG)
{
mcuboot.print_string("\r\n------Bootloader false, begin backup!------\r\n");
BackupVersion();
}
else
{
ota_info.lastjumpflag = JUMP_FAILED_FLAG;
UpdateOTAFlag(&ota_info);
}
mcuboot.flash_deinit();
mcuboot.op_jump();
}
/*******************************************************************************
* : UpdateOTAFlag
* : OTA Flag区域的信息app里进行调用
* : ptr:ota_info_t结构体指针,OTA升级相关信息
* : kStatus_Success
*******************************************************************************/
static status_t UpdateOTAFlag(ota_info_t *ptr)
{
status_t status;
status = mcuboot.op_flash_erase(FLAG_FLAH_ADDRESS,sizeof(ota_info_t));
if(status != kStatus_Success)
{
return status;
}
status = mcuboot.op_flash_write(FLAG_FLAH_ADDRESS,(void *)ptr,sizeof(ota_info_t));
return status;
}
/*******************************************************************************
* : app_ota
* : app中通过命令来进行ota升级,
* :
* :
*******************************************************************************/
static void app_ota(void)
{
int32_t size;
ota_info_t ota_info;
mcuboot.flash_init();
mcuboot.serial_init();
mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t));
ota_info.status = OTA_STATUS_DOWNLOADING;
UpdateOTAFlag(&ota_info);
size = mcuboot.download_by_serial(DOWN_FLAH_ADDRESS);
ota_info.status = OTA_STATUS_DOWNLOADED;
UpdateOTAFlag(&ota_info);
if(size > 0)
{
ota_info.down.size = size;
ota_info.down.crc32= calculate_crc32(DOWN_FLAH_ADDRESS, size);
ota_info.down.version = ota_info.os.version + 1;
strncpy(ota_info.down.description, "OTA Test!",sizeof(ota_info.down.description));
ota_info.status = OTA_STATUS_READY;
strncpy(ota_info.error_message, "No error message!",sizeof(ota_info.error_message));
UpdateOTAFlag(&ota_info);
}
else
{
ota_info.status = OTA_STATUS_ERROR;
strncpy(ota_info.error_message, "Failed to download firmware to download partition!",sizeof(ota_info.error_message));
UpdateOTAFlag(&ota_info);
}
mcuboot.flash_deinit();
mcuboot.op_reset();
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),ota, app_ota, ota function);
/*******************************************************************************
* : app_clear_jumpflag
* : app成功后,app中调用将lastjumpflag重置为0XCDCDCDCD
* :
* :
*******************************************************************************/
void app_clear_jumpflag(void)
{
mcuboot.flash_init();
//跳转成功设置lastjumpflag为JUMP_SUCCESS_FLAG
ota_info_t ota_info;
mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t));
ota_info.lastjumpflag = JUMP_SUCCESS_FLAG;
UpdateOTAFlag(&ota_info);
mcuboot.flash_deinit();
}
/*******************************************************************************
* : ota_entry
* : bootloader的入口函数
* :
* :
*******************************************************************************/
void ota_entry(void)
{
uint8_t ch1, ch2;
uint32_t ret;
ota_info_t ota_info;
uint32_t timeout = 1000;
mcuboot.board_init();
mcuboot.print_string("Please press 'space' key into menu in 10s !!!\r\n");
while(timeout)
{
ret = (SerialKeyPressed((uint8_t*)&ch1));
if(ret) break;
timeout--;
mcuboot.op_delay(10);
}
while(1)
{
if((ret)&&(ch1 == 0x20))
{
mcuboot.print_string("\r\nPlease slecet:");
mcuboot.print_string("\r\n 1:run app");
mcuboot.print_string("\r\n 2:update app");
mcuboot.print_string("\r\n 3:reboot \r\n");
ch2 = GetKey();
switch(ch2)
{
case 0x31:
BootLoaderJumpApp();
break;
case 0x32:
mcuboot.flash_init();
mcuboot.op_flash_read(FLAG_FLAH_ADDRESS, (void*)&ota_info, sizeof(ota_info_t));
/* 此时APP分区还没有有效的固件,需要在bootloader下通过iap烧写出厂固件 */
if((ota_info.os.size > APP_FLASH_SIZE) || (calculate_crc32(XIUOS_FLAH_ADDRESS, ota_info.os.size) != ota_info.os.crc32))
{
mcuboot.print_string("\r\nNeed to flash initial firmware!\r\n");
InitialVersion();
}
else
{
UpdateApplication();
}
mcuboot.flash_deinit();
BootLoaderJumpApp();
break;
case 0x33:
mcuboot.op_reset();
default:
break;
}
}
else
{
BootLoaderJumpApp();
}
}
}

View File

@ -1,38 +1,32 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
* Copyright 2018-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file: imxrt_ota.h
* @brief: file imxrt_ota.h
* @version: 1.0
* @author: AIIT XUOS Lab
* @date: 2023/3/24
* @file ota.h
* @brief file ota.h
* @version 2.0
* @author AIIT XUOS Lab
* @date 2023-04-03
*/
#ifndef __OTA_DEF_H__
#define __OTA_DEF_H__
#ifndef __IMXRT_OTA__H__
#define __IMXRT_OTA__H__
#include "flash_ops.h"
#include <stdint.h>
#include "mcuboot.h"
#include "flash.h"
#include "ymodem.h"
#define JUMP_FAILED_FLAG 0XABABABAB
#define JUMP_SUCCESS_FLAG 0XCDCDCDCD
/* OTA升级过程中的状态描述 */
typedef enum {
OTA_STATUS_IDLE = 0, // 空闲状态,没有进行OTA升级
OTA_STATUS_READY, // 准备状态,可以进行OTA升级
OTA_STATUS_DOWNLOADING, // 正在下载固件
OTA_STATUS_DOWNLOADED, // 固件下载完成
OTA_STATUS_UPDATING, // 正在进行OTA升级
OTA_STATUS_BACKUP, // 正在版本回退
OTA_STATUS_ERROR, // 出现错误,升级失败
} ota_status_t;
@ -53,14 +47,11 @@ typedef struct {
firmware_t bak; // Bakup分区属性信息
firmware_t down; // Download分区属性信息
uint32_t status; // 升级状态,取值来自于ota_status_t类型
uint32_t lastjumpflag; // bootloaer跳转失败的标志,bootloader里置0xABABABAB,跳转成功后在应用里置0x00000000
uint32_t lastjumpflag; // bootloaer跳转失败的标志,bootloader里置0xABABABAB,跳转成功后在应用里置0xCDCDCDCD
uint32_t reserve[2]; // 保留字段
uint8_t error_message[128]; // 错误信息,最多128个字符
} ota_info_t;
uint32_t calculate_crc32(uint32_t addr, uint32_t len);
status_t UpdateOTAFlag(ota_info_t *ptr);
void UpdateApplication(void);
void app_clear_jumpflag(void);
void ota_entry(void);
#endif