Май 09

STM32 CCM

Есть у некоторых взрослых STM-ок такая дурная штука, как CCM (core coupled memory). Это отдельный регион памяти, не шуточного размера в 64K (для F4xx), который по-умолчанию вообще не используется. Выделена эта память в отдельный регион, потому что имеет подключение только к D-BUS ядра, что накладывает кое-какие ограничения. Главное — это невозможно использовать вместе с DMA и DMA2D, а в остальном — память как память.
Есть несколько способов хоть как-то его начать использовать, самый простой способ — это положить туда стек.
Для этого нужно модифицировать всего одну строку скрипта линковки, ту что задает адрес _estack и положить в этот символ адрес конца CCM (0x10010000):

_estack = 0x10010000;    /* end of CCMRAM */

При этом весь стек переедет в CCM и как следствие все локальные переменные, аргументы функции итд.
Второй не менее простой, но довольно ручной способ — это указание секции при описании переменной:

__attribute__((section(".ccmram"))) int ccmvar;

однако, стоит при этом помнить, что без модификации startup-скрипта при инициализации там будет мусор, заполним нулями, добавив где-нибудь после FillZeroBSS

/* Zero fill the CCM segment. */
ldr  r2, =_sccmram
FillZeroCCM:
  movs  r3, #0
  str  r3, [r2], #4
 
LoopFillZeroCCM:
  ldr  r3, = _eccmram
  cmp  r2, r3
  bcc  FillZeroCCM

а заодно уберем в скрипте линковки из описания секции .ccmram запись инициализации во FLASH:

  .ccmram :
  {
    . = ALIGN(4);
    _sccmram = .;       /* create a global symbol at ccmram start */
    *(.ccmram)
    *(.ccmram*)
 
    . = ALIGN(4);
    _eccmram = .;       /* create a global symbol at ccmram end */
   } >CCMRAM

теперь все переменные с attribute((section(«.ccmram»))) будут стартовать с нулевыми значениями

Фев 19

PJSIP отладка

А вот что сделали удобно, так это отладку. Вместо грязного sip set debug on, теперь есть история пакетов. Включается запись истории командой pjsip set history on, выключается соответственно: pjsip set history off. Посмотреть, что записалось в историю поможет команда pjsip show history, которая в удобном формате покажет, какие сообщения sip пробежали за время записи, а команда pjsip show history entry 1 покажет полностью сообщение номер 1 (как не сложно догадаться)
В общем, удобно

Фев 18

Asterisk PJSIP и voip.domru.ru

В догонку к предыдущему, подключение телефонии Дом.Ру к Asterisk pjsip. Поскольку voip.domru.ru желает видеть в регистрации длинный номер (UserID), а идентифицирует по короткому (AuthID) использовать pjsip_wizard не получится, о чем мелким шрифтом сообщает документация придется писать полный конфиг. Впрочем, ничего сложного. Пример конфигурации ниже.
Да, в бумажке по астериску, которую они присылают непонятно зачем устанавливается CallerID, делать этого не стоит — он подменит все входящие звонки.
Continue reading

Фев 18

Asterisk и миграция на PJSIP

Не буду писать о том, что такое PJSIP и почему он теперь есть. И без меня писателей хватает, поэтому быстренько пробежимся по настройкам, и основным моментам для тех, кто использовал chan_sip.
Главная проблема при переходе заключается в том, что в PJSIP добавили гибкости, причем в таких количествах, что ей подавиться не сложно. Для каждого пира (теперь он называется endpoint) нужно сделать несколько секций (входящая и исходящая авторизация, регистрация, сам endpoint и еще несколько). Но, через какое-то время передумали и добавили модуль pjsip wizard, который, при загрузке сам сделает что нужно. На него-то и будем рассчитывать. В ubuntu-server 18.04 LTS Asterisk версии 13, древненько но пусть будет.
Continue reading

Янв 14

Прозрачный gVim в windows

Мне нравятся терминалы с прозрачным фоном, а вот gVim под Windows как-то из этой темы выпадает, а бывает что им иногда пользуюсь. Никогда не заморачивался, а вот решение оказывается есть:

if has("win32")
Plug 'mattn/transparency-windows-vim'
Plug 'mattn/vimtweak'
endif

Дек 26

STM32: Шифруем прошивку.

Не сильно хорошая, но все же защита от бездумного копирования устройства. А может быть и еще что-то. В общем, идея такая: зашифровать некоторые критические функции, без которых устройство работать не будет, хитрожопые алгоритмы или математика какая-нибудь. Причем, желательно не потерять удобную сборку и отладку, и использовать желательно без всяких указателей. Я использую arm-none-eabi-gcc в качестве тулчейна и CMake как систему сборки. Поэтому все нижесказанное относится именно к этой связки и для других компиляторов-сборщиков придется немного перепилить.
Continue reading

Авг 31

STM32 и malloc во внешней памяти FMC / SDRAM

После того, как FMC/FSMC запустился и работает, внешняя память отражается по соответствующим адресам. Эту память можно использовать по захардкоденным адресам

char * ptr = (char*)0xC0000000;

но каждый раз вычислять адреса не комильфо. Тем более, для этого как раз есть специальная штука — heap и malloc/free.
Нужно только рассказать malloc где у нас эта память и сколько её. Самый простой способ — исправить правила линковки: Суть такова. _sbrk использует память начиная c адреса переданного линковщиком как end, стоит положить его адрес SDRAM, как malloc начинает раздавать адреса из неё.
Continue reading

Ноя 01

AVR упрощаем TWI (I2C)

Давно уже написал, а выложить все как-то влом было. Но если вдруг, кому потребуется, простенькая библиотечка для работы с Two-Wire Interface (TWI, он же I2C) на AVR вообще и ATMega328p (та самая, которая в arduino nano v3 стоит) в частности.

Пользоваться проще некуда, подглядеть в libtwi.h всегда можно.

Скачать на гитхабе github.com/bevice/libtwi

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include "main.h"
#include "libtwi.h"
#include <util/delay.h>
void setup() {
    twi_init();
    DDRB |= _BV(PB5); // включим PB5 на выход, на Arduino Nano там светодиодик
 
}
 
#define DATA_SIZE 10
static uint8_t data[DATA_SIZE] ={0};
 
void twi_cb(uint8_t status){
    if(status!= TWI_STATUS_ERROR) // если все прочиталось - перевернем светодиод
        DDRB ^= _BV(PB5);
}
 
int main() {
    setup();
 
    while (1) {
        // для 24CXX при записи передается адрес и следом данные.
        uint8_t buff[] = {0x10,1,2,3,4,5}; 
        // передаем buff в железку с адресом  0xA0, 
        // как закончим передавать - дергаем twi_cb
        twi_transmit_data(0xA0, sizeof(buff), buff, &twi_cb);
 
        _delay_ms(1000);
 
        // читаем  DATA_SIZE байт из железки 
        // с адресом 0xA0 начиная с регистра 0x10
        // как в буффер data, как дочитаем
        //  - попадем в коллбек twi_cb с соответствующим статусом
    twi_receive_data_adr8(0xA0, 0x10, DATA_SIZE, data, &twi_cb);
 
    _delay_ms(1000);
    }
}
Июл 08

Такие дела..


Сижу отлаживаю железку на китайской arduino-nano-v3, тыкаю анализатором на RX ногу, а там пусто, иголки одни. Хотя AVR-ка точно с уарта читает и отвечает как надо.
А на самом деле-то не должна, полтора вольта за логический 0 это вообще как?