环境搭建
https://docs.rtems.org/branches/master/user/start/index.html
依赖
https://docs.rtems.org/branches/master/user/hosts/posix.html#xubuntu
RTEMS5(建议用RTEMS6)
get src
git clone git://git.rtems.org/rtems-source-builder.git rsb
git clone git://git.rtems.org/rtems.git
!将branch更换到5!
install tools
../source-builder/sb-set-builder --prefix=$HOME/devel/rtems/tools/rtems/5 5/rtems-arm
../source-builder/sb-set-builder --prefix=/home/yangn0/devel/rtems5-i386/rtems/5 5/rtems-i386
../source-builder/sb-set-builder --prefix=/home/yangn0/devel/rtems5-sparc/rtems/5 5/rtems-sparc
export PATH=/home/yangn0/devel/rtems5-i386/rtems/5/bin:$PATH
bootstrap(RTEMS6没有这个)
cd ~/devel/rtems5-i386/src/rtems
./rtems-bootstrap
BSP build
https://docs.rtems.org/branches/master/user/start/bsp-build.html
https://www.jsolano.com/uncategorized/rtems-workflow-on-a-stm32f4-nucleo-board/
../source-builder/sb-set-builder --list-bsets
# Build the stm32f4 bsp
cd ~/devel/rtems/src/build
~/devel/rtems/src/rtems/configure --prefix=$HOME/devel/rtems/tools/rtems/5 --target=arm-rtems5 --enable-rtemsbsp=stm32f4 --enable-posix --disable-networking --enable-tests=samples --enable-maintainer-mode
make all
make install
# build i386 bsp
cd ~/devel/rtems5-i386/build/bsp-pc386
/home/yangn0/devel/rtems5-i386/src/rtems/configure \
--prefix=/home/yangn0/devel/rtems5-i386/rtems/5 \
--target=i386-rtems5 \
--enable-rtemsbsp=pc386
make
make install
# build erc32 bsp
cd /home/yangn0/devel/rtems5-sparc/src/rsb/rtems
../source-builder/sb-set-builder --prefix=/home/yangn0/devel/rtems5-sparc/rtems/5 \
--target=sparc-rtems5 --with-rtems-bsp=erc32 --with-rtems-legacy-network 5/rtems-kernel
samples
/home/yangn0/devel/rtems/src/build/arm-rtems5/c/stm32f4/testsuites/samples/hello.exe
RTEMS6(aarch64)
目录结构
├── app
│ ├── hello
│ ├── rtems-btstack
│ └── test
├── buildbsp.sh
├── buildlibbsd.sh
├── rtems
│ └── 6
└── src
├── rtems
├── rtems-libbsd
└── rtems-source-builder
get src
git clone https://github.com/RTEMS/rtems-source-builder
git clone https://github.com/RTEMS/rtems
install tools
cd /home/yangn0/devel/rtems-aarch64/src/rtems-source-builder/rtems
../source-builder/sb-set-builder --prefix=$HOME/devel/rtems-aarch64/rtems/6 6/rtems-aarch64
加入环境变量
nano ~/.profile
PATH=$PATH:/home/yangn0/devel/rtems-aarch64/rtems/6/bin
source ~/.profile
手动构建BSP
./waf bspdefaults --rtems-bsps=aarch64/raspberrypi4b
:get all options with default values for base BSP variants
./waf bsplist
:lists base BSP variants
cd ~/devel/rtems2/src/rtems
./rtems-bsps
nano config.ini
[aarch64/raspberrypi4b]
BUILD_TESTS = True
[aarch64/a72_lp64_qemu]
BUILD_TESTS = True
[arm/nucleo-h743zi]
[arm/stm32f4]
[arm/stm32f105rc]
./waf distclean
./waf configure --prefix=$HOME/devel/rtems-aarch64/rtems/6
./waf
./waf install
test BSP
ls /home/yangn0/devel/rtems2/tools/rtems/6/share/rtems/tester/rtems/testing/bsps
rtems-test --rtems-bsp=a72_lp64_qemu build/aarch64/a72_lp64_qemu
rtems-test --rtems-bsp=stm32h7-stlink build/arm/nucleo-h743zi/
exe 转 bin
arm-rtems6-objcopy -Obinary hello.exe hello.bin
aarch64-rtems6-objcopy -Obinary hello.exe hello.img
qemu
https://www.qemu.org/docs/master/system/arm/stm32.html
https://zhuanlan.zhihu.com/p/479666128
https://blog.csdn.net/BLUCEJIE/article/details/113482065
先git拉取qemu源码
git clone https://gitlab.com/qemu-project/qemu.git
git submodule init
git submodule update --recursive
./configure --target-list=arm-softmmu,aarch64-softmmu,i386-softmmu,sparc-softmmu
make
qemu-system-arm -M netduinoplus2 -nographic -kernel ~/devel/rtems/src/build/arm-rtems5/c/stm32f4/testsuites/samples/hello.exe
arm-rtems5-stm32f4
qemu-system-aarch64 -no-reboot -nographic -serial mon:stdio -machine virt,gic-version=3 -cpu cortex-a72 -m 4096 -kernel hello.exe
windows
.\sdk-debugger-qemu\qemu-system-arm.exe -M stm32f407-atk-explorer -nographic -kernel .\rtthread.bin
raspberrypi4b
https://www.reddit.com/r/RASPBERRY_PI_PROJECTS/comments/xv6r24/need_testers_for_testing_out_rtems_rtos_on_the/
https://docs.rtems.org/branches/master/user/bsps/bsps-aarch64.html?highlight=qemu#raspberry-pi-4b
https://github.com/0xNoor/rtems/commit/b57c6541a15689776a2c94a9d5c5e448587972f0
https://www.reddit.com/user/Noor528/
构建应用
https://waf.io/
https://docs.rtems.org/branches/master/user/start/app.html
mkdir -p ~/devel/rtems2/app/hello/
curl https://waf.io/waf-2.0.19 > waf
chmod +x waf
git init
git submodule add git://git.rtems.org/rtems_waf.git rtems_waf
nano init.c
nano hello.c
nano wscript
./waf distclean
./waf configure --rtems=$HOME/devel/rtems-aarch64/tools/rtems/6 --rtems-bsp=aarch64/raspberrypi4b
./waf
cd build/aarch64-rtems6-raspberrypi4b/
aarch64-rtems6-objcopy -O binary hello.exe hello.img
./waf configure --rtems=/home/yangn0/devel/rtems5-i386/rtems/5 --rtems-bsp=i386/pc386
UART
https://wlink.blog.csdn.net/article/details/124043034
2023.4.11
https://www.eet-china.com/mp/a98363.html
FlyMcu不可以烧bin文件,bin文件可以使用STM32CubeProgrammer软件通过STLINK进行下载
st-link
--connect-under-reset
Flash firmware.bin to device
$ st-flash write firmware.bin 0x8000000 --connect-under-reset
Read firmware from device (4096 bytes)
$ st-flash read firmware.bin 0x8000000 0x1000
Erase firmware from device
$ st-flash erase
gdb调试
https://wangchujiang.com/linux-command/c/gdb.html
连接板子的电脑:
./st-util --connect-under-reset
有rtems环境的电脑:
./arm-rtems6-gdb ~/devel/rtems-arm/app/test/build/arm-rtems6-nucleo-h743zi/test.exe
linux串口设置
https://blog.csdn.net/zoomdy/article/details/50921336
stty -F /dev/ttyUSB0 -a
stty -F /dev/ttyUSB0 ispeed 115200 ospeed 115200 cs8
cat /dev/ttyUSB0
echo "hello" > /dev/ttyUSB0
RTEMS Shell
init.c
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_UNLIMITED_OBJECTS
#define CONFIGURE_UNIFIED_WORK_AREAS
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_INIT
#define CONFIGURE_FILESYSTEM_IMFS
// /* configuration for shell test */
#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
#define CONFIGURE_MAXIMUM_TASKS 20
#define CONFIGURE_MAXIMUM_SEMAPHORES 20
#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 20
#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 20
#define CONFIGURE_STACK_CHECKER_ENABLED
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_EXTRA_TASK_STACKS (6 * RTEMS_MINIMUM_STACK_SIZE)
#define CONFIGURE_MALLOC_STATISTICS
#define CONFIGURE_UNIFIED_WORK_AREAS
#include <rtems/confdefs.h>
#define CONFIGURE_SHELL_COMMANDS_INIT
#define CONFIGURE_SHELL_COMMANDS_ALL
#include <rtems/shellconfig.h>
test.c
#include <stdlib.h>
#include <stdio.h>
#include <bsp.h>
#include <rtems/shell.h>
static rtems_task user_task(rtems_task_argument ignored)
{
printf("In User tASK\n");
printf("starting shell\n");
rtems_shell_init(
"SHLL", /* task_name */
RTEMS_MINIMUM_STACK_SIZE * 4, /* task_stacksize */
100, /* task_priority */
"/dev/ttyS2", /* devname */
false, /* forever */
true, /* wait */
NULL /* login */
);
printf("Initialized shell.\n");
}
rtems_task Init(rtems_task_argument ignored)
{
rtems_name Task_name;
rtems_id Task_id;
rtems_status_code status;
int i;
for (i = 0; i < 3; i++)
{
printf("\n\n*** HELLO WORLD Etual ***\n");
sleep(1);
}
Task_name = rtems_build_name('U', 'S', 'E', 'R');
status = rtems_task_create(
Task_name, 1, RTEMS_MINIMUM_STACK_SIZE * 2,
RTEMS_DEFAULT_MODES,
RTEMS_FLOATING_POINT | RTEMS_DEFAULT_ATTRIBUTES, &Task_id);
status = rtems_task_start(Task_id, user_task, 1);
status = rtems_task_delete(RTEMS_SELF);
}
rtems-libbsd
git clone git://git.rtems.org/rtems-libbsd.git
cd rtems-libbsd
git submodule init
git submodule update rtems_waf
./waf configure --prefix=/home/yangn0/devel/rtems-arm/tools/rtems/6 --rtems-bsps=arm/nucleo-h743zi --buildset=buildset/default.ini
./waf
./waf install
i386
https://imkira.com/QEMU-GDB-Linux-Kernel/
qemu-system-i386.exe -machine pc-q35-2.10 -m 4096 -cpu 486 -serial COM5 -kernel .\app.exe
qemu-system-i386 -m 128 -no-reboot -serial COM5 -kernel app.exe
qemu-system-i386 -m 128 -no-reboot -append "--video=off --console=/dev/com1" -nographic -kernel ./hello.exe
qemu-system-i386 -m 128 -no-reboot -append "--video=off --console=/dev/com3,115200" -nographic -kernel ./build/i386-rtems5-pc386/shell.exe -serial mon:stdio -serial /dev/ttyUSB2
qemu-system-i386 -m 128 -no-reboot -append "--video=off --console=/dev/com2" -nographic -kernel ./o-optimize/app.exe -serial /dev/ttyUSB1 -serial /dev/ttyUSB2
qemu-system-i386 -m 128 -no-reboot -append "--video=off --console=/dev/com3,115200" -nographic -kernel ./build/i386-rtems5-pc386/shell.exe -serial /dev/ttyUSB2 -serial /dev/ttyUSB2 -serial /dev/ttyUSB2 -serial /dev/ttyUSB2
qemu-system-i386 -m 128 -no-reboot -append "--video=off --console=/dev/com2" -nographic -kernel ./build/i386-rtems5-pc386/shell.exe -serial file:./s1 -serial file:./s2 -serial file:./s3 -serial file:./s4
qemu-system-i386 -m 128 -no-reboot -append "--video=off --console=/dev/com1" -nographic -kernel ./o-optimize/app.exe -serial mon:stdio -serial /dev/ttyUSB1 -serial file:./s3
windows:
qemu-system-i386.exe -kernel C:\Users\79230\Desktop\app.exe -serial COM5
gdb调试:
qemu-system-i386 -m 128 -s -S -append "--video=off --console=/dev/com1" -no-reboot -nographic -kernel ./o-optimize/app.exe
erc32
rtems-run --rtems-bsps=erc32-sis build/sparc-rtems5-erc32/hello.exe
rtems-test --rtems-bsps=erc32-sis --debug-trace=gdb o-optimize/app.exe
arm/xilinx-zynq-a9
qemu-system-arm -serial null -serial mon:stdio -nographic -M xilinx-zynq-a9 -m 256M -kernel test.exe
qemu-system-arm -serial null -serial mon:stdio -nographic -M xilinx-zynq-a9 -m 256M -kernel /home/yangn0/devel/rtems-arm/rtems-libbsd/build/arm-rtems6-xilinx_zynq_a9_qemu-default/selectpollkqueue01.exe
qemu-system-arm -semihosting --semihosting-config enable=on,target=native -serial COM5 -serial mon:stdio -nographic -M xilinx-zynq-a9 -m 2048M -kernel app.exe > b.log
aarch64/xilinx_versal_qemu
qemu-system-aarch64 -no-reboot -nographic -serial mon:stdio -serial COM5 -machine xlnx-versal-virt -m 4096 -kernel app.exe
aarch64/xilinx_zynqmp_lp64_qemu
qemu-system-aarch64 -no-reboot -nographic -serial mon:stdio -serial COM5 -machine xlnx-zcu102 -m 4096 -kernel app.exe
RTEMS nonblock 仍然阻塞问题
http://unixwiz.net/techtips/termios-vmin-vtime.html
https://stackoverflow.com/questions/20154157/termios-vmin-vtime-and-blocking-non-blocking-read-operations
问题复现:
在Linux下的正常情况:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <string.h>
int main()
{
int ttyS[8] = {-1};
char s[80];
int i;
struct termios btstack_uart_block_termios;
printf("hello uart\n");
int fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY |O_NONBLOCK);
// printf("%d\n",O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd == -1)
{
puts("fd==-1 !!");
exit(0);
}
printf("fd=%d\n", fd);
if (tcgetattr(fd, &btstack_uart_block_termios) < 0)
{
puts("Couldn't get term attributes");
exit(0);
}
cfmakeraw(&btstack_uart_block_termios); // make raw
// 8N1
btstack_uart_block_termios.c_cflag &= ~CSTOPB;
btstack_uart_block_termios.c_cflag |= CS8;
btstack_uart_block_termios.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines
btstack_uart_block_termios.c_iflag &= ~(IXON | IXOFF | IXANY); // turn off s/w flow ctrl
btstack_uart_block_termios.c_cc[VMIN] = 1;
btstack_uart_block_termios.c_cc[VTIME] = 0;
// no parity
btstack_uart_block_termios.c_cflag &= ~PARENB;
btstack_uart_block_termios.c_cflag &= ~PARODD;
// no flow control
btstack_uart_block_termios.c_cflag &= ~CRTSCTS;
speed_t brate = B115200;
cfsetospeed(&btstack_uart_block_termios, brate);
cfsetispeed(&btstack_uart_block_termios, brate);
if (tcsetattr(fd, TCSANOW, &btstack_uart_block_termios) < 0)
{
puts("Couldn't set term attributes");
exit(0);
}
int buffer=-1;
static int *btstack_uart_block_read_bytes_data;
static int btstack_uart_block_read_bytes_len = 1;
// fcntl(fd, F_SETFL, O_NONBLOCK);
int bytes_read = read(fd, &buffer, btstack_uart_block_read_bytes_len);
printf("bytes_read=%d\n",bytes_read);
printf("buffer=%d\n",buffer);
printf("end uart\n");
exit(0);
}
输出如下:
hello uart
fd=3
bytes_read=-1
buffer=-1
end uart
由于在open()时设置了O_NONBLOCK,所以在read()时没有阻塞直接返回-1。
在RTEMS下的异常情况:
#include <rtems.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <rtems/error.h>
#include <string.h>
void writeUart(int fd, int i)
{
char str[80];
sprintf(str, "Hello /dev/ttyAMA%d\n", i);
int ret = write(fd, str, strlen(str));
if (ret <= 0)
{
printf("send str error. error no: %d\n", errno);
}
}
rtems_task Init(
rtems_task_argument ignored)
{
int ttyS[5] = {-1};
char s[80];
int i;
struct termios btstack_uart_block_termios;
printf("hello uart\n");
int fd = open("/dev/ttyAMA2", O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd == -1)
{
puts("fd==-1 !!");
exit(0);
}
printf("fd=%d\n", fd);
if (tcgetattr(fd, &btstack_uart_block_termios) < 0)
{
puts("Couldn't get term attributes");
exit(0);
}
cfmakeraw(&btstack_uart_block_termios); // make raw
// 8N1
btstack_uart_block_termios.c_cflag &= ~CSTOPB;
btstack_uart_block_termios.c_cflag |= CS8;
btstack_uart_block_termios.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines
btstack_uart_block_termios.c_iflag &= ~(IXON | IXOFF | IXANY); // turn off s/w flow ctrl
btstack_uart_block_termios.c_cc[VMIN] = 1;
btstack_uart_block_termios.c_cc[VTIME] = 0;
// no parity
btstack_uart_block_termios.c_cflag &= ~PARENB;
btstack_uart_block_termios.c_cflag &= ~PARODD;
// no flow control
btstack_uart_block_termios.c_cflag &= ~CRTSCTS;
speed_t brate = B115200;
cfsetospeed(&btstack_uart_block_termios, brate);
cfsetispeed(&btstack_uart_block_termios, brate);
if (tcsetattr(fd, TCSANOW, &btstack_uart_block_termios) < 0)
{
puts("Couldn't set term attributes");
exit(0);
}
writeUart(fd, 0);
static uint8_t *btstack_uart_block_read_bytes_data;
static uint16_t btstack_uart_block_read_bytes_len=1;
char buffer[20]={'\0'};
ssize_t bytes_read = read(fd, buffer, btstack_uart_block_read_bytes_len);
printf("%d\n",bytes_read);
printf("buffer=%s\n",buffer);
puts(" ");
printf("end uart\n");
exit(0);
}
输出如下:
由于在read()处阻塞,导致后面的
bytes_read=-1
buffer=-1
end uart
无法输出。
在RTEMS下open()设置O_NONBLOCK后,read()仍然阻塞,与posix规范不一致。
临时解决方法:
将VMIN设置为0
debug
There is a configure option you can find with:
./waf bspdefaults | grep OPT | less
that is OPTIMIZATION_FLAGS = -O2 -g -fdata-sections -ffunction-sections
if you provide this with the changed -O
option it should build RTEMS at a different level.
Note, I think these options -g -fdata-sections -ffunction-sections
in this setting are wrong and broken and should not be there. RTEMS should either say you need -fdata-sections -ffunction-sections
or it is not needed and -g
has nothing to do with optimisation. There presence makes this type of optimisation change harder than it needs to be because users need to know or understand what they do and for -fdata-*
that is complicated.