{"id":37916,"date":"2019-10-31T22:20:31","date_gmt":"2019-10-31T19:20:31","guid":{"rendered":"https:\/\/prohoster.info\/blog\/sip-telefon-na-stm32f7-discovery\/"},"modified":"2019-10-31T22:20:31","modified_gmt":"2019-10-31T19:20:31","slug":"sip-telefon-na-stm32f7-discovery","status":"publish","type":"post","link":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/sip-telefon-na-stm32f7-discovery","title":{"rendered":"SIP phone on STM32F7-Discovery","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Hello everyone.<\/p>\n<p>Some time ago we <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/embox\/blog\/259721\">reported<\/a><\/noindex> discussed how we managed to launch a SIP phone on STM32F4-Discovery with 1 MB of ROM and 192 KB of RAM based on <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/embox\/embox\">Embox<\/a><\/noindex>. It should be noted that that version was minimal and connected two phones directly without a server, transmitting voice only in one direction. Therefore, we decided to launch a more complete phone with calls through a server, two-way voice transmission, while keeping the memory footprint as small as possible.<\/p>\n<p><center><div class=\"youtube-placeholder\" data-id=\"W6wuEIZJf8o\" onclick=\"loadVideo(this)\">\r\n        <img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/W6wuEIZJf8o\/hqdefault.jpg\" alt=\"Play video\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nFor the phone, we decided to choose the application <i>simple_pjsua<\/i> from the PJSIP library. This is a minimal application that can register on a server, receive and make calls. Below, I will immediately provide a description of how to run it on STM32F7-Discovery.<\/p>\n<h3>How to run it<\/h3>\n<p><\/p>\n<ol>\n<li> Configuring Embox\n<pre><code class=\"bash\">make confload-platform\/pjsip\/stm32f7cube<\/code><\/pre>\n<\/li>\n<li>In the file conf\/mods.config, we specify the required SIP account.\n<pre><code class=\"bash\">\ninclude platform.pjsip.cmd.simple_pjsua_imported(\n    sip_domain=\"server\", \n    sip_user=\"username\",\n    sip_passwd=\"password\")\n<\/code><\/pre>\n<p>\nwhere <i>server<\/i> \u2014 this is the SIP server (for example, sip.linphone.org), <i>username<\/i> and <i>password<\/i> \u2014 the username and password for the account.\n<\/li>\n<li>We build Embox with the command <i>make<\/i>. We have information on flashing the board at <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/embox\/embox\/wiki\/Running-Embox-on-STM32xxDiscovery\">wiki<\/a><\/noindex> and in <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/embox\/blog\/349034\/\">article<\/a><\/noindex>.\n<\/li>\n<li>We run the Embox console command \u201csimple_pjsua_imported\u201d\n<pre><code class=\"bash\">\n00:00:12.870    pjsua_acc.c  ....SIP outbound status for acc 0 is not active\n00:00:12.884    pjsua_acc.c  ....sip:alexk2222@sip.linphone.org: registration success, status=200 (Registration success)\n00:00:12.911    pjsua_acc.c  ....Keep-alive timer started for acc 0, destination:91.121.209.194:5060, interval:15s\n<\/code><\/pre>\n<p>\n<\/li>\n<li>Finally, you need to connect speakers or headphones to the audio output and speak into two small MEMS microphones next to the display. We call from Linux through the simple_pjsua application, pjsua. Or you can use any other like linphone.\n<\/li>\n<\/ol>\n<p>\nAll this is described on our <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/embox\/embox\/wiki\/AUDIO-on-STM32\">wiki<\/a><\/noindex>.<\/p>\n<h3>How we got here<\/h3>\n<p>\nSo initially, the question of choosing the hardware platform arose. Since it was clear that STM32F4-Discovery would not be sufficient in terms of memory, STM32F7-Discovery was chosen. It has 1 MB of flash memory and 256 KB of RAM (+ 64 KB of special fast memory, which we will also use). Not abundant for server calls, but we decided to give it a try.<\/p>\n<p>We conditionally divided the task into several stages:<\/p>\n<ul>\n<li>Launching PJSIP on QEMU. This was convenient for debugging, plus we already had support for the AC97 codec there. <\/li>\n<li>Recording voice and playback on QEMU and STM32. <\/li>\n<li> Porting the application <i>simple_pjsua<\/i> from the PJSIP library. It allows registration on the SIP server and making calls. <\/li>\n<li>Setting up our own server based on Asterisk and testing on it, after which we will try external ones, such as sip.linphone.org. <\/li>\n<\/ul>\n<p>\nAudio in Embox works through Portaudio, which is also used in PISIP. The first issues appeared in QEMU \u2014 WAV files played well at 44100 Hz, but at 8000 Hz something clearly went wrong. It turned out that the issue was with the frequency setting \u2014 by default, it was 44100 in the hardware, and this was not changed programmatically on our end. <\/p>\n<p>Here, it might be worth explaining how audio playback actually works. The sound card can be set up with a pointer to a chunk of memory from which it needs to play or record at a predetermined frequency. Once the buffer runs out, an interrupt is generated, and execution continues with the next buffer. The thing is, these buffers need to be filled in advance while the previous one is still being played. We will encounter this issue again later on the STM32F7. <\/p>\n<p>Next, we rented a server and deployed Asterisk on it. Since a lot of debugging was needed and speaking into the microphone wasn\u2019t desirable, we had to implement automatic playback and recording. For this, we patched simple_pjsua so that we could feed files instead of audio devices. In PJSIP, this is quite straightforward as they have the concept of a port, which can be either a device or a file. These ports can be flexibly connected to other ports. You can check the code in our pjsip. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/embox\/pjsip\">the repository<\/a><\/noindex>As a result, the setup was as follows. On the Asterisk server, I created two accounts \u2014 for Linux and for Embox. Then, on Embox, the command <i>simple_pjsua_imported<\/i>, Embox registers on the server, after which we call Embox from Linux. At the moment of the connection, we check on the Asterisk server that the connection is established, and after some time, we should hear the sound from Linux in Embox, while in Linux, we save the file being played from Embox.<\/p>\n<p>After it worked on QEMU, we moved on to porting it to STM32F7-Discovery. The first issue was that it didn\u2019t fit into 1 MB of ROM without enabling the compiler optimization \u201c-Os\u201d for the image size. So we enabled \u201c-Os.\u201d Next, we patched to disable C++ support, as it\u2019s only needed for pjsua, while we use simple_pjsua. <\/p>\n<p>After we managed to fit it in <i>simple_pjsua<\/i>, we decided that there was a chance to run it now. But first, we needed to deal with recording and playback of voice. The question was \u2014 where to record? We chose external memory \u2014 SDRAM (128 MB). You can try this yourself:<\/p>\n<p>Creates a stereo WAV at a frequency of 16000 Hz and a duration of 10 seconds:<\/p>\n<pre><code class=\"bash\">\nrecord -r 16000 -c 2 -d 10000 -m C0000000\n<\/code><\/pre>\n<p>\nPlaying:<\/p>\n<pre><code class=\"bash\">\nplay -m C0000000\n<\/code><\/pre>\n<p>\nHere, two problems arose. The first was with the codec \u2014 it uses WM8994, which has a concept called slots, of which there are 4. By default, if it is not configured, audio playback occurs through all four slots. Therefore, at a frequency of 16000 Hz, we were getting 8000 Hz, and for 8000 Hz the playback simply didn't work. When we selected only slots 0 and 2, it worked as it should. Another problem was with the audio interface in STM32Cube, where the audio output works through SAI (Serial Audio Interface) synchronously with the audio input (I didn't delve into details, but it seems they share a common clock, and during audio output initialization, the audio input gets somehow tied to it). This means they cannot be started separately, so we did the following \u2014 both the audio input and audio output always operate (including generating interrupts). But when nothing is playing in the system, we simply feed an empty buffer to the audio output, and when playback starts, we honestly begin to fill it.<\/p>\n<p>Next, we faced the issue that the sound during voice recording was very quiet. This happens because MEMS microphones on the STM32F7-Discovery somehow perform poorly at frequencies below 16000 Hz. Therefore, we set 16000 Hz even if 8000 Hz comes in. For this, it was necessary to add software conversion from one frequency to another.<\/p>\n<p>Next, it was necessary to increase the heap size located in RAM. According to our calculations, pjsip required about 190 KB, but we had only about 100 KB left. Here, we had to involve a bit of external memory \u2014 SDRAM (about 128 KB).<\/p>\n<p>After all these adjustments, I saw the first packets between Linux and Embox, and I heard sound! But the sound was terrible, nothing like on QEMU, it was impossible to make anything out. Then we wondered what might be the issue. Debugging showed that Embox simply could not keep up with filling\/unloading audio buffers. While pjsip processes one frame, 2 interrupts regarding buffer processing completion occurred, which is too much. The first thought for speeding things up was compiler optimization, but that was already enabled in PJSIP. The second was hardware floating-point support, which we discussed in <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/embox\/blog\/418295\">article<\/a><\/noindex>. However, as practice showed, the FPU did not provide a significant speed increase. The next step was to prioritize streams. In Embox, there are different scheduling strategies, and I enabled the one that supports priorities, giving the highest priority to audio streams. This also did not help.<\/p>\n<p>The next idea was that we work with external memory and it would be good to move structures there that are accessed very frequently. I conducted a preliminary analysis of when and for what purposes <i>simple_pjsua<\/i> memory is allocated. It turned out that of the 190 KB, the first 90 KB are allocated for internal PJSIP needs, and access to them is not very frequent. Then, during an incoming call, the pjsua_call_answer function is called, where buffers for working with incoming and outgoing frames are allocated. This was another about 100 KB. And here\u2019s what we did: until the call, we place the data in external memory. As soon as the call comes in, we immediately swap the heap for another one\u2014in RAM. Thus, all 'hot' data was moved to faster and more predictable memory.<\/p>\n<p>In the end, all of this together allowed us to run <i>simple_pjsua<\/i> and make calls through our server. Then we extended this to other servers such as sip.linphone.org.<\/p>\n<h3>Conclusions<\/h3>\n<p>\nAs a result, we managed to start <i>simple_pjsua<\/i> with voice transmission in both directions through the server. The issue with the additional 128 KB of SDRAM can be resolved by using a slightly more powerful Cortex-M7 (for example, STM32F769NI with 512 KB of RAM), but at the same time, we haven't given up hope of squeezing into 256 KB \ud83d\ude42 We would be happy if anyone is interested, and even better\u2014if they try. As usual, all source codes are available in our <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/embox\/embox\">the repository<\/a><\/noindex>.<br \/>\n<br \/>Source: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/embox\/blog\/431134\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442. \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 \u043c\u044b \u043f\u0438\u0441\u0430\u043b\u0438 \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u043d\u0430\u043c \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c SIP \u0442\u0435\u043b\u0435\u0444\u043e\u043d \u043d\u0430 STM32F4-Discovery c 1 \u041c\u0431 ROM \u0438 192 \u041a\u0431 RAM) \u043d\u0430 \u0431\u0430\u0437\u0435 Embox. \u0422\u0443\u0442 \u043d\u0430\u0434\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u0431\u044b\u043b\u0430 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u044f\u043b\u0430 \u0434\u0432\u0430 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0430 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0431\u0435\u0437 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438 \u0441 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435\u0439 \u0433\u043e\u043b\u043e\u0441\u0430 \u043b\u0438\u0448\u044c \u0432 \u043e\u0434\u043d\u0443 \u0441\u0442\u043e\u0440\u043e\u043d\u0443. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-37916","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442. \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 \u043c\u044b \u043f\u0438\u0441\u0430\u043b\u0438 \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u043d\u0430\u043c \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c SIP \u0442\u0435\u043b\u0435\u0444\u043e\u043d \u043d\u0430 STM32F4-Discovery c 1 \u041c\u0431.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/sip-telefon-na-stm32f7-discovery\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47SIP \u0442\u0435\u043b\u0435\u0444\u043e\u043d \u043d\u0430 STM32F7-Discovery | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442. \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 \u043c\u044b \u043f\u0438\u0441\u0430\u043b\u0438 \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u043d\u0430\u043c \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c SIP \u0442\u0435\u043b\u0435\u0444\u043e\u043d \u043d\u0430 STM32F4-Discovery c 1 \u041c\u0431.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/sip-telefon-na-stm32f7-discovery\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:20:31+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:20:31+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47SIP Phone on STM32F7-Discovery | ProHoster","description":"Hello everyone. Some time ago, we wrote about how we managed to run a SIP phone on STM32F4-Discovery with 1 MB.","canonical_url":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/sip-telefon-na-stm32f7-discovery","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"en_US","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47SIP \u0442\u0435\u043b\u0435\u0444\u043e\u043d \u043d\u0430 STM32F7-Discovery | ProHoster","og:description":"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442. \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 \u043c\u044b \u043f\u0438\u0441\u0430\u043b\u0438 \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u043d\u0430\u043c \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c SIP \u0442\u0435\u043b\u0435\u0444\u043e\u043d \u043d\u0430 STM32F4-Discovery c 1 \u041c\u0431.","og:url":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/sip-telefon-na-stm32f7-discovery","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:20:31+00:00","article:modified_time":"2019-10-31T19:20:31+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"37916","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-23 19:45:21","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:18:22","updated":"2026-01-23 19:45:21","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts\/37916","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/comments?post=37916"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts\/37916\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/media?parent=37916"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/categories?post=37916"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/tags?post=37916"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}