Перейти к содержанию
    

А что на основной плате нет диодов?

ОЧень много файлов и я не пойму что они делают. Как вызываются прерывания? где задается время через которое они произойдут? Можно ли сделать прерывание от нажатия на кнопку на отладочной плате? Если да то как(поподробней алгоритм и возможно в сопровождении с кодом).

p.s. как во всем этом разобраться, с чего начать, какой логики следовать и вообще есть доки по русски где описано что да как работает...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А что на основной плате нет диодов?

ОЧень много файлов и я не пойму что они делают. Как вызываются прерывания? где задается время через которое они произойдут? Можно ли сделать прерывание от нажатия на кнопку на отладочной плате? Если да то как(поподробней алгоритм и возможно в сопровождении с кодом).

p.s. как во всем этом разобраться, с чего начать, какой логики следовать и вообще есть доки по русски где описано что да как работает...

 

У вас совсем туго с чтением схем?

На основной плате нет светодиодов напрямую управляемых микроконтроллером, но при желании их можно было бы припаять к разъему X5.

 

Прерывания вызываются все по одному и тому же вектору INTERRUPT_TABLE .

Этот вектор указывает на вход стандартного обработчика прерывания RTOS в файле os_cpu_a.asm

Установка же этого вектора в контроллере прерываний производится

процедурой Set_OS_interrupt каждый раз когда вы хотите назначить новый источник прерываний.

Например для включения таймера тиков RTOS эта процедура вызывается из функции OSTickInit() которая вызывается из main при инициализации RTOS.

Как там организуются прерывания от портов я уже не помню.

 

Логики особой в изучении нет, все зависит от того как лучше воспринимает ваша память.

Я бы начал с просмотра первых функций в main и изучения их содержимого.

Потом с мануала Микриума по их оси.

 

На русском документации конечно никакой не найдете.

За пяток лет проведенных в этой конфе вы наверно пятый, кто интересуется осью под STR912. :biggrin:

Что вас занесло то на него?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

... через пару недель сдавать а мне и показать то нечего т.к. я нифига не понимаю))

 

 

Тогда есть более легкий вариант.

В директории где у вас проинсталлирован Keil должна быть директория Keil\ARM\Boards\ST\STR9_DONGLE\RTX_Blinky

Там как раз пример моргания светодиода сделанный в RTOS RL ARM под плату STR9 Dongle.

Проще уже не бывает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Разбирал пример 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.

з.ы. извините за дурацкие вопросы))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Разбирал пример 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 не поленился.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо за ваши ответы!

по 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. Христос Воскресе

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо за ваши ответы!

по 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 ясно видно как программируется прерывание одного из таймеров.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Смотрите схему платы

На какую схему смотреть и что там я должен увидеть?

Где находится порт P6?

Напишите пожалуйста хотя бы основные служебные команды Keilа, ну или какие помните.

Не могли бы Вы дать ссылочку на проект Measure-RT, а то я найти не могу его.

Как проверит работоспособность данного проекта?

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На какую схему смотреть и что там я должен увидеть?

Где находится порт 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. Если начну все здесь перечислять меня забанят за излишнее цитирование.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

или попробовать запустить проект в симуляторе Keil

Как это сделать? Примерик если можно...

 

 

Изменено пользователем Новичек

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как это сделать? Примерик если можно...

 

Шаг 1. Выбирает конфигурацию симулятора

Шаг 2. Запускаете отладчик

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Шаг 1. Выбирает конфигурацию симулятора

Шаг 2. Запускаете отладчик

сделал , Затем нажал на ctrl+F10, затем нажал на Peripherials->Io Ports -> GPIO6. вижу что галочки как то беспорядочно перемещаются GPIO6_data и Pins остальные никак не изменяются . что это значит? или я что то не так делаю?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня появилась плата 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

post-76382-1368712594_thumb.jpg

Изменено пользователем Новичек

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В проекте 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; вообще не понятно)

Изменено пользователем Новичек

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...