글 혹은 그림의 출처가 문제있다면 수정 및 삭제하겠습니다. 우측의 Tags 와 검색기능을 이용하여 편하게 찾을 수 있습니다.
Please check buttons on the right like Tags and language options if can't read this blog (*mobile not support)
Modbus 가 기본적으로 Request/Response 기반이므로, SCADA(Master), 특정 Register를 Command 기반으로 변경하여 진행하도록 한다.
이에 대한 반응 항상 특정 Resiter를 통해, Deivce Status 체크하는 구조이다.
상위에서 언급한 MMC가 이런 방식으로 동작하며, 다양한 Device Driver들이 이와 유사한다.
그리고, 각 Command마다 Flow 및 Status가 본인 알아서 정의하도록 하자.
OTA 구현시 문제사항
OTA를 진행할 경우, Modbus-RTU 에서는 많은 Data를 전송하기 때문에, 여기에도 좀 문제가 발생하는데,
주로 Cache(CPU Cache가 아니며, Buffer)로 인하여, 중복되는 문제 부분일 것 같다.
이 부분은, OTA 진행 할 경우,
RS232의 Flow Control 이 존재하지만, RS485에서 크게 의미가 없어서, 별도로, S/W Flow Control Header 정의해서, 이 부분을 보완하였다.
테스트를 해봤지만, RS232 Flow Control이 RS485로 되면서 별의미가 없고, Modbus-RTU(RS485)는 내부적으로 Flow Control이 없는걸로 생각되어짐
이 부분은 간단히 정의해서 이 부분을 보완하여 넣도록하자.
예를들면, 각 Offset 과 Size 정의하고, 이를 Master 와 Slave가 각각 확인하는 구조이며, 이외 Buffer 성능 및 에러문제등을 개선하여 만들어 보도록하자.
이외 다양한 문제가 발생할 수 있으며, 각 상황에 맞추어 본인이 세부적으로 분석해서 대응하자.
나의 경우는 HW적으로 다음과 같은 문제가 발생
RS485 Tranceiver 의 오동작 ( Reset 후 발생 문제가 발생)
Master에서 Response를 제대로 못가져오는 문제
이 문제가 발생하여 상위 Flow Control 기능추가
ESP32의 FreeRTOS 문제 및 성능문제
이 문제는 S/W 문제가 다양하며, Serial 부분과 많이 연관되어짐
Serial Buffer 이외 FreeRTOS Buffer도 별도로 존재
일단 나의 경우는 각 OTA Command 와 Status를 별도로 정의하여 구현했으며, 테스트 결과 별 이상이 없다.
더불어, 좀 더 세부적으로 성능 및 OTA 테스트 분석하기 위해서 Python 기반으로 이를 OTA 테스트 하는 Program을 작성하였다.
또한 Modbus RTU 기능을 간단히 Profiling (RS485 버스 점유율 및 속도)해주는 Program도 별도 추가구현 하였다.
만약, 이를 상용으로 동작되는 프로그램있다면,이를 적극 이용하거나, 그 Tool에 맞게 제작 하도록하자.
구지, 나처럼 다 일일이 만들지 말도록 하자.
주로 Profiling 하는 부분은 ESP32의 RS485/Modbus-RTU 성능이므로, 이 Bus 점유율(Share-rate)를 각 속도별로 비교해보면 되겠다.
그리고, 각 에러율도 좀 비교해보면 더욱 좋겠다. (이 부분은 만들었지만, 비교하지 않았다)
참고로, ESP32의 경우, 속도가 높아질수록 성능 많이 부족해지는데, 다른 곳에 많은 리소스를 사용해서 그런건지,(아마 이쪽이 가능성이 높다)
아님 ESP32 문제인지는 나도 아직 세부적으로 분석하지 않았다.
2. SCADA 에 Modbus RTU 적용문제
나 역시, 정확한 SCADA를 실제로 접해 본적이 없기에, 이에 적용하는 방법은 본인 정한 Protocol Flow와 Memory Map 을 알려주는 방법 밖에는 없는 거 같다.
나의 경우, Python 기반으로 나만의 Master기반으로 직접 테스트하며 구현했기 때문에, 이 부분은 나중에 한 번 다시 한번 생각해봐야겠다.
2.1 Python 기반 Unit 테스트
Modbus 역시, Python 과 NodeJS도 지원해주기 때문에, 본인 작성하기 쉬운 걸로 선택해서 각 테스트 프로그램들을 작성하도록 하자.
상위에 이미 설명을 했으며, 각 OTA 성능 및 Profile을 위해서 가 부분을 비교 분석하도록 하였다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(idf4.2_py3.8_env) D:\Works\Project> espefuse.py //esefuse 사용법확인
espefuse.py v3.1-dev
usage: espefuse.py [-h] [--chip {auto,esp32,esp32s2,esp32s3beta2,esp32s3beta3,esp32c3}] [--baud BAUD] [--port PORT]
[--before {default_reset,no_reset,esp32r1,no_reset_no_sync}] [--debug] [--virt] [--path-efuse-file PATH_EFUSE_FILE]
[--do-not-confirm]
{burn_efuse,read_protect_efuse,write_protect_efuse,burn_block_data,burn_bit,adc_info,dump,summary,burn_key,burn_key_digest,set_flash_voltage,burn_custom_mac,get_custom_mac}
...
positional arguments:
{burn_efuse,read_protect_efuse,write_protect_efuse,burn_block_data,burn_bit,adc_info,dump,summary,burn_key,burn_key_digest,set_flash_voltage,burn_custom_mac,get_custom_mac}
Run espefuse.py {command} -h for additional help
burn_efuse Burn the efuse with the specified name //Feild name 기반 Write 기능, burn_bit 와 동일
read_protect_efuse Disable readback for the efuse with the specified name
write_protect_efuse
Disable writing to the efuse with the specified name
burn_block_data Burn non-key data to EFUSE blocks. (Don't use this command to burn key data for Flash Encryption or ESP32 Secure
Boot V1, as the byte order of keys is swapped (use burn_key)).
burn_bit Burn bit in the efuse block. //burn_efuse 거의 동일하며, Block 과 Bit를 입력하여 Write
adc_info Display information about ADC calibration data stored in efuse.
dump Dump raw hex values of all efusessummary Print human-readable summary of efuse valuesburn_key Burn a 256-bit key to EFUSE: BLOCK1, flash_encryption, BLOCK2, secure_boot_v1, secure_boot_v2, BLOCK3burn_key_digest Parse a RSA public key and burn the digest to eFuse for use with Secure Boot V2
set_flash_voltage Permanently set the internal flash voltage regulator to either 1.8V, 3.3V or OFF. This means GPIO12 can be high or
low at reset without changing the flash voltage.
burn_custom_mac Burn a 48-bit Custom MAC Address to EFUSE BLOCK3.
get_custom_mac Prints the Custom MAC Address.
optional arguments:
-h, --help show this help message and exit
--chip {auto,esp32,esp32s2,esp32s3beta2,esp32s3beta3,esp32c3}, -c {auto,esp32,esp32s2,esp32s3beta2,esp32s3beta3,esp32c3}
Target chip type
--baud BAUD, -b BAUD Serial port baud rate used when flashing/reading
--port PORT, -p PORT Serial port device
--before {default_reset,no_reset,esp32r1,no_reset_no_sync}
What to do before connecting to the chip
--debug, -d Show debugging information (loglevel=DEBUG)
--virt For host tests, the tool will work in the virtual mode (without connecting to a chip).
--path-efuse-file PATH_EFUSE_FILE
For host tests, saves efuse memory to file.
--do-not-confirm Do not pause for confirmation before permanently writing efuses. Use with caution.
(idf4.2_py3.8_env) D:\Works\Project> espefuse.py -p COM15 get_custom_mac//기본으로 사용하므로 없음
Connecting.....
Detecting chip type... ESP32
espefuse.py v3.1-dev
Custom MAC Address is not set in the device.
Secure Boot 설정완료 후 OTP 설정 할 것
SecureBoot를 완벽히 진행하려면, 나중에는 JTAG 과 UART를 막아야 하며, 이후 부터 OTA로만 진행