|
RTOS для STR912fw44 RTOS, планировщик задач |
|
|
|
Apr 6 2013, 17:31
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 6-04-13
Пользователь №: 76 382

|
Всем доброго времени суток! Мне нужно реализовать планировщик задач. Для начала самый простой: без приоритетов через квант времени переключать два какие-нибудь процесса. p.s. извините что если это глупый вопрос)
Сообщение отредактировал Новичек - Apr 6 2013, 17:33
|
|
|
|
|
Apr 6 2013, 18:26
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 6-04-13
Пользователь №: 76 382

|
У меня курсовая работа. Научник сказал написать планировщик. Как я понял за основу нужно взять freeRTOS (как бы все кроме планировщика). Я не очень хорошо программирую. Я не могу понять к примеру от куда, как взять квант времени.
|
|
|
|
|
Apr 7 2013, 15:45
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 6-04-13
Пользователь №: 76 382

|
Где найти этот таймер или есть какая та определенная команда?
|
|
|
|
|
Apr 7 2013, 16:32
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Цитата(Новичек @ Apr 6 2013, 21:26)  У меня курсовая работа. Научник сказал написать планировщик. Как я понял за основу нужно взять freeRTOS (как бы все кроме планировщика). Я не очень хорошо программирую. Я не могу понять к примеру от куда, как взять квант времени. Квант времени не берут, а задают или ждут. Задается квант один раз при инициализации какого либо таймера который может генерировать прерывания. В STR912fw44 я использовал для этих целей таймер часов реального времени (RTC). У меня есть порт uCOS-II на STR912fw44. Рекомендую изучать uCOS-II. Эта RTOS гораздо легче(яснее) написана чем FreeRTOS, лучше откоментирована и документирована. Из нее проще будет вычленить планировщик и сделать рефакторинг.
|
|
|
|
|
Apr 7 2013, 17:37
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 6-04-13
Пользователь №: 76 382

|
Цитата(AlexandrY @ Apr 7 2013, 20:32)  Квант времени не берут, а задают или ждут. Задается квант один раз при инициализации какого либо таймера который может генерировать прерывания. В STR912fw44 я использовал для этих целей таймер часов реального времени (RTC).
У меня есть порт uCOS-II на STR912fw44. Рекомендую изучать uCOS-II. Эта RTOS гораздо легче(яснее) написана чем FreeRTOS, лучше откоментирована и документирована. Из нее проще будет вычленить планировщик и сделать рефакторинг. AlexandrY могу ли я с вами связаться по почте или каким либо другим образом т.к. л/c не могу написать (выдает ошибку)? Моя почта veselvi@rambler.ru.
|
|
|
|
|
Apr 13 2013, 17:13
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 6-04-13
Пользователь №: 76 382

|
Где можно скачать uCOS-II? Никак не могу найти.
|
|
|
|
|
Apr 29 2013, 13:17
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 6-04-13
Пользователь №: 76 382

|
Помогите создать проект в Keil для str912 мигания светодиода. Может быть нужно подключить какие нибудь уже ненаписанные библиотеки для данного МК?
|
|
|
|
|
Apr 29 2013, 19:55
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Цитата(Новичек @ Apr 29 2013, 16:17)  Помогите создать проект в Keil для str912 мигания светодиода. Может быть нужно подключить какие нибудь уже ненаписанные библиотеки для данного МК? Вот выложил порт UCOSII для STR912Порт сделан для моей платформы, схема и плата есть в том же архиве. Там же есть и файловая система от Keil и TCP стек от Micrium. Есть тесты Dhrystone и Whetstone. Ну и конечно моргание светодиодом. Но по STR912 я не консультирую, так как перестал ими заниматься уже несколько лет. Скачиватель может ругнуться, так как в архиве есть .exe файл микриума для тестирования быстродействия TCP/IP протокола - PCATTCP.
|
|
|
|
|
Apr 30 2013, 14:03
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 6-04-13
Пользователь №: 76 382

|
Спасибо Александр. Как я понял там 3 проекта: Flash, Ram, extRam. Когда компилируешь выдает кучу ошибок. Мне кается что в проектах не хватает файлов Ekernel и EkernelComps. Можешь ещё сказать какие файлы что означает а то я их открываю и голова сразу взрывается... Не понимаю как связь организована между ними и что каждый из них может делать. Какие из этих файлов представляют особую важность для начального освоения. с чего начать? может быть где то лежит документация на русском что означают сокращения? Можете ещё объяснить как по схеме что нибудь понять) хот бы одну логическую цепочку. p.s. где мигалка то? ))) и какие файлы для её работы необходимы?
Сообщение отредактировал Новичек - Apr 30 2013, 14:07
|
|
|
|
|
Apr 30 2013, 19:39
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Цитата(Новичек @ Apr 30 2013, 17:03)  Спасибо Александр. Как я понял там 3 проекта: Flash, Ram, extRam. Когда компилируешь выдает кучу ошибок. Мне кается что в проектах не хватает файлов Ekernel и EkernelComps. Можешь ещё сказать какие файлы что означает а то я их открываю и голова сразу взрывается... Не понимаю как связь организована между ними и что каждый из них может делать. Какие из этих файлов представляют особую важность для начального освоения. с чего начать? может быть где то лежит документация на русском что означают сокращения? Можете ещё объяснить как по схеме что нибудь понять) хот бы одну логическую цепочку. p.s. где мигалка то? ))) и какие файлы для её работы необходимы? Эт потому что взялись компилировать последним Keil-ом, а я ж говорил, что проект старый. Значит и компилировать надо старыми тулсами. Но ничего, я исправил. Снова скачайте по старой ссылке. Keil в последних своих хидерах RTL.h взялся объявлять BSD сокеты, а в проекте они уже были в TCP стеке микриума. Ekernel я убрал чтоб не мешал, это был движок логического контроллера. Еще я добавил схему верхней платы поскольку светодиоды находились на ней. Платы связаны через 40-а пиновый разъем X5 (на main board) и X14 (на AddOn board). Светодиоды управляются с помощью микросхемы расширителя портов по I2C (U5 на AddOn board, MCP23016-I/SS). I2C идет по линиям SDA1, SCL1 на контакты 13, 14 разъема X14 (на AddOn board) и приходит к микроконтроллеру (U2, STR912FW44X6) на ноги 33, 35 на main board. Все начинается с файла app.c, там процедура main. В ней создается задача AppManTask в которой инициализируется расширитель портов, драйвер UART, виртуальный COM порт по USB, WEB сервер, VT100 терминал и проч. и кроме этого создается задача LedTask в которой то и производится циклическое включение и выключение всех светодиодов. Сама RTOS находится в директории UCOS. Я ее скомпилировал в библиотеку. Там найдете проект для компиляции библиотеки. Тут же и самый важный и самый хитрый и самый критичный файл RTOS - os_cpu_a.asm. Это ручная работа, которая выполняется для каждой платформы индивидуально, переключатель контекстов RTOS. От надежности и оптимальности этого переключателя зависит стабильность и быстродействие всей оси и то насколько быстро будут обрабатываться все прерывания. На втором по важности месте находятся файлы в директории BSP. Там собраны процедуры низкоуровневой работы с периферией. В других осях их бы называли драйверами, но в UCOS нет выраженной концепции драйверов, поэтому там просто наборы функций для работы с интерфейсами, портами, таймерами и проч. В частности за работу с расширителем портов по I2C отвечает файл MCP23016_IOexp.c Стек TCP микриума находится в директории TCP В USB находится понятно все что связано с USB. Дальше уж как нибудь сами разбирайтесь. В проекте есть файл proj.vpw это рабочее пространство редактора SlickEdit, я всегда им пользуюсь для написания и изучения исходников. Рекомендую. Проект Keil карту адресов берет из диалога в IDE. .sct файлы не используются. Проект грузится во Flash и выполняется с адреса 0. Там сами смотрите STR91x_startup.s если что пойдет не так с инициализацией памяти.
|
|
|
|
|
May 2 2013, 13:10
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 6-04-13
Пользователь №: 76 382

|
А что на основной плате нет диодов? ОЧень много файлов и я не пойму что они делают. Как вызываются прерывания? где задается время через которое они произойдут? Можно ли сделать прерывание от нажатия на кнопку на отладочной плате? Если да то как(поподробней алгоритм и возможно в сопровождении с кодом). p.s. как во всем этом разобраться, с чего начать, какой логики следовать и вообще есть доки по русски где описано что да как работает...
|
|
|
|
|
May 2 2013, 13:58
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Цитата(Новичек @ May 2 2013, 16:10)  А что на основной плате нет диодов? ОЧень много файлов и я не пойму что они делают. Как вызываются прерывания? где задается время через которое они произойдут? Можно ли сделать прерывание от нажатия на кнопку на отладочной плате? Если да то как(поподробней алгоритм и возможно в сопровождении с кодом). p.s. как во всем этом разобраться, с чего начать, какой логики следовать и вообще есть доки по русски где описано что да как работает... У вас совсем туго с чтением схем? На основной плате нет светодиодов напрямую управляемых микроконтроллером, но при желании их можно было бы припаять к разъему X5. Прерывания вызываются все по одному и тому же вектору INTERRUPT_TABLE . Этот вектор указывает на вход стандартного обработчика прерывания RTOS в файле os_cpu_a.asmУстановка же этого вектора в контроллере прерываний производится процедурой Set_OS_interrupt каждый раз когда вы хотите назначить новый источник прерываний. Например для включения таймера тиков RTOS эта процедура вызывается из функции OSTickInit() которая вызывается из main при инициализации RTOS. Как там организуются прерывания от портов я уже не помню. Логики особой в изучении нет, все зависит от того как лучше воспринимает ваша память. Я бы начал с просмотра первых функций в main и изучения их содержимого. Потом с мануала Микриума по их оси. На русском документации конечно никакой не найдете. За пяток лет проведенных в этой конфе вы наверно пятый, кто интересуется осью под STR912. Что вас занесло то на него?
|
|
|
|
|
May 2 2013, 14:32
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 6-04-13
Пользователь №: 76 382

|
У меня курсовая работа. Научник сказал рабирайся сам. сказал научиться управлять светодиодами, писать функции, вызываемые в программе по аппаратному прерыванию (удобным источником прерывания может быть нажатие кнопки на отладочной плате), программировать системный таймер на генерацию аппаратного прерывания через предсказуемый интервал времени, совместить все предыдущее + планировщик, то есть написать пару программ управления светодиодами, которые поочередно запускаются планировщиком, который, в свою очередь, получает управление по сигналу прерывания от системного таймера. Конечно ничего не ясно и ничего не понятно что и делать когда ты полный ноль... через пару недель сдавать а мне и показать то нечего т.к. я нифига не понимаю))
|
|
|
|
|
May 2 2013, 19:30
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Цитата(Новичек @ May 2 2013, 17:32)  ... через пару недель сдавать а мне и показать то нечего т.к. я нифига не понимаю)) Тогда есть более легкий вариант. В директории где у вас проинсталлирован Keil должна быть директория Keil\ARM\Boards\ST\STR9_DONGLE\RTX_Blinky Там как раз пример моргания светодиода сделанный в RTOS RL ARM под плату STR9 Dongle. Проще уже не бывает.
|
|
|
|
|
May 3 2013, 18:08
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 6-04-13
Пользователь №: 76 382

|
Разбирал пример 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. з.ы. извините за дурацкие вопросы))
|
|
|
|
|
May 3 2013, 19:31
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Цитата(Новичек @ May 3 2013, 21:08)  Разбирал пример RTX_Blinky. Возникли следующие вопросы: 1)присваиваются значение Код #define LED_A 0x02 #define LED_B 0x01 #define LED_C 0x08 #define LED_CLK 0x04 Из каких соображений взяли именно эти значения? Заметьте что в каждом определении есть только по одному единичному биту. Эти биты определяют пин в порте GPIO6 к которому подключен соответствующий светодиод. Цитата(Новичек @ May 3 2013, 21:08)  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. По уму надо было бы тогда запрещать прерывания другими задачами участка где идет изменение бита в порту, но тогда запись каждого бита превращается в целую процедуру. Цитата(Новичек @ May 3 2013, 21:08)  Код #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. Цитата(Новичек @ May 3 2013, 21:08)  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 не поленился.
|
|
|
|
|
May 5 2013, 13:28
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 6-04-13
Пользователь №: 76 382

|
Спасибо за ваши ответы! по 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. Христос Воскресе
|
|
|
|
|
May 5 2013, 20:09
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Цитата(Новичек @ May 5 2013, 16:28)  Спасибо за ваши ответы! по 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 ясно видно как программируется прерывание одного из таймеров.
|
|
|
|
|
May 6 2013, 11:09
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 6-04-13
Пользователь №: 76 382

|
Цитата Смотрите схему платы На какую схему смотреть и что там я должен увидеть? Где находится порт P6? Напишите пожалуйста хотя бы основные служебные команды Keilа, ну или какие помните. Не могли бы Вы дать ссылочку на проект Measure-RT, а то я найти не могу его. Как проверит работоспособность данного проекта?
|
|
|
|
|
May 8 2013, 13:01
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Цитата(Новичек @ May 6 2013, 14:09)  На какую схему смотреть и что там я должен увидеть? Где находится порт 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. Если начну все здесь перечислять меня забанят за излишнее цитирование.
|
|
|
|
|
May 9 2013, 13:26
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 6-04-13
Пользователь №: 76 382

|
Цитата или попробовать запустить проект в симуляторе Keil Как это сделать? Примерик если можно...
Сообщение отредактировал Новичек - May 9 2013, 13:26
|
|
|
|
|
May 12 2013, 19:07
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 6-04-13
Пользователь №: 76 382

|
Шаг 1. Выбирает конфигурацию симулятора Шаг 2. Запускаете отладчик сделал , Затем нажал на ctrl+F10, затем нажал на Peripherials->Io Ports -> GPIO6. вижу что галочки как то беспорядочно перемещаются GPIO6_data и Pins остальные никак не изменяются . что это значит? или я что то не так делаю?
|
|
|
|
|
May 16 2013, 14:46
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 6-04-13
Пользователь №: 76 382

|
У меня появилась плата 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? Если да то что нужно сделать?
Сообщение отредактировал Новичек - May 16 2013, 13:55
Эскизы прикрепленных изображений
|
|
|
|
|
May 18 2013, 19:23
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 6-04-13
Пользователь №: 76 382

|
В проекте 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; вообще не понятно)
Сообщение отредактировал Новичек - May 18 2013, 19:29
|
|
|
|
|
May 23 2013, 19:32
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 6-04-13
Пользователь №: 76 382

|
В мануале только написано что POR бит установления в режим ожидания. Про STB даже расшифровки не нашёл. В мануале про биты СR и CCR тоже ничего нет. Может я какой не тот мануал смотрю? Я начинаю понимать что я не понимаю самой работы МК. Вот есть векторный контроллер прерываний VIC. vu32 DVAR; /* Default Vector Address Register */ вектор адреса регистра по умолчанию vu32 VAiR[16]; /* Vector Address 0-15 Register */ вектор адреса регистра vu32 VCiR[16]; /* Vector Control 0-15 Register */ вектор управления регистрами Для чего эти вектора нужны? Вот на плате есть кнопка у нее Пин 3.5. Как сделать что бы нажатие на нее вызвало прерывание? Сделаем Обычный входом SCU->GPIOOUT[3] &= 0xF3FF; Для того что бы ей подключить нужно подать напряжение это GPIO3->DDR &= 0xDF; При нажатии что происходит (что изменится?) и куда направляется сигнал? После того как порт подключили надо как то вектор прерывания включить.... Как это сделать? На 48 странице моего мануала там есть таблица 8. Там есть Pin3.5. Там написаны названия функция а описания их нет. Зачем тогда нужны эти функции?
|
|
|
|
|
May 24 2013, 17:10
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 6-04-13
Пользователь №: 76 382

|
В примере где задействован потенциометр blinky.project я не могу понять как значение AD_last определяется в соответствии c вращением потенциометра. .
E:\Keil\ARM\Boards\Keil\MCBSTR9\Blinky\IRQ.c(15) : short AD_last; /* Last AD value read in interrupt */ E:\Keil\ARM\Boards\Keil\MCBSTR9\Blinky\IRQ.c(40) : AD_last = ADC->DR0 & 0x03FF; /* AD value for global usage (10 bit) */
E:\Keil\ARM\Inc\ST\91x\91x_map.h(61) : vu16 DR0; /* Data Register for Channel 0 */
тут как бы получается что используются первые 10 бит нулевого канала. А как понять что именно с нулевого канала идут изменения от потенциометра? или я что то не так понимаю?
p.s. Помогите пожалуйста.... курсовая в пятницу а мне и показать нечего...
Сообщение отредактировал Новичек - May 24 2013, 17:10
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|