Специфика программирования CC2540
Недавно перестал правильно работать код прошивки небольшого BLE контроллера TI CC2540.
Было довольно проблематично и интересно выяснить причину ...
Основной функционал прошивки работал верно, но при попытке bonding'а происходило что-то странное. Пин код вроде принимался, но последующий запрос атрибута помеченного GATT_PERMIT_ENCRYPT_READ или GATT_PERMIT_ENCRYPT_WRITE возвращал ошибку авторизации.
Так как это произошло после обновления SDK платформы и подключения небольшого нового функционала я решил, что дело в этих изменениях.
Средства отладки довольно убогие и медленные - иногда они сами влияли на логику работы своими задержками. Пришлось потратить довольно много времени на запуски демок из SDK и сравнении их исходников с проектом.
В конце концов все оказалось просто.
Вот мой код, который влиял на функционал GAP Bond Manager:
if(bufferPage == NULL)
bufferPage = (uint32*) osal_mem_alloc(HAL_FLASH_PAGE_SIZE);
Это динамическое выделение буфера забирало последние доступные 2K RAM и последующая работа GAP Bond Manager уже была невозможна. Т.к. здесь мы имеем дело с контроллером мы не получим runtime exception "Out of Memory".
Компилятор может сругнуться об превышении допустимого значения ОЗУ, только если объявить массив с фиксированным большим размером.
Пришлось переписать код без выделения такого "огромного" буфера. Формально код стол медленней, но память RAM контроллера в 2К теперь не нужна.
Очевидные выводы:
0) Нельзя расслабляться и совсем деградировать. Когда используешь C# для десктоп приложений на современных писюках забываешь вообще про память.
1) Память можно контролировать по *.map файлу проекта. Там уже было около 6К и предел в 8К был очень близок.
2) Правильно говорил мне авторитетный спец - всякие фреймворки в MCU это зло. Хочешь сделать хорошо сделай это сам. Считай память, считай тайминги прерываний и разряды ЦАП/АЦП и тогда микронтроллер будет работать оптимально и эффективно.