dsp c6657 SYS/BIOS学习笔记

1 SYS/BIOS简介

SYS/BIOS是一种用于TI的DSP平台的嵌入式操作系统(RTOS)。

2 任务

2.1 任务调度

SYS/BIOS任务线程有0-31个优先级(默认0-15,优先级0被空闲线程使用,任务最低优先级为1,最高优先级为15),在内存允许的情况下可以不限制的创建任务数量。SYS/BIOS有独立的内存堆栈,可以为等待某一事件的发生而被挂起,任务会被其他更高优先级的线程打断。

2.2 动态创建任务

以下例程将动态创造两个任务:

cpp 复制代码
/*
 *  ======== task ========
 */
Void taskFxn1(UArg a0, UArg a1) {
	System_printf("enter task1\n");
	Task_sleep(10);
	System_printf("exit task1\n");
	System_flush();
}

Void taskFxn2(UArg a0, UArg a1) {
	System_printf("enter task2\n");
	Task_sleep(10);
	System_printf("exit task2\n");
	System_flush();
}

/*
 *  ======== main ========
 */
Int main() {
	Task_Handle task1;
	Task_Handle task2;

	Task_Params taskParams;
	// 创建两个任务
	Task_Params_init(&taskParams);
	taskParams.priority = 1;//任务优先级
	taskParams.stackSize = 1024;//任务栈大小
	task1 = Task_create(taskFxn1, &taskParams, NULL);

	Task_Params_init(&taskParams);
	taskParams.priority = 2;//任务优先级
	taskParams.stackSize = 1024;//任务栈大小
	task2 = Task_create(taskFxn2, &taskParams, NULL);

	BIOS_start(); /* does not return */
	return (0);
}

3 同步模块

3.1 信号量

3.1.1 信号量简介

信号量通常用于协调一些处于竞争关系的任务之间对共享资源的访问。可以使任务处于挂起状态,用来等待某一个特定的事件,只有当这个事件发布的时候才能继续执行任务。

信号量的操作主要包括Semaphore_pend()Semaphore_post()两个API。Semaphore_pend()用于请求信号量,如果信号量的计数值大于0,则任务可以继续执行,否则任务将被挂起等待信号量的发布。Semaphore_post()用于释放信号量,增加信号量的计数值,如果其他任务因等待此信号量而被挂起,则会唤醒这些任务中的一个。

简单来说:信号量的值为0的时候任务处于挂起状态,信号量大于等于1的时候任务恢复继续执行。

信号量有两种模式:计数信号量(Counting)和二进制信号量(Binary)。计数信号量可以有大于1的计数值,表示多个资源或资源的多个访问权限;而二进制信号量只有0和1两个状态,用于最简单的同步机制,比如一个资源的锁定和解锁。下面是两种计数模式的区别:

3.1.2 动态创建信号量

以下是创建信号量的例程,其中任务2优先级高于任务1,所以进入系统之后优先运行任务2,任务2执行到Semaphore_pend(sem, BIOS_WAIT_FOREVER);时,代表信号量为0将任务2挂起,运行任务1。任务1开始后,运行到Semaphore_post(sem);代表信号量为1,之前被挂起的任务2恢复运行。

cpp 复制代码
Semaphore_Handle sem;

/*
 *  ======== task ========
 */
Void taskFxn1(UArg a0, UArg a1) {
	while (1) {
		System_printf("进入任务1\n");
		System_flush();
		// 发布
		Semaphore_post(sem);
		System_printf("退出任务1\n");
		System_flush();
	}
}

Void taskFxn2(UArg a0, UArg a1) {
	while (1) {
		System_printf("进入任务2\n");
		System_flush();
		// 挂起
		Semaphore_pend(sem, BIOS_WAIT_FOREVER);
		System_printf("退出任务2\n");
		System_flush();
	}
}

/*
 *  ======== main ========
 */
Int main() {
	Task_Handle task1;
	Task_Handle task2;

	Error_Block eb;

	System_printf("enter main()\n");

	Error_init(&eb);

	// 创建两个任务
	Task_Params taskParams;

	Task_Params_init(&taskParams);
	taskParams.priority = 1;
	taskParams.stackSize = 1024;
	task1 = Task_create(taskFxn1, &taskParams, NULL);

	Task_Params_init(&taskParams);
	taskParams.priority = 2;
	taskParams.stackSize = 1024;
	task2 = Task_create(taskFxn2, &taskParams, NULL);

	// 创建一个信号量
	Semaphore_Params semParams;
	Semaphore_Params_init(&semParams);
	semParams.mode = Semaphore_Mode_BINARY; //二进制模式
	sem = Semaphore_create(0, &semParams, NULL); //1为该信号量的初始值

	BIOS_start(); /* does not return */
	return (0);
}

运行结果:

3.2 邮箱

3.2.1 邮箱简介

邮箱SYS/BIOS系统用来在任务间进行buffer传输的。可以将邮箱理解为一个FIFO的队列,Mailbox_post表示向队列写数据,Mailbox_pend表示向队列读数据,如果队列数据存满了,那么就无法向队列再写新的数据。

如果队列已满,执行 Mailbox_post则返回0,在time_out为BIOS_WAIT_FOREVER情况下,则任务被挂起,直到队列可以写数据。

如果队列为空,执行Mailbox_pend则返回0,在time_out为BIOS_WAIT_FOREVER情况下,则任务被挂起,直到队列有数据。

3.2.2 动态创建邮箱

cpp 复制代码
Mailbox_Handle mbx;

Void task_writer(UArg arg0, UArg arg1) {
	Int32 data_addr;
	data_addr = 12345678;
	//推送消息到邮箱
	//第一个参数为邮箱句柄,第二个参数为传递的消息地址,第三个表示超时时间
	Mailbox_post(mbx, &data_addr, BIOS_NO_WAIT);
	System_printf("writer done\n");
	System_flush();
}

Void task_reader(UArg arg0, UArg arg1) {
	Int32 read_addr;
	while (1) {
		//第一个参数为邮箱句柄,第二个参数为传递的消息地址,第三个表示超时时间
		Mailbox_pend(mbx, &read_addr, BIOS_WAIT_FOREVER);
		System_printf("read data = %d \n", read_addr);
		System_flush();
	}
}

Int main() {
	Task_Params taskParams;
	Mailbox_Params mbxParams;
	//创造一个邮箱实例
	Mailbox_Params_init(&mbxParams);
	//在Mailbox_create中,第一个参数表示邮箱传递消息的字节数,第二个参数表示邮箱消息的最大数量
	mbx = Mailbox_create(sizeof(Int32), 1, &mbxParams, NULL);
	//创建一个任务实例
	Task_Params_init(&taskParams);
	//写任务
	taskParams.priority = 10;
	Task_create(task_writer, &taskParams, NULL);
	//读任务
	taskParams.priority = 1;
	Task_create(task_reader, &taskParams, NULL);
	BIOS_start();
	return (0);
}

运行结果:

相关推荐
风雨同舟14 天前
【EtherCAT】关于TwinCAT的使用
人工智能·stm32·单片机·嵌入式硬件·物联网·机器人·dsp开发
淡忘的江南7 天前
《FreeRTOS列表和列表项篇》
freertos·dsp开发
ICGOODFIND1 个月前
STMicroelectronics意法半导体车规芯片系列--亿配芯城(ICgoodFind)
单片机·嵌入式硬件·物联网·fpga开发·硬件架构·硬件工程·dsp开发
linweidong1 个月前
《嵌入式最全面试题-Offer直通车》目录
arm开发·fpga开发·dsp开发·大厂面试·嵌入式面试·单片机面试·硬件面试
芯橦1 个月前
【瑞昱RTL8763E】py文件的执行
驱动开发·python·嵌入式硬件·mcu·物联网·dsp开发·iot
芯橦1 个月前
迷茫!能走出迷茫?
嵌入式硬件·物联网·计算机外设·dsp开发·iot
RIGOL小普1 个月前
用示波器观测RC一阶电路零输入响应是否激励必须是方波信号
单片机·嵌入式硬件·fpga开发·硬件工程·dsp开发
我感觉。2 个月前
【信号与系统第五章】13、希尔伯特变换
学习·dsp开发
乐思智能科技有限公司2 个月前
C语言贪吃蛇小游戏演示和说明
c语言·开发语言·单片机·嵌入式硬件·dsp开发
ManTou馒头2 个月前
01DSP学习-了解DSP外设-以逆变器控制为例
学习·dsp开发