В своей работе с микросхемой M25P40VP мы использовали библиотеку SPIFlash. Но, как вы могли заметить, в этой библиотеке реализованы только базовые функции коммуникации с чипом M25P40VP и работать с ней не очень удобно — все нужные нам функции по записи и чтению нужных нам типов данных нам приходилось реализовывать «вручную» прямо в скетчах.
Это, по большому счёту, несерьёзно — конечно весь этот функционал должен содержаться в самой библиотеке. Как же быть? Давайте попробуем решить эту проблему путём создания собственной библиотеки для работы с чипом M25P40VP.
И назовём мы нашу будущую библиотеку «My M25P40» (my25p40).
Архитектура библиотеки
Для решения нашей проблемы и написания собственной библиотеки M25P40VP возможны 3 варианта:
1. Написание собственной библиотеки работы с M25P40VP с нуля.
2. Модернизация и изменение исходной библиотеки SPIFlash.
3. Создание отдельного дополнения (обёртки) базовой библиотеки SPIFlash.
В принципе право на жизнь имеют все три варианта и каждый из них имеет свои достоинства и недостатки, разберём их подробнее:
1. Это, безусловно, самый правильный вариант, но он для своей реализации требует определённой квалификации и серьёзных временных и трудозатрат.
2. Тоже неплохой и вполне рабочий вариант, из недостатков тут можно назвать зависимость от базовой версии (которая взята за основу) исходной библиотеки.
3. С одно стороны немного «замороченный» вариант, но обеспечивающий независимость от базовой версии исходной библиотеки (при условии соблюдения авторами синтаксической совместимости в новых версиях) и быстрота разработки — от нас требуется только дописать нужные нам функции-обёртки.
Как вы уже догадались, мы будем создавать свою библиотеку в виде обёртки исходной библиотеки SPIFlash. Заодно вы сможете посмотреть как это делается и отметить для себя множество нюансов подобной реализации библиотеки.
Каркас библиотеки my25p40
Начнём с определения структуры папок нашей библиотеки. Главная папка будет называться так же, ка и сама библиотека.
my25p40
Внутри главной папки будут находиться два каталога:
examples — для примеров использования библиотеки
src — собственно файлы самой библиотеки
В «корне» библиотеки будут находиться 2 файла:
keywords.txt — файл, содержащий названия функций библиотеки для выделения их в среде Arduino IDE
library.properties — основные выходные данные библиотеки
В папке src будут находиться 2 файла библиотеки my25p40:
my25p40.h — заголовочный файл библиотеки my25p40
my25p40.cpp — сами функции библиотеки
Важный момент: поскольку мы решили реализовывать нашу библиотеку в виде обёртки исходной библиотеки SPIFlash, то в папку src мы помещаем саму библиотеку SPIFlash.
На этом мы заканчиваем рассмотрение структуры папок и файлов библиотеки и переходим к рассмотрению содержимого самих файлов.
library.properties
Как уже было замечено выше, library.properties — это файл, который содержит основные выходные данные нашей библиотеки. Вот его содержимое:
name=my25p40 version=0.1 author=EM maintainer=em sentence=My m25p40 Library paragraph= category=Memory url=http://electromicro.ru/ architectures=*
Смысл и содержание надписей понятно из их обозначений ключевыми словами.
keywords.txt
Файл keywords.txt содержит названия функций нашей библиотеки для выделения их (цветом) в среде Arduino IDE.
####################################### # Syntax Coloring Map ####################################### ####################################### # Datatypes (KEYWORD1) ####################################### my25p40 KEYWORD1 ####################################### # Methods and Functions (KEYWORD2) ####################################### readWord KEYWORD2 readInt KEYWORD2 readULong KEYWORD2 readLong KEYWORD2 readFloat KEYWORD2 readChars KEYWORD2 readString KEYWORD2 writeWord KEYWORD2 writeInt KEYWORD2 writeULong KEYWORD2 writeLong KEYWORD2 writeFloat KEYWORD2 writeChars KEYWORD2 writeString KEYWORD2 checkBusy KEYWORD2 initInfo KEYWORD2 readInfo KEYWORD2 writeInfo KEYWORD2 erase KEYWORD2 erase64K KEYWORD2 ####################################### # Instances (KEYWORD2) ####################################### ####################################### # Constants (LITERAL1) #######################################
О самих функциях и их назначении будет рассказано немного ниже.
my25p40.h
my25p40.h — это заголовочный файл библиотеки my25p40. Вот его каркас (который мы дополним необходимым содержимым чуть ниже).
/* My m25p40 Library version 0.1 2021, electromicro.ru License: GNU GPL 2.1 */ #ifndef MY25P40_H #define MY25P40_H #include <Arduino.h> #include "SPIFlash/SPIFlash.h" ... ... … #endif // #ifndef MY25P40_H
Он содержит:
- Блок названия, версии, копирайта и лицензии библиотеки
- Блок защиты от повторного подключения библиотеки (#ifndef MY25P40_H...)
- Подключённые библиотеки (Arduino и SPIFlash)
my25p40.cpp
my25p40.cpp — это файл реализации функций нашей библиотеки, пока пустой каркас этого файла:
/* My m25p40 Library version 0.1 2021, electromicro.ru License: GNU GPL 2.1 */ #ifndef MY25P40_CPP #define MY25P40_CPP #include "my25p40.h" ... ... … #endif // #ifndef MY25P40_CPP
Он содержит:
- Блок названия, версии, копирайта и лицензии библиотеки
- Блок защиты от повторного подключения библиотеки (#ifndef MY25P40_CPP...)
- Подключение заголовочного файла (my25p40.h)
Как вы видите структура файлов my25p40.h и my25p40.cpp довольно проста, осталось только наполнить эти файлы нужными нам функциями с нужным нам функционалом.
Функции библиотеки my25p40
Теперь давайте разберём состав функций, которые мы должны реализовать в нашей библиотеке. Все эти дополнительные функции можно разбить на 4 группы:
- Системные
- Информационные
- Стирание памяти
- Работа (запись и чтение) с различными типами данных
Теперь подробно рассмотрим каждую из этих групп.
Системные
void checkBusy() — это специальная функция для отслеживания «занятости» чипа M25P40VP при проведении им различных операций (см. предыдущие статьи цикла).
Информационные
void initInfo() — вывод диагностических сообщений при инициализации чипа M25P40VP.
void readInfo(uint32_t adr, String s) — вывод информации о чтении данных.
void writeInfo(uint32_t adr, String s) — вывод информации о записи данных.
Стирание памяти
void erase() — функция полного стирания чипа M25P40VP с выводом соответствующего сообщения.
void erase64K(byte sec) — функция посекторного стирания памяти с выводом соответствующего сообщения.
Работа с различными типами данных
void writeWord(uint32_t adr, word w) — запись по определённому адресу данных типа word.
word readWord(uint32_t adr) — чтение по определённому адресу данных типа word.
void writeULong(uint32_t adr, unsigned long ul) — запись данных типа unsigned long.
unsigned long readULong(uint32_t adr) — чтение данных типа unsigned long.
void writeInt(uint32_t adr, int i) — запись данных типа int.
int readInt(uint32_t adr) — чтение данных типа int.
void writeLong(uint32_t adr, long lg) — запись данных типа long.
long readLong(uint32_t adr) — чтение данных типа long.
void writeFloat(uint32_t adr, float fl) — запись данных типа float.
float readFloat(uint32_t adr) — чтение данных типа float.
void writeChars(uint32_t adr, char chs[], byte len) — запись данных типа char[].
void readChars(uint32_t adr, char *buf, byte len) — чтение данных типа char[].
void writeString(uint32_t adr, String s) — запись данных типа String.
String readString(uint32_t adr, byte len) — чтение данных типа String.
Пример использования библиотеки my25p40
Приведём здесь наглядный пример пример использования библиотеки my25p40 и того, насколько упрощается работа с чипом M25P40VP при её использовании. Сначала пример работы с чипом M25P40VP при помощи стандартной библиотеки SPIFlash из одной из наших предыдущих статей:
/* M25P40 Read & Write Word */ #include <SPI.h> #include <SPIFlash .h> #define FLASH_SS 8 #define TEST_ADR 0 #define TEST_VAL 65000 SPIFlash flash(FLASH_SS); void setup() { Serial.begin(115200); Serial.println(F("M25P40 Read & Write Word start...")); Serial.print(F("Init ")); if (flash.initialize()) {Serial.println(F("OK"));} else {Serial.println(F("FAIL"));} erase(); readWord(TEST_ADR); writeWord(TEST_ADR, TEST_VAL); readWord(TEST_ADR); } void checkBusy() { uint32_t stt = millis(); while (flash.busy()) { } uint32_t del = millis() - stt; if (del) { Serial.print(F(" (")); Serial.print(del); Serial.print(F(" ms)")); } Serial.println(); } void erase() { Serial.print(F("Full erase...")); flash.chipErase(); checkBusy(); } void readWord(uint32_t adr) { byte bytes[2]; flash.readBytes(adr, bytes, 2); word wordValue = (bytes[0] << 8) | bytes[1] & 0xFF; Serial.print(F("Read #")); Serial.print(adr); Serial.print(F(": ")); Serial.println(wordValue); } void writeWord(uint32_t adr, word w) { byte bytes[2]; bytes[0] = highByte(w); bytes[1] = lowByte(w); flash.writeBytes(adr, bytes, 2); Serial.print(F("Write #")); Serial.print(adr); Serial.print(F(": ")); Serial.println(w); } void loop() { }
Теперь тот же пример, но уже при использовании нашей библиотеки для работы с чипом M25P40VP:
/* my25p40 Library Read & Write Word */ #include <SPI.h> #include <my25p40.h> #define FLASH_SS 8 #define TEST_ADR 0 #define TEST_VAL 65000 my25p40 flash(FLASH_SS); void setup() { Serial.begin(115200); Serial.println(F("my25p40 Library Read & Write Word start...")); flash.initInfo(); flash.erase(); flash.readInfo(TEST_ADR, String(flash.readWord(TEST_ADR))); flash.writeWord(TEST_ADR, TEST_VAL); flash.writeInfo(TEST_ADR, String(TEST_VAL)); flash.readInfo(TEST_ADR, String(flash.readWord(TEST_ADR))); } void loop() { }
Как вы видите размер кода и его сложность изменились кардинально: теперь для реализации основного функционала скетча нужны всего 6 строк:
flash.initInfo(); flash.erase(); flash.readInfo(TEST_ADR, String(flash.readWord(TEST_ADR))); flash.writeWord(TEST_ADR, TEST_VAL); flash.writeInfo(TEST_ADR, String(TEST_VAL)); flash.readInfo(TEST_ADR, String(flash.readWord(TEST_ADR)));
вместо примерно 30 в базовом варианте — выигрыш в 5 раз!
Заключение
На этом уроке мы разобрали базовые принципы создания нашей собственной библиотеки для работы с чипом M25P40VP, на следующем уроке мы подробно разберём уже сам код нашей библиотеки и различные нюансы её создания.
Ссылки по теме
Обзор контроллера uniSensors nRF24
Программирование uniSensors nRF24
Работа с памятью M25P40. Часть 1. Спецификации и библиотека
Работа с памятью M25P40. Часть 2. Sleep, Wakeup, Erase и Busy
Работа с памятью M25P40. Часть 3. Read и Write Byte и Arrays
Работа с памятью M25P40. Часть 4. Работа с беззнаковыми типами данных
Работа с памятью M25P40. Часть 5. Работа со знаковыми типами данных
Работа с памятью M25P40. Часть 6. Read и Write Float
Работа с памятью M25P40. Часть 7. Read и Write Char array и String
Работа с памятью M25P40. Часть 8. Работа с секторами
Работа с памятью M25P40. Часть 9. Выборочное стирание секторов
Работа с памятью M25P40. Часть 10. Копирование секторов
Работа с памятью M25P40. Часть 11. Восстановление (backup) секторов
Работа с памятью M25P40. Часть 12. Работа с блоками памяти
Работа с памятью M25P40. Часть 13. Пишем библиотеку для M25P40
Работа с памятью M25P40. Часть 14. Пишем библиотеку для M25P40 (2)
Работа с памятью M25P40. Часть 15. Пишем библиотеку для M25P40 (3)
Где купить?
uniSensors nRF24 в магазине «Electromicro»
Техническая поддержка
Мы внимательно относимся к потребностям наших клиентов и осуществляем техническую поддержку всей выпускаемой продукции. Вы можете написать нам письмо с вашим вопросом или позвонить по телефону и специалист нашей компании проконсультирует вас и поможет решить вашу проблему.
- Емейл для вопросов по нашей продукции: electromicro@bk.ru
- Наш телефон: +7 (495) 997-37-74