FreeRTOS 8.2.1在MSP430 上的低功耗实现

在IAR环境下向MSP430f5529lp移植freertos 总的来说,基于demo出发对这个移植的帮助比参考stm32移植大,因为概括来说,基于demo只需要完成运行demo——配置config.h——运行例程就可完成,能最大程度避免出现未知错误,下面的开发就可以参考相应的基于stm32的freertos资料完成后续任务。demo里的RegTest.s43移除掉,因为这个.s43是跟测试例程有关,然后因为5529和5438的差别,我们要修改main.c,所以原来的.s43里的定义也就不适用了,移除后就不会报错了。最终例程成功在开发板运行,成功点灯。 阅读详情

应用FreeRTOS在MSP430上做项目已经很久了,如何配合MSP430这样的低功耗芯片让系统尽可能的工作在低功耗模式是本文的议题。

(本文原创,转载请注明出处RickLeaf 优快云http://blog.youkuaiyun.com/rickleaf)

一、IDLE线程作为低功耗入口

对于现在流行的大部分RTOS来说启动系统调度环境以后,都会创建出一个IDLE线程,而这个线程又往往运行在最低的优先级,这个线程让系统的调度环境继续工作。

在FreeRTOS的网站上会建议大家引用这个线程让系统进入MSP430的低功耗模式,事实上从官方拿到的代码就有下面这一句(本文以MSP430F5438A的主芯片为例子,代码跑在EXP-MSP5438A演示板上):

void vApplicationIdleHook( void )
{
	/* Called on each iteration of the idle task.  In this case the idle task
	just enters a low power mode. */
	__bis_SR_register( LPM3_bits + GIE );
}

__bis_SR_register( LPM3_bits + GIE );

这个语句会让MSP430进入LPM3模式,这个模式会关闭CPU,SCG1和SCG0,在进入这个模式以后PC指针会停到下一跳指令那里不动,只有在有中断唤醒以后CPU开始执行中断的代码,在中断的代码中加入下面的语句:

__bic_SR_register_on_exit( SCG1 + SCG0 + OSCOFF + CPUOFF );

中断返回以后CPU才会退出LPM3模式,从__bis_SR_register( LPM3_bits + GIE );之后的指令开始往后执行。

看到这里,或许我们已经觉得这个接口很简单哦。我曾经也是这么以为,直到我发现在这样进入LPM3以后,我的串口经常丢数,花费很多资源在校验重发上,直到我发现CPU的功耗一直很难满足硬件工程师的需求。让我们再看一下FreeRTOS的配置文件,或者说去了解你的系统的时钟滴答,下面是我的FreeRTOS的时钟滴答设置

#define configCPU_CLOCK_HZ    ( 25000000UL )
#define configLFXT_CLOCK_HZ   ( 32768L )
#define configTICK_RATE_HZ    ( ( TickType_t ) 1000 )

可以看到我用一个低速的晶振把系统的工作时钟PLL到25M,并且我把FreeRTOS的时钟滴答设置成了1毫秒(1ms),现在我们设想一下如果我其它任务都已经挂起,只有我IDLE这个线程一直在工作,我们看一下系统的ticker中断

#pragma vector=configTICK_VECTOR
__interrupt __raw void vTickISREntry( void )
{
extern void vPortTickISR( void );
__bic_SR_register_on_exit( SCG1 + SCG0 + OSCOFF + CPUOFF );
	vPortTickISR();
}

每隔1个毫秒系统会唤醒一次CPU,然后CPU再进入LPM3。暂时不考虑其他因素,我们单单从功耗的角度去看就会发现系统大部分时间还是在唤醒状态。而且,LPM3本来进入和退出就需要一定的时间,而且这个时间都是10us级的,这无疑会给中断响应增加负担。事实上,这个是我串口丢数据的直接原因。那么我们该如何去实现低功耗模式呢?我们马上继续讨论。

二、FreeRTOS Tickless低功耗模式在MSP430上的应用

在FreeRTOS网站上很容易找到一种低功耗的解决方案,并且大量的应用CortexM的内核上。所有tickless就是指,在系统进入低功耗模式以后,系统的ticker不会继续工作,听上去挺吓人吧,不是休眠是假死,因为没有心跳了。对于我来说,我只是找到一种方法让系统在没有一些event的时候系统能够停留在CPU的某个低功耗模式,当有中断发生以后再让系统的ticker继续工作。

其实,即使ticker不在,系统还是在运行的只是我们不希望在ticker每个中断都要让系统退出低功耗模式,只要在需要的时候才退出低功耗模式。而FreeRTOS的tickless功能本身就提供了这样的接口。

功能总是以耗费资源为代价的,就像如果我们想得到FreeRTOS的runtime states,我们必须要有一个额外的timer,我们为了实现tickless也必须有个额外的timer。大家可以先去看看FreeRTOS的官方文档。

http://www.freertos.org/low-power-tickless-rtos.html

当我们的系统进入IDLE以后,FreeRTOS内核会估算出下一个时间触发事件的到来的时刻,我们假设那个时刻和当前时刻的差值是T。

这时候我们配置要一个和FreeRTOS的ticker同样频率的timer, 并且希望这个tickless定制器在超时T时刻以后,唤醒并且让系统退出低功耗模式LPM3。然后我们停止系统ticker,系统就有T这么长的时间在LPM3中,等到tickless定时器唤醒并且退出LPM3以后,我们在重新启动ticker并且要把时间T的流逝告诉FreeRTOS,老大我们沉睡了1万年现在要到阿凡达了。

当然我们必须要考虑其它的中断唤醒并且退出LPM3的情况,假想一下沉睡的飞船也要能抵御敌人吧。所以如果其它中断唤醒系统并让系统退出LPM3以后,我们要告诉FreeRTOS你睡了几个月,需要紧急处理一些特别任务。

在FreeRTOS的配置文件中其实已经有了这样的接口,只是在MSP430上可能用的人不多。下面是内核配置:

#define configIDLE_SHOULD_YIELD			0
#define configUSE_TICKLESS_IDLE                 1
</pre><pre name="code" class="cpp">#ifdef __ICC430__
    extern void vApplicationSleep( uint32_t xExpectedIdleTime );
#endif /* __ICCARM__ */


#define portSUPPRESS_TICKS_AND_SLEEP( xIdleTime ) vApplicationSleep( xIdleTime )

我们用timer0 a0作为系统的tickless时钟,用timer0 b0作为系统的ticker,因为EXP-MSP5438的板子timer0 a1是lcd的backlight pwm信号。下面是我的tickless,希望对大家有用,欢迎交流:


/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"

/* Hardware includes. */
#include "msp430.h"

volatile unsigned long ulTicklessCount = 0;
volatile unsigned long ulExpectedIdleTime = 0;
volatile unsigned char TickLessEnable = 0;

/*-----------------------------------------------------------*/
void vConfigureTimerForTickless( void )
{
const unsigned short usACLK_Frequency_Hz = 32768;

	/* Ensure the timer is stopped. */
	TA0CTL = 0;

	/* Run the timer from the ACLK. */
	TA0CTL = TASSEL_1;

	/* Clear everything to start with. */
	TA0CTL |= TACLR;

	/* Set the compare match value according to the tick rate we want. */
	TA0CCR0 = usACLK_Frequency_Hz / configTICK_RATE_HZ;

	/* Enable the interrupts. */
	TA0CCTL0 = CCIE;

	/* Start up clean. */
	TA0CTL |= TACLR;

	/* Up mode. */
	TA0CTL |= MC_1;
}

/*-----------------------------------------------------------*/
unsigned long ulGetExternalTime(void)
{
   return ulTicklessCount;
}

/*-----------------------------------------------------------*/
void vSetWakeTimeInterrupt(unsigned long xExpectedIdleTime)
{
    ulExpectedIdleTime = xExpectedIdleTime;
    ulTicklessCount = 0;
    TickLessEnable = 1;
}

#pragma vector=TIMER0_A0_VECTOR
__interrupt void prvTIMER0_A0_ISR( void )
{
	ulTicklessCount++;
    if((ulTicklessCount >= ulExpectedIdleTime) && TickLessEnable )
    {
        __bic_SR_register_on_exit( SCG1 + SCG0 + OSCOFF + CPUOFF );
        TickLessEnable = 0;
    }
}

void vApplicationSleep( TickType_t xExpectedIdleTime )
{
    unsigned long ulLowPowerTimeAfterSleep;
    eSleepModeStatus eSleepStatus;
    /* Read the current time from a time source that will remain operational
    while the microcontroller is in a low power state. */
    //ulLowPowerTimeBeforeSleep = ulGetExternalTime();
    
    /* Stop the timer that is generating the tick interrupt. */
    TB0CTL &= ~MC_1;
    
    /* Enter a critical section that will not effect interrupts bringing the MCU
    out of sleep mode. */
    __disable_interrupt();
    
    /* Ensure it is still ok to enter the sleep mode. */
    eSleepStatus = eTaskConfirmSleepModeStatus();

    if( eSleepStatus == eAbortSleep )
    {
        /* A task has been moved out of the Blocked state since this macro was
        executed, or a context siwth is being held pending.  Do not enter a
        sleep state.  Restart the tick and exit the critical section. */
        TB0CTL |= MC_1;
        __enable_interrupt();
    }
    else
    {
        if( eSleepStatus == eNoTasksWaitingTimeout )
        {
            /* It is not necessary to configure an interrupt to bring the
            microcontroller out of its low power state at a fixed time in the
            future. */
            __bis_SR_register( LPM3_bits + GIE );
        }
        else
        {
            /* Configure an interrupt to bring the microcontroller out of its low
            power state at the time the kernel next needs to execute.  The
            interrupt must be generated from a source that remains operational
            when the microcontroller is in a low power state. */
            vSetWakeTimeInterrupt(xExpectedIdleTime);

            /* Enter the low power state. */
            __bis_SR_register( LPM3_bits + GIE );
            
            /* Determine how long the microcontroller was actually in a low power
            state for, which will be less than xExpectedIdleTime if the
            microcontroller was brought out of low power mode by an interrupt
            other than that configured by the vSetWakeTimeInterrupt() call.
            Note that the scheduler is suspended before
            portSUPPRESS_TICKS_AND_SLEEP() is called, and resumed when
            portSUPPRESS_TICKS_AND_SLEEP() returns.  Therefore no other tasks will
            execute until this function completes. */
            ulLowPowerTimeAfterSleep = ulGetExternalTime();
            
            /* Correct the kernels tick count to account for the time the
            microcontroller spent in its low power state. */
            vTaskStepTick( ulLowPowerTimeAfterSleep );
        }
        __enable_interrupt();
        TB0CTL |= MC_1;
    }
}


 在成功应用了FreeRTOS的tickless以后,我的系统大部分时间都在LPM3中,而且我的串口在115200波特率上工作没有误码。 



freertos移植心得 1.freertos移植msp430 今天终于移植成功了freertos。现在写下这篇博文来整理这一路移植过程中遇到的问题和心得。 由于使用的是IAR FOR MSP430的IDE,博文只讨论在IAR下的移植。本文针对的是官方支持的平台架构下的移植,不使用官方提供的demo,得到的是一个纯洁版的系统。 1.下载源代码 在freertos的官网下载一份最新的源代码点击打开链接。 2.选择平 阅读详情

相关推荐

基于JTAG Mailbox与Spy-Bi-Wire的MSP430运行时隐蔽通信实战

在嵌入式系统开发中,调试接口不仅是程序下载与调试的通道,其底层协议本身也可被创造性复用,构建出高效的运行时数据交换机制。JTAG(联合测试行动组)作为一种广泛使用的芯片调试标准,定义了访问芯片内部寄存器和内存的协议。其精简变体Spy-Bi-Wire(SBW)将四线JTAG简化为两线,极大节省了MCU的引脚资源。基于此原理,JTAG Mailbox(JMB)技术应运而生,它利用JTAG/SBW接口在完成初始化后保留的专用硬件寄存器,实现主机与目标MCU之间的双向、异步数据通信,其核心价值在于零占用用户外设、对

weixin_34032792的博客 387

嵌入式RTOS在MSP430单片机上的实现

单片机作为嵌入式信息产品的一个重要应用方面,其使用、设计面临着全新的挑战。一方面,人们对嵌入式产品的要求越来越高,稳定可靠、功能丰富、物美价廉的信息产品将成为人们的首选。另一方面,随着微电子工艺水平的发展,单片机处理器的能力不断提高,从最初的8位单片机到16位,进而32位单片机,功能越来越强大,执行速度越来越快,集成度、精确度也越来越高,应用领域进一步拓宽。可以说,单片机芯片的性能已经能够满足现代

beyondhenry的专栏 2101

MSP430软件模拟SPI驱动ShiftBrite RGB LED链

RGB LED链式驱动是嵌入式人机交互与状态指示的关键技术,其核心在于精确时序控制的串行数据移位与同步锁存。基于A6281芯片的ShiftBrite模块支持10位PWM亮度调节与级联扩展,但依赖严格的32位帧格式与时序(如CLOCK上升沿采样、RCK≥100ns脉冲)。在无硬件SPI外设的超低功耗MCU(如MSP430)上,常采用GPIO位操作+周期精准延时(__delay_cycles)实现软件模拟SPI,兼顾资源约束与可靠性。该方案适用于工业面板、传感器节点等对稳定性与电流精度要求较高的场景,同时为学习

weixin_42181686的博客 212

MSP430G2553 移植 Contiki RTOS 实时操作系统

目录新建工程移植过程多任务示例main.c效果 平台:Code Composer Studio 10.4.0 MSP-EXP430G2 LaunchPad 试验板 MSP430G2553 LaunchPad™ Development Kit (MSP‑EXP430G2ET) contiki-os Github 本文参考自二、Contiki移植 —— 一根线 新建工程 移植过程 新建contiki文件夹 添加core、cpu文件夹 将Github下载的contiki/core内如下文件复制进刚建好

乙酸氧铍的博客 1300

基于MSP430F149平台的uCOSII和freeRTOS移植

基于MSP430F149平台的uCOSII和freeRTOS移植,都是从官网下载的最新代码,带一个流水灯测试例程

如何在FreeRTOS下实现低功耗——MSP430F5438平台

MCU实现低功耗本质而言便是停止MCU工作,通过中断的方式重新唤醒MCU,这些中断可以包括外部IO中断,UART接收中断,定时器中断等等。如果结合嵌入式操作系统,可以在空任务或者空任务钩子函数中进入低功耗模式,在系统滴答时钟中断服务函数中重新回到正常工作模式。利用操作系统进入和退出低功耗模式,需要熟悉嵌入式操作系统的空任务和系统滴答时钟中断,下面结合MSP430F5438和FreeRTOS总结一下如何使用嵌入式操作系统实现低功耗工作。

基于MSP430与CC2560的嵌入式蓝牙开发实战:从低功耗设计到SPP透传应用

在嵌入式系统开发中,无线通信技术是实现设备互联的关键。蓝牙技术作为一种成熟的短距离无线通信标准,其经典版本(如蓝牙2.1+EDR)凭借低功耗、高兼容性和易用性,在物联网、智能家居和便携式设备中广泛应用。其工作原理基于2.4GHz频段跳频,通过协议栈(如HCI、L2CAP、RFCOMM)分层处理数据,确保可靠传输。技术价值在于为资源受限的嵌入式设备提供了稳定、低功耗的无线连接方案,显著降低了射频设计和协议开发的复杂度。典型应用场景包括传感器数据采集、工业遥控、医疗设备与手机互联等。本文聚焦于德州仪器(TI)的

weixin_30292745的博客 307

MSP430F5529LP_FreeRTOS_ProjTemplate-master_rtosmsp430_

rtos 移植到msp430列子,可以参考。

FreeRTOS——低功耗管理

是的话,终止休眠状态,当前systick计数值放到systick装载寄存器中,启动systick,重新赋值装载寄存器值为一个系统的tick周期,开启中断。否则装载休眠systick装载值,清除systick当前计数值,启动systick定时器,进入休眠前的工作,然后休眠。补偿系统的tick周期值,也就是说运行了多少时间,因为调度器恢复的时候,会根据tick值进行遍历,保证实时性。四种唤醒方式,WKUP引脚上升沿,RTC闹钟事件,NRST引脚的复位、IWDG独立看门狗的复位。

2301_79532069的博客 1913

FreeRTOSv10.2-MSP430-master_freertos_msp430freertos_msp430f55rto

msp430上运行freertos

Matlab Arduino 硬件支持包安装 MATLAB_Support_Package_for_Arduino_Hardware

Matlab Arduino硬件支持包离线安装

weixin_43283734的博客 2840

Deneyap触摸按键模块:基于MSP430的I²C电容触控方案

电容式触摸按键是嵌入式人机交互的基础输入技术,其核心原理是通过检测电极寄生电容变化实现无机械接触的用户操作。该技术依赖弛张振荡器或专用ADC采样,结合数字滤波与阈值判断生成稳定按键事件。相比传统机械开关,它具备防水防尘、长寿命、低功耗等工程优势;相较于软件RC方案,硬件级电容传感(如MSP430G2352内置CTS模块)显著提升抗噪性与一致性。典型应用场景包括教育开发板交互界面、IoT设备控制面板及电池供电的便携终端。Deneyap Keypad正是面向Arduino生态优化的I²C接口电容触控模块,支持多

weixin_35757191的博客 597

从零开始 使用OMNET++结合VEINS,INET和SUMO的联合仿真

搭建仿真的环境,导入VEINS和INET开源库,使用INET库中提供的网络协议和功能模型来模拟通信协议和网络功能,使用SUMO创建道路网络和车辆轨迹,并导出到OMNeT++中 在OMNeT++中使用VEINS通过socket和SUMO连接,借助VEINS实现的TRACI接口来设置车辆相关的行为和场景,最后在OMNET++中结合VEINS,SUMO和INET运行联合仿真实验,并分析车辆在遇到紧急情况下的通信状况和具体行为

mjmmm的博客 1万+

ServoLight:面向MSP430的超轻量舵机控制库

舵机控制是嵌入式系统中典型的PWM时序应用,其本质是生成周期20ms、脉宽1.0–2.0ms的方波信号。理解该物理层协议是实现低开销驱动的基础。ServoLight 通过摒弃浮点运算、动态内存与中断依赖,采用整数映射、静态引脚绑定和用户主导刷新机制,在TI MSP430等超低资源MCU上达成905字节Flash占用。这种极致优化不仅满足1KB Flash芯片(如MSP430G2211)的部署约束,更保障了确定性时序与亚微秒级脉宽精度,适用于电池供电设备、微型机器人及工业传感器节点等对成本、功耗与可靠性高度敏

weixin_32251525的博客 238

量化人必看|miniQMT踩坑记:回测太慢?一招教你把行情数据“搬回家”!

这篇文章主要聊的是。

奔跑的蜗牛 3476

[Dify 实战] 如何在内网环境部署 Dify 应用:彻底离线的企业级方案解析

企业内网环境如何离线部署Dify?本文提供详细教程:Dify作为开源AI平台,支持完全离线部署,无需外网访问。文中介绍两种部署方式:推荐使用Docker一键部署,也可选择源码安装定制化方案。重点讲解内网模型配置(支持Ollama/GPT-OSS等)、知识库存储(MinIO/PostgreSQL)及内网代理设置,并给出常见问题排查方法。该方案适用于金融、政府等对数据安全要求高的场景,确保敏感数据不泄露,实现完全本地化的AI应用闭环。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 452

MSP430软件I2C主从通信实现:原理、代码与调试指南

I2C总线是一种广泛应用的串行通信协议,通过SDA和SCL两根线实现多设备通信。其工作原理基于主从架构,通过起始/停止条件、地址寻址和应答机制完成数据传输。软件模拟I2C的核心价值在于突破硬件限制,允许在无专用I2C外设的微控制器上实现标准通信。这项技术特别适用于引脚资源紧张的嵌入式场景,如传感器数据采集和低功耗设备互联。本文以MSP430FR2111为例,深入解析如何通过GPIO模拟I2C时序,实现稳定的主从通信,涵盖状态机设计、中断处理和时序控制等关键环节,并针对软件I2C和MSP430开发中的常见问题

weixin_30314793的博客 386

YOLOv11 改进 - 注意力机制 | GC Block(GlobalContext Block)全局上下文块:三重变换捕获全局依赖,提升复杂场景鲁棒性

本文介绍了全局上下文块(GC Block)及其在YOLOv11中的集成应用。GC Block是GCNet的核心组件,结合了NLNet和SENet的优势,通过上下文建模、特征变换和特征融合三个模块,高效捕获特征图中的全局依赖关系,在提高模型性能的同时降低计算成本。我们将GC Block引入YOLOv11,在检测头部分的不同尺度特征图上应用该模块。实验表明,改进后的YOLOv11在目标检测任务中表现良好,展现了GC Block在实际应用中的价值。

魔改工程师的博客 951

基于TI MSP430与CC3200的智能插座:高精度电能计量与Wi-Fi物联网设计详解

在物联网和智能家居领域,实现设备状态感知与远程控制是核心技术。其原理在于通过传感器精确采集物理信号,经由微控制器处理,再通过无线通信模块将数据上传至云端或用户终端,从而赋予传统设备智能化能力。这项技术的核心价值在于实现能源精细化管理、设备状态远程监控与自动化控制,广泛应用于家庭能源管理、工业设备监测及智能电网等场景。本文以德州仪器(TI)的参考设计TIDU531为例,深入剖析了如何利用MSP430i2040高精度计量MCU与CC3200 Wi-Fi SoC的黄金组合,构建一个集“量得准、传得稳、控得住”于一

weixin_29181861的博客 331

操作系统实验四 进程运行轨迹的跟踪与统计(哈工大李治军)

实验4 进程运行轨迹的跟踪与统计 实验目的 掌握 Linux 下的多进程编程技术; 通过对进程运行轨迹的跟踪来形象化进程的概念; 在进程运行轨迹跟踪的基础上进行相应的数据统计,从而能对进程调度算法进行实际的量化评价,更进一步加深对调度和调度算法的理解,获得能在实际操作系统上对调度算法进行实验数据对比的直接经验。 实验内容 进程从创建(Linux 下调用 fork())到结束的整个过程就是进程的生命期,进程在其生命期中的运行轨迹实际上就表现为进程状态的多次切换,如进程创建以后会成为就绪态;当该进程被调度以

leoabcd12的博客 4652

DeepSeek+Cline:开启自动化编程新纪元

随着 AI 技术不断进步,编程领域迎来效率变革。DeepSeek 与 Cline 的结合,成为自动化编程的强大工具。DeepSeek 凭借先进的自然语言处理能力,能精准理解编程需求;Cline 作为 VSCode 插件,可实现代码生成、调试、注释等功能的无缝衔接。本文详细阐述二者安装配置、实战操作流程,涵盖从基础代码生成到复杂项目开发的应用技巧,同时解答常见问题,帮助开发者快速掌握这对 “智能搭档”,提升编程效率,解锁自动化编程的无限可能。

邓邓子的博客 6254

MSP430开发框架解析:事件驱动与状态机在嵌入式系统中的应用

在嵌入式系统开发中,事件驱动架构和有限状态机是管理复杂软件系统的核心设计模式。事件驱动通过中断、定时器等异步机制触发处理函数,替代低效的轮询方式,能显著降低CPU功耗并提升响应效率。有限状态机则将系统行为建模为离散状态和状态转移,使复杂逻辑可视化、易于维护和验证。这些技术特别适用于MSP430这类资源受限的微控制器,能有效管理外设交互、任务调度和数据流。其工程价值在于提升代码可维护性、可测试性及系统可靠性,广泛应用于物联网节点、传感器设备、电池供电装置等场景。本文以Beningo Engineering为M

weixin_30570101的博客 424

GJB 5000B二级-II实施基础

本文主要描述GJB 5000B二级II实施基础与GJB 5000A的变化情况,以及过程域各条款的实施要点

Abel的博客 2580

基于MSP430与AFE44xx的智能手表低功耗心率监测固件架构实战

在嵌入式系统开发中,硬件抽象层(HAL)和模块化设计是构建可维护、可移植固件的基石。HAL通过封装底层硬件操作,为上层的驱动和应用提供统一接口,有效隔离硬件差异,提升代码复用率。状态机与协作式调度器则是实现复杂应用逻辑与实时多任务管理的核心模式,它们将系统行为分解为离散状态,并基于时间片调度周期性任务,在保证功能实时性的同时,最大化CPU空闲时间以降低功耗。这种架构组合对于资源受限的微控制器(如TI MSP430系列)开发具有极高的技术价值,尤其适用于对功耗和可靠性有严苛要求的可穿戴设备、物联网传感器等场景

weixin_33888907的博客 409

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

上一篇: MingW Autotools 编写Vala程序 之二
下一篇: mintty下启动emacs shell mode后,垃圾字符问题
知秋一叶
博客等级 码龄19年 196粉丝 68原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值