KolinRol 0 2 мая, 2013 Опубликовано 2 мая, 2013 · Жалоба А что на основной плате нет диодов? ОЧень много файлов и я не пойму что они делают. Как вызываются прерывания? где задается время через которое они произойдут? Можно ли сделать прерывание от нажатия на кнопку на отладочной плате? Если да то как(поподробней алгоритм и возможно в сопровождении с кодом). p.s. как во всем этом разобраться, с чего начать, какой логики следовать и вообще есть доки по русски где описано что да как работает... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 2 мая, 2013 Опубликовано 2 мая, 2013 · Жалоба А что на основной плате нет диодов? ОЧень много файлов и я не пойму что они делают. Как вызываются прерывания? где задается время через которое они произойдут? Можно ли сделать прерывание от нажатия на кнопку на отладочной плате? Если да то как(поподробней алгоритм и возможно в сопровождении с кодом). p.s. как во всем этом разобраться, с чего начать, какой логики следовать и вообще есть доки по русски где описано что да как работает... У вас совсем туго с чтением схем? На основной плате нет светодиодов напрямую управляемых микроконтроллером, но при желании их можно было бы припаять к разъему X5. Прерывания вызываются все по одному и тому же вектору INTERRUPT_TABLE . Этот вектор указывает на вход стандартного обработчика прерывания RTOS в файле os_cpu_a.asm Установка же этого вектора в контроллере прерываний производится процедурой Set_OS_interrupt каждый раз когда вы хотите назначить новый источник прерываний. Например для включения таймера тиков RTOS эта процедура вызывается из функции OSTickInit() которая вызывается из main при инициализации RTOS. Как там организуются прерывания от портов я уже не помню. Логики особой в изучении нет, все зависит от того как лучше воспринимает ваша память. Я бы начал с просмотра первых функций в main и изучения их содержимого. Потом с мануала Микриума по их оси. На русском документации конечно никакой не найдете. За пяток лет проведенных в этой конфе вы наверно пятый, кто интересуется осью под STR912. Что вас занесло то на него? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KolinRol 0 2 мая, 2013 Опубликовано 2 мая, 2013 · Жалоба У меня курсовая работа. Научник сказал рабирайся сам. сказал научиться управлять светодиодами, писать функции, вызываемые в программе по аппаратному прерыванию (удобным источником прерывания может быть нажатие кнопки на отладочной плате), программировать системный таймер на генерацию аппаратного прерывания через предсказуемый интервал времени, совместить все предыдущее + планировщик, то есть написать пару программ управления светодиодами, которые поочередно запускаются планировщиком, который, в свою очередь, получает управление по сигналу прерывания от системного таймера. Конечно ничего не ясно и ничего не понятно что и делать когда ты полный ноль... через пару недель сдавать а мне и показать то нечего т.к. я нифига не понимаю)) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 2 мая, 2013 Опубликовано 2 мая, 2013 · Жалоба ... через пару недель сдавать а мне и показать то нечего т.к. я нифига не понимаю)) Тогда есть более легкий вариант. В директории где у вас проинсталлирован Keil должна быть директория Keil\ARM\Boards\ST\STR9_DONGLE\RTX_Blinky Там как раз пример моргания светодиода сделанный в RTOS RL ARM под плату STR9 Dongle. Проще уже не бывает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KolinRol 0 3 мая, 2013 Опубликовано 3 мая, 2013 · Жалоба Разбирал пример RTX_Blinky. Возникли следующие вопросы: 1)присваиваются значение #define LED_A 0x02 #define LED_B 0x01 #define LED_C 0x08 #define LED_CLK 0x04 Из каких соображений взяли именно эти значения? 2что это значит? #define LED_On(led) GPIO6->DR[led<<2] = ~led #define LED_Off(led) GPIO6->DR[led<<2] = led Я нашёл что #define GPIO6 ((GPIO_TypeDef *)GPIO6_BASE) что это? потом это typedef struct { vu8 DR[1021]; /* Data Register */ vu32 DDR; /* Data Direction Register */ } GPIO_TypeDef; #define GPIO6_BASE (AHBAPB0_BASE + APB_GPIO6_OFST) #define AHBAPB0_BASE (AHB_APB_BRDG0_U) #define AHB_APB_BRDG0_U (0x58000000) /* AHB/APB Bridge 0 UnBuffered Space */ #define APB_GPIO6_OFST (0x0000C000) /* Offset of GPIO6 */ И тут я перестал понимать что я получил... Тоже самое получил с разбором этого: #define SCU ((SCU_TypeDef *)SCU_BASE) typedef struct { vu32 CLKCNTR; /* Clock Control Register */ vu32 PLLCONF; /* PLL Configuration Register */ vu32 SYSSTATUS; /* System Status Register */ vu32 PWRMNG; /* Power Management Register */ vu32 ITCMSK; /* Interrupt Mask Register */ vu32 PCGRO; /* Peripheral Clock Gating Register 0 */ vu32 PCGR1; /* Peripheral Clock Gating Register 1 */ vu32 PRR0; /* Peripheral Reset Register 0 */ vu32 PRR1; /* Peripheral Reset Register 1 */ vu32 MGR0; /* Idle Mode Mask Gating Register 0 */ vu32 MGR1; /* Idle Mode Mask Gating Register 1 */ vu32 PECGR0; /* Peripheral Emulation Clock Gating Register 0 */ vu32 PECGR1; /* Peripheral Emulation Clock Gating Register 1 */ vu32 SCR0; /* System Configuration Register 0 */ vu32 SCR1; /* System Configuration Register 1 */ vu32 SCR2; /* System Configuration Register 2 */ u32 EMPTY1; vu32 GPIOOUT[8]; /* GPIO Output Registers */ vu32 GPIOIN[8]; /* GPIO Input Registers */ vu32 GPIOTYPE[10]; /* GPIO Type Registers */ vu32 GPIOEMI; /* GPIO EMI Selector Register */ vu32 WKUPSEL; /* Wake-Up Selection Register */ u32 EMPTY2[2]; vu32 GPIOANA; /* GPIO Analag mode Register */ } SCU_TypeDef; #define SCU_BASE (AHBAPB1_BASE + APB_SCU_OFST) #define AHBAPB1_BASE (AHB_APB_BRDG1_U) #define AHB_APB_BRDG1_U (0x5C000000) /* AHB/APB Bridge 1 UnBuffered Space */ #define APB_SCU_OFST (0x00002000) /* Offset of System Controller */ объясните какие выводы я должен сделать? 4) разбирал функции которые там применяются получил: #define os_tsk_create(tsk,prio) os_tsk_create0(tsk,prio,NULL,NULL) typedef U32 OS_TID; extern OS_TID os_tsk_create0 (void (*task)(void), U32 prio_stksz, void *stk, void *argv); ********************************************************************** #define os_evt_set(evt_flags,task_id) _os_evt_set((U32)rt_evt_set,evt_flags,task_id) extern void _os_evt_set (U32 p, U16 event_flags, OS_TID task_id) __SVC_0; ********************************************************************** #define os_tsk_delete_self() os_tsk_delete(0) extern OS_RESULT os_tsk_delete (OS_TID task_id); #define os_tsk_delete(task_id) _os_tsk_delete((U32)rt_tsk_delete,task_id) extern OS_RESULT _os_tsk_delete (U32 p, OS_TID task_id) __SVC_0; #define __SVC_0 __svc_indirect(0) ********************************************************************** #define os_evt_wait_and(wflags,tmo) _os_evt_wait((U32)rt_evt_wait,wflags,tmo,__TRUE) extern OS_RESULT _os_evt_wait(U32 p, U16 wait_flags, U16 timeout, BOOL and_wait) __SVC_0; ********************************************************************** #define os_dly_wait(delay_time) _os_dly_wait((U32)rt_dly_wait,delay_time) extern void _os_dly_wait (U32 p, U16 delay_time) __SVC_0; функции объявлены а что они делают вообще не понятно.. Мб я не то нашёл... так же вообще не нашёл что делает _os_dly_wait, __SVC_0 , __svc_indirect(0). Или как раз _os_dly_wait выполняет __SVC_0 тогда все равно не ясно что делает __SVC_0. з.ы. извините за дурацкие вопросы)) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 3 мая, 2013 Опубликовано 3 мая, 2013 · Жалоба Разбирал пример RTX_Blinky. Возникли следующие вопросы: 1)присваиваются значение #define LED_A 0x02 #define LED_B 0x01 #define LED_C 0x08 #define LED_CLK 0x04 Из каких соображений взяли именно эти значения? Заметьте что в каждом определении есть только по одному единичному биту. Эти биты определяют пин в порте GPIO6 к которому подключен соответствующий светодиод. 2что это значит? #define LED_On(led) GPIO6->DR[led<<2] = ~led #define LED_Off(led) GPIO6->DR[led<<2] = led Я нашёл что #define GPIO6 ((GPIO_TypeDef *)GPIO6_BASE) что это? потом это typedef struct { vu8 DR[1021]; /* Data Register */ vu32 DDR; /* Data Direction Register */ } GPIO_TypeDef; Здесь вам надо прочитать параграф 3.2.1 GPIO_DATA register read/write masking из юзермануала на STR912. Так программисты Keil-а объявили порты чтобы реализовать запись единичных битов без предварительного чтения порта. А маской служит шина адреса. Т.е. индекc массива он появляется на шине адреса во время записи и определяет маску куда будет записан бит. Такой вот оригинальный подход есть в STR912. Если бы не этот финт, то надо было бы сначала прочитать в регистр CPU состояние порта, потом изменить один интересующий бит в регистре и обратно записать регистр в порт. Этот метод называют чтение-модификация-запись. Но в многозадачной среде надо быть готовым, что в момент времени между чтением порта и записью в него может влезть другая более приоритетная задача, которая тоже хочет что-то записать в другой бит этого порта. Она свое дело сделает и отдаст управление первой задаче, а та тут же перезапишет в порт старые не актуальные данные. Так рождаются самые самые мистические и трудно ловимые баги в RTOS. По уму надо было бы тогда запрещать прерывания другими задачами участка где идет изменение бита в порту, но тогда запись каждого бита превращается в целую процедуру. #define GPIO6_BASE (AHBAPB0_BASE + APB_GPIO6_OFST) #define AHBAPB0_BASE (AHB_APB_BRDG0_U) #define AHB_APB_BRDG0_U (0x58000000) /* AHB/APB Bridge 0 UnBuffered Space */ #define APB_GPIO6_OFST (0x0000C000) /* Offset of GPIO6 */ И тут я перестал понимать что я получил... Здесь как бы понятно. Адреса задаются как смещения от базы. Причем базы может быть две с разными адресами. Здесь выбрана база AHB_APB_BRDG0_U. Если адресоваться от нее то запись не будет внутри чипа буферизироваться. Это медленнее, но зато не будет конфликтов с движком DMA. Есть другая база, при адресации от нее запись буферизируется. Это быстрее, но надо следить чтобы туда не лазил DMA. 4) разбирал функции которые там применяются получил: #define os_tsk_create(tsk,prio) os_tsk_create0(tsk,prio,NULL,NULL) typedef U32 OS_TID; extern OS_TID os_tsk_create0 (void (*task)(void), U32 prio_stksz, void *stk, void *argv); ********************************************************************** #define os_evt_set(evt_flags,task_id) _os_evt_set((U32)rt_evt_set,evt_flags,task_id) extern void _os_evt_set (U32 p, U16 event_flags, OS_TID task_id) __SVC_0; ********************************************************************** #define os_tsk_delete_self() os_tsk_delete(0) extern OS_RESULT os_tsk_delete (OS_TID task_id); #define os_tsk_delete(task_id) _os_tsk_delete((U32)rt_tsk_delete,task_id) extern OS_RESULT _os_tsk_delete (U32 p, OS_TID task_id) __SVC_0; #define __SVC_0 __svc_indirect(0) ********************************************************************** #define os_evt_wait_and(wflags,tmo) _os_evt_wait((U32)rt_evt_wait,wflags,tmo,__TRUE) extern OS_RESULT _os_evt_wait(U32 p, U16 wait_flags, U16 timeout, BOOL and_wait) __SVC_0; ********************************************************************** #define os_dly_wait(delay_time) _os_dly_wait((U32)rt_dly_wait,delay_time) extern void _os_dly_wait (U32 p, U16 delay_time) __SVC_0; функции объявлены а что они делают вообще не понятно.. Мб я не то нашёл... так же вообще не нашёл что делает _os_dly_wait, __SVC_0 , __svc_indirect(0). Или как раз _os_dly_wait выполняет __SVC_0 тогда все равно не ясно что делает __SVC_0. з.ы. извините за дурацкие вопросы)) __SVC_0 - это служебное слово Keil-а и означает вызов прерывания супервизора по вектору SWI_Handler (определен в файле STR91x.s) Далее обработчик в режиме супервизора достает из стека аргументы переданные при вызове прерывания. Первым аргументом идет собственно указатель на функцию которую процедура прерывания должна выполнить. Для _os_dly_wait это будет rt_dly_wait. Но выполняться она уже будет с правами супервизора. Т.е. обычные задачи в RL ARM выполняются с правами юзера и это значит, что доступ к некоторым регистрам из задач будет закрыт. Другие RTOS под ARM9 такое не применяют в виду громоздкости создания функций доступа к защищенной периферии. А вот Keil не поленился. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KolinRol 0 5 мая, 2013 Опубликовано 5 мая, 2013 · Жалоба Спасибо за ваши ответы! по 1 вопросу. получается что GPIO имеет 4 выхода и при установлении соответствующей единицы туда подается напряжение? по 2 вопросу. Почему в данном случае сначала используют указатель GPIO6->DR[led<<2] = ~led а потом не указатель GPIO6->DR[led<<2] = led? Так программисты Keil-а объявили порты чтобы реализовать запись единичных битов без предварительного чтения порта. А маской служит шина адреса. Т.е. индекc массива он появляется на шине адреса во время записи и определяет маску куда будет записан бит. здесь немного не понял... у нас в структуре GPIO_TypeDef 1024 значения. GPIO6->DR[led<<2] = ~led к примеру led=LED_A=0000 0010. смещаем на два. получаем 0000 0000 , т.е. DR[0] записали 0000 0010. и что?) #define GPIO6 ((GPIO_TypeDef *)GPIO6_BASE) - это строка не очень ясна. Что означает " *) ". Это что то на подобие умножение значения на маску? почему выбрано такое смещение APB_GPIO6_OFST (0x0000C000)? или это просто так? по 4 вопросу. Какие ещё существуют служебные команды? Можете ещё разъяснить про вектора и как пишутся прерывание. p.s. Христос Воскресе Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 5 мая, 2013 Опубликовано 5 мая, 2013 · Жалоба Спасибо за ваши ответы! по 1 вопросу. получается что GPIO имеет 4 выхода и при установлении соответствующей единицы туда подается напряжение? по 2 вопросу. Почему в данном случае сначала используют указатель GPIO6->DR[led<<2] = ~led а потом не указатель GPIO6->DR[led<<2] = led? Итак код #define LED_On(led) GPIO6->DR[led<<2] = ~led #define LED_Off(led) GPIO6->DR[led<<2] = led он правильный, во первых. Сомневаться в нем не надо. Смотрите схему платы. Светодиоды зажигаются установкой нуля на линии порта! Не на порту всего есть 4 выхода, а только 4-е выхода используются на порту для светодиодов. Возьмем LED_On(LED_A) перепишем: GPIO6->DR[0x02<<2] = ~0x02 и далее упростив: GPIO6->DR[0x08] = 0xFD Т.е. по адресу (0x58000000 + 0x0000C008) записывается значение 0xFD где 0x0000C000 это смещение порта P6 , а 0x58000000 -база для смещения Сместили на 2-а бита влево значение индекса потому, что младшие два бита на шине адреса не входят в маску. Главное, что маска(она же индекс в массиве DR) содержит только один бит, и этот бит указывает позицию в регистре порта где может быть изменено(вернее разрешено изменить) значение бита. И этот бит этой операцией изменяется на 0. В принципе вместо ~0x02 программеры могли просто написать 0. Но видать что-то в душе им не дало так написать, чего-то побоялись. Я их понимаю. Глючнее чем STR912 не видал чипа. Еще служебных команд смотрите все таки в хелпе на компилятор Keil. Мне затруднительно сейчас все вспоминать. Как назначаются прерывания и как пишутся обработчики прерываний можете посмотреть в соседнем проекте Measure-RT. Там прямо в функции main ясно видно как программируется прерывание одного из таймеров. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KolinRol 0 6 мая, 2013 Опубликовано 6 мая, 2013 · Жалоба Смотрите схему платы На какую схему смотреть и что там я должен увидеть? Где находится порт P6? Напишите пожалуйста хотя бы основные служебные команды Keilа, ну или какие помните. Не могли бы Вы дать ссылочку на проект Measure-RT, а то я найти не могу его. Как проверит работоспособность данного проекта? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 8 мая, 2013 Опубликовано 8 мая, 2013 · Жалоба На какую схему смотреть и что там я должен увидеть? Где находится порт P6? Напишите пожалуйста хотя бы основные служебные команды Keilа, ну или какие помните. Не могли бы Вы дать ссылочку на проект Measure-RT, а то я найти не могу его. Как проверит работоспособность данного проекта? Смотреть надо схему платы "STR912 Dongle" http://media.digikey.com/pdf/Data%20Sheets...01V(1,%202).pdf лист 6/19 , там изображены светодиоды и написано к каким сигналам микроконтроллера они подключены. На листе 4/19 изображен микроконтроллер с портом P6 (пины 21,31,19,20) Для этой платы созданы проекты из папаки C:\Keil\ARM\Boards\ST\STR9_DONGLE Проект Measure-RT можете найти в директории C:\Keil\ARM\Boards\ST\STR9_DONGLE\Measure-RT Чтобы проверить работоспособность, можете плату купить http://www.oemstrade.com/search/STEVAL-IFD001V1/#A2115664355 или попробовать запустить проект в симуляторе Keil Служебные команды можете найти в меню HELP-> uVision Help в IDE Keil следуя пути: ARM Development Tools -> Compiler Reference Guide -> Compiler-specific Features их там под 150. Если начну все здесь перечислять меня забанят за излишнее цитирование. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KolinRol 0 9 мая, 2013 Опубликовано 9 мая, 2013 (изменено) · Жалоба или попробовать запустить проект в симуляторе Keil Как это сделать? Примерик если можно... Изменено 9 мая, 2013 пользователем Новичек Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 9 мая, 2013 Опубликовано 9 мая, 2013 · Жалоба Как это сделать? Примерик если можно... Шаг 1. Выбирает конфигурацию симулятора Шаг 2. Запускаете отладчик Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KolinRol 0 12 мая, 2013 Опубликовано 12 мая, 2013 · Жалоба Шаг 1. Выбирает конфигурацию симулятора Шаг 2. Запускаете отладчик сделал , Затем нажал на ctrl+F10, затем нажал на Peripherials->Io Ports -> GPIO6. вижу что галочки как то беспорядочно перемещаются GPIO6_data и Pins остальные никак не изменяются . что это значит? или я что то не так делаю? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KolinRol 0 16 мая, 2013 Опубликовано 16 мая, 2013 (изменено) · Жалоба У меня появилась плата MCB-STR9. Запустил на нее мигание светодиодами. Не могу теперь понять, как написать сделать что бы при нажатии на кнопку на плате загорались к примеру разные светодиоды. Вот сама плата. Пробовал портировать uCOS AlexsandrY выдало ошибку Error: Cannot load driver 'E:\Keil\ARM\BIN\AGDIRDI.DLL'. Possible Reasons: - Driver DLL could not be found in the specified path - Driver DLL requires additional DLL's which are not installed - Required Hardware Drivers are not installed Что это значит? Вообще реально портировать на эту плату uCOS? Если да то что нужно сделать? ______________MSB_str9.pdf STR912FAW44X6_datasheet.pdf Изменено 16 мая, 2013 пользователем Новичек Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KolinRol 0 18 мая, 2013 Опубликовано 18 мая, 2013 (изменено) · Жалоба В проекте Measure есть описание как подключить кнопки. Есть непонятность с режимами(mode). Что за режимы и с чем его едят?? SCU->GPIOOUT[7] = 0x5555; /* P7.0..7 output - mode 1 */ SCU->GPIOOUT[3] &= 0xC3FF; /* P3.5, P3.6 input mode */ Подскажите почему в одном случае присваивание идет а в другом & ? /* ADC Setup */ ADC->CR |= 0x0002; /* Set POR bit */ for (i = 0; i < 48000; i ++); /* Wait > 1 ms (at 48 MHz) */ ADC->CR &= 0xFFF7; /* Clear STB bit */ for (i = 0; i < (48*15); i ++); /* Wait > 15 us (at 48 MHz) */ ADC->CR |= 0x0033; /* cont. conversion all channels */ ADC->CCR |= 0x00FF; /* ADC, no WDG, Channel 0..4 */ Что за POR bit, STB bit? Задержки нужны что бы что то произошло? ADC->CR |= 0x0033; ADC->CCR |= 0x00FF; вообще не понятно) Изменено 18 мая, 2013 пользователем Новичек Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться