======Пример взаимодействия двух ядер в МК 1901ВЦ1Т====== Микроконтроллер 1901ВЦ1Т является двухъядерным, на борту которого расположено 32-разрядное RISC ядро и 16-разрядное DSP. В данной статье будет рассмотрена работа и взаимодействие между собой двух подсистем на примере совместной отладки. =====Взаимодействие двух подсистем===== Основным ядром процессора 1901ВЦ1Т является RISC, DSP – подчиненным. Поэтому для начала выполнения DSP-программы, RISC ядро должно выполнить инициализацию ядра DSP и записать в программную область код для выполнения. После этого, ядра могут работать независимо друг от друга. Всё адресное пространство и вся память DSP (память данных, память программ, регистры периферийных блоков), за исключением регистров ядра, доступны RISC-ядру и, поскольку оно является ведущим в микроконтроллере, то на него возложены функции управления синхросигналами, сигналами сброса, режимами работы и энергопотребления. При подаче питания DSP-система находится в состоянии сброса. RISC загружает в ОЗУ область DSP нужную программу, после чего, непосредственно перед началом работы с подчиненной системой, снимает сброс, и DSP начинает выполнять поставленную задачу. По завершению выполнения задачи подсистема DSP может оповестить RISC-ядро, которое, в свою очередь, сформирует новую задачу или отключит DSP. Если RISC-ядро загружено непрерываемой задачей, то может пройти существенное время, прежде чем оно выполнит отключение уже неактивного DSP. {{prog:spec:dsp-risc:shot_21.png}} =====CCS,CodeMaster-ARM, Jem-MultiChip===== Для программирования и отладки DSP-подсистемы рекомендуется использовать Code Composer Studio v3.3. в сочетании с отладчиком компании Фитон Jem-MultiChip. {{prog:spec:dsp-risc:shot_9.jpg}} Конечно же, среда CCS 3.3 не сможет работать с данным отладчиком «из коробки». Необходимо установить драйверы и саму среду компании Фитон CodeMaster-ARM, которая является посредником между CCS и отладчиком JEM-MultiChip. Отладку ядер системы можно осуществлять независимо друг от друга, через один и тот же порт и с использованием одного и того же адаптера. Поэтому, если мы хотим отлаживать только DSP-ядро, нам все равно необходимо открыть среду CodeMaster-ARM, чтобы установить связь с отладчиком. Работать только с ядром RISC можно по аналогии, как и с другими 32-разрядными МК компании: использовать такие же средства разработки в сочетании с совместимыми с ними средствами отладки. Загрузить драйвер для отладчика можно с сайта производителя отладчика по данной [[http://www.phyton.ru/files/SFX/JEM-MultiChip.exe|ссылке]]. Установку драйвера необходимо выполнять по данной [[https://www.dropbox.com/s/23xgmbyxc90zkyx/JEM-MultiChip.pdf?dl=0|инструкции]](стр 14).Затем необходимо произвести настройки среды CSS в зависимости от версии среды. Эти настройки также представлены в том же мануале (стр.18 для версии 2.2 и стр.22 для версии 3.3). Подключать отладчик можно как к разъёму JTAG-B, так и к разъему JTAG-A. =====Проект===== Архив проекта можно загрузить с форума по данной [[http://forum.milandr.ru/download/file.php?id=807|ссылке]]. _risc_dsp.rar – архив проекта под Code Composer Studio _rdc.rar – проекта под CodeMaster-ARM. Обе среды обязательно необходимо запускать с правами администратора. После установки драйверов, убедимся что CCS обнаруживает отладчик. Для этого сначала запускаем CodeMaster-ARM, выбираем наш Jem-MultiChip. {{prog:spec:dsp-risc:shot_3.png}} Теперь CodeMaster можно свернуть и запустить CCS (запускать надо приложение Setup CCStudio v3.3). В нем мы видим, что выбрано устройство TMS320C5400_0 (является функциональным аналогом ЦОС ядра микроконтроллера) по результатам настройки из предыдущего раздела с отладчиком JEM. {{prog:spec:dsp-risc:shot_5.png}} В этом окне выбираем вкладку File-> Start Code Composer Studio. После старта среды сверху будет вкладка с нашим отладчиком, где можно выбрать частоту TCK, это свидетельствует о том, что связь отладчика и среды установлена. {{prog:spec:dsp-risc:shot_6.png}} =====RISC===== Теперь воспользуемся архивом _rdc.rar и откроем проект в ранее запущенном Code Master-ARM. Чтобы обеспечить взаимодействие двух систем RISC и DSP между собой, в системе реализованы два регистра прерываний. Один от RISC к DSP (5 пользовательских прерываний), другой DSP к RISC(4 пользовательских прерывания). Рассмотрим сразу основную функцию: void main() { ClockConfig(); //настройка тактирования RISC и DSP PortsConfig(); //конфигурация портов ввода вывода UART3Config(); //конфигурация UART ClearRAMDSP(); //очистка ОЗУ DSP buffer = (uint32_t*)(DSP_BUFFER); for(temp=0;temp<256;temp++) { *buffer++ = temp; } buffer = (uint32_t*)(DSP_BUFFER); NVIC_EnableIRQ(DSP_IRQ_IRQn); // разрешение прерываний от DSP StartDSPTask(); // постановка задачи DSP записать информацию в программную область while(1); } В программе после настроек тактирования, конфигурирования портов и настройки UART, происходит постановка задачи для DSP-ядра, затем попадание в бесконечный цикл. DSP-программа принимает запрос на выполнение задачи и решает её. По завершению выставляется бит запроса прерывания DIRQ0. После ожидается постановка новой задачи. Как только выставляется запрос прерывания от DSP, RISC-ядро переходит в функцию обработчика прерываний void DSP_IRQ_IRQHandler, в которой происходит передача данных (буфер 256, 16-разрядных слов) через UART3, и вновь ставится DSP новая задача. =====DSP===== После разбора программы в для RISC ядра можно выполнить компиляцию и вернуться (или открыть заново) в CCS. Здесь открываем проект _risc_dsp.rar Поскольку ранее не работали с этой средой, начнём по пунктам. Выбираем вкладку Project->Open и выбираем файл с расширением *.pjt И слева в дереве проекта находим и открываем main.c Задача DSP в данном примере - сформировать счётчик в буфере и сгенерировать запрос к RISC. #include "_include.h" #include "math.h" #define _SIZE 256 #pragma DATA_SECTION(_status,"_STATUS"); static unsigned short _status=0x0000; #pragma DATA_SECTION(_buff,"_BUFF"); static float _buff[_SIZE]; #pragma DATA_SECTION(_intr_reg,"_INTR_RISC"); static unsigned short _intr_reg; void main() { unsigned short _i; unsigned short _counter=0; float _in; _in = 100.0; while(1) { //while(!(_status&0x0001)) asm(" NOP "); for(_i=0;_i<_SIZE;_i++) _buff[_i] = sqrt(_in);//_counter++; _status &= ~0x0001; _intr_reg = 0x8001; } } Теперь можно также выполнить компиляцию проекта, выбрав вкладку Project-> Build(или можно воспользоваться клавишей F7). =====Совместная отладка===== Наша задача состоит в том, чтобы поймать обработанное прерывание от DSP к RISC. Для этого вернёмся в CodeMaster-ARM и выберем пункт в меню «Создать проект и запустить отладку» (Сочетание клавиш Shift+F7). Теперь перед запуском программы необходимо поставить точку останова в функции обработчика прерываний DSP_IRQ_IRQHandler. Так мы убедимся, что прерывание от DSP пришло и RISC запустил его обработку. Саму программу пока не запускаем. {{prog:spec:dsp-risc:shot_7.png}} Возвращаемся в CCS. И приступим к отладке ЦОСа. Проект мы уже собрали, теперь его необходимо загрузить. Для этого переходим по вкладке File->Load Program. Здесь чуть посложнее, чем в других IDE. Нам необходимо выбрать объектный файл, и наша программа загрузится в память контроллера. Есть более упрощенный вариант: перейти по вкладке Option->Customize. Затем идём на вкладку Program/Project/CIO и ставим галочку напротив пункта “Load Program After Build”. Так после каждой сборки проекта он автоматически будет загружаться в контроллер. После выполнения загрузки сразу откроется окно Disassembly. Переходим во вкладку Debug->Go to main (сочетание клавиш Ctrl+M). Нам открывается main.c, а отладчик стоит в начале главной функции. {{prog:spec:dsp-risc:shot_8.png}} Слева становятся доступны клавиши для отладки по шагам. Мы же просто запустим программу, выбрав Run ("бегущего человечка"). DSP выполняет задачу и постоянно генерирует запросы на прерывания к RISC. Возвращаемся в CodeMaster-ARM, запускаем программу и наблюдаем, как RISC ядро встало на выставленной ранее точке останова, тем самым подтверждая полученный запрос на прерывание от DSP и приступив к его обработке. В функции обработчика идёт отправка данных по UART. Можно подключить плату к PC и наблюдать посылаемые данные при каждом прерывании от DSP.