本帖最后由 suncl110 于 2023-12-18 16:43 编辑
#申请原创# #申请开发板# (本人自己编写的一个操作系统和CAN协议栈,十分简洁,比较适合小系统的应用)
感谢21家厚爱,由于最近比较忙,就晚些日子发此帖了。本次发帖的主要内容是介绍一下我编写的一个微小的操作系统及与之匹配的CAN收发管理的协议栈
本着开源和互相学习的精神,就分享给大家了,希望能给21IC及杰发MCU添砖加瓦。也希望各位大佬,给点赞回帖,鼓励鼓励!废话不多说了,直接上。
1.由于采用的是GCC+J-LINK方案,先要把杰发芯片型号及FLASH烧录算法加入至J-LINK
如上图操作,算法文件我也放在最下方附件里了
2。调试参数如下图配置:
3。再给大家介绍一个segger家出的调试软件-Ozone v3.26c,比较nice
4.接下来介绍一下这个操作系统的用法,如下:
包含头文件:
#include "SwTmr.h"
#include "task.h"
在taskcfg.h里配置系统参数:
#define TASK_CNT (7u)-->最多任务个数,任务中能被使用的值为0~5,第6个任务分配给了TASKIDLE.0为最高优先级
#define configCPU_CLOCK_HZ (120000000u)-->cpu运行的时钟
#define configTICK_RATE_HZ (1000u)--->系统节拍,1000表示1毫秒
定义任务参数:栈及优先级等
//----------------------------------------------------------------------------
#define TASK_LED3_PRO (4u)
#define TASK_LED3_STACK_DEPTH (128u)
static uint32_t TaskLed3Stack[TASK_LED3_STACK_DEPTH];
//----------------------------------------------------------------------------
#define TASK_LED4_PRO (1u)
#define TASK_LED4_STACK_DEPTH (128u)
static uint32_t TaskLed4Stack[TASK_LED4_STACK_DEPTH];
//----------------------------------------------------------------------------
#define TASK_LEDRGB_PRO (3u)
#define TASK_LEDRGB_STACK_DEPTH (128u)
static uint32_t TaskLedRgbStack[TASK_LEDRGB_STACK_DEPTH];
//----------------------------------------------------------------------------
#define TASK_CAN_PRO (0u)
#define TASK_CAN_STACK_DEPTH (256u)
static uint32_t TaskCanStack[TASK_CAN_STACK_DEPTH];
/* Private functions ---------------------------------------------------------*/
在main函数里创建任务:
int main(void)
{
SystemClock_Config();
InitDebug();
printf("GPIO Basic Test\r\n");
GPIO_LedInit();
GPIO_KeyInit();
CanIf_Bus0Init();
//---------------------------------------------------------------------------------
Task_CreateStatic(Task_Led3,
TaskLed3Stack,
TASK_LED3_STACK_DEPTH,
TASK_LED3_PRO);
Task_CreateStatic(Task_Led4,
TaskLed4Stack,
TASK_LED4_STACK_DEPTH,
TASK_LED4_PRO);
Task_CreateStatic(Task_LedRgb,
TaskLedRgbStack,
TASK_LEDRGB_STACK_DEPTH,
TASK_LEDRGB_PRO);
Task_CreateStatic(Task_Can,
TaskCanStack,
TASK_CAN_STACK_DEPTH,
TASK_CAN_PRO);
//---------------------------------------------------------------------------------
Task_StartScheduler();
while(1u)
{
}
}
各任务简介:
void Task_Led3(void)//LED3每200ms闪烁一次
{
//------------------------------------
while (1)
{
Task_Delay(200);
LED3_TOGGLE;
}
}
void Task_Led4(void)[size=13.3333px]//[size=13.3333px]LED4每400ms闪烁一次
{
//------------------------------------
while (1)
{
Task_Delay(400);
LED4_TOGGLE;
}
}
void Task_LedRgb(void)[size=13.3333px]//[size=13.3333px]当有效按键被按下时,会向此任务发一邮件,当本任务收到邮件后,控制RGB灯变一次色
{
uint8_t key;
//------------------------------------
while (1)
{
//Task_Delay(100);
key = (uint8_t)Task_WaitMail();
if(0u != key)
{ RGB_Toggle();}
}
}
void Task_Can(void)
{
uint32_t taskTick;
uint8_t key;
//------------------------------------
taskTick = Task_GetTick();
//CanSm_Init();
//UdsDsp_Init();
//CanNm_Init();
CanCom_MsgInit();---->初始化CAN收发协议栈
CanTx_Init();-------->初始化发送CAN数据及参数
CanRx_Init();
//------------------------------------
while (1)
{
key = Get_Key4Value();
if(0u != key)
{ Task_GiveMail(TASK_LEDRGB_PRO,(void *)key);}--------》给RGB任务发邮件
Task_DelayUntil(&taskTick,5u);
//CanNm_NetworkManageProcess();
//UdsDsp_DiagServiceProcess();
CanCom_MsgDispatch();------------------------------------》运行CAN协议栈
SwTmr_Dispatch();
}
}
5。CAN协议栈简介:
CANIF.C里给将MCU的CAN数据进行抽象
static void LoadMessageExp(comMsg_s *pPar)//每帧CAN数据在发送前,进行数据加载,将所需发送的数据在此加载
{
static uint8_t cnt=0;
//--------------------------------------------------
pPar->msg.data[0u] = cnt++;
pPar->msg.data[1u] = 0x34;
pPar->msg.data[2u] = 0x56;
pPar->msg.data[3u] = 0x78;
pPar->msg.data[4u] = 0x9a;
pPar->msg.data[5u] = 0xbc;
pPar->msg.data[6u] = 0xde;
pPar->msg.data[7u] = 0xf5;
}
void CanTx_Init(void)
{
//--------------------------------------------------
MsgExp1.sendType = CYCLED_FRAME;----》设置为周期发送帧
MsgExp1.sendDis = 0u;
MsgExp1.stamp = -1000u+0u;
MsgExp1.period = 1000u;-------------》发送周期为1秒
MsgExp1.msg.id = 0x330u;------------》帧ID
MsgExp1.msg.length = 8u;
MsgExp1.preDealFunc = LoadMessageExp;-->发送数据加载函数
(void)CanCom_MsgAdd(&MsgExp1);---------》将本帧加入发送队列
//--------------------------------------------------
MsgExp2.sendType = CYCLED_FRAME;
MsgExp2.sendDis = 0u;
MsgExp2.stamp = -1000u+500u;
MsgExp2.period = 1000u;
MsgExp2.msg.id = 0x181EFF78u|CAN_EXTENDED_FRAME_MASK;///扩散帧实例
MsgExp2.msg.length = 8u;
MsgExp2.preDealFunc = LoadMessageExp;
(void)CanCom_MsgAdd(&MsgExp2);
}
6。好了,将程序烧录进开发板:
祝大家玩的愉快!!!请回帖下载源码
|
如果觉得本实例好,请不吝点赞&回复,以示鼓励,谢谢!