1. 本地开发就直接启动本地安装的CCS
从起始导航页,选择resource explore加载项目,就如云端引入和加载界面是一样的,不过,遇到了网络代理通讯问题,始终加载不出工程
对应网上可以访问,并且可以用加重的Import按钮直接加载到云端开发环境
重启后,提示需要验证cookie并接受条款。暂时跳过这个方法。
2 . 使用本地安装的sdk加载范例项目,因为sdk已经安装,找到下述位置就可以
不过首先需要安装ARM GCC,从网上更新源
选中对应的版本,
安装后要求重新启动ccs。
这时可以启动导入ccs项目的选项
根据本次的目的加载多个范例
3. 上述范例都可以顺利编译,下载到开发板。那么接下来,就分析一下这些代码是如何组织的。首先是标准的电灯游戏,
#include "ti_msp_dl_config.h"
int main(void)
{
/* Power on GPIO, initialize pins as digital outputs */
SYSCFG_DL_init();
/* Default: LED1 and LED3 ON, LED2 OFF */
DL_GPIO_clearPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_2_PIN);
DL_GPIO_setPins(
GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN | GPIO_LEDS_USER_LED_3_PIN);
while (1) {
/*
* Call togglePins API to flip the current value of LEDs 1-3. This
* API causes the corresponding HW bits to be flipped by the GPIO HW
* without need for additional R-M-W cycles by the processor.
*/
delay_cycles(10000000);
DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN |
GPIO_LEDS_USER_LED_2_PIN |
GPIO_LEDS_USER_LED_3_PIN);
}
}
这个开发逻辑和其他类似项目基本一致,就是导入开发板设置,选择LED的连接port和pin,使用togglePin这个功能,配合delay_cycles就可以完成。单文件就可以完成。
4. 使用RTOS的开发逻辑,是首先启动硬件环境,然后初始化线程,创建线程,然后启动线程的逻辑。FreeRTOS的配置在单独的程序里。
int main(void)
{
pthread_t thread;
pthread_attr_t attrs;
struct sched_param priParam;
int retc;
/* Prepare the hardware to run this demo. */
prvSetupHardware();
/* Initialize the attributes structure with default values */
pthread_attr_init(&attrs);
/* Set priority, detach state, and stack size attributes */
priParam.sched_priority = 1;
retc = pthread_attr_setschedparam(&attrs, &priParam);
retc |= pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
retc |= pthread_attr_setstacksize(&attrs, THREADSTACKSIZE);
if (retc != 0) {
/* failed to set attributes */
while (1) {
}
}
retc = pthread_create(&thread, &attrs, mainThread, NULL);
if (retc != 0) {
/* pthread_create() failed */
while (1) {
}
}
/* Start the FreeRTOS scheduler */
vTaskStartScheduler();
return (0);
}
有所不同的是,这个线程中对应uart的硬件初始化也纳入这个线程,本线程内自己包括一个while循环,没有找到线程间通讯的接口
void mainThread(void *arg0)
{
size_t rdCount = 0;
size_t wrCount = 0;
UART_Params_init(&uartParams);
uartParams.baudRate = CONFIG_UART_BAUD_RATE;
uart = UART_open(CONFIG_UART_0, &uartParams);
if (uart == NULL) {
// UART_open failed
__BKPT();
}
/* Turn on user LED to indicate successful initialization */
DL_GPIO_clearPins(GPIO_GRP_0_PORT, GPIO_GRP_0_PIN_0_PIN);
/* Loop forever echoing */
while (1) {
UART_read(uart, gBuffer, CONFIG_UART_BUFFER_LENGTH, &rdCount);
UART_write(uart, gBuffer, CONFIG_UART_BUFFER_LENGTH, &wrCount);
}
}
但是完成这个简单任务应该没有问题。
5. 相对大一些的项目,需要多个外设协同的,这里分析一下板载出厂项目的代码。这个是用case-switch选择函数实现,然后各个任务使用硬流程和中断组合实现。
int main(void)
{
/*
* Initialize peripherals used in the overall out of box i.e. UART and
* switch to change between examples
*/
HAL_System_Init();
/* Initialize GUI layer */
GUI_Init();
GUI_InitRxCmd(&gGUI_RXCommands[0],
(sizeof(gGUI_RXCommands) / sizeof(gGUI_RXCommands[0])));
while (1) {
/* The particular demo mode can be changed by GUI or switch */
switch (gDemoMode) {
case BLINK_LED_MODE:
blink_led_runExample();
break;
case LIGHTSENSOR_MODE:
lightsensor_runExample();
break;
case THERMISTOR_MODE:
thermistor_runExample();
break;
case IDLE:
/* LED1 toggles every 500ms in IDLE mode */
DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
delay_cycles(16000000);
break;
default:
break;
}
}
}
以传感器读取这个任务为例
oid thermistor_runExample(void)
{
uint16_t celcius_reading = 0;
uint16_t initial_reading = 0;
bool first_reading = true;
setupExample();
while (gDemoMode == THERMISTOR_MODE) {
while (gCheckThermistor == false && gDemoMode == THERMISTOR_MODE) {
__WFE();
}
celcius_reading =
(uint32_t) thermistor_calc_temperature(gThermistorADCResult);
if (first_reading) {
initial_reading = celcius_reading;
first_reading = false;
}
GUIComm_sendUInt32("thADC", STR_LEN_FIVE, celcius_reading);
/*
* Change in LEDs is based on current sample compared to previous sample
*
* If the new sample is warmer than 2* from initial temp, turn LED red
* If the new sample is colder than 2* from initial temp, turn LED blue
* Else, keep LED green
*/
if (celcius_reading - 64 > initial_reading) {
DL_GPIO_clearPins(
GPIO_RGB_PORT, (GPIO_RGB_GREEN_PIN | GPIO_RGB_BLUE_PIN));
DL_GPIO_setPins(GPIO_RGB_PORT, GPIO_RGB_RED_PIN);
} else if (celcius_reading < initial_reading - 64) {
DL_GPIO_clearPins(
GPIO_RGB_PORT, (GPIO_RGB_RED_PIN | GPIO_RGB_BLUE_PIN));
DL_GPIO_setPins(GPIO_RGB_PORT, GPIO_RGB_BLUE_PIN);
} else {
DL_GPIO_clearPins(
GPIO_RGB_PORT, (GPIO_RGB_RED_PIN | GPIO_RGB_BLUE_PIN));
DL_GPIO_setPins(GPIO_RGB_PORT, GPIO_RGB_GREEN_PIN);
}
gCheckThermistor = false;
}
cleanupExample();
}
完全是单线程实现。
6 小结
基于MSPM0L1306的开发,受到内存和性能的制约,因此需要注意编程效率和编译后大小。这里,提供了两种开发的思路,可以用线程进行并行开发也可以单线程流水执行,具体研究这些范例代码就可以更深刻认识,在后面的开发边学边干。