三个微内核和四个名字的故事

译者注:本文摘取下面博客的一部分内容说明。因为OKL4和seL4这些概念比较乱,作者的说明能帮我们稍微理清一下。

http://microkerneldude.wordpress.com/2012/10/02/giving-it-away-part-2-on-microkernels-and-the-national-interes/

L4

在OK Labs公司成立之前曾有一个NICTA的L4微内核版本。这是开源的Pistachio微内核的演变,最早主要是在德国的卡尔斯鲁厄大学开发的。我们已经把它移植到了一些架构,包括ARM,针对在资源受限的嵌入式系统做了一些优化,并设计和实现了一些非常酷的方式来进行快速的上下文切换(比Linux快50倍)。我们也将Linux移植到它上面运行(即使用L4作为一个管理程序来支持虚拟化的Linux)。得益于快速上下文切换技术,虚拟化的Linux比原生的Linux跑的还要快。

正如我所说,该微内核从一开始就是开源的(BSD许可证),并一直保持开源。而BSD许可证将允许我们fork出一个封闭源代码的版本(同时承认原作者),这将是一件愚蠢的事。我们希望我们的研究成果尽可能被广泛的使用。

高通

在2004年,L4微内核获得高通的关注。他们有两个具体的(而且相当不同的)的技术问题,因此他们正在寻找解决方案。一个需要快速,具有内存保护功能的实时内核。另一个是要求ARM上的Linux虚拟化。我们的L4提供了这两个问题的解决方案,这就是全部的内容。

高通公司聘请NICTA以帮助他们在他们的无线通信芯片部署L4。最初的评估和原型进行得很顺利,他们决定用L4作为其固件的基础。

这就是OK Labs公司成立所发生的一切。事实上,在我们创建了OK Labs公司时,第一台内置L4的手机已经在日本开始发售了!所有都是基于开源的内核。

OKL4 Microkernel

与高通合作开发的工作量变得太多了而无法在研究机构内部完成。事实上,税务局开始威胁NICTA的免税地位!此外,我们看到商业机会需要承担经营风险,这是你不能用纳税人的钱去做的。这就是为什么我们决定将相关的业务分拆出去成立OK Labs公司。 OK Labs公司OKL4微内核”名义下销售L4,并继续发展成为一个商业级的平台。

OK Labs公司最初做为一个服务企业运营,服务于高通,同时也有其他的客户。需要注意的是,OK Labs甚至不需要NICTA的授权去做到这一点,因为它采取了一个开放源码的发布和技术支持。任何人都可以这样做了(不过,当然,谁先创造了该技术也最适合这么做)。这些都意味着,从来就没有涉及到NICTA版税的任何问题。

另外,需要注意的是如果L4不是开源的话,高通几乎肯定不会采用,这是很重要的。他们的风格是在内部自己弄一套,重新实现L4将是他们自然的方法。我们的承诺对他们来说是不寻常的,却使得NICTA的技术被部署在超过15亿的台设备上。

OKL4 Microvisor

OK Labs公司后来决定要成为一家产品公司,并寻求风险投资来实现这个目标。他们开发了自己的产品,OKL4 Microvisor。这是OKL4微内核的下一代,并是在OK Labs公司从无到有开发出来的,NICTA(或其他人)对它没有所有权。它是(并且提供)在特许的基础上授权的,而这正是你期望一个产品公司做的。

seL4


然后就是第三个微内核了,seL4。这是由NICTA从头开始开发的,它的实现在数学上被证明是规范正确的。

正确性的证明是世界各地的头条大新闻事件。它是真正突破性的,但主要是作为一项科学成果:自上世纪70年代一些人曾试图证明但都没有成功。但是,按我的原子弹的比喻,一旦人们知道这是可能的,他们可以弄清楚自己如何去做。特别是自我们公布了该方法的基本知识之后(毕竟,做研究是NICTA的首要工作,如果不公布就不是研究了)。而且seL4的开发(和所有验证其可行的开发)花了25人一年的时间。这来自很长一段时间内澳大利亚最大的ICT研究的努力。公平地说,这已经使NICTA登上了国际舞台。

seL4的商业化


seL4可以变成一个令人兴奋的产品,但需要进一步的工作。这不是你在实验室做一些事情,这是公司的业务。这就是为什么NICTA需要一个商业化的渠道。

他们决定做的方式是专门授权seL4给OK Labs公司,在达到某些里程碑时有买断的选项(即获取IP买断的选项)。作为交换,NICTA获取了OK Labs公司的股权,以此来作为商业化成功的回报。通过OK Labs公司做为商业化的加速是一个显而易见的选择:首先,OK Labs公司开发市场和销售这种技术。其次,OK Labs公司在澳大利亚执行其所有工程,其他任何替代的企业都在海外。这是一个合理的交易。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 下面是一个简单的基于STM32F103C8T6控制四个520编码器电机的PID代码: ```c #include "stm32f10x.h" #include "stm32f10x_tim.h" #define MOTOR1_PIN1 GPIO_Pin_0 #define MOTOR1_PIN2 GPIO_Pin_1 #define MOTOR2_PIN1 GPIO_Pin_2 #define MOTOR2_PIN2 GPIO_Pin_3 #define MOTOR3_PIN1 GPIO_Pin_4 #define MOTOR3_PIN2 GPIO_Pin_5 #define MOTOR4_PIN1 GPIO_Pin_6 #define MOTOR4_PIN2 GPIO_Pin_7 #define MOTOR1_PORT GPIOA #define MOTOR2_PORT GPIOA #define MOTOR3_PORT GPIOA #define MOTOR4_PORT GPIOA #define MOTOR1_TIMER TIM2 #define MOTOR2_TIMER TIM2 #define MOTOR3_TIMER TIM3 #define MOTOR4_TIMER TIM3 #define MOTOR_PWM_FREQ 20000 #define MOTOR_PWM_PERIOD (SystemCoreClock / MOTOR_PWM_FREQ) #define MOTOR_PWM_PRESCALER 0 #define MOTOR_MAX_SPEED 1000 // PID Control constants #define KP 1.0 #define KI 0.1 #define KD 0.01 // Encoder counts per revolution #define ENCODER_COUNTS_PER_REV 520 uint32_t motor1_speed = 0; uint32_t motor2_speed = 0; uint32_t motor3_speed = 0; uint32_t motor4_speed = 0; int32_t motor1_position = 0; int32_t motor2_position = 0; int32_t motor3_position = 0; int32_t motor4_position = 0; int32_t motor1_error = 0; int32_t motor2_error = 0; int32_t motor3_error = 0; int32_t motor4_error = 0; int32_t motor1_error_sum = 0; int32_t motor2_error_sum = 0; int32_t motor3_error_sum = 0; int32_t motor4_error_sum = 0; int32_t motor1_error_prev = 0; int32_t motor2_error_prev = 0; int32_t motor3_error_prev = 0; int32_t motor4_error_prev = 0; int32_t motor1_derivative = 0; int32_t motor2_derivative = 0; int32_t motor3_derivative = 0; int32_t motor4_derivative = 0; void TIM_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; // Enable TIM2 and TIM3 clocks RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3, ENABLE); // Configure TIM2 and TIM3 to generate PWM signals TIM_TimeBaseStructure.TIM_Prescaler = MOTOR_PWM_PRESCALER; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = MOTOR_PWM_PERIOD; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(MOTOR1_TIMER, &TIM_TimeBaseStructure); TIM_TimeBaseInit(MOTOR2_TIMER, &TIM_TimeBaseStructure); TIM_TimeBaseInit(MOTOR3_TIMER, &TIM_TimeBaseStructure); TIM_TimeBaseInit(MOTOR4_TIMER, &TIM_TimeBaseStructure); // Configure TIM2 and TIM3 to generate PWM signals on channel 1 and 2 TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(MOTOR1_TIMER, &TIM_OCInitStructure); TIM_OC2Init(MOTOR1_TIMER, &TIM_OCInitStructure); TIM_OC1Init(MOTOR2_TIMER, &TIM_OCInitStructure); TIM_OC2Init(MOTOR2_TIMER, &TIM_OCInitStructure); TIM_OC1Init(MOTOR3_TIMER, &TIM_OCInitStructure); TIM_OC2Init(MOTOR3_TIMER, &TIM_OCInitStructure); TIM_OC1Init(MOTOR4_TIMER, &TIM_OCInitStructure); TIM_OC2Init(MOTOR4_TIMER, &TIM_OCInitStructure); // Enable TIM2 and TIM3 TIM_Cmd(MOTOR1_TIMER, ENABLE); TIM_Cmd(MOTOR2_TIMER, ENABLE); TIM_Cmd(MOTOR3_TIMER, ENABLE); TIM_Cmd(MOTOR4_TIMER, ENABLE); } void GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; // Enable GPIOA clock RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // Configure GPIO pins as alternate function push-pull GPIO_InitStructure.GPIO_Pin = MOTOR1_PIN1 | MOTOR1_PIN2 | MOTOR2_PIN1 | MOTOR2_PIN2 | MOTOR3_PIN1 | MOTOR3_PIN2 | MOTOR4_PIN1 | MOTOR4_PIN2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(MOTOR1_PORT, &GPIO_InitStructure); GPIO_Init(MOTOR2_PORT, &GPIO_InitStructure); GPIO_Init(MOTOR3_PORT, &GPIO_InitStructure); GPIO_Init(MOTOR4_PORT, &GPIO_InitStructure); } void Encoder_Config(void) { // TODO: Implement encoder configuration } void PID_Control(void) { // TODO: Implement PID control algorithm } int main(void) { // Initialize system SystemInit(); // Configure TIM2 and TIM3 for PWM output TIM_Config(); // Configure GPIO pins as alternate function push-pull GPIO_Config(); // Configure encoders Encoder_Config(); while(1) { // Perform PID control PID_Control(); // Update motor speeds TIM_SetCompare1(MOTOR1_TIMER, motor1_speed); TIM_SetCompare2(MOTOR1_TIMER, 0); TIM_SetCompare1(MOTOR2_TIMER, motor2_speed); TIM_SetCompare2(MOTOR2_TIMER, 0); TIM_SetCompare1(MOTOR3_TIMER, motor3_speed); TIM_SetCompare2(MOTOR3_TIMER, 0); TIM_SetCompare1(MOTOR4_TIMER, motor4_speed); TIM_SetCompare2(MOTOR4_TIMER, 0); } } ``` 这段代码还需要实现Encoder_Config()和PID_Control()函数,以便正确处理编码器和实现PID控制算法。 ### 回答2: 要使用STM32F103C8T6控制四个520编码器电机的PID代码,可以按照以下步骤进行: 1. 首先,为每个电机设置四个变量,分别为目标位置(target position)、当前位置(current position)、上一次位置(previous position)和误差(error)。 2. 初始化PID参数,包括比例系数(Kp)、积分系数(Ki)和分系数(Kd)。根据具体需求和实际情况进行调整。 3. 在主循环中,不断读取编码器的当前位置,并计算误差(error)。 4. 根据PID算法,计算控制信号。首先计算比例控制项(P),即P = Kp * error;然后计算积分控制项(I),即I = Ki * (error + previous error);最后计算分控制项(D),即D = Kd * (error - previous error)。将这三个控制项相加,得到总控制信号。 5. 根据总控制信号,控制电机的转动。可以使用PWM信号控制电机的转速和方向。将控制信号映射到PWM信号的范围内,然后输出至对应的引脚控制电机。 6. 更新变量,将当前位置更新为上一次位置,将误差更新为当前位置与目标位置之间的差值。 7. 重复步骤3到步骤6,不断进行PID控制,实现电机的位置控制。 需要注意的是,以上只是一个简单的框架代码,具体实现要根据具体的硬件连接和编码器的驱动程序来进行相应的修改和调试。同时,还需要根据实际需求来调整PID参数和控制算法,以实现更好的控制效果。 ### 回答3: 首先,我们需要了解stm32f103c8t6单片机的基本原理和功能。stm32f103c8t6是ST公司生产的一款32位ARM Cortex-M3内核控制器,具有高性能、低功耗和丰富的外设资源特点。 接下来我们来编写控制四个520编码器电机的PID代码: 1. 首先,我们需要配置stm32f103c8t6的GPIO端口,将其连接到电机驱动器的输入端口。利用STM32CubeMX工具,我们可以方便地进行GPIO配置。 2. 接下来,我们需要编写PWM初始化函数,以设置电机的速度控制。PWM可以通过调节占空比来控制电机的转速。通过使用定时器/计数器和PWM模块,可以生成PWM信号并输出到电机驱动器的使能引脚。 3. 然后,我们需要编写编码器读取函数,以读取电机的转速反馈信息。编码器是一种传感器,用于测量电机转动的角度和速度。通过读取编码器反馈信号,我们可以得到电机实际转速的数据。 4. 接下来,我们可以编写PID控制算法函数。PID控制器是一种经典的控制算法,根据给定的目标转速和电机实际转速之间的误差,产生控制输出。PID控制器由比例、积分和分三部分组成。 5. 最后,我们需要编写主函数。在主函数中,我们可以调用上述函数,并在一个循环中实时更新电机的转速控制输出。我们可以使用定时中断来实现PID控制算法的周期性运行。 总结起来,以上就是使用stm32f103c8t6控制四个520编码器电机的PID代码的基本步骤。通过合理的配置和编写代码,我们可以实现精确的电机控制和运动位置的调节。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值