Téléphone SIP sur STM32F7-Discovery

Bonjour Ă  tous.

Il y a quelque temps, nous avons Ă©crit comment nous avons rĂ©ussi Ă  lancer un tĂ©lĂ©phone SIP sur STM32F4-Discovery avec 1 Mo de ROM et 192 Ko de RAM) basĂ© sur Embox . Ici, je dois dire que cette version Ă©tait minimale et connectait deux tĂ©lĂ©phones directement sans serveur et avec une transmission vocale dans un seul sens. Par consĂ©quent, nous avons dĂ©cidĂ© de lancer un tĂ©lĂ©phone plus complet avec un appel via le serveur, une transmission vocale dans les deux sens, mais en mĂȘme temps, garder la taille de mĂ©moire la plus petite possible.


Pour le téléphone, il a été décidé de choisir l'application simple_pjsua dans le cadre de la bibliothÚque PJSIP. Il s'agit d'une application minimale qui peut s'inscrire sur le serveur, recevoir et répondre aux appels. Ci-dessous, je vais immédiatement décrire comment exécuter cela sur le STM32F7-Discovery.

Comment courir


  1. Configuration d'Embox
    make confload-platform/pjsip/stm32f7cube 
  2. Dans le fichier conf / mods.config, définissez le compte SIP souhaité.

     include platform.pjsip.cmd.simple_pjsua_imported( sip_domain="server", sip_user="username", sip_passwd="password") 

    oĂč serveur est le serveur SIP (par exemple, sip.linphone.org), le nom d'utilisateur et le mot de passe sont le nom d'utilisateur et le mot de passe du compte.
  3. Construisez Embox avec la commande make . À propos du firmware de la carte que nous avons sur le wiki et dans l' article .
  4. Exécutez la commande "simple_pjsua_imported" dans la console Embox

     00:00:12.870 pjsua_acc.c ....SIP outbound status for acc 0 is not active 00:00:12.884 pjsua_acc.c ....sip:alexk2222@sip.linphone.org: registration success, status=200 (Registration succes 00:00:12.911 pjsua_acc.c ....Keep-alive timer started for acc 0, destination:91.121.209.194:5060, interval:15s 

  5. Enfin, il reste à insérer des haut-parleurs ou des écouteurs dans la sortie audio, et à parler dans deux petits microphones MEMS prÚs de l'écran. Nous appelons depuis Linux via l'application simple_pjsua, pjsua. Eh bien, ou vous pouvez tout autre type de téléphone portable.

Tout cela est décrit sur notre wiki .

Comment en sommes-nous arrivés là?


Ainsi, au départ, la question s'est posée de choisir une plate-forme matérielle. Comme il était clair que le STM32F4-Discovery ne tiendrait pas en mémoire, le STM32F7-Discovery a été choisi. Elle possÚde un lecteur flash de 1 Mo et 256 Ko de RAM (+ 64 mémoires rapides spéciales, que nous utiliserons également). Pas beaucoup non plus pour les appels via le serveur, mais j'ai décidé d'essayer d'entrer.

Classiquement, la tùche était divisée en plusieurs étapes:

  • ExĂ©cution de PJSIP sur QEMU. C'Ă©tait pratique pour le dĂ©bogage, en plus nous avions dĂ©jĂ  le support du codec AC97 lĂ -bas.
  • Enregistrement et lecture de la voix sur QEMU et STM32.
  • Portage d' une application simple_pjsua Ă  partir de PJSIP. Il vous permet de vous inscrire sur le serveur SIP et de passer des appels.
  • DĂ©ployez votre propre serveur basĂ© sur Asterisk et testez-le, puis essayez des serveurs externes tels que sip.linphone.org

Le son dans Embox fonctionne via Portaudio, qui est également utilisé dans PISIP. Les premiers problÚmes sont apparus sur QEMU - WAV a bien joué à 44100 Hz, mais quelque chose s'est mal passé à 8000. Il s'est avéré qu'il s'agissait de régler la fréquence - par défaut, c'était 44100 dans l'équipement, et cela n'a pas changé de programme avec nous.

Ici, il vaut probablement la peine d'expliquer un peu comment le son est jouĂ© en gĂ©nĂ©ral. La carte son peut dĂ©finir un pointeur sur un morceau de mĂ©moire Ă  partir duquel vous souhaitez lire ou enregistrer Ă  une frĂ©quence prĂ©dĂ©terminĂ©e. Une fois le tampon terminĂ©, une interruption est gĂ©nĂ©rĂ©e et l'exĂ©cution se poursuit Ă  partir du tampon suivant. Le fait est que ces tampons doivent ĂȘtre remplis Ă  l'avance avant que le prĂ©cĂ©dent ne soit jouĂ©. Ce problĂšme, nous le rencontrerons plus loin sur le STM32F7.

Ensuite, nous avons louĂ© un serveur et dĂ©ployĂ© Asterisk dessus. Puisqu'il fallait beaucoup dĂ©boguer, mais ne voulait pas parler beaucoup dans le microphone, il fallait faire la lecture et l'enregistrement automatiques. Pour ce faire, nous avons patchĂ© simple_pjsua afin qu'il soit possible de glisser des fichiers Ă  la place des pĂ©riphĂ©riques audio. Dans PJSIP, cela se fait tout simplement, car ils ont le concept d'un port, qui peut ĂȘtre un pĂ©riphĂ©rique ou un fichier. Et ces ports peuvent ĂȘtre connectĂ©s de maniĂšre flexible Ă  d'autres ports. Vous pouvez voir le code dans notre rĂ©fĂ©rentiel pjsip. En consĂ©quence, le schĂ©ma Ă©tait le suivant. J'ai crĂ©Ă© deux comptes sur le serveur Asterisk - pour Linux et pour Embox. Ensuite, la commande simple_pjsua_imported est exĂ©cutĂ©e sur Embox, Embox est enregistrĂ©e sur le serveur, aprĂšs quoi nous appelons Embox depuis Linux. Au moment de la connexion, nous vĂ©rifions sur le serveur Asterisk que la connexion entiĂšre est Ă©tablie, et aprĂšs un certain temps, ils devraient entendre le son de Linux dans Embox, et sous Linux, nous enregistrons le fichier lu depuis Embox.

AprÚs avoir travaillé sur QEMU, nous sommes passés au portage sur STM32F7-Discovery. Le premier problÚme - ils ne sont pas entrés dans 1 Mo de ROM sans l'optimisation incluse du compilateur «-Os» en termes de taille d'image. Par conséquent, inclus "-O". De plus, le patch a désactivé la prise en charge C ++, il n'est donc nécessaire que pour pjsua, et nous utilisons simple_pjsua.

AprĂšs avoir installĂ© simple_pjsua , nous avons dĂ©cidĂ© qu'il y avait maintenant des chances de le lancer. Mais d'abord, il fallait gĂ©rer l'enregistrement et la lecture de la voix. Question - oĂč Ă©crire? Nous avons choisi une mĂ©moire externe - SDRAM (128 Mo). Vous pouvez l'essayer vous-mĂȘme:

Crée un WAV stéréo avec une fréquence de 16000 Hz et une durée de 10 secondes:

 record -r 16000 -c 2 -d 10000 -m C0000000 

Nous perdons:

 play -m C0000000 

Il y avait deux problĂšmes. Le premier avec un codec est WM8994, et il a un concept comme un slot, et ces slots sont 4. Donc, par dĂ©faut, si ce n'est pas configurĂ©, alors lors de la lecture audio, la lecture se produit dans les quatre slots. Par consĂ©quent, Ă  une frĂ©quence de 16000 Hz, nous avons reçu 8000 Hz, mais pour 8000 Hz, la lecture n'a tout simplement pas fonctionnĂ©. Lorsque seuls les emplacements 0 et 2 ont Ă©tĂ© sĂ©lectionnĂ©s, cela a fonctionnĂ© comme il se doit. Un autre problĂšme Ă©tait l'interface audio dans le STM32Cube, dans laquelle la sortie audio fonctionne via SAI (Serial Audio Interface) de maniĂšre synchrone avec l'entrĂ©e audio (n'a pas compris les dĂ©tails, mais il s'avĂšre qu'ils partagent une horloge commune et que l'audio y est attachĂ© lors de l'initialisation de la sortie audio entrĂ©e). Autrement dit, ils ne peuvent pas ĂȘtre lancĂ©s sĂ©parĂ©ment, ils ont donc fait ce qui suit - l'entrĂ©e audio et la sortie audio fonctionnent toujours (y compris les interruptions sont gĂ©nĂ©rĂ©es). Mais lorsque rien n'est perdu dans le systĂšme, nous glissons simplement un tampon vide dans la sortie audio, et lorsque la lecture commence, nous commençons honnĂȘtement Ă  le remplir.

De plus, ils ont rencontrĂ© le fait que le son lors de l'enregistrement de la voix Ă©tait trĂšs silencieux. Cela est dĂ» au fait que les microphones MEMS du STM32F7-Discovery ne fonctionnent pas bien Ă  des frĂ©quences infĂ©rieures Ă  16000 Hz. Par consĂ©quent, nous dĂ©finissons 16000 Hz, mĂȘme si 8000 Hz arrive. Pour ce faire, la vĂ©ritĂ© Ă©tait d'ajouter une conversion logicielle d'une frĂ©quence Ă  l'autre.

Ensuite, j'ai dû augmenter la taille du tas, qui est situé dans la RAM. Selon nos estimations, pjsip nécessitait environ 190 Ko, et nous n'en avions qu'environ 100 Ko. Ici, je devais utiliser un peu de mémoire externe - SDRAM (environ 128 Ko).

AprĂšs toutes ces modifications, j'ai vu les premiers packages entre Linux et Embox, et j'ai entendu un son! Mais le son Ă©tait terrible, pas du tout comme sur QEMU, rien ne pouvait ĂȘtre discernĂ©. Ensuite, nous avons rĂ©flĂ©chi Ă  ce qui pourrait ĂȘtre le problĂšme. Le dĂ©bogage a montrĂ© qu'Embox n'a tout simplement pas le temps de remplir / dĂ©charger les tampons audio. Pendant que pjsip traite une trame, 2 interruptions se sont produites avant la fin du traitement de la mĂ©moire tampon, ce qui est trop. La premiĂšre pensĂ©e pour accĂ©lĂ©rer Ă©tait d'optimiser le compilateur, mais il Ă©tait dĂ©jĂ  inclus dans PJSIP. Le second est un virgule flottante matĂ©rielle, nous en avons parlĂ© dans l' article . Mais comme la pratique l'a montrĂ©, le FPU n'a pas donnĂ© une augmentation significative de la vitesse. L'Ă©tape suivante consistait Ă  hiĂ©rarchiser les threads. Embox a diffĂ©rentes stratĂ©gies de planification, et j'en ai inclus une qui prend en charge les prioritĂ©s et dĂ©finit les flux audio sur la prioritĂ© la plus Ă©levĂ©e. Cela n'a pas aidĂ© non plus.

L'idée suivante était que nous travaillions avec de la mémoire externe et qu'il serait bien d'y déplacer des structures, auxquelles on accÚde trÚs souvent. J'ai fait une analyse préliminaire de quand et sous quel simple_pjsua alloue de la mémoire. Il s'est avéré que sur 190 Ko, les 90 premiers Ko sont alloués aux besoins internes du PJSIP et qu'ils ne sont pas consultés trÚs souvent. Ensuite, pendant un appel entrant, la fonction pjsua_call_answer est appelée, dans laquelle les tampons pour travailler avec les trames entrantes et sortantes sont ensuite alloués. C'était environ 100 ko. Et ici, nous avons agi comme suit. Avant l'appel, les données sont placées dans la mémoire externe. DÚs que l'appel - remplacez immédiatement le tas par un autre - en RAM. Ainsi, toutes les données «chaudes» ont été transférées vers une mémoire plus rapide et plus prévisible.

En conséquence, tout cela ensemble a permis de démarrer simple_pjsua et de passer un appel via son serveur. Et puis via d'autres serveurs tels que sip.linphone.org.

Conclusions


En consĂ©quence, il s'est avĂ©rĂ© exĂ©cuter simple_pjsua avec une transmission vocale dans les deux sens via le serveur. Le problĂšme avec la SDRAM de 128 Ko supplĂ©mentaire peut ĂȘtre rĂ©solu en utilisant un Cortex-M7 lĂ©gĂšrement plus puissant (par exemple, STM32F769NI avec 512 Ko de RAM), mais en mĂȘme temps, nous n'avons toujours aucun espoir de tenir dans 256 Ko :) Nous serons heureux si quelqu'un est intĂ©ressĂ© , et encore mieux - essayez. Toutes les sources, comme d'habitude, sont dans notre rĂ©fĂ©rentiel .

Source: https://habr.com/ru/post/fr431134/


All Articles