Skip to content

Commit d1e7a90

Browse files
authored
Добавлен курс LFD112x (Building Applications with RISC-V and FreeRTOS) (#7)
* Add draft of course LFD112x * Fixed note and table rendering * moved .gitignore for images and deleted unused video frames * added quotes substitutions * added links in russian and some minor fixes * added LFD112x to course list * added unbreakable block, fixed some mistakes * some renames in chapter 3 * fixed some typos added links in russian * fixed some typos * fixed some typos, added unbreakable block * added terms draft * fixed `risc-v` line breakage and table alignment * updated terms
1 parent ebd7e4f commit d1e7a90

33 files changed

+2428
-0
lines changed

Courses.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
LFD113x-RU,RISC-V_Toolchain_and_Compiler_Optimization_Techniques_LFD113x_RU,Инструментарий и компиляторные оптимизации для RISC-V (LFD113x) RU
2+
LFD112x-RU,Building_Applications_with_FreeRTOS_and_RISC-V_LFD112x_RU,Создание приложений на базе RISC-V и FreeRTOS (LFD112x) RU

LFD112x-RU/Chapters/Chapter1.adoc

Lines changed: 293 additions & 0 deletions
Large diffs are not rendered by default.

LFD112x-RU/Chapters/Chapter2.adoc

Lines changed: 745 additions & 0 deletions
Large diffs are not rendered by default.

LFD112x-RU/Chapters/Chapter3.adoc

Lines changed: 240 additions & 0 deletions
Large diffs are not rendered by default.

LFD112x-RU/Chapters/Chapter4.adoc

Lines changed: 489 additions & 0 deletions
Large diffs are not rendered by default.

LFD112x-RU/Chapters/Chapter5.adoc

Lines changed: 289 additions & 0 deletions
Large diffs are not rendered by default.

LFD112x-RU/Chapters/Chapter6.adoc

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
== Создание приложений под FreeRTOS и RISC-V
2+
3+
В последней главе этого курса мы рассмотрим процесс создания простого приложения FreeRTOS для процессора RISC-V, а затем скомпилируем и запустим наше приложение с помощью инструментария RISC-V.
4+
Мы закончим главу описанием различных сложных приложений, которые уже являются частью платформы FreeRTOS.
5+
6+
К концу этой главы вы будете в силах:
7+
8+
* Объяснять этапы создания и запуска приложения FreeRTOS.
9+
* Создавать простые приложения.
10+
* Компилировать и запускать приложения.
11+
* Понимать процесс создания более сложных приложений.
12+
13+
=== Этапы создания приложения FreeRTOS
14+
15+
==== Инструкции
16+
17+
Давайте рассмотрим шаги, необходимые для создания приложения FreeRTOS.
18+
19+
===== Шаг 1:
20+
21+
Начните со списка файлов и настроек, представленных в главе <<section-freertos>>.
22+
23+
===== Шаг 2:
24+
25+
Определите требования к приложению.
26+
После определения требований к приложению убедитесь, что следующие детали также определены:
27+
28+
* необходимые задачи для приложения;
29+
* взаимодействие между задачами;
30+
* зависимости между задачами:
31+
** зависимости от данных;
32+
** зависимости управления;
33+
* требования к отклику в реальном времени для задач в приложении.
34+
35+
После их определения разработчик приложения может планировать использование либо одного файла, либо нескольких файлов для определения и создания приложения.
36+
37+
===== Шаг 3:
38+
39+
Начните определять задачи в файлах по мере необходимости.
40+
Все задачи должны быть определены перед запуском планировщика FreeRTOS.
41+
42+
.Пример определения задачи
43+
[source,c]
44+
----
45+
xTaskCreate(
46+
/* Pointer to the function that implements the task. */
47+
vTaskCode,
48+
/* Name of the task. */
49+
"Demo task",
50+
/* The size of the stack that should be created for the task. This is defined in words, not bytes. */
51+
STACK_SIZE,
52+
/* A reference to xParameters is used as the task parameter. This is cast to a void * to prevent compiler warnings. */
53+
(void*) &xParameter,
54+
/* The priority to be assigned to the newly created task. */
55+
TASK_PRIORITY,
56+
/* The handle to the created task will be placed into xHandle parameter as the output of the xTaskCreate function. */
57+
&xHandle
58+
)
59+
----
60+
61+
Более подробную информацию о создании задач см. в https://www.freertos.org/Documentation/RTOS_book.html[справочном руководстве FreeRTOS], доступном на веб-сайте FreeRTOS.
62+
63+
Добавьте дополнительные задачи, если это необходимо для приложения.
64+
Когда все задачи определены, можно запускать планировщик.
65+
66+
===== Шаг 4:
67+
68+
Скомпилируйте код с помощью установленного компилятора RISC-V и запустите приложение в QEMU.
69+
Позже вы сможете портировать его на выбранное вами оборудование.
70+
71+
=== Создание простого приложения
72+
73+
==== Описание примера приложения
74+
75+
Ниже приводится описание упрощенного образца приложения.
76+
На основе этого описания мы создадим требования и построим приложение.
77+
78+
Есть два входа, которые поступают в систему из двух внешних источников.
79+
Назовем эти входы `In1` и `In2`.
80+
Имеется один выход, `Out1`, размер которого составляет два бита.
81+
82+
`In1` может менять свое состояние каждые 10 мс, а `In2` может менять свое состояние каждые 20 мс.
83+
Исходя из значений `In1` и `In2`, поведение `Out1` определено ниже.
84+
85+
* Если `In1` *высокий*, бит `0` `Out1` *высокий*; если `In1` *низкий*, бит `0` `Out1` *низкий*
86+
* Если `In2` *высокий*, бит `1` `Out1` *высокий*; если `In2` *низкий*, бит `1` `Out1` *низкий*
87+
88+
Для этого приложения необходимо три задачи: две для сбора входных данных и одна для управления выходом.
89+
Поэтому мы определим три задачи в главной функции.
90+
91+
Ниже приводится одна из возможных реализаций двух задач для сбора входных данных:
92+
93+
[source,c]
94+
----
95+
static void prvQueueSendTask1( void *pvParameters )
96+
{
97+
TickType_t xNextWakeTime;
98+
const unsigned long ulValueToSend = 100UL;
99+
const char * const pcMessage1 = "Transfer1";
100+
const char * const pcMessage2 = "Transfer2";
101+
102+
/* Remove compiler warning about unused parameter. */
103+
( void ) pvParameters;
104+
105+
/* Initialize xNextWakeTime; this only needs to be done once. */
106+
xNextWakeTime = xTaskGetTickCount();
107+
108+
for( ;; )
109+
{
110+
111+
char buf[40];
112+
113+
sprintf( buf, "%d: %s: %s", xGetCoreID(),
114+
pcTaskGetName( xTaskGetCurrentTaskHandle() ),
115+
pcMessage1 );
116+
vSendString( buf );
117+
118+
/* Place this task into Blocked state until it is time to run again. */
119+
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS1 );
120+
121+
/* Send input of 100UL to the queue, causing the queue to
122+
receive the task to unblock and toggle the LED. Since 0 is
123+
used as the block time, the sending operation will not block;
124+
it shouldn't need to block, as the queue should always be
125+
empty at this point in the code. */
126+
xQueueSend( xQueue, &ulValueToSend, 0U );
127+
}
128+
}
129+
130+
static void prvQueueSendTask2( void *pvParameters )
131+
{
132+
133+
TickType_t xNextWakeTime;
134+
const unsigned long ulValueToSend = 200UL;
135+
const char * const pcMessage1 = "Transfer1";
136+
const char * const pcMessage2 = "Transfer2";
137+
138+
/* Remove compiler warning about unused parameter. */
139+
( void ) pvParameters;
140+
141+
/* Initialize xNextWakeTime; this only needs to be done once. */
142+
xNextWakeTime = xTaskGetTickCount();
143+
144+
for( ;; )
145+
{
146+
147+
char buf[40];
148+
149+
sprintf( buf, "%d: %s: %s", xGetCoreID(),
150+
pcTaskGetName( xTaskGetCurrentTaskHandle() ),
151+
pcMessage2 );
152+
vSendString( buf );
153+
154+
/* Place this task into Blocked state until it is time to run again. */
155+
vTaskDelayUntil( &xNextWakeTime,mainQUEUE_SEND_FREQUENCY_MS2 );
156+
157+
/* Send input of 200UL to the queue, causing the queue to
158+
receive the task to unblock and toggle the LED. Since 0 is
159+
used as the block time, the sending operation will not block;
160+
it shouldn't need to block, as the queue should always be
161+
empty at this point in the code. */
162+
xQueueSend( xQueue, &ulValueToSend, 0U );
163+
}
164+
}
165+
----
166+
167+
Задача для управления выходом может быть смоделирована следующим образом:
168+
169+
[source,c]
170+
----
171+
static void prvQueueReceiveTask( void *pvParameters )
172+
{
173+
174+
unsigned long ulReceivedValue;
175+
const unsigned long ulExpectedValue1 = 100UL;
176+
const unsigned long ulExpectedValue2 = 200UL;
177+
const char * const pcMessage1 = "Blink1";
178+
const char * const pcMessage2 = "Blink2";
179+
const char * const pcFailMessage = "Unexpected value received\r\n";
180+
181+
/* Remove compiler warning about unused parameter. */
182+
( void ) pvParameters;
183+
184+
for( ;; )
185+
{
186+
187+
char buf[40];
188+
189+
/* Wait until something arrives in the queue; this task will
190+
block indefinitely, provided that INCLUDE_vTaskSuspend is set
191+
to 1 in FreeRTOSConfig.h. */
192+
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
193+
194+
/* To get here, something must have been received from the queue – but is it the expected value? If it is, toggle the LED. */
195+
if( ulReceivedValue == ulExpectedValue1 )
196+
{
197+
sprintf( buf, "%d: %s: %s", xGetCoreID(),
198+
pcTaskGetName( xTaskGetCurrentTaskHandle() ),
199+
pcMessage1 );
200+
vSendString( buf );
201+
202+
ulReceivedValue = 0U;
203+
}
204+
else if( ulReceivedValue == ulExpectedValue2 )
205+
{
206+
sprintf( buf, "%d: %s: %s", xGetCoreID(),
207+
pcTaskGetName( xTaskGetCurrentTaskHandle() ),
208+
pcMessage2 );
209+
vSendString( buf );
210+
211+
ulReceivedValue = 0U;
212+
}
213+
else
214+
{
215+
vSendString( pcFailMessage );
216+
}
217+
}
218+
}
219+
----
220+
221+
Поскольку этот пример выполняется в режиме эмуляции, мы реализовали задачи ввода для совместного использования входных данных с задачей вывода через очередь.
222+
В реальной системе эти данные поступали бы через входные контакты.
223+
Аналогично, выходной сигнал в примере представлен в виде текстовых сообщений, тогда как в реальном приложении он будет иметь форму светящихся светодиодов.
224+
225+
=== Компиляция и запуск приложения
226+
227+
==== Как компилировать и запускать приложения
228+
229+
Компиляция и запуск приложения могут быть выполнены с помощью скриптов или простых файлов `make`.
230+
231+
[%unbreakable]
232+
--
233+
Результат примера показан на изображении ниже:
234+
235+
image:app_execution.png[Пример запуска приложения]
236+
--
237+
238+
Вывод для этого примера также можно увидеть в демонстрационном видео, представленном в главе <<section-porting>>.
239+
240+
=== Создание более сложных приложений
241+
242+
Общие шаги для создания более сложных приложений такие же, как и для создания простых приложений, а именно:
243+
244+
[arabic]
245+
. Сбор требований к приложению.
246+
. Определение входов и выходов системы и их зависимостей.
247+
. Сбор всех требований к приложению, связанных со временем.
248+
249+
После сбора вышеуказанной информации следующим шагом будет определение необходимых задач, очередей, семафоров и других соответствующих компонентов для приложения.
250+
Создайте приложение, используя эту информацию, а затем перейдите к фазам компиляции и запуска.
251+
252+
Сложные демонстрационные приложения для FreeRTOS можно найти в следующем месте FreeRTOS на GitHub: `+FreeRTOS/FreeRTOS-Plus/Demo/+`.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
[#section-terms]
2+
[glossary]
3+
== Список терминов
4+
5+
non-real-time systems:: системы общего назначения
6+
round-robin:: круговое обслуживание
7+
static time scheduling algorithm:: статическое планирование
8+
rate-monotonic scheduling:: монотонное планирование скорости
9+
tick hook functions:: функции перехвата, вызванные прерыванием тика
10+
idle hook functions:: функции перехвата, вызванные задачей ожидания
11+
trace:: трассировка
12+
interrupt:: прерывание
13+
interrupt vector:: вектор прерываний
14+
Full interrupt nesting model:: модель полной вложенности прерываний
15+
scheduler:: планировщик
16+
Third party contributions:: сторонние контрибуции
17+
core of the kernel:: ядро ядра
18+
best-fit:: алгоритм наибольшего соответствия
19+
deeply embedded:: глубоко встраиваемые
20+
task prior state:: предшествующее состояние задачи
21+
ready (task state):: готова к выполнению
22+
running (task state):: выполняется
23+
blocked (task state):: заблокирована
24+
suspended (task state):: приостановлена
25+
resume operation:: операция возобновления
26+
run tasks of equal priority in a time slice manner:: выполнение задач с одинаковым приоритетом в режиме «нарезания времени»
27+
fixed-function accelerators:: ускорители с фиксированными функциями
28+
toolchaint:: инструментарий
29+
porting:: портирование, перенос
30+
ISA (Instruction Set Architecture):: архитектура набора команд, в курсе используется аббревиатура
31+
trap:: ловушка
32+
CSR (Control and Status Register):: в курсе не переводится
33+
EEI (Execution Environment Interface):: интерфейс среды выполнения, в курсе используется аббревиатура
34+
cross compiler:: кросс-компилятор
35+
sanity test:: тест на работоспособность
36+
tool flow:: поток инструментов
37+
coroutines:: сопрограммы/корутины

LFD112x-RU/Course.adoc

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
:riscv: RISC&#8209;V
2+
3+
= Создание приложений на базе {riscv} и FreeRTOS
4+
:source-highlighter: rouge
5+
:doctype: book
6+
:icons: font
7+
:toc: macro
8+
:toc-title: Содержание
9+
:chapter-signifier: Глава
10+
:figure-caption: Рисунок
11+
:table-caption: Таблица
12+
:stem: latexmath
13+
:imagesdir: images
14+
15+
Данные материалы являются переводом курса https://training.linuxfoundation.org/training/building-applications-with-risc-v-and-freertos-lfd112x/[Building Applications with RISC-V and FreeRTOS (LFD112x)], распространяемого под лицензией https://creativecommons.org/licenses/by/4.0/[CC BY 4.0].
16+
17+
Перед прочтением курса рекомендуем читателю ознакомиться с используемыми в нём терминами и их переводами, список которых можно найти в разделе <<section-terms>>.
18+
19+
toc::[]
20+
21+
:imagesoutdir: images
22+
:pp: ++
23+
:lquot: &#171;
24+
:rquot: &#187;
25+
26+
:sectnums:
27+
include::Chapters/Chapter1.adoc[Глава 1. Введение в RTOS и встраиваемые системы]
28+
29+
:sectnumlevels: 2
30+
include::Chapters/Chapter2.adoc[Глава 2. FreeRTOS]
31+
32+
:sectnumlevels: 3
33+
include::Chapters/Chapter3.adoc[Глава 3. Портирование FreeRTOS на другую программную или аппаратную платформу]
34+
35+
include::Chapters/Chapter4.adoc[Глава 4. Процессоры {riscv}]
36+
37+
include::Chapters/Chapter5.adoc[Глава 5. Портирование приложений FreeRTOS на процессоры {riscv}]
38+
39+
include::Chapters/Chapter6.adoc[Глава 6. Создание приложений под FreeRTOS и {riscv}]
40+
41+
include::Chapters/TechnicalTerms.adoc[Список терминов]

LFD112x-RU/Makefile

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
ASCIIDOCTOR_PDF = asciidoctor-pdf
2+
3+
ROOT_ASCIIDOC_NAME = Course
4+
5+
CHAPTERS_DIR = Chapters
6+
CHAPTERS = $(wildcard $(CHAPTERS_DIR)/*.adoc)
7+
8+
ROOT_ASCIIDOC = $(ROOT_ASCIIDOC_NAME).adoc
9+
RESULT_PDF = $(ROOT_ASCIIDOC_NAME).pdf
10+
11+
THEME = theme.yml
12+
13+
.PHONY: all
14+
all: $(RESULT_PDF)
15+
16+
$(RESULT_PDF): $(ROOT_ASCIIDOC) $(CHAPTERS) $(THEME)
17+
$(ASCIIDOCTOR_PDF) \
18+
-r asciidoctor-mathematical \
19+
-a mathematical-format=svg \
20+
--theme $(THEME) \
21+
--out-file='$@' '$<'
22+
23+
.PHONY: clean
24+
clean:
25+
$(RM) $(RESULT_PDF)

0 commit comments

Comments
 (0)