Запускаем scmRTOS для Cortex-M3 в среде KEIL uVision4

Ну, не нашёл я порт для Кейла на оффсайте, да и чёрт с ним. Сейчас всё сами сделаем. Пиво можно не открывать, всё произойдёт быстрее, чем ты успеешь допить первую банку. Поехали…
- Качаем с оффсайта последний дистрибутив scmRTOS для IAR EWARM – файл scmRTOS.4.00.cortexm3.iar.stm32f1xx.rar (есть внизу топика, если чё).
- Создаём папку для нового Keil-проекта. Назовём её RTOS.
- Распаковываем ранее скачанный архив и копируем из него папку scmRTOS целиком в созданную нами папку RTOS.
- Находим в содержимом архива папку 1-EventFlag, заходим в неё и копируем оттуда папку Src целиком опять же в папку RTOS.
- Итого, имеем папку проекта RTOS, а в ней две папки – scmRTOS и Src. Запускаем Keil uVision4 и переходим к созданию нового проекта: Project –> New uVision Project.
- Выбираем нашу папку RTOS и придумываем название для файла проекта. Назовём его так же, как и папку проекта – RTOS.uvproj.
- Далее выбираем подопытный камень. Пусть это будет STM32F103C8T6, как в DiHalt'овском stm32-модуле к Пинборде-2. Открываем ветку STMicroelectronics и выбираем там наш камень — STM32F103C8.
- Визард предлагает нам создать в папке с проектом startup-файл startup_stm32f10x_md.s. Соглашаемся с ним.
- В окне проекта жмём правой кнопкой мыши по корню проекта – папке Target1 – и выбираем в выпадающем меню «Add group…», чтобы создать новую группу файлов проекта. Переименовываем только что созданную группу в scmRTOS.
- Таким же образом создаём новую группу файлов проекта и называем её Usr.
- Двойной клик по группе scmRTOS, чтобы добавить в неё файлы проекта. Откроется проводник проекта, в котором надо выбрать и добавить все файлы из папок внутри папки RTOS/scmRTOS.
- Точно так же добавляем все файлы из папки RTOS/Usr (за исключением файлов stm32f10x_it.h, stm32f10x_it.c, stm32f10x_vector.c и stm32f10x_flash.icf) в группу файлов проекта Usr. Должно получиться следующее дерево папок и файлов:
Можно было, конечно, дать более благозвучные имена для Target1 и Source Group 1, но оставлю это на чужое усмотрение. - Кликаем правой кнопкой мыши по Target1 и выбираем «Options for Target ‘Target1’…».
- Откроем вкладку C/C++ и внизу в поле Include Paths добавим пути ко всем папкам нашего проекта. Получится как-то так:
- Создадим файл с Intrinsics’ами для KEIL’а. Без него Keil будет ругаться на несуществующие функции __get_interrupt_state(), __set_interrupt_state(), __enable_interrupt(), __disable_interrupt() и __CLZ(), которые есть в IAR’е. Нажимаем Ctrl+N, чтобы создать чистый файл. Вписываем в него следующий код:
#ifndef _INTRINSICS_H_ #define _INTRINSICS_H_ #ifdef __cplusplus extern "C" { #endif static ASM INLINE status_reg_t __get_interrupt_state(void) { mrs r0, primask bx lr } static ASM INLINE void __set_interrupt_state(status_reg_t StatusReg) { msr primask, r0 bx lr } // // Keil specific intrinsics. // #define __enable_interrupt() __enable_irq() #define __disable_interrupt() __disable_irq() #define __CLZ(x) __clz(x) #ifdef __cplusplus } #endif #endif // _INTRINSICS_H_
Оставляем последнюю строку пустой, чтобы компилятор не ругался. Сохраняем этот файл под именем intrinsics.h в папке RTOS/Usr и добавляем его в группу файлов проекта Usr. - Открываем файл OS_Target.h. Комментируем строки с 55 по 65, в которых располагаются проверки на тип используемого компилятора и проца. В строке 74 меняем «#define INLINE _Pragma(«inline=forced») inline» на «#define INLINE __inline», а в строке 78 меняем «#define NORETURN __noreturn» на «#define NORETURN __declspec(noreturn)». Далее в строке 96 меняем «#define DUMMY_INSTR() __no_operation()» на «#define DUMMY_INSTR() __nop()». Когда все изменения сделаны, добавим ещё три строчки в секцию Compiler specific attributes. Делаем отступ на 80-й строчке и добавляем:
#ifndef ASM #define ASM __asm #endif
получаем
// // Compiler specific attributes // // #ifndef INLINE #define INLINE __inline #endif #ifndef NORETURN #define NORETURN __declspec(noreturn) #endif #ifndef ASM #define ASM __asm #endif ... // // Configuration macros // // #define OS_PROCESS #define OS_INTERRUPT extern "C" #define DUMMY_INSTR() __nop() #define INLINE_PROCESS_CTOR
- Открываем файл OS_Target_asm.s. Keil пока не понимает, что написано в этом файле, т.к. считает, что в S-файлах синтаксис должен быть ассемблерным. Начинаем джедайствовать и переведём для него этот файл. Для начала заменим все двойные слэши – комментарии для C-кода на «точку с запятой» — комментарии для ассемблера. Сделать это проще всего функцией замены Ctrl+H или меню Edit -> Replace. Итак, меняем “//” на “;” во всём файле – Replace All.
- Комментируем (уже при помощи «;», помнишь?) строки: 47, 52, 54, 55. В строке 78 меняем «RSEG CODE:CODE(2)» на «PRESERVE8».
- Далее идёт код обработчика системного исключения PendSV. С ним мы совершим маленькое шаманство. Так что, копируем весь код обработчика, т.е. строки 110–123 и сохраняем его где-нибудь в пустом файле, чтобы вернуться к нему чуть позже. А весь код обработчика заодно с меткой (т.е. строки 109-123) переводим в комментарии, чтобы под ногами не путались.
- В строке 147 содержится логическое выражение «(NVIC_ST_CTRL_CLK_SRC | NVIC_ST_CTRL_INTEN | NVIC_ST_CTRL_ENABLE)». Компилятор выругается на него из-за неверного синтаксиса. Так что, заменяем все «неправильные ИЛИ» (|) на «правильные ИЛИ» для ассемблера (:OR:)
LDR R2, =(NVIC_ST_CTRL_CLK_SRC :OR: NVIC_ST_CTRL_INTEN :OR: NVIC_ST_CTRL_ENABLE)
- В строке 144 есть команда «LDR R2, =(SYSTICKFREQ/SYSTICKINTRATE-1)», которая задаёт значение регистра перезагрузки для SysTick, т.е. настраивает его частоту срабатывания. В команде используются константы SYSTICKFREQ и SYSTICKINTRATE, которые находятся в файле scmRTOS_TARGET_CFG.h, ныне нами закомментченом. Поэтому добавим их в начало нашего файла перед определениями констант с адресами регистров:
SYSTICKFREQ EQU 8000000 SYSTICKINTRATE EQU 500
- Теперь оформим функцию os_start() как положено – по-ассемблерски. Выглядеть она будет так:
AREA |.text|, CODE, READONLY os_start PROC EXPORT os_start [WEAK] LDR R1, =NVIC_SYSPRI14 ; Set the PendSV exception priority (lowest) LDR R2, =NVIC_PENDSV_PRI STRB R2, [R1] LDR R1, =NVIC_SYSPRI15 ; Set the SysTick exception priority (lowest) LDR R2, =NVIC_ST_PRI STRB R2, [R1] LDR R1, =NVIC_ST_RELOAD ; Setup SysTick LDR R2, =(SYSTICKFREQ/SYSTICKINTRATE-1) STR R2, [R1] LDR R1, =NVIC_ST_CTRL ; Enable and run SysTick LDR R2, =(NVIC_ST_CTRL_CLK_SRC :OR: NVIC_ST_CTRL_INTEN :OR: NVIC_ST_CTRL_ENABLE) STR R2, [R1] LDR R3, [R0, #(4 * 14)] ; Load process entry point into R3 ADD R0, R0, #(4 * 16) ; emulate context restore MSR PSP, R0 ; store process SP to PSP MOV R0, #2 ; Switch thread mode stack to PSP MSR CONTROL, R0 ISB ; Insert a barrier CPSIE I ; Enable interrupts at processor level BX R3 ; Jump to process exec() function ENDP ALIGN
- Открываем файл startup_stm32f10x_md.s. Комментируем строки 132-134. В них находится ссылка на функцию инициализации SystemInit(), которая определена в CMSIS и отсутствует в нашем проекте. Её можно добавить, но, опять же, оставлю это вам.
- Ниже в этом файле находим область кода обработчика системного исключения PendSV (строка 174). Помните, в п.19 мы скопировали его код? Теперь вставляем этот код вместо строки 176 «B .». И, чтобы всё заработало правильно, вставляем после строки 175 «EXPORT PendSV_Handler [WEAK]» строку «IMPORT os_context_switch_hook»:
PendSV_Handler PROC EXPORT PendSV_Handler [WEAK] IMPORT os_context_switch_hook CPSID I ; Prevent interruption during context switch MRS R0, PSP ; PSP is process stack pointer STMDB R0!, {R4-R11} ; Save remaining regs r4-11 on process stack ; At this point, entire context of process has been saved PUSH {LR} ; Save LR exc_return value LDR R1, =os_context_switch_hook ; os_context_switch_hook(); BLX R1 ; R0 is new process SP; LDMIA R0!, {R4-R11} ; Restore r4-11 from new process stack MSR PSP, R0 ; Load PSP with new process SP CPSIE I POP {PC} ; Return to saved exc_return. Exception return will restore remaining context ENDP
Джедайства закончились. - Заключительный штрих. Открываем файл main.cpp. И оформляем функцию main() следующим образом:
int main() { OS::run(); }
- +6
- 29 августа 2013, 08:44
- uRTOS
- 2
Файлы в топике:
scmRTOS_CortexM3_Keil.ZIP, scmRTOS.4.00.cortexm3.iar.stm32f1xx.rar.zip
Комментарии (8)
RSS свернуть / развернуть