Доброго времени суток, уважаемое сообщество!
Так уж свершилось, что пришлось столкнуться с задачей написания прошивки для довольно интересного модема Telit GL865-DUAL. И в данном топике мне хотелось бы хотя бы в общих чертах описать процесс разработки прошивки для него.
Итак, начнем, пожалуй, с общего представления о том, в каком месте «торчит» прошивка у Телита. Это очень наглядно демонстрирует схема из официальной документации:
Как прекрасно видно из данной схемы, прошивка работает с устройством, общаясь с ним через уже готовые интерфейсы, находясь при этом в достаточно стесненных условиях. Кстати, сразу хотелось бы оговориться — указанные на схеме объемы памяти очень абстрактны. У Telit GL865-DUAL, к примеру, только 1 мегабайт оперативной памяти доступен и всего лишь 2 мегабайта flash памяти.
Пару слов о доступных интерфейсах. Всего их 9, но число рабочих напрямую зависит от железки, на которой запускается скрипт.
MDM
Интерфейс является самым важным. Он позволяет отправлять отправлять и принимать АТ команды, отправлять и принимать данные из сети и так далее и тому подобное. Отправляемые через него данные обрабатываются при помощи обработчика АТ команд. MDM модуль не взаимодействует с реальным последовательным портом, поэтому не важно, какие настройки стоят на порту — данные все равно дойдут до модуля.
MDM2
Это второй интерфейс между Python и обработчиком AT команд. Через него можно отправлять и получать ответы на АТ команды, когда MDM интерфейс занят.
SER
Данный интерфейс позволяет Python скрипту читать и отправлять данные в физический последовательный порт ASC0, обычно используемый для отправки AT команд в модуль (когда общаемся с модулем извне, с компа например). Когда Python скрипт работает, этот последовательный порт поступает в его полное распоряжение и не используется обработчиком АТ команд (то есть в это время на этот порт слать команды не получится). На данном порту при помощи скриптов Python нельзя управлять flow-control.
SER2
Интерфейс позволяет Python скрипту читать и писать данные в физический последовательный порт ASC1, который обычно используется для отладки.
GPIO
Интерфейс позволяет управлять портами ввода-вывода (или по простому — дергать ногами) в обход обработчика АТ команд, что выходит быстрее.
MOD
Интерфейс представляет собой набор пользовательских функций.
IIC
Интерфейс представляет собой реализацию IIC Bus Master в ядре Python. Он позволяет Python создавать одну или более IIC шин на существующих GPIO пинах.
SPI
Интерфейс представляет собой реализацию SPI Master Bus в ядре Python. Он позволяет Python создавать одну или более SPI шин на существующих GPIO пинах.
GPS
Интерфейс обеспечивает взаимодействие между Python и встроенным в модуль GPS контроллером. Он позволяет работать с ним в обход АТ команд.
Данный набор интерфейсов позволяет выполнять, в принципе, любые махинации с железом на достаточно приемлемых скоростях. Но не обошлось и без подводных камней. При портировании Python, ребята из Telit зачем-то удалили поддержку языком таких простых типов данных как:
- complex;
- float;
- docstring.
Так что каких-то сложных вычислений, к сожалению, на железке не попроизводить. Ну хватит о грустном — пора перейти непосредственно к написанию и тестированию первой простой прошивки. Будем считать, что устройство уже подготовлено к работе. Если нет, то добро пожаловать сюда и сюда.
Для обеспечения связи с устройством я, лично, использую терминал RSTerm. Он удобен, портативен и даже, кажется, бесплатен.
Итак, приступим к написанию самой прошивки. Я не придумал ничего глупее, чем отправить СМС с текстом «Hello world» на свой телефон.
В самом начале скрипта подключим необходимые интерфейсы
import MOD
import MDM
Далее, по логике вещей, нам необходимо проверить, зарегистрировался ли модуль в сети. Для этого я набросал простую функцию, которая отправляет AT команду AT+CREG? и обрабатывает результаты.
def checkNetwork():
MOD.sleep(20)
REC_TIME = 200
for _ in range(10):
MDM.send("AT+CREG?r",0)
res = MDM.receive(REC_TIME)
if (res.find('0,1')!=-1): return 1
else: MOD.sleep(50)
return 0
Да, чуть не забыл. Python в Telit-е не знает такого типа как bool, поэтому приходится работать с 0 и 1.
Следом нам, конечно-же, понадобится функция, которая поможет нам отправить СМС. У меня получилось нечто такое.
def sendSMS( number, smstext, csca):
if number=="" or smstext=="" or csca == "" : return 0
MDM.send('AT+CSCA='+csca+'r',2)
MDM.receive(20)
MDM.send('AT+CMGF=1r',2)
MDM.receive(20)
a = MDM.send('AT+CMGS="' + number + '"r', 2)
res = MDM.receive(10)
a = MDM.send(smstext, 2)
a = MDM.sendbyte(0x1A, 2)
a=''
while a=='':
a = MDM.receive(20)
return ( a.find('OK')!=-1 )
Параметрами ее являются соответственно:
- Номер телефона;
- Текст сообщения;
- Номер центра сообщений оператора.
Ну и теперь осталось только обернуть все это в логику и обеспечить хотя бы простой дебаг. Да, для дебага можно использовать второй порт последовательный порт устройства, но для меня это было излишним шиком, поэтому для своего же удобства я переопределил вывод команды print в первый последовательный порт.
import SER2
SER.set_speed('115200','8N1')
class SerWriter:
def __init__(self):
SER.set_speed('115200','8N1')
def write(self,s):
SER.send(s+'r')
sys.stdout = sys.stderr = SerWriter()
Ну и весь исходник целиком
import MOD
import MDM
import SER
SER.set_speed('115200','8N1')
class SerWriter:
def __init__(self):
SER.set_speed('115200','8N1')
def write(self,s):
SER.send(s+'r')
sys.stdout = sys.stderr = SerWriter()
def checkNetwork():
MOD.sleep(20)
REC_TIME = 200
for _ in range(10):
MDM.send("AT+CREG?r",0)
res = MDM.receive(REC_TIME)
if (res.find('0,1')!=-1): return 1
else: MOD.sleep(50)
return 0
def sendSMS( number, smstext, csca):
if number=="" or smstext=="" or csca == "" : return 0
MDM.send('AT+CSCA='+csca+'r',2)
MDM.receive(20)
MDM.send('AT+CMGF=1r',2)
MDM.receive(20)
a = MDM.send('AT+CMGS="' + number + '"r', 2)
res = MDM.receive(10)
a = MDM.send(smstext, 2)
a = MDM.sendbyte(0x1A, 2)
a=''
while a=='':
a = MDM.receive(20)
return ( a.find('OK')!=-1 )
print "Start"
while not checkNetwork():
print "No network"
MOD.sleep(10)
print "I find network"
myNumber = "+7960*******"
myText = "Hello world"
smsGate = "+79037011111"
print "Try to send SMS"
if sendSMS(myNumber,myText,smsGate):
print "SMS sended"
else:
print "SMS not sended"
Я сохранил этот скрипт под именем hello.py
Теперь остается только открыть RSTerm, выбрать меню Telit Python, залить файл при помощи кнопки Upload selected file(s) from PC to module, активировать его при помощи кнопки AT#ESCRIPT=«hello.py» и запустить кнопкой AT#EXECSCR.
Надеюсь данный материал хоть кому-нибудь пригодится. Спасибо за внимание.
Автор: zloiia
Большое вам спасибо за эту статью и эту http://el-tc.ru/?p=146. Каким бы опытом не обладал, всегда уходит много времени на начальный этап, когда не понятно с какой стороны приступить к теме. До ваших статей прочитал почти всю документацию Telit, общался с продавцами модуля EVK2 и нигде не мог найти ссылки на хороший терминал для начальной проверки модуля и организации работы с Python, хотя он мне и не нужен. Тот терминал, что предложили продавцы просто не работает.
Привет
Я не знаю возможно ошибки отображения но все команды содержат в конце ‘r’ вместо ‘\r’
For example:
MDM.send(“AT+CREG?r”,0)
Очень интересная тема, спасибо. Статьи по ссылке http://el-tc.ru/?p=146 и 132 не доступны, копии случайно не сохранилось?