假设有两个任务正在运行TASK_A和TASK_B.当TASK_A正在运行时发生中断并且需要上下文切换到TASK_B.
在ISR内部,TASK_B不应该直接跳转,因为它仍然在ISR中并且还没有返回(例如:RETI未执行).如果通常从ISR返回,它将照常返回TASK_A的最后一个程序计数器.因此,RTOS必须退出ISR,一旦它离开ISR,就必须进行到TASK_B的上下文切换.而不是回到TASK_A,RTOS退出ISR后如何立即取回控制权.
如果从RTOS功能切换,例如在解锁互斥锁时,可以通过备份寄存器来进行直接切换.
RTOS如何处理这种情况
请原谅我这是一个普遍的问题......
实际上malloc如何获得微控制器中可用的当前空闲存储空间.它是否保留了运行时中未连续分配的区域列表?如果代码中有两个malloc语句,它如何获取先前malloc赋值内存分配的信息
如何知道哪个内存是空闲的,哪个内存不在运行时.在编译时,我们可以知道编译器为变量分配RAM中的所有位置.malloc是否使用此信息执行此操作.
我想写一个非常基本的RTOS,可以在两个任务之间切换.它不适合任何专业用途.它只是为了好玩
大多数参考文献都说明了如何使用RTOS而不是如何编写RTOS.
引用像FreeRTOS这样的开源RTOS不会让我们理解基本概念.
我找到的一个参考是Simple Real Time Operating Sysytems
我想知道是否有任何其他来源可以成为那些希望从头开始编写RTOS的人的kickstarter.
我需要制作一个数据控制设备,其任务是对一些 GPIO 进行采样并记录 GPIO 状态,然后通过 UART 将其发送到 PC 以在 PC 中显示。我选择的算法是(请纠正我,因为我是 RTOS 的新手)创建一个以 1us 运行的计时器,然后轮询所需的所有 GPIO 的状态。为此,我在 freertos 演示中使用了一个计时器。并在定时器 ISR 中给出一个信号量,它应该调用一个任务来完成所有剩余的工作。
不知道为什么,但我编辑的代码不起作用
我的主要()是
int main(void) {
/* Prepare the hardware to run this demo. */
prvSetupHardware();
vSemaphoreCreateBinary(SemaphoreTask);
if( SemaphoreTask != NULL )
{
xTaskCreate( SemaphoreTakeTask, "SemaphoreTakeTask", 240, NULL , 3, NULL );
vTaskStartScheduler();
}
for(;;);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
任务 1一个我写的虚拟函数只是为了测试信号量是否正常工作
void SemaphoreTakeTask(void* parameter){
vSetupTimerTest(10); // Timer initialization function in FreeRtos DEMO
TRISEbits.TRISE6 = 0; // Set the GPIO as …Run Code Online (Sandbox Code Playgroud) 在其中一个PCI DMA驱动程序中,我多次见过wmb().wmb()函数究竟做了什么?在某处,它被称为"不伤害的圣水".这个功能的目的是什么?
使用指针写入常量变量会产生运行时错误.
const int i;
int *p;
void main()
{
p = (int*)&i;
*p = 10; // Causes runtime error
}
Run Code Online (Sandbox Code Playgroud)
但是在Windows系统中,一切都是从RAM本身运行的.
当我打印const变量和普通变量的地址时,我可以看到它们处于不同的偏移量.
系统如何知道指针访问的地址是const一个?
当从引导加载程序跳转到应用程序时,我们通常将堆栈指针更新为应用程序堆栈指针,然后将程序计数器更新为应用程序的 Reset_Handler。
void jump_to_application(void)
{
/* Function pointer to the address of the user application. */
fnc_ptr_for_app jump_to_app;
jump_to_app = (fnc_ptr_for_app)(*(volatile uint32_t*) (FLASH_APP_START_ADDRESS+4u));
__CRC_CLK_DISABLE();
HAL_DeInit();
/* Change the main stack pointer. */
__set_MSP(*(volatile uint32_t*)FLASH_APP_START_ADDRESS);
jump_to_app();
}
Run Code Online (Sandbox Code Playgroud)
Reset_Handler的第一行代码如下,将栈指针初始化为自己的栈指针值
Reset_Handler:
ldr sp, =_estack /* Atollic update: set stack pointer */
/* Copy the data segment initializers from flash to SRAM */
movs r1, #0
b LoopCopyDataInit
Run Code Online (Sandbox Code Playgroud)
但仍然建议使用应用程序的堆栈指针更新堆栈指针。
为什么需要,不更新就跳转有什么副作用
如果我有两个任务TASK_A和TASK_B.
堆栈大小TASK_A = 300
堆栈大小TASK_B = 600
TASK_A和TASK_B的上下文切换时间是否依赖于它们各自的堆栈大小.