Цитата(Новичек @ 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 не поленился.